ngenutil.pas 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. {
  2. Copyright (c) 1998-20011 by Florian Klaempfl
  3. Generic version of some node tree helper routines that can be overridden
  4. by cpu-specific versions
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit ngenutil;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node;
  23. type
  24. tnodeutils = class
  25. class function call_fail_node:tnode; virtual;
  26. class function initialize_data_node(p:tnode):tnode; virtual;
  27. class function finalize_data_node(p:tnode):tnode; virtual;
  28. end;
  29. tnodeutilsclass = class of tnodeutils;
  30. const
  31. cnodeutils: tnodeutilsclass = tnodeutils;
  32. implementation
  33. uses
  34. verbose,constexp,
  35. symconst,symtype,symdef,symsym,symbase,symtable,defutil,
  36. nadd,nbas,ncal,ncnv,ncon,nflw,nld,nmem,nobj,nutils,
  37. pass_1;
  38. class function tnodeutils.call_fail_node:tnode;
  39. var
  40. para : tcallparanode;
  41. newstatement : tstatementnode;
  42. srsym : tsym;
  43. begin
  44. result:=internalstatements(newstatement);
  45. { call fail helper and exit normal }
  46. if is_class(current_structdef) then
  47. begin
  48. srsym:=search_struct_member(current_structdef,'FREEINSTANCE');
  49. if assigned(srsym) and
  50. (srsym.typ=procsym) then
  51. begin
  52. { if self<>0 and vmt<>0 then freeinstance }
  53. addstatement(newstatement,cifnode.create(
  54. caddnode.create(andn,
  55. caddnode.create(unequaln,
  56. load_self_pointer_node,
  57. cnilnode.create),
  58. caddnode.create(unequaln,
  59. load_vmt_pointer_node,
  60. cnilnode.create)),
  61. ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
  62. nil));
  63. end
  64. else
  65. internalerror(200305108);
  66. end
  67. else
  68. if is_object(current_structdef) then
  69. begin
  70. { parameter 3 : vmt_offset }
  71. { parameter 2 : pointer to vmt }
  72. { parameter 1 : self pointer }
  73. para:=ccallparanode.create(
  74. cordconstnode.create(tobjectdef(current_structdef).vmt_offset,s32inttype,false),
  75. ccallparanode.create(
  76. ctypeconvnode.create_internal(
  77. load_vmt_pointer_node,
  78. voidpointertype),
  79. ccallparanode.create(
  80. ctypeconvnode.create_internal(
  81. load_self_pointer_node,
  82. voidpointertype),
  83. nil)));
  84. addstatement(newstatement,
  85. ccallnode.createintern('fpc_help_fail',para));
  86. end
  87. else
  88. internalerror(200305132);
  89. { self:=nil }
  90. addstatement(newstatement,cassignmentnode.create(
  91. load_self_pointer_node,
  92. cnilnode.create));
  93. { exit }
  94. addstatement(newstatement,cexitnode.create(nil));
  95. end;
  96. class function tnodeutils.initialize_data_node(p:tnode):tnode;
  97. begin
  98. if not assigned(p.resultdef) then
  99. typecheckpass(p);
  100. if is_ansistring(p.resultdef) or
  101. is_wide_or_unicode_string(p.resultdef) or
  102. is_interfacecom_or_dispinterface(p.resultdef) or
  103. is_dynamic_array(p.resultdef) then
  104. begin
  105. result:=cassignmentnode.create(
  106. ctypeconvnode.create_internal(p,voidpointertype),
  107. cnilnode.create
  108. );
  109. end
  110. else
  111. begin
  112. result:=ccallnode.createintern('fpc_initialize',
  113. ccallparanode.create(
  114. caddrnode.create_internal(
  115. crttinode.create(
  116. tstoreddef(p.resultdef),initrtti,rdt_normal)),
  117. ccallparanode.create(
  118. caddrnode.create_internal(p),
  119. nil)));
  120. end;
  121. end;
  122. class function tnodeutils.finalize_data_node(p:tnode):tnode;
  123. var
  124. newstatement : tstatementnode;
  125. begin
  126. if not assigned(p.resultdef) then
  127. typecheckpass(p);
  128. if is_ansistring(p.resultdef) then
  129. begin
  130. result:=internalstatements(newstatement);
  131. addstatement(newstatement,ccallnode.createintern('fpc_ansistr_decr_ref',
  132. ccallparanode.create(
  133. ctypeconvnode.create_internal(p,voidpointertype),
  134. nil)));
  135. addstatement(newstatement,cassignmentnode.create(
  136. ctypeconvnode.create_internal(p.getcopy,voidpointertype),
  137. cnilnode.create
  138. ));
  139. end
  140. else if is_widestring(p.resultdef) then
  141. begin
  142. result:=internalstatements(newstatement);
  143. addstatement(newstatement,ccallnode.createintern('fpc_widestr_decr_ref',
  144. ccallparanode.create(
  145. ctypeconvnode.create_internal(p,voidpointertype),
  146. nil)));
  147. addstatement(newstatement,cassignmentnode.create(
  148. ctypeconvnode.create_internal(p.getcopy,voidpointertype),
  149. cnilnode.create
  150. ));
  151. end
  152. else if is_unicodestring(p.resultdef) then
  153. begin
  154. result:=internalstatements(newstatement);
  155. addstatement(newstatement,ccallnode.createintern('fpc_unicodestr_decr_ref',
  156. ccallparanode.create(
  157. ctypeconvnode.create_internal(p,voidpointertype),
  158. nil)));
  159. addstatement(newstatement,cassignmentnode.create(
  160. ctypeconvnode.create_internal(p.getcopy,voidpointertype),
  161. cnilnode.create
  162. ));
  163. end
  164. else if is_interfacecom_or_dispinterface(p.resultdef) then
  165. begin
  166. result:=internalstatements(newstatement);
  167. addstatement(newstatement,ccallnode.createintern('fpc_intf_decr_ref',
  168. ccallparanode.create(
  169. ctypeconvnode.create_internal(p,voidpointertype),
  170. nil)));
  171. addstatement(newstatement,cassignmentnode.create(
  172. ctypeconvnode.create_internal(p.getcopy,voidpointertype),
  173. cnilnode.create
  174. ));
  175. end
  176. else
  177. result:=ccallnode.createintern('fpc_finalize',
  178. ccallparanode.create(
  179. caddrnode.create_internal(
  180. crttinode.create(
  181. tstoreddef(p.resultdef),initrtti,rdt_normal)),
  182. ccallparanode.create(
  183. caddrnode.create_internal(p),
  184. nil)));
  185. end;
  186. end.