tgcpu.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. {
  2. Copyright (C) 2010 by Jonas Maebe
  3. This unit handles the temporary variables for the JVM
  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. {
  18. This unit handles the temporary variables for the JVM.
  19. }
  20. unit tgcpu;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. globtype,
  25. aasmdata,
  26. cgutils,
  27. symtype,tgobj;
  28. type
  29. ttgjs = class(ttgobj)
  30. protected
  31. procedure getimplicitobjtemp(list: TAsmList; def: tdef; temptype: ttemptype; out ref: treference);
  32. function getifspecialtemp(list: TAsmList; def: tdef; forcesize: aint; temptype: ttemptype; out ref: treference): boolean;
  33. procedure alloctemp(list: TAsmList; size, alignment: longint; temptype: ttemptype; def: tdef; out ref: treference); override;
  34. public
  35. procedure setfirsttemp(l : longint); override;
  36. procedure getlocal(list: TAsmList; size: longint; alignment: shortint; def: tdef; var ref: treference); override;
  37. procedure gethltemp(list: TAsmList; def: tdef; forcesize: aint; temptype: ttemptype; out ref: treference); override;
  38. procedure gethltemptyped(list: TAsmList; def: tdef; temptype: ttemptype; out ref: treference); override;
  39. end;
  40. implementation
  41. uses
  42. verbose,
  43. cgbase,
  44. symconst,symdef,symsym,defutil,
  45. cpubase,aasmcpu,
  46. hlcgobj,hlcgcpu;
  47. procedure ttgjs.getimplicitobjtemp(list: TAsmList; def: tdef; temptype: ttemptype; out ref: treference);
  48. var
  49. sym: tsym;
  50. pd: tprocdef;
  51. begin
  52. gettemp(list,java_jlobject.size,java_jlobject.alignment,temptype,ref);
  53. list.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(tabstractrecorddef(def).jvm_full_typename(true))));
  54. { the constructor doesn't return anything, so put a duplicate of the
  55. self pointer on the evaluation stack for use as function result
  56. after the constructor has run }
  57. list.concat(taicpu.op_none(a_dup));
  58. //!!!!!!!!!!!! thlcgjvm(hlcg).incstack(list,2);
  59. { call the constructor }
  60. sym:=tsym(tabstractrecorddef(def).symtable.find('CREATE'));
  61. if assigned(sym) and
  62. (sym.typ=procsym) then
  63. begin
  64. pd:=tprocsym(sym).find_bytype_parameterless(potype_constructor);
  65. if not assigned(pd) then
  66. internalerror(2011032701);
  67. end
  68. else
  69. internalerror(2011060301);
  70. hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
  71. //!!!!!!!!!!!!!! thlcgjvm(hlcg).decstack(list,1);
  72. { store reference to instance }
  73. //!!!!!!!!!!!!!!! thlcgjvm(hlcg).a_load_stack_ref(list,java_jlobject,ref,0);
  74. end;
  75. function ttgjs.getifspecialtemp(list: TAsmList; def: tdef; forcesize: aint; temptype: ttemptype; out ref: treference): boolean;
  76. var
  77. eledef: tdef;
  78. ndim: longint;
  79. sym: tsym;
  80. pd: tprocdef;
  81. begin
  82. result:=false;
  83. case def.typ of
  84. arraydef:
  85. begin
  86. if not is_dynamic_array(def) then
  87. begin
  88. { allocate an array of the right size }
  89. gettemp(list,java_jlobject.size,java_jlobject.alignment,temptype,ref);
  90. ndim:=0;
  91. eledef:=def;
  92. repeat
  93. //!!!!!!!!!!!!!!!! if forcesize<>-1 then
  94. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,forcesize div tarraydef(eledef).elesize,R_INTREGISTER)
  95. //!!!!!!!!!!!!!!!! else
  96. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).a_load_const_stack(list,s32inttype,tarraydef(eledef).elecount,R_INTREGISTER);
  97. eledef:=tarraydef(eledef).elementdef;
  98. inc(ndim);
  99. forcesize:=-1;
  100. until (eledef.typ<>arraydef) or
  101. is_dynamic_array(eledef);
  102. eledef:=tarraydef(def).elementdef;
  103. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).g_newarray(list,def,ndim);
  104. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).a_load_stack_ref(list,java_jlobject,ref,0);
  105. result:=true;
  106. end;
  107. end;
  108. recorddef:
  109. begin
  110. getimplicitobjtemp(list,def,temptype,ref);
  111. result:=true;
  112. end;
  113. setdef:
  114. begin
  115. if tsetdef(def).elementdef.typ=enumdef then
  116. begin
  117. { load enum class type }
  118. //!!!!!!!!!!!!!!!! list.concat(taicpu.op_sym(a_ldc,current_asmdata.RefAsmSymbol(tenumdef(tsetdef(def).elementdef).getbasedef.classdef.jvm_full_typename(true))));
  119. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).incstack(current_asmdata.CurrAsmList,1);
  120. { call tenumset.noneOf() class method }
  121. sym:=tsym(tobjectdef(java_juenumset).symtable.find('NONEOF'));
  122. if assigned(sym) and
  123. (sym.typ=procsym) then
  124. begin
  125. if tprocsym(sym).procdeflist.Count<>1 then
  126. internalerror(2011062801);
  127. pd:=tprocdef(tprocsym(sym).procdeflist[0]);
  128. end;
  129. hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
  130. { static calls method replaces parameter with set instance
  131. -> no change in stack height }
  132. end
  133. else
  134. begin
  135. list.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(java_jubitset.jvm_full_typename(true))));
  136. { the constructor doesn't return anything, so put a duplicate of the
  137. self pointer on the evaluation stack for use as function result
  138. after the constructor has run }
  139. list.concat(taicpu.op_none(a_dup));
  140. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).incstack(list,2);
  141. { call the constructor }
  142. sym:=tsym(java_jubitset.symtable.find('CREATE'));
  143. if assigned(sym) and
  144. (sym.typ=procsym) then
  145. begin
  146. pd:=tprocsym(sym).find_bytype_parameterless(potype_constructor);
  147. if not assigned(pd) then
  148. internalerror(2011062802);
  149. end
  150. else
  151. internalerror(2011062803);
  152. hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
  153. { duplicate self pointer is removed }
  154. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).decstack(list,1);
  155. end;
  156. { store reference to instance }
  157. gettemp(list,java_jlobject.size,java_jlobject.alignment,temptype,ref);
  158. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).a_load_stack_ref(list,java_jlobject,ref,0);
  159. result:=true;
  160. end;
  161. procvardef:
  162. begin
  163. if not tprocvardef(def).is_addressonly then
  164. begin
  165. //!!!!!!!!!!!!!!!! getimplicitobjtemp(list,tprocvardef(def).classdef,temptype,ref);
  166. result:=true;
  167. end;
  168. end;
  169. stringdef:
  170. begin
  171. if is_shortstring(def) then
  172. begin
  173. gettemp(list,java_jlobject.size,java_jlobject.alignment,temptype,ref);
  174. { add the maxlen parameter (s8inttype because parameters must
  175. be sign extended) }
  176. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).a_load_const_stack(list,s8inttype,shortint(tstringdef(def).len),R_INTREGISTER);
  177. { call the constructor }
  178. sym:=tsym(tobjectdef(java_shortstring).symtable.find('CREATEEMPTY'));
  179. if assigned(sym) and
  180. (sym.typ=procsym) then
  181. begin
  182. if tprocsym(sym).procdeflist.Count<>1 then
  183. internalerror(2011052404);
  184. pd:=tprocdef(tprocsym(sym).procdeflist[0]);
  185. end;
  186. hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
  187. { static calls method replaces parameter with string instance
  188. -> no change in stack height }
  189. { store reference to instance }
  190. //!!!!!!!!!!!!!!!! thlcgjvm(hlcg).a_load_stack_ref(list,java_jlobject,ref,0);
  191. result:=true;
  192. end;
  193. end;
  194. end;
  195. end;
  196. procedure ttgjs.alloctemp(list: TAsmList; size, alignment: longint; temptype: ttemptype; def: tdef; out ref: treference);
  197. begin
  198. { the JVM only supports 1 slot (= 4 bytes in FPC) and 2 slot (= 8 bytes in
  199. FPC) temps on the stack. double and int64 are 2 slots, the rest is one slot.
  200. There are no problems with reusing the same slot for a value of a different
  201. type. There are no alignment requirements either. }
  202. if size<4 then
  203. size:=4;
  204. if not(size in [4,8]) then
  205. internalerror(2010121401);
  206. { don't pass on "def", since we don't care if a slot is used again for a
  207. different type }
  208. inherited alloctemp(list, size shr 2, 1, temptype, nil,ref);
  209. end;
  210. procedure ttgjs.setfirsttemp(l: longint);
  211. begin
  212. firsttemp:=l;
  213. lasttemp:=l;
  214. end;
  215. procedure ttgjs.getlocal(list: TAsmList; size: longint; alignment: shortint; def: tdef; var ref: treference);
  216. begin
  217. if not getifspecialtemp(list,def,size,tt_persistent,ref) then
  218. inherited;
  219. end;
  220. procedure ttgjs.gethltemp(list: TAsmList; def: tdef; forcesize: aint; temptype: ttemptype; out ref: treference);
  221. begin
  222. if not getifspecialtemp(list,def,forcesize,temptype,ref) then
  223. inherited;
  224. end;
  225. procedure ttgjs.gethltemptyped(list: TAsmList; def: tdef; temptype: ttemptype; out ref: treference);
  226. begin
  227. gethltemp(list,def,def.size,temptype,ref);
  228. end;
  229. begin
  230. tgobjclass:=ttgjs;
  231. end.