therubyracer 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of therubyracer might be problematic. Click here for more details.

Files changed (482) hide show
  1. data/History.txt +11 -0
  2. data/Rakefile +1 -1
  3. data/ext/v8/extconf.rb +0 -18
  4. data/ext/v8/rr.cpp +2 -2
  5. data/ext/v8/upstream/{2.1.10 → 2.3.3}/AUTHORS +1 -0
  6. data/ext/v8/upstream/{2.1.10 → 2.3.3}/ChangeLog +239 -0
  7. data/ext/v8/upstream/{2.1.10 → 2.3.3}/LICENSE +0 -0
  8. data/ext/v8/upstream/{2.1.10 → 2.3.3}/SConstruct +29 -17
  9. data/ext/v8/upstream/{2.1.10 → 2.3.3}/include/v8-debug.h +61 -3
  10. data/ext/v8/upstream/{2.1.10 → 2.3.3}/include/v8-profiler.h +182 -5
  11. data/ext/v8/upstream/{2.1.10 → 2.3.3}/include/v8.h +458 -257
  12. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/SConscript +2 -5
  13. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/accessors.cc +2 -2
  14. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/accessors.h +0 -0
  15. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/allocation.cc +0 -0
  16. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/allocation.h +0 -0
  17. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/api.cc +574 -30
  18. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/api.h +12 -10
  19. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/apinatives.js +0 -0
  20. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/apiutils.h +0 -0
  21. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arguments.h +0 -0
  22. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/assembler-arm-inl.h +38 -15
  23. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/assembler-arm.cc +646 -101
  24. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/assembler-arm.h +174 -15
  25. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/builtins-arm.cc +56 -47
  26. data/ext/v8/upstream/2.3.3/src/arm/codegen-arm-inl.h +48 -0
  27. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/codegen-arm.cc +2957 -1448
  28. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/codegen-arm.h +230 -74
  29. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/constants-arm.cc +25 -1
  30. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/constants-arm.h +16 -1
  31. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/cpu-arm.cc +4 -0
  32. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/debug-arm.cc +76 -6
  33. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/disasm-arm.cc +168 -20
  34. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/fast-codegen-arm.cc +5 -2
  35. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/frames-arm.cc +4 -4
  36. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/frames-arm.h +0 -0
  37. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/full-codegen-arm.cc +1558 -248
  38. data/ext/v8/upstream/2.3.3/src/arm/ic-arm.cc +2258 -0
  39. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/jump-target-arm.cc +55 -103
  40. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/macro-assembler-arm.cc +358 -185
  41. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/macro-assembler-arm.h +136 -41
  42. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/regexp-macro-assembler-arm.cc +26 -5
  43. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/regexp-macro-assembler-arm.h +0 -0
  44. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/register-allocator-arm-inl.h +0 -0
  45. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/register-allocator-arm.cc +4 -0
  46. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/register-allocator-arm.h +0 -0
  47. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/simulator-arm.cc +203 -22
  48. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/simulator-arm.h +7 -0
  49. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/stub-cache-arm.cc +531 -324
  50. data/ext/v8/upstream/2.3.3/src/arm/virtual-frame-arm-inl.h +59 -0
  51. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/virtual-frame-arm.cc +247 -81
  52. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/virtual-frame-arm.h +99 -83
  53. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/array.js +2 -2
  54. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/assembler.cc +6 -13
  55. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/assembler.h +36 -10
  56. data/ext/v8/upstream/2.3.3/src/ast-inl.h +81 -0
  57. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ast.cc +14 -0
  58. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ast.h +20 -35
  59. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/bootstrapper.cc +32 -1
  60. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/bootstrapper.h +0 -4
  61. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/builtins.cc +50 -33
  62. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/builtins.h +2 -0
  63. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/bytecodes-irregexp.h +0 -0
  64. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cached-powers.h +0 -0
  65. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/char-predicates-inl.h +0 -0
  66. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/char-predicates.h +0 -0
  67. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/checks.cc +0 -0
  68. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/checks.h +8 -6
  69. data/ext/v8/upstream/2.3.3/src/circular-queue-inl.h +53 -0
  70. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/circular-queue.cc +0 -0
  71. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/circular-queue.h +0 -26
  72. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/code-stubs.cc +2 -4
  73. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/code-stubs.h +1 -0
  74. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/code.h +0 -0
  75. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/codegen-inl.h +0 -0
  76. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/codegen.cc +44 -13
  77. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/codegen.h +310 -31
  78. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compilation-cache.cc +28 -0
  79. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compilation-cache.h +3 -0
  80. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compiler.cc +45 -14
  81. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compiler.h +0 -0
  82. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/contexts.cc +11 -11
  83. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/contexts.h +0 -0
  84. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/conversions-inl.h +0 -0
  85. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/conversions.cc +25 -11
  86. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/conversions.h +0 -0
  87. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/counters.cc +0 -0
  88. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/counters.h +0 -0
  89. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu-profiler-inl.h +2 -1
  90. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu-profiler.cc +68 -24
  91. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu-profiler.h +19 -11
  92. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu.h +0 -0
  93. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-debug.cc +0 -0
  94. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-debug.h +0 -0
  95. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-posix.cc +0 -0
  96. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-readline.cc +0 -0
  97. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-windows.cc +0 -0
  98. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8.cc +3 -0
  99. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8.h +0 -0
  100. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8.js +55 -2
  101. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/data-flow.cc +3 -0
  102. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/data-flow.h +0 -0
  103. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/date.js +68 -137
  104. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dateparser-inl.h +0 -0
  105. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dateparser.cc +2 -8
  106. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dateparser.h +0 -0
  107. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug-agent.cc +3 -3
  108. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug-agent.h +0 -0
  109. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug-debugger.js +81 -23
  110. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug.cc +275 -81
  111. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug.h +85 -6
  112. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/disasm.h +0 -0
  113. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/disassembler.cc +1 -1
  114. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/disassembler.h +0 -0
  115. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/diy-fp.cc +0 -0
  116. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/diy-fp.h +0 -0
  117. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/double.h +0 -0
  118. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dtoa-config.c +0 -0
  119. data/ext/v8/upstream/2.3.3/src/dtoa.cc +77 -0
  120. data/ext/v8/upstream/2.3.3/src/dtoa.h +81 -0
  121. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/execution.cc +111 -3
  122. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/execution.h +12 -1
  123. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/factory.cc +25 -3
  124. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/factory.h +16 -9
  125. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-codegen.cc +0 -0
  126. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-codegen.h +0 -0
  127. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-dtoa.cc +2 -9
  128. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-dtoa.h +1 -2
  129. data/ext/v8/upstream/2.3.3/src/fixed-dtoa.cc +405 -0
  130. data/ext/v8/upstream/{2.1.10/src/jump-target-light.cc → 2.3.3/src/fixed-dtoa.h} +22 -53
  131. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flag-definitions.h +14 -6
  132. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flags.cc +5 -9
  133. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flags.h +0 -0
  134. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flow-graph.cc +0 -0
  135. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flow-graph.h +0 -0
  136. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frame-element.cc +0 -0
  137. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frame-element.h +0 -0
  138. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frames-inl.h +0 -0
  139. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frames.cc +5 -2
  140. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frames.h +1 -0
  141. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/full-codegen.cc +387 -20
  142. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/full-codegen.h +102 -5
  143. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/func-name-inferrer.cc +0 -0
  144. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/func-name-inferrer.h +0 -0
  145. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/global-handles.cc +8 -4
  146. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/global-handles.h +0 -0
  147. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/globals.h +44 -7
  148. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/handles-inl.h +0 -0
  149. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/handles.cc +19 -0
  150. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/handles.h +8 -0
  151. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/hashmap.cc +0 -0
  152. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/hashmap.h +0 -0
  153. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap-inl.h +56 -14
  154. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap-profiler.cc +85 -1
  155. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap-profiler.h +45 -1
  156. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap.cc +994 -396
  157. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap.h +220 -65
  158. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/assembler-ia32-inl.h +41 -12
  159. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/assembler-ia32.cc +94 -24
  160. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/assembler-ia32.h +32 -4
  161. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/builtins-ia32.cc +42 -30
  162. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/codegen-ia32-inl.h +0 -0
  163. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/codegen-ia32.cc +1758 -916
  164. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/codegen-ia32.h +67 -74
  165. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/cpu-ia32.cc +4 -0
  166. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/debug-ia32.cc +46 -0
  167. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/disasm-ia32.cc +37 -6
  168. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/fast-codegen-ia32.cc +4 -0
  169. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/fast-codegen-ia32.h +0 -0
  170. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/frames-ia32.cc +4 -0
  171. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/frames-ia32.h +0 -0
  172. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/full-codegen-ia32.cc +1465 -198
  173. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/ic-ia32.cc +688 -367
  174. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/jump-target-ia32.cc +4 -0
  175. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/macro-assembler-ia32.cc +82 -180
  176. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/macro-assembler-ia32.h +41 -25
  177. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/regexp-macro-assembler-ia32.cc +68 -24
  178. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/regexp-macro-assembler-ia32.h +1 -2
  179. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/register-allocator-ia32-inl.h +0 -0
  180. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/register-allocator-ia32.cc +4 -0
  181. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/register-allocator-ia32.h +0 -0
  182. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/simulator-ia32.cc +0 -0
  183. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/simulator-ia32.h +0 -0
  184. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/stub-cache-ia32.cc +649 -302
  185. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/virtual-frame-ia32.cc +23 -1
  186. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/virtual-frame-ia32.h +18 -27
  187. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ic-inl.h +30 -3
  188. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ic.cc +384 -66
  189. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ic.h +65 -24
  190. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/interpreter-irregexp.cc +0 -0
  191. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/interpreter-irregexp.h +0 -0
  192. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/json.js +3 -3
  193. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jsregexp.cc +20 -4
  194. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jsregexp.h +0 -0
  195. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-heavy-inl.h +0 -0
  196. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-heavy.cc +79 -13
  197. data/ext/v8/upstream/{2.1.10/src/jump-target.h → 2.3.3/src/jump-target-heavy.h} +5 -47
  198. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-inl.h +0 -0
  199. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-light-inl.h +16 -2
  200. data/ext/v8/upstream/2.3.3/src/jump-target-light.cc +110 -0
  201. data/ext/v8/upstream/2.3.3/src/jump-target-light.h +192 -0
  202. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target.cc +0 -64
  203. data/ext/v8/upstream/2.3.3/src/jump-target.h +90 -0
  204. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/list-inl.h +0 -0
  205. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/list.h +0 -0
  206. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/liveedit-debugger.js +141 -28
  207. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/liveedit.cc +19 -7
  208. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/liveedit.h +0 -0
  209. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log-inl.h +0 -0
  210. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log-utils.cc +0 -0
  211. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log-utils.h +0 -0
  212. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log.cc +12 -11
  213. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log.h +12 -0
  214. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/macro-assembler.h +0 -16
  215. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/macros.py +21 -0
  216. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mark-compact.cc +120 -109
  217. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mark-compact.h +25 -37
  218. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/math.js +0 -0
  219. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/memory.h +0 -0
  220. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/messages.cc +8 -3
  221. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/messages.h +2 -1
  222. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/messages.js +15 -7
  223. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/assembler-mips-inl.h +0 -0
  224. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/assembler-mips.cc +12 -1
  225. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/assembler-mips.h +4 -1
  226. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/builtins-mips.cc +3 -0
  227. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/codegen-mips-inl.h +0 -0
  228. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/codegen-mips.cc +9 -0
  229. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/codegen-mips.h +1 -0
  230. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/constants-mips.cc +5 -0
  231. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/constants-mips.h +0 -0
  232. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/cpu-mips.cc +4 -0
  233. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/debug-mips.cc +3 -0
  234. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/disasm-mips.cc +3 -0
  235. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/fast-codegen-mips.cc +3 -0
  236. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/frames-mips.cc +3 -0
  237. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/frames-mips.h +0 -0
  238. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/full-codegen-mips.cc +5 -1
  239. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/ic-mips.cc +3 -0
  240. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/jump-target-mips.cc +3 -0
  241. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/macro-assembler-mips.cc +3 -0
  242. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/macro-assembler-mips.h +0 -0
  243. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/register-allocator-mips-inl.h +0 -0
  244. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/register-allocator-mips.cc +3 -0
  245. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/register-allocator-mips.h +0 -0
  246. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/simulator-mips.cc +3 -0
  247. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/simulator-mips.h +0 -0
  248. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/stub-cache-mips.cc +3 -0
  249. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/virtual-frame-mips.cc +3 -0
  250. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/virtual-frame-mips.h +0 -0
  251. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mirror-debugger.js +46 -4
  252. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mksnapshot.cc +0 -0
  253. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/natives.h +0 -0
  254. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects-debug.cc +8 -1
  255. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects-inl.h +235 -62
  256. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects.cc +497 -231
  257. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects.h +355 -149
  258. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/oprofile-agent.cc +0 -0
  259. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/oprofile-agent.h +0 -0
  260. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/parser.cc +31 -6
  261. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/parser.h +1 -1
  262. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-freebsd.cc +9 -6
  263. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-linux.cc +26 -6
  264. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-macos.cc +11 -6
  265. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-nullos.cc +0 -0
  266. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-openbsd.cc +6 -0
  267. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-posix.cc +0 -0
  268. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-solaris.cc +69 -23
  269. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-win32.cc +15 -11
  270. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform.h +10 -6
  271. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/powers-ten.h +0 -0
  272. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/prettyprinter.cc +0 -0
  273. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/prettyprinter.h +0 -0
  274. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/profile-generator-inl.h +26 -2
  275. data/ext/v8/upstream/2.3.3/src/profile-generator.cc +1830 -0
  276. data/ext/v8/upstream/2.3.3/src/profile-generator.h +853 -0
  277. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/property.cc +0 -0
  278. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/property.h +0 -0
  279. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-irregexp-inl.h +0 -0
  280. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-irregexp.cc +0 -0
  281. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-irregexp.h +0 -0
  282. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-tracer.cc +0 -0
  283. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-tracer.h +0 -0
  284. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler.cc +1 -3
  285. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler.h +0 -0
  286. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-stack.cc +0 -0
  287. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-stack.h +0 -0
  288. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp.js +25 -4
  289. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/register-allocator-inl.h +0 -0
  290. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/register-allocator.cc +4 -3
  291. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/register-allocator.h +0 -0
  292. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/rewriter.cc +85 -8
  293. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/rewriter.h +0 -0
  294. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/runtime.cc +547 -221
  295. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/runtime.h +5 -1
  296. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/runtime.js +23 -31
  297. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scanner.cc +12 -6
  298. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scanner.h +60 -53
  299. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopeinfo.cc +156 -168
  300. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopeinfo.h +58 -62
  301. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopes.cc +0 -0
  302. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopes.h +0 -0
  303. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/serialize.cc +320 -242
  304. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/serialize.h +81 -48
  305. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/shell.h +0 -0
  306. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/simulator.h +0 -0
  307. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/smart-pointer.h +0 -0
  308. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/snapshot-common.cc +0 -0
  309. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/snapshot-empty.cc +0 -0
  310. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/snapshot.h +0 -0
  311. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/spaces-inl.h +177 -74
  312. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/spaces.cc +138 -315
  313. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/spaces.h +155 -124
  314. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/splay-tree-inl.h +0 -0
  315. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/splay-tree.h +0 -0
  316. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/string-stream.cc +0 -0
  317. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/string-stream.h +0 -0
  318. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/string.js +113 -119
  319. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/stub-cache.cc +242 -97
  320. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/stub-cache.h +118 -55
  321. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/third_party/dtoa/COPYING +0 -0
  322. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/third_party/dtoa/dtoa.c +4 -0
  323. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/third_party/valgrind/valgrind.h +0 -0
  324. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/token.cc +0 -0
  325. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/token.h +0 -0
  326. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/top.cc +107 -26
  327. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/top.h +9 -4
  328. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/type-info.cc +0 -0
  329. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/type-info.h +2 -2
  330. data/ext/v8/upstream/2.3.3/src/unbound-queue-inl.h +95 -0
  331. data/ext/v8/upstream/2.3.3/src/unbound-queue.h +67 -0
  332. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/unicode-inl.h +0 -0
  333. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/unicode.cc +0 -0
  334. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/unicode.h +0 -0
  335. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/uri.js +0 -0
  336. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/utils.cc +0 -0
  337. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/utils.h +83 -1
  338. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8-counters.cc +0 -0
  339. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8-counters.h +20 -0
  340. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8.cc +5 -1
  341. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8.h +0 -0
  342. data/ext/v8/upstream/2.3.3/src/v8dll-main.cc +39 -0
  343. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8natives.js +210 -33
  344. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8threads.cc +1 -1
  345. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8threads.h +1 -1
  346. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/variables.cc +0 -0
  347. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/variables.h +0 -0
  348. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/version.cc +3 -3
  349. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/version.h +0 -0
  350. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-heavy-inl.h +40 -0
  351. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-heavy.cc +0 -0
  352. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-inl.h +0 -0
  353. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-light-inl.h +106 -5
  354. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-light.cc +4 -1
  355. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame.cc +0 -0
  356. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame.h +0 -0
  357. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/vm-state-inl.h +6 -3
  358. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/vm-state.cc +1 -1
  359. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/vm-state.h +6 -4
  360. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/assembler-x64-inl.h +42 -5
  361. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/assembler-x64.cc +285 -53
  362. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/assembler-x64.h +54 -18
  363. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/builtins-x64.cc +31 -33
  364. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/codegen-x64-inl.h +0 -0
  365. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/codegen-x64.cc +9787 -8722
  366. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/codegen-x64.h +82 -47
  367. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/cpu-x64.cc +4 -0
  368. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/debug-x64.cc +55 -6
  369. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/disasm-x64.cc +42 -19
  370. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/fast-codegen-x64.cc +4 -0
  371. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/frames-x64.cc +4 -0
  372. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/frames-x64.h +4 -0
  373. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/full-codegen-x64.cc +1487 -210
  374. data/ext/v8/upstream/2.3.3/src/x64/ic-x64.cc +1907 -0
  375. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/jump-target-x64.cc +4 -0
  376. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/macro-assembler-x64.cc +366 -338
  377. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/macro-assembler-x64.h +83 -38
  378. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/regexp-macro-assembler-x64.cc +82 -23
  379. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/regexp-macro-assembler-x64.h +1 -2
  380. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/register-allocator-x64-inl.h +6 -5
  381. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/register-allocator-x64.cc +4 -0
  382. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/register-allocator-x64.h +1 -1
  383. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/simulator-x64.cc +0 -0
  384. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/simulator-x64.h +0 -0
  385. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/stub-cache-x64.cc +556 -377
  386. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/virtual-frame-x64.cc +197 -98
  387. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/virtual-frame-x64.h +37 -28
  388. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/zone-inl.h +0 -0
  389. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/zone.cc +0 -0
  390. data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/zone.h +0 -0
  391. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/codemap.js +0 -0
  392. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/consarray.js +0 -0
  393. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/csvparser.js +0 -0
  394. data/ext/v8/upstream/2.3.3/tools/gc-nvp-trace-processor.py +317 -0
  395. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/generate-ten-powers.scm +0 -0
  396. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/gyp/v8.gyp +87 -20
  397. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/js2c.py +19 -15
  398. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/jsmin.py +0 -0
  399. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/linux-tick-processor +0 -0
  400. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/linux-tick-processor.py +0 -0
  401. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/logreader.js +0 -0
  402. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/mac-nm +0 -0
  403. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/mac-tick-processor +0 -0
  404. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/annotate +0 -0
  405. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/common +0 -0
  406. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/dump +0 -0
  407. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/report +0 -0
  408. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/reset +0 -0
  409. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/run +0 -0
  410. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/shutdown +0 -0
  411. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/start +0 -0
  412. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/presubmit.py +0 -0
  413. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/process-heap-prof.py +0 -0
  414. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/profile.js +0 -0
  415. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/profile_view.js +0 -0
  416. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/run-valgrind.py +0 -0
  417. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/splaytree.js +0 -0
  418. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/splaytree.py +0 -0
  419. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/stats-viewer.py +25 -13
  420. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/test.py +0 -0
  421. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/tickprocessor-driver.js +0 -0
  422. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/tickprocessor.js +0 -0
  423. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/tickprocessor.py +0 -0
  424. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/utils.py +0 -0
  425. data/ext/v8/upstream/2.3.3/tools/v8.xcodeproj/project.pbxproj +1855 -0
  426. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/README.txt +0 -0
  427. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/arm.vsprops +0 -0
  428. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/common.vsprops +0 -0
  429. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8.vcproj +0 -0
  430. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8_arm.vcproj +0 -0
  431. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8_x64.vcproj +0 -0
  432. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8js2c.cmd +0 -0
  433. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/debug.vsprops +0 -0
  434. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/ia32.vsprops +0 -0
  435. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/js2c.cmd +0 -0
  436. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/release.vsprops +0 -0
  437. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8.sln +0 -0
  438. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8.vcproj +0 -0
  439. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_arm.sln +0 -0
  440. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_arm.vcproj +0 -0
  441. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_base.vcproj +40 -0
  442. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_base_arm.vcproj +20 -0
  443. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_base_x64.vcproj +16 -0
  444. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_cctest.vcproj +4 -0
  445. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_cctest_arm.vcproj +0 -0
  446. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_cctest_x64.vcproj +0 -0
  447. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_mksnapshot.vcproj +0 -0
  448. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_mksnapshot_x64.vcproj +0 -0
  449. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_process_sample.vcproj +0 -0
  450. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_process_sample_arm.vcproj +0 -0
  451. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_process_sample_x64.vcproj +0 -0
  452. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_shell_sample.vcproj +0 -0
  453. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_shell_sample_arm.vcproj +0 -0
  454. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_shell_sample_x64.vcproj +0 -0
  455. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot.vcproj +0 -0
  456. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot_cc.vcproj +0 -0
  457. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot_cc_x64.vcproj +0 -0
  458. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot_x64.vcproj +0 -0
  459. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_x64.sln +0 -0
  460. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_x64.vcproj +0 -0
  461. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/x64.vsprops +0 -0
  462. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/windows-tick-processor.bat +0 -0
  463. data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/windows-tick-processor.py +0 -0
  464. data/ext/v8/upstream/Makefile +1 -1
  465. data/ext/v8/v8_template.cpp +94 -2
  466. data/ext/v8/v8_try_catch.cpp +2 -2
  467. data/lib/v8.rb +1 -1
  468. data/lib/v8/access.rb +93 -40
  469. data/lib/v8/cli.rb +1 -1
  470. data/lib/v8/function.rb +14 -2
  471. data/spec/redjs/jsapi_spec.rb +231 -42
  472. data/therubyracer.gemspec +3 -3
  473. metadata +463 -453
  474. data/ext/v8/upstream/2.1.10/src/arm/assembler-thumb2-inl.h +0 -263
  475. data/ext/v8/upstream/2.1.10/src/arm/assembler-thumb2.cc +0 -1878
  476. data/ext/v8/upstream/2.1.10/src/arm/assembler-thumb2.h +0 -1036
  477. data/ext/v8/upstream/2.1.10/src/arm/codegen-arm-inl.h +0 -72
  478. data/ext/v8/upstream/2.1.10/src/arm/ic-arm.cc +0 -1833
  479. data/ext/v8/upstream/2.1.10/src/circular-queue-inl.h +0 -101
  480. data/ext/v8/upstream/2.1.10/src/profile-generator.cc +0 -583
  481. data/ext/v8/upstream/2.1.10/src/profile-generator.h +0 -364
  482. data/ext/v8/upstream/2.1.10/src/x64/ic-x64.cc +0 -1621
