diff --git a/Cargo.toml b/Cargo.toml index 7ac2615..f8bb11b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ semver = { version = "1.0.20", default-features = false } serde = { version = "1.0.193", optional = true, default-features = false, features = [ "derive", "rc" ] } slab = { version = "0.4.9", default-features = false } wasm_runtime_layer = { version = ">=0.2.0", default-features = false } -wasmtime-environ = { version = ">=18.0.1", features = [ "component-model" ] } +wasmtime-environ = { version = "<=18.0", features = [ "component-model" ] } wit-component = { version = ">=0.19.0", default-features = false } wit-parser = { version = ">=0.13.0", default-features = false } @@ -28,4 +28,4 @@ serde = [ "dep:serde", "semver/serde" ] [dev-dependencies] wasmi = "0.31.1" -wasm_runtime_layer = { version = "0.2.0", features = [ "backend_wasmi" ] } \ No newline at end of file +wasm_runtime_layer = { version = "0.2.0", features = [ "backend_wasmi" ] } diff --git a/src/abi.rs b/src/abi.rs index 4562fbe..e070ba7 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -11,10 +11,41 @@ fn join(a: WasmType, b: WasmType) -> WasmType { use WasmType::*; match (a, b) { - (I32, I32) | (I64, I64) | (F32, F32) | (F64, F64) => a, + (I32, I32) + | (I64, I64) + | (F32, F32) + | (F64, F64) + | (Pointer, Pointer) + | (PointerOrI64, PointerOrI64) + | (Length, Length) => a, (I32, F32) | (F32, I32) => I32, + // A length is at least an `i32`, maybe more, so it wins over + // 32-bit types. + (Length, I32 | F32) => Length, + (I32 | F32, Length) => Length, + + // A length might be an `i64`, but might not be, so if we have + // 64-bit types, they win. + (Length, I64 | F64) => I64, + (I64 | F64, Length) => I64, + + // Pointers have provenance and are at least an `i32`, so they + // win over 32-bit and length types. + (Pointer, I32 | F32 | Length) => Pointer, + (I32 | F32 | Length, Pointer) => Pointer, + + // If we need 64 bits and provenance, we need to use the special + // `PointerOrI64`. + (Pointer, I64 | F64) => PointerOrI64, + (I64 | F64, Pointer) => PointerOrI64, + + // PointerOrI64 wins over everything. + (PointerOrI64, _) => PointerOrI64, + (_, PointerOrI64) => PointerOrI64, + + // Otherwise, `i64` wins. (_, I64 | F64) | (I64 | F64, _) => I64, } } @@ -782,8 +813,8 @@ impl<'a, B: Bindgen> Generator<'a, B> { Type::S64 => self.emit(&I64FromS64), Type::U64 => self.emit(&I64FromU64), Type::Char => self.emit(&I32FromChar), - Type::Float32 => self.emit(&F32FromFloat32), - Type::Float64 => self.emit(&F64FromFloat64), + Type::F32 => self.emit(&F32FromFloat32), + Type::F64 => self.emit(&F64FromFloat64), Type::String => { let realloc = self.list_realloc(); self.emit(&StringLower { realloc }) @@ -958,8 +989,8 @@ impl<'a, B: Bindgen> Generator<'a, B> { Type::S64 => self.emit(&S64FromI64), Type::U64 => self.emit(&U64FromI64), Type::Char => self.emit(&CharFromI32), - Type::Float32 => self.emit(&Float32FromF32), - Type::Float64 => self.emit(&Float64FromF64), + Type::F32 => self.emit(&Float32FromF32), + Type::F64 => self.emit(&Float64FromF64), Type::String => self.emit(&StringLift), Type::Id(id) => match &self.resolve.types[id].kind { TypeDefKind::Type(t) => self.lift(t), @@ -1153,8 +1184,8 @@ impl<'a, B: Bindgen> Generator<'a, B> { self.lower_and_emit(ty, addr, &I32Store { offset }) } Type::U64 | Type::S64 => self.lower_and_emit(ty, addr, &I64Store { offset }), - Type::Float32 => self.lower_and_emit(ty, addr, &F32Store { offset }), - Type::Float64 => self.lower_and_emit(ty, addr, &F64Store { offset }), + Type::F32 => self.lower_and_emit(ty, addr, &F32Store { offset }), + Type::F64 => self.lower_and_emit(ty, addr, &F64Store { offset }), Type::String => self.write_list_to_memory(ty, addr, offset), Type::Id(id) => match &self.resolve.types[id].kind { @@ -1340,8 +1371,8 @@ impl<'a, B: Bindgen> Generator<'a, B> { Type::S16 => self.emit_and_lift(ty, addr, &I32Load16S { offset }), Type::U32 | Type::S32 | Type::Char => self.emit_and_lift(ty, addr, &I32Load { offset }), Type::U64 | Type::S64 => self.emit_and_lift(ty, addr, &I64Load { offset }), - Type::Float32 => self.emit_and_lift(ty, addr, &F32Load { offset }), - Type::Float64 => self.emit_and_lift(ty, addr, &F64Load { offset }), + Type::F32 => self.emit_and_lift(ty, addr, &F32Load { offset }), + Type::F64 => self.emit_and_lift(ty, addr, &F64Load { offset }), Type::String => self.read_list_from_memory(ty, addr, offset), Type::Id(id) => match &self.resolve.types[id].kind { @@ -1555,20 +1586,25 @@ fn cast(from: WasmType, to: WasmType) -> Bitcast { use WasmType::*; match (from, to) { - (I32, I32) | (I64, I64) | (F32, F32) | (F64, F64) => Bitcast::None, + (I32 | Pointer | Length, I32 | Pointer | Length) + | (I64 | PointerOrI64, I64 | PointerOrI64) + | (F32, F32) + | (F64, F64) => Bitcast::None, - (I32, I64) => Bitcast::I32ToI64, - (F32, I32) => Bitcast::F32ToI32, - (F64, I64) => Bitcast::F64ToI64, + (I32 | Pointer | Length, I64 | PointerOrI64) => Bitcast::I32ToI64, + (F32, I32 | Pointer | Length) => Bitcast::F32ToI32, + (F64, I64 | PointerOrI64) => Bitcast::F64ToI64, - (I64, I32) => Bitcast::I64ToI32, - (I32, F32) => Bitcast::I32ToF32, - (I64, F64) => Bitcast::I64ToF64, + (I64 | PointerOrI64, I32 | Pointer | Length) => Bitcast::I64ToI32, + (I32 | Pointer | Length, F32) => Bitcast::I32ToF32, + (I64 | PointerOrI64, F64) => Bitcast::I64ToF64, - (F32, I64) => Bitcast::F32ToI64, - (I64, F32) => Bitcast::I64ToF32, + (F32, I64 | PointerOrI64) => Bitcast::F32ToI64, + (I64 | PointerOrI64, F32) => Bitcast::I64ToF32, - (F32, F64) | (F64, F32) | (F64, I32) | (I32, F64) => unreachable!(), + (F32, F64) | (F64, F32) | (F64, I32 | Pointer | Length) | (I32 | Pointer | Length, F64) => { + unreachable!() + } } } @@ -1585,8 +1621,8 @@ fn push_wasm(resolve: &Resolve, variant: AbiVariant, ty: &Type, result: &mut Vec | Type::Char => result.push(WasmType::I32), Type::U64 | Type::S64 => result.push(WasmType::I64), - Type::Float32 => result.push(WasmType::F32), - Type::Float64 => result.push(WasmType::F64), + Type::F32 => result.push(WasmType::F32), + Type::F64 => result.push(WasmType::F64), Type::String => { result.push(WasmType::I32); result.push(WasmType::I32); diff --git a/src/func.rs b/src/func.rs index 063c992..b3554c9 100644 --- a/src/func.rs +++ b/src/func.rs @@ -425,8 +425,10 @@ impl<'a, C: AsContextMut> Bindgen for FuncBindgen<'a, C> { Instruction::ConstZero { tys } => { for t in tys.iter() { match t { - WasmType::I32 => results.push(Value::S32(0)), - WasmType::I64 => results.push(Value::S64(0)), + WasmType::I32 | WasmType::Pointer | WasmType::Length => { + results.push(Value::S32(0)) + } + WasmType::I64 | WasmType::PointerOrI64 => results.push(Value::S64(0)), WasmType::F32 => results.push(Value::F32(0.0)), WasmType::F64 => results.push(Value::F64(0.0)), } @@ -712,8 +714,8 @@ impl<'a, C: AsContextMut> Bindgen for FuncBindgen<'a, C> { Type::S16 => self.store_array(ptr as usize, list.typed::()?)?, Type::S32 => self.store_array(ptr as usize, list.typed::()?)?, Type::S64 => self.store_array(ptr as usize, list.typed::()?)?, - Type::Float32 => self.store_array(ptr as usize, list.typed::()?)?, - Type::Float64 => self.store_array(ptr as usize, list.typed::()?)?, + Type::F32 => self.store_array(ptr as usize, list.typed::()?)?, + Type::F64 => self.store_array(ptr as usize, list.typed::()?)?, _ => unreachable!(), } @@ -796,8 +798,8 @@ impl<'a, C: AsContextMut> Bindgen for FuncBindgen<'a, C> { Type::S16 => self.load_array::(ptr as usize, len as usize)?.into(), Type::S32 => self.load_array::(ptr as usize, len as usize)?.into(), Type::S64 => self.load_array::(ptr as usize, len as usize)?.into(), - Type::Float32 => self.load_array::(ptr as usize, len as usize)?.into(), - Type::Float64 => self.load_array::(ptr as usize, len as usize)?.into(), + Type::F32 => self.load_array::(ptr as usize, len as usize)?.into(), + Type::F64 => self.load_array::(ptr as usize, len as usize)?.into(), _ => unreachable!(), })); } @@ -1188,8 +1190,8 @@ impl<'a, C: AsContextMut> Bindgen for FuncBindgen<'a, C> { Type::S16 => LITTLE_ENDIAN, Type::S32 => LITTLE_ENDIAN, Type::S64 => LITTLE_ENDIAN, - Type::Float32 => LITTLE_ENDIAN, - Type::Float64 => LITTLE_ENDIAN, + Type::F32 => LITTLE_ENDIAN, + Type::F64 => LITTLE_ENDIAN, Type::Char => false, Type::String => false, Type::Id(_) => false, diff --git a/src/types.rs b/src/types.rs index cd15db2..4215b69 100644 --- a/src/types.rs +++ b/src/types.rs @@ -201,8 +201,8 @@ impl ValueType { wit_parser::Type::S16 => Self::S16, wit_parser::Type::S32 => Self::S32, wit_parser::Type::S64 => Self::S64, - wit_parser::Type::Float32 => Self::F32, - wit_parser::Type::Float64 => Self::F64, + wit_parser::Type::F32 => Self::F32, + wit_parser::Type::F64 => Self::F64, wit_parser::Type::Char => Self::Char, wit_parser::Type::String => Self::String, wit_parser::Type::Id(x) => Self::from_component_typedef(*x, component, resource_map)?,