-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathspec.emu
More file actions
265 lines (252 loc) · 14.8 KB
/
Copy pathspec.emu
File metadata and controls
265 lines (252 loc) · 14.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
<!doctype html>
<meta charset="utf8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">
<script src="./spec.js"></script>
<pre class="metadata">
title: SafePromiseResolve
stage: 2
contributors: Matthew Gaudet, Justin Ridgewell
</pre>
<emu-clause id="sec-safe-resolve-promise">
<h1>SafePromiseResolve Abstract Operations</h1>
<p>These operations provide a mechanism for resolving a promise such that, if resolution would synchronously execute arbitrary user code, the user-code-running portion is deferred to a subsequent microtask. On return from SafePromiseResolve, the caller's PromiseCapability Record is guaranteed to be latched: any subsequent call to its [[Resolve]] or [[Reject]] is a no-op, regardless of whether the deferred job has yet run.</p>
<emu-clause id="sec-has-property-which-could-run-user-code" type="abstract operation">
<h1>
PropertyAccessCouldRunUserCode (
_o_: an Object,
_propertyKey_: a property key,
_kind_: ~any~, ~set~ or ~get~
): a Boolean
</h1>
<dl class="header">
<dt>description</dt>
<dd>It walks the prototype chain of _o_ looking for _propertyKey_, returning *true* if retrieving the property could run user code when performing the operation of _kind_: that is, the property is a getter, setter, or a Proxy is encountered on the chain. This should never run user code.</dd>
</dl>
<emu-alg>
1. <ins>Assert: The following steps do not run user code.</ins>
1. <ins>If _o_ is *null*, return *false*.</ins>
1. <ins>If HostObjectHasImpureLookupInternalMethods(_o_) is *true*, return *true*.</ins>
1. <ins>If _o_ has a [[ProxyHandler]] internal slot, return *true*.</ins>
1. <ins>if _o_ has the [[GetPrototypeOf]] and [[GetOwnProperty]] internal methods as defined in <emu-xref href="#sec-ordinary-object-internal-methods-and-internal-slots"></emu-xref>, return *true*.</ins>
1. <ins>Let _desc_ be _o_.[[GetOwnProperty]](_propertyKey_).</ins>
1. <ins>If _desc_ is not *undefined*, then</ins>
1. <ins>If _desc_ has a [[Get]] field and kind is ~any~ or ~get~, return *true*.</ins>
1. <ins>If _desc_ has a [[Set]] field and kind is ~any~ or ~set~, return *true*.</ins>
1. <ins>Return *false*.</ins>
1. <ins>Return PropertyAccessCouldRunUserCode(_o_.[[GetPrototypeOf]](), _propertyKey_, _kind_).</ins>
</emu-alg>
</emu-clause>
<emu-clause id="sec-perform-promise-resolution" type="abstract operation">
<h1>
PerformPromiseResolution (
_promise_: a Promise,
_resolution_: an ECMAScript language value,
_thenCallTiming_: ~sync~ or ~deferred~,
): a normal completion containing ~unused~
</h1>
<dl class="header">
<dt>description</dt>
<dd>It performs the value-inspecting steps of resolving _promise_ with _resolution_.</dd>
</dl>
<emu-alg>
1. <ins>Assert: _promise_ has a [[PromiseState]] internal slot.</ins>
1. <ins>If SameValue(_resolution_, _promise_) is *true*, then</ins>
1. <ins>Let _selfResolutionError_ be a newly created *TypeError* object.</ins>
1. <ins>Perform RejectPromise(_promise_, _selfResolutionError_).</ins>
1. <ins>Return ~unused~.</ins>
1. <ins>If _resolution_ is not an Object, then</ins>
1. <ins>Perform FulfillPromise(_promise_, _resolution_).</ins>
1. <ins>Return ~unused~.</ins>
1. <ins>Let _then_ be Completion(Get(_resolution_, *"then"*)).</ins>
1. <ins>If _then_ is an abrupt completion, then</ins>
1. <ins>Perform RejectPromise(_promise_, _then_.[[Value]]).</ins>
1. <ins>Return ~unused~.</ins>
1. <ins>Let _thenAction_ be _then_.[[Value]].</ins>
1. <ins>If IsCallable(_thenAction_) is *false*, then</ins>
1. <ins>Perform FulfillPromise(_promise_, _resolution_).</ins>
1. <ins>Return ~unused~.</ins>
1. <ins>If _thenCallTiming_ is ~deferred~, then</ins>
1. <ins>Perform ! PerformPromiseResolveThenable(_promise_, _resolution_, _thenAction_).</ins>
1. <ins>Return ~unused~.</ins>
1. <ins>Let _thenJobCallback_ be HostMakeJobCallback(_thenAction_).</ins>
1. <ins>Let _job_ be NewPromiseResolveThenableJob(_promise_, _resolution_, _thenJobCallback_).</ins>
1. <ins>Perform HostEnqueuePromiseJob(_job_.[[Job]], _job_.[[Realm]]).</ins>
1. <ins>Return ~unused~.</ins>
</emu-alg>
</emu-clause>
<emu-clause id="sec-newpromiseresolvethenablejob" type="abstract operation" oldids="sec-promiseresolvethenablejob">
<h1>
NewPromiseResolveThenableJob (
_promiseToResolve_: a Promise,
_thenable_: an Object,
_then_: a JobCallback Record,
): a Record with fields [[Job]] (a Job Abstract Closure) and [[Realm]] (a Realm Record)
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Let _job_ be a new Job Abstract Closure with no parameters that captures _promiseToResolve_, _thenable_, and _then_ and performs the following steps when called:
1. <ins>Return ? PerformPromiseResolveThenable(_promiseToResolve_, _thenable_, _then_).</ins>
1. <del>Let _resolvingFunctions_ be CreateResolvingFunctions(_promiseToResolve_).</del>
1. <del>Let _thenCallResult_ be Completion(HostCallJobCallback(_then_, _thenable_, « _resolvingFunctions_.[[Resolve]], _resolvingFunctions_.[[Reject]] »)).</del>
1. <del>If _thenCallResult_ is an abrupt completion, then</del>
1. <del>Return ? Call(_resolvingFunctions_.[[Reject]], *undefined*, « _thenCallResult_.[[Value]] »).</del>
1. <del>Return ! _thenCallResult_.</del>
1. Let _getThenRealmResult_ be Completion(GetFunctionRealm(_then_.[[Callback]])).
1. If _getThenRealmResult_ is a normal completion, let _thenRealm_ be _getThenRealmResult_.[[Value]].
1. Else, let _thenRealm_ be the current Realm Record.
1. NOTE: _thenRealm_ is never *null*. When _then_.[[Callback]] is a revoked Proxy and no code runs, _thenRealm_ is used to create error objects.
1. Return the Record { [[Job]]: _job_, [[Realm]]: _thenRealm_ }.
</emu-alg>
<emu-note>
<p>This Job uses the supplied thenable and its `then` method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the `then` method occurs after evaluation of any surrounding code has completed.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-perform-promise-resolve-thenable" type="abstract operation">
<h1>
PerformPromiseResolveThenable (
_promiseToResolve_: a Promise,
_thenable_: an Object,
_then_: a JobCallback Record or a function object,
): a normal completion containing an ECMAScript language value
</h1>
<dl class="header">
</dl>
<emu-alg>
1. <ins>Let _resolvingFunctions_ be CreateResolvingFunctions(_promiseToResolve_).</ins>
1. <ins>If _then_ is a function object, then</ins>
1. <ins>Let _thenCallResult_ be Completion(Call(_then_, _thenable_, « _resolvingFunctions_.[[Resolve]], _resolvingFunctions_.[[Reject]] »)).</ins>
1. <ins>Else,</ins>
1. <ins>Let _thenCallResult_ be Completion(HostCallJobCallback(_then_, _thenable_, « _resolvingFunctions_.[[Resolve]], _resolvingFunctions_.[[Reject]] »)).</ins>
1. <ins>If _thenCallResult_ is an abrupt completion, then</ins>
1. <ins>Return ! Call(_resolvingFunctions_.[[Reject]], *undefined*, « _thenCallResult_.[[Value]] »).</ins>
1. <ins>Return ! _thenCallResult_.</ins>
</emu-alg>
</emu-clause>
<emu-clause id="sec-createresolvingfunctions-modified" type="abstract operation">
<h1>
CreateResolvingFunctions (
_toResolve_: a Promise,
): a Record with fields [[Resolve]] (a function object) and [[Reject]] (a function object)
</h1>
<dl class="header">
<dt>description</dt>
<dd>This is a modification of the existing <emu-xref href="#sec-createresolvingfunctions">CreateResolvingFunctions</emu-xref>.</dd>
</dl>
<emu-alg>
1. Let _promiseOrEmpty_ be the Record { [[Value]]: _toResolve_ }.
1. Let _resolveSteps_ be a new Abstract Closure with parameters (_resolution_) that captures _promiseOrEmpty_ and performs the following steps when called:
1. If _promiseOrEmpty_.[[Value]] is ~empty~, return *undefined*.
1. Let _promise_ be _promiseOrEmpty_.[[Value]].
1. Set _promiseOrEmpty_.[[Value]] to ~empty~.
1. <ins>Perform ? PerformPromiseResolution(_promise_, _resolution_, ~sync~).</ins>
1. <del>If SameValue(_resolution_, _promise_) is *true*, then</del>
1. <del>Let _selfResolutionError_ be a newly created *TypeError* object.</del>
1. <del>Perform RejectPromise(_promise_, _selfResolutionError_).</del>
1. <del>Return *undefined*.</del>
1. <del>If _resolution_ is not an Object, then</del>
1. <del>Perform FulfillPromise(_promise_, _resolution_).</del>
1. <del>Return *undefined*.</del>
1. <del>Let _then_ be Completion(Get(_resolution_, *"then"*)).</del>
1. <del>If _then_ is an abrupt completion, then</del>
1. <del>Perform RejectPromise(_promise_, _then_.[[Value]]).</del>
1. <del>Return *undefined*.</del>
1. <del>Let _thenAction_ be _then_.[[Value]].</del>
1. <del>If IsCallable(_thenAction_) is *false*, then</del>
1. <del>Perform FulfillPromise(_promise_, _resolution_).</del>
1. <del>Return *undefined*.</del>
1. <del>Let _thenJobCallback_ be HostMakeJobCallback(_thenAction_).</del>
1. <del>Let _job_ be NewPromiseResolveThenableJob(_promise_, _resolution_, _thenJobCallback_).</del>
1. <del>Perform HostEnqueuePromiseJob(_job_.[[Job]], _job_.[[Realm]]).</del>
1. Return *undefined*.
1. Let _resolve_ be CreateBuiltinFunction(_resolveSteps_, 1, *""*, « »).
1. Let _rejectSteps_ be a new Abstract Closure with parameters (_reason_) that captures _promiseOrEmpty_ and performs the following steps when called:
1. If _promiseOrEmpty_.[[Value]] is ~empty~, return *undefined*.
1. Let _promise_ be _promiseOrEmpty_.[[Value]].
1. Set _promiseOrEmpty_.[[Value]] to ~empty~.
1. Perform RejectPromise(_promise_, _reason_).
1. Return *undefined*.
1. Let _reject_ be CreateBuiltinFunction(_rejectSteps_, 1, *""*, « »).
1. Return the Record { [[Resolve]]: _resolve_, [[Reject]]: _reject_ }.
</emu-alg>
</emu-clause>
<emu-clause id="sec-safe-promise-resolve" type="abstract operation">
<h1>
SafePromiseResolve (
_promiseCapability_: a PromiseCapability Record,
_resolution_: an ECMAScript language value,
): either a normal completion containing *undefined* or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It resolves _promiseCapability_.[[Promise]] with _resolution_, deferring the user-code-running steps to a subsequent microtask if _resolution_ might execute user code synchronously. In either branch, _promiseCapability_'s resolving functions are latched on return. Safe in this sense refers only to the execution of user code during the execution of the promise resolve.</dd>
</dl>
<emu-alg>
1. <ins>If RequiresDeferredPromiseResolution(_resolution_) is *false*, then</ins>
1. <ins>Return ? Call(_promiseCapability_.[[Resolve]], *undefined*, « _resolution_ »).</ins>
1. <ins>Let _promise_ be _promiseCapability_.[[Promise]].</ins>
1. <ins>Let _deferredSteps_ be a new Abstract Closure that captures _promise_ and _resolution_ and performs the following steps when called:</ins>
1. <ins>Perform ? PerformPromiseResolution(_promise_, _resolution_, ~deferred~).</ins>
1. <ins>Return *undefined*.</ins>
1. <ins>Let _deferredThen_ be CreateBuiltinFunction(_deferredSteps_, 0, *""*, « »).</ins>
1. <ins>Let _wrapper_ be OrdinaryObjectCreate(*null*).</ins>
1. <ins>Perform ! CreateDataPropertyOrThrow(_wrapper_, *"then"*, _deferredThen_).</ins>
1. <ins>Return ? Call(_promiseCapability_.[[Resolve]], *undefined*, « _wrapper_ »).</ins>
</emu-alg>
<emu-note>
<p>The wrapper object is never exposed to user code. It is constructed solely so that resolving _promise_ with it uses the existing thenable support for good rather than evil; we mark the promise as not eligible for overriding resolve, and a job is created for running the 'then' code.</p>
</emu-note>
<emu-clause id="sec-requires-deferred-promise-resolution" type="abstract operation">
<h1>
RequiresDeferredPromiseResolution (
_value_: an ECMAScript language value,
): a Boolean
</h1>
<dl class="header">
<dt>description</dt>
<dd>It determines whether the synchronous steps of resolving a promise with _value_ might execute user code.</dd>
</dl>
<emu-alg>
1. <ins>If _value_ is not an Object, return *false*.</ins>
1. <ins>If PropertyAccessCouldRunUserCode(_value_, *"then"*, ~get~) is *true*, return *true*.</ins>
1. <ins>Let _thenValue_ be ! _value_.[[Get]](*"then"*).</ins>
1. <ins>If IsCallable(_thenValue_) is *true*, return *true*.</ins>
1. <ins>Return *false*.</ins>
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-hosthasinternalmethodswhichcanrunusercode" type="host-defined abstract operation">
<h1>
HostObjectHasImpureLookupInternalMethods (
_object_: an Object.
): a Boolean
</h1>
<dl class="header">
<dt>description</dt>
<dd>Indicates if a host object overrides the methods [[GetOwnProperty]] or [[GetPrototypeOf]] in such a way that user code could run.</dd>
</dl>
<p>An implementation of HostObjectHasImpureLookupInternalMethods should return *true* if the given object is a host defined object with its own definition of [[GetOwnProperty]] or [[GetPrototypeOf]] such that
user code could run</p>
<p>The default implementation of HostObjectHasImpureLookupInternalMethods is to return *false*.</p>
</emu-clause>
<emu-annex id="sec-host-hooks-summary">
<h1>Host Hooks</h1>
<p><b>HostCallJobCallback(...)</b></p>
<p><b>HostEnqueueFinalizationRegistryCleanupJob(...)</b></p>
<p><b>HostEnqueueGenericJob(...)</b></p>
<p><b>HostEnqueuePromiseJob(...)</b></p>
<p><b>HostEnqueueTimeoutJob(...)</b></p>
<p><b>HostEnsureCanCompileStrings(...)</b></p>
<p><b>HostFinalizeImportMeta(...)</b></p>
<p><b>HostGetImportMetaProperties(...)</b></p>
<p><b>HostGrowSharedArrayBuffer(...)</b></p>
<p><b>HostHasSourceTextAvailable(...)</b></p>
<p><b>HostLoadImportedModule(...)</b></p>
<p><b>HostGetSupportedImportAttributes(...)</b></p>
<p><b>HostMakeJobCallback(...)</b></p>
<p><b>HostPromiseRejectionTracker(...)</b></p>
<p><b>HostResizeArrayBuffer(...)</b></p>
<p><b>InitializeHostDefinedRealm(...)</b></p>
<ins><p><b>HostObjectHasImpureLookupInternalMethods(...)</b></p></ins>
</emu-annex>