@@ -27,6 +27,8 @@
27
27
 
28
28
  #include "v8.h"
29
29
 
30
+ #if defined(V8_TARGET_ARCH_ARM)
31
+
30
32
  #include "codegen-inl.h"
31
33
  #include "fast-codegen.h"
32
34
  #include "scopes.h"
@@ -100,8 +102,7 @@ void FastCodeGenerator::EmitThisPropertyStore(Handle<String> name) {
100
102
  }
101
103
 
102
104
  if (needs_write_barrier) {
103
- __ mov(scratch1(), Operand(offset));
104
- __ RecordWrite(scratch0(), scratch1(), scratch2());
105
+ __ RecordWrite(scratch0(), Operand(offset), scratch1(), scratch2());
105
106
  }
106
107
 
107
108
  if (destination().is(accumulator1())) {
@@ -236,3 +237,5 @@ void FastCodeGenerator::Generate(CompilationInfo* compilation_info) {
236
237
 
237
238
 
238
239
  } } // namespace v8::internal
240
+
241
+ #endif // V8_TARGET_ARCH_ARM
@@ -27,12 +27,10 @@
27
27
 
28
28
  #include "v8.h"
29
29
 
30
+ #if defined(V8_TARGET_ARCH_ARM)
31
+
30
32
  #include "frames-inl.h"
31
- #ifdef V8_ARM_VARIANT_THUMB
32
- #include "arm/assembler-thumb2-inl.h"
33
- #else
34
33
  #include "arm/assembler-arm-inl.h"
35
- #endif
36
34
 
37
35
 
38
36
  namespace v8 {
@@ -121,3 +119,5 @@ Address InternalFrame::GetCallerStackPointer() const {
121
119
 
122
120
 
123
121
  } } // namespace v8::internal
122
+
123
+ #endif // V8_TARGET_ARCH_ARM
@@ -27,6 +27,8 @@
27
27
 
28
28
  #include "v8.h"
29
29
 
30
+ #if defined(V8_TARGET_ARCH_ARM)
31
+
30
32
  #include "codegen-inl.h"
31
33
  #include "compiler.h"
32
34
  #include "debug.h"
@@ -62,7 +64,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
62
64
  if (mode == PRIMARY) {
63
65
  int locals_count = scope()->num_stack_slots();
64
66
 
65
- __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
67
+ __ Push(lr, fp, cp, r1);
66
68
  if (locals_count > 0) {
67
69
  // Load undefined value here, so the value is ready for the loop
68
70
  // below.
@@ -80,11 +82,17 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
80
82
  bool function_in_register = true;
81
83
 
82
84
  // Possibly allocate a local context.
83
- if (scope()->num_heap_slots() > 0) {
85
+ int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
86
+ if (heap_slots > 0) {
84
87
  Comment cmnt(masm_, "[ Allocate local context");
85
88
  // Argument to NewContext is the function, which is in r1.
86
89
  __ push(r1);
87
- __ CallRuntime(Runtime::kNewContext, 1);
90
+ if (heap_slots <= FastNewContextStub::kMaximumSlots) {
91
+ FastNewContextStub stub(heap_slots);
92
+ __ CallStub(&stub);
93
+ } else {
94
+ __ CallRuntime(Runtime::kNewContext, 1);
95
+ }
88
96
  function_in_register = false;
89
97
  // Context is returned in both r0 and cp. It replaces the context
90
98
  // passed to us. It's saved in the stack and kept live in cp.
@@ -102,10 +110,10 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
102
110
  __ mov(r1, Operand(Context::SlotOffset(slot->index())));
103
111
  __ str(r0, MemOperand(cp, r1));
104
112
  // Update the write barrier. This clobbers all involved
105
- // registers, so we have use a third register to avoid
113
+ // registers, so we have to use two more registers to avoid
106
114
  // clobbering cp.
107
115
  __ mov(r2, Operand(cp));
108
- __ RecordWrite(r2, r1, r0);
116
+ __ RecordWrite(r2, Operand(r1), r3, r0);
109
117
  }
110
118
  }
111
119
  }
@@ -142,6 +150,21 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
142
150
  }
143
151
  }
144
152
 
153
+ { Comment cmnt(masm_, "[ Declarations");
154
+ // For named function expressions, declare the function name as a
155
+ // constant.
156
+ if (scope()->is_function_scope() && scope()->function() != NULL) {
157
+ EmitDeclaration(scope()->function(), Variable::CONST, NULL);
158
+ }
159
+ // Visit all the explicit declarations unless there is an illegal
160
+ // redeclaration.
161
+ if (scope()->HasIllegalRedeclaration()) {
162
+ scope()->VisitIllegalRedeclaration(this);
163
+ } else {
164
+ VisitDeclarations(scope()->declarations());
165
+ }
166
+ }
167
+
145
168
  // Check the stack for overflow or break request.
146
169
  // Put the lr setup instruction in the delay slot. The kInstrSize is
147
170
  // added to the implicit 8 byte offset that always applies to operations
@@ -158,10 +181,6 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
158
181
  lo);
159
182
  }
160
183
 
161
- { Comment cmnt(masm_, "[ Declarations");
162
- VisitDeclarations(scope()->declarations());
163
- }
164
-
165
184
  if (FLAG_trace) {
166
185
  __ CallRuntime(Runtime::kTraceEnter, 0);
167
186
  }
@@ -177,11 +196,11 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
177
196
  // body.
178
197
  __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
179
198
  }
180
- EmitReturnSequence(function()->end_position());
199
+ EmitReturnSequence();
181
200
  }
182
201
 
183
202
 
