Merge jdk8u60-b08

Wed, 18 Mar 2015 18:21:55 -0700

author
lana
date
Wed, 18 Mar 2015 18:21:55 -0700
changeset 1259
e024db176497
parent 1246
da9741520576
parent 1258
4ba23f4c0ed6
child 1260
5ec92df8ca4f
child 1265
bfea11f8c8f2

Merge

src/jdk/nashorn/internal/codegen/RuntimeCallSite.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/api/scripting/AbstractJSObject.java	Wed Mar 18 13:57:04 2015 -0700
     1.2 +++ b/src/jdk/nashorn/api/scripting/AbstractJSObject.java	Wed Mar 18 18:21:55 2015 -0700
     1.3 @@ -28,6 +28,7 @@
     1.4  import java.util.Collection;
     1.5  import java.util.Collections;
     1.6  import java.util.Set;
     1.7 +import jdk.nashorn.internal.runtime.JSType;
     1.8  
     1.9  /**
    1.10   * This is the base class for nashorn ScriptObjectMirror class.
    1.11 @@ -161,9 +162,8 @@
    1.12       * @return set of property names
    1.13       */
    1.14      @Override
    1.15 -    @SuppressWarnings("unchecked")
    1.16      public Set<String> keySet() {
    1.17 -        return Collections.EMPTY_SET;
    1.18 +        return Collections.emptySet();
    1.19      }
    1.20  
    1.21      /**
    1.22 @@ -172,9 +172,8 @@
    1.23       * @return set of property values.
    1.24       */
    1.25      @Override
    1.26 -    @SuppressWarnings("unchecked")
    1.27      public Collection<Object> values() {
    1.28 -        return Collections.EMPTY_SET;
    1.29 +        return Collections.emptySet();
    1.30      }
    1.31  
    1.32      // JavaScript instanceof check
    1.33 @@ -249,9 +248,41 @@
    1.34       * Returns this object's numeric value.
    1.35       *
    1.36       * @return this object's numeric value.
    1.37 +     * @deprecated use {@link #getDefaultValue(Class)} with {@link Number} hint instead.
    1.38       */
    1.39 -    @Override
    1.40 +    @Override @Deprecated
    1.41      public double toNumber() {
    1.42 -        return Double.NaN;
    1.43 +        return JSType.toNumber(JSType.toPrimitive(this, Number.class));
    1.44 +    }
    1.45 +
    1.46 +    /**
    1.47 +     * Implements this object's {@code [[DefaultValue]]} method. The default implementation follows ECMAScript 5.1
    1.48 +     * section 8.6.2 but subclasses are free to provide their own implementations.
    1.49 +     *
    1.50 +     * @param hint the type hint. Should be either {@code null}, {@code Number.class} or {@code String.class}.
    1.51 +     * @return this object's default value.
    1.52 +     * @throws UnsupportedOperationException if the conversion can't be performed. The engine will convert this
    1.53 +     * exception into a JavaScript {@code TypeError}.
    1.54 +     */
    1.55 +    public Object getDefaultValue(final Class<?> hint) {
    1.56 +        return DefaultValueImpl.getDefaultValue(this, hint);
    1.57 +    }
    1.58 +
    1.59 +    /**
    1.60 +     * When passed an {@link AbstractJSObject}, invokes its {@link #getDefaultValue(Class)} method. When passed any
    1.61 +     * other {@link JSObject}, it will obtain its {@code [[DefaultValue]]} method as per ECMAScript 5.1 section
    1.62 +     * 8.6.2.
    1.63 +     *
    1.64 +     * @param jsobj the {@link JSObject} whose {@code [[DefaultValue]]} is obtained.
    1.65 +     * @param hint the type hint. Should be either {@code null}, {@code Number.class} or {@code String.class}.
    1.66 +     * @return this object's default value.
    1.67 +     * @throws UnsupportedOperationException if the conversion can't be performed. The engine will convert this
    1.68 +     * exception into a JavaScript {@code TypeError}.
    1.69 +     */
    1.70 +    public static Object getDefaultValue(final JSObject jsobj, final Class<?> hint) {
    1.71 +        if (jsobj instanceof AbstractJSObject) {
    1.72 +            return ((AbstractJSObject)jsobj).getDefaultValue(hint);
    1.73 +        }
    1.74 +        return DefaultValueImpl.getDefaultValue(jsobj, hint);
    1.75      }
    1.76  }
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/jdk/nashorn/api/scripting/DefaultValueImpl.java	Wed Mar 18 18:21:55 2015 -0700
     2.3 @@ -0,0 +1,55 @@
     2.4 +/*
     2.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.  Oracle designates this
    2.11 + * particular file as subject to the "Classpath" exception as provided
    2.12 + * by Oracle in the LICENSE file that accompanied this code.
    2.13 + *
    2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.17 + * version 2 for more details (a copy is included in the LICENSE file that
    2.18 + * accompanied this code).
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License version
    2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.23 + *
    2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.25 + * or visit www.oracle.com if you need additional information or have any
    2.26 + * questions.
    2.27 + */
    2.28 +
    2.29 +package jdk.nashorn.api.scripting;
    2.30 +
    2.31 +import jdk.nashorn.internal.runtime.JSType;
    2.32 +
    2.33 +/**
    2.34 + * Default implementation of {@link JSObject#getDefaultValue(Class)}. Isolated into a separate class mostly so
    2.35 + * that we can have private static instances of function name arrays, something we couldn't declare without it
    2.36 + * being visible in {@link JSObject} interface.
    2.37 + */
    2.38 +class DefaultValueImpl {
    2.39 +    private static final String[] DEFAULT_VALUE_FNS_NUMBER = new String[] { "valueOf", "toString" };
    2.40 +    private static final String[] DEFAULT_VALUE_FNS_STRING = new String[] { "toString", "valueOf" };
    2.41 +
    2.42 +    static Object getDefaultValue(final JSObject jsobj, final Class<?> hint) throws UnsupportedOperationException {
    2.43 +        final boolean isNumber = hint == null || hint == Number.class;
    2.44 +        for(final String methodName: isNumber ? DEFAULT_VALUE_FNS_NUMBER : DEFAULT_VALUE_FNS_STRING) {
    2.45 +            final Object objMember = jsobj.getMember(methodName);
    2.46 +            if (objMember instanceof JSObject) {
    2.47 +                final JSObject member = (JSObject)objMember;
    2.48 +                if (member.isFunction()) {
    2.49 +                    final Object value = member.call(jsobj);
    2.50 +                    if (JSType.isPrimitive(value)) {
    2.51 +                        return value;
    2.52 +                    }
    2.53 +                }
    2.54 +            }
    2.55 +        }
    2.56 +        throw new UnsupportedOperationException(isNumber ? "cannot.get.default.number" : "cannot.get.default.string");
    2.57 +    }
    2.58 +}
     3.1 --- a/src/jdk/nashorn/api/scripting/JSObject.java	Wed Mar 18 13:57:04 2015 -0700
     3.2 +++ b/src/jdk/nashorn/api/scripting/JSObject.java	Wed Mar 18 18:21:55 2015 -0700
     3.3 @@ -186,6 +186,8 @@
     3.4       * Returns this object's numeric value.
     3.5       *
     3.6       * @return this object's numeric value.
     3.7 +     * @deprecated use {@link AbstractJSObject#getDefaultValue(JSObject, Class)} with {@link Number} hint instead.
     3.8       */
     3.9 +    @Deprecated
    3.10      public double toNumber();
    3.11  }
     4.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Wed Mar 18 13:57:04 2015 -0700
     4.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Wed Mar 18 18:21:55 2015 -0700
     4.3 @@ -46,6 +46,7 @@
     4.4  import jdk.nashorn.internal.objects.Global;
     4.5  import jdk.nashorn.internal.runtime.ConsString;
     4.6  import jdk.nashorn.internal.runtime.Context;
     4.7 +import jdk.nashorn.internal.runtime.ECMAException;
     4.8  import jdk.nashorn.internal.runtime.JSType;
     4.9  import jdk.nashorn.internal.runtime.ScriptFunction;
    4.10  import jdk.nashorn.internal.runtime.ScriptObject;
    4.11 @@ -812,7 +813,7 @@
    4.12          }
    4.13      }
    4.14  
    4.15 -    @Override
    4.16 +    @Override @Deprecated
    4.17      public double toNumber() {
    4.18          return inGlobal(new Callable<Double>() {
    4.19              @Override public Double call() {
    4.20 @@ -820,4 +821,21 @@
    4.21              }
    4.22          });
    4.23      }
    4.24 +
    4.25 +    @Override
    4.26 +    public Object getDefaultValue(final Class<?> hint) {
    4.27 +        return inGlobal(new Callable<Object>() {
    4.28 +            @Override public Object call() {
    4.29 +                try {
    4.30 +                    return sobj.getDefaultValue(hint);
    4.31 +                } catch (final ECMAException e) {
    4.32 +                    // We're catching ECMAException (likely TypeError), and translating it to
    4.33 +                    // UnsupportedOperationException. This in turn will be translated into TypeError of the
    4.34 +                    // caller's Global by JSType#toPrimitive(JSObject,Class) therefore ensuring that it's
    4.35 +                    // recognized as "instanceof TypeError" in the caller.
    4.36 +                    throw new UnsupportedOperationException(e.getMessage(), e);
    4.37 +                }
    4.38 +            }
    4.39 +        });
    4.40 +    }
    4.41  }
     5.1 --- a/src/jdk/nashorn/internal/codegen/BranchOptimizer.java	Wed Mar 18 13:57:04 2015 -0700
     5.2 +++ b/src/jdk/nashorn/internal/codegen/BranchOptimizer.java	Wed Mar 18 18:21:55 2015 -0700
     5.3 @@ -105,33 +105,33 @@
     5.4  
     5.5          case EQ:
     5.6          case EQ_STRICT:
     5.7 -            codegen.loadBinaryOperands(binaryNode);
     5.8 +            codegen.loadComparisonOperands(binaryNode);
     5.9              method.conditionalJump(state ? EQ : NE, true, label);
    5.10              return;
    5.11  
    5.12          case NE:
    5.13          case NE_STRICT:
    5.14 -            codegen.loadBinaryOperands(binaryNode);
    5.15 +            codegen.loadComparisonOperands(binaryNode);
    5.16              method.conditionalJump(state ? NE : EQ, true, label);
    5.17              return;
    5.18  
    5.19          case GE:
    5.20 -            codegen.loadBinaryOperands(binaryNode);
    5.21 +            codegen.loadComparisonOperands(binaryNode);
    5.22              method.conditionalJump(state ? GE : LT, false, label);
    5.23              return;
    5.24  
    5.25          case GT:
    5.26 -            codegen.loadBinaryOperands(binaryNode);
    5.27 +            codegen.loadComparisonOperands(binaryNode);
    5.28              method.conditionalJump(state ? GT : LE, false, label);
    5.29              return;
    5.30  
    5.31          case LE:
    5.32 -            codegen.loadBinaryOperands(binaryNode);
    5.33 +            codegen.loadComparisonOperands(binaryNode);
    5.34              method.conditionalJump(state ? LE : GT, true, label);
    5.35              return;
    5.36  
    5.37          case LT:
    5.38 -            codegen.loadBinaryOperands(binaryNode);
    5.39 +            codegen.loadComparisonOperands(binaryNode);
    5.40              method.conditionalJump(state ? LT : GE, true, label);
    5.41              return;
    5.42  
     6.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Mar 18 13:57:04 2015 -0700
     6.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Mar 18 18:21:55 2015 -0700
     6.3 @@ -202,6 +202,12 @@
     6.4      private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
     6.5              "create", ScriptFunction.class, Object[].class, int.class);
     6.6  
     6.7 +    private static final Call TO_NUMBER_FOR_EQ = CompilerConstants.staticCallNoLookup(JSType.class,
     6.8 +            "toNumberForEq", double.class, Object.class);
     6.9 +    private static final Call TO_NUMBER_FOR_STRICT_EQ = CompilerConstants.staticCallNoLookup(JSType.class,
    6.10 +            "toNumberForStrictEq", double.class, Object.class);
    6.11 +
    6.12 +
    6.13      private static final Class<?> ITERATOR_CLASS = Iterator.class;
    6.14      static {
    6.15          assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type();
    6.16 @@ -618,6 +624,104 @@
    6.17          return method;
    6.18      }
    6.19  
    6.20 +    /**
    6.21 +     * Similar to {@link #loadBinaryOperands(BinaryNode)} but used specifically for loading operands of
    6.22 +     * relational and equality comparison operators where at least one argument is non-object. (When both
    6.23 +     * arguments are objects, we use {@link ScriptRuntime#EQ(Object, Object)}, {@link ScriptRuntime#LT(Object, Object)}
    6.24 +     * etc. methods instead. Additionally, {@code ScriptRuntime} methods are used for strict (in)equality comparison
    6.25 +     * of a boolean to anything that isn't a boolean.) This method handles the special case where one argument
    6.26 +     * is an object and another is a primitive. Naively, these could also be delegated to {@code ScriptRuntime} methods
    6.27 +     * by boxing the primitive. However, in all such cases the comparison is performed on numeric values, so it is
    6.28 +     * possible to strength-reduce the operation by taking the number value of the object argument instead and
    6.29 +     * comparing that to the primitive value ("primitive" will always be int, long, double, or boolean, and booleans
    6.30 +     * compare as ints in these cases, so they're essentially numbers too). This method will emit code for loading
    6.31 +     * arguments for such strength-reduced comparison. When both arguments are primitives, it just delegates to
    6.32 +     * {@link #loadBinaryOperands(BinaryNode)}.
    6.33 +     *
    6.34 +     * @param cmp the comparison operation for which the operands need to be loaded on stack.
    6.35 +     * @return the current method emitter.
    6.36 +     */
    6.37 +    MethodEmitter loadComparisonOperands(final BinaryNode cmp) {
    6.38 +        final Expression lhs = cmp.lhs();
    6.39 +        final Expression rhs = cmp.rhs();
    6.40 +        final Type lhsType = lhs.getType();
    6.41 +        final Type rhsType = rhs.getType();
    6.42 +
    6.43 +        // Only used when not both are object, for that we have ScriptRuntime.LT etc.
    6.44 +        assert !(lhsType.isObject() && rhsType.isObject());
    6.45 +
    6.46 +        if (lhsType.isObject() || rhsType.isObject()) {
    6.47 +            // We can reorder CONVERT LEFT and LOAD RIGHT only if either the left is a primitive, or the right
    6.48 +            // is a local. This is more strict than loadBinaryNode reorder criteria, as it can allow JS primitive
    6.49 +            // types too (notably: String is a JS primitive, but not a JVM primitive). We disallow String otherwise
    6.50 +            // we would prematurely convert it to number when comparing to an optimistic expression, e.g. in
    6.51 +            // "Hello" === String("Hello") the RHS starts out as an optimistic-int function call. If we allowed
    6.52 +            // reordering, we'd end up with ToNumber("Hello") === {I%}String("Hello") that is obviously incorrect.
    6.53 +            final boolean canReorder = lhsType.isPrimitive() || rhs.isLocal();
    6.54 +            // If reordering is allowed, and we're using a relational operator (that is, <, <=, >, >=) and not an
    6.55 +            // (in)equality operator, then we encourage combining of LOAD and CONVERT into a single operation.
    6.56 +            // This is because relational operators' semantics prescribes vanilla ToNumber() conversion, while
    6.57 +            // (in)equality operators need the specialized JSType.toNumberFor[Strict]Equals. E.g. in the code snippet
    6.58 +            // "i < obj.size" (where i is primitive and obj.size is statically an object), ".size" will thus be allowed
    6.59 +            // to compile as:
    6.60 +            //   invokedynamic dyn:getProp|getElem|getMethod:size(Object;)D
    6.61 +            // instead of the more costly:
    6.62 +            //   invokedynamic dyn:getProp|getElem|getMethod:size(Object;)Object
    6.63 +            //   invokestatic JSType.toNumber(Object)D
    6.64 +            // Note also that even if this is allowed, we're only using it on operands that are non-optimistic, as
    6.65 +            // otherwise the logic for determining effective optimistic-ness would turn an optimistic double return
    6.66 +            // into a freely coercible one, which would be wrong.
    6.67 +            final boolean canCombineLoadAndConvert = canReorder && cmp.isRelational();
    6.68 +
    6.69 +            // LOAD LEFT
    6.70 +            loadExpression(lhs, canCombineLoadAndConvert && !lhs.isOptimistic() ? TypeBounds.NUMBER : TypeBounds.UNBOUNDED);
    6.71 +
    6.72 +            final Type lhsLoadedType = method.peekType();
    6.73 +            final TokenType tt = cmp.tokenType();
    6.74 +            if (canReorder) {
    6.75 +                // Can reorder CONVERT LEFT and LOAD RIGHT
    6.76 +                emitObjectToNumberComparisonConversion(method, tt);
    6.77 +                loadExpression(rhs, canCombineLoadAndConvert && !rhs.isOptimistic() ? TypeBounds.NUMBER : TypeBounds.UNBOUNDED);
    6.78 +            } else {
    6.79 +                // Can't reorder CONVERT LEFT and LOAD RIGHT
    6.80 +                loadExpression(rhs, TypeBounds.UNBOUNDED);
    6.81 +                if (lhsLoadedType != Type.NUMBER) {
    6.82 +                    method.swap();
    6.83 +                    emitObjectToNumberComparisonConversion(method, tt);
    6.84 +                    method.swap();
    6.85 +                }
    6.86 +            }
    6.87 +
    6.88 +            // CONVERT RIGHT
    6.89 +            emitObjectToNumberComparisonConversion(method, tt);
    6.90 +            return method;
    6.91 +        }
    6.92 +        // For primitive operands, just don't do anything special.
    6.93 +        return loadBinaryOperands(cmp);
    6.94 +    }
    6.95 +
    6.96 +    private static void emitObjectToNumberComparisonConversion(final MethodEmitter method, final TokenType tt) {
    6.97 +        switch(tt) {
    6.98 +        case EQ:
    6.99 +        case NE:
   6.100 +            if (method.peekType().isObject()) {
   6.101 +                TO_NUMBER_FOR_EQ.invoke(method);
   6.102 +                return;
   6.103 +            }
   6.104 +            break;
   6.105 +        case EQ_STRICT:
   6.106 +        case NE_STRICT:
   6.107 +            if (method.peekType().isObject()) {
   6.108 +                TO_NUMBER_FOR_STRICT_EQ.invoke(method);
   6.109 +                return;
   6.110 +            }
   6.111 +            break;
   6.112 +        default:
   6.113 +            break;
   6.114 +        }
   6.115 +        method.convert(Type.NUMBER);
   6.116 +    }
   6.117 +
   6.118      private static final Type undefinedToNumber(final Type type) {
   6.119          return type == Type.UNDEFINED ? Type.NUMBER : type;
   6.120      }
   6.121 @@ -628,6 +732,7 @@
   6.122  
   6.123          static final TypeBounds UNBOUNDED = new TypeBounds(Type.UNKNOWN, Type.OBJECT);
   6.124          static final TypeBounds INT = exact(Type.INT);
   6.125 +        static final TypeBounds NUMBER = exact(Type.NUMBER);
   6.126          static final TypeBounds OBJECT = exact(Type.OBJECT);
   6.127          static final TypeBounds BOOLEAN = exact(Type.BOOLEAN);
   6.128  
   6.129 @@ -731,7 +836,7 @@
   6.130           */
   6.131          final CodeGenerator codegen = this;
   6.132  
   6.133 -        final Node currentDiscard = codegen.lc.getCurrentDiscard();
   6.134 +        final boolean isCurrentDiscard = codegen.lc.isCurrentDiscard(expr);
   6.135          expr.accept(new NodeOperatorVisitor<LexicalContext>(new LexicalContext()) {
   6.136              @Override
   6.137              public boolean enterIdentNode(final IdentNode identNode) {
   6.138 @@ -1087,7 +1192,7 @@
   6.139  
   6.140              @Override
   6.141              public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression joinExpr) {
   6.142 -                loadExpression(joinExpr.getExpression(), resultBounds);
   6.143 +                loadMaybeDiscard(joinExpr, joinExpr.getExpression(), resultBounds);
   6.144                  return false;
   6.145              }
   6.146  
   6.147 @@ -1104,7 +1209,7 @@
   6.148                  throw new AssertionError(otherNode.getClass().getName());
   6.149              }
   6.150          });
   6.151 -        if(currentDiscard != expr) {
   6.152 +        if(!isCurrentDiscard) {
   6.153              coerceStackTop(resultBounds);
   6.154          }
   6.155          return method;
   6.156 @@ -2756,25 +2861,18 @@
   6.157              newRuntimeNode = runtimeNode;
   6.158          }
   6.159  
   6.160 -        new OptimisticOperation(newRuntimeNode, TypeBounds.UNBOUNDED) {
   6.161 -            @Override
   6.162 -            void loadStack() {
   6.163 -                for (final Expression arg : args) {
   6.164 -                    loadExpression(arg, TypeBounds.OBJECT);
   6.165 -                }
   6.166 -            }
   6.167 -            @Override
   6.168 -            void consumeStack() {
   6.169 -                method.invokestatic(
   6.170 -                        CompilerConstants.className(ScriptRuntime.class),
   6.171 -                        newRuntimeNode.getRequest().toString(),
   6.172 -                        new FunctionSignature(
   6.173 -                            false,
   6.174 -                            false,
   6.175 -                            newRuntimeNode.getType(),
   6.176 -                            args.size()).toString());
   6.177 -            }
   6.178 -        }.emit();
   6.179 +        for (final Expression arg : args) {
   6.180 +            loadExpression(arg, TypeBounds.OBJECT);
   6.181 +        }
   6.182 +
   6.183 +        method.invokestatic(
   6.184 +                CompilerConstants.className(ScriptRuntime.class),
   6.185 +                newRuntimeNode.getRequest().toString(),
   6.186 +                new FunctionSignature(
   6.187 +                    false,
   6.188 +                    false,
   6.189 +                    newRuntimeNode.getType(),
   6.190 +                    args.size()).toString());
   6.191  
   6.192          method.convert(newRuntimeNode.getType());
   6.193      }
   6.194 @@ -3550,7 +3648,7 @@
   6.195          // TODO: move checks for discarding to actual expression load code (e.g. as we do with void). That way we might
   6.196          // be able to eliminate even more checks.
   6.197          if(expr instanceof PrimitiveLiteralNode | isLocalVariable(expr)) {
   6.198 -            assert lc.getCurrentDiscard() != expr;
   6.199 +            assert !lc.isCurrentDiscard(expr);
   6.200              // Don't bother evaluating expressions without side effects. Typical usage is "void 0" for reliably generating
   6.201              // undefined.
   6.202              return;
   6.203 @@ -3558,11 +3656,37 @@
   6.204  
   6.205          lc.pushDiscard(expr);
   6.206          loadExpression(expr, TypeBounds.UNBOUNDED);
   6.207 -        if (lc.getCurrentDiscard() == expr) {
   6.208 +        if (lc.popDiscardIfCurrent(expr)) {
   6.209              assert !expr.isAssignment();
   6.210              // NOTE: if we had a way to load with type void, we could avoid popping
   6.211              method.pop();
   6.212 -            lc.popDiscard();
   6.213 +        }
   6.214 +    }
   6.215 +
   6.216 +    /**
   6.217 +     * Loads the expression with the specified type bounds, but if the parent expression is the current discard,
   6.218 +     * then instead loads and discards the expression.
   6.219 +     * @param parent the parent expression that's tested for being the current discard
   6.220 +     * @param expr the expression that's either normally loaded or discard-loaded
   6.221 +     * @param resultBounds result bounds for when loading the expression normally
   6.222 +     */
   6.223 +    private void loadMaybeDiscard(final Expression parent, final Expression expr, final TypeBounds resultBounds) {
   6.224 +        loadMaybeDiscard(lc.popDiscardIfCurrent(parent), expr, resultBounds);
   6.225 +    }
   6.226 +
   6.227 +    /**
   6.228 +     * Loads the expression with the specified type bounds, or loads and discards the expression, depending on the
   6.229 +     * value of the discard flag. Useful as a helper for expressions with control flow where you often can't combine
   6.230 +     * testing for being the current discard and loading the subexpressions.
   6.231 +     * @param discard if true, the expression is loaded and discarded
   6.232 +     * @param expr the expression that's either normally loaded or discard-loaded
   6.233 +     * @param resultBounds result bounds for when loading the expression normally
   6.234 +     */
   6.235 +    private void loadMaybeDiscard(final boolean discard, final Expression expr, final TypeBounds resultBounds) {
   6.236 +        if (discard) {
   6.237 +            loadAndDiscard(expr);
   6.238 +        } else {
   6.239 +            loadExpression(expr, resultBounds);
   6.240          }
   6.241      }
   6.242  
   6.243 @@ -3619,9 +3743,7 @@
   6.244  
   6.245      public void loadVOID(final UnaryNode unaryNode, final TypeBounds resultBounds) {
   6.246          loadAndDiscard(unaryNode.getExpression());
   6.247 -        if(lc.getCurrentDiscard() == unaryNode) {
   6.248 -            lc.popDiscard();
   6.249 -        } else {
   6.250 +        if (!lc.popDiscardIfCurrent(unaryNode)) {
   6.251              method.loadUndefined(resultBounds.widest);
   6.252          }
   6.253      }
   6.254 @@ -3654,16 +3776,23 @@
   6.255      private void loadAND_OR(final BinaryNode binaryNode, final TypeBounds resultBounds, final boolean isAnd) {
   6.256          final Type narrowestOperandType = Type.widestReturnType(binaryNode.lhs().getType(), binaryNode.rhs().getType());
   6.257  
   6.258 +        final boolean isCurrentDiscard = lc.popDiscardIfCurrent(binaryNode);
   6.259 +
   6.260          final Label skip = new Label("skip");
   6.261          if(narrowestOperandType == Type.BOOLEAN) {
   6.262              // optimize all-boolean logical expressions
   6.263              final Label onTrue = new Label("andor_true");
   6.264              emitBranch(binaryNode, onTrue, true);
   6.265 -            method.load(false);
   6.266 -            method._goto(skip);
   6.267 -            method.label(onTrue);
   6.268 -            method.load(true);
   6.269 -            method.label(skip);
   6.270 +            if (isCurrentDiscard) {
   6.271 +                method.label(onTrue);
   6.272 +                method.pop();
   6.273 +            } else {
   6.274 +                method.load(false);
   6.275 +                method._goto(skip);
   6.276 +                method.label(onTrue);
   6.277 +                method.load(true);
   6.278 +                method.label(skip);
   6.279 +            }
   6.280              return;
   6.281          }
   6.282  
   6.283 @@ -3672,7 +3801,11 @@
   6.284          final boolean lhsConvert = LocalVariableConversion.hasLiveConversion(lhs);
   6.285          final Label evalRhs = lhsConvert ? new Label("eval_rhs") : null;
   6.286  
   6.287 -        loadExpression(lhs, outBounds).dup().convert(Type.BOOLEAN);
   6.288 +        loadExpression(lhs, outBounds);
   6.289 +        if (!isCurrentDiscard) {
   6.290 +            method.dup();
   6.291 +        }
   6.292 +        method.convert(Type.BOOLEAN);
   6.293          if (isAnd) {
   6.294              if(lhsConvert) {
   6.295                  method.ifne(evalRhs);
   6.296 @@ -3691,9 +3824,11 @@
   6.297              method.label(evalRhs);
   6.298          }
   6.299  
   6.300 -        method.pop();
   6.301 +        if (!isCurrentDiscard) {
   6.302 +            method.pop();
   6.303 +        }
   6.304          final JoinPredecessorExpression rhs = (JoinPredecessorExpression)binaryNode.rhs();
   6.305 -        loadExpression(rhs, outBounds);
   6.306 +        loadMaybeDiscard(isCurrentDiscard, rhs, outBounds);
   6.307          method.beforeJoinPoint(rhs);
   6.308          method.label(skip);
   6.309      }
   6.310 @@ -3715,9 +3850,8 @@
   6.311          // Detect dead assignments
   6.312          if(lhs instanceof IdentNode) {
   6.313              final Symbol symbol = ((IdentNode)lhs).getSymbol();
   6.314 -            if(!symbol.isScope() && !symbol.hasSlotFor(rhsType) && lc.getCurrentDiscard() == binaryNode) {
   6.315 +            if(!symbol.isScope() && !symbol.hasSlotFor(rhsType) && lc.popDiscardIfCurrent(binaryNode)) {
   6.316                  loadAndDiscard(rhs);
   6.317 -                lc.popDiscard();
   6.318                  method.markDeadLocalVariable(symbol);
   6.319                  return;
   6.320              }
   6.321 @@ -3971,11 +4105,11 @@
   6.322  
   6.323      private void loadCOMMARIGHT(final BinaryNode binaryNode, final TypeBounds resultBounds) {
   6.324          loadAndDiscard(binaryNode.lhs());
   6.325 -        loadExpression(binaryNode.rhs(), resultBounds);
   6.326 +        loadMaybeDiscard(binaryNode, binaryNode.rhs(), resultBounds);
   6.327      }
   6.328  
   6.329      private void loadCOMMALEFT(final BinaryNode binaryNode, final TypeBounds resultBounds) {
   6.330 -        loadExpression(binaryNode.lhs(), resultBounds);
   6.331 +        loadMaybeDiscard(binaryNode, binaryNode.lhs(), resultBounds);
   6.332          loadAndDiscard(binaryNode.rhs());
   6.333      }
   6.334  
   6.335 @@ -3989,8 +4123,7 @@
   6.336      }
   6.337  
   6.338      private void loadCmp(final BinaryNode binaryNode, final Condition cond) {
   6.339 -        assert comparisonOperandsArePrimitive(binaryNode) : binaryNode;
   6.340 -        loadBinaryOperands(binaryNode);
   6.341 +        loadComparisonOperands(binaryNode);
   6.342  
   6.343          final Label trueLabel  = new Label("trueLabel");
   6.344          final Label afterLabel = new Label("skip");
   6.345 @@ -4004,11 +4137,6 @@
   6.346          method.label(afterLabel);
   6.347      }
   6.348  
   6.349 -    private static boolean comparisonOperandsArePrimitive(final BinaryNode binaryNode) {
   6.350 -        final Type widest = Type.widest(binaryNode.lhs().getType(), binaryNode.rhs().getType());
   6.351 -        return widest.isNumeric() || widest.isBoolean();
   6.352 -    }
   6.353 -
   6.354      private void loadMOD(final BinaryNode binaryNode, final TypeBounds resultBounds) {
   6.355          new BinaryArith() {
   6.356              @Override
   6.357 @@ -4081,13 +4209,14 @@
   6.358  
   6.359          emitBranch(test, falseLabel, false);
   6.360  
   6.361 -        loadExpression(trueExpr.getExpression(), outBounds);
   6.362 -        assert Type.generic(method.peekType()) == outBounds.narrowest;
   6.363 +        final boolean isCurrentDiscard = lc.popDiscardIfCurrent(ternaryNode);
   6.364 +        loadMaybeDiscard(isCurrentDiscard, trueExpr.getExpression(), outBounds);
   6.365 +        assert isCurrentDiscard || Type.generic(method.peekType()) == outBounds.narrowest;
   6.366          method.beforeJoinPoint(trueExpr);
   6.367          method._goto(exitLabel);
   6.368          method.label(falseLabel);
   6.369 -        loadExpression(falseExpr.getExpression(), outBounds);
   6.370 -        assert Type.generic(method.peekType()) == outBounds.narrowest;
   6.371 +        loadMaybeDiscard(isCurrentDiscard, falseExpr.getExpression(), outBounds);
   6.372 +        assert isCurrentDiscard || Type.generic(method.peekType()) == outBounds.narrowest;
   6.373          method.beforeJoinPoint(falseExpr);
   6.374          method.label(exitLabel);
   6.375      }
   6.376 @@ -4273,9 +4402,8 @@
   6.377  
   6.378          // store the result that "lives on" after the op, e.g. "i" in i++ postfix.
   6.379          protected void storeNonDiscard() {
   6.380 -            if (lc.getCurrentDiscard() == assignNode) {
   6.381 +            if (lc.popDiscardIfCurrent(assignNode)) {
   6.382                  assert assignNode.isAssignment();
   6.383 -                lc.popDiscard();
   6.384                  return;
   6.385              }
   6.386  
     7.1 --- a/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java	Wed Mar 18 13:57:04 2015 -0700
     7.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java	Wed Mar 18 18:21:55 2015 -0700
     7.3 @@ -34,6 +34,7 @@
     7.4  import jdk.nashorn.internal.IntDeque;
     7.5  import jdk.nashorn.internal.codegen.types.Type;
     7.6  import jdk.nashorn.internal.ir.Block;
     7.7 +import jdk.nashorn.internal.ir.Expression;
     7.8  import jdk.nashorn.internal.ir.FunctionNode;
     7.9  import jdk.nashorn.internal.ir.LexicalContext;
    7.10  import jdk.nashorn.internal.ir.LexicalContextNode;
    7.11 @@ -59,9 +60,11 @@
    7.12      /** Method emitter stack - every time we start a sub method (e.g. a split) we push one */
    7.13      private final Deque<MethodEmitter> methodEmitters = new ArrayDeque<>();
    7.14  
    7.15 -    /** The discard stack - whenever we enter a discard node we keep track of its return value status -
    7.16 -     *  i.e. should we keep it or throw it away */
    7.17 -    private final Deque<Node> discard = new ArrayDeque<>();
    7.18 +    /** The discard stack - whenever we evaluate an expression that will be discarded, we push it on this stack. Various
    7.19 +     * implementations of expression code emitter can choose to emit code that'll discard the expression themselves, or
    7.20 +     * ignore it in which case CodeGenerator.loadAndDiscard() will explicitly emit a pop instruction. */
    7.21 +    private final Deque<Expression> discard = new ArrayDeque<>();
    7.22 +
    7.23  
    7.24      private final Deque<Map<String, Collection<Label>>> unwarrantedOptimismHandlers = new ArrayDeque<>();
    7.25      private final Deque<StringBuilder> slotTypesDescriptors = new ArrayDeque<>();
    7.26 @@ -270,16 +273,20 @@
    7.27          }
    7.28      }
    7.29  
    7.30 -    void pushDiscard(final Node node) {
    7.31 -        discard.push(node);
    7.32 +    void pushDiscard(final Expression expr) {
    7.33 +        discard.push(expr);
    7.34      }
    7.35  
    7.36 -    Node popDiscard() {
    7.37 -        return discard.pop();
    7.38 +    boolean popDiscardIfCurrent(final Expression expr) {
    7.39 +        if (isCurrentDiscard(expr)) {
    7.40 +            discard.pop();
    7.41 +            return true;
    7.42 +        }
    7.43 +        return false;
    7.44      }
    7.45  
    7.46 -    Node getCurrentDiscard() {
    7.47 -        return discard.peek();
    7.48 +    boolean isCurrentDiscard(final Expression expr) {
    7.49 +        return discard.peek() == expr;
    7.50      }
    7.51  
    7.52      int quickSlot(final Type type) {
     8.1 --- a/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Wed Mar 18 13:57:04 2015 -0700
     8.2 +++ b/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Wed Mar 18 18:21:55 2015 -0700
     8.3 @@ -32,7 +32,6 @@
     8.4  import java.util.Iterator;
     8.5  import java.util.Map;
     8.6  import java.util.Set;
     8.7 -import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
     8.8  import jdk.nashorn.internal.ir.Block;
     8.9  import jdk.nashorn.internal.ir.FunctionNode;
    8.10  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
    8.11 @@ -208,7 +207,7 @@
    8.12          final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData(
    8.13                  newFunctionNode,
    8.14                  compiler.getCodeInstaller(),
    8.15 -                new AllocatorDescriptor(newFunctionNode.getThisProperties()),
    8.16 +                ObjectClassGenerator.createAllocationStrategy(newFunctionNode.getThisProperties()),
    8.17                  nestedFunctions,
    8.18                  externalSymbolDepths.get(fnId),
    8.19                  internalSymbols.get(fnId),
     9.1 --- a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Wed Mar 18 13:57:04 2015 -0700
     9.2 +++ b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Wed Mar 18 18:21:55 2015 -0700
     9.3 @@ -206,7 +206,6 @@
     9.4          // continuations (since RewriteException's byteCodeSlots carries an array and not a name-value map).
     9.5  
     9.6          symbolIsConverted(symbol, branchLvarType, targetType);
     9.7 -        //symbolIsUsed(symbol, branchLvarType);
     9.8          return new LocalVariableConversion(symbol, branchLvarType.type, targetType.type, next);
     9.9      }
    9.10  
    9.11 @@ -229,7 +228,7 @@
    9.12              for(final Symbol symbol: commonSymbols) {
    9.13                  final LvarType type1 = types1.get(symbol);
    9.14                  final LvarType type2 = types2.get(symbol);
    9.15 -                final LvarType widest = widestLvarType(type1,  type2);
    9.16 +                final LvarType widest = widestLvarType(type1, type2);
    9.17                  if(widest != type1 && matches1) {
    9.18                      matches1 = false;
    9.19                      if(!matches2) {
    9.20 @@ -242,7 +241,7 @@
    9.21                          union = cloneMap(types2);
    9.22                      }
    9.23                  }
    9.24 -                if(!(matches1 || matches2) && union != null) { //remove overly enthusiastic "union can be null" warning
    9.25 +                if(!(matches1 || matches2)) {
    9.26                      assert union != null;
    9.27                      union.put(symbol, widest);
    9.28                  }
    9.29 @@ -711,8 +710,13 @@
    9.30  
    9.31      @Override
    9.32      public boolean enterIfNode(final IfNode ifNode) {
    9.33 +        processIfNode(ifNode);
    9.34 +        return false;
    9.35 +    }
    9.36 +
    9.37 +    private void processIfNode(final IfNode ifNode) {
    9.38          if(!reachable) {
    9.39 -            return false;
    9.40 +            return;
    9.41          }
    9.42  
    9.43          final Expression test = ifNode.getTest();
    9.44 @@ -721,48 +725,48 @@
    9.45  
    9.46          visitExpressionOnEmptyStack(test);
    9.47  
    9.48 -        final Map<Symbol, LvarType> afterTestLvarTypes = localVariableTypes;
    9.49 -        if(!isAlwaysFalse(test)) {
    9.50 +        final Map<Symbol, LvarType> passLvarTypes;
    9.51 +        final boolean reachableFromPass;
    9.52 +        final boolean isTestAlwaysTrue = isAlwaysTrue(test);
    9.53 +        if(isAlwaysFalse(test)) {
    9.54 +            passLvarTypes = null;
    9.55 +            reachableFromPass = false;
    9.56 +        } else {
    9.57 +            final Map<Symbol, LvarType> afterTestLvarTypes = localVariableTypes;
    9.58              pass.accept(this);
    9.59              assertTypeStackIsEmpty();
    9.60 +            if (isTestAlwaysTrue) {
    9.61 +                return;
    9.62 +            }
    9.63 +            passLvarTypes = localVariableTypes;
    9.64 +            reachableFromPass = reachable;
    9.65 +            localVariableTypes = afterTestLvarTypes;
    9.66 +            reachable = true;
    9.67          }
    9.68 -        final Map<Symbol, LvarType> passLvarTypes = localVariableTypes;
    9.69 -        final boolean reachableFromPass = reachable;
    9.70  
    9.71 -        reachable = true;
    9.72 -        localVariableTypes = afterTestLvarTypes;
    9.73 -        if(!isAlwaysTrue(test) && fail != null) {
    9.74 +        // If we get here, then we need to consider the case where pass block is not executed
    9.75 +        assert !isTestAlwaysTrue;
    9.76 +
    9.77 +        if (fail != null) {
    9.78              fail.accept(this);
    9.79              assertTypeStackIsEmpty();
    9.80 -            final boolean reachableFromFail = reachable;
    9.81 -            reachable |= reachableFromPass;
    9.82 -            if(!reachable) {
    9.83 -                return false;
    9.84 -            }
    9.85 -
    9.86 -            if(reachableFromFail) {
    9.87 -                if(reachableFromPass) {
    9.88 -                    final Map<Symbol, LvarType> failLvarTypes = localVariableTypes;
    9.89 -                    localVariableTypes = getUnionTypes(passLvarTypes, failLvarTypes);
    9.90 -                    setConversion(pass, passLvarTypes, localVariableTypes);
    9.91 -                    setConversion(fail, failLvarTypes, localVariableTypes);
    9.92 -                }
    9.93 -                return false;
    9.94 -            }
    9.95          }
    9.96  
    9.97 -        if(reachableFromPass) {
    9.98 -            localVariableTypes = getUnionTypes(afterTestLvarTypes, passLvarTypes);
    9.99 -            // IfNode itself is associated with conversions that might need to be performed after the test if there's no
   9.100 -            // else branch. E.g.
   9.101 -            // if(x = 1, cond) { x = 1.0 } must widen "x = 1" to a double.
   9.102 -            setConversion(pass, passLvarTypes, localVariableTypes);
   9.103 -            setConversion(ifNode, afterTestLvarTypes, localVariableTypes);
   9.104 -        } else {
   9.105 -            localVariableTypes = afterTestLvarTypes;
   9.106 +        if(reachable) {
   9.107 +            if(reachableFromPass) {
   9.108 +                final Map<Symbol, LvarType> failLvarTypes = localVariableTypes;
   9.109 +                localVariableTypes = getUnionTypes(passLvarTypes, failLvarTypes);
   9.110 +                setConversion(pass, passLvarTypes, localVariableTypes);
   9.111 +                // IfNode itself is associated with conversions that might need to be performed after the test if
   9.112 +                // there's no else branch. E.g.
   9.113 +                // if(x = 1, cond) { x = 1.0 } must widen "x = 1" to a double.
   9.114 +                setConversion(fail != null ? fail : ifNode, failLvarTypes, localVariableTypes);
   9.115 +            }
   9.116 +        } else if (reachableFromPass) {
   9.117 +            assert passLvarTypes != null;
   9.118 +            localVariableTypes = passLvarTypes;
   9.119 +            reachable = true;
   9.120          }
   9.121 -
   9.122 -        return false;
   9.123      }
   9.124  
   9.125      @Override
   9.126 @@ -1359,8 +1363,6 @@
   9.127                      final Expression lhs = binaryNode.lhs();
   9.128                      final Expression rhs = binaryNode.rhs();
   9.129  
   9.130 -                    Type cmpWidest = Type.widest(lhs.getType(), rhs.getType());
   9.131 -                    boolean newRuntimeNode = false, finalized = false;
   9.132                      final TokenType tt = binaryNode.tokenType();
   9.133                      switch (tt) {
   9.134                      case EQ_STRICT:
   9.135 @@ -1373,14 +1375,12 @@
   9.136                          }
   9.137                          // Specialize comparison of boolean with non-boolean
   9.138                          if (lhs.getType().isBoolean() != rhs.getType().isBoolean()) {
   9.139 -                            newRuntimeNode = true;
   9.140 -                            cmpWidest = Type.OBJECT;
   9.141 -                            finalized = true;
   9.142 +                            return new RuntimeNode(binaryNode);
   9.143                          }
   9.144                          // fallthrough
   9.145                      default:
   9.146 -                        if (newRuntimeNode || cmpWidest.isObject()) {
   9.147 -                            return new RuntimeNode(binaryNode).setIsFinal(finalized);
   9.148 +                        if (lhs.getType().isObject() && rhs.getType().isObject()) {
   9.149 +                            return new RuntimeNode(binaryNode);
   9.150                          }
   9.151                      }
   9.152                  } else if(binaryNode.isOptimisticUndecidedType()) {
    10.1 --- a/src/jdk/nashorn/internal/codegen/MapCreator.java	Wed Mar 18 13:57:04 2015 -0700
    10.2 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java	Wed Mar 18 18:21:55 2015 -0700
    10.3 @@ -100,15 +100,16 @@
    10.4          for (final MapTuple<T> tuple : tuples) {
    10.5              final String key    = tuple.key;
    10.6              final Symbol symbol = tuple.symbol;
    10.7 +            final Class<?> initialType = tuple.getValueType();
    10.8  
    10.9 -            //TODO initial type is object here no matter what. Is that right?
   10.10              if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) {
   10.11                  final int flags = getPropertyFlags(symbol, hasArguments, false);
   10.12                  properties.add(
   10.13                          new SpillProperty(
   10.14                                  key,
   10.15                                  flags,
   10.16 -                                spillIndex++));
   10.17 +                                spillIndex++,
   10.18 +                                initialType));
   10.19              }
   10.20          }
   10.21  
    11.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Wed Mar 18 13:57:04 2015 -0700
    11.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Wed Mar 18 18:21:55 2015 -0700
    11.3 @@ -94,7 +94,6 @@
    11.4  import jdk.nashorn.internal.ir.JoinPredecessor;
    11.5  import jdk.nashorn.internal.ir.LiteralNode;
    11.6  import jdk.nashorn.internal.ir.LocalVariableConversion;
    11.7 -import jdk.nashorn.internal.ir.RuntimeNode;
    11.8  import jdk.nashorn.internal.ir.Symbol;
    11.9  import jdk.nashorn.internal.ir.TryNode;
   11.10  import jdk.nashorn.internal.objects.Global;
   11.11 @@ -175,9 +174,6 @@
   11.12      /** Bootstrap for normal indy:s */
   11.13      private static final Handle LINKERBOOTSTRAP  = new Handle(H_INVOKESTATIC, Bootstrap.BOOTSTRAP.className(), Bootstrap.BOOTSTRAP.name(), Bootstrap.BOOTSTRAP.descriptor());
   11.14  
   11.15 -    /** Bootstrap for runtime node indy:s */
   11.16 -    private static final Handle RUNTIMEBOOTSTRAP = new Handle(H_INVOKESTATIC, RuntimeCallSite.BOOTSTRAP.className(), RuntimeCallSite.BOOTSTRAP.name(), RuntimeCallSite.BOOTSTRAP.descriptor());
   11.17 -
   11.18      /** Bootstrap for array populators */
   11.19      private static final Handle POPULATE_ARRAY_BOOTSTRAP = new Handle(H_INVOKESTATIC, RewriteException.BOOTSTRAP.className(), RewriteException.BOOTSTRAP.name(), RewriteException.BOOTSTRAP.descriptor());
   11.20  
   11.21 @@ -2189,25 +2185,6 @@
   11.22      }
   11.23  
   11.24      /**
   11.25 -     * Generate a dynamic call for a runtime node
   11.26 -     *
   11.27 -     * @param name       tag for the invoke dynamic for this runtime node
   11.28 -     * @param returnType return type
   11.29 -     * @param request    RuntimeNode request
   11.30 -     *
   11.31 -     * @return the method emitter
   11.32 -     */
   11.33 -    MethodEmitter dynamicRuntimeCall(final String name, final Type returnType, final RuntimeNode.Request request) {
   11.34 -        debug("dynamic_runtime_call", name, "args=", request.getArity(), "returnType=", returnType);
   11.35 -        final String signature = getDynamicSignature(returnType, request.getArity());
   11.36 -        debug("   signature", signature);
   11.37 -        method.visitInvokeDynamicInsn(name, signature, RUNTIMEBOOTSTRAP);
   11.38 -        pushType(returnType);
   11.39 -
   11.40 -        return this;
   11.41 -    }
   11.42 -
   11.43 -    /**
   11.44       * Generate dynamic getter. Pop scope from stack. Push result
   11.45       *
   11.46       * @param valueType type of the value to set
    12.1 --- a/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Wed Mar 18 13:57:04 2015 -0700
    12.2 +++ b/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Wed Mar 18 18:21:55 2015 -0700
    12.3 @@ -56,6 +56,7 @@
    12.4  import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
    12.5  import jdk.nashorn.internal.codegen.types.Type;
    12.6  import jdk.nashorn.internal.runtime.AccessorProperty;
    12.7 +import jdk.nashorn.internal.runtime.AllocationStrategy;
    12.8  import jdk.nashorn.internal.runtime.Context;
    12.9  import jdk.nashorn.internal.runtime.FunctionScope;
   12.10  import jdk.nashorn.internal.runtime.JSType;
   12.11 @@ -826,44 +827,13 @@
   12.12      }
   12.13  
   12.14      /**
   12.15 -     * Describes the allocator class name and property map for a constructor function with the specified
   12.16 +     * Creates the allocator class name and property map for a constructor function with the specified
   12.17       * number of "this" properties that it initializes.
   12.18 -     *
   12.19 +     * @param thisProperties number of properties assigned to "this"
   12.20 +     * @return the allocation strategy
   12.21       */
   12.22 -    public static class AllocatorDescriptor {
   12.23 -        private final String allocatorClassName;
   12.24 -        private final PropertyMap allocatorMap;
   12.25 -
   12.26 -        /**
   12.27 -         * Creates a new allocator descriptor
   12.28 -         * @param thisProperties the number of "this" properties that the function initializes
   12.29 -         */
   12.30 -        public AllocatorDescriptor(final int thisProperties) {
   12.31 -            final int paddedFieldCount = getPaddedFieldCount(thisProperties);
   12.32 -            this.allocatorClassName = Compiler.binaryName(getClassName(paddedFieldCount));
   12.33 -            this.allocatorMap = PropertyMap.newMap(null, allocatorClassName, 0, paddedFieldCount, 0);
   12.34 -        }
   12.35 -
   12.36 -        /**
   12.37 -         * Returns the name of the class that the function allocates
   12.38 -         * @return the name of the class that the function allocates
   12.39 -         */
   12.40 -        public String getAllocatorClassName() {
   12.41 -            return allocatorClassName;
   12.42 -        }
   12.43 -
   12.44 -        /**
   12.45 -         * Returns the allocator map for the function.
   12.46 -         * @return the allocator map for the function.
   12.47 -         */
   12.48 -        public PropertyMap getAllocatorMap() {
   12.49 -            return allocatorMap;
   12.50 -        }
   12.51 -
   12.52 -        @Override
   12.53 -        public String toString() {
   12.54 -            return "AllocatorDescriptor[allocatorClassName=" + allocatorClassName + ", allocatorMap.size=" +
   12.55 -                    allocatorMap.size() + "]";
   12.56 -        }
   12.57 +    static AllocationStrategy createAllocationStrategy(final int thisProperties) {
   12.58 +        final int paddedFieldCount = getPaddedFieldCount(thisProperties);
   12.59 +        return new AllocationStrategy(paddedFieldCount);
   12.60      }
   12.61  }
    13.1 --- a/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java	Wed Mar 18 13:57:04 2015 -0700
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,683 +0,0 @@
    13.4 -/*
    13.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    13.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 - *
    13.8 - * This code is free software; you can redistribute it and/or modify it
    13.9 - * under the terms of the GNU General Public License version 2 only, as
   13.10 - * published by the Free Software Foundation.  Oracle designates this
   13.11 - * particular file as subject to the "Classpath" exception as provided
   13.12 - * by Oracle in the LICENSE file that accompanied this code.
   13.13 - *
   13.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 - * version 2 for more details (a copy is included in the LICENSE file that
   13.18 - * accompanied this code).
   13.19 - *
   13.20 - * You should have received a copy of the GNU General Public License version
   13.21 - * 2 along with this work; if not, write to the Free Software Foundation,
   13.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 - *
   13.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.25 - * or visit www.oracle.com if you need additional information or have any
   13.26 - * questions.
   13.27 - */
   13.28 -
   13.29 -package jdk.nashorn.internal.codegen;
   13.30 -
   13.31 -import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
   13.32 -import static jdk.nashorn.internal.codegen.types.Type.BOOLEAN;
   13.33 -import static jdk.nashorn.internal.codegen.types.Type.INT;
   13.34 -import static jdk.nashorn.internal.lookup.Lookup.MH;
   13.35 -
   13.36 -import java.lang.invoke.CallSite;
   13.37 -import java.lang.invoke.MethodHandle;
   13.38 -import java.lang.invoke.MethodHandles;
   13.39 -import java.lang.invoke.MethodType;
   13.40 -import java.lang.invoke.MutableCallSite;
   13.41 -import java.util.HashMap;
   13.42 -import java.util.Map;
   13.43 -import jdk.nashorn.internal.codegen.CompilerConstants.Call;
   13.44 -import jdk.nashorn.internal.codegen.types.Type;
   13.45 -import jdk.nashorn.internal.ir.RuntimeNode;
   13.46 -import jdk.nashorn.internal.ir.RuntimeNode.Request;
   13.47 -import jdk.nashorn.internal.lookup.Lookup;
   13.48 -import jdk.nashorn.internal.runtime.ScriptRuntime;
   13.49 -import jdk.nashorn.internal.runtime.linker.Bootstrap;
   13.50 -
   13.51 -/**
   13.52 - * Optimistic call site that assumes its Object arguments to be of a boxed type.
   13.53 - * Gradually reverts to wider boxed types if the assumption for the RuntimeNode
   13.54 - * is proven wrong. Finally reverts to the generic ScriptRuntime method.
   13.55 - *
   13.56 - * This is used from the CodeGenerator when we have a runtime node, but 1 or more
   13.57 - * primitive arguments. This class generated appropriate specializations, for example
   13.58 - * {@code Object a === int b} is a good idea to specialize to {@code ((Integer)a).intValue() == b}
   13.59 - * surrounded by catch blocks that will try less narrow specializations
   13.60 - */
   13.61 -public final class RuntimeCallSite extends MutableCallSite {
   13.62 -    static final Call BOOTSTRAP = staticCallNoLookup(Bootstrap.class, "runtimeBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
   13.63 -
   13.64 -    private static final MethodHandle NEXT = findOwnMH_V("next",  MethodHandle.class, String.class);
   13.65 -
   13.66 -    private final RuntimeNode.Request request;
   13.67 -
   13.68 -    /**
   13.69 -     * A specialized runtime node, i.e. on where we know at least one more specific type than object
   13.70 -     */
   13.71 -    static final class SpecializedRuntimeNode {
   13.72 -        private static final char REQUEST_SEPARATOR = ':';
   13.73 -
   13.74 -        private final RuntimeNode.Request request;
   13.75 -
   13.76 -        private final Type[] parameterTypes;
   13.77 -
   13.78 -        private final Type   returnType;
   13.79 -
   13.80 -        /**
   13.81 -         * Constructor.
   13.82 -         *
   13.83 -         * @param request        runtime node request to specialize
   13.84 -         * @param parameterTypes parameter types of the call site
   13.85 -         * @param returnType     return type of the call site
   13.86 -         */
   13.87 -        SpecializedRuntimeNode(final RuntimeNode.Request request, final Type[] parameterTypes, final Type returnType) {
   13.88 -            this.request        = request;
   13.89 -            this.parameterTypes = parameterTypes;
   13.90 -            this.returnType     = returnType;
   13.91 -        }
   13.92 -
   13.93 -        /**
   13.94 -         * The first type to try to use for this generated runtime node
   13.95 -         *
   13.96 -         * @return a type
   13.97 -         */
   13.98 -        public Type firstTypeGuess() {
   13.99 -            Type widest = Type.UNKNOWN;
  13.100 -            for (final Type type : parameterTypes) {
  13.101 -                if (type.isObject()) {
  13.102 -                    continue;
  13.103 -                }
  13.104 -                widest = Type.widest(type, widest);
  13.105 -            }
  13.106 -            widest = Type.widest(widest, firstTypeGuessForObject(request));
  13.107 -
  13.108 -            return widest;
  13.109 -        }
  13.110 -
  13.111 -        private static Type firstTypeGuessForObject(final Request request) {
  13.112 -            switch (request) {
  13.113 -            case ADD:
  13.114 -                return INT;
  13.115 -            default:
  13.116 -                return BOOLEAN;
  13.117 -            }
  13.118 -        }
  13.119 -
  13.120 -        Request getRequest() {
  13.121 -            return request;
  13.122 -        }
  13.123 -
  13.124 -        Type[] getParameterTypes() {
  13.125 -            return parameterTypes;
  13.126 -        }
  13.127 -
  13.128 -        Type getReturnType() {
  13.129 -            return returnType;
  13.130 -        }
  13.131 -
  13.132 -        private static char descFor(final Type type) {
  13.133 -            if (type.isObject()) {
  13.134 -                return 'O';
  13.135 -            }
  13.136 -            return type.getDescriptor().charAt(0);
  13.137 -        }
  13.138 -
  13.139 -        @Override
  13.140 -        public boolean equals(final Object other) {
  13.141 -            if (other instanceof SpecializedRuntimeNode) {
  13.142 -                final SpecializedRuntimeNode otherNode = (SpecializedRuntimeNode)other;
  13.143 -
  13.144 -                if (!otherNode.getReturnType().equals(getReturnType())) {
  13.145 -                    return false;
  13.146 -                }
  13.147 -
  13.148 -                if (getParameterTypes().length != otherNode.getParameterTypes().length) {
  13.149 -                    return false;
  13.150 -                }
  13.151 -
  13.152 -                for (int i = 0; i < getParameterTypes().length; i++) {
  13.153 -                    if (!Type.areEquivalent(getParameterTypes()[i], otherNode.getParameterTypes()[i])) {
  13.154 -                        return false;
  13.155 -                    }
  13.156 -                }
  13.157 -
  13.158 -                return otherNode.getRequest().equals(getRequest());
  13.159 -            }
  13.160 -
  13.161 -            return false;
  13.162 -        }
  13.163 -
  13.164 -        @Override
  13.165 -        public int hashCode() {
  13.166 -            int hashCode = getRequest().toString().hashCode();
  13.167 -            hashCode ^= getReturnType().hashCode();
  13.168 -            for (final Type type : getParameterTypes()) {
  13.169 -                hashCode ^= type.hashCode();
  13.170 -            }
  13.171 -            return hashCode;
  13.172 -        }
  13.173 -
  13.174 -        @Override
  13.175 -        public String toString() {
  13.176 -            final StringBuilder sb = new StringBuilder();
  13.177 -            sb.append(getRequest().toString());
  13.178 -            sb.append(REQUEST_SEPARATOR);
  13.179 -            sb.append(descFor(getReturnType()));
  13.180 -
  13.181 -            for (final Type type : getParameterTypes()) {
  13.182 -                sb.append(descFor(type));
  13.183 -            }
  13.184 -
  13.185 -            return sb.toString();
  13.186 -        }
  13.187 -
  13.188 -        String getName(final Type extraType) {
  13.189 -            return toString() + "_" + descFor(extraType);
  13.190 -        }
  13.191 -
  13.192 -        String getInitialName() {
  13.193 -            return getName(firstTypeGuess());
  13.194 -        }
  13.195 -    }
  13.196 -
  13.197 -
  13.198 -    /**
  13.199 -     * Constructor
  13.200 -     *
  13.201 -     * @param type method type for call site
  13.202 -     * @param name name of runtime call
  13.203 -     */
  13.204 -    public RuntimeCallSite(final MethodType type, final String name) {
  13.205 -        super(type);
  13.206 -        this.request = Request.valueOf(name.substring(0, name.indexOf(SpecializedRuntimeNode.REQUEST_SEPARATOR)));
  13.207 -        setTarget(makeMethod(name));
  13.208 -    }
  13.209 -
  13.210 -    private String nextName(final String requestName) {
  13.211 -        if (requestName.equals(request.toString())) {
  13.212 -            return null;
  13.213 -        }
  13.214 -
  13.215 -        final char[] c = requestName.toCharArray();
  13.216 -        final int last = c.length - 1;
  13.217 -
  13.218 -        if (c[last - 1] != '_') {
  13.219 -            return null;
  13.220 -        }
  13.221 -
  13.222 -        switch (c[last]) {
  13.223 -        case 'Z':
  13.224 -            c[last] = 'I';
  13.225 -            break;
  13.226 -        case 'I':
  13.227 -            c[last] = 'J';
  13.228 -            break;
  13.229 -        case 'J':
  13.230 -            c[last] = 'D';
  13.231 -            break;
  13.232 -        case 'D':
  13.233 -        default:
  13.234 -            return request.toString();
  13.235 -        }
  13.236 -
  13.237 -        return new String(c);
  13.238 -    }
  13.239 -
  13.240 -    private boolean isSpecialized(final String requestName) {
  13.241 -        return nextName(requestName) != null;
  13.242 -    }
  13.243 -
  13.244 -    private MethodHandle makeMethod(final String requestName) {
  13.245 -        MethodHandle mh;
  13.246 -
  13.247 -        if (isSpecialized(requestName)) {
  13.248 -            final Class<?> boxedType;
  13.249 -            final Class<?> primitiveType;
  13.250 -
  13.251 -            switch (requestName.charAt(requestName.length() - 1)) {
  13.252 -            case 'Z':
  13.253 -                boxedType = Boolean.class;
  13.254 -                primitiveType = int.class;
  13.255 -                break;
  13.256 -            case 'I':
  13.257 -                boxedType = Integer.class;
  13.258 -                primitiveType = int.class;
  13.259 -                break;
  13.260 -            case 'J':
  13.261 -                boxedType = Long.class;
  13.262 -                primitiveType = long.class;
  13.263 -                break;
  13.264 -            case 'D':
  13.265 -                boxedType = Number.class;
  13.266 -                primitiveType = double.class;
  13.267 -                break;
  13.268 -            default:
  13.269 -                throw new RuntimeException("should not reach here");
  13.270 -            }
  13.271 -
  13.272 -            final boolean isStrictCmp = (request == Request.EQ_STRICT || request == Request.NE_STRICT);
  13.273 -
  13.274 -            if (isStrictCmp &&
  13.275 -                    (boxedType != Boolean.class &&
  13.276 -                        (type().parameterType(0) == boolean.class ||
  13.277 -                         type().parameterType(1) == boolean.class))) {
  13.278 -                // number and boolean are never strictly equal, e.g. 0 !== false
  13.279 -                mh = MH.dropArguments(MH.constant(boolean.class, request == Request.NE_STRICT), 0, type().parameterArray());
  13.280 -            } else {
  13.281 -                mh = METHODS.get(request.nonStrictName() + primitiveType.getSimpleName());
  13.282 -                // unbox objects
  13.283 -
  13.284 -                for (int i = 0; i < type().parameterCount(); i++) {
  13.285 -                    if (!type().parameterType(i).isPrimitive()) {
  13.286 -                        mh = MH.filterArguments(mh, i, UNBOX.get(boxedType));
  13.287 -                    }
  13.288 -                }
  13.289 -
  13.290 -                mh = Lookup.filterReturnType(mh, type().returnType());
  13.291 -                mh = MH.explicitCastArguments(mh, type());
  13.292 -            }
  13.293 -
  13.294 -            final MethodHandle fallback = MH.foldArguments(MethodHandles.exactInvoker(type()), MH.insertArguments(NEXT, 0, this, requestName));
  13.295 -
  13.296 -            MethodHandle guard;
  13.297 -            if (type().parameterType(0).isPrimitive()) {
  13.298 -                guard = MH.insertArguments(
  13.299 -                            MH.dropArguments(CHECKCAST, 1, type().parameterType(0)), 0, boxedType);
  13.300 -            } else if (type().parameterType(1).isPrimitive()) {
  13.301 -                guard = MH.insertArguments(
  13.302 -                            MH.dropArguments(CHECKCAST, 2, type().parameterType(1)), 0, boxedType);
  13.303 -            } else {
  13.304 -                assert !type().parameterType(0).isPrimitive() && !type().parameterType(1).isPrimitive();
  13.305 -                guard = MH.insertArguments(CHECKCAST2, 0, boxedType);
  13.306 -            }
  13.307 -
  13.308 -            if (request == Request.ADD && boxedType == Integer.class) {
  13.309 -                // int add needs additional overflow check
  13.310 -                MethodHandle addcheck = ADDCHECK;
  13.311 -                for (int i = 0; i < type().parameterCount(); i++) {
  13.312 -                    if (!type().parameterType(i).isPrimitive()) {
  13.313 -                        addcheck = MH.filterArguments(addcheck, i, UNBOX.get(boxedType));
  13.314 -                    }
  13.315 -                }
  13.316 -                addcheck = MH.explicitCastArguments(addcheck, type().changeReturnType(boolean.class));
  13.317 -                guard    = MH.guardWithTest(upcastGuard(guard), addcheck,
  13.318 -                                MH.dropArguments(MH.constant(boolean.class, false), 0, type().parameterArray()));
  13.319 -            }
  13.320 -
  13.321 -            return MH.guardWithTest(upcastGuard(guard), mh, fallback);
  13.322 -        }
  13.323 -
  13.324 -        // generic fallback
  13.325 -        return MH.explicitCastArguments(Lookup.filterReturnType(GENERIC_METHODS.get(request.name()), type().returnType()), type());
  13.326 -    }
  13.327 -
  13.328 -    private MethodHandle upcastGuard(final MethodHandle guard) {
  13.329 -        return MH.asType(guard, type().changeReturnType(boolean.class));
  13.330 -    }
  13.331 -
  13.332 -    /**
  13.333 -     * This is public just so that the generated specialization code can
  13.334 -     * use it to get the next wider typed method
  13.335 -     *
  13.336 -     * Do not call directly
  13.337 -     *
  13.338 -     * @param name current name (with type) of runtime call at the call site
  13.339 -     * @return next wider specialization method for this RuntimeCallSite
  13.340 -     */
  13.341 -   public MethodHandle next(final String name) {
  13.342 -        final MethodHandle next = makeMethod(nextName(name));
  13.343 -        setTarget(next);
  13.344 -        return next;
  13.345 -    }
  13.346 -
  13.347 -    /** Method cache */
  13.348 -    private static final Map<String, MethodHandle> METHODS;
  13.349 -
  13.350 -    /** Generic method cache */
  13.351 -    private static final Map<String, MethodHandle> GENERIC_METHODS;
  13.352 -
  13.353 -    /** Unbox cache */
  13.354 -    private static final Map<Class<?>, MethodHandle> UNBOX;
  13.355 -
  13.356 -    private static final MethodHandle CHECKCAST  = findOwnMH_S("checkcast", boolean.class, Class.class, Object.class);
  13.357 -    private static final MethodHandle CHECKCAST2 = findOwnMH_S("checkcast", boolean.class, Class.class, Object.class, Object.class);
  13.358 -    private static final MethodHandle ADDCHECK   = findOwnMH_S("ADDcheck",  boolean.class, int.class, int.class);
  13.359 -
  13.360 -    /**
  13.361 -     * Build maps of correct boxing operations
  13.362 -     */
  13.363 -    static {
  13.364 -        UNBOX = new HashMap<>();
  13.365 -        UNBOX.put(Boolean.class, findOwnMH_S("unboxZ", int.class, Object.class));
  13.366 -        UNBOX.put(Integer.class, findOwnMH_S("unboxI", int.class, Object.class));
  13.367 -        UNBOX.put(Long.class,    findOwnMH_S("unboxJ", long.class, Object.class));
  13.368 -        UNBOX.put(Number.class,  findOwnMH_S("unboxD", double.class, Object.class));
  13.369 -
  13.370 -        METHODS = new HashMap<>();
  13.371 -
  13.372 -        for (final Request req : Request.values()) {
  13.373 -            if (req.canSpecialize()) {
  13.374 -                if (req.name().endsWith("_STRICT")) {
  13.375 -                    continue;
  13.376 -                }
  13.377 -
  13.378 -                final boolean isCmp = Request.isComparison(req);
  13.379 -
  13.380 -                METHODS.put(req.name() + "int",    findOwnMH_S(req.name(), (isCmp ? boolean.class : int.class),  int.class, int.class));
  13.381 -                METHODS.put(req.name() + "long",   findOwnMH_S(req.name(), (isCmp ? boolean.class : long.class), long.class, long.class));
  13.382 -                METHODS.put(req.name() + "double", findOwnMH_S(req.name(), (isCmp ? boolean.class : double.class), double.class, double.class));
  13.383 -            }
  13.384 -        }
  13.385 -
  13.386 -        GENERIC_METHODS = new HashMap<>();
  13.387 -        for (final Request req : Request.values()) {
  13.388 -            if (req.canSpecialize()) {
  13.389 -                GENERIC_METHODS.put(req.name(), MH.findStatic(MethodHandles.lookup(), ScriptRuntime.class, req.name(),
  13.390 -                        MH.type(req.getReturnType().getTypeClass(), Object.class, Object.class)));
  13.391 -            }
  13.392 -        }
  13.393 -    }
  13.394 -
  13.395 -    /**
  13.396 -     * Specialized version of != operator for two int arguments. Do not call directly.
  13.397 -     * @param a int
  13.398 -     * @param b int
  13.399 -     * @return a != b
  13.400 -     */
  13.401 -    public static boolean NE(final int a, final int b) {
  13.402 -        return a != b;
  13.403 -    }
  13.404 -
  13.405 -    /**
  13.406 -     * Specialized version of != operator for two double arguments. Do not call directly.
  13.407 -     * @param a double
  13.408 -     * @param b double
  13.409 -     * @return a != b
  13.410 -     */
  13.411 -    public static boolean NE(final double a, final double b) {
  13.412 -        return a != b;
  13.413 -    }
  13.414 -
  13.415 -    /**
  13.416 -     * Specialized version of != operator for two long arguments. Do not call directly.
  13.417 -     * @param a long
  13.418 -     * @param b long
  13.419 -     * @return a != b
  13.420 -     */
  13.421 -    public static boolean NE(final long a, final long b) {
  13.422 -        return a != b;
  13.423 -    }
  13.424 -
  13.425 -    /**
  13.426 -     * Specialized version of == operator for two int arguments. Do not call directly.
  13.427 -     * @param a int
  13.428 -     * @param b int
  13.429 -     * @return a == b
  13.430 -     */
  13.431 -    public static boolean EQ(final int a, final int b) {
  13.432 -        return a == b;
  13.433 -    }
  13.434 -
  13.435 -    /**
  13.436 -     * Specialized version of == operator for two double arguments. Do not call directly.
  13.437 -     * @param a double
  13.438 -     * @param b double
  13.439 -     * @return a == b
  13.440 -     */
  13.441 -    public static boolean EQ(final double a, final double b) {
  13.442 -        return a == b;
  13.443 -    }
  13.444 -
  13.445 -    /**
  13.446 -     * Specialized version of == operator for two long arguments. Do not call directly.
  13.447 -     * @param a long
  13.448 -     * @param b long
  13.449 -     * @return a == b
  13.450 -     */
  13.451 -    public static boolean EQ(final long a, final long b) {
  13.452 -        return a == b;
  13.453 -    }
  13.454 -
  13.455 -    /**
  13.456 -     * Specialized version of {@literal <} operator for two int arguments. Do not call directly.
  13.457 -     * @param a int
  13.458 -     * @param b int
  13.459 -     * @return a {@code <} b
  13.460 -     */
  13.461 -    public static boolean LT(final int a, final int b) {
  13.462 -        return a < b;
  13.463 -    }
  13.464 -
  13.465 -    /**
  13.466 -     * Specialized version of {@literal <} operator for two double arguments. Do not call directly.
  13.467 -     * @param a double
  13.468 -     * @param b double
  13.469 -     * @return a {@literal <} b
  13.470 -     */
  13.471 -    public static boolean LT(final double a, final double b) {
  13.472 -        return a < b;
  13.473 -    }
  13.474 -
  13.475 -    /**
  13.476 -     * Specialized version of {@literal <} operator for two long arguments. Do not call directly.
  13.477 -     * @param a long
  13.478 -     * @param b long
  13.479 -     * @return a {@literal <} b
  13.480 -     */
  13.481 -    public static boolean LT(final long a, final long b) {
  13.482 -        return a < b;
  13.483 -    }
  13.484 -
  13.485 -    /**
  13.486 -     * Specialized version of {@literal <=} operator for two int arguments. Do not call directly.
  13.487 -     * @param a int
  13.488 -     * @param b int
  13.489 -     * @return a {@literal <=} b
  13.490 -     */
  13.491 -    public static boolean LE(final int a, final int b) {
  13.492 -        return a <= b;
  13.493 -    }
  13.494 -
  13.495 -    /**
  13.496 -     * Specialized version of {@literal <=} operator for two double arguments. Do not call directly.
  13.497 -     * @param a double
  13.498 -     * @param b double
  13.499 -     * @return a {@literal <=} b
  13.500 -     */
  13.501 -    public static boolean LE(final double a, final double b) {
  13.502 -        return a <= b;
  13.503 -    }
  13.504 -
  13.505 -    /**
  13.506 -     * Specialized version of {@literal <=} operator for two long arguments. Do not call directly.
  13.507 -     * @param a long
  13.508 -     * @param b long
  13.509 -     * @return a {@literal <=} b
  13.510 -     */
  13.511 -    public static boolean LE(final long a, final long b) {
  13.512 -        return a <= b;
  13.513 -    }
  13.514 -
  13.515 -    /**
  13.516 -     * Specialized version of {@literal >} operator for two int arguments. Do not call directly.
  13.517 -     * @param a int
  13.518 -     * @param b int
  13.519 -     * @return a {@literal >} b
  13.520 -     */
  13.521 -    public static boolean GT(final int a, final int b) {
  13.522 -        return a > b;
  13.523 -    }
  13.524 -
  13.525 -    /**
  13.526 -     * Specialized version of {@literal >} operator for two double arguments. Do not call directly.
  13.527 -     * @param a double
  13.528 -     * @param b double
  13.529 -     * @return a {@literal >} b
  13.530 -     */
  13.531 -    public static boolean GT(final double a, final double b) {
  13.532 -        return a > b;
  13.533 -    }
  13.534 -
  13.535 -    /**
  13.536 -     * Specialized version of {@literal >} operator for two long arguments. Do not call directly.
  13.537 -     * @param a long
  13.538 -     * @param b long
  13.539 -     * @return a {@literal >} b
  13.540 -     */
  13.541 -    public static boolean GT(final long a, final long b) {
  13.542 -        return a > b;
  13.543 -    }
  13.544 -
  13.545 -    /**
  13.546 -     * Specialized version of {@literal >=} operator for two int arguments. Do not call directly.
  13.547 -     * @param a int
  13.548 -     * @param b int
  13.549 -     * @return a {@literal >=} b
  13.550 -     */
  13.551 -    public static boolean GE(final int a, final int b) {
  13.552 -        return a >= b;
  13.553 -    }
  13.554 -
  13.555 -    /**
  13.556 -     * Specialized version of {@literal >=} operator for two double arguments. Do not call directly.
  13.557 -     * @param a double
  13.558 -     * @param b double
  13.559 -     * @return a {@literal >=} b
  13.560 -     */
  13.561 -    public static boolean GE(final double a, final double b) {
  13.562 -        return a >= b;
  13.563 -    }
  13.564 -
  13.565 -    /**
  13.566 -     * Specialized version of {@literal >=} operator for two long arguments. Do not call directly.
  13.567 -     * @param a long
  13.568 -     * @param b long
  13.569 -     * @return a {@code >=} b
  13.570 -     */
  13.571 -    public static boolean GE(final long a, final long b) {
  13.572 -        return a >= b;
  13.573 -    }
  13.574 -
  13.575 -    /**
  13.576 -     * Specialized version of + operator for two int arguments. Do not call directly.
  13.577 -     * @param a int
  13.578 -     * @param b int
  13.579 -     * @return a + b
  13.580 -     */
  13.581 -    public static int ADD(final int a, final int b) {
  13.582 -        return a + b;
  13.583 -    }
  13.584 -
  13.585 -    /**
  13.586 -     * Specialized version of + operator for two long arguments. Do not call directly.
  13.587 -     * @param a long
  13.588 -     * @param b long
  13.589 -     * @return a + b
  13.590 -     */
  13.591 -    public static long ADD(final long a, final long b) {
  13.592 -        return a + b;
  13.593 -    }
  13.594 -
  13.595 -    /**
  13.596 -     * Specialized version of + operator for two double arguments. Do not call directly.
  13.597 -     * @param a double
  13.598 -     * @param b double
  13.599 -     * @return a + b
  13.600 -     */
  13.601 -    public static double ADD(final double a, final double b) {
  13.602 -        return a + b;
  13.603 -    }
  13.604 -
  13.605 -    /**
  13.606 -     * Check that ints are addition compatible, i.e. their sum is equal to the sum
  13.607 -     * of them cast to long. Otherwise the addition will overflow. Do not call directly.
  13.608 -     *
  13.609 -     * @param a int
  13.610 -     * @param b int
  13.611 -     *
  13.612 -     * @return true if addition does not overflow
  13.613 -     */
  13.614 -    public static boolean ADDcheck(final int a, final int b) {
  13.615 -        return (a + b == (long)a + (long)b);
  13.616 -    }
  13.617 -
  13.618 -    /**
  13.619 -     * Checkcast used for specialized ops. Do not call directly
  13.620 -     *
  13.621 -     * @param type to to check against
  13.622 -     * @param obj  object to check for type
  13.623 -     *
  13.624 -     * @return true if type check holds
  13.625 -     */
  13.626 -    public static boolean checkcast(final Class<?> type, final Object obj) {
  13.627 -        return type.isInstance(obj);
  13.628 -    }
  13.629 -
  13.630 -    /**
  13.631 -     * Checkcast used for specialized ops. Do not call directly
  13.632 -     *
  13.633 -     * @param type type to check against
  13.634 -     * @param objA first object to check against type
  13.635 -     * @param objB second object to check against type
  13.636 -     *
  13.637 -     * @return true if type check holds for both objects
  13.638 -     */
  13.639 -    public static boolean checkcast(final Class<?> type, final Object objA, final Object objB) {
  13.640 -        return type.isInstance(objA) && type.isInstance(objB);
  13.641 -    }
  13.642 -
  13.643 -    /**
  13.644 -     * Unbox a java.lang.Boolean. Do not call directly
  13.645 -     * @param obj object to cast to int and unbox
  13.646 -     * @return an int value for the boolean, 1 is true, 0 is false
  13.647 -     */
  13.648 -    public static int unboxZ(final Object obj) {
  13.649 -        return (boolean)obj ? 1 : 0;
  13.650 -    }
  13.651 -
  13.652 -    /**
  13.653 -     * Unbox a java.lang.Integer. Do not call directly
  13.654 -     * @param obj object to cast to int and unbox
  13.655 -     * @return an int
  13.656 -     */
  13.657 -    public static int unboxI(final Object obj) {
  13.658 -        return (int)obj;
  13.659 -    }
  13.660 -
  13.661 -    /**
  13.662 -     * Unbox a java.lang.Long. Do not call directly
  13.663 -     * @param obj object to cast to long and unbox
  13.664 -     * @return a long
  13.665 -     */
  13.666 -    public static long unboxJ(final Object obj) {
  13.667 -        return (long)obj;
  13.668 -    }
  13.669 -
  13.670 -    /**
  13.671 -     * Unbox a java.lang.Number. Do not call directly
  13.672 -     * @param obj object to cast to Number and unbox
  13.673 -     * @return a double
  13.674 -     */
  13.675 -    public static double unboxD(final Object obj) {
  13.676 -        return ((Number)obj).doubleValue();
  13.677 -    }
  13.678 -
  13.679 -    private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
  13.680 -        return MH.findStatic(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
  13.681 -    }
  13.682 -
  13.683 -    private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
  13.684 -        return MH.findVirtual(MethodHandles.lookup(), RuntimeCallSite.class, name, MH.type(rtype, types));
  13.685 -    }
  13.686 -}
    14.1 --- a/src/jdk/nashorn/internal/ir/BinaryNode.java	Wed Mar 18 13:57:04 2015 -0700
    14.2 +++ b/src/jdk/nashorn/internal/ir/BinaryNode.java	Wed Mar 18 18:21:55 2015 -0700
    14.3 @@ -98,7 +98,7 @@
    14.4      }
    14.5  
    14.6      /**
    14.7 -     * Returns true if the node is a comparison operation.
    14.8 +     * Returns true if the node is a comparison operation (either equality, inequality, or relational).
    14.9       * @return true if the node is a comparison operation.
   14.10       */
   14.11      public boolean isComparison() {
   14.12 @@ -118,6 +118,22 @@
   14.13      }
   14.14  
   14.15      /**
   14.16 +     * Returns true if the node is a relational operation (less than (or equals), greater than (or equals)).
   14.17 +     * @return true if the node is a relational operation.
   14.18 +     */
   14.19 +    public boolean isRelational() {
   14.20 +        switch (tokenType()) {
   14.21 +        case LT:
   14.22 +        case GT:
   14.23 +        case LE:
   14.24 +        case GE:
   14.25 +            return true;
   14.26 +        default:
   14.27 +            return false;
   14.28 +        }
   14.29 +    }
   14.30 +
   14.31 +    /**
   14.32       * Returns true if the node is a logical operation.
   14.33       * @return true if the node is a logical operation.
   14.34       */
    15.1 --- a/src/jdk/nashorn/internal/ir/RuntimeNode.java	Wed Mar 18 13:57:04 2015 -0700
    15.2 +++ b/src/jdk/nashorn/internal/ir/RuntimeNode.java	Wed Mar 18 18:21:55 2015 -0700
    15.3 @@ -25,8 +25,6 @@
    15.4  
    15.5  package jdk.nashorn.internal.ir;
    15.6  
    15.7 -import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
    15.8 -
    15.9  import java.util.Arrays;
   15.10  import java.util.Collections;
   15.11  import java.util.List;
   15.12 @@ -39,7 +37,7 @@
   15.13   * IR representation for a runtime call.
   15.14   */
   15.15  @Immutable
   15.16 -public class RuntimeNode extends Expression implements Optimistic {
   15.17 +public class RuntimeNode extends Expression {
   15.18      private static final long serialVersionUID = 1L;
   15.19  
   15.20      /**
   15.21 @@ -333,11 +331,6 @@
   15.22      /** Call arguments. */
   15.23      private final List<Expression> args;
   15.24  
   15.25 -    /** is final - i.e. may not be removed again, lower in the code pipeline */
   15.26 -    private final boolean isFinal;
   15.27 -
   15.28 -    private final int programPoint;
   15.29 -
   15.30      /**
   15.31       * Constructor
   15.32       *
   15.33 @@ -351,17 +344,13 @@
   15.34  
   15.35          this.request      = request;
   15.36          this.args         = args;
   15.37 -        this.isFinal      = false;
   15.38 -        this.programPoint = INVALID_PROGRAM_POINT;
   15.39      }
   15.40  
   15.41 -    private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final boolean isFinal, final List<Expression> args, final int programPoint) {
   15.42 +    private RuntimeNode(final RuntimeNode runtimeNode, final Request request, final List<Expression> args) {
   15.43          super(runtimeNode);
   15.44  
   15.45          this.request      = request;
   15.46          this.args         = args;
   15.47 -        this.isFinal      = isFinal;
   15.48 -        this.programPoint = programPoint;
   15.49      }
   15.50  
   15.51      /**
   15.52 @@ -399,8 +388,6 @@
   15.53  
   15.54          this.request      = request;
   15.55          this.args         = args;
   15.56 -        this.isFinal      = false;
   15.57 -        this.programPoint = parent instanceof Optimistic ? ((Optimistic)parent).getProgramPoint() : INVALID_PROGRAM_POINT;
   15.58      }
   15.59  
   15.60      /**
   15.61 @@ -428,32 +415,11 @@
   15.62       * @return new runtime node or same if same request
   15.63       */
   15.64      public RuntimeNode setRequest(final Request request) {
   15.65 -       if (this.request == request) {
   15.66 -           return this;
   15.67 -       }
   15.68 -       return new RuntimeNode(this, request, isFinal, args, programPoint);
   15.69 -   }
   15.70 -
   15.71 -
   15.72 -    /**
   15.73 -     * Is this node final - i.e. it can never be replaced with other nodes again
   15.74 -     * @return true if final
   15.75 -     */
   15.76 -    public boolean isFinal() {
   15.77 -        return isFinal;
   15.78 -    }
   15.79 -
   15.80 -    /**
   15.81 -     * Flag this node as final - i.e it may never be replaced with other nodes again
   15.82 -     * @param isFinal is the node final, i.e. can not be removed and replaced by a less generic one later in codegen
   15.83 -     * @return same runtime node if already final, otherwise a new one
   15.84 -     */
   15.85 -    public RuntimeNode setIsFinal(final boolean isFinal) {
   15.86 -        if (this.isFinal == isFinal) {
   15.87 +        if (this.request == request) {
   15.88              return this;
   15.89          }
   15.90 -        return new RuntimeNode(this, request, isFinal, args, programPoint);
   15.91 -    }
   15.92 +        return new RuntimeNode(this, request, args);
   15.93 +   }
   15.94  
   15.95      /**
   15.96       * Return type for the ReferenceNode
   15.97 @@ -510,7 +476,7 @@
   15.98          if (this.args == args) {
   15.99              return this;
  15.100          }
  15.101 -        return new RuntimeNode(this, request, isFinal, args, programPoint);
  15.102 +        return new RuntimeNode(this, request, args);
  15.103      }
  15.104  
  15.105      /**
  15.106 @@ -536,39 +502,4 @@
  15.107          }
  15.108          return true;
  15.109      }
  15.110 -
  15.111 -//TODO these are blank for now:
  15.112 -
  15.113 -    @Override
  15.114 -    public int getProgramPoint() {
  15.115 -        return programPoint;
  15.116 -    }
  15.117 -
  15.118 -    @Override
  15.119 -    public RuntimeNode setProgramPoint(final int programPoint) {
  15.120 -        if(this.programPoint == programPoint) {
  15.121 -            return this;
  15.122 -        }
  15.123 -        return new RuntimeNode(this, request, isFinal, args, programPoint);
  15.124 -    }
  15.125 -
  15.126 -    @Override
  15.127 -    public boolean canBeOptimistic() {
  15.128 -        return false;
  15.129 -    }
  15.130 -
  15.131 -    @Override
  15.132 -    public Type getMostOptimisticType() {
  15.133 -        return getType();
  15.134 -    }
  15.135 -
  15.136 -    @Override
  15.137 -    public Type getMostPessimisticType() {
  15.138 -        return getType();
  15.139 -    }
  15.140 -
  15.141 -    @Override
  15.142 -    public RuntimeNode setType(final Type type) {
  15.143 -        return this;
  15.144 -    }
  15.145  }
    16.1 --- a/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java	Wed Mar 18 13:57:04 2015 -0700
    16.2 +++ b/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java	Wed Mar 18 18:21:55 2015 -0700
    16.3 @@ -25,6 +25,8 @@
    16.4  
    16.5  package jdk.nashorn.internal.lookup;
    16.6  
    16.7 +import static jdk.nashorn.internal.runtime.JSType.isString;
    16.8 +
    16.9  import java.io.ByteArrayOutputStream;
   16.10  import java.io.PrintStream;
   16.11  import java.lang.invoke.MethodHandle;
   16.12 @@ -36,7 +38,6 @@
   16.13  import java.util.Arrays;
   16.14  import java.util.List;
   16.15  import java.util.logging.Level;
   16.16 -import jdk.nashorn.internal.runtime.ConsString;
   16.17  import jdk.nashorn.internal.runtime.Context;
   16.18  import jdk.nashorn.internal.runtime.Debug;
   16.19  import jdk.nashorn.internal.runtime.ScriptObject;
   16.20 @@ -343,7 +344,7 @@
   16.21                  final Object d = data[i];
   16.22                  if (d == null) {
   16.23                      sb.append("<null> ");
   16.24 -                } else if (d instanceof String || d instanceof ConsString) {
   16.25 +                } else if (isString(d)) {
   16.26                      sb.append(d.toString());
   16.27                      sb.append(' ');
   16.28                  } else if (d.getClass().isArray()) {
    17.1 --- a/src/jdk/nashorn/internal/objects/Global.java	Wed Mar 18 13:57:04 2015 -0700
    17.2 +++ b/src/jdk/nashorn/internal/objects/Global.java	Wed Mar 18 18:21:55 2015 -0700
    17.3 @@ -28,6 +28,7 @@
    17.4  import static jdk.nashorn.internal.lookup.Lookup.MH;
    17.5  import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
    17.6  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    17.7 +import static jdk.nashorn.internal.runtime.JSType.isString;
    17.8  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    17.9  
   17.10  import java.io.IOException;
   17.11 @@ -55,7 +56,6 @@
   17.12  import jdk.nashorn.internal.objects.annotations.Attribute;
   17.13  import jdk.nashorn.internal.objects.annotations.Property;
   17.14  import jdk.nashorn.internal.objects.annotations.ScriptClass;
   17.15 -import jdk.nashorn.internal.runtime.ConsString;
   17.16  import jdk.nashorn.internal.runtime.Context;
   17.17  import jdk.nashorn.internal.runtime.ECMAErrors;
   17.18  import jdk.nashorn.internal.runtime.GlobalConstants;
   17.19 @@ -578,7 +578,7 @@
   17.20              return new NativeBoolean((Boolean)obj, this);
   17.21          } else if (obj instanceof Number) {
   17.22              return new NativeNumber(((Number)obj).doubleValue(), this);
   17.23 -        } else if (obj instanceof String || obj instanceof ConsString) {
   17.24 +        } else if (isString(obj)) {
   17.25              return new NativeString((CharSequence)obj, this);
   17.26          } else if (obj instanceof Object[]) { // extension
   17.27              return new NativeArray(ArrayData.allocate((Object[])obj), this);
   17.28 @@ -605,7 +605,7 @@
   17.29       * @return guarded invocation
   17.30       */
   17.31      public static GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
   17.32 -        if (self instanceof String || self instanceof ConsString) {
   17.33 +        if (isString(self)) {
   17.34              return NativeString.lookupPrimitive(request, self);
   17.35          } else if (self instanceof Number) {
   17.36              return NativeNumber.lookupPrimitive(request, self);
   17.37 @@ -622,7 +622,7 @@
   17.38       * @return method handle to create wrapper objects for primitive receiver
   17.39       */
   17.40      public static MethodHandle getPrimitiveWrapFilter(final Object self) {
   17.41 -        if (self instanceof String || self instanceof ConsString) {
   17.42 +        if (isString(self)) {
   17.43              return NativeString.WRAPFILTER;
   17.44          } else if (self instanceof Number) {
   17.45              return NativeNumber.WRAPFILTER;
   17.46 @@ -948,7 +948,7 @@
   17.47       * This is directly invoked from generated when eval(code) is called in user code
   17.48       */
   17.49      public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final boolean strict) {
   17.50 -        if (!(str instanceof String || str instanceof ConsString)) {
   17.51 +        if (!isString(str)) {
   17.52              return str;
   17.53          }
   17.54          final Global global = Global.instanceFrom(self);
    18.1 --- a/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Wed Mar 18 13:57:04 2015 -0700
    18.2 +++ b/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Wed Mar 18 18:21:55 2015 -0700
    18.3 @@ -101,7 +101,7 @@
    18.4          }
    18.5  
    18.6          if (args.length == 0) {
    18.7 -            throw new RuntimeException("missing length argument");
    18.8 +            return new NativeArrayBuffer(0);
    18.9          }
   18.10  
   18.11          return new NativeArrayBuffer(JSType.toInt32(args[0]));
    19.1 --- a/src/jdk/nashorn/internal/objects/NativeDate.java	Wed Mar 18 13:57:04 2015 -0700
    19.2 +++ b/src/jdk/nashorn/internal/objects/NativeDate.java	Wed Mar 18 18:21:55 2015 -0700
    19.3 @@ -30,6 +30,7 @@
    19.4  import static java.lang.Double.isNaN;
    19.5  import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
    19.6  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    19.7 +
    19.8  import java.util.Locale;
    19.9  import java.util.TimeZone;
   19.10  import java.util.concurrent.Callable;
   19.11 @@ -40,7 +41,6 @@
   19.12  import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
   19.13  import jdk.nashorn.internal.objects.annotations.Where;
   19.14  import jdk.nashorn.internal.parser.DateParser;
   19.15 -import jdk.nashorn.internal.runtime.ConsString;
   19.16  import jdk.nashorn.internal.runtime.JSType;
   19.17  import jdk.nashorn.internal.runtime.PropertyMap;
   19.18  import jdk.nashorn.internal.runtime.ScriptEnvironment;
   19.19 @@ -183,7 +183,7 @@
   19.20          case 1:
   19.21              double num;
   19.22              final Object arg = JSType.toPrimitive(args[0]);
   19.23 -            if (arg instanceof String || arg instanceof ConsString) {
   19.24 +            if (JSType.isString(arg)) {
   19.25                  num = parseDateString(arg.toString());
   19.26              } else {
   19.27                  num = timeClip(JSType.toNumber(args[0]));
    20.1 --- a/src/jdk/nashorn/internal/objects/NativeJSON.java	Wed Mar 18 13:57:04 2015 -0700
    20.2 +++ b/src/jdk/nashorn/internal/objects/NativeJSON.java	Wed Mar 18 18:21:55 2015 -0700
    20.3 @@ -181,7 +181,7 @@
    20.4                  }
    20.5                  gap = sb.toString();
    20.6              }
    20.7 -        } else if (modSpace instanceof String || modSpace instanceof ConsString) {
    20.8 +        } else if (JSType.isString(modSpace)) {
    20.9              final String str = modSpace.toString();
   20.10              gap = str.substring(0, Math.min(10, str.length()));
   20.11          } else {
    21.1 --- a/src/jdk/nashorn/internal/objects/NativeString.java	Wed Mar 18 13:57:04 2015 -0700
    21.2 +++ b/src/jdk/nashorn/internal/objects/NativeString.java	Wed Mar 18 18:21:55 2015 -0700
    21.3 @@ -90,7 +90,7 @@
    21.4  
    21.5      private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
    21.6          super(proto, map);
    21.7 -        assert value instanceof String || value instanceof ConsString;
    21.8 +        assert JSType.isString(value);
    21.9          this.value = value;
   21.10      }
   21.11  
   21.12 @@ -155,7 +155,7 @@
   21.13          final Object self = request.getReceiver();
   21.14          final Class<?> returnType = desc.getMethodType().returnType();
   21.15  
   21.16 -        if (returnType == Object.class && (self instanceof String || self instanceof ConsString)) {
   21.17 +        if (returnType == Object.class && JSType.isString(self)) {
   21.18              try {
   21.19                  return new GuardedInvocation(MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType()), NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
   21.20              } catch (final LookupException e) {
   21.21 @@ -1312,7 +1312,7 @@
   21.22      }
   21.23  
   21.24      private static CharSequence getCharSequence(final Object self) {
   21.25 -        if (self instanceof String || self instanceof ConsString) {
   21.26 +        if (JSType.isString(self)) {
   21.27              return (CharSequence)self;
   21.28          } else if (self instanceof NativeString) {
   21.29              return ((NativeString)self).getValue();
    22.1 --- a/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Wed Mar 18 13:57:04 2015 -0700
    22.2 +++ b/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Wed Mar 18 18:21:55 2015 -0700
    22.3 @@ -305,7 +305,7 @@
    22.4          final ScriptFunction typeErrorThrower = global.getTypeErrorThrower();
    22.5          if (findProperty("arguments", true) != null) {
    22.6              initUserAccessors("arguments", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
    22.7 -       }
    22.8 +        }
    22.9          if (findProperty("caller", true) != null) {
   22.10              initUserAccessors("caller", Property.NOT_CONFIGURABLE | Property.NOT_ENUMERABLE, typeErrorThrower, typeErrorThrower);
   22.11         }
    23.1 --- a/src/jdk/nashorn/internal/parser/JSONParser.java	Wed Mar 18 13:57:04 2015 -0700
    23.2 +++ b/src/jdk/nashorn/internal/parser/JSONParser.java	Wed Mar 18 18:21:55 2015 -0700
    23.3 @@ -244,20 +244,15 @@
    23.4      private static PropertyMap addObjectProperty(final PropertyMap propertyMap, final List<Object> values,
    23.5                                                   final String id, final Object value) {
    23.6          final Property oldProperty = propertyMap.findProperty(id);
    23.7 -        final Property newProperty;
    23.8          final PropertyMap newMap;
    23.9          final Class<?> type = ObjectClassGenerator.OBJECT_FIELDS_ONLY ? Object.class : getType(value);
   23.10  
   23.11          if (oldProperty != null) {
   23.12              values.set(oldProperty.getSlot(), value);
   23.13 -            newProperty = new SpillProperty(id, 0, oldProperty.getSlot());
   23.14 -            newProperty.setType(type);
   23.15 -            newMap = propertyMap.replaceProperty(oldProperty, newProperty);;
   23.16 +            newMap = propertyMap.replaceProperty(oldProperty, new SpillProperty(id, 0, oldProperty.getSlot(), type));;
   23.17          } else {
   23.18              values.add(value);
   23.19 -            newProperty = new SpillProperty(id, 0, propertyMap.size());
   23.20 -            newProperty.setType(type);
   23.21 -            newMap = propertyMap.addProperty(newProperty);
   23.22 +            newMap = propertyMap.addProperty(new SpillProperty(id, 0, propertyMap.size(), type));
   23.23          }
   23.24  
   23.25          return newMap;
    24.1 --- a/src/jdk/nashorn/internal/runtime/AllocationStrategy.java	Wed Mar 18 13:57:04 2015 -0700
    24.2 +++ b/src/jdk/nashorn/internal/runtime/AllocationStrategy.java	Wed Mar 18 18:21:55 2015 -0700
    24.3 @@ -29,55 +29,52 @@
    24.4  import java.io.Serializable;
    24.5  import java.lang.invoke.MethodHandle;
    24.6  import java.lang.invoke.MethodHandles;
    24.7 +import jdk.nashorn.internal.codegen.Compiler;
    24.8  import jdk.nashorn.internal.codegen.CompilerConstants;
    24.9 -import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
   24.10 +import jdk.nashorn.internal.codegen.ObjectClassGenerator;
   24.11  
   24.12  /**
   24.13 - * Encapsulates the allocation strategy for a function when used as a constructor. Basically the same as
   24.14 - * {@link AllocatorDescriptor}, but with an additionally cached resolved method handle. There is also a
   24.15 - * canonical default allocation strategy for functions that don't assign any "this" properties (vast majority
   24.16 - * of all functions), therefore saving some storage space in {@link RecompilableScriptFunctionData} that would
   24.17 - * otherwise be lost to identical tuples of (map, className, handle) fields.
   24.18 + * Encapsulates the allocation strategy for a function when used as a constructor.
   24.19   */
   24.20 -final class AllocationStrategy implements Serializable {
   24.21 +final public class AllocationStrategy implements Serializable {
   24.22      private static final long serialVersionUID = 1L;
   24.23  
   24.24      private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
   24.25  
   24.26 -    private static final AllocationStrategy DEFAULT_STRATEGY = new AllocationStrategy(new AllocatorDescriptor(0));
   24.27 -
   24.28 -    /** Allocator map from allocator descriptor */
   24.29 -    private final PropertyMap allocatorMap;
   24.30 +    /** Number of fields in the allocated object */
   24.31 +    private final int fieldCount;
   24.32  
   24.33      /** Name of class where allocator function resides */
   24.34 -    private final String allocatorClassName;
   24.35 +    private transient String allocatorClassName;
   24.36  
   24.37      /** lazily generated allocator */
   24.38      private transient MethodHandle allocator;
   24.39  
   24.40 -    private AllocationStrategy(final AllocatorDescriptor desc) {
   24.41 -        this.allocatorMap = desc.getAllocatorMap();
   24.42 -        // These classes get loaded, so an interned variant of their name is most likely around anyway.
   24.43 -        this.allocatorClassName = desc.getAllocatorClassName().intern();
   24.44 +    /**
   24.45 +     * Construct an allocation strategy with the given map and class name.
   24.46 +     * @param fieldCount number of fields in the allocated object
   24.47 +     */
   24.48 +    public AllocationStrategy(final int fieldCount) {
   24.49 +        this.fieldCount = fieldCount;
   24.50      }
   24.51  
   24.52 -    private boolean matches(final AllocatorDescriptor desc) {
   24.53 -        return desc.getAllocatorMap().size() == allocatorMap.size() &&
   24.54 -                desc.getAllocatorClassName().equals(allocatorClassName);
   24.55 -    }
   24.56 -
   24.57 -    static AllocationStrategy get(final AllocatorDescriptor desc) {
   24.58 -        return DEFAULT_STRATEGY.matches(desc) ? DEFAULT_STRATEGY : new AllocationStrategy(desc);
   24.59 +    private String getAllocatorClassName() {
   24.60 +        if (allocatorClassName == null) {
   24.61 +            // These classes get loaded, so an interned variant of their name is most likely around anyway.
   24.62 +            allocatorClassName = Compiler.binaryName(ObjectClassGenerator.getClassName(fieldCount)).intern();
   24.63 +        }
   24.64 +        return allocatorClassName;
   24.65      }
   24.66  
   24.67      PropertyMap getAllocatorMap() {
   24.68 -        return allocatorMap;
   24.69 +        // Create a new map for each function instance
   24.70 +        return PropertyMap.newMap(null, getAllocatorClassName(), 0, fieldCount, 0);
   24.71      }
   24.72  
   24.73      ScriptObject allocate(final PropertyMap map) {
   24.74          try {
   24.75              if (allocator == null) {
   24.76 -                allocator = MH.findStatic(LOOKUP, Context.forStructureClass(allocatorClassName),
   24.77 +                allocator = MH.findStatic(LOOKUP, Context.forStructureClass(getAllocatorClassName()),
   24.78                          CompilerConstants.ALLOCATE.symbolName(), MH.type(ScriptObject.class, PropertyMap.class));
   24.79              }
   24.80              return (ScriptObject)allocator.invokeExact(map);
   24.81 @@ -88,17 +85,8 @@
   24.82          }
   24.83      }
   24.84  
   24.85 -    private Object readResolve() {
   24.86 -        if(allocatorMap.size() == DEFAULT_STRATEGY.allocatorMap.size() &&
   24.87 -                allocatorClassName.equals(DEFAULT_STRATEGY.allocatorClassName)) {
   24.88 -            return DEFAULT_STRATEGY;
   24.89 -        }
   24.90 -        return this;
   24.91 -    }
   24.92 -
   24.93      @Override
   24.94      public String toString() {
   24.95 -        return "AllocationStrategy[allocatorClassName=" + allocatorClassName + ", allocatorMap.size=" +
   24.96 -                allocatorMap.size() + "]";
   24.97 +        return "AllocationStrategy[fieldCount=" + fieldCount + "]";
   24.98      }
   24.99  }
    25.1 --- a/src/jdk/nashorn/internal/runtime/ConsString.java	Wed Mar 18 13:57:04 2015 -0700
    25.2 +++ b/src/jdk/nashorn/internal/runtime/ConsString.java	Wed Mar 18 18:21:55 2015 -0700
    25.3 @@ -25,6 +25,8 @@
    25.4  
    25.5  package jdk.nashorn.internal.runtime;
    25.6  
    25.7 +import static jdk.nashorn.internal.runtime.JSType.isString;
    25.8 +
    25.9  import java.util.ArrayDeque;
   25.10  import java.util.Deque;
   25.11  
   25.12 @@ -52,8 +54,8 @@
   25.13       * @param right right char sequence
   25.14       */
   25.15      public ConsString(final CharSequence left, final CharSequence right) {
   25.16 -        assert left instanceof String || left instanceof ConsString;
   25.17 -        assert right instanceof String || right instanceof ConsString;
   25.18 +        assert isString(left);
   25.19 +        assert isString(right);
   25.20          this.left = left;
   25.21          this.right = right;
   25.22          length = left.length() + right.length();
    26.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java	Wed Mar 18 13:57:04 2015 -0700
    26.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java	Wed Mar 18 18:21:55 2015 -0700
    26.3 @@ -29,6 +29,7 @@
    26.4  import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
    26.5  import static jdk.nashorn.internal.lookup.Lookup.MH;
    26.6  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    26.7 +
    26.8  import java.lang.invoke.MethodHandle;
    26.9  import java.lang.invoke.MethodHandles;
   26.10  import java.lang.reflect.Array;
   26.11 @@ -37,6 +38,7 @@
   26.12  import java.util.Deque;
   26.13  import java.util.List;
   26.14  import jdk.internal.dynalink.beans.StaticClass;
   26.15 +import jdk.nashorn.api.scripting.AbstractJSObject;
   26.16  import jdk.nashorn.api.scripting.JSObject;
   26.17  import jdk.nashorn.internal.codegen.CompilerConstants.Call;
   26.18  import jdk.nashorn.internal.codegen.types.Type;
   26.19 @@ -210,7 +212,6 @@
   26.20      /** Method handle for void returns. */
   26.21      public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class);
   26.22  
   26.23 -
   26.24      /**
   26.25       * The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
   26.26       *  in the dual--fields world
   26.27 @@ -311,7 +312,7 @@
   26.28              return JSType.BOOLEAN;
   26.29          }
   26.30  
   26.31 -        if (obj instanceof String || obj instanceof ConsString) {
   26.32 +        if (isString(obj)) {
   26.33              return JSType.STRING;
   26.34          }
   26.35  
   26.36 @@ -349,7 +350,7 @@
   26.37              return JSType.BOOLEAN;
   26.38          }
   26.39  
   26.40 -        if (obj instanceof String || obj instanceof ConsString) {
   26.41 +        if (isString(obj)) {
   26.42              return JSType.STRING;
   26.43          }
   26.44  
   26.45 @@ -455,8 +456,7 @@
   26.46                 obj == ScriptRuntime.UNDEFINED ||
   26.47                 obj instanceof Boolean ||
   26.48                 obj instanceof Number ||
   26.49 -               obj instanceof String ||
   26.50 -               obj instanceof ConsString;
   26.51 +               isString(obj);
   26.52      }
   26.53  
   26.54     /**
   26.55 @@ -480,17 +480,47 @@
   26.56       * @return the primitive form of the object
   26.57       */
   26.58      public static Object toPrimitive(final Object obj, final Class<?> hint) {
   26.59 -        return obj instanceof ScriptObject ? toPrimitive((ScriptObject)obj, hint) : obj;
   26.60 +        if (obj instanceof ScriptObject) {
   26.61 +            return toPrimitive((ScriptObject)obj, hint);
   26.62 +        } else if (isPrimitive(obj)) {
   26.63 +            return obj;
   26.64 +        } else if (obj instanceof JSObject) {
   26.65 +            return toPrimitive((JSObject)obj, hint);
   26.66 +        } else if (obj instanceof StaticClass) {
   26.67 +            final String name = ((StaticClass)obj).getRepresentedClass().getName();
   26.68 +            return new StringBuilder(12 + name.length()).append("[JavaClass ").append(name).append(']').toString();
   26.69 +        }
   26.70 +        return obj.toString();
   26.71      }
   26.72  
   26.73      private static Object toPrimitive(final ScriptObject sobj, final Class<?> hint) {
   26.74 -        final Object result = sobj.getDefaultValue(hint);
   26.75 +        return requirePrimitive(sobj.getDefaultValue(hint));
   26.76 +    }
   26.77  
   26.78 +    private static Object requirePrimitive(final Object result) {
   26.79          if (!isPrimitive(result)) {
   26.80              throw typeError("bad.default.value", result.toString());
   26.81          }
   26.82 +        return result;
   26.83 +    }
   26.84  
   26.85 -        return result;
   26.86 +    /**
   26.87 +     * Primitive converter for a {@link JSObject} including type hint. Invokes
   26.88 +     * {@link AbstractJSObject#getDefaultValue(JSObject, Class)} and translates any thrown
   26.89 +     * {@link UnsupportedOperationException} to an ECMAScript {@code TypeError}.
   26.90 +     * See ECMA 9.1 ToPrimitive
   26.91 +     *
   26.92 +     * @param jsobj  a JSObject
   26.93 +     * @param hint a type hint
   26.94 +     *
   26.95 +     * @return the primitive form of the JSObject
   26.96 +     */
   26.97 +    public static Object toPrimitive(final JSObject jsobj, final Class<?> hint) {
   26.98 +        try {
   26.99 +            return requirePrimitive(AbstractJSObject.getDefaultValue(jsobj, hint));
  26.100 +        } catch (final UnsupportedOperationException e) {
  26.101 +            throw new ECMAException(Context.getGlobal().newTypeError(e.getMessage()), e);
  26.102 +        }
  26.103      }
  26.104  
  26.105      /**
  26.106 @@ -547,7 +577,7 @@
  26.107              return num != 0 && !Double.isNaN(num);
  26.108          }
  26.109  
  26.110 -        if (obj instanceof String || obj instanceof ConsString) {
  26.111 +        if (isString(obj)) {
  26.112              return ((CharSequence)obj).length() > 0;
  26.113          }
  26.114  
  26.115 @@ -598,6 +628,15 @@
  26.116      }
  26.117  
  26.118      /**
  26.119 +     * Returns true if object represents a primitive JavaScript string value.
  26.120 +     * @param obj the object
  26.121 +     * @return true if the object represents a primitive JavaScript string value.
  26.122 +     */
  26.123 +    public static boolean isString(final Object obj) {
  26.124 +        return obj instanceof String || obj instanceof ConsString;
  26.125 +    }
  26.126 +
  26.127 +    /**
  26.128       * JavaScript compliant conversion of integer to String
  26.129       *
  26.130       * @param num an integer
  26.131 @@ -723,6 +762,48 @@
  26.132          return toNumberGeneric(obj);
  26.133      }
  26.134  
  26.135 +    /**
  26.136 +     * Converts an object for a comparison with a number. Almost identical to {@link #toNumber(Object)} but
  26.137 +     * converts {@code null} to {@code NaN} instead of zero, so it won't compare equal to zero.
  26.138 +     *
  26.139 +     * @param obj  an object
  26.140 +     *
  26.141 +     * @return a number
  26.142 +     */
  26.143 +    public static double toNumberForEq(final Object obj) {
  26.144 +        return obj == null ? Double.NaN : toNumber(obj);
  26.145 +    }
  26.146 +
  26.147 +    /**
  26.148 +     * Converts an object for strict comparison with a number. Returns {@code NaN} for any object that is not
  26.149 +     * a {@link Number}, so only boxed numerics can compare strictly equal to numbers.
  26.150 +     *
  26.151 +     * @param obj  an object
  26.152 +     *
  26.153 +     * @return a number
  26.154 +     */
  26.155 +    public static double toNumberForStrictEq(final Object obj) {
  26.156 +        if (obj instanceof Double) {
  26.157 +            return (Double)obj;
  26.158 +        }
  26.159 +        if (obj instanceof Number) {
  26.160 +            return ((Number)obj).doubleValue();
  26.161 +        }
  26.162 +        return Double.NaN;
  26.163 +    }
  26.164 +
  26.165 +
  26.166 +    /**
  26.167 +     * JavaScript compliant conversion of Boolean to number
  26.168 +     * See ECMA 9.3 ToNumber
  26.169 +     *
  26.170 +     * @param b a boolean
  26.171 +     *
  26.172 +     * @return JS numeric value of the boolean: 1.0 or 0.0
  26.173 +     */
  26.174 +    public static double toNumber(final Boolean b) {
  26.175 +        return b ? 1d : +0d;
  26.176 +    }
  26.177  
  26.178      /**
  26.179       * JavaScript compliant conversion of Object to number
  26.180 @@ -1301,6 +1382,10 @@
  26.181              return (String)obj;
  26.182          }
  26.183  
  26.184 +        if (obj instanceof ConsString) {
  26.185 +            return obj.toString();
  26.186 +        }
  26.187 +
  26.188          if (obj instanceof Number) {
  26.189              return toString(((Number)obj).doubleValue());
  26.190          }
  26.191 @@ -1313,23 +1398,19 @@
  26.192              return "null";
  26.193          }
  26.194  
  26.195 -        if (obj instanceof ScriptObject) {
  26.196 -            if (safe) {
  26.197 -                final ScriptObject sobj = (ScriptObject)obj;
  26.198 -                final Global gobj = Context.getGlobal();
  26.199 -                return gobj.isError(sobj) ?
  26.200 -                    ECMAException.safeToString(sobj) :
  26.201 -                    sobj.safeToString();
  26.202 -            }
  26.203 -
  26.204 -            return toString(toPrimitive(obj, String.class));
  26.205 +        if (obj instanceof Boolean) {
  26.206 +            return obj.toString();
  26.207          }
  26.208  
  26.209 -        if (obj instanceof StaticClass) {
  26.210 -            return "[JavaClass " + ((StaticClass)obj).getRepresentedClass().getName() + "]";
  26.211 +        if (safe && obj instanceof ScriptObject) {
  26.212 +            final ScriptObject sobj = (ScriptObject)obj;
  26.213 +            final Global gobj = Context.getGlobal();
  26.214 +            return gobj.isError(sobj) ?
  26.215 +                ECMAException.safeToString(sobj) :
  26.216 +                sobj.safeToString();
  26.217          }
  26.218  
  26.219 -        return obj.toString();
  26.220 +        return toString(toPrimitive(obj, String.class));
  26.221      }
  26.222  
  26.223      // trim from left for JS whitespaces.
  26.224 @@ -1822,18 +1903,18 @@
  26.225          }
  26.226  
  26.227          if (obj instanceof Boolean) {
  26.228 -            return (Boolean)obj ? 1 : +0.0;
  26.229 +            return toNumber((Boolean)obj);
  26.230          }
  26.231  
  26.232          if (obj instanceof ScriptObject) {
  26.233              return toNumber((ScriptObject)obj);
  26.234          }
  26.235  
  26.236 -        if (obj instanceof JSObject) {
  26.237 -            return ((JSObject)obj).toNumber();
  26.238 +        if (obj instanceof Undefined) {
  26.239 +            return Double.NaN;
  26.240          }
  26.241  
  26.242 -        return Double.NaN;
  26.243 +        return toNumber(toPrimitive(obj, Number.class));
  26.244      }
  26.245  
  26.246      private static Object invoke(final MethodHandle mh, final Object arg) {
    27.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Mar 18 13:57:04 2015 -0700
    27.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Mar 18 18:21:55 2015 -0700
    27.3 @@ -43,7 +43,6 @@
    27.4  import jdk.nashorn.internal.codegen.CompilerConstants;
    27.5  import jdk.nashorn.internal.codegen.FunctionSignature;
    27.6  import jdk.nashorn.internal.codegen.Namespace;
    27.7 -import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
    27.8  import jdk.nashorn.internal.codegen.OptimisticTypesPersistence;
    27.9  import jdk.nashorn.internal.codegen.TypeMap;
   27.10  import jdk.nashorn.internal.codegen.types.Type;
   27.11 @@ -126,7 +125,7 @@
   27.12       *
   27.13       * @param functionNode        functionNode that represents this function code
   27.14       * @param installer           installer for code regeneration versions of this function
   27.15 -     * @param allocationDescriptor descriptor for the allocation behavior when this function is used as a constructor
   27.16 +     * @param allocationStrategy  strategy for the allocation behavior when this function is used as a constructor
   27.17       * @param nestedFunctions     nested function map
   27.18       * @param externalScopeDepths external scope depths
   27.19       * @param internalSymbols     internal symbols to method, defined in its scope
   27.20 @@ -135,7 +134,7 @@
   27.21      public RecompilableScriptFunctionData(
   27.22          final FunctionNode functionNode,
   27.23          final CodeInstaller<ScriptEnvironment> installer,
   27.24 -        final AllocatorDescriptor allocationDescriptor,
   27.25 +        final AllocationStrategy allocationStrategy,
   27.26          final Map<Integer, RecompilableScriptFunctionData> nestedFunctions,
   27.27          final Map<String, Integer> externalScopeDepths,
   27.28          final Set<String> internalSymbols,
   27.29 @@ -153,7 +152,7 @@
   27.30          this.endParserState      = functionNode.getEndParserState();
   27.31          this.token               = tokenFor(functionNode);
   27.32          this.installer           = installer;
   27.33 -        this.allocationStrategy  = AllocationStrategy.get(allocationDescriptor);
   27.34 +        this.allocationStrategy  = allocationStrategy;
   27.35          this.nestedFunctions     = smallMap(nestedFunctions);
   27.36          this.externalScopeDepths = smallMap(externalScopeDepths);
   27.37          this.internalSymbols     = smallSet(new HashSet<>(internalSymbols));
    28.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Mar 18 13:57:04 2015 -0700
    28.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Mar 18 18:21:55 2015 -0700
    28.3 @@ -143,7 +143,6 @@
    28.4  
    28.5          this.data  = data;
    28.6          this.scope = scope;
    28.7 -        this.allocatorMap = data.getAllocatorMap();
    28.8      }
    28.9  
   28.10      @Override
   28.11 @@ -253,7 +252,7 @@
   28.12  
   28.13          assert !isBoundFunction(); // allocate never invoked on bound functions
   28.14  
   28.15 -        final ScriptObject object = data.allocate(allocatorMap);
   28.16 +        final ScriptObject object = data.allocate(getAllocatorMap());
   28.17  
   28.18          if (object != null) {
   28.19              final Object prototype = getPrototype();
   28.20 @@ -269,6 +268,13 @@
   28.21          return object;
   28.22      }
   28.23  
   28.24 +    private PropertyMap getAllocatorMap() {
   28.25 +        if (allocatorMap == null) {
   28.26 +            allocatorMap = data.getAllocatorMap();
   28.27 +        }
   28.28 +        return allocatorMap;
   28.29 +    }
   28.30 +
   28.31      /**
   28.32       * Return Object.prototype - used by "allocate"
   28.33       * @return Object.prototype
    29.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed Mar 18 13:57:04 2015 -0700
    29.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Wed Mar 18 18:21:55 2015 -0700
    29.3 @@ -28,6 +28,7 @@
    29.4  import static jdk.nashorn.internal.lookup.Lookup.MH;
    29.5  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    29.6  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    29.7 +
    29.8  import java.io.IOException;
    29.9  import java.io.ObjectInputStream;
   29.10  import java.io.Serializable;
   29.11 @@ -456,8 +457,7 @@
   29.12      }
   29.13  
   29.14      static boolean isPrimitiveThis(final Object obj) {
   29.15 -        return obj instanceof String || obj instanceof ConsString ||
   29.16 -               obj instanceof Number || obj instanceof Boolean;
   29.17 +        return JSType.isString(obj) || obj instanceof Number || obj instanceof Boolean;
   29.18      }
   29.19  
   29.20      /**
    30.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Wed Mar 18 13:57:04 2015 -0700
    30.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Wed Mar 18 18:21:55 2015 -0700
    30.3 @@ -32,6 +32,8 @@
    30.4  import static jdk.nashorn.internal.runtime.ECMAErrors.syntaxError;
    30.5  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    30.6  import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
    30.7 +import static jdk.nashorn.internal.runtime.JSType.isString;
    30.8 +
    30.9  import java.lang.invoke.MethodHandle;
   30.10  import java.lang.invoke.MethodHandles;
   30.11  import java.lang.invoke.SwitchPoint;
   30.12 @@ -55,7 +57,6 @@
   30.13  import jdk.nashorn.internal.parser.Lexer;
   30.14  import jdk.nashorn.internal.runtime.linker.Bootstrap;
   30.15  
   30.16 -
   30.17  /**
   30.18   * Utilities to be called by JavaScript runtime API and generated classes.
   30.19   */
   30.20 @@ -535,8 +536,6 @@
   30.21  
   30.22      /**
   30.23       * ECMA 11.6.1 - The addition operator (+) - generic implementation
   30.24 -     * Compiler specializes using {@link jdk.nashorn.internal.codegen.RuntimeCallSite}
   30.25 -     * if any type information is available for any of the operands
   30.26       *
   30.27       * @param x  first term
   30.28       * @param y  second term
   30.29 @@ -563,8 +562,7 @@
   30.30          final Object xPrim = JSType.toPrimitive(x);
   30.31          final Object yPrim = JSType.toPrimitive(y);
   30.32  
   30.33 -        if (xPrim instanceof String || yPrim instanceof String
   30.34 -                || xPrim instanceof ConsString || yPrim instanceof ConsString) {
   30.35 +        if (isString(xPrim) || isString(yPrim)) {
   30.36              try {
   30.37                  return new ConsString(JSType.toCharSequence(xPrim), JSType.toCharSequence(yPrim));
   30.38              } catch (final IllegalArgumentException iae) {
   30.39 @@ -734,7 +732,7 @@
   30.40              return true;
   30.41          }
   30.42          if (x instanceof ScriptObject && y instanceof ScriptObject) {
   30.43 -            return x == y;
   30.44 +            return false; // x != y
   30.45          }
   30.46          if (x instanceof ScriptObjectMirror || y instanceof ScriptObjectMirror) {
   30.47              return ScriptObjectMirror.identical(x, y);
   30.48 @@ -798,37 +796,55 @@
   30.49       * @return true if they're equal
   30.50       */
   30.51      private static boolean equalDifferentTypeValues(final Object x, final Object y, final JSType xType, final JSType yType) {
   30.52 -        if (xType == JSType.UNDEFINED && yType == JSType.NULL || xType == JSType.NULL && yType == JSType.UNDEFINED) {
   30.53 +        if (isUndefinedAndNull(xType, yType) || isUndefinedAndNull(yType, xType)) {
   30.54              return true;
   30.55 -        }
   30.56 -
   30.57 -        if (xType == JSType.NUMBER && yType == JSType.STRING) {
   30.58 -            return equals(x, JSType.toNumber(y));
   30.59 -        }
   30.60 -
   30.61 -        if (xType == JSType.STRING && yType == JSType.NUMBER) {
   30.62 -            return equals(JSType.toNumber(x), y);
   30.63 -        }
   30.64 -
   30.65 -        if (xType == JSType.BOOLEAN) {
   30.66 -            return equals(JSType.toNumber(x), y);
   30.67 -        }
   30.68 -
   30.69 -        if (yType == JSType.BOOLEAN) {
   30.70 -            return equals(x, JSType.toNumber(y));
   30.71 -        }
   30.72 -
   30.73 -        if ((xType == JSType.STRING || xType == JSType.NUMBER) && y instanceof ScriptObject)  {
   30.74 -            return equals(x, JSType.toPrimitive(y));
   30.75 -        }
   30.76 -
   30.77 -        if (x instanceof ScriptObject && (yType == JSType.STRING || yType == JSType.NUMBER)) {
   30.78 -            return equals(JSType.toPrimitive(x), y);
   30.79 +        } else if (isNumberAndString(xType, yType)) {
   30.80 +            return equalNumberToString(x, y);
   30.81 +        } else if (isNumberAndString(yType, xType)) {
   30.82 +            // Can reverse order as both are primitives
   30.83 +            return equalNumberToString(y, x);
   30.84 +        } else if (xType == JSType.BOOLEAN) {
   30.85 +            return equalBooleanToAny(x, y);
   30.86 +        } else if (yType == JSType.BOOLEAN) {
   30.87 +            // Can reverse order as y is primitive
   30.88 +            return equalBooleanToAny(y, x);
   30.89 +        } else if (isNumberOrStringAndObject(xType, yType)) {
   30.90 +            return equalNumberOrStringToObject(x, y);
   30.91 +        } else if (isNumberOrStringAndObject(yType, xType)) {
   30.92 +            // Can reverse order as y is primitive
   30.93 +            return equalNumberOrStringToObject(y, x);
   30.94          }
   30.95  
   30.96          return false;
   30.97      }
   30.98  
   30.99 +    private static boolean isUndefinedAndNull(final JSType xType, final JSType yType) {
  30.100 +        return xType == JSType.UNDEFINED && yType == JSType.NULL;
  30.101 +    }
  30.102 +
  30.103 +    private static boolean isNumberAndString(final JSType xType, final JSType yType) {
  30.104 +        return xType == JSType.NUMBER && yType == JSType.STRING;
  30.105 +    }
  30.106 +
  30.107 +    private static boolean isNumberOrStringAndObject(final JSType xType, final JSType yType) {
  30.108 +        return (xType == JSType.NUMBER || xType == JSType.STRING) && yType == JSType.OBJECT;
  30.109 +    }
  30.110 +
  30.111 +    private static boolean equalNumberToString(final Object num, final Object str) {
  30.112 +        // Specification says comparing a number to string should be done as "equals(num, JSType.toNumber(str))". We
  30.113 +        // can short circuit it to this as we know that "num" is a number, so it'll end up being a number-number
  30.114 +        // comparison.
  30.115 +        return ((Number)num).doubleValue() == JSType.toNumber(str.toString());
  30.116 +    }
  30.117 +
  30.118 +    private static boolean equalBooleanToAny(final Object bool, final Object any) {
  30.119 +        return equals(JSType.toNumber((Boolean)bool), any);
  30.120 +    }
  30.121 +
  30.122 +    private static boolean equalNumberOrStringToObject(final Object numOrStr, final Object any) {
  30.123 +        return equals(numOrStr, JSType.toPrimitive(any));
  30.124 +    }
  30.125 +
  30.126      /**
  30.127       * ECMA 11.9.4 - The strict equal operator (===) - generic implementation
  30.128       *
  30.129 @@ -935,8 +951,15 @@
  30.130       * @return true if x is less than y
  30.131       */
  30.132      public static boolean LT(final Object x, final Object y) {
  30.133 -        final Object value = lessThan(x, y, true);
  30.134 -        return value == UNDEFINED ? false : (Boolean)value;
  30.135 +        final Object px = JSType.toPrimitive(x, Number.class);
  30.136 +        final Object py = JSType.toPrimitive(y, Number.class);
  30.137 +
  30.138 +        return areBothString(px, py) ? px.toString().compareTo(py.toString()) < 0 :
  30.139 +            JSType.toNumber(px) < JSType.toNumber(py);
  30.140 +    }
  30.141 +
  30.142 +    private static boolean areBothString(final Object x, final Object y) {
  30.143 +        return isString(x) && isString(y);
  30.144      }
  30.145  
  30.146      /**
  30.147 @@ -948,8 +971,11 @@
  30.148       * @return true if x is greater than y
  30.149       */
  30.150      public static boolean GT(final Object x, final Object y) {
  30.151 -        final Object value = lessThan(y, x, false);
  30.152 -        return value == UNDEFINED ? false : (Boolean)value;
  30.153 +        final Object px = JSType.toPrimitive(x, Number.class);
  30.154 +        final Object py = JSType.toPrimitive(y, Number.class);
  30.155 +
  30.156 +        return areBothString(px, py) ? px.toString().compareTo(py.toString()) > 0 :
  30.157 +            JSType.toNumber(px) > JSType.toNumber(py);
  30.158      }
  30.159  
  30.160      /**
  30.161 @@ -961,8 +987,11 @@
  30.162       * @return true if x is less than or equal to y
  30.163       */
  30.164      public static boolean LE(final Object x, final Object y) {
  30.165 -        final Object value = lessThan(y, x, false);
  30.166 -        return !(Boolean.TRUE.equals(value) || value == UNDEFINED);
  30.167 +        final Object px = JSType.toPrimitive(x, Number.class);
  30.168 +        final Object py = JSType.toPrimitive(y, Number.class);
  30.169 +
  30.170 +        return areBothString(px, py) ? px.toString().compareTo(py.toString()) <= 0 :
  30.171 +            JSType.toNumber(px) <= JSType.toNumber(py);
  30.172      }
  30.173  
  30.174      /**
  30.175 @@ -974,48 +1003,11 @@
  30.176       * @return true if x is greater than or equal to y
  30.177       */
  30.178      public static boolean GE(final Object x, final Object y) {
  30.179 -        final Object value = lessThan(x, y, true);
  30.180 -        return !(Boolean.TRUE.equals(value) || value == UNDEFINED);
  30.181 -    }
  30.182 +        final Object px = JSType.toPrimitive(x, Number.class);
  30.183 +        final Object py = JSType.toPrimitive(y, Number.class);
  30.184  
  30.185 -    /** ECMA 11.8.5 The Abstract Relational Comparison Algorithm */
  30.186 -    private static Object lessThan(final Object x, final Object y, final boolean leftFirst) {
  30.187 -        Object px, py;
  30.188 -
  30.189 -        //support e.g. x < y should throw exception correctly if x or y are not numeric
  30.190 -        if (leftFirst) {
  30.191 -            px = JSType.toPrimitive(x, Number.class);
  30.192 -            py = JSType.toPrimitive(y, Number.class);
  30.193 -        } else {
  30.194 -            py = JSType.toPrimitive(y, Number.class);
  30.195 -            px = JSType.toPrimitive(x, Number.class);
  30.196 -        }
  30.197 -
  30.198 -        if (JSType.ofNoFunction(px) == JSType.STRING && JSType.ofNoFunction(py) == JSType.STRING) {
  30.199 -            // May be String or ConsString
  30.200 -            return px.toString().compareTo(py.toString()) < 0;
  30.201 -        }
  30.202 -
  30.203 -        final double nx = JSType.toNumber(px);
  30.204 -        final double ny = JSType.toNumber(py);
  30.205 -
  30.206 -        if (Double.isNaN(nx) || Double.isNaN(ny)) {
  30.207 -            return UNDEFINED;
  30.208 -        }
  30.209 -
  30.210 -        if (nx == ny) {
  30.211 -            return false;
  30.212 -        }
  30.213 -
  30.214 -        if (nx > 0 && ny > 0 && Double.isInfinite(nx) && Double.isInfinite(ny)) {
  30.215 -            return false;
  30.216 -        }
  30.217 -
  30.218 -        if (nx < 0 && ny < 0 && Double.isInfinite(nx) && Double.isInfinite(ny)) {
  30.219 -            return false;
  30.220 -        }
  30.221 -
  30.222 -        return nx < ny;
  30.223 +        return areBothString(px, py) ? px.toString().compareTo(py.toString()) >= 0 :
  30.224 +            JSType.toNumber(px) >= JSType.toNumber(py);
  30.225      }
  30.226  
  30.227      /**
  30.228 @@ -1028,9 +1020,7 @@
  30.229          final Context context = Context.getContextTrusted();
  30.230          final SwitchPoint sp = context.getBuiltinSwitchPoint(name);
  30.231          assert sp != null;
  30.232 -        if (sp != null) {
  30.233 -            context.getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
  30.234 -            SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
  30.235 -        }
  30.236 +        context.getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
  30.237 +        SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
  30.238      }
  30.239  }
    31.1 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Wed Mar 18 13:57:04 2015 -0700
    31.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Wed Mar 18 18:21:55 2015 -0700
    31.3 @@ -107,7 +107,7 @@
    31.4  
    31.5          if (file instanceof File) {
    31.6              f = (File)file;
    31.7 -        } else if (file instanceof String || file instanceof ConsString) {
    31.8 +        } else if (JSType.isString(file)) {
    31.9              f = new java.io.File(((CharSequence)file).toString());
   31.10          }
   31.11  
    32.1 --- a/src/jdk/nashorn/internal/runtime/SpillProperty.java	Wed Mar 18 13:57:04 2015 -0700
    32.2 +++ b/src/jdk/nashorn/internal/runtime/SpillProperty.java	Wed Mar 18 18:21:55 2015 -0700
    32.3 @@ -164,7 +164,14 @@
    32.4          assert !OBJECT_FIELDS_ONLY || getLocalType() == Object.class;
    32.5      }
    32.6  
    32.7 -    SpillProperty(final String key, final int flags, final int slot, final Class<?> initialType) {
    32.8 +    /**
    32.9 +     * Constructor for spill properties with an initial type.
   32.10 +     * @param key         the property key
   32.11 +     * @param flags       the property flags
   32.12 +     * @param slot        spill slot
   32.13 +     * @param initialType initial type
   32.14 +     */
   32.15 +    public SpillProperty(final String key, final int flags, final int slot, final Class<?> initialType) {
   32.16          this(key, flags, slot);
   32.17          setType(OBJECT_FIELDS_ONLY ? Object.class : initialType);
   32.18      }
    33.1 --- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Wed Mar 18 13:57:04 2015 -0700
    33.2 +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Wed Mar 18 18:21:55 2015 -0700
    33.3 @@ -48,7 +48,6 @@
    33.4  import jdk.nashorn.api.scripting.JSObject;
    33.5  import jdk.nashorn.internal.codegen.CompilerConstants.Call;
    33.6  import jdk.nashorn.internal.codegen.ObjectClassGenerator;
    33.7 -import jdk.nashorn.internal.codegen.RuntimeCallSite;
    33.8  import jdk.nashorn.internal.lookup.MethodHandleFactory;
    33.9  import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
   33.10  import jdk.nashorn.internal.objects.ScriptFunctionImpl;
   33.11 @@ -210,19 +209,6 @@
   33.12      }
   33.13  
   33.14      /**
   33.15 -     * Bootstrapper for a specialized Runtime call
   33.16 -     *
   33.17 -     * @param lookup       lookup
   33.18 -     * @param initialName  initial name for callsite
   33.19 -     * @param type         method type for call site
   33.20 -     *
   33.21 -     * @return callsite for a runtime node
   33.22 -     */
   33.23 -    public static CallSite runtimeBootstrap(final MethodHandles.Lookup lookup, final String initialName, final MethodType type) {
   33.24 -        return new RuntimeCallSite(type, initialName);
   33.25 -    }
   33.26 -
   33.27 -    /**
   33.28       * Boostrapper for math calls that may overflow
   33.29       * @param lookup         lookup
   33.30       * @param name           name of operation
    34.1 --- a/src/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java	Wed Mar 18 13:57:04 2015 -0700
    34.2 +++ b/src/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java	Wed Mar 18 18:21:55 2015 -0700
    34.3 @@ -25,11 +25,13 @@
    34.4  
    34.5  package jdk.nashorn.internal.runtime.linker;
    34.6  
    34.7 +import static jdk.nashorn.internal.runtime.JSType.isString;
    34.8 +import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_CALL;
    34.9  import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_GETMEMBER;
   34.10  import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_GETSLOT;
   34.11  import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_SETMEMBER;
   34.12  import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_SETSLOT;
   34.13 -import static jdk.nashorn.internal.runtime.linker.BrowserJSObjectLinker.JSObjectHandles.JSOBJECT_CALL;
   34.14 +
   34.15  import java.lang.invoke.MethodHandle;
   34.16  import java.lang.invoke.MethodHandles;
   34.17  import jdk.internal.dynalink.CallSiteDescriptor;
   34.18 @@ -170,12 +172,12 @@
   34.19              if (index > -1) {
   34.20                  return JSOBJECT_GETSLOT.invokeExact(jsobj, index);
   34.21              }
   34.22 -        } else if (key instanceof String) {
   34.23 -            final String name = (String)key;
   34.24 +        } else if (isString(key)) {
   34.25 +            final String name = key.toString();
   34.26              if (name.indexOf('(') != -1) {
   34.27 -                return fallback.invokeExact(jsobj, key);
   34.28 +                return fallback.invokeExact(jsobj, (Object) name);
   34.29              }
   34.30 -            return JSOBJECT_GETMEMBER.invokeExact(jsobj, (String)key);
   34.31 +            return JSOBJECT_GETMEMBER.invokeExact(jsobj, name);
   34.32          }
   34.33          return null;
   34.34      }
   34.35 @@ -186,8 +188,8 @@
   34.36              JSOBJECT_SETSLOT.invokeExact(jsobj, (int)key, value);
   34.37          } else if (key instanceof Number) {
   34.38              JSOBJECT_SETSLOT.invokeExact(jsobj, getIndex((Number)key), value);
   34.39 -        } else if (key instanceof String) {
   34.40 -            JSOBJECT_SETMEMBER.invokeExact(jsobj, (String)key, value);
   34.41 +        } else if (isString(key)) {
   34.42 +            JSOBJECT_SETMEMBER.invokeExact(jsobj, key.toString(), value);
   34.43          }
   34.44      }
   34.45  
    35.1 --- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Wed Mar 18 13:57:04 2015 -0700
    35.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Wed Mar 18 18:21:55 2015 -0700
    35.3 @@ -25,16 +25,14 @@
    35.4  
    35.5  package jdk.nashorn.internal.runtime.linker;
    35.6  
    35.7 +import static jdk.nashorn.internal.runtime.JSType.isString;
    35.8 +
    35.9  import java.lang.invoke.MethodHandle;
   35.10  import java.lang.invoke.MethodHandles;
   35.11 -import java.lang.invoke.MethodType;
   35.12 -import java.util.HashMap;
   35.13  import java.util.Map;
   35.14  import javax.script.Bindings;
   35.15  import jdk.internal.dynalink.CallSiteDescriptor;
   35.16  import jdk.internal.dynalink.linker.GuardedInvocation;
   35.17 -import jdk.internal.dynalink.linker.GuardedTypeConversion;
   35.18 -import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
   35.19  import jdk.internal.dynalink.linker.LinkRequest;
   35.20  import jdk.internal.dynalink.linker.LinkerServices;
   35.21  import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
   35.22 @@ -48,7 +46,7 @@
   35.23   * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
   35.24   * as ScriptObjects from other Nashorn contexts.
   35.25   */
   35.26 -final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory {
   35.27 +final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
   35.28      private final NashornBeansLinker nashornBeansLinker;
   35.29  
   35.30      JSObjectLinker(final NashornBeansLinker nashornBeansLinker) {
   35.31 @@ -94,22 +92,6 @@
   35.32          return Bootstrap.asTypeSafeReturn(inv, linkerServices, desc);
   35.33      }
   35.34  
   35.35 -    @Override
   35.36 -    public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   35.37 -        final boolean sourceIsAlwaysJSObject = JSObject.class.isAssignableFrom(sourceType);
   35.38 -        if(!sourceIsAlwaysJSObject && !sourceType.isAssignableFrom(JSObject.class)) {
   35.39 -            return null;
   35.40 -        }
   35.41 -
   35.42 -        final MethodHandle converter = CONVERTERS.get(targetType);
   35.43 -        if(converter == null) {
   35.44 -            return null;
   35.45 -        }
   35.46 -
   35.47 -        return new GuardedTypeConversion(new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType)), true);
   35.48 -    }
   35.49 -
   35.50 -
   35.51      private GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request, final LinkerServices linkerServices) throws Exception {
   35.52          final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
   35.53          final int c = desc.getNameTokenCount();
   35.54 @@ -185,11 +167,11 @@
   35.55              if (index > -1) {
   35.56                  return ((JSObject)jsobj).getSlot(index);
   35.57              }
   35.58 -        } else if (key instanceof String) {
   35.59 -            final String name = (String)key;
   35.60 +        } else if (isString(key)) {
   35.61 +            final String name = key.toString();
   35.62              // get with method name and signature. delegate it to beans linker!
   35.63              if (name.indexOf('(') != -1) {
   35.64 -                return fallback.invokeExact(jsobj, key);
   35.65 +                return fallback.invokeExact(jsobj, (Object) name);
   35.66              }
   35.67              return ((JSObject)jsobj).getMember(name);
   35.68          }
   35.69 @@ -202,30 +184,11 @@
   35.70              ((JSObject)jsobj).setSlot((Integer)key, value);
   35.71          } else if (key instanceof Number) {
   35.72              ((JSObject)jsobj).setSlot(getIndex((Number)key), value);
   35.73 -        } else if (key instanceof String) {
   35.74 -            ((JSObject)jsobj).setMember((String)key, value);
   35.75 +        } else if (isString(key)) {
   35.76 +            ((JSObject)jsobj).setMember(key.toString(), value);
   35.77          }
   35.78      }
   35.79  
   35.80 -    @SuppressWarnings("unused")
   35.81 -    private static int toInt32(final JSObject obj) {
   35.82 -        return JSType.toInt32(toNumber(obj));
   35.83 -    }
   35.84 -
   35.85 -    @SuppressWarnings("unused")
   35.86 -    private static long toLong(final JSObject obj) {
   35.87 -        return JSType.toLong(toNumber(obj));
   35.88 -    }
   35.89 -
   35.90 -    private static double toNumber(final JSObject obj) {
   35.91 -        return obj == null ? 0 : obj.toNumber();
   35.92 -    }
   35.93 -
   35.94 -    @SuppressWarnings("unused")
   35.95 -    private static boolean toBoolean(final JSObject obj) {
   35.96 -        return obj != null;
   35.97 -    }
   35.98 -
   35.99      private static int getIndex(final Number n) {
  35.100          final double value = n.doubleValue();
  35.101          return JSType.isRepresentableAsInt(value) ? (int)value : -1;
  35.102 @@ -260,14 +223,6 @@
  35.103      private static final MethodHandle JSOBJECT_CALL_TO_APPLY = findOwnMH_S("callToApply", Object.class, MethodHandle.class, JSObject.class, Object.class, Object[].class);
  35.104      private static final MethodHandle JSOBJECT_NEW           = findJSObjectMH_V("newObject", Object.class, Object[].class);
  35.105  
  35.106 -    private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>();
  35.107 -    static {
  35.108 -        CONVERTERS.put(boolean.class, findOwnMH_S("toBoolean", boolean.class, JSObject.class));
  35.109 -        CONVERTERS.put(int.class,     findOwnMH_S("toInt32", int.class, JSObject.class));
  35.110 -        CONVERTERS.put(long.class,    findOwnMH_S("toLong", long.class, JSObject.class));
  35.111 -        CONVERTERS.put(double.class,  findOwnMH_S("toNumber", double.class, JSObject.class));
  35.112 -    }
  35.113 -
  35.114      private static MethodHandle findJSObjectMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
  35.115          return MH.findVirtual(MethodHandles.lookup(), JSObject.class, name, MH.type(rtype, types));
  35.116      }
    36.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Wed Mar 18 13:57:04 2015 -0700
    36.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java	Wed Mar 18 18:21:55 2015 -0700
    36.3 @@ -27,6 +27,7 @@
    36.4  
    36.5  import static jdk.nashorn.internal.lookup.Lookup.MH;
    36.6  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    36.7 +import static jdk.nashorn.internal.runtime.JSType.isString;
    36.8  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    36.9  
   36.10  import java.lang.invoke.MethodHandle;
   36.11 @@ -78,7 +79,7 @@
   36.12          }
   36.13  
   36.14          if (obj == UNDEFINED) {
   36.15 -            // NOTE: same reasoning for FindBugs NP_BOOLEAN_RETURN_NUL warning as in the preceding comment.
   36.16 +            // NOTE: same reasoning for FindBugs NP_BOOLEAN_RETURN_NULL warning as in the preceding comment.
   36.17              return null;
   36.18          }
   36.19  
   36.20 @@ -87,7 +88,7 @@
   36.21              return num != 0 && !Double.isNaN(num);
   36.22          }
   36.23  
   36.24 -        if (obj instanceof String || obj instanceof ConsString) {
   36.25 +        if (isString(obj)) {
   36.26              return ((CharSequence) obj).length() > 0;
   36.27          }
   36.28  
   36.29 @@ -207,7 +208,7 @@
   36.30                  return f.longValue();
   36.31              } else if (obj instanceof Number) {
   36.32                  return ((Number)obj).longValue();
   36.33 -            } else if (obj instanceof String || obj instanceof ConsString) {
   36.34 +            } else if (isString(obj)) {
   36.35                  return JSType.toLong(obj);
   36.36              } else if (obj instanceof Boolean) {
   36.37                  return (Boolean)obj ? 1L : 0L;
    37.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Wed Mar 18 13:57:04 2015 -0700
    37.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Wed Mar 18 18:21:55 2015 -0700
    37.3 @@ -39,6 +39,7 @@
    37.4  import jdk.internal.dynalink.support.TypeUtilities;
    37.5  import jdk.nashorn.internal.objects.Global;
    37.6  import jdk.nashorn.internal.runtime.ConsString;
    37.7 +import jdk.nashorn.internal.runtime.JSType;
    37.8  import jdk.nashorn.internal.runtime.ScriptRuntime;
    37.9  
   37.10  /**
   37.11 @@ -170,7 +171,7 @@
   37.12  
   37.13      @SuppressWarnings("unused")
   37.14      private static boolean isJavaScriptPrimitive(final Object o) {
   37.15 -        return o instanceof String || o instanceof Boolean || o instanceof Number || o instanceof ConsString || o == null;
   37.16 +        return JSType.isString(o) || o instanceof Boolean || o instanceof Number || o == null;
   37.17      }
   37.18  
   37.19      private static final MethodHandle GUARD_PRIMITIVE = findOwnMH("isJavaScriptPrimitive", boolean.class, Object.class);
    38.1 --- a/test/script/basic/JDK-8023026.js.EXPECTED	Wed Mar 18 13:57:04 2015 -0700
    38.2 +++ b/test/script/basic/JDK-8023026.js.EXPECTED	Wed Mar 18 18:21:55 2015 -0700
    38.3 @@ -26,7 +26,7 @@
    38.4  reduceRight 15 1
    38.5  right sum 16
    38.6  squared 1,9,25,49
    38.7 -iterating on [object Array]
    38.8 +iterating on 2,4,6,8
    38.9  forEach 2
   38.10  forEach 4
   38.11  forEach 6
    39.1 --- a/test/script/basic/JDK-8024847.js	Wed Mar 18 13:57:04 2015 -0700
    39.2 +++ b/test/script/basic/JDK-8024847.js	Wed Mar 18 18:21:55 2015 -0700
    39.3 @@ -102,7 +102,18 @@
    39.4  print(jlist);
    39.5  
    39.6  var obj = new JSObject() {
    39.7 -    toNumber: function() { return 42; }
    39.8 +    getMember: function(name) {
    39.9 +        if (name == "valueOf") {
   39.10 +            return new JSObject() {
   39.11 +                isFunction: function() {
   39.12 +                    return true;
   39.13 +                },
   39.14 +                call: function(thiz) {
   39.15 +                    return 42;
   39.16 +                }
   39.17 +            };
   39.18 +        }
   39.19 +    }
   39.20  };
   39.21  
   39.22  print(32 + obj);
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/test/script/basic/JDK-8035712.js	Wed Mar 18 18:21:55 2015 -0700
    40.3 @@ -0,0 +1,282 @@
    40.4 +/*
    40.5 + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
    40.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    40.7 + * 
    40.8 + * This code is free software; you can redistribute it and/or modify it
    40.9 + * under the terms of the GNU General Public License version 2 only, as
   40.10 + * published by the Free Software Foundation.
   40.11 + * 
   40.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   40.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   40.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   40.15 + * version 2 for more details (a copy is included in the LICENSE file that
   40.16 + * accompanied this code).
   40.17 + * 
   40.18 + * You should have received a copy of the GNU General Public License version
   40.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   40.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   40.21 + * 
   40.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   40.23 + * or visit www.oracle.com if you need additional information or have any
   40.24 + * questions.
   40.25 + */
   40.26 +
   40.27 +/**
   40.28 + * JDK-8035712: Restore some of the RuntimeCallSite specializations
   40.29 + *
   40.30 + * @test
   40.31 + * @run
   40.32 + */
   40.33 +
   40.34 +if ((typeof Assert) == "undefined") {
   40.35 +    Assert = { 
   40.36 +        assertTrue: function(x) { if(!x) { throw "expected true" } },
   40.37 +        assertFalse: function(x) { if(x) { throw "expected false" } },
   40.38 +    };
   40.39 +}
   40.40 +
   40.41 +function nop() {}
   40.42 +
   40.43 +function EQ(x, y) {
   40.44 +    // Exercise normal evaluation
   40.45 +    Assert.assertTrue (x == y);
   40.46 +    Assert.assertTrue (y == x);
   40.47 +    Assert.assertFalse(x != y);
   40.48 +    Assert.assertFalse(y != x);
   40.49 +    // Exercise the branch optimizer
   40.50 +    if (x == y) { nop(); } else { Assert.fail(); }
   40.51 +    if (y == x) { nop(); } else { Assert.fail(); }
   40.52 +    if (x != y) { Assert.fail(); } else { nop(); }
   40.53 +    if (y != x) { Assert.fail(); } else { nop(); }
   40.54 +}
   40.55 +
   40.56 +function NE(x, y) {
   40.57 +    // Exercise normal evaluation
   40.58 +    Assert.assertTrue (x != y);
   40.59 +    Assert.assertTrue (y != x);
   40.60 +    Assert.assertFalse(x == y);
   40.61 +    Assert.assertFalse(y == x);
   40.62 +    // Exercise the branch optimizer
   40.63 +    if (x != y) { nop(); } else { Assert.fail(); }
   40.64 +    if (y != x) { nop(); } else { Assert.fail(); }
   40.65 +    if (x == y) { Assert.fail(); } else { nop(); }
   40.66 +    if (y == x) { Assert.fail(); } else { nop(); }
   40.67 +}
   40.68 +
   40.69 +function STRICT_EQ(x, y) {
   40.70 +    // Exercise normal evaluation
   40.71 +    Assert.assertTrue (x === y);
   40.72 +    Assert.assertTrue (y === x);
   40.73 +    Assert.assertFalse(x !== y);
   40.74 +    Assert.assertFalse(y !== x);
   40.75 +    // Exercise the branch optimizer
   40.76 +    if (x === y) { nop(); } else { Assert.fail(); }
   40.77 +    if (y === x) { nop(); } else { Assert.fail(); }
   40.78 +    if (x !== y) { Assert.fail(); } else { nop(); }
   40.79 +    if (y !== x) { Assert.fail(); } else { nop(); }
   40.80 +}
   40.81 +
   40.82 +function STRICT_NE(x, y) {
   40.83 +    // Exercise normal evaluation
   40.84 +    Assert.assertTrue (x !== y);
   40.85 +    Assert.assertTrue (y !== x);
   40.86 +    Assert.assertFalse(x === y);
   40.87 +    Assert.assertFalse(y === x);
   40.88 +    // Exercise the branch optimizer
   40.89 +    if (x !== y) { nop(); } else { Assert.fail(); }
   40.90 +    if (y !== x) { nop(); } else { Assert.fail(); }
   40.91 +    if (x === y) { Assert.fail(); } else { nop(); }
   40.92 +    if (y === x) { Assert.fail(); } else { nop(); }
   40.93 +}
   40.94 +
   40.95 +function cmpToAnyNumber(cmp, value) {
   40.96 +    cmp(1, value);
   40.97 +    cmp(4294967296, value);
   40.98 +    cmp(1.2, value);
   40.99 +    cmp(Infinity, value);
  40.100 +    cmp(-Infinity, value);
  40.101 +    cmp(1/Infinity, value);
  40.102 +    cmp(0, value);
  40.103 +    cmp(-0, value);
  40.104 +    cmp(true, value);
  40.105 +    cmp(false, value);
  40.106 +}
  40.107 +
  40.108 +function notEqualToAnyNumber(value) {
  40.109 +    cmpToAnyNumber(NE, value);
  40.110 +    cmpToAnyNumber(STRICT_NE, value);
  40.111 +}
  40.112 +
  40.113 +notEqualToAnyNumber(null);
  40.114 +notEqualToAnyNumber(void 0);
  40.115 +notEqualToAnyNumber("abc");
  40.116 +notEqualToAnyNumber({});
  40.117 +notEqualToAnyNumber(["xyz"]);
  40.118 +
  40.119 +function objectWithPrimitiveFunctionNotEqualToAnyNumber(fnName) {
  40.120 +    var obj = {
  40.121 +        count: 0
  40.122 +    };
  40.123 +    obj[fnName] = function() { this.count++; return "foo"; };
  40.124 +    notEqualToAnyNumber(obj);
  40.125 +    // Every NE will invoke it 8 times; cmpToAnyNumber has 10 comparisons
  40.126 +    // STRICT_NE doesn't invoke toString.
  40.127 +    Assert.assertTrue(80 === obj.count);
  40.128 +}
  40.129 +objectWithPrimitiveFunctionNotEqualToAnyNumber("valueOf");
  40.130 +objectWithPrimitiveFunctionNotEqualToAnyNumber("toString");
  40.131 +
  40.132 +function objectEqualButNotStrictlyEqual(val, obj) {
  40.133 +    EQ(val, obj);
  40.134 +    STRICT_NE(val, obj);
  40.135 +}
  40.136 +
  40.137 +function numberEqualButNotStrictlyEqualToObject(num, obj) {
  40.138 +    objectEqualButNotStrictlyEqual(num, obj);
  40.139 +    objectEqualButNotStrictlyEqual(num, [obj]);
  40.140 +    objectEqualButNotStrictlyEqual(num, [[obj]]);
  40.141 +}
  40.142 +
  40.143 +function numberEqualButNotStrictlyEqualToZeroObjects(num) {
  40.144 +    numberEqualButNotStrictlyEqualToObject(num, [0]);
  40.145 +    numberEqualButNotStrictlyEqualToObject(num, "");
  40.146 +    numberEqualButNotStrictlyEqualToObject(num, []);
  40.147 +    numberEqualButNotStrictlyEqualToObject(num, "0");
  40.148 +}
  40.149 +
  40.150 +numberEqualButNotStrictlyEqualToZeroObjects(0);
  40.151 +numberEqualButNotStrictlyEqualToZeroObjects(1/Infinity);
  40.152 +numberEqualButNotStrictlyEqualToZeroObjects(false);
  40.153 +
  40.154 +function numberEqualButNotStrictlyEqualToObjectEquivalent(num) {
  40.155 +    var str = String(num);
  40.156 +    objectEqualButNotStrictlyEqual(num, str);
  40.157 +    objectEqualButNotStrictlyEqual(num, { valueOf:  function() { return str }});
  40.158 +    objectEqualButNotStrictlyEqual(num, { toString: function() { return str }});
  40.159 +    objectEqualButNotStrictlyEqual(num, { valueOf:  function() { return num }});
  40.160 +    objectEqualButNotStrictlyEqual(num, { toString: function() { return num }});
  40.161 +}
  40.162 +
  40.163 +numberEqualButNotStrictlyEqualToObjectEquivalent(1);
  40.164 +numberEqualButNotStrictlyEqualToObjectEquivalent(4294967296);
  40.165 +numberEqualButNotStrictlyEqualToObjectEquivalent(1.2);
  40.166 +numberEqualButNotStrictlyEqualToObjectEquivalent(Infinity);
  40.167 +numberEqualButNotStrictlyEqualToObjectEquivalent(-Infinity);
  40.168 +numberEqualButNotStrictlyEqualToObjectEquivalent(1/Infinity);
  40.169 +numberEqualButNotStrictlyEqualToObjectEquivalent(0);
  40.170 +numberEqualButNotStrictlyEqualToObjectEquivalent(-0);
  40.171 +
  40.172 +STRICT_EQ(1, new java.lang.Integer(1));
  40.173 +STRICT_EQ(1, new java.lang.Double(1));
  40.174 +STRICT_EQ(1.2, new java.lang.Double(1.2));
  40.175 +
  40.176 +function LE(x, y) {
  40.177 +    // Exercise normal evaluation
  40.178 +    Assert.assertTrue(x <= y);
  40.179 +    Assert.assertTrue(y >= x);
  40.180 +    Assert.assertFalse(x > y);
  40.181 +    Assert.assertFalse(x < y);
  40.182 +    // Exercise the branch optimizer
  40.183 +    if (x <= y) { nop(); } else { Assert.fail(); }
  40.184 +    if (y >= x) { nop(); } else { Assert.fail(); }
  40.185 +    if (x > y) { Assert.fail(); } else { nop(); }
  40.186 +    if (y < x) { Assert.fail(); } else { nop(); }
  40.187 +}
  40.188 +
  40.189 +function mutuallyLessThanOrEqual(x, y) {
  40.190 +    LE(x, y);
  40.191 +    LE(y, x);
  40.192 +}
  40.193 +
  40.194 +mutuallyLessThanOrEqual(0, null);
  40.195 +mutuallyLessThanOrEqual(false, null);
  40.196 +mutuallyLessThanOrEqual(1/Infinity, null);
  40.197 +
  40.198 +function mutuallyLessThanEqualToObjectWithValue(num, val) {
  40.199 +    mutuallyLessThanOrEqual(num, { valueOf: function() { return val } });
  40.200 +    mutuallyLessThanOrEqual(num, { toString: function() { return val } });
  40.201 +}
  40.202 +
  40.203 +mutuallyLessThanEqualToObjectWithValue(false, 0);
  40.204 +mutuallyLessThanEqualToObjectWithValue(false, "");
  40.205 +
  40.206 +mutuallyLessThanEqualToObjectWithValue(true, 1);
  40.207 +mutuallyLessThanEqualToObjectWithValue(true, "1");
  40.208 +
  40.209 +function lessThanEqualToObjectEquivalent(num) {
  40.210 +    var str = String(num);
  40.211 +    mutuallyLessThanOrEqual(num, str);
  40.212 +    mutuallyLessThanEqualToObjectWithValue(num, num);
  40.213 +    mutuallyLessThanEqualToObjectWithValue(num, str);
  40.214 +}
  40.215 +
  40.216 +lessThanEqualToObjectEquivalent(1);
  40.217 +lessThanEqualToObjectEquivalent(4294967296);
  40.218 +lessThanEqualToObjectEquivalent(1.2);
  40.219 +lessThanEqualToObjectEquivalent(Infinity);
  40.220 +lessThanEqualToObjectEquivalent(-Infinity);
  40.221 +lessThanEqualToObjectEquivalent(1/Infinity);
  40.222 +lessThanEqualToObjectEquivalent(0);
  40.223 +lessThanEqualToObjectEquivalent(-0);
  40.224 +
  40.225 +function INCOMPARABLE(x, y) {
  40.226 +    // Exercise normal evaluation
  40.227 +    Assert.assertFalse(x < y);
  40.228 +    Assert.assertFalse(x > y);
  40.229 +    Assert.assertFalse(x <= y);
  40.230 +    Assert.assertFalse(x >= y);
  40.231 +    Assert.assertFalse(y < x);
  40.232 +    Assert.assertFalse(y > x);
  40.233 +    Assert.assertFalse(y <= x);
  40.234 +    Assert.assertFalse(y >= x);
  40.235 +    // Exercise the branch optimizer
  40.236 +    if (x < y) { Assert.fail(); } else { nop(); }
  40.237 +    if (x > y) { Assert.fail(); } else { nop(); }
  40.238 +    if (x <= y) { Assert.fail(); } else { nop(); }
  40.239 +    if (x >= y) { Assert.fail(); } else { nop(); }
  40.240 +    if (y < x) { Assert.fail(); } else { nop(); }
  40.241 +    if (y > x) { Assert.fail(); } else { nop(); }
  40.242 +    if (y <= x) { Assert.fail(); } else { nop(); }
  40.243 +    if (y >= x) { Assert.fail(); } else { nop(); }
  40.244 +}
  40.245 +
  40.246 +function isIncomparable(value) {
  40.247 +    cmpToAnyNumber(INCOMPARABLE, value);
  40.248 +}
  40.249 +
  40.250 +isIncomparable(void 0);
  40.251 +isIncomparable({ valueOf: function() { return NaN }});
  40.252 +isIncomparable({ toString: function() { return NaN }});
  40.253 +
  40.254 +// Force ScriptRuntime.LT(Object, Object) etc. comparisons
  40.255 +function cmpObj(fn, x, y) {
  40.256 +    fn({valueOf: function() { return x }}, {valueOf: function() { return y }});
  40.257 +}
  40.258 +
  40.259 +function LT(x, y) {
  40.260 +    Assert.assertTrue(x < y);
  40.261 +    Assert.assertTrue(y > x);
  40.262 +    Assert.assertFalse(x >= y);
  40.263 +    Assert.assertFalse(y <= x);
  40.264 +}
  40.265 +
  40.266 +cmpObj(LT, 1, 2);
  40.267 +cmpObj(LT, 1, "2");
  40.268 +cmpObj(LT, "1", 2);
  40.269 +cmpObj(LT, "a", "b");
  40.270 +cmpObj(LT, -Infinity, 0);
  40.271 +cmpObj(LT, 0, Infinity);
  40.272 +cmpObj(LT, -Infinity, Infinity);
  40.273 +cmpObj(INCOMPARABLE, 1, NaN);
  40.274 +cmpObj(INCOMPARABLE, NaN, NaN);
  40.275 +cmpObj(INCOMPARABLE, "boo", NaN);
  40.276 +cmpObj(INCOMPARABLE, 1, "boo"); // boo number value will be NaN
  40.277 +
  40.278 +// Test that a comparison call site can deoptimize from (int, int) to (object, object)
  40.279 +(function(){
  40.280 +    var x = [1,  2,  "a"];
  40.281 +    var y = [2, "3", "b"];
  40.282 +    for(var i = 0; i < 3; ++i) {
  40.283 +        Assert.assertTrue(x[i] < y[i]);
  40.284 +    }
  40.285 +})();
    41.1 --- a/test/script/basic/JDK-8055762.js	Wed Mar 18 13:57:04 2015 -0700
    41.2 +++ b/test/script/basic/JDK-8055762.js	Wed Mar 18 18:21:55 2015 -0700
    41.3 @@ -74,9 +74,12 @@
    41.4          }
    41.5      };
    41.6  
    41.7 +    var a = "a";
    41.8      print(obj["foo"]);
    41.9 +    print(obj[a + "bc"]);
   41.10      print(obj[2]);
   41.11      obj.bar = 23;
   41.12 +    obj[a + "bc"] = 23;
   41.13      obj[3] = 23;
   41.14      obj.func("hello");
   41.15  }
    42.1 --- a/test/script/basic/JDK-8055762.js.EXPECTED	Wed Mar 18 13:57:04 2015 -0700
    42.2 +++ b/test/script/basic/JDK-8055762.js.EXPECTED	Wed Mar 18 18:21:55 2015 -0700
    42.3 @@ -1,5 +1,7 @@
    42.4  FOO
    42.5 +ABC
    42.6  0
    42.7  bar set to 23
    42.8 +abc set to 23
    42.9  [3] set to 23
   42.10  func called with hello
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/test/script/basic/JDK-8072426.js	Wed Mar 18 18:21:55 2015 -0700
    43.3 @@ -0,0 +1,164 @@
    43.4 +/*
    43.5 + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
    43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    43.7 + * 
    43.8 + * This code is free software; you can redistribute it and/or modify it
    43.9 + * under the terms of the GNU General Public License version 2 only, as
   43.10 + * published by the Free Software Foundation.
   43.11 + * 
   43.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   43.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   43.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   43.15 + * version 2 for more details (a copy is included in the LICENSE file that
   43.16 + * accompanied this code).
   43.17 + * 
   43.18 + * You should have received a copy of the GNU General Public License version
   43.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   43.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   43.21 + * 
   43.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   43.23 + * or visit www.oracle.com if you need additional information or have any
   43.24 + * questions.
   43.25 + */
   43.26 +
   43.27 +/**
   43.28 + * JDK-8072426: Can't compare Java objects to strings or numbers
   43.29 + *
   43.30 + * @test
   43.31 + * @run
   43.32 + */
   43.33 +
   43.34 +Assert.assertTrue(java.math.RoundingMode.UP == "UP");
   43.35 +
   43.36 +var JSObject = Java.type("jdk.nashorn.api.scripting.JSObject");
   43.37 +
   43.38 +// Adds an "isFunction" member to the JSObject that returns the specified value
   43.39 +function addIsFunction(isFunction, obj) {
   43.40 +    obj.isFunction = function() {
   43.41 +        return isFunction;
   43.42 +    };
   43.43 +    return obj;
   43.44 +}
   43.45 +
   43.46 +function makeJSObjectConstantFunction(value) {
   43.47 +    return new JSObject(addIsFunction(true, {
   43.48 +        call: function() {
   43.49 +            return value;
   43.50 +        }
   43.51 +    }));
   43.52 +}
   43.53 +
   43.54 +function makeJSObjectWithMembers(mapping) {
   43.55 +    return new JSObject({
   43.56 +        getMember: function(name) {
   43.57 +            Assert.assertTrue(mapping.hasOwnProperty(name));
   43.58 +            return mapping[name];
   43.59 +        },
   43.60 +        toNumber: function() {
   43.61 +            // toNumber no longer invoked
   43.62 +            Assert.fail();
   43.63 +        }
   43.64 +    });
   43.65 +}
   43.66 +
   43.67 +// Test JSObjectLinker toInt32/toLong/toNumber
   43.68 +function testNumericJSObject(kind, value) {
   43.69 +    var obj = makeJSObjectWithMembers({
   43.70 +            valueOf: makeJSObjectConstantFunction(value)
   43.71 +        });
   43.72 +
   43.73 +    if (kind === "double") {
   43.74 +        // There's no assertEquals(double actual, double expected). There's only
   43.75 +        // assertEquals(double actual, double expected, double delta).
   43.76 +        Assert["assertEquals(double,double,double)"](value, obj, 0);
   43.77 +    } else {
   43.78 +        Assert["assertEquals(" + kind + ", " + kind + ")"](value, obj);
   43.79 +    }
   43.80 +    Assert.assertTrue(value == Number(obj));
   43.81 +}
   43.82 +testNumericJSObject("int", 42);
   43.83 +testNumericJSObject("long", 4294967296);
   43.84 +testNumericJSObject("double", 1.2);
   43.85 +
   43.86 +// Test fallback from toNumber to toString for numeric conversion when toNumber doesn't exist
   43.87 +(function() {
   43.88 +    var obj = makeJSObjectWithMembers({
   43.89 +        valueOf:  null, // Explicitly no valueOf
   43.90 +        toString: makeJSObjectConstantFunction("123")
   43.91 +    });
   43.92 +    Assert["assertEquals(int,int)"](123, obj);
   43.93 +})();
   43.94 +
   43.95 +// Test fallback from toNumber to toString for numeric conversion when toNumber isn't a callable
   43.96 +(function() {
   43.97 +    var obj = makeJSObjectWithMembers({
   43.98 +        valueOf:  new JSObject(addIsFunction(false, {})),
   43.99 +        toString: makeJSObjectConstantFunction("124")
  43.100 +    });
  43.101 +    Assert["assertEquals(int,int)"](124, obj);
  43.102 +})();
  43.103 +
  43.104 +// Test fallback from toNumber to toString for numeric conversion when toNumber returns a non-primitive
  43.105 +(function() {
  43.106 +    var obj = makeJSObjectWithMembers({
  43.107 +        valueOf:  makeJSObjectConstantFunction({}),
  43.108 +        toString: makeJSObjectConstantFunction("125")
  43.109 +    });
  43.110 +    Assert["assertEquals(int,int)"](125, obj);
  43.111 +})();
  43.112 +
  43.113 +// Test TypeError from toNumber to toString when both return a non-primitive
  43.114 +(function() {
  43.115 +    var obj = makeJSObjectWithMembers({
  43.116 +        valueOf:  makeJSObjectConstantFunction({}),
  43.117 +        toString: makeJSObjectConstantFunction({})
  43.118 +    });
  43.119 +    try {
  43.120 +        Number(obj);
  43.121 +        Assert.fail(); // must throw
  43.122 +    } catch(e) {
  43.123 +        Assert.assertTrue(e instanceof TypeError); 
  43.124 +    }
  43.125 +})();
  43.126 +
  43.127 +// Test toString for string conversion
  43.128 +(function() {
  43.129 +    var obj = makeJSObjectWithMembers({
  43.130 +        toString: makeJSObjectConstantFunction("Hello")
  43.131 +    });
  43.132 +    Assert.assertTrue("Hello" === String(obj));
  43.133 +    Assert["assertEquals(String,String)"]("Hello", obj);
  43.134 +})();
  43.135 +
  43.136 +// Test fallback from toString to valueOf for string conversion when toString doesn't exist
  43.137 +(function() {
  43.138 +    var obj = makeJSObjectWithMembers({
  43.139 +        toString: null,
  43.140 +        valueOf:  makeJSObjectConstantFunction("Hello1")
  43.141 +    });
  43.142 +    Assert.assertTrue("Hello1" === String(obj));
  43.143 +    Assert["assertEquals(String,String)"]("Hello1", obj);
  43.144 +})();
  43.145 +
  43.146 +// Test fallback from toString to valueOf for string conversion when toString is not callable
  43.147 +(function() {
  43.148 +    var obj = makeJSObjectWithMembers({
  43.149 +        toString: new JSObject(addIsFunction(false, {})),
  43.150 +        valueOf:  makeJSObjectConstantFunction("Hello2")
  43.151 +    });
  43.152 +    Assert["assertEquals(String,String)"]("Hello2", obj);
  43.153 +})();
  43.154 +
  43.155 +// Test fallback from toString to valueOf for string conversion when toString returns non-primitive
  43.156 +(function() {
  43.157 +    var obj = makeJSObjectWithMembers({
  43.158 +        toString: makeJSObjectConstantFunction({}),
  43.159 +        valueOf:  makeJSObjectConstantFunction("Hello3")
  43.160 +    });
  43.161 +    Assert["assertEquals(String,String)"]("Hello3", obj);
  43.162 +})();
  43.163 +
  43.164 +// Test toBoolean for JSObject
  43.165 +(function() {
  43.166 +    Assert["assertEquals(boolean,boolean)"](true, new JSObject({}));
  43.167 +})();
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/test/script/basic/JDK-8074545.js	Wed Mar 18 18:21:55 2015 -0700
    44.3 @@ -0,0 +1,1038 @@
    44.4 +/*
    44.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    44.7 + * 
    44.8 + * This code is free software; you can redistribute it and/or modify it
    44.9 + * under the terms of the GNU General Public License version 2 only, as
   44.10 + * published by the Free Software Foundation.
   44.11 + * 
   44.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   44.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   44.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   44.15 + * version 2 for more details (a copy is included in the LICENSE file that
   44.16 + * accompanied this code).
   44.17 + * 
   44.18 + * You should have received a copy of the GNU General Public License version
   44.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   44.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   44.21 + * 
   44.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   44.23 + * or visit www.oracle.com if you need additional information or have any
   44.24 + * questions.
   44.25 + */
   44.26 +
   44.27 +/**
   44.28 + * JDK-8074545: Undefined object values in object literals with spill properties
   44.29 + *
   44.30 + * @test
   44.31 + * @run
   44.32 + */
   44.33 +
   44.34 +var obj = {
   44.35 +    "p0": { "x" : 0 },
   44.36 +    "p1": { "x" : 1 },
   44.37 +    "p2": { "x" : 2 },
   44.38 +    "p3": { "x" : 3 },
   44.39 +    "p4": { "x" : 4 },
   44.40 +    "p5": { "x" : 5 },
   44.41 +    "p6": { "x" : 6 },
   44.42 +    "p7": { "x" : 7 },
   44.43 +    "p8": { "x" : 8 },
   44.44 +    "p9": { "x" : 9 },
   44.45 +    "p10": { "x" : 10 },
   44.46 +    "p11": { "x" : 11 },
   44.47 +    "p12": { "x" : 12 },
   44.48 +    "p13": { "x" : 13 },
   44.49 +    "p14": { "x" : 14 },
   44.50 +    "p15": { "x" : 15 },
   44.51 +    "p16": { "x" : 16 },
   44.52 +    "p17": { "x" : 17 },
   44.53 +    "p18": { "x" : 18 },
   44.54 +    "p19": { "x" : 19 },
   44.55 +    "p20": { "x" : 20 },
   44.56 +    "p21": { "x" : 21 },
   44.57 +    "p22": { "x" : 22 },
   44.58 +    "p23": { "x" : 23 },
   44.59 +    "p24": { "x" : 24 },
   44.60 +    "p25": { "x" : 25 },
   44.61 +    "p26": { "x" : 26 },
   44.62 +    "p27": { "x" : 27 },
   44.63 +    "p28": { "x" : 28 },
   44.64 +    "p29": { "x" : 29 },
   44.65 +    "p30": { "x" : 30 },
   44.66 +    "p31": { "x" : 31 },
   44.67 +    "p32": { "x" : 32 },
   44.68 +    "p33": { "x" : 33 },
   44.69 +    "p34": { "x" : 34 },
   44.70 +    "p35": { "x" : 35 },
   44.71 +    "p36": { "x" : 36 },
   44.72 +    "p37": { "x" : 37 },
   44.73 +    "p38": { "x" : 38 },
   44.74 +    "p39": { "x" : 39 },
   44.75 +    "p40": { "x" : 40 },
   44.76 +    "p41": { "x" : 41 },
   44.77 +    "p42": { "x" : 42 },
   44.78 +    "p43": { "x" : 43 },
   44.79 +    "p44": { "x" : 44 },
   44.80 +    "p45": { "x" : 45 },
   44.81 +    "p46": { "x" : 46 },
   44.82 +    "p47": { "x" : 47 },
   44.83 +    "p48": { "x" : 48 },
   44.84 +    "p49": { "x" : 49 },
   44.85 +    "p50": { "x" : 50 },
   44.86 +    "p51": { "x" : 51 },
   44.87 +    "p52": { "x" : 52 },
   44.88 +    "p53": { "x" : 53 },
   44.89 +    "p54": { "x" : 54 },
   44.90 +    "p55": { "x" : 55 },
   44.91 +    "p56": { "x" : 56 },
   44.92 +    "p57": { "x" : 57 },
   44.93 +    "p58": { "x" : 58 },
   44.94 +    "p59": { "x" : 59 },
   44.95 +    "p60": { "x" : 60 },
   44.96 +    "p61": { "x" : 61 },
   44.97 +    "p62": { "x" : 62 },
   44.98 +    "p63": { "x" : 63 },
   44.99 +    "p64": { "x" : 64 },
  44.100 +    "p65": { "x" : 65 },
  44.101 +    "p66": { "x" : 66 },
  44.102 +    "p67": { "x" : 67 },
  44.103 +    "p68": { "x" : 68 },
  44.104 +    "p69": { "x" : 69 },
  44.105 +    "p70": { "x" : 70 },
  44.106 +    "p71": { "x" : 71 },
  44.107 +    "p72": { "x" : 72 },
  44.108 +    "p73": { "x" : 73 },
  44.109 +    "p74": { "x" : 74 },
  44.110 +    "p75": { "x" : 75 },
  44.111 +    "p76": { "x" : 76 },
  44.112 +    "p77": { "x" : 77 },
  44.113 +    "p78": { "x" : 78 },
  44.114 +    "p79": { "x" : 79 },
  44.115 +    "p80": { "x" : 80 },
  44.116 +    "p81": { "x" : 81 },
  44.117 +    "p82": { "x" : 82 },
  44.118 +    "p83": { "x" : 83 },
  44.119 +    "p84": { "x" : 84 },
  44.120 +    "p85": { "x" : 85 },
  44.121 +    "p86": { "x" : 86 },
  44.122 +    "p87": { "x" : 87 },
  44.123 +    "p88": { "x" : 88 },
  44.124 +    "p89": { "x" : 89 },
  44.125 +    "p90": { "x" : 90 },
  44.126 +    "p91": { "x" : 91 },
  44.127 +    "p92": { "x" : 92 },
  44.128 +    "p93": { "x" : 93 },
  44.129 +    "p94": { "x" : 94 },
  44.130 +    "p95": { "x" : 95 },
  44.131 +    "p96": { "x" : 96 },
  44.132 +    "p97": { "x" : 97 },
  44.133 +    "p98": { "x" : 98 },
  44.134 +    "p99": { "x" : 99 },
  44.135 +    "p100": { "x" : 100 },
  44.136 +    "p101": { "x" : 101 },
  44.137 +    "p102": { "x" : 102 },
  44.138 +    "p103": { "x" : 103 },
  44.139 +    "p104": { "x" : 104 },
  44.140 +    "p105": { "x" : 105 },
  44.141 +    "p106": { "x" : 106 },
  44.142 +    "p107": { "x" : 107 },
  44.143 +    "p108": { "x" : 108 },
  44.144 +    "p109": { "x" : 109 },
  44.145 +    "p110": { "x" : 110 },
  44.146 +    "p111": { "x" : 111 },
  44.147 +    "p112": { "x" : 112 },
  44.148 +    "p113": { "x" : 113 },
  44.149 +    "p114": { "x" : 114 },
  44.150 +    "p115": { "x" : 115 },
  44.151 +    "p116": { "x" : 116 },
  44.152 +    "p117": { "x" : 117 },
  44.153 +    "p118": { "x" : 118 },
  44.154 +    "p119": { "x" : 119 },
  44.155 +    "p120": { "x" : 120 },
  44.156 +    "p121": { "x" : 121 },
  44.157 +    "p122": { "x" : 122 },
  44.158 +    "p123": { "x" : 123 },
  44.159 +    "p124": { "x" : 124 },
  44.160 +    "p125": { "x" : 125 },
  44.161 +    "p126": { "x" : 126 },
  44.162 +    "p127": { "x" : 127 },
  44.163 +    "p128": { "x" : 128 },
  44.164 +    "p129": { "x" : 129 },
  44.165 +    "p130": { "x" : 130 },
  44.166 +    "p131": { "x" : 131 },
  44.167 +    "p132": { "x" : 132 },
  44.168 +    "p133": { "x" : 133 },
  44.169 +    "p134": { "x" : 134 },
  44.170 +    "p135": { "x" : 135 },
  44.171 +    "p136": { "x" : 136 },
  44.172 +    "p137": { "x" : 137 },
  44.173 +    "p138": { "x" : 138 },
  44.174 +    "p139": { "x" : 139 },
  44.175 +    "p140": { "x" : 140 },
  44.176 +    "p141": { "x" : 141 },
  44.177 +    "p142": { "x" : 142 },
  44.178 +    "p143": { "x" : 143 },
  44.179 +    "p144": { "x" : 144 },
  44.180 +    "p145": { "x" : 145 },
  44.181 +    "p146": { "x" : 146 },
  44.182 +    "p147": { "x" : 147 },
  44.183 +    "p148": { "x" : 148 },
  44.184 +    "p149": { "x" : 149 },
  44.185 +    "p150": { "x" : 150 },
  44.186 +    "p151": { "x" : 151 },
  44.187 +    "p152": { "x" : 152 },
  44.188 +    "p153": { "x" : 153 },
  44.189 +    "p154": { "x" : 154 },
  44.190 +    "p155": { "x" : 155 },
  44.191 +    "p156": { "x" : 156 },
  44.192 +    "p157": { "x" : 157 },
  44.193 +    "p158": { "x" : 158 },
  44.194 +    "p159": { "x" : 159 },
  44.195 +    "p160": { "x" : 160 },
  44.196 +    "p161": { "x" : 161 },
  44.197 +    "p162": { "x" : 162 },
  44.198 +    "p163": { "x" : 163 },
  44.199 +    "p164": { "x" : 164 },
  44.200 +    "p165": { "x" : 165 },
  44.201 +    "p166": { "x" : 166 },
  44.202 +    "p167": { "x" : 167 },
  44.203 +    "p168": { "x" : 168 },
  44.204 +    "p169": { "x" : 169 },
  44.205 +    "p170": { "x" : 170 },
  44.206 +    "p171": { "x" : 171 },
  44.207 +    "p172": { "x" : 172 },
  44.208 +    "p173": { "x" : 173 },
  44.209 +    "p174": { "x" : 174 },
  44.210 +    "p175": { "x" : 175 },
  44.211 +    "p176": { "x" : 176 },
  44.212 +    "p177": { "x" : 177 },
  44.213 +    "p178": { "x" : 178 },
  44.214 +    "p179": { "x" : 179 },
  44.215 +    "p180": { "x" : 180 },
  44.216 +    "p181": { "x" : 181 },
  44.217 +    "p182": { "x" : 182 },
  44.218 +    "p183": { "x" : 183 },
  44.219 +    "p184": { "x" : 184 },
  44.220 +    "p185": { "x" : 185 },
  44.221 +    "p186": { "x" : 186 },
  44.222 +    "p187": { "x" : 187 },
  44.223 +    "p188": { "x" : 188 },
  44.224 +    "p189": { "x" : 189 },
  44.225 +    "p190": { "x" : 190 },
  44.226 +    "p191": { "x" : 191 },
  44.227 +    "p192": { "x" : 192 },
  44.228 +    "p193": { "x" : 193 },
  44.229 +    "p194": { "x" : 194 },
  44.230 +    "p195": { "x" : 195 },
  44.231 +    "p196": { "x" : 196 },
  44.232 +    "p197": { "x" : 197 },
  44.233 +    "p198": { "x" : 198 },
  44.234 +    "p199": { "x" : 199 },
  44.235 +    "p200": { "x" : 200 },
  44.236 +    "p201": { "x" : 201 },
  44.237 +    "p202": { "x" : 202 },
  44.238 +    "p203": { "x" : 203 },
  44.239 +    "p204": { "x" : 204 },
  44.240 +    "p205": { "x" : 205 },
  44.241 +    "p206": { "x" : 206 },
  44.242 +    "p207": { "x" : 207 },
  44.243 +    "p208": { "x" : 208 },
  44.244 +    "p209": { "x" : 209 },
  44.245 +    "p210": { "x" : 210 },
  44.246 +    "p211": { "x" : 211 },
  44.247 +    "p212": { "x" : 212 },
  44.248 +    "p213": { "x" : 213 },
  44.249 +    "p214": { "x" : 214 },
  44.250 +    "p215": { "x" : 215 },
  44.251 +    "p216": { "x" : 216 },
  44.252 +    "p217": { "x" : 217 },
  44.253 +    "p218": { "x" : 218 },
  44.254 +    "p219": { "x" : 219 },
  44.255 +    "p220": { "x" : 220 },
  44.256 +    "p221": { "x" : 221 },
  44.257 +    "p222": { "x" : 222 },
  44.258 +    "p223": { "x" : 223 },
  44.259 +    "p224": { "x" : 224 },
  44.260 +    "p225": { "x" : 225 },
  44.261 +    "p226": { "x" : 226 },
  44.262 +    "p227": { "x" : 227 },
  44.263 +    "p228": { "x" : 228 },
  44.264 +    "p229": { "x" : 229 },
  44.265 +    "p230": { "x" : 230 },
  44.266 +    "p231": { "x" : 231 },
  44.267 +    "p232": { "x" : 232 },
  44.268 +    "p233": { "x" : 233 },
  44.269 +    "p234": { "x" : 234 },
  44.270 +    "p235": { "x" : 235 },
  44.271 +    "p236": { "x" : 236 },
  44.272 +    "p237": { "x" : 237 },
  44.273 +    "p238": { "x" : 238 },
  44.274 +    "p239": { "x" : 239 },
  44.275 +    "p240": { "x" : 240 },
  44.276 +    "p241": { "x" : 241 },
  44.277 +    "p242": { "x" : 242 },
  44.278 +    "p243": { "x" : 243 },
  44.279 +    "p244": { "x" : 244 },
  44.280 +    "p245": { "x" : 245 },
  44.281 +    "p246": { "x" : 246 },
  44.282 +    "p247": { "x" : 247 },
  44.283 +    "p248": { "x" : 248 },
  44.284 +    "p249": { "x" : 249 },
  44.285 +    "p250": { "x" : 250 },
  44.286 +    "p251": { "x" : 251 },
  44.287 +    "p252": { "x" : 252 },
  44.288 +    "p253": { "x" : 253 },
  44.289 +    "p254": { "x" : 254 },
  44.290 +    "p255": { "x" : 255 },
  44.291 +    "p256": { "x" : 256 },
  44.292 +    "p257": { "x" : 257 },
  44.293 +    "p258": { "x" : 258 },
  44.294 +    "p259": { "x" : 259 },
  44.295 +    "p260": { "x" : 260 },
  44.296 +    "p261": { "x" : 261 },
  44.297 +    "p262": { "x" : 262 },
  44.298 +    "p263": { "x" : 263 },
  44.299 +    "p264": { "x" : 264 },
  44.300 +    "p265": { "x" : 265 },
  44.301 +    "p266": { "x" : 266 },
  44.302 +    "p267": { "x" : 267 },
  44.303 +    "p268": { "x" : 268 },
  44.304 +    "p269": { "x" : 269 },
  44.305 +    "p270": { "x" : 270 },
  44.306 +    "p271": { "x" : 271 },
  44.307 +    "p272": { "x" : 272 },
  44.308 +    "p273": { "x" : 273 },
  44.309 +    "p274": { "x" : 274 },
  44.310 +    "p275": { "x" : 275 },
  44.311 +    "p276": { "x" : 276 },
  44.312 +    "p277": { "x" : 277 },
  44.313 +    "p278": { "x" : 278 },
  44.314 +    "p279": { "x" : 279 },
  44.315 +    "p280": { "x" : 280 },
  44.316 +    "p281": { "x" : 281 },
  44.317 +    "p282": { "x" : 282 },
  44.318 +    "p283": { "x" : 283 },
  44.319 +    "p284": { "x" : 284 },
  44.320 +    "p285": { "x" : 285 },
  44.321 +    "p286": { "x" : 286 },
  44.322 +    "p287": { "x" : 287 },
  44.323 +    "p288": { "x" : 288 },
  44.324 +    "p289": { "x" : 289 },
  44.325 +    "p290": { "x" : 290 },
  44.326 +    "p291": { "x" : 291 },
  44.327 +    "p292": { "x" : 292 },
  44.328 +    "p293": { "x" : 293 },
  44.329 +    "p294": { "x" : 294 },
  44.330 +    "p295": { "x" : 295 },
  44.331 +    "p296": { "x" : 296 },
  44.332 +    "p297": { "x" : 297 },
  44.333 +    "p298": { "x" : 298 },
  44.334 +    "p299": { "x" : 299 },
  44.335 +    "p300": { "x" : 300 },
  44.336 +    "p301": { "x" : 301 },
  44.337 +    "p302": { "x" : 302 },
  44.338 +    "p303": { "x" : 303 },
  44.339 +    "p304": { "x" : 304 },
  44.340 +    "p305": { "x" : 305 },
  44.341 +    "p306": { "x" : 306 },
  44.342 +    "p307": { "x" : 307 },
  44.343 +    "p308": { "x" : 308 },
  44.344 +    "p309": { "x" : 309 },
  44.345 +    "p310": { "x" : 310 },
  44.346 +    "p311": { "x" : 311 },
  44.347 +    "p312": { "x" : 312 },
  44.348 +    "p313": { "x" : 313 },
  44.349 +    "p314": { "x" : 314 },
  44.350 +    "p315": { "x" : 315 },
  44.351 +    "p316": { "x" : 316 },
  44.352 +    "p317": { "x" : 317 },
  44.353 +    "p318": { "x" : 318 },
  44.354 +    "p319": { "x" : 319 },
  44.355 +    "p320": { "x" : 320 },
  44.356 +    "p321": { "x" : 321 },
  44.357 +    "p322": { "x" : 322 },
  44.358 +    "p323": { "x" : 323 },
  44.359 +    "p324": { "x" : 324 },
  44.360 +    "p325": { "x" : 325 },
  44.361 +    "p326": { "x" : 326 },
  44.362 +    "p327": { "x" : 327 },
  44.363 +    "p328": { "x" : 328 },
  44.364 +    "p329": { "x" : 329 },
  44.365 +    "p330": { "x" : 330 },
  44.366 +    "p331": { "x" : 331 },
  44.367 +    "p332": { "x" : 332 },
  44.368 +    "p333": { "x" : 333 },
  44.369 +    "p334": { "x" : 334 },
  44.370 +    "p335": { "x" : 335 },
  44.371 +    "p336": { "x" : 336 },
  44.372 +    "p337": { "x" : 337 },
  44.373 +    "p338": { "x" : 338 },
  44.374 +    "p339": { "x" : 339 },
  44.375 +    "p340": { "x" : 340 },
  44.376 +    "p341": { "x" : 341 },
  44.377 +    "p342": { "x" : 342 },
  44.378 +    "p343": { "x" : 343 },
  44.379 +    "p344": { "x" : 344 },
  44.380 +    "p345": { "x" : 345 },
  44.381 +    "p346": { "x" : 346 },
  44.382 +    "p347": { "x" : 347 },
  44.383 +    "p348": { "x" : 348 },
  44.384 +    "p349": { "x" : 349 },
  44.385 +    "p350": { "x" : 350 },
  44.386 +    "p351": { "x" : 351 },
  44.387 +    "p352": { "x" : 352 },
  44.388 +    "p353": { "x" : 353 },
  44.389 +    "p354": { "x" : 354 },
  44.390 +    "p355": { "x" : 355 },
  44.391 +    "p356": { "x" : 356 },
  44.392 +    "p357": { "x" : 357 },
  44.393 +    "p358": { "x" : 358 },
  44.394 +    "p359": { "x" : 359 },
  44.395 +    "p360": { "x" : 360 },
  44.396 +    "p361": { "x" : 361 },
  44.397 +    "p362": { "x" : 362 },
  44.398 +    "p363": { "x" : 363 },
  44.399 +    "p364": { "x" : 364 },
  44.400 +    "p365": { "x" : 365 },
  44.401 +    "p366": { "x" : 366 },
  44.402 +    "p367": { "x" : 367 },
  44.403 +    "p368": { "x" : 368 },
  44.404 +    "p369": { "x" : 369 },
  44.405 +    "p370": { "x" : 370 },
  44.406 +    "p371": { "x" : 371 },
  44.407 +    "p372": { "x" : 372 },
  44.408 +    "p373": { "x" : 373 },
  44.409 +    "p374": { "x" : 374 },
  44.410 +    "p375": { "x" : 375 },
  44.411 +    "p376": { "x" : 376 },
  44.412 +    "p377": { "x" : 377 },
  44.413 +    "p378": { "x" : 378 },
  44.414 +    "p379": { "x" : 379 },
  44.415 +    "p380": { "x" : 380 },
  44.416 +    "p381": { "x" : 381 },
  44.417 +    "p382": { "x" : 382 },
  44.418 +    "p383": { "x" : 383 },
  44.419 +    "p384": { "x" : 384 },
  44.420 +    "p385": { "x" : 385 },
  44.421 +    "p386": { "x" : 386 },
  44.422 +    "p387": { "x" : 387 },
  44.423 +    "p388": { "x" : 388 },
  44.424 +    "p389": { "x" : 389 },
  44.425 +    "p390": { "x" : 390 },
  44.426 +    "p391": { "x" : 391 },
  44.427 +    "p392": { "x" : 392 },
  44.428 +    "p393": { "x" : 393 },
  44.429 +    "p394": { "x" : 394 },
  44.430 +    "p395": { "x" : 395 },
  44.431 +    "p396": { "x" : 396 },
  44.432 +    "p397": { "x" : 397 },
  44.433 +    "p398": { "x" : 398 },
  44.434 +    "p399": { "x" : 399 },
  44.435 +    "p400": { "x" : 400 },
  44.436 +    "p401": { "x" : 401 },
  44.437 +    "p402": { "x" : 402 },
  44.438 +    "p403": { "x" : 403 },
  44.439 +    "p404": { "x" : 404 },
  44.440 +    "p405": { "x" : 405 },
  44.441 +    "p406": { "x" : 406 },
  44.442 +    "p407": { "x" : 407 },
  44.443 +    "p408": { "x" : 408 },
  44.444 +    "p409": { "x" : 409 },
  44.445 +    "p410": { "x" : 410 },
  44.446 +    "p411": { "x" : 411 },
  44.447 +    "p412": { "x" : 412 },
  44.448 +    "p413": { "x" : 413 },
  44.449 +    "p414": { "x" : 414 },
  44.450 +    "p415": { "x" : 415 },
  44.451 +    "p416": { "x" : 416 },
  44.452 +    "p417": { "x" : 417 },
  44.453 +    "p418": { "x" : 418 },
  44.454 +    "p419": { "x" : 419 },
  44.455 +    "p420": { "x" : 420 },
  44.456 +    "p421": { "x" : 421 },
  44.457 +    "p422": { "x" : 422 },
  44.458 +    "p423": { "x" : 423 },
  44.459 +    "p424": { "x" : 424 },
  44.460 +    "p425": { "x" : 425 },
  44.461 +    "p426": { "x" : 426 },
  44.462 +    "p427": { "x" : 427 },
  44.463 +    "p428": { "x" : 428 },
  44.464 +    "p429": { "x" : 429 },
  44.465 +    "p430": { "x" : 430 },
  44.466 +    "p431": { "x" : 431 },
  44.467 +    "p432": { "x" : 432 },
  44.468 +    "p433": { "x" : 433 },
  44.469 +    "p434": { "x" : 434 },
  44.470 +    "p435": { "x" : 435 },
  44.471 +    "p436": { "x" : 436 },
  44.472 +    "p437": { "x" : 437 },
  44.473 +    "p438": { "x" : 438 },
  44.474 +    "p439": { "x" : 439 },
  44.475 +    "p440": { "x" : 440 },
  44.476 +    "p441": { "x" : 441 },
  44.477 +    "p442": { "x" : 442 },
  44.478 +    "p443": { "x" : 443 },
  44.479 +    "p444": { "x" : 444 },
  44.480 +    "p445": { "x" : 445 },
  44.481 +    "p446": { "x" : 446 },
  44.482 +    "p447": { "x" : 447 },
  44.483 +    "p448": { "x" : 448 },
  44.484 +    "p449": { "x" : 449 },
  44.485 +    "p450": { "x" : 450 },
  44.486 +    "p451": { "x" : 451 },
  44.487 +    "p452": { "x" : 452 },
  44.488 +    "p453": { "x" : 453 },
  44.489 +    "p454": { "x" : 454 },
  44.490 +    "p455": { "x" : 455 },
  44.491 +    "p456": { "x" : 456 },
  44.492 +    "p457": { "x" : 457 },
  44.493 +    "p458": { "x" : 458 },
  44.494 +    "p459": { "x" : 459 },
  44.495 +    "p460": { "x" : 460 },
  44.496 +    "p461": { "x" : 461 },
  44.497 +    "p462": { "x" : 462 },
  44.498 +    "p463": { "x" : 463 },
  44.499 +    "p464": { "x" : 464 },
  44.500 +    "p465": { "x" : 465 },
  44.501 +    "p466": { "x" : 466 },
  44.502 +    "p467": { "x" : 467 },
  44.503 +    "p468": { "x" : 468 },
  44.504 +    "p469": { "x" : 469 },
  44.505 +    "p470": { "x" : 470 },
  44.506 +    "p471": { "x" : 471 },
  44.507 +    "p472": { "x" : 472 },
  44.508 +    "p473": { "x" : 473 },
  44.509 +    "p474": { "x" : 474 },
  44.510 +    "p475": { "x" : 475 },
  44.511 +    "p476": { "x" : 476 },
  44.512 +    "p477": { "x" : 477 },
  44.513 +    "p478": { "x" : 478 },
  44.514 +    "p479": { "x" : 479 },
  44.515 +    "p480": { "x" : 480 },
  44.516 +    "p481": { "x" : 481 },
  44.517 +    "p482": { "x" : 482 },
  44.518 +    "p483": { "x" : 483 },
  44.519 +    "p484": { "x" : 484 },
  44.520 +    "p485": { "x" : 485 },
  44.521 +    "p486": { "x" : 486 },
  44.522 +    "p487": { "x" : 487 },
  44.523 +    "p488": { "x" : 488 },
  44.524 +    "p489": { "x" : 489 },
  44.525 +    "p490": { "x" : 490 },
  44.526 +    "p491": { "x" : 491 },
  44.527 +    "p492": { "x" : 492 },
  44.528 +    "p493": { "x" : 493 },
  44.529 +    "p494": { "x" : 494 },
  44.530 +    "p495": { "x" : 495 },
  44.531 +    "p496": { "x" : 496 },
  44.532 +    "p497": { "x" : 497 },
  44.533 +    "p498": { "x" : 498 },
  44.534 +    "p499": { "x" : 499 },
  44.535 +    "p500": { "x" : 500 },
  44.536 +    "p501": { "x" : 501 },
  44.537 +    "p502": { "x" : 502 },
  44.538 +    "p503": { "x" : 503 },
  44.539 +    "p504": { "x" : 504 },
  44.540 +    "p505": { "x" : 505 },
  44.541 +    "p506": { "x" : 506 },
  44.542 +    "p507": { "x" : 507 },
  44.543 +    "p508": { "x" : 508 },
  44.544 +    "p509": { "x" : 509 },
  44.545 +    "p510": { "x" : 510 },
  44.546 +    "p511": { "x" : 511 },
  44.547 +    "p512": { "x" : 512 },
  44.548 +    "p513": { "x" : 513 },
  44.549 +    "p514": { "x" : 514 },
  44.550 +    "p515": { "x" : 515 },
  44.551 +    "p516": { "x" : 516 },
  44.552 +    "p517": { "x" : 517 },
  44.553 +    "p518": { "x" : 518 },
  44.554 +    "p519": { "x" : 519 },
  44.555 +    "p520": { "x" : 520 },
  44.556 +    "p521": { "x" : 521 },
  44.557 +    "p522": { "x" : 522 },
  44.558 +    "p523": { "x" : 523 },
  44.559 +    "p524": { "x" : 524 },
  44.560 +    "p525": { "x" : 525 },
  44.561 +    "p526": { "x" : 526 },
  44.562 +    "p527": { "x" : 527 },
  44.563 +    "p528": { "x" : 528 },
  44.564 +    "p529": { "x" : 529 },
  44.565 +    "p530": { "x" : 530 },
  44.566 +    "p531": { "x" : 531 },
  44.567 +    "p532": { "x" : 532 },
  44.568 +    "p533": { "x" : 533 },
  44.569 +    "p534": { "x" : 534 },
  44.570 +    "p535": { "x" : 535 },
  44.571 +    "p536": { "x" : 536 },
  44.572 +    "p537": { "x" : 537 },
  44.573 +    "p538": { "x" : 538 },
  44.574 +    "p539": { "x" : 539 },
  44.575 +    "p540": { "x" : 540 },
  44.576 +    "p541": { "x" : 541 },
  44.577 +    "p542": { "x" : 542 },
  44.578 +    "p543": { "x" : 543 },
  44.579 +    "p544": { "x" : 544 },
  44.580 +    "p545": { "x" : 545 },
  44.581 +    "p546": { "x" : 546 },
  44.582 +    "p547": { "x" : 547 },
  44.583 +    "p548": { "x" : 548 },
  44.584 +    "p549": { "x" : 549 },
  44.585 +    "p550": { "x" : 550 },
  44.586 +    "p551": { "x" : 551 },
  44.587 +    "p552": { "x" : 552 },
  44.588 +    "p553": { "x" : 553 },
  44.589 +    "p554": { "x" : 554 },
  44.590 +    "p555": { "x" : 555 },
  44.591 +    "p556": { "x" : 556 },
  44.592 +    "p557": { "x" : 557 },
  44.593 +    "p558": { "x" : 558 },
  44.594 +    "p559": { "x" : 559 },
  44.595 +    "p560": { "x" : 560 },
  44.596 +    "p561": { "x" : 561 },
  44.597 +    "p562": { "x" : 562 },
  44.598 +    "p563": { "x" : 563 },
  44.599 +    "p564": { "x" : 564 },
  44.600 +    "p565": { "x" : 565 },
  44.601 +    "p566": { "x" : 566 },
  44.602 +    "p567": { "x" : 567 },
  44.603 +    "p568": { "x" : 568 },
  44.604 +    "p569": { "x" : 569 },
  44.605 +    "p570": { "x" : 570 },
  44.606 +    "p571": { "x" : 571 },
  44.607 +    "p572": { "x" : 572 },
  44.608 +    "p573": { "x" : 573 },
  44.609 +    "p574": { "x" : 574 },
  44.610 +    "p575": { "x" : 575 },
  44.611 +    "p576": { "x" : 576 },
  44.612 +    "p577": { "x" : 577 },
  44.613 +    "p578": { "x" : 578 },
  44.614 +    "p579": { "x" : 579 },
  44.615 +    "p580": { "x" : 580 },
  44.616 +    "p581": { "x" : 581 },
  44.617 +    "p582": { "x" : 582 },
  44.618 +    "p583": { "x" : 583 },
  44.619 +    "p584": { "x" : 584 },
  44.620 +    "p585": { "x" : 585 },
  44.621 +    "p586": { "x" : 586 },
  44.622 +    "p587": { "x" : 587 },
  44.623 +    "p588": { "x" : 588 },
  44.624 +    "p589": { "x" : 589 },
  44.625 +    "p590": { "x" : 590 },
  44.626 +    "p591": { "x" : 591 },
  44.627 +    "p592": { "x" : 592 },
  44.628 +    "p593": { "x" : 593 },
  44.629 +    "p594": { "x" : 594 },
  44.630 +    "p595": { "x" : 595 },
  44.631 +    "p596": { "x" : 596 },
  44.632 +    "p597": { "x" : 597 },
  44.633 +    "p598": { "x" : 598 },
  44.634 +    "p599": { "x" : 599 },
  44.635 +    "p600": { "x" : 600 },
  44.636 +    "p601": { "x" : 601 },
  44.637 +    "p602": { "x" : 602 },
  44.638 +    "p603": { "x" : 603 },
  44.639 +    "p604": { "x" : 604 },
  44.640 +    "p605": { "x" : 605 },
  44.641 +    "p606": { "x" : 606 },
  44.642 +    "p607": { "x" : 607 },
  44.643 +    "p608": { "x" : 608 },
  44.644 +    "p609": { "x" : 609 },
  44.645 +    "p610": { "x" : 610 },
  44.646 +    "p611": { "x" : 611 },
  44.647 +    "p612": { "x" : 612 },
  44.648 +    "p613": { "x" : 613 },
  44.649 +    "p614": { "x" : 614 },
  44.650 +    "p615": { "x" : 615 },
  44.651 +    "p616": { "x" : 616 },
  44.652 +    "p617": { "x" : 617 },
  44.653 +    "p618": { "x" : 618 },
  44.654 +    "p619": { "x" : 619 },
  44.655 +    "p620": { "x" : 620 },
  44.656 +    "p621": { "x" : 621 },
  44.657 +    "p622": { "x" : 622 },
  44.658 +    "p623": { "x" : 623 },
  44.659 +    "p624": { "x" : 624 },
  44.660 +    "p625": { "x" : 625 },
  44.661 +    "p626": { "x" : 626 },
  44.662 +    "p627": { "x" : 627 },
  44.663 +    "p628": { "x" : 628 },
  44.664 +    "p629": { "x" : 629 },
  44.665 +    "p630": { "x" : 630 },
  44.666 +    "p631": { "x" : 631 },
  44.667 +    "p632": { "x" : 632 },
  44.668 +    "p633": { "x" : 633 },
  44.669 +    "p634": { "x" : 634 },
  44.670 +    "p635": { "x" : 635 },
  44.671 +    "p636": { "x" : 636 },
  44.672 +    "p637": { "x" : 637 },
  44.673 +    "p638": { "x" : 638 },
  44.674 +    "p639": { "x" : 639 },
  44.675 +    "p640": { "x" : 640 },
  44.676 +    "p641": { "x" : 641 },
  44.677 +    "p642": { "x" : 642 },
  44.678 +    "p643": { "x" : 643 },
  44.679 +    "p644": { "x" : 644 },
  44.680 +    "p645": { "x" : 645 },
  44.681 +    "p646": { "x" : 646 },
  44.682 +    "p647": { "x" : 647 },
  44.683 +    "p648": { "x" : 648 },
  44.684 +    "p649": { "x" : 649 },
  44.685 +    "p650": { "x" : 650 },
  44.686 +    "p651": { "x" : 651 },
  44.687 +    "p652": { "x" : 652 },
  44.688 +    "p653": { "x" : 653 },
  44.689 +    "p654": { "x" : 654 },
  44.690 +    "p655": { "x" : 655 },
  44.691 +    "p656": { "x" : 656 },
  44.692 +    "p657": { "x" : 657 },
  44.693 +    "p658": { "x" : 658 },
  44.694 +    "p659": { "x" : 659 },
  44.695 +    "p660": { "x" : 660 },
  44.696 +    "p661": { "x" : 661 },
  44.697 +    "p662": { "x" : 662 },
  44.698 +    "p663": { "x" : 663 },
  44.699 +    "p664": { "x" : 664 },
  44.700 +    "p665": { "x" : 665 },
  44.701 +    "p666": { "x" : 666 },
  44.702 +    "p667": { "x" : 667 },
  44.703 +    "p668": { "x" : 668 },
  44.704 +    "p669": { "x" : 669 },
  44.705 +    "p670": { "x" : 670 },
  44.706 +    "p671": { "x" : 671 },
  44.707 +    "p672": { "x" : 672 },
  44.708 +    "p673": { "x" : 673 },
  44.709 +    "p674": { "x" : 674 },
  44.710 +    "p675": { "x" : 675 },
  44.711 +    "p676": { "x" : 676 },
  44.712 +    "p677": { "x" : 677 },
  44.713 +    "p678": { "x" : 678 },
  44.714 +    "p679": { "x" : 679 },
  44.715 +    "p680": { "x" : 680 },
  44.716 +    "p681": { "x" : 681 },
  44.717 +    "p682": { "x" : 682 },
  44.718 +    "p683": { "x" : 683 },
  44.719 +    "p684": { "x" : 684 },
  44.720 +    "p685": { "x" : 685 },
  44.721 +    "p686": { "x" : 686 },
  44.722 +    "p687": { "x" : 687 },
  44.723 +    "p688": { "x" : 688 },
  44.724 +    "p689": { "x" : 689 },
  44.725 +    "p690": { "x" : 690 },
  44.726 +    "p691": { "x" : 691 },
  44.727 +    "p692": { "x" : 692 },
  44.728 +    "p693": { "x" : 693 },
  44.729 +    "p694": { "x" : 694 },
  44.730 +    "p695": { "x" : 695 },
  44.731 +    "p696": { "x" : 696 },
  44.732 +    "p697": { "x" : 697 },
  44.733 +    "p698": { "x" : 698 },
  44.734 +    "p699": { "x" : 699 },
  44.735 +    "p700": { "x" : 700 },
  44.736 +    "p701": { "x" : 701 },
  44.737 +    "p702": { "x" : 702 },
  44.738 +    "p703": { "x" : 703 },
  44.739 +    "p704": { "x" : 704 },
  44.740 +    "p705": { "x" : 705 },
  44.741 +    "p706": { "x" : 706 },
  44.742 +    "p707": { "x" : 707 },
  44.743 +    "p708": { "x" : 708 },
  44.744 +    "p709": { "x" : 709 },
  44.745 +    "p710": { "x" : 710 },
  44.746 +    "p711": { "x" : 711 },
  44.747 +    "p712": { "x" : 712 },
  44.748 +    "p713": { "x" : 713 },
  44.749 +    "p714": { "x" : 714 },
  44.750 +    "p715": { "x" : 715 },
  44.751 +    "p716": { "x" : 716 },
  44.752 +    "p717": { "x" : 717 },
  44.753 +    "p718": { "x" : 718 },
  44.754 +    "p719": { "x" : 719 },
  44.755 +    "p720": { "x" : 720 },
  44.756 +    "p721": { "x" : 721 },
  44.757 +    "p722": { "x" : 722 },
  44.758 +    "p723": { "x" : 723 },
  44.759 +    "p724": { "x" : 724 },
  44.760 +    "p725": { "x" : 725 },
  44.761 +    "p726": { "x" : 726 },
  44.762 +    "p727": { "x" : 727 },
  44.763 +    "p728": { "x" : 728 },
  44.764 +    "p729": { "x" : 729 },
  44.765 +    "p730": { "x" : 730 },
  44.766 +    "p731": { "x" : 731 },
  44.767 +    "p732": { "x" : 732 },
  44.768 +    "p733": { "x" : 733 },
  44.769 +    "p734": { "x" : 734 },
  44.770 +    "p735": { "x" : 735 },
  44.771 +    "p736": { "x" : 736 },
  44.772 +    "p737": { "x" : 737 },
  44.773 +    "p738": { "x" : 738 },
  44.774 +    "p739": { "x" : 739 },
  44.775 +    "p740": { "x" : 740 },
  44.776 +    "p741": { "x" : 741 },
  44.777 +    "p742": { "x" : 742 },
  44.778 +    "p743": { "x" : 743 },
  44.779 +    "p744": { "x" : 744 },
  44.780 +    "p745": { "x" : 745 },
  44.781 +    "p746": { "x" : 746 },
  44.782 +    "p747": { "x" : 747 },
  44.783 +    "p748": { "x" : 748 },
  44.784 +    "p749": { "x" : 749 },
  44.785 +    "p750": { "x" : 750 },
  44.786 +    "p751": { "x" : 751 },
  44.787 +    "p752": { "x" : 752 },
  44.788 +    "p753": { "x" : 753 },
  44.789 +    "p754": { "x" : 754 },
  44.790 +    "p755": { "x" : 755 },
  44.791 +    "p756": { "x" : 756 },
  44.792 +    "p757": { "x" : 757 },
  44.793 +    "p758": { "x" : 758 },
  44.794 +    "p759": { "x" : 759 },
  44.795 +    "p760": { "x" : 760 },
  44.796 +    "p761": { "x" : 761 },
  44.797 +    "p762": { "x" : 762 },
  44.798 +    "p763": { "x" : 763 },
  44.799 +    "p764": { "x" : 764 },
  44.800 +    "p765": { "x" : 765 },
  44.801 +    "p766": { "x" : 766 },
  44.802 +    "p767": { "x" : 767 },
  44.803 +    "p768": { "x" : 768 },
  44.804 +    "p769": { "x" : 769 },
  44.805 +    "p770": { "x" : 770 },
  44.806 +    "p771": { "x" : 771 },
  44.807 +    "p772": { "x" : 772 },
  44.808 +    "p773": { "x" : 773 },
  44.809 +    "p774": { "x" : 774 },
  44.810 +    "p775": { "x" : 775 },
  44.811 +    "p776": { "x" : 776 },
  44.812 +    "p777": { "x" : 777 },
  44.813 +    "p778": { "x" : 778 },
  44.814 +    "p779": { "x" : 779 },
  44.815 +    "p780": { "x" : 780 },
  44.816 +    "p781": { "x" : 781 },
  44.817 +    "p782": { "x" : 782 },
  44.818 +    "p783": { "x" : 783 },
  44.819 +    "p784": { "x" : 784 },
  44.820 +    "p785": { "x" : 785 },
  44.821 +    "p786": { "x" : 786 },
  44.822 +    "p787": { "x" : 787 },
  44.823 +    "p788": { "x" : 788 },
  44.824 +    "p789": { "x" : 789 },
  44.825 +    "p790": { "x" : 790 },
  44.826 +    "p791": { "x" : 791 },
  44.827 +    "p792": { "x" : 792 },
  44.828 +    "p793": { "x" : 793 },
  44.829 +    "p794": { "x" : 794 },
  44.830 +    "p795": { "x" : 795 },
  44.831 +    "p796": { "x" : 796 },
  44.832 +    "p797": { "x" : 797 },
  44.833 +    "p798": { "x" : 798 },
  44.834 +    "p799": { "x" : 799 },
  44.835 +    "p800": { "x" : 800 },
  44.836 +    "p801": { "x" : 801 },
  44.837 +    "p802": { "x" : 802 },
  44.838 +    "p803": { "x" : 803 },
  44.839 +    "p804": { "x" : 804 },
  44.840 +    "p805": { "x" : 805 },
  44.841 +    "p806": { "x" : 806 },
  44.842 +    "p807": { "x" : 807 },
  44.843 +    "p808": { "x" : 808 },
  44.844 +    "p809": { "x" : 809 },
  44.845 +    "p810": { "x" : 810 },
  44.846 +    "p811": { "x" : 811 },
  44.847 +    "p812": { "x" : 812 },
  44.848 +    "p813": { "x" : 813 },
  44.849 +    "p814": { "x" : 814 },
  44.850 +    "p815": { "x" : 815 },
  44.851 +    "p816": { "x" : 816 },
  44.852 +    "p817": { "x" : 817 },
  44.853 +    "p818": { "x" : 818 },
  44.854 +    "p819": { "x" : 819 },
  44.855 +    "p820": { "x" : 820 },
  44.856 +    "p821": { "x" : 821 },
  44.857 +    "p822": { "x" : 822 },
  44.858 +    "p823": { "x" : 823 },
  44.859 +    "p824": { "x" : 824 },
  44.860 +    "p825": { "x" : 825 },
  44.861 +    "p826": { "x" : 826 },
  44.862 +    "p827": { "x" : 827 },
  44.863 +    "p828": { "x" : 828 },
  44.864 +    "p829": { "x" : 829 },
  44.865 +    "p830": { "x" : 830 },
  44.866 +    "p831": { "x" : 831 },
  44.867 +    "p832": { "x" : 832 },
  44.868 +    "p833": { "x" : 833 },
  44.869 +    "p834": { "x" : 834 },
  44.870 +    "p835": { "x" : 835 },
  44.871 +    "p836": { "x" : 836 },
  44.872 +    "p837": { "x" : 837 },
  44.873 +    "p838": { "x" : 838 },
  44.874 +    "p839": { "x" : 839 },
  44.875 +    "p840": { "x" : 840 },
  44.876 +    "p841": { "x" : 841 },
  44.877 +    "p842": { "x" : 842 },
  44.878 +    "p843": { "x" : 843 },
  44.879 +    "p844": { "x" : 844 },
  44.880 +    "p845": { "x" : 845 },
  44.881 +    "p846": { "x" : 846 },
  44.882 +    "p847": { "x" : 847 },
  44.883 +    "p848": { "x" : 848 },
  44.884 +    "p849": { "x" : 849 },
  44.885 +    "p850": { "x" : 850 },
  44.886 +    "p851": { "x" : 851 },
  44.887 +    "p852": { "x" : 852 },
  44.888 +    "p853": { "x" : 853 },
  44.889 +    "p854": { "x" : 854 },
  44.890 +    "p855": { "x" : 855 },
  44.891 +    "p856": { "x" : 856 },
  44.892 +    "p857": { "x" : 857 },
  44.893 +    "p858": { "x" : 858 },
  44.894 +    "p859": { "x" : 859 },
  44.895 +    "p860": { "x" : 860 },
  44.896 +    "p861": { "x" : 861 },
  44.897 +    "p862": { "x" : 862 },
  44.898 +    "p863": { "x" : 863 },
  44.899 +    "p864": { "x" : 864 },
  44.900 +    "p865": { "x" : 865 },
  44.901 +    "p866": { "x" : 866 },
  44.902 +    "p867": { "x" : 867 },
  44.903 +    "p868": { "x" : 868 },
  44.904 +    "p869": { "x" : 869 },
  44.905 +    "p870": { "x" : 870 },
  44.906 +    "p871": { "x" : 871 },
  44.907 +    "p872": { "x" : 872 },
  44.908 +    "p873": { "x" : 873 },
  44.909 +    "p874": { "x" : 874 },
  44.910 +    "p875": { "x" : 875 },
  44.911 +    "p876": { "x" : 876 },
  44.912 +    "p877": { "x" : 877 },
  44.913 +    "p878": { "x" : 878 },
  44.914 +    "p879": { "x" : 879 },
  44.915 +    "p880": { "x" : 880 },
  44.916 +    "p881": { "x" : 881 },
  44.917 +    "p882": { "x" : 882 },
  44.918 +    "p883": { "x" : 883 },
  44.919 +    "p884": { "x" : 884 },
  44.920 +    "p885": { "x" : 885 },
  44.921 +    "p886": { "x" : 886 },
  44.922 +    "p887": { "x" : 887 },
  44.923 +    "p888": { "x" : 888 },
  44.924 +    "p889": { "x" : 889 },
  44.925 +    "p890": { "x" : 890 },
  44.926 +    "p891": { "x" : 891 },
  44.927 +    "p892": { "x" : 892 },
  44.928 +    "p893": { "x" : 893 },
  44.929 +    "p894": { "x" : 894 },
  44.930 +    "p895": { "x" : 895 },
  44.931 +    "p896": { "x" : 896 },
  44.932 +    "p897": { "x" : 897 },
  44.933 +    "p898": { "x" : 898 },
  44.934 +    "p899": { "x" : 899 },
  44.935 +    "p900": { "x" : 900 },
  44.936 +    "p901": { "x" : 901 },
  44.937 +    "p902": { "x" : 902 },
  44.938 +    "p903": { "x" : 903 },
  44.939 +    "p904": { "x" : 904 },
  44.940 +    "p905": { "x" : 905 },
  44.941 +    "p906": { "x" : 906 },
  44.942 +    "p907": { "x" : 907 },
  44.943 +    "p908": { "x" : 908 },
  44.944 +    "p909": { "x" : 909 },
  44.945 +    "p910": { "x" : 910 },
  44.946 +    "p911": { "x" : 911 },
  44.947 +    "p912": { "x" : 912 },
  44.948 +    "p913": { "x" : 913 },
  44.949 +    "p914": { "x" : 914 },
  44.950 +    "p915": { "x" : 915 },
  44.951 +    "p916": { "x" : 916 },
  44.952 +    "p917": { "x" : 917 },
  44.953 +    "p918": { "x" : 918 },
  44.954 +    "p919": { "x" : 919 },
  44.955 +    "p920": { "x" : 920 },
  44.956 +    "p921": { "x" : 921 },
  44.957 +    "p922": { "x" : 922 },
  44.958 +    "p923": { "x" : 923 },
  44.959 +    "p924": { "x" : 924 },
  44.960 +    "p925": { "x" : 925 },
  44.961 +    "p926": { "x" : 926 },
  44.962 +    "p927": { "x" : 927 },
  44.963 +    "p928": { "x" : 928 },
  44.964 +    "p929": { "x" : 929 },
  44.965 +    "p930": { "x" : 930 },
  44.966 +    "p931": { "x" : 931 },
  44.967 +    "p932": { "x" : 932 },
  44.968 +    "p933": { "x" : 933 },
  44.969 +    "p934": { "x" : 934 },
  44.970 +    "p935": { "x" : 935 },
  44.971 +    "p936": { "x" : 936 },
  44.972 +    "p937": { "x" : 937 },
  44.973 +    "p938": { "x" : 938 },
  44.974 +    "p939": { "x" : 939 },
  44.975 +    "p940": { "x" : 940 },
  44.976 +    "p941": { "x" : 941 },
  44.977 +    "p942": { "x" : 942 },
  44.978 +    "p943": { "x" : 943 },
  44.979 +    "p944": { "x" : 944 },
  44.980 +    "p945": { "x" : 945 },
  44.981 +    "p946": { "x" : 946 },
  44.982 +    "p947": { "x" : 947 },
  44.983 +    "p948": { "x" : 948 },
  44.984 +    "p949": { "x" : 949 },
  44.985 +    "p950": { "x" : 950 },
  44.986 +    "p951": { "x" : 951 },
  44.987 +    "p952": { "x" : 952 },
  44.988 +    "p953": { "x" : 953 },
  44.989 +    "p954": { "x" : 954 },
  44.990 +    "p955": { "x" : 955 },
  44.991 +    "p956": { "x" : 956 },
  44.992 +    "p957": { "x" : 957 },
  44.993 +    "p958": { "x" : 958 },
  44.994 +    "p959": { "x" : 959 },
  44.995 +    "p960": { "x" : 960 },
  44.996 +    "p961": { "x" : 961 },
  44.997 +    "p962": { "x" : 962 },
  44.998 +    "p963": { "x" : 963 },
  44.999 +    "p964": { "x" : 964 },
 44.1000 +    "p965": { "x" : 965 },
 44.1001 +    "p966": { "x" : 966 },
 44.1002 +    "p967": { "x" : 967 },
 44.1003 +    "p968": { "x" : 968 },
 44.1004 +    "p969": { "x" : 969 },
 44.1005 +    "p970": { "x" : 970 },
 44.1006 +    "p971": { "x" : 971 },
 44.1007 +    "p972": { "x" : 972 },
 44.1008 +    "p973": { "x" : 973 },
 44.1009 +    "p974": { "x" : 974 },
 44.1010 +    "p975": { "x" : 975 },
 44.1011 +    "p976": { "x" : 976 },
 44.1012 +    "p977": { "x" : 977 },
 44.1013 +    "p978": { "x" : 978 },
 44.1014 +    "p979": { "x" : 979 },
 44.1015 +    "p980": { "x" : 980 },
 44.1016 +    "p981": { "x" : 981 },
 44.1017 +    "p982": { "x" : 982 },
 44.1018 +    "p983": { "x" : 983 },
 44.1019 +    "p984": { "x" : 984 },
 44.1020 +    "p985": { "x" : 985 },
 44.1021 +    "p986": { "x" : 986 },
 44.1022 +    "p987": { "x" : 987 },
 44.1023 +    "p988": { "x" : 988 },
 44.1024 +    "p989": { "x" : 989 },
 44.1025 +    "p990": { "x" : 990 },
 44.1026 +    "p991": { "x" : 991 },
 44.1027 +    "p992": { "x" : 992 },
 44.1028 +    "p993": { "x" : 993 },
 44.1029 +    "p994": { "x" : 994 },
 44.1030 +    "p995": { "x" : 995 },
 44.1031 +    "p996": { "x" : 996 },
 44.1032 +    "p997": { "x" : 997 },
 44.1033 +    "p998": { "x" : 998 },
 44.1034 +    "p999": { "x" : 999 }
 44.1035 +};
 44.1036 +
 44.1037 +for (var i = 0; i < 1000; i++) {
 44.1038 +    var value = obj["p" + i];
 44.1039 +    Assert.assertTrue(typeof value === "object");
 44.1040 +    Assert.assertTrue(value.x === i);
 44.1041 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/test/script/basic/JDK-8074556.js	Wed Mar 18 18:21:55 2015 -0700
    45.3 @@ -0,0 +1,52 @@
    45.4 +/*
    45.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    45.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    45.7 + * 
    45.8 + * This code is free software; you can redistribute it and/or modify it
    45.9 + * under the terms of the GNU General Public License version 2 only, as
   45.10 + * published by the Free Software Foundation.
   45.11 + * 
   45.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   45.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   45.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   45.15 + * version 2 for more details (a copy is included in the LICENSE file that
   45.16 + * accompanied this code).
   45.17 + * 
   45.18 + * You should have received a copy of the GNU General Public License version
   45.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   45.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   45.21 + * 
   45.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   45.23 + * or visit www.oracle.com if you need additional information or have any
   45.24 + * questions.
   45.25 + */
   45.26 +
   45.27 +/**
   45.28 + * JDK-8074556: Functions should not share allocator maps
   45.29 + *
   45.30 + * @test
   45.31 + * @run
   45.32 + */
   45.33 +
   45.34 +function A () {
   45.35 +    return this;
   45.36 +}
   45.37 +
   45.38 +function B() {
   45.39 +    return this;
   45.40 +}
   45.41 +
   45.42 +A.prototype.x = "x";
   45.43 +A.prototype.y = "y";
   45.44 +B.prototype.y = "y";  // same properties but different order
   45.45 +B.prototype.x = "x";
   45.46 +
   45.47 +function test(o) {
   45.48 +    Assert.assertEquals(o.x, "x");
   45.49 +    Assert.assertEquals(o.y, "y");
   45.50 +}
   45.51 +
   45.52 +test(new A());
   45.53 +test(new B());
   45.54 +test(new A());
   45.55 +test(new B());
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/test/script/basic/JDK-8074687.js	Wed Mar 18 18:21:55 2015 -0700
    46.3 @@ -0,0 +1,60 @@
    46.4 +/*
    46.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    46.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    46.7 + * 
    46.8 + * This code is free software; you can redistribute it and/or modify it
    46.9 + * under the terms of the GNU General Public License version 2 only, as
   46.10 + * published by the Free Software Foundation.
   46.11 + * 
   46.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   46.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   46.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   46.15 + * version 2 for more details (a copy is included in the LICENSE file that
   46.16 + * accompanied this code).
   46.17 + * 
   46.18 + * You should have received a copy of the GNU General Public License version
   46.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   46.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   46.21 + * 
   46.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   46.23 + * or visit www.oracle.com if you need additional information or have any
   46.24 + * questions.
   46.25 + */
   46.26 +
   46.27 +/**
   46.28 + * JDK-8074687:  Add tests for JSON parsing of numeric keys
   46.29 + *
   46.30 + * @test
   46.31 + * @run
   46.32 + */
   46.33 +
   46.34 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": {} }')),                   '{"0":{}}');
   46.35 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": 1 }')),                    '{"0":1}');
   46.36 +
   46.37 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "65503": {} }')),               '{"65503":{}}');
   46.38 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "65503": 1 }')),                '{"65503":1}');
   46.39 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": {}, "65503": {} }')),      '{"0":{},"65503":{}}');
   46.40 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": 1, "65503": 1 }')),        '{"0":1,"65503":1}');
   46.41 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "65503": {}, "0": {} }')),      '{"0":{},"65503":{}}');
   46.42 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "65503": 1, "0": 1 }')),        '{"0":1,"65503":1}');
   46.43 +
   46.44 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "4294967295": {} }')),          '{"4294967295":{}}');
   46.45 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "4294967295": 1 }')),           '{"4294967295":1}');
   46.46 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": {}, "4294967295": {} }')), '{"0":{},"4294967295":{}}');
   46.47 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": 1, "4294967295": 1 }')),   '{"0":1,"4294967295":1}');
   46.48 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "4294967295": {}, "0": {} }')), '{"0":{},"4294967295":{}}');
   46.49 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "4294967295": 1, "0": 1 }')),   '{"0":1,"4294967295":1}');
   46.50 +
   46.51 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "100": {} }')),                 '{"100":{}}');
   46.52 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "100": 1 }')),                  '{"100":1}');
   46.53 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": {}, "100": {} }')),        '{"0":{},"100":{}}');
   46.54 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": 1, "100": 1 }')),          '{"0":1,"100":1}');
   46.55 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "100": {}, "0": {} }')),        '{"0":{},"100":{}}');
   46.56 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "100": 1, "0": 1 }')),          '{"0":1,"100":1}');
   46.57 +
   46.58 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "-100": {} }')),                '{"-100":{}}');
   46.59 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "-100": 1 }')),                 '{"-100":1}');
   46.60 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": {}, "-100": {} }')),       '{"0":{},"-100":{}}');
   46.61 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "0": 1, "-100": 1 }')),         '{"0":1,"-100":1}');
   46.62 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "-100": {}, "0": {} }')),       '{"0":{},"-100":{}}');
   46.63 +Assert.assertEquals(JSON.stringify(JSON.parse('{ "-100": 1, "0": 1 }')),         '{"0":1,"-100":1}');
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/test/script/basic/JDK-8074693.js	Wed Mar 18 18:21:55 2015 -0700
    47.3 @@ -0,0 +1,74 @@
    47.4 +/*
    47.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    47.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    47.7 + * 
    47.8 + * This code is free software; you can redistribute it and/or modify it
    47.9 + * under the terms of the GNU General Public License version 2 only, as
   47.10 + * published by the Free Software Foundation.
   47.11 + * 
   47.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   47.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   47.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   47.15 + * version 2 for more details (a copy is included in the LICENSE file that
   47.16 + * accompanied this code).
   47.17 + * 
   47.18 + * You should have received a copy of the GNU General Public License version
   47.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   47.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   47.21 + * 
   47.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   47.23 + * or visit www.oracle.com if you need additional information or have any
   47.24 + * questions.
   47.25 + */
   47.26 +
   47.27 +/**
   47.28 + * JDK-8074693: Different instances of same function use same allocator map
   47.29 + *
   47.30 + * @test
   47.31 + * @run
   47.32 + */
   47.33 +
   47.34 +var lib = {};
   47.35 +
   47.36 +lib.mixin = function(target, source) {
   47.37 +    for (var p in source) {
   47.38 +        if (source.hasOwnProperty(p) && !target.hasOwnProperty(p)) {
   47.39 +            target.prototype[p] = source[p];
   47.40 +        }
   47.41 +    }
   47.42 +};
   47.43 +
   47.44 +lib.declare = function(def) {
   47.45 +    var className = def.name;
   47.46 +
   47.47 +    lib[className] = function() {
   47.48 +        this.init.apply(this, arguments);
   47.49 +    };
   47.50 +
   47.51 +    lib.mixin(lib[className], def.members);
   47.52 +};
   47.53 +
   47.54 +
   47.55 +lib.declare({
   47.56 +    name: "ClassA",
   47.57 +    members: {
   47.58 +        init : function () {
   47.59 +            print("init A called");
   47.60 +        }
   47.61 +    }
   47.62 +});
   47.63 +
   47.64 +lib.declare({
   47.65 +    name: "ClassB",
   47.66 +    members: {
   47.67 +        util : function () {
   47.68 +            print("util called")
   47.69 +        },
   47.70 +        init : function() {
   47.71 +            print("init B called");
   47.72 +        }
   47.73 +    }
   47.74 +});
   47.75 +
   47.76 +var objA = new lib.ClassA();
   47.77 +var objB = new lib.ClassB();
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/test/script/basic/JDK-8074693.js.EXPECTED	Wed Mar 18 18:21:55 2015 -0700
    48.3 @@ -0,0 +1,2 @@
    48.4 +init A called
    48.5 +init B called
    49.1 --- a/test/script/basic/typedarrays.js	Wed Mar 18 13:57:04 2015 -0700
    49.2 +++ b/test/script/basic/typedarrays.js	Wed Mar 18 18:21:55 2015 -0700
    49.3 @@ -28,6 +28,17 @@
    49.4   * @run
    49.5   */
    49.6  
    49.7 +//JDK-8066217, constructor for arraybuffer not behaving as per spec
    49.8 +function checkLength(ab, l) {
    49.9 +    if (ab.byteLength != l) {
   49.10 +        throw "length error: " + ab.byteLength + " != " + l;
   49.11 +    }
   49.12 +}
   49.13 +checkLength(new ArrayBuffer(), 0);
   49.14 +checkLength(new ArrayBuffer(0), 0);
   49.15 +checkLength(new ArrayBuffer(1024), 1024);
   49.16 +checkLength(new ArrayBuffer(1,2,3), 1);
   49.17 +checkLength(new ArrayBuffer([17]), 17);
   49.18  
   49.19  var typeDefinitions = [
   49.20  Int8Array,
    50.1 --- a/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java	Wed Mar 18 13:57:04 2015 -0700
    50.2 +++ b/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java	Wed Mar 18 18:21:55 2015 -0700
    50.3 @@ -109,6 +109,35 @@
    50.4          }
    50.5      }
    50.6  
    50.7 +    // @bug 8062030: Nashorn bug retrieving array property after key string concatenation
    50.8 +    @Test
    50.9 +    // ConsString attribute access on a JSObject
   50.10 +    public void consStringTest() {
   50.11 +        final ScriptEngineManager m = new ScriptEngineManager();
   50.12 +        final ScriptEngine e = m.getEngineByName("nashorn");
   50.13 +        try {
   50.14 +            final MapWrapperObject obj = new MapWrapperObject();
   50.15 +            e.put("obj", obj);
   50.16 +            e.put("f", "f");
   50.17 +            e.eval("obj[f + 'oo'] = 'bar';");
   50.18 +
   50.19 +            assertEquals(obj.getMap().get("foo"), "bar");
   50.20 +            assertEquals(e.eval("obj[f + 'oo']"), "bar");
   50.21 +            assertEquals(e.eval("obj['foo']"), "bar");
   50.22 +            assertEquals(e.eval("f + 'oo' in obj"), Boolean.TRUE);
   50.23 +            assertEquals(e.eval("'foo' in obj"), Boolean.TRUE);
   50.24 +            e.eval("delete obj[f + 'oo']");
   50.25 +            assertFalse(obj.getMap().containsKey("foo"));
   50.26 +            assertEquals(e.eval("obj[f + 'oo']"), null);
   50.27 +            assertEquals(e.eval("obj['foo']"), null);
   50.28 +            assertEquals(e.eval("f + 'oo' in obj"), Boolean.FALSE);
   50.29 +            assertEquals(e.eval("'foo' in obj"), Boolean.FALSE);
   50.30 +        } catch (final Exception exp) {
   50.31 +            exp.printStackTrace();
   50.32 +            fail(exp.getMessage());
   50.33 +        }
   50.34 +    }
   50.35 +
   50.36      public static class BufferObject extends AbstractJSObject {
   50.37          private final IntBuffer buf;
   50.38  

mercurial