jvmdef.pas 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  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. globtype,
  23. node,
  24. symbase,symtype;
  25. { returns whether a def can make use of an extra type signature (for
  26. Java-style generics annotations; not use for FPC-style generics or their
  27. translations, but to annotate the kind of classref a java.lang.Class is
  28. and things like that) }
  29. function jvmtypeneedssignature(def: tdef): boolean;
  30. { create a signature encoding of a particular type; requires that
  31. jvmtypeneedssignature returned "true" for this type }
  32. procedure jvmaddencodedsignature(def: tdef; bpacked: boolean; var encodedstr: TSymStr);
  33. { Encode a type into the internal format used by the JVM (descriptor).
  34. Returns false if a type is not representable by the JVM,
  35. and in that case also the failing definition. }
  36. function jvmtryencodetype(def: tdef; out encodedtype: TSymStr; forcesignature: boolean; out founderror: tdef): boolean;
  37. { same as above, but throws an internal error on failure }
  38. function jvmencodetype(def: tdef; withsignature: boolean): TSymStr;
  39. { Check whether a type can be used in a JVM methom signature or field
  40. declaration. }
  41. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  42. { incremental version of jvmtryencodetype() }
  43. function jvmaddencodedtype(def: tdef; bpacked: boolean; var encodedstr: TSymStr; forcesignature: boolean; out founderror: tdef): boolean;
  44. { add type prefix (package name) to a type }
  45. procedure jvmaddtypeownerprefix(owner: tsymtable; var name: TSymStr);
  46. { returns type string for a single-dimensional array (different from normal
  47. typestring in case of a primitive type) }
  48. function jvmarrtype(def: tdef; out primitivetype: boolean): TSymStr;
  49. function jvmarrtype_setlength(def: tdef): char;
  50. { returns whether a def is emulated using an implicit pointer type on the
  51. JVM target (e.g., records, regular arrays, ...) }
  52. function jvmimplicitpointertype(def: tdef): boolean;
  53. { returns the mangled base name for a tsym (type + symbol name, no
  54. visibility etc); also adds signature attribute if requested and
  55. appropriate }
  56. function jvmmangledbasename(sym: tsym; withsignature: boolean): TSymStr;
  57. function jvmmangledbasename(sym: tsym; const usesymname: TSymStr; withsignature: boolean): TSymStr;
  58. { sometimes primitive types have to be boxed/unboxed via class types. This
  59. routine returns the appropriate box type for the passed primitive type }
  60. procedure jvmgetboxtype(def: tdef; out objdef, paradef: tdef; mergeints: boolean);
  61. function jvmgetunboxmethod(def: tdef): string;
  62. function jvmgetcorrespondingclassdef(def: tdef): tdef;
  63. function get_para_push_size(def: tdef): tdef;
  64. { threadvars are wrapped via descendents of java.lang.ThreadLocal }
  65. function jvmgetthreadvardef(def: tdef): tdef;
  66. { gets the number of dimensions and the final element type of a normal
  67. array }
  68. procedure jvmgetarraydimdef(arrdef: tdef; out eledef: tdef; out ndim: longint);
  69. implementation
  70. uses
  71. cutils,cclasses,constexp,
  72. verbose,systems,
  73. fmodule,
  74. symtable,symconst,symsym,symdef,symcpu,symcreat,
  75. defutil,paramgr;
  76. {******************************************************************
  77. Type encoding
  78. *******************************************************************}
  79. function jvmtypeneedssignature(def: tdef): boolean;
  80. var
  81. i: longint;
  82. begin
  83. result:=false;
  84. case def.typ of
  85. classrefdef,
  86. setdef:
  87. begin
  88. result:=true;
  89. end;
  90. arraydef :
  91. begin
  92. result:=jvmtypeneedssignature(tarraydef(def).elementdef);
  93. end;
  94. procvardef :
  95. begin
  96. { may change in the future }
  97. end;
  98. procdef :
  99. begin
  100. for i:=0 to tprocdef(def).paras.count-1 do
  101. begin
  102. result:=jvmtypeneedssignature(tparavarsym(tprocdef(def).paras[i]).vardef);
  103. if result then
  104. exit;
  105. end;
  106. end
  107. else
  108. result:=false;
  109. end;
  110. end;
  111. procedure jvmaddencodedsignature(def: tdef; bpacked: boolean; var encodedstr: TSymStr);
  112. var
  113. founderror: tdef;
  114. begin
  115. case def.typ of
  116. pointerdef :
  117. begin
  118. { maybe one day }
  119. internalerror(2011051403);
  120. end;
  121. classrefdef :
  122. begin
  123. { Ljava/lang/Class<+SomeClassType> means
  124. "Ljava/lang/Class<SomeClassType_or_any_of_its_descendents>" }
  125. encodedstr:=encodedstr+'Ljava/lang/Class<+';
  126. jvmaddencodedtype(tclassrefdef(def).pointeddef,false,encodedstr,true,founderror);
  127. encodedstr:=encodedstr+'>;';
  128. end;
  129. setdef :
  130. begin
  131. if tsetdef(def).elementdef.typ=enumdef then
  132. begin
  133. encodedstr:=encodedstr+'Ljava/util/EnumSet<';
  134. jvmaddencodedtype(tenumdef(tsetdef(def).elementdef).getbasedef,false,encodedstr,true,founderror);
  135. encodedstr:=encodedstr+'>;';
  136. end
  137. else
  138. internalerror(2011051404);
  139. end;
  140. arraydef :
  141. begin
  142. if is_array_of_const(def) then
  143. begin
  144. internalerror(2011051405);
  145. end
  146. else if is_packed_array(def) then
  147. begin
  148. internalerror(2011051406);
  149. end
  150. else
  151. begin
  152. encodedstr:=encodedstr+'[';
  153. jvmaddencodedsignature(tarraydef(def).elementdef,false,encodedstr);
  154. end;
  155. end;
  156. procvardef :
  157. begin
  158. { maybe one day }
  159. internalerror(2011051407);
  160. end;
  161. objectdef :
  162. begin
  163. { maybe one day }
  164. end;
  165. undefineddef,
  166. errordef :
  167. begin
  168. internalerror(2011051408);
  169. end;
  170. procdef :
  171. { must be done via jvmencodemethod() }
  172. internalerror(2011051401);
  173. else
  174. internalerror(2011051402);
  175. end;
  176. end;
  177. function jvmaddencodedtype(def: tdef; bpacked: boolean; var encodedstr: TSymStr; forcesignature: boolean; out founderror: tdef): boolean;
  178. var
  179. c: char;
  180. begin
  181. result:=true;
  182. case def.typ of
  183. stringdef :
  184. begin
  185. case tstringdef(def).stringtype of
  186. { translated into java.lang.String }
  187. st_widestring,
  188. st_unicodestring:
  189. result:=jvmaddencodedtype(java_jlstring,false,encodedstr,forcesignature,founderror);
  190. st_ansistring:
  191. result:=jvmaddencodedtype(java_ansistring,false,encodedstr,forcesignature,founderror);
  192. st_shortstring:
  193. result:=jvmaddencodedtype(java_shortstring,false,encodedstr,forcesignature,founderror);
  194. else
  195. { May be handled via wrapping later }
  196. result:=false;
  197. end;
  198. end;
  199. enumdef:
  200. begin
  201. result:=jvmaddencodedtype(tcpuenumdef(tenumdef(def).getbasedef).classdef,false,encodedstr,forcesignature,founderror);
  202. end;
  203. orddef :
  204. begin
  205. { for procedure "results" }
  206. if is_void(def) then
  207. c:='V'
  208. { only Pascal-style booleans conform to Java's definition of
  209. Boolean }
  210. else if is_pasbool(def) and
  211. (def.size=1) then
  212. c:='Z'
  213. else if is_widechar(def) then
  214. c:='C'
  215. else
  216. begin
  217. case def.size of
  218. 1:
  219. c:='B';
  220. 2:
  221. c:='S';
  222. 4:
  223. c:='I';
  224. 8:
  225. c:='J';
  226. else
  227. internalerror(2010121905);
  228. end;
  229. end;
  230. encodedstr:=encodedstr+c;
  231. end;
  232. pointerdef :
  233. begin
  234. if is_voidpointer(def) then
  235. result:=jvmaddencodedtype(java_jlobject,false,encodedstr,forcesignature,founderror)
  236. else if jvmimplicitpointertype(tpointerdef(def).pointeddef) then
  237. result:=jvmaddencodedtype(tpointerdef(def).pointeddef,false,encodedstr,forcesignature,founderror)
  238. else
  239. begin
  240. { all pointer types are emulated via arrays }
  241. encodedstr:=encodedstr+'[';
  242. result:=jvmaddencodedtype(tpointerdef(def).pointeddef,false,encodedstr,forcesignature,founderror);
  243. end
  244. end;
  245. floatdef :
  246. begin
  247. case tfloatdef(def).floattype of
  248. s32real:
  249. c:='F';
  250. s64real:
  251. c:='D';
  252. else
  253. begin
  254. result:=false;
  255. c:=' ';
  256. end;
  257. end;
  258. encodedstr:=encodedstr+c;
  259. end;
  260. filedef :
  261. begin
  262. case tfiledef(def).filetyp of
  263. ft_text:
  264. result:=jvmaddencodedtype(search_system_type('TEXTREC').typedef,false,encodedstr,forcesignature,founderror);
  265. ft_typed,
  266. ft_untyped:
  267. result:=jvmaddencodedtype(search_system_type('FILEREC').typedef,false,encodedstr,forcesignature,founderror);
  268. else
  269. internalerror(2015091406);
  270. end;
  271. end;
  272. recorddef :
  273. begin
  274. encodedstr:=encodedstr+'L'+trecorddef(def).jvm_full_typename(true)+';'
  275. end;
  276. variantdef :
  277. begin
  278. { will be hanlded via wrapping later, although wrapping may
  279. happen at higher level }
  280. result:=false;
  281. end;
  282. classrefdef :
  283. begin
  284. if not forcesignature then
  285. { unfortunately, java.lang.Class is final, so we can't create
  286. different versions for difference class reference types }
  287. encodedstr:=encodedstr+'Ljava/lang/Class;'
  288. { we can however annotate it with extra signature information in
  289. using Java's generic annotations }
  290. else
  291. jvmaddencodedsignature(def,false,encodedstr);
  292. result:=true;
  293. end;
  294. setdef :
  295. begin
  296. if tsetdef(def).elementdef.typ=enumdef then
  297. begin
  298. if forcesignature then
  299. jvmaddencodedsignature(def,false,encodedstr)
  300. else
  301. result:=jvmaddencodedtype(java_juenumset,false,encodedstr,forcesignature,founderror)
  302. end
  303. else
  304. result:=jvmaddencodedtype(java_jubitset,false,encodedstr,forcesignature,founderror)
  305. end;
  306. formaldef :
  307. begin
  308. { var/const/out x: JLObject }
  309. result:=jvmaddencodedtype(java_jlobject,false,encodedstr,forcesignature,founderror);
  310. end;
  311. arraydef :
  312. begin
  313. if is_array_of_const(def) then
  314. begin
  315. encodedstr:=encodedstr+'[';
  316. result:=jvmaddencodedtype(search_system_type('TVARREC').typedef,false,encodedstr,forcesignature,founderror);
  317. end
  318. else if is_packed_array(def) then
  319. result:=false
  320. else
  321. begin
  322. encodedstr:=encodedstr+'[';
  323. if not jvmaddencodedtype(tarraydef(def).elementdef,false,encodedstr,forcesignature,founderror) then
  324. begin
  325. result:=false;
  326. { report the exact (nested) error defintion }
  327. exit;
  328. end;
  329. end;
  330. end;
  331. procvardef :
  332. begin
  333. result:=jvmaddencodedtype(tcpuprocvardef(def).classdef,false,encodedstr,forcesignature,founderror);
  334. end;
  335. objectdef :
  336. case tobjectdef(def).objecttype of
  337. odt_javaclass,
  338. odt_interfacejava:
  339. begin
  340. def:=maybe_find_real_class_definition(def,false);
  341. encodedstr:=encodedstr+'L'+tobjectdef(def).jvm_full_typename(true)+';'
  342. end
  343. else
  344. result:=false;
  345. end;
  346. undefineddef,
  347. errordef :
  348. result:=false;
  349. procdef :
  350. { must be done via jvmencodemethod() }
  351. internalerror(2010121903);
  352. else
  353. internalerror(2010121904);
  354. end;
  355. if not result then
  356. founderror:=def;
  357. end;
  358. function jvmtryencodetype(def: tdef; out encodedtype: TSymStr; forcesignature: boolean; out founderror: tdef): boolean;
  359. begin
  360. encodedtype:='';
  361. result:=jvmaddencodedtype(def,false,encodedtype,forcesignature,founderror);
  362. end;
  363. procedure jvmaddtypeownerprefix(owner: tsymtable; var name: TSymStr);
  364. var
  365. owningcontainer: tsymtable;
  366. tmpresult: TSymStr;
  367. module: tmodule;
  368. nameendpos: longint;
  369. begin
  370. { see tprocdef.jvmmangledbasename for description of the format }
  371. owningcontainer:=owner;
  372. while (owningcontainer.symtabletype=localsymtable) do
  373. owningcontainer:=owningcontainer.defowner.owner;
  374. case owningcontainer.symtabletype of
  375. globalsymtable,
  376. staticsymtable:
  377. begin
  378. module:=find_module_from_symtable(owningcontainer);
  379. tmpresult:='';
  380. if assigned(module.namespace) then
  381. tmpresult:=module.namespace^+'/';
  382. tmpresult:=tmpresult+module.realmodulename^+'/';
  383. end;
  384. objectsymtable:
  385. case tobjectdef(owningcontainer.defowner).objecttype of
  386. odt_javaclass,
  387. odt_interfacejava:
  388. begin
  389. tmpresult:=tobjectdef(owningcontainer.defowner).jvm_full_typename(true)+'/'
  390. end
  391. else
  392. internalerror(2010122606);
  393. end;
  394. recordsymtable:
  395. tmpresult:=trecorddef(owningcontainer.defowner).jvm_full_typename(true)+'/'
  396. else
  397. internalerror(2010122605);
  398. end;
  399. name:=tmpresult+name;
  400. nameendpos:=pos(' ',name);
  401. if nameendpos=0 then
  402. nameendpos:=length(name)+1;
  403. insert('''',name,nameendpos);
  404. name:=''''+name;
  405. end;
  406. function jvmarrtype(def: tdef; out primitivetype: boolean): TSymStr;
  407. var
  408. errdef: tdef;
  409. begin
  410. if not jvmtryencodetype(def,result,false,errdef) then
  411. internalerror(2011012205);
  412. primitivetype:=false;
  413. if length(result)=1 then
  414. begin
  415. case result[1] of
  416. 'Z': result:='boolean';
  417. 'C': result:='char';
  418. 'B': result:='byte';
  419. 'S': result:='short';
  420. 'I': result:='int';
  421. 'J': result:='long';
  422. 'F': result:='float';
  423. 'D': result:='double';
  424. else
  425. internalerror(2011012206);
  426. end;
  427. primitivetype:=true;
  428. end
  429. else if (result[1]='L') then
  430. begin
  431. { in case of a class reference, strip the leading 'L' and the
  432. trailing ';' }
  433. setlength(result,length(result)-1);
  434. delete(result,1,1);
  435. end;
  436. { for arrays, use the actual reference type }
  437. end;
  438. function jvmarrtype_setlength(def: tdef): char;
  439. var
  440. errdef: tdef;
  441. res: TSymStr;
  442. begin
  443. { keep in sync with rtl/java/jdynarrh.inc and usage in njvminl }
  444. if is_record(def) then
  445. result:='R'
  446. else if is_shortstring(def) then
  447. result:='T'
  448. else if def.typ=setdef then
  449. begin
  450. if tsetdef(def).elementdef.typ=enumdef then
  451. result:='E'
  452. else
  453. result:='L'
  454. end
  455. else if (def.typ=procvardef) and
  456. not tprocvardef(def).is_addressonly then
  457. result:='P'
  458. else
  459. begin
  460. if not jvmtryencodetype(def,res,false,errdef) then
  461. internalerror(2011012209);
  462. if length(res)=1 then
  463. result:=res[1]
  464. else
  465. result:='A';
  466. end;
  467. end;
  468. function jvmimplicitpointertype(def: tdef): boolean;
  469. begin
  470. case def.typ of
  471. arraydef:
  472. result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
  473. is_open_array(def) or
  474. is_array_of_const(def) or
  475. is_array_constructor(def);
  476. filedef,
  477. recorddef,
  478. setdef:
  479. result:=true;
  480. objectdef:
  481. result:=is_object(def);
  482. stringdef :
  483. result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
  484. procvardef:
  485. result:=not tprocvardef(def).is_addressonly;
  486. else
  487. result:=false;
  488. end;
  489. end;
  490. { mergeints = true means that all integer types are mapped to jllong,
  491. otherwise they are mapped to the closest corresponding type }
  492. procedure jvmgetboxtype(def: tdef; out objdef, paradef: tdef; mergeints: boolean);
  493. begin
  494. case def.typ of
  495. orddef:
  496. begin
  497. case torddef(def).ordtype of
  498. pasbool1,
  499. pasbool8:
  500. begin
  501. objdef:=tobjectdef(search_system_type('JLBOOLEAN').typedef);
  502. paradef:=pasbool8type;
  503. end;
  504. uwidechar:
  505. begin
  506. objdef:=tobjectdef(search_system_type('JLCHARACTER').typedef);
  507. paradef:=cwidechartype;
  508. end;
  509. else
  510. begin
  511. { wrap all integer types into a JLLONG, so that we don't get
  512. errors after returning a byte assigned to a long etc }
  513. if mergeints or
  514. (torddef(def).ordtype in [s64bit,u64bit,scurrency,bool64bit,pasbool64]) then
  515. begin
  516. objdef:=tobjectdef(search_system_type('JLLONG').typedef);
  517. paradef:=s64inttype;
  518. end
  519. else
  520. begin
  521. case torddef(def).ordtype of
  522. s8bit,
  523. u8bit,
  524. uchar,
  525. bool8bit:
  526. begin
  527. objdef:=tobjectdef(search_system_type('JLBYTE').typedef);
  528. paradef:=s8inttype;
  529. end;
  530. s16bit,
  531. u16bit,
  532. bool16bit,
  533. pasbool16:
  534. begin
  535. objdef:=tobjectdef(search_system_type('JLSHORT').typedef);
  536. paradef:=s16inttype;
  537. end;
  538. s32bit,
  539. u32bit,
  540. bool32bit,
  541. pasbool32:
  542. begin
  543. objdef:=tobjectdef(search_system_type('JLINTEGER').typedef);
  544. paradef:=s32inttype;
  545. end;
  546. else
  547. internalerror(2011052101);
  548. end;
  549. end;
  550. end;
  551. end;
  552. end;
  553. floatdef:
  554. begin
  555. case tfloatdef(def).floattype of
  556. s32real:
  557. begin
  558. objdef:=tobjectdef(search_system_type('JLFLOAT').typedef);
  559. paradef:=s32floattype;
  560. end;
  561. s64real:
  562. begin
  563. objdef:=tobjectdef(search_system_type('JLDOUBLE').typedef);
  564. paradef:=s64floattype;
  565. end;
  566. else
  567. internalerror(2011052102);
  568. end;
  569. end;
  570. else
  571. internalerror(2011052103);
  572. end;
  573. end;
  574. function jvmgetunboxmethod(def: tdef): string;
  575. begin
  576. case def.typ of
  577. orddef:
  578. begin
  579. case torddef(def).ordtype of
  580. pasbool1,
  581. pasbool8:
  582. result:='BOOLEANVALUE';
  583. s8bit,
  584. u8bit,
  585. uchar,
  586. bool8bit:
  587. result:='BYTEVALUE';
  588. s16bit,
  589. u16bit,
  590. bool16bit,
  591. pasbool16:
  592. result:='SHORTVALUE';
  593. s32bit,
  594. u32bit,
  595. bool32bit,
  596. pasbool32:
  597. result:='INTVALUE';
  598. s64bit,
  599. u64bit,
  600. scurrency,
  601. bool64bit,
  602. pasbool64:
  603. result:='LONGVALUE';
  604. uwidechar:
  605. result:='CHARVALUE';
  606. else
  607. internalerror(2011071702);
  608. end;
  609. end;
  610. floatdef:
  611. begin
  612. case tfloatdef(def).floattype of
  613. s32real:
  614. result:='FLOATVALUE';
  615. s64real:
  616. result:='DOUBLEVALUE';
  617. else
  618. internalerror(2011071703);
  619. end;
  620. end;
  621. else
  622. internalerror(2011071704);
  623. end;
  624. end;
  625. function jvmgetcorrespondingclassdef(def: tdef): tdef;
  626. var
  627. paradef: tdef;
  628. begin
  629. if def.typ in [orddef,floatdef] then
  630. jvmgetboxtype(def,result,paradef,false)
  631. else
  632. begin
  633. case def.typ of
  634. stringdef :
  635. begin
  636. case tstringdef(def).stringtype of
  637. { translated into java.lang.String }
  638. st_widestring,
  639. st_unicodestring:
  640. result:=java_jlstring;
  641. st_ansistring:
  642. result:=java_ansistring;
  643. st_shortstring:
  644. result:=java_shortstring;
  645. else
  646. internalerror(2011072409);
  647. end;
  648. end;
  649. enumdef:
  650. begin
  651. result:=tcpuenumdef(tenumdef(def).getbasedef).classdef;
  652. end;
  653. pointerdef :
  654. begin
  655. if def=voidpointertype then
  656. result:=java_jlobject
  657. else if jvmimplicitpointertype(tpointerdef(def).pointeddef) then
  658. result:=tpointerdef(def).pointeddef
  659. else
  660. internalerror(2011072410);
  661. end;
  662. recorddef :
  663. begin
  664. result:=def;
  665. end;
  666. variantdef :
  667. begin
  668. result:=cvarianttype;
  669. end;
  670. classrefdef :
  671. begin
  672. result:=search_system_type('JLCLASS').typedef;
  673. end;
  674. setdef :
  675. begin
  676. if tsetdef(def).elementdef.typ=enumdef then
  677. result:=java_juenumset
  678. else
  679. result:=java_jubitset;
  680. end;
  681. formaldef :
  682. begin
  683. result:=java_jlobject;
  684. end;
  685. arraydef :
  686. begin
  687. { cannot represent statically }
  688. internalerror(2011072411);
  689. end;
  690. procvardef :
  691. begin
  692. result:=tcpuprocvardef(def).classdef;
  693. end;
  694. objectdef :
  695. case tobjectdef(def).objecttype of
  696. odt_javaclass,
  697. odt_interfacejava:
  698. result:=def
  699. else
  700. internalerror(2011072412);
  701. end;
  702. else
  703. internalerror(2011072413);
  704. end;
  705. end;
  706. end;
  707. function get_para_push_size(def: tdef): tdef;
  708. begin
  709. result:=def;
  710. if def.typ=orddef then
  711. case torddef(def).ordtype of
  712. u8bit,uchar:
  713. if torddef(def).high>127 then
  714. result:=s8inttype;
  715. u16bit:
  716. if torddef(def).high>32767 then
  717. result:=s16inttype;
  718. end;
  719. end;
  720. function jvmgetthreadvardef(def: tdef): tdef;
  721. begin
  722. if (def.typ=arraydef) and
  723. not is_dynamic_array(def) then
  724. begin
  725. result:=search_system_type('FPCNORMALARRAYTHREADVAR').typedef;
  726. exit;
  727. end;
  728. if jvmimplicitpointertype(def) then
  729. begin
  730. result:=search_system_type('FPCIMPLICITPTRTHREADVAR').typedef;
  731. exit;
  732. end;
  733. case def.typ of
  734. orddef:
  735. begin
  736. case torddef(def).ordtype of
  737. pasbool1,
  738. pasbool8:
  739. begin
  740. result:=tobjectdef(search_system_type('FPCBOOLEANTHREADVAR').typedef);
  741. end;
  742. uwidechar:
  743. begin
  744. result:=tobjectdef(search_system_type('FPCCHARTHREADVAR').typedef);
  745. end;
  746. s8bit,
  747. u8bit,
  748. uchar,
  749. bool8bit:
  750. begin
  751. result:=tobjectdef(search_system_type('FPCBYTETHREADVAR').typedef);
  752. end;
  753. s16bit,
  754. u16bit,
  755. bool16bit,
  756. pasbool16:
  757. begin
  758. result:=tobjectdef(search_system_type('FPCSHORTTHREADVAR').typedef);
  759. end;
  760. s32bit,
  761. u32bit,
  762. bool32bit,
  763. pasbool32:
  764. begin
  765. result:=tobjectdef(search_system_type('FPCINTTHREADVAR').typedef);
  766. end;
  767. s64bit,
  768. u64bit,
  769. scurrency,
  770. bool64bit,
  771. pasbool64:
  772. begin
  773. result:=tobjectdef(search_system_type('FPCLONGTHREADVAR').typedef);
  774. end
  775. else
  776. internalerror(2011082101);
  777. end;
  778. end;
  779. floatdef:
  780. begin
  781. case tfloatdef(def).floattype of
  782. s32real:
  783. begin
  784. result:=tobjectdef(search_system_type('FPCFLOATTHREADVAR').typedef);
  785. end;
  786. s64real:
  787. begin
  788. result:=tobjectdef(search_system_type('FPCDOUBLETHREADVAR').typedef);
  789. end;
  790. else
  791. internalerror(2011082102);
  792. end;
  793. end
  794. else
  795. begin
  796. result:=search_system_type('FPCPOINTERTHREADVAR').typedef
  797. end;
  798. end;
  799. end;
  800. procedure jvmgetarraydimdef(arrdef: tdef; out eledef: tdef; out ndim: longint);
  801. begin
  802. eledef:=arrdef;
  803. ndim:=0;
  804. repeat
  805. eledef:=tarraydef(eledef).elementdef;
  806. inc(ndim);
  807. until (eledef.typ<>arraydef) or
  808. is_dynamic_array(eledef);
  809. end;
  810. function jvmmangledbasename(sym: tsym; const usesymname: TSymStr; withsignature: boolean): TSymStr;
  811. var
  812. container: tsymtable;
  813. vsym: tabstractvarsym;
  814. csym: tconstsym;
  815. usedef: tdef;
  816. begin
  817. case sym.typ of
  818. staticvarsym,
  819. paravarsym,
  820. localvarsym,
  821. fieldvarsym:
  822. begin
  823. vsym:=tabstractvarsym(sym);
  824. { for local and paravarsyms that are unsigned 8/16 bit, change the
  825. outputted type to signed 16/32 bit:
  826. a) the stack slots are all 32 bit anyway, so the storage allocation
  827. is still correct
  828. b) since at the JVM level all types are signed, this makes sure
  829. that the values in the stack slots are valid for the specified
  830. types
  831. }
  832. usedef:=vsym.vardef;
  833. if vsym.typ in [localvarsym,paravarsym] then
  834. begin
  835. if (usedef.typ=orddef) then
  836. case torddef(usedef).ordtype of
  837. u8bit,uchar:
  838. usedef:=s16inttype;
  839. u16bit:
  840. usedef:=s32inttype;
  841. end;
  842. end;
  843. result:=jvmencodetype(usedef,false);
  844. if withsignature and
  845. jvmtypeneedssignature(usedef) then
  846. begin
  847. result:=result+' signature "';
  848. result:=result+jvmencodetype(usedef,true)+'"';
  849. end;
  850. if (vsym.typ=paravarsym) and
  851. (vo_is_self in tparavarsym(vsym).varoptions) then
  852. result:='''this'' ' +result
  853. else if (vsym.typ in [paravarsym,localvarsym]) and
  854. ([vo_is_funcret,vo_is_result] * tabstractnormalvarsym(vsym).varoptions <> []) then
  855. result:='''result'' '+result
  856. else
  857. begin
  858. { add array indirection if required }
  859. if (vsym.typ=paravarsym) and
  860. ((usedef.typ=formaldef) or
  861. ((vsym.varspez in [vs_var,vs_out,vs_constref]) and
  862. not jvmimplicitpointertype(usedef))) then
  863. result:='['+result;
  864. { single quotes for definitions to prevent clashes with Java
  865. opcodes }
  866. if withsignature then
  867. result:=usesymname+''' '+result
  868. else
  869. result:=usesymname+' '+result;
  870. { we have to mangle staticvarsyms in localsymtables to
  871. prevent name clashes... }
  872. if (vsym.typ=staticvarsym) then
  873. begin
  874. container:=sym.Owner;
  875. while (container.symtabletype=localsymtable) do
  876. begin
  877. if tdef(container.defowner).typ<>procdef then
  878. internalerror(2011040303);
  879. { unique_id_str is added to prevent problem with overloads }
  880. result:=tprocdef(container.defowner).procsym.realname+'$$'+tprocdef(container.defowner).unique_id_str+'$'+result;
  881. container:=container.defowner.owner;
  882. end;
  883. end;
  884. if withsignature then
  885. result:=''''+result
  886. end;
  887. end;
  888. constsym:
  889. begin
  890. csym:=tconstsym(sym);
  891. { some constants can be untyped }
  892. if assigned(csym.constdef) and
  893. not(csym.consttyp in [constwstring,conststring]) then
  894. begin
  895. result:=jvmencodetype(csym.constdef,false);
  896. if withsignature and
  897. jvmtypeneedssignature(csym.constdef) then
  898. begin
  899. result:=result+' signature "';
  900. result:=result+jvmencodetype(csym.constdef,true)+'"';
  901. end;
  902. end
  903. else
  904. begin
  905. case csym.consttyp of
  906. constord:
  907. result:=jvmencodetype(s32inttype,withsignature);
  908. constreal:
  909. result:=jvmencodetype(s64floattype,withsignature);
  910. constset:
  911. internalerror(2011040701);
  912. constpointer,
  913. constnil:
  914. result:=jvmencodetype(java_jlobject,withsignature);
  915. constwstring,
  916. conststring:
  917. result:=jvmencodetype(java_jlstring,withsignature);
  918. constresourcestring:
  919. internalerror(2011040702);
  920. else
  921. internalerror(2011040703);
  922. end;
  923. end;
  924. if withsignature then
  925. result:=''''+usesymname+''' '+result
  926. else
  927. result:=usesymname+' '+result
  928. end;
  929. else
  930. internalerror(2011021703);
  931. end;
  932. end;
  933. function jvmmangledbasename(sym: tsym; withsignature: boolean): TSymStr;
  934. begin
  935. if (sym.typ=fieldvarsym) and
  936. assigned(tfieldvarsym(sym).externalname) then
  937. result:=jvmmangledbasename(sym,tfieldvarsym(sym).externalname^,withsignature)
  938. else if (sym.typ=staticvarsym) and
  939. (tstaticvarsym(sym).mangledbasename<>'') then
  940. result:=jvmmangledbasename(sym,tstaticvarsym(sym).mangledbasename,withsignature)
  941. else
  942. result:=jvmmangledbasename(sym,sym.RealName,withsignature);
  943. end;
  944. {******************************************************************
  945. jvm type validity checking
  946. *******************************************************************}
  947. function jvmencodetype(def: tdef; withsignature: boolean): TSymStr;
  948. var
  949. errordef: tdef;
  950. begin
  951. if not jvmtryencodetype(def,result,withsignature,errordef) then
  952. internalerror(2011012305);
  953. end;
  954. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  955. var
  956. encodedtype: TSymStr;
  957. begin
  958. { don't duplicate the code like in objcdef, since the resulting strings
  959. are much shorter here so it's not worth it }
  960. result:=jvmtryencodetype(def,encodedtype,false,founderror);
  961. end;
  962. end.