-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Editorial: Introduce an operation for backing To{Int,Uint}{8,16,32} and To{BigInt,BigUint}64 #3832
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
bf286aa
0b5401f
24b3ce1
85ca958
8d9d33f
06ccf1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5316,39 +5316,54 @@ <h1> | |||||
| </emu-note> | ||||||
| </emu-clause> | ||||||
|
|
||||||
| <emu-clause id="sec-toint32" type="abstract operation"> | ||||||
| <emu-clause id="sec-tofixedsizeinteger" type="abstract operation"> | ||||||
| <h1> | ||||||
| ToInt32 ( | ||||||
| ToFixedSizeInteger ( | ||||||
| _argument_: an ECMAScript language value, | ||||||
| ): either a normal completion containing an integral Number or a throw completion | ||||||
| _signed_: ~unsigned~ or ~signed~, | ||||||
| _bitWidth_: a positive integer, | ||||||
| _type_: ~number~ or ~bigint~, | ||||||
|
Member
Author
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. These three arguments are partially redundant with what TypedArray element type describes in a single enumeration, but the latter also includes FLOAT{16,32,64} and I couldn't find a clean way to layer separation of just the INT/BIGINT values so I've left that as a potential exercise for the future (but ideas for the present are nonetheless welcome). I suspect that going that route would involve something like introducing ToFloat{16,32,64} operations, migrating the last four columns of that table into Abstract Operations along with Is{Unsigned,UnclampedInteger,BigInt}ElementType for use by ToFixedSizeInteger, and simplifying e.g. NumericToRawBytes/NumericToRawBytes/etc.
Contributor
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. Three separate abstract operations seem a bit nicer, because it more clearly separates conversion from and to Number resp. BigInt.
Member
Author
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. Thanks for the suggestion. I took a half step in this direction, keeping the single new operation but making it infallibly map extended mathematical values and moving initial conversion to call sites. |
||||||
| ): either a normal completion containing an integer or a throw completion | ||||||
| </h1> | ||||||
| <dl class="header"> | ||||||
| <dt>description</dt> | ||||||
| <dd>It converts _argument_ to one of 2<sup>32</sup> integral Number values in the inclusive interval from 𝔽(-2<sup>31</sup>) to 𝔽(2<sup>31</sup> - 1).</dd> | ||||||
| <dd>It converts _argument_ to one of 2<sup>_bitWidth_</sup> integers in the inclusive interval from 0 to 2<sup>_bitWidth_</sup> - 1 (if _signed_ is ~unsigned~) or -2<sup>_bitWidth_ - 1</sup> to 2<sup>_bitWidth_ - 1</sup> - 1 (if _signed_ is ~signed~).</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
|
Collaborator
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.
Suggested change
(editorial convention)
Collaborator
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. To be clear (despite GitHub bug), my suggestion is to insert "either".
Member
Author
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 find the comparison conventions terribly confusing/incomplete and possibly contradictory, but since int is a mathematical value, shouldn't this actually be
Collaborator
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. Technically, it's an 'extended mathematical value', which the comparison conventions don't mention, but lumping it in with mathematical values would be reasonable. So yeah, using
Member
Author
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. Done. |
||||||
| 1. Let _int_ be ? ToIntegerOrInfinity(_argument_). | ||||||
| 1. If _int_ is not finite, return *+0*<sub>𝔽</sub>. | ||||||
| 1. Let _int32bit_ be _int_ modulo 2<sup>32</sup>. | ||||||
| 1. If _int32bit_ ≥ 2<sup>31</sup>, return 𝔽(_int32bit_ - 2<sup>32</sup>). | ||||||
| 1. Return 𝔽(_int32bit_). | ||||||
| 1. If _type_ is ~number~, let _int_ be ? ToIntegerOrInfinity(_argument_); else let _int_ be ℝ(? ToBigInt(_argument_)). | ||||||
| 1. If _int_ is not finite, return 0. | ||||||
| 1. Let _fixedInt_ be _int_ modulo 2<sup>_bitWidth_</sup>. | ||||||
| 1. If _signed_ is ~signed~ and _fixedInt_ ≥ 2<sup>_bitWidth_ - 1</sup>, return _fixedInt_ - 2<sup>_bitWidth_</sup>. | ||||||
| 1. Return _fixedInt_. | ||||||
| </emu-alg> | ||||||
| <emu-note> | ||||||
| <p>Given the above definition:</p> | ||||||
| <ul> | ||||||
| <li> | ||||||
| It is idempotent: for any ECMAScript language value _x_, ToInt32(ToInt32(_x_)) is the same as ToInt32(_x_). | ||||||
| </li> | ||||||
| <li> | ||||||
| For any ECMAScript language value _x_, ToInt32(ToUint32(_x_)) is the same as ToInt32(_x_). (It is to preserve this property that *+∞*<sub>𝔽</sub> and *-∞*<sub>𝔽</sub> are mapped to *+0*<sub>𝔽</sub>.) | ||||||
| It is idempotent: for any ECMAScript language value _x_, ToFixedSizeInteger(ToFixedSizeInteger(_x_, _signed_, _bitWidth_, _type_), _signed_, _bitWidth_, _type_) is the same as ToFixedSizeInteger(_x_, _signed_, _bitWidth_, _type_). | ||||||
| </li> | ||||||
|
Contributor
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'd prefer us to retain something like the example from the old note. Something like
Member
Author
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. Done. |
||||||
| <li> | ||||||
| ToInt32 maps *-0*<sub>𝔽</sub> to *+0*<sub>𝔽</sub>. | ||||||
| It is bijective with respect to inversion of _signed_: for any ECMAScript language value _x_, ToFixedSizeInteger(ToFixedSizeInteger(_x_, ~unsigned~, _bitWidth_, _type_), ~signed~, _bitWidth_, _type_) is the same as ToFixedSizeInteger(_x_, ~signed~, _bitWidth_, _type_) and ToFixedSizeInteger(ToFixedSizeInteger(_x_, ~signed~, _bitWidth_, _type_), ~unsigned~, _bitWidth_, _type_) is the same as ToFixedSizeInteger(_x_, ~unsigned~, _bitWidth_, _type_). (It is to preserve this property that +∞ and -∞ are mapped to 0.) | ||||||
| </li> | ||||||
| </ul> | ||||||
| </emu-note> | ||||||
| </emu-clause> | ||||||
|
|
||||||
| <emu-clause id="sec-toint32" type="abstract operation"> | ||||||
| <h1> | ||||||
| ToInt32 ( | ||||||
| _argument_: an ECMAScript language value, | ||||||
| ): either a normal completion containing an integral Number or a throw completion | ||||||
| </h1> | ||||||
| <dl class="header"> | ||||||
| <dt>description</dt> | ||||||
| <dd>It converts _argument_ to one of 2<sup>32</sup> integral Number values in the inclusive interval from 𝔽(-2<sup>31</sup>) to 𝔽(2<sup>31</sup> - 1), excluding *-0*<sub>𝔽</sub>.</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Return 𝔽(? ToFixedSizeInteger(_argument_, ~signed~, 32, ~number~)). | ||||||
| </emu-alg> | ||||||
| </emu-clause> | ||||||
|
|
||||||
| <emu-clause id="sec-touint32" type="abstract operation"> | ||||||
| <h1> | ||||||
| ToUint32 ( | ||||||
|
|
@@ -5360,28 +5375,8 @@ <h1> | |||||
| <dd>It converts _argument_ to one of 2<sup>32</sup> integral Number values in the inclusive interval from *+0*<sub>𝔽</sub> to 𝔽(2<sup>32</sup> - 1).</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Let _int_ be ? ToIntegerOrInfinity(_argument_). | ||||||
| 1. If _int_ is not finite, return *+0*<sub>𝔽</sub>. | ||||||
| 1. Let _int32bit_ be _int_ modulo 2<sup>32</sup>. | ||||||
| 1. [id="step-touint32-return"] Return 𝔽(_int32bit_). | ||||||
| 1. Return 𝔽(? ToFixedSizeInteger(_argument_, ~unsigned~, 32, ~number~)). | ||||||
| </emu-alg> | ||||||
| <emu-note> | ||||||
| <p>Given the above definition:</p> | ||||||
| <ul> | ||||||
| <li> | ||||||
| Step <emu-xref href="#step-touint32-return"></emu-xref> is the only difference between ToUint32 and ToInt32. | ||||||
| </li> | ||||||
| <li> | ||||||
| It is idempotent: for any ECMAScript language value _x_, ToUint32(ToUint32(_x_)) is the same as ToUint32(_x_). | ||||||
| </li> | ||||||
| <li> | ||||||
| For any ECMAScript language value _x_, ToUint32(ToInt32(_x_)) is the same as ToUint32(_x_). (It is to preserve this property that *+∞*<sub>𝔽</sub> and *-∞*<sub>𝔽</sub> are mapped to *+0*<sub>𝔽</sub>.) | ||||||
| </li> | ||||||
| <li> | ||||||
| ToUint32 maps *-0*<sub>𝔽</sub> to *+0*<sub>𝔽</sub>. | ||||||
| </li> | ||||||
| </ul> | ||||||
| </emu-note> | ||||||
| </emu-clause> | ||||||
|
|
||||||
| <emu-clause id="sec-toint16" type="abstract operation"> | ||||||
|
|
@@ -5392,14 +5387,10 @@ <h1> | |||||
| </h1> | ||||||
| <dl class="header"> | ||||||
| <dt>description</dt> | ||||||
| <dd>It converts _argument_ to one of 2<sup>16</sup> integral Number values in the inclusive interval from 𝔽(-2<sup>15</sup>) to 𝔽(2<sup>15</sup> - 1).</dd> | ||||||
| <dd>It converts _argument_ to one of 2<sup>16</sup> integral Number values in the inclusive interval from 𝔽(-2<sup>15</sup>) to 𝔽(2<sup>15</sup> - 1), excluding *-0*<sub>𝔽</sub>.</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Let _int_ be ? ToIntegerOrInfinity(_argument_). | ||||||
| 1. If _int_ is not finite, return *+0*<sub>𝔽</sub>. | ||||||
| 1. Let _int16bit_ be _int_ modulo 2<sup>16</sup>. | ||||||
| 1. If _int16bit_ ≥ 2<sup>15</sup>, return 𝔽(_int16bit_ - 2<sup>16</sup>). | ||||||
| 1. Return 𝔽(_int16bit_). | ||||||
| 1. Return 𝔽(? ToFixedSizeInteger(_argument_, ~signed~, 16, ~number~)). | ||||||
| </emu-alg> | ||||||
| </emu-clause> | ||||||
|
|
||||||
|
|
@@ -5414,22 +5405,8 @@ <h1> | |||||
| <dd>It converts _argument_ to one of 2<sup>16</sup> integral Number values in the inclusive interval from *+0*<sub>𝔽</sub> to 𝔽(2<sup>16</sup> - 1).</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Let _int_ be ? ToIntegerOrInfinity(_argument_). | ||||||
| 1. If _int_ is not finite, return *+0*<sub>𝔽</sub>. | ||||||
| 1. [id="step-touint16-mod"] Let _int16bit_ be _int_ modulo 2<sup>16</sup>. | ||||||
| 1. Return 𝔽(_int16bit_). | ||||||
| 1. Return 𝔽(? ToFixedSizeInteger(_argument_, ~unsigned~, 16, ~number~)). | ||||||
| </emu-alg> | ||||||
| <emu-note> | ||||||
| <p>Given the above definition:</p> | ||||||
| <ul> | ||||||
| <li> | ||||||
| The substitution of 2<sup>16</sup> for 2<sup>32</sup> in step <emu-xref href="#step-touint16-mod"></emu-xref> is the only difference between ToUint32 and ToUint16. | ||||||
| </li> | ||||||
| <li> | ||||||
| ToUint16 maps *-0*<sub>𝔽</sub> to *+0*<sub>𝔽</sub>. | ||||||
| </li> | ||||||
| </ul> | ||||||
| </emu-note> | ||||||
| </emu-clause> | ||||||
|
|
||||||
| <emu-clause id="sec-toint8" type="abstract operation"> | ||||||
|
|
@@ -5440,14 +5417,10 @@ <h1> | |||||
| </h1> | ||||||
| <dl class="header"> | ||||||
| <dt>description</dt> | ||||||
| <dd>It converts _argument_ to one of 2<sup>8</sup> integral Number values in the inclusive interval from *-128*<sub>𝔽</sub> to *127*<sub>𝔽</sub>.</dd> | ||||||
| <dd>It converts _argument_ to one of 2<sup>8</sup> integral Number values in the inclusive interval from *-128*<sub>𝔽</sub> to *127*<sub>𝔽</sub>, excluding *-0*<sub>𝔽</sub>.</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Let _int_ be ? ToIntegerOrInfinity(_argument_). | ||||||
| 1. If _int_ is not finite, return *+0*<sub>𝔽</sub>. | ||||||
| 1. Let _int8bit_ be _int_ modulo 2<sup>8</sup>. | ||||||
| 1. If _int8bit_ ≥ 2<sup>7</sup>, return 𝔽(_int8bit_ - 2<sup>8</sup>). | ||||||
| 1. Return 𝔽(_int8bit_). | ||||||
| 1. Return 𝔽(? ToFixedSizeInteger(_argument_, ~signed~, 8, ~number~)). | ||||||
| </emu-alg> | ||||||
| </emu-clause> | ||||||
|
|
||||||
|
|
@@ -5462,10 +5435,7 @@ <h1> | |||||
| <dd>It converts _argument_ to one of 2<sup>8</sup> integral Number values in the inclusive interval from *+0*<sub>𝔽</sub> to *255*<sub>𝔽</sub>.</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Let _int_ be ? ToIntegerOrInfinity(_argument_). | ||||||
| 1. If _int_ is not finite, return *+0*<sub>𝔽</sub>. | ||||||
| 1. Let _int8bit_ be _int_ modulo 2<sup>8</sup>. | ||||||
| 1. Return 𝔽(_int8bit_). | ||||||
| 1. Return 𝔽(? ToFixedSizeInteger(_argument_, ~unsigned~, 8, ~number~)). | ||||||
| </emu-alg> | ||||||
| </emu-clause> | ||||||
|
|
||||||
|
|
@@ -5640,10 +5610,7 @@ <h1> | |||||
| <dd>It converts _argument_ to one of 2<sup>64</sup> BigInt values in the inclusive interval from ℤ(-2<sup>63</sup>) to ℤ(2<sup>63</sup> - 1).</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Let _n_ be ? ToBigInt(_argument_). | ||||||
| 1. Let _int64bit_ be ℝ(_n_) modulo 2<sup>64</sup>. | ||||||
| 1. If _int64bit_ ≥ 2<sup>63</sup>, return ℤ(_int64bit_ - 2<sup>64</sup>). | ||||||
| 1. Return ℤ(_int64bit_). | ||||||
| 1. Return ℤ(? ToFixedSizeInteger(_argument_, ~signed~, 64, ~bigint~)). | ||||||
| </emu-alg> | ||||||
| </emu-clause> | ||||||
|
|
||||||
|
|
@@ -5658,9 +5625,7 @@ <h1> | |||||
| <dd>It converts _argument_ to one of 2<sup>64</sup> BigInt values in the inclusive interval from *0*<sub>ℤ</sub> to ℤ(2<sup>64</sup> - 1).</dd> | ||||||
| </dl> | ||||||
| <emu-alg> | ||||||
| 1. Let _n_ be ? ToBigInt(_argument_). | ||||||
| 1. Let _int64bit_ be ℝ(_n_) modulo 2<sup>64</sup>. | ||||||
| 1. Return ℤ(_int64bit_). | ||||||
| 1. Return ℤ(? ToFixedSizeInteger(_argument_, ~unsigned~, 64, ~bigint~)). | ||||||
| </emu-alg> | ||||||
| </emu-clause> | ||||||
|
|
||||||
|
|
||||||
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.
Since this now performs no type conversion, "IntegerToFixedSize" might be a better name. Opinions are welcome.