Skip to content

Commit caad5ea

Browse files
authored
fix: early update wasm memory for views (#206)
1 parent 792607f commit caad5ea

5 files changed

Lines changed: 41 additions & 12 deletions

File tree

packages/emnapi/src/memory.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ export const emnapiExternalMemory: {
126126
return view
127127
}
128128

129-
const maybeOldWasmMemory = emnapiExternalMemory.isDetachedArrayBuffer(view.buffer) ||
130-
((typeof SharedArrayBuffer === 'function') && (view.buffer instanceof SharedArrayBuffer))
129+
const maybeOldWasmMemory = emnapiExternalMemory.isDetachedArrayBuffer(view.buffer) || emnapiExternalMemory.isSharedArrayBuffer(view.buffer)
131130
if (maybeOldWasmMemory && emnapiExternalMemory.wasmMemoryViewTable.has(view)) {
132131
const info = emnapiExternalMemory.wasmMemoryViewTable.get(view)!
133132
const Ctor = info.Ctor

packages/emnapi/src/value/convert2c.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export function napi_get_typedarray_info (
115115
if (!(ArrayBuffer.isView(jsValue)) && !(jsValue instanceof DataView)) {
116116
return envObject.setLastError(napi_status.napi_invalid_arg)
117117
}
118-
const v: ArrayBufferView = jsValue
118+
let v: ArrayBufferView = jsValue
119119
if (type) {
120120
from64('type')
121121
let t: napi_typedarray_type
@@ -148,13 +148,13 @@ export function napi_get_typedarray_info (
148148
}
149149
makeSetValue('type', 0, 't', 'i32')
150150
}
151+
v = emnapiExternalMemory.getOrUpdateMemoryView(v)
151152
if (length) {
152153
from64('length')
153154
makeSetValue('length', 0, 'v.length', SIZE_TYPE)
154155
}
155-
let buffer: ArrayBufferLike
156+
156157
if (data || arraybuffer) {
157-
buffer = v.buffer
158158
if (data) {
159159
from64('data')
160160

@@ -164,7 +164,7 @@ export function napi_get_typedarray_info (
164164
if (arraybuffer) {
165165
from64('arraybuffer')
166166

167-
const ab = emnapiCtx.napiValueFromJsValue(buffer)
167+
const ab = emnapiCtx.napiValueFromJsValue(v.buffer)
168168
makeSetValue('arraybuffer', 0, 'ab', '*')
169169
}
170170
}
@@ -213,14 +213,13 @@ export function napi_get_dataview_info (
213213
if (!(jsValue instanceof DataView)) {
214214
return envObject.setLastError(napi_status.napi_invalid_arg)
215215
}
216-
const v = jsValue as DataView
216+
const v = emnapiExternalMemory.getOrUpdateMemoryView(jsValue as DataView)
217217
if (byte_length) {
218218
from64('byte_length')
219219
makeSetValue('byte_length', 0, 'v.byteLength', SIZE_TYPE)
220220
}
221-
let buffer: ArrayBufferLike
221+
222222
if (data || arraybuffer) {
223-
buffer = v.buffer
224223
if (data) {
225224
from64('data')
226225

@@ -230,7 +229,7 @@ export function napi_get_dataview_info (
230229
if (arraybuffer) {
231230
from64('arraybuffer')
232231

233-
const ab = emnapiCtx.napiValueFromJsValue(buffer)
232+
const ab = emnapiCtx.napiValueFromJsValue(v.buffer)
234233
makeSetValue('arraybuffer', 0, 'ab', '*')
235234
}
236235
}

packages/test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ if(IS_EMSCRIPTEN)
9393
"-sMAXIMUM_MEMORY=4294967296"
9494
"-sSAFE_HEAP=1"
9595
"-sMODULARIZE=1"
96-
"-sEXPORTED_RUNTIME_METHODS=['emnapiInit','ExitStatus']"
96+
"-sEXPORTED_RUNTIME_METHODS=['emnapiInit','ExitStatus','wasmMemory','growMemory']"
9797
)
9898
set(COMMON_EXPORTS_NAPI
9999
"-sEXPORTED_FUNCTIONS=['_malloc','_free','_napi_register_wasm_v1','_node_api_module_get_api_version_v1','_emnapi_create_env','_emnapi_delete_env']"

packages/test/dataview/dataview.test.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
const assert = require('assert')
66
const { load } = require('../util')
77

8-
module.exports = load('dataview').then(test_dataview => {
8+
const loadPromise = load('dataview')
9+
10+
module.exports = loadPromise.then(test_dataview => {
911
// Test for creating dataview with ArrayBuffer
1012
{
1113
const buffer = new ArrayBuffer(128)
@@ -43,4 +45,31 @@ module.exports = load('dataview').then(test_dataview => {
4345
test_dataview.CreateDataView(buffer, 10, 200)
4446
}, RangeError)
4547
}
48+
49+
{
50+
const binding = test_dataview
51+
const wasmMemory = loadPromise.Module.wasmMemory
52+
const before = wasmMemory.buffer
53+
const view = binding.CreateDataView(before, 0, 4)
54+
if (loadPromise.Module.growMemory) {
55+
loadPromise.Module.growMemory(before.byteLength + 65536)
56+
} else {
57+
wasmMemory.grow(1)
58+
}
59+
60+
const after = wasmMemory.buffer
61+
const cloned = binding.CreateDataViewFromJSDataView(view)
62+
63+
const result = {
64+
trackedViewUsesCurrentBuffer: view.buffer === before,
65+
bufferIdentityChangedAfterGrow: before !== after,
66+
oldBufferLength: before.byteLength,
67+
newBufferLength: after.byteLength,
68+
returnedViewUsesOldBuffer: cloned.buffer === before,
69+
returnedViewUsesNewBuffer: cloned.buffer === after
70+
}
71+
console.log(result)
72+
assert.strictEqual(result.returnedViewUsesOldBuffer, false)
73+
assert.strictEqual(result.returnedViewUsesNewBuffer, true)
74+
}
4675
})

packages/test/util.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ function loadPath (request, options) {
9393
}
9494
}
9595
}).then((source) => {
96+
napiModule.wasmMemory = source.instance.exports.memory
9697
if (process.env.EMNAPI_TEST_4GB) {
9798
source.instance.exports.malloc(2147483648)
9899
}
@@ -157,6 +158,7 @@ function loadPath (request, options) {
157158
}
158159
}).then(({ instance }) => {
159160
wasmMemory = instance.exports.memory || sharedMemory
161+
napiModule.wasmMemory = wasmMemory
160162
resolve(napiModule.exports)
161163
}).catch(reject)
162164
})

0 commit comments

Comments
 (0)