wasmdef.pas 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. unit wasmdef;
  2. {$i fpcdefs.inc}
  3. interface
  4. uses
  5. symtype, symsym, symdef, symconst, constexp
  6. ,defutil, procdefutil, cclasses;
  7. type
  8. { TWasmTypeEntry }
  9. TWasmTypeEntry = class(Tobject)
  10. name : string; // always empty
  11. idx : integer;
  12. constructor Create(aidx: integer; aname: string);
  13. end;
  14. { TWasmProcTypeLookup }
  15. TWasmProcTypeLookup = class(TObject)
  16. list: TFPHashObjectList;
  17. idx: integer;
  18. constructor Create(astartIndex: integer = 0);
  19. destructor Destroy; override;
  20. function GetTypeIndex(const typecode: string): Integer;
  21. end;
  22. // encodes procedure definition to a code used for the proc type lookup
  23. // it's case-sensitive!!!
  24. // i = i32, I = i64, f = f32, F = f32
  25. function WasmGetTypeCodeForDef(def: tdef; var ch: char): Boolean;
  26. function WasmGetTypeCode(aprocdef: tabstractprocdef): string;
  27. { returns whether a def always resides in memory,
  28. rather than in wasm local variables...) }
  29. function wasmAlwayInMem(def: tdef): boolean;
  30. function get_para_push_size(def: tdef): tdef;
  31. implementation
  32. function get_para_push_size(def: tdef): tdef;
  33. begin
  34. result:=def;
  35. if def.typ=orddef then
  36. case torddef(def).ordtype of
  37. u8bit,uchar:
  38. if torddef(def).high>127 then
  39. result:=s8inttype;
  40. u16bit:
  41. begin
  42. if torddef(def).high>32767 then
  43. result:=s16inttype;
  44. end
  45. else
  46. ;
  47. end;
  48. end;
  49. function wasmAlwayInMem(def: tdef): boolean;
  50. begin
  51. case def.typ of
  52. arraydef,
  53. filedef,
  54. recorddef,
  55. objectdef,
  56. stringdef:
  57. result:=true;
  58. else
  59. result:=false;
  60. end;
  61. end;
  62. function WasmGetTypeCodeForDef(def: tdef; var ch: char): Boolean;
  63. begin
  64. Result := assigned(def);
  65. if not Result then Exit;
  66. case def.typ of
  67. floatdef:
  68. if def.size = 4 then ch :='f'
  69. else ch :='F';
  70. orddef:
  71. if def.size = 8 then ch :='I'
  72. else ch := 'i';
  73. // todo: set can be bigger
  74. else
  75. ch:='i'; // by address
  76. end;
  77. end;
  78. function WasmGetTypeCode(aprocdef: tabstractprocdef): string;
  79. var
  80. ch : char;
  81. i : integer;
  82. begin
  83. Result := '';
  84. if not Assigned(aprocdef) then exit;
  85. for i:=0 to aprocdef.paras.Count-1 do begin
  86. WasmGetTypeCodeForDef( tparavarsym(aprocdef.paras[i]).paraloc[callerside].Def, ch);
  87. result:=result+ch;
  88. end;
  89. if assigned(aprocdef) then begin
  90. result:=result+':';
  91. WasmGetTypeCodeForDef(aprocdef.returndef, ch);
  92. result:=result+ch;
  93. end;
  94. end;
  95. { TWasmTypeEntry }
  96. constructor TWasmTypeEntry.Create(aidx: integer; aname: string);
  97. begin
  98. idx := aidx;
  99. name := aname;
  100. end;
  101. { TWasmProcTypeLookup }
  102. constructor TWasmProcTypeLookup.Create(astartIndex: integer = 0);
  103. begin
  104. inherited Create;
  105. list := TFPHashObjectList.Create(true);
  106. idx := astartIndex;
  107. end;
  108. destructor TWasmProcTypeLookup.Destroy;
  109. begin
  110. list.Free;
  111. inherited Destroy;
  112. end;
  113. function TWasmProcTypeLookup.GetTypeIndex(const typecode: string): Integer;
  114. var
  115. en : TWasmTypeEntry;
  116. begin
  117. en := TWasmTypeEntry(list.Find(typecode));
  118. if not Assigned(en) then begin
  119. en := TWasmTypeEntry.Create(idx, ''); // no need to copy
  120. inc(idx);
  121. list.Add(typecode, en);
  122. end;
  123. Result := en.idx;
  124. end;
  125. end.