jvmdef.pas 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  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. begin
  808. case sym.typ of
  809. staticvarsym,
  810. paravarsym,
  811. localvarsym,
  812. fieldvarsym:
  813. begin
  814. vsym:=tabstractvarsym(sym);
  815. result:=jvmencodetype(vsym.vardef,false);
  816. if withsignature and
  817. jvmtypeneedssignature(vsym.vardef) then
  818. begin
  819. result:=result+' signature "';
  820. result:=result+jvmencodetype(vsym.vardef,true)+'"';
  821. end;
  822. if (vsym.typ=paravarsym) and
  823. (vo_is_self in tparavarsym(vsym).varoptions) then
  824. result:='''this'' ' +result
  825. else if (vsym.typ in [paravarsym,localvarsym]) and
  826. ([vo_is_funcret,vo_is_result] * tabstractnormalvarsym(vsym).varoptions <> []) then
  827. result:='''result'' '+result
  828. else
  829. begin
  830. { add array indirection if required }
  831. if (vsym.typ=paravarsym) and
  832. (vsym.vardef.typ=formaldef) or
  833. ((vsym.varspez in [vs_var,vs_out,vs_constref]) and
  834. not jvmimplicitpointertype(vsym.vardef)) then
  835. result:='['+result;
  836. { single quotes for definitions to prevent clashes with Java
  837. opcodes }
  838. if withsignature then
  839. result:=usesymname+''' '+result
  840. else
  841. result:=usesymname+' '+result;
  842. { we have to mangle staticvarsyms in localsymtables to
  843. prevent name clashes... }
  844. if (vsym.typ=staticvarsym) then
  845. begin
  846. container:=sym.Owner;
  847. while (container.symtabletype=localsymtable) do
  848. begin
  849. if tdef(container.defowner).typ<>procdef then
  850. internalerror(2011040303);
  851. { defid is added to prevent problem with overloads }
  852. result:=tprocdef(container.defowner).procsym.realname+'$$'+tostr(tprocdef(container.defowner).defid)+'$'+result;
  853. container:=container.defowner.owner;
  854. end;
  855. end;
  856. if withsignature then
  857. result:=''''+result
  858. end;
  859. end;
  860. constsym:
  861. begin
  862. csym:=tconstsym(sym);
  863. { some constants can be untyped }
  864. if assigned (csym.constdef) then
  865. begin
  866. result:=jvmencodetype(csym.constdef,false);
  867. if withsignature and
  868. jvmtypeneedssignature(csym.constdef) then
  869. begin
  870. result:=result+' signature "';
  871. result:=result+jvmencodetype(csym.constdef,true)+'"';
  872. end;
  873. end
  874. else
  875. begin
  876. case csym.consttyp of
  877. constord:
  878. result:=jvmencodetype(s32inttype,withsignature);
  879. constreal:
  880. result:=jvmencodetype(s64floattype,withsignature);
  881. constset:
  882. internalerror(2011040701);
  883. constpointer,
  884. constnil:
  885. result:=jvmencodetype(java_jlobject,withsignature);
  886. constwstring,
  887. conststring:
  888. result:=jvmencodetype(java_jlstring,withsignature);
  889. constresourcestring:
  890. internalerror(2011040702);
  891. else
  892. internalerror(2011040703);
  893. end;
  894. end;
  895. if withsignature then
  896. result:=''''+usesymname+''' '+result
  897. else
  898. result:=usesymname+' '+result
  899. end;
  900. else
  901. internalerror(2011021703);
  902. end;
  903. end;
  904. function jvmmangledbasename(sym: tsym; withsignature: boolean): TSymStr;
  905. begin
  906. if (sym.typ=fieldvarsym) and
  907. assigned(tfieldvarsym(sym).externalname) then
  908. result:=jvmmangledbasename(sym,tfieldvarsym(sym).externalname^,withsignature)
  909. else if (sym.typ=staticvarsym) and
  910. (tstaticvarsym(sym).mangledbasename<>'') then
  911. result:=jvmmangledbasename(sym,tstaticvarsym(sym).mangledbasename,withsignature)
  912. else
  913. result:=jvmmangledbasename(sym,sym.RealName,withsignature);
  914. end;
  915. {******************************************************************
  916. jvm type validity checking
  917. *******************************************************************}
  918. function jvmencodetype(def: tdef; withsignature: boolean): TSymStr;
  919. var
  920. errordef: tdef;
  921. begin
  922. if not jvmtryencodetype(def,result,withsignature,errordef) then
  923. internalerror(2011012305);
  924. end;
  925. function jvmchecktype(def: tdef; out founderror: tdef): boolean;
  926. var
  927. encodedtype: TSymStr;
  928. begin
  929. { don't duplicate the code like in objcdef, since the resulting strings
  930. are much shorter here so it's not worth it }
  931. result:=jvmtryencodetype(def,encodedtype,false,founderror);
  932. end;
  933. end.