Evaluate a constant expression
(
&self,
const_instrs: &[tinywasm_types::ConstInstruction],
module_global_addrs: &[Addr],
module_func_addrs: &[FuncAddr],
)
| 538 | |
| 539 | /// Evaluate a constant expression |
| 540 | fn eval_const( |
| 541 | &self, |
| 542 | const_instrs: &[tinywasm_types::ConstInstruction], |
| 543 | module_global_addrs: &[Addr], |
| 544 | module_func_addrs: &[FuncAddr], |
| 545 | ) -> Result<TinyWasmValue> { |
| 546 | use tinywasm_types::ConstInstruction::*; |
| 547 | |
| 548 | let resolve_global = |idx: u32| -> Result<TinyWasmValue> { |
| 549 | let Some(addr) = module_global_addrs.get(idx as usize) else { |
| 550 | cold_path(); |
| 551 | return Err(Error::Other(format!( |
| 552 | "global {idx} not found. This should have been caught by the validator" |
| 553 | ))); |
| 554 | }; |
| 555 | |
| 556 | let Some(global) = self.state.globals.get(*addr as usize) else { |
| 557 | cold_path(); |
| 558 | return Err(Error::Other(format!("global {addr} not found"))); |
| 559 | }; |
| 560 | |
| 561 | Ok(global.value.get()) |
| 562 | }; |
| 563 | |
| 564 | let resolve_func = |idx: u32| -> Result<u32> { |
| 565 | match module_func_addrs.get(idx as usize).copied() { |
| 566 | Some(func_addr) => Ok(func_addr), |
| 567 | None => { |
| 568 | cold_path(); |
| 569 | Err(Error::Other(format!( |
| 570 | "function {idx} not found. This should have been caught by the validator" |
| 571 | ))) |
| 572 | } |
| 573 | } |
| 574 | }; |
| 575 | |
| 576 | if const_instrs.len() == 1 { |
| 577 | let val = match &const_instrs[0] { |
| 578 | F32Const(f) => (*f).into(), |
| 579 | F64Const(f) => (*f).into(), |
| 580 | I32Const(i) => (*i).into(), |
| 581 | I64Const(i) => (*i).into(), |
| 582 | V128Const(i) => (*i).into(), |
| 583 | GlobalGet(addr) => resolve_global(*addr)?, |
| 584 | RefFunc(None) => TinyWasmValue::ValueRef(ValueRef::NULL), |
| 585 | RefExtern(None) => TinyWasmValue::ValueRef(ValueRef::NULL), |
| 586 | RefFunc(Some(idx)) => TinyWasmValue::ValueRef(ValueRef::from_addr(Some(resolve_func(*idx)?))), |
| 587 | _ => { |
| 588 | cold_path(); |
| 589 | return Err(Error::other("unsupported const instruction")); |
| 590 | } |
| 591 | }; |
| 592 | |
| 593 | return Ok(val); |
| 594 | } |
| 595 | |
| 596 | let mut stack = Vec::with_capacity(const_instrs.len()); |
| 597 | for instr in const_instrs { |