mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-21 04:31:33 +00:00
Parse input in a single pass.
This commit is contained in:
@ -23,7 +23,7 @@ pub trait FunctionCodeGenerator {
|
|||||||
fn feed_param(&mut self, ty: WpType) -> Result<(), CodegenError>;
|
fn feed_param(&mut self, ty: WpType) -> Result<(), CodegenError>;
|
||||||
fn feed_local(&mut self, ty: WpType, n: usize) -> Result<(), CodegenError>;
|
fn feed_local(&mut self, ty: WpType, n: usize) -> Result<(), CodegenError>;
|
||||||
fn begin_body(&mut self) -> Result<(), CodegenError>;
|
fn begin_body(&mut self) -> Result<(), CodegenError>;
|
||||||
fn feed_opcode(&mut self, op: Operator, module_info: &ModuleInfo) -> Result<(), CodegenError>;
|
fn feed_opcode(&mut self, op: &Operator, module_info: &ModuleInfo) -> Result<(), CodegenError>;
|
||||||
fn finalize(&mut self) -> Result<(), CodegenError>;
|
fn finalize(&mut self) -> Result<(), CodegenError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,11 +1232,7 @@ impl X64FunctionCode {
|
|||||||
a.emit_mov(Size::S32, addr, Location::GPR(tmp_addr));
|
a.emit_mov(Size::S32, addr, Location::GPR(tmp_addr));
|
||||||
match (offset as u32).checked_add(value_size as u32) {
|
match (offset as u32).checked_add(value_size as u32) {
|
||||||
Some(x) => {
|
Some(x) => {
|
||||||
a.emit_add(
|
a.emit_add(Size::S64, Location::Imm32(x), Location::GPR(tmp_addr));
|
||||||
Size::S64,
|
|
||||||
Location::Imm32(x),
|
|
||||||
Location::GPR(tmp_addr),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
a.emit_add(
|
a.emit_add(
|
||||||
@ -1409,13 +1405,13 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn feed_opcode(&mut self, op: Operator, module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
fn feed_opcode(&mut self, op: &Operator, module_info: &ModuleInfo) -> Result<(), CodegenError> {
|
||||||
//println!("{:?} {}", op, self.value_stack.len());
|
//println!("{:?} {}", op, self.value_stack.len());
|
||||||
let was_unreachable;
|
let was_unreachable;
|
||||||
|
|
||||||
if self.unreachable_depth > 0 {
|
if self.unreachable_depth > 0 {
|
||||||
was_unreachable = true;
|
was_unreachable = true;
|
||||||
match op {
|
match *op {
|
||||||
Operator::Block { .. } | Operator::Loop { .. } | Operator::If { .. } => {
|
Operator::Block { .. } | Operator::Loop { .. } | Operator::If { .. } => {
|
||||||
self.unreachable_depth += 1;
|
self.unreachable_depth += 1;
|
||||||
}
|
}
|
||||||
@ -1442,7 +1438,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let a = self.assembler.as_mut().unwrap();
|
let a = self.assembler.as_mut().unwrap();
|
||||||
match op {
|
match *op {
|
||||||
Operator::GetGlobal { global_index } => {
|
Operator::GetGlobal { global_index } => {
|
||||||
let global_index = global_index as usize;
|
let global_index = global_index as usize;
|
||||||
|
|
||||||
@ -3344,7 +3340,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
self.value_stack.push((ret, LocalOrTemp::Temp));
|
self.value_stack.push((ret, LocalOrTemp::Temp));
|
||||||
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
|
a.emit_mov(Size::S64, Location::GPR(GPR::RAX), ret);
|
||||||
}
|
}
|
||||||
Operator::I32Load { memarg } => {
|
Operator::I32Load { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
||||||
@ -3369,7 +3365,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::F32Load { memarg } => {
|
Operator::F32Load { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::F32], false)[0];
|
||||||
@ -3394,7 +3390,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I32Load8U { memarg } => {
|
Operator::I32Load8U { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
||||||
@ -3420,7 +3416,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I32Load8S { memarg } => {
|
Operator::I32Load8S { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
||||||
@ -3446,7 +3442,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I32Load16U { memarg } => {
|
Operator::I32Load16U { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
||||||
@ -3472,7 +3468,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I32Load16S { memarg } => {
|
Operator::I32Load16S { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I32], false)[0];
|
||||||
@ -3498,7 +3494,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I32Store { memarg } => {
|
Operator::I32Store { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3523,7 +3519,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::F32Store { memarg } => {
|
Operator::F32Store { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3548,7 +3544,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I32Store8 { memarg } => {
|
Operator::I32Store8 { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3573,7 +3569,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I32Store16 { memarg } => {
|
Operator::I32Store16 { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3598,7 +3594,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Load { memarg } => {
|
Operator::I64Load { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
@ -3623,7 +3619,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::F64Load { memarg } => {
|
Operator::F64Load { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::F64], false)[0];
|
||||||
@ -3648,7 +3644,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Load8U { memarg } => {
|
Operator::I64Load8U { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
@ -3674,7 +3670,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Load8S { memarg } => {
|
Operator::I64Load8S { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
@ -3700,7 +3696,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Load16U { memarg } => {
|
Operator::I64Load16U { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
@ -3726,7 +3722,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Load16S { memarg } => {
|
Operator::I64Load16S { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
@ -3752,7 +3748,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Load32U { memarg } => {
|
Operator::I64Load32U { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
@ -3783,7 +3779,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Load32S { memarg } => {
|
Operator::I64Load32S { ref memarg } => {
|
||||||
let target =
|
let target =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
@ -3809,7 +3805,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Store { memarg } => {
|
Operator::I64Store { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3834,7 +3830,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::F64Store { memarg } => {
|
Operator::F64Store { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3859,7 +3855,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Store8 { memarg } => {
|
Operator::I64Store8 { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3884,7 +3880,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Store16 { memarg } => {
|
Operator::I64Store16 { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -3909,7 +3905,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Operator::I64Store32 { memarg } => {
|
Operator::I64Store32 { ref memarg } => {
|
||||||
let target_value =
|
let target_value =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
let target_addr =
|
let target_addr =
|
||||||
@ -4009,7 +4005,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
|
|
||||||
a.emit_label(after);
|
a.emit_label(after);
|
||||||
}
|
}
|
||||||
Operator::BrTable { table } => {
|
Operator::BrTable { ref table } => {
|
||||||
let (targets, default_target) = table.read_table().unwrap();
|
let (targets, default_target) = table.read_table().unwrap();
|
||||||
let cond =
|
let cond =
|
||||||
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
|
||||||
|
@ -502,18 +502,42 @@ impl Emitter for Assembler {
|
|||||||
(Size::S8, Location::Memory(src, disp), Location::GPR(dst)) => {
|
(Size::S8, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||||
dynasm!(self ; mov Rb(dst as u8), [Rq(src as u8) + disp]);
|
dynasm!(self ; mov Rb(dst as u8), [Rq(src as u8) + disp]);
|
||||||
}
|
}
|
||||||
|
(Size::S8, Location::Imm32(src), Location::GPR(dst)) => {
|
||||||
|
dynasm!(self ; mov Rb(dst as u8), src as i8);
|
||||||
|
}
|
||||||
|
(Size::S8, Location::Imm64(src), Location::GPR(dst)) => {
|
||||||
|
dynasm!(self ; mov Rb(dst as u8), src as i8);
|
||||||
|
}
|
||||||
(Size::S8, Location::Imm32(src), Location::Memory(dst, disp)) => {
|
(Size::S8, Location::Imm32(src), Location::Memory(dst, disp)) => {
|
||||||
dynasm!(self ; mov BYTE [Rq(dst as u8) + disp], src as i8);
|
dynasm!(self ; mov BYTE [Rq(dst as u8) + disp], src as i8);
|
||||||
}
|
}
|
||||||
|
(Size::S8, Location::Imm64(src), Location::Memory(dst, disp)) => {
|
||||||
|
dynasm!(self ; mov BYTE [Rq(dst as u8) + disp], src as i8);
|
||||||
|
}
|
||||||
(Size::S16, Location::GPR(src), Location::Memory(dst, disp)) => {
|
(Size::S16, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||||
dynasm!(self ; mov [Rq(dst as u8) + disp], Rw(src as u8));
|
dynasm!(self ; mov [Rq(dst as u8) + disp], Rw(src as u8));
|
||||||
}
|
}
|
||||||
(Size::S16, Location::Memory(src, disp), Location::GPR(dst)) => {
|
(Size::S16, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||||
dynasm!(self ; mov Rw(dst as u8), [Rq(src as u8) + disp]);
|
dynasm!(self ; mov Rw(dst as u8), [Rq(src as u8) + disp]);
|
||||||
}
|
}
|
||||||
|
(Size::S16, Location::Imm32(src), Location::GPR(dst)) => {
|
||||||
|
dynasm!(self ; mov Rw(dst as u8), src as i16);
|
||||||
|
}
|
||||||
|
(Size::S16, Location::Imm64(src), Location::GPR(dst)) => {
|
||||||
|
dynasm!(self ; mov Rw(dst as u8), src as i16);
|
||||||
|
}
|
||||||
(Size::S16, Location::Imm32(src), Location::Memory(dst, disp)) => {
|
(Size::S16, Location::Imm32(src), Location::Memory(dst, disp)) => {
|
||||||
dynasm!(self ; mov WORD [Rq(dst as u8) + disp], src as i16);
|
dynasm!(self ; mov WORD [Rq(dst as u8) + disp], src as i16);
|
||||||
}
|
}
|
||||||
|
(Size::S16, Location::Imm64(src), Location::Memory(dst, disp)) => {
|
||||||
|
dynasm!(self ; mov WORD [Rq(dst as u8) + disp], src as i16);
|
||||||
|
}
|
||||||
|
(Size::S32, Location::Imm64(src), Location::GPR(dst)) => {
|
||||||
|
dynasm!(self ; mov Rd(dst as u8), src as i32);
|
||||||
|
}
|
||||||
|
(Size::S32, Location::Imm64(src), Location::Memory(dst, disp)) => {
|
||||||
|
dynasm!(self ; mov DWORD [Rq(dst as u8) + disp], src as i32);
|
||||||
|
}
|
||||||
(Size::S32, Location::GPR(src), Location::XMM(dst)) => {
|
(Size::S32, Location::GPR(src), Location::XMM(dst)) => {
|
||||||
dynasm!(self ; movd Rx(dst as u8), Rd(src as u8));
|
dynasm!(self ; movd Rx(dst as u8), Rd(src as u8));
|
||||||
}
|
}
|
||||||
|
@ -38,30 +38,6 @@ impl From<CodegenError> for LoadError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(bytes: &[u8]) -> Result<(), LoadError> {
|
|
||||||
let mut parser = wasmparser::ValidatingParser::new(
|
|
||||||
bytes,
|
|
||||||
Some(wasmparser::ValidatingParserConfig {
|
|
||||||
operator_config: wasmparser::OperatorValidatorConfig {
|
|
||||||
enable_threads: false,
|
|
||||||
enable_reference_types: false,
|
|
||||||
enable_simd: false,
|
|
||||||
enable_bulk_memory: false,
|
|
||||||
},
|
|
||||||
mutable_global_imports: false,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let state = parser.read();
|
|
||||||
match *state {
|
|
||||||
wasmparser::ParserState::EndWasm => break Ok(()),
|
|
||||||
wasmparser::ParserState::Error(err) => Err(LoadError::Parse(err))?,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_module<
|
pub fn read_module<
|
||||||
MCG: ModuleCodeGenerator<FCG, PC, FR>,
|
MCG: ModuleCodeGenerator<FCG, PC, FR>,
|
||||||
FCG: FunctionCodeGenerator,
|
FCG: FunctionCodeGenerator,
|
||||||
@ -73,7 +49,6 @@ pub fn read_module<
|
|||||||
mcg: &mut MCG,
|
mcg: &mut MCG,
|
||||||
compiler_config: &CompilerConfig,
|
compiler_config: &CompilerConfig,
|
||||||
) -> Result<ModuleInfo, LoadError> {
|
) -> Result<ModuleInfo, LoadError> {
|
||||||
validate(wasm)?;
|
|
||||||
let mut info = ModuleInfo {
|
let mut info = ModuleInfo {
|
||||||
memories: Map::new(),
|
memories: Map::new(),
|
||||||
globals: Map::new(),
|
globals: Map::new(),
|
||||||
@ -103,277 +78,251 @@ pub fn read_module<
|
|||||||
custom_sections: HashMap::new(),
|
custom_sections: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut reader = ModuleReader::new(wasm)?;
|
let mut parser = wasmparser::ValidatingParser::new(
|
||||||
|
wasm,
|
||||||
|
Some(wasmparser::ValidatingParserConfig {
|
||||||
|
operator_config: wasmparser::OperatorValidatorConfig {
|
||||||
|
enable_threads: false,
|
||||||
|
enable_reference_types: false,
|
||||||
|
enable_simd: false,
|
||||||
|
enable_bulk_memory: false,
|
||||||
|
},
|
||||||
|
mutable_global_imports: false,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut namespace_builder = Some(StringTableBuilder::new());
|
||||||
|
let mut name_builder = Some(StringTableBuilder::new());
|
||||||
|
let mut func_count: usize = ::std::usize::MAX;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if reader.eof() {
|
use wasmparser::ParserState;
|
||||||
return Ok(info);
|
let state = parser.read();
|
||||||
}
|
match *state {
|
||||||
|
ParserState::EndWasm => break Ok(info),
|
||||||
let section = reader.read()?;
|
ParserState::Error(err) => Err(LoadError::Parse(err))?,
|
||||||
|
ParserState::TypeSectionEntry(ref ty) => {
|
||||||
match section.code {
|
info.signatures.push(func_type_to_func_sig(ty)?);
|
||||||
SectionCode::Type => {
|
|
||||||
let type_reader = section.get_type_section_reader()?;
|
|
||||||
|
|
||||||
for ty in type_reader {
|
|
||||||
let ty = ty?;
|
|
||||||
info.signatures.push(func_type_to_func_sig(ty)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
mcg.feed_signatures(info.signatures.clone())?;
|
|
||||||
}
|
}
|
||||||
SectionCode::Import => {
|
ParserState::ImportSectionEntry { module, field, ty } => {
|
||||||
let import_reader = section.get_import_section_reader()?;
|
let namespace_index = namespace_builder.as_mut().unwrap().register(module);
|
||||||
let mut namespace_builder = StringTableBuilder::new();
|
let name_index = name_builder.as_mut().unwrap().register(field);
|
||||||
let mut name_builder = StringTableBuilder::new();
|
let import_name = ImportName {
|
||||||
|
namespace_index,
|
||||||
|
name_index,
|
||||||
|
};
|
||||||
|
|
||||||
for import in import_reader {
|
match ty {
|
||||||
let Import { module, field, ty } = import?;
|
ImportSectionEntryType::Function(sigindex) => {
|
||||||
|
let sigindex = SigIndex::new(sigindex as usize);
|
||||||
|
info.imported_functions.push(import_name);
|
||||||
|
info.func_assoc.push(sigindex);
|
||||||
|
mcg.feed_import_function()?;
|
||||||
|
}
|
||||||
|
ImportSectionEntryType::Table(table_ty) => {
|
||||||
|
assert_eq!(table_ty.element_type, WpType::AnyFunc);
|
||||||
|
let table_desc = TableDescriptor {
|
||||||
|
element: ElementType::Anyfunc,
|
||||||
|
minimum: table_ty.limits.initial,
|
||||||
|
maximum: table_ty.limits.maximum,
|
||||||
|
};
|
||||||
|
|
||||||
let namespace_index = namespace_builder.register(module);
|
info.imported_tables.push((import_name, table_desc));
|
||||||
let name_index = name_builder.register(field);
|
}
|
||||||
let import_name = ImportName {
|
ImportSectionEntryType::Memory(memory_ty) => {
|
||||||
namespace_index,
|
let mem_desc = MemoryDescriptor {
|
||||||
name_index,
|
minimum: Pages(memory_ty.limits.initial),
|
||||||
};
|
maximum: memory_ty.limits.maximum.map(|max| Pages(max)),
|
||||||
|
shared: memory_ty.shared,
|
||||||
match ty {
|
};
|
||||||
ImportSectionEntryType::Function(sigindex) => {
|
info.imported_memories.push((import_name, mem_desc));
|
||||||
let sigindex = SigIndex::new(sigindex as usize);
|
}
|
||||||
info.imported_functions.push(import_name);
|
ImportSectionEntryType::Global(global_ty) => {
|
||||||
info.func_assoc.push(sigindex);
|
let global_desc = GlobalDescriptor {
|
||||||
mcg.feed_import_function()?;
|
mutable: global_ty.mutable,
|
||||||
}
|
ty: wp_type_to_type(global_ty.content_type)?,
|
||||||
ImportSectionEntryType::Table(table_ty) => {
|
};
|
||||||
assert_eq!(table_ty.element_type, WpType::AnyFunc);
|
info.imported_globals.push((import_name, global_desc));
|
||||||
let table_desc = TableDescriptor {
|
|
||||||
element: ElementType::Anyfunc,
|
|
||||||
minimum: table_ty.limits.initial,
|
|
||||||
maximum: table_ty.limits.maximum,
|
|
||||||
};
|
|
||||||
|
|
||||||
info.imported_tables.push((import_name, table_desc));
|
|
||||||
}
|
|
||||||
ImportSectionEntryType::Memory(memory_ty) => {
|
|
||||||
let mem_desc = MemoryDescriptor {
|
|
||||||
minimum: Pages(memory_ty.limits.initial),
|
|
||||||
maximum: memory_ty.limits.maximum.map(|max| Pages(max)),
|
|
||||||
shared: memory_ty.shared,
|
|
||||||
};
|
|
||||||
info.imported_memories.push((import_name, mem_desc));
|
|
||||||
}
|
|
||||||
ImportSectionEntryType::Global(global_ty) => {
|
|
||||||
let global_desc = GlobalDescriptor {
|
|
||||||
mutable: global_ty.mutable,
|
|
||||||
ty: wp_type_to_type(global_ty.content_type)?,
|
|
||||||
};
|
|
||||||
info.imported_globals.push((import_name, global_desc));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info.namespace_table = namespace_builder.finish();
|
|
||||||
info.name_table = name_builder.finish();
|
|
||||||
}
|
}
|
||||||
SectionCode::Function => {
|
ParserState::FunctionSectionEntry(sigindex) => {
|
||||||
let func_decl_reader = section.get_function_section_reader()?;
|
let sigindex = SigIndex::new(sigindex as usize);
|
||||||
|
info.func_assoc.push(sigindex);
|
||||||
for sigindex in func_decl_reader {
|
|
||||||
let sigindex = sigindex?;
|
|
||||||
|
|
||||||
let sigindex = SigIndex::new(sigindex as usize);
|
|
||||||
info.func_assoc.push(sigindex);
|
|
||||||
}
|
|
||||||
|
|
||||||
mcg.feed_function_signatures(info.func_assoc.clone())?;
|
|
||||||
}
|
}
|
||||||
SectionCode::Table => {
|
ParserState::TableSectionEntry(table_ty) => {
|
||||||
let table_decl_reader = section.get_table_section_reader()?;
|
let table_desc = TableDescriptor {
|
||||||
|
element: ElementType::Anyfunc,
|
||||||
|
minimum: table_ty.limits.initial,
|
||||||
|
maximum: table_ty.limits.maximum,
|
||||||
|
};
|
||||||
|
|
||||||
for table_ty in table_decl_reader {
|
info.tables.push(table_desc);
|
||||||
let table_ty = table_ty?;
|
|
||||||
|
|
||||||
let table_desc = TableDescriptor {
|
|
||||||
element: ElementType::Anyfunc,
|
|
||||||
minimum: table_ty.limits.initial,
|
|
||||||
maximum: table_ty.limits.maximum,
|
|
||||||
};
|
|
||||||
|
|
||||||
info.tables.push(table_desc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SectionCode::Memory => {
|
ParserState::MemorySectionEntry(memory_ty) => {
|
||||||
let mem_decl_reader = section.get_memory_section_reader()?;
|
let mem_desc = MemoryDescriptor {
|
||||||
|
minimum: Pages(memory_ty.limits.initial),
|
||||||
|
maximum: memory_ty.limits.maximum.map(|max| Pages(max)),
|
||||||
|
shared: memory_ty.shared,
|
||||||
|
};
|
||||||
|
|
||||||
for memory_ty in mem_decl_reader {
|
info.memories.push(mem_desc);
|
||||||
let memory_ty = memory_ty?;
|
|
||||||
|
|
||||||
let mem_desc = MemoryDescriptor {
|
|
||||||
minimum: Pages(memory_ty.limits.initial),
|
|
||||||
maximum: memory_ty.limits.maximum.map(|max| Pages(max)),
|
|
||||||
shared: memory_ty.shared,
|
|
||||||
};
|
|
||||||
|
|
||||||
info.memories.push(mem_desc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SectionCode::Global => {
|
ParserState::ExportSectionEntry { field, kind, index } => {
|
||||||
let global_decl_reader = section.get_global_section_reader()?;
|
let export_index = match kind {
|
||||||
|
ExternalKind::Function => ExportIndex::Func(FuncIndex::new(index as usize)),
|
||||||
|
ExternalKind::Table => ExportIndex::Table(TableIndex::new(index as usize)),
|
||||||
|
ExternalKind::Memory => ExportIndex::Memory(MemoryIndex::new(index as usize)),
|
||||||
|
ExternalKind::Global => ExportIndex::Global(GlobalIndex::new(index as usize)),
|
||||||
|
};
|
||||||
|
|
||||||
for global in global_decl_reader {
|
info.exports.insert(field.to_string(), export_index);
|
||||||
let global = global?;
|
|
||||||
|
|
||||||
let desc = GlobalDescriptor {
|
|
||||||
mutable: global.ty.mutable,
|
|
||||||
ty: wp_type_to_type(global.ty.content_type)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
let global_init = GlobalInit {
|
|
||||||
desc,
|
|
||||||
init: eval_init_expr(&global.init_expr)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
info.globals.push(global_init);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SectionCode::Export => {
|
ParserState::StartSectionEntry(start_index) => {
|
||||||
let export_reader = section.get_export_section_reader()?;
|
|
||||||
|
|
||||||
for export in export_reader {
|
|
||||||
let Export { field, kind, index } = export?;
|
|
||||||
|
|
||||||
let export_index = match kind {
|
|
||||||
ExternalKind::Function => ExportIndex::Func(FuncIndex::new(index as usize)),
|
|
||||||
ExternalKind::Table => ExportIndex::Table(TableIndex::new(index as usize)),
|
|
||||||
ExternalKind::Memory => {
|
|
||||||
ExportIndex::Memory(MemoryIndex::new(index as usize))
|
|
||||||
}
|
|
||||||
ExternalKind::Global => {
|
|
||||||
ExportIndex::Global(GlobalIndex::new(index as usize))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
info.exports.insert(field.to_string(), export_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Start => {
|
|
||||||
let start_index = section.get_start_section_content()?;
|
|
||||||
|
|
||||||
info.start_func = Some(FuncIndex::new(start_index as usize));
|
info.start_func = Some(FuncIndex::new(start_index as usize));
|
||||||
}
|
}
|
||||||
SectionCode::Element => {
|
ParserState::BeginFunctionBody { .. } => {
|
||||||
let element_reader = section.get_element_section_reader()?;
|
let id = func_count.wrapping_add(1);
|
||||||
|
func_count = id;
|
||||||
|
if func_count == 0 {
|
||||||
|
info.namespace_table = namespace_builder.take().unwrap().finish();
|
||||||
|
info.name_table = name_builder.take().unwrap().finish();
|
||||||
|
mcg.feed_signatures(info.signatures.clone())?;
|
||||||
|
mcg.feed_function_signatures(info.func_assoc.clone())?;
|
||||||
|
mcg.check_precondition(&info)?;
|
||||||
|
}
|
||||||
|
|
||||||
for element in element_reader {
|
let fcg = mcg.next_function()?;
|
||||||
let Element { kind, items } = element?;
|
let sig = info
|
||||||
|
.signatures
|
||||||
|
.get(
|
||||||
|
*info
|
||||||
|
.func_assoc
|
||||||
|
.get(FuncIndex::new(id as usize + info.imported_functions.len()))
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
for ret in sig.returns() {
|
||||||
|
fcg.feed_return(type_to_wp_type(*ret))?;
|
||||||
|
}
|
||||||
|
for param in sig.params() {
|
||||||
|
fcg.feed_param(type_to_wp_type(*param))?;
|
||||||
|
}
|
||||||
|
|
||||||
match kind {
|
let mut body_begun = false;
|
||||||
ElementKind::Active {
|
|
||||||
table_index,
|
|
||||||
init_expr,
|
|
||||||
} => {
|
|
||||||
let table_index = TableIndex::new(table_index as usize);
|
|
||||||
let base = eval_init_expr(&init_expr)?;
|
|
||||||
let items_reader = items.get_items_reader()?;
|
|
||||||
|
|
||||||
let elements: Vec<_> = items_reader
|
loop {
|
||||||
.into_iter()
|
let state = parser.read();
|
||||||
.map(|res| res.map(|index| FuncIndex::new(index as usize)))
|
match *state {
|
||||||
.collect::<Result<_, _>>()?;
|
ParserState::Error(err) => return Err(LoadError::Parse(err)),
|
||||||
|
ParserState::FunctionBodyLocals { ref locals } => {
|
||||||
let table_init = TableInitializer {
|
for &(count, ty) in locals.iter() {
|
||||||
table_index,
|
fcg.feed_local(ty, count as usize)?;
|
||||||
base,
|
|
||||||
elements,
|
|
||||||
};
|
|
||||||
|
|
||||||
info.elem_initializers.push(table_init);
|
|
||||||
}
|
|
||||||
ElementKind::Passive(_ty) => {
|
|
||||||
return Err(BinaryReaderError {
|
|
||||||
message: "passive tables are not yet supported",
|
|
||||||
offset: -1isize as usize,
|
|
||||||
}
|
}
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
}
|
ParserState::CodeOperator(ref op) => {
|
||||||
}
|
if !body_begun {
|
||||||
}
|
body_begun = true;
|
||||||
SectionCode::Code => {
|
fcg.begin_body()?;
|
||||||
let mut code_reader = section.get_code_section_reader()?;
|
|
||||||
if code_reader.get_count() as usize > info.func_assoc.len() {
|
|
||||||
return Err(BinaryReaderError {
|
|
||||||
message: "code_reader.get_count() > info.func_assoc.len()",
|
|
||||||
offset: ::std::usize::MAX,
|
|
||||||
}
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
mcg.check_precondition(&info)?;
|
|
||||||
for i in 0..code_reader.get_count() {
|
|
||||||
let item = code_reader.read()?;
|
|
||||||
let fcg = mcg.next_function()?;
|
|
||||||
let sig = info
|
|
||||||
.signatures
|
|
||||||
.get(
|
|
||||||
*info
|
|
||||||
.func_assoc
|
|
||||||
.get(FuncIndex::new(i as usize + info.imported_functions.len()))
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
for ret in sig.returns() {
|
|
||||||
fcg.feed_return(type_to_wp_type(*ret))?;
|
|
||||||
}
|
|
||||||
for param in sig.params() {
|
|
||||||
fcg.feed_param(type_to_wp_type(*param))?;
|
|
||||||
}
|
|
||||||
for local in item.get_locals_reader()? {
|
|
||||||
let (count, ty) = local?;
|
|
||||||
fcg.feed_local(ty, count as usize)?;
|
|
||||||
}
|
|
||||||
fcg.begin_body()?;
|
|
||||||
for op in item.get_operators_reader()? {
|
|
||||||
let op = op?;
|
|
||||||
fcg.feed_opcode(op, &info)?;
|
|
||||||
}
|
|
||||||
fcg.finalize()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Data => {
|
|
||||||
let data_reader = section.get_data_section_reader()?;
|
|
||||||
|
|
||||||
for data in data_reader {
|
|
||||||
let Data { kind, data } = data?;
|
|
||||||
|
|
||||||
match kind {
|
|
||||||
DataKind::Active {
|
|
||||||
memory_index,
|
|
||||||
init_expr,
|
|
||||||
} => {
|
|
||||||
let memory_index = MemoryIndex::new(memory_index as usize);
|
|
||||||
let base = eval_init_expr(&init_expr)?;
|
|
||||||
|
|
||||||
let data_init = DataInitializer {
|
|
||||||
memory_index,
|
|
||||||
base,
|
|
||||||
data: data.to_vec(),
|
|
||||||
};
|
|
||||||
|
|
||||||
info.data_initializers.push(data_init);
|
|
||||||
}
|
|
||||||
DataKind::Passive => {
|
|
||||||
return Err(BinaryReaderError {
|
|
||||||
message: "passive memories are not yet supported",
|
|
||||||
offset: -1isize as usize,
|
|
||||||
}
|
}
|
||||||
.into());
|
fcg.feed_opcode(op, &info)?;
|
||||||
}
|
}
|
||||||
|
ParserState::EndFunctionBody => break,
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fcg.finalize()?;
|
||||||
}
|
}
|
||||||
SectionCode::DataCount => {}
|
ParserState::BeginActiveElementSectionEntry(table_index) => {
|
||||||
SectionCode::Custom { .. } => {}
|
let table_index = TableIndex::new(table_index as usize);
|
||||||
|
let mut elements: Option<Vec<FuncIndex>> = None;
|
||||||
|
let mut base: Option<Initializer> = None;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let state = parser.read();
|
||||||
|
match *state {
|
||||||
|
ParserState::Error(err) => return Err(LoadError::Parse(err)),
|
||||||
|
ParserState::InitExpressionOperator(ref op) => {
|
||||||
|
base = Some(eval_init_expr(op)?)
|
||||||
|
}
|
||||||
|
ParserState::ElementSectionEntryBody(ref _elements) => {
|
||||||
|
elements = Some(
|
||||||
|
_elements
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(|index| FuncIndex::new(index as usize))
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ParserState::BeginInitExpressionBody
|
||||||
|
| ParserState::EndInitExpressionBody => {}
|
||||||
|
ParserState::EndElementSectionEntry => break,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let table_init = TableInitializer {
|
||||||
|
table_index,
|
||||||
|
base: base.unwrap(),
|
||||||
|
elements: elements.unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
info.elem_initializers.push(table_init);
|
||||||
|
}
|
||||||
|
ParserState::BeginActiveDataSectionEntry(memory_index) => {
|
||||||
|
let memory_index = MemoryIndex::new(memory_index as usize);
|
||||||
|
let mut base: Option<Initializer> = None;
|
||||||
|
let mut data: Vec<u8> = vec![];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let state = parser.read();
|
||||||
|
match *state {
|
||||||
|
ParserState::Error(err) => return Err(LoadError::Parse(err)),
|
||||||
|
ParserState::InitExpressionOperator(ref op) => {
|
||||||
|
base = Some(eval_init_expr(op)?)
|
||||||
|
}
|
||||||
|
ParserState::DataSectionEntryBodyChunk(chunk) => {
|
||||||
|
data = chunk.to_vec();
|
||||||
|
}
|
||||||
|
ParserState::BeginInitExpressionBody
|
||||||
|
| ParserState::EndInitExpressionBody => {}
|
||||||
|
ParserState::BeginDataSectionEntryBody(_)
|
||||||
|
| ParserState::EndDataSectionEntryBody => {}
|
||||||
|
ParserState::EndDataSectionEntry => break,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let data_init = DataInitializer {
|
||||||
|
memory_index,
|
||||||
|
base: base.unwrap(),
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
info.data_initializers.push(data_init);
|
||||||
|
}
|
||||||
|
ParserState::BeginGlobalSectionEntry(ty) => {
|
||||||
|
let init = loop {
|
||||||
|
let state = parser.read();
|
||||||
|
match *state {
|
||||||
|
ParserState::Error(err) => return Err(LoadError::Parse(err)),
|
||||||
|
ParserState::InitExpressionOperator(ref op) => {
|
||||||
|
break eval_init_expr(op)?;
|
||||||
|
}
|
||||||
|
ParserState::BeginInitExpressionBody => {}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let desc = GlobalDescriptor {
|
||||||
|
mutable: ty.mutable,
|
||||||
|
ty: wp_type_to_type(ty.content_type)?,
|
||||||
|
};
|
||||||
|
|
||||||
|
let global_init = GlobalInit { desc, init };
|
||||||
|
|
||||||
|
info.globals.push(global_init);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,7 +352,7 @@ pub fn type_to_wp_type(ty: Type) -> WpType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn func_type_to_func_sig(func_ty: FuncType) -> Result<FuncSig, BinaryReaderError> {
|
fn func_type_to_func_sig(func_ty: &FuncType) -> Result<FuncSig, BinaryReaderError> {
|
||||||
assert_eq!(func_ty.form, WpType::Func);
|
assert_eq!(func_ty.form, WpType::Func);
|
||||||
|
|
||||||
Ok(FuncSig::new(
|
Ok(FuncSig::new(
|
||||||
@ -422,10 +371,8 @@ fn func_type_to_func_sig(func_ty: FuncType) -> Result<FuncSig, BinaryReaderError
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_init_expr(expr: &InitExpr) -> Result<Initializer, BinaryReaderError> {
|
fn eval_init_expr(op: &Operator) -> Result<Initializer, BinaryReaderError> {
|
||||||
let mut reader = expr.get_operators_reader();
|
Ok(match *op {
|
||||||
let (op, offset) = reader.read_with_offset()?;
|
|
||||||
Ok(match op {
|
|
||||||
Operator::GetGlobal { global_index } => {
|
Operator::GetGlobal { global_index } => {
|
||||||
Initializer::GetGlobal(ImportedGlobalIndex::new(global_index as usize))
|
Initializer::GetGlobal(ImportedGlobalIndex::new(global_index as usize))
|
||||||
}
|
}
|
||||||
@ -440,7 +387,7 @@ fn eval_init_expr(expr: &InitExpr) -> Result<Initializer, BinaryReaderError> {
|
|||||||
_ => {
|
_ => {
|
||||||
return Err(BinaryReaderError {
|
return Err(BinaryReaderError {
|
||||||
message: "init expr evaluation failed: unsupported opcode",
|
message: "init expr evaluation failed: unsupported opcode",
|
||||||
offset,
|
offset: -1isize as usize,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user