njvmcnv.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. {
  2. Copyright (c) 1998-2011 by Florian Klaempfl and Jonas Maebe
  3. Generate JVM code for type converting nodes
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************}
  16. unit njvmcnv;
  17. {$i fpcdefs.inc}
  18. interface
  19. uses
  20. node,ncnv,ncgcnv,
  21. symtype;
  22. type
  23. tjvmtypeconvnode = class(tcgtypeconvnode)
  24. function typecheck_dynarray_to_openarray: tnode; override;
  25. procedure second_int_to_int;override;
  26. { procedure second_string_to_string;override; }
  27. { procedure second_cstring_to_pchar;override; }
  28. { procedure second_string_to_chararray;override; }
  29. { procedure second_array_to_pointer;override; }
  30. function first_int_to_real: tnode; override;
  31. { procedure second_pointer_to_array;override; }
  32. { procedure second_chararray_to_string;override; }
  33. { procedure second_char_to_string;override; }
  34. procedure second_int_to_real;override;
  35. { procedure second_real_to_real;override; }
  36. { procedure second_cord_to_pointer;override; }
  37. { procedure second_proc_to_procvar;override; }
  38. procedure second_bool_to_int;override;
  39. procedure second_int_to_bool;override;
  40. { procedure second_load_smallset;override; }
  41. { procedure second_ansistring_to_pchar;override; }
  42. { procedure second_pchar_to_string;override; }
  43. { procedure second_class_to_intf;override; }
  44. { procedure second_char_to_char;override; }
  45. protected
  46. function target_specific_explicit_typeconv: tnode; override;
  47. end;
  48. tjvmasnode = class(tcgasnode)
  49. protected
  50. function target_specific_typecheck: boolean;override;
  51. public
  52. function pass_1 : tnode;override;
  53. procedure pass_generate_code; override;
  54. end;
  55. tjvmisnode = class(tisnode)
  56. protected
  57. function target_specific_typecheck: boolean;override;
  58. public
  59. function pass_1 : tnode;override;
  60. procedure pass_generate_code; override;
  61. end;
  62. implementation
  63. uses
  64. verbose,globals,globtype,
  65. symconst,symdef,symsym,symtable,aasmbase,aasmdata,
  66. defutil,defcmp,jvmdef,
  67. cgbase,cgutils,pass_1,pass_2,
  68. nbas,ncon,ncal,nld,nmem,procinfo,
  69. nutils,
  70. cpubase,aasmcpu,
  71. tgobj,hlcgobj,hlcgcpu;
  72. {*****************************************************************************
  73. TypeCheckTypeConv
  74. *****************************************************************************}
  75. function tjvmtypeconvnode.typecheck_dynarray_to_openarray: tnode;
  76. begin
  77. { all arrays are equal in Java }
  78. left.resultdef:=resultdef;
  79. result:=left;
  80. left:=nil;
  81. end;
  82. {*****************************************************************************
  83. FirstTypeConv
  84. *****************************************************************************}
  85. function tjvmtypeconvnode.first_int_to_real: tnode;
  86. begin
  87. if not is_64bitint(left.resultdef) then
  88. if is_signed(left.resultdef) or
  89. (left.resultdef.size<4) then
  90. inserttypeconv(left,s32inttype)
  91. else
  92. inserttypeconv(left,u32inttype);
  93. firstpass(left);
  94. result := nil;
  95. expectloc:=LOC_FPUREGISTER;
  96. end;
  97. {*****************************************************************************
  98. SecondTypeConv
  99. *****************************************************************************}
  100. procedure tjvmtypeconvnode.second_int_to_int;
  101. var
  102. ressize,
  103. leftsize : longint;
  104. begin
  105. { insert range check if not explicit conversion }
  106. if not(nf_explicit in flags) then
  107. hlcg.g_rangecheck(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef);
  108. { is the result size smaller? when typecasting from void
  109. we always reuse the current location, because there is
  110. nothing that we can load in a register }
  111. ressize:=resultdef.size;
  112. leftsize :=left.resultdef.size;
  113. if ((ressize<>leftsize) or
  114. ((location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) and
  115. (location.reference.arrayreftype<>art_none) and
  116. (is_widechar(left.resultdef)<>is_widechar(resultdef))) or
  117. is_bitpacked_access(left)) and
  118. not is_void(left.resultdef) then
  119. begin
  120. location_copy(location,left.location);
  121. { reuse a loc_reference when the newsize is smaller than
  122. than the original, except
  123. a) for arrays (they use different load instructions for
  124. differently sized data types)
  125. b) when going from 8 to 4 bytes, because these are different
  126. data types
  127. -- note that this is different from other targets, and will
  128. break stuff like passing byte(shortintvar) to a var-parameter;
  129. although that may be "fixed" again because we have to use
  130. copy-in/copy-out to emulate var-parameters anyway... }
  131. if (location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) and
  132. (location.reference.arrayreftype=art_none) and
  133. (ressize<leftsize) and
  134. (leftsize<=4) then
  135. begin
  136. location.size:=def_cgsize(resultdef);
  137. { no adjustment of the ffset even though Java is big endian,
  138. because the load instruction will remain the same }
  139. end
  140. else
  141. hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,false);
  142. end
  143. else
  144. begin
  145. location_copy(location,left.location);
  146. location.size:=def_cgsize(resultdef);
  147. if (ressize < sizeof(aint)) and
  148. (location.loc in [LOC_REGISTER,LOC_CREGISTER]) and
  149. (def_cgsize(left.resultdef)<>def_cgsize(resultdef)) then
  150. begin
  151. location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
  152. location.loc:=LOC_REGISTER;
  153. hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,left.resultdef,resultdef,left.location.register,location.register);
  154. end;
  155. end;
  156. end;
  157. procedure tjvmtypeconvnode.second_int_to_real;
  158. var
  159. srcsize, ressize: longint;
  160. procedure convertsignedstackloc;
  161. begin
  162. case srcsize of
  163. 4:
  164. case ressize of
  165. 4:
  166. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_i2f));
  167. 8:
  168. begin
  169. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_i2d));
  170. thlcgjvm(hlcg).incstack(current_asmdata.CurrAsmList,1);
  171. end;
  172. else
  173. internalerror(2011010601);
  174. end;
  175. 8:
  176. case ressize of
  177. 4:
  178. begin
  179. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_l2f));
  180. thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  181. end;
  182. 8:
  183. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_l2d));
  184. else
  185. internalerror(2011010602);
  186. end;
  187. else
  188. internalerror(2011010603);
  189. end;
  190. end;
  191. var
  192. signeddef : tdef;
  193. l1 : tasmlabel;
  194. begin
  195. srcsize:=left.resultdef.size;
  196. ressize:=resultdef.size;
  197. location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
  198. location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
  199. { first always convert as if it's a signed number }
  200. thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  201. convertsignedstackloc;
  202. if not is_signed(left.resultdef) then
  203. begin
  204. { if it was unsigned, add high(cardinal)+1/high(qword)+1 in case
  205. the signed interpretation is < 0 }
  206. current_asmdata.getjumplabel(l1);
  207. if srcsize=4 then
  208. signeddef:=s32inttype
  209. else
  210. signeddef:=s64inttype;
  211. hlcg.a_cmp_const_loc_label(current_asmdata.CurrAsmList,signeddef,OC_GTE,0,left.location,l1);
  212. if srcsize=4 then
  213. thlcgjvm(hlcg).a_loadfpu_const_stack(current_asmdata.CurrAsmList,resultdef,4294967296.0)
  214. else
  215. thlcgjvm(hlcg).a_loadfpu_const_stack(current_asmdata.CurrAsmList,resultdef,18446744073709551616.0);
  216. if ressize=4 then
  217. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_fadd))
  218. else
  219. current_asmdata.CurrAsmList.concat(taicpu.op_none(a_dadd));
  220. hlcg.a_label(current_asmdata.CurrAsmList,l1);
  221. end;
  222. thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
  223. end;
  224. procedure tjvmtypeconvnode.second_bool_to_int;
  225. var
  226. newsize: tcgsize;
  227. oldTrueLabel,oldFalseLabel : tasmlabel;
  228. begin
  229. oldTrueLabel:=current_procinfo.CurrTrueLabel;
  230. oldFalseLabel:=current_procinfo.CurrFalseLabel;
  231. current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel);
  232. current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
  233. secondpass(left);
  234. location_copy(location,left.location);
  235. newsize:=def_cgsize(resultdef);
  236. { byte(bytebool) or word(wordbool) or longint(longbool) must be }
  237. { accepted for var parameters and assignments, and must not }
  238. { change the ordinal value or value location. }
  239. { htypechk.valid_for_assign ensures that such locations with a }
  240. { size<sizeof(register) cannot be LOC_CREGISTER (they otherwise }
  241. { could be in case of a plain assignment), and LOC_REGISTER can }
  242. { never be an assignment target. The remaining LOC_REGISTER/ }
  243. { LOC_CREGISTER locations do have to be sign/zero-extended. }
  244. { -- Note: this does not work for Java and 2/4 byte sized
  245. values, because bytebool/wordbool are signed and
  246. are stored in 4 byte locations -> will result in
  247. "byte" with the value high(cardinal); see remark
  248. in second_int_to_int above regarding consequences }
  249. if not(nf_explicit in flags) or
  250. (location.loc in [LOC_FLAGS,LOC_JUMP]) or
  251. ((newsize<>left.location.size) and
  252. ((left.resultdef.size<>resultdef.size) or
  253. not(left.resultdef.size in [4,8]))
  254. ) then
  255. hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true)
  256. else
  257. { may differ in sign, e.g. bytebool -> byte }
  258. location.size:=newsize;
  259. current_procinfo.CurrTrueLabel:=oldTrueLabel;
  260. current_procinfo.CurrFalseLabel:=oldFalseLabel;
  261. end;
  262. procedure tjvmtypeconvnode.second_int_to_bool;
  263. var
  264. hlabel1,hlabel2,oldTrueLabel,oldFalseLabel : tasmlabel;
  265. newsize : tcgsize;
  266. begin
  267. oldTrueLabel:=current_procinfo.CurrTrueLabel;
  268. oldFalseLabel:=current_procinfo.CurrFalseLabel;
  269. current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel);
  270. current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
  271. secondpass(left);
  272. if codegenerror then
  273. exit;
  274. { Explicit typecasts from any ordinal type to a boolean type }
  275. { must not change the ordinal value }
  276. if (nf_explicit in flags) and
  277. not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
  278. begin
  279. location_copy(location,left.location);
  280. newsize:=def_cgsize(resultdef);
  281. { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend }
  282. if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or
  283. ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
  284. hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true)
  285. else
  286. location.size:=newsize;
  287. current_procinfo.CurrTrueLabel:=oldTrueLabel;
  288. current_procinfo.CurrFalseLabel:=oldFalseLabel;
  289. exit;
  290. end;
  291. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  292. location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
  293. current_asmdata.getjumplabel(hlabel2);
  294. case left.location.loc of
  295. LOC_CREFERENCE,LOC_REFERENCE,LOC_REGISTER,LOC_CREGISTER:
  296. begin
  297. current_asmdata.getjumplabel(hlabel1);
  298. hlcg.a_cmp_const_loc_label(current_asmdata.CurrAsmList,left.resultdef,OC_EQ,0,left.location,hlabel1);
  299. end;
  300. LOC_JUMP :
  301. begin
  302. hlabel1:=current_procinfo.CurrFalseLabel;
  303. hlcg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
  304. end;
  305. else
  306. internalerror(10062);
  307. end;
  308. if not(is_cbool(resultdef)) then
  309. thlcgjvm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,resultdef,1,R_INTREGISTER)
  310. else
  311. thlcgjvm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,resultdef,-1,R_INTREGISTER);
  312. { we jump over the next constant load -> they don't appear on the
  313. stack simulataneously }
  314. thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  315. hlcg.a_jmp_always(current_asmdata.CurrAsmList,hlabel2);
  316. hlcg.a_label(current_asmdata.CurrAsmList,hlabel1);
  317. thlcgjvm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,resultdef,0,R_INTREGISTER);
  318. hlcg.a_label(current_asmdata.CurrAsmList,hlabel2);
  319. thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,resultdef,location.register);
  320. current_procinfo.CurrTrueLabel:=oldTrueLabel;
  321. current_procinfo.CurrFalseLabel:=oldFalseLabel;
  322. end;
  323. procedure get_most_nested_types(var fromdef, todef: tdef);
  324. begin
  325. while is_dynamic_array(fromdef) and
  326. is_dynamic_array(todef) do
  327. begin
  328. fromdef:=tarraydef(fromdef).elementdef;
  329. todef:=tarraydef(todef).elementdef;
  330. end;
  331. end;
  332. function tjvmtypeconvnode.target_specific_explicit_typeconv: tnode;
  333. { handle explicit typecast from int to to real or vice versa }
  334. function int_real_explicit_typecast(fdef: tfloatdef; const singlemethod, doublemethod: string): tnode;
  335. var
  336. csym: ttypesym;
  337. psym: tsym;
  338. begin
  339. { use the float/double to raw bits methods to get the bit pattern }
  340. if fdef.floattype=s32real then
  341. begin
  342. csym:=search_system_type('JLFLOAT');
  343. psym:=search_struct_member(tobjectdef(csym.typedef),singlemethod);
  344. end
  345. else
  346. begin
  347. csym:=search_system_type('JLDOUBLE');
  348. psym:=search_struct_member(tobjectdef(csym.typedef),doublemethod);
  349. end;
  350. if not assigned(psym) or
  351. (psym.typ<>procsym) then
  352. internalerror(2011012901);
  353. { call the (static class) method to get the raw bits }
  354. result:=ccallnode.create(ccallparanode.create(left,nil),
  355. tprocsym(psym),psym.owner,
  356. cloadvmtaddrnode.create(ctypenode.create(csym.typedef)),[]);
  357. { convert the result to the result type of this type conversion node }
  358. inserttypeconv_explicit(result,resultdef);
  359. { left is reused }
  360. left:=nil;
  361. end;
  362. var
  363. frominclass,
  364. toinclass: boolean;
  365. fromdef,
  366. todef: tdef;
  367. begin
  368. result:=nil;
  369. { This routine is only called for explicit typeconversions of same-sized
  370. entities that aren't handled by normal type conversions -> bit pattern
  371. reinterpretations. In the JVM, many of these also need special
  372. handling because of the type safety. }
  373. { don't allow conversions between object-based and non-object-based
  374. types }
  375. frominclass:=
  376. (left.resultdef.typ=objectdef) or
  377. is_dynamic_array(left.resultdef);
  378. toinclass:=
  379. (resultdef.typ=objectdef) or
  380. is_dynamic_array(resultdef);
  381. if frominclass and
  382. toinclass then
  383. begin
  384. { we need an as-node to check the validity of the conversion (since
  385. it wasn't handled by another type conversion, we know it can't
  386. have been valid normally)
  387. Exception: (most nested) destination is java.lang.Object, since
  388. everything is compatible with that type }
  389. fromdef:=left.resultdef;
  390. todef:=resultdef;
  391. get_most_nested_types(fromdef,todef);
  392. if ((fromdef.typ<>objectdef) and
  393. not is_dynamic_array(fromdef)) or
  394. (todef<>java_jlobject) then
  395. begin
  396. result:=ctypenode.create(resultdef);
  397. if resultdef.typ=objectdef then
  398. result:=cloadvmtaddrnode.create(result);
  399. result:=casnode.create(left,result);
  400. left:=nil;
  401. end;
  402. exit;
  403. end;
  404. { don't allow conversions between different classes of primitive types,
  405. except for a few special cases }
  406. { float to int/enum explicit type conversion: get the bits }
  407. if (left.resultdef.typ=floatdef) and
  408. (is_integer(resultdef) or
  409. (resultdef.typ=enumdef)) then
  410. begin
  411. result:=int_real_explicit_typecast(tfloatdef(left.resultdef),'FLOATTORAWINTBITS','DOUBLETORAWLONGBITS');
  412. exit;
  413. end;
  414. { int to float explicit type conversion: also use the bits }
  415. if (is_integer(left.resultdef) or
  416. (left.resultdef.typ=enumdef)) and
  417. (resultdef.typ=floatdef) then
  418. begin
  419. result:=int_real_explicit_typecast(tfloatdef(resultdef),'INTBITSTOFLOAT','LONGBITSTODOUBLE');
  420. exit;
  421. end;
  422. { nothing special required when going between ordinals and enums }
  423. if (left.resultdef.typ in [orddef,enumdef])=(resultdef.typ in [orddef,enumdef]) then
  424. exit;
  425. { Todo:
  426. * int to set and vice versa
  427. * set to float and vice versa (via int) (maybe)
  428. * regular array of primitive to primitive and vice versa (maybe)
  429. * packed record to primitive and vice versa (maybe)
  430. Definitely not:
  431. * unpacked record to anything and vice versa (no alignment rules
  432. for Java)
  433. }
  434. { anything not explicitly handled is a problem }
  435. CGMessage2(type_e_illegal_type_conversion,left.resultdef.typename,resultdef.typename);
  436. end;
  437. {*****************************************************************************
  438. AsNode and IsNode common helpers
  439. *****************************************************************************}
  440. function asis_target_specific_typecheck(node: tasisnode): boolean;
  441. var
  442. fromelt, toelt: tdef;
  443. begin
  444. { dynamic arrays can be converted to java.lang.Object and vice versa }
  445. if node.right.resultdef=java_jlobject then
  446. { dynamic array to java.lang.Object }
  447. result:=is_dynamic_array(node.left.resultdef)
  448. else if is_dynamic_array(node.right.resultdef) then
  449. begin
  450. { <x> to dynamic array: only if possibly valid }
  451. fromelt:=node.left.resultdef;
  452. toelt:=node.right.resultdef;
  453. get_most_nested_types(fromelt,toelt);
  454. { final levels must be convertable:
  455. a) from array (dynamic or not) to java.lang.Object or vice versa,
  456. or
  457. b) the same primitive/class type
  458. }
  459. result:=
  460. (compare_defs(fromelt,toelt,node.left.nodetype) in [te_exact,te_equal]) or
  461. (((fromelt.typ=objectdef) or
  462. (fromelt.typ=arraydef)) and
  463. ((toelt.typ=objectdef) or
  464. (toelt.typ=arraydef)));
  465. end
  466. else
  467. begin
  468. { full class reference support requires using the Java reflection API,
  469. not yet implemented }
  470. if (node.right.nodetype<>loadvmtaddrn) or
  471. (tloadvmtaddrnode(node.right).left.nodetype<>typen) then
  472. internalerror(2011012601);
  473. result:=false;
  474. end;
  475. if result then
  476. if node.nodetype=asn then
  477. begin
  478. if node.right.resultdef.typ<>classrefdef then
  479. node.resultdef:=node.right.resultdef
  480. else
  481. node.resultdef:=tclassrefdef(node.right.resultdef).pointeddef
  482. end
  483. else
  484. node.resultdef:=pasbool8type;
  485. end;
  486. procedure asis_generate_code(node: tasisnode; opcode: tasmop);
  487. var
  488. checkdef: tdef;
  489. begin
  490. secondpass(node.left);
  491. thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,node.left.resultdef,node.left.location);
  492. location_freetemp(current_asmdata.CurrAsmList,node.left.location);
  493. { Perform a checkcast instruction, which will raise an exception in case
  494. the actual type does not match/inherit from the expected type.
  495. Object types need the full type name (package+class name), arrays only
  496. the array definition }
  497. if node.nodetype=asn then
  498. checkdef:=node.resultdef
  499. else if node.right.resultdef.typ=classrefdef then
  500. checkdef:=tclassrefdef(node.right.resultdef).pointeddef
  501. else
  502. checkdef:=node.right.resultdef;
  503. if checkdef.typ=objectdef then
  504. current_asmdata.CurrAsmList.concat(taicpu.op_sym(opcode,current_asmdata.RefAsmSymbol(tobjectdef(checkdef).jvm_full_typename(true))))
  505. else
  506. current_asmdata.CurrAsmList.concat(taicpu.op_sym(opcode,current_asmdata.RefAsmSymbol(jvmencodetype(checkdef))));
  507. location_reset(node.location,LOC_REGISTER,OS_ADDR);
  508. node.location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,node.resultdef);
  509. thlcgjvm(hlcg).a_load_stack_reg(current_asmdata.CurrAsmList,node.resultdef,node.location.register);
  510. end;
  511. {*****************************************************************************
  512. TJVMAsNode
  513. *****************************************************************************}
  514. function tjvmasnode.target_specific_typecheck: boolean;
  515. begin
  516. result:=asis_target_specific_typecheck(self);
  517. end;
  518. function tjvmasnode.pass_1: tnode;
  519. begin
  520. { call-by-reference does not exist in Java, so it's no problem to
  521. change a memory location to a register }
  522. firstpass(left);
  523. if right.nodetype<>typen then
  524. firstpass(right);
  525. expectloc:=LOC_REGISTER;
  526. result:=nil;
  527. end;
  528. procedure tjvmasnode.pass_generate_code;
  529. begin
  530. asis_generate_code(self,a_checkcast);
  531. end;
  532. {*****************************************************************************
  533. TJVMIsNode
  534. *****************************************************************************}
  535. function tjvmisnode.target_specific_typecheck: boolean;
  536. begin
  537. result:=asis_target_specific_typecheck(self);
  538. end;
  539. function tjvmisnode.pass_1: tnode;
  540. begin
  541. firstpass(left);
  542. if right.nodetype<>typen then
  543. firstpass(right);
  544. expectloc:=LOC_REGISTER;
  545. result:=nil;
  546. end;
  547. procedure tjvmisnode.pass_generate_code;
  548. begin
  549. asis_generate_code(self,a_instanceof);
  550. end;
  551. begin
  552. ctypeconvnode:=tjvmtypeconvnode;
  553. casnode:=tjvmasnode;
  554. cisnode:=tjvmisnode;
  555. end.