jvmdef.pas 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  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,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(tenumdef(def).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 tpointerdef(def).pointeddef.typ in [orddef,floatdef] then
  237. begin
  238. encodedstr:=encodedstr+'[';
  239. result:=jvmaddencodedtype(tpointerdef(def).pointeddef,false,encodedstr,forcesignature,founderror);
  240. end
  241. else if jvmimplicitpointertype(tpointerdef(def).pointeddef) then
  242. result:=jvmaddencodedtype(tpointerdef(def).pointeddef,false,encodedstr,forcesignature,founderror)
  243. else
  244. begin
  245. { Semantically, these are pointers to types that are
  246. pointer-based themselves (or typecastable to pointer).
  247. Internally, we represent them all as array of JLObject so that
  248. they are assignment-compatible. We will perform the type
  249. checks when actually loading a value from them }
  250. encodedstr:=encodedstr+'[';
  251. result:=jvmaddencodedtype(java_jlobject,false,encodedstr,forcesignature,founderror)
  252. end;
  253. end;
  254. floatdef :
  255. begin
  256. case tfloatdef(def).floattype of
  257. s32real:
  258. c:='F';
  259. s64real:
  260. c:='D';
  261. else
  262. result:=false;
  263. end;
  264. encodedstr:=encodedstr+c;
  265. end;
  266. filedef :
  267. result:=false;
  268. recorddef :
  269. begin
  270. encodedstr:=encodedstr+'L'+trecorddef(def).jvm_full_typename(true)+';'
  271. end;
  272. variantdef :
  273. begin
  274. { will be hanlded via wrapping later, although wrapping may
  275. happen at higher level }
  276. result:=false;
  277. end;
  278. classrefdef :
  279. begin
  280. if not forcesignature then
  281. { unfortunately, java.lang.Class is final, so we can't create
  282. different versions for difference class reference types }
  283. encodedstr:=encodedstr+'Ljava/lang/Class;'
  284. { we can however annotate it with extra signature information in
  285. using Java's generic annotations }
  286. else
  287. jvmaddencodedsignature(def,false,encodedstr);
  288. result:=true;
  289. end;
  290. setdef :
  291. begin
  292. if tsetdef(def).elementdef.typ=enumdef then
  293. begin
  294. if forcesignature then
  295. jvmaddencodedsignature(def,false,encodedstr)
  296. else
  297. result:=jvmaddencodedtype(java_juenumset,false,encodedstr,forcesignature,founderror)
  298. end
  299. else
  300. result:=jvmaddencodedtype(java_jubitset,false,encodedstr,forcesignature,founderror)
  301. end;
  302. formaldef :
  303. begin
  304. { var/const/out x: JLObject }
  305. result:=jvmaddencodedtype(java_jlobject,false,encodedstr,forcesignature,founderror);
  306. end;
  307. arraydef :
  308. begin
  309. if is_array_of_const(def) then
  310. begin
  311. encodedstr:=encodedstr+'[';
  312. result:=jvmaddencodedtype(search_system_type('TVARREC').typedef,false,encodedstr,forcesignature,founderror);
  313. end
  314. else if is_packed_array(def) then
  315. result:=false
  316. else
  317. begin
  318. encodedstr:=encodedstr+'[';
  319. if not jvmaddencodedtype(tarraydef(def).elementdef,false,encodedstr,forcesignature,founderror) then
  320. begin
  321. result:=false;
  322. { report the exact (nested) error defintion }
  323. exit;
  324. end;
  325. end;
  326. end;
  327. procvardef :
  328. begin
  329. result:=jvmaddencodedtype(tprocvardef(def).classdef,false,encodedstr,forcesignature,founderror);
  330. end;
  331. objectdef :
  332. case tobjectdef(def).objecttype of
  333. odt_javaclass,
  334. odt_interfacejava:
  335. begin
  336. def:=maybe_find_real_class_definition(def,false);
  337. encodedstr:=encodedstr+'L'+tobjectdef(def).jvm_full_typename(true)+';'
  338. end
  339. else
  340. result:=false;
  341. end;
  342. undefineddef,
  343. errordef :
  344. result:=false;
  345. procdef :
  346. { must be done via jvmencodemethod() }
  347. internalerror(2010121903);
  348. else
  349. internalerror(2010121904);
  350. end;
  351. if not result then
  352. founderror:=def;
  353. end;
  354. function jvmtryencodetype(def: tdef; out encodedtype: TSymStr; forcesignature: boolean; out founderror: tdef): boolean;
  355. begin
  356. encodedtype:='';
  357. result:=jvmaddencodedtype(def,false,encodedtype,forcesignature,founderror);
  358. end;
  359. procedure jvmaddtypeownerprefix(owner: tsymtable; var name: TSymStr);
  360. var
  361. owningcontainer: tsymtable;
  362. tmpresult: TSymStr;
  363. module: tmodule;
  364. nameendpos: longint;
  365. begin
  366. { see tprocdef.jvmmangledbasename for description of the format }
  367. owningcontainer:=owner;
  368. while (owningcontainer.symtabletype=localsymtable) do
  369. owningcontainer:=owningcontainer.defowner.owner;
  370. case owningcontainer.symtabletype of
  371. globalsymtable,
  372. staticsymtable:
  373. begin
  374. module:=find_module_from_symtable(owningcontainer);
  375. tmpresult:='';
  376. if assigned(module.namespace) then
  377. tmpresult:=module.namespace^+'/';
  378. tmpresult:=tmpresult+module.realmodulename^+'/';
  379. end;
  380. objectsymtable:
  381. case tobjectdef(owningcontainer.defowner).objecttype of
  382. odt_javaclass,
  383. odt_interfacejava:
  384. begin
  385. tmpresult:=tobjectdef(owningcontainer.defowner).jvm_full_typename(true)+'/'
  386. end
  387. else
  388. internalerror(2010122606);
  389. end;
  390. recordsymtable:
  391. tmpresult:=trecorddef(owningcontainer.defowner).jvm_full_typename(true)+'/'
  392. else
  393. internalerror(2010122605);
  394. end;
  395. name:=tmpresult+name;
  396. nameendpos:=pos(' ',name);
  397. if nameendpos=0 then
  398. nameendpos:=length(name)+1;
  399. insert('''',name,nameendpos);
  400. name:=''''+name;
  401. end;
  402. function jvmarrtype(def: tdef; out primitivetype: boolean): TSymStr;
  403. var
  404. errdef: tdef;
  405. begin
  406. if not jvmtryencodetype(def,result,false,errdef) then
  407. internalerror(2011012205);
  408. primitivetype:=false;
  409. if length(result)=1 then
  410. begin
  411. case result[1] of
  412. 'Z': result:='boolean';
  413. 'C': result:='char';
  414. 'B': result:='byte';
  415. 'S': result:='short';
  416. 'I': result:='int';
  417. 'J': result:='long';
  418. 'F': result:='float';
  419. 'D': result:='double';
  420. else
  421. internalerror(2011012206);
  422. end;
  423. primitivetype:=true;
  424. end
  425. else if (result[1]='L') then
  426. begin
  427. { in case of a class reference, strip the leading 'L' and the
  428. trailing ';' }
  429. setlength(result,length(result)-1);
  430. delete(result,1,1);
  431. end;
  432. { for arrays, use the actual reference type }
  433. end;
  434. function jvmarrtype_setlength(def: tdef): char;
  435. var
  436. errdef: tdef;
  437. res: TSymStr;
  438. begin
  439. { keep in sync with rtl/java/jdynarrh.inc and usage in njvminl }
  440. if is_record(def) then
  441. result:='R'
  442. else if is_shortstring(def) then
  443. result:='T'
  444. else if def.typ=setdef then
  445. begin
  446. if tsetdef(def).elementdef.typ=enumdef then
  447. result:='E'
  448. else
  449. result:='L'
  450. end
  451. else if (def.typ=procvardef) and
  452. not tprocvardef(def).is_addressonly then
  453. result:='P'
  454. else
  455. begin
  456. if not jvmtryencodetype(def,res,false,errdef) then
  457. internalerror(2011012209);
  458. if length(res)=1 then
  459. result:=res[1]
  460. else
  461. result:='A';
  462. end;
  463. end;
  464. function jvmimplicitpointertype(def: tdef): boolean;
  465. begin
  466. case def.typ of
  467. arraydef:
  468. result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
  469. is_open_array(def) or
  470. is_array_of_const(def) or
  471. is_array_constructor(def);
  472. recorddef,
  473. setdef:
  474. result:=true;
  475. objectdef:
  476. result:=is_object(def);
  477. stringdef :
  478. result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
  479. procvardef:
  480. result:=not tprocvardef(def).is_addressonly;
  481. else
  482. result:=false;
  483. end;
  484. end;
  485. { mergeints = true means that all integer types are mapped to jllong,
  486. otherwise they are mapped to the closest corresponding type }
  487. procedure jvmgetboxtype(def: tdef; out objdef, paradef: tdef; mergeints: boolean);
  488. begin
  489. case def.typ of
  490. orddef:
  491. begin
  492. case torddef(def).ordtype of
  493. pasbool8:
  494. begin
  495. objdef:=tobjectdef(search_system_type('JLBOOLEAN').typedef);
  496. paradef:=pasbool8type;
  497. end;
  498. uwidechar:
  499. begin
  500. objdef:=tobjectdef(search_system_type('JLCHARACTER').typedef);
  501. paradef:=cwidechartype;
  502. end;
  503. else
  504. begin
  505. { wrap all integer types into a JLLONG, so that we don't get
  506. errors after returning a byte assigned to a long etc }
  507. if mergeints or
  508. (torddef(def).ordtype in [s64bit,u64bit,scurrency,bool64bit,pasbool64]) then
  509. begin
  510. objdef:=tobjectdef(search_system_type('JLLONG').typedef);
  511. paradef:=s64inttype;
  512. end
  513. else
  514. begin
  515. case torddef(def).ordtype of
  516. s8bit,
  517. u8bit,
  518. uchar,
  519. bool8bit:
  520. begin
  521. objdef:=tobjectdef(search_system_type('JLBYTE').typedef);
  522. paradef:=s8inttype;
  523. end;
  524. s16bit,
  525. u16bit,
  526. bool16bit,
  527. pasbool16:
  528. begin
  529. objdef:=tobjectdef(search_system_type('JLSHORT').typedef);
  530. paradef:=s16inttype;
  531. end;
  532. s32bit,
  533. u32bit,
  534. bool32bit,
  535. pasbool32:
  536. begin
  537. objdef:=tobjectdef(search_system_type('JLINTEGER').typedef);
  538. paradef:=s32inttype;
  539. end;
  540. else
  541. internalerror(2011052101);
  542. end;
  543. end;
  544. end;
  545. end;
  546. end;
  547. floatdef:
  548. begin
  549. case tfloatdef(def).floattype of
  550. s32real:
  551. begin
  552. objdef:=tobjectdef(search_system_type('JLFLOAT').typedef);
  553. paradef:=s32floattype;
  554. end;
  555. s64real:
  556. begin
  557. objdef:=tobjectdef(search_system_type('JLDOUBLE').typedef);
  558. paradef:=s64floattype;
  559. end;
  560. else
  561. internalerror(2011052102);
  562. end;
  563. end;
  564. else
  565. internalerror(2011052103);
  566. end;
  567. end;
  568. function jvmgetunboxmethod(def: tdef): string;
  569. begin
  570. case def.typ of
  571. orddef:
  572. begin
  573. case torddef(def).ordtype of
  574. pasbool8:
  575. result:='BOOLEANVALUE';
  576. s8bit,
  577. u8bit,
  578. uchar,
  579. bool8bit:
  580. result:='BYTEVALUE';
  581. s16bit,
  582. u16bit,
  583. bool16bit,
  584. pasbool16:
  585. result:='SHORTVALUE';
  586. s32bit,
  587. u32bit,
  588. bool32bit,
  589. pasbool32:
  590. result:='INTVALUE';
  591. s64bit,
  592. u64bit,
  593. scurrency,
  594. bool64bit,
  595. pasbool64:
  596. result:='LONGVALUE';
  597. uwidechar:
  598. result:='CHARVALUE';
  599. else
  600. internalerror(2011071702);
  601. end;
  602. end;
  603. floatdef:
  604. begin
  605. case tfloatdef(def).floattype of
  606. s32real:
  607. result:='FLOATVALUE';
  608. s64real:
  609. result:='DOUBLEVALUE';
  610. else
  611. internalerror(2011071703);
  612. end;
  613. end;
  614. else
  615. internalerror(2011071704);
  616. end;
  617. end;
  618. function jvmgetcorrespondingclassdef(def: tdef): tdef;
  619. var
  620. paradef: tdef;
  621. begin
  622. if def.typ in [orddef,floatdef] then
  623. jvmgetboxtype(def,result,paradef,false)
  624. else
  625. begin
  626. case def.typ of
  627. stringdef :
  628. begin
  629. case tstringdef(def).stringtype of
  630. { translated into java.lang.String }
  631. st_widestring,
  632. st_unicodestring:
  633. result:=java_jlstring;
  634. st_ansistring:
  635. result:=java_ansistring;
  636. st_shortstring:
  637. result:=java_shortstring;
  638. else
  639. internalerror(2011072409);
  640. end;
  641. end;
  642. enumdef:
  643. begin
  644. result:=tenumdef(def).classdef;
  645. end;
  646. pointerdef :
  647. begin
  648. if def=voidpointertype then
  649. result:=java_jlobject
  650. else if jvmimplicitpointertype(tpointerdef(def).pointeddef) then
  651. result:=tpointerdef(def).pointeddef
  652. else
  653. internalerror(2011072410);
  654. end;
  655. recorddef :
  656. begin
  657. result:=def;
  658. end;
  659. variantdef :
  660. begin
  661. result:=cvarianttype;
  662. end;
  663. classrefdef :
  664. begin
  665. result:=search_system_type('JLCLASS').typedef;
  666. end;
  667. setdef :
  668. begin
  669. if tsetdef(def).elementdef.typ=enumdef then
  670. result:=java_juenumset
  671. else
  672. result:=java_jubitset;
  673. end;
  674. formaldef :
  675. begin
  676. result:=java_jlobject;
  677. end;
  678. arraydef :
  679. begin
  680. { cannot represent statically }
  681. internalerror(2011072411);
  682. end;
  683. procvardef :
  684. begin
  685. result:=tprocvardef(def).classdef;
  686. end;
  687. objectdef :
  688. case tobjectdef(def).objecttype of
  689. odt_javaclass,
  690. odt_interfacejava:
  691. result:=def
  692. else
  693. internalerror(2011072412);
  694. end;
  695. else
  696. internalerror(2011072413);
  697. end;
  698. end;
  699. end;
  700. function get_para_push_size(def: tdef): tdef;
  701. begin
  702. result:=def;
  703. if def.typ=orddef then
  704. case torddef(def).ordtype of
  705. u8bit,uchar:
  706. if torddef(def).high>127 then
  707. result:=s8inttype;
  708. u16bit:
  709. if torddef(def).high>32767 then
  710. result:=s16inttype;
  711. end;
  712. end;
  713. function jvmgetthreadvardef(def: tdef): tdef;
  714. begin
  715. if (def.typ=arraydef) and
  716. not is_dynamic_array(def) then
  717. begin
  718. result:=search_system_type('FPCNORMALARRAYTHREADVAR').typedef;
  719. exit;
  720. end;
  721. if jvmimplicitpointertype(def) then
  722. begin
  723. result:=search_system_type('FPCIMPLICITPTRTHREADVAR').typedef;
  724. exit;
  725. end;
  726. case def.typ of
  727. orddef:
  728. begin
  729. case torddef(def).ordtype of
  730. pasbool8:
  731. begin
  732. result:=tobjectdef(search_system_type('FPCBOOLEANTHREADVAR').typedef);
  733. end;
  734. uwidechar:
  735. begin
  736. result:=tobjectdef(search_system_type('FPCCHARTHREADVAR').typedef);
  737. end;
  738. s8bit,
  739. u8bit,
  740. uchar,
  741. bool8bit:
  742. begin
  743. result:=tobjectdef(search_system_type('FPCBYTETHREADVAR').typedef);
  744. end;
  745. s16bit,
  746. u16bit,
  747. bool16bit,
  748. pasbool16:
  749. begin
  750. result:=tobjectdef(search_system_type('FPCSHORTTHREADVAR').typedef);
  751. end;
  752. s32bit,
  753. u32bit,
  754. bool32bit,
  755. pasbool32:
  756. begin
  757. result:=tobjectdef(search_system_type('FPCINTTHREADVAR').typedef);
  758. end;
  759. s64bit,
  760. u64bit,
  761. scurrency,
  762. bool64bit,
  763. pasbool64:
  764. begin
  765. result:=tobjectdef(search_system_type('FPCLONGTHREADVAR').typedef);
  766. end
  767. else
  768. internalerror(2011082101);
  769. end;
  770. end;
  771. floatdef:
  772. begin
  773. case tfloatdef(def).floattype of
  774. s32real:
  775. begin
  776. result:=tobjectdef(search_system_type('FPCFLOATTHREADVAR').typedef);
  777. end;
  778. s64real:
  779. begin
  780. result:=tobjectdef(search_system_type('FPCDOUBLETHREADVAR').typedef);
  781. end;
  782. else
  783. internalerror(2011082102);
  784. end;
  785. end
  786. else
  787. begin
  788. result:=search_system_type('FPCPOINTERTHREADVAR').typedef
  789. end;
  790. end;
  791. end;
  792. procedure jvmgetarraydimdef(arrdef: tdef; out eledef: tdef; out ndim: longint);
  793. begin
  794. eledef:=arrdef;
  795. ndim:=0;
  796. repeat
  797. eledef:=tarraydef(eledef).elementdef;
  798. inc(ndim);
  799. until (eledef.typ<>arraydef) or
  800. is_dynamic_array(eledef);
  801. end;
  802. function jvmmangledbasename(sym: tsym; const usesymname: TSymStr; withsignature: boolean): TSymStr;
  803. var
  804. container: tsymtable;
  805. vsym: tabstractvarsym;
  806. csym: tconstsym;
  807. usedef: tdef;
  808. begin
  809. case sym.typ of
  810. staticvarsym,
  811. paravarsym,
  812. localvarsym,
  813. fieldvarsym:
  814. begin
  815. vsym:=tabstractvarsym(sym);
  816. { for local and paravarsyms that are unsigned 8/16 bit, change the
  817. outputted type to signed 16/32 bit:
  818. a) the stack slots are all 32 bit anyway, so the storage allocation
  819. is still correct
  820. b) since at the JVM level all types are signed, this makes sure
  821. that the values in the stack slots are valid for the specified
  822. types
  823. }
  824. usedef:=vsym.vardef;
  825. if vsym.typ in [localvarsym,paravarsym] then
  826. begin
  827. if (usedef.typ=orddef) then
  828. case torddef(usedef).ordtype of
  829. u8bit,uchar:
  830. usedef:=s16inttype;
  831. u16bit:
  832. usedef:=s32inttype;
  833. end;
  834. end;
  835. result:=jvmencodetype(usedef,false);
  836. if withsignature and
  837. jvmtypeneedssignature(usedef) then
  838. begin
  839. result:=result+' signature "';
  840. result:=result+jvmencodetype(usedef,true)+'"';
  841. end;
  842. if (vsym.typ=paravarsym) and
  843. (vo_is_self in tparavarsym(vsym).varoptions) then
  844. result:='''this'' ' +result
  845. else if (vsym.typ in [paravarsym,localvarsym]) and
  846. ([vo_is_funcret,vo_is_result] * tabstractnormalvarsym(vsym).varoptions <> []) then
  847. result:='''result'' '+result
  848. else
  849. begin
  850. { add array indirection if required }
  851. if (vsym.typ=paravarsym) and
  852. ((usedef.typ=formaldef) or
  853. ((vsym.varspez in [vs_var,vs_out,vs_constref]) and
  854. not jvmimplicitpointertype(usedef))) then
  855. result:='['+result;
  856. { single quotes for definitions to prevent clashes with Java
  857. opcodes }
  858. if withsignature then
  859. result:=usesymname+''' '+result
  860. else
  861. result:=usesymname+' '+result;
  862. { we have to mangle staticvarsyms in localsymtables to
  863. prevent name clashes... }
  864. if (vsym.typ=staticvarsym) then
  865. begin
  866. container:=sym.Owner;
  867. while (container.symtabletype=localsymtable) do
  868. begin
  869. if tdef(container.defowner).typ<>procdef then
  870. internalerror(2011040303);
  871. { defid is added to prevent problem with overloads }
  872. result:=tprocdef(container.defowner).procsym.realname+'$$'+tostr(tprocdef(container.defowner).defid)+'$'+result;
  873. container:=container.defowner.owner;
  874. end;
  875. end;
  876. if withsignature then
  877. result:=''''+result
  878. end;
  879. end;
  880. constsym:
  881. begin
  882. csym:=tconstsym(sym);
  883. { some constants can be untyped }
  884. if assigned (csym.constdef) then
  885. begin
  886. result:=jvmencodetype(csym.constdef,false);
  887. if withsignature and
  888. jvmtypeneedssignature(csym.constdef) then
  889. begin
  890. result:=result+' signature "';
  891. result:=result+jvmencodetype(csym.constdef,true)+'"';
  892. end;
  893. end
  894. else
  895. begin
  896. case csym.consttyp of
  897. constord:
  898. result:=jvmencodetype(s32inttype,withsignature);
  899. constreal:
  900. result:=jvmencodetype(s64floattype,withsignature);
  901. constset:
  902. internalerror(2011040701);
  903. constpointer,
  904. constnil:
  905. result:=jvmencodetype(java_jlobject,withsignature);
  906. constwstring,
  907. conststring:
  908. result:=jvmencodetype(java_jlstring,withsignature);
  909. constresourcestring:
  910. internalerror(2011040702);
  911. else
  912. internalerror(2011040703);
  913. end;
  914. end;
  915. if withsignature then
  916. result:=''''+usesymname+''' '+result
  917. else
  918. result:=usesymname+' '+result
  919. end;
  920. else
  921. internalerror(2011021703);
  922. end;
  923. end;
  924. function jvmmangledbasename(sym: tsym; withsignature: boolean): TSymStr;
  925. begin
  926. if (sym.typ=fieldvarsym) and
  927. assigned(tfieldvarsym(sym).externalname) then
  928. result:=jvmmangledbasename(sym,tfieldvarsym(sym).externalname^,withsignature)
  929. else if (sym.typ=staticvarsym) and
  930. (tstaticvarsym(sym).mangledbasename<>'') then
  931. result:=jvmmangledbasename(sym,tstaticvarsym(sym).mangledbasename,withsignature)
  932. else
  933. result:=jvmmangledbasename(sym,sym.RealName,withsignature);
  934. end;
  935. {******************************************************************
  936. jvm type validity checking
  937. *******************************************************************}
  938. function jvmencodetype(def: tdef; withsignature: boolean): TSymStr;
  939. var
  940. errordef: tdef;
  941. begin
  942. if not jvmtryencodetype(def,result,withsignature,errordef) then
  943. internalerror(2011012305);
  944. end;
  945. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  946. var
  947. encodedtype: TSymStr;
  948. begin
  949. { don't duplicate the code like in objcdef, since the resulting strings
  950. are much shorter here so it's not worth it }
  951. result:=jvmtryencodetype(def,encodedtype,false,founderror);
  952. end;
  953. end.