njvmld.pas 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. {
  2. Copyright (c) 2011 by Jonas Maebe
  3. Generate JVM assembler for nodes that handle loads and assignments
  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 njvmld;
  18. {$I fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,
  22. symtype,
  23. cgutils,
  24. node, ncgld, ncgnstld;
  25. type
  26. tjvmloadnode = class(tcgnestloadnode)
  27. protected
  28. function is_copyout_addr_param_load: boolean;
  29. public
  30. function is_addr_param_load: boolean; override;
  31. procedure pass_generate_code; override;
  32. end;
  33. tjvmassignmentnode = class(tcgassignmentnode)
  34. function pass_1: tnode; override;
  35. end;
  36. tjvmarrayconstructornode = class(tcgarrayconstructornode)
  37. protected
  38. procedure makearrayref(var ref: treference; eledef: tdef); override;
  39. procedure advancearrayoffset(var ref: treference; elesize: asizeint); override;
  40. end;
  41. implementation
  42. uses
  43. verbose,
  44. aasmdata,
  45. nbas,nld,ncal,nmem,ncnv,
  46. symconst,symsym,symdef,symtable,defutil,jvmdef,
  47. paramgr,
  48. cgbase,hlcgobj;
  49. { tjvmassignmentnode }
  50. function tjvmassignmentnode.pass_1: tnode;
  51. var
  52. target: tnode;
  53. psym: tsym;
  54. begin
  55. { intercept writes to string elements, because Java strings are immutable
  56. -> detour via StringBuilder
  57. }
  58. target:=left.actualtargetnode;
  59. if (target.nodetype=vecn) and
  60. (is_wide_or_unicode_string(tvecnode(target).left.resultdef) or
  61. is_ansistring(tvecnode(target).left.resultdef)) then
  62. begin
  63. { prevent errors in case of an expression such as
  64. word(str[x]):=1234;
  65. }
  66. inserttypeconv_explicit(right,cwidechartype);
  67. result:=ccallnode.createintern('fpc_'+tstringdef(tvecnode(target).left.resultdef).stringtypname+'_setchar',
  68. ccallparanode.create(right,
  69. ccallparanode.create(tvecnode(target).right,
  70. ccallparanode.create(tvecnode(target).left.getcopy,nil))));
  71. result:=cassignmentnode.create(tvecnode(target).left,result);
  72. right:=nil;
  73. tvecnode(target).left:=nil;
  74. tvecnode(target).right:=nil;
  75. exit;
  76. end
  77. else if (target.nodetype=vecn) and
  78. is_shortstring(tvecnode(target).left.resultdef) then
  79. begin
  80. { prevent errors in case of an expression such as
  81. byte(str[x]):=12;
  82. }
  83. inserttypeconv_explicit(right,cchartype);
  84. { call ShortstringClass(@shortstring).setChar(index,char) }
  85. tvecnode(target).left:=caddrnode.create_internal(tvecnode(target).left);
  86. inserttypeconv_explicit(tvecnode(target).left,java_shortstring);
  87. psym:=search_struct_member(tabstractrecorddef(java_shortstring),'SETCHAR');
  88. if not assigned(psym) or
  89. (psym.typ<>procsym) then
  90. internalerror(2011052408);
  91. result:=
  92. ccallnode.create(
  93. ccallparanode.create(right,
  94. ccallparanode.create(tvecnode(target).right,nil)),
  95. tprocsym(psym),psym.owner,tvecnode(target).left,[]);
  96. right:=nil;
  97. tvecnode(target).left:=nil;
  98. tvecnode(target).right:=nil;
  99. exit;
  100. end
  101. else
  102. result:=inherited;
  103. end;
  104. function tjvmloadnode.is_copyout_addr_param_load: boolean;
  105. begin
  106. result:=
  107. { passed via array of one element }
  108. ((symtable.symtabletype=parasymtable) and
  109. (symtableentry.typ=paravarsym) and
  110. paramanager.push_copyout_param(tparavarsym(symtableentry).varspez,resultdef,tprocdef(symtable.defowner).proccalloption));
  111. end;
  112. function tjvmloadnode.is_addr_param_load: boolean;
  113. begin
  114. result:=
  115. (inherited and
  116. not jvmimplicitpointertype(tparavarsym(symtableentry).vardef)) or
  117. is_copyout_addr_param_load;
  118. end;
  119. procedure tjvmloadnode.pass_generate_code;
  120. begin
  121. if is_copyout_addr_param_load then
  122. begin
  123. { the parameter is passed as an array of one element containing the
  124. parameter value }
  125. location_reset_ref(location,LOC_REFERENCE,def_cgsize(resultdef),4);
  126. location.reference.arrayreftype:=art_indexconst;
  127. location.reference.base:=hlcg.getaddressregister(current_asmdata.CurrAsmList,java_jlobject);
  128. hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,java_jlobject,java_jlobject,tparavarsym(symtableentry).localloc,location.reference.base);
  129. location.reference.indexoffset:=0;
  130. end
  131. else
  132. inherited pass_generate_code;
  133. end;
  134. { tjvmarrayconstructornode }
  135. procedure tjvmarrayconstructornode.makearrayref(var ref: treference; eledef: tdef);
  136. var
  137. basereg: tregister;
  138. begin
  139. { arrays are implicitly dereferenced }
  140. basereg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,java_jlobject);
  141. hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,java_jlobject,java_jlobject,ref,basereg);
  142. reference_reset_base(ref,basereg,0,1);
  143. ref.arrayreftype:=art_indexconst;
  144. ref.indexoffset:=0;
  145. end;
  146. procedure tjvmarrayconstructornode.advancearrayoffset(var ref: treference; elesize: asizeint);
  147. begin
  148. inc(ref.indexoffset);
  149. end;
  150. begin
  151. cloadnode:=tjvmloadnode;
  152. cassignmentnode:=tjvmassignmentnode;
  153. carrayconstructornode:=tjvmarrayconstructornode;
  154. end.