-
Notifications
You must be signed in to change notification settings - Fork 5
/
spec.emu
166 lines (160 loc) · 8.05 KB
/
spec.emu
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
<!doctype html>
<meta charset="utf8">
<link rel="stylesheet" href="./spec.css">
<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: Dynamic Code Brand Checks
stage: 3
copyright: false
contributors: Krzysztof Kotowicz, Mike Samuel, Luke Warlow
</pre>
<emu-clause id="sec-hostgetcodeforeval" type="host-defined abstract operation">
<h1>
HostGetCodeForEval (
_argument_: an Object,
): a String or ~no-code~
</h1>
<dl class="header">
<dt>description</dt>
<dd>It allows host environments to return a String of code from _argument_ to be used by eval,
rather than eval returning _argument_.</dd>
</dl>
<p>
_argument_ represents the Object to be checked for code.
</p>
<p>The default implementation of HostGetCodeForEval is to return ~no-code~.</p>
</emu-clause>
<emu-clause id="sec-hostensurecancompilestrings" type="host-defined abstract operation">
<h1>
HostEnsureCanCompileStrings (
_calleeRealm_: a Realm Record,
_parameterStrings_: a List of Strings,
_bodyString_: a String,
<del>_direct_: a Boolean,</del>
<ins>_codeString_: a String,</ins>
<ins>_compilationType_: ~direct-eval~, ~indirect-eval~, or ~function~,</ins>
<ins>_parameterArgs_: a List of ECMAScript language values,</ins>
<ins>_bodyArg_: an ECMAScript language value,</ins>
): either a normal completion containing ~UNUSED~ or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It allows host environments to block certain ECMAScript functions which allow developers to interpret and evaluate strings as ECMAScript code.</dd>
</dl>
<p>
_parameterStrings_ represents the strings that, when using one of the function constructors, will be concatenated together to build the parameters list.
_bodyString_ represents the function body or the string passed to an `eval` call.
<del>_direct_ signifies whether the evaluation is a direct eval.</del>
<ins>_codeString_ represents the string that will be compiled.</ins>
<ins>_compilationType_ is an enum that indicates what type of compilation this is.</ins>
<ins>_parameterArgs_ are the values passed as the leading parameters to one of the Function constructors.</ins>
<ins>_bodyArg_ is either the final parameter passed to one of the Function constructors or the value passed to an `eval` call.</ins>
</p>
<p>The default implementation of HostEnsureCanCompileStrings is to return NormalCompletion(~UNUSED~).</p>
</emu-clause>
<emu-clause id="sec-performeval" type="abstract operation" oldids="sec-performeval-rules-outside-functions,sec-performeval-rules-outside-methods,sec-performeval-rules-outside-constructors">
<h1>
PerformEval (
_x_: an ECMAScript language value,
_strictCaller_: a Boolean,
_direct_: ~direct-eval~ or ~indirect-eval~,
): either a normal completion containing an ECMAScript language value or a throw completion
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: If _direct_ is ~indirect-eval~, then _strictCaller_ is also *false*.
1. <ins>If _x_ is a String, then</ins>
1. <ins>Let _xStr_ be _x_.</ins>
1. <ins>Else if _x_ is an Object, then</ins>
1. <ins>Let _code_ be HostGetCodeForEval(_x_).</ins>
1. <ins>If _code_ is a String, let _xStr_ be _code_.</ins>
1. <ins>Else, return _x_.</ins>
1. <ins>Else,</ins>
1. <ins>Return _x_.</ins>
1. <del>If _x_ is not a String, return _x_.</del>
1. <ins>If _x_ is an Object and ! IsCodeLike(_x_) is *true*, then</ins>
1. <ins>Let _xStr_ be ? ToString(_x_).</ins>
1. <ins>Else, if _x_ is a String, then</ins>
1. <ins>Let _xStr_ be _x_.</ins>
1. <ins>Else,</ins>
1. <ins>Return _x_.</ins>
1. Let _evalRealm_ be the current Realm Record.
1. NOTE: In the case of a direct eval, _evalRealm_ is the realm of both the caller of `eval` and of the `eval` function itself.
1. Perform ? HostEnsureCanCompileStrings(_evalRealm_, « », <del>_x_</del> <ins>_xStr_, _xStr_,</ins> _direct_<ins>, « », _x_</ins>).<br>
1. ...
</emu-alg>
</emu-clause>
<emu-clause id="sec-createdynamicfunction" type="abstract operation" oldids="table-dynamic-function-sourcetext-prefixes">
<h1>
CreateDynamicFunction (
_constructor_: a constructor,
_newTarget_: a constructor,
_kind_: ~normal~, ~generator~, ~async~, or ~async-generator~,
_parameterArgs_: a List of ECMAScript language values,
_bodyArg_: an ECMAScript language value,
): either a normal completion containing an ECMAScript function object or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>_constructor_ is the constructor function that is performing this action. _newTarget_ is the constructor that `new` was initially applied to. _parameterArgs_ and _bodyArg_ reflect the argument values that were passed to _constructor_.</dd>
</dl>
<emu-alg>
1. If _newTarget_ is *undefined*, set _newTarget_ to _constructor_.
1. If _kind_ is ~normal~, then
1. Let _prefix_ be *"function"*.
1. Let _exprSym_ be the grammar symbol |FunctionExpression|.
1. Let _bodySym_ be the grammar symbol |FunctionBody[~Yield, ~Await]|.
1. Let _parameterSym_ be the grammar symbol |FormalParameters[~Yield, ~Await]|.
1. Let _fallbackProto_ be *"%Function.prototype%"*.
1. Else if _kind_ is ~generator~, then
1. Let _prefix_ be *"function\*"*.
1. Let _exprSym_ be the grammar symbol |GeneratorExpression|.
1. Let _bodySym_ be the grammar symbol |GeneratorBody|.
1. Let _parameterSym_ be the grammar symbol |FormalParameters[+Yield, ~Await]|.
1. Let _fallbackProto_ be *"%GeneratorFunction.prototype%"*.
1. Else if _kind_ is ~async~, then
1. Let _prefix_ be *"async function"*.
1. Let _exprSym_ be the grammar symbol |AsyncFunctionExpression|.
1. Let _bodySym_ be the grammar symbol |AsyncFunctionBody|.
1. Let _parameterSym_ be the grammar symbol |FormalParameters[~Yield, +Await]|.
1. Let _fallbackProto_ be *"%AsyncFunction.prototype%"*.
1. Else,
1. Assert: _kind_ is ~async-generator~.
1. Let _prefix_ be *"async function\*"*.
1. Let _exprSym_ be the grammar symbol |AsyncGeneratorExpression|.
1. Let _bodySym_ be the grammar symbol |AsyncGeneratorBody|.
1. Let _parameterSym_ be the grammar symbol |FormalParameters[+Yield, +Await]|.
1. Let _fallbackProto_ be *"%AsyncGeneratorFunction.prototype%"*.
1. Let _argCount_ be the number of elements in _parameterArgs_.
1. Let _parameterStrings_ be a new empty List.
1. For each element _arg_ of _parameterArgs_, do
1. Append ? ToString(_arg_) to _parameterStrings_.
1. Let _bodyString_ be ? ToString(_bodyArg_).
1. Let _currentRealm_ be the current Realm Record.
1. <del>Perform ? HostEnsureCanCompileStrings(_currentRealm_, _parameterStrings_, _bodyString_, *false*).</del>
1. Let _P_ be the empty String.
1. If _argCount_ > 0, then
1. Set _P_ to _parameterStrings_[0].
1. Let _k_ be 1.
1. Repeat, while _k_ < _argCount_,
1. Let _nextArgString_ be _parameterStrings_[_k_].
1. Set _P_ to the string-concatenation of _P_, *","* (a comma), and _nextArgString_.
1. Set _k_ to _k_ + 1.
1. Let _bodyParseString_ be the string-concatenation of 0x000A (LINE FEED), _bodyString_, and 0x000A (LINE FEED).
1. Let _sourceString_ be the string-concatenation of _prefix_, *" anonymous("*, _P_, 0x000A (LINE FEED), *") {"*, _bodyParseString_, and *"}"*.
1. <ins>Perform ? HostEnsureCanCompileStrings(_currentRealm_, _parameterStrings_, _bodyString_, _sourceString_, ~FUNCTION~, _parameterArgs_, _bodyArg_).</ins>
1. ...
</emu-alg>
<emu-note>
<p>CreateDynamicFunction defines a *"prototype"* property on any function it creates whose _kind_ is not ~async~ to provide for the possibility that the function will be used as a constructor.</p>
</emu-note>
</emu-clause>
<emu-annex id="sec-host-layering-points">
<h1>Host Layering Points</h1>
<emu-annex id="sec-host-hooks-summary">
<h1>Host Hooks</h1>
<p><ins><b>HostGetCodeForEval(...)</b></ins></p>
</emu-annex>
</emu-annex>