Editorial: Express some 'bitwise' Number methods more explicitly
When expressing 'bitwise' operations on Number values, NumberBitwiseOp explicitly expresses the conversion from Number to mathematical integer to bit string, and then from bit string to mathematical integer to Number.
This PR expresses
- Number::bitwiseNOT
- Number::leftShift
- Number::signedRightShift
- Number::unsignedRightShift
to the same level of explicitness.
To do so, it introduces abstract operations:
- NumberToInt32Bits and Int32BitsToNumber
- NumberToUint32Bits and Uint32BitsToNumber
force-pushed to rebase to master, resolve merge-conflicts
Could you reuse NumericToRawBytes and RawBytesToNumeric?
Consider NumberToInt32Bits(_number_), which is effectively:
the 32-bit two's complement bit string representing ℝ(ToInt32(_number_))
Looking at NumericToRawBytes, if we pass _number_ to _value_ and Int32 to _type_, then step 3.c performs
Let _intValue_ be ℝ(ToInt32(_number_)).
which is a good chunk of what NumberToInt32Bits does, so that's promising.
But then, where NumberToInt32Bits wants the 32-bit two's complement bit string for the integer, NumericToRawBytes converts that integer into a List of 4 bytes. So to get from there to what NumberToInt32Bits wants, we'd have to convert each of those bytes to (something like) a List of 8 bits and then concatenate all those bits to reconstruct the 32-bit two's complement bit string. And however you want to express that, you'd probably want to abstract over the details, so you'd end up defining NumberToInt32Bits anyway.
Here's an alternative suggestion:
In 5.2.5 Mathematical Operations, we could define (say) to_s32(_i_) ('s' for 'signed') to be the 32-bit two's complement bit string representing an integer _i_ in the appropriate range.
Then NumberToInt32Bits(_number_) could be defined as to_s32(R(ToInt32(_number_))), at which point it becomes feasible to just use the latter expression instead of defining NumberToInt32Bits.
Similarly, for the rest of this PR, we could replace:
-
NumberToUint32Bits(_number_)->to_u32(ℝ(ToUint32(_number_))) -
Int32BitsToNumber(_bits_)->𝔽(from_s32(_bits_)) -
Uint32BitsToNumber(_bits_)->𝔽(from_u32(_bits_))
You're right, there would need to be additional massaging required for conversion between List of bytes and bit strings. My high-order bit here is to have a chokepoint on the binary conversions.
In RawBytesToNumeric there is the following language:
"Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of a binary little-endian two's complement number of bit length elementSize × 8."
Seems like we should be able to factor out a numeric <> bit string AO, and then the numeric <> List-of-bytes AO can be layered on top.
Okay, but has the scope now grown to the point where it should be a new PR?
Okay, but has the scope now grown to the point where it should be a new PR?
Nope, I think the same PR is fine.
@jmdyck Reminder ping: still interested in doing https://github.com/tc39/ecma262/pull/2274#issuecomment-941687549?
Yup, still interested, it's just not high priority for me right now.
Converting to draft until it's ready for review again.