diff --git a/src/execution/mod.rs b/src/execution/mod.rs index bc3ab4b5..c0a697ce 100644 --- a/src/execution/mod.rs +++ b/src/execution/mod.rs @@ -372,18 +372,27 @@ where run_const_span(validation_info.wasm, expr, ()).unwrap_validated(), ) }) - .collect(), + .collect::>>(), ElemItems::RefFuncs(indicies) => { // This branch gets taken when the elements are direct function references (i32 values), so we just return the indices - indicies.clone() + indicies + .iter() + .map(|el| Some(*el)) + .collect::>>() } }; let references: Vec = offsets .iter() - .map(|offset| match elem.ty() { - RefType::FuncRef => Ref::Func(FuncAddr::new(Some(*offset as usize))), - RefType::ExternRef => Ref::Extern(ExternAddr::new(Some(*offset as usize))), + .map(|offset| { + let offset = match offset { + Some(offset) => Some(*offset as usize), + None => None, + }; + match elem.ty() { + RefType::FuncRef => Ref::Func(FuncAddr::new(offset)), + RefType::ExternRef => Ref::Extern(ExternAddr::new(offset)), + } }) .collect(); @@ -411,7 +420,8 @@ where let offset = get_address_offset( run_const_span(validation_info.wasm, &active_elem.init_expr, ()) .unwrap_validated(), - ) as usize; + ) + .unwrap() as usize; let table = &mut tables[table_idx]; // This can't be verified at validation-time because we don't keep track of actual values when validating expressions @@ -529,13 +539,19 @@ where /// they can only be an i32 (which can be understood from either a [`Value::I32`] - but /// since we don't unbox the address of the reference, for us also a [`Value::Ref`] - /// or from a Global) -fn get_address_offset(value: Value) -> u32 { +fn get_address_offset(value: Value) -> Option { match value { - Value::I32(val) => val, + Value::I32(val) => Some(val), Value::Ref(rref) => match rref { Ref::Extern(_) => todo!("Not yet implemented"), // TODO: fix - Ref::Func(func_addr) => func_addr.addr.unwrap_or(u32::MAX as usize) as u32, + Ref::Func(func_addr) => { + if func_addr.is_null() { + None + } else { + Some(func_addr.addr.unwrap() as u32) + } + } }, // INFO: from wasmtime - implement only global _ => unreachable!(),