Skip to content

Commit

Permalink
Fix byte order for big-endian platform
Browse files Browse the repository at this point in the history
  • Loading branch information
magic-akari committed Jul 23, 2024
1 parent e8b023c commit fabe89c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 47 deletions.
30 changes: 18 additions & 12 deletions crates/cli-support/src/js/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => ("setBigInt64", 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,
Expand All @@ -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 => ("getBigInt64", 2),
AdapterType::F32 => ("getFloat32", 1),
AdapterType::F64 => ("getFloat64", 2),
other => bail!("invalid aggregate return type {:?}", other),
};
let size = quads * 4;
Expand All @@ -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));
}
Expand Down
34 changes: 22 additions & 12 deletions crates/cli-support/src/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ impl<'a> Context<'a> {
}

fn expose_pass_array_jsvalue_to_wasm(&mut self, memory: MemoryId) -> Result<MemView, Error> {
let mem = self.expose_uint32_memory(memory);
let mem = self.expose_dataview_memory(memory);
let ret = MemView {
name: "passArrayJsValueToWasm".into(),
num: mem.num,
Expand All @@ -1370,7 +1370,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;
Expand All @@ -1387,7 +1387,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;
Expand Down Expand Up @@ -1597,7 +1597,7 @@ impl<'a> Context<'a> {
}

fn expose_get_array_js_value_from_wasm(&mut self, memory: MemoryId) -> Result<MemView, Error> {
let mem = self.expose_uint32_memory(memory);
let mem = self.expose_dataview_memory(memory);
let ret = MemView {
name: "getArrayJsValueFromWasm".into(),
num: mem.num,
Expand All @@ -1614,10 +1614,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;
Expand All @@ -1633,10 +1632,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;
}}
Expand Down Expand Up @@ -1769,15 +1767,21 @@ 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()) {
return view;
}
let mem = self.export_name_of(memory);

let is_dataview = kind == "DataView";

let cache = format!("cached{}Memory{}", kind, view.num);
let resized_check = if self.module.memories.get(memory).shared {
let resized_check = if self.module.memories.get(memory).shared || is_dataview {
// When it's backed by a `SharedArrayBuffer`, growing the wasm module's memory
// doesn't detach old references; instead, it just leaves them pointing to a
// slice of the up-to-date memory. So in order to check if it's been grown, we
Expand All @@ -1795,11 +1799,17 @@ impl<'a> Context<'a> {

self.global(&format!("let {cache} = null;\n"));

let kind = if is_dataview {
kind
} 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};
}}
Expand Down
14 changes: 7 additions & 7 deletions crates/cli/tests/reference/anyref-import-catch.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.buffer !== wasm.memory.buffer) {
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
}
return cachedInt32Memory0;
return cachedDataViewMemory0;
}

function takeFromExternrefTable0(idx) {
Expand All @@ -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);
}
Expand Down
14 changes: 7 additions & 7 deletions crates/cli/tests/reference/import-catch.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.buffer !== wasm.memory.buffer) {
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
}
return cachedInt32Memory0;
return cachedDataViewMemory0;
}

function getObject(idx) { return heap[idx]; }
Expand All @@ -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);
}
Expand Down
18 changes: 9 additions & 9 deletions crates/cli/tests/reference/result-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.buffer !== wasm.memory.buffer) {
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
}
return cachedInt32Memory0;
return cachedDataViewMemory0;
}

function getObject(idx) { return heap[idx]; }
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit fabe89c

Please sign in to comment.