Browse Source

[PATCH 044/188] export section parsing

From 3b23f9480a31b7f65580d4cd731283456b28be75 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Wed, 20 Nov 2019 14:14:21 -0500

git-svn-id: branches/wasm@46040 -
nickysn 5 years ago
parent
commit
d47696380e
2 changed files with 137 additions and 66 deletions
  1. 134 63
      utils/wasmbin/watparser.pas
  2. 3 3
      utils/wasmbin/watscanner.pas

+ 134 - 63
utils/wasmbin/watparser.pas

@@ -5,7 +5,7 @@ unit watparser;
 interface
 interface
 
 
 uses
 uses
-  SysUtils, Classes, wasmtext, wasmmodule, wasmbin, watscanner;
+  SysUtils, Classes, wasmtext, wasmmodule, watscanner, wasmbincode, wasmbin;
 
 
 type
 type
   TParseResult = record
   TParseResult = record
@@ -17,7 +17,7 @@ type
 
 
 const
 const
   TokenStr : array[TWatToken] of string = (
   TokenStr : array[TWatToken] of string = (
-     'uknown', 'end of file', 'error',
+     'uknown', 'error',
      'index',
      'index',
      'string', 'number', '(', ')',
      'string', 'number', '(', ')',
      'linksymbol',
      'linksymbol',
@@ -57,11 +57,6 @@ begin
   raise EParserError.Create(errMsg, sc.ofs);
   raise EParserError.Create(errMsg, sc.ofs);
 end;
 end;
 
 
-procedure ErrorUnexpected(sc: TWatScanner; const tokenstr: string = '');
-begin
-  ParseError(sc, 'unexpected '+tokenstr);
-end;
-
 procedure ErrorExpectButFound(sc: TWatScanner; const expected: string; const butfound: string  =''); overload;
 procedure ErrorExpectButFound(sc: TWatScanner; const expected: string; const butfound: string  =''); overload;
 var
 var
   r : string;
   r : string;
@@ -79,12 +74,18 @@ end;
 procedure ConsumeAnyOpenToken(sc: TWatScanner; out tk: TWatToken;
 procedure ConsumeAnyOpenToken(sc: TWatScanner; out tk: TWatToken;
   out hadOpenBrace: Boolean); overload;
   out hadOpenBrace: Boolean); overload;
 begin
 begin
-  sc.Next;
   hadOpenBrace := sc.token = weOpenBrace;
   hadOpenBrace := sc.token = weOpenBrace;
   if hadOpenBrace then sc.Next;
   if hadOpenBrace then sc.Next;
   tk:=sc.token;
   tk:=sc.token;
 end;
 end;
 
 
+procedure ConsumeAnyOpenToken(sc: TWatScanner); overload;
+var
+  tk: TWatToken;
+  op: Boolean;
+begin
+  ConsumeAnyOpenToken(sc, tk, op);
+end;
 
 
 procedure ConsumeAnyOpenToken(sc: TWatScanner; out tk: TWatToken); overload;
 procedure ConsumeAnyOpenToken(sc: TWatScanner; out tk: TWatToken); overload;
 var
 var
@@ -124,7 +125,7 @@ begin
   end;
   end;
 
 
   case sc.token of
   case sc.token of
-    weNumber: num:=sc.GetInt32;
+    weNumber: num:=sc.resInt32;
     weIdent: id:=sc.resText;
     weIdent: id:=sc.resText;
   else
   else
     ErrorExpectButFound(sc, 'index', TokenStr[sc.token]);
     ErrorExpectButFound(sc, 'index', TokenStr[sc.token]);
@@ -167,6 +168,48 @@ begin
     ConsumeToken(sc, weCloseBrace);
     ConsumeToken(sc, weCloseBrace);
 end;
 end;
 
 
+procedure ParseNumOrIdx(sc: TWatScanner; out num: integer; out idx: string);
+begin
+  if sc.token = weIdent then begin
+    idx := sc.resText;
+    num := -1;
+  end else if sc.token = weNumber then begin
+    idx := '';
+    num := sc.resInt32;
+  end else
+    ErrorExpectButFound(sc, 'number');
+  sc.Next;
+end;
+
+procedure ParseInstrList(sc: TWatScanner; dst: TWasmInstrList);
+var
+  ci  : TWasmInstr;
+begin
+  while sc.token=weInstr do begin
+    sc.Next;
+    ci := dst.AddInstr(sc.instrCode);
+    case INST_FLAGS[ci.code].Param of
+      ipNone:; // do nothing
+
+      ipLeb:
+        ParseNumOrIdx(sc, ci.operandNum, ci.operandIdx);
+
+      ipi32,ipi64,ipf32,ipf64:
+      begin
+        if sc.token<>weNumber then
+          ErrorExpectButFound(sc, 'number');
+        ci.operandText := sc.resText;
+      end;
+
+      //ip2Leb,  // memory arguments, ask for offset + align
+      //ipTable,   // a complex structure... used for br_table only
+      //ipResType  // result type used for blocks, such as If, block or loop
+
+    end;
+  end;
+
+end;
+
 procedure ParseFunc(sc: TWatScanner; dst: TWasmFunc);
 procedure ParseFunc(sc: TWatScanner; dst: TWasmFunc);
 var
 var
   nm : integer;
   nm : integer;
@@ -175,77 +218,105 @@ var
   tk  : TWatToken;
   tk  : TWatToken;
 begin
 begin
   if sc.token=weFunc then sc.Next;
   if sc.token=weFunc then sc.Next;
-  repeat
-    if sc.token=weIdent then begin
-      dst.id:=sc.resText;
-      sc.Next;
-    end;
 
 
+  if sc.token=weIdent then begin
+    dst.id:=sc.resText;
+    sc.Next;
+  end;
+
+  ConsumeAnyOpenToken(sc, tk);
+
+  if tk = weType then begin
+    if not ParseNumOfId(sc, nm, id) then Exit;
+    if nm>=0 then dst.typeIdx:=nm
+    else dst.typeId:=id;
     ConsumeAnyOpenToken(sc, tk);
     ConsumeAnyOpenToken(sc, tk);
+  end;
 
 
-    if tk = weType then begin
-      if not ParseNumOfId(sc, nm, id) then Exit;
-      if nm>=0 then dst.typeIdx:=nm
-      else dst.typeId:=id;
-      ConsumeAnyOpenToken(sc, tk);
-    end;
+  while tk = weParam do begin
+    p:=dst.GetInlineType.AddParam;
+    sc.Next;
+    ParseParam(sc, p.id, p.tp);
+    ConsumeAnyOpenToken(sc, tk);
+  end;
 
 
-    while tk = weParam do begin
-      p:=dst.GetInlineType.AddParam;
-      sc.Next;
-      ParseParam(sc, p.id, p.tp);
-      ConsumeAnyOpenToken(sc, tk);
-    end;
+  while tk = weResult do begin
+    p:=dst.GetInlineType.AddResult;
+    sc.Next;
+    ParseParam(sc, p.id, p.tp, false);
+    ConsumeAnyOpenToken(sc, tk);
+  end;
 
 
-    while tk = weResult do begin
-      p:=dst.GetInlineType.AddResult;
-      sc.Next;
-      ParseParam(sc, p.id, p.tp, false);
-      ConsumeAnyOpenToken(sc, tk);
-    end;
+  while tk = weLocal do begin
+    p:=dst.AddLocal;
+    sc.Next;
+    ParseParam(sc, p.id, p.tp);
+    ConsumeAnyOpenToken(sc, tk);
+  end;
 
 
-    while tk = weLocal do begin
-      p:=dst.AddLocal;
-      sc.Next;
-      ParseParam(sc, p.id, p.tp);
-      ConsumeAnyOpenToken(sc, tk);
-    end;
+  if not (sc.token in [weInstr, weCloseBrace]) then
+    ErrorExpectButFound(sc, 'identifier');
+
+  ParseInstrList(sc, dst.instr);
+  ConsumeToken(sc, weCloseBrace);
+end;
 
 
-    if not (tk in [weInstr, weCloseBrace]) then
-      ErrorExpectButFound(sc, 'identifier');
+procedure ParseExport(sc: TWatScanner; dst: TWasmExport);
+begin
+  if sc.token=weExport then
+    sc.Next;
 
 
-    while tk<>weCloseBrace do begin
-      ConsumeToken(sc, weInstr);
-    end;
+  if sc.token<>weString then
+    ErrorExpectButFound(sc, 'string');
 
 
-  until sc.token=weCloseBrace;
+  dst.name := sc.resText;
   sc.Next;
   sc.Next;
+
+  ConsumeAnyOpenToken(sc);
+  case sc.token of
+    weFunc:  dst.exportType:=EXPDESC_FUNC;
+    weTable: dst.exportType:=EXPDESC_TABLE;
+    weMemory: dst.exportType:=EXPDESC_MEM;
+    weGlobal: dst.exportType:=EXPDESC_GLOBAL;
+  else
+    ErrorExpectButFound(sc, 'func');
+  end;
+
+  sc.Next;
+  case sc.token of
+    weNumber:
+      dst.exportNum := sc.resInt32;
+    weIdent:
+      dst.exportIdx := sc.resText;
+  else
+    ErrorExpectButFound(sc, 'index');
+  end;
+  sc.Next;
+  ConsumeToken(sc, weCloseBrace);
+  ConsumeToken(sc, weCloseBrace);
 end;
 end;
 
 
-function ParseModuleInt(sc: TWatScanner; dst: TWasmModule): Boolean;
+procedure ParseModuleInt(sc: TWatScanner; dst: TWasmModule);
+var
+  tk : TWatToken;
 begin
 begin
-  if not ConsumeOpenToken(sc, weModule) then begin
+  if not ConsumeOpenToken(sc, weModule) then
     ErrorExpectButFound(sc, 'module');
     ErrorExpectButFound(sc, 'module');
-    Exit;
-  end;
 
 
-  repeat
-    sc.Next;
-    if sc.token=weOpenBrace then begin
-      sc.Next;
-
-      if sc.token = weFunc then begin
+  sc.Next;
+  ConsumeAnyOpenToken(sc, tk);
+  while tk <> weCloseBrace do begin
+    case tk of
+      weFunc:
         ParseFunc(sc, dst.AddFunc);
         ParseFunc(sc, dst.AddFunc);
-      end;
-
-    end else if sc.token<>weCloseBrace then begin
-      ErrorUnexpected(sc, TokenStr[sc.token]);
-      Result := false;
-      exit;
+      weExport:
+        ParseExport(sc, dst.AddExport);
+    else
+      ErrorExpectButFound(sc, 'func', TokenStr[sc.token]);
     end;
     end;
-
-  until sc.token=weCloseBrace;
-  Result := true;
+    ConsumeAnyOpenToken(sc, tk);
+  end;
+  ConsumeToken(sc, weCloseBrace);
 end;
 end;
 
 
 function ParseModule(sc: TWatScanner; dst: TWasmModule; var errMsg: string): Boolean;
 function ParseModule(sc: TWatScanner; dst: TWasmModule; var errMsg: string): Boolean;

+ 3 - 3
utils/wasmbin/watscanner.pas

@@ -41,7 +41,7 @@ type
     procedure SetSource(const abuf: string);
     procedure SetSource(const abuf: string);
     function Next: Boolean;
     function Next: Boolean;
 
 
-    function GetInt32: Integer;
+    function resInt32(const def: integer=-1): Integer;
   end;
   end;
 
 
 const
 const
@@ -241,12 +241,12 @@ begin
     resText := Copy(buf, ofs, idx-ofs);
     resText := Copy(buf, ofs, idx-ofs);
 end;
 end;
 
 
-function TWatScanner.GetInt32: Integer;
+function TWatScanner.resInt32(const def: integer=-1): Integer;
 var
 var
   err: integer;
   err: integer;
 begin
 begin
   Val(resText, Result, err);
   Val(resText, Result, err);
-  if err<>0 then Result:=0;
+  if err<>0 then Result:=def;
 end;
 end;