< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java

Print this page




 132     private PropertyMap map;
 133 
 134     /** objects proto. */
 135     private ScriptObject proto;
 136 
 137     /** Object flags. */
 138     private int flags;
 139 
 140     /** Area for primitive properties added to object after instantiation, see {@link AccessorProperty} */
 141     protected long[]   primitiveSpill;
 142 
 143     /** Area for reference properties added to object after instantiation, see {@link AccessorProperty} */
 144     protected Object[] objectSpill;
 145 
 146     /** Indexed array data. */
 147     private ArrayData arrayData;
 148 
 149     /** Method handle to retrieve prototype of this object */
 150     public static final MethodHandle GETPROTO      = findOwnMH_V("getProto", ScriptObject.class);
 151 
 152     static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class);
 153     static final MethodHandle GLOBALFILTER       = findOwnMH_S("globalFilter", Object.class, Object.class);
 154     static final MethodHandle DECLARE_AND_SET    = findOwnMH_V("declareAndSet", void.class, String.class, Object.class);
 155 
 156     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
 157     private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class);
 158     private static final MethodHandle KNOWNFUNCPROPGUARDPROTO = findOwnMH_S("knownFunctionPropertyGuardProto", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, int.class, ScriptFunction.class);
 159 
 160     private static final ArrayList<MethodHandle> PROTO_FILTERS = new ArrayList<>();
 161 
 162     /** Method handle for getting the array data */
 163     public static final Call GET_ARRAY          = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArray", ArrayData.class);
 164 
 165     /** Method handle for getting a function argument at a given index. Used from MapCreator */
 166     public static final Call GET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
 167 
 168     /** Method handle for setting a function argument at a given index. Used from MapCreator */
 169     public static final Call SET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArgument", void.class, int.class, Object.class);
 170 
 171     /** Method handle for getting the proto of a ScriptObject */
 172     public static final Call GET_PROTO          = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);


2018             mh = Lookup.emptyGetter(returnType);
2019             protoSwitchPoint = getProtoSwitchPoint(name, owner);
2020         } else if (!find.isSelf()) {
2021             assert mh.type().returnType().equals(returnType) :
2022                     "return type mismatch for getter " + mh.type().returnType() + " != " + returnType;
2023             if (!(property instanceof UserAccessorProperty)) {
2024                 // Add a filter that replaces the self object with the prototype owning the property.
2025                 mh = addProtoFilter(mh, find.getProtoChainLength());
2026             }
2027             protoSwitchPoint = getProtoSwitchPoint(name, owner);
2028         } else {
2029             protoSwitchPoint = null;
2030         }
2031 
2032         final GuardedInvocation inv = new GuardedInvocation(mh, guard, protoSwitchPoint, exception);
2033         return inv.addSwitchPoint(findBuiltinSwitchPoint(name));
2034     }
2035 
2036     private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
2037         Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
2038         final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
2039         final MethodHandle guard   = getScriptObjectGuard(desc.getMethodType(), true);
2040         return new GuardedInvocation(invoker, guard);
2041     }
2042 
2043     @SuppressWarnings("unused")
2044     private Object megamorphicGet(final String key, final boolean isMethod) {
2045         final FindProperty find = findProperty(key, true);
2046         if (find != null) {
2047             return find.getObjectValue();
2048         }
2049 
2050         return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
2051     }
2052 
2053     // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
2054     @SuppressWarnings("unused")
2055     private void declareAndSet(final String key, final Object value) {
2056         final PropertyMap oldMap = getMap();
2057         final FindProperty find = findProperty(key, false);
2058         assert find != null;
2059 
2060         final Property property = find.getProperty();
2061         assert property != null;
2062         assert property.needsDeclaration();
2063 
2064         final PropertyMap newMap = oldMap.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
2065         setMap(newMap);
2066         set(key, value, 0);
2067     }
2068 
2069     /**
2070      * Find the appropriate GETINDEX method for an invoke dynamic call.


2365                                 getMap(),
2366                                 find.getGetter(Object.class, INVALID_PROGRAM_POINT, request),
2367                                 find.getProtoChainLength(),
2368                                 func),
2369                         getProtoSwitchPoint(NO_SUCH_PROPERTY_NAME, find.getOwner()),
2370                         //TODO this doesn't need a ClassCastException as guard always checks script object
2371                         null);
2372             }
2373         }
2374 
2375         if (scopeAccess) {
2376             throw referenceError("not.defined", name);
2377         }
2378 
2379         return createEmptyGetter(desc, explicitInstanceOfCheck(desc, request), name);
2380     }
2381 
2382     /**
2383      * Invoke fall back if a property is not found.
2384      * @param name Name of property.

2385      * @param programPoint program point
2386      * @return Result from call.
2387      */
2388     protected Object invokeNoSuchProperty(final String name, final int programPoint) {
2389         final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
2390 
2391         Object ret = UNDEFINED;
2392 
2393         if (find != null) {
2394             final Object func = find.getObjectValue();
2395 
2396             if (func instanceof ScriptFunction) {
2397                 ret = ScriptRuntime.apply((ScriptFunction)func, this, name);


2398             }
2399         }
2400 
2401         if (isValid(programPoint)) {
2402             throw new UnwarrantedOptimismException(ret, programPoint);
2403         }
2404 
2405         return ret;
2406     }
2407 
2408 
2409     /**
2410      * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined.
2411      * @param name the method name

2412      * @return the bound function, or undefined
2413      */
2414     private Object getNoSuchMethod(final String name, final int programPoint) {
2415         final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true);
2416 
2417         if (find == null) {
2418             return invokeNoSuchProperty(name, programPoint);
2419         }
2420 
2421         final Object value = find.getObjectValue();
2422         if (!(value instanceof ScriptFunction)) {
2423             return UNDEFINED;
2424         }
2425 
2426         return ((ScriptFunction)value).createBound(this, new Object[] {name});


