BigETI

JI-9015069

Sep 15th, 2014
413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.98 KB | None | 0 0
  1. Compiler Bug - Incorrect results are returned in the end (by using for example nested xor-assignment operators)
  2.  
  3. ----------------------------------------
  4. Overview and description:
  5. ------------------------------
  6.  
  7. As this code
  8.  
  9. int a = 10, b = 20;
  10. a ^= (b ^= (a ^= b));
  11.  
  12. should swap the values of "a" and "b", actually makes the compiler spit out wrong bytecode,
  13. hence you get different results in the end.
  14.  
  15. Results:
  16. a = 0
  17. b = 10
  18.  
  19.  
  20. Where this method
  21.  
  22. int a = 10, b = 20;
  23. a ^= b;
  24. b ^= a;
  25. a ^= b;
  26.  
  27. returns the correct values.
  28.  
  29. Results:
  30. a = 20
  31. b = 10
  32.  
  33.  
  34. ----------------------------------------
  35. Versions:
  36. ------------------------------
  37.  
  38. javac.exe version:
  39. javac 1.8.0_20
  40.  
  41. --------------------
  42.  
  43. java.exe version:
  44. java version "1.8.0_20"
  45. Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
  46. Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
  47.  
  48. --------------------
  49.  
  50. javap.exe version:
  51. 1.8.0_20
  52.  
  53.  
  54. ----------------------------------------
  55. Decompiled bytecode from the incorrect working method (partial):
  56. ------------------------------
  57.  
  58. ; BugSwap.class (partial view of the main() method)
  59.  
  60. ; int a = 10, b = 20;
  61. bipush 10 ; Push 10 into stack (Int)
  62. istore_1 ; Store into 1st variable (Int)
  63. bipush 20 ; Push 20 into stack (Int)
  64. istore_2 ; Store into 2nd variable (Int)
  65.  
  66. ; a ^= (b ^= (a ^= b));
  67. iload_1 ; Load from 1st variable (Int)
  68. iload_2 ; Load from 2nd variable (Int)
  69. iload_1 ; Load from 1st variable (Int)
  70. iload_2 ; Load from 2nd variable (Int)
  71. ixor ; XOR (Int)
  72. dup ; Duplicate top operand into stack
  73. istore_1 ; Store into 1st variable (Int)
  74. ixor ; XOR (Int)
  75. dup ; Duplicate top operand into stack
  76. istore_2 ; Store into 2nd variable (Int)
  77. ixor ; XOR (Int)
  78. istore_1 ; Store into 1st variable (Int)
  79.  
  80. ; Results:
  81. ; a = 0
  82. ; b = 10
  83. ;
  84. ; Incorrect!
  85.  
  86.  
  87. ----------------------------------------
  88. Decompiled bytecode from the correct working method (partial):
  89. ------------------------------
  90.  
  91. ; AlternativeSwap.class (partial view of the main() method)
  92.  
  93. ; int a = 10, b = 20;
  94. bipush 10 ; Push 10 into stack (Int)
  95. istore_1 ; Store into 1st variable (Int)
  96. bipush 20 ; Push 20 into stack (Int)
  97. istore_2 ; Store into 2nd variable (Int)
  98.  
  99. ; a ^= b;
  100. iload_1 ; Load from 1st variable (Int)
  101. iload_2 ; Load from 2nd variable (Int)
  102. ixor ; XOR (Int)
  103. istore_1 ; Store into 1st variable (Int)
  104.  
  105. ; b ^= a;
  106. iload_2 ; Load from 2nd variable (Int)
  107. iload_1 ; Load from 1st variable (Int)
  108. ixor ; XOR (Int)
  109. istore_2 ; Store into 2nd variable (Int)
  110.  
  111. ; a ^= b;
  112. iload_1 ; Load from 1st variable (Int)
  113. iload_2 ; Load from 2nd variable (Int)
  114. ixor ; XOR (Int)
  115. istore_1 ; Store into 1st variable (Int)
  116.  
  117. ; Results:
  118. ; a = 20
  119. ; b = 10
  120. ;
  121. ; Correct!
  122.  
  123.  
  124. ----------------------------------------
  125. Decompiled bytecode and edited from the former incorrect working method (partial):
  126. ------------------------------
  127.  
  128. ; EditedBugSwap.class (partial view of the main() method, which is edited)
  129.  
  130. ; int a = 10, b = 20;
  131. bipush 10 ; Push 10 into stack (Int)
  132. istore_1 ; Store into 1st variable (Int)
  133. bipush 20 ; Push 20 into stack (Int)
  134. istore_2 ; Store into 2nd variable (Int)
  135.  
  136. ; a ^= (b ^= (a ^= b));
  137. iload_1 ; Load from 1st variable (Int)
  138. iload_2 ; Load from 2nd variable (Int)
  139. ixor ; XOR (Int)
  140. dup ; Duplicate top operand into stack
  141. istore_1 ; Store into 1st variable (Int)
  142. iload_2 ; Load from 2nd variable (Int)
  143. ixor ; XOR (Int)
  144. dup ; Duplicate top operand into stack
  145. istore_2 ; Store into 2nd variable (Int)
  146. iload_1 ; Load from 2nd variable (Int)
  147. ixor ; XOR (Int)
  148. istore_1 ; Store into 1st variable (Int)
  149.  
  150. ; Results:
  151. ; a = 20
  152. ; b = 10
  153. ;
  154. ; Correct!
  155.  
  156.  
  157. ----------------------------------------
  158. Conclusion:
  159. ------------------------------
  160.  
  161. Loading the old values in the first place may work correctly,
  162. if the stack values are synced with the variables,
  163. otherwise you may end up using the incorrect values within the stack,
  164. because the variables are being manipulated in runtime,
  165. hence the alternative code (3rd one) works as intended.
Advertisement
Add Comment
Please, Sign In to add comment