jvmdef.pas 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  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. pasbool8:
  499. begin
  500. objdef:=tobjectdef(search_system_type('JLBOOLEAN').typedef);
  501. paradef:=pasbool8type;
  502. end;
  503. uwidechar:
  504. begin
  505. objdef:=tobjectdef(search_system_type('JLCHARACTER').typedef);
  506. paradef:=cwidechartype;
  507. end;
  508. else
  509. begin
  510. { wrap all integer types into a JLLONG, so that we don't get
  511. errors after returning a byte assigned to a long etc }
  512. if mergeints or
  513. (torddef(def).ordtype in [s64bit,u64bit,scurrency,bool64bit,pasbool64]) then
  514. begin
  515. objdef:=tobjectdef(search_system_type('JLLONG').typedef);
  516. paradef:=s64inttype;
  517. end
  518. else
  519. begin
  520. case torddef(def).ordtype of
  521. s8bit,
  522. u8bit,
  523. uchar,
  524. bool8bit:
  525. begin
  526. objdef:=tobjectdef(search_system_type('JLBYTE').typedef);
  527. paradef:=s8inttype;
  528. end;
  529. s16bit,
  530. u16bit,
  531. bool16bit,
  532. pasbool16:
  533. begin
  534. objdef:=tobjectdef(search_system_type('JLSHORT').typedef);
  535. paradef:=s16inttype;
  536. end;
  537. s32bit,
  538. u32bit,
  539. bool32bit,
  540. pasbool32:
  541. begin
  542. objdef:=tobjectdef(search_system_type('JLINTEGER').typedef);
  543. paradef:=s32inttype;
  544. end;
  545. else
  546. internalerror(2011052101);
  547. end;
  548. end;
  549. end;
  550. end;
  551. end;
  552. floatdef:
  553. begin
  554. case tfloatdef(def).floattype of
  555. s32real:
  556. begin
  557. objdef:=tobjectdef(search_system_type('JLFLOAT').typedef);
  558. paradef:=s32floattype;
  559. end;
  560. s64real:
  561. begin
  562. objdef:=tobjectdef(search_system_type('JLDOUBLE').typedef);
  563. paradef:=s64floattype;
  564. end;
  565. else
  566. internalerror(2011052102);
  567. end;
  568. end;
  569. else
  570. internalerror(2011052103);
  571. end;
  572. end;
  573. function jvmgetunboxmethod(def: tdef): string;
  574. begin
  575. case def.typ of
  576. orddef:
  577. begin
  578. case torddef(def).ordtype of
  579. pasbool8:
  580. result:='BOOLEANVALUE';
  581. s8bit,
  582. u8bit,
  583. uchar,
  584. bool8bit:
  585. result:='BYTEVALUE';
  586. s16bit,
  587. u16bit,
  588. bool16bit,
  589. pasbool16:
  590. result:='SHORTVALUE';
  591. s32bit,
  592. u32bit,
  593. bool32bit,
  594. pasbool32:
  595. result:='INTVALUE';
  596. s64bit,
  597. u64bit,
  598. scurrency,
  599. bool64bit,
  600. pasbool64:
  601. result:='LONGVALUE';
  602. uwidechar:
  603. result:='CHARVALUE';
  604. else
  605. internalerror(2011071702);
  606. end;
  607. end;
  608. floatdef:
  609. begin
  610. case tfloatdef(def).floattype of
  611. s32real:
  612. result:='FLOATVALUE';
  613. s64real:
  614. result:='DOUBLEVALUE';
  615. else
  616. internalerror(2011071703);
  617. end;
  618. end;
  619. else
  620. internalerror(2011071704);
  621. end;
  622. end;
  623. function jvmgetcorrespondingclassdef(def: tdef): tdef;
  624. var
  625. paradef: tdef;
  626. begin
  627. if def.typ in [orddef,floatdef] then
  628. jvmgetboxtype(def,result,paradef,false)
  629. else
  630. begin
  631. case def.typ of
  632. stringdef :
  633. begin
  634. case tstringdef(def).stringtype of
  635. { translated into java.lang.String }
  636. st_widestring,
  637. st_unicodestring:
  638. result:=java_jlstring;
  639. st_ansistring:
  640. result:=java_ansistring;
  641. st_shortstring:
  642. result:=java_shortstring;
  643. else
  644. internalerror(2011072409);
  645. end;
  646. end;
  647. enumdef:
  648. begin
  649. result:=tcpuenumdef(tenumdef(def).getbasedef).classdef;
  650. end;
  651. pointerdef :
  652. begin
  653. if def=voidpointertype then
  654. result:=java_jlobject
  655. else if jvmimplicitpointertype(tpointerdef(def).pointeddef) then
  656. result:=tpointerdef(def).pointeddef
  657. else
  658. internalerror(2011072410);
  659. end;
  660. recorddef :
  661. begin
  662. result:=def;
  663. end;
  664. variantdef :
  665. begin
  666. result:=cvarianttype;
  667. end;
  668. classrefdef :
  669. begin
  670. result:=search_system_type('JLCLASS').typedef;
  671. end;
  672. setdef :
  673. begin
  674. if tsetdef(def).elementdef.typ=enumdef then
  675. result:=java_juenumset
  676. else
  677. result:=java_jubitset;
  678. end;
  679. formaldef :
  680. begin
  681. result:=java_jlobject;
  682. end;
  683. arraydef :
  684. begin
  685. { cannot represent statically }
  686. internalerror(2011072411);
  687. end;
  688. procvardef :
  689. begin
  690. result:=tcpuprocvardef(def).classdef;
  691. end;
  692. objectdef :
  693. case tobjectdef(def).objecttype of
  694. odt_javaclass,
  695. odt_interfacejava:
  696. result:=def
  697. else
  698. internalerror(2011072412);
  699. end;
  700. else
  701. internalerror(2011072413);
  702. end;
  703. end;
  704. end;
  705. function get_para_push_size(def: tdef): tdef;
  706. begin
  707. result:=def;
  708. if def.typ=orddef then
  709. case torddef(def).ordtype of
  710. u8bit,uchar:
  711. if torddef(def).high>127 then
  712. result:=s8inttype;
  713. u16bit:
  714. if torddef(def).high>32767 then
  715. result:=s16inttype;
  716. end;
  717. end;
  718. function jvmgetthreadvardef(def: tdef): tdef;
  719. begin
  720. if (def.typ=arraydef) and
  721. not is_dynamic_array(def) then
  722. begin
  723. result:=search_system_type('FPCNORMALARRAYTHREADVAR').typedef;
  724. exit;
  725. end;
  726. if jvmimplicitpointertype(def) then
  727. begin
  728. result:=search_system_type('FPCIMPLICITPTRTHREADVAR').typedef;
  729. exit;
  730. end;
  731. case def.typ of
  732. orddef:
  733. begin
  734. case torddef(def).ordtype of
  735. pasbool8:
  736. begin
  737. result:=tobjectdef(search_system_type('FPCBOOLEANTHREADVAR').typedef);
  738. end;
  739. uwidechar:
  740. begin
  741. result:=tobjectdef(search_system_type('FPCCHARTHREADVAR').typedef);
  742. end;
  743. s8bit,
  744. u8bit,
  745. uchar,
  746. bool8bit:
  747. begin
  748. result:=tobjectdef(search_system_type('FPCBYTETHREADVAR').typedef);
  749. end;
  750. s16bit,
  751. u16bit,
  752. bool16bit,
  753. pasbool16:
  754. begin
  755. result:=tobjectdef(search_system_type('FPCSHORTTHREADVAR').typedef);
  756. end;
  757. s32bit,
  758. u32bit,
  759. bool32bit,
  760. pasbool32:
  761. begin
  762. result:=tobjectdef(search_system_type('FPCINTTHREADVAR').typedef);
  763. end;
  764. s64bit,
  765. u64bit,
  766. scurrency,
  767. bool64bit,
  768. pasbool64:
  769. begin
  770. result:=tobjectdef(search_system_type('FPCLONGTHREADVAR').typedef);
  771. end
  772. else
  773. internalerror(2011082101);
  774. end;
  775. end;
  776. floatdef:
  777. begin
  778. case tfloatdef(def).floattype of
  779. s32real:
  780. begin
  781. result:=tobjectdef(search_system_type('FPCFLOATTHREADVAR').typedef);
  782. end;
  783. s64real:
  784. begin
  785. result:=tobjectdef(search_system_type('FPCDOUBLETHREADVAR').typedef);
  786. end;
  787. else
  788. internalerror(2011082102);
  789. end;
  790. end
  791. else
  792. begin
  793. result:=search_system_type('FPCPOINTERTHREADVAR').typedef
  794. end;
  795. end;
  796. end;
  797. procedure jvmgetarraydimdef(arrdef: tdef; out eledef: tdef; out ndim: longint);
  798. begin
  799. eledef:=arrdef;
  800. ndim:=0;
  801. repeat
  802. eledef:=tarraydef(eledef).elementdef;
  803. inc(ndim);
  804. until (eledef.typ<>arraydef) or
  805. is_dynamic_array(eledef);
  806. end;
  807. function jvmmangledbasename(sym: tsym; const usesymname: TSymStr; withsignature: boolean): TSymStr;
  808. var
  809. container: tsymtable;
  810. vsym: tabstractvarsym;
  811. csym: tconstsym;
  812. usedef: tdef;
  813. begin
  814. case sym.typ of
  815. staticvarsym,
  816. paravarsym,
  817. localvarsym,
  818. fieldvarsym:
  819. begin
  820. vsym:=tabstractvarsym(sym);
  821. { for local and paravarsyms that are unsigned 8/16 bit, change the
  822. outputted type to signed 16/32 bit:
  823. a) the stack slots are all 32 bit anyway, so the storage allocation
  824. is still correct
  825. b) since at the JVM level all types are signed, this makes sure
  826. that the values in the stack slots are valid for the specified
  827. types
  828. }
  829. usedef:=vsym.vardef;
  830. if vsym.typ in [localvarsym,paravarsym] then
  831. begin
  832. if (usedef.typ=orddef) then
  833. case torddef(usedef).ordtype of
  834. u8bit,uchar:
  835. usedef:=s16inttype;
  836. u16bit:
  837. usedef:=s32inttype;
  838. end;
  839. end;
  840. result:=jvmencodetype(usedef,false);
  841. if withsignature and
  842. jvmtypeneedssignature(usedef) then
  843. begin
  844. result:=result+' signature "';
  845. result:=result+jvmencodetype(usedef,true)+'"';
  846. end;
  847. if (vsym.typ=paravarsym) and
  848. (vo_is_self in tparavarsym(vsym).varoptions) then
  849. result:='''this'' ' +result
  850. else if (vsym.typ in [paravarsym,localvarsym]) and
  851. ([vo_is_funcret,vo_is_result] * tabstractnormalvarsym(vsym).varoptions <> []) then
  852. result:='''result'' '+result
  853. else
  854. begin
  855. { add array indirection if required }
  856. if (vsym.typ=paravarsym) and
  857. ((usedef.typ=formaldef) or
  858. ((vsym.varspez in [vs_var,vs_out,vs_constref]) and
  859. not jvmimplicitpointertype(usedef))) then
  860. result:='['+result;
  861. { single quotes for definitions to prevent clashes with Java
  862. opcodes }
  863. if withsignature then
  864. result:=usesymname+''' '+result
  865. else
  866. result:=usesymname+' '+result;
  867. { we have to mangle staticvarsyms in localsymtables to
  868. prevent name clashes... }
  869. if (vsym.typ=staticvarsym) then
  870. begin
  871. container:=sym.Owner;
  872. while (container.symtabletype=localsymtable) do
  873. begin
  874. if tdef(container.defowner).typ<>procdef then
  875. internalerror(2011040303);
  876. { unique_id_str is added to prevent problem with overloads }
  877. result:=tprocdef(container.defowner).procsym.realname+'$$'+tprocdef(container.defowner).unique_id_str+'$'+result;
  878. container:=container.defowner.owner;
  879. end;
  880. end;
  881. if withsignature then
  882. result:=''''+result
  883. end;
  884. end;
  885. constsym:
  886. begin
  887. csym:=tconstsym(sym);
  888. { some constants can be untyped }
  889. if assigned(csym.constdef) and
  890. not(csym.consttyp in [constwstring,conststring]) then
  891. begin
  892. result:=jvmencodetype(csym.constdef,false);
  893. if withsignature and
  894. jvmtypeneedssignature(csym.constdef) then
  895. begin
  896. result:=result+' signature "';
  897. result:=result+jvmencodetype(csym.constdef,true)+'"';
  898. end;
  899. end
  900. else
  901. begin
  902. case csym.consttyp of
  903. constord:
  904. result:=jvmencodetype(s32inttype,withsignature);
  905. constreal:
  906. result:=jvmencodetype(s64floattype,withsignature);
  907. constset:
  908. internalerror(2011040701);
  909. constpointer,
  910. constnil:
  911. result:=jvmencodetype(java_jlobject,withsignature);
  912. constwstring,
  913. conststring:
  914. result:=jvmencodetype(java_jlstring,withsignature);
  915. constresourcestring:
  916. internalerror(2011040702);
  917. else
  918. internalerror(2011040703);
  919. end;
  920. end;
  921. if withsignature then
  922. result:=''''+usesymname+''' '+result
  923. else
  924. result:=usesymname+' '+result
  925. end;
  926. else
  927. internalerror(2011021703);
  928. end;
  929. end;
  930. function jvmmangledbasename(sym: tsym; withsignature: boolean): TSymStr;
  931. begin
  932. if (sym.typ=fieldvarsym) and
  933. assigned(tfieldvarsym(sym).externalname) then
  934. result:=jvmmangledbasename(sym,tfieldvarsym(sym).externalname^,withsignature)
  935. else if (sym.typ=staticvarsym) and
  936. (tstaticvarsym(sym).mangledbasename<>'') then
  937. result:=jvmmangledbasename(sym,tstaticvarsym(sym).mangledbasename,withsignature)
  938. else
  939. result:=jvmmangledbasename(sym,sym.RealName,withsignature);
  940. end;
  941. {******************************************************************
  942. jvm type validity checking
  943. *******************************************************************}
  944. function jvmencodetype(def: tdef; withsignature: boolean): TSymStr;
  945. var
  946. errordef: tdef;
  947. begin
  948. if not jvmtryencodetype(def,result,withsignature,errordef) then
  949. internalerror(2011012305);
  950. end;
  951. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  952. var
  953. encodedtype: TSymStr;
  954. begin
  955. { don't duplicate the code like in objcdef, since the resulting strings
  956. are much shorter here so it's not worth it }
  957. result:=jvmtryencodetype(def,encodedtype,false,founderror);
  958. end;
  959. end.