Browse Source

[PATCH 149/188] table index normalization

From ac123fcbd571f5cc7fbef5ded307d4f435ca5f0c Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Wed, 25 Mar 2020 17:31:09 -0400

git-svn-id: branches/wasm@46145 -
nickysn 5 years ago
parent
commit
eff566cc32
1 changed files with 58 additions and 37 deletions
  1. 58 37
      utils/wasmbin/wasmmodule.pas

+ 58 - 37
utils/wasmbin/wasmmodule.pas

@@ -960,60 +960,81 @@ var
   j   : integer;
   j   : integer;
   ci  : TWasmInstr;
   ci  : TWasmInstr;
   endNeed : Integer;
   endNeed : Integer;
+  lbl     : TStringList;
+  li      : Integer;
 const
 const
   ValidResTypes = [VALTYPE_NONE,VALTYPE_I32,VALTYPE_I64,VALTYPE_F32,VALTYPE_F64];
   ValidResTypes = [VALTYPE_NONE,VALTYPE_I32,VALTYPE_I64,VALTYPE_F32,VALTYPE_F64];
 begin
 begin
   Result := true;
   Result := true;
   endNeed := 1;
   endNeed := 1;
-  for i:=0 to l.Count-1 do begin
-    ci:=l[i];
-
-    if INST_FLAGS[ci.code].Param = ipResType then
-    begin
-      inc(endNeed);
-      if not (byte(ci.operandNum) in ValidResTypes) then
-        ci.operandNum := VALTYPE_NONE;
-    end;
+  lbl := TStringList.Create;
+  try
+    for i:=0 to l.Count-1 do begin
+      ci:=l[i];
 
 
-    case ci.code of
-      INST_local_get, INST_local_set, INST_local_tee:
+      if INST_FLAGS[ci.code].Param = ipResType then
       begin
       begin
-        if not Assigned(f) then begin
-          Result:=false;
-          Exit;
-        end;
+        inc(endNeed);
+        if not (byte(ci.operandNum) in ValidResTypes) then
+          ci.operandNum := VALTYPE_NONE;
 
 
-        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);
-            if j>=0 then inc(j, f.functype.ParamCount);
+        lbl.Add(ci.jumplabel);
+      end;
+
+      case ci.code of
+        INST_local_get, INST_local_set, INST_local_tee:
+        begin
+          if not Assigned(f) then begin
+            Result:=false;
+            Exit;
+          end;
+
+          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);
+              if j>=0 then inc(j, f.functype.ParamCount);
+            end;
+            ci.operandNum:=j;
           end;
           end;
-          ci.operandNum:=j;
         end;
         end;
-      end;
 
 
-      INST_call:
-      begin
-        if (ci.operandIdx<>'') and (ci.operandNum<0) then
-          ci.operandNum:=FindFunc(m,ci.operandIdx);
-      end;
+        INST_call:
+        begin
+          if (ci.operandIdx<>'') and (ci.operandNum<0) then
+            ci.operandNum:=FindFunc(m,ci.operandIdx);
+        end;
 
 
-      INST_call_indirect:
-      begin
-        if Assigned(ci.insttype) and (ci.insttype.typeNum<0) then
-          ci.insttype.typeNum:=RegisterFuncType(m, ci.insttype);
+        INST_call_indirect:
+        begin
+          if Assigned(ci.insttype) and (ci.insttype.typeNum<0) then
+            ci.insttype.typeNum:=RegisterFuncType(m, ci.insttype);
+        end;
+
+        INST_br, INST_br_if: begin
+          if ci.operandIdx<>'' then begin
+            li:=lbl.Count-1;
+            while (li>=0) and (lbl[li]<>ci.operandIdx) do
+              dec(li);
+            ci.operandNum:=(lbl.Count-1)-li;
+          end;
+        end;
+
+        INST_END: begin
+          dec(endNeed);
+          if lbl.Count>0 then lbl.Delete(lbl.Count-1);
+        end;
       end;
       end;
 
 
-      INST_END: dec(endNeed);
+      PopulateRelocData(m, ci);
     end;
     end;
 
 
-    PopulateRelocData(m, ci);
+    // adding end instruction
+    if checkEnd and (endNeed>0) then
+      l.AddInstr(INST_END);
+  finally
+    lbl.Free;
   end;
   end;
-
-  // adding end instruction
-  if checkEnd and (endNeed>0) then
-    l.AddInstr(INST_END);
 end;
 end;