fpc/compiler/wasm32/wasmdef.pas
nickysn c9ee72b05a * the compiler/wasm directory renamed compiler/wasm32
git-svn-id: branches/wasm@46251 -
2020-08-05 14:19:18 +00:00

156 lines
3.5 KiB
ObjectPascal

unit wasmdef;
{$i fpcdefs.inc}
interface
uses
symtype, symsym, symdef, symconst, constexp
,defutil, procdefutil, cclasses;
type
{ TWasmTypeEntry }
TWasmTypeEntry = class(Tobject)
name : string; // always empty
idx : integer;
constructor Create(aidx: integer; aname: string);
end;
{ TWasmProcTypeLookup }
TWasmProcTypeLookup = class(TObject)
list: TFPHashObjectList;
idx: integer;
constructor Create(astartIndex: integer = 0);
destructor Destroy; override;
function GetTypeIndex(const typecode: string): Integer;
end;
// encodes procedure definition to a code used for the proc type lookup
// it's case-sensitive!!!
// i = i32, I = i64, f = f32, F = f32
function WasmGetTypeCodeForDef(def: tdef; var ch: char): Boolean;
function WasmGetTypeCode(aprocdef: tabstractprocdef): string;
{ returns whether a def always resides in memory,
rather than in wasm local variables...) }
function wasmAlwayInMem(def: tdef): boolean;
function get_para_push_size(def: tdef): tdef;
implementation
function get_para_push_size(def: tdef): tdef;
begin
result:=def;
if def.typ=orddef then
case torddef(def).ordtype of
u8bit,uchar:
if torddef(def).high>127 then
result:=s8inttype;
u16bit:
begin
if torddef(def).high>32767 then
result:=s16inttype;
end
else
;
end;
end;
function wasmAlwayInMem(def: tdef): boolean;
begin
case def.typ of
arraydef,
filedef,
recorddef,
objectdef,
stringdef:
result:=true;
else
result:=false;
end;
end;
function WasmGetTypeCodeForDef(def: tdef; var ch: char): Boolean;
begin
Result := assigned(def);
if not Result then Exit;
case def.typ of
floatdef:
if def.size = 4 then ch :='f'
else ch :='F';
orddef:
if def.size = 8 then ch :='I'
else ch := 'i';
// todo: set can be bigger
else
ch:='i'; // by address
end;
end;
function WasmGetTypeCode(aprocdef: tabstractprocdef): string;
var
ch : char;
i : integer;
begin
Result := '';
if not Assigned(aprocdef) then exit;
for i:=0 to aprocdef.paras.Count-1 do begin
WasmGetTypeCodeForDef( tparavarsym(aprocdef.paras[i]).paraloc[callerside].Def, ch);
result:=result+ch;
end;
if assigned(aprocdef) then begin
result:=result+':';
WasmGetTypeCodeForDef(aprocdef.returndef, ch);
result:=result+ch;
end;
end;
{ TWasmTypeEntry }
constructor TWasmTypeEntry.Create(aidx: integer; aname: string);
begin
idx := aidx;
name := aname;
end;
{ TWasmProcTypeLookup }
constructor TWasmProcTypeLookup.Create(astartIndex: integer = 0);
begin
inherited Create;
list := TFPHashObjectList.Create(true);
idx := astartIndex;
end;
destructor TWasmProcTypeLookup.Destroy;
begin
list.Free;
inherited Destroy;
end;
function TWasmProcTypeLookup.GetTypeIndex(const typecode: string): Integer;
var
en : TWasmTypeEntry;
begin
en := TWasmTypeEntry(list.Find(typecode));
if not Assigned(en) then begin
en := TWasmTypeEntry.Create(idx, ''); // no need to copy
inc(idx);
list.Add(typecode, en);
end;
Result := en.idx;
end;
end.