Skip to content

Commit 74d9c79

Browse files
authored
Separate top level scope and globalThis
Distinguish between the top-level scope and "globalThis." This changes the return value to "initStandardObjects" and friends and is the first step in a set of changes that will bring us closer to the more subtle parts of the ECMAscript spec. More context in this issue: mozilla#2164
1 parent f30fc61 commit 74d9c79

73 files changed

Lines changed: 654 additions & 350 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/src/main/java/Shell.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.mozilla.javascript.JavaScriptException;
1616
import org.mozilla.javascript.Scriptable;
1717
import org.mozilla.javascript.ScriptableObject;
18+
import org.mozilla.javascript.TopLevel;
1819
import org.mozilla.javascript.WrappedException;
1920

2021
/**
@@ -49,12 +50,13 @@ public static void main(String args[]) {
4950
// Initialize the standard objects (Object, Function, etc.)
5051
// This must be done before scripts can be executed.
5152
Shell shell = new Shell();
52-
cx.initStandardObjects(shell);
53+
TopLevel topLevel = new TopLevel(shell);
54+
cx.initStandardObjects(topLevel);
5355

5456
// Define some global functions particular to the shell. Note
5557
// that these functions are not part of ECMA.
5658
String[] names = {"print", "quit", "version", "load", "help"};
57-
shell.defineFunctionProperties(names, Shell.class, ScriptableObject.DONTENUM);
59+
shell.defineFunctionProperties(topLevel, names, Shell.class, ScriptableObject.DONTENUM);
5860

5961
args = processOptions(cx, args);
6062

@@ -202,7 +204,7 @@ public static double version(Context cx, Scriptable thisObj, Object[] args, Func
202204
* @param funObj the function object of the invoked JavaScript function
203205
*/
204206
public static void load(Context cx, Scriptable thisObj, Object[] args, Function funObj) {
205-
Shell shell = (Shell) getTopLevelScope(thisObj);
207+
Shell shell = (Shell) getTopLevelScope(thisObj).getGlobalThis();
206208
for (int i = 0; i < args.length; i++) {
207209
shell.processSource(cx, Context.toString(args[i]));
208210
}

it-android/src/main/java/org/mozilla/javascript/android/TestCase.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import org.mozilla.javascript.ContextFactory;
1414
import org.mozilla.javascript.ScriptRuntime;
1515
import org.mozilla.javascript.Scriptable;
16-
import org.mozilla.javascript.ScriptableObject;
16+
import org.mozilla.javascript.TopLevel;
1717

1818
/**
1919
* Utility class, that search for testcases in "assets/tests".
@@ -25,7 +25,7 @@
2525
public abstract class TestCase {
2626

2727
protected final String name;
28-
protected final Scriptable global;
28+
protected final TopLevel global;
2929

3030
private static final ContextFactory factory =
3131
new ContextFactory() {
@@ -47,17 +47,15 @@ protected Context makeContext() {
4747
}
4848
};
4949

50-
public TestCase(String name, Scriptable global) {
50+
public TestCase(String name, TopLevel global) {
5151
this.name = name;
5252
this.global = global;
5353
}
5454

5555
public String run() {
5656
Context cx = factory.enterContext();
5757
try {
58-
Scriptable scope = cx.newObject(global);
59-
scope.setPrototype(global);
60-
scope.setParentScope(null);
58+
Scriptable scope = TopLevel.createIsolate(global);
6159
return ScriptRuntime.toString(runTest(cx, scope));
6260
} finally {
6361
Context.exit();
@@ -74,7 +72,7 @@ public String toString() {
7472
public static class AssetScript extends TestCase {
7573
protected final AssetManager assetManager;
7674

77-
public AssetScript(String name, Scriptable global, AssetManager assetManager) {
75+
public AssetScript(String name, TopLevel global, AssetManager assetManager) {
7876
super(name, global);
7977
this.assetManager = assetManager;
8078
}
@@ -94,7 +92,7 @@ public static List<TestCase> getTestCases(android.content.Context context) throw
9492

9593
AssetManager assetManager = context.getAssets();
9694
// define assert object
97-
ScriptableObject global;
95+
TopLevel global;
9896
Context cx = factory.enterContext();
9997
try (InputStream in = assetManager.open("assert.js");
10098
Reader rdr = new InputStreamReader(in, StandardCharsets.UTF_8)) {

it-android/src/main/java/org/mozilla/javascript/android/TypeInfoFactoryTestCase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import org.mozilla.javascript.Context;
44
import org.mozilla.javascript.Scriptable;
5+
import org.mozilla.javascript.TopLevel;
56
import org.mozilla.javascript.lc.type.TypeInfoFactory;
67
import org.mozilla.javascript.lc.type.impl.factory.ClassValueCacheFactory;
78

89
/**
910
* @author ZZZank
1011
*/
1112
public class TypeInfoFactoryTestCase extends TestCase {
12-
public TypeInfoFactoryTestCase(String name, Scriptable global) {
13+
public TypeInfoFactoryTestCase(String name, TopLevel global) {
1314
super(name, global);
1415
}
1516

rhino-engine/src/main/java/org/mozilla/javascript/engine/Builtins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void register(Context cx, ScriptableObject scope, ScriptContext sc) {
4747

4848
private static Object print(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
4949
try {
50-
Builtins self = getSelf(thisObj);
50+
Builtins self = getSelf(scope);
5151
for (Object arg : args) {
5252
self.stdout.write(ScriptRuntime.toString(arg));
5353
}

rhino-engine/src/main/java/org/mozilla/javascript/engine/RhinoScriptEngine.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.mozilla.javascript.Script;
2626
import org.mozilla.javascript.Scriptable;
2727
import org.mozilla.javascript.ScriptableObject;
28+
import org.mozilla.javascript.TopLevel;
2829

2930
/**
3031
* This is the implementation of the standard ScriptEngine interface for Rhino.
@@ -76,7 +77,7 @@ public class RhinoScriptEngine extends AbstractScriptEngine implements Compilabl
7677

7778
private final RhinoScriptEngineFactory factory;
7879
private final Builtins builtins;
79-
private ScriptableObject topLevelScope = null;
80+
private TopLevel topLevelScope = null;
8081

8182
RhinoScriptEngine(RhinoScriptEngineFactory factory) {
8283
this.factory = factory;
@@ -94,18 +95,17 @@ private Scriptable initScope(Context cx, ScriptContext sc) throws ScriptExceptio
9495
builtins.register(cx, topLevelScope, sc);
9596
}
9697

97-
Scriptable engineScope = new BindingsObject(sc.getBindings(ScriptContext.ENGINE_SCOPE));
98-
engineScope.setParentScope(null);
99-
engineScope.setPrototype(topLevelScope);
100-
10198
if (sc.getBindings(ScriptContext.GLOBAL_SCOPE) != null) {
102-
Scriptable globalScope = new BindingsObject(sc.getBindings(ScriptContext.GLOBAL_SCOPE));
103-
globalScope.setParentScope(null);
104-
globalScope.setPrototype(topLevelScope);
105-
engineScope.setPrototype(globalScope);
99+
var globalScope =
100+
TopLevel.createIsolate(
101+
topLevelScope,
102+
new BindingsObject(sc.getBindings(ScriptContext.GLOBAL_SCOPE)));
103+
return TopLevel.createIsolate(
104+
globalScope, new BindingsObject(sc.getBindings(ScriptContext.ENGINE_SCOPE)));
105+
} else {
106+
return TopLevel.createIsolate(
107+
topLevelScope, new BindingsObject(sc.getBindings(ScriptContext.ENGINE_SCOPE)));
106108
}
107-
108-
return engineScope;
109109
}
110110

111111
@Override

rhino-tools/src/main/java/org/mozilla/javascript/tools/debugger/Main.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.mozilla.javascript.ContextFactory;
1717
import org.mozilla.javascript.Kit;
1818
import org.mozilla.javascript.Scriptable;
19+
import org.mozilla.javascript.ScriptableObject;
1920
import org.mozilla.javascript.commonjs.module.ModuleScope;
2021
import org.mozilla.javascript.tools.shell.Global;
2122

@@ -180,7 +181,7 @@ public static void main(String[] args) {
180181
global.installRequire(cx, List.of(), false);
181182

182183
URI uri = new File(System.getProperty("user.dir")).toURI();
183-
ModuleScope scope = new ModuleScope(global, uri, null);
184+
ScriptableObject scope = ModuleScope.createModuleScope(global, uri, null);
184185

185186
main.setScope(scope);
186187

rhino-tools/src/main/java/org/mozilla/javascript/tools/shell/Global.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,12 @@ public class Global extends ImporterTopLevel {
9797
private static final String[] prompts = {"js> ", " > "};
9898
private HashMap<String, String> doctestCanonicalizations;
9999

100-
public Global() {}
100+
public Global() {
101+
super(true);
102+
}
101103

102104
public Global(Context cx) {
105+
super(true);
103106
init(cx);
104107
}
105108

@@ -128,7 +131,7 @@ public void init(Context cx) {
128131
// that these functions are not part of ECMA.
129132
initStandardObjects(cx, sealedStdLib);
130133
NativeConsole.init(this, sealedStdLib, new ShellConsolePrinter());
131-
defineFunctionProperties(TOP_COMMANDS, Global.class, ScriptableObject.DONTENUM);
134+
defineFunctionProperties(this, TOP_COMMANDS, Global.class, ScriptableObject.DONTENUM);
132135

133136
// Set up "environment" in the global scope to provide access to the
134137
// System environment variables.
@@ -261,7 +264,7 @@ public static void load(Context cx, Scriptable thisObj, Object[] args, Function
261264
for (Object arg : args) {
262265
String file = Context.toString(arg);
263266
try {
264-
Main.processFile(cx, thisObj, file);
267+
Main.processFile(cx, funObj.getDeclarationScope(), file);
265268
} catch (IOException ioex) {
266269
String msg =
267270
ToolErrorReporter.getMessage(
@@ -295,7 +298,8 @@ public static void defineClass(Context cx, Scriptable thisObj, Object[] args, Fu
295298
if (!Scriptable.class.isAssignableFrom(clazz)) {
296299
throw reportRuntimeError("msg.must.implement.Scriptable");
297300
}
298-
ScriptableObject.defineClass(thisObj, (Class<? extends Scriptable>) clazz);
301+
ScriptableObject.defineClass(
302+
funObj.getDeclarationScope(), (Class<? extends Scriptable>) clazz);
299303
}
300304

301305
/**
@@ -348,7 +352,7 @@ public static void serialize(Context cx, Scriptable thisObj, Object[] args, Func
348352
Object obj = args[0];
349353
String filename = Context.toString(args[1]);
350354
FileOutputStream fos = new FileOutputStream(filename);
351-
Scriptable scope = ScriptableObject.getTopLevelScope(thisObj);
355+
Scriptable scope = ScriptableObject.getTopLevelScope(funObj.getDeclarationScope());
352356
try (ScriptableOutputStream out = new ScriptableOutputStream(fos, scope)) {
353357
out.writeObject(obj);
354358
}
@@ -361,7 +365,7 @@ public static Object deserialize(Context cx, Scriptable thisObj, Object[] args,
361365
}
362366
String filename = Context.toString(args[0]);
363367
try (FileInputStream fis = new FileInputStream(filename)) {
364-
Scriptable scope = ScriptableObject.getTopLevelScope(thisObj);
368+
Scriptable scope = ScriptableObject.getTopLevelScope(funObj.getDeclarationScope());
365369
try (ObjectInputStream in = new ScriptableInputStream(fis, scope)) {
366370
Object deserialized = in.readObject();
367371
return Context.toObject(deserialized, scope);

rhino-tools/src/main/java/org/mozilla/javascript/tools/shell/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ static Scriptable getScope(String path) {
251251
uri = new File(path).toURI();
252252
}
253253
}
254-
return new ModuleScope(global, uri, null);
254+
return ModuleScope.createModuleScope(global, uri, null);
255255
}
256256
return global;
257257
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public Object getValue(Scriptable start) {
169169

170170
@Override
171171
public Function asGetterFunction(String name, Scriptable scope) {
172-
return member.asGetterFunction(name, scope);
172+
return member.asGetterFunction(name);
173173
}
174174

175175
@Override
@@ -246,7 +246,7 @@ public boolean setValue(Object value, Scriptable owner, Scriptable start) {
246246

247247
@Override
248248
public Function asSetterFunction(String name, Scriptable scope) {
249-
return member.asSetterFunction(name, scope);
249+
return member.asSetterFunction(name);
250250
}
251251

252252
@Override

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ public static Object coercibleIterativeMethod(
137137
Object callbackArg = args.length > 0 ? args[0] : Undefined.instance;
138138

139139
Function f = getCallbackArg(cx, callbackArg);
140-
Scriptable parent = ScriptableObject.getTopLevelScope(f);
140+
TopLevel parent = ScriptableObject.getTopLevelScope(f);
141141
Scriptable thisArg;
142142
if (args.length < 2 || args[1] == null || args[1] == Undefined.instance) {
143-
thisArg = parent;
143+
thisArg = parent.getGlobalThis();
144144
} else {
145145
thisArg = ScriptRuntime.toObject(cx, scope, args[1]);
146146
}
@@ -339,7 +339,8 @@ public static Object reduceMethodWithLength(
339339
throw ScriptRuntime.notFunctionError(callbackArg);
340340
}
341341
Function f = (Function) callbackArg;
342-
Scriptable parent = ScriptableObject.getTopLevelScope(f);
342+
TopLevel parent = ScriptableObject.getTopLevelScope(f);
343+
Scriptable globalThis = parent.getGlobalThis();
343344
// hack to serve both reduce and reduceRight with the same loop
344345
boolean movingLeft = operation == ReduceOperation.REDUCE;
345346
Object value = args.length > 1 ? args[1] : NOT_FOUND;
@@ -354,7 +355,7 @@ public static Object reduceMethodWithLength(
354355
value = elem;
355356
} else {
356357
Object[] innerArgs = {value, elem, index, o};
357-
value = f.call(cx, parent, parent, innerArgs);
358+
value = f.call(cx, parent, globalThis, innerArgs);
358359
}
359360
}
360361
if (value == NOT_FOUND) {

0 commit comments

Comments
 (0)