-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
feat(ext/web): use ArrayBuffer.was_detached() #16307
feat(ext/web): use ArrayBuffer.was_detached() #16307
Conversation
710ba13
to
f6d4b41
Compare
ext/web/lib.rs
Outdated
#[op(v8)] | ||
fn op_arraybuffer_was_detached<'a>( | ||
_scope: &mut v8::HandleScope<'a>, | ||
input: serde_v8::Value<'a>, | ||
) -> Result<bool, AnyError> { | ||
let ab = v8::Local::<v8::ArrayBuffer>::try_from(input.v8_value)?; | ||
Ok(ab.was_detached()) | ||
} | ||
|
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.
Why not make this a function in Deno.core
, like Deno.core.isProxy
?
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.
Like this?
Line 355 in edaba4d
isProxy: (value) => ops.op_is_proxy(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.
Yeah. The op would have to be moved to core/ops_builtin_v8.rs
.
f6d4b41
to
d5e8c42
Compare
@marcosc90 you should be now unblocked on this PR after rebasing against |
// TODO(marcosc90) remove isFakeDetached once transferArrayBuffer | ||
// actually detaches the buffer | ||
return ReflectHas(O, isFakeDetached) || | ||
core.ops.op_arraybuffer_was_detached(O); |
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.
This can be changed after is merged #16294 to:
return core.ops.op_arraybuffer_was_detached(O);
core/01_core.js
Outdated
@@ -364,6 +364,7 @@ | |||
eventLoopHasMoreWork: () => ops.op_event_loop_has_more_work(), | |||
setPromiseRejectCallback: (fn) => ops.op_set_promise_reject_callback(fn), | |||
byteLength: (str) => ops.op_str_byte_length(str), | |||
arrayBufferWasDetached: (ab) => ops.op_arraybuffer_was_detached(ab), |
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.
This is not needed, since you're calling it like core.ops.op_arraybuffer_was_detached
in code. Feel free to remove it 👍
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.
Done! I added it because it was proposed by Andreu #16307 (comment)
To be honest, I'm not sure what's the reason for exposing some methods to Deno.core
if almost all of them are available in Deno.core.ops
, couldn't find any info about the reasoning, AFAIK those APIs are not documented, although they're publicly exposed.
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.
It's legacy stuff, that was left to not break deno_std
. We should really fix this...
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.
Good to know, thanks!
for (let i = 0, j = 0; i < transferables.length; i++) { | ||
const ab = transferables[i]; | ||
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, ab)) { | ||
if (ab.byteLength === 0 && core.ops.op_arraybuffer_was_detached(ab)) { | ||
throw new DOMException( | ||
`ArrayBuffer at index ${j} is already detached`, | ||
"DataCloneError", | ||
); | ||
} | ||
j++; | ||
transferredArrayBuffers.push(ab); |
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.
for (let i = 0, j = 0; i < transferables.length; i++) { | |
const ab = transferables[i]; | |
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, ab)) { | |
if (ab.byteLength === 0 && core.ops.op_arraybuffer_was_detached(ab)) { | |
throw new DOMException( | |
`ArrayBuffer at index ${j} is already detached`, | |
"DataCloneError", | |
); | |
} | |
j++; | |
transferredArrayBuffers.push(ab); | |
for (let i = 0; i < transferables.length; i++) { | |
const ab = transferables[i]; | |
if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, ab)) { | |
if (ab.byteLength === 0 && core.ops.op_arraybuffer_was_detached(ab)) { | |
throw new DOMException( | |
`ArrayBuffer at index ${i} is already detached`, | |
"DataCloneError", | |
); | |
} | |
transferredArrayBuffers.push(ab); |
The user doesn't care about the index of the AB, they care about the index in the transferables
array.
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.
@lucacasonato Wanted to mimic Chrome error message.
const buf = new Uint8Array(5);
structuredClone(buf, { transfer: [buf.buffer] });
structuredClone([buf.buffer], { transfer: [new ReadableStream(), buf.buffer] });
// Uncaught DOMException: ... ArrayBuffer at index 0 is already detached
Also did it that way to make JS error be the same as Rust's where we're looping through AB list, not transferables
Line 471 in d361155
format!("ArrayBuffer at index {} is already detached", index), |
Since we're not passing the transferables
array to Rust, should I just remove the index hint, and leave the old message: Can not transfer detached ArrayBuffer
?
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.
Okay, I think mimicing Chrome is fine 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.
LGTM, thanks @marcosc90!
This PR adds a way to reliably check if an ArrayBuffer was detached
Blocked by: denoland/rusty_v8#1103