Merge

Tue, 15 Oct 2013 22:13:56 +0530

author
sundar
date
Tue, 15 Oct 2013 22:13:56 +0530
changeset 625
9a13e95cc40f
parent 618
1b0a71a9920a
parent 624
b3ee112a328e
child 628
adc5639fc4b9

Merge

     1.1 --- a/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java	Fri Oct 11 23:31:18 2013 -0700
     1.2 +++ b/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java	Tue Oct 15 22:13:56 2013 +0530
     1.3 @@ -91,6 +91,7 @@
     1.4  import jdk.internal.dynalink.CallSiteDescriptor;
     1.5  import jdk.internal.dynalink.linker.LinkerServices;
     1.6  import jdk.internal.dynalink.support.Guards;
     1.7 +import jdk.internal.dynalink.support.Lookup;
     1.8  
     1.9  /**
    1.10   * Base class for dynamic methods that dispatch to a single target Java method or constructor. Handles adaptation of the
    1.11 @@ -100,6 +101,9 @@
    1.12   * @version $Id: $
    1.13   */
    1.14  abstract class SingleDynamicMethod extends DynamicMethod {
    1.15 +
    1.16 +    private static final MethodHandle CAN_CONVERT_TO = Lookup.findOwnStatic(MethodHandles.lookup(), "canConvertTo", boolean.class, LinkerServices.class, Class.class, Object.class);
    1.17 +
    1.18      SingleDynamicMethod(String name) {
    1.19          super(name);
    1.20      }
    1.21 @@ -201,23 +205,69 @@
    1.22                  return createConvertingInvocation(target, linkerServices, callSiteType).asVarargsCollector(
    1.23                          callSiteLastArgType);
    1.24              }
    1.25 -            if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) {
    1.26 -                // Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive);
    1.27 -                // link immediately to a vararg-packing method handle.
    1.28 -                return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
    1.29 +
    1.30 +            // This method handle takes the single argument and packs it into a newly allocated single-element array. It
    1.31 +            // will be used when the incoming argument can't be converted to the vararg array type (the "vararg packer"
    1.32 +            // method).
    1.33 +            final MethodHandle varArgCollectingInvocation = createConvertingInvocation(collectArguments(fixTarget,
    1.34 +                    argsLen), linkerServices, callSiteType);
    1.35 +
    1.36 +            // Is call site type assignable from an array type (e.g. Object:int[], or Object[]:String[])
    1.37 +            final boolean isAssignableFromArray = callSiteLastArgType.isAssignableFrom(varArgType);
    1.38 +            // Do we have a custom conversion that can potentially convert the call site type to an array?
    1.39 +            final boolean isCustomConvertible = linkerServices.canConvert(callSiteLastArgType, varArgType);
    1.40 +            if(!isAssignableFromArray && !isCustomConvertible) {
    1.41 +                // Call site signature guarantees the argument can definitely not be converted to an array (i.e. it is
    1.42 +                // primitive), and no conversion can help with it either. Link immediately to a vararg-packing method
    1.43 +                // handle.
    1.44 +                return varArgCollectingInvocation;
    1.45              }
    1.46 -            // Call site signature makes no guarantees that the single argument in the vararg position will be
    1.47 -            // compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg
    1.48 -            // method when it is not.
    1.49 -            return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType),
    1.50 -                    createConvertingInvocation(fixTarget, linkerServices, callSiteType),
    1.51 -                    createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType));
    1.52 +
    1.53 +            // This method handle employs language-specific conversions to convert the last argument into an array of
    1.54 +            // vararg type.
    1.55 +            final MethodHandle arrayConvertingInvocation = createConvertingInvocation(MethodHandles.filterArguments(
    1.56 +                    fixTarget, fixParamsLen, linkerServices.getTypeConverter(callSiteLastArgType, varArgType)),
    1.57 +                    linkerServices, callSiteType);
    1.58 +
    1.59 +            // This method handle determines whether the value can be converted to the array of vararg type using a
    1.60 +            // language-specific conversion.
    1.61 +            final MethodHandle canConvertArgToArray = MethodHandles.insertArguments(CAN_CONVERT_TO, 0, linkerServices,
    1.62 +                    varArgType);
    1.63 +
    1.64 +            // This one adjusts the previous one for the location of the argument and the call site type.
    1.65 +            final MethodHandle canConvertLastArgToArray = MethodHandles.dropArguments(canConvertArgToArray, 0,
    1.66 +                    MethodType.genericMethodType(fixParamsLen).parameterList()).asType(callSiteType.changeReturnType(boolean.class));
    1.67 +
    1.68 +            // This one takes the previous ones and combines them into a method handle that converts the argument into
    1.69 +            // a vararg array when it can, otherwise falls back to the vararg packer.
    1.70 +            final MethodHandle convertToArrayWhenPossible = MethodHandles.guardWithTest(canConvertLastArgToArray,
    1.71 +                    arrayConvertingInvocation, varArgCollectingInvocation);
    1.72 +
    1.73 +            if(isAssignableFromArray) {
    1.74 +                return MethodHandles.guardWithTest(
    1.75 +                        // Is incoming parameter already a compatible array?
    1.76 +                        Guards.isInstance(varArgType, fixParamsLen, callSiteType),
    1.77 +                        // Yes: just pass it to the method
    1.78 +                        createConvertingInvocation(fixTarget, linkerServices, callSiteType),
    1.79 +                        // No: either go through a custom conversion, or if it is not possible, go directly to the
    1.80 +                        // vararg packer.
    1.81 +                        isCustomConvertible ? convertToArrayWhenPossible : varArgCollectingInvocation);
    1.82 +            }
    1.83 +
    1.84 +            // Just do the custom conversion with fallback to the vararg packer logic.
    1.85 +            assert isCustomConvertible;
    1.86 +            return convertToArrayWhenPossible;
    1.87          }
    1.88  
    1.89          // Remaining case: more than one vararg.
    1.90          return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType);
    1.91      }
    1.92  
    1.93 +    @SuppressWarnings("unused")
    1.94 +    private static boolean canConvertTo(final LinkerServices linkerServices, Class<?> to, Object obj) {
    1.95 +        return obj == null ? false : linkerServices.canConvert(obj.getClass(), to);
    1.96 +    }
    1.97 +
    1.98      /**
    1.99       * Creates a method handle out of the original target that will collect the varargs for the exact component type of
   1.100       * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs
     2.1 --- a/src/jdk/internal/dynalink/support/Guards.java	Fri Oct 11 23:31:18 2013 -0700
     2.2 +++ b/src/jdk/internal/dynalink/support/Guards.java	Tue Oct 15 22:13:56 2013 +0530
     2.3 @@ -88,6 +88,7 @@
     2.4  import java.lang.invoke.MethodType;
     2.5  import java.util.logging.Level;
     2.6  import java.util.logging.Logger;
     2.7 +import jdk.internal.dynalink.DynamicLinker;
     2.8  import jdk.internal.dynalink.linker.LinkerServices;
     2.9  
    2.10  /**
    2.11 @@ -115,11 +116,11 @@
    2.12      public static MethodHandle isOfClass(Class<?> clazz, MethodType type) {
    2.13          final Class<?> declaredType = type.parameterType(0);
    2.14          if(clazz == declaredType) {
    2.15 -            LOG.log(Level.WARNING, "isOfClassGuardAlwaysTrue", new Object[] { clazz.getName(), 0, type });
    2.16 +            LOG.log(Level.WARNING, "isOfClassGuardAlwaysTrue", new Object[] { clazz.getName(), 0, type, DynamicLinker.getLinkedCallSiteLocation() });
    2.17              return constantTrue(type);
    2.18          }
    2.19          if(!declaredType.isAssignableFrom(clazz)) {
    2.20 -            LOG.log(Level.WARNING, "isOfClassGuardAlwaysFalse", new Object[] { clazz.getName(), 0, type });
    2.21 +            LOG.log(Level.WARNING, "isOfClassGuardAlwaysFalse", new Object[] { clazz.getName(), 0, type, DynamicLinker.getLinkedCallSiteLocation() });
    2.22              return constantFalse(type);
    2.23          }
    2.24          return getClassBoundArgumentTest(IS_OF_CLASS, clazz, 0, type);
    2.25 @@ -152,11 +153,11 @@
    2.26      public static MethodHandle isInstance(Class<?> clazz, int pos, MethodType type) {
    2.27          final Class<?> declaredType = type.parameterType(pos);
    2.28          if(clazz.isAssignableFrom(declaredType)) {
    2.29 -            LOG.log(Level.WARNING, "isInstanceGuardAlwaysTrue", new Object[] { clazz.getName(), pos, type });
    2.30 +            LOG.log(Level.WARNING, "isInstanceGuardAlwaysTrue", new Object[] { clazz.getName(), pos, type, DynamicLinker.getLinkedCallSiteLocation() });
    2.31              return constantTrue(type);
    2.32          }
    2.33          if(!declaredType.isAssignableFrom(clazz)) {
    2.34 -            LOG.log(Level.WARNING, "isInstanceGuardAlwaysFalse", new Object[] { clazz.getName(), pos, type });
    2.35 +            LOG.log(Level.WARNING, "isInstanceGuardAlwaysFalse", new Object[] { clazz.getName(), pos, type, DynamicLinker.getLinkedCallSiteLocation() });
    2.36              return constantFalse(type);
    2.37          }
    2.38          return getClassBoundArgumentTest(IS_INSTANCE, clazz, pos, type);
    2.39 @@ -174,11 +175,11 @@
    2.40      public static MethodHandle isArray(int pos, MethodType type) {
    2.41          final Class<?> declaredType = type.parameterType(pos);
    2.42          if(declaredType.isArray()) {
    2.43 -            LOG.log(Level.WARNING, "isArrayGuardAlwaysTrue", new Object[] { pos, type });
    2.44 +            LOG.log(Level.WARNING, "isArrayGuardAlwaysTrue", new Object[] { pos, type, DynamicLinker.getLinkedCallSiteLocation() });
    2.45              return constantTrue(type);
    2.46          }
    2.47          if(!declaredType.isAssignableFrom(Object[].class)) {
    2.48 -            LOG.log(Level.WARNING, "isArrayGuardAlwaysFalse", new Object[] { pos, type });
    2.49 +            LOG.log(Level.WARNING, "isArrayGuardAlwaysFalse", new Object[] { pos, type, DynamicLinker.getLinkedCallSiteLocation() });
    2.50              return constantFalse(type);
    2.51          }
    2.52          return asType(IS_ARRAY, pos, type);
     3.1 --- a/src/jdk/internal/dynalink/support/messages.properties	Fri Oct 11 23:31:18 2013 -0700
     3.2 +++ b/src/jdk/internal/dynalink/support/messages.properties	Tue Oct 15 22:13:56 2013 +0530
     3.3 @@ -76,11 +76,11 @@
     3.4  #      OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     3.5  #      ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     3.6  
     3.7 -isInstanceGuardAlwaysTrue=isInstance guard for {0} in position {1} in method type {2} will always return true
     3.8 -isInstanceGuardAlwaysFalse=isInstance guard for {0} in position {1} in method type {2} will always return false
     3.9 +isInstanceGuardAlwaysTrue=isInstance guard for {0} in position {1} in method type {2} at {3} will always return true
    3.10 +isInstanceGuardAlwaysFalse=isInstance guard for {0} in position {1} in method type {2} at {3} will always return false
    3.11  
    3.12 -isOfClassGuardAlwaysTrue=isOfClass guard for {0} in position {1} in method type {2} will always return true
    3.13 -isOfClassGuardAlwaysFalse=isOfClass guard for {0} in position {1} in method type {2} will always return false
    3.14 +isOfClassGuardAlwaysTrue=isOfClass guard for {0} in position {1} in method type {2} at {3} will always return true
    3.15 +isOfClassGuardAlwaysFalse=isOfClass guard for {0} in position {1} in method type {2} at {3} will always return false
    3.16  
    3.17 -isArrayGuardAlwaysTrue=isArray guard in position {0} in method type {1} will always return true
    3.18 -isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} will always return false
    3.19 \ No newline at end of file
    3.20 +isArrayGuardAlwaysTrue=isArray guard in position {0} in method type {1} at {2} will always return true
    3.21 +isArrayGuardAlwaysFalse=isArray guard in position {0} in method type {1} at {2} will always return false
    3.22 \ No newline at end of file
     4.1 --- a/src/jdk/nashorn/api/scripting/ScriptUtils.java	Fri Oct 11 23:31:18 2013 -0700
     4.2 +++ b/src/jdk/nashorn/api/scripting/ScriptUtils.java	Tue Oct 15 22:13:56 2013 +0530
     4.3 @@ -25,6 +25,7 @@
     4.4  
     4.5  package jdk.nashorn.api.scripting;
     4.6  
     4.7 +import jdk.nashorn.internal.runtime.ScriptFunction;
     4.8  import jdk.nashorn.internal.runtime.ScriptRuntime;
     4.9  
    4.10  /**
    4.11 @@ -57,4 +58,17 @@
    4.12      public static String format(final String format, final Object[] args) {
    4.13          return Formatter.format(format, args);
    4.14      }
    4.15 +
    4.16 +    /**
    4.17 +     * Create a wrapper function that calls {@code func} synchronized on {@code sync} or, if that is undefined,
    4.18 +     * {@code self}. Used to implement "sync" function in resources/mozilla_compat.js.
    4.19 +     *
    4.20 +     * @param func the function to invoke
    4.21 +     * @param sync the object to synchronize on
    4.22 +     * @return a synchronizing wrapper function
    4.23 +     */
    4.24 +    public static Object makeSynchronizedFunction(final ScriptFunction func, final Object sync) {
    4.25 +        return func.makeSynchronizedFunction(sync);
    4.26 +    }
    4.27 +
    4.28  }
     5.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Fri Oct 11 23:31:18 2013 -0700
     5.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Tue Oct 15 22:13:56 2013 +0530
     5.3 @@ -453,7 +453,13 @@
     5.4              public boolean enterFunctionNode(FunctionNode functionNode) {
     5.5                  // function nodes will always leave a constructed function object on stack, no need to load the symbol
     5.6                  // separately as in enterDefault()
     5.7 +                lc.pop(functionNode);
     5.8                  functionNode.accept(codegen);
     5.9 +                // NOTE: functionNode.accept() will produce a different FunctionNode that we discard. This incidentally
    5.10 +                // doesn't cause problems as we're never touching FunctionNode again after it's visited here - codegen
    5.11 +                // is the last element in the compilation pipeline, the AST it produces is not used externally. So, we
    5.12 +                // re-push the original functionNode.
    5.13 +                lc.push(functionNode);
    5.14                  method.convert(type);
    5.15                  return false;
    5.16              }
     6.1 --- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Fri Oct 11 23:31:18 2013 -0700
     6.2 +++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Tue Oct 15 22:13:56 2013 +0530
     6.3 @@ -25,6 +25,7 @@
     6.4  
     6.5  package jdk.nashorn.internal.objects;
     6.6  
     6.7 +import static jdk.nashorn.internal.lookup.Lookup.MH;
     6.8  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
     6.9  
    6.10  import java.lang.invoke.MethodHandle;
    6.11 @@ -255,6 +256,12 @@
    6.12          return makeFunction(name, methodHandle, null);
    6.13      }
    6.14  
    6.15 +    @Override
    6.16 +    public ScriptFunction makeSynchronizedFunction(final Object sync) {
    6.17 +        final MethodHandle mh = MH.insertArguments(ScriptFunction.INVOKE_SYNC, 0, this, sync);
    6.18 +        return makeFunction(getName(), mh);
    6.19 +    }
    6.20 +
    6.21      /**
    6.22       * Same as {@link ScriptFunction#makeBoundFunction(Object, Object[])}. The only reason we override it is so that we
    6.23       * can expose it to methods in this package.
     7.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java	Fri Oct 11 23:31:18 2013 -0700
     7.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java	Tue Oct 15 22:13:56 2013 +0530
     7.3 @@ -31,6 +31,8 @@
     7.4  import java.lang.invoke.MethodHandle;
     7.5  import java.lang.invoke.MethodHandles;
     7.6  import java.lang.reflect.Array;
     7.7 +import java.util.Deque;
     7.8 +import java.util.List;
     7.9  import jdk.internal.dynalink.beans.StaticClass;
    7.10  import jdk.nashorn.api.scripting.JSObject;
    7.11  import jdk.nashorn.internal.codegen.CompilerConstants.Call;
    7.12 @@ -110,6 +112,15 @@
    7.13      /** Combined call to toPrimitive followed by toString. */
    7.14      public static final Call TO_PRIMITIVE_TO_STRING = staticCall(myLookup, JSType.class, "toPrimitiveToString", String.class,  Object.class);
    7.15  
    7.16 +    /** Method handle to convert a JS Object to a Java array. */
    7.17 +    public static final Call TO_JAVA_ARRAY = staticCall(myLookup, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
    7.18 +
    7.19 +    /** Method handle to convert a JS Object to a Java List. */
    7.20 +    public static final Call TO_JAVA_LIST = staticCall(myLookup, JSType.class, "toJavaList", List.class, Object.class);
    7.21 +
    7.22 +    /** Method handle to convert a JS Object to a Java deque. */
    7.23 +   public static final Call TO_JAVA_DEQUE = staticCall(myLookup, JSType.class, "toJavaDeque", Deque.class, Object.class);
    7.24 +
    7.25      private static final double INT32_LIMIT = 4294967296.0;
    7.26  
    7.27      /**
    7.28 @@ -890,6 +901,8 @@
    7.29                  res[idx++] = itr.next();
    7.30              }
    7.31              return convertArray(res, componentType);
    7.32 +        } else if(obj == null) {
    7.33 +            return null;
    7.34          } else {
    7.35              throw new IllegalArgumentException("not a script object");
    7.36          }
    7.37 @@ -919,6 +932,24 @@
    7.38      }
    7.39  
    7.40      /**
    7.41 +     * Converts a JavaScript object to a Java List. See {@link ListAdapter} for details.
    7.42 +     * @param obj the object to convert. Can be any array-like object.
    7.43 +     * @return a List that is live-backed by the JavaScript object.
    7.44 +     */
    7.45 +    public static List<?> toJavaList(final Object obj) {
    7.46 +        return ListAdapter.create(obj);
    7.47 +    }
    7.48 +
    7.49 +    /**
    7.50 +     * Converts a JavaScript object to a Java Deque. See {@link ListAdapter} for details.
    7.51 +     * @param obj the object to convert. Can be any array-like object.
    7.52 +     * @return a Deque that is live-backed by the JavaScript object.
    7.53 +     */
    7.54 +    public static Deque<?> toJavaDeque(final Object obj) {
    7.55 +        return ListAdapter.create(obj);
    7.56 +    }
    7.57 +
    7.58 +    /**
    7.59       * Check if an object is null or undefined
    7.60       *
    7.61       * @param obj object to check
     8.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Fri Oct 11 23:31:18 2013 -0700
     8.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Tue Oct 15 22:13:56 2013 +0530
     8.3 @@ -53,7 +53,7 @@
     8.4  public final class RecompilableScriptFunctionData extends ScriptFunctionData {
     8.5  
     8.6      /** FunctionNode with the code for this ScriptFunction */
     8.7 -    private volatile FunctionNode functionNode;
     8.8 +    private FunctionNode functionNode;
     8.9  
    8.10      /** Source from which FunctionNode was parsed. */
    8.11      private final Source source;
    8.12 @@ -65,7 +65,7 @@
    8.13      private final PropertyMap allocatorMap;
    8.14  
    8.15      /** Code installer used for all further recompilation/specialization of this ScriptFunction */
    8.16 -    private volatile CodeInstaller<ScriptEnvironment> installer;
    8.17 +    private CodeInstaller<ScriptEnvironment> installer;
    8.18  
    8.19      /** Name of class where allocator function resides */
    8.20      private final String allocatorClassName;
    8.21 @@ -178,7 +178,7 @@
    8.22      }
    8.23  
    8.24      @Override
    8.25 -    protected void ensureCodeGenerated() {
    8.26 +    protected synchronized void ensureCodeGenerated() {
    8.27           if (!code.isEmpty()) {
    8.28               return; // nothing to do, we have code, at least some.
    8.29           }
    8.30 @@ -336,7 +336,7 @@
    8.31      }
    8.32  
    8.33      @Override
    8.34 -    MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) {
    8.35 +    synchronized MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) {
    8.36          final MethodType runtimeType = runtimeType(callSiteType, args);
    8.37          assert runtimeType.parameterCount() == callSiteType.parameterCount();
    8.38  
     9.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Fri Oct 11 23:31:18 2013 -0700
     9.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Tue Oct 15 22:13:56 2013 +0530
     9.3 @@ -59,6 +59,9 @@
     9.4      /** Method handle for name getter for this ScriptFunction */
     9.5      public static final MethodHandle G$NAME = findOwnMH("G$name", Object.class, Object.class);
     9.6  
     9.7 +    /** Method handle used for implementing sync() in mozilla_compat */
     9.8 +    public static final MethodHandle INVOKE_SYNC = findOwnMH("invokeSync", Object.class, ScriptFunction.class, Object.class, Object.class, Object[].class);
     9.9 +
    9.10      /** Method handle for allocate function for this ScriptFunction */
    9.11      static final MethodHandle ALLOCATE = findOwnMH("allocate", Object.class);
    9.12  
    9.13 @@ -301,6 +304,14 @@
    9.14      public abstract void setPrototype(Object prototype);
    9.15  
    9.16      /**
    9.17 +     * Create a function that invokes this function synchronized on {@code sync} or the self object
    9.18 +     * of the invocation.
    9.19 +     * @param sync the Object to synchronize on, or undefined
    9.20 +     * @return synchronized function
    9.21 +     */
    9.22 +    public abstract ScriptFunction makeSynchronizedFunction(Object sync);
    9.23 +
    9.24 +    /**
    9.25       * Return the most appropriate invoke handle if there are specializations
    9.26       * @param type most specific method type to look for invocation with
    9.27       * @param args args for trampoline invocation
    9.28 @@ -614,6 +625,15 @@
    9.29          return result;
    9.30      }
    9.31  
    9.32 +    @SuppressWarnings("unused")
    9.33 +    private static Object invokeSync(final ScriptFunction func, final Object sync, final Object self, final Object... args)
    9.34 +            throws Throwable {
    9.35 +        final Object syncObj = sync == UNDEFINED ? self : sync;
    9.36 +        synchronized (syncObj) {
    9.37 +            return func.invoke(self, args);
    9.38 +        }
    9.39 +    }
    9.40 +
    9.41      private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
    9.42          final Class<?>   own = ScriptFunction.class;
    9.43          final MethodType mt  = MH.type(rtype, types);
    10.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Fri Oct 11 23:31:18 2013 -0700
    10.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Tue Oct 15 22:13:56 2013 +0530
    10.3 @@ -675,7 +675,7 @@
    10.4  
    10.5      /**
    10.6       * Heuristic to figure out if the method handle has a callee argument. If it's type is either
    10.7 -     * {@code (boolean, Object, ScriptFunction, ...)} or {@code (Object, ScriptFunction, ...)}, then we'll assume it has
    10.8 +     * {@code (boolean, ScriptFunction, ...)} or {@code (ScriptFunction, ...)}, then we'll assume it has
    10.9       * a callee argument. We need this as the constructor above is not passed this information, and can't just blindly
   10.10       * assume it's false (notably, it's being invoked for creation of new scripts, and scripts have scopes, therefore
   10.11       * they also always receive a callee).
   10.12 @@ -692,11 +692,11 @@
   10.13              return false;
   10.14          }
   10.15  
   10.16 -        if (type.parameterType(0) == boolean.class) {
   10.17 -            return length > 1 && type.parameterType(1) == ScriptFunction.class;
   10.18 +        if (type.parameterType(0) == ScriptFunction.class) {
   10.19 +            return true;
   10.20          }
   10.21  
   10.22 -        return type.parameterType(0) == ScriptFunction.class;
   10.23 +        return length > 1 && type.parameterType(0) == boolean.class && type.parameterType(1) == ScriptFunction.class;
   10.24      }
   10.25  
   10.26      /**
    11.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Fri Oct 11 23:31:18 2013 -0700
    11.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Tue Oct 15 22:13:56 2013 +0530
    11.3 @@ -37,6 +37,8 @@
    11.4  import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
    11.5  import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
    11.6  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    11.7 +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
    11.8 +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
    11.9  
   11.10  import java.lang.invoke.MethodHandle;
   11.11  import java.lang.invoke.MethodHandles;
   11.12 @@ -131,6 +133,7 @@
   11.13  
   11.14      static final MethodHandle GETPROTO           = findOwnMH("getProto", ScriptObject.class);
   11.15      static final MethodHandle SETPROTOCHECK      = findOwnMH("setProtoCheck", void.class, Object.class);
   11.16 +    static final MethodHandle MEGAMORPHIC_GET    = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class);
   11.17  
   11.18      static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
   11.19      static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
   11.20 @@ -388,7 +391,7 @@
   11.21              return global.newDataDescriptor(getWithProperty(property), configurable, enumerable, writable);
   11.22          }
   11.23  
   11.24 -        final int index = ArrayIndex.getArrayIndex(key);
   11.25 +        final int index = getArrayIndex(key);
   11.26          final ArrayData array = getArray();
   11.27  
   11.28          if (array.has(index)) {
   11.29 @@ -592,7 +595,7 @@
   11.30       * @param value value to define
   11.31       */
   11.32      protected final void defineOwnProperty(final int index, final Object value) {
   11.33 -        assert ArrayIndex.isValidArrayIndex(index) : "invalid array index";
   11.34 +        assert isValidArrayIndex(index) : "invalid array index";
   11.35          final long longIndex = ArrayIndex.toLongIndex(index);
   11.36          if (longIndex >= getArray().length()) {
   11.37              // make array big enough to hold..
   11.38 @@ -602,9 +605,9 @@
   11.39      }
   11.40  
   11.41      private void checkIntegerKey(final String key) {
   11.42 -        final int index = ArrayIndex.getArrayIndex(key);
   11.43 -
   11.44 -        if (ArrayIndex.isValidArrayIndex(index)) {
   11.45 +        final int index = getArrayIndex(key);
   11.46 +
   11.47 +        if (isValidArrayIndex(index)) {
   11.48              final ArrayData data = getArray();
   11.49  
   11.50              if (data.has(index)) {
   11.51 @@ -614,7 +617,7 @@
   11.52      }
   11.53  
   11.54      private void removeArraySlot(final String key) {
   11.55 -        final int index = ArrayIndex.getArrayIndex(key);
   11.56 +        final int index = getArrayIndex(key);
   11.57          final ArrayData array = getArray();
   11.58  
   11.59          if (array.has(index)) {
   11.60 @@ -717,6 +720,28 @@
   11.61      }
   11.62  
   11.63      /**
   11.64 +     * Low level property API. This is similar to {@link #findProperty(String, boolean)} but returns a
   11.65 +     * {@code boolean} value instead of a {@link FindProperty} object.
   11.66 +     * @param key  Property key.
   11.67 +     * @param deep Whether the search should look up proto chain.
   11.68 +     * @return true if the property was found.
   11.69 +     */
   11.70 +    boolean hasProperty(final String key, final boolean deep) {
   11.71 +        if (getMap().findProperty(key) != null) {
   11.72 +            return true;
   11.73 +        }
   11.74 +
   11.75 +        if (deep) {
   11.76 +            final ScriptObject myProto = getProto();
   11.77 +            if (myProto != null) {
   11.78 +                return myProto.hasProperty(key, deep);
   11.79 +            }
   11.80 +        }
   11.81 +
   11.82 +        return false;
   11.83 +    }
   11.84 +
   11.85 +    /**
   11.86       * Add a new property to the object.
   11.87       * <p>
   11.88       * This a more "low level" way that doesn't involve {@link PropertyDescriptor}s
   11.89 @@ -1708,8 +1733,11 @@
   11.90       */
   11.91      protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
   11.92          final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
   11.93 +        if (request.isCallSiteUnstable()) {
   11.94 +            return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
   11.95 +        }
   11.96 +
   11.97          final FindProperty find = findProperty(name, true);
   11.98 -
   11.99          MethodHandle methodHandle;
  11.100  
  11.101          if (find == null) {
  11.102 @@ -1727,10 +1755,6 @@
  11.103              throw new AssertionError(); // never invoked with any other operation
  11.104          }
  11.105  
  11.106 -        if (request.isCallSiteUnstable()) {
  11.107 -            return findMegaMorphicGetMethod(desc, name);
  11.108 -        }
  11.109 -
  11.110          final Class<?> returnType = desc.getMethodType().returnType();
  11.111          final Property property = find.getProperty();
  11.112          methodHandle = find.getGetter(returnType);
  11.113 @@ -1757,11 +1781,21 @@
  11.114          return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(proto, name), guard);
  11.115      }
  11.116  
  11.117 -    private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name) {
  11.118 -        final MethodType mhType = desc.getMethodType().insertParameterTypes(1, Object.class);
  11.119 -        final GuardedInvocation inv = findGetIndexMethod(mhType);
  11.120 -
  11.121 -        return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
  11.122 +    private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
  11.123 +        final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
  11.124 +        final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
  11.125 +        return new GuardedInvocation(invoker, guard);
  11.126 +    }
  11.127 +
  11.128 +    @SuppressWarnings("unused")
  11.129 +    private Object megamorphicGet(final String key, final boolean isMethod) {
  11.130 +        final FindProperty find = findProperty(key, true);
  11.131 +
  11.132 +        if (find != null) {
  11.133 +            return getObjectValue(find);
  11.134 +        }
  11.135 +
  11.136 +        return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
  11.137      }
  11.138  
  11.139      /**
  11.140 @@ -1810,7 +1844,7 @@
  11.141       */
  11.142      protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
  11.143          final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
  11.144 -        if(request.isCallSiteUnstable()) {
  11.145 +        if (request.isCallSiteUnstable()) {
  11.146              return findMegaMorphicSetMethod(desc, name);
  11.147          }
  11.148  
  11.149 @@ -2045,6 +2079,26 @@
  11.150          return UNDEFINED;
  11.151      }
  11.152  
  11.153 +    /**
  11.154 +     * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined.
  11.155 +     * @param name the method name
  11.156 +     * @return the bound function, or undefined
  11.157 +     */
  11.158 +    private Object getNoSuchMethod(final String name) {
  11.159 +        final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true);
  11.160 +
  11.161 +        if (find == null) {
  11.162 +            return invokeNoSuchProperty(name);
  11.163 +        }
  11.164 +
  11.165 +        final Object value = getObjectValue(find);
  11.166 +        if (! (value instanceof ScriptFunction)) {
  11.167 +            return UNDEFINED;
  11.168 +        }
  11.169 +
  11.170 +        return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name});
  11.171 +    }
  11.172 +
  11.173      private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) {
  11.174          return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(getMap()));
  11.175      }
  11.176 @@ -2308,7 +2362,7 @@
  11.177      }
  11.178  
  11.179      private int getInt(final int index, final String key) {
  11.180 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.181 +        if (isValidArrayIndex(index)) {
  11.182               for (ScriptObject object = this; ; ) {
  11.183                  final FindProperty find = object.findProperty(key, false, false, this);
  11.184  
  11.185 @@ -2339,7 +2393,7 @@
  11.186  
  11.187      @Override
  11.188      public int getInt(final Object key) {
  11.189 -        final int index = ArrayIndex.getArrayIndex(key);
  11.190 +        final int index = getArrayIndex(key);
  11.191          final ArrayData array = getArray();
  11.192  
  11.193          if (array.has(index)) {
  11.194 @@ -2351,7 +2405,7 @@
  11.195  
  11.196      @Override
  11.197      public int getInt(final double key) {
  11.198 -        final int index = ArrayIndex.getArrayIndex(key);
  11.199 +        final int index = getArrayIndex(key);
  11.200          final ArrayData array = getArray();
  11.201  
  11.202          if (array.has(index)) {
  11.203 @@ -2363,7 +2417,7 @@
  11.204  
  11.205      @Override
  11.206      public int getInt(final long key) {
  11.207 -        final int index = ArrayIndex.getArrayIndex(key);
  11.208 +        final int index = getArrayIndex(key);
  11.209          final ArrayData array = getArray();
  11.210  
  11.211          if (array.has(index)) {
  11.212 @@ -2385,7 +2439,7 @@
  11.213      }
  11.214  
  11.215      private long getLong(final int index, final String key) {
  11.216 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.217 +        if (isValidArrayIndex(index)) {
  11.218              for (ScriptObject object = this; ; ) {
  11.219                  final FindProperty find = object.findProperty(key, false, false, this);
  11.220  
  11.221 @@ -2416,7 +2470,7 @@
  11.222  
  11.223      @Override
  11.224      public long getLong(final Object key) {
  11.225 -        final int index = ArrayIndex.getArrayIndex(key);
  11.226 +        final int index = getArrayIndex(key);
  11.227          final ArrayData array = getArray();
  11.228  
  11.229          if (array.has(index)) {
  11.230 @@ -2428,7 +2482,7 @@
  11.231  
  11.232      @Override
  11.233      public long getLong(final double key) {
  11.234 -        final int index = ArrayIndex.getArrayIndex(key);
  11.235 +        final int index = getArrayIndex(key);
  11.236          final ArrayData array = getArray();
  11.237  
  11.238          if (array.has(index)) {
  11.239 @@ -2440,7 +2494,7 @@
  11.240  
  11.241      @Override
  11.242      public long getLong(final long key) {
  11.243 -        final int index = ArrayIndex.getArrayIndex(key);
  11.244 +        final int index = getArrayIndex(key);
  11.245          final ArrayData array = getArray();
  11.246  
  11.247          if (array.has(index)) {
  11.248 @@ -2462,7 +2516,7 @@
  11.249      }
  11.250  
  11.251      private double getDouble(final int index, final String key) {
  11.252 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.253 +        if (isValidArrayIndex(index)) {
  11.254              for (ScriptObject object = this; ; ) {
  11.255                  final FindProperty find = object.findProperty(key, false, false, this);
  11.256  
  11.257 @@ -2493,7 +2547,7 @@
  11.258  
  11.259      @Override
  11.260      public double getDouble(final Object key) {
  11.261 -        final int index = ArrayIndex.getArrayIndex(key);
  11.262 +        final int index = getArrayIndex(key);
  11.263          final ArrayData array = getArray();
  11.264  
  11.265          if (array.has(index)) {
  11.266 @@ -2505,7 +2559,7 @@
  11.267  
  11.268      @Override
  11.269      public double getDouble(final double key) {
  11.270 -        final int index = ArrayIndex.getArrayIndex(key);
  11.271 +        final int index = getArrayIndex(key);
  11.272          final ArrayData array = getArray();
  11.273  
  11.274          if (array.has(index)) {
  11.275 @@ -2517,7 +2571,7 @@
  11.276  
  11.277      @Override
  11.278      public double getDouble(final long key) {
  11.279 -        final int index = ArrayIndex.getArrayIndex(key);
  11.280 +        final int index = getArrayIndex(key);
  11.281          final ArrayData array = getArray();
  11.282  
  11.283          if (array.has(index)) {
  11.284 @@ -2539,7 +2593,7 @@
  11.285      }
  11.286  
  11.287      private Object get(final int index, final String key) {
  11.288 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.289 +        if (isValidArrayIndex(index)) {
  11.290              for (ScriptObject object = this; ; ) {
  11.291                  final FindProperty find = object.findProperty(key, false, false, this);
  11.292  
  11.293 @@ -2570,7 +2624,7 @@
  11.294  
  11.295      @Override
  11.296      public Object get(final Object key) {
  11.297 -        final int index = ArrayIndex.getArrayIndex(key);
  11.298 +        final int index = getArrayIndex(key);
  11.299          final ArrayData array = getArray();
  11.300  
  11.301          if (array.has(index)) {
  11.302 @@ -2582,7 +2636,7 @@
  11.303  
  11.304      @Override
  11.305      public Object get(final double key) {
  11.306 -        final int index = ArrayIndex.getArrayIndex(key);
  11.307 +        final int index = getArrayIndex(key);
  11.308          final ArrayData array = getArray();
  11.309  
  11.310          if (array.has(index)) {
  11.311 @@ -2594,7 +2648,7 @@
  11.312  
  11.313      @Override
  11.314      public Object get(final long key) {
  11.315 -        final int index = ArrayIndex.getArrayIndex(key);
  11.316 +        final int index = getArrayIndex(key);
  11.317          final ArrayData array = getArray();
  11.318  
  11.319          if (array.has(index)) {
  11.320 @@ -2710,9 +2764,9 @@
  11.321  
  11.322      @Override
  11.323      public void set(final Object key, final int value, final boolean strict) {
  11.324 -        final int index = ArrayIndex.getArrayIndex(key);
  11.325 -
  11.326 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.327 +        final int index = getArrayIndex(key);
  11.328 +
  11.329 +        if (isValidArrayIndex(index)) {
  11.330              if (getArray().has(index)) {
  11.331                  setArray(getArray().set(index, value, strict));
  11.332              } else {
  11.333 @@ -2722,14 +2776,15 @@
  11.334              return;
  11.335          }
  11.336  
  11.337 -        set(key, JSType.toObject(value), strict);
  11.338 +        final String propName = JSType.toString(key);
  11.339 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.340      }
  11.341  
  11.342      @Override
  11.343      public void set(final Object key, final long value, final boolean strict) {
  11.344 -        final int index = ArrayIndex.getArrayIndex(key);
  11.345 -
  11.346 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.347 +        final int index = getArrayIndex(key);
  11.348 +
  11.349 +        if (isValidArrayIndex(index)) {
  11.350              if (getArray().has(index)) {
  11.351                  setArray(getArray().set(index, value, strict));
  11.352              } else {
  11.353 @@ -2739,14 +2794,15 @@
  11.354              return;
  11.355          }
  11.356  
  11.357 -        set(key, JSType.toObject(value), strict);
  11.358 +        final String propName = JSType.toString(key);
  11.359 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.360      }
  11.361  
  11.362      @Override
  11.363      public void set(final Object key, final double value, final boolean strict) {
  11.364 -        final int index = ArrayIndex.getArrayIndex(key);
  11.365 -
  11.366 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.367 +        final int index = getArrayIndex(key);
  11.368 +
  11.369 +        if (isValidArrayIndex(index)) {
  11.370              if (getArray().has(index)) {
  11.371                  setArray(getArray().set(index, value, strict));
  11.372              } else {
  11.373 @@ -2756,14 +2812,15 @@
  11.374              return;
  11.375          }
  11.376  
  11.377 -        set(key, JSType.toObject(value), strict);
  11.378 +        final String propName = JSType.toString(key);
  11.379 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.380      }
  11.381  
  11.382      @Override
  11.383      public void set(final Object key, final Object value, final boolean strict) {
  11.384 -        final int index = ArrayIndex.getArrayIndex(key);
  11.385 -
  11.386 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.387 +        final int index = getArrayIndex(key);
  11.388 +
  11.389 +        if (isValidArrayIndex(index)) {
  11.390              if (getArray().has(index)) {
  11.391                  setArray(getArray().set(index, value, strict));
  11.392              } else {
  11.393 @@ -2773,17 +2830,15 @@
  11.394              return;
  11.395          }
  11.396  
  11.397 -        final String       propName = JSType.toString(key);
  11.398 -        final FindProperty find     = findProperty(propName, true);
  11.399 -
  11.400 -        setObject(find, strict, propName, value);
  11.401 +        final String propName = JSType.toString(key);
  11.402 +        setObject(findProperty(propName, true), strict, propName, value);
  11.403      }
  11.404  
  11.405      @Override
  11.406      public void set(final double key, final int value, final boolean strict) {
  11.407 -        final int index = ArrayIndex.getArrayIndex(key);
  11.408 -
  11.409 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.410 +        final int index = getArrayIndex(key);
  11.411 +
  11.412 +        if (isValidArrayIndex(index)) {
  11.413              if (getArray().has(index)) {
  11.414                  setArray(getArray().set(index, value, strict));
  11.415              } else {
  11.416 @@ -2793,14 +2848,15 @@
  11.417              return;
  11.418          }
  11.419  
  11.420 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.421 +        final String propName = JSType.toString(key);
  11.422 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.423      }
  11.424  
  11.425      @Override
  11.426      public void set(final double key, final long value, final boolean strict) {
  11.427 -        final int index = ArrayIndex.getArrayIndex(key);
  11.428 -
  11.429 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.430 +        final int index = getArrayIndex(key);
  11.431 +
  11.432 +        if (isValidArrayIndex(index)) {
  11.433              if (getArray().has(index)) {
  11.434                  setArray(getArray().set(index, value, strict));
  11.435              } else {
  11.436 @@ -2810,14 +2866,15 @@
  11.437              return;
  11.438          }
  11.439  
  11.440 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.441 +        final String propName = JSType.toString(key);
  11.442 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.443      }
  11.444  
  11.445      @Override
  11.446      public void set(final double key, final double value, final boolean strict) {
  11.447 -        final int index = ArrayIndex.getArrayIndex(key);
  11.448 -
  11.449 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.450 +        final int index = getArrayIndex(key);
  11.451 +
  11.452 +        if (isValidArrayIndex(index)) {
  11.453              if (getArray().has(index)) {
  11.454                  setArray(getArray().set(index, value, strict));
  11.455              } else {
  11.456 @@ -2827,14 +2884,15 @@
  11.457              return;
  11.458          }
  11.459  
  11.460 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.461 +        final String propName = JSType.toString(key);
  11.462 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.463      }
  11.464  
  11.465      @Override
  11.466      public void set(final double key, final Object value, final boolean strict) {
  11.467 -        final int index = ArrayIndex.getArrayIndex(key);
  11.468 -
  11.469 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.470 +        final int index = getArrayIndex(key);
  11.471 +
  11.472 +        if (isValidArrayIndex(index)) {
  11.473              if (getArray().has(index)) {
  11.474                  setArray(getArray().set(index, value, strict));
  11.475              } else {
  11.476 @@ -2844,14 +2902,15 @@
  11.477              return;
  11.478          }
  11.479  
  11.480 -        set(JSType.toObject(key), value, strict);
  11.481 +        final String propName = JSType.toString(key);
  11.482 +        setObject(findProperty(propName, true), strict, propName, value);
  11.483      }
  11.484  
  11.485      @Override
  11.486      public void set(final long key, final int value, final boolean strict) {
  11.487 -        final int index = ArrayIndex.getArrayIndex(key);
  11.488 -
  11.489 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.490 +        final int index = getArrayIndex(key);
  11.491 +
  11.492 +        if (isValidArrayIndex(index)) {
  11.493              if (getArray().has(index)) {
  11.494                  setArray(getArray().set(index, value, strict));
  11.495              } else {
  11.496 @@ -2861,14 +2920,15 @@
  11.497              return;
  11.498          }
  11.499  
  11.500 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.501 +        final String propName = JSType.toString(key);
  11.502 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.503      }
  11.504  
  11.505      @Override
  11.506      public void set(final long key, final long value, final boolean strict) {
  11.507 -        final int index = ArrayIndex.getArrayIndex(key);
  11.508 -
  11.509 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.510 +        final int index = getArrayIndex(key);
  11.511 +
  11.512 +        if (isValidArrayIndex(index)) {
  11.513              if (getArray().has(index)) {
  11.514                  setArray(getArray().set(index, value, strict));
  11.515              } else {
  11.516 @@ -2878,14 +2938,15 @@
  11.517              return;
  11.518          }
  11.519  
  11.520 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.521 +        final String propName = JSType.toString(key);
  11.522 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.523      }
  11.524  
  11.525      @Override
  11.526      public void set(final long key, final double value, final boolean strict) {
  11.527 -        final int index = ArrayIndex.getArrayIndex(key);
  11.528 -
  11.529 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.530 +        final int index = getArrayIndex(key);
  11.531 +
  11.532 +        if (isValidArrayIndex(index)) {
  11.533              if (getArray().has(index)) {
  11.534                  setArray(getArray().set(index, value, strict));
  11.535              } else {
  11.536 @@ -2895,14 +2956,15 @@
  11.537              return;
  11.538          }
  11.539  
  11.540 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.541 +        final String propName = JSType.toString(key);
  11.542 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.543      }
  11.544  
  11.545      @Override
  11.546      public void set(final long key, final Object value, final boolean strict) {
  11.547 -        final int index = ArrayIndex.getArrayIndex(key);
  11.548 -
  11.549 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.550 +        final int index = getArrayIndex(key);
  11.551 +
  11.552 +        if (isValidArrayIndex(index)) {
  11.553              if (getArray().has(index)) {
  11.554                  setArray(getArray().set(index, value, strict));
  11.555              } else {
  11.556 @@ -2912,14 +2974,15 @@
  11.557              return;
  11.558          }
  11.559  
  11.560 -        set(JSType.toObject(key), value, strict);
  11.561 +        final String propName = JSType.toString(key);
  11.562 +        setObject(findProperty(propName, true), strict, propName, value);
  11.563      }
  11.564  
  11.565      @Override
  11.566      public void set(final int key, final int value, final boolean strict) {
  11.567 -        final int index = ArrayIndex.getArrayIndex(key);
  11.568 -
  11.569 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.570 +        final int index = getArrayIndex(key);
  11.571 +
  11.572 +        if (isValidArrayIndex(index)) {
  11.573              if (getArray().has(index)) {
  11.574                  setArray(getArray().set(index, value, strict));
  11.575              } else {
  11.576 @@ -2929,14 +2992,15 @@
  11.577              return;
  11.578          }
  11.579  
  11.580 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.581 +        final String propName = JSType.toString(key);
  11.582 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.583      }
  11.584  
  11.585      @Override
  11.586      public void set(final int key, final long value, final boolean strict) {
  11.587 -        final int index = ArrayIndex.getArrayIndex(key);
  11.588 -
  11.589 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.590 +        final int index = getArrayIndex(key);
  11.591 +
  11.592 +        if (isValidArrayIndex(index)) {
  11.593              if (getArray().has(index)) {
  11.594                  setArray(getArray().set(index, value, strict));
  11.595              } else {
  11.596 @@ -2946,14 +3010,15 @@
  11.597              return;
  11.598          }
  11.599  
  11.600 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.601 +        final String propName = JSType.toString(key);
  11.602 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.603      }
  11.604  
  11.605      @Override
  11.606      public void set(final int key, final double value, final boolean strict) {
  11.607 -        final int index = ArrayIndex.getArrayIndex(key);
  11.608 -
  11.609 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.610 +        final int index = getArrayIndex(key);
  11.611 +
  11.612 +        if (isValidArrayIndex(index)) {
  11.613              if (getArray().has(index)) {
  11.614                  setArray(getArray().set(index, value, strict));
  11.615              } else {
  11.616 @@ -2963,14 +3028,15 @@
  11.617              return;
  11.618          }
  11.619  
  11.620 -        set(JSType.toObject(key), JSType.toObject(value), strict);
  11.621 +        final String propName = JSType.toString(key);
  11.622 +        setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
  11.623      }
  11.624  
  11.625      @Override
  11.626      public void set(final int key, final Object value, final boolean strict) {
  11.627 -        final int index = ArrayIndex.getArrayIndex(key);
  11.628 -
  11.629 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.630 +        final int index = getArrayIndex(key);
  11.631 +
  11.632 +        if (isValidArrayIndex(index)) {
  11.633              if (getArray().has(index)) {
  11.634                  setArray(getArray().set(index, value, strict));
  11.635              } else {
  11.636 @@ -2980,14 +3046,15 @@
  11.637              return;
  11.638          }
  11.639  
  11.640 -        set(JSType.toObject(key), value, strict);
  11.641 +        final String propName = JSType.toString(key);
  11.642 +        setObject(findProperty(propName, true), strict, propName, value);
  11.643      }
  11.644  
  11.645      @Override
  11.646      public boolean has(final Object key) {
  11.647 -        final int index = ArrayIndex.getArrayIndex(key);
  11.648 -
  11.649 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.650 +        final int index = getArrayIndex(key);
  11.651 +
  11.652 +        if (isValidArrayIndex(index)) {
  11.653              for (ScriptObject self = this; self != null; self = self.getProto()) {
  11.654                  if (self.getArray().has(index)) {
  11.655                      return true;
  11.656 @@ -2995,16 +3062,14 @@
  11.657              }
  11.658          }
  11.659  
  11.660 -        final FindProperty find = findProperty(JSType.toString(key), true);
  11.661 -
  11.662 -        return find != null;
  11.663 +        return hasProperty(JSType.toString(key), true);
  11.664      }
  11.665  
  11.666      @Override
  11.667      public boolean has(final double key) {
  11.668 -        final int index = ArrayIndex.getArrayIndex(key);
  11.669 -
  11.670 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.671 +        final int index = getArrayIndex(key);
  11.672 +
  11.673 +        if (isValidArrayIndex(index)) {
  11.674              for (ScriptObject self = this; self != null; self = self.getProto()) {
  11.675                  if (self.getArray().has(index)) {
  11.676                      return true;
  11.677 @@ -3012,16 +3077,14 @@
  11.678              }
  11.679          }
  11.680  
  11.681 -        final FindProperty find = findProperty(JSType.toString(key), true);
  11.682 -
  11.683 -        return find != null;
  11.684 +        return hasProperty(JSType.toString(key), true);
  11.685      }
  11.686  
  11.687      @Override
  11.688      public boolean has(final long key) {
  11.689 -        final int index = ArrayIndex.getArrayIndex(key);
  11.690 -
  11.691 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.692 +        final int index = getArrayIndex(key);
  11.693 +
  11.694 +        if (isValidArrayIndex(index)) {
  11.695              for (ScriptObject self = this; self != null; self = self.getProto()) {
  11.696                  if (self.getArray().has(index)) {
  11.697                      return true;
  11.698 @@ -3029,16 +3092,14 @@
  11.699              }
  11.700          }
  11.701  
  11.702 -        final FindProperty find = findProperty(JSType.toString(key), true);
  11.703 -
  11.704 -        return find != null;
  11.705 +        return hasProperty(JSType.toString(key), true);
  11.706      }
  11.707  
  11.708      @Override
  11.709      public boolean has(final int key) {
  11.710 -        final int index = ArrayIndex.getArrayIndex(key);
  11.711 -
  11.712 -        if (ArrayIndex.isValidArrayIndex(index)) {
  11.713 +        final int index = getArrayIndex(key);
  11.714 +
  11.715 +        if (isValidArrayIndex(index)) {
  11.716              for (ScriptObject self = this; self != null; self = self.getProto()) {
  11.717                  if (self.getArray().has(index)) {
  11.718                      return true;
  11.719 @@ -3046,66 +3107,32 @@
  11.720              }
  11.721          }
  11.722  
  11.723 -        final FindProperty find = findProperty(JSType.toString(key), true);
  11.724 -
  11.725 -        return find != null;
  11.726 +        return hasProperty(JSType.toString(key), true);
  11.727      }
  11.728  
  11.729      @Override
  11.730      public boolean hasOwnProperty(final Object key) {
  11.731 -        final int index = ArrayIndex.getArrayIndex(key);
  11.732 -
  11.733 -        if (getArray().has(index)) {
  11.734 -            return true;
  11.735 -        }
  11.736 -
  11.737 -        final FindProperty find = findProperty(JSType.toString(key), false);
  11.738 -
  11.739 -        return find != null;
  11.740 +        return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false);
  11.741      }
  11.742  
  11.743      @Override
  11.744      public boolean hasOwnProperty(final int key) {
  11.745 -        final int index = ArrayIndex.getArrayIndex(key);
  11.746 -
  11.747 -        if (getArray().has(index)) {
  11.748 -            return true;
  11.749 -        }
  11.750 -
  11.751 -        final FindProperty find = findProperty(JSType.toString(key), false);
  11.752 -
  11.753 -        return find != null;
  11.754 +        return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false);
  11.755      }
  11.756  
  11.757      @Override
  11.758      public boolean hasOwnProperty(final long key) {
  11.759 -        final int index = ArrayIndex.getArrayIndex(key);
  11.760 -
  11.761 -        if (getArray().has(index)) {
  11.762 -            return true;
  11.763 -        }
  11.764 -
  11.765 -        final FindProperty find = findProperty(JSType.toString(key), false);
  11.766 -
  11.767 -        return find != null;
  11.768 +        return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false);
  11.769      }
  11.770  
  11.771      @Override
  11.772      public boolean hasOwnProperty(final double key) {
  11.773 -        final int index = ArrayIndex.getArrayIndex(key);
  11.774 -
  11.775 -        if (getArray().has(index)) {
  11.776 -            return true;
  11.777 -        }
  11.778 -
  11.779 -        final FindProperty find = findProperty(JSType.toString(key), false);
  11.780 -
  11.781 -        return find != null;
  11.782 +        return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false);
  11.783      }
  11.784  
  11.785      @Override
  11.786      public boolean delete(final int key, final boolean strict) {
  11.787 -        final int index = ArrayIndex.getArrayIndex(key);
  11.788 +        final int index = getArrayIndex(key);
  11.789          final ArrayData array = getArray();
  11.790  
  11.791          if (array.has(index)) {
  11.792 @@ -3121,7 +3148,7 @@
  11.793  
  11.794      @Override
  11.795      public boolean delete(final long key, final boolean strict) {
  11.796 -        final int index = ArrayIndex.getArrayIndex(key);
  11.797 +        final int index = getArrayIndex(key);
  11.798          final ArrayData array = getArray();
  11.799  
  11.800          if (array.has(index)) {
  11.801 @@ -3137,7 +3164,7 @@
  11.802  
  11.803      @Override
  11.804      public boolean delete(final double key, final boolean strict) {
  11.805 -        final int index = ArrayIndex.getArrayIndex(key);
  11.806 +        final int index = getArrayIndex(key);
  11.807          final ArrayData array = getArray();
  11.808  
  11.809          if (array.has(index)) {
  11.810 @@ -3153,7 +3180,7 @@
  11.811  
  11.812      @Override
  11.813      public boolean delete(final Object key, final boolean strict) {
  11.814 -        final int index = ArrayIndex.getArrayIndex(key);
  11.815 +        final int index = getArrayIndex(key);
  11.816          final ArrayData array = getArray();
  11.817  
  11.818          if (array.has(index)) {
    12.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Fri Oct 11 23:31:18 2013 -0700
    12.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Tue Oct 15 22:13:56 2013 +0530
    12.3 @@ -25,9 +25,9 @@
    12.4  
    12.5  package jdk.nashorn.internal.runtime.linker;
    12.6  
    12.7 +import static jdk.nashorn.internal.lookup.Lookup.MH;
    12.8  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    12.9  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   12.10 -import static jdk.nashorn.internal.lookup.Lookup.MH;
   12.11  
   12.12  import java.lang.invoke.MethodHandle;
   12.13  import java.lang.invoke.MethodHandles;
   12.14 @@ -211,6 +211,20 @@
   12.15                  return null;
   12.16              } else if (obj instanceof Long) {
   12.17                  return (Long) obj;
   12.18 +            } else if (obj instanceof Integer) {
   12.19 +                return ((Integer)obj).longValue();
   12.20 +            } else if (obj instanceof Double) {
   12.21 +                final Double d = (Double)obj;
   12.22 +                if(Double.isInfinite(d.doubleValue())) {
   12.23 +                    return 0L;
   12.24 +                }
   12.25 +                return d.longValue();
   12.26 +            } else if (obj instanceof Float) {
   12.27 +                final Float f = (Float)obj;
   12.28 +                if(Float.isInfinite(f.floatValue())) {
   12.29 +                    return 0L;
   12.30 +                }
   12.31 +                return f.longValue();
   12.32              } else if (obj instanceof Number) {
   12.33                  return ((Number)obj).longValue();
   12.34              } else if (obj instanceof String || obj instanceof ConsString) {
    13.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Fri Oct 11 23:31:18 2013 -0700
    13.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Tue Oct 15 22:13:56 2013 +0530
    13.3 @@ -30,6 +30,8 @@
    13.4  import java.lang.invoke.MethodHandle;
    13.5  import java.lang.invoke.MethodHandles;
    13.6  import java.lang.reflect.Modifier;
    13.7 +import java.util.Deque;
    13.8 +import java.util.List;
    13.9  import jdk.internal.dynalink.CallSiteDescriptor;
   13.10  import jdk.internal.dynalink.linker.ConversionComparator;
   13.11  import jdk.internal.dynalink.linker.GuardedInvocation;
   13.12 @@ -38,6 +40,8 @@
   13.13  import jdk.internal.dynalink.linker.LinkerServices;
   13.14  import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
   13.15  import jdk.internal.dynalink.support.Guards;
   13.16 +import jdk.nashorn.internal.objects.NativeArray;
   13.17 +import jdk.nashorn.internal.runtime.JSType;
   13.18  import jdk.nashorn.internal.runtime.ScriptFunction;
   13.19  import jdk.nashorn.internal.runtime.ScriptObject;
   13.20  import jdk.nashorn.internal.runtime.Undefined;
   13.21 @@ -47,6 +51,13 @@
   13.22   * includes {@link ScriptFunction} and its subclasses) as well as {@link Undefined}.
   13.23   */
   13.24  final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
   13.25 +    private static final ClassValue<MethodHandle> ARRAY_CONVERTERS = new ClassValue<MethodHandle>() {
   13.26 +        @Override
   13.27 +        protected MethodHandle computeValue(Class<?> type) {
   13.28 +            return createArrayConverter(type);
   13.29 +        }
   13.30 +    };
   13.31 +
   13.32      /**
   13.33       * Returns true if {@code ScriptObject} is assignable from {@code type}, or it is {@code Undefined}.
   13.34       */
   13.35 @@ -103,6 +114,12 @@
   13.36          if (mh != null) {
   13.37              return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE);
   13.38          }
   13.39 +
   13.40 +        GuardedInvocation inv = getArrayConverter(sourceType, targetType);
   13.41 +        if(inv != null) {
   13.42 +            return inv;
   13.43 +        }
   13.44 +
   13.45          return getSamTypeConverter(sourceType, targetType);
   13.46      }
   13.47  
   13.48 @@ -129,6 +146,41 @@
   13.49          return null;
   13.50      }
   13.51  
   13.52 +    /**
   13.53 +     * Returns a guarded invocation that converts from a source type that is NativeArray to a Java array or List or
   13.54 +     * Deque type.
   13.55 +     * @param sourceType the source type (presumably NativeArray a superclass of it)
   13.56 +     * @param targetType the target type (presumably an array type, or List or Deque)
   13.57 +     * @return a guarded invocation that converts from the source type to the target type. null is returned if
   13.58 +     * either the source type is neither NativeArray, nor a superclass of it, or if the target type is not an array
   13.59 +     * type, List, or Deque.
   13.60 +     */
   13.61 +    private static GuardedInvocation getArrayConverter(final Class<?> sourceType, final Class<?> targetType) {
   13.62 +        final boolean isSourceTypeNativeArray = sourceType == NativeArray.class;
   13.63 +        // If source type is more generic than ScriptFunction class, we'll need to use a guard
   13.64 +        final boolean isSourceTypeGeneric = !isSourceTypeNativeArray && sourceType.isAssignableFrom(NativeArray.class);
   13.65 +
   13.66 +        if (isSourceTypeNativeArray || isSourceTypeGeneric) {
   13.67 +            final MethodHandle guard = isSourceTypeGeneric ? IS_NATIVE_ARRAY : null;
   13.68 +            if(targetType.isArray()) {
   13.69 +                return new GuardedInvocation(ARRAY_CONVERTERS.get(targetType), guard);
   13.70 +            }
   13.71 +            if(targetType == List.class) {
   13.72 +                return new GuardedInvocation(JSType.TO_JAVA_LIST.methodHandle(), guard);
   13.73 +            }
   13.74 +            if(targetType == Deque.class) {
   13.75 +                return new GuardedInvocation(JSType.TO_JAVA_DEQUE.methodHandle(), guard);
   13.76 +            }
   13.77 +        }
   13.78 +        return null;
   13.79 +    }
   13.80 +
   13.81 +    private static MethodHandle createArrayConverter(final Class<?> type) {
   13.82 +        assert type.isArray();
   13.83 +        final MethodHandle converter = MH.insertArguments(JSType.TO_JAVA_ARRAY.methodHandle(), 1, type.getComponentType());
   13.84 +        return MH.asType(converter, converter.type().changeReturnType(type));
   13.85 +    }
   13.86 +
   13.87      private static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {
   13.88          return isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) &&
   13.89                  JavaAdapterFactory.isAutoConvertibleFromFunction(clazz);
   13.90 @@ -148,7 +200,26 @@
   13.91  
   13.92      @Override
   13.93      public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
   13.94 +        if(sourceType == NativeArray.class) {
   13.95 +            // Prefer lists, as they're less costly to create than arrays.
   13.96 +            if(isList(targetType1)) {
   13.97 +                if(!isList(targetType2)) {
   13.98 +                    return Comparison.TYPE_1_BETTER;
   13.99 +                }
  13.100 +            } else if(isList(targetType2)) {
  13.101 +                return Comparison.TYPE_2_BETTER;
  13.102 +            }
  13.103 +            // Then prefer arrays
  13.104 +            if(targetType1.isArray()) {
  13.105 +                if(!targetType2.isArray()) {
  13.106 +                    return Comparison.TYPE_1_BETTER;
  13.107 +                }
  13.108 +            } else if(targetType2.isArray()) {
  13.109 +                return Comparison.TYPE_2_BETTER;
  13.110 +            }
  13.111 +        }
  13.112          if(ScriptObject.class.isAssignableFrom(sourceType)) {
  13.113 +            // Prefer interfaces
  13.114              if(targetType1.isInterface()) {
  13.115                  if(!targetType2.isInterface()) {
  13.116                      return Comparison.TYPE_1_BETTER;
  13.117 @@ -160,7 +231,12 @@
  13.118          return Comparison.INDETERMINATE;
  13.119      }
  13.120  
  13.121 +    private static boolean isList(Class<?> clazz) {
  13.122 +        return clazz == List.class || clazz == Deque.class;
  13.123 +    }
  13.124 +
  13.125      private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class));
  13.126 +    private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class));
  13.127  
  13.128      private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined",
  13.129              Boolean.TYPE, Object.class);
    14.1 --- a/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js	Fri Oct 11 23:31:18 2013 -0700
    14.2 +++ b/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js	Tue Oct 15 22:13:56 2013 +0530
    14.3 @@ -98,6 +98,17 @@
    14.4  
    14.5  }
    14.6  
    14.7 +// sync
    14.8 +Object.defineProperty(this, "sync", {
    14.9 +    configurable: true, enumerable: false, writable: true,
   14.10 +    value: function(func, syncobj) {
   14.11 +        if (arguments.length < 1 || arguments.length > 2 ) {
   14.12 +            throw "sync(function [,object]) parameter count mismatch";
   14.13 +        }
   14.14 +        return Packages.jdk.nashorn.api.scripting.ScriptUtils.makeSynchronizedFunction(func, syncobj);
   14.15 +    }
   14.16 +});
   14.17 +
   14.18  // Object.prototype.__defineGetter__
   14.19  Object.defineProperty(Object.prototype, "__defineGetter__", {
   14.20      configurable: true, enumerable: false, writable: true,
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/script/basic/JDK-8026016.js	Tue Oct 15 22:13:56 2013 +0530
    15.3 @@ -0,0 +1,68 @@
    15.4 +/*
    15.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + * 
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.
   15.11 + * 
   15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.15 + * version 2 for more details (a copy is included in the LICENSE file that
   15.16 + * accompanied this code).
   15.17 + * 
   15.18 + * You should have received a copy of the GNU General Public License version
   15.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.21 + * 
   15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.23 + * or visit www.oracle.com if you need additional information or have any
   15.24 + * questions.
   15.25 + */
   15.26 +
   15.27 +/**
   15.28 + * JDK-8026016: too many relinks dominate avatar.js http benchmark
   15.29 + *
   15.30 + * @test
   15.31 + * @run
   15.32 + */
   15.33 +
   15.34 +function accessMegamorphic() {
   15.35 +    for (var i = 0; i < 26; i++) {
   15.36 +        var o = {};
   15.37 +        o[String.fromCharCode(i + 97)] = 1;
   15.38 +        o._;
   15.39 +    }
   15.40 +}
   15.41 +
   15.42 +function invokeMegamorphic() {
   15.43 +    for (var i = 0; i < 26; i++) {
   15.44 +        var o = {};
   15.45 +        o[String.fromCharCode(i + 97)] = 1;
   15.46 +        try {
   15.47 +            o._(i);
   15.48 +        } catch (e) {
   15.49 +            print(e);
   15.50 +        }
   15.51 +    }
   15.52 +}
   15.53 +
   15.54 +Object.prototype.__noSuchProperty__ = function() {
   15.55 +    print("no such property", Array.prototype.slice.call(arguments));
   15.56 +};
   15.57 +
   15.58 +invokeMegamorphic();
   15.59 +accessMegamorphic();
   15.60 +
   15.61 +Object.prototype.__noSuchMethod__ = function() {
   15.62 +    print("no such method", Array.prototype.slice.call(arguments));
   15.63 +};
   15.64 +
   15.65 +invokeMegamorphic();
   15.66 +accessMegamorphic();
   15.67 +
   15.68 +Object.prototype.__noSuchMethod__ = "nofunction";
   15.69 +
   15.70 +invokeMegamorphic();
   15.71 +accessMegamorphic();
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/script/basic/JDK-8026016.js.EXPECTED	Tue Oct 15 22:13:56 2013 +0530
    16.3 @@ -0,0 +1,182 @@
    16.4 +no such property _
    16.5 +TypeError: Cannot call undefined
    16.6 +no such property _
    16.7 +TypeError: Cannot call undefined
    16.8 +no such property _
    16.9 +TypeError: Cannot call undefined
   16.10 +no such property _
   16.11 +TypeError: Cannot call undefined
   16.12 +no such property _
   16.13 +TypeError: Cannot call undefined
   16.14 +no such property _
   16.15 +TypeError: Cannot call undefined
   16.16 +no such property _
   16.17 +TypeError: Cannot call undefined
   16.18 +no such property _
   16.19 +TypeError: Cannot call undefined
   16.20 +no such property _
   16.21 +TypeError: Cannot call undefined
   16.22 +no such property _
   16.23 +TypeError: Cannot call undefined
   16.24 +no such property _
   16.25 +TypeError: Cannot call undefined
   16.26 +no such property _
   16.27 +TypeError: Cannot call undefined
   16.28 +no such property _
   16.29 +TypeError: Cannot call undefined
   16.30 +no such property _
   16.31 +TypeError: Cannot call undefined
   16.32 +no such property _
   16.33 +TypeError: Cannot call undefined
   16.34 +no such property _
   16.35 +TypeError: Cannot call undefined
   16.36 +no such property _
   16.37 +TypeError: Cannot call undefined
   16.38 +no such property _
   16.39 +TypeError: Cannot call undefined
   16.40 +no such property _
   16.41 +TypeError: Cannot call undefined
   16.42 +no such property _
   16.43 +TypeError: Cannot call undefined
   16.44 +no such property _
   16.45 +TypeError: Cannot call undefined
   16.46 +no such property _
   16.47 +TypeError: Cannot call undefined
   16.48 +no such property _
   16.49 +TypeError: Cannot call undefined
   16.50 +no such property _
   16.51 +TypeError: Cannot call undefined
   16.52 +no such property _
   16.53 +TypeError: Cannot call undefined
   16.54 +no such property _
   16.55 +TypeError: Cannot call undefined
   16.56 +no such property _
   16.57 +no such property _
   16.58 +no such property _
   16.59 +no such property _
   16.60 +no such property _
   16.61 +no such property _
   16.62 +no such property _
   16.63 +no such property _
   16.64 +no such property _
   16.65 +no such property _
   16.66 +no such property _
   16.67 +no such property _
   16.68 +no such property _
   16.69 +no such property _
   16.70 +no such property _
   16.71 +no such property _
   16.72 +no such property _
   16.73 +no such property _
   16.74 +no such property _
   16.75 +no such property _
   16.76 +no such property _
   16.77 +no such property _
   16.78 +no such property _
   16.79 +no such property _
   16.80 +no such property _
   16.81 +no such property _
   16.82 +no such method _,0
   16.83 +no such method _,1
   16.84 +no such method _,2
   16.85 +no such method _,3
   16.86 +no such method _,4
   16.87 +no such method _,5
   16.88 +no such method _,6
   16.89 +no such method _,7
   16.90 +no such method _,8
   16.91 +no such method _,9
   16.92 +no such method _,10
   16.93 +no such method _,11
   16.94 +no such method _,12
   16.95 +no such method _,13
   16.96 +no such method _,14
   16.97 +no such method _,15
   16.98 +no such method _,16
   16.99 +no such method _,17
  16.100 +no such method _,18
  16.101 +no such method _,19
  16.102 +no such method _,20
  16.103 +no such method _,21
  16.104 +no such method _,22
  16.105 +no such method _,23
  16.106 +no such method _,24
  16.107 +no such method _,25
  16.108 +no such property _
  16.109 +no such property _
  16.110 +no such property _
  16.111 +no such property _
  16.112 +no such property _
  16.113 +no such property _
  16.114 +no such property _
  16.115 +no such property _
  16.116 +no such property _
  16.117 +no such property _
  16.118 +no such property _
  16.119 +no such property _
  16.120 +no such property _
  16.121 +no such property _
  16.122 +no such property _
  16.123 +no such property _
  16.124 +no such property _
  16.125 +no such property _
  16.126 +no such property _
  16.127 +no such property _
  16.128 +no such property _
  16.129 +no such property _
  16.130 +no such property _
  16.131 +no such property _
  16.132 +no such property _
  16.133 +no such property _
  16.134 +TypeError: Cannot call undefined
  16.135 +TypeError: Cannot call undefined
  16.136 +TypeError: Cannot call undefined
  16.137 +TypeError: Cannot call undefined
  16.138 +TypeError: Cannot call undefined
  16.139 +TypeError: Cannot call undefined
  16.140 +TypeError: Cannot call undefined
  16.141 +TypeError: Cannot call undefined
  16.142 +TypeError: Cannot call undefined
  16.143 +TypeError: Cannot call undefined
  16.144 +TypeError: Cannot call undefined
  16.145 +TypeError: Cannot call undefined
  16.146 +TypeError: Cannot call undefined
  16.147 +TypeError: Cannot call undefined
  16.148 +TypeError: Cannot call undefined
  16.149 +TypeError: Cannot call undefined
  16.150 +TypeError: Cannot call undefined
  16.151 +TypeError: Cannot call undefined
  16.152 +TypeError: Cannot call undefined
  16.153 +TypeError: Cannot call undefined
  16.154 +TypeError: Cannot call undefined
  16.155 +TypeError: Cannot call undefined
  16.156 +TypeError: Cannot call undefined
  16.157 +TypeError: Cannot call undefined
  16.158 +TypeError: Cannot call undefined
  16.159 +TypeError: Cannot call undefined
  16.160 +no such property _
  16.161 +no such property _
  16.162 +no such property _
  16.163 +no such property _
  16.164 +no such property _
  16.165 +no such property _
  16.166 +no such property _
  16.167 +no such property _
  16.168 +no such property _
  16.169 +no such property _
  16.170 +no such property _
  16.171 +no such property _
  16.172 +no such property _
  16.173 +no such property _
  16.174 +no such property _
  16.175 +no such property _
  16.176 +no such property _
  16.177 +no such property _
  16.178 +no such property _
  16.179 +no such property _
  16.180 +no such property _
  16.181 +no such property _
  16.182 +no such property _
  16.183 +no such property _
  16.184 +no such property _
  16.185 +no such property _
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/script/basic/JDK-8026367.js	Tue Oct 15 22:13:56 2013 +0530
    17.3 @@ -0,0 +1,61 @@
    17.4 +/*
    17.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + * 
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.
   17.11 + * 
   17.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.15 + * version 2 for more details (a copy is included in the LICENSE file that
   17.16 + * accompanied this code).
   17.17 + * 
   17.18 + * You should have received a copy of the GNU General Public License version
   17.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.21 + * 
   17.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.23 + * or visit www.oracle.com if you need additional information or have any
   17.24 + * questions.
   17.25 + */
   17.26 +
   17.27 +/**
   17.28 + * JDK-8026367: Add a sync keyword to mozilla_compat
   17.29 + *
   17.30 + * @test
   17.31 + * @run
   17.32 + */
   17.33 +
   17.34 +if (typeof sync === "undefined") {
   17.35 +    load("nashorn:mozilla_compat.js");
   17.36 +}
   17.37 +
   17.38 +var obj = {
   17.39 +    count: 0,
   17.40 +    // Sync called with one argument will synchronize on this-object of invocation
   17.41 +    inc: sync(function(d) {
   17.42 +        this.count += d;
   17.43 +    }),
   17.44 +    // Pass explicit object to synchronize on as second argument
   17.45 +    dec: sync(function(d) {
   17.46 +        this.count -= d;
   17.47 +    }, obj)
   17.48 +};
   17.49 +
   17.50 +var t1 = new java.lang.Thread(function() {
   17.51 +    for (var i = 0; i < 100000; i++) obj.inc(1);
   17.52 +});
   17.53 +var t2 = new java.lang.Thread(function() {
   17.54 +    for (var i = 0; i < 100000; i++) obj.dec(1);
   17.55 +});
   17.56 +
   17.57 +t1.start();
   17.58 +t2.start();
   17.59 +t1.join();
   17.60 +t2.join();
   17.61 +
   17.62 +if (obj.count !== 0) {
   17.63 +    throw new Error("Expected count == 0, got " + obj.count);
   17.64 +}
    18.1 --- a/test/script/sandbox/loadcompat.js	Fri Oct 11 23:31:18 2013 -0700
    18.2 +++ b/test/script/sandbox/loadcompat.js	Tue Oct 15 22:13:56 2013 +0530
    18.3 @@ -48,3 +48,7 @@
    18.4  if (typeof importPackage != 'function') {
    18.5      fail("importPackage function is missing in compatibility script");
    18.6  }
    18.7 +
    18.8 +if (typeof sync != 'function') {
    18.9 +    fail("sync function is missing in compatibility script");
   18.10 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java	Tue Oct 15 22:13:56 2013 +0530
    19.3 @@ -0,0 +1,235 @@
    19.4 +/*
    19.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    19.7 + *
    19.8 + * This code is free software; you can redistribute it and/or modify it
    19.9 + * under the terms of the GNU General Public License version 2 only, as
   19.10 + * published by the Free Software Foundation.  Oracle designates this
   19.11 + * particular file as subject to the "Classpath" exception as provided
   19.12 + * by Oracle in the LICENSE file that accompanied this code.
   19.13 + *
   19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   19.17 + * version 2 for more details (a copy is included in the LICENSE file that
   19.18 + * accompanied this code).
   19.19 + *
   19.20 + * You should have received a copy of the GNU General Public License version
   19.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   19.23 + *
   19.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   19.25 + * or visit www.oracle.com if you need additional information or have any
   19.26 + * questions.
   19.27 + */
   19.28 +
   19.29 +package jdk.nashorn.api.javaaccess;
   19.30 +
   19.31 +import static org.testng.AssertJUnit.assertEquals;
   19.32 +import static org.testng.AssertJUnit.assertFalse;
   19.33 +import static org.testng.AssertJUnit.assertNull;
   19.34 +import static org.testng.AssertJUnit.assertTrue;
   19.35 +
   19.36 +import java.util.Arrays;
   19.37 +import java.util.List;
   19.38 +import javax.script.ScriptContext;
   19.39 +import javax.script.ScriptEngine;
   19.40 +import javax.script.ScriptEngineManager;
   19.41 +import javax.script.ScriptException;
   19.42 +import org.testng.TestNG;
   19.43 +import org.testng.annotations.AfterClass;
   19.44 +import org.testng.annotations.BeforeClass;
   19.45 +import org.testng.annotations.Test;
   19.46 +
   19.47 +public class ArrayConversionTest {
   19.48 +    private static ScriptEngine e = null;
   19.49 +
   19.50 +    public static void main(final String[] args) {
   19.51 +        TestNG.main(args);
   19.52 +    }
   19.53 +
   19.54 +    @BeforeClass
   19.55 +    public static void setUpClass() throws ScriptException {
   19.56 +        e = new ScriptEngineManager().getEngineByName("nashorn");
   19.57 +    }
   19.58 +
   19.59 +    @AfterClass
   19.60 +    public static void tearDownClass() {
   19.61 +        e = null;
   19.62 +    }
   19.63 +
   19.64 +    @Test
   19.65 +    public void testIntArrays() throws ScriptException {
   19.66 +        runTest("assertNullIntArray", "null");
   19.67 +        runTest("assertEmptyIntArray", "[]");
   19.68 +        runTest("assertSingle42IntArray", "[42]");
   19.69 +        runTest("assertSingle42IntArray", "['42']");
   19.70 +        runTest("assertIntArrayConversions", "[false, true, NaN, Infinity, -Infinity, 0.4, 0.6, null, undefined, [], {}, [1], [1, 2]]");
   19.71 +    }
   19.72 +
   19.73 +    @Test
   19.74 +    public void testIntIntArrays() throws ScriptException {
   19.75 +        runTest("assertNullIntIntArray", "null");
   19.76 +        runTest("assertEmptyIntIntArray", "[]");
   19.77 +        runTest("assertSingleEmptyIntIntArray", "[[]]");
   19.78 +        runTest("assertSingleNullIntIntArray", "[null]");
   19.79 +        runTest("assertLargeIntIntArray", "[[false], [1], [2, 3], [4, 5, 6], ['7', {valueOf: function() { return 8 }}]]");
   19.80 +    }
   19.81 +
   19.82 +    @Test
   19.83 +    public void testObjectObjectArrays() throws ScriptException {
   19.84 +        runTest("assertLargeObjectObjectArray", "[[false], [1], ['foo', 42.3], [{x: 17}]]");
   19.85 +    }
   19.86 +
   19.87 +    @Test
   19.88 +    public void testBooleanArrays() throws ScriptException {
   19.89 +        runTest("assertBooleanArrayConversions", "[false, true, '', 'false', 0, 1, 0.4, 0.6, {}, [], [false], [true], NaN, Infinity, null, undefined]");
   19.90 +    }
   19.91 +
   19.92 +    @Test
   19.93 +    public void testArrayAmbiguity() throws ScriptException {
   19.94 +        runTest("x", "'abc'");
   19.95 +        runTest("x", "['foo', 'bar']");
   19.96 +    }
   19.97 +
   19.98 +    @Test
   19.99 +    public void testListArrays() throws ScriptException {
  19.100 +        runTest("assertListArray", "[['foo', 'bar'], ['apple', 'orange']]");
  19.101 +    }
  19.102 +
  19.103 +    @Test
  19.104 +    public void testVarArgs() throws ScriptException {
  19.105 +        // Sole NativeArray in vararg position becomes vararg array itself
  19.106 +        runTest("assertVarArg_42_17", "[42, 17]");
  19.107 +        // NativeArray in vararg position becomes an argument if there are more arguments
  19.108 +        runTest("assertVarArg_array_17", "[42], 18");
  19.109 +        // Only NativeArray is converted to vararg array, other objects (e.g. a function) aren't
  19.110 +        runTest("assertVarArg_function", "function() { return 'Hello' }");
  19.111 +    }
  19.112 +
  19.113 +    private static void runTest(final String testMethodName, final String argument) throws ScriptException {
  19.114 +        e.eval("Java.type('" + ArrayConversionTest.class.getName() + "')." + testMethodName + "(" + argument + ")");
  19.115 +    }
  19.116 +
  19.117 +    public static void assertNullIntArray(int[] array) {
  19.118 +        assertNull(array);
  19.119 +    }
  19.120 +
  19.121 +    public static void assertNullIntIntArray(int[][] array) {
  19.122 +        assertNull(array);
  19.123 +    }
  19.124 +
  19.125 +    public static void assertEmptyIntArray(int[] array) {
  19.126 +        assertEquals(0, array.length);
  19.127 +    }
  19.128 +
  19.129 +    public static void assertSingle42IntArray(int[] array) {
  19.130 +        assertEquals(1, array.length);
  19.131 +        assertEquals(42, array[0]);
  19.132 +    }
  19.133 +
  19.134 +
  19.135 +    public static void assertIntArrayConversions(int[] array) {
  19.136 +        assertEquals(13, array.length);
  19.137 +        assertEquals(0, array[0]); // false
  19.138 +        assertEquals(1, array[1]); // true
  19.139 +        assertEquals(0, array[2]); // NaN
  19.140 +        assertEquals(0, array[3]); // Infinity
  19.141 +        assertEquals(0, array[4]); // -Infinity
  19.142 +        assertEquals(0, array[5]); // 0.4
  19.143 +        assertEquals(0, array[6]); // 0.6 - floor, not round
  19.144 +        assertEquals(0, array[7]); // null
  19.145 +        assertEquals(0, array[8]); // undefined
  19.146 +        assertEquals(0, array[9]); // []
  19.147 +        assertEquals(0, array[10]); // {}
  19.148 +        assertEquals(1, array[11]); // [1]
  19.149 +        assertEquals(0, array[12]); // [1, 2]
  19.150 +    }
  19.151 +
  19.152 +    public static void assertEmptyIntIntArray(int[][] array) {
  19.153 +        assertEquals(0, array.length);
  19.154 +    }
  19.155 +
  19.156 +    public static void assertSingleEmptyIntIntArray(int[][] array) {
  19.157 +        assertEquals(1, array.length);
  19.158 +        assertTrue(Arrays.equals(new int[0], array[0]));
  19.159 +    }
  19.160 +
  19.161 +    public static void assertSingleNullIntIntArray(int[][] array) {
  19.162 +        assertEquals(1, array.length);
  19.163 +        assertNull(null, array[0]);
  19.164 +    }
  19.165 +
  19.166 +    public static void assertLargeIntIntArray(int[][] array) {
  19.167 +        assertEquals(5, array.length);
  19.168 +        assertTrue(Arrays.equals(new int[] { 0 }, array[0]));
  19.169 +        assertTrue(Arrays.equals(new int[] { 1 }, array[1]));
  19.170 +        assertTrue(Arrays.equals(new int[] { 2, 3 }, array[2]));
  19.171 +        assertTrue(Arrays.equals(new int[] { 4, 5, 6 }, array[3]));
  19.172 +        assertTrue(Arrays.equals(new int[] { 7, 8 }, array[4]));
  19.173 +    }
  19.174 +
  19.175 +    public static void assertLargeObjectObjectArray(Object[][] array) throws ScriptException {
  19.176 +        assertEquals(4, array.length);
  19.177 +        assertTrue(Arrays.equals(new Object[] { Boolean.FALSE }, array[0]));
  19.178 +        assertTrue(Arrays.equals(new Object[] { 1 }, array[1]));
  19.179 +        assertTrue(Arrays.equals(new Object[] { "foo", 42.3d }, array[2]));
  19.180 +        assertEquals(1, array[3].length);
  19.181 +        e.getBindings(ScriptContext.ENGINE_SCOPE).put("obj", array[3][0]);
  19.182 +        assertEquals(17, e.eval("obj.x"));
  19.183 +    }
  19.184 +
  19.185 +    public static void assertBooleanArrayConversions(boolean[] array) {
  19.186 +        assertEquals(16, array.length);
  19.187 +        assertFalse(array[0]); // false
  19.188 +        assertTrue(array[1]); // true
  19.189 +        assertFalse(array[2]); // ''
  19.190 +        assertTrue(array[3]); // 'false' (yep, every non-empty string converts to true)
  19.191 +        assertFalse(array[4]); // 0
  19.192 +        assertTrue(array[5]); // 1
  19.193 +        assertTrue(array[6]); // 0.4
  19.194 +        assertTrue(array[7]); // 0.6
  19.195 +        assertTrue(array[8]); // {}
  19.196 +        assertTrue(array[9]); // []
  19.197 +        assertTrue(array[10]); // [false]
  19.198 +        assertTrue(array[11]); // [true]
  19.199 +        assertFalse(array[12]); // NaN
  19.200 +        assertTrue(array[13]); // Infinity
  19.201 +        assertFalse(array[14]); // null
  19.202 +        assertFalse(array[15]); // undefined
  19.203 +    }
  19.204 +
  19.205 +    public static void assertListArray(List<?>[] array) {
  19.206 +        assertEquals(2, array.length);
  19.207 +        assertEquals(Arrays.asList("foo", "bar"), array[0]);
  19.208 +        assertEquals(Arrays.asList("apple", "orange"), array[1]);
  19.209 +    }
  19.210 +
  19.211 +    public static void assertVarArg_42_17(Object... args) throws ScriptException {
  19.212 +        assertEquals(2, args.length);
  19.213 +        assertEquals(42, ((Number)args[0]).intValue());
  19.214 +        assertEquals(17, ((Number)args[1]).intValue());
  19.215 +    }
  19.216 +
  19.217 +    public static void assertVarArg_array_17(Object... args) throws ScriptException {
  19.218 +        assertEquals(2, args.length);
  19.219 +        e.getBindings(ScriptContext.ENGINE_SCOPE).put("arr", args[0]);
  19.220 +        assertTrue((Boolean)e.eval("arr instanceof Array && arr.length == 1 && arr[0] == 42"));
  19.221 +        assertEquals(18, ((Number)args[1]).intValue());
  19.222 +    }
  19.223 +
  19.224 +    public static void assertVarArg_function(Object... args) throws ScriptException {
  19.225 +        assertEquals(1, args.length);
  19.226 +        e.getBindings(ScriptContext.ENGINE_SCOPE).put("fn", args[0]);
  19.227 +        assertEquals("Hello", e.eval("fn()"));
  19.228 +    }
  19.229 +
  19.230 +
  19.231 +
  19.232 +    public static void x(String y) {
  19.233 +        assertEquals("abc", y);
  19.234 +    }
  19.235 +    public static void x(String[] y) {
  19.236 +        assertTrue(Arrays.equals(new String[] { "foo", "bar"}, y));
  19.237 +    }
  19.238 +}

mercurial