-
Notifications
You must be signed in to change notification settings - Fork 152
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add JS_ToBigUint64 #416
Add JS_ToBigUint64 #416
Conversation
Ping @chqrlie, can you PTAL? |
quickjs.c
Outdated
int JS_ToBigUint64(JSContext *ctx, uint64_t *pres, JSValue val) | ||
{ | ||
bf_t a_s, *a; | ||
|
||
a = JS_ToBigIntFree(ctx, &a_s, js_dup(val)); | ||
if (!a) { | ||
*pres = 0; | ||
return -1; | ||
} | ||
bf_get_uint64(pres, a); | ||
JS_FreeBigInt(ctx, a, &a_s); | ||
return 0; | ||
} | ||
|
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.
What is the expected behavior of JS_ToBigUint64
for values larger or equal to 264 and for negative values? As a matter of fact, the behavior of JS_ToBigInt64
for values outside the range of int64_t
is unclear to me too.
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.
Well, I'd say it'd defined as extracting the value in the val
BigInt JS object, right? Whatever a JS BigInt objectg can represent, that's what what you'll get here.
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.
Yes, but what if the BigInt value is out of range? Should these functions return the value modulo 264 as specified in ECMA 7.1.7 ToUint32
for example or should they clamp the value and return UINT64_MAX
for values beyond and 0
for negative values.
I much prefer the former (modulo) and it seems to be what the implementation of JS_ToBigInt64
does, but your implementation of JS_ToBigUint64
does the second, which is inconsistent.
The implementation is somewhat tricky because the current implementation of BigInt uses sign+magnitude and a mantissa/exponent representation, but this will change when Fabrice completes his reimplementation of BigInt using a more standard approach and 2's complement representation.
What is the current use case for JS_ToBigUint64
?
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.
I see. Looks like libbf would need to be extended then, since now all it does is set it to UINT64_MAX
. It's also currently unused by quickjs itself, so there is that.
Regarding motivation / use case, I have none, personally. It was requested in #376 and it looked like low hanging fruit, but maybe it isn't after all 😅
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.
Looking again, there are 2 abstract operations defined by ECMA with the corresponding semantics:
- 7.1.15
ToBigInt64
- 7.1.16
ToBigUint64
Both compute the 64-bit value modulo 264, which means they can be implemented using the same internal function and a simple cast on the pointer argument:
int JS_ToBigUint64(JSContext *ctx, uint64_t *pres, JSValue val)
{
return JS_ToBigInt64Free(ctx, (int64_t *)pres, js_dup(val));
}
Or pedantically correct but slower (I prefer the simpler version here above):
int JS_ToBigUint64(JSContext *ctx, uint64_t *pres, JSValue val)
{
int64_t val;
int res = JS_ToBigInt64Free(ctx, &val, js_dup(val));
*pres = val;
return res;
}
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.
I see! Let's go with the simple one then!
Fixes: #376
@chqrlie Updated! |
Fixes: #376