phoboslab / JavaScriptCore-iOS

Apple's JavaScript Engine, with modified project files for iOS
695 stars 166 forks source link

Problem using JSTypedArray #37

Open kyriosli opened 5 years ago

kyriosli commented 5 years ago

Hello, I ran into a problem using JSTypedArray and was wondering if you could give me some help.

I read through the blog here and figured it out it could not solve my problem, but wondering if you might have ran into the same problem. I used an ArrayBuffer to transfer large amount of data from js to C, but the result is sometimes wrong. When I set a value in js, the underlying memory is untouched. for example

let arr = ... // arr is a Uint8Array
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
console.log(arr[0], arr[1], arr[2], arr[3]); // 1 2 3 4
console.log('' + arr); // something other than 1,2,3,4
console.log(arr[0], arr[1], arr[2], arr[3]); // something other than 1 2 3 4

It happens randomly, cannot be reproduced every time. The key is that when I made a native call, such as passing the TypedArray object into a native function, or calling toString of the typed array, the array then acts normally. Even if the native function does nothing with the array (such as JSObjectGetTypedArrayBytesPtr).

I sincerely hope that you could give some guidance about how to avoid this bug, many thanks.

phoboslab commented 5 years ago

Sounds like this might be a bug in this JSC version. The JSC version here is now more than 3 years old - I would advise against using it.

Is there any reason why you can't use the JSC version that comes with iOS?

kyriosli commented 5 years ago

Thanks for your response, I was exactly using the bundled JavaScriptCore.framework in iOS and OSX, and this bug was first found in iOS 11 / MacOS X 10.13, and it still happens in latest version of iOS and OSX.

So I wonder if you happens to encountered into the same problem when using embed JSC in Ejecta or other projects. I realized that Ejecta uses JSObjectGetTypedArrayBytesPtr to get low level storage of TypedArray in EJConvert.m, which is exactly what I was doing.

phoboslab commented 5 years ago

Well, if this problem occurs with the current, stable JSC version, I would assume it's either a bug in your code or some very specific use case/interaction with other APIs. Otherwise lots of other people would have encountered this problem.

So, no, I have not encountered this problem. But I may be able to help if you can share your code.

kyriosli commented 5 years ago

Thanks, actually I still cannot reproduce it with very simple code, it only happens in cases of a large quantity of js codes. But I'd let you know if there being any progress.

kyriosli commented 3 years ago

Just wanna let you know that after a period of digging into such weird cases, We figured out that the reason might be that, jsc processes micro tasks inappropriately.

When a native call occurs, such as calling a user-defined native function callback, or accessing typed array elms, it triggers pending micro tasks and some unexpected callbacks is called before the native callbacks run. And if the callback, such as a Promise.then callback, alters the contents of typed array, the bug appears.