jvmdef.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. {
  2. Copyright (c) 2010 by Jonas Maebe
  3. This unit implements some JVM type helper routines (minimal
  4. unit dependencies, usable in symdef).
  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. {$i fpcdefs.inc}
  19. unit jvmdef;
  20. interface
  21. uses
  22. node,
  23. symbase,symtype;
  24. { Encode a type into the internal format used by the JVM (descriptor).
  25. Returns false if a type is not representable by the JVM,
  26. and in that case also the failing definition. }
  27. function jvmtryencodetype(def: tdef; out encodedtype: string; out founderror: tdef): boolean;
  28. { Check whether a type can be used in a JVM methom signature or field
  29. declaration. }
  30. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  31. { incremental version of jvmtryencodetype() }
  32. function jvmaddencodedtype(def: tdef; bpacked: boolean; var encodedstr: string; out founderror: tdef): boolean;
  33. { add type prefix (package name) to a type }
  34. procedure jvmaddtypeownerprefix(owner: tsymtable; var name: string);
  35. { generate internal static field name based on regular field name }
  36. function jvminternalstaticfieldname(const fieldname: string): string;
  37. implementation
  38. uses
  39. globtype,
  40. cutils,cclasses,
  41. verbose,systems,
  42. fmodule,
  43. symtable,symconst,symsym,symdef,
  44. defutil,paramgr;
  45. {******************************************************************
  46. Type encoding
  47. *******************************************************************}
  48. function jvmaddencodedtype(def: tdef; bpacked: boolean; var encodedstr: string; out founderror: tdef): boolean;
  49. var
  50. c: char;
  51. begin
  52. result:=true;
  53. case def.typ of
  54. stringdef :
  55. begin
  56. case tstringdef(def).stringtype of
  57. { translated into Java.Lang.String }
  58. st_widestring:
  59. encodedstr:=encodedstr+'Ljava/lang/String;';
  60. else
  61. { May be handled via wrapping later }
  62. result:=false;
  63. end;
  64. end;
  65. enumdef,
  66. orddef :
  67. begin
  68. { for procedure "results" }
  69. if is_void(def) then
  70. c:='V'
  71. { only Pascal-style booleans conform to Java's definition of
  72. Boolean }
  73. else if is_pasbool(def) and
  74. (def.size=1) then
  75. c:='Z'
  76. else if is_widechar(def) then
  77. c:='C'
  78. else
  79. begin
  80. case def.size of
  81. 1:
  82. c:='B';
  83. 2:
  84. c:='S';
  85. 4:
  86. c:='I';
  87. 8:
  88. c:='J';
  89. else
  90. internalerror(2010121905);
  91. end;
  92. end;
  93. encodedstr:=encodedstr+c;
  94. end;
  95. pointerdef :
  96. begin
  97. { some may be handled via wrapping later }
  98. result:=false;
  99. end;
  100. floatdef :
  101. begin
  102. case tfloatdef(def).floattype of
  103. s32real:
  104. c:='F';
  105. s64real:
  106. c:='D';
  107. else
  108. result:=false;
  109. end;
  110. encodedstr:=encodedstr+c;
  111. end;
  112. filedef :
  113. result:=false;
  114. recorddef :
  115. begin
  116. { will be hanlded via wrapping later, although wrapping may
  117. happen at higher level }
  118. result:=false;
  119. end;
  120. variantdef :
  121. begin
  122. { will be hanlded via wrapping later, although wrapping may
  123. happen at higher level }
  124. result:=false;
  125. end;
  126. classrefdef :
  127. begin
  128. { may be handled via wrapping later }
  129. result:=false;
  130. end;
  131. setdef :
  132. begin
  133. if is_smallset(def) then
  134. encodedstr:=encodedstr+'I'
  135. else
  136. { will be hanlded via wrapping later, although wrapping may
  137. happen at higher level }
  138. result:=false;
  139. end;
  140. formaldef :
  141. begin
  142. { not supported (may be changed into "java.lang.Object" later) }
  143. result:=false;
  144. end;
  145. arraydef :
  146. begin
  147. if is_array_of_const(def) or
  148. is_open_array(def) or
  149. is_packed_array(def) then
  150. result:=false
  151. else
  152. begin
  153. encodedstr:=encodedstr+'[';
  154. if not jvmaddencodedtype(tarraydef(def).elementdef,false,encodedstr,founderror) then
  155. begin
  156. result:=false;
  157. { report the exact (nested) error defintion }
  158. exit;
  159. end;
  160. end;
  161. end;
  162. procvardef :
  163. begin
  164. { will be hanlded via wrapping later, although wrapping may
  165. happen at higher level }
  166. result:=false;
  167. end;
  168. objectdef :
  169. case tobjectdef(def).objecttype of
  170. odt_javaclass,
  171. odt_interfacejava:
  172. encodedstr:=encodedstr+'L'+tobjectdef(def).jvm_full_typename+';'
  173. else
  174. result:=false;
  175. end;
  176. undefineddef,
  177. errordef :
  178. result:=false;
  179. procdef :
  180. { must be done via jvmencodemethod() }
  181. internalerror(2010121903);
  182. else
  183. internalerror(2010121904);
  184. end;
  185. if not result then
  186. founderror:=def;
  187. end;
  188. function jvmtryencodetype(def: tdef; out encodedtype: string; out founderror: tdef): boolean;
  189. begin
  190. encodedtype:='';
  191. result:=jvmaddencodedtype(def,false,encodedtype,founderror);
  192. end;
  193. procedure jvmaddtypeownerprefix(owner: tsymtable; var name: string);
  194. var
  195. owningunit: tsymtable;
  196. tmpresult: string;
  197. begin
  198. { see tprocdef.jvmmangledbasename for description of the format }
  199. case owner.symtabletype of
  200. globalsymtable,
  201. staticsymtable,
  202. localsymtable:
  203. begin
  204. owningunit:=owner;
  205. while (owningunit.symtabletype in [localsymtable,objectsymtable,recordsymtable]) do
  206. owningunit:=owningunit.defowner.owner;
  207. tmpresult:=find_module_from_symtable(owningunit).realmodulename^+'/';
  208. end;
  209. objectsymtable:
  210. case tobjectdef(owner.defowner).objecttype of
  211. odt_javaclass,
  212. odt_interfacejava:
  213. begin
  214. tmpresult:=tobjectdef(owner.defowner).jvm_full_typename+'/'
  215. end
  216. else
  217. internalerror(2010122606);
  218. end
  219. else
  220. internalerror(2010122605);
  221. end;
  222. name:=tmpresult+name;
  223. end;
  224. function jvminternalstaticfieldname(const fieldname: string): string;
  225. begin
  226. result:='$_static_'+fieldname;
  227. end;
  228. {******************************************************************
  229. jvm type validity checking
  230. *******************************************************************}
  231. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  232. var
  233. encodedtype: string;
  234. begin
  235. { don't duplicate the code like in objcdef, since the resulting strings
  236. are much shorter here so it's not worth it }
  237. result:=jvmtryencodetype(def,encodedtype,founderror);
  238. end;
  239. end.