-
Notifications
You must be signed in to change notification settings - Fork 8
Initial addition of builtin steps #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
5b629af
Mark up options appropriately
ajklein 970e9f6
Make UnwrapString an abstract-op and use it to implement cast
ajklein 8ae777d
Consistently use "steps" instead of "algorithm" for builtins
ajklein 60ae9af
Add test
ajklein 24b7a6a
Add stubs for the rest of the operations
ajklein c85900b
Add fromCharCode
ajklein da36f03
Switch to using the Call abstract op, and add fromCodePoint
ajklein 7410c0d
Add length
ajklein a25d2ae
Add charCodeAt and codePointAt
ajklein b2bd766
Add concat
ajklein 08353e3
Add substring
ajklein ebd3d5f
Use angle quotes appropriately
ajklein f2e5080
Add basic support for fromCharCodeArray
ajklein 76b4db2
Make fromCharCodeArray slightly less formal
ajklein c94a261
Add intoCharCodeArray
ajklein 2631599
Add equals and compare
ajklein File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,14 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT | |
text: 𝔽; url: #𝔽 | ||
text: ℤ; url: #ℤ | ||
text: SameValue; url: sec-samevalue | ||
text: IsStrictlyEqual; url: sec-isstrictlyequal | ||
text: IsLessThan; url: sec-islessthan | ||
text: String.fromCharCode; url: sec-string.fromcharcode | ||
text: String.fromCodePoint; url: sec-string.fromcodepoint | ||
text: String.prototype.charCodeAt; url: sec-string.prototype.charcodeat | ||
text: String.prototype.codePointAt; url: sec-string.prototype.codepointat | ||
text: String.prototype.concat; url: sec-string.prototype.concat | ||
text: String.prototype.substring; url: sec-string.prototype.substring | ||
urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: dfn | ||
url: valid/modules.html#valid-module | ||
text: valid | ||
|
@@ -358,8 +366,8 @@ Note: | |
1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|. | ||
1. [=Compile a WebAssembly module|Compile=] |stableBytes| as a WebAssembly module and store the results as |module|. | ||
1. If |module| is [=error=], return false. | ||
1. Let |builtinSetNames| be options["builtins"] | ||
1. Let |importedStringModule| be options["importedStringConstants"] | ||
1. Let |builtinSetNames| be |options|["builtins"] | ||
1. Let |importedStringModule| be |options|["importedStringConstants"] | ||
1. If [=validate builtins and imported string for a WebAssembly module|validating builtins and imported strings=] for |module| with |builtinSetNames| and |importedStringModule| returns false, return false. | ||
1. Return true. | ||
</div> | ||
|
@@ -390,8 +398,8 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje | |
1. [=compile a WebAssembly module|Compile the WebAssembly module=] |bytes| and store the result as |module|. | ||
1. [=Queue a task=] to perform the following steps. If |taskSource| was provided, queue the task on that task source. | ||
1. If |module| is [=error=], reject |promise| with a {{CompileError}} exception. | ||
1. Let |builtinSetNames| be options["builtins"] | ||
1. Let |importedStringModule| be options["importedStringConstants"] | ||
1. Let |builtinSetNames| be |options|["builtins"] | ||
1. Let |importedStringModule| be |options|["importedStringConstants"] | ||
1. If [=validate builtins and imported string for a WebAssembly module|validating builtins and imported strings=] for |module| with |builtinSetNames| and |importedStringModule| is false, reject |promise| with a {{CompileError}} exception. | ||
1. Otherwise, | ||
1. [=Construct a WebAssembly module object=] from |module|, |bytes|, |builtinSetNames|, |importedStringModule|, and let |moduleObject| be the result. | ||
|
@@ -686,8 +694,8 @@ interface Module { | |
1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|. | ||
1. [=Compile a WebAssembly module|Compile the WebAssembly module=] |stableBytes| and store the result as |module|. | ||
1. If |module| is [=error=], throw a {{CompileError}} exception. | ||
1. Let |builtinSetNames| be options["builtins"] | ||
1. Let |importedStringModule| be options["importedStringConstants"] | ||
1. Let |builtinSetNames| be |options|["builtins"] | ||
1. Let |importedStringModule| be |options|["importedStringConstants"] | ||
1. If [=validate builtins and imported string for a WebAssembly module|validating builtins and imported strings=] for |module| with |builtinSetNames| and |importedStringModule| returns false, throw a {{CompileError}} exception. | ||
1. Set **this**.\[[Module]] to |module|. | ||
1. Set **this**.\[[Bytes]] to |stableBytes|. | ||
|
@@ -1753,7 +1761,7 @@ To <dfn>validate builtin set names</dfn> with |builtinSetNames|, perform the fol | |
</div> | ||
|
||
<div algorithm> | ||
To <dfn>create a builtin function</dfn> from type |functype| and execution steps |steps|, perform the following steps: | ||
To <dfn>create a builtin function</dfn> from type |funcType| and execution steps |steps|, perform the following steps: | ||
|
||
1. Let |stored settings| be the <a spec=HTML>incumbent settings object</a>. | ||
1. Let |hostfunc| be a [=host function=] which executes |steps| when called. | ||
|
@@ -1769,8 +1777,8 @@ To <dfn>instantiate a builtin set</dfn> with name |builtinSetName|, perform the | |
1. Let |builtins| be the result of [=get the builtins for a builtin set=] |builtinSetName| | ||
1. Let |exportsObject| be [=!=] [$OrdinaryObjectCreate$](null). | ||
1. If |externtype| is of the form [=external-type/func=] <var ignore>functype</var>, | ||
1. [=list/iterate|For each=] (|name|, |funcType|, |algorithm|) of |builtins|, | ||
1. Let |funcaddr| be the result fo [=create a builtin function=] with |funcType| and |algorithm| | ||
1. [=list/iterate|For each=] (|name|, |funcType|, |steps|) of |builtins|, | ||
1. Let |funcaddr| be the result fo [=create a builtin function=] with |funcType| and |steps| | ||
1. Let |func| be the result of creating [=a new Exported Function=] from |funcaddr|. | ||
1. Let |value| be |func|. | ||
1. Let |status| be [=!=] [$CreateDataProperty$](|exportsObject|, |name|, |value|). | ||
|
@@ -1797,28 +1805,245 @@ To <dfn>validate an import for builtins</dfn> with |import|, enabled builtins |b | |
|
||
String builtins adapt the interface of the String builtin object. The import name for this set is `wasm:js-string`. | ||
|
||
<div algorithm="js-string-unwrapString"> | ||
<h4 id="builtins-js-string-abstract-ops">Abstract operations</h4> | ||
<div algorithm> | ||
|
||
The <dfn>unwrapString(|v|)</dfn> method, when invoked, performs the following steps: | ||
The <dfn abstract-op lt="UnwrapString">UnwrapString(|v|)</dfn> abstract operation, when invoked, performs the following steps: | ||
|
||
1. If [=Type=](|v|) is not String | ||
1. If [=Type=](|v|) is not [=String=] | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Return |v| | ||
|
||
</div> | ||
|
||
<div algorithm> | ||
|
||
The <dfn abstract-op lt="FromCharCode">FromCharCode(|v|)</dfn> abstract operation, when invoked, performs the following steps: | ||
|
||
1. Assert: |v| is of type [=i32=]. | ||
1. Return [=!=] [$Call$]([=String.fromCharCode=], undefined, « [=ToJSValue=](|v|) »). | ||
|
||
</div> | ||
|
||
<div algorithm> | ||
|
||
The <dfn abstract-op lt="CharCodeAt ">CharCodeAt(|string|, |index|)</dfn> abstract operation, when invoked, performs the following steps: | ||
|
||
1. Assert: |index| is of type [=i32=]. | ||
1. Return [=!=] [$Call$]([=String.prototype.charCodeAt=], |string|, « [=ToJSValue=](|index|) »). | ||
|
||
</div> | ||
|
||
<h4 id="js-string-cast">cast</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref) (result externref))`. | ||
|
||
<div algorithm="js-string-cast"> | ||
When this builtin is invoked with parameter |v|, the following steps must be run: | ||
|
||
1. Return [=?=] [$UnwrapString$](|v|) | ||
|
||
</div> | ||
|
||
<h4 id="js-string-test">test</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref) (result i32))`. | ||
|
||
<div algorithm="js-string-test"> | ||
When this builtin is invoked with parameter |v|, the following steps must be run: | ||
|
||
1. If [=Type=](|v|) is not [=String=] | ||
1. Return 0 | ||
1. Return 1 | ||
|
||
</div> | ||
|
||
<h4 id="js-string-fromCharCodeArray">fromCharCodeArray</h4> | ||
|
||
The |funcType| of this builtin is `(func (param (ref null (array (mut i16))) i32 i32) (result externref))`. | ||
|
||
Note: This function only takes a mutable i16 array defined in its own recursion group. | ||
If this is an issue for toolchains, we can look into how to relax the function type | ||
while still maintaining good performance. | ||
|
||
<div algorithm="js-string-fromCharCodeArray"> | ||
When this builtin is invoked with parameters |array|, |start|, and |end|, the following steps must be run: | ||
|
||
1. If |array| is null | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Let |length| be the number of elements in |array|. | ||
1. If |start| > |end| or |end| > |length| | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Let |result| be the empty string. | ||
1. Let |i| be |start|. | ||
1. While |i| < |end|: | ||
1. Let |charCode| be the value of the element stored at index |i| in |array|. | ||
1. Let |charCodeString| be [$FromCharCode$](|charCode|). | ||
1. Let |result| be the concatenation of |result| and |charCodeString|. | ||
1. Set |i| to |i| + 1. | ||
1. Return |result|. | ||
|
||
</div> | ||
|
||
<h4 id="js-string-intoCharCodeArray">intoCharCodeArray</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref (ref null (array (mut i16))) i32) (result i32))`. | ||
|
||
Note: This function only takes a mutable i16 array defined in its own recursion group. | ||
If this is an issue for toolchains, we can look into how to relax the function type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above. |
||
while still maintaining good performance. | ||
|
||
<div algorithm="js-string-intoCharCodeArray"> | ||
When this builtin is invoked with parameters |string|, |array|, and |start|, the following steps must be run: | ||
|
||
1. If |array| is null | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Let |string| be [=?=] [$UnwrapString$](|string|). | ||
1. Let |stringLength| be the [=string/length=] of |string|. | ||
1. Let |arrayLength| be the number of elements in |array|. | ||
1. If |start| + |length| > |arrayLength| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this needs to be |
||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Let |i| be 0. | ||
1. While |i| < |stringLength|: | ||
1. Let |charCode| be [$CharCodeAt$](|string|, |i|). | ||
1. Set the element at index |start| + |i| in |array| to [=ToWebAssemblyValue=](|charCode|). | ||
1. Set |i| to |i| + 1. | ||
1. Return |stringLength|. | ||
|
||
</div> | ||
|
||
|
||
<h4 id="js-string-fromCharCode">fromCharCode</h4> | ||
|
||
The |funcType| of this builtin is `(func (param i32) (result externref))`. | ||
|
||
<div algorithm="js-string-fromCharCode"> | ||
When this builtin is invoked with parameter |v|, the following steps must be run: | ||
|
||
1. Return [$FromCharCode$](|v|). | ||
|
||
</div> | ||
|
||
<h4 id="js-string-fromCodePoint">fromCodePoint</h4> | ||
|
||
The |funcType| of this builtin is `(func (param i32) (result externref))`. | ||
|
||
<div algorithm="js-string-fromCodePoint"> | ||
When this builtin is invoked with parameter |v|, the following steps must be run: | ||
|
||
1. If |v| > 0x10ffff | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Return [=!=] [$Call$]([=String.fromCodePoint=], undefined, « [=ToJSValue=](|v|) »). | ||
|
||
</div> | ||
|
||
<h4 id="js-string-charCodeAt">charCodeAt</h4> | ||
|
||
The type of this function is `(func (param externref i32) (result i32))`. | ||
|
||
<div algorithm="js-string-charCodeAt"> | ||
When this builtin is invoked, the following steps must be run: | ||
When this builtin is invoked with parameters |string| and |index|, the following steps must be run: | ||
|
||
1. Let |string| be [=?=] [$UnwrapString$](|string|). | ||
1. Let |length| be the [=string/length=] of |string|. | ||
1. If |index| >= |length| | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Return [$CharCodeAt$](|string|, |index|). | ||
|
||
</div> | ||
|
||
<h4 id="js-string-codePointAt">codePointAt</h4> | ||
|
||
The type of this function is `(func (param externref i32) (result i32))`. | ||
|
||
<div algorithm="js-string-codePointAt"> | ||
When this builtin is invoked with parameters |string| and |index|, the following steps must be run: | ||
|
||
1. Let |string| be [=?=] [$UnwrapString$](|string|). | ||
1. Let |length| be the [=string/length=] of |string|. | ||
1. If |index| >= |length| | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. Return [=!=] [$Call$]([=String.prototype.codePointAt=], |string|, « [=ToJSValue=](|index|) »). | ||
|
||
</div> | ||
|
||
<h4 id="js-string-length">length</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref) (result i32))`. | ||
|
||
<div algorithm="js-string-length"> | ||
When this builtin is invoked with parameter |v|, the following steps must be run: | ||
|
||
1. Let |string| be [=?=] [$UnwrapString$](|v|). | ||
1. Return the [=string/length=] of |string|. | ||
|
||
</div> | ||
|
||
1. Let |string| be [$unwrapString$](param0) | ||
1. TODO | ||
<h4 id="js-string-concat">concat</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref externref) (result externref))`. | ||
|
||
<div algorithm="js-string-concat"> | ||
When this builtin is invoked with parameters |first| and |second|, the following steps must be run: | ||
|
||
1. Let |first| be [=?=] [$UnwrapString$](|first|). | ||
1. Let |second| be [=?=] [$UnwrapString$](|second|). | ||
1. Return [=!=] [$Call$]([=String.prototype.concat=], |first|, « |second| »). | ||
|
||
</div> | ||
|
||
<h4 id="js-string-substring">substring</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref i32 i32) (result externref))`. | ||
|
||
<div algorithm="js-string-substring"> | ||
When this builtin is invoked with parameters |string|, |start|, and |end|, the following steps must be run: | ||
|
||
1. Let |string| be [=?=] [$UnwrapString$](|string|). | ||
1. Let |length| be the [=string/length=] of |string|. | ||
1. If |start| > |end| or |start| > |length| | ||
1. Return the empty string. | ||
1. Return [=!=] [$Call$]([=String.prototype.substring=], |string|, « [=ToJSValue=](|start|), [=ToJSValue=](|end|) »). | ||
|
||
</div> | ||
|
||
<h4 id="js-string-equals">equals</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref externref) (result i32))`. | ||
|
||
Note: Explicitly allow null strings to be compared for equality as that is meaningful. | ||
|
||
<div algorithm="js-string-equals"> | ||
|
||
When this builtin is invoked with parameters |first| and |second|, the following steps must be run: | ||
|
||
1. If |first| is not null and [=Type=](|first|) is not [=String=] | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. If |second| is not null and [=Type=](|second|) is not [=String=] | ||
1. Throw a {{RuntimeError}} exception. TODO: this needs to not be catchable, like a trap. | ||
1. If [=!=] [=IsStrictlyEqual=](|first|, |second|) is true | ||
1. Return 1. | ||
1. Return 0. | ||
|
||
</div> | ||
|
||
<h4 id="js-string-compare">compare</h4> | ||
|
||
The |funcType| of this builtin is `(func (param externref externref) (result i32))`. | ||
|
||
<div algorithm="js-string-compare"> | ||
|
||
When this builtin is invoked with parameters |first| and |second|, the following steps must be run: | ||
|
||
1. Let |first| be [=?=] [$UnwrapString$](|first|). | ||
1. Let |second| be [=?=] [$UnwrapString$](|second|). | ||
1. If [=!=] [=IsStrictlyEqual=](|first|, |second|) is true | ||
1. Return 0. | ||
1. If [=!=] [=IsLessThan=](|first|, |second|, true) is true | ||
1. Return -1. | ||
1. Return 1. | ||
|
||
</div> | ||
|
||
<h2 id="errors">Error Condition Mappings to JavaScript</h2> | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets drop the second line of "If this is an issue...good performance". It's not clear how we could do that at this point, and no one has seemed to complain.