@@ -282,21 +282,10 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
282
282
}
283
283
284
284
#[ cfg( feature = "threads" ) ]
285
- fn get_memory_atomic_wait (
286
- & mut self ,
287
- func : & mut Function ,
288
- memory_index : MemoryIndex ,
289
- ty : ir:: Type ,
290
- ) -> ( ir:: FuncRef , usize ) {
285
+ fn get_memory_atomic_wait ( & mut self , func : & mut Function , ty : ir:: Type ) -> ir:: FuncRef {
291
286
match ty {
292
- I32 => (
293
- self . builtin_functions . memory_atomic_wait32 ( func) ,
294
- memory_index. index ( ) ,
295
- ) ,
296
- I64 => (
297
- self . builtin_functions . memory_atomic_wait64 ( func) ,
298
- memory_index. index ( ) ,
299
- ) ,
287
+ I32 => self . builtin_functions . memory_atomic_wait32 ( func) ,
288
+ I64 => self . builtin_functions . memory_atomic_wait64 ( func) ,
300
289
x => panic ! ( "get_memory_atomic_wait unsupported type: {x:?}" ) ,
301
290
}
302
291
}
@@ -2744,6 +2733,45 @@ impl FuncEnvironment<'_> {
2744
2733
Ok ( ( ) )
2745
2734
}
2746
2735
2736
+ /// Returns two `ir::Value`s, the first of which is the vmctx for the memory
2737
+ /// `index` and the second of which is the `DefinedMemoryIndex` for `index`.
2738
+ ///
2739
+ /// Handles internally whether `index` is an imported memory or not.
2740
+ fn memory_vmctx_and_defined_index (
2741
+ & mut self ,
2742
+ pos : & mut FuncCursor ,
2743
+ index : MemoryIndex ,
2744
+ ) -> ( ir:: Value , ir:: Value ) {
2745
+ let cur_vmctx = self . vmctx_val ( pos) ;
2746
+ match self . module . defined_memory_index ( index) {
2747
+ // This is a defined memory, so the vmctx is our own and the defined
2748
+ // index is `index` here.
2749
+ Some ( index) => ( cur_vmctx, pos. ins ( ) . iconst ( I32 , i64:: from ( index. as_u32 ( ) ) ) ) ,
2750
+
2751
+ // This is an imported memory, so load the vmctx/defined index from
2752
+ // the import definition itself.
2753
+ None => {
2754
+ let vmimport = self . offsets . vmctx_vmmemory_import ( index) ;
2755
+
2756
+ let vmctx = pos. ins ( ) . load (
2757
+ self . isa . pointer_type ( ) ,
2758
+ ir:: MemFlags :: trusted ( ) ,
2759
+ cur_vmctx,
2760
+ i32:: try_from ( vmimport + u32:: from ( self . offsets . vmmemory_import_vmctx ( ) ) )
2761
+ . unwrap ( ) ,
2762
+ ) ;
2763
+ let index = pos. ins ( ) . load (
2764
+ ir:: types:: I32 ,
2765
+ ir:: MemFlags :: trusted ( ) ,
2766
+ cur_vmctx,
2767
+ i32:: try_from ( vmimport + u32:: from ( self . offsets . vmmemory_import_index ( ) ) )
2768
+ . unwrap ( ) ,
2769
+ ) ;
2770
+ ( vmctx, index)
2771
+ }
2772
+ }
2773
+ }
2774
+
2747
2775
pub fn translate_memory_grow (
2748
2776
& mut self ,
2749
2777
builder : & mut FunctionBuilder < ' _ > ,
@@ -2753,14 +2781,15 @@ impl FuncEnvironment<'_> {
2753
2781
) -> WasmResult < ir:: Value > {
2754
2782
let mut pos = builder. cursor ( ) ;
2755
2783
let memory_grow = self . builtin_functions . memory_grow ( & mut pos. func ) ;
2756
- let index_arg = index. index ( ) ;
2757
2784
2758
- let memory_index = pos . ins ( ) . iconst ( I32 , index_arg as i64 ) ;
2759
- let vmctx = self . vmctx_val ( & mut pos) ;
2785
+ let ( memory_vmctx , defined_memory_index ) =
2786
+ self . memory_vmctx_and_defined_index ( & mut pos, index ) ;
2760
2787
2761
2788
let index_type = self . memory ( index) . idx_type ;
2762
2789
let val = self . cast_index_to_i64 ( & mut pos, val, index_type) ;
2763
- let call_inst = pos. ins ( ) . call ( memory_grow, & [ vmctx, val, memory_index] ) ;
2790
+ let call_inst = pos
2791
+ . ins ( )
2792
+ . call ( memory_grow, & [ memory_vmctx, val, defined_memory_index] ) ;
2764
2793
let result = * pos. func . dfg . inst_results ( call_inst) . first ( ) . unwrap ( ) ;
2765
2794
let single_byte_pages = match self . memory ( index) . page_size_log2 {
2766
2795
16 => false ,
@@ -2910,12 +2939,13 @@ impl FuncEnvironment<'_> {
2910
2939
let memory_fill = self . builtin_functions . memory_fill ( & mut pos. func ) ;
2911
2940
let dst = self . cast_index_to_i64 ( & mut pos, dst, self . memory ( memory_index) . idx_type ) ;
2912
2941
let len = self . cast_index_to_i64 ( & mut pos, len, self . memory ( memory_index) . idx_type ) ;
2913
- let memory_index_arg = pos. ins ( ) . iconst ( I32 , i64:: from ( memory_index. as_u32 ( ) ) ) ;
2914
-
2915
- let vmctx = self . vmctx_val ( & mut pos) ;
2942
+ let ( memory_vmctx, defined_memory_index) =
2943
+ self . memory_vmctx_and_defined_index ( & mut pos, memory_index) ;
2916
2944
2917
- pos. ins ( )
2918
- . call ( memory_fill, & [ vmctx, memory_index_arg, dst, val, len] ) ;
2945
+ pos. ins ( ) . call (
2946
+ memory_fill,
2947
+ & [ memory_vmctx, defined_memory_index, dst, val, len] ,
2948
+ ) ;
2919
2949
2920
2950
Ok ( ( ) )
2921
2951
}
@@ -3056,16 +3086,14 @@ impl FuncEnvironment<'_> {
3056
3086
let mut pos = builder. cursor ( ) ;
3057
3087
let addr = self . cast_index_to_i64 ( & mut pos, addr, self . memory ( memory_index) . idx_type ) ;
3058
3088
let implied_ty = pos. func . dfg . value_type ( expected) ;
3059
- let ( wait_func, memory_index) =
3060
- self . get_memory_atomic_wait ( & mut pos. func , memory_index, implied_ty) ;
3061
-
3062
- let memory_index_arg = pos. ins ( ) . iconst ( I32 , memory_index as i64 ) ;
3089
+ let wait_func = self . get_memory_atomic_wait ( & mut pos. func , implied_ty) ;
3063
3090
3064
- let vmctx = self . vmctx_val ( & mut pos) ;
3091
+ let ( memory_vmctx, defined_memory_index) =
3092
+ self . memory_vmctx_and_defined_index ( & mut pos, memory_index) ;
3065
3093
3066
3094
let call_inst = pos. ins ( ) . call (
3067
3095
wait_func,
3068
- & [ vmctx , memory_index_arg , addr, expected, timeout] ,
3096
+ & [ memory_vmctx , defined_memory_index , addr, expected, timeout] ,
3069
3097
) ;
3070
3098
let ret = pos. func . dfg . inst_results ( call_inst) [ 0 ] ;
3071
3099
Ok ( builder. ins ( ) . ireduce ( ir:: types:: I32 , ret) )
@@ -3093,11 +3121,12 @@ impl FuncEnvironment<'_> {
3093
3121
let addr = self . cast_index_to_i64 ( & mut pos, addr, self . memory ( memory_index) . idx_type ) ;
3094
3122
let atomic_notify = self . builtin_functions . memory_atomic_notify ( & mut pos. func ) ;
3095
3123
3096
- let memory_index_arg = pos. ins ( ) . iconst ( I32 , memory_index. index ( ) as i64 ) ;
3097
- let vmctx = self . vmctx_val ( & mut pos) ;
3098
- let call_inst = pos
3099
- . ins ( )
3100
- . call ( atomic_notify, & [ vmctx, memory_index_arg, addr, count] ) ;
3124
+ let ( memory_vmctx, defined_memory_index) =
3125
+ self . memory_vmctx_and_defined_index ( & mut pos, memory_index) ;
3126
+ let call_inst = pos. ins ( ) . call (
3127
+ atomic_notify,
3128
+ & [ memory_vmctx, defined_memory_index, addr, count] ,
3129
+ ) ;
3101
3130
let ret = pos. func . dfg . inst_results ( call_inst) [ 0 ] ;
3102
3131
Ok ( builder. ins ( ) . ireduce ( ir:: types:: I32 , ret) )
3103
3132
}
0 commit comments