Browse Source

[PATCH 131/188] parsing for table inline element

From aded8a790e3830f32db312744a35c22003a2afd8 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Tue, 24 Mar 2020 15:47:48 -0400

git-svn-id: branches/wasm@46127 -
nickysn 5 years ago
parent
commit
5c9d1df31d
2 changed files with 77 additions and 3 deletions
  1. 36 1
      utils/wasmbin/wasmmodule.pas
  2. 41 2
      utils/wasmbin/watparser.pas

+ 36 - 1
utils/wasmbin/wasmmodule.pas

@@ -137,6 +137,8 @@ type
     funcCount : Integer;
     funcCount : Integer;
     funcs     : array of TWasmId;
     funcs     : array of TWasmId;
     function AddFunc(idx: integer): integer;
     function AddFunc(idx: integer): integer;
+    function AddFuncId(const idx: TWasmID): integer;
+    function AddOffset: TWasmInstrList;
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
   end;
   end;
@@ -168,6 +170,9 @@ type
     elemsType : Byte; // type of elements
     elemsType : Byte; // type of elements
     min       : LongWord;
     min       : LongWord;
     max       : LongWord;
     max       : LongWord;
+    elem      : TWasmElement;
+    function AddElem: TWasmElement;
+    destructor Destroy; override;
   end;
   end;
 
 
   { TWasmData }
   { TWasmData }
@@ -321,6 +326,21 @@ begin
   l.Clear;
   l.Clear;
 end;
 end;
 
 
+{ TWasmTable }
+
+function TWasmTable.AddElem: TWasmElement;
+begin
+  if not Assigned(elem) then
+    elem:= TWasmElement.Create;
+  Result := elem;
+end;
+
+destructor TWasmTable.Destroy;
+begin
+  elem.Free;
+  inherited Destroy;
+end;
+
 { TWasmData }
 { TWasmData }
 
 
 function TWasmData.StartOffset: TWasmInstrList;
 function TWasmData.StartOffset: TWasmInstrList;
@@ -339,16 +359,31 @@ end;
 { TWasmElement }
 { TWasmElement }
 
 
 function TWasmElement.AddFunc(idx: integer): integer;
 function TWasmElement.AddFunc(idx: integer): integer;
+var
+  w : TWasmId;
+begin
+  w.id:='';
+  w.idNum:=idx;
+  AddFuncId(w);
+end;
+
+function TWasmElement.AddFuncId(const idx: TWasmID): integer;
 begin
 begin
   if funcCount = length(funcs) then begin
   if funcCount = length(funcs) then begin
     if funcCount=0 then SetLength(funcs, 4)
     if funcCount=0 then SetLength(funcs, 4)
     else SetLength(funcs, funcCount*2);
     else SetLength(funcs, funcCount*2);
   end;
   end;
   Result:=funcCount;
   Result:=funcCount;
-  funcs[funcCount].idNum :=idx;
+  funcs[funcCount] := idx;
   inc(funcCount);
   inc(funcCount);
 end;
 end;
 
 
+function TWasmElement.AddOffset: TWasmInstrList;
+begin
+  if not Assigned(offset) then offset:=TWasmInstrList.Create;
+  Result := offset;
+end;
+
 constructor TWasmElement.Create;
 constructor TWasmElement.Create;
 begin
 begin
   inherited Create;
   inherited Create;

+ 41 - 2
utils/wasmbin/watparser.pas

@@ -494,12 +494,51 @@ begin
   sc.Next;
   sc.Next;
 end;
 end;
 
 
+// parseIdOffset - should only be used for elems declareted at module leve
+// if elems declared in a table, parseIdOffset should be set to false
+procedure ParseElem(sc: TWatScanner; dst: TWasmElement; parseIdOffset: Boolean);
+var
+  vid : TWasmId;
+begin
+  if sc.token = weElem then sc.Next;
+
+  if parseIdOffset then begin
+    if sc.token<>weIdent then
+      ErrorExpectButFound(sc, 'identifier');
+
+    dst.tableIdx := sc.resInt32;
+    sc.Next;
+
+    if (sc.token = weOpenBrace) then begin
+      ParseInstrList(sc, dst.AddOffset);
+      ConsumeToken(sc, weCloseBrace);
+    end;
+  end;
+
+  while sc.token in [weIdent, weNumber] do begin
+    ParseId(sc, vid);
+    dst.AddFuncId(vid);
+  end;
+  ConsumeToken(sc, weCloseBrace);
+end;
+
 procedure ParseTable(sc: TWatScanner; dst: TWasmTable);
 procedure ParseTable(sc: TWatScanner; dst: TWasmTable);
 begin
 begin
-  sc.Next;
-  ParseId(sc, dst.id);
+  if sc.token = weTable then sc.Next;
+
+  // table ident can be missing? If missing, then it's zero
+  if (sc.token in [weIdent, weNumber]) then
+    ParseId(sc, dst.id);
+
   ConsumeToken(sc, weFuncRef);
   ConsumeToken(sc, weFuncRef);
   dst.elemsType := elem_type;
   dst.elemsType := elem_type;
+
+  // consuming elements
+  if (sc.token = weOpenBrace) then begin
+    sc.Next;
+    ParseElem(sc, dst.AddElem, false);
+  end;
+
   ConsumeToken(sc, weCloseBrace);
   ConsumeToken(sc, weCloseBrace);
 end;
 end;