Skip to content

Commit

Permalink
Fix JS integer conversion (#411)
Browse files Browse the repository at this point in the history
Fix #399 and a couple of other small bugs with conversion to/from JS numbers.
  • Loading branch information
rossberg authored Aug 9, 2023
1 parent 9acb6e2 commit 1d9585f
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions document/js-api/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
text: var
text: const
text: address; url: exec/runtime.html#addresses
text: signed_31; url: exec/numerics.html#aux-signed
text: signed_32; url: exec/numerics.html#aux-signed
text: memory.grow; url: exec/instructions.html#exec-memory-grow
text: current frame; url: exec/conventions.html#exec-notation-textual
Expand Down Expand Up @@ -1079,10 +1080,12 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not
The algorithm <dfn>ToJSValue</dfn>(|w|) coerces a [=WebAssembly value=] to a JavaScript value by performing the following steps:

1. Assert: |w| is not of the form [=v128.const=] <var ignore>v128</var>.
1. If |w| is of the form [=i64.const=] |i64|,
1. Let |v| be [=signed_64=](|i64|).
1. Return [=ℤ=](|v| interpreted as a mathematical value).
1. If |w| is of the form [=i32.const=] |i32|, return [=𝔽=]([=signed_32=](|i32| interpreted as a mathematical value)).
1. If |w| is of the form [=i64.const=] |u64|,
1. Let |i64| be [=signed_64=](|u64|).
1. Return [=ℤ=](|i64| interpreted as a mathematical value).
1. If |w| is of the form [=i32.const=] |u32|,
1. Let |i32| be [=signed_32=](|i32|).
2. Return [=𝔽=](|i32| interpreted as a mathematical value).
1. If |w| is of the form [=f32.const=] |f32|,
1. If |f32| is [=+∞=] or [=−∞=], return **+∞**<sub>𝔽</sub> or **-∞**<sub>𝔽</sub>, respectively.
1. If |f32| is [=nan=], return **NaN**.
Expand All @@ -1091,8 +1094,10 @@ The algorithm <dfn>ToJSValue</dfn>(|w|) coerces a [=WebAssembly value=] to a Jav
1. If |f64| is [=+∞=] or [=−∞=], return **+∞**<sub>𝔽</sub> or **-∞**<sub>𝔽</sub>, respectively.
1. If |f64| is [=nan=], return **NaN**.
1. Return [=𝔽=](|f64| interpreted as a mathematical value).
1. If |w| is of the form [=ref.null=] <var ignore>t</var>, return null.
1. If |w| is of the form [=ref.i31=] <var ignore>i</var>, return [=ℤ=](|i|).
1. If |w| is of the form [=ref.null=] |t|, return null.
1. If |w| is of the form [=ref.i31=] |u31|,
1. Let |i31| be [=signed_31=](|u31|).
1. Let return [=𝔽=](|i31|).
1. If |w| is of the form [=ref.struct=] |structaddr|, return the result of creating [=a new Exported GC Object=] from |structaddr| and "struct".
1. If |w| is of the form [=ref.array=] |arrayaddr|, return the result of creating [=a new Exported GC Object=] from |arrayaddr| and "array".
1. If |w| is of the form [=ref.func=] |funcaddr|, return the result of creating [=a new Exported Function=] from |funcaddr|.
Expand All @@ -1119,10 +1124,12 @@ The algorithm <dfn>ToWebAssemblyValue</dfn>(|v|, |type|) coerces a JavaScript va
1. Assert: |type| is not [=v128=].
1. If |type| is [=i64=],
1. Let |i64| be [=?=] [$ToBigInt64$](|v|).
1. Return [=i64.const=] |i64|.
1. Let |u64| be the unsigned integer such that |i64| is [=signed_64=](|u64|).
1. Return [=i64.const=] |u64|.
1. If |type| is [=i32=],
1. Let |i32| be [=?=] [$ToInt32$](|v|).
1. Return [=i32.const=] |i32|.
1. Let |u32| be the unsigned integer such that |i32| is [=signed_32=](|u32|).
1. Return [=i32.const=] |u32|.
1. If |type| is [=f32=],
1. Let |number| be [=?=] [$ToNumber$](|v|).
1. If |number| is **NaN**,
Expand All @@ -1145,8 +1152,10 @@ The algorithm <dfn>ToWebAssemblyValue</dfn>(|v|, |type|) coerces a JavaScript va
1. Return [=ref.extern=] |r|.
1. If |v| is null,
1. Let |r| be [=ref.null=] |heaptype|.
1. Else if |v| [=is a Number=] and |v| is equal to ? [$ToInt32$](|v|) and [=ℝ=](|v|) < 2<sup>30</sup> and [=ℝ=](|v|) ⩾ -2<sup>30</sup>,
1. Let |r| be [=ref.i31=] |v|.
1. Else if |v| [=is a Number=] and |v| is equal to [=?=] [$ToInt32$](|v|) and [=ℝ=](|v|) < 2<sup>30</sup> and [=ℝ=](|v|) ⩾ -2<sup>30</sup>,
1. Let |i31| [=?=] [$ToInt32$](|v|).
1. Let |u31| be the unsigned integer such that |i31| is [=signed_31=](|i31|).
1. Let |r| be [=ref.i31=] |u31|.
1. Else if |v| is an [=Exported Function=],
1. Let |funcaddr| be the value of |v|'s \[[FunctionAddress]] internal slot.
1. Let |r| be [=ref.func=] |funcaddr|.
Expand Down

0 comments on commit 1d9585f

Please sign in to comment.