nwasmutil.pas 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. {
  2. Copyright (c) 2021 by Nikolay Nikolov
  3. WebAssembly version of some node tree helper routines
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit nwasmutil;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. ngenutil,
  22. symsym;
  23. type
  24. { twasmnodeutils }
  25. twasmnodeutils = class(tnodeutils)
  26. public
  27. class procedure insertbssdata(sym : tstaticvarsym); override;
  28. class procedure InsertObjectInfo; override;
  29. end;
  30. implementation
  31. uses
  32. cclasses,
  33. globtype,globals,
  34. cpubase,
  35. aasmbase,aasmdata,aasmtai,aasmcpu,
  36. hlcgobj,hlcgcpu,
  37. symdef,symtype,symconst,symcpu,
  38. fmodule;
  39. { twasmnodeutils }
  40. class procedure twasmnodeutils.insertbssdata(sym: tstaticvarsym);
  41. var
  42. symcpu: tcpustaticvarsym;
  43. begin
  44. symcpu:=tcpustaticvarsym(sym);
  45. if symcpu.is_wasm_global then
  46. begin
  47. if sym.globalasmsym then
  48. current_asmdata.asmlists[al_start].Concat(tai_globaltype.create_global(symcpu.mangledname,symcpu.get_wasm_global_vardef_type,false,symcpu.vardef))
  49. else
  50. current_asmdata.asmlists[al_start].Concat(tai_globaltype.create_local(symcpu.mangledname,symcpu.get_wasm_global_vardef_type,false,symcpu.vardef));
  51. end
  52. else
  53. inherited;
  54. end;
  55. class procedure twasmnodeutils.InsertObjectInfo;
  56. var
  57. modules: TFPList;
  58. function ModuleExists(m: tmodule): Boolean;
  59. var
  60. q: tmodule;
  61. begin
  62. result:=modules.IndexOf(Pointer(m))>=0;
  63. end;
  64. procedure AddModule(m: tmodule);
  65. begin
  66. modules.Add(Pointer(m));
  67. end;
  68. procedure WriteImportDll(list: TAsmList; proc: tprocdef);
  69. begin
  70. thlcgwasm(hlcg).g_procdef(list,proc,false);
  71. list.Concat(tai_import_module.create(proc.mangledname,proc.import_dll^));
  72. list.Concat(tai_import_name.create(proc.mangledname,proc.import_name^));
  73. end;
  74. procedure InsertModuleInfo(list : TAsmList;u: tmodule);
  75. var
  76. i: Integer;
  77. def : tdef;
  78. proc : tprocdef;
  79. cur_unit : tused_unit;
  80. begin
  81. if ModuleExists(u) then
  82. exit;
  83. AddModule(u);
  84. cur_unit:=tused_unit(u.used_units.First);
  85. while assigned(cur_unit) do
  86. begin
  87. InsertModuleInfo(list,cur_unit.u);
  88. cur_unit:=tused_unit(cur_unit.Next);
  89. end;
  90. if ((u.moduleflags * [mf_init,mf_finalize])<>[]) and assigned(u.globalsymtable) then
  91. begin
  92. if mf_init in u.moduleflags then
  93. list.Concat(tai_functype.create(make_mangledname('INIT$',u.globalsymtable,''),TWasmFuncType.Create([],[]),false));
  94. if mf_finalize in u.moduleflags then
  95. list.Concat(tai_functype.create(make_mangledname('FINALIZE$',u.globalsymtable,''),TWasmFuncType.Create([],[]),false));
  96. end;
  97. for i:=0 to u.deflist.Count-1 do
  98. begin
  99. def:=tdef(u.deflist[i]);
  100. if assigned(def) and (tdef(def).typ = procdef) then
  101. begin
  102. proc := tprocdef(def);
  103. if (po_external in proc.procoptions) and (po_has_importdll in proc.procoptions) then
  104. WriteImportDll(list,proc)
  105. else if not proc.owner.iscurrentunit or (po_external in proc.procoptions) then
  106. thlcgwasm(hlcg).g_procdef(list,proc,false)
  107. else
  108. thlcgwasm(hlcg).g_procdef(list,proc,true);
  109. end;
  110. end;
  111. end;
  112. var
  113. i : integer;
  114. def : tdef;
  115. proc : tprocdef;
  116. list : TAsmList;
  117. cur_unit: tused_unit;
  118. begin
  119. inherited;
  120. modules:=TFPList.Create;
  121. list:=current_asmdata.asmlists[al_start];
  122. list.Concat(tai_globaltype.create(STACK_POINTER_SYM,wbt_i32,false));
  123. if ts_wasm_threads in current_settings.targetswitches then
  124. begin
  125. list.Concat(tai_globaltype.create(TLS_SIZE_SYM,wbt_i32,true));
  126. list.Concat(tai_globaltype.create(TLS_ALIGN_SYM,wbt_i32,true));
  127. list.Concat(tai_globaltype.create(TLS_BASE_SYM,wbt_i32,false));
  128. end;
  129. if ts_wasm_native_exceptions in current_settings.targetswitches then
  130. begin
  131. list.Concat(tai_tagtype.create(FPC_EXCEPTION_TAG_SYM, []));
  132. list.Concat(tai_symbol.Create_Weak(current_asmdata.WeakRefAsmSymbol(FPC_EXCEPTION_TAG_SYM,AT_WASM_EXCEPTION_TAG),0));
  133. end;
  134. for i:=0 to current_module.deflist.Count-1 do
  135. begin
  136. def:=tdef(current_module.deflist[i]);
  137. { since commit 48986 deflist might have NIL entries }
  138. if assigned(def) and (def.typ=procdef) then
  139. begin
  140. proc := tprocdef(def);
  141. if po_external in proc.procoptions then
  142. if po_has_importdll in proc.procoptions then
  143. WriteImportDll(list,proc)
  144. else
  145. thlcgwasm(hlcg).g_procdef(list,proc,false);
  146. end;
  147. end;
  148. create_hlcodegen;
  149. InsertModuleInfo(list,current_module);
  150. cur_unit:=tused_unit(usedunits.First);
  151. while assigned(cur_unit) do
  152. begin
  153. InsertModuleInfo(list,cur_unit.u);
  154. cur_unit:=tused_unit(cur_unit.Next);
  155. end;
  156. destroy_hlcodegen;
  157. modules.Free;
  158. end;
  159. begin
  160. cnodeutils:=twasmnodeutils;
  161. end.