changeset 450:d685fec24d13

Merge
author sundar
date Tue, 16 Jul 2013 09:54:04 +0530
parents cbfeffbcd3f2 28f1f2374004
children 965d876853ec
files
diffstat 24 files changed, 978 insertions(+), 145 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk/internal/dynalink/DynamicLinker.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/internal/dynalink/DynamicLinker.java	Tue Jul 16 09:54:04 2013 +0530
@@ -144,6 +144,9 @@
     private static final String CLASS_NAME = DynamicLinker.class.getName();
     private static final String RELINK_METHOD_NAME = "relink";
 
+    private static final String INITIAL_LINK_CLASS_NAME = "java.lang.invoke.MethodHandleNatives";
+    private static final String INITIAL_LINK_METHOD_NAME = "linkCallSite";
+
     private final LinkerServices linkerServices;
     private final int runtimeContextArgCount;
     private final boolean syncOnRelink;
@@ -262,20 +265,54 @@
     }
 
     /**
-     * Returns a stack trace element describing the location of the call site currently being relinked on the current
+     * Returns a stack trace element describing the location of the call site currently being linked on the current
      * thread. The operation internally creates a Throwable object and inspects its stack trace, so it's potentially
      * expensive. The recommended usage for it is in writing diagnostics code.
-     * @return a stack trace element describing the location of the call site currently being relinked, or null if it is
-     * not invoked while a call site is being relinked.
+     * @return a stack trace element describing the location of the call site currently being linked, or null if it is
+     * not invoked while a call site is being linked.
      */
