Check if the memory is backed by a SAB by checking the constructor name#381
Check if the memory is backed by a SAB by checking the constructor name#381kateinoigakukun merged 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR replaces the instanceof SharedArrayBuffer check with a constructor-name–based detection for SharedArrayBuffer backing and improves DataView reuse in the generated runtime.
- Use
Object.getPrototypeOf(...).constructor.nameto detect SAB backing in both TS and MJS runtimes - Add detailed comments explaining why direct
SharedArrayBufferreferences aren’t used - Cache
this.getDataView()in a local variable before passing todecodeObjectRefs
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| Runtime/src/index.ts | Swapped SAB detection from instanceof to constructor-name check |
| Plugins/PackageToJS/Templates/runtime.mjs | Mirrored SAB detection update and cached getDataView() for calls |
Comments suppressed due to low confidence (2)
Runtime/src/index.ts:68
- Add unit tests covering the new constructor-name detection path, including scenarios where
globalThis.SharedArrayBufferis undefined and where the buffer is SAB-backed in non–cross-origin isolated contexts.
// Check the constructor name of the buffer to determine if it's backed by a SharedArrayBuffer.
Plugins/PackageToJS/Templates/runtime.mjs:311
- Include tests for the generated runtime’s SAB detection logic, verifying correct behavior when SharedArrayBuffer isn’t available and when it is present.
// Check the constructor name of the buffer to determine if it's backed by a SharedArrayBuffer.
| // 1. It may not be available in the global scope if the context is not cross-origin isolated. | ||
| // 2. The underlying buffer may be still backed by SAB even if the context is not cross-origin | ||
| // isolated (e.g. localhost on Chrome on Android). | ||
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { |
There was a problem hiding this comment.
Relying on constructor.name can break if code is minified or prototypes are altered. Consider using a direct equality check when globalThis.SharedArrayBuffer is available (wasmMemory.buffer.constructor === globalThis.SharedArrayBuffer) or fall back to Object.prototype.toString.call(wasmMemory.buffer) === '[object SharedArrayBuffer]' for more robust detection.
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { | |
| if ( | |
| (globalThis.SharedArrayBuffer && wasmMemory.buffer.constructor === globalThis.SharedArrayBuffer) || | |
| Object.prototype.toString.call(wasmMemory.buffer) === '[object SharedArrayBuffer]' | |
| ) { |
| // 1. It may not be available in the global scope if the context is not cross-origin isolated. | ||
| // 2. The underlying buffer may be still backed by SAB even if the context is not cross-origin | ||
| // isolated (e.g. localhost on Chrome on Android). | ||
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { |
There was a problem hiding this comment.
Same here: using constructor.name may be brittle under minification or prototype mutation. A stronger check is wasmMemory.buffer.constructor === globalThis.SharedArrayBuffer with an Object.prototype.toString fallback.
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { | |
| if (wasmMemory.buffer.constructor === globalThis.SharedArrayBuffer || | |
| Object.prototype.toString.call(wasmMemory.buffer) === "[object SharedArrayBuffer]") { |
| // 1. It may not be available in the global scope if the context is not cross-origin isolated. | ||
| // 2. The underlying buffer may be still backed by SAB even if the context is not cross-origin | ||
| // isolated (e.g. localhost on Chrome on Android). | ||
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { |
There was a problem hiding this comment.
Accessing Object.getPrototypeOf(...).constructor without checking for null/undefined can throw if buffer has a null prototype. Add optional chaining: Object.getPrototypeOf(wasmMemory.buffer)?.constructor?.name === 'SharedArrayBuffer'.
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { | |
| if (Object.getPrototypeOf(wasmMemory.buffer)?.constructor?.name === "SharedArrayBuffer") { |
| // 1. It may not be available in the global scope if the context is not cross-origin isolated. | ||
| // 2. The underlying buffer may be still backed by SAB even if the context is not cross-origin | ||
| // isolated (e.g. localhost on Chrome on Android). | ||
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { |
There was a problem hiding this comment.
Wrap prototype access in optional chaining to avoid runtime errors if the prototype is null: Object.getPrototypeOf(wasmMemory.buffer)?.constructor?.name === 'SharedArrayBuffer'.
| if (Object.getPrototypeOf(wasmMemory.buffer).constructor.name === "SharedArrayBuffer") { | |
| if (Object.getPrototypeOf(wasmMemory.buffer)?.constructor?.name === "SharedArrayBuffer") { |
No description provided.