184
- void FullCodeGenerator::EmitReturnSequence(int position) {
203
+ void FullCodeGenerator::EmitReturnSequence() {
185
204
  Comment cmnt(masm_, "[ Return sequence");
186
205
  if (return_label_.is_bound()) {
187
206
  __ b(&return_label_);
@@ -205,7 +224,7 @@ void FullCodeGenerator::EmitReturnSequence(int position) {
205
224
  // Here we use masm_-> instead of the __ macro to avoid the code coverage
206
225
  // tool from instrumenting as we rely on the code size here.
207
226
  int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
208
- CodeGenerator::RecordPositions(masm_, position);
227
+ CodeGenerator::RecordPositions(masm_, function()->end_position());
209
228
  __ RecordJSReturn();
210
229
  masm_->mov(sp, fp);
211
230
  masm_->ldm(ia_w, sp, fp.bit() | lr.bit());
@@ -219,8 +238,10 @@ void FullCodeGenerator::EmitReturnSequence(int position) {
219
238
  // add instruction the add will generate two instructions.
220
239
  int return_sequence_length =
221
240
  masm_->InstructionsGeneratedSince(&check_exit_codesize);
222
- CHECK(return_sequence_length == Assembler::kJSReturnSequenceLength ||
223
- return_sequence_length == Assembler::kJSReturnSequenceLength + 1);
241
+ CHECK(return_sequence_length ==
242
+ Assembler::kJSReturnSequenceInstructions ||
243
+ return_sequence_length ==
244
+ Assembler::kJSReturnSequenceInstructions + 1);
224
245
  #endif
225
246
  }
226
247
  }
@@ -382,6 +403,38 @@ void FullCodeGenerator::DropAndApply(int count,
382
403
  }
383
404
  }
384
405
 
406
+ void FullCodeGenerator::PrepareTest(Label* materialize_true,
407
+ Label* materialize_false,
408
+ Label** if_true,
409
+ Label** if_false) {
410
+ switch (context_) {
411
+ case Expression::kUninitialized:
412
+ UNREACHABLE();
413
+ break;
414
+ case Expression::kEffect:
415
+ // In an effect context, the true and the false case branch to the
416
+ // same label.
417
+ *if_true = *if_false = materialize_true;
418
+ break;
419
+ case Expression::kValue:
420
+ *if_true = materialize_true;
421
+ *if_false = materialize_false;
422
+ break;
423
+ case Expression::kTest:
424
+ *if_true = true_label_;
425
+ *if_false = false_label_;
426
+ break;
427
+ case Expression::kValueTest:
428
+ *if_true = materialize_true;
429
+ *if_false = false_label_;
430
+ break;
431
+ case Expression::kTestValue:
432
+ *if_true = true_label_;
433
+ *if_false = materialize_false;
434
+ break;
435
+ }
436
+ }
437
+
385
438
 
386
439
  void FullCodeGenerator::Apply(Expression::Context context,
387
440
  Label* materialize_true,
@@ -396,19 +449,25 @@ void FullCodeGenerator::Apply(Expression::Context context,
396
449
 
397
450
  case Expression::kValue: {
398
451
  Label done;
399
- __ bind(materialize_true);
400
- __ mov(result_register(), Operand(Factory::true_value()));
401
- __ jmp(&done);
402
- __ bind(materialize_false);
403
- __ mov(result_register(), Operand(Factory::false_value()));
404
- __ bind(&done);
405
452
  switch (location_) {
406
453
  case kAccumulator:
454
+ __ bind(materialize_true);
455
+ __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
456
+ __ jmp(&done);
457
+ __ bind(materialize_false);
458
+ __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
407
459
  break;
408
460
  case kStack:
409
- __ push(result_register());
461
+ __ bind(materialize_true);
462
+ __ LoadRoot(ip, Heap::kTrueValueRootIndex);
463
+ __ push(ip);
464
+ __ jmp(&done);
465
+ __ bind(materialize_false);
466
+ __ LoadRoot(ip, Heap::kFalseValueRootIndex);
467
+ __ push(ip);
410
468
  break;
411
469
  }
470
+ __ bind(&done);
412
471
  break;
413
472
  }
414
473
 
@@ -417,12 +476,13 @@ void FullCodeGenerator::Apply(Expression::Context context,
417
476
 
418
477
  case Expression::kValueTest:
419
478
  __ bind(materialize_true);
420
- __ mov(result_register(), Operand(Factory::true_value()));
421
479
  switch (location_) {
422
480
  case kAccumulator:
481
+ __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
423
482
  break;
424
483
  case kStack:
425
- __ push(result_register());
484
+ __ LoadRoot(ip, Heap::kTrueValueRootIndex);
485
+ __ push(ip);
426
486
  break;
427
487
  }
428
488
  __ jmp(true_label_);
@@ -430,12 +490,13 @@ void FullCodeGenerator::Apply(Expression::Context context,
430
490
 
431
491
  case Expression::kTestValue:
432
492
  __ bind(materialize_false);
433
- __ mov(result_register(), Operand(Factory::false_value()));
434
493
  switch (location_) {
435
494
  case kAccumulator:
495
+ __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
436
496
  break;
437
497
  case kStack:
438
- __ push(result_register());
498
+ __ LoadRoot(ip, Heap::kFalseValueRootIndex);
499
+ __ push(ip);
439
500
  break;
440
501
  }
441
502
  __ jmp(false_label_);
@@ -444,6 +505,68 @@ void FullCodeGenerator::Apply(Expression::Context context,
444
505
  }
445
506
 
446
507
 
508
+ // Convert constant control flow (true or false) to the result expected for
509
+ // a given expression context.
510
+ void FullCodeGenerator::Apply(Expression::Context context, bool flag) {
511
+ switch (context) {
512
+ case Expression::kUninitialized:
513
+ UNREACHABLE();
514
+ break;
515
+ case Expression::kEffect:
516
+ break;
517
+ case Expression::kValue: {
518
+ Heap::RootListIndex value_root_index =
519
+ flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
520
+ switch (location_) {
521
+ case kAccumulator:
522
+ __ LoadRoot(result_register(), value_root_index);
523
+ break;
524
+ case kStack:
525
+ __ LoadRoot(ip, value_root_index);
526
+ __ push(ip);
527
+ break;
528
+ }
529
+ break;
530
+ }
531
+ case Expression::kTest:
532
+ __ b(flag ? true_label_ : false_label_);
533
+ break;
534
+ case Expression::kTestValue:
535
+ switch (location_) {
536
+ case kAccumulator:
537
+ // If value is false it's needed.
538
+ if (!flag) __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
539
+ break;
540
+ case kStack:
541
+ // If value is false it's needed.
542
+ if (!flag) {
543
+ __ LoadRoot(ip, Heap::kFalseValueRootIndex);
544
+ __ push(ip);
545
+ }
546
+ break;
547
+ }
548
+ __ b(flag ? true_label_ : false_label_);
549
+ break;
550
+ case Expression::kValueTest:
551
+ switch (location_) {
552
+ case kAccumulator:
553
+ // If value is true it's needed.
554
+ if (flag) __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
555
+ break;
556
+ case kStack:
557
+ // If value is true it's needed.
558
+ if (flag) {
559
+ __ LoadRoot(ip, Heap::kTrueValueRootIndex);
560
+ __ push(ip);
561
+ }
562
+ break;
563
+ }
564
+ __ b(flag ? true_label_ : false_label_);
565
+ break;
566
+ }
567
+ }
568
+
569
+
447
570
  void FullCodeGenerator::DoTest(Expression::Context context) {
448
571
  // The value to test is pushed on the stack, and duplicated on the stack
449
572
  // if necessary (for value/test and test/value contexts).
@@ -543,28 +666,31 @@ void FullCodeGenerator::Move(Slot* dst,
543
666
  __ str(src, location);
544
667
  // Emit the write barrier code if the location is in the heap.
545
668
  if (dst->type() == Slot::CONTEXT) {
546
- __ mov(scratch2, Operand(Context::SlotOffset(dst->index())));
547
- __ RecordWrite(scratch1, scratch2, src);
669
+ __ RecordWrite(scratch1,
670
+ Operand(Context::SlotOffset(dst->index())),
671
+ scratch2,
672
+ src);
548
673
  }
549
674
  }
550
675
 
551
676
 
552
- void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
677
+ void FullCodeGenerator::EmitDeclaration(Variable* variable,
678
+ Variable::Mode mode,
679
+ FunctionLiteral* function) {
553
680
  Comment cmnt(masm_, "[ Declaration");
554
- Variable* var = decl->proxy()->var();
555
- ASSERT(var != NULL); // Must have been resolved.
556
- Slot* slot = var->slot();
557
- Property* prop = var->AsProperty();
681
+ ASSERT(variable != NULL); // Must have been resolved.
682
+ Slot* slot = variable->slot();
683
+ Property* prop = variable->AsProperty();
558
684
 
559
685
  if (slot != NULL) {
560
686
  switch (slot->type()) {
561
687
  case Slot::PARAMETER:
562
688
  case Slot::LOCAL:
563
- if (decl->mode() == Variable::CONST) {
689
+ if (mode == Variable::CONST) {
564
690
  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
565
691
  __ str(ip, MemOperand(fp, SlotOffset(slot)));
566
- } else if (decl->fun() != NULL) {
567
- VisitForValue(decl->fun(), kAccumulator);
692
+ } else if (function != NULL) {
693
+ VisitForValue(function, kAccumulator);
568
694
  __ str(result_register(), MemOperand(fp, SlotOffset(slot)));
569
695
  }
570
696
  break;
@@ -574,7 +700,7 @@ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
574
700
  // this specific context.
575
701
 
576
702
  // The variable in the decl always resides in the current context.
577
- ASSERT_EQ(0, scope()->ContextChainLength(var->scope()));
703
+ ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
578
704
  if (FLAG_debug_code) {
579
705
  // Check if we have the correct context pointer.
580
706
  __ ldr(r1,
@@ -582,44 +708,43 @@ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
582
708
  __ cmp(r1, cp);
583
709
  __ Check(eq, "Unexpected declaration in current context.");
584
710
  }
585
- if (decl->mode() == Variable::CONST) {
711
+ if (mode == Variable::CONST) {
586
712
  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
587
713
  __ str(ip, CodeGenerator::ContextOperand(cp, slot->index()));
588
714
  // No write barrier since the_hole_value is in old space.
589
- } else if (decl->fun() != NULL) {
590
- VisitForValue(decl->fun(), kAccumulator);
715
+ } else if (function != NULL) {
716
+ VisitForValue(function, kAccumulator);
591
717
  __ str(result_register(),
592
718
  CodeGenerator::ContextOperand(cp, slot->index()));
593
719
  int offset = Context::SlotOffset(slot->index());
594
- __ mov(r2, Operand(offset));
595
720
  // We know that we have written a function, which is not a smi.
596
721
  __ mov(r1, Operand(cp));
597
- __ RecordWrite(r1, r2, result_register());
722
+ __ RecordWrite(r1, Operand(offset), r2, result_register());
598
723
  }
599
724
  break;
600
725
 
601
726
  case Slot::LOOKUP: {
602
- __ mov(r2, Operand(var->name()));
727
+ __ mov(r2, Operand(variable->name()));
603
728
  // Declaration nodes are always introduced in one of two modes.
604
- ASSERT(decl->mode() == Variable::VAR ||
605
- decl->mode() == Variable::CONST);
729
+ ASSERT(mode == Variable::VAR ||
730
+ mode == Variable::CONST);
606
731
  PropertyAttributes attr =
607
- (decl->mode() == Variable::VAR) ? NONE : READ_ONLY;
732
+ (mode == Variable::VAR) ? NONE : READ_ONLY;
608
733
  __ mov(r1, Operand(Smi::FromInt(attr)));
609
734
  // Push initial value, if any.
610
735
  // Note: For variables we must not push an initial value (such as
611
736
  // 'undefined') because we may have a (legal) redeclaration and we
612
737
  // must not destroy the current value.
613
- if (decl->mode() == Variable::CONST) {
738
+ if (mode == Variable::CONST) {
614
739
  __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
615
- __ stm(db_w, sp, cp.bit() | r2.bit() | r1.bit() | r0.bit());
616
- } else if (decl->fun() != NULL) {
617
- __ stm(db_w, sp, cp.bit() | r2.bit() | r1.bit());
740
+ __ Push(cp, r2, r1, r0);
741
+ } else if (function != NULL) {
742
+ __ Push(cp, r2, r1);
618
743
  // Push initial value for function declaration.
619
- VisitForValue(decl->fun(), kStack);
744
+ VisitForValue(function, kStack);
620
745
  } else {
621
746
  __ mov(r0, Operand(Smi::FromInt(0))); // No initial value!
622
- __ stm(db_w, sp, cp.bit() | r2.bit() | r1.bit() | r0.bit());
747
+ __ Push(cp, r2, r1, r0);
623
748
  }
624
749
  __ CallRuntime(Runtime::kDeclareContextSlot, 4);
625
750
  break;
@@ -627,53 +752,272 @@ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
627
752
  }
628
753
 
629
754
  } else if (prop != NULL) {
630
- if (decl->fun() != NULL || decl->mode() == Variable::CONST) {
755
+ if (function != NULL || mode == Variable::CONST) {
631
756
  // We are declaring a function or constant that rewrites to a
632
757
  // property. Use (keyed) IC to set the initial value.
633
758
  VisitForValue(prop->obj(), kStack);
634
- VisitForValue(prop->key(), kStack);
635
-
636
- if (decl->fun() != NULL) {
637
- VisitForValue(decl->fun(), kAccumulator);
759
+ if (function != NULL) {
760
+ VisitForValue(prop->key(), kStack);
761
+ VisitForValue(function, kAccumulator);
762
+ __ pop(r1); // Key.
638
763
  } else {
764
+ VisitForValue(prop->key(), kAccumulator);
765
+ __ mov(r1, result_register()); // Key.
639
766
  __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex);
640
767
  }
768
+ __ pop(r2); // Receiver.
641
769
 
642
770
  Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
643
771
  __ Call(ic, RelocInfo::CODE_TARGET);
644
-
645
- // Value in r0 is ignored (declarations are statements). Receiver
646
- // and key on stack are discarded.
647
- __ Drop(2);
772
+ // Value in r0 is ignored (declarations are statements).
648
773
  }
649
774
  }
650
775
  }
651
776
 
652
777
 
778
+ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
779
+ EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
780
+ }
781
+
782
+
653
783
  void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
654
784
  // Call the runtime to declare the globals.
655
785
  // The context is the first argument.
656
786
  __ mov(r1, Operand(pairs));
657
787
  __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
658
- __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit());
788
+ __ Push(cp, r1, r0);
659
789
  __ CallRuntime(Runtime::kDeclareGlobals, 3);
660
790
  // Return value is ignored.
661
791
  }
662
792
 
663
793
 
664
- void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
665
- Comment cmnt(masm_, "[ FunctionLiteral");
794
+ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
795
+ Comment cmnt(masm_, "[ SwitchStatement");
796
+ Breakable nested_statement(this, stmt);
797
+ SetStatementPosition(stmt);
798
+ // Keep the switch value on the stack until a case matches.
799
+ VisitForValue(stmt->tag(), kStack);
800
+
801
+ ZoneList<CaseClause*>* clauses = stmt->cases();
802
+ CaseClause* default_clause = NULL; // Can occur anywhere in the list.
803
+
804
+ Label next_test; // Recycled for each test.
805
+ // Compile all the tests with branches to their bodies.
806
+ for (int i = 0; i < clauses->length(); i++) {
807
+ CaseClause* clause = clauses->at(i);
808
+ // The default is not a test, but remember it as final fall through.
809
+ if (clause->is_default()) {
810
+ default_clause = clause;
811
+ continue;
812
+ }
813
+
814
+ Comment cmnt(masm_, "[ Case comparison");
815
+ __ bind(&next_test);
816
+ next_test.Unuse();
817
+
818
+ // Compile the label expression.
819
+ VisitForValue(clause->label(), kAccumulator);
820
+
821
+ // Perform the comparison as if via '==='. The comparison stub expects
822
+ // the smi vs. smi case to be handled before it is called.
823
+ Label slow_case;
824
+ __ ldr(r1, MemOperand(sp, 0)); // Switch value.
825
+ __ orr(r2, r1, r0);
826
+ __ tst(r2, Operand(kSmiTagMask));
827
+ __ b(ne, &slow_case);
828
+ __ cmp(r1, r0);
829
+ __ b(ne, &next_test);
830
+ __ Drop(1); // Switch value is no longer needed.
831
+ __ b(clause->body_target()->entry_label());
832
+
833
+ __ bind(&slow_case);
834
+ CompareStub stub(eq, true, kBothCouldBeNaN, true, r1, r0);
835
+ __ CallStub(&stub);
836
+ __ cmp(r0, Operand(0));
837
+ __ b(ne, &next_test);
838
+ __ Drop(1); // Switch value is no longer needed.
839
+ __ b(clause->body_target()->entry_label());
840
+ }
841
+
842
+ // Discard the test value and jump to the default if present, otherwise to
843
+ // the end of the statement.
844
+ __ bind(&next_test);
845
+ __ Drop(1); // Switch value is no longer needed.
846
+ if (default_clause == NULL) {
847
+ __ b(nested_statement.break_target());
848
+ } else {
849
+ __ b(default_clause->body_target()->entry_label());
850
+ }
851
+
852
+ // Compile all the case bodies.
853
+ for (int i = 0; i < clauses->length(); i++) {
854
+ Comment cmnt(masm_, "[ Case body");
855
+ CaseClause* clause = clauses->at(i);
856
+ __ bind(clause->body_target()->entry_label());
857
+ VisitStatements(clause->statements());
858
+ }
859
+
860
+ __ bind(nested_statement.break_target());
861
+ }
862
+
863
+
864
+ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
865
+ Comment cmnt(masm_, "[ ForInStatement");
866
+ SetStatementPosition(stmt);
867
+
868
+ Label loop, exit;
869
+ ForIn loop_statement(this, stmt);
870
+ increment_loop_depth();
666
871
 
667
- // Build the shared function info and instantiate the function based
668
- // on it.
669
- Handle<SharedFunctionInfo> function_info =
670
- Compiler::BuildFunctionInfo(expr, script(), this);
671
- if (HasStackOverflow()) return;
872
+ // Get the object to enumerate over. Both SpiderMonkey and JSC
873
+ // ignore null and undefined in contrast to the specification; see
874
+ // ECMA-262 section 12.6.4.
875
+ VisitForValue(stmt->enumerable(), kAccumulator);
876
+ __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
877
+ __ cmp(r0, ip);
878
+ __ b(eq, &exit);
879
+ __ LoadRoot(ip, Heap::kNullValueRootIndex);
880
+ __ cmp(r0, ip);
881
+ __ b(eq, &exit);
882
+
883
+ // Convert the object to a JS object.
884
+ Label convert, done_convert;
885
+ __ BranchOnSmi(r0, &convert);
886
+ __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
887
+ __ b(hs, &done_convert);
888
+ __ bind(&convert);
889
+ __ push(r0);
890
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
891
+ __ bind(&done_convert);
892
+ __ push(r0);
893
+
894
+ // TODO(kasperl): Check cache validity in generated code. This is a
895
+ // fast case for the JSObject::IsSimpleEnum cache validity
896
+ // checks. If we cannot guarantee cache validity, call the runtime
897
+ // system to check cache validity or get the property names in a
898
+ // fixed array.
899
+
900
+ // Get the set of properties to enumerate.
901
+ __ push(r0); // Duplicate the enumerable object on the stack.
902
+ __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
903
+
904
+ // If we got a map from the runtime call, we can do a fast
905
+ // modification check. Otherwise, we got a fixed array, and we have
906
+ // to do a slow check.
907
+ Label fixed_array;
908
+ __ mov(r2, r0);
909
+ __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset));
910
+ __ LoadRoot(ip, Heap::kMetaMapRootIndex);
911
+ __ cmp(r1, ip);
912
+ __ b(ne, &fixed_array);
913
+
914
+ // We got a map in register r0. Get the enumeration cache from it.
915
+ __ ldr(r1, FieldMemOperand(r0, Map::kInstanceDescriptorsOffset));
916
+ __ ldr(r1, FieldMemOperand(r1, DescriptorArray::kEnumerationIndexOffset));
917
+ __ ldr(r2, FieldMemOperand(r1, DescriptorArray::kEnumCacheBridgeCacheOffset));
918
+
919
+ // Setup the four remaining stack slots.
920
+ __ push(r0); // Map.
921
+ __ ldr(r1, FieldMemOperand(r2, FixedArray::kLengthOffset));
922
+ __ mov(r0, Operand(Smi::FromInt(0)));
923
+ // Push enumeration cache, enumeration cache length (as smi) and zero.
924
+ __ Push(r2, r1, r0);
925
+ __ jmp(&loop);
926
+
927
+ // We got a fixed array in register r0. Iterate through that.
928
+ __ bind(&fixed_array);
929
+ __ mov(r1, Operand(Smi::FromInt(0))); // Map (0) - force slow check.
930
+ __ Push(r1, r0);
931
+ __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
932
+ __ mov(r0, Operand(Smi::FromInt(0)));
933
+ __ Push(r1, r0); // Fixed array length (as smi) and initial index.
934
+
935
+ // Generate code for doing the condition check.
936
+ __ bind(&loop);
937
+ // Load the current count to r0, load the length to r1.
938
+ __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
939
+ __ cmp(r0, r1); // Compare to the array length.
940
+ __ b(hs, loop_statement.break_target());
941
+
942
+ // Get the current entry of the array into register r3.
943
+ __ ldr(r2, MemOperand(sp, 2 * kPointerSize));
944
+ __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
945
+ __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize));
946
+
947
+ // Get the expected map from the stack or a zero map in the
948
+ // permanent slow case into register r2.
949
+ __ ldr(r2, MemOperand(sp, 3 * kPointerSize));
950
+
951
+ // Check if the expected map still matches that of the enumerable.
952
+ // If not, we have to filter the key.
953
+ Label update_each;
954
+ __ ldr(r1, MemOperand(sp, 4 * kPointerSize));
955
+ __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
956
+ __ cmp(r4, Operand(r2));
957
+ __ b(eq, &update_each);
958
+
959
+ // Convert the entry to a string or null if it isn't a property
960
+ // anymore. If the property has been removed while iterating, we
961
+ // just skip it.
962
+ __ push(r1); // Enumerable.
963
+ __ push(r3); // Current entry.
964
+ __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS);
965
+ __ mov(r3, Operand(r0));
966
+ __ LoadRoot(ip, Heap::kNullValueRootIndex);
967
+ __ cmp(r3, ip);
968
+ __ b(eq, loop_statement.continue_target());
969
+
970
+ // Update the 'each' property or variable from the possibly filtered
971
+ // entry in register r3.
972
+ __ bind(&update_each);
973
+ __ mov(result_register(), r3);
974
+ // Perform the assignment as if via '='.
975
+ EmitAssignment(stmt->each());
976
+
977
+ // Generate code for the body of the loop.
978
+ Label stack_limit_hit, stack_check_done;
979
+ Visit(stmt->body());
980
+
981
+ __ StackLimitCheck(&stack_limit_hit);
982
+ __ bind(&stack_check_done);
983
+
984
+ // Generate code for the going to the next element by incrementing
985
+ // the index (smi) stored on top of the stack.
986
+ __ bind(loop_statement.continue_target());
987
+ __ pop(r0);
988
+ __ add(r0, r0, Operand(Smi::FromInt(1)));
989
+ __ push(r0);
990
+ __ b(&loop);
991
+
992
+ // Slow case for the stack limit check.
993
+ StackCheckStub stack_check_stub;
994
+ __ bind(&stack_limit_hit);
995
+ __ CallStub(&stack_check_stub);
996
+ __ b(&stack_check_done);
672
997
 
673
- // Create a new closure.
674
- __ mov(r0, Operand(function_info));
675
- __ stm(db_w, sp, cp.bit() | r0.bit());
676
- __ CallRuntime(Runtime::kNewClosure, 2);
998
+ // Remove the pointers stored on the stack.
999
+ __ bind(loop_statement.break_target());
1000
+ __ Drop(5);
1001
+
1002
+ // Exit and decrement the loop depth.
1003
+ __ bind(&exit);
1004
+ decrement_loop_depth();
1005
+ }
1006
+
1007
+
1008
+ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info) {
1009
+ // Use the fast case closure allocation code that allocates in new
1010
+ // space for nested functions that don't need literals cloning.
1011
+ if (scope()->is_function_scope() && info->num_literals() == 0) {
1012
+ FastNewClosureStub stub;
1013
+ __ mov(r0, Operand(info));
1014
+ __ push(r0);
1015
+ __ CallStub(&stub);
1016
+ } else {
1017
+ __ mov(r0, Operand(info));
1018
+ __ Push(cp, r0);
1019
+ __ CallRuntime(Runtime::kNewClosure, 2);
1020
+ }
677
1021
  Apply(context_, r0);
678
1022
  }
679
1023
 
@@ -695,18 +1039,17 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
695
1039
  if (var->is_global() && !var->is_this()) {
696
1040
  Comment cmnt(masm_, "Global variable");
697
1041
  // Use inline caching. Variable name is passed in r2 and the global
698
- // object on the stack.
1042
+ // object (receiver) in r0.
699
1043
  __ ldr(r0, CodeGenerator::GlobalObject());
700
- __ push(r0);
701
1044
  __ mov(r2, Operand(var->name()));
702
1045
  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
703
1046
  __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
704
- DropAndApply(1, context, r0);
1047
+ Apply(context, r0);
705
1048
 
706
1049
  } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
707
1050
  Comment cmnt(masm_, "Lookup slot");
708
1051
  __ mov(r1, Operand(var->name()));
709
- __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name.
1052
+ __ Push(cp, r1); // Context and name.
710
1053
  __ CallRuntime(Runtime::kLoadContextSlot, 2);
711
1054
  Apply(context, r0);
712
1055
 
@@ -714,8 +1057,21 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
714
1057
  Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
715
1058
  ? "Context slot"
716
1059
  : "Stack slot");
717
- Apply(context, slot);
718
-
1060
+ if (var->mode() == Variable::CONST) {
1061
+ // Constants may be the hole value if they have not been initialized.
1062
+ // Unhole them.
1063
+ Label done;
1064
+ MemOperand slot_operand = EmitSlotSearch(slot, r0);
1065
+ __ ldr(r0, slot_operand);
1066
+ __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1067
+ __ cmp(r0, ip);
1068
+ __ b(ne, &done);
1069
+ __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
1070
+ __ bind(&done);
1071
+ Apply(context, r0);
1072
+ } else {
1073
+ Apply(context, slot);
1074
+ }
719
1075
  } else {
720
1076
  Comment cmnt(masm_, "Rewritten parameter");
721
1077
  ASSERT_NOT_NULL(property);
@@ -738,15 +1094,10 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
738
1094
  // Load the key.
739
1095
  __ mov(r0, Operand(key_literal->handle()));
740
1096
 
741
- // Push both as arguments to ic.
742
- __ Push(r1, r0);
743
-
744
- // Call keyed load IC. It has all arguments on the stack and the key in r0.
1097
+ // Call keyed load IC. It has arguments key and receiver in r0 and r1.
745
1098
  Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
746
1099
  __ Call(ic, RelocInfo::CODE_TARGET);
747
-
748
- // Drop key and object left on the stack by IC, and push the result.
749
- DropAndApply(2, context, r0);
1100
+ Apply(context, r0);
750
1101
  }
