From 85877e39eeb0fd8eabfca694ab1bc67b51871df1 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Wed, 17 Jul 2024 17:03:32 +0800 Subject: [PATCH] Fix byte order for big-endian platform --- crates/cli-support/src/js/binding.rs | 30 +++++++++++-------- crates/cli-support/src/js/mod.rs | 30 ++++++++++++------- .../tests/reference/anyref-import-catch.js | 14 ++++----- crates/cli/tests/reference/import-catch.js | 14 ++++----- crates/cli/tests/reference/result-string.js | 18 +++++------ 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index dfbd28b8b2fa..8cdded7ee883 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -784,19 +784,21 @@ fn instruction( } Instruction::StoreRetptr { ty, offset, mem } => { - let (mem, size) = match ty { - AdapterType::I32 => (js.cx.expose_int32_memory(*mem), 4), - AdapterType::I64 => (js.cx.expose_int64_memory(*mem), 8), - AdapterType::F32 => (js.cx.expose_f32_memory(*mem), 4), - AdapterType::F64 => (js.cx.expose_f64_memory(*mem), 8), + let mem = js.cx.expose_dataview_memory(*mem); + let (method, size) = match ty { + AdapterType::I32 => ("setInt32", 4), + AdapterType::I64 => ("setInt64", 8), + AdapterType::F32 => ("setFloat32", 4), + AdapterType::F64 => ("setFloat64", 8), other => bail!("invalid aggregate return type {:?}", other), }; // Note that we always assume the return pointer is argument 0, // which is currently the case for LLVM. let val = js.pop(); let expr = format!( - "{}()[{} / {} + {}] = {};", + "{}().{}({} + {} * {}, {}, true);", mem, + method, js.arg(0), size, offset, @@ -806,11 +808,12 @@ fn instruction( } Instruction::LoadRetptr { ty, offset, mem } => { - let (mem, quads) = match ty { - AdapterType::I32 => (js.cx.expose_int32_memory(*mem), 1), - AdapterType::I64 => (js.cx.expose_int64_memory(*mem), 2), - AdapterType::F32 => (js.cx.expose_f32_memory(*mem), 1), - AdapterType::F64 => (js.cx.expose_f64_memory(*mem), 2), + let mem = js.cx.expose_dataview_memory(*mem); + let (method, quads) = match ty { + AdapterType::I32 => ("getInt32", 1), + AdapterType::I64 => ("getInt64", 2), + AdapterType::F32 => ("getFloat32", 1), + AdapterType::F64 => ("getFloat64", 1), other => bail!("invalid aggregate return type {:?}", other), }; let size = quads * 4; @@ -820,7 +823,10 @@ fn instruction( // If we're loading from the return pointer then we must have pushed // it earlier, and we always push the same value, so load that value // here - let expr = format!("{}()[retptr / {} + {}]", mem, size, scaled_offset); + let expr = format!( + "{}().{}(retptr + {} * {}, true)", + mem, method, size, scaled_offset + ); js.prelude(&format!("var r{} = {};", offset, expr)); js.push(format!("r{}", offset)); } diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 97a7cbd80444..3252c6fab599 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1349,7 +1349,7 @@ impl<'a> Context<'a> { } fn expose_pass_array_jsvalue_to_wasm(&mut self, memory: MemoryId) -> Result { - let mem = self.expose_uint32_memory(memory); + let mem = self.expose_dataview_memory(memory); let ret = MemView { name: "passArrayJsValueToWasm".into(), num: mem.num, @@ -1369,7 +1369,7 @@ impl<'a> Context<'a> { const ptr = malloc(array.length * 4, 4) >>> 0; const mem = {}(); for (let i = 0; i < array.length; i++) {{ - mem[ptr / 4 + i] = {}(array[i]); + mem.setUint32(ptr + 4 * i, {}(array[i]), true); }} WASM_VECTOR_LEN = array.length; return ptr; @@ -1386,7 +1386,7 @@ impl<'a> Context<'a> { const ptr = malloc(array.length * 4, 4) >>> 0; const mem = {}(); for (let i = 0; i < array.length; i++) {{ - mem[ptr / 4 + i] = addHeapObject(array[i]); + mem.setUint32(ptr + 4 * i, addHeapObject(array[i]), true); }} WASM_VECTOR_LEN = array.length; return ptr; @@ -1596,7 +1596,7 @@ impl<'a> Context<'a> { } fn expose_get_array_js_value_from_wasm(&mut self, memory: MemoryId) -> Result { - let mem = self.expose_uint32_memory(memory); + let mem = self.expose_dataview_memory(memory); let ret = MemView { name: "getArrayJsValueFromWasm".into(), num: mem.num, @@ -1613,10 +1613,9 @@ impl<'a> Context<'a> { function {}(ptr, len) {{ ptr = ptr >>> 0; const mem = {}(); - const slice = mem.subarray(ptr / 4, ptr / 4 + len); const result = []; - for (let i = 0; i < slice.length; i++) {{ - result.push(wasm.{}.get(slice[i])); + for (let i = ptr; i < ptr + 4 * len; i += 4) {{ + result.push(wasm.{}.get(mem.getUint32(i, true))); }} wasm.{}(ptr, len); return result; @@ -1632,10 +1631,9 @@ impl<'a> Context<'a> { function {}(ptr, len) {{ ptr = ptr >>> 0; const mem = {}(); - const slice = mem.subarray(ptr / 4, ptr / 4 + len); const result = []; - for (let i = 0; i < slice.length; i++) {{ - result.push(takeObject(slice[i])); + for (let i = ptr; i < ptr + 4 * len; i += 4) {{ + result.push(takeObject(mem.getUint32(i, true))); }} return result; }} @@ -1768,6 +1766,10 @@ impl<'a> Context<'a> { self.memview("Float64", memory) } + fn expose_dataview_memory(&mut self, memory: MemoryId) -> MemView { + self.memview("DataView", memory) + } + fn memview(&mut self, kind: &'static str, memory: walrus::MemoryId) -> MemView { let view = self.memview_memory(kind, memory); if !self.should_write_global(view.name.clone()) { @@ -1794,11 +1796,17 @@ impl<'a> Context<'a> { self.global(&format!("let {cache} = null;\n")); + let kind = if kind == "DataView" { + "DataView" + } else { + &format!("{}Array", kind) + }; + self.global(&format!( " function {name}() {{ if ({cache} === null || {resized_check}) {{ - {cache} = new {kind}Array(wasm.{mem}.buffer); + {cache} = new {kind}(wasm.{mem}.buffer); }} return {cache}; }} diff --git a/crates/cli/tests/reference/anyref-import-catch.js b/crates/cli/tests/reference/anyref-import-catch.js index f7727f5e6275..aae2e3c21ca5 100644 --- a/crates/cli/tests/reference/anyref-import-catch.js +++ b/crates/cli/tests/reference/anyref-import-catch.js @@ -39,13 +39,13 @@ function handleError(f, args) { } } -let cachedInt32Memory0 = null; +let cachedDataViewMemory0 = null; -function getInt32Memory0() { - if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { - cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.byteLength === 0) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); } - return cachedInt32Memory0; + return cachedDataViewMemory0; } function takeFromExternrefTable0(idx) { @@ -59,8 +59,8 @@ export function exported() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.exported(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); if (r1) { throw takeFromExternrefTable0(r0); } diff --git a/crates/cli/tests/reference/import-catch.js b/crates/cli/tests/reference/import-catch.js index f587b8346c37..d854b92db3e0 100644 --- a/crates/cli/tests/reference/import-catch.js +++ b/crates/cli/tests/reference/import-catch.js @@ -27,13 +27,13 @@ function handleError(f, args) { } } -let cachedInt32Memory0 = null; +let cachedDataViewMemory0 = null; -function getInt32Memory0() { - if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { - cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.byteLength === 0) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); } - return cachedInt32Memory0; + return cachedDataViewMemory0; } function getObject(idx) { return heap[idx]; } @@ -55,8 +55,8 @@ export function exported() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.exported(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); if (r1) { throw takeObject(r0); } diff --git a/crates/cli/tests/reference/result-string.js b/crates/cli/tests/reference/result-string.js index a0795b44d4dc..ce09837f32ba 100644 --- a/crates/cli/tests/reference/result-string.js +++ b/crates/cli/tests/reference/result-string.js @@ -19,13 +19,13 @@ function addHeapObject(obj) { return idx; } -let cachedInt32Memory0 = null; +let cachedDataViewMemory0 = null; -function getInt32Memory0() { - if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { - cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.byteLength === 0) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); } - return cachedInt32Memory0; + return cachedDataViewMemory0; } function getObject(idx) { return heap[idx]; } @@ -70,10 +70,10 @@ export function exported() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.exported(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - var r3 = getInt32Memory0()[retptr / 4 + 3]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); var ptr1 = r0; var len1 = r1; if (r3) {