2427     }
2428 
2429     private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) {
2430         if (NashornCallSiteDescriptor.isOptimistic(desc)) {
2431             throw new UnwarrantedOptimismException(UNDEFINED, NashornCallSiteDescriptor.getProgramPoint(desc), Type.OBJECT);
2432         }
2433 
2434         return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()),
2435                 NashornGuards.getMapGuard(getMap(), explicitInstanceOfCheck), getProtoSwitchPoint(name, null),
2436                 explicitInstanceOfCheck ? null : ClassCastException.class);
2437     }
2438 
2439     private abstract static class ScriptObjectIterator <T extends Object> implements Iterator<T> {
2440         protected T[] values;
2441         protected final ScriptObject object;
2442         private int index;
2443 
2444         ScriptObjectIterator(final ScriptObject object) {
2445             this.object = object;
2446         }


2721                 if ((object = object.getProto()) == null) {
2722                     break;
2723                 }
2724 
2725                 final ArrayData array = object.getArray();
2726 
2727                 if (array.has(index)) {
2728                     return isValid(programPoint) ?
2729                         array.getIntOptimistic(index, programPoint) :
2730                         array.getInt(index);
2731                 }
2732             }
2733         } else {
2734             final FindProperty find = findProperty(key, true);
2735 
2736             if (find != null) {
2737                 return getIntValue(find, programPoint);
2738             }
2739         }
2740 
2741         return JSType.toInt32(invokeNoSuchProperty(key, programPoint));
2742     }
2743 
2744     @Override
2745     public int getInt(final Object key, final int programPoint) {
2746         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2747         final int       index        = getArrayIndex(primitiveKey);
2748         final ArrayData array        = getArray();
2749 
2750         if (array.has(index)) {
2751             return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index);
2752         }
2753 
2754         return getInt(index, JSType.toString(primitiveKey), programPoint);
2755     }
2756 
2757     @Override
2758     public int getInt(final double key, final int programPoint) {
2759         final int       index = getArrayIndex(key);
2760         final ArrayData array = getArray();
2761 


2803                 if ((object = object.getProto()) == null) {
2804                     break;
2805                 }
2806 
2807                 final ArrayData array = object.getArray();
2808 
2809                 if (array.has(index)) {
2810                     return isValid(programPoint) ?
2811                         array.getLongOptimistic(index, programPoint) :
2812                         array.getLong(index);
2813                 }
2814             }
2815         } else {
2816             final FindProperty find = findProperty(key, true);
2817 
2818             if (find != null) {
2819                 return getLongValue(find, programPoint);
2820             }
2821         }
2822 
2823         return JSType.toLong(invokeNoSuchProperty(key, programPoint));
2824     }
2825 
2826     @Override
2827     public long getLong(final Object key, final int programPoint) {
2828         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2829         final int       index        = getArrayIndex(primitiveKey);
2830         final ArrayData array        = getArray();
2831 
2832         if (array.has(index)) {
2833             return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
2834         }
2835 
2836         return getLong(index, JSType.toString(primitiveKey), programPoint);
2837     }
2838 
2839     @Override
2840     public long getLong(final double key, final int programPoint) {
2841         final int       index = getArrayIndex(key);
2842         final ArrayData array = getArray();
2843 


2885                 if ((object = object.getProto()) == null) {
2886                     break;
2887                 }
2888 
2889                 final ArrayData array = object.getArray();
2890 
2891                 if (array.has(index)) {
2892                     return isValid(programPoint) ?
2893                         array.getDoubleOptimistic(index, programPoint) :
2894                         array.getDouble(index);
2895                 }
2896             }
2897         } else {
2898             final FindProperty find = findProperty(key, true);
2899 
2900             if (find != null) {
2901                 return getDoubleValue(find, programPoint);
2902             }
2903         }
2904 
2905         return JSType.toNumber(invokeNoSuchProperty(key, INVALID_PROGRAM_POINT));
2906     }
2907 
2908     @Override
2909     public double getDouble(final Object key, final int programPoint) {
2910         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2911         final int       index        = getArrayIndex(primitiveKey);
2912         final ArrayData array        = getArray();
2913 
2914         if (array.has(index)) {
2915             return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index);
2916         }
2917 
2918         return getDouble(index, JSType.toString(primitiveKey), programPoint);
2919     }
2920 
2921     @Override
2922     public double getDouble(final double key, final int programPoint) {
2923         final int       index = getArrayIndex(key);
2924         final ArrayData array = getArray();
2925 


2966                 }
2967 
2968                 if ((object = object.getProto()) == null) {
2969                     break;
2970                 }
2971 
2972                 final ArrayData array = object.getArray();
2973 
2974                 if (array.has(index)) {
2975                     return array.getObject(index);
2976                 }
2977             }
2978         } else {
2979             final FindProperty find = findProperty(key, true);
2980 
2981             if (find != null) {
2982                 return find.getObjectValue();
2983             }
2984         }
2985 
2986         return invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
2987     }
2988 
2989     @Override
2990     public Object get(final Object key) {
2991         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2992         final int       index        = getArrayIndex(primitiveKey);
2993         final ArrayData array        = getArray();
2994 
2995         if (array.has(index)) {
2996             return array.getObject(index);
2997         }
2998 
2999         return get(index, JSType.toString(primitiveKey));
3000     }
3001 
3002     @Override
3003     public Object get(final double key) {
3004         final int index = getArrayIndex(key);
3005         final ArrayData array = getArray();
3006 




 132     private PropertyMap map;
 133 
 134     /** objects proto. */
 135     private ScriptObject proto;
 136 
 137     /** Object flags. */
 138     private int flags;
 139 
 140     /** Area for primitive properties added to object after instantiation, see {@link AccessorProperty} */
 141     protected long[]   primitiveSpill;
 142 
 143     /** Area for reference properties added to object after instantiation, see {@link AccessorProperty} */
 144     protected Object[] objectSpill;
 145 
 146     /** Indexed array data. */
 147     private ArrayData arrayData;
 148 
 149     /** Method handle to retrieve prototype of this object */
 150     public static final MethodHandle GETPROTO      = findOwnMH_V("getProto", ScriptObject.class);
 151 
 152     static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
 153     static final MethodHandle GLOBALFILTER       = findOwnMH_S("globalFilter", Object.class, Object.class);
 154     static final MethodHandle DECLARE_AND_SET    = findOwnMH_V("declareAndSet", void.class, String.class, Object.class);
 155 
 156     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
 157     private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class);
 158     private static final MethodHandle KNOWNFUNCPROPGUARDPROTO = findOwnMH_S("knownFunctionPropertyGuardProto", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, int.class, ScriptFunction.class);
 159 
 160     private static final ArrayList<MethodHandle> PROTO_FILTERS = new ArrayList<>();
 161 
 162     /** Method handle for getting the array data */
 163     public static final Call GET_ARRAY          = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArray", ArrayData.class);
 164 
 165     /** Method handle for getting a function argument at a given index. Used from MapCreator */
 166     public static final Call GET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
 167 
 168     /** Method handle for setting a function argument at a given index. Used from MapCreator */
 169     public static final Call SET_ARGUMENT       = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArgument", void.class, int.class, Object.class);
 170 
 171     /** Method handle for getting the proto of a ScriptObject */
 172     public static final Call GET_PROTO          = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);


