Browse Source

* fixed i32.const with large unsigned 32-bit const parameter (>2GB)

Nikolay Nikolov 3 years ago
parent
commit
cb3ac37fb3
1 changed files with 52 additions and 14 deletions
  1. 52 14
      compiler/wasm32/aasmcpu.pas

+ 52 - 14
compiler/wasm32/aasmcpu.pas

@@ -532,7 +532,29 @@ uses
           a_memory_size,
           a_memory_size,
           a_memory_grow:
           a_memory_grow:
             result:=2;
             result:=2;
-          a_i32_const,
+          a_i32_const:
+            begin
+              if ops<>1 then
+                internalerror(2021092001);
+              with oper[0]^ do
+                case typ of
+                  top_ref:
+                    begin
+                      if assigned(ref^.symbol) then
+                        result:=6
+                      else
+                        begin
+                          if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
+                            internalerror(2021092018);
+                          result:=1+SlebSize(longint(ref^.offset));
+                        end;
+                    end;
+                  top_const:
+                    result:=1+SlebSize(longint(val));
+                  else
+                    internalerror(2021092615);
+                end;
+            end;
           a_i64_const:
           a_i64_const:
             begin
             begin
               if ops<>1 then
               if ops<>1 then
@@ -547,11 +569,11 @@ uses
                         begin
                         begin
                           if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
                           if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
                             internalerror(2021092018);
                             internalerror(2021092018);
-                          result:=1+SlebSize(ref^.offset);
+                          result:=1+SlebSize(int64(ref^.offset));
                         end;
                         end;
                     end;
                     end;
                   top_const:
                   top_const:
-                    result:=1+SlebSize(val);
+                    result:=1+SlebSize(int64(val));
                   else
                   else
                     internalerror(2021092615);
                     internalerror(2021092615);
                 end;
                 end;
@@ -1086,17 +1108,33 @@ uses
             WriteByte($0B);
             WriteByte($0B);
           a_catch_all:
           a_catch_all:
             WriteByte($19);
             WriteByte($19);
-          a_i32_const,
+          a_i32_const:
+            begin
+              WriteByte($41);
+              if ops<>1 then
+                internalerror(2021092001);
+              with oper[0]^ do
+                case typ of
+                  top_ref:
+                    begin
+                      if assigned(ref^.symbol) then
+                        objdata.writeReloc(ref^.offset,5,ObjData.symbolref(ref^.symbol),RELOC_MEMORY_ADDR_OR_TABLE_INDEX_SLEB)
+                      else
+                        begin
+                          if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
+                            internalerror(2021092018);
+                          WriteSleb(longint(ref^.offset));
+                        end;
+                    end;
+                  top_const:
+                    WriteSleb(longint(val));
+                  else
+                    internalerror(2021092615);
+                end;
+            end;
           a_i64_const:
           a_i64_const:
             begin
             begin
-              case opcode of
-                a_i32_const:
-                  WriteByte($41);
-                a_i64_const:
-                  WriteByte($42);
-                else
-                  internalerror(2021092002);
-              end;
+              WriteByte($42);
               if ops<>1 then
               if ops<>1 then
                 internalerror(2021092001);
                 internalerror(2021092001);
               with oper[0]^ do
               with oper[0]^ do
@@ -1109,11 +1147,11 @@ uses
                         begin
                         begin
                           if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
                           if assigned(ref^.symbol) or (ref^.base<>NR_NO) or (ref^.index<>NR_NO) then
                             internalerror(2021092018);
                             internalerror(2021092018);
-                          WriteSleb(ref^.offset);
+                          WriteSleb(int64(ref^.offset));
                         end;
                         end;
                     end;
                     end;
                   top_const:
                   top_const:
-                    WriteSleb(val);
+                    WriteSleb(int64(val));
                   else
                   else
                     internalerror(2021092615);
                     internalerror(2021092615);
                 end;
                 end;