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); }
/** * Declares a symbol name as belonging to a non-scoped local variable during an on-demand * compilation of a single function. This method will add an explicit Undefined binding for the * local into the runtime scope if it's otherwise implicitly undefined so that when an expression * is evaluated for the name, it won't accidentally find an unrelated value higher up the scope * chain. It is only required to call this method when doing an optimistic on-demand compilation. * * @param symbolName the name of the symbol that is to be declared as being a non-scoped local * variable. */ void declareLocalSymbol(final String symbolName) { assert compiler.useOptimisticTypes() && compiler.isOnDemandCompilation() && runtimeScope != null : "useOptimistic=" + compiler.useOptimisticTypes() + " isOnDemand=" + compiler.isOnDemandCompilation() + " scope=" + runtimeScope; if (runtimeScope.findProperty(symbolName, false) == null) { runtimeScope.addOwnProperty( symbolName, NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE, ScriptRuntime.UNDEFINED); } }
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)); }