@@ -251,13 +251,15 @@ pub struct WasmGlobal {
251251
252252#[ derive( Clone ) ]
253253pub enum RuntimeFunction {
254- Wasm {
254+ OwnedWasm {
255255 runtime_sig : RuntimeSignature ,
256256 pc_start : usize ,
257257 locals_count : usize ,
258- // For cross-instance calls, weak is to avoid cycles
259- owner : Option < Weak < Instance > > ,
260- function_index : Option < usize > ,
258+ } ,
259+ ImportedWasm {
260+ runtime_sig : RuntimeSignature ,
261+ owner : Weak < Instance > ,
262+ function_index : usize ,
261263 } ,
262264 Host {
263265 callback : Rc < dyn Fn ( & [ WasmValue ] ) -> Option < WasmValue > > ,
@@ -268,7 +270,8 @@ pub enum RuntimeFunction {
268270impl RuntimeFunction {
269271 pub fn signature ( & self ) -> RuntimeSignature {
270272 match self {
271- RuntimeFunction :: Wasm { runtime_sig, .. } => * runtime_sig,
273+ RuntimeFunction :: OwnedWasm { runtime_sig, .. } => * runtime_sig,
274+ RuntimeFunction :: ImportedWasm { runtime_sig, .. } => * runtime_sig,
272275 RuntimeFunction :: Host { runtime_sig, .. } => * runtime_sig,
273276 }
274277 }
@@ -391,12 +394,10 @@ impl Instance {
391394 }
392395 } else {
393396 let locals_count = function. locals . len ( ) . saturating_sub ( function. ty . params . len ( ) ) ;
394- inst. functions . push ( RuntimeFunction :: Wasm {
397+ inst. functions . push ( RuntimeFunction :: OwnedWasm {
395398 runtime_sig : RuntimeSignature :: from_signature ( & function. ty ) ,
396399 pc_start : function. body . start ,
397- locals_count,
398- owner : None ,
399- function_index : None
400+ locals_count,
400401 } ) ;
401402 }
402403 }
@@ -481,18 +482,10 @@ impl Instance {
481482 let func_idx = * idx as usize ;
482483 let f = inst. functions [ func_idx] . clone ( ) ;
483484 let ( owner_id, owner_func_idx) = match & f {
484- RuntimeFunction :: Wasm { owner, function_index : owner_idx, .. } => {
485- if let ( Some ( weak_owner) , Some ( idx) ) = ( owner, owner_idx) {
486- if let Some ( owner_rc) = weak_owner. upgrade ( ) {
487- ( owner_rc. id , * idx as u32 )
488- } else {
489- ( inst. id , func_idx as u32 )
490- }
491- } else {
492- ( inst. id , func_idx as u32 )
493- }
485+ RuntimeFunction :: ImportedWasm { owner, function_index, .. } => {
486+ if let Some ( owner_rc) = owner. upgrade ( ) { ( owner_rc. id , * function_index as u32 ) } else { ( inst. id , func_idx as u32 ) }
494487 }
495- RuntimeFunction :: Host { .. } => ( inst. id , func_idx as u32 ) ,
488+ RuntimeFunction :: OwnedWasm { .. } | RuntimeFunction :: Host { .. } => ( inst. id , func_idx as u32 ) ,
496489 } ;
497490 let func_ref = FuncRef :: new ( owner_id, owner_func_idx) ;
498491 let func_ref_value = WasmValue :: from_u64 ( func_ref. as_raw ( ) ) ;
@@ -508,9 +501,7 @@ impl Instance {
508501 if !pending. is_empty ( ) {
509502 let mut m = mem. borrow_mut ( ) ;
510503 for ( offset, bytes_vec) in pending. into_iter ( ) {
511- for ( i, b) in bytes_vec. iter ( ) . enumerate ( ) {
512- m. store_u8 ( offset + i as u32 , 0 , * b) . map_err ( Error :: Trap ) ?;
513- }
504+ m. write_bytes ( offset, & bytes_vec) . map_err ( Error :: Trap ) ?;
514505 }
515506 }
516507 }
@@ -649,17 +640,15 @@ impl Instance {
649640 }
650641 let fi = & self . functions [ idx] ;
651642 match fi {
652- RuntimeFunction :: Wasm { runtime_sig, pc_start, locals_count, owner, function_index : owner_idx } => {
653- if let ( Some ( owner_weak) , Some ( owner_idx) ) = ( owner, owner_idx) {
654- // Cross-instance call
655- if let Some ( owner_rc) = owner_weak. upgrade ( ) {
656- owner_rc. call_function_idx ( * owner_idx, return_pc, stack, control, func_bases, ctrl_bases) ?;
657- } else {
658- return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
659- }
643+ RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
644+ let pc = Self :: setup_wasm_function_call ( * runtime_sig, * pc_start, * locals_count, stack, control, func_bases, ctrl_bases, * return_pc) ?;
645+ self . interpret ( pc, stack, control, func_bases, ctrl_bases) ?;
646+ }
647+ RuntimeFunction :: ImportedWasm { owner, function_index, .. } => {
648+ if let Some ( owner_rc) = owner. upgrade ( ) {
649+ owner_rc. call_function_idx ( * function_index, return_pc, stack, control, func_bases, ctrl_bases) ?;
660650 } else {
661- let pc = Self :: setup_wasm_function_call ( * runtime_sig, * pc_start, * locals_count, stack, control, func_bases, ctrl_bases, * return_pc) ?;
662- self . interpret ( pc, stack, control, func_bases, ctrl_bases) ?;
651+ return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
663652 }
664653 }
665654 RuntimeFunction :: Host { callback, runtime_sig } => {
@@ -893,7 +882,7 @@ impl Instance {
893882 let offset: u32 = read_leb128( bytes, & mut pc) ?;
894883 let addr = pop_val!( ) . as_u32( ) ;
895884 let mem = mem_opt. ok_or_else( || Error :: Validation ( UNKNOWN_MEMORY ) ) ?;
896- let v = mem. borrow( ) . $method( addr, offset) . map_err( |e| Error :: Trap ( e ) ) ?;
885+ let v = mem. borrow( ) . $method( addr, offset) . map_err( Error :: Trap ) ?;
897886 let val = ( $push) ( v) ;
898887 stack. push( val) ;
899888 } } }
@@ -904,7 +893,7 @@ impl Instance {
904893 let addr = pop_val!( ) . as_u32( ) ;
905894 let val = ( $from) ( raw) ;
906895 let mem = mem_opt. ok_or_else( || Error :: Validation ( UNKNOWN_MEMORY ) ) ?;
907- mem. borrow_mut( ) . $method( addr, offset, val) . map_err( |e| Error :: Trap ( e ) ) ?;
896+ mem. borrow_mut( ) . $method( addr, offset, val) . map_err( Error :: Trap ) ?;
908897 } } }
909898
910899 loop {
@@ -1017,25 +1006,24 @@ impl Instance {
10171006 let f = & self . functions [ fi as usize ] ;
10181007
10191008 match f {
1020- RuntimeFunction :: Wasm { runtime_sig, pc_start, locals_count, owner, function_index : owner_idx } => {
1021- if let ( Some ( owner_weak) , Some ( idx) ) = ( owner, owner_idx) {
1022- if let Some ( owner_rc) = owner_weak. upgrade ( ) {
1023- let n_params = runtime_sig. n_params ( ) as usize ;
1024- let params_start = stack. len ( ) - n_params;
1025- let mut tmp_stack: Vec < WasmValue > = vec ! [ WasmValue :: default ( ) ; n_params] ;
1026- tmp_stack[ ..n_params] . copy_from_slice ( & stack[ params_start..( n_params + params_start) ] ) ;
1027- stack. truncate ( params_start) ;
1028- let mut control_nested: Vec < ControlFrame > = Vec :: new ( ) ;
1029- let mut ret_pc_nested = 0usize ;
1030- let mut func_bases_nested: Vec < usize > = Vec :: new ( ) ;
1031- let mut ctrl_bases_nested = vec ! [ ] ;
1032- owner_rc. call_function_idx ( * idx, & mut ret_pc_nested, & mut tmp_stack, & mut control_nested, & mut func_bases_nested, & mut ctrl_bases_nested) ?;
1033- for v in tmp_stack { stack. push ( v) ; }
1034- } else {
1035- return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
1036- }
1009+ RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
1010+ pc = Self :: setup_wasm_function_call ( * runtime_sig, * pc_start, * locals_count, stack, control, func_bases, ctrl_bases, pc) ?;
1011+ }
1012+ RuntimeFunction :: ImportedWasm { owner, function_index, runtime_sig } => {
1013+ if let Some ( owner_rc) = owner. upgrade ( ) {
1014+ let n_params = runtime_sig. n_params ( ) as usize ;
1015+ let params_start = stack. len ( ) - n_params;
1016+ let mut tmp_stack: Vec < WasmValue > = Vec :: with_capacity ( n_params) ;
1017+ tmp_stack. extend_from_slice ( & stack[ params_start..( n_params + params_start) ] ) ;
1018+ stack. truncate ( params_start) ;
1019+ let mut control_nested: Vec < ControlFrame > = Vec :: new ( ) ;
1020+ let mut ret_pc_nested = 0usize ;
1021+ let mut func_bases_nested: Vec < usize > = Vec :: new ( ) ;
1022+ let mut ctrl_bases_nested = vec ! [ ] ;
1023+ owner_rc. call_function_idx ( * function_index, & mut ret_pc_nested, & mut tmp_stack, & mut control_nested, & mut func_bases_nested, & mut ctrl_bases_nested) ?;
1024+ for v in tmp_stack { stack. push ( v) ; }
10371025 } else {
1038- pc = Self :: setup_wasm_function_call ( * runtime_sig , * pc_start , * locals_count , stack , control , func_bases , ctrl_bases , pc ) ? ;
1026+ return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
10391027 }
10401028 }
10411029 RuntimeFunction :: Host { callback, runtime_sig } => {
@@ -1094,7 +1082,7 @@ impl Instance {
10941082 let n_params = callee. param_count ( ) ;
10951083 let params_start = stack. len ( ) - n_params;
10961084 let mut tmp_stack: Vec < WasmValue > = Vec :: with_capacity ( n_params) ;
1097- for i in 0 ..n_params { tmp_stack. push ( stack[ params_start + i ] ) ; }
1085+ tmp_stack. extend_from_slice ( & stack[ params_start.. ( params_start + n_params ) ] ) ;
10981086 stack. truncate ( params_start) ;
10991087 let mut control_nested: Vec < ControlFrame > = Vec :: new ( ) ;
11001088 let mut ret_pc_nested = 0usize ;
@@ -1126,27 +1114,26 @@ impl Instance {
11261114 }
11271115
11281116 match callee {
1129- RuntimeFunction :: Wasm { runtime_sig, pc_start, locals_count, owner, function_index : owner_idx } => {
1130- if let ( Some ( owner_weak) , Some ( idx) ) = ( & owner, owner_idx) {
1131- if let Some ( owner_rc) = owner_weak. upgrade ( ) {
1132- let n_params = runtime_sig. n_params ( ) as usize ;
1133- let params_start = stack. len ( ) - n_params;
1134- let mut tmp_stack: Vec < WasmValue > = Vec :: with_capacity ( n_params) ;
1135- for i in 0 ..n_params { tmp_stack. push ( stack[ params_start + i] ) ; }
1136- stack. truncate ( params_start) ;
1137- let mut control_nested: Vec < ControlFrame > = Vec :: new ( ) ;
1138- let mut ret_pc_nested = 0usize ;
1139- let mut func_bases_nested: Vec < usize > = Vec :: new ( ) ;
1140- let mut ctrl_bases_nested = vec ! [ ] ;
1141- owner_rc. call_function_idx ( idx, & mut ret_pc_nested, & mut tmp_stack, & mut control_nested, & mut func_bases_nested, & mut ctrl_bases_nested) ?;
1142- for v in tmp_stack { stack. push ( v) ; }
1143- } else {
1144- return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
1145- }
1117+ RuntimeFunction :: ImportedWasm { runtime_sig, owner, function_index } => {
1118+ if let Some ( owner_rc) = owner. upgrade ( ) {
1119+ let n_params = runtime_sig. n_params ( ) as usize ;
1120+ let params_start = stack. len ( ) - n_params;
1121+ let mut tmp_stack: Vec < WasmValue > = Vec :: with_capacity ( n_params) ;
1122+ tmp_stack. extend_from_slice ( & stack[ params_start..( params_start + n_params) ] ) ;
1123+ stack. truncate ( params_start) ;
1124+ let mut control_nested: Vec < ControlFrame > = Vec :: new ( ) ;
1125+ let mut ret_pc_nested = 0usize ;
1126+ let mut func_bases_nested: Vec < usize > = Vec :: new ( ) ;
1127+ let mut ctrl_bases_nested = vec ! [ ] ;
1128+ owner_rc. call_function_idx ( function_index, & mut ret_pc_nested, & mut tmp_stack, & mut control_nested, & mut func_bases_nested, & mut ctrl_bases_nested) ?;
1129+ for v in tmp_stack { stack. push ( v) ; }
11461130 } else {
1147- pc = Self :: setup_wasm_function_call ( runtime_sig , pc_start , locals_count , stack , control , func_bases , ctrl_bases , pc ) ? ;
1131+ return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
11481132 }
11491133 }
1134+ RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
1135+ pc = Self :: setup_wasm_function_call ( runtime_sig, pc_start, locals_count, stack, control, func_bases, ctrl_bases, pc) ?;
1136+ }
11501137 RuntimeFunction :: Host { callback, runtime_sig } => {
11511138 let param_count = runtime_sig. n_params ( ) as usize ;
11521139 let params_start = stack. len ( ) - param_count;
@@ -1456,26 +1443,23 @@ impl Instance {
14561443 let return_pc: usize = 0 ;
14571444
14581445 match func {
1459- RuntimeFunction :: Wasm { runtime_sig, pc_start, locals_count, owner, function_index : owner_idx } => {
1460- // Execute in the correct instance: if this Function has an owner,
1461- // delegate invocation to that instance.
1462- if let ( Some ( owner_weak) , Some ( idx) ) = ( owner, owner_idx) {
1463- if let Some ( owner_rc) = owner_weak. upgrade ( ) {
1464- let mut owned_stack = Vec :: with_capacity ( 64 ) ;
1465- owned_stack. extend_from_slice ( args) ;
1466- let mut control: Vec < ControlFrame > = Vec :: new ( ) ;
1467- let mut return_pc: usize = 0 ;
1468- let mut func_bases: Vec < usize > = Vec :: new ( ) ;
1469- let mut ctrl_bases = vec ! [ ] ;
1470- owner_rc. call_function_idx ( * idx, & mut return_pc, & mut owned_stack, & mut control, & mut func_bases, & mut ctrl_bases) ?;
1471- return Ok ( owned_stack) ;
1472- } else {
1473- return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
1474- }
1446+ RuntimeFunction :: OwnedWasm { runtime_sig, pc_start, locals_count } => {
1447+ let mut ctrl_bases = Vec :: new ( ) ;
1448+ let pc = Self :: setup_wasm_function_call ( * runtime_sig, * pc_start, * locals_count, & mut stack, & mut control, & mut func_bases, & mut ctrl_bases, return_pc) ?;
1449+ self . interpret ( pc, & mut stack, & mut control, & mut func_bases, & mut ctrl_bases) ?;
1450+ }
1451+ RuntimeFunction :: ImportedWasm { owner, function_index, .. } => {
1452+ if let Some ( owner_rc) = owner. upgrade ( ) {
1453+ let mut owned_stack = Vec :: with_capacity ( 64 ) ;
1454+ owned_stack. extend_from_slice ( args) ;
1455+ let mut control: Vec < ControlFrame > = Vec :: new ( ) ;
1456+ let mut return_pc: usize = 0 ;
1457+ let mut func_bases: Vec < usize > = Vec :: new ( ) ;
1458+ let mut ctrl_bases = vec ! [ ] ;
1459+ owner_rc. call_function_idx ( * function_index, & mut return_pc, & mut owned_stack, & mut control, & mut func_bases, & mut ctrl_bases) ?;
1460+ return Ok ( owned_stack) ;
14751461 } else {
1476- let mut ctrl_bases = Vec :: new ( ) ;
1477- let pc = Self :: setup_wasm_function_call ( * runtime_sig, * pc_start, * locals_count, & mut stack, & mut control, & mut func_bases, & mut ctrl_bases, return_pc) ?;
1478- self . interpret ( pc, & mut stack, & mut control, & mut func_bases, & mut ctrl_bases) ?;
1462+ return Err ( Error :: Trap ( FUNC_NO_IMPL ) ) ;
14791463 }
14801464 }
14811465 RuntimeFunction :: Host { callback, .. } => {
0 commit comments