소스 검색

+ workaround for WebAssembly treating the stack parameter of the store and load
instructions as unsigned. This caused an 'out of bounds memory access' trap
when accessing arrays with negative offset index, e.g. in test/cg/tvec.pp

Nikolay Nikolov 3 년 전
부모
커밋
5adec3ca98
1개의 변경된 파일60개의 추가작업 그리고 4개의 파일을 삭제
  1. 60 4
      compiler/wasm32/hlcgcpu.pas

+ 60 - 4
compiler/wasm32/hlcgcpu.pas

@@ -1072,12 +1072,26 @@ implementation
           incstack(list,1);
           list.Concat(taicpu.op_none(a_i32_add));
           decstack(list,1);
+          if assigned(ref.symbol) then
+            begin
+              list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
+              incstack(list,1);
+              list.Concat(taicpu.op_none(a_i32_add));
+              decstack(list,1);
+            end;
           if ref.offset<0 then
             begin
               list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
               incstack(list,1);
               list.Concat(taicpu.op_none(a_i32_sub));
               decstack(list,1);
+            end
+          else if ref.offset>0 then
+            begin
+              list.Concat(taicpu.op_const(a_i32_const,ref.offset));
+              incstack(list,1);
+              list.Concat(taicpu.op_none(a_i32_add));
+              decstack(list,1);
             end;
           if dup then
             begin
@@ -1087,18 +1101,32 @@ implementation
               incstack(list,1);
               list.Concat(taicpu.op_none(a_i32_add));
               decstack(list,1);
+              if assigned(ref.symbol) then
+                begin
+                  list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
+                  incstack(list,1);
+                  list.Concat(taicpu.op_none(a_i32_add));
+                  decstack(list,1);
+                end;
               if ref.offset<0 then
                 begin
                   list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
                   incstack(list,1);
                   list.Concat(taicpu.op_none(a_i32_sub));
                   decstack(list,1);
+                end
+              else if ref.offset>0 then
+                begin
+                  list.Concat(taicpu.op_const(a_i32_const,ref.offset));
+                  incstack(list,1);
+                  list.Concat(taicpu.op_none(a_i32_add));
+                  decstack(list,1);
                 end;
             end;
           ref.base:=NR_NO;
           ref.index:=NR_NO;
-          if ref.offset<0 then
-            ref.offset:=0;
+          ref.offset:=0;
+          ref.symbol:=nil;
           result:=1;
         end
       else if (ref.base<>NR_NO) then
@@ -1107,26 +1135,54 @@ implementation
             begin
               { regular field -> load self on the stack }
               a_load_reg_stack(list,voidpointertype,ref.base);
+              if assigned(ref.symbol) then
+                begin
+                  list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
+                  incstack(list,1);
+                  list.Concat(taicpu.op_none(a_i32_add));
+                  decstack(list,1);
+                end;
               if ref.offset<0 then
                 begin
                   list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
                   incstack(list,1);
                   list.Concat(taicpu.op_none(a_i32_sub));
                   decstack(list,1);
+                end
+              else if ref.offset>0 then
+                begin
+                  list.Concat(taicpu.op_const(a_i32_const,ref.offset));
+                  incstack(list,1);
+                  list.Concat(taicpu.op_none(a_i32_add));
+                  decstack(list,1);
                 end;
               if dup then
                 begin
                   a_load_reg_stack(list,voidpointertype,ref.base);
+                  if assigned(ref.symbol) then
+                    begin
+                      list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
+                      incstack(list,1);
+                      list.Concat(taicpu.op_none(a_i32_add));
+                      decstack(list,1);
+                    end;
                   if ref.offset<0 then
                     begin
                       list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
                       incstack(list,1);
                       list.Concat(taicpu.op_none(a_i32_sub));
                       decstack(list,1);
+                    end
+                  else if ref.offset>0 then
+                    begin
+                      list.Concat(taicpu.op_const(a_i32_const,ref.offset));
+                      incstack(list,1);
+                      list.Concat(taicpu.op_none(a_i32_add));
+                      decstack(list,1);
                     end;
                 end;
-              if ref.offset<0 then
-                ref.offset:=0;
+              ref.offset:=0;
+              ref.symbol:=nil;
               ref.base:=NR_NO;
               result:=1;
             end