-
-
Notifications
You must be signed in to change notification settings - Fork 6
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
Buffer support #13
Buffer support #13
Conversation
0115d98
to
d0c2923
Compare
|
Thank you for your contribution.
Honestly, I don't know how to use node-gyp to build emscripten project. To use the official test cases, I manually copied them to this repository, then used my toy project @tybys/cgen as the build tool, and I could use JavaScript to write the configuration ( I will add official buffer test here later. |
Heh, I actually have separate upcoming PR for that to emnapi :)
Thanks! |
Ok fixed the problems found via tests (btw, can you enable CI for me please?). One thing I'm not happy about and couldn't figure out is how upstream N-API implementation gets away with not truncating the NULL terminator from the char array when creating a same-sized Buffer: That is, without me doing this |
Oh, It's Without -1, Seems we can not use |
Ah... yes, an old problem :( emscripten-core/emscripten#4693 |
Ok I removed the |
Before merge this PR, I have two questions ask for your opinion:
|
I briefly thought about this, but there are two problems:
If you reallocate, it triggers So, yes, I do think that switching to
Ah yeah, good point - I didn't think of the missing |
Yeah confirmed with a simple failing test: RReverser@b44912b. Feel free to cherry-pick if you want to make it work with |
Nice, didn't realize it, thanks for pointing this out. I will try to make it work. |
if (!handle.isBuffer()) { | ||
return envObject.setLastError(napi_status.napi_invalid_arg) | ||
} | ||
return napi_get_typedarray_info(env, buffer, 0, length, data, 0, 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.
imported symbols start with _
at runtime
packages/emnapi/src/value/create.ts
Outdated
const value = emnapiCtx.addToCurrentScope(arrayBuffer).id | ||
$makeSetValue('result', 0, 'value', '*') |
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.
value
is renamed here by macro expanding, cause makeSetValue receive a wrong variable. It should be declared outside of $PREAMBLE!
macro.
The return value is an ArrayBuffer, but nodejs Buffer is a Uint8Array.
packages/emnapi/src/value/create.ts
Outdated
function napi_create_external_buffer( | ||
env: napi_env, | ||
length: size_t, | ||
data: Pointer<void>, | ||
finalize_cb: napi_finalize, | ||
finalize_hint: Pointer<void>, | ||
result: Pointer<napi_value> | ||
) { | ||
$PREAMBLE!(env, (envObject) => { | ||
const status = napi_create_external_arraybuffer(env, data, length, finalize_cb, finalize_hint, result) | ||
if (status !== napi_status.napi_ok) { | ||
return status | ||
} | ||
const handleId = $makeGetValue('result', 0, '*') | ||
const handle = emnapiCtx.handleStore.get(handleId)! | ||
// I know I'm the only owner of handle, so just wrap value in-place. | ||
handle.value = Buffer.from(handle.value) | ||
return envObject.getReturnStatus() | ||
}) | ||
} |
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.
Should we do something like emnapi_create_external_uint8array
here to avoid memory copying?
packages/runtime/src/Handle.ts
Outdated
@@ -63,6 +63,10 @@ export class Handle<S> { | |||
return !this.isEmpty() && (ArrayBuffer.isView(this.value)) && !(this.value instanceof DataView) | |||
} | |||
|
|||
public isBuffer (): boolean { | |||
return !this.isEmpty() && (this.value instanceof Buffer) |
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.
There is no globalThis.Buffer
in browser environment, prefer typeof Buffer !== 'undefined' && Buffer.isBuffer(this.value)
Hm, little confused at these comments - they seem to be the ones I already found & fixed but Github shows that they were left after the PR was merged? |
emm, sorry, probably it was my bad, I left those comments but forgot to clicked "submit review" button at first, and clicked approve before merging. I thought you had seen it. |
Ah, no, I just ran into same bugs on my own after you added tests, and fixed them myself 😅 |
I don't understand the test structure - they seem to be adapted versions of official N-API tests, but without GYP and with some other modifications. Are they converted automatically somehow or do you rewrite them manually?
Also, you might notice that I went the slightly easier path for
napi_create_external_buffer
by simply wrappingnapi_create_external_arraybuffer
. In theory, both should have more or less the same effect, except that array buffer might be reused for other views and so the finalize callback might be called a bit later; that said, finalize callbacks are already not guaranteed to run at specific time (or at all) so this shouldn't be an issue.