Skip to content

Commit

Permalink
Literal object rework: push the object on the stack before the props
Browse files Browse the repository at this point in the history
Co-authored-by: Satish Srinivasan <[email protected]>
  • Loading branch information
andreabergia and 0xe committed Nov 27, 2024
1 parent de5b554 commit 8406632
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
4 changes: 2 additions & 2 deletions rhino/src/main/java/org/mozilla/javascript/CodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
14 changes: 8 additions & 6 deletions rhino/src/main/java/org/mozilla/javascript/Interpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
28 changes: 24 additions & 4 deletions rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -4815,23 +4815,44 @@ public static Scriptable newArrayLiteral(
* object literal is compiled. The next instance will be the version called from new code.
* <strong>This method only present for compatibility.</strong>
*
* @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. <strong>This method only
* present for compatibility.</strong>
*
* @deprecated Use {@link #fillObjectLiteral(Scriptable, Object[], Object[], int[], Context,
* Scriptable)}
*/
@Deprecated
public static Scriptable newObjectLiteral(
Object[] propertyIds,
Object[] propertyValues,
int[] getterSetters,
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];
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 8406632

Please sign in to comment.