-    public static StackTraceElement getRelinkedCallSiteLocation() {
+    public static StackTraceElement getLinkedCallSiteLocation() {
         final StackTraceElement[] trace = new Throwable().getStackTrace();
         for(int i = 0; i < trace.length - 1; ++i) {
             final StackTraceElement frame = trace[i];
-            if(RELINK_METHOD_NAME.equals(frame.getMethodName()) && CLASS_NAME.equals(frame.getClassName())) {
+            if(isRelinkFrame(frame) || isInitialLinkFrame(frame)) {
                 return trace[i + 1];
             }
         }
         return null;
     }
+
+    /**
+     * Deprecated because of not precise name.
+     * @deprecated Use {@link #getLinkedCallSiteLocation()} instead.
+     * @return see non-deprecated method
+     */
+    @Deprecated
+    public static StackTraceElement getRelinkedCallSiteLocation() {
+        return getLinkedCallSiteLocation();
+    }
+
+    /**
+     * Returns true if the frame represents {@code MethodHandleNatives.linkCallSite()}, the frame immediately on top of
+     * the call site frame when the call site is being linked for the first time.
+     * @param frame the frame
+     * @return true if this frame represents {@code MethodHandleNatives.linkCallSite()}
+     */
+    private static boolean isInitialLinkFrame(final StackTraceElement frame) {
+        return testFrame(frame, INITIAL_LINK_METHOD_NAME, INITIAL_LINK_CLASS_NAME);
+    }
+
+    /**
+     * Returns true if the frame represents {@code DynamicLinker.relink()}, the frame immediately on top of the call
+     * site frame when the call site is being relinked (linked for second and subsequent times).
+     * @param frame the frame
+     * @return true if this frame represents {@code DynamicLinker.relink()}
+     */
+    private static boolean isRelinkFrame(final StackTraceElement frame) {
+        return testFrame(frame, RELINK_METHOD_NAME, CLASS_NAME);
+    }
+
+    private static boolean testFrame(final StackTraceElement frame, final String methodName, final String className) {
+        return methodName.equals(frame.getMethodName()) && className.equals(frame.getClassName());
+    }
 }
--- a/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java	Tue Jul 16 09:54:04 2013 +0530
@@ -92,6 +92,8 @@
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -194,6 +196,22 @@
 
     abstract FacetIntrospector createFacetIntrospector();
 
+    Collection<String> getReadablePropertyNames() {
+        return getUnmodifiableKeys(propertyGetters);
+    }
+
+    Collection<String> getWritablePropertyNames() {
+        return getUnmodifiableKeys(propertySetters);
+    }
+
+    Collection<String> getMethodNames() {
+        return getUnmodifiableKeys(methods);
+    }
+
+    private static Collection<String> getUnmodifiableKeys(Map<String, ?> m) {
+        return Collections.unmodifiableCollection(m.keySet());
+    }
+
     /**
      * Sets the specified dynamic method to be the property getter for the specified property. Note that you can only
      * use this when you're certain that the method handle does not belong to a caller-sensitive method. For properties
--- a/src/jdk/internal/dynalink/beans/BeansLinker.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/internal/dynalink/beans/BeansLinker.java	Tue Jul 16 09:54:04 2013 +0530
@@ -84,6 +84,8 @@
 package jdk.internal.dynalink.beans;
 
 import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.Collections;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.DynamicLinkerFactory;
 import jdk.internal.dynalink.linker.GuardedInvocation;
@@ -166,6 +168,72 @@
         return obj instanceof DynamicMethod;
     }
 
+    /**
+     * Returns a collection of names of all readable instance properties of a class.
+     * @param clazz the class
+     * @return a collection of names of all readable instance properties of a class.
+     */
+    public static Collection<String> getReadableInstancePropertyNames(Class<?> clazz) {
+        TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+        if(linker instanceof BeanLinker) {
+            return ((BeanLinker)linker).getReadablePropertyNames();
+        }
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns a collection of names of all writable instance properties of a class.
+     * @param clazz the class
+     * @return a collection of names of all writable instance properties of a class.
+     */
+    public static Collection<String> getWritableInstancePropertyNames(Class<?> clazz) {
+        TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+        if(linker instanceof BeanLinker) {
+            return ((BeanLinker)linker).getWritablePropertyNames();
+        }
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns a collection of names of all instance methods of a class.
+     * @param clazz the class
+     * @return a collection of names of all instance methods of a class.
+     */
+    public static Collection<String> getInstanceMethodNames(Class<?> clazz) {
+        TypeBasedGuardingDynamicLinker linker = getLinkerForClass(clazz);
+        if(linker instanceof BeanLinker) {
+            return ((BeanLinker)linker).getMethodNames();
+        }
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns a collection of names of all readable static properties of a class.
+     * @param clazz the class
+     * @return a collection of names of all readable static properties of a class.
+     */
+    public static Collection<String> getReadableStaticPropertyNames(Class<?> clazz) {
+        return StaticClassLinker.getReadableStaticPropertyNames(clazz);
+    }
+
+    /**
+     * Returns a collection of names of all writable static properties of a class.
+     * @param clazz the class
+     * @return a collection of names of all writable static properties of a class.
+     */
+    public static Collection<String> getWritableStaticPropertyNames(Class<?> clazz) {
+        return StaticClassLinker.getWritableStaticPropertyNames(clazz);
+    }
+
+    /**
+     * Returns a collection of names of all static methods of a class.
+     * @param clazz the class
+     * @return a collection of names of all static methods of a class.
+     */
+    public static Collection<String> getStaticMethodNames(Class<?> clazz) {
+        return StaticClassLinker.getStaticMethodNames(clazz);
+    }
+
     @Override
     public GuardedInvocation getGuardedInvocation(LinkRequest request, final LinkerServices linkerServices)
             throws Exception {
--- a/src/jdk/internal/dynalink/beans/StaticClassLinker.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/internal/dynalink/beans/StaticClassLinker.java	Tue Jul 16 09:54:04 2013 +0530
@@ -88,10 +88,10 @@
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Array;
 import java.util.Arrays;
+import java.util.Collection;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
 import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.internal.dynalink.linker.GuardingDynamicLinker;
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
@@ -102,9 +102,9 @@
  * @author Attila Szegedi
  */
 class StaticClassLinker implements TypeBasedGuardingDynamicLinker {
-    private final ClassValue<GuardingDynamicLinker> linkers = new ClassValue<GuardingDynamicLinker>() {
+    private static final ClassValue<SingleClassStaticsLinker> linkers = new ClassValue<SingleClassStaticsLinker>() {
         @Override
-        protected GuardingDynamicLinker computeValue(Class<?> clazz) {
+        protected SingleClassStaticsLinker computeValue(Class<?> clazz) {
             return new SingleClassStaticsLinker(clazz);
         }
     };
@@ -160,6 +160,18 @@
         }
     }
 
+    static Collection<String> getReadableStaticPropertyNames(Class<?> clazz) {
+        return linkers.get(clazz).getReadablePropertyNames();
+    }
+
+    static Collection<String> getWritableStaticPropertyNames(Class<?> clazz) {
+        return linkers.get(clazz).getWritablePropertyNames();
+    }
+
+    static Collection<String> getStaticMethodNames(Class<?> clazz) {
+        return linkers.get(clazz).getMethodNames();
+    }
+
     @Override
     public GuardedInvocation getGuardedInvocation(LinkRequest request, LinkerServices linkerServices) throws Exception {
         final Object receiver = request.getReceiver();
--- a/src/jdk/nashorn/internal/objects/NativeObject.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/objects/NativeObject.java	Tue Jul 16 09:54:04 2013 +0530
@@ -29,8 +29,22 @@
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
 import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.beans.StaticClass;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
+import jdk.internal.dynalink.support.LinkRequestImpl;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
@@ -58,6 +72,8 @@
 @ScriptClass("Object")
 public final class NativeObject {
     private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
+    private static final MethodType MIRROR_GETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class);
+    private static final MethodType MIRROR_SETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class, Object.class);
 
     // initialized by nasgen
     @SuppressWarnings("unused")
@@ -577,14 +593,92 @@
             final AccessorProperty[] props = new AccessorProperty[keys.length];
             for (int idx = 0; idx < keys.length; idx++) {
                 final String name = keys[idx];
-                final MethodHandle getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, Object.class, ScriptObjectMirror.class);
-                final MethodHandle setter = Bootstrap.createDynamicInvoker("dyn:setProp|setElem:" + name, Object.class, ScriptObjectMirror.class, Object.class);
+                final MethodHandle getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, MIRROR_GETTER_TYPE);
+                final MethodHandle setter = Bootstrap.createDynamicInvoker("dyn:setProp|setElem:" + name, MIRROR_SETTER_TYPE);
                 props[idx] = (AccessorProperty.create(name, 0, getter, setter));
             }
 
             targetObj.addBoundProperties(source, props);
+        } else if (source instanceof StaticClass) {
+            final Class<?> clazz = ((StaticClass)source).getRepresentedClass();
+            bindBeanProperties(targetObj, source, BeansLinker.getReadableStaticPropertyNames(clazz),
+                    BeansLinker.getWritableStaticPropertyNames(clazz), BeansLinker.getStaticMethodNames(clazz));
+        } else {
+            final Class<?> clazz = source.getClass();
+            bindBeanProperties(targetObj, source, BeansLinker.getReadableInstancePropertyNames(clazz),
+                    BeansLinker.getWritableInstancePropertyNames(clazz), BeansLinker.getInstanceMethodNames(clazz));
         }
 
         return target;
     }
+
+    private static void bindBeanProperties(final ScriptObject targetObj, final Object source,
+            final Collection<String> readablePropertyNames, final Collection<String> writablePropertyNames,
+            final Collection<String> methodNames) {
+        final Set<String> propertyNames = new HashSet<>(readablePropertyNames);
+        propertyNames.addAll(writablePropertyNames);
+
+        final Class<?> clazz = source.getClass();
+        Bootstrap.checkReflectionAccess(clazz);
+
+        final MethodType getterType = MethodType.methodType(Object.class, clazz);
+        final MethodType setterType = MethodType.methodType(Object.class, clazz, Object.class);
+
+        final GuardingDynamicLinker linker = BeansLinker.getLinkerForClass(clazz);
+
+        final List<AccessorProperty> properties = new ArrayList<>(propertyNames.size() + methodNames.size());
+        for(final String methodName: methodNames) {
+            properties.add(AccessorProperty.create(methodName, Property.NOT_WRITABLE,
+                    getBoundBeanMethodGetter(source, getBeanOperation(linker, "dyn:getMethod:" + methodName, getterType, source)),
+                    null));
+        }
+        for(final String propertyName: propertyNames) {
+            final boolean isWritable = writablePropertyNames.contains(propertyName);
+            properties.add(AccessorProperty.create(propertyName, isWritable ? 0 : Property.NOT_WRITABLE,
+                    readablePropertyNames.contains(propertyName) ? getBeanOperation(linker, "dyn:getProp:" + propertyName, getterType, source) : Lookup.EMPTY_GETTER,
+                    isWritable ? getBeanOperation(linker, "dyn:setProp:" + propertyName, setterType, source) : Lookup.EMPTY_SETTER));
+        }
+
+        targetObj.addBoundProperties(source, properties.toArray(new AccessorProperty[properties.size()]));
+    }
+
+    private static MethodHandle getBoundBeanMethodGetter(Object source, MethodHandle methodGetter) {
+        try {
+            // NOTE: we're relying on the fact that "dyn:getMethod:..." return value is constant for any given method
+            // name and object linked with BeansLinker. (Actually, an even stronger assumption is true: return value is
+            // constant for any given method name and object's class.)
+            return MethodHandles.dropArguments(MethodHandles.constant(Object.class,
+                    Bootstrap.bindDynamicMethod(methodGetter.invoke(source), source)), 0, Object.class);
+        } catch(RuntimeException|Error e) {
+            throw e;
+        } catch(Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    private static MethodHandle getBeanOperation(final GuardingDynamicLinker linker, final String operation,
+            final MethodType methodType, final Object source) {
+        final GuardedInvocation inv;
+        try {
+            inv = linker.getGuardedInvocation(createLinkRequest(operation, methodType, source),
+                Bootstrap.getLinkerServices());
+            assert passesGuard(source, inv.getGuard());
+        } catch(RuntimeException|Error e) {
+            throw e;
+        } catch(Throwable t) {
+            throw new RuntimeException(t);
+        }
+        assert inv.getSwitchPoint() == null; // Linkers in Dynalink's beans package don't use switchpoints.
+        // We discard the guard, as all method handles will be bound to a specific object.
+        return inv.getInvocation();
+    }
+
+    private static boolean passesGuard(final Object obj, final MethodHandle guard) throws Throwable {
+        return guard == null || (boolean)guard.invoke(obj);
+    }
+
+    private static LinkRequest createLinkRequest(String operation, MethodType methodType, Object source) {
+        return new LinkRequestImpl(CallSiteDescriptorFactory.create(MethodHandles.publicLookup(), operation,
+                methodType), false, source);
+    }
 }
--- a/src/jdk/nashorn/internal/parser/Parser.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/parser/Parser.java	Tue Jul 16 09:54:04 2013 +0530
@@ -55,9 +55,9 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import jdk.nashorn.internal.codegen.CompilerConstants;
@@ -1946,14 +1946,14 @@
 
         // Object context.
         // Prepare to accumulate elements.
-        // final List<Node> elements = new ArrayList<>();
-        final Map<String, PropertyNode> map = new LinkedHashMap<>();
+        final List<PropertyNode> elements = new ArrayList<>();
+        final Map<String, Integer> map = new HashMap<>();
 
         // Create a block for the object literal.
-            boolean commaSeen = true;
+        boolean commaSeen = true;
 loop:
-            while (true) {
-                switch (type) {
+        while (true) {
+            switch (type) {
                 case RBRACE:
                     next();
                     break loop;
@@ -1975,14 +1975,16 @@
                     // Get and add the next property.
                     final PropertyNode property = propertyAssignment();
                     final String key = property.getKeyName();
-                    final PropertyNode existingProperty = map.get(key);
-
-                    if (existingProperty == null) {
-                        map.put(key, property);
-                       // elements.add(property);
+                    final Integer existing = map.get(key);
+
+                    if (existing == null) {
+                        map.put(key, elements.size());
+                        elements.add(property);
                         break;
                     }
 
+                    final PropertyNode existingProperty = elements.get(existing);
+
                     // ECMA section 11.1.5 Object Initialiser
                     // point # 4 on property assignment production
                     final Expression   value  = property.getValue();
@@ -1993,62 +1995,43 @@
                     final FunctionNode prevGetter = existingProperty.getGetter();
                     final FunctionNode prevSetter = existingProperty.getSetter();
 
-                    boolean redefinitionOk = true;
                     // ECMA 11.1.5 strict mode restrictions
-                    if (isStrictMode) {
-                        if (value != null && prevValue != null) {
-                            redefinitionOk = false;
+                    if (isStrictMode && value != null && prevValue != null) {
+                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
+                    }
+
+                    final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
+                    final boolean isAccessor     = getter != null     || setter != null;
+
+                    // data property redefined as accessor property
+                    if (prevValue != null && isAccessor) {
+                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
+                    }
+
+                    // accessor property redefined as data
+                    if (isPrevAccessor && value != null) {
+                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
+                    }
+
+                    if (isAccessor && isPrevAccessor) {
+                        if (getter != null && prevGetter != null ||
+                                setter != null && prevSetter != null) {
+                            throw error(AbstractParser.message("property.redefinition", key), property.getToken());
                         }
                     }
 
-                    final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
-                    final boolean isAccessor     = getter != null     || setter != null;
-
-                    // data property redefined as accessor property
-                    if (prevValue != null && isAccessor) {
-                        redefinitionOk = false;
-                    }
-
-                    // accessor property redefined as data
-                    if (isPrevAccessor && value != null) {
-                        redefinitionOk = false;
-                    }
-
-                    if (isAccessor && isPrevAccessor) {
-                        if (getter != null && prevGetter != null ||
-                            setter != null && prevSetter != null) {
-                            redefinitionOk = false;
-                        }
-                    }
-
-                    if (!redefinitionOk) {
-                        throw error(AbstractParser.message("property.redefinition", key), property.getToken());
-                    }
-
-                    PropertyNode newProperty = existingProperty;
                     if (value != null) {
-                        if (prevValue == null) {
-                            map.put(key, newProperty = newProperty.setValue(value));
-                        } else {
-                            final long propertyToken = Token.recast(newProperty.getToken(), COMMARIGHT);
-                            map.put(key, newProperty = newProperty.setValue(new BinaryNode(propertyToken, prevValue, value)));
-                        }
-
-                        map.put(key, newProperty = newProperty.setGetter(null).setSetter(null));
-                    }
-
-                    if (getter != null) {
-                        map.put(key, newProperty = newProperty.setGetter(getter));
-                    }
-
-                    if (setter != null) {
-                        map.put(key, newProperty = newProperty.setSetter(setter));
+                        elements.add(property);
+                    } else if (getter != null) {
+                        elements.set(existing, existingProperty.setGetter(getter));
+                    } else if (setter != null) {
+                        elements.set(existing, existingProperty.setSetter(setter));
                     }
                     break;
             }
         }
 
-        return new ObjectNode(objectToken, finish, new ArrayList<>(map.values()));
+        return new ObjectNode(objectToken, finish, elements);
     }
 
     /**
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Tue Jul 16 09:54:04 2013 +0530
@@ -75,8 +75,13 @@
      * @return ArrayData
      */
     public static ArrayData allocate(final int length) {
-        final ArrayData arrayData = new IntArrayData(length);
-        return length == 0 ? arrayData : new DeletedRangeArrayFilter(arrayData, 0, length - 1);
+        if (length == 0) {
+            return new IntArrayData();
+        } else if (length >= SparseArrayData.MAX_DENSE_LENGTH) {
+            return new SparseArrayData(EMPTY_ARRAY, length);
+        } else {
+            return new DeletedRangeArrayFilter(new IntArrayData(length), 0, length - 1);
+        }
     }
 
     /**
--- a/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java	Tue Jul 16 09:54:04 2013 +0530
@@ -75,7 +75,9 @@
     }
 
     private static Object[] toObjectArray(final int[] array, final int length) {
-        final Object[] oarray = new Object[length];
+        assert length <= array.length : "length exceeds internal array size";
+        final Object[] oarray = new Object[array.length];
+
         for (int index = 0; index < length; index++) {
             oarray[index] = Integer.valueOf(array[index]);
         }
@@ -83,18 +85,22 @@
         return oarray;
     }
 
-    private static double[] toDoubleArray(final int[] array) {
+    private static double[] toDoubleArray(final int[] array, final int length) {
+        assert length <= array.length : "length exceeds internal array size";
         final double[] darray = new double[array.length];
-        for (int index = 0; index < array.length; index++) {
+
+        for (int index = 0; index < length; index++) {
             darray[index] = array[index];
         }
 
         return darray;
     }
 
-    private static long[] toLongArray(final int[] array) {
+    private static long[] toLongArray(final int[] array, final int length) {
+        assert length <= array.length : "length exceeds internal array size";
         final long[] larray = new long[array.length];
-        for (int index = 0; index < array.length; index++) {
+
+        for (int index = 0; index < length; index++) {
             larray[index] = array[index];
         }
 
@@ -105,12 +111,14 @@
     public ArrayData convert(final Class<?> type) {
         if (type == Integer.class) {
             return this;
-        } else if (type == Long.class) {
-            return new LongArrayData(IntArrayData.toLongArray(array), (int) length());
+        }
+        final int length = (int) length();
+        if (type == Long.class) {
+            return new LongArrayData(IntArrayData.toLongArray(array, length), length);
         } else if (type == Double.class) {
-            return new NumberArrayData(IntArrayData.toDoubleArray(array), (int) length());
+            return new NumberArrayData(IntArrayData.toDoubleArray(array, length), length);
         } else {
-            return new ObjectArrayData(IntArrayData.toObjectArray(array, array.length), (int) length());
+            return new ObjectArrayData(IntArrayData.toObjectArray(array, length), length);
         }
     }
 
@@ -161,26 +169,13 @@
 
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
-        try {
-            final int intValue = ((Integer)value).intValue();
-            array[index] = intValue;
-            setLength(Math.max(index + 1, length()));
-            return this;
-        } catch (final NullPointerException | ClassCastException e) {
-            if (value instanceof Short || value instanceof Byte) {
-                final int intValue = ((Number)value).intValue();
-                array[index] = intValue;
-                setLength(Math.max(index + 1, length()));
-                return this;
-            }
-
-            if (value == ScriptRuntime.UNDEFINED) {
-                return new UndefinedArrayFilter(this).set(index, value, strict);
-            }
+        if (value instanceof Integer) {
+            return set(index, ((Number)value).intValue(), strict);
+        } else if (value == ScriptRuntime.UNDEFINED) {
+            return new UndefinedArrayFilter(this).set(index, value, strict);
         }
 
         final ArrayData newData = convert(value == null ? Object.class : value.getClass());
-
         return newData.set(index, value, strict);
     }
 
--- a/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java	Tue Jul 16 09:54:04 2013 +0530
@@ -55,7 +55,9 @@
     }
 
     private static Object[] toObjectArray(final long[] array, final int length) {
-        final Object[] oarray = new Object[length];
+        assert length <= array.length : "length exceeds internal array size";
+        final Object[] oarray = new Object[array.length];
+
         for (int index = 0; index < length; index++) {
             oarray[index] = Long.valueOf(array[index]);
         }
@@ -71,9 +73,11 @@
         return super.asArrayOfType(componentType);
     }
 
-    private static double[] toDoubleArray(final long[] array) {
+    private static double[] toDoubleArray(final long[] array, final int length) {
+        assert length <= array.length : "length exceeds internal array size";
         final double[] darray = new double[array.length];
-        for (int index = 0; index < array.length; index++) {
+
+        for (int index = 0; index < length; index++) {
             darray[index] = array[index];
         }
 
@@ -84,10 +88,12 @@
     public ArrayData convert(final Class<?> type) {
         if (type == Long.class) {
             return this;
-        } else if (type == Double.class) {
-            return new NumberArrayData(LongArrayData.toDoubleArray(array), (int) length());
+        }
+        final int length = (int) length();
+        if (type == Double.class) {
+            return new NumberArrayData(LongArrayData.toDoubleArray(array, length), length);
         } else {
-            return new ObjectArrayData(LongArrayData.toObjectArray(array, array.length), (int) length());
+            return new ObjectArrayData(LongArrayData.toObjectArray(array, length), length);
         }
     }
 
@@ -138,19 +144,13 @@
 
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
-        try {
-            final long longValue = ((Long)value).longValue();
-            array[index] = longValue;
-            setLength(Math.max(index + 1, length()));
-            return this;
-        } catch (final NullPointerException | ClassCastException e) {
-            if (value == ScriptRuntime.UNDEFINED) {
-                return new UndefinedArrayFilter(this).set(index, value, strict);
-            }
+        if (value instanceof Long || value instanceof Integer) {
+            return set(index, ((Number)value).longValue(), strict);
+        } else if (value == ScriptRuntime.UNDEFINED) {
+            return new UndefinedArrayFilter(this).set(index, value, strict);
         }
 
         final ArrayData newData = convert(value == null ? Object.class : value.getClass());
-
         return newData.set(index, value, strict);
     }
 
--- a/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java	Tue Jul 16 09:54:04 2013 +0530
@@ -58,7 +58,9 @@
     }
 
     private static Object[] toObjectArray(final double[] array, final int length) {
-        final Object[] oarray = new Object[length];
+        assert length <= array.length : "length exceeds internal array size";
+        final Object[] oarray = new Object[array.length];
+
         for (int index = 0; index < length; index++) {
             oarray[index] = Double.valueOf(array[index]);
         }
@@ -76,7 +78,8 @@
     @Override
     public ArrayData convert(final Class<?> type) {
         if (type != Double.class && type != Integer.class && type != Long.class) {
-            return new ObjectArrayData(NumberArrayData.toObjectArray(array, array.length), (int) length());
+            final int length = (int) length();
+            return new ObjectArrayData(NumberArrayData.toObjectArray(array, length), length);
         }
         return this;
     }
@@ -127,16 +130,12 @@
 
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
-        try {
-            final double doubleValue = ((Number)value).doubleValue();
-            array[index] = doubleValue;
-            setLength(Math.max(index + 1, length()));
-            return this;
-        } catch (final NullPointerException | ClassCastException e) {
-            if (value == UNDEFINED) {
-                return new UndefinedArrayFilter(this).set(index, value, strict);
-            }
+        if (value instanceof Double || value instanceof Integer || value instanceof Long) {
+            return set(index, ((Number)value).doubleValue(), strict);
+        } else if (value == UNDEFINED) {
+            return new UndefinedArrayFilter(this).set(index, value, strict);
         }
+
         final ArrayData newData = convert(value == null ? Object.class : value.getClass());
         return newData.set(index, value, strict);
     }
--- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Tue Jul 16 09:54:04 2013 +0530
@@ -57,7 +57,7 @@
     static {
         final DynamicLinkerFactory factory = new DynamicLinkerFactory();
         factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(),
-                new JSObjectLinker(), new ReflectionCheckLinker());
+                new BoundDynamicMethodLinker(), new JSObjectLinker(), new ReflectionCheckLinker());
         factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker());
         factory.setSyncOnRelink(true);
         final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
@@ -208,6 +208,27 @@
     }
 
     /**
+     * Binds a bean dynamic method (returned by invoking {@code dyn:getMethod} on an object linked with
+     * {@code BeansLinker} to a receiver.
+     * @param dynamicMethod the dynamic method to bind
+     * @param boundThis the bound "this" value.
+     * @return a bound dynamic method.
+     */
+    public static Object bindDynamicMethod(Object dynamicMethod, Object boundThis) {
+        return new BoundDynamicMethod(dynamicMethod, boundThis);
+    }
+
+    /**
+     * If the given class is a reflection-specific class (anything in {@code java.lang.reflect} and
+     * {@code java.lang.invoke} package, as well a {@link Class} and any subclass of {@link ClassLoader}) and there is
+     * a security manager in the system, then it checks the {@code nashorn.JavaReflection} {@code RuntimePermission}.
+     * @param clazz the class being tested
+     */
+    public static void checkReflectionAccess(Class<?> clazz) {
+        ReflectionCheckLinker.checkReflectionAccess(clazz);
+    }
+
+    /**
      * Returns the Nashorn's internally used dynamic linker's services object. Note that in code that is processing a
      * linking request, you will normally use the {@code LinkerServices} object passed by whatever top-level linker
      * invoked the linking (if the call site is in Nashorn-generated code, you'll get this object anyway). You should
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethod.java	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime.linker;
+
+import jdk.internal.dynalink.beans.BeansLinker;
+
+/**
+ * Represents a Dynalink dynamic method bound to a receiver. Note that objects of this class are just the tuples of
+ * a method and a bound this, without any behavior. All the behavior is defined in the {@link BoundDynamicMethodLinker}.
+ */
+final class BoundDynamicMethod {
+    private final Object dynamicMethod;
+    private final Object boundThis;
+
+    BoundDynamicMethod(final Object dynamicMethod, final Object boundThis) {
+        assert BeansLinker.isDynamicMethod(dynamicMethod);
+        this.dynamicMethod = dynamicMethod;
+        this.boundThis = boundThis;
+    }
+
+    Object getDynamicMethod() {
+        return dynamicMethod;
+    }
+
+    Object getBoundThis() {
+        return boundThis;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.runtime.linker;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
+import jdk.internal.dynalink.support.Guards;
+
+/**
+ * Links {@link BoundDynamicMethod} objects. Passes through to Dynalink's BeansLinker for linking a dynamic method
+ * (they only respond to "dyn:call"), and modifies the returned invocation to deal with the receiver binding.
+ */
+final class BoundDynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
+    @Override
+    public boolean canLinkType(Class<?> type) {
+        return type == BoundDynamicMethod.class;
+    }
+
+    @Override
+    public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) throws Exception {
+        final Object objBoundDynamicMethod = linkRequest.getReceiver();
+        if(!(objBoundDynamicMethod instanceof BoundDynamicMethod)) {
+            return null;
+        }
+
+        final BoundDynamicMethod boundDynamicMethod = (BoundDynamicMethod)objBoundDynamicMethod;
+        final Object dynamicMethod = boundDynamicMethod.getDynamicMethod();
+        final Object boundThis = boundDynamicMethod.getBoundThis();
+
+        // Replace arguments (boundDynamicMethod, this, ...) => (dynamicMethod, boundThis, ...) when delegating to
+        // BeansLinker
+        final Object[] args = linkRequest.getArguments();
+        args[0] = dynamicMethod;
+        args[1] = boundThis;
+
+        // Use R(T0, T1, ...) => R(dynamicMethod.class, boundThis.class, ...) call site type when delegating to
+        // BeansLinker.
+        final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
+        final MethodType type = descriptor.getMethodType();
+        final CallSiteDescriptor newDescriptor = descriptor.changeMethodType(
+                type.changeParameterType(0, dynamicMethod.getClass()).changeParameterType(1, boundThis.getClass()));
+
+        // Delegate to BeansLinker
+        final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethod.getClass()).getGuardedInvocation(
+                linkRequest.replaceArguments(newDescriptor, args), linkerServices);
+        if(inv == null) {
+            return null;
+        }
+
+        // Bind (dynamicMethod, boundThis) to the handle
+        final MethodHandle boundHandle = MethodHandles.insertArguments(inv.getInvocation(), 0, dynamicMethod, boundThis);
+        final Class<?> p0Type = type.parameterType(0);
+        // Ignore incoming (boundDynamicMethod, this)
+        final MethodHandle droppingHandle = MethodHandles.dropArguments(boundHandle, 0, p0Type, type.parameterType(1));
+        // Identity guard on boundDynamicMethod object
+        final MethodHandle newGuard = Guards.getIdentityGuard(boundDynamicMethod);
+
+        return inv.replaceMethods(droppingHandle, newGuard.asType(newGuard.type().changeParameterType(0, p0Type)));
+    }
+}
--- a/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Tue Jul 16 09:54:04 2013 +0530
@@ -133,7 +133,7 @@
     }
 
     private static String getScriptLocation() {
-        final StackTraceElement caller = DynamicLinker.getRelinkedCallSiteLocation();
+        final StackTraceElement caller = DynamicLinker.getLinkedCallSiteLocation();
         return caller == null ? "unknown location" : (caller.getFileName() + ":" + caller.getLineNumber());
     }
 
@@ -317,7 +317,7 @@
 
         private static final MethodHandle TRACEOBJECT = findOwnMH("traceObject", Object.class, MethodHandle.class, Object[].class);
         private static final MethodHandle TRACEVOID   = findOwnMH("traceVoid", void.class, MethodHandle.class, Object[].class);
-        private static final MethodHandle TRACEMISS   = findOwnMH("traceMiss", void.class, Object[].class);
+        private static final MethodHandle TRACEMISS   = findOwnMH("traceMiss", void.class, String.class, Object[].class);
 
         TracingLinkerCallSite(final NashornCallSiteDescriptor desc) {
            super(desc);
@@ -363,7 +363,7 @@
                 return relink;
             }
             final MethodType type = relink.type();
-            return MH.foldArguments(relink, MH.asType(MH.asCollector(MH.bindTo(TRACEMISS, this), Object[].class, type.parameterCount()), type.changeReturnType(void.class)));
+            return MH.foldArguments(relink, MH.asType(MH.asCollector(MH.insertArguments(TRACEMISS, 0, this, "MISS " + getScriptLocation() + " "), Object[].class, type.parameterCount()), type.changeReturnType(void.class)));
         }
 
         private void printObject(final PrintWriter out, final Object arg) {
@@ -482,8 +482,8 @@
          * @throws Throwable if invocation failes or throws exception/error
          */
         @SuppressWarnings("unused")
-        public void traceMiss(final Object... args) throws Throwable {
-            tracePrint(Context.getCurrentErr(), "MISS ", args, null);
+        public void traceMiss(final String desc, final Object... args) throws Throwable {
+            tracePrint(Context.getCurrentErr(), desc, args, null);
         }
 
         private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
--- a/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Fri Jul 12 20:13:43 2013 +0530
+++ b/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Tue Jul 16 09:54:04 2013 +0530
@@ -40,10 +40,10 @@
 final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{
     @Override
     public boolean canLinkType(final Class<?> type) {
-        return canLinkTypeStatic(type);
+        return isReflectionClass(type);
     }
 
-    private static boolean canLinkTypeStatic(final Class<?> type) {
+    private static boolean isReflectionClass(final Class<?> type) {
         if (type == Class.class || ClassLoader.class.isAssignableFrom(type)) {
             return true;
         }
@@ -54,6 +54,19 @@
     @Override
     public GuardedInvocation getGuardedInvocation(final LinkRequest origRequest, final LinkerServices linkerServices)
             throws Exception {
+        checkLinkRequest(origRequest);
+        // let the next linker deal with actual linking
+        return null;
+    }
+
+    static void checkReflectionAccess(Class<?> clazz) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null && isReflectionClass(clazz)) {
+            checkReflectionPermission(sm);
+        }
+    }
+
+    private static void checkLinkRequest(final LinkRequest origRequest) {
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             final LinkRequest requestWithoutContext = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
@@ -61,23 +74,19 @@
             // allow 'static' access on Class objects representing public classes of non-restricted packages
             if ((self instanceof Class) && Modifier.isPublic(((Class<?>)self).getModifiers())) {
                 final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor();
-                final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
-                // check for 'get' on 'static' property
-                switch (operator) {
-                    case "getProp":
-                    case "getMethod": {
-                       if ("static".equals(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
-                           Context.checkPackageAccess(((Class)self).getName());
-                           // let bean linker do the actual linking part
-                           return null;
-                       }
+                if(CallSiteDescriptorFactory.tokenizeOperators(desc).contains("getProp")) {
+                    if ("static".equals(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
+                        Context.checkPackageAccess(((Class)self).getName());
+                        // If "getProp:static" passes package access, allow access.
+                        return;
                     }
-                    break;
-                } // fall through for all other stuff
+                }
             }
-            sm.checkPermission(new RuntimePermission("nashorn.JavaReflection"));
+            checkReflectionPermission(sm);
         }
-        // let the next linker deal with actual linking
-        return null;
+    }
+
+    private static void checkReflectionPermission(final SecurityManager sm) {
+        sm.checkPermission(new RuntimePermission("nashorn.JavaReflection"));
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020324.js	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020324: Implement Object.bindProperties(target, source) for beans
+ *
+ * @test
+ * @run
+ */
+
+var PropertyBind = Java.type("jdk.nashorn.test.models.PropertyBind")
+var bean = new PropertyBind
+
+var obj1 = {}
+Object.bindProperties(obj1, bean)
+
+printBanner("Two-way read-write instance field")
+printEval("obj1.publicInt = 13")
+printEval("bean.publicInt")
+printEval("bean.publicInt = 15")
+printEval("obj1.publicInt")
+
+printBanner("Read only public instance field")
+printEval("obj1.publicFinalInt")
+printEval("obj1.publicFinalInt = 16")
+printEval("obj1.publicFinalInt")
+printEval("bean.publicFinalInt")
+
+printBanner("Two-way read-write instance property")
+printEval("obj1.readWrite = 17")
+printEval("bean.readWrite")
+printEval("bean.readWrite = 18")
+printEval("obj1.readWrite")
+printEval("obj1.getReadWrite()")
+printEval("obj1.setReadWrite(19)")
+printEval("obj1.readWrite")
+printEval("bean.readWrite")
+
+printBanner("Read only instance property")
+printEval("obj1.readOnly")
+printEval("obj1.readOnly = 20")
+printEval("obj1.readOnly")
+printEval("obj1.getReadOnly()")
+printEval("bean.getReadOnly()")
+
+printBanner("Write only instance property")
+printEval("obj1.writeOnly = 21")
+printEval("obj1.writeOnly")
+printEval("bean.writeOnly")
+printEval("bean.peekWriteOnly()")
+
+var obj2 = {}
+Object.bindProperties(obj2, PropertyBind)
+
+printBanner("Two-way read-write public static field")
+printEval("obj2.publicStaticInt = 22")
+printEval("PropertyBind.publicStaticInt")
+printEval("PropertyBind.publicStaticInt = 23")
+printEval("obj2.publicStaticInt")
+
+printBanner("Read only public static field")
+printEval("obj2.publicStaticFinalInt")
+printEval("obj2.publicStaticFinalInt = 24")
+printEval("obj2.publicStaticFinalInt")
+printEval("PropertyBind.publicStaticFinalInt")
+
+printBanner("Two-way read-write static property")
+printEval("obj2.staticReadWrite = 25")
+printEval("PropertyBind.staticReadWrite")
+printEval("PropertyBind.staticReadWrite = 26")
+printEval("obj2.staticReadWrite")
+printEval("obj2.getStaticReadWrite()")
+printEval("obj2.setStaticReadWrite(27)")
+printEval("obj2.staticReadWrite")
+printEval("PropertyBind.staticReadWrite")
+
+printBanner("Read only static property")
+printEval("obj2.staticReadOnly")
+printEval("obj2.staticReadOnly = 28")
+printEval("obj2.staticReadOnly")
+printEval("obj2.getStaticReadOnly()")
+printEval("PropertyBind.getStaticReadOnly()")
+
+printBanner("Write only static property")
+printEval("obj2.staticWriteOnly = 29")
+printEval("obj2.staticWriteOnly")
+printEval("PropertyBind.staticWriteOnly")
+printEval("PropertyBind.peekStaticWriteOnly()")
+
+printBanner("Sanity check to ensure property values remained what they were")
+printEval("obj1.publicInt")
+printEval("bean.publicInt")
+printEval("obj1.publicFinalInt")
+printEval("bean.publicFinalInt")
+printEval("obj1.readWrite")
+printEval("bean.readWrite")
+printEval("obj1.readOnly")
+printEval("bean.readOnly")
+printEval("bean.peekWriteOnly()")
+
+printEval("obj2.publicStaticInt")
+printEval("PropertyBind.publicStaticInt")
+printEval("obj2.publicStaticFinalInt")
+printEval("PropertyBind.publicStaticFinalInt")
+printEval("obj2.staticReadWrite")
+printEval("PropertyBind.staticReadWrite")
+printEval("obj2.staticReadOnly")
+printEval("PropertyBind.staticReadOnly")
+printEval("PropertyBind.peekStaticWriteOnly()")
+
+
+function printEval(s) {
+    print(s + ": " + eval(s))
+}
+
+function printBanner(s) {
+    print()
+    print("==== " + s + " ====")
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020324.js.EXPECTED	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,90 @@
+
+==== Two-way read-write instance field ====
+obj1.publicInt = 13: 13
+bean.publicInt: 13
+bean.publicInt = 15: 15
+obj1.publicInt: 15
+
+==== Read only public instance field ====
+obj1.publicFinalInt: 42
+obj1.publicFinalInt = 16: 16
+obj1.publicFinalInt: 42
+bean.publicFinalInt: 42
+
+==== Two-way read-write instance property ====
+obj1.readWrite = 17: 17
+bean.readWrite: 17
+bean.readWrite = 18: 18
+obj1.readWrite: 18
+obj1.getReadWrite(): 18
+obj1.setReadWrite(19): null
+obj1.readWrite: 19
+bean.readWrite: 19
+
+==== Read only instance property ====
+obj1.readOnly: 123
+obj1.readOnly = 20: 20
+obj1.readOnly: 123
+obj1.getReadOnly(): 123
+bean.getReadOnly(): 123
+
+==== Write only instance property ====
+obj1.writeOnly = 21: 21
+obj1.writeOnly: undefined
+bean.writeOnly: undefined
+bean.peekWriteOnly(): 21
+
+==== Two-way read-write public static field ====
+obj2.publicStaticInt = 22: 22
+PropertyBind.publicStaticInt: 22
+PropertyBind.publicStaticInt = 23: 23
+obj2.publicStaticInt: 23
+
+==== Read only public static field ====
+obj2.publicStaticFinalInt: 2112
+obj2.publicStaticFinalInt = 24: 24
+obj2.publicStaticFinalInt: 2112
+PropertyBind.publicStaticFinalInt: 2112
+
+==== Two-way read-write static property ====
+obj2.staticReadWrite = 25: 25
+PropertyBind.staticReadWrite: 25
+PropertyBind.staticReadWrite = 26: 26
+obj2.staticReadWrite: 26
+obj2.getStaticReadWrite(): 26
+obj2.setStaticReadWrite(27): null
+obj2.staticReadWrite: 27
+PropertyBind.staticReadWrite: 27
+
+==== Read only static property ====
+obj2.staticReadOnly: 1230
+obj2.staticReadOnly = 28: 28
+obj2.staticReadOnly: 1230
+obj2.getStaticReadOnly(): 1230
+PropertyBind.getStaticReadOnly(): 1230
+
+==== Write only static property ====
+obj2.staticWriteOnly = 29: 29
+obj2.staticWriteOnly: undefined
+PropertyBind.staticWriteOnly: undefined
+PropertyBind.peekStaticWriteOnly(): 29
+
+==== Sanity check to ensure property values remained what they were ====
+obj1.publicInt: 15
+bean.publicInt: 15
+obj1.publicFinalInt: 42
+bean.publicFinalInt: 42
+obj1.readWrite: 19
+bean.readWrite: 19
+obj1.readOnly: 123
+bean.readOnly: 123
+bean.peekWriteOnly(): 21
+obj2.publicStaticInt: 23
+PropertyBind.publicStaticInt: 23
+obj2.publicStaticFinalInt: 2112
+PropertyBind.publicStaticFinalInt: 2112
+obj2.staticReadWrite: 27
+PropertyBind.staticReadWrite: 27
+obj2.staticReadOnly: 1230
+PropertyBind.staticReadOnly: 1230
+PropertyBind.peekStaticWriteOnly(): 29
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020354.js	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020354: Object literal property initialization is not done in source order
+ *
+ * @test
+ * @run
+ */
+
+
+var obj = ({a: print(1), b: print(2), a: print(3)});
+
+var obj = ({
+    a: print(1),
+    get x() { print("getting x"); return "x" },
+    set x(v) { print("setting x"); },
+    b: print(2),
+    a: print(3)
+});
+
+print(obj.x);
+obj.x = 4;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020354.js.EXPECTED	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,9 @@
+1
+2
+3
+1
+2
+3
+getting x
+x
+setting x
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020358.js	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020358: Array(0xfffffff) throws OutOfMemoryError
+ *
+ * @test
+ * @run
+ */
+
+var x = new Array(0xfffffff);
+print(x.length);
+x[0xffffffe] = 1;
+print(x.length);
+x[0xfffffff] = 1;
+print(x.length);
+
+x = new Array(0x8ffff);
+print(x.length);
+print(Function("return 'ok'").apply(null, x));
+x[0] = "pass";
+print(Function("p", "return p").apply(null, x));
+print(Function("return arguments[0]").apply(null, x));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020358.js.EXPECTED	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,7 @@
+268435455
+268435455
+268435456
+589823
+ok
+pass
+pass
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020508.js	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020508: Enforce reflection check on 
+ * Object.bindProperties(target, source) for beans
+ *
+ * @test
+ * @run
+ */
+
+var x = {}
+try {
+  Object.bindProperties(x, java.util.Vector.class)
+} catch(e) {
+  print(e)
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8020508.js.EXPECTED	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,1 @@
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "nashorn.JavaReflection")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/nashorn/test/models/PropertyBind.java	Tue Jul 16 09:54:04 2013 +0530
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.test.models;
+
+public class PropertyBind {
+    public static int publicStaticInt;
+    public static final int publicStaticFinalInt = 2112;
+
+    private static int staticReadWrite;
+    private static int staticReadOnly = 1230;
+    private static int staticWriteOnly;
+
+    public int publicInt;
+    public final int publicFinalInt = 42;
+
+    private int readWrite;
+    private int readOnly = 123;
+    private int writeOnly;
+
+    public int getReadWrite() {
+        return readWrite;
+    }
+
+    public void setReadWrite(int readWrite) {
+        this.readWrite = readWrite;
+    }
+
+    public int getReadOnly() {
+        return readOnly;
+    }
+
+    public void setWriteOnly(int writeOnly) {
+        this.writeOnly = writeOnly;
+    }
+
+    public int peekWriteOnly() {
+        return writeOnly;
+    }
+
+    public static int getStaticReadWrite() {
+        return staticReadWrite;
+    }
+
+    public static void setStaticReadWrite(int staticReadWrite) {
+        PropertyBind.staticReadWrite = staticReadWrite;
+    }
+
+    public static int getStaticReadOnly() {
+        return staticReadOnly;
+    }
+
+    public static void setStaticWriteOnly(int staticWriteOnly) {
+        PropertyBind.staticWriteOnly = staticWriteOnly;
+    }
+
+    public static int peekStaticWriteOnly() {
+        return PropertyBind.staticWriteOnly;
+    }
+}