diff --git a/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java b/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java index 5fdd1334ce..e9b70da565 100644 --- a/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java +++ b/rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java @@ -1321,7 +1321,7 @@ private void visitObjectLiteral(Node node, Node child) { addIndexOp(Icode_LITERAL_NEW_OBJECT, nextLiteralIndex); addUint8(hasAnyComputedProperty ? 1 : 0); - stackChange(3); + stackChange(4); int i = 0; while (child != null) { @@ -1343,7 +1343,7 @@ private void visitObjectLiteral(Node node, Node child) { addToken(Token.OBJECTLIT); - stackChange(-2); + stackChange(-3); } private void visitArrayLiteral(Node node, Node child) { diff --git a/rhino/src/main/java/org/mozilla/javascript/Interpreter.java b/rhino/src/main/java/org/mozilla/javascript/Interpreter.java index e98e6f4cc2..ff9a9efc41 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Interpreter.java +++ b/rhino/src/main/java/org/mozilla/javascript/Interpreter.java @@ -2437,6 +2437,8 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl boolean copyArray = iCode[frame.pc] != 0; ++frame.pc; ++stackTop; + stack[stackTop] = cx.newObject(frame.scope); + ++stackTop; stack[stackTop] = copyArray ? Arrays.copyOf(ids, ids.length) : ids; ++stackTop; @@ -2499,15 +2501,15 @@ private static Object interpretLoop(Context cx, CallFrame frame, Object throwabl } case Token.OBJECTLIT: { - Object[] data = (Object[]) stack[stackTop]; + Object[] values = (Object[]) stack[stackTop]; --stackTop; int[] getterSetters = (int[]) stack[stackTop]; --stackTop; - Object[] ids = (Object[]) stack[stackTop]; - Object val = - ScriptRuntime.newObjectLiteral( - ids, data, getterSetters, cx, frame.scope); - stack[stackTop] = val; + Object[] keys = (Object[]) stack[stackTop]; + --stackTop; + Scriptable object = (Scriptable) stack[stackTop]; + ScriptRuntime.fillObjectLiteral( + object, keys, values, getterSetters, cx, frame.scope); continue Loop; } case Token.ARRAYLIT: diff --git a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java index 9edefaf67d..2fe205e15c 100644 --- a/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java +++ b/rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java @@ -4815,16 +4815,26 @@ public static Scriptable newArrayLiteral( * object literal is compiled. The next instance will be the version called from new code. * This method only present for compatibility. * - * @deprecated Use {@link #newObjectLiteral(Object[], Object[], int[], Context, Scriptable)} - * instead + * @deprecated Use {@link #fillObjectLiteral(Scriptable, Object[], Object[], int[], Context, + * Scriptable)} instead */ @Deprecated public static Scriptable newObjectLiteral( Object[] propertyIds, Object[] propertyValues, Context cx, Scriptable scope) { // Passing null for getterSetters means no getters or setters - return newObjectLiteral(propertyIds, propertyValues, null, cx, scope); + Scriptable object = cx.newObject(scope); + fillObjectLiteral(object, propertyIds, propertyValues, null, cx, scope); + return object; } + /** + * This method is here for backward compat with existing compiled code. This method only + * present for compatibility. + * + * @deprecated Use {@link #fillObjectLiteral(Scriptable, Object[], Object[], int[], Context, + * Scriptable)} + */ + @Deprecated public static Scriptable newObjectLiteral( Object[] propertyIds, Object[] propertyValues, @@ -4832,6 +4842,17 @@ public static Scriptable newObjectLiteral( Context cx, Scriptable scope) { Scriptable object = cx.newObject(scope); + fillObjectLiteral(object, propertyIds, propertyValues, getterSetters, cx, scope); + return object; + } + + public static void fillObjectLiteral( + Scriptable object, + Object[] propertyIds, + Object[] propertyValues, + int[] getterSetters, + Context cx, + Scriptable scope) { int end = propertyIds == null ? 0 : propertyIds.length; for (int i = 0; i != end; ++i) { Object id = propertyIds[i]; @@ -4868,7 +4889,6 @@ public static Scriptable newObjectLiteral( so.setGetterOrSetter(key, index == null ? 0 : index, getterOrSetter, isSetter); } } - return object; } public static boolean isArrayObject(Object obj) { diff --git a/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java b/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java index 6bb3a000de..b872eca764 100644 --- a/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java +++ b/rhino/src/main/java/org/mozilla/javascript/optimizer/BodyCodegen.java @@ -2266,6 +2266,15 @@ private void visitObjectLiteral(Node node, Node child, boolean topLevel) { return; } + cfw.addALoad(contextLocal); + cfw.addALoad(variableObjectLocal); + cfw.addInvoke( + ByteCode.INVOKEVIRTUAL, + "org/mozilla/javascript/Context", + "newObject", + "(Lorg/mozilla/javascript/Scriptable;)Lorg/mozilla/javascript/Scriptable;"); + cfw.add(ByteCode.DUP); + addLoadProperty(node, child, properties, count); // check if object literal actually has any getters or setters @@ -2305,13 +2314,15 @@ private void visitObjectLiteral(Node node, Node child, boolean topLevel) { cfw.addALoad(contextLocal); cfw.addALoad(variableObjectLocal); addScriptRuntimeInvoke( - "newObjectLiteral", - "([Ljava/lang/Object;" + "fillObjectLiteral", + "(" + + "Lorg/mozilla/javascript/Scriptable;" + + "[Ljava/lang/Object;" + "[Ljava/lang/Object;" + "[I" + "Lorg/mozilla/javascript/Context;" + "Lorg/mozilla/javascript/Scriptable;" - + ")Lorg/mozilla/javascript/Scriptable;"); + + ")V"); } private void visitSpecialCall(Node node, int type, int specialType, Node child) {