2018             mh = Lookup.emptyGetter(returnType);
2019             protoSwitchPoint = getProtoSwitchPoint(name, owner);
2020         } else if (!find.isSelf()) {
2021             assert mh.type().returnType().equals(returnType) :
2022                     "return type mismatch for getter " + mh.type().returnType() + " != " + returnType;
2023             if (!(property instanceof UserAccessorProperty)) {
2024                 // Add a filter that replaces the self object with the prototype owning the property.
2025                 mh = addProtoFilter(mh, find.getProtoChainLength());
2026             }
2027             protoSwitchPoint = getProtoSwitchPoint(name, owner);
2028         } else {
2029             protoSwitchPoint = null;
2030         }
2031 
2032         final GuardedInvocation inv = new GuardedInvocation(mh, guard, protoSwitchPoint, exception);
2033         return inv.addSwitchPoint(findBuiltinSwitchPoint(name));
2034     }
2035 
2036     private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
2037         Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
2038         final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, NashornCallSiteDescriptor.isScope(desc));
2039         final MethodHandle guard   = getScriptObjectGuard(desc.getMethodType(), true);
2040         return new GuardedInvocation(invoker, guard);
2041     }
2042 
2043     @SuppressWarnings("unused")
2044     private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
2045         final FindProperty find = findProperty(key, true);
2046         if (find != null) {
2047             return find.getObjectValue();
2048         }
2049 
2050         return isMethod ? getNoSuchMethod(key, isScope, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, isScope, INVALID_PROGRAM_POINT);
2051     }
2052 
2053     // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
2054     @SuppressWarnings("unused")
2055     private void declareAndSet(final String key, final Object value) {
2056         final PropertyMap oldMap = getMap();
2057         final FindProperty find = findProperty(key, false);
2058         assert find != null;
2059 
2060         final Property property = find.getProperty();
2061         assert property != null;
2062         assert property.needsDeclaration();
2063 
2064         final PropertyMap newMap = oldMap.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
2065         setMap(newMap);
2066         set(key, value, 0);
2067     }
2068 
2069     /**
2070      * Find the appropriate GETINDEX method for an invoke dynamic call.


2365                                 getMap(),
2366                                 find.getGetter(Object.class, INVALID_PROGRAM_POINT, request),
2367                                 find.getProtoChainLength(),
2368                                 func),
2369                         getProtoSwitchPoint(NO_SUCH_PROPERTY_NAME, find.getOwner()),
2370                         //TODO this doesn't need a ClassCastException as guard always checks script object
2371                         null);
2372             }
2373         }
2374 
2375         if (scopeAccess) {
2376             throw referenceError("not.defined", name);
2377         }
2378 
2379         return createEmptyGetter(desc, explicitInstanceOfCheck(desc, request), name);
2380     }
2381 
2382     /**
2383      * Invoke fall back if a property is not found.
2384      * @param name Name of property.
2385      * @param isScope is this a scope access?
2386      * @param programPoint program point
2387      * @return Result from call.
2388      */
2389     protected Object invokeNoSuchProperty(final String name, final boolean isScope, final int programPoint) {
2390         final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
2391 
2392         Object ret = UNDEFINED;
2393 
2394         if (find != null) {
2395             final Object func = find.getObjectValue();
2396 
2397             if (func instanceof ScriptFunction) {
2398                 final ScriptFunction sfunc = (ScriptFunction)func;
2399                 final Object self = isScope && sfunc.isStrict()? UNDEFINED : this;
2400                 ret = ScriptRuntime.apply(sfunc, self, name);
2401             }
2402         }
2403 
2404         if (isValid(programPoint)) {
2405             throw new UnwarrantedOptimismException(ret, programPoint);
2406         }
2407 
2408         return ret;
2409     }
2410 
2411 
2412     /**
2413      * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined.
2414      * @param name the method name
2415      * @param isScope is this a scope access?
2416      * @return the bound function, or undefined
2417      */
2418     private Object getNoSuchMethod(final String name, final boolean isScope, final int programPoint) {
2419         final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true);
2420 
2421         if (find == null) {
2422             return invokeNoSuchProperty(name, isScope, programPoint);
2423         }
2424 
2425         final Object value = find.getObjectValue();
2426         if (!(value instanceof ScriptFunction)) {
2427             return UNDEFINED;
2428         }
2429 
2430         final ScriptFunction func = (ScriptFunction)value;
2431         final Object self = isScope && func.isStrict()? UNDEFINED : this;
2432         return func.createBound(self, new Object[] {name});
2433     }
2434 
2435     private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String name) {
2436         if (NashornCallSiteDescriptor.isOptimistic(desc)) {
2437             throw new UnwarrantedOptimismException(UNDEFINED, NashornCallSiteDescriptor.getProgramPoint(desc), Type.OBJECT);
2438         }
2439 
2440         return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()),
2441                 NashornGuards.getMapGuard(getMap(), explicitInstanceOfCheck), getProtoSwitchPoint(name, null),
2442                 explicitInstanceOfCheck ? null : ClassCastException.class);
2443     }
2444 
2445     private abstract static class ScriptObjectIterator <T extends Object> implements Iterator<T> {
2446         protected T[] values;
2447         protected final ScriptObject object;
2448         private int index;
2449 
2450         ScriptObjectIterator(final ScriptObject object) {
2451             this.object = object;
2452         }


2727                 if ((object = object.getProto()) == null) {
2728                     break;
2729                 }
2730 
2731                 final ArrayData array = object.getArray();
2732 
2733                 if (array.has(index)) {
2734                     return isValid(programPoint) ?
2735                         array.getIntOptimistic(index, programPoint) :
2736                         array.getInt(index);
2737                 }
2738             }
2739         } else {
2740             final FindProperty find = findProperty(key, true);
2741 
2742             if (find != null) {
2743                 return getIntValue(find, programPoint);
2744             }
2745         }
2746 
2747         return JSType.toInt32(invokeNoSuchProperty(key, false, programPoint));
2748     }
2749 
2750     @Override
2751     public int getInt(final Object key, final int programPoint) {
2752         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2753         final int       index        = getArrayIndex(primitiveKey);
2754         final ArrayData array        = getArray();
2755 
2756         if (array.has(index)) {
2757             return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index);
2758         }
2759 
2760         return getInt(index, JSType.toString(primitiveKey), programPoint);
2761     }
2762 
2763     @Override
2764     public int getInt(final double key, final int programPoint) {
2765         final int       index = getArrayIndex(key);
2766         final ArrayData array = getArray();
2767 


2809                 if ((object = object.getProto()) == null) {
2810                     break;
2811                 }
2812 
2813                 final ArrayData array = object.getArray();
2814 
2815                 if (array.has(index)) {
2816                     return isValid(programPoint) ?
2817                         array.getLongOptimistic(index, programPoint) :
2818                         array.getLong(index);
2819                 }
2820             }
2821         } else {
2822             final FindProperty find = findProperty(key, true);
2823 
2824             if (find != null) {
2825                 return getLongValue(find, programPoint);
2826             }
2827         }
2828 
2829         return JSType.toLong(invokeNoSuchProperty(key, false, programPoint));
2830     }
2831 
2832     @Override
2833     public long getLong(final Object key, final int programPoint) {
2834         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2835         final int       index        = getArrayIndex(primitiveKey);
2836         final ArrayData array        = getArray();
2837 
2838         if (array.has(index)) {
2839             return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
2840         }
2841 
2842         return getLong(index, JSType.toString(primitiveKey), programPoint);
2843     }
2844 
2845     @Override
2846     public long getLong(final double key, final int programPoint) {
2847         final int       index = getArrayIndex(key);
2848         final ArrayData array = getArray();
2849 


2891                 if ((object = object.getProto()) == null) {
2892                     break;
2893                 }
2894 
2895                 final ArrayData array = object.getArray();
2896 
2897                 if (array.has(index)) {
2898                     return isValid(programPoint) ?
2899                         array.getDoubleOptimistic(index, programPoint) :
2900                         array.getDouble(index);
2901                 }
2902             }
2903         } else {
2904             final FindProperty find = findProperty(key, true);
2905 
2906             if (find != null) {
2907                 return getDoubleValue(find, programPoint);
2908             }
2909         }
2910 
2911         return JSType.toNumber(invokeNoSuchProperty(key, false, INVALID_PROGRAM_POINT));
2912     }
2913 
2914     @Override
2915     public double getDouble(final Object key, final int programPoint) {
2916         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2917         final int       index        = getArrayIndex(primitiveKey);
2918         final ArrayData array        = getArray();
2919 
2920         if (array.has(index)) {
2921             return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index);
2922         }
2923 
2924         return getDouble(index, JSType.toString(primitiveKey), programPoint);
2925     }
2926 
2927     @Override
2928     public double getDouble(final double key, final int programPoint) {
2929         final int       index = getArrayIndex(key);
2930         final ArrayData array = getArray();
2931 


2972                 }
2973 
2974                 if ((object = object.getProto()) == null) {
2975                     break;
2976                 }
2977 
2978                 final ArrayData array = object.getArray();
2979 
2980                 if (array.has(index)) {
2981                     return array.getObject(index);
2982                 }
2983             }
2984         } else {
2985             final FindProperty find = findProperty(key, true);
2986 
2987             if (find != null) {
2988                 return find.getObjectValue();
2989             }
2990         }
2991 
2992         return invokeNoSuchProperty(key, false, INVALID_PROGRAM_POINT);
2993     }
2994 
2995     @Override
2996     public Object get(final Object key) {
2997         final Object    primitiveKey = JSType.toPrimitive(key, String.class);
2998         final int       index        = getArrayIndex(primitiveKey);
2999         final ArrayData array        = getArray();
3000 
3001         if (array.has(index)) {
3002             return array.getObject(index);
3003         }
3004 
3005         return get(index, JSType.toString(primitiveKey));
3006     }
3007 
3008     @Override
3009     public Object get(final double key) {
3010         final int index = getArrayIndex(key);
3011         final ArrayData array = getArray();
3012 


< prev index next >