diff --git a/hetrans/src/main.rs b/hetrans/src/main.rs index c001ab2..ead246d 100644 --- a/hetrans/src/main.rs +++ b/hetrans/src/main.rs @@ -9,6 +9,7 @@ use wasm_core::value::Value; use wasm_core::module::*; use wasm_core::trans::config::ModuleConfig; use wasm_core::hetrans::translate_module; +use wasm_core::hetrans::NullMapNativeInvoke; fn main() { let mut args = env::args(); @@ -25,7 +26,7 @@ fn main() { let module = wasm_core::trans::translate_module_raw(code.as_slice(), cfg); let entry_fn = module.lookup_exported_func(&entry_fn_name).expect("Entry function not found"); - let result = translate_module(&module, entry_fn); + let result = translate_module(&module, entry_fn, &mut NullMapNativeInvoke); eprintln!("{:?}", module.functions[entry_fn].body.opcodes); ::std::io::stdout().write_all(&result).unwrap(); } diff --git a/src/hetrans.rs b/src/hetrans.rs index 393da3d..d7f233d 100644 --- a/src/hetrans.rs +++ b/src/hetrans.rs @@ -128,6 +128,15 @@ pub enum TargetOp { Never } +pub trait MapNativeInvoke { + fn map_native_invoke(&mut self, module: &str, field: &str) -> Option; +} + +pub struct NullMapNativeInvoke; +impl MapNativeInvoke for NullMapNativeInvoke { + fn map_native_invoke(&mut self, _module: &str, _field: &str) -> Option { None } +} + struct Reloc { code_loc: usize, ty: RelocType @@ -150,7 +159,7 @@ struct TargetFunction { generic_relocs: Vec } -pub fn translate_module(m: &Module, entry_fn: usize) -> Vec { +pub fn translate_module(m: &Module, entry_fn: usize, mni: &mut MapNativeInvoke) -> Vec { let mut target_code: Vec = Vec::new(); let (target_dss, slot_values, offset_table) = build_initializers(m); @@ -161,7 +170,7 @@ pub fn translate_module(m: &Module, entry_fn: usize) -> Vec { let mut functions: Vec = Vec::with_capacity(m.functions.len()); for f in &m.functions { - functions.push(translate_function(&m, f, &offset_table)); + functions.push(translate_function(&m, f, &offset_table, mni)); } let mut slot_initializer_relocs: Vec = Vec::with_capacity(functions.len()); @@ -249,7 +258,7 @@ fn build_call(m: &Module, out: &mut Vec, target: usize) -> usize /* reloc */ reloc_point } -fn translate_function(m: &Module, f: &Function, offset_table: &OffsetTable) -> TargetFunction { +fn translate_function(m: &Module, f: &Function, offset_table: &OffsetTable, mni: &mut MapNativeInvoke) -> TargetFunction { let mut result: Vec = Vec::new(); let mut relocs: Vec = Vec::new(); let opcodes = &f.body.opcodes; @@ -556,20 +565,27 @@ fn translate_function(m: &Module, f: &Function, offset_table: &OffsetTable) -> T Opcode::NativeInvoke(id) => { let native = &m.natives[id as usize]; - if native.module != "hexagon_e" { - panic!("NativeInvoke with a module other than `hexagon_e` is not supported. Got: {}", native.module); - } - - if !native.field.starts_with("syscall_") { - panic!("Invalid NativeInvoke field prefix; Expecting `syscall_`"); - } - - let ni_id: u32 = native.field.splitn(2, "_").nth(1).unwrap().parse().unwrap_or_else(|_| { - panic!("Unable to parse NativeInvoke id"); - }); - result.push(TargetOp::NativeInvoke as u8); - write_u32(&mut result, ni_id); + write_u32( + &mut result, + if let Some(ni_id) = mni.map_native_invoke(&native.module, &native.field) { + ni_id + } else { + if native.module != "hexagon_e" { + panic!("NativeInvoke with a module other than `hexagon_e` is not supported. Got: {}", native.module); + } + + if !native.field.starts_with("syscall_") { + panic!("Invalid NativeInvoke field prefix; Expecting `syscall_`"); + } + + let ni_id: u32 = native.field.splitn(2, "_").nth(1).unwrap().parse().unwrap_or_else(|_| { + panic!("Unable to parse NativeInvoke id"); + }); + + ni_id + } + ); }, _ => { eprintln!("Not implemented: {:?}", op);