mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-05 05:58:02 +02:00
156 lines
3.5 KiB
ObjectPascal
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.
|