jvmdef.pas 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. 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: ansistring; 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. function jvmaddencodedtype(def: tdef; bpacked: boolean; var encodedstr: ansistring; out founderror: tdef): boolean;
  32. implementation
  33. uses
  34. globtype,
  35. cutils,cclasses,
  36. verbose,systems,
  37. symtable,symconst,symsym,symdef,
  38. defutil,paramgr;
  39. {******************************************************************
  40. Type encoding
  41. *******************************************************************}
  42. function jvmaddencodedtype(def: tdef; bpacked: boolean; var encodedstr: ansistring; out founderror: tdef): boolean;
  43. var
  44. recname: ansistring;
  45. recdef: trecorddef;
  46. objdef: tobjectdef;
  47. len: aint;
  48. c: char;
  49. addrpara: boolean;
  50. begin
  51. result:=true;
  52. case def.typ of
  53. stringdef :
  54. begin
  55. case tstringdef(def).stringtype of
  56. { translated into Java.Lang.String }
  57. st_widestring:
  58. encodedstr:=encodedstr+'Ljava/lang/String;';
  59. else
  60. { May be handled via wrapping later }
  61. result:=false;
  62. end;
  63. end;
  64. enumdef,
  65. orddef :
  66. begin
  67. { for procedure "results" }
  68. if is_void(def) then
  69. c:='V'
  70. { only Pascal-style booleans conform to Java's definition of
  71. Boolean }
  72. else if is_pasbool(def) and
  73. (def.size=1) then
  74. c:='Z'
  75. else if is_widechar(def) then
  76. c:='C'
  77. else
  78. begin
  79. case def.size of
  80. 1:
  81. c:='B';
  82. 2:
  83. c:='S';
  84. 4:
  85. c:='I';
  86. 8:
  87. c:='J';
  88. else
  89. internalerror(2010121905);
  90. end;
  91. end;
  92. encodedstr:=encodedstr+c;
  93. end;
  94. pointerdef :
  95. begin
  96. { some may be handled via wrapping later }
  97. result:=false;
  98. end;
  99. floatdef :
  100. begin
  101. case tfloatdef(def).floattype of
  102. s32real:
  103. c:='F';
  104. s64real:
  105. c:='D';
  106. else
  107. result:=false;
  108. end;
  109. encodedstr:=encodedstr+c;
  110. end;
  111. filedef :
  112. result:=false;
  113. recorddef :
  114. begin
  115. { will be hanlded via wrapping later, although wrapping may
  116. happen at higher level }
  117. result:=false;
  118. end;
  119. variantdef :
  120. begin
  121. { will be hanlded via wrapping later, although wrapping may
  122. happen at higher level }
  123. result:=false;
  124. end;
  125. classrefdef :
  126. begin
  127. { may be handled via wrapping later }
  128. result:=false;
  129. end;
  130. setdef :
  131. begin
  132. { will be hanlded via wrapping later, although wrapping may
  133. happen at higher level }
  134. result:=false;
  135. end;
  136. formaldef :
  137. begin
  138. { not supported (may be changed into "java.lang.Object" later) }
  139. result:=false;
  140. end;
  141. arraydef :
  142. begin
  143. if is_array_of_const(def) or
  144. is_open_array(def) or
  145. is_packed_array(def) then
  146. result:=false
  147. else
  148. begin
  149. encodedstr:=encodedstr+'[';
  150. if not jvmaddencodedtype(tarraydef(def).elementdef,false,encodedstr,founderror) then
  151. begin
  152. result:=false;
  153. { report the exact (nested) error defintion }
  154. exit;
  155. end;
  156. end;
  157. end;
  158. procvardef :
  159. begin
  160. { will be hanlded via wrapping later, although wrapping may
  161. happen at higher level }
  162. result:=false;
  163. end;
  164. objectdef :
  165. case tobjectdef(def).objecttype of
  166. odt_javaclass,
  167. odt_interfacejava:
  168. begin
  169. encodedstr:=encodedstr+'L';
  170. if assigned(tobjectdef(def).import_lib) then
  171. encodedstr:=encodedstr+tobjectdef(def).import_lib^+'/';
  172. encodedstr:=encodedstr+tobjectdef(def).objextname^+';';
  173. end
  174. else
  175. result:=false;
  176. end;
  177. undefineddef,
  178. errordef :
  179. result:=false;
  180. procdef :
  181. { must be done via jvmencodemethod() }
  182. internalerror(2010121903);
  183. else
  184. internalerror(2010121904);
  185. end;
  186. if not result then
  187. founderror:=def;
  188. end;
  189. function jvmtryencodetype(def: tdef; out encodedtype: ansistring; out founderror: tdef): boolean;
  190. begin
  191. result:=jvmaddencodedtype(def,false,encodedtype,founderror);
  192. end;
  193. {******************************************************************
  194. jvm type validity checking
  195. *******************************************************************}
  196. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  197. var
  198. encodedtype: ansistring;
  199. begin
  200. { don't duplicate the code like in objcdef, since the resulting strings
  201. are much shorter here so it's not worth it }
  202. result:=jvmtryencodetype(def,encodedtype,founderror);
  203. end;
  204. end.