751
1102
  }
752
1103
 
@@ -856,6 +1207,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
856
1207
 
857
1208
  void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
858
1209
  Comment cmnt(masm_, "[ ArrayLiteral");
1210
+
1211
+ ZoneList<Expression*>* subexprs = expr->values();
1212
+ int length = subexprs->length();
1213
+
859
1214
  __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
860
1215
  __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
861
1216
  __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
@@ -863,16 +1218,18 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
863
1218
  __ Push(r3, r2, r1);
864
1219
  if (expr->depth() > 1) {
865
1220
  __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
866
- } else {
1221
+ } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
867
1222
  __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
1223
+ } else {
1224
+ FastCloneShallowArrayStub stub(length);
1225
+ __ CallStub(&stub);
868
1226
  }
869
1227
 
870
1228
  bool result_saved = false; // Is the result saved to the stack?
871
1229
 
872
1230
  // Emit code to evaluate all the non-constant subexpressions and to store
873
1231
  // them into the newly cloned array.
874
- ZoneList<Expression*>* subexprs = expr->values();
875
- for (int i = 0, len = subexprs->length(); i < len; i++) {
1232
+ for (int i = 0; i < length; i++) {
876
1233
  Expression* subexpr = subexprs->at(i);
877
1234
  // If the subexpression is a literal or a simple materialized literal it
878
1235
  // is already set in the cloned array.
@@ -895,8 +1252,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
895
1252
 
896
1253
  // Update the write barrier for the array store with r0 as the scratch
897
1254
  // register.
898
- __ mov(r2, Operand(offset));
899
- __ RecordWrite(r1, r2, result_register());
1255
+ __ RecordWrite(r1, Operand(offset), r2, result_register());
900
1256
  }
901
1257
 
902
1258
  if (result_saved) {
@@ -909,7 +1265,13 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
909
1265
 
910
1266
  void FullCodeGenerator::VisitAssignment(Assignment* expr) {
911
1267
  Comment cmnt(masm_, "[ Assignment");
912
- ASSERT(expr->op() != Token::INIT_CONST);
1268
+ // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
1269
+ // on the left-hand side.
1270
+ if (!expr->target()->IsValidLeftHandSide()) {
1271
+ VisitForEffect(expr->target());
1272
+ return;
1273
+ }
1274
+
913
1275
  // Left-hand side can only be a property, a global or a (parameter or local)
914
1276
  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
915
1277
  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
@@ -935,8 +1297,16 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
935
1297
  }
936
1298
  break;
937
1299
  case KEYED_PROPERTY:
938
- VisitForValue(prop->obj(), kStack);
939
- VisitForValue(prop->key(), kStack);
1300
+ // We need the key and receiver on both the stack and in r0 and r1.
1301
+ if (expr->is_compound()) {
1302
+ VisitForValue(prop->obj(), kStack);
1303
+ VisitForValue(prop->key(), kAccumulator);
1304
+ __ ldr(r1, MemOperand(sp, 0));
1305
+ __ push(r0);
1306
+ } else {
1307
+ VisitForValue(prop->obj(), kStack);
1308
+ VisitForValue(prop->key(), kStack);
1309
+ }
940
1310
  break;
941
1311
  }
942
1312
 
@@ -981,6 +1351,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
981
1351
  switch (assign_type) {
982
1352
  case VARIABLE:
983
1353
  EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1354
+ expr->op(),
984
1355
  context_);
985
1356
  break;
986
1357
  case NAMED_PROPERTY:
@@ -997,7 +1368,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
997
1368
  SetSourcePosition(prop->position());
998
1369
  Literal* key = prop->key()->AsLiteral();
999
1370
  __ mov(r2, Operand(key->handle()));
1000
- __ ldr(r0, MemOperand(sp, 0));
1371
+ // Call load IC. It has arguments receiver and property name r0 and r2.
1001
1372
  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1002
1373
  __ Call(ic, RelocInfo::CODE_TARGET);
1003
1374
  }
