@@ -510,7 +510,7 @@ jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
510510 /* Convert bool to uint32 */
511511 GEN_INSN (AND , grow_res , grow_res , NEW_CONST (I32 , 0xFF ));
512512
513- /* Check if enlarge memory success */
513+ /* return different values according to memory.grow result */
514514 res = jit_cc_new_reg_I32 (cc );
515515 GEN_INSN (CMP , cc -> cmp_reg , grow_res , NEW_CONST (I32 , 0 ));
516516 GEN_INSN (SELECTNE , res , cc -> cmp_reg , prev_page_count ,
@@ -526,27 +526,204 @@ jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
526526}
527527
528528#if WASM_ENABLE_BULK_MEMORY != 0
529+ static int
530+ wasm_init_memory (WASMModuleInstance * inst , uint32 mem_idx , uint32 seg_idx ,
531+ uint32 len , uint32 mem_offset , uint32 data_offset )
532+ {
533+ WASMMemoryInstance * mem_inst ;
534+ WASMDataSeg * data_segment ;
535+ uint32 mem_size ;
536+ uint8 * mem_addr , * data_addr ;
537+
538+ /* if d + n > the length of mem.data */
539+ mem_inst = inst -> memories [mem_idx ];
540+ mem_size = mem_inst -> cur_page_count * mem_inst -> num_bytes_per_page ;
541+ if (mem_size < mem_offset || mem_size - mem_offset < len )
542+ goto out_of_bounds ;
543+
544+ /* if s + n > the length of data.data */
545+ bh_assert (seg_idx < inst -> module -> data_seg_count );
546+ data_segment = inst -> module -> data_segments [seg_idx ];
547+ if (data_segment -> data_length < data_offset
548+ || data_segment -> data_length - data_offset < len )
549+ goto out_of_bounds ;
550+
551+ mem_addr = mem_inst -> memory_data + mem_offset ;
552+ data_addr = data_segment -> data + data_offset ;
553+ bh_memcpy_s (mem_addr , mem_size - mem_offset , data_addr , len );
554+
555+ return 0 ;
556+ out_of_bounds :
557+ wasm_set_exception (inst , "out of bounds memory access" );
558+ return -1 ;
559+ }
560+
529561bool
530- jit_compile_op_memory_init (JitCompContext * cc , uint32 seg_index )
562+ jit_compile_op_memory_init (JitCompContext * cc , uint32 mem_idx , uint32 seg_idx )
531563{
564+ JitReg len , mem_offset , data_offset , res ;
565+ JitReg args [6 ] = { 0 };
566+
567+ POP_I32 (len );
568+ POP_I32 (data_offset );
569+ POP_I32 (mem_offset );
570+
571+ res = jit_cc_new_reg_I32 (cc );
572+ args [0 ] = get_module_inst_reg (cc -> jit_frame );
573+ args [1 ] = NEW_CONST (I32 , mem_idx );
574+ args [2 ] = NEW_CONST (I32 , seg_idx );
575+ args [3 ] = len ;
576+ args [4 ] = mem_offset ;
577+ args [5 ] = data_offset ;
578+
579+ if (!jit_emit_callnative (cc , wasm_init_memory , res , args ,
580+ sizeof (args ) / sizeof (args [0 ])))
581+ goto fail ;
582+
583+ GEN_INSN (CMP , cc -> cmp_reg , res , NEW_CONST (I32 , 0 ));
584+ if (!jit_emit_exception (cc , EXCE_ALREADY_THROWN , JIT_OP_BLTS , cc -> cmp_reg ,
585+ NULL ))
586+ goto fail ;
587+
588+ return true;
589+ fail :
532590 return false;
533591}
534592
535593bool
536- jit_compile_op_data_drop (JitCompContext * cc , uint32 seg_index )
594+ jit_compile_op_data_drop (JitCompContext * cc , uint32 seg_idx )
537595{
538- return false;
596+ JitReg module = get_module_reg (cc -> jit_frame );
597+ JitReg data_segments = jit_cc_new_reg_ptr (cc );
598+ JitReg data_segment = jit_cc_new_reg_ptr (cc );
599+
600+ GEN_INSN (LDPTR , data_segments , module ,
601+ NEW_CONST (I32 , offsetof(WASMModule , data_segments )));
602+ GEN_INSN (LDPTR , data_segment , data_segments ,
603+ NEW_CONST (I32 , seg_idx * sizeof (WASMDataSeg * )));
604+ GEN_INSN (STI32 , NEW_CONST (I32 , 0 ), data_segment ,
605+ NEW_CONST (I32 , offsetof(WASMDataSeg , data_length )));
606+
607+ return true;
608+ }
609+
610+ static int
611+ wasm_copy_memory (WASMModuleInstance * inst , uint32 src_mem_idx ,
612+ uint32 dst_mem_idx , uint32 len , uint32 src_offset ,
613+ uint32 dst_offset )
614+ {
615+ WASMMemoryInstance * src_mem , * dst_mem ;
616+ uint32 src_mem_size , dst_mem_size ;
617+ uint8 * src_addr , * dst_addr ;
618+
619+ src_mem = inst -> memories [src_mem_idx ];
620+ dst_mem = inst -> memories [dst_mem_idx ];
621+ src_mem_size = src_mem -> cur_page_count * src_mem -> num_bytes_per_page ;
622+ dst_mem_size = dst_mem -> cur_page_count * dst_mem -> num_bytes_per_page ;
623+
624+ /* if s + n > the length of mem.data */
625+ if (src_mem_size < src_offset || src_mem_size - src_offset < len )
626+ goto out_of_bounds ;
627+
628+ /* if d + n > the length of mem.data */
629+ if (dst_mem_size < dst_offset || dst_mem_size - dst_offset < len )
630+ goto out_of_bounds ;
631+
632+ src_addr = src_mem -> memory_data + src_offset ;
633+ dst_addr = dst_mem -> memory_data + dst_offset ;
634+ /* allowing the destination and source to overlap */
635+ bh_memmove_s (dst_addr , dst_mem_size - dst_offset , src_addr , len );
636+
637+ return 0 ;
638+ out_of_bounds :
639+ wasm_set_exception (inst , "out of bounds memory access" );
640+ return -1 ;
539641}
540642
541643bool
542- jit_compile_op_memory_copy (JitCompContext * cc )
644+ jit_compile_op_memory_copy (JitCompContext * cc , uint32 src_mem_idx ,
645+ uint32 dst_mem_idx )
543646{
647+ JitReg len , src , dst , res ;
648+ JitReg args [6 ] = { 0 };
649+
650+ POP_I32 (len );
651+ POP_I32 (src );
652+ POP_I32 (dst );
653+
654+ res = jit_cc_new_reg_I32 (cc );
655+ args [0 ] = get_module_inst_reg (cc -> jit_frame );
656+ args [1 ] = NEW_CONST (I32 , src_mem_idx );
657+ args [2 ] = NEW_CONST (I32 , dst_mem_idx );
658+ args [3 ] = len ;
659+ args [4 ] = src ;
660+ args [5 ] = dst ;
661+
662+ if (!jit_emit_callnative (cc , wasm_copy_memory , res , args ,
663+ sizeof (args ) / sizeof (args [0 ])))
664+ goto fail ;
665+
666+ GEN_INSN (CMP , cc -> cmp_reg , res , NEW_CONST (I32 , 0 ));
667+ if (!jit_emit_exception (cc , EXCE_ALREADY_THROWN , JIT_OP_BLTS , cc -> cmp_reg ,
668+ NULL ))
669+ goto fail ;
670+
671+ return true;
672+ fail :
544673 return false;
545674}
546675
676+ static int
677+ wasm_fill_memory (WASMModuleInstance * inst , uint32 mem_idx , uint32 len ,
678+ uint32 val , uint32 dst )
679+ {
680+ WASMMemoryInstance * mem_inst ;
681+ uint32 mem_size ;
682+ uint8 * dst_addr ;
683+
684+ mem_inst = inst -> memories [mem_idx ];
685+ mem_size = mem_inst -> cur_page_count * mem_inst -> num_bytes_per_page ;
686+
687+ if (mem_size < dst || mem_size - dst < len )
688+ goto out_of_bounds ;
689+
690+ dst_addr = mem_inst -> memory_data + dst ;
691+ memset (dst_addr , val , len );
692+
693+ return 0 ;
694+ out_of_bounds :
695+ wasm_set_exception (inst , "out of bounds memory access" );
696+ return -1 ;
697+ }
698+
547699bool
548- jit_compile_op_memory_fill (JitCompContext * cc )
700+ jit_compile_op_memory_fill (JitCompContext * cc , uint32 mem_idx )
549701{
702+ JitReg res , len , val , dst ;
703+ JitReg args [5 ] = { 0 };
704+
705+ POP_I32 (len );
706+ POP_I32 (val );
707+ POP_I32 (dst );
708+
709+ res = jit_cc_new_reg_I32 (cc );
710+ args [0 ] = get_module_inst_reg (cc -> jit_frame );
711+ args [1 ] = NEW_CONST (I32 , mem_idx );
712+ args [2 ] = len ;
713+ args [3 ] = val ;
714+ args [4 ] = dst ;
715+
716+ if (!jit_emit_callnative (cc , wasm_fill_memory , res , args ,
717+ sizeof (args ) / sizeof (args [0 ])))
718+ goto fail ;
719+
720+ GEN_INSN (CMP , cc -> cmp_reg , res , NEW_CONST (I32 , 0 ));
721+ if (!jit_emit_exception (cc , EXCE_ALREADY_THROWN , JIT_OP_BLTS , cc -> cmp_reg ,
722+ NULL ))
723+ goto fail ;
724+
725+ return true;
726+ fail :
550727 return false;
551728}
552729#endif
0 commit comments