You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -91,57 +94,77 @@ That includes REPLs, inline code execution results in editors (eg. [Quokka.js](h
91
94
92
95
Maintaining the global state between executions of user-provided code snippets would benefit from the ability to control scope
93
96
94
-
## Intersection Semantics
97
+
## Proposal
95
98
96
-
TBD
99
+
Allow evaluating a module without access to global context by severing the tie to the `GlobalEnvironmentRecord` in `ModuleEnvironmentRecord` instances
100
+
by setting `[[OuterEnv]]` to a different record than `module.[[Realm]].[[GlobalEnv]]`, replacing it with user-defined emulation of a global we will refer to as **Scope Ceiling**
`globalThis` in the browser has a non-trivial prototype chain for some Window
103
-
API functionality and events.
104
-
105
-
```js
106
-
let pro =globalThis;
107
-
while (pro =Object.getPrototypeOf(pro)) {
108
-
console.log(pro.toString())
109
-
}
110
-
```
111
-
```
112
-
// browsers
113
-
[object Window]
114
-
[object WindowProperties]
115
-
[object EventTarget]
116
-
[object Object]
117
-
null
118
-
```
119
-
```
120
-
// web extension contentscript
121
-
[object Window]
122
-
[object WindowProperties]
123
-
null
124
-
```
106
+
```scheme
107
+
3. Let realm be module.[[Realm]].
108
+
4. Assert: realm is not undefined.
109
+
+ if module.[[ScopeCeiling]] is not EMPTY, then
110
+
+ Let outer be NewObjectEnvironment(module.[[ScopeCeiling]], false, null)
111
+
+ Let env be NewModuleEnvironment(outer)
112
+
+ Else
113
+
Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
114
+
5. Set module.[[Environment]] to env.
125
115
```
126
-
// Node.js
127
-
[object Object]
128
-
[object Object]
129
-
null
130
-
```
131
-
```
132
-
// Deno
133
-
[object Window]
134
-
[object EventTarget]
135
-
[object Object]
136
-
null
137
-
```
138
-
```
139
-
// Hermes
140
-
[object Object]
141
-
undefined
116
+
> note:
117
+
> -`module` is Source Text Module Record
118
+
> - NewObjectEnvironment could be called earlier
119
+
> -`[[ScopeCeiling]]` will likely be accessed indirectly
120
+
121
+
122
+
The association between `ModuleRecord` and `ScopeCeiling` ultimately needs to be introduced by an intermediary - potentially the same intermediary that introduces a Module Map or an `importHook`. (e.g. Compartment)
123
+
124
+
> We initially considered associating `ScopeCeiling` with `ModuleSource` in its constructor. It doesn't compose well with the esm-phase-imports proposal anymore.
125
+
126
+
---
127
+
128
+
#### Execution Context interactions
129
+
130
+
131
+
> Note: `module.[[Environment]]` becomes `LexicalEnvironment` of the `moduleContext`
132
+
133
+
```scheme
134
+
11. Set the Realm of moduleContext to module.[[Realm]].
135
+
12. Set the ScriptOrModule of moduleContext to module.
136
+
13. Set the VariableEnvironment of moduleContext to module.[[Environment]].
137
+
14. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
138
+
15. Set the PrivateEnvironment of moduleContext to null.
139
+
16. Set module.[[Context]] to moduleContext.
140
+
17. Push moduleContext onto the execution context stack;
141
+
moduleContext is now the running execution context.
142
142
```
143
143
144
144
145
+
1. The `x` IdentifierReference is evaluated. Per [§13.1.3](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-identifiers-runtime-semantics-evaluation) (Runtime Semantics: Evaluation of IdentifierReference), calls [`ResolveBinding("x")`](https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-resolvebinding).
146
+
147
+
2.[`ResolveBinding`](https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-resolvebinding) reads `env` from the **running execution context's `LexicalEnvironment`**. The running execution context is `module.[[Context]]`, and its `LexicalEnvironment` is the module's `ModuleEnvironmentRecord`. Since module code is always strict, `strict` = **true**. Calls `GetIdentifierReference(moduleEnv, "x", true)`.
148
+
149
+
150
+
3.[`GetIdentifierReference`](https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-getidentifierreference) calls **`moduleEnv.HasBinding("x")`** on the `ModuleEnvironmentRecord`. The module environment holds only the module's own top-level `var`/`let`/`const`/`class` declarations and imported bindings. `x` is none of these, so `HasBinding` returns **false**.
5.`ScopeCeiling.[[OuterEnv]]` is null, so it cannot progress to Realm global for lookup
155
+
156
+
157
+
The change would result in an option to run a module in a context that does not have the means to reach globals lexically.
158
+
The *undeniables* would come from the shared Realm, convenience of accessing intrinsics lexically via their global name
159
+
would depend on the provider of `ScopeCeiling` adding them.
160
+
161
+
---
162
+
163
+
## Intersection Semantics
164
+
165
+
Depends on an umbrella proposal to have an entrypoint to defining a `ScopeCeiling`, so likely will be folded into a Compartment proposal or its subset.
link SourceTextModuleRecord "https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#sourctextmodule-record"
75
+
note for SourceTextModuleRecord "<ahref=https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#sec-source-text-module-record-initialize-environment>InitializeEnvironment()</a><br>to use [[ScopeCeiling]]<br>instead of realm.[[GlobalEnv]]<br>for NewModuleEnvironment(OuterEnv)<br>if [[ScopeCeiling]] not EMPTY"
76
+
77
+
class ScopeCeiling:::added {
78
+
[[OuterEnv]] = null
79
+
[[BindingObject]] handles the globalThis binding and var
80
+
:
81
+
inheriting from ObjectEnvironmentRecord is sufficient,
82
+
but all bindings are dynamic andcould be slower than
83
+
a mix of ObjectRecord and DeclarativeRecord
84
+
}
85
+
86
+
class EnvironmentRecord {
87
+
<<abstract>>
88
+
[[OuterEnv]] : Environment Record | null
89
+
}
90
+
link EnvironmentRecord "https://tc39.es/ecma262/#sec-environment-records"
91
+
92
+
93
+
94
+
class DeclarativeEnvironmentRecord {
95
+
}
96
+
link DeclarativeEnvironmentRecord "https://tc39.es/ecma262/#sec-declarative-environment-records"
97
+
98
+
class ObjectEnvironmentRecord {
99
+
[[BindingObject]] : Object
100
+
[[IsWithEnvironment]] : Boolean
101
+
}
102
+
103
+
class GlobalEnvironmentRecord {
104
+
[[ObjectRecord]] : Object Environment Record
105
+
[[GlobalThisValue]] : Object
106
+
[[DeclarativeRecord]] : Declarative Environment Record
107
+
[[OuterEnv]] = null
108
+
}
109
+
110
+
class ModuleEnvironmentRecord {
111
+
[[OuterEnv]] : Environment Record
112
+
}
113
+
link ModuleEnvironmentRecord "https://tc39.es/ecma262/#sec-module-environment-records"
0 commit comments