Skip to content

Commit

Permalink
support rest paramaters also for activation
Browse files Browse the repository at this point in the history
  • Loading branch information
rbri committed Feb 27, 2024
1 parent 775290e commit ee07a4a
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 75 deletions.
14 changes: 12 additions & 2 deletions src/org/mozilla/javascript/Interpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,21 @@ void initializeArgs(
if (idata.itsFunctionType == FunctionNode.ARROW_FUNCTION) {
scope =
ScriptRuntime.createArrowFunctionActivation(
fnOrScript, scope, args, idata.isStrict);
fnOrScript,
cx,
scope,
args,
idata.isStrict,
idata.argsHasRest);
} else {
scope =
ScriptRuntime.createFunctionActivation(
fnOrScript, scope, args, idata.isStrict);
fnOrScript,
cx,
scope,
args,
idata.isStrict,
idata.argsHasRest);
}
}
} else {
Expand Down
32 changes: 27 additions & 5 deletions src/org/mozilla/javascript/NativeCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ static void init(Scriptable scope, boolean sealed) {

NativeCall(
NativeFunction function,
Context cx,
Scriptable scope,
Object[] args,
boolean isArrow,
boolean isStrict) {
boolean isStrict,
boolean argsHasRest) {
this.function = function;

setParentScope(scope);
Expand All @@ -44,10 +46,30 @@ static void init(Scriptable scope, boolean sealed) {
int paramAndVarCount = function.getParamAndVarCount();
int paramCount = function.getParamCount();
if (paramAndVarCount != 0) {
for (int i = 0; i < paramCount; ++i) {
String name = function.getParamOrVarName(i);
Object val = i < args.length ? args[i] : Undefined.instance;
defineProperty(name, val, PERMANENT);
if (argsHasRest) {
Object[] vals;
if (args.length >= paramCount) {
vals = new Object[args.length - paramCount];
System.arraycopy(args, paramCount, vals, 0, args.length - paramCount);
} else {
vals = ScriptRuntime.emptyArgs;
}

for (int i = 0; i < paramCount; ++i) {
String name = function.getParamOrVarName(i);
Object val = i < args.length ? args[i] : Undefined.instance;
defineProperty(name, val, PERMANENT);
}
defineProperty(
function.getParamOrVarName(paramCount),
cx.newArray(scope, vals),
PERMANENT);
} else {
for (int i = 0; i < paramCount; ++i) {
String name = function.getParamOrVarName(i);
Object val = i < args.length ? args[i] : Undefined.instance;
defineProperty(name, val, PERMANENT);
}
}
}

Expand Down
43 changes: 38 additions & 5 deletions src/org/mozilla/javascript/ScriptRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -4028,23 +4028,56 @@ public static void initScript(
}

/**
* @deprecated Use {@link #createFunctionActivation(NativeFunction, Scriptable, Object[],
* boolean)} instead
* @deprecated Use {@link #createFunctionActivation(NativeFunction, Context, Scriptable,
* Object[], boolean, boolean)} instead
*/
@Deprecated
public static Scriptable createFunctionActivation(
NativeFunction funObj, Scriptable scope, Object[] args) {
return createFunctionActivation(funObj, scope, args, false);
return createFunctionActivation(
funObj, Context.getCurrentContext(), scope, args, false, false);
}

/**
* @deprecated Use {@link #createFunctionActivation(NativeFunction, Context, Scriptable,
* Object[], boolean, boolean)} instead
*/
@Deprecated
public static Scriptable createFunctionActivation(
NativeFunction funObj, Scriptable scope, Object[] args, boolean isStrict) {
return new NativeCall(funObj, scope, args, false, isStrict);
return new NativeCall(
funObj, Context.getCurrentContext(), scope, args, false, isStrict, false);
}

public static Scriptable createFunctionActivation(
NativeFunction funObj,
Context cx,
Scriptable scope,
Object[] args,
boolean isStrict,
boolean argsHasRest) {
return new NativeCall(funObj, cx, scope, args, false, isStrict, argsHasRest);
}

/**
* @deprecated Use {@link #createArrowFunctionActivation(NativeFunction, Context, Scriptable,
* Object[], boolean, boolean)} instead
*/
@Deprecated
public static Scriptable createArrowFunctionActivation(
NativeFunction funObj, Scriptable scope, Object[] args, boolean isStrict) {
return new NativeCall(funObj, scope, args, true, isStrict);
return new NativeCall(
funObj, Context.getCurrentContext(), scope, args, true, isStrict, false);
}

public static Scriptable createArrowFunctionActivation(
NativeFunction funObj,
Context cx,
Scriptable scope,
Object[] args,
boolean isStrict,
boolean argsHasRest) {
return new NativeCall(funObj, cx, scope, args, true, isStrict, argsHasRest);
}

public static void enterActivationFunction(Context cx, Scriptable scope) {
Expand Down
10 changes: 9 additions & 1 deletion src/org/mozilla/javascript/optimizer/BodyCodegen.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,19 @@ private void generateGenerator() {

// generators are forced to have an activation record
cfw.addALoad(funObjLocal);
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addALoad(argsLocal);
cfw.addPush(scriptOrFn.isInStrictMode());
cfw.addPush(scriptOrFn.hasRestParameter());
addScriptRuntimeInvoke(
"createFunctionActivation",
"(Lorg/mozilla/javascript/NativeFunction;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ "[Ljava/lang/Object;"
+ "Z"
+ "Z"
+ ")Lorg/mozilla/javascript/Scriptable;");
cfw.addAStore(variableObjectLocal);

Expand Down Expand Up @@ -415,17 +419,21 @@ private void generatePrologue() {
if (fnCurrent != null) {
debugVariableName = "activation";
cfw.addALoad(funObjLocal);
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addALoad(argsLocal);
cfw.addPush(scriptOrFn.isInStrictMode());
cfw.addPush(scriptOrFn.hasRestParameter());
String methodName =
isArrow ? "createArrowFunctionActivation" : "createFunctionActivation";
cfw.addPush(scriptOrFn.isInStrictMode());
addScriptRuntimeInvoke(
methodName,
"(Lorg/mozilla/javascript/NativeFunction;"
+ "Lorg/mozilla/javascript/Context;"
+ "Lorg/mozilla/javascript/Scriptable;"
+ "[Ljava/lang/Object;"
+ "Z"
+ "Z"
+ ")Lorg/mozilla/javascript/Scriptable;");
cfw.addAStore(variableObjectLocal);
cfw.addALoad(contextLocal);
Expand Down
Loading

0 comments on commit ee07a4a

Please sign in to comment.