@@ -1005,8 +1376,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1005
1376
 
1006
1377
  void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1007
1378
  SetSourcePosition(prop->position());
1008
- // Call keyed load IC. It has all arguments on the stack and the key in r0.
1009
- __ ldr(r0, MemOperand(sp, 0));
1379
+ // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1010
1380
  Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1011
1381
  __ Call(ic, RelocInfo::CODE_TARGET);
1012
1382
  }
@@ -1021,15 +1391,64 @@ void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1021
1391
  }
1022
1392
 
1023
1393
 
1394
+ void FullCodeGenerator::EmitAssignment(Expression* expr) {
1395
+ // Invalid left-hand sides are rewritten to have a 'throw
1396
+ // ReferenceError' on the left-hand side.
1397
+ if (!expr->IsValidLeftHandSide()) {
1398
+ VisitForEffect(expr);
1399
+ return;
1400
+ }
1401
+
1402
+ // Left-hand side can only be a property, a global or a (parameter or local)
1403
+ // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
1404
+ enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1405
+ LhsKind assign_type = VARIABLE;
1406
+ Property* prop = expr->AsProperty();
1407
+ if (prop != NULL) {
1408
+ assign_type = (prop->key()->IsPropertyName())
1409
+ ? NAMED_PROPERTY
1410
+ : KEYED_PROPERTY;
1411
+ }
1412
+
1413
+ switch (assign_type) {
1414
+ case VARIABLE: {
1415
+ Variable* var = expr->AsVariableProxy()->var();
1416
+ EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect);
1417
+ break;
1418
+ }
1419
+ case NAMED_PROPERTY: {
1420
+ __ push(r0); // Preserve value.
1421
+ VisitForValue(prop->obj(), kAccumulator);
1422
+ __ mov(r1, r0);
1423
+ __ pop(r0); // Restore value.
1424
+ __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
1425
+ Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1426
+ __ Call(ic, RelocInfo::CODE_TARGET);
1427
+ break;
1428
+ }
1429
+ case KEYED_PROPERTY: {
1430
+ __ push(r0); // Preserve value.
1431
+ VisitForValue(prop->obj(), kStack);
1432
+ VisitForValue(prop->key(), kAccumulator);
1433
+ __ mov(r1, r0);
1434
+ __ pop(r2);
1435
+ __ pop(r0); // Restore value.
1436
+ Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1437
+ __ Call(ic, RelocInfo::CODE_TARGET);
1438
+ break;
1439
+ }
1440
+ }
1441
+ }
1442
+
1443
+
1024
1444
  void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1445
+ Token::Value op,
1025
1446
  Expression::Context context) {
1026
- // Three main cases: global variables, lookup slots, and all other
1027
- // types of slots. Left-hand-side parameters that rewrite to
1028
- // explicit property accesses do not reach here.
1447
+ // Left-hand sides that rewrite to explicit property accesses do not reach
1448
+ // here.
1029
1449
  ASSERT(var != NULL);
1030
1450
  ASSERT(var->is_global() || var->slot() != NULL);
1031
1451
 
1032
- Slot* slot = var->slot();
1033
1452
  if (var->is_global()) {
1034
1453
  ASSERT(!var->is_this());
1035
1454
  // Assignment to a global variable. Use inline caching for the
@@ -1040,43 +1459,60 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1040
1459
  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
1041
1460
  __ Call(ic, RelocInfo::CODE_TARGET);
1042
1461
 
1043
- } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1044
- __ push(result_register()); // Value.
1045
- __ mov(r1, Operand(var->name()));
1046
- __ stm(db_w, sp, cp.bit() | r1.bit()); // Context and name.
1047
- __ CallRuntime(Runtime::kStoreContextSlot, 3);
1048
-
1049
- } else if (var->slot() != NULL) {
1462
+ } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
1463
+ // Perform the assignment for non-const variables and for initialization
1464
+ // of const variables. Const assignments are simply skipped.
1465
+ Label done;
1050
1466
  Slot* slot = var->slot();
1051
1467
  switch (slot->type()) {
1052
- case Slot::LOCAL:
1053
1468
  case Slot::PARAMETER:
1469
+ case Slot::LOCAL:
1470
+ if (op == Token::INIT_CONST) {
1471
+ // Detect const reinitialization by checking for the hole value.
1472
+ __ ldr(r1, MemOperand(fp, SlotOffset(slot)));
1473
+ __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1474
+ __ cmp(r1, ip);
1475
+ __ b(ne, &done);
1476
+ }
1477
+ // Perform the assignment.
1054
1478
  __ str(result_register(), MemOperand(fp, SlotOffset(slot)));
1055
1479
  break;
1056
1480
 
1057
1481
  case Slot::CONTEXT: {
1058
1482
  MemOperand target = EmitSlotSearch(slot, r1);
1483
+ if (op == Token::INIT_CONST) {
1484
+ // Detect const reinitialization by checking for the hole value.
1485
+ __ ldr(r2, target);
1486
+ __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
1487
+ __ cmp(r2, ip);
1488
+ __ b(ne, &done);
1489
+ }
1490
+ // Perform the assignment and issue the write barrier.
1059
1491
  __ str(result_register(), target);
1060
-
1061
1492
  // RecordWrite may destroy all its register arguments.
1062
1493
  __ mov(r3, result_register());
1063
1494
  int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
1064
-
1065
- __ mov(r2, Operand(offset));
1066
- __ RecordWrite(r1, r2, r3);
1495
+ __ RecordWrite(r1, Operand(offset), r2, r3);
1067
1496
  break;
1068
1497
  }
1069
1498
 
1070
1499
  case Slot::LOOKUP:
1071
- UNREACHABLE();
1500
+ // Call the runtime for the assignment. The runtime will ignore
1501
+ // const reinitialization.
1502
+ __ push(r0); // Value.
1503
+ __ mov(r0, Operand(slot->var()->name()));
1504
+ __ Push(cp, r0); // Context and name.
1505
+ if (op == Token::INIT_CONST) {
1506
+ // The runtime will ignore const redeclaration.
1507
+ __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1508
+ } else {
1509
+ __ CallRuntime(Runtime::kStoreContextSlot, 3);
1510
+ }
1072
1511
  break;
1073
1512
  }
1074
-
1075
- } else {
1076
- // Variables rewritten as properties are not treated as variables in
1077
- // assignments.
1078
- UNREACHABLE();
1513
+ __ bind(&done);
1079
1514
  }
1515
+
1080
1516
  Apply(context, result_register());
1081
1517
  }
1082
1518
 
@@ -1101,6 +1537,8 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1101
1537
  // Record source code position before IC call.
1102
1538
  SetSourcePosition(expr->position());
1103
1539
  __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
1540
+ // Load receiver to r1. Leave a copy in the stack if needed for turning the
1541
+ // receiver into fast case.
1104
1542
  if (expr->ends_initialization_block()) {
1105
1543
  __ ldr(r1, MemOperand(sp));
1106
1544
  } else {
@@ -1113,7 +1551,8 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1113
1551
  // If the assignment ends an initialization block, revert to fast case.
1114
1552
  if (expr->ends_initialization_block()) {
1115
1553
  __ push(r0); // Result of assignment, saved even if not needed.
1116
- __ ldr(ip, MemOperand(sp, kPointerSize)); // Receiver is under value.
1554
+ // Receiver is under the result value.
1555
+ __ ldr(ip, MemOperand(sp, kPointerSize));
1117
1556
  __ push(ip);
1118
1557
  __ CallRuntime(Runtime::kToFastProperties, 1);
1119
1558
  __ pop(r0);
@@ -1141,21 +1580,30 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
1141
1580
 
1142
1581
  // Record source code position before IC call.
1143
1582
  SetSourcePosition(expr->position());
1583
+ __ pop(r1); // Key.
1584
+ // Load receiver to r2. Leave a copy in the stack if needed for turning the
1585
+ // receiver into fast case.
1586
+ if (expr->ends_initialization_block()) {
1587
+ __ ldr(r2, MemOperand(sp));
1588
+ } else {
1589
+ __ pop(r2);
1590
+ }
1591
+
1144
1592
  Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1145
1593
  __ Call(ic, RelocInfo::CODE_TARGET);
1146
1594
 
1147
1595
  // If the assignment ends an initialization block, revert to fast case.
1148
1596
  if (expr->ends_initialization_block()) {
1149
1597
  __ push(r0); // Result of assignment, saved even if not needed.
1150
- // Receiver is under the key and value.
1151
- __ ldr(ip, MemOperand(sp, 2 * kPointerSize));
1598
+ // Receiver is under the result value.
1599
+ __ ldr(ip, MemOperand(sp, kPointerSize));
1152
1600
  __ push(ip);
1153
1601
  __ CallRuntime(Runtime::kToFastProperties, 1);
1154
1602
  __ pop(r0);
1603
+ DropAndApply(1, context_, r0);
1604
+ } else {
1605
+ Apply(context_, r0);
1155
1606
  }
1156
-
1157
- // Receiver and key are still on stack.
1158
- DropAndApply(2, context_, r0);
1159
1607
  }
1160
1608
 
1161
1609
 
@@ -1163,18 +1611,16 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
1163
1611
  Comment cmnt(masm_, "[ Property");
1164
1612
  Expression* key = expr->key();
1165
1613
 
1166
- // Evaluate receiver.
1167
- VisitForValue(expr->obj(), kStack);
1168
-
1169
1614
  if (key->IsPropertyName()) {
1615
+ VisitForValue(expr->obj(), kAccumulator);
1170
1616
  EmitNamedPropertyLoad(expr);
1171
- // Drop receiver left on the stack by IC.
1172
- DropAndApply(1, context_, r0);
1617
+ Apply(context_, r0);
1173
1618
  } else {
1174
- VisitForValue(expr->key(), kStack);
1619
+ VisitForValue(expr->obj(), kStack);
1620
+ VisitForValue(expr->key(), kAccumulator);
1621
+ __ pop(r1);
1175
1622
  EmitKeyedPropertyLoad(expr);
1176
- // Drop key and receiver left on the stack by IC.
1177
- DropAndApply(2, context_, r0);
1623
+ Apply(context_, r0);
1178
1624
  }
1179
1625
  }
1180
1626
 
@@ -1200,6 +1646,30 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
1200
1646
  }
1201
1647
 
1202
1648
 
1649
+ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
1650
+ Expression* key,
1651
+ RelocInfo::Mode mode) {
1652
+ // Code common for calls using the IC.
1653
+ ZoneList<Expression*>* args = expr->arguments();
1654
+ int arg_count = args->length();
1655
+ for (int i = 0; i < arg_count; i++) {
1656
+ VisitForValue(args->at(i), kStack);
1657
+ }
1658
+ VisitForValue(key, kAccumulator);
1659
+ __ mov(r2, r0);
1660
+ // Record source position for debugger.
1661
+ SetSourcePosition(expr->position());
1662
+ // Call the IC initialization code.
1663
+ InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1664
+ Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
1665
+ in_loop);
1666
+ __ Call(ic, mode);
1667
+ // Restore context register.
1668
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1669
+ Apply(context_, r0);
1670
+ }
1671
+
1672
+
1203
1673
  void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1204
1674
  // Code common for calls using the call stub.
1205
1675
  ZoneList<Expression*>* args = expr->arguments();
@@ -1209,7 +1679,8 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
1209
1679
  }
1210
1680
  // Record source position for debugger.
1211
1681
  SetSourcePosition(expr->position());
1212
- CallFunctionStub stub(arg_count, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE);
1682
+ InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1683
+ CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1213
1684
  __ CallStub(&stub);
1214
1685
  // Restore context register.
