Skip to content

Fix splitI64 so it can be used to send values from JS libraries into wasm #19575

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 8 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/parseTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ function makeInlineCalculation(expression, value, tempVar) {
// value, represented by a low and high i32 pair.
// Will suffer from rounding and truncation.
function splitI64(value) {
if (WASM_BIGINT) {
// Nothing to do: just make sure it is a BigInt (as it must be of that
// type, to be sent into wasm).
return `BigInt(${value})`;
}

// general idea:
//
// $1$0 = ~~$d >>> 0;
Expand All @@ -229,7 +235,6 @@ function splitI64(value) {
// For negatives, we need to ensure a -1 if the value is overall negative,
// even if not significant negative component

assert(!WASM_BIGINT, 'splitI64 should not be used when WASM_BIGINT is enabled');
const low = value + '>>>0';
const high = makeInlineCalculation(
asmCoercion('Math.abs(VALUE)', 'double') + ' >= ' + asmEnsureFloat('1', 'double') + ' ? ' +
Expand Down Expand Up @@ -886,15 +891,10 @@ function receiveI64ParamAsI53(name, onError) {
}

function receiveI64ParamAsI53Unchecked(name) {
if (WASM_BIGINT) return `${name} = Number(${name});`;
return `var ${name} = convertI32PairToI53(${name}_low, ${name}_high);`;
}

function sendI64Argument(low, high) {
if (WASM_BIGINT) {
return 'BigInt(low) | (BigInt(high) << 32n)';
return `${name} = Number(${name});`;
}
return low + ', ' + high;
return `var ${name} = convertI32PairToI53(${name}_low, ${name}_high);`;
}

// Any function called from wasm64 may have bigint args, this function takes
Expand Down
10 changes: 10 additions & 0 deletions test/core/js_library_i64_params.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <assert.h>
#include <emscripten.h>
#include <stdio.h>

#define MAX_SAFE_INTEGER (1ll<<53)
Expand All @@ -8,6 +9,11 @@

int64_t jscall(int64_t arg);

EMSCRIPTEN_KEEPALIVE
void called_from_js(uint64_t arg) {
printf("called_from_js with: %lld\n", arg);
}

void check_ok(int64_t val) {
printf("checking: %lld\n", val);
int64_t rtn = jscall(val);
Expand All @@ -25,7 +31,11 @@ void check_invalid(int64_t val) {
}

int main() {
check_ok(0);
check_ok(1);
check_ok(-1);
check_ok(42);
check_ok(-42);
check_ok(MAX_SAFE_INTEGER/2);
check_ok(MIN_SAFE_INTEGER/2);
check_ok(MAX_SAFE_INTEGER);
Expand Down
3 changes: 3 additions & 0 deletions test/core/js_library_i64_params.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ TestLibrary = {
jscall: function({{{ defineI64Param('foo') }}}) {
{{{ receiveI64ParamAsI53('foo', `(err('overflow'), ${makeReturn64('42')})`) }}}
err('js:got: ' + foo);

_called_from_js({{{ splitI64("foo") }}});

if (foo < 0)
var rtn = Math.ceil(foo / 2);
else
Expand Down
29 changes: 29 additions & 0 deletions test/core/js_library_i64_params.out
Original file line number Diff line number Diff line change
@@ -1,25 +1,54 @@
checking: 0
js:got: 0
called_from_js with: 0
js:returning: 0
got: 0
expected: 0
checking: 1
js:got: 1
called_from_js with: 1
js:returning: 0
got: 0
expected: 0
checking: -1
js:got: -1
called_from_js with: -1
js:returning: 0
got: 0
expected: 0
checking: 42
js:got: 42
called_from_js with: 42
js:returning: 21
got: 21
expected: 21
checking: -42
js:got: -42
called_from_js with: -42
js:returning: -21
got: -21
expected: -21
checking: 4503599627370496
js:got: 4503599627370496
called_from_js with: 4503599627370496
js:returning: 2251799813685248
got: 2251799813685248
expected: 2251799813685248
checking: -4503599627370496
js:got: -4503599627370496
called_from_js with: -4503599627370496
js:returning: -2251799813685248
got: -2251799813685248
expected: -2251799813685248
checking: 9007199254740992
js:got: 9007199254740992
called_from_js with: 9007199254740992
js:returning: 4503599627370496
got: 4503599627370496
expected: 4503599627370496
checking: -9007199254740992
js:got: -9007199254740992
called_from_js with: -9007199254740992
js:returning: -4503599627370496
got: -4503599627370496
expected: -4503599627370496
Expand Down