njvmset.pas 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. {
  2. Copyright (c) 2011 by Jonas Maebe
  3. Generate JVM bytecode for in set/case 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. }
  17. unit njvmset;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,
  22. node,nset,ncgset;
  23. type
  24. tjvminnode = class(tcginnode)
  25. function pass_1: tnode; override;
  26. end;
  27. tjvmcasenode = class(tcgcasenode)
  28. function pass_1: tnode; override;
  29. end;
  30. implementation
  31. uses
  32. symconst,symdef,
  33. pass_1,
  34. ncal,ncnv,ncon,nmem,
  35. njvmcon,
  36. cgbase;
  37. {*****************************************************************************
  38. TJVMINNODE
  39. *****************************************************************************}
  40. function tjvminnode.pass_1: tnode;
  41. var
  42. setparts: Tsetparts;
  43. numparts: byte;
  44. use_small: boolean;
  45. isenum: boolean;
  46. begin
  47. { before calling "inherited pass_1", so that in case left is an enum
  48. constant it's not yet translated into a class instance }
  49. isenum:=left.resultdef.typ=enumdef;
  50. { if we can use jumps, don't transform the set constant and (if
  51. applicable) the value to be tested }
  52. if checkgenjumps(setparts,numparts,use_small) then
  53. begin
  54. if right.nodetype=setconstn then
  55. tjvmsetconstnode(right).setconsttype:=sct_notransform;
  56. if isenum then
  57. if (left.nodetype=ordconstn) then
  58. tjvmordconstnode(left).enumconstok:=true
  59. else
  60. { not very clean, since we now have "longint in enumset", but
  61. the code generator doesn't really mind }
  62. inserttypeconv_explicit(left,s32inttype);
  63. end;
  64. result:=inherited pass_1;
  65. if assigned(result) then
  66. exit;
  67. { in case of jumps let the regular code handle it }
  68. if expectloc=LOC_JUMP then
  69. exit;
  70. { otherwise call set helper }
  71. right:=caddrnode.create_internal(right);
  72. include(right.flags,nf_typedaddr);
  73. if isenum then
  74. begin
  75. inserttypeconv_explicit(left,java_jlenum);
  76. inserttypeconv_explicit(right,java_juenumset);
  77. end
  78. else
  79. begin
  80. inserttypeconv_explicit(left,s32inttype);
  81. inserttypeconv_explicit(right,java_jubitset);
  82. end;
  83. result:=ccallnode.createinternmethod(right,'CONTAINS',ccallparanode.create(left,nil));
  84. right:=nil;
  85. left:=nil;
  86. end;
  87. {*****************************************************************************
  88. TJVMCASENODE
  89. *****************************************************************************}
  90. function tjvmcasenode.pass_1: tnode;
  91. begin
  92. { convert case expression to an integer in case it's an enum, since
  93. enums are class instances in the JVM. All labels are stored as
  94. ordinal values, so it doesn't matter that we change the type }
  95. if left.resultdef.typ=enumdef then
  96. inserttypeconv_explicit(left,s32inttype);
  97. result:=inherited pass_1;
  98. end;
  99. begin
  100. cinnode:=tjvminnode;
  101. ccasenode:=tjvmcasenode;
  102. end.