Skip to content

Commit 64cf33c

Browse files
chore: more superinstructions, cleanup
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent be3c350 commit 64cf33c

16 files changed

Lines changed: 827 additions & 732 deletions

File tree

crates/parser/src/conversion.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,7 @@ fn convert_heap_type_with_group(
440440
)));
441441
}
442442
};
443-
RefType::new_concrete(nullable, index)
444-
.ok_or_else(|| crate::ParseError::Other(format!("heap type index is too large: {index}")))
443+
Ok(RefType::new_concrete(nullable, index))
445444
}
446445
wasmparser::HeapType::Abstract { shared: true, .. } | wasmparser::HeapType::Exact(_) => {
447446
Err(crate::ParseError::UnsupportedOperator(format!("Unsupported heap type: {heap:?}")))

crates/parser/src/optimize.rs

Lines changed: 96 additions & 12 deletions
Large diffs are not rendered by default.

crates/tinywasm/src/func/host.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ impl HostFunction {
3131
let canonical = *type_addrs
3232
.get(module_addr as usize)
3333
.ok_or_else(|| crate::Error::other("host function signature contains an invalid concrete type"))?;
34-
Ok(WasmType::Ref(
35-
tinywasm_types::RefType::new_concrete(ref_ty.is_nullable(), canonical)
36-
.expect("canonical type addresses fit in references"),
37-
))
34+
Ok(WasmType::Ref(tinywasm_types::RefType::new_concrete(ref_ty.is_nullable(), canonical)))
3835
};
3936
let params = self.0.ty.params().iter().copied().map(resolve).collect::<Result<Vec<_>>>()?;
4037
let results = self.0.ty.results().iter().copied().map(resolve).collect::<Result<Vec<_>>>()?;

crates/tinywasm/src/interpreter/executor.rs

Lines changed: 632 additions & 672 deletions
Large diffs are not rendered by default.

crates/tinywasm/src/store/state.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -271,23 +271,20 @@ impl State {
271271
if expected_func {
272272
let Some(func_addr) = value.addr() else { return false };
273273
let Some(func) = self.funcs.get(func_addr as usize) else { return false };
274-
let actual = RefType::new_concrete(false, func.type_addr).expect("canonical type fits");
275-
return self.ref_type_is_subtype(actual, expected);
274+
return self.ref_type_is_subtype(RefType::new_concrete(false, func.type_addr), expected);
276275
}
277276
if expected.abstract_heap_type() == Some(AbstractHeapType::Exn) {
278277
return value.addr().is_some_and(|addr| self.exceptions.get(addr as usize).is_some());
279278
}
280279
if value.is_i31() {
281-
let actual = RefType::new_abstract(false, AbstractHeapType::I31);
282-
return self.ref_type_is_subtype(actual, expected);
280+
return self.ref_type_is_subtype(RefType::new_abstract(false, AbstractHeapType::I31), expected);
283281
}
284282
if value.is_host_any() {
285-
let actual = RefType::new_abstract(false, AbstractHeapType::Any);
286-
return self.ref_type_is_subtype(actual, expected);
283+
return self.ref_type_is_subtype(RefType::new_abstract(false, AbstractHeapType::Any), expected);
287284
}
288285

289286
let Some(object) = self.gc.get(value) else { return false };
290-
let actual = RefType::new_concrete(false, object.type_addr).expect("canonical type fits");
287+
let actual = RefType::new_concrete(false, object.type_addr);
291288
self.ref_type_is_subtype(actual, expected)
292289
}
293290

@@ -309,12 +306,10 @@ impl State {
309306
pub(crate) fn value_matches_type(&self, value: WasmValue, expected: WasmType) -> bool {
310307
match (value, expected) {
311308
(WasmValue::Ref(RefValue::Null), WasmType::Ref(expected)) => expected.is_nullable(),
312-
(WasmValue::Ref(RefValue::Func(func)), WasmType::Ref(expected)) => {
313-
self.funcs.get(func.addr() as usize).is_some_and(|func| {
314-
let actual = RefType::new_concrete(false, func.type_addr).expect("canonical type fits");
315-
self.ref_type_is_subtype(actual, expected)
316-
})
317-
}
309+
(WasmValue::Ref(RefValue::Func(func)), WasmType::Ref(expected)) => self
310+
.funcs
311+
.get(func.addr() as usize)
312+
.is_some_and(|func| self.ref_type_is_subtype(RefType::new_concrete(false, func.type_addr), expected)),
318313
(WasmValue::Ref(RefValue::Any(_)), WasmType::Ref(expected))
319314
if expected.is_func() || expected.is_extern() || expected.is_exn() =>
320315
{

crates/tinywasm/src/store/types.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use super::Store;
66
pub(crate) fn canonicalize_ref_type(ty: RefType, type_addrs: &[TypeAddr]) -> RefType {
77
let Some(type_addr) = ty.type_index() else { return ty };
88
let canonical = *type_addrs.get(type_addr as usize).expect("validated type address should exist");
9-
RefType::new_concrete(ty.is_nullable(), canonical).expect("canonical type addresses fit in references")
9+
RefType::new_concrete(ty.is_nullable(), canonical)
1010
}
1111

1212
pub(crate) fn canonicalize_value_type(ty: WasmType, type_addrs: &[TypeAddr]) -> WasmType {
@@ -18,12 +18,10 @@ pub(crate) fn canonicalize_value_type(ty: WasmType, type_addrs: &[TypeAddr]) ->
1818

1919
fn map_value_type(ty: WasmType, resolve: &mut impl FnMut(TypeAddr) -> TypeAddr) -> WasmType {
2020
match ty {
21-
WasmType::Ref(ty) if ty.is_concrete() => {
22-
let addr = resolve(ty.type_index().expect("concrete reference has a type index"));
23-
WasmType::Ref(
24-
RefType::new_concrete(ty.is_nullable(), addr).expect("canonical type addresses fit in references"),
25-
)
26-
}
21+
WasmType::Ref(ty) if ty.is_concrete() => WasmType::Ref(RefType::new_concrete(
22+
ty.is_nullable(),
23+
resolve(ty.type_index().expect("concrete reference has a type index")),
24+
)),
2725
ty => ty,
2826
}
2927
}

crates/tinywasm/tests/host_func_signature_check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ fn imported_host_functions_resolve_concrete_types() -> Result<(), Box<dyn core::
155155
"#,
156156
)?;
157157
let module = tinywasm::parse_bytes(&wasm)?;
158-
let concrete = RefType::new_concrete(true, 0).expect("valid module-local type index");
158+
let concrete = RefType::new_concrete(true, 0);
159159
let host_ty = FuncType::new(&[WasmType::Ref(concrete)], &[]);
160160
let host = HostFunction::from_untyped(&host_ty, |_, args| {
161161
assert_eq!(args, &[WasmValue::Ref(RefValue::Null)]);

crates/types/src/instructions.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ pub enum Instruction {
194194
BinOpLocalLocalTee64(BinOp, LocalAddr, LocalAddr, LocalAddr),
195195
BinOpLocalLocalTee128(BinOp128, LocalAddr, LocalAddr, LocalAddr),
196196
BinOpLocalConst32(BinOp, LocalAddr, i32), BinOpLocalConst64(BinOp, LocalAddr, i64),
197+
BinOpGlobalConst32(BinOp, GlobalAddr, i32), BinOpGlobalConst64(BinOp, GlobalAddr, i64),
198+
BinOpGlobalConst128(BinOp128, GlobalAddr, ConstIdx),
197199
BinOpLocalConst128(BinOp128, LocalAddr, ConstIdx),
198200
BinOpLocalConstSet32(BinOp, LocalAddr, i32, LocalAddr),
199201
BinOpLocalConstSet64(BinOp, LocalAddr, i64, LocalAddr),
@@ -258,7 +260,13 @@ pub enum Instruction {
258260
JumpCmpStackConst64 { target_ip: u32, imm: i64, op: CmpOp },
259261
JumpCmpStackLocal32 { target_ip: u32, local: LocalAddr, op: CmpOp },
260262
JumpCmpStackLocal64 { target_ip: u32, local: LocalAddr, op: CmpOp },
263+
BinOpLocalConstJump32 { target_ip: u32, local: LocalAddr, imm: i32, op: BinOp, on_zero: bool },
264+
BinOpLocalConstJumpCmpLocal32 { target_ip: u32, local: LocalAddr, imm: i32, binop: BinOp, right: LocalAddr, cmp: CmpOp },
265+
BinOpStackConstTeeLocalJump32 { target_ip: u32, local: LocalAddr, imm: i32, op: BinOp, on_zero: bool },
266+
BinOpGlobalConstJump32 { target_ip: u32, global: GlobalAddr, imm: i32, op: BinOp, on_zero: bool },
261267
IncLocalJump32 { target_ip: u32, local: LocalAddr, delta: i32, on_zero: bool },
268+
IncStackTeeLocalJump32 { target_ip: u32, local: LocalAddr, delta: i32, on_zero: bool },
269+
IncGlobalJump32 { target_ip: u32, global: GlobalAddr, delta: i32, on_zero: bool },
262270
IncLocalJumpCmpLocal32 { target_ip: u32, local: LocalAddr, delta: i32, right: LocalAddr, op: CmpOp },
263271
JumpCmpLocalConst32 { target_ip: u32, local: LocalAddr, imm: i32, op: CmpOp },
264272
JumpCmpLocalConst64 { target_ip: u32, local: LocalAddr, imm: i32, op: CmpOp },
@@ -291,9 +299,9 @@ pub enum Instruction {
291299

292300
// > Variable Instructions
293301
// See <https://webassembly.github.io/spec/core/binary/instructions.html#variable-instructions>
294-
GlobalGet32(GlobalAddr), LocalGet32(LocalAddr), LocalSet32(LocalAddr), LocalTee32(LocalAddr), GlobalSet32(GlobalAddr),
295-
GlobalGet64(GlobalAddr), LocalGet64(LocalAddr), LocalSet64(LocalAddr), LocalTee64(LocalAddr), GlobalSet64(GlobalAddr),
296-
GlobalGet128(GlobalAddr), LocalGet128(LocalAddr), LocalSet128(LocalAddr), LocalTee128(LocalAddr), GlobalSet128(GlobalAddr),
302+
GlobalGet32(GlobalAddr), GlobalSet32(GlobalAddr), GlobalTee32(GlobalAddr), LocalGet32(LocalAddr), LocalSet32(LocalAddr), LocalTee32(LocalAddr),
303+
GlobalGet64(GlobalAddr), GlobalSet64(GlobalAddr), GlobalTee64(GlobalAddr), LocalGet64(LocalAddr), LocalSet64(LocalAddr), LocalTee64(LocalAddr),
304+
GlobalGet128(GlobalAddr), GlobalSet128(GlobalAddr), GlobalTee128(GlobalAddr), LocalGet128(LocalAddr), LocalSet128(LocalAddr), LocalTee128(LocalAddr),
297305

298306
// > Memory Instructions
299307
I32Load(MemoryArg),

crates/types/src/reference.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,9 @@ impl RefType {
7373
}
7474

7575
#[inline]
76-
pub const fn new_concrete(nullable: bool, type_index: u32) -> Option<Self> {
77-
if type_index <= Self::PAYLOAD_MASK {
78-
Some(Self(((nullable as u32) << 31) | Self::CONCRETE | type_index))
79-
} else {
80-
None
81-
}
76+
pub const fn new_concrete(nullable: bool, type_index: u32) -> Self {
77+
assert!(type_index <= Self::PAYLOAD_MASK, "type index is too large for a reference type");
78+
Self(((nullable as u32) << 31) | Self::CONCRETE | type_index)
8279
}
8380

8481
#[inline]
@@ -193,7 +190,7 @@ impl ExternRef {
193190
#[inline]
194191
pub const fn try_new(addr: u32) -> Option<Self> {
195192
match encode_host_ref(addr) {
196-
Some(raw) => Some(Self(raw)),
193+
Some(encoded) => Some(Self(encoded)),
197194
None => None,
198195
}
199196
}
@@ -251,7 +248,7 @@ impl AnyRef {
251248
#[inline]
252249
pub const fn from_host(addr: u32) -> Option<Self> {
253250
match encode_host_ref(addr) {
254-
Some(raw) => Some(Self(raw)),
251+
Some(encoded) => Some(Self(encoded)),
255252
None => None,
256253
}
257254
}

crates/types/src/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ mod tests {
8181

8282
#[test]
8383
fn concrete_references_require_store_type_information() {
84-
let concrete = WasmType::Ref(RefType::new_concrete(false, 0).unwrap());
84+
let concrete = WasmType::Ref(RefType::new_concrete(false, 0));
8585

8686
assert!(!WasmValue::from(FuncRef::new(0)).matches_type(concrete));
8787
assert!(!WasmValue::from(AnyRef::from_host(0).unwrap()).matches_type(concrete));

0 commit comments

Comments
 (0)