1215
1686
  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -1223,8 +1694,51 @@ void FullCodeGenerator::VisitCall(Call* expr) {
1223
1694
  Variable* var = fun->AsVariableProxy()->AsVariable();
1224
1695
 
1225
1696
  if (var != NULL && var->is_possibly_eval()) {
1226
- // Call to the identifier 'eval'.
1227
- UNREACHABLE();
1697
+ // In a call to eval, we first call %ResolvePossiblyDirectEval to
1698
+ // resolve the function we need to call and the receiver of the
1699
+ // call. Then we call the resolved function using the given
1700
+ // arguments.
1701
+ VisitForValue(fun, kStack);
1702
+ __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1703
+ __ push(r2); // Reserved receiver slot.
1704
+
1705
+ // Push the arguments.
1706
+ ZoneList<Expression*>* args = expr->arguments();
1707
+ int arg_count = args->length();
1708
+ for (int i = 0; i < arg_count; i++) {
1709
+ VisitForValue(args->at(i), kStack);
1710
+ }
1711
+
1712
+ // Push copy of the function - found below the arguments.
1713
+ __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
1714
+ __ push(r1);
1715
+
1716
+ // Push copy of the first argument or undefined if it doesn't exist.
1717
+ if (arg_count > 0) {
1718
+ __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
1719
+ __ push(r1);
1720
+ } else {
1721
+ __ push(r2);
1722
+ }
1723
+
1724
+ // Push the receiver of the enclosing function and do runtime call.
1725
+ __ ldr(r1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize));
1726
+ __ push(r1);
1727
+ __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
1728
+
1729
+ // The runtime call returns a pair of values in r0 (function) and
1730
+ // r1 (receiver). Touch up the stack with the right values.
1731
+ __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
1732
+ __ str(r1, MemOperand(sp, arg_count * kPointerSize));
1733
+
1734
+ // Record source position for debugger.
1735
+ SetSourcePosition(expr->position());
1736
+ InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
1737
+ CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
1738
+ __ CallStub(&stub);
1739
+ // Restore context register.
1740
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1741
+ DropAndApply(1, context_, r0);
1228
1742
  } else if (var != NULL && !var->is_this() && var->is_global()) {
1229
1743
  // Push global object as receiver for the call IC.
1230
1744
  __ ldr(r0, CodeGenerator::GlobalObject());
@@ -1232,8 +1746,16 @@ void FullCodeGenerator::VisitCall(Call* expr) {
1232
1746
  EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
1233
1747
  } else if (var != NULL && var->slot() != NULL &&
1234
1748
  var->slot()->type() == Slot::LOOKUP) {
1235
- // Call to a lookup slot.
1236
- UNREACHABLE();
1749
+ // Call to a lookup slot (dynamically introduced variable). Call the
1750
+ // runtime to find the function to call (returned in eax) and the object
1751
+ // holding it (returned in edx).
1752
+ __ push(context_register());
1753
+ __ mov(r2, Operand(var->name()));
1754
+ __ push(r2);
1755
+ __ CallRuntime(Runtime::kLoadContextSlot, 2);
1756
+ __ push(r0); // Function.
1757
+ __ push(r1); // Receiver.
1758
+ EmitCallWithStub(expr);
1237
1759
  } else if (fun->AsProperty() != NULL) {
1238
1760
  // Call to an object property.
1239
1761
  Property* prop = fun->AsProperty();
@@ -1243,28 +1765,28 @@ void FullCodeGenerator::VisitCall(Call* expr) {
1243
1765
  VisitForValue(prop->obj(), kStack);
1244
1766
  EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
1245
1767
  } else {
1246
- // Call to a keyed property, use keyed load IC followed by function
1247
- // call.
1768
+ // Call to a keyed property.
1769
+ // For a synthetic property use keyed load IC followed by function call,
1770
+ // for a regular property use keyed CallIC.
1248
1771
  VisitForValue(prop->obj(), kStack);
1249
- VisitForValue(prop->key(), kStack);
1250
- // Record source code position for IC call.
1251
- SetSourcePosition(prop->position());
1252
- // Call keyed load IC. It has all arguments on the stack and the key in
1253
- // r0.
1254
- __ ldr(r0, MemOperand(sp, 0));
1255
- Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1256
- __ Call(ic, RelocInfo::CODE_TARGET);
1257
- // Load receiver object into r1.
1258
1772
  if (prop->is_synthetic()) {
1773
+ VisitForValue(prop->key(), kAccumulator);
1774
+ // Record source code position for IC call.
1775
+ SetSourcePosition(prop->position());
1776
+ __ pop(r1); // We do not need to keep the receiver.
1777
+
1778
+ Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1779
+ __ Call(ic, RelocInfo::CODE_TARGET);
1780
+ // Push result (function).
1781
+ __ push(r0);
1782
+ // Push Global receiver.
1259
1783
  __ ldr(r1, CodeGenerator::GlobalObject());
1260
1784
  __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
1785
+ __ push(r1);
1786
+ EmitCallWithStub(expr);
1261
1787
  } else {
1262
- __ ldr(r1, MemOperand(sp, kPointerSize));
1788
+ EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
1263
1789
  }
1264
- // Overwrite (object, key) with (function, receiver).
1265
- __ str(r0, MemOperand(sp, kPointerSize));
1266
- __ str(r1, MemOperand(sp));
1267
- EmitCallWithStub(expr);
1268
1790
  }
1269
1791
  } else {
1270
1792
  // Call to some other expression. If the expression is an anonymous
@@ -1322,34 +1844,763 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
1322
1844
  }
1323
1845
 
1324
1846
 
1325
- void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1326
- Comment cmnt(masm_, "[ CallRuntime");
1327
- ZoneList<Expression*>* args = expr->arguments();
1847
+ void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
1848
+ ASSERT(args->length() == 1);
1328
1849
 
1329
- if (expr->is_jsruntime()) {
1330
- // Prepare for calling JS runtime function.
1331
- __ ldr(r0, CodeGenerator::GlobalObject());
1332
- __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
1333
- __ push(r0);
1334
- }
1850
+ VisitForValue(args->at(0), kAccumulator);
1335
1851
 
1336
- // Push the arguments ("left-to-right").
1337
- int arg_count = args->length();
1338
- for (int i = 0; i < arg_count; i++) {
1339
- VisitForValue(args->at(i), kStack);
1340
- }
1852
+ Label materialize_true, materialize_false;
1853
+ Label* if_true = NULL;
1854
+ Label* if_false = NULL;
1855
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1341
1856
 
1342
- if (expr->is_jsruntime()) {
1343
- // Call the JS runtime function.
1344
- __ mov(r2, Operand(expr->name()));
1345
- Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
1346
- NOT_IN_LOOP);
1347
- __ Call(ic, RelocInfo::CODE_TARGET);
1348
- // Restore context register.
1349
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1350
- } else {
1351
- // Call the C runtime function.
1352
- __ CallRuntime(expr->function(), arg_count);
1857
+ __ BranchOnSmi(r0, if_true);
1858
+ __ b(if_false);
1859
+
1860
+ Apply(context_, if_true, if_false);
1861
+ }
1862
+
1863
+
1864
+ void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) {
1865
+ ASSERT(args->length() == 1);
1866
+
1867
+ VisitForValue(args->at(0), kAccumulator);
1868
+
1869
+ Label materialize_true, materialize_false;
1870
+ Label* if_true = NULL;
1871
+ Label* if_false = NULL;
1872
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1873
+
1874
+ __ tst(r0, Operand(kSmiTagMask | 0x80000000));
1875
+ __ b(eq, if_true);
1876
+ __ b(if_false);
1877
+
1878
+ Apply(context_, if_true, if_false);
1879
+ }
1880
+
1881
+
1882
+ void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
1883
+ ASSERT(args->length() == 1);
1884
+
1885
+ VisitForValue(args->at(0), kAccumulator);
1886
+
1887
+ Label materialize_true, materialize_false;
1888
+ Label* if_true = NULL;
1889
+ Label* if_false = NULL;
1890
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1891
+ __ BranchOnSmi(r0, if_false);
1892
+ __ LoadRoot(ip, Heap::kNullValueRootIndex);
1893
+ __ cmp(r0, ip);
1894
+ __ b(eq, if_true);
1895
+ __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1896
+ // Undetectable objects behave like undefined when tested with typeof.
1897
+ __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset));
1898
+ __ tst(r1, Operand(1 << Map::kIsUndetectable));
1899
+ __ b(ne, if_false);
1900
+ __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset));
1901
+ __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
1902
+ __ b(lt, if_false);
1903
+ __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
1904
+ __ b(le, if_true);
1905
+ __ b(if_false);
1906
+
1907
+ Apply(context_, if_true, if_false);
1908
+ }
1909
+
1910
+
1911
+ void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
1912
+ ASSERT(args->length() == 1);
1913
+
1914
+ VisitForValue(args->at(0), kAccumulator);
1915
+
1916
+ Label materialize_true, materialize_false;
1917
+ Label* if_true = NULL;
1918
+ Label* if_false = NULL;
1919
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1920
+
1921
+ __ BranchOnSmi(r0, if_false);
1922
+ __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
1923
+ __ b(ge, if_true);
1924
+ __ b(if_false);
1925
+
1926
+ Apply(context_, if_true, if_false);
1927
+ }
1928
+
1929
+
1930
+ void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
1931
+ ASSERT(args->length() == 1);
1932
+
1933
+ VisitForValue(args->at(0), kAccumulator);
1934
+
1935
+ Label materialize_true, materialize_false;
1936
+ Label* if_true = NULL;
1937
+ Label* if_false = NULL;
1938
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1939
+
1940
+ __ BranchOnSmi(r0, if_false);
1941
+ __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
1942
+ __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
1943
+ __ tst(r1, Operand(1 << Map::kIsUndetectable));
1944
+ __ b(ne, if_true);
1945
+ __ b(if_false);
1946
+
1947
+ Apply(context_, if_true, if_false);
1948
+ }
1949
+
1950
+
1951
+ void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
1952
+ ASSERT(args->length() == 1);
1953
+
1954
+ VisitForValue(args->at(0), kAccumulator);
1955
+
1956
+ Label materialize_true, materialize_false;
1957
+ Label* if_true = NULL;
1958
+ Label* if_false = NULL;
1959
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1960
+
1961
+ __ BranchOnSmi(r0, if_false);
1962
+ __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
1963
+ __ b(eq, if_true);
1964
+ __ b(if_false);
1965
+
1966
+ Apply(context_, if_true, if_false);
1967
+ }
1968
+
1969
+
1970
+ void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
1971
+ ASSERT(args->length() == 1);
1972
+
1973
+ VisitForValue(args->at(0), kAccumulator);
1974
+
1975
+ Label materialize_true, materialize_false;
1976
+ Label* if_true = NULL;
1977
+ Label* if_false = NULL;
1978
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1979
+
1980
+ __ BranchOnSmi(r0, if_false);
1981
+ __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
1982
+ __ b(eq, if_true);
1983
+ __ b(if_false);
1984
+
1985
+ Apply(context_, if_true, if_false);
1986
+ }
1987
+
1988
+
1989
+ void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
1990
+ ASSERT(args->length() == 1);
1991
+
1992
+ VisitForValue(args->at(0), kAccumulator);
1993
+
1994
+ Label materialize_true, materialize_false;
1995
+ Label* if_true = NULL;
1996
+ Label* if_false = NULL;
1997
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1998
+
1999
+ __ BranchOnSmi(r0, if_false);
2000
+ __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
2001
+ __ b(eq, if_true);
2002
+ __ b(if_false);
2003
+
2004
+ Apply(context_, if_true, if_false);
2005
+ }
2006
+
2007
+
2008
+
2009
+ void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
2010
+ ASSERT(args->length() == 0);
2011
+
2012
+ Label materialize_true, materialize_false;
2013
+ Label* if_true = NULL;
2014
+ Label* if_false = NULL;
2015
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
2016
+
2017
+ // Get the frame pointer for the calling frame.
2018
+ __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2019
+
2020
+ // Skip the arguments adaptor frame if it exists.
2021
+ Label check_frame_marker;
2022
+ __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset));
2023
+ __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2024
+ __ b(ne, &check_frame_marker);
2025
+ __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset));
2026
+
2027
+ // Check the marker in the calling frame.
2028
+ __ bind(&check_frame_marker);
2029
+ __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
2030
+ __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
2031
+ __ b(eq, if_true);
2032
+ __ b(if_false);
2033
+
2034
+ Apply(context_, if_true, if_false);
2035
+ }
2036
+
2037
+
2038
+ void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) {
2039
+ ASSERT(args->length() == 2);
2040
+
2041
+ // Load the two objects into registers and perform the comparison.
2042
+ VisitForValue(args->at(0), kStack);
2043
+ VisitForValue(args->at(1), kAccumulator);
2044
+
2045
+ Label materialize_true, materialize_false;
2046
+ Label* if_true = NULL;
2047
+ Label* if_false = NULL;
2048
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
2049
+
2050
+ __ pop(r1);
2051
+ __ cmp(r0, r1);
2052
+ __ b(eq, if_true);
2053
+ __ b(if_false);
2054
+
2055
+ Apply(context_, if_true, if_false);
2056
+ }
2057
+
2058
+
2059
+ void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
2060
+ ASSERT(args->length() == 1);
2061
+
2062
+ // ArgumentsAccessStub expects the key in edx and the formal
2063
+ // parameter count in eax.
2064
+ VisitForValue(args->at(0), kAccumulator);
2065
+ __ mov(r1, r0);
2066
+ __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
2067
+ ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
2068
+ __ CallStub(&stub);
2069
+ Apply(context_, r0);
2070
+ }
2071
+
2072
+
2073
+ void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
2074
+ ASSERT(args->length() == 0);
2075
+
2076
+ Label exit;
2077
+ // Get the number of formal parameters.
2078
+ __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
2079
+
2080
+ // Check if the calling frame is an arguments adaptor frame.
2081
+ __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2082
+ __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
2083
+ __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2084
+ __ b(ne, &exit);
2085
+
2086
+ // Arguments adaptor case: Read the arguments length from the
2087
+ // adaptor frame.
2088
+ __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
2089
+
2090
+ __ bind(&exit);
2091
+ Apply(context_, r0);
2092
+ }
2093
+
2094
+
2095
+ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
2096
+ ASSERT(args->length() == 1);
2097
+ Label done, null, function, non_function_constructor;
2098
+
2099
+ VisitForValue(args->at(0), kAccumulator);
2100
+
2101
+ // If the object is a smi, we return null.
2102
+ __ BranchOnSmi(r0, &null);
2103
+
2104
+ // Check that the object is a JS object but take special care of JS
2105
+ // functions to make sure they have 'Function' as their class.
2106
+ __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); // Map is now in r0.
2107
+ __ b(lt, &null);
2108
+
2109
+ // As long as JS_FUNCTION_TYPE is the last instance type and it is
2110
+ // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
2111
+ // LAST_JS_OBJECT_TYPE.
2112
+ ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
2113
+ ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
2114
+ __ cmp(r1, Operand(JS_FUNCTION_TYPE));
2115
+ __ b(eq, &function);
2116
+
2117
+ // Check if the constructor in the map is a function.
2118
+ __ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset));
2119
+ __ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE);
2120
+ __ b(ne, &non_function_constructor);
2121
+
2122
+ // r0 now contains the constructor function. Grab the
2123
+ // instance class name from there.
2124
+ __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
2125
+ __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset));
2126
+ __ b(&done);
2127
+
2128
+ // Functions have class 'Function'.
2129
+ __ bind(&function);
2130
+ __ LoadRoot(r0, Heap::kfunction_class_symbolRootIndex);
2131
+ __ jmp(&done);
2132
+
2133
+ // Objects with a non-function constructor have class 'Object'.
2134
+ __ bind(&non_function_constructor);
2135
+ __ LoadRoot(r0, Heap::kfunction_class_symbolRootIndex);
2136
+ __ jmp(&done);
2137
+
2138
+ // Non-JS objects have class null.
2139
+ __ bind(&null);
2140
+ __ LoadRoot(r0, Heap::kNullValueRootIndex);
2141
+
2142
+ // All done.
2143
+ __ bind(&done);
2144
+
2145
+ Apply(context_, r0);
2146
+ }
2147
+
2148
+
2149
+ void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
2150
+ // Conditionally generate a log call.
2151
+ // Args:
2152
+ // 0 (literal string): The type of logging (corresponds to the flags).
2153
+ // This is used to determine whether or not to generate the log call.
2154
+ // 1 (string): Format string. Access the string at argument index 2
2155
+ // with '%2s' (see Logger::LogRuntime for all the formats).
2156
+ // 2 (array): Arguments to the format string.
2157
+ ASSERT_EQ(args->length(), 3);
2158
+ #ifdef ENABLE_LOGGING_AND_PROFILING
2159
+ if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
2160
+ VisitForValue(args->at(1), kStack);
2161
+ VisitForValue(args->at(2), kStack);
2162
+ __ CallRuntime(Runtime::kLog, 2);
2163
+ }
2164
+ #endif
2165
+ // Finally, we're expected to leave a value on the top of the stack.
2166
+ __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2167
+ Apply(context_, r0);
2168
+ }
2169
+
2170
+
2171
+ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
2172
+ ASSERT(args->length() == 0);
2173
+
2174
+ Label slow_allocate_heapnumber;
2175
+ Label heapnumber_allocated;
2176
+
2177
+ __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
2178
+ __ AllocateHeapNumber(r4, r1, r2, r6, &slow_allocate_heapnumber);
2179
+ __ jmp(&heapnumber_allocated);
2180
+
2181
+ __ bind(&slow_allocate_heapnumber);
2182
+ // Allocate a heap number.
2183
+ __ CallRuntime(Runtime::kNumberAlloc, 0);
2184
+ __ mov(r4, Operand(r0));
2185
+
2186
+ __ bind(&heapnumber_allocated);
2187
+
2188
+ // Convert 32 random bits in r0 to 0.(32 random bits) in a double
2189
+ // by computing:
2190
+ // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2191
+ if (CpuFeatures::IsSupported(VFP3)) {
2192
+ __ PrepareCallCFunction(0, r1);
2193
+ __ CallCFunction(ExternalReference::random_uint32_function(), 0);
2194
+
2195
+ CpuFeatures::Scope scope(VFP3);
2196
+ // 0x41300000 is the top half of 1.0 x 2^20 as a double.
2197
+ // Create this constant using mov/orr to avoid PC relative load.
2198
+ __ mov(r1, Operand(0x41000000));
2199
+ __ orr(r1, r1, Operand(0x300000));
2200
+ // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
2201
+ __ vmov(d7, r0, r1);
2202
+ // Move 0x4130000000000000 to VFP.
2203
+ __ mov(r0, Operand(0));
2204
+ __ vmov(d8, r0, r1);
2205
+ // Subtract and store the result in the heap number.
2206
+ __ vsub(d7, d7, d8);
2207
+ __ sub(r0, r4, Operand(kHeapObjectTag));
2208
+ __ vstr(d7, r0, HeapNumber::kValueOffset);
2209
+ __ mov(r0, r4);
2210
+ } else {
2211
+ __ mov(r0, Operand(r4));
2212
+ __ PrepareCallCFunction(1, r1);
2213
+ __ CallCFunction(
2214
+ ExternalReference::fill_heap_number_with_random_function(), 1);
2215
+ }
2216
+
2217
+ Apply(context_, r0);
2218
+ }
2219
+
2220
+
2221
+ void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
2222
+ // Load the arguments on the stack and call the stub.
2223
+ SubStringStub stub;
2224
+ ASSERT(args->length() == 3);
2225
+ VisitForValue(args->at(0), kStack);
2226
+ VisitForValue(args->at(1), kStack);
2227
+ VisitForValue(args->at(2), kStack);
2228
+ __ CallStub(&stub);
2229
+ Apply(context_, r0);
2230
+ }
2231
+
2232
+
2233
+ void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
2234
+ // Load the arguments on the stack and call the stub.
2235
+ RegExpExecStub stub;
2236
+ ASSERT(args->length() == 4);
2237
+ VisitForValue(args->at(0), kStack);
2238
+ VisitForValue(args->at(1), kStack);
2239
+ VisitForValue(args->at(2), kStack);
2240
+ VisitForValue(args->at(3), kStack);
2241
+ __ CallStub(&stub);
2242
+ Apply(context_, r0);
2243
+ }
2244
+
2245
+
2246
+ void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2247
+ ASSERT(args->length() == 1);
2248
+
2249
+ VisitForValue(args->at(0), kAccumulator); // Load the object.
2250
+
2251
+ Label done;
2252
+ // If the object is a smi return the object.
2253
+ __ BranchOnSmi(r0, &done);
2254
+ // If the object is not a value type, return the object.
2255
+ __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE);
2256
+ __ b(ne, &done);
2257
+ __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset));
2258
+
2259
+ __ bind(&done);
2260
+ Apply(context_, r0);
2261
+ }
2262
+
2263
+
2264
+ void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
2265
+ // Load the arguments on the stack and call the runtime function.
2266
+ ASSERT(args->length() == 2);
2267
+ VisitForValue(args->at(0), kStack);
2268
+ VisitForValue(args->at(1), kStack);
2269
+ __ CallRuntime(Runtime::kMath_pow, 2);
2270
+ Apply(context_, r0);
2271
+ }
2272
+
2273
+
2274
+ void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2275
+ ASSERT(args->length() == 2);
2276
+
2277
+ VisitForValue(args->at(0), kStack); // Load the object.
2278
+ VisitForValue(args->at(1), kAccumulator); // Load the value.
2279
+ __ pop(r1); // r0 = value. r1 = object.
2280
+
2281
+ Label done;
2282
+ // If the object is a smi, return the value.
2283
+ __ BranchOnSmi(r1, &done);
2284
+
2285
+ // If the object is not a value type, return the value.
2286
+ __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE);
2287
+ __ b(ne, &done);
2288
+
2289
+ // Store the value.
2290
+ __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset));
2291
+ // Update the write barrier. Save the value as it will be
2292
+ // overwritten by the write barrier code and is needed afterward.
2293
+ __ RecordWrite(r1, Operand(JSValue::kValueOffset - kHeapObjectTag), r2, r3);
2294
+
2295
+ __ bind(&done);
2296
+ Apply(context_, r0);
2297
+ }
2298
+
2299
+
2300
+ void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
2301
+ ASSERT_EQ(args->length(), 1);
2302
+
2303
+ // Load the argument on the stack and call the stub.
2304
+ VisitForValue(args->at(0), kStack);
2305
+
2306
+ NumberToStringStub stub;
2307
+ __ CallStub(&stub);
2308
+ Apply(context_, r0);
2309
+ }
2310
+
2311
+
2312
+ void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
2313
+ ASSERT(args->length() == 1);
2314
+
2315
+ VisitForValue(args->at(0), kAccumulator);
2316
+
2317
+ Label done;
2318
+ StringCharFromCodeGenerator generator(r0, r1);
2319
+ generator.GenerateFast(masm_);
2320
+ __ jmp(&done);
2321
+
2322
+ NopRuntimeCallHelper call_helper;
2323
+ generator.GenerateSlow(masm_, call_helper);
2324
+
2325
+ __ bind(&done);
2326
+ Apply(context_, r1);
2327
+ }
2328
+
2329
+
2330
+ void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
2331
+ ASSERT(args->length() == 2);
2332
+
2333
+ VisitForValue(args->at(0), kStack);
2334
+ VisitForValue(args->at(1), kAccumulator);
2335
+
2336
+ Register object = r1;
2337
+ Register index = r0;
2338
+ Register scratch = r2;
2339
+ Register result = r3;
2340
+
2341
+ __ pop(object);
2342
+
2343
+ Label need_conversion;
2344
+ Label index_out_of_range;
2345
+ Label done;
2346
+ StringCharCodeAtGenerator generator(object,
2347
+ index,
2348
+ scratch,
2349
+ result,
2350
+ &need_conversion,
2351
+ &need_conversion,
2352
+ &index_out_of_range,
2353
+ STRING_INDEX_IS_NUMBER);
2354
+ generator.GenerateFast(masm_);
2355
+ __ jmp(&done);
2356
+
2357
+ __ bind(&index_out_of_range);
2358
+ // When the index is out of range, the spec requires us to return
2359
+ // NaN.
2360
+ __ LoadRoot(result, Heap::kNanValueRootIndex);
2361
+ __ jmp(&done);
2362
+
2363
+ __ bind(&need_conversion);
2364
+ // Load the undefined value into the result register, which will
2365
+ // trigger conversion.
2366
+ __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2367
+ __ jmp(&done);
2368
+
2369
+ NopRuntimeCallHelper call_helper;
2370
+ generator.GenerateSlow(masm_, call_helper);
2371
+
2372
+ __ bind(&done);
2373
+ Apply(context_, result);
2374
+ }
2375
+
2376
+
2377
+ void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
2378
+ ASSERT(args->length() == 2);
2379
+
2380
+ VisitForValue(args->at(0), kStack);
2381
+ VisitForValue(args->at(1), kAccumulator);
2382
+
2383
+ Register object = r1;
2384
+ Register index = r0;
2385
+ Register scratch1 = r2;
2386
+ Register scratch2 = r3;
2387
+ Register result = r0;
2388
+
2389
+ __ pop(object);
2390
+
2391
+ Label need_conversion;
2392
+ Label index_out_of_range;
2393
+ Label done;
2394
+ StringCharAtGenerator generator(object,
2395
+ index,
2396
+ scratch1,
2397
+ scratch2,
2398
+ result,
2399
+ &need_conversion,
2400
+ &need_conversion,
2401
+ &index_out_of_range,
2402
+ STRING_INDEX_IS_NUMBER);
2403
+ generator.GenerateFast(masm_);
2404
+ __ jmp(&done);
2405
+
2406
+ __ bind(&index_out_of_range);
2407
+ // When the index is out of range, the spec requires us to return
2408
+ // the empty string.
2409
+ __ LoadRoot(result, Heap::kEmptyStringRootIndex);
2410
+ __ jmp(&done);
2411
+
2412
+ __ bind(&need_conversion);
2413
+ // Move smi zero into the result register, which will trigger
2414
+ // conversion.
2415
+ __ mov(result, Operand(Smi::FromInt(0)));
2416
+ __ jmp(&done);
2417
+
2418
+ NopRuntimeCallHelper call_helper;
2419
+ generator.GenerateSlow(masm_, call_helper);
2420
+
2421
+ __ bind(&done);
2422
+ Apply(context_, result);
2423
+ }
2424
+
2425
+
2426
+ void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
2427
+ ASSERT_EQ(2, args->length());
2428
+
2429
+ VisitForValue(args->at(0), kStack);
2430
+ VisitForValue(args->at(1), kStack);
2431
+
2432
+ StringAddStub stub(NO_STRING_ADD_FLAGS);
2433
+ __ CallStub(&stub);
2434
+ Apply(context_, r0);
2435
+ }
2436
+
2437
+
2438
+ void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
2439
+ ASSERT_EQ(2, args->length());
2440
+
2441
+ VisitForValue(args->at(0), kStack);
2442
+ VisitForValue(args->at(1), kStack);
2443
+
2444
+ StringCompareStub stub;
2445
+ __ CallStub(&stub);
2446
+ Apply(context_, r0);
2447
+ }
2448
+
2449
+
2450
+ void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
2451
+ // Load the argument on the stack and call the runtime.
2452
+ ASSERT(args->length() == 1);
2453
+ VisitForValue(args->at(0), kStack);
2454
+ __ CallRuntime(Runtime::kMath_sin, 1);
2455
+ Apply(context_, r0);
2456
+ }
2457
+
2458
+
2459
+ void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
2460
+ // Load the argument on the stack and call the runtime.
2461
+ ASSERT(args->length() == 1);
2462
+ VisitForValue(args->at(0), kStack);
2463
+ __ CallRuntime(Runtime::kMath_cos, 1);
2464
+ Apply(context_, r0);
2465
+ }
2466
+
2467
+
2468
+ void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
2469
+ // Load the argument on the stack and call the runtime function.
2470
+ ASSERT(args->length() == 1);
2471
+ VisitForValue(args->at(0), kStack);
2472
+ __ CallRuntime(Runtime::kMath_sqrt, 1);
2473
+ Apply(context_, r0);
2474
+ }
2475
+
2476
+
2477
+ void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
2478
+ ASSERT(args->length() >= 2);
2479
+
2480
+ int arg_count = args->length() - 2; // For receiver and function.
2481
+ VisitForValue(args->at(0), kStack); // Receiver.
2482
+ for (int i = 0; i < arg_count; i++) {
2483
+ VisitForValue(args->at(i + 1), kStack);
2484
+ }
2485
+ VisitForValue(args->at(arg_count + 1), kAccumulator); // Function.
2486
+
2487
+ // InvokeFunction requires function in r1. Move it in there.
2488
+ if (!result_register().is(r1)) __ mov(r1, result_register());
2489
+ ParameterCount count(arg_count);
2490
+ __ InvokeFunction(r1, count, CALL_FUNCTION);
2491
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2492
+ Apply(context_, r0);
2493
+ }
2494
+
2495
+
2496
+ void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
2497
+ ASSERT(args->length() == 3);
2498
+ VisitForValue(args->at(0), kStack);
2499
+ VisitForValue(args->at(1), kStack);
2500
+ VisitForValue(args->at(2), kStack);
2501
+ __ CallRuntime(Runtime::kRegExpConstructResult, 3);
2502
+ Apply(context_, r0);
2503
+ }
2504
+
2505
+
2506
+ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
2507
+ ASSERT(args->length() == 3);
2508
+ VisitForValue(args->at(0), kStack);
2509
+ VisitForValue(args->at(1), kStack);
2510
+ VisitForValue(args->at(2), kStack);
2511
+ __ CallRuntime(Runtime::kSwapElements, 3);
2512
+ Apply(context_, r0);
2513
+ }
2514
+
2515
+
2516
+ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
2517
+ ASSERT_EQ(2, args->length());
2518
+
2519
+ ASSERT_NE(NULL, args->at(0)->AsLiteral());
2520
+ int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
2521
+
2522
+ Handle<FixedArray> jsfunction_result_caches(
2523
+ Top::global_context()->jsfunction_result_caches());
2524
+ if (jsfunction_result_caches->length() <= cache_id) {
2525
+ __ Abort("Attempt to use undefined cache.");
2526
+ __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2527
+ Apply(context_, r0);
2528
+ return;
2529
+ }
2530
+
2531
+ VisitForValue(args->at(1), kAccumulator);
2532
+
2533
+ Register key = r0;
2534
+ Register cache = r1;
2535
+ __ ldr(cache, CodeGenerator::ContextOperand(cp, Context::GLOBAL_INDEX));
2536
+ __ ldr(cache, FieldMemOperand(cache, GlobalObject::kGlobalContextOffset));
2537
+ __ ldr(cache,
2538
+ CodeGenerator::ContextOperand(
2539
+ cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
2540
+ __ ldr(cache,
2541
+ FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
2542
+
2543
+
2544
+ Label done, not_found;
2545
+ // tmp now holds finger offset as a smi.
2546
+ ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
2547
+ __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset));
2548
+ // r2 now holds finger offset as a smi.
2549
+ __ add(r3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
2550
+ // r3 now points to the start of fixed array elements.
2551
+ __ ldr(r2, MemOperand(r3, r2, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex));
2552
+ // Note side effect of PreIndex: r3 now points to the key of the pair.
2553
+ __ cmp(key, r2);
2554
+ __ b(ne, &not_found);
2555
+
2556
+ __ ldr(r0, MemOperand(r3, kPointerSize));
2557
+ __ b(&done);
2558
+
2559
+ __ bind(&not_found);
2560
+ // Call runtime to perform the lookup.
2561
+ __ Push(cache, key);
2562
+ __ CallRuntime(Runtime::kGetFromCache, 2);
2563
+
2564
+ __ bind(&done);
2565
+ Apply(context_, r0);
2566
+ }
2567
+
2568
+
2569
+ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
2570
+ Handle<String> name = expr->name();
2571
+ if (name->length() > 0 && name->Get(0) == '_') {
2572
+ Comment cmnt(masm_, "[ InlineRuntimeCall");
2573
+ EmitInlineRuntimeCall(expr);
2574
+ return;
2575
+ }
2576
+
2577
+ Comment cmnt(masm_, "[ CallRuntime");
2578
+ ZoneList<Expression*>* args = expr->arguments();
2579
+
2580
+ if (expr->is_jsruntime()) {
2581
+ // Prepare for calling JS runtime function.
2582
+ __ ldr(r0, CodeGenerator::GlobalObject());
2583
+ __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset));
2584
+ __ push(r0);
2585
+ }
2586
+
2587
+ // Push the arguments ("left-to-right").
2588
+ int arg_count = args->length();
2589
+ for (int i = 0; i < arg_count; i++) {
2590
+ VisitForValue(args->at(i), kStack);
2591
+ }
2592
+
2593
+ if (expr->is_jsruntime()) {
2594
+ // Call the JS runtime function.
2595
+ __ mov(r2, Operand(expr->name()));
2596
+ Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
2597
+ NOT_IN_LOOP);
2598
+ __ Call(ic, RelocInfo::CODE_TARGET);
2599
+ // Restore context register.
2600
+ __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2601
+ } else {
2602
+ // Call the C runtime function.
2603
+ __ CallRuntime(expr->function(), arg_count);
1353
2604
  }
