Closed yar2001 closed 3 months ago
Thanks for the report. Does it need to be x < -128
? Because to me the creation of many runtime/context instances seems more likely to be the cause. I wonder if Safari is hitting some limit with memory allocation so we end up with a runtime or context pointer that’s out of bounds for some reason.
Does the error occur with other build variants?
Does it need to be
x < -128
?
Yes, it needs to be a negative number smaller than -2. The code will throw the error if it is -2
, -3
, -128
...
My original scenario is a long piece of code that executes 60 times per second. There will be no error if I remove the negative number from the code. A strange behavior that I took a while to find.
Does the error occur with other build variants?
Yes, it also occurs on quickjs-ng.
Hi, we have encountered the same issue in our app on Safari.
The issue is somehow related to negative numbers.
I was able to test and reproduce the issue on the following environments.
I couldn't reproduce the issue on asyncify builds.
Variant | Works |
---|---|
@jitl/quickjs-wasmfile-release-sync | :x: |
@jitl/quickjs-wasmfile-release-asyncify | :white_check_mark: |
@jitl/quickjs-ng-wasmfile-release-sync | :x: |
@jitl/quickjs-ng-wasmfile-release-asyncify | :white_check_mark: |
@jitl/quickjs-singlefile-browser-release-sync | :x: |
@jitl/quickjs-singlefile-browser-release-asyncify | :white_check_mark: |
We managed to get the out of bounds memory access by using a single context.
const context = QuickJS.newContext();
for (let i = 0; i < 1000000; i++) {
const result = context.evalCode(`1 < -128`);
context.unwrapResult(result).dispose();
}
context.dispose();
console.log("ok");
I tested it again and found that any negative integer literal that is less than -2 would throw the error.
Error: -2
-(2)
-2.0
-0b10
1 < -2
OK: -1
-0
+2
-2.1
0 - 2
-(2 + 0)
var x = 2; -x
-0b1
I guess the problem may occur in js_atof
function (quickjs.c#L10189) ?
We don't use this project directly, but we do use QuickJS embedded into a larger C++ project which is compiled to WASM via Emscripten.
If this is the same issue that I've been digging into, it seems it may have something to do with push_short_int()
and the OP_push_i8
and OP_push_i16
SHORT_OPCODES.
Possible workaround:
push_short_int()
as follows seems to avoid the crash on Safari (at least in some very initial testing in my own particular use-case - I have not tested with the repro above, as we don't use this project directly):
static void push_short_int(DynBuf *bc_out, int val)
{
#if SHORT_OPCODES
if (val >= -1 && val <= 7) {
dbuf_putc(bc_out, OP_push_0 + val);
return;
}
if (val == (int8_t)val) { dbuf_putc(bc_out, OP_push_i8); dbuf_putc(bc_out, val); return; } if (val == (int16_t)val) { dbuf_putc(bc_out, OP_push_i16); dbuf_put_u16(bc_out, val); return; }
dbuf_putc(bc_out, OP_push_i32); dbuf_put_u32(bc_out, val); }
We don't use this project directly, but we do use QuickJS embedded into a larger C++ project which is compiled to WASM via Emscripten.
If this is the same issue that I've been digging into, it seems it may have something to do with
push_short_int()
and theOP_push_i8
andOP_push_i16
SHORT_OPCODES.
Thanks a lot! Based on my testing, it will fix the problem.
This seems to be an upstream library issue, should we report it to QuickJS, Emscripten or Webkit?
Thanks a lot! Based on my testing, it will fix the problem.
This seems to be an upstream library issue, should we report it to QuickJS, Emscripten or Webkit?
I am only able to reproduce this on Safari (never had an issue on Chrome or Firefox), so it seems like a WebKit-specific issue.
As such, I’d suggest reporting it to Emscripten (who might have some further ideas as to what might be going wrong) and WebKit.
Something important to note: This issue is only reproducible on Safari / WebKit on Apple Silicon / ARM. The issue does not occur on Safari on Intel Macs. So it looks to be a WebKit + ARM / Apple Silicon specific issue.
I'm not sure if I can provide an informative enough issue for Emscripten, can @justjake help? Probably we should report the Out of bounds memory access
error that is caused by OP_push_i8
and OP_push_i16
SHORT_OPCODES in push_short_int() only on ARM Safari. Thanks a lot!
I encountered a strange issue: when running a code that includes a negative number smaller than
-2
on Safari, it will throwOut of bounds memory access (evaluating 'a.apply(null,h)')
Error.The following code will work on all platforms except iOS or Mac ARM Safari.
To get the error, the code should be executed multiple times. In a real-world scenario, with longer code, the error will appear sooner.
I looked at a related issue but did not solve the problem: https://github.com/justjake/quickjs-emscripten/issues/35
Here is the replication:
quickjs-emscripten-ios-error.zip
Works on Chrome:
Mac M2 Safari 17.4 throws the error: