mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 19:49:22 +02:00
[PATCH 044/188] export section parsing
From 3b23f9480a31b7f65580d4cd731283456b28be75 Mon Sep 17 00:00:00 2001 From: Dmitry Boyarintsev <skalogryz.lists@gmail.com> Date: Wed, 20 Nov 2019 14:14:21 -0500 git-svn-id: branches/wasm@46040 -
This commit is contained in:
parent
b726751b3a
commit
d47696380e
@ -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;
|
|
||||||
|
|
||||||
ConsumeAnyOpenToken(sc, tk);
|
if sc.token=weIdent then begin
|
||||||
|
dst.id:=sc.resText;
|
||||||
if tk = weType then begin
|
sc.Next;
|
||||||
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 = 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;
|
|
||||||
|
|
||||||
if not (tk in [weInstr, weCloseBrace]) then
|
|
||||||
ErrorExpectButFound(sc, 'identifier');
|
|
||||||
|
|
||||||
while tk<>weCloseBrace do begin
|
|
||||||
ConsumeToken(sc, weInstr);
|
|
||||||
end;
|
|
||||||
|
|
||||||
until sc.token=weCloseBrace;
|
|
||||||
sc.Next;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function ParseModuleInt(sc: TWatScanner; dst: TWasmModule): Boolean;
|
|
||||||
begin
|
|
||||||
if not ConsumeOpenToken(sc, weModule) then begin
|
|
||||||
ErrorExpectButFound(sc, 'module');
|
|
||||||
Exit;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
repeat
|
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);
|
||||||
|
end;
|
||||||
|
|
||||||
|
while tk = weParam do begin
|
||||||
|
p:=dst.GetInlineType.AddParam;
|
||||||
sc.Next;
|
sc.Next;
|
||||||
if sc.token=weOpenBrace then begin
|
ParseParam(sc, p.id, p.tp);
|
||||||
sc.Next;
|
ConsumeAnyOpenToken(sc, tk);
|
||||||
|
end;
|
||||||
|
|
||||||
if sc.token = weFunc then begin
|
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;
|
||||||
|
|
||||||
|
if not (sc.token in [weInstr, weCloseBrace]) then
|
||||||
|
ErrorExpectButFound(sc, 'identifier');
|
||||||
|
|
||||||
|
ParseInstrList(sc, dst.instr);
|
||||||
|
ConsumeToken(sc, weCloseBrace);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure ParseExport(sc: TWatScanner; dst: TWasmExport);
|
||||||
|
begin
|
||||||
|
if sc.token=weExport then
|
||||||
|
sc.Next;
|
||||||
|
|
||||||
|
if sc.token<>weString then
|
||||||
|
ErrorExpectButFound(sc, 'string');
|
||||||
|
|
||||||
|
dst.name := sc.resText;
|
||||||
|
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;
|
||||||
|
|
||||||
|
procedure ParseModuleInt(sc: TWatScanner; dst: TWasmModule);
|
||||||
|
var
|
||||||
|
tk : TWatToken;
|
||||||
|
begin
|
||||||
|
if not ConsumeOpenToken(sc, weModule) then
|
||||||
|
ErrorExpectButFound(sc, 'module');
|
||||||
|
|
||||||
|
sc.Next;
|
||||||
|
ConsumeAnyOpenToken(sc, tk);
|
||||||
|
while tk <> weCloseBrace do begin
|
||||||
|
case tk of
|
||||||
|
weFunc:
|
||||||
ParseFunc(sc, dst.AddFunc);
|
ParseFunc(sc, dst.AddFunc);
|
||||||
end;
|
weExport:
|
||||||
|
ParseExport(sc, dst.AddExport);
|
||||||
end else if sc.token<>weCloseBrace then begin
|
else
|
||||||
ErrorUnexpected(sc, TokenStr[sc.token]);
|
ErrorExpectButFound(sc, 'func', TokenStr[sc.token]);
|
||||||
Result := false;
|
|
||||||
exit;
|
|
||||||
end;
|
end;
|
||||||
|
ConsumeAnyOpenToken(sc, tk);
|
||||||
until sc.token=weCloseBrace;
|
end;
|
||||||
Result := true;
|
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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user