1354
2605
  Apply(context_, r0);
1355
2606
  }
@@ -1357,6 +2608,49 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
1357
2608
 
1358
2609
  void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1359
2610
  switch (expr->op()) {
2611
+ case Token::DELETE: {
2612
+ Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
2613
+ Property* prop = expr->expression()->AsProperty();
2614
+ Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
2615
+ if (prop == NULL && var == NULL) {
2616
+ // Result of deleting non-property, non-variable reference is true.
2617
+ // The subexpression may have side effects.
2618
+ VisitForEffect(expr->expression());
2619
+ Apply(context_, true);
2620
+ } else if (var != NULL &&
2621
+ !var->is_global() &&
2622
+ var->slot() != NULL &&
2623
+ var->slot()->type() != Slot::LOOKUP) {
2624
+ // Result of deleting non-global, non-dynamic variables is false.
2625
+ // The subexpression does not have side effects.
2626
+ Apply(context_, false);
2627
+ } else {
2628
+ // Property or variable reference. Call the delete builtin with
2629
+ // object and property name as arguments.
2630
+ if (prop != NULL) {
2631
+ VisitForValue(prop->obj(), kStack);
2632
+ VisitForValue(prop->key(), kStack);
2633
+ } else if (var->is_global()) {
2634
+ __ ldr(r1, CodeGenerator::GlobalObject());
2635
+ __ mov(r0, Operand(var->name()));
2636
+ __ Push(r1, r0);
2637
+ } else {
2638
+ // Non-global variable. Call the runtime to look up the context
2639
+ // where the variable was introduced.
2640
+ __ push(context_register());
2641
+ __ mov(r2, Operand(var->name()));
2642
+ __ push(r2);
2643
+ __ CallRuntime(Runtime::kLookupContext, 2);
2644
+ __ push(r0);
2645
+ __ mov(r2, Operand(var->name()));
2646
+ __ push(r2);
2647
+ }
2648
+ __ InvokeBuiltin(Builtins::DELETE, CALL_JS);
2649
+ Apply(context_, r0);
2650
+ }
2651
+ break;
2652
+ }
2653
+
1360
2654
  case Token::VOID: {
1361
2655
  Comment cmnt(masm_, "[ UnaryOperation (VOID)");
1362
2656
  VisitForEffect(expr->expression());
@@ -1397,33 +2691,15 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1397
2691
 
1398
2692
  case Token::NOT: {
1399
2693
  Comment cmnt(masm_, "[ UnaryOperation (NOT)");
1400
- Label materialize_true, materialize_false, done;
1401
- // Initially assume a pure test context. Notice that the labels are
1402
- // swapped.
1403
- Label* if_true = false_label_;
1404
- Label* if_false = true_label_;
1405
- switch (context_) {
1406
- case Expression::kUninitialized:
1407
- UNREACHABLE();
1408
- break;
1409
- case Expression::kEffect:
1410
- if_true = &done;
1411
- if_false = &done;
1412
- break;
1413
- case Expression::kValue:
1414
- if_true = &materialize_false;
1415
- if_false = &materialize_true;
1416
- break;
1417
- case Expression::kTest:
1418
- break;
1419
- case Expression::kValueTest:
1420
- if_false = &materialize_true;
1421
- break;
1422
- case Expression::kTestValue:
1423
- if_true = &materialize_false;
1424
- break;
1425
- }
2694
+ Label materialize_true, materialize_false;
2695
+ Label* if_true = NULL;
2696
+ Label* if_false = NULL;
2697
+
2698
+ // Notice that the labels are swapped.
2699
+ PrepareTest(&materialize_true, &materialize_false, &if_false, &if_true);
2700
+
1426
2701
  VisitForControl(expr->expression(), if_true, if_false);
2702
+
1427
2703
  Apply(context_, if_false, if_true); // Labels swapped.
1428
2704
  break;
1429
2705
  }
@@ -1436,18 +2712,17 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1436
2712
  proxy->var()->is_global()) {
1437
2713
  Comment cmnt(masm_, "Global variable");
1438
2714
  __ ldr(r0, CodeGenerator::GlobalObject());
1439
- __ push(r0);
1440
2715
  __ mov(r2, Operand(proxy->name()));
1441
2716
  Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
1442
2717
  // Use a regular load, not a contextual load, to avoid a reference
1443
2718
  // error.
1444
2719
  __ Call(ic, RelocInfo::CODE_TARGET);
1445
- __ str(r0, MemOperand(sp));
2720
+ __ push(r0);
1446
2721
  } else if (proxy != NULL &&
1447
2722
  proxy->var()->slot() != NULL &&
1448
2723
  proxy->var()->slot()->type() == Slot::LOOKUP) {
1449
2724
  __ mov(r0, Operand(proxy->name()));
1450
- __ stm(db_w, sp, cp.bit() | r0.bit());
2725
+ __ Push(cp, r0);
1451
2726
  __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
1452
2727
  __ push(r0);
1453
2728
  } else {
@@ -1475,9 +2750,11 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1475
2750
 
1476
2751
  case Token::SUB: {
1477
2752
  Comment cmt(masm_, "[ UnaryOperation (SUB)");
1478
- bool overwrite =
2753
+ bool can_overwrite =
1479
2754
  (expr->expression()->AsBinaryOperation() != NULL &&
1480
2755
  expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
2756
+ UnaryOverwriteMode overwrite =
2757
+ can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
1481
2758
  GenericUnaryOpStub stub(Token::SUB, overwrite);
1482
2759
  // GenericUnaryOpStub expects the argument to be in the
1483
2760
  // accumulator register r0.
@@ -1489,17 +2766,18 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1489
2766
 
1490
2767
  case Token::BIT_NOT: {
1491
2768
  Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
1492
- bool overwrite =
2769
+ bool can_overwrite =
1493
2770
  (expr->expression()->AsBinaryOperation() != NULL &&
1494
2771
  expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
2772
+ UnaryOverwriteMode overwrite =
2773
+ can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
1495
2774
  GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
1496
2775
  // GenericUnaryOpStub expects the argument to be in the
1497
2776
  // accumulator register r0.
1498
2777
  VisitForValue(expr->expression(), kAccumulator);
1499
2778
  // Avoid calling the stub for Smis.
1500
2779
  Label smi, done;
1501
- __ tst(result_register(), Operand(kSmiTagMask));
1502
- __ b(eq, &smi);
2780
+ __ BranchOnSmi(result_register(), &smi);
1503
2781
  // Non-smi: call stub leaving result in accumulator register.
1504
2782
  __ CallStub(&stub);
1505
2783
  __ b(&done);
@@ -1521,6 +2799,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
1521
2799
 
1522
2800
  void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1523
2801
  Comment cmnt(masm_, "[ CountOperation");
2802
+ // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
2803
+ // as the left-hand side.
2804
+ if (!expr->expression()->IsValidLeftHandSide()) {
2805
+ VisitForEffect(expr->expression());
2806
+ return;
2807
+ }
1524
2808
 
1525
2809
  // Expression can only be a property, a global or a (parameter or local)
1526
2810
  // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
@@ -1548,19 +2832,23 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1548
2832
  __ mov(ip, Operand(Smi::FromInt(0)));
1549
2833
  __ push(ip);
1550
2834
  }
1551
- VisitForValue(prop->obj(), kStack);
1552
2835
  if (assign_type == NAMED_PROPERTY) {
2836
+ // Put the object both on the stack and in the accumulator.
2837
+ VisitForValue(prop->obj(), kAccumulator);
2838
+ __ push(r0);
1553
2839
  EmitNamedPropertyLoad(prop);
1554
2840
  } else {
1555
- VisitForValue(prop->key(), kStack);
2841
+ VisitForValue(prop->obj(), kStack);
2842
+ VisitForValue(prop->key(), kAccumulator);
2843
+ __ ldr(r1, MemOperand(sp, 0));
2844
+ __ push(r0);
1556
2845
  EmitKeyedPropertyLoad(prop);
1557
2846
  }
1558
2847
  }
1559
2848
 
1560
2849
  // Call ToNumber only if operand is not a smi.
1561
2850
  Label no_conversion;
1562
- __ tst(r0, Operand(kSmiTagMask));
1563
- __ b(eq, &no_conversion);
2851
+ __ BranchOnSmi(r0, &no_conversion);
1564
2852
  __ push(r0);
1565
2853
  __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS);
1566
2854
  __ bind(&no_conversion);
@@ -1604,8 +2892,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1604
2892
  __ b(vs, &stub_call);
1605
2893
  // We could eliminate this smi check if we split the code at
1606
2894
  // the first smi check before calling ToNumber.
1607
- __ tst(r0, Operand(kSmiTagMask));
1608
- __ b(eq, &done);
2895
+ __ BranchOnSmi(r0, &done);
1609
2896
  __ bind(&stub_call);
1610
2897
  // Call stub. Undo operation first.
1611
2898
  __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
@@ -1620,6 +2907,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1620
2907
  case VARIABLE:
1621
2908
  if (expr->is_postfix()) {
1622
2909
  EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
2910
+ Token::ASSIGN,
1623
2911
  Expression::kEffect);
1624
2912
  // For all contexts except kEffect: We have the result on
1625
2913
  // top of the stack.
@@ -1628,6 +2916,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1628
2916
  }
1629
2917
  } else {
1630
2918
  EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
2919
+ Token::ASSIGN,
1631
2920
  context_);
1632
2921
  }
