jvmdef.pas 34 KB

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