Browse Source

[PATCH 099/188] update call indirect parsing and binary writing

From 381db5737ad19fe149ad352e732a8af8917f1ae7 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Tue, 17 Mar 2020 09:21:35 -0400

git-svn-id: branches/wasm@46095 -
nickysn 5 years ago
parent
commit
0767d971ab
3 changed files with 25 additions and 5 deletions
  1. 19 1
      utils/wasmbin/wasmbinwriter.pas
  2. 2 3
      utils/wasmbin/wasmmodule.pas
  3. 4 1
      utils/wasmbin/watparser.pas

+ 19 - 1
utils/wasmbin/wasmbinwriter.pas

@@ -520,7 +520,7 @@ begin
           idx := FindFunc(module, ci.operandText);
           AddReloc(INST_RELOC_FLAGS[ci.code].relocType, dst.Position+ofsAddition, idx);
           //todo: there's no need
-          WriteU32(dst, LongWord(idx));
+          WriteRelocU32(LongWord(idx));
         end else
           WriteI32Operand(dst, ci.operandText);
       end;
@@ -529,12 +529,30 @@ begin
 
 
       ipLeb:
+      begin
         if INST_RELOC_FLAGS[ci.code].doReloc then begin
           AddReloc(INST_RELOC_FLAGS[ci.code].relocType, dst.Position+ofsAddition, ci.operandNum);
           WriteRelocU32(ci.operandNum)
         end
         else
           WriteU32(dst, ci.operandNum);
+      end;
+
+      ipCallType:
+      begin
+        if Assigned(ci.insttype) then begin
+          if INST_RELOC_FLAGS[ci.code].doReloc then begin
+            AddReloc(INST_RELOC_FLAGS[ci.code].relocType, dst.Position+ofsAddition, ci.insttype.typeNum);
+            WriteRelocU32(ci.insttype.typeNum);
+          end
+          else
+            WriteU32(dst, ci.insttype.typeNum);
+        end else
+          WriteU32(dst, LongWord(-1)); // this is an error.
+
+        // table index reference
+        WriteU32(dst, ci.operandNum);
+      end;
     end;
   end;
 end;

+ 2 - 3
utils/wasmbin/wasmmodule.pas

@@ -68,7 +68,7 @@ type
   TWasmInstr = class(TObject)
     code        : byte;
     operandIdx  : string;
-    operandNum  : integer;
+    operandNum  : integer;    // for call_indirect this is table index
     operandText : string;
     insttype : TWasmFuncType; // used by call_indirect only
     function addInstType: TWasmFuncType;
@@ -655,11 +655,10 @@ var
 begin
   for i:=0 to l.Count-1 do begin
     ci:=l[i];
-    if ci.operandNum>=0 then Continue;
     case ci.code of
       INST_local_get, INST_local_set, INST_local_tee:
       begin
-        if ci.operandIdx<>'' then begin
+        if (ci.operandIdx<>'') and (ci.operandNum<0) then begin
           j:=FindParam(f.functype.params, ci.operandIdx);
           if j<0 then begin
             j:=FindParam(f.locals, ci.operandIdx);

+ 4 - 1
utils/wasmbin/watparser.pas

@@ -250,10 +250,13 @@ begin
 
       ipCallType:
       begin
-        //writeln('token type=',sc.token);
+        // call_indirect operator consists of 2 parameters
+        //  1 - type call
+        //  2 - table reference index. Which should always be zero.
         ConsumeToken(sc, weOpenBrace);
         ft := ci.addInstType;
         ParseFuncParamResult(sc, ft);
+        ci.operandNum := 0; // table reference index
       end;
 
       //ip2Leb,  // memory arguments, ask for offset + align