Skip to content

Commit f30fc61

Browse files
authored
Don't create activations to track strictness
Clean up tracking of strict mode in general. * Don't clear strictness tracking from Context when compiling * Don't create activations just to track strictness * Remove isTopLevelStrict from Context * Deprecate isStrict in activations and get it from function desc * Deprecate NativeCall constructor that has a strictness parameter * Remove deprecated create*FunctionActivation functions from ScriptRuntime * Improve Bug782363Test to assert exact number of allowed user-defined locals
1 parent be2c09e commit f30fc61

File tree

9 files changed

+69
-125
lines changed

9 files changed

+69
-125
lines changed

rhino/src/main/java/org/mozilla/javascript/Arguments.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public Arguments(NativeCall activation, Context cx) {
5353
ScriptableObject.DONTENUM);
5454
defineProperty("length", lengthObj, ScriptableObject.DONTENUM);
5555

56-
if (activation.isStrict) {
56+
if (f.isStrict()) {
5757
// ECMAScript2015
5858
// 9.4.4.6 CreateUnmappedArgumentsObject(argumentsList)
5959
// 8. Perform DefinePropertyOrThrow(obj, "caller", PropertyDescriptor {[[Get]]:
@@ -150,11 +150,10 @@ public Object get(int index, Scriptable start) {
150150
}
151151

152152
private boolean sharedWithActivation(int index) {
153-
Context cx = Context.getContext();
154-
if (cx.isStrictMode()) {
153+
JSFunction f = activation.function;
154+
if (f.isStrict()) {
155155
return false;
156156
}
157-
JSFunction f = activation.function;
158157

159158
// Check if default arguments are present
160159
if (f == null || f.hasDefaultParameters()) {

rhino/src/main/java/org/mozilla/javascript/BaseFunction.java

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -491,21 +491,7 @@ private static Scriptable js_gen_constructorCall(
491491
}
492492

493493
private static Scriptable js_constructor(Context cx, Scriptable scope, Object[] args) {
494-
if (cx.isStrictMode()) {
495-
// Disable strict mode forcefully, and restore it after the call
496-
NativeCall activation = cx.currentActivationCall;
497-
boolean strictMode = cx.isTopLevelStrict;
498-
try {
499-
cx.currentActivationCall = null;
500-
cx.isTopLevelStrict = false;
501-
return jsConstructor(cx, scope, args, false);
502-
} finally {
503-
cx.isTopLevelStrict = strictMode;
504-
cx.currentActivationCall = activation;
505-
}
506-
} else {
507-
return jsConstructor(cx, scope, args, false);
508-
}
494+
return jsConstructor(cx, scope, args, false);
509495
}
510496

511497
private static Scriptable js_constructorCall(
@@ -514,21 +500,7 @@ private static Scriptable js_constructorCall(
514500
}
515501

516502
private static Scriptable js_gen_constructor(Context cx, Scriptable scope, Object[] args) {
517-
if (cx.isStrictMode()) {
518-
// Disable strict mode forcefully, and restore it after the call
519-
NativeCall activation = cx.currentActivationCall;
520-
boolean strictMode = cx.isTopLevelStrict;
521-
try {
522-
cx.currentActivationCall = null;
523-
cx.isTopLevelStrict = false;
524-
return jsConstructor(cx, scope, args, true);
525-
} finally {
526-
cx.isTopLevelStrict = strictMode;
527-
cx.currentActivationCall = activation;
528-
}
529-
} else {
530-
return jsConstructor(cx, scope, args, true);
531-
}
503+
return jsConstructor(cx, scope, args, true);
532504
}
533505

534506
private static BaseFunction realFunction(Scriptable thisObj, String functionName) {
@@ -762,7 +734,7 @@ Object getArguments() {
762734
if (activation == null) {
763735
return null;
764736
}
765-
if (activation.isStrict && cx.getLanguageVersion() >= Context.VERSION_ES6) {
737+
if (activation.function.isStrict() && cx.getLanguageVersion() >= Context.VERSION_ES6) {
766738
ScriptRuntime.ThrowTypeError.throwNotAllowed();
767739
}
768740
Object arguments = activation.get("arguments", activation);

rhino/src/main/java/org/mozilla/javascript/Context.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,7 @@ public Object callFunctionWithContinuations(Script script, Scriptable scope)
13041304
// Annotate so we can check later to ensure no java code in
13051305
// intervening frames
13061306
isContinuationsTopCall = true;
1307-
return ScriptRuntime.doTopCall(script, this, scope, scope, isTopLevelStrict);
1307+
return ScriptRuntime.doTopCall(script, this, scope, scope, isStrict);
13081308
}
13091309

13101310
public Object callFunctionWithContinuations(Callable callable, Scriptable scope, Object[] args)
@@ -1324,8 +1324,7 @@ public Object callFunctionWithContinuations(Callable callable, Scriptable scope,
13241324
// Annotate so we can check later to ensure no java code in
13251325
// intervening frames
13261326
isContinuationsTopCall = true;
1327-
return ScriptRuntime.doTopCall(
1328-
(JSFunction) callable, this, scope, scope, args, isTopLevelStrict);
1327+
return ScriptRuntime.doTopCall((JSFunction) callable, this, scope, scope, args, isStrict);
13291328
}
13301329

13311330
/**
@@ -2771,9 +2770,12 @@ public void removeActivationName(String name) {
27712770
if (activationNames != null) activationNames.remove(name);
27722771
}
27732772

2773+
public final void setIsStrictMode(boolean isStrict) {
2774+
this.isStrict = isStrict;
2775+
}
2776+
27742777
public final boolean isStrictMode() {
2775-
return isTopLevelStrict
2776-
|| (currentActivationCall != null && currentActivationCall.isStrict);
2778+
return isStrict;
27772779
}
27782780

27792781
public static boolean isCurrentContextStrict() {
@@ -2791,6 +2793,7 @@ public static boolean isCurrentContextStrict() {
27912793
Scriptable topCallScope;
27922794
boolean isContinuationsTopCall;
27932795
NativeCall currentActivationCall;
2796+
private boolean isStrict;
27942797
XMLLib cachedXMLLib;
27952798
BaseFunction typeErrorThrower;
27962799

@@ -2847,6 +2850,4 @@ public static boolean isCurrentContextStrict() {
28472850

28482851
// Generate an observer count on compiled code
28492852
boolean generateObserverCount = false;
2850-
2851-
boolean isTopLevelStrict;
28522853
}

rhino/src/main/java/org/mozilla/javascript/Interpreter.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ private static class CallFrame implements Cloneable, Serializable {
8686
int savedStackTop;
8787
int savedCallOp;
8888
Object throwable;
89+
boolean parentStrictness;
8990

9091
CallFrame(
9192
Context cx,
@@ -268,6 +269,7 @@ void initializeArgs(
268269

269270
if (desc.getFunctionType() != 0) {
270271
scope = fnOrScript.getDeclarationScope();
272+
this.parentStrictness = ScriptRuntime.enterFunctionStrictness(cx, desc.isStrict());
271273

272274
if (useActivation) {
273275
if (desc.getFunctionType() == FunctionNode.ARROW_FUNCTION) {
@@ -277,7 +279,6 @@ void initializeArgs(
277279
cx,
278280
scope,
279281
args,
280-
desc.isStrict(),
281282
desc.hasRestArg(),
282283
desc.requiresArgumentObject());
283284
} else {
@@ -287,7 +288,6 @@ void initializeArgs(
287288
cx,
288289
scope,
289290
args,
290-
desc.isStrict(),
291291
desc.hasRestArg(),
292292
desc.requiresArgumentObject());
293293
}
@@ -1251,7 +1251,7 @@ public static Object resumeGenerator(
12511251
public static Object restartContinuation(
12521252
NativeContinuation c, Context cx, Scriptable scope, Object[] args) {
12531253
if (!ScriptRuntime.hasTopCall(cx)) {
1254-
return ScriptRuntime.doTopCall(c, cx, scope, null, args, cx.isTopLevelStrict);
1254+
return ScriptRuntime.doTopCall(c, cx, scope, null, args, cx.isStrictMode());
12551255
}
12561256

12571257
Object arg;
@@ -5084,6 +5084,10 @@ private static void exitFrame(Context cx, CallFrame frame, Object throwable) {
50845084
ScriptRuntime.exitActivationFunction(cx);
50855085
}
50865086

5087+
if (frame.fnOrScript.getDescriptor().getFunctionType() != 0) {
5088+
ScriptRuntime.exitFunctionStrictness(cx, frame.parentStrictness);
5089+
}
5090+
50875091
if (frame.debuggerFrame != null) {
50885092
try {
50895093
if (throwable instanceof Throwable) {

rhino/src/main/java/org/mozilla/javascript/NativeCall.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ static void init(Scriptable scope, boolean sealed) {
2727
NativeCall() {
2828
function = null;
2929
originalArgs = null;
30-
isStrict = false;
3130
}
3231

3332
NativeCall(
@@ -36,7 +35,6 @@ static void init(Scriptable scope, boolean sealed) {
3635
Scriptable scope,
3736
Object[] args,
3837
boolean isArrow,
39-
boolean isStrict,
4038
boolean argsHasRest,
4139
boolean requiresArgumentObject) {
4240
this.function = function;
@@ -45,7 +43,6 @@ static void init(Scriptable scope, boolean sealed) {
4543
// leave prototype null
4644

4745
this.originalArgs = (args == null) ? ScriptRuntime.emptyArgs : args;
48-
this.isStrict = isStrict;
4946

5047
// initialize values of arguments
5148
int paramAndVarCount = function.getParamAndVarCount();
@@ -148,7 +145,6 @@ public Scriptable getHomeObject() {
148145

149146
final JSFunction function;
150147
final Object[] originalArgs;
151-
final boolean isStrict;
152148

153149
transient NativeCall parentActivationCall;
154150
}

rhino/src/main/java/org/mozilla/javascript/Parser.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,9 +748,6 @@ private AstNode parseFunctionBody(int type, FunctionNode fnNode) throws IOExcept
748748
}
749749
inUseStrictDirective = true;
750750
fnNode.setInStrictMode(true);
751-
if (!savedStrictMode) {
752-
setRequiresActivation();
753-
}
754751
}
755752
}
756753
break;

rhino/src/main/java/org/mozilla/javascript/ScriptRuntime.java

Lines changed: 21 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -4883,13 +4883,13 @@ public static Scriptable getTopCallScope(Context cx) {
48834883
@Deprecated
48844884
public static Object doTopCall(
48854885
Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
4886-
return doTopCall(callable, cx, scope, thisObj, args, cx.isTopLevelStrict);
4886+
return doTopCall(callable, cx, scope, thisObj, args, cx.isStrictMode());
48874887
}
48884888

48894889
@Deprecated
48904890
public static Object doTopCall(
48914891
Script script, Context cx, Scriptable scope, Scriptable thisObj) {
4892-
return doTopCall(script, cx, scope, thisObj, cx.isTopLevelStrict);
4892+
return doTopCall(script, cx, scope, thisObj, cx.isStrictMode());
48934893
}
48944894

48954895
public static Object doTopCall(
@@ -4905,16 +4905,16 @@ public static Object doTopCall(
49054905
Object result;
49064906
cx.topCallScope = ScriptableObject.getTopLevelScope(scope);
49074907
cx.useDynamicScope = cx.hasFeature(Context.FEATURE_DYNAMIC_SCOPE);
4908-
boolean previousTopLevelStrict = cx.isTopLevelStrict;
4909-
cx.isTopLevelStrict = isTopLevelStrict;
4908+
boolean previousStrictness = cx.isStrictMode();
4909+
cx.setIsStrictMode(isTopLevelStrict);
49104910
ContextFactory f = cx.getFactory();
49114911
try {
49124912
result = f.doTopCall(callable, cx, scope, thisObj, args);
49134913
} finally {
49144914
cx.topCallScope = null;
49154915
// Cleanup cached references
49164916
cx.cachedXMLLib = null;
4917-
cx.isTopLevelStrict = previousTopLevelStrict;
4917+
cx.setIsStrictMode(previousStrictness);
49184918
// Function should always call exitActivationFunction
49194919
// if it creates activation record
49204920
assert (cx.currentActivationCall == null);
@@ -4934,16 +4934,16 @@ public static Object doTopCall(
49344934
Object result;
49354935
cx.topCallScope = ScriptableObject.getTopLevelScope(scope);
49364936
cx.useDynamicScope = cx.hasFeature(Context.FEATURE_DYNAMIC_SCOPE);
4937-
boolean previousTopLevelStrict = cx.isTopLevelStrict;
4938-
cx.isTopLevelStrict = isTopLevelStrict;
4937+
boolean previousStrictness = cx.isStrictMode();
4938+
cx.setIsStrictMode(isTopLevelStrict);
49394939
ContextFactory f = cx.getFactory();
49404940
try {
49414941
result = f.doTopCall(script, cx, scope, thisObj);
49424942
} finally {
49434943
cx.topCallScope = null;
49444944
// Cleanup cached references
49454945
cx.cachedXMLLib = null;
4946-
cx.isTopLevelStrict = previousTopLevelStrict;
4946+
cx.setIsStrictMode(previousStrictness);
49474947
// Function should always call exitActivationFunction
49484948
// if it creates activation record
49494949
assert (cx.currentActivationCall == null);
@@ -5034,83 +5034,27 @@ public static void initScript(
50345034
public static Scriptable createFunctionActivation(
50355035
JSFunction funObj, Scriptable scope, Object[] args) {
50365036
return createFunctionActivation(
5037-
funObj, Context.getCurrentContext(), scope, args, false, false);
5037+
funObj, Context.getCurrentContext(), scope, args, false, true);
50385038
}
50395039

5040-
/**
5041-
* @deprecated Use {@link #createFunctionActivation(JSFunction, Context, Scriptable, Object[],
5042-
* boolean, boolean, boolean)} instead
5043-
*/
5044-
@Deprecated
5045-
public static Scriptable createFunctionActivation(
5046-
JSFunction funObj, Scriptable scope, Object[] args, boolean isStrict) {
5047-
return new NativeCall(
5048-
funObj, Context.getCurrentContext(), scope, args, false, isStrict, false, true);
5049-
}
5050-
5051-
/**
5052-
* @deprecated Use {@link #createFunctionActivation(JSFunction, Context, Scriptable, Object[],
5053-
* boolean, boolean, boolean)} instead
5054-
*/
5055-
@Deprecated
50565040
public static Scriptable createFunctionActivation(
50575041
JSFunction funObj,
50585042
Context cx,
50595043
Scriptable scope,
50605044
Object[] args,
5061-
boolean isStrict,
5062-
boolean argsHasRest) {
5063-
return new NativeCall(funObj, cx, scope, args, false, isStrict, argsHasRest, true);
5064-
}
5065-
5066-
public static Scriptable createFunctionActivation(
5067-
JSFunction funObj,
5068-
Context cx,
5069-
Scriptable scope,
5070-
Object[] args,
5071-
boolean isStrict,
50725045
boolean argsHasRest,
50735046
boolean requiresArgumentObject) {
5074-
return new NativeCall(
5075-
funObj, cx, scope, args, false, isStrict, argsHasRest, requiresArgumentObject);
5076-
}
5077-
5078-
/**
5079-
* @deprecated Use {@link #createArrowFunctionActivation(JSFunction, Context, Scriptable,
5080-
* Object[], boolean, boolean, boolean)} instead
5081-
*/
5082-
@Deprecated
5083-
public static Scriptable createArrowFunctionActivation(
5084-
JSFunction funObj, Scriptable scope, Object[] args, boolean isStrict) {
5085-
return new NativeCall(
5086-
funObj, Context.getCurrentContext(), scope, args, true, isStrict, false, true);
5047+
return new NativeCall(funObj, cx, scope, args, false, argsHasRest, requiresArgumentObject);
50875048
}
50885049

5089-
/**
5090-
* @deprecated Use {@link #createArrowFunctionActivation(JSFunction, Context, Scriptable,
5091-
* Object[], boolean, boolean, boolean)} instead
5092-
*/
5093-
@Deprecated
50945050
public static Scriptable createArrowFunctionActivation(
50955051
JSFunction funObj,
50965052
Context cx,
50975053
Scriptable scope,
50985054
Object[] args,
5099-
boolean isStrict,
5100-
boolean argsHasRest) {
5101-
return new NativeCall(funObj, cx, scope, args, true, isStrict, argsHasRest, true);
5102-
}
5103-
5104-
public static Scriptable createArrowFunctionActivation(
5105-
JSFunction funObj,
5106-
Context cx,
5107-
Scriptable scope,
5108-
Object[] args,
5109-
boolean isStrict,
51105055
boolean argsHasRest,
51115056
boolean requiresArgumentObject) {
5112-
return new NativeCall(
5113-
funObj, cx, scope, args, true, isStrict, argsHasRest, requiresArgumentObject);
5057+
return new NativeCall(funObj, cx, scope, args, true, argsHasRest, requiresArgumentObject);
51145058
}
51155059

51165060
public static void enterActivationFunction(Context cx, Scriptable scope) {
@@ -5126,6 +5070,16 @@ public static void exitActivationFunction(Context cx) {
51265070
call.parentActivationCall = null;
51275071
}
51285072

5073+
public static boolean enterFunctionStrictness(Context cx, boolean functionIsStrict) {
5074+
boolean parent = cx.isStrictMode();
5075+
cx.setIsStrictMode(functionIsStrict);
5076+
return parent;
5077+
}
5078+
5079+
public static void exitFunctionStrictness(Context cx, boolean parentWasStrict) {
5080+
cx.setIsStrictMode(parentWasStrict);
5081+
}
5082+
51295083
static NativeCall findFunctionActivation(Context cx, Function f) {
51305084
NativeCall call = cx.currentActivationCall;
51315085
while (call != null) {

0 commit comments

Comments
 (0)