123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- 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.
|