jvmdef.pas 35 KB

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