@SuppressWarnings("unused") private static void primitiveSetter(final ScriptObject wrappedSelf, final Object self, final Object key, final boolean strict, final Object value) { // See ES5.1 8.7.2 PutValue (V, W) final String name = JSType.toString(key); final FindProperty find = wrappedSelf.findProperty(name, true); if (find == null || !find.getProperty().isAccessorProperty() || !find.getProperty().hasNativeSetter()) { if (strict) { if (find == null || !find.getProperty().isAccessorProperty()) { throw typeError("property.not.writable", name, ScriptRuntime.safeToString(self)); } else { throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self)); } } return; } // property found and is a UserAccessorProperty find.setValue(value, strict); }
@Override protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operation) { final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); if (overrides && super.hasOwnProperty(name)) { try { final GuardedInvocation inv = super.findGetMethod(desc, request, operation); if (inv != null) { return inv; } } catch (final Exception e) { //ignored } } switch(operation) { case "getProp": case "getElem": return findHook(desc, __get__); case "getMethod": final FindProperty find = adaptee.findProperty(__call__, true); if (find != null) { final Object value = find.getObjectValue(); if (value instanceof ScriptFunction) { final ScriptFunctionImpl func = (ScriptFunctionImpl)value; // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, func.makeBoundFunction(this, new Object[] { name })), 0, Object.class), testJSAdaptor(adaptee, null, null, null), adaptee.getProtoSwitchPoint(__call__, find.getOwner())); } } throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this)); default: break; } throw new AssertionError("should not reach here"); }
private static Type getPropertyType(final ScriptObject sobj, final String name) { final FindProperty find = sobj.findProperty(name, true); if (find == null) { return null; } final Property property = find.getProperty(); final Class<?> propertyClass = property.getType(); if (propertyClass == null) { // propertyClass == null means its value is Undefined. It is probably not initialized yet, so we won't make // a type assumption yet. return null; } else if (propertyClass.isPrimitive()) { return Type.typeFor(propertyClass); } final ScriptObject owner = find.getOwner(); if (property.hasGetterFunction(owner)) { // Can have side effects, so we can't safely evaluate it; since !propertyClass.isPrimitive(), it's Object. return Type.OBJECT; } // Safely evaluate the property, and return the narrowest type for the actual value (e.g. Type.INT for a boxed // integer). final Object value = property.needsDeclaration() ? ScriptRuntime.UNDEFINED : property.getObjectValue(owner, owner); if (value == ScriptRuntime.UNDEFINED) { return null; } return Type.typeFor(JSType.unboxedFieldType(value)); }
private static Object evaluatePropertySafely(final ScriptObject sobj, final String name) { final FindProperty find = sobj.findProperty(name, true); if (find == null) { return null; } final Property property = find.getProperty(); final ScriptObject owner = find.getOwner(); if (property.hasGetterFunction(owner)) { // Possible side effects; can't evaluate safely return null; } return property.getObjectValue(owner, owner); }
@Override protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request) { final String name = NashornCallSiteDescriptor.getOperand(desc); if (overrides && super.hasOwnProperty(name)) { try { final GuardedInvocation inv = super.findGetMethod(desc, request); if (inv != null) { return inv; } } catch (final Exception e) { //ignored } } if (!NashornCallSiteDescriptor.isMethodFirstOperation(desc)) { return findHook(desc, __get__); } else { final FindProperty find = adaptee.findProperty(__call__, true); if (find != null) { final Object value = find.getObjectValue(); if (value instanceof ScriptFunction) { final ScriptFunction func = (ScriptFunction)value; // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, func.createBound(this, new Object[] { name })), 0, Object.class), testJSAdapter(adaptee, null, null, null), adaptee.getProtoSwitchPoints(__call__, find.getOwner()), null); } } throw typeError("no.such.function", name, ScriptRuntime.safeToString(this)); } }
@Override protected FindProperty findProperty(final Object key, final boolean deep, final boolean isScope, final ScriptObject start) { if (lexicalScope != null && isScope) { final FindProperty find = lexicalScope.findProperty(key, false); if (find != null) { return find; } } return super.findProperty(key, deep, isScope, start); }
@Override protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final StandardOperation operation) { final String name = NashornCallSiteDescriptor.getOperand(desc); if (overrides && super.hasOwnProperty(name)) { try { final GuardedInvocation inv = super.findGetMethod(desc, request, operation); if (inv != null) { return inv; } } catch (final Exception e) { //ignored } } switch(operation) { case GET_PROPERTY: case GET_ELEMENT: return findHook(desc, __get__); case GET_METHOD: final FindProperty find = adaptee.findProperty(__call__, true); if (find != null) { final Object value = find.getObjectValue(); if (value instanceof ScriptFunction) { final ScriptFunction func = (ScriptFunction)value; // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, func.createBound(this, new Object[] { name })), 0, Object.class), testJSAdapter(adaptee, null, null, null), adaptee.getProtoSwitchPoints(__call__, find.getOwner()), null); } } throw typeError("no.such.function", name, ScriptRuntime.safeToString(this)); default: break; } throw new AssertionError("should not reach here"); }
@Override protected FindProperty findProperty(final Object key, final boolean deep, final ScriptObject start) { if (lexicalScope != null && start != this && start.isScope()) { final FindProperty find = lexicalScope.findProperty(key, false); if (find != null) { return find; } } return super.findProperty(key, deep, start); }
@Override protected FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) { if (lexicalScope != null && start != this && start.isScope()) { final FindProperty find = lexicalScope.findProperty(key, false); if (find != null) { return find; } } return super.findProperty(key, deep, start); }
@SuppressWarnings("unused") private static void primitiveSetter(final ScriptObject wrappedSelf, final Object self, final Object key, final boolean strict, final Object value) { // See ES5.1 8.7.2 PutValue (V, W) final String name = JSType.toString(key); final FindProperty find = wrappedSelf.findProperty(name, true); if (find == null || !(find.getProperty() instanceof UserAccessorProperty) || !find.getProperty().isWritable()) { if (strict) { throw typeError("property.not.writable", name, ScriptRuntime.safeToString(self)); } return; } // property found and is a UserAccessorProperty find.setValue(value, strict); }
@Override protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operation) { final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); if (overrides && super.hasOwnProperty(name)) { try { final GuardedInvocation inv = super.findGetMethod(desc, request, operation); if (inv != null) { return inv; } } catch (final Exception e) { //ignored } } switch(operation) { case "getProp": case "getElem": return findHook(desc, __get__); case "getMethod": final FindProperty find = adaptee.findProperty(__call__, true); if (find != null) { final Object value = find.getObjectValue(); if (value instanceof ScriptFunction) { final ScriptFunction func = (ScriptFunction)value; // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, func.createBound(this, new Object[] { name })), 0, Object.class), testJSAdaptor(adaptee, null, null, null), adaptee.getProtoSwitchPoints(__call__, find.getOwner()), null); } } throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this)); default: break; } throw new AssertionError("should not reach here"); }
@Override protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operation) { final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); if (overrides && super.hasOwnProperty(name)) { try { final GuardedInvocation inv = super.findGetMethod(desc, request, operation); if (inv != null) { return inv; } } catch (final Exception e) { //ignored } } switch(operation) { case "getProp": case "getElem": return findHook(desc, __get__); case "getMethod": final FindProperty find = adaptee.findProperty(__call__, true); if (find != null) { final Object value = getObjectValue(find); if (value instanceof ScriptFunction) { final ScriptFunctionImpl func = (ScriptFunctionImpl)value; // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, func.makeBoundFunction(this, new Object[] { name })), 0, Object.class), adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), testJSAdaptor(adaptee, null, null, null)); } } throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this)); default: break; } throw new AssertionError("should not reach here"); }