1633
2922
  break;
@@ -1646,15 +2935,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
1646
2935
  break;
1647
2936
  }
1648
2937
  case KEYED_PROPERTY: {
2938
+ __ pop(r1); // Key.
2939
+ __ pop(r2); // Receiver.
1649
2940
  Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
1650
2941
  __ Call(ic, RelocInfo::CODE_TARGET);
1651
2942
  if (expr->is_postfix()) {
1652
- __ Drop(2); // Result is on the stack under the key and the receiver.
1653
2943
  if (context_ != Expression::kEffect) {
1654
2944
  ApplyTOS(context_);
1655
2945
  }
1656
2946
  } else {
1657
- DropAndApply(2, context_, r0);
2947
+ Apply(context_, r0);
1658
2948
  }
1659
2949
  break;
1660
2950
  }
@@ -1697,36 +2987,41 @@ void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
1697
2987
  }
1698
2988
 
1699
2989
 
2990
+ void FullCodeGenerator::EmitNullCompare(bool strict,
2991
+ Register obj,
2992
+ Register null_const,
2993
+ Label* if_true,
2994
+ Label* if_false,
2995
+ Register scratch) {
2996
+ __ cmp(obj, null_const);
2997
+ if (strict) {
2998
+ __ b(eq, if_true);
2999
+ } else {
3000
+ __ b(eq, if_true);
3001
+ __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3002
+ __ cmp(obj, ip);
3003
+ __ b(eq, if_true);
3004
+ __ BranchOnSmi(obj, if_false);
3005
+ // It can be an undetectable object.
3006
+ __ ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
3007
+ __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
3008
+ __ tst(scratch, Operand(1 << Map::kIsUndetectable));
3009
+ __ b(ne, if_true);
3010
+ }
3011
+ __ jmp(if_false);
3012
+ }
3013
+
3014
+
1700
3015
  void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1701
3016
  Comment cmnt(masm_, "[ CompareOperation");
1702
3017
 
1703
3018
  // Always perform the comparison for its control flow. Pack the result
1704
3019
  // into the expression's context after the comparison is performed.
1705
- Label materialize_true, materialize_false, done;
1706
- // Initially assume we are in a test context.
1707
- Label* if_true = true_label_;
1708
- Label* if_false = false_label_;
1709
- switch (context_) {
1710
- case Expression::kUninitialized:
1711
- UNREACHABLE();
1712
- break;
1713
- case Expression::kEffect:
1714
- if_true = &done;
1715
- if_false = &done;
1716
- break;
1717
- case Expression::kValue:
1718
- if_true = &materialize_true;
1719
- if_false = &materialize_false;
1720
- break;
1721
- case Expression::kTest:
1722
- break;
1723
- case Expression::kValueTest:
1724
- if_true = &materialize_true;
1725
- break;
1726
- case Expression::kTestValue:
1727
- if_false = &materialize_false;
1728
- break;
1729
- }
3020
+
3021
+ Label materialize_true, materialize_false;
3022
+ Label* if_true = NULL;
3023
+ Label* if_false = NULL;
3024
+ PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
1730
3025
 
1731
3026
  VisitForValue(expr->left(), kStack);
1732
3027
  switch (expr->op()) {
@@ -1757,10 +3052,24 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1757
3052
  case Token::EQ_STRICT:
1758
3053
  strict = true;
1759
3054
  // Fall through
1760
- case Token::EQ:
3055
+ case Token::EQ: {
1761
3056
  cc = eq;
1762
3057
  __ pop(r1);
3058
+ // If either operand is constant null we do a fast compare
3059
+ // against null.
3060
+ Literal* right_literal = expr->right()->AsLiteral();
3061
+ Literal* left_literal = expr->left()->AsLiteral();
3062
+ if (right_literal != NULL && right_literal->handle()->IsNull()) {
3063
+ EmitNullCompare(strict, r1, r0, if_true, if_false, r2);
3064
+ Apply(context_, if_true, if_false);
3065
+ return;
3066
+ } else if (left_literal != NULL && left_literal->handle()->IsNull()) {
3067
+ EmitNullCompare(strict, r0, r1, if_true, if_false, r2);
3068
+ Apply(context_, if_true, if_false);
3069
+ return;
3070
+ }
1763
3071
  break;
3072
+ }
1764
3073
  case Token::LT:
1765
3074
  cc = lt;
1766
3075
  __ pop(r1);
@@ -1791,14 +3100,13 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1791
3100
  // before it is called.
1792
3101
  Label slow_case;
1793
3102
  __ orr(r2, r0, Operand(r1));
1794
- __ tst(r2, Operand(kSmiTagMask));
1795
- __ b(ne, &slow_case);
3103
+ __ BranchOnNotSmi(r2, &slow_case);
1796
3104
  __ cmp(r1, r0);
1797
3105
  __ b(cc, if_true);
1798
3106
  __ jmp(if_false);
1799
3107
 
1800
3108
  __ bind(&slow_case);
1801
- CompareStub stub(cc, strict);
3109
+ CompareStub stub(cc, strict, kBothCouldBeNaN, true, r1, r0);
1802
3110
  __ CallStub(&stub);
1803
3111
  __ cmp(r0, Operand(0));
1804
3112
  __ b(cc, if_true);
@@ -1866,3 +3174,5 @@ void FullCodeGenerator::ExitFinallyBlock() {
1866
3174
  #undef __
1867
3175
 
1868
3176
  } } // namespace v8::internal
3177
+
3178
+ #endif // V8_TARGET_ARCH_ARM