瀏覽代碼

+ 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