@@ -135,7 +135,8 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
135135#ifndef OS_ENABLE_HW_BOUND_CHECK
136136 /* ---------- check ---------- */
137137 /* 1. shortcut if the memory size is 0 */
138- if (0 == cc -> cur_wasm_module -> memories [mem_idx ].init_page_count ) {
138+ if (cc -> cur_wasm_module -> memories != NULL
139+ && 0 == cc -> cur_wasm_module -> memories [mem_idx ].init_page_count ) {
139140 JitReg module_inst , cur_page_count ;
140141 uint32 cur_page_count_offset =
141142 (uint32 )offsetof(WASMModuleInstance , global_table_data .bytes )
@@ -176,6 +177,18 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
176177 return 0 ;
177178}
178179
180+ #define CHECK_ALIGNMENT (maddr , memory_data , offset1 ) \
181+ do { \
182+ GEN_INSN(ADD, maddr, memory_data, offset1); \
183+ JitReg align_mask = NEW_CONST(I64, ((uint64)1 << align) - 1); \
184+ JitReg AND_res = jit_cc_new_reg_I64(cc); \
185+ GEN_INSN(AND, AND_res, maddr, align_mask); \
186+ GEN_INSN(CMP, cc->cmp_reg, AND_res, NEW_CONST(I64, 0)); \
187+ if (!jit_emit_exception(cc, EXCE_UNALIGNED_ATOMIC, JIT_OP_BNE, \
188+ cc->cmp_reg, NULL)) \
189+ goto fail; \
190+ } while (0)
191+
179192bool
180193jit_compile_op_i32_load (JitCompContext * cc , uint32 align , uint32 offset ,
181194 uint32 bytes , bool sign , bool atomic )
@@ -779,13 +792,91 @@ bool
779792jit_compile_op_atomic_wait (JitCompContext * cc , uint8 op_type , uint32 align ,
780793 uint32 offset , uint32 bytes )
781794{
795+ bh_assert (op_type == VALUE_TYPE_I32 || op_type == VALUE_TYPE_I64 );
796+
797+ // Pop atomic.wait arguments
798+ JitReg timeout , expect , expect_64 , addr ;
799+ POP_I64 (timeout );
800+ if (op_type == VALUE_TYPE_I32 ) {
801+ POP_I32 (expect );
802+ expect_64 = jit_cc_new_reg_I64 (cc );
803+ GEN_INSN (I32TOI64 , expect_64 , expect );
804+ }
805+ else {
806+ POP_I64 (expect_64 );
807+ }
808+ POP_I32 (addr );
809+
810+ // Get referenced address and store it in `maddr`
811+ JitReg memory_data = get_memory_data_reg (cc -> jit_frame , 0 );
812+ JitReg offset1 = check_and_seek (cc , addr , offset , bytes );
813+ if (!offset1 )
814+ goto fail ;
815+ JitReg maddr = jit_cc_new_reg_I64 (cc );
816+ CHECK_ALIGNMENT (maddr , memory_data , offset1 );
817+
818+ // Prepare `wasm_runtime_atomic_wait` arguments
819+ JitReg res = jit_cc_new_reg_I32 (cc );
820+ JitReg args [5 ] = { 0 };
821+ args [0 ] = get_module_inst_reg (cc -> jit_frame );
822+ args [1 ] = maddr ;
823+ args [2 ] = expect_64 ;
824+ args [3 ] = timeout ;
825+ args [4 ] = NEW_CONST (I32 , false);
826+
827+ if (!jit_emit_callnative (cc , wasm_runtime_atomic_wait , res , args ,
828+ sizeof (args ) / sizeof (args [0 ])))
829+ goto fail ;
830+
831+ // Handle return code
832+ GEN_INSN (CMP , cc -> cmp_reg , res , NEW_CONST (I32 , -1 ));
833+ if (!jit_emit_exception (cc , EXCE_ALREADY_THROWN , JIT_OP_BEQ , cc -> cmp_reg ,
834+ NULL ))
835+ goto fail ;
836+
837+ PUSH_I32 (res );
838+ return true;
839+ fail :
782840 return false;
783841}
784842
785843bool
786844jit_compiler_op_atomic_notify (JitCompContext * cc , uint32 align , uint32 offset ,
787845 uint32 bytes )
788846{
847+ // Pop atomic.notify arguments
848+ JitReg notify_count , addr ;
849+ POP_I32 (notify_count );
850+ POP_I32 (addr );
851+
852+ // Get referenced address and store it in `maddr`
853+ JitReg memory_data = get_memory_data_reg (cc -> jit_frame , 0 );
854+ JitReg offset1 = check_and_seek (cc , addr , offset , bytes );
855+ if (!offset1 )
856+ goto fail ;
857+ JitReg maddr = jit_cc_new_reg_I64 (cc );
858+ CHECK_ALIGNMENT (maddr , memory_data , offset1 );
859+
860+ // Prepare `wasm_runtime_atomic_notify` arguments
861+ JitReg res = jit_cc_new_reg_I32 (cc );
862+ JitReg args [3 ] = { 0 };
863+ args [0 ] = get_module_inst_reg (cc -> jit_frame );
864+ args [1 ] = maddr ;
865+ args [2 ] = notify_count ;
866+
867+ if (!jit_emit_callnative (cc , wasm_runtime_atomic_notify , res , args ,
868+ sizeof (args ) / sizeof (args [0 ])))
869+ goto fail ;
870+
871+ // Handle return code
872+ GEN_INSN (CMP , cc -> cmp_reg , res , NEW_CONST (I32 , 0 ));
873+ if (!jit_emit_exception (cc , EXCE_ALREADY_THROWN , JIT_OP_BLTS , cc -> cmp_reg ,
874+ NULL ))
875+ goto fail ;
876+
877+ PUSH_I32 (res );
878+ return true;
879+ fail :
789880 return false;
790881}
791882#endif
0 commit comments