therubyracer 0.6.3 → 0.7.0.pre

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 (520) hide show
  1. data/Rakefile +10 -9
  2. data/ext/v8/callbacks.cpp +15 -8
  3. data/ext/v8/converters.cpp +7 -8
  4. data/ext/v8/converters.h +0 -2
  5. data/ext/v8/extconf.rb +2 -0
  6. data/ext/v8/rr.cpp +169 -0
  7. data/ext/v8/rr.h +34 -0
  8. data/ext/v8/upstream/{2.0.6 → 2.1.10}/AUTHORS +8 -1
  9. data/ext/v8/upstream/{2.0.6 → 2.1.10}/ChangeLog +198 -0
  10. data/ext/v8/upstream/{2.0.6 → 2.1.10}/LICENSE +0 -0
  11. data/ext/v8/upstream/{2.0.6 → 2.1.10}/SConstruct +152 -38
  12. data/ext/v8/upstream/{2.0.6 → 2.1.10}/include/v8-debug.h +52 -4
  13. data/ext/v8/upstream/2.1.10/include/v8-profiler.h +176 -0
  14. data/ext/v8/upstream/{2.0.6 → 2.1.10}/include/v8.h +227 -48
  15. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/SConscript +60 -10
  16. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/accessors.cc +5 -39
  17. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/accessors.h +0 -0
  18. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/allocation.cc +0 -0
  19. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/allocation.h +0 -0
  20. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/api.cc +477 -57
  21. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/api.h +8 -4
  22. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/apinatives.js +1 -1
  23. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/apiutils.h +0 -0
  24. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arguments.h +5 -6
  25. data/ext/v8/upstream/{2.0.6/src/arm/assembler-thumb2-inl.h → 2.1.10/src/arm/assembler-arm-inl.h} +42 -27
  26. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-arm.cc +430 -216
  27. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-arm.h +199 -110
  28. data/ext/v8/upstream/{2.0.6/src/arm/assembler-arm-inl.h → 2.1.10/src/arm/assembler-thumb2-inl.h} +4 -18
  29. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-thumb2.cc +142 -85
  30. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-thumb2.h +18 -9
  31. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/builtins-arm.cc +127 -87
  32. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/codegen-arm-inl.h +3 -5
  33. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/codegen-arm.cc +4634 -1427
  34. data/ext/v8/upstream/2.1.10/src/arm/codegen-arm.h +946 -0
  35. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/constants-arm.cc +21 -3
  36. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/constants-arm.h +39 -13
  37. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/cpu-arm.cc +9 -3
  38. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/debug-arm.cc +34 -8
  39. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/disasm-arm.cc +262 -117
  40. data/ext/v8/upstream/2.1.10/src/arm/fast-codegen-arm.cc +238 -0
  41. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/frames-arm.cc +0 -0
  42. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/frames-arm.h +0 -0
  43. data/ext/v8/upstream/{2.0.6/src/arm/fast-codegen-arm.cc → 2.1.10/src/arm/full-codegen-arm.cc} +453 -283
  44. data/ext/v8/upstream/2.1.10/src/arm/ic-arm.cc +1833 -0
  45. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/jump-target-arm.cc +3 -29
  46. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/macro-assembler-arm.cc +564 -104
  47. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/macro-assembler-arm.h +255 -46
  48. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/regexp-macro-assembler-arm.cc +78 -104
  49. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/regexp-macro-assembler-arm.h +6 -22
  50. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/register-allocator-arm-inl.h +0 -3
  51. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/register-allocator-arm.cc +0 -0
  52. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/register-allocator-arm.h +2 -1
  53. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/simulator-arm.cc +557 -180
  54. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/simulator-arm.h +52 -4
  55. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/stub-cache-arm.cc +904 -240
  56. data/ext/v8/upstream/2.1.10/src/arm/virtual-frame-arm.cc +668 -0
  57. data/ext/v8/upstream/2.1.10/src/arm/virtual-frame-arm.h +503 -0
  58. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/array.js +82 -109
  59. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/assembler.cc +49 -13
  60. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/assembler.h +27 -5
  61. data/ext/v8/upstream/2.1.10/src/ast.cc +1138 -0
  62. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ast.h +354 -53
  63. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/bootstrapper.cc +609 -501
  64. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/bootstrapper.h +27 -8
  65. data/ext/v8/upstream/2.1.10/src/builtins.cc +1512 -0
  66. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/builtins.h +41 -25
  67. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/bytecodes-irregexp.h +0 -0
  68. data/ext/v8/upstream/2.1.10/src/cached-powers.h +119 -0
  69. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/char-predicates-inl.h +0 -0
  70. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/char-predicates.h +0 -0
  71. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/checks.cc +0 -0
  72. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/checks.h +25 -1
  73. data/ext/v8/upstream/2.1.10/src/circular-queue-inl.h +101 -0
  74. data/ext/v8/upstream/2.1.10/src/circular-queue.cc +121 -0
  75. data/ext/v8/upstream/2.1.10/src/circular-queue.h +129 -0
  76. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/code-stubs.cc +23 -8
  77. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/code-stubs.h +16 -4
  78. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/code.h +0 -0
  79. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/codegen-inl.h +6 -34
  80. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/codegen.cc +73 -92
  81. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/codegen.h +164 -68
  82. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/compilation-cache.cc +117 -73
  83. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/compilation-cache.h +18 -17
  84. data/ext/v8/upstream/2.1.10/src/compiler.cc +623 -0
  85. data/ext/v8/upstream/2.1.10/src/compiler.h +299 -0
  86. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/contexts.cc +0 -0
  87. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/contexts.h +8 -11
  88. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/conversions-inl.h +28 -13
  89. data/ext/v8/upstream/2.1.10/src/conversions.cc +1105 -0
  90. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/conversions.h +9 -4
  91. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/counters.cc +0 -0
  92. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/counters.h +1 -1
  93. data/ext/v8/upstream/2.1.10/src/cpu-profiler-inl.h +99 -0
  94. data/ext/v8/upstream/2.1.10/src/cpu-profiler.cc +494 -0
  95. data/ext/v8/upstream/2.1.10/src/cpu-profiler.h +277 -0
  96. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/cpu.h +0 -0
  97. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-debug.cc +15 -4
  98. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-debug.h +0 -0
  99. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-posix.cc +18 -0
  100. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-readline.cc +2 -2
  101. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-windows.cc +0 -0
  102. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8.cc +10 -6
  103. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8.h +2 -0
  104. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8.js +43 -38
  105. data/ext/v8/upstream/2.1.10/src/data-flow.cc +755 -0
  106. data/ext/v8/upstream/2.1.10/src/data-flow.h +278 -0
  107. data/ext/v8/upstream/{2.0.6/src/date-delay.js → 2.1.10/src/date.js} +100 -110
  108. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dateparser-inl.h +11 -2
  109. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dateparser.cc +24 -26
  110. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dateparser.h +8 -4
  111. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug-agent.cc +3 -1
  112. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug-agent.h +0 -0
  113. data/ext/v8/upstream/{2.0.6/src/debug-delay.js → 2.1.10/src/debug-debugger.js} +111 -15
  114. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug.cc +156 -96
  115. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug.h +53 -5
  116. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/disasm.h +0 -0
  117. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/disassembler.cc +2 -8
  118. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/disassembler.h +0 -0
  119. data/ext/v8/upstream/2.1.10/src/diy-fp.cc +58 -0
  120. data/ext/v8/upstream/2.1.10/src/diy-fp.h +117 -0
  121. data/ext/v8/upstream/2.1.10/src/double.h +169 -0
  122. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dtoa-config.c +4 -3
  123. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/execution.cc +22 -22
  124. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/execution.h +17 -4
  125. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/factory.cc +70 -46
  126. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/factory.h +27 -17
  127. data/ext/v8/upstream/2.1.10/src/fast-codegen.cc +746 -0
  128. data/ext/v8/upstream/2.1.10/src/fast-codegen.h +161 -0
  129. data/ext/v8/upstream/2.1.10/src/fast-dtoa.cc +512 -0
  130. data/ext/v8/upstream/2.1.10/src/fast-dtoa.h +59 -0
  131. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/flag-definitions.h +32 -11
  132. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/flags.cc +0 -0
  133. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/flags.h +0 -0
  134. data/ext/v8/upstream/2.1.10/src/flow-graph.cc +763 -0
  135. data/ext/v8/upstream/2.1.10/src/flow-graph.h +180 -0
  136. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frame-element.cc +1 -4
  137. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frame-element.h +49 -11
  138. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frames-inl.h +2 -0
  139. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frames.cc +91 -17
  140. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frames.h +24 -2
  141. data/ext/v8/upstream/{2.0.6/src/fast-codegen.cc → 2.1.10/src/full-codegen.cc} +549 -198
  142. data/ext/v8/upstream/{2.0.6/src/fast-codegen.h → 2.1.10/src/full-codegen.h} +109 -29
  143. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/func-name-inferrer.cc +0 -0
  144. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/func-name-inferrer.h +0 -0
  145. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/global-handles.cc +0 -0
  146. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/global-handles.h +0 -0
  147. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/globals.h +67 -43
  148. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/handles-inl.h +0 -0
  149. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/handles.cc +124 -129
  150. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/handles.h +33 -15
  151. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/hashmap.cc +0 -0
  152. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/hashmap.h +0 -0
  153. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap-inl.h +56 -12
  154. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap-profiler.cc +2 -2
  155. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap-profiler.h +2 -0
  156. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap.cc +413 -221
  157. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap.h +192 -67
  158. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/assembler-ia32-inl.h +6 -0
  159. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/assembler-ia32.cc +187 -32
  160. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/assembler-ia32.h +31 -4
  161. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/builtins-ia32.cc +160 -133
  162. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/codegen-ia32-inl.h +0 -0
  163. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/codegen-ia32.cc +5533 -2177
  164. data/ext/v8/upstream/{2.0.6/src/x64/codegen-x64.h → 2.1.10/src/ia32/codegen-ia32.h} +453 -134
  165. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/cpu-ia32.cc +0 -0
  166. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/debug-ia32.cc +63 -8
  167. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/disasm-ia32.cc +99 -16
  168. data/ext/v8/upstream/2.1.10/src/ia32/fast-codegen-ia32.cc +950 -0
  169. data/ext/v8/upstream/2.1.10/src/ia32/fast-codegen-ia32.h +155 -0
  170. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/frames-ia32.cc +0 -0
  171. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/frames-ia32.h +0 -0
  172. data/ext/v8/upstream/{2.0.6/src/ia32/fast-codegen-ia32.cc → 2.1.10/src/ia32/full-codegen-ia32.cc} +454 -253
  173. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/ic-ia32.cc +545 -390
  174. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/jump-target-ia32.cc +1 -0
  175. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/macro-assembler-ia32.cc +330 -139
  176. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/macro-assembler-ia32.h +96 -30
  177. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/regexp-macro-assembler-ia32.cc +73 -89
  178. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/regexp-macro-assembler-ia32.h +6 -21
  179. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/register-allocator-ia32-inl.h +0 -0
  180. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/register-allocator-ia32.cc +59 -5
  181. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/register-allocator-ia32.h +0 -0
  182. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/simulator-ia32.cc +0 -0
  183. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/simulator-ia32.h +2 -2
  184. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/stub-cache-ia32.cc +745 -303
  185. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/virtual-frame-ia32.cc +278 -71
  186. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/virtual-frame-ia32.h +78 -22
  187. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ic-inl.h +0 -0
  188. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ic.cc +172 -89
  189. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ic.h +51 -20
  190. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/interpreter-irregexp.cc +0 -0
  191. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/interpreter-irregexp.h +0 -0
  192. data/ext/v8/upstream/{2.0.6/src/json-delay.js → 2.1.10/src/json.js} +26 -12
  193. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jsregexp.cc +151 -118
  194. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jsregexp.h +31 -7
  195. data/ext/v8/upstream/2.1.10/src/jump-target-heavy-inl.h +51 -0
  196. data/ext/v8/upstream/{2.0.6/src/jump-target.cc → 2.1.10/src/jump-target-heavy.cc} +164 -184
  197. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jump-target-inl.h +8 -9
  198. data/ext/v8/upstream/{2.0.6/src/usage-analyzer.h → 2.1.10/src/jump-target-light-inl.h} +9 -7
  199. data/ext/v8/upstream/2.1.10/src/jump-target-light.cc +86 -0
  200. data/ext/v8/upstream/2.1.10/src/jump-target.cc +155 -0
  201. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jump-target.h +6 -0
  202. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/list-inl.h +0 -0
  203. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/list.h +2 -1
  204. data/ext/v8/upstream/2.1.10/src/liveedit-debugger.js +944 -0
  205. data/ext/v8/upstream/2.1.10/src/liveedit.cc +1468 -0
  206. data/ext/v8/upstream/2.1.10/src/liveedit.h +170 -0
  207. data/ext/v8/upstream/2.1.10/src/log-inl.h +59 -0
  208. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log-utils.cc +3 -9
  209. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log-utils.h +1 -4
  210. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log.cc +198 -95
  211. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log.h +50 -49
  212. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/macro-assembler.h +9 -0
  213. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/macros.py +30 -11
  214. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/mark-compact.cc +464 -152
  215. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/mark-compact.h +41 -20
  216. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/math.js +9 -8
  217. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/memory.h +0 -0
  218. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/messages.cc +1 -0
  219. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/messages.h +0 -0
  220. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/messages.js +46 -9
  221. data/ext/v8/upstream/2.1.10/src/mips/assembler-mips-inl.h +215 -0
  222. data/ext/v8/upstream/2.1.10/src/mips/assembler-mips.cc +1208 -0
  223. data/ext/v8/upstream/2.1.10/src/mips/assembler-mips.h +665 -0
  224. data/ext/v8/upstream/2.1.10/src/mips/builtins-mips.cc +202 -0
  225. data/ext/v8/upstream/2.1.10/src/mips/codegen-mips-inl.h +70 -0
  226. data/ext/v8/upstream/2.1.10/src/mips/codegen-mips.cc +1428 -0
  227. data/ext/v8/upstream/{2.0.6/src/arm/codegen-arm.h → 2.1.10/src/mips/codegen-mips.h} +103 -205
  228. data/ext/v8/upstream/2.1.10/src/mips/constants-mips.cc +323 -0
  229. data/ext/v8/upstream/2.1.10/src/mips/constants-mips.h +525 -0
  230. data/ext/v8/upstream/2.1.10/src/mips/cpu-mips.cc +69 -0
  231. data/ext/v8/upstream/2.1.10/src/mips/debug-mips.cc +128 -0
  232. data/ext/v8/upstream/2.1.10/src/mips/disasm-mips.cc +784 -0
  233. data/ext/v8/upstream/2.1.10/src/mips/fast-codegen-mips.cc +74 -0
  234. data/ext/v8/upstream/2.1.10/src/mips/frames-mips.cc +99 -0
  235. data/ext/v8/upstream/2.1.10/src/mips/frames-mips.h +164 -0
  236. data/ext/v8/upstream/2.1.10/src/mips/full-codegen-mips.cc +273 -0
  237. data/ext/v8/upstream/2.1.10/src/mips/ic-mips.cc +217 -0
  238. data/ext/v8/upstream/2.1.10/src/mips/jump-target-mips.cc +172 -0
  239. data/ext/v8/upstream/2.1.10/src/mips/macro-assembler-mips.cc +1323 -0
  240. data/ext/v8/upstream/2.1.10/src/mips/macro-assembler-mips.h +461 -0
  241. data/ext/v8/upstream/2.1.10/src/mips/register-allocator-mips-inl.h +137 -0
  242. data/ext/v8/upstream/2.1.10/src/mips/register-allocator-mips.cc +60 -0
  243. data/ext/v8/upstream/2.1.10/src/mips/register-allocator-mips.h +46 -0
  244. data/ext/v8/upstream/2.1.10/src/mips/simulator-mips.cc +1648 -0
  245. data/ext/v8/upstream/2.1.10/src/mips/simulator-mips.h +311 -0
  246. data/ext/v8/upstream/2.1.10/src/mips/stub-cache-mips.cc +400 -0
  247. data/ext/v8/upstream/2.1.10/src/mips/virtual-frame-mips.cc +316 -0
  248. data/ext/v8/upstream/{2.0.6/src/arm/virtual-frame-arm.h → 2.1.10/src/mips/virtual-frame-mips.h} +87 -71
  249. data/ext/v8/upstream/{2.0.6/src/mirror-delay.js → 2.1.10/src/mirror-debugger.js} +51 -45
  250. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/mksnapshot.cc +97 -10
  251. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/natives.h +6 -6
  252. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects-debug.cc +47 -5
  253. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects-inl.h +154 -38
  254. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects.cc +528 -280
  255. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects.h +302 -95
  256. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/oprofile-agent.cc +25 -33
  257. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/oprofile-agent.h +9 -1
  258. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/parser.cc +444 -72
  259. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/parser.h +4 -2
  260. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-freebsd.cc +32 -13
  261. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-linux.cc +59 -25
  262. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-macos.cc +30 -13
  263. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-nullos.cc +0 -0
  264. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-openbsd.cc +21 -2
  265. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-posix.cc +0 -18
  266. data/ext/v8/upstream/2.1.10/src/platform-solaris.cc +607 -0
  267. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-win32.cc +16 -17
  268. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform.h +25 -8
  269. data/ext/v8/upstream/2.1.10/src/powers-ten.h +2461 -0
  270. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/prettyprinter.cc +49 -29
  271. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/prettyprinter.h +3 -1
  272. data/ext/v8/upstream/2.1.10/src/profile-generator-inl.h +124 -0
  273. data/ext/v8/upstream/2.1.10/src/profile-generator.cc +583 -0
  274. data/ext/v8/upstream/2.1.10/src/profile-generator.h +364 -0
  275. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/property.cc +1 -1
  276. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/property.h +12 -24
  277. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-irregexp-inl.h +2 -2
  278. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-irregexp.cc +2 -2
  279. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-irregexp.h +2 -2
  280. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-tracer.cc +2 -2
  281. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-tracer.h +0 -0
  282. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler.cc +33 -10
  283. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler.h +12 -4
  284. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-stack.cc +0 -0
  285. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-stack.h +0 -0
  286. data/ext/v8/upstream/{2.0.6/src/regexp-delay.js → 2.1.10/src/regexp.js} +180 -58
  287. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/register-allocator-inl.h +68 -1
  288. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/register-allocator.cc +5 -2
  289. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/register-allocator.h +42 -17
  290. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/rewriter.cc +110 -4
  291. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/rewriter.h +0 -0
  292. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/runtime.cc +2733 -623
  293. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/runtime.h +43 -20
  294. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/runtime.js +46 -35
  295. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scanner.cc +278 -36
  296. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scanner.h +97 -26
  297. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopeinfo.cc +3 -3
  298. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopeinfo.h +1 -0
  299. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopes.cc +11 -12
  300. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopes.h +0 -1
  301. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/serialize.cc +298 -175
  302. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/serialize.h +184 -40
  303. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/shell.h +0 -0
  304. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/simulator.h +2 -0
  305. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/smart-pointer.h +0 -0
  306. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/snapshot-common.cc +16 -31
  307. data/ext/v8/upstream/2.1.10/src/snapshot-empty.cc +50 -0
  308. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/snapshot.h +13 -1
  309. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/spaces-inl.h +35 -27
  310. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/spaces.cc +256 -42
  311. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/spaces.h +136 -42
  312. data/ext/v8/upstream/{2.0.6/src/zone-inl.h → 2.1.10/src/splay-tree-inl.h} +102 -89
  313. data/ext/v8/upstream/2.1.10/src/splay-tree.h +203 -0
  314. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/string-stream.cc +0 -0
  315. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/string-stream.h +0 -0
  316. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/string.js +260 -149
  317. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/stub-cache.cc +195 -69
  318. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/stub-cache.h +127 -12
  319. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/third_party/dtoa/COPYING +0 -0
  320. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/third_party/dtoa/dtoa.c +0 -0
  321. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/third_party/valgrind/valgrind.h +0 -0
  322. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/token.cc +0 -0
  323. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/token.h +0 -0
  324. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/top.cc +26 -31
  325. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/top.h +3 -4
  326. data/ext/v8/upstream/2.1.10/src/type-info.cc +53 -0
  327. data/ext/v8/upstream/2.1.10/src/type-info.h +244 -0
  328. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/unicode-inl.h +0 -0
  329. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/unicode.cc +0 -0
  330. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/unicode.h +0 -0
  331. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/uri.js +6 -6
  332. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/utils.cc +0 -37
  333. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/utils.h +121 -50
  334. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8-counters.cc +0 -0
  335. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8-counters.h +130 -98
  336. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8.cc +42 -11
  337. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8.h +4 -2
  338. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8natives.js +202 -37
  339. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8threads.cc +11 -0
  340. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8threads.h +15 -0
  341. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/variables.cc +7 -51
  342. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/variables.h +5 -35
  343. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/version.cc +3 -3
  344. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/version.h +0 -0
  345. data/ext/v8/upstream/2.1.10/src/virtual-frame-heavy-inl.h +152 -0
  346. data/ext/v8/upstream/{2.0.6/src/virtual-frame.cc → 2.1.10/src/virtual-frame-heavy.cc} +107 -176
  347. data/ext/v8/upstream/2.1.10/src/virtual-frame-inl.h +39 -0
  348. data/ext/v8/upstream/2.1.10/src/virtual-frame-light-inl.h +69 -0
  349. data/ext/v8/upstream/2.1.10/src/virtual-frame-light.cc +49 -0
  350. data/ext/v8/upstream/2.1.10/src/virtual-frame.cc +49 -0
  351. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/virtual-frame.h +2 -0
  352. data/ext/v8/upstream/{2.0.6/src/log-inl.h → 2.1.10/src/vm-state-inl.h} +28 -20
  353. data/ext/v8/upstream/{2.0.6/src/snapshot-empty.cc → 2.1.10/src/vm-state.cc} +5 -6
  354. data/ext/v8/upstream/2.1.10/src/vm-state.h +75 -0
  355. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/assembler-x64-inl.h +11 -0
  356. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/assembler-x64.cc +285 -93
  357. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/assembler-x64.h +81 -78
  358. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/builtins-x64.cc +130 -87
  359. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/codegen-x64-inl.h +0 -0
  360. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/codegen-x64.cc +4520 -1317
  361. data/ext/v8/upstream/{2.0.6/src/ia32/codegen-ia32.h → 2.1.10/src/x64/codegen-x64.h} +362 -141
  362. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/cpu-x64.cc +0 -0
  363. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/debug-x64.cc +20 -4
  364. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/disasm-x64.cc +121 -44
  365. data/ext/v8/upstream/2.1.10/src/x64/fast-codegen-x64.cc +246 -0
  366. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/frames-x64.cc +0 -0
  367. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/frames-x64.h +0 -0
  368. data/ext/v8/upstream/{2.0.6/src/x64/fast-codegen-x64.cc → 2.1.10/src/x64/full-codegen-x64.cc} +404 -231
  369. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/ic-x64.cc +346 -117
  370. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/jump-target-x64.cc +1 -0
  371. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/macro-assembler-x64.cc +537 -181
  372. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/macro-assembler-x64.h +140 -34
  373. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/regexp-macro-assembler-x64.cc +74 -96
  374. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/regexp-macro-assembler-x64.h +8 -25
  375. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/register-allocator-x64-inl.h +1 -1
  376. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/register-allocator-x64.cc +3 -0
  377. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/register-allocator-x64.h +0 -0
  378. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/simulator-x64.cc +0 -0
  379. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/simulator-x64.h +2 -2
  380. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/stub-cache-x64.cc +785 -288
  381. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/virtual-frame-x64.cc +128 -52
  382. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/virtual-frame-x64.h +40 -19
  383. data/ext/v8/upstream/2.1.10/src/zone-inl.h +82 -0
  384. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/zone.cc +1 -0
  385. data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/zone.h +6 -90
  386. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/codemap.js +12 -0
  387. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/consarray.js +0 -0
  388. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/csvparser.js +22 -37
  389. data/ext/v8/upstream/2.1.10/tools/generate-ten-powers.scm +286 -0
  390. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/gyp/v8.gyp +86 -24
  391. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/js2c.py +22 -22
  392. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/jsmin.py +0 -0
  393. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/linux-tick-processor +10 -1
  394. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/linux-tick-processor.py +0 -0
  395. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/logreader.js +34 -16
  396. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/mac-nm +0 -0
  397. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/mac-tick-processor +0 -0
  398. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/annotate +0 -0
  399. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/common +0 -0
  400. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/dump +0 -0
  401. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/report +0 -0
  402. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/reset +0 -0
  403. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/run +0 -0
  404. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/shutdown +0 -0
  405. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/start +0 -0
  406. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/presubmit.py +0 -0
  407. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/process-heap-prof.py +0 -0
  408. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/profile.js +70 -0
  409. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/profile_view.js +0 -0
  410. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/run-valgrind.py +0 -0
  411. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/splaytree.js +0 -0
  412. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/splaytree.py +0 -0
  413. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/stats-viewer.py +0 -0
  414. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/test.py +7 -7
  415. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/tickprocessor-driver.js +7 -1
  416. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/tickprocessor.js +140 -9
  417. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/tickprocessor.py +40 -4
  418. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/utils.py +6 -0
  419. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/README.txt +0 -0
  420. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/arm.vsprops +1 -1
  421. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/common.vsprops +1 -2
  422. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8.vcproj +0 -6
  423. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8_arm.vcproj +193 -199
  424. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8_x64.vcproj +16 -8
  425. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8js2c.cmd +0 -0
  426. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/debug.vsprops +0 -0
  427. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/ia32.vsprops +5 -1
  428. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/js2c.cmd +1 -1
  429. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/release.vsprops +0 -0
  430. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8.sln +0 -0
  431. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8.vcproj +11 -7
  432. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_arm.sln +0 -0
  433. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_arm.vcproj +227 -223
  434. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_base.vcproj +137 -5
  435. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_base_arm.vcproj +116 -4
  436. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_base_x64.vcproj +125 -4
  437. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_cctest.vcproj +12 -6
  438. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_cctest_arm.vcproj +12 -6
  439. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_cctest_x64.vcproj +11 -11
  440. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_mksnapshot.vcproj +0 -6
  441. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_mksnapshot_x64.vcproj +0 -6
  442. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_process_sample.vcproj +0 -6
  443. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_process_sample_arm.vcproj +145 -151
  444. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_process_sample_x64.vcproj +16 -6
  445. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_shell_sample.vcproj +0 -6
  446. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_shell_sample_arm.vcproj +145 -151
  447. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_shell_sample_x64.vcproj +16 -8
  448. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot.vcproj +0 -0
  449. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot_cc.vcproj +0 -0
  450. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot_cc_x64.vcproj +0 -0
  451. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot_x64.vcproj +0 -0
  452. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_x64.sln +0 -0
  453. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_x64.vcproj +11 -7
  454. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/x64.vsprops +5 -1
  455. data/ext/v8/upstream/2.1.10/tools/windows-tick-processor.bat +29 -0
  456. data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/windows-tick-processor.py +0 -0
  457. data/ext/v8/upstream/Makefile +8 -2
  458. data/ext/v8/v8.cpp +21 -73
  459. data/ext/v8/v8_array.cpp +56 -0
  460. data/ext/v8/v8_array.h +8 -0
  461. data/ext/v8/v8_callbacks.cpp +121 -0
  462. data/ext/v8/v8_callbacks.h +8 -0
  463. data/ext/v8/v8_cxt.cpp +74 -77
  464. data/ext/v8/v8_cxt.h +2 -9
  465. data/ext/v8/v8_date.cpp +26 -0
  466. data/ext/v8/v8_date.h +6 -0
  467. data/ext/v8/v8_exception.cpp +55 -0
  468. data/ext/v8/v8_exception.h +6 -0
  469. data/ext/v8/v8_external.cpp +50 -0
  470. data/ext/v8/v8_external.h +8 -0
  471. data/ext/v8/v8_func.cpp +76 -18
  472. data/ext/v8/v8_func.h +5 -4
  473. data/ext/v8/v8_msg.cpp +55 -46
  474. data/ext/v8/v8_msg.h +3 -11
  475. data/ext/v8/v8_obj.cpp +67 -36
  476. data/ext/v8/v8_obj.h +6 -8
  477. data/ext/v8/v8_ref.cpp +25 -9
  478. data/ext/v8/v8_ref.h +3 -5
  479. data/ext/v8/v8_script.cpp +17 -10
  480. data/ext/v8/v8_script.h +3 -3
  481. data/ext/v8/v8_str.cpp +34 -6
  482. data/ext/v8/v8_str.h +4 -2
  483. data/ext/v8/v8_template.cpp +195 -33
  484. data/ext/v8/v8_template.h +4 -5
  485. data/ext/v8/v8_try_catch.cpp +99 -0
  486. data/ext/v8/v8_try_catch.h +5 -0
  487. data/ext/v8/v8_value.cpp +164 -0
  488. data/ext/v8/v8_value.h +10 -0
  489. data/lib/v8.rb +3 -1
  490. data/lib/v8/access.rb +60 -0
  491. data/lib/v8/array.rb +15 -0
  492. data/lib/v8/callbacks.rb +88 -0
  493. data/lib/v8/cli.rb +1 -1
  494. data/lib/v8/context.rb +55 -66
  495. data/lib/v8/function.rb +20 -2
  496. data/lib/v8/object.rb +14 -12
  497. data/lib/v8/ruby_error.rb +3 -0
  498. data/lib/v8/to.rb +59 -7
  499. data/spec/ext/cxt_spec.rb +2 -15
  500. data/spec/ext/func_spec.rb +17 -10
  501. data/spec/ext/try_catch_spec.rb +32 -0
  502. data/spec/foo.rb +17 -0
  503. data/spec/redjs/jsapi_spec.rb +173 -96
  504. data/spec/spec_helper.rb +7 -0
  505. data/spec/v8/to_spec.rb +0 -1
  506. data/therubyracer.gemspec +6 -6
  507. metadata +493 -386
  508. data/ext/v8/upstream/2.0.6/src/arm/ic-arm.cc +0 -849
  509. data/ext/v8/upstream/2.0.6/src/arm/virtual-frame-arm.cc +0 -412
  510. data/ext/v8/upstream/2.0.6/src/ast.cc +0 -512
  511. data/ext/v8/upstream/2.0.6/src/builtins.cc +0 -851
  512. data/ext/v8/upstream/2.0.6/src/compiler.cc +0 -1132
  513. data/ext/v8/upstream/2.0.6/src/compiler.h +0 -107
  514. data/ext/v8/upstream/2.0.6/src/conversions.cc +0 -709
  515. data/ext/v8/upstream/2.0.6/src/usage-analyzer.cc +0 -426
  516. data/ext/v8/upstream/2.0.6/tools/windows-tick-processor.bat +0 -5
  517. data/ext/v8/upstream/no-strict-aliasing.patch +0 -13
  518. data/ext/v8/v8_standalone.cpp +0 -69
  519. data/ext/v8/v8_standalone.h +0 -31
  520. data/spec/ext/obj_spec.rb +0 -13
@@ -32,12 +32,14 @@
32
32
  #include "accessors.h"
33
33
  #include "api.h"
34
34
  #include "arguments.h"
35
+ #include "codegen.h"
35
36
  #include "compiler.h"
36
37
  #include "cpu.h"
37
38
  #include "dateparser-inl.h"
38
39
  #include "debug.h"
39
40
  #include "execution.h"
40
41
  #include "jsregexp.h"
42
+ #include "liveedit.h"
41
43
  #include "parser.h"
42
44
  #include "platform.h"
43
45
  #include "runtime.h"
@@ -107,25 +109,23 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
107
109
  // Deep copy local properties.
108
110
  if (copy->HasFastProperties()) {
109
111
  FixedArray* properties = copy->properties();
110
- WriteBarrierMode mode = properties->GetWriteBarrierMode();
111
112
  for (int i = 0; i < properties->length(); i++) {
112
113
  Object* value = properties->get(i);
113
114
  if (value->IsJSObject()) {
114
- JSObject* jsObject = JSObject::cast(value);
115
- result = DeepCopyBoilerplate(jsObject);
115
+ JSObject* js_object = JSObject::cast(value);
116
+ result = DeepCopyBoilerplate(js_object);
116
117
  if (result->IsFailure()) return result;
117
- properties->set(i, result, mode);
118
+ properties->set(i, result);
118
119
  }
119
120
  }
120
- mode = copy->GetWriteBarrierMode();
121
121
  int nof = copy->map()->inobject_properties();
122
122
  for (int i = 0; i < nof; i++) {
123
123
  Object* value = copy->InObjectPropertyAt(i);
124
124
  if (value->IsJSObject()) {
125
- JSObject* jsObject = JSObject::cast(value);
126
- result = DeepCopyBoilerplate(jsObject);
125
+ JSObject* js_object = JSObject::cast(value);
126
+ result = DeepCopyBoilerplate(js_object);
127
127
  if (result->IsFailure()) return result;
128
- copy->InObjectPropertyAtPut(i, result, mode);
128
+ copy->InObjectPropertyAtPut(i, result);
129
129
  }
130
130
  }
131
131
  } else {
@@ -135,20 +135,20 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
135
135
  copy->GetLocalPropertyNames(names, 0);
136
136
  for (int i = 0; i < names->length(); i++) {
137
137
  ASSERT(names->get(i)->IsString());
138
- String* keyString = String::cast(names->get(i));
138
+ String* key_string = String::cast(names->get(i));
139
139
  PropertyAttributes attributes =
140
- copy->GetLocalPropertyAttribute(keyString);
140
+ copy->GetLocalPropertyAttribute(key_string);
141
141
  // Only deep copy fields from the object literal expression.
142
142
  // In particular, don't try to copy the length attribute of
143
143
  // an array.
144
144
  if (attributes != NONE) continue;
145
- Object* value = copy->GetProperty(keyString, &attributes);
145
+ Object* value = copy->GetProperty(key_string, &attributes);
146
146
  ASSERT(!value->IsFailure());
147
147
  if (value->IsJSObject()) {
148
- JSObject* jsObject = JSObject::cast(value);
149
- result = DeepCopyBoilerplate(jsObject);
148
+ JSObject* js_object = JSObject::cast(value);
149
+ result = DeepCopyBoilerplate(js_object);
150
150
  if (result->IsFailure()) return result;
151
- result = copy->SetProperty(keyString, result, NONE);
151
+ result = copy->SetProperty(key_string, result, NONE);
152
152
  if (result->IsFailure()) return result;
153
153
  }
154
154
  }
@@ -160,14 +160,13 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
160
160
  switch (copy->GetElementsKind()) {
161
161
  case JSObject::FAST_ELEMENTS: {
162
162
  FixedArray* elements = FixedArray::cast(copy->elements());
163
- WriteBarrierMode mode = elements->GetWriteBarrierMode();
164
163
  for (int i = 0; i < elements->length(); i++) {
165
164
  Object* value = elements->get(i);
166
165
  if (value->IsJSObject()) {
167
- JSObject* jsObject = JSObject::cast(value);
168
- result = DeepCopyBoilerplate(jsObject);
166
+ JSObject* js_object = JSObject::cast(value);
167
+ result = DeepCopyBoilerplate(js_object);
169
168
  if (result->IsFailure()) return result;
170
- elements->set(i, result, mode);
169
+ elements->set(i, result);
171
170
  }
172
171
  }
173
172
  break;
@@ -180,8 +179,8 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
180
179
  if (element_dictionary->IsKey(k)) {
181
180
  Object* value = element_dictionary->ValueAt(i);
182
181
  if (value->IsJSObject()) {
183
- JSObject* jsObject = JSObject::cast(value);
184
- result = DeepCopyBoilerplate(jsObject);
182
+ JSObject* js_object = JSObject::cast(value);
183
+ result = DeepCopyBoilerplate(js_object);
185
184
  if (result->IsFailure()) return result;
186
185
  element_dictionary->ValueAtPut(i, result);
187
186
  }
@@ -249,7 +248,8 @@ static Handle<Object> CreateLiteralBoilerplate(
249
248
 
250
249
  static Handle<Object> CreateObjectLiteralBoilerplate(
251
250
  Handle<FixedArray> literals,
252
- Handle<FixedArray> constant_properties) {
251
+ Handle<FixedArray> constant_properties,
252
+ bool should_have_fast_elements) {
253
253
  // Get the global context from the literals array. This is the
254
254
  // context in which the function was created and we use the object
255
255
  // function from this context to create the object literal. We do
@@ -265,6 +265,10 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
265
265
  &is_result_from_cache);
266
266
 
267
267
  Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map);
268
+
269
+ // Normalize the elements of the boilerplate to save space if needed.
270
+ if (!should_have_fast_elements) NormalizeElements(boilerplate);
271
+
268
272
  { // Add the constant properties to the boilerplate.
269
273
  int length = constant_properties->length();
270
274
  OptimizedObjectForAddingMultipleProperties opt(boilerplate,
@@ -346,8 +350,10 @@ static Handle<Object> CreateLiteralBoilerplate(
346
350
  Handle<FixedArray> array) {
347
351
  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
348
352
  switch (CompileTimeValue::GetType(array)) {
349
- case CompileTimeValue::OBJECT_LITERAL:
350
- return CreateObjectLiteralBoilerplate(literals, elements);
353
+ case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
354
+ return CreateObjectLiteralBoilerplate(literals, elements, true);
355
+ case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
356
+ return CreateObjectLiteralBoilerplate(literals, elements, false);
351
357
  case CompileTimeValue::ARRAY_LITERAL:
352
358
  return CreateArrayLiteralBoilerplate(literals, elements);
353
359
  default:
@@ -357,26 +363,6 @@ static Handle<Object> CreateLiteralBoilerplate(
357
363
  }
358
364
 
359
365
 
360
- static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) {
361
- HandleScope scope;
362
- ASSERT(args.length() == 3);
363
- // Copy the arguments.
364
- CONVERT_ARG_CHECKED(FixedArray, literals, 0);
365
- CONVERT_SMI_CHECKED(literals_index, args[1]);
366
- CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
367
-
368
- Handle<Object> result =
369
- CreateObjectLiteralBoilerplate(literals, constant_properties);
370
-
371
- if (result.is_null()) return Failure::Exception();
372
-
373
- // Update the functions literal and return the boilerplate.
374
- literals->set(literals_index, *result);
375
-
376
- return *result;
377
- }
378
-
379
-
380
366
  static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) {
381
367
  // Takes a FixedArray of elements containing the literal elements of
382
368
  // the array literal and produces JSArray with those elements.
@@ -400,15 +386,19 @@ static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) {
400
386
 
401
387
  static Object* Runtime_CreateObjectLiteral(Arguments args) {
402
388
  HandleScope scope;
403
- ASSERT(args.length() == 3);
389
+ ASSERT(args.length() == 4);
404
390
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
405
391
  CONVERT_SMI_CHECKED(literals_index, args[1]);
406
392
  CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
393
+ CONVERT_SMI_CHECKED(fast_elements, args[3]);
394
+ bool should_have_fast_elements = fast_elements == 1;
407
395
 
408
396
  // Check if boilerplate exists. If not, create it first.
409
397
  Handle<Object> boilerplate(literals->get(literals_index));
410
398
  if (*boilerplate == Heap::undefined_value()) {
411
- boilerplate = CreateObjectLiteralBoilerplate(literals, constant_properties);
399
+ boilerplate = CreateObjectLiteralBoilerplate(literals,
400
+ constant_properties,
401
+ should_have_fast_elements);
412
402
  if (boilerplate.is_null()) return Failure::Exception();
413
403
  // Update the functions literal and return the boilerplate.
414
404
  literals->set(literals_index, *boilerplate);
@@ -419,15 +409,19 @@ static Object* Runtime_CreateObjectLiteral(Arguments args) {
419
409
 
420
410
  static Object* Runtime_CreateObjectLiteralShallow(Arguments args) {
421
411
  HandleScope scope;
422
- ASSERT(args.length() == 3);
412
+ ASSERT(args.length() == 4);
423
413
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
424
414
  CONVERT_SMI_CHECKED(literals_index, args[1]);
425
415
  CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
416
+ CONVERT_SMI_CHECKED(fast_elements, args[3]);
417
+ bool should_have_fast_elements = fast_elements == 1;
426
418
 
427
419
  // Check if boilerplate exists. If not, create it first.
428
420
  Handle<Object> boilerplate(literals->get(literals_index));
429
421
  if (*boilerplate == Heap::undefined_value()) {
430
- boilerplate = CreateObjectLiteralBoilerplate(literals, constant_properties);
422
+ boilerplate = CreateObjectLiteralBoilerplate(literals,
423
+ constant_properties,
424
+ should_have_fast_elements);
431
425
  if (boilerplate.is_null()) return Failure::Exception();
432
426
  // Update the functions literal and return the boilerplate.
433
427
  literals->set(literals_index, *boilerplate);
@@ -583,6 +577,7 @@ static void GetOwnPropertyImplementation(JSObject* obj,
583
577
  // if args[1] is an accessor on args[0]
584
578
  // [true, GetFunction, SetFunction, Enumerable, Configurable]
585
579
  static Object* Runtime_GetOwnProperty(Arguments args) {
580
+ ASSERT(args.length() == 2);
586
581
  HandleScope scope;
587
582
  Handle<FixedArray> elms = Factory::NewFixedArray(5);
588
583
  Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms);
@@ -598,8 +593,9 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
598
593
 
599
594
  if (result.type() == CALLBACKS) {
600
595
  Object* structure = result.GetCallbackObject();
601
- if (structure->IsProxy()) {
602
- // Property that is internally implemented as a callback.
596
+ if (structure->IsProxy() || structure->IsAccessorInfo()) {
597
+ // Property that is internally implemented as a callback or
598
+ // an API defined callback.
603
599
  Object* value = obj->GetPropertyWithCallback(
604
600
  obj, structure, name, result.holder());
605
601
  elms->set(0, Heap::false_value());
@@ -611,7 +607,6 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
611
607
  elms->set(1, FixedArray::cast(structure)->get(0));
612
608
  elms->set(2, FixedArray::cast(structure)->get(1));
613
609
  } else {
614
- // TODO(ricow): Handle API callbacks.
615
610
  return Heap::undefined_value();
616
611
  }
617
612
  } else {
@@ -621,11 +616,19 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
621
616
  }
622
617
 
623
618
  elms->set(3, Heap::ToBoolean(!result.IsDontEnum()));
624
- elms->set(4, Heap::ToBoolean(!result.IsReadOnly()));
619
+ elms->set(4, Heap::ToBoolean(!result.IsDontDelete()));
625
620
  return *desc;
626
621
  }
627
622
 
628
623
 
624
+ static Object* Runtime_IsExtensible(Arguments args) {
625
+ ASSERT(args.length() == 1);
626
+ CONVERT_CHECKED(JSObject, obj, args[0]);
627
+ return obj->map()->is_extensible() ? Heap::true_value()
628
+ : Heap::false_value();
629
+ }
630
+
631
+
629
632
  static Object* Runtime_RegExpCompile(Arguments args) {
630
633
  HandleScope scope;
631
634
  ASSERT(args.length() == 3);
@@ -785,9 +788,10 @@ static Object* Runtime_DeclareGlobals(Arguments args) {
785
788
  }
786
789
  } else {
787
790
  // Copy the function and update its context. Use it as value.
788
- Handle<JSFunction> boilerplate = Handle<JSFunction>::cast(value);
791
+ Handle<SharedFunctionInfo> shared =
792
+ Handle<SharedFunctionInfo>::cast(value);
789
793
  Handle<JSFunction> function =
790
- Factory::NewFunctionFromBoilerplate(boilerplate, context, TENURED);
794
+ Factory::NewFunctionFromSharedFunctionInfo(shared, context, TENURED);
791
795
  value = function;
792
796
  }
793
797
 
@@ -1202,17 +1206,6 @@ static Object* Runtime_OptimizeObjectForAddingMultipleProperties(
1202
1206
  }
1203
1207
 
1204
1208
 
1205
- static Object* Runtime_TransformToFastProperties(Arguments args) {
1206
- HandleScope scope;
1207
- ASSERT(args.length() == 1);
1208
- CONVERT_ARG_CHECKED(JSObject, object, 0);
1209
- if (!object->HasFastProperties() && !object->IsGlobalObject()) {
1210
- TransformToFastProperties(object, 0);
1211
- }
1212
- return *object;
1213
- }
1214
-
1215
-
1216
1209
  static Object* Runtime_RegExpExec(Arguments args) {
1217
1210
  HandleScope scope;
1218
1211
  ASSERT(args.length() == 4);
@@ -1235,6 +1228,178 @@ static Object* Runtime_RegExpExec(Arguments args) {
1235
1228
  }
1236
1229
 
1237
1230
 
1231
+ static Object* Runtime_RegExpConstructResult(Arguments args) {
1232
+ ASSERT(args.length() == 3);
1233
+ CONVERT_SMI_CHECKED(elements_count, args[0]);
1234
+ if (elements_count > JSArray::kMaxFastElementsLength) {
1235
+ return Top::ThrowIllegalOperation();
1236
+ }
1237
+ Object* new_object = Heap::AllocateFixedArrayWithHoles(elements_count);
1238
+ if (new_object->IsFailure()) return new_object;
1239
+ FixedArray* elements = FixedArray::cast(new_object);
1240
+ new_object = Heap::AllocateRaw(JSRegExpResult::kSize,
1241
+ NEW_SPACE,
1242
+ OLD_POINTER_SPACE);
1243
+ if (new_object->IsFailure()) return new_object;
1244
+ {
1245
+ AssertNoAllocation no_gc;
1246
+ HandleScope scope;
1247
+ reinterpret_cast<HeapObject*>(new_object)->
1248
+ set_map(Top::global_context()->regexp_result_map());
1249
+ }
1250
+ JSArray* array = JSArray::cast(new_object);
1251
+ array->set_properties(Heap::empty_fixed_array());
1252
+ array->set_elements(elements);
1253
+ array->set_length(Smi::FromInt(elements_count));
1254
+ // Write in-object properties after the length of the array.
1255
+ array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
1256
+ array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
1257
+ return array;
1258
+ }
1259
+
1260
+
1261
+ static Object* Runtime_RegExpInitializeObject(Arguments args) {
1262
+ AssertNoAllocation no_alloc;
1263
+ ASSERT(args.length() == 5);
1264
+ CONVERT_CHECKED(JSRegExp, regexp, args[0]);
1265
+ CONVERT_CHECKED(String, source, args[1]);
1266
+
1267
+ Object* global = args[2];
1268
+ if (!global->IsTrue()) global = Heap::false_value();
1269
+
1270
+ Object* ignoreCase = args[3];
1271
+ if (!ignoreCase->IsTrue()) ignoreCase = Heap::false_value();
1272
+
1273
+ Object* multiline = args[4];
1274
+ if (!multiline->IsTrue()) multiline = Heap::false_value();
1275
+
1276
+ Map* map = regexp->map();
1277
+ Object* constructor = map->constructor();
1278
+ if (constructor->IsJSFunction() &&
1279
+ JSFunction::cast(constructor)->initial_map() == map) {
1280
+ // If we still have the original map, set in-object properties directly.
1281
+ regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
1282
+ // TODO(lrn): Consider skipping write barrier on booleans as well.
1283
+ // Both true and false should be in oldspace at all times.
1284
+ regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global);
1285
+ regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase);
1286
+ regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline);
1287
+ regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
1288
+ Smi::FromInt(0),
1289
+ SKIP_WRITE_BARRIER);
1290
+ return regexp;
1291
+ }
1292
+
1293
+ // Map has changed, so use generic, but slower, method.
1294
+ PropertyAttributes final =
1295
+ static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
1296
+ PropertyAttributes writable =
1297
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1298
+ regexp->IgnoreAttributesAndSetLocalProperty(Heap::source_symbol(),
1299
+ source,
1300
+ final);
1301
+ regexp->IgnoreAttributesAndSetLocalProperty(Heap::global_symbol(),
1302
+ global,
1303
+ final);
1304
+ regexp->IgnoreAttributesAndSetLocalProperty(Heap::ignore_case_symbol(),
1305
+ ignoreCase,
1306
+ final);
1307
+ regexp->IgnoreAttributesAndSetLocalProperty(Heap::multiline_symbol(),
1308
+ multiline,
1309
+ final);
1310
+ regexp->IgnoreAttributesAndSetLocalProperty(Heap::last_index_symbol(),
1311
+ Smi::FromInt(0),
1312
+ writable);
1313
+ return regexp;
1314
+ }
1315
+
1316
+
1317
+ static Object* Runtime_FinishArrayPrototypeSetup(Arguments args) {
1318
+ HandleScope scope;
1319
+ ASSERT(args.length() == 1);
1320
+ CONVERT_ARG_CHECKED(JSArray, prototype, 0);
1321
+ // This is necessary to enable fast checks for absence of elements
1322
+ // on Array.prototype and below.
1323
+ prototype->set_elements(Heap::empty_fixed_array());
1324
+ return Smi::FromInt(0);
1325
+ }
1326
+
1327
+
1328
+ static void SetCustomCallGenerator(Handle<JSFunction> function,
1329
+ ExternalReference* generator) {
1330
+ if (function->shared()->function_data()->IsUndefined()) {
1331
+ function->shared()->set_function_data(*FromCData(generator->address()));
1332
+ }
1333
+ }
1334
+
1335
+
1336
+ static Handle<JSFunction> InstallBuiltin(Handle<JSObject> holder,
1337
+ const char* name,
1338
+ Builtins::Name builtin_name,
1339
+ ExternalReference* generator = NULL) {
1340
+ Handle<String> key = Factory::LookupAsciiSymbol(name);
1341
+ Handle<Code> code(Builtins::builtin(builtin_name));
1342
+ Handle<JSFunction> optimized = Factory::NewFunction(key,
1343
+ JS_OBJECT_TYPE,
1344
+ JSObject::kHeaderSize,
1345
+ code,
1346
+ false);
1347
+ optimized->shared()->DontAdaptArguments();
1348
+ if (generator != NULL) {
1349
+ SetCustomCallGenerator(optimized, generator);
1350
+ }
1351
+ SetProperty(holder, key, optimized, NONE);
1352
+ return optimized;
1353
+ }
1354
+
1355
+
1356
+ Object* CompileArrayPushCall(CallStubCompiler* compiler,
1357
+ Object* object,
1358
+ JSObject* holder,
1359
+ JSFunction* function,
1360
+ String* name,
1361
+ StubCompiler::CheckType check) {
1362
+ return compiler->CompileArrayPushCall(object, holder, function, name, check);
1363
+ }
1364
+
1365
+
1366
+ Object* CompileArrayPopCall(CallStubCompiler* compiler,
1367
+ Object* object,
1368
+ JSObject* holder,
1369
+ JSFunction* function,
1370
+ String* name,
1371
+ StubCompiler::CheckType check) {
1372
+ return compiler->CompileArrayPopCall(object, holder, function, name, check);
1373
+ }
1374
+
1375
+
1376
+ static Object* Runtime_SpecialArrayFunctions(Arguments args) {
1377
+ HandleScope scope;
1378
+ ASSERT(args.length() == 1);
1379
+ CONVERT_ARG_CHECKED(JSObject, holder, 0);
1380
+
1381
+ ExternalReference pop = ExternalReference::compile_array_pop_call();
1382
+ ExternalReference push = ExternalReference::compile_array_push_call();
1383
+
1384
+ InstallBuiltin(holder, "pop", Builtins::ArrayPop, &pop);
1385
+ InstallBuiltin(holder, "push", Builtins::ArrayPush, &push);
1386
+ InstallBuiltin(holder, "shift", Builtins::ArrayShift);
1387
+ InstallBuiltin(holder, "unshift", Builtins::ArrayUnshift);
1388
+ InstallBuiltin(holder, "slice", Builtins::ArraySlice);
1389
+ InstallBuiltin(holder, "splice", Builtins::ArraySplice);
1390
+ InstallBuiltin(holder, "concat", Builtins::ArrayConcat);
1391
+
1392
+ return *holder;
1393
+ }
1394
+
1395
+
1396
+ static Object* Runtime_GetGlobalReceiver(Arguments args) {
1397
+ // Returns a real global receiver, not one of builtins object.
1398
+ Context* global_context = Top::context()->global()->global_context();
1399
+ return global_context->global()->global_receiver();
1400
+ }
1401
+
1402
+
1238
1403
  static Object* Runtime_MaterializeRegExpLiteral(Arguments args) {
1239
1404
  HandleScope scope;
1240
1405
  ASSERT(args.length() == 4);
@@ -1285,6 +1450,18 @@ static Object* Runtime_FunctionSetName(Arguments args) {
1285
1450
  }
1286
1451
 
1287
1452
 
1453
+ static Object* Runtime_FunctionRemovePrototype(Arguments args) {
1454
+ NoHandleAllocation ha;
1455
+ ASSERT(args.length() == 1);
1456
+
1457
+ CONVERT_CHECKED(JSFunction, f, args[0]);
1458
+ Object* obj = f->RemovePrototype();
1459
+ if (obj->IsFailure()) return obj;
1460
+
1461
+ return Heap::undefined_value();
1462
+ }
1463
+
1464
+
1288
1465
  static Object* Runtime_FunctionGetScript(Arguments args) {
1289
1466
  HandleScope scope;
1290
1467
  ASSERT(args.length() == 1);
@@ -1358,6 +1535,7 @@ static Object* Runtime_FunctionSetPrototype(Arguments args) {
1358
1535
  ASSERT(args.length() == 2);
1359
1536
 
1360
1537
  CONVERT_CHECKED(JSFunction, fun, args[0]);
1538
+ ASSERT(fun->should_have_prototype());
1361
1539
  Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL);
1362
1540
  if (obj->IsFailure()) return obj;
1363
1541
  return args[0]; // return TOS
@@ -1369,10 +1547,8 @@ static Object* Runtime_FunctionIsAPIFunction(Arguments args) {
1369
1547
  ASSERT(args.length() == 1);
1370
1548
 
1371
1549
  CONVERT_CHECKED(JSFunction, f, args[0]);
1372
- // The function_data field of the shared function info is used exclusively by
1373
- // the API.
1374
- return !f->shared()->function_data()->IsUndefined() ? Heap::true_value()
1375
- : Heap::false_value();
1550
+ return f->shared()->IsApiFunction() ? Heap::true_value()
1551
+ : Heap::false_value();
1376
1552
  }
1377
1553
 
1378
1554
  static Object* Runtime_FunctionIsBuiltin(Arguments args) {
@@ -1396,16 +1572,18 @@ static Object* Runtime_SetCode(Arguments args) {
1396
1572
  if (!code->IsNull()) {
1397
1573
  RUNTIME_ASSERT(code->IsJSFunction());
1398
1574
  Handle<JSFunction> fun = Handle<JSFunction>::cast(code);
1399
- SetExpectedNofProperties(target, fun->shared()->expected_nof_properties());
1400
- if (!fun->is_compiled() && !CompileLazy(fun, KEEP_EXCEPTION)) {
1575
+ Handle<SharedFunctionInfo> shared(fun->shared());
1576
+ SetExpectedNofProperties(target, shared->expected_nof_properties());
1577
+
1578
+ if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
1401
1579
  return Failure::Exception();
1402
1580
  }
1403
1581
  // Set the code, formal parameter count, and the length of the target
1404
1582
  // function.
1405
1583
  target->set_code(fun->code());
1406
- target->shared()->set_length(fun->shared()->length());
1584
+ target->shared()->set_length(shared->length());
1407
1585
  target->shared()->set_formal_parameter_count(
1408
- fun->shared()->formal_parameter_count());
1586
+ shared->formal_parameter_count());
1409
1587
  // Set the source code of the target function to undefined.
1410
1588
  // SetCode is only used for built-in constructors like String,
1411
1589
  // Array, and Object, and some web code
@@ -1428,6 +1606,8 @@ static Object* Runtime_SetCode(Arguments args) {
1428
1606
  literals->set(JSFunction::kLiteralGlobalContextIndex,
1429
1607
  context->global_context());
1430
1608
  }
1609
+ // It's okay to skip the write barrier here because the literals
1610
+ // are guaranteed to be in old space.
1431
1611
  target->set_literals(*literals, SKIP_WRITE_BARRIER);
1432
1612
  }
1433
1613
 
@@ -1493,9 +1673,91 @@ static Object* Runtime_CharFromCode(Arguments args) {
1493
1673
  return CharFromCode(args[0]);
1494
1674
  }
1495
1675
 
1676
+
1677
+ class FixedArrayBuilder {
1678
+ public:
1679
+ explicit FixedArrayBuilder(int initial_capacity)
1680
+ : array_(Factory::NewFixedArrayWithHoles(initial_capacity)),
1681
+ length_(0) {
1682
+ // Require a non-zero initial size. Ensures that doubling the size to
1683
+ // extend the array will work.
1684
+ ASSERT(initial_capacity > 0);
1685
+ }
1686
+
1687
+ explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
1688
+ : array_(backing_store),
1689
+ length_(0) {
1690
+ // Require a non-zero initial size. Ensures that doubling the size to
1691
+ // extend the array will work.
1692
+ ASSERT(backing_store->length() > 0);
1693
+ }
1694
+
1695
+ bool HasCapacity(int elements) {
1696
+ int length = array_->length();
1697
+ int required_length = length_ + elements;
1698
+ return (length >= required_length);
1699
+ }
1700
+
1701
+ void EnsureCapacity(int elements) {
1702
+ int length = array_->length();
1703
+ int required_length = length_ + elements;
1704
+ if (length < required_length) {
1705
+ int new_length = length;
1706
+ do {
1707
+ new_length *= 2;
1708
+ } while (new_length < required_length);
1709
+ Handle<FixedArray> extended_array =
1710
+ Factory::NewFixedArrayWithHoles(new_length);
1711
+ array_->CopyTo(0, *extended_array, 0, length_);
1712
+ array_ = extended_array;
1713
+ }
1714
+ }
1715
+
1716
+ void Add(Object* value) {
1717
+ ASSERT(length_ < capacity());
1718
+ array_->set(length_, value);
1719
+ length_++;
1720
+ }
1721
+
1722
+ void Add(Smi* value) {
1723
+ ASSERT(length_ < capacity());
1724
+ array_->set(length_, value);
1725
+ length_++;
1726
+ }
1727
+
1728
+ Handle<FixedArray> array() {
1729
+ return array_;
1730
+ }
1731
+
1732
+ int length() {
1733
+ return length_;
1734
+ }
1735
+
1736
+ int capacity() {
1737
+ return array_->length();
1738
+ }
1739
+
1740
+ Handle<JSArray> ToJSArray() {
1741
+ Handle<JSArray> result_array = Factory::NewJSArrayWithElements(array_);
1742
+ result_array->set_length(Smi::FromInt(length_));
1743
+ return result_array;
1744
+ }
1745
+
1746
+ Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
1747
+ target_array->set_elements(*array_);
1748
+ target_array->set_length(Smi::FromInt(length_));
1749
+ return target_array;
1750
+ }
1751
+
1752
+ private:
1753
+ Handle<FixedArray> array_;
1754
+ int length_;
1755
+ };
1756
+
1757
+
1496
1758
  // Forward declarations.
1497
- static const int kStringBuilderConcatHelperLengthBits = 11;
1498
- static const int kStringBuilderConcatHelperPositionBits = 19;
1759
+ const int kStringBuilderConcatHelperLengthBits = 11;
1760
+ const int kStringBuilderConcatHelperPositionBits = 19;
1499
1761
 
1500
1762
  template <typename schar>
1501
1763
  static inline void StringBuilderConcatHelper(String*,
@@ -1503,15 +1765,19 @@ static inline void StringBuilderConcatHelper(String*,
1503
1765
  FixedArray*,
1504
1766
  int);
1505
1767
 
1506
- typedef BitField<int, 0, 11> StringBuilderSubstringLength;
1507
- typedef BitField<int, 11, 19> StringBuilderSubstringPosition;
1768
+ typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
1769
+ StringBuilderSubstringLength;
1770
+ typedef BitField<int,
1771
+ kStringBuilderConcatHelperLengthBits,
1772
+ kStringBuilderConcatHelperPositionBits>
1773
+ StringBuilderSubstringPosition;
1774
+
1508
1775
 
1509
1776
  class ReplacementStringBuilder {
1510
1777
  public:
1511
1778
  ReplacementStringBuilder(Handle<String> subject, int estimated_part_count)
1512
- : subject_(subject),
1513
- parts_(Factory::NewFixedArray(estimated_part_count)),
1514
- part_count_(0),
1779
+ : array_builder_(estimated_part_count),
1780
+ subject_(subject),
1515
1781
  character_count_(0),
1516
1782
  is_ascii_(subject->IsAsciiRepresentation()) {
1517
1783
  // Require a non-zero initial size. Ensures that doubling the size to
@@ -1519,38 +1785,33 @@ class ReplacementStringBuilder {
1519
1785
  ASSERT(estimated_part_count > 0);
1520
1786
  }
1521
1787
 
1522
- void EnsureCapacity(int elements) {
1523
- int length = parts_->length();
1524
- int required_length = part_count_ + elements;
1525
- if (length < required_length) {
1526
- int new_length = length;
1527
- do {
1528
- new_length *= 2;
1529
- } while (new_length < required_length);
1530
- Handle<FixedArray> extended_array =
1531
- Factory::NewFixedArray(new_length);
1532
- parts_->CopyTo(0, *extended_array, 0, part_count_);
1533
- parts_ = extended_array;
1534
- }
1535
- }
1536
-
1537
- void AddSubjectSlice(int from, int to) {
1788
+ static inline void AddSubjectSlice(FixedArrayBuilder* builder,
1789
+ int from,
1790
+ int to) {
1538
1791
  ASSERT(from >= 0);
1539
1792
  int length = to - from;
1540
1793
  ASSERT(length > 0);
1541
- // Can we encode the slice in 11 bits for length and 19 bits for
1542
- // start position - as used by StringBuilderConcatHelper?
1543
1794
  if (StringBuilderSubstringLength::is_valid(length) &&
1544
1795
  StringBuilderSubstringPosition::is_valid(from)) {
1545
1796
  int encoded_slice = StringBuilderSubstringLength::encode(length) |
1546
1797
  StringBuilderSubstringPosition::encode(from);
1547
- AddElement(Smi::FromInt(encoded_slice));
1798
+ builder->Add(Smi::FromInt(encoded_slice));
1548
1799
  } else {
1549
1800
  // Otherwise encode as two smis.
1550
- AddElement(Smi::FromInt(-length));
1551
- AddElement(Smi::FromInt(from));
1801
+ builder->Add(Smi::FromInt(-length));
1802
+ builder->Add(Smi::FromInt(from));
1552
1803
  }
1553
- IncrementCharacterCount(length);
1804
+ }
1805
+
1806
+
1807
+ void EnsureCapacity(int elements) {
1808
+ array_builder_.EnsureCapacity(elements);
1809
+ }
1810
+
1811
+
1812
+ void AddSubjectSlice(int from, int to) {
1813
+ AddSubjectSlice(&array_builder_, from, to);
1814
+ IncrementCharacterCount(to - from);
1554
1815
  }
1555
1816
 
1556
1817
 
@@ -1566,7 +1827,7 @@ class ReplacementStringBuilder {
1566
1827
 
1567
1828
 
1568
1829
  Handle<String> ToString() {
1569
- if (part_count_ == 0) {
1830
+ if (array_builder_.length() == 0) {
1570
1831
  return Factory::empty_string();
1571
1832
  }
1572
1833
 
@@ -1578,8 +1839,8 @@ class ReplacementStringBuilder {
1578
1839
  char* char_buffer = seq->GetChars();
1579
1840
  StringBuilderConcatHelper(*subject_,
1580
1841
  char_buffer,
1581
- *parts_,
1582
- part_count_);
1842
+ *array_builder_.array(),
1843
+ array_builder_.length());
1583
1844
  } else {
1584
1845
  // Non-ASCII.
1585
1846
  joined_string = NewRawTwoByteString(character_count_);
@@ -1588,8 +1849,8 @@ class ReplacementStringBuilder {
1588
1849
  uc16* char_buffer = seq->GetChars();
1589
1850
  StringBuilderConcatHelper(*subject_,
1590
1851
  char_buffer,
1591
- *parts_,
1592
- part_count_);
1852
+ *array_builder_.array(),
1853
+ array_builder_.length());
1593
1854
  }
1594
1855
  return joined_string;
1595
1856
  }
@@ -1602,8 +1863,14 @@ class ReplacementStringBuilder {
1602
1863
  character_count_ += by;
1603
1864
  }
1604
1865
 
1605
- private:
1866
+ Handle<JSArray> GetParts() {
1867
+ Handle<JSArray> result =
1868
+ Factory::NewJSArrayWithElements(array_builder_.array());
1869
+ result->set_length(Smi::FromInt(array_builder_.length()));
1870
+ return result;
1871
+ }
1606
1872
 
1873
+ private:
1607
1874
  Handle<String> NewRawAsciiString(int size) {
1608
1875
  CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String);
1609
1876
  }
@@ -1616,14 +1883,12 @@ class ReplacementStringBuilder {
1616
1883
 
1617
1884
  void AddElement(Object* element) {
1618
1885
  ASSERT(element->IsSmi() || element->IsString());
1619
- ASSERT(parts_->length() > part_count_);
1620
- parts_->set(part_count_, element);
1621
- part_count_++;
1886
+ ASSERT(array_builder_.capacity() > array_builder_.length());
1887
+ array_builder_.Add(element);
1622
1888
  }
1623
1889
 
1890
+ FixedArrayBuilder array_builder_;
1624
1891
  Handle<String> subject_;
1625
- Handle<FixedArray> parts_;
1626
- int part_count_;
1627
1892
  int character_count_;
1628
1893
  bool is_ascii_;
1629
1894
  };
@@ -2031,7 +2296,6 @@ static Object* Runtime_StringReplaceRegExpWithString(Arguments args) {
2031
2296
  }
2032
2297
 
2033
2298
 
2034
-
2035
2299
  // Cap on the maximal shift in the Boyer-Moore implementation. By setting a
2036
2300
  // limit, we can fix the size of tables.
2037
2301
  static const int kBMMaxShift = 0xff;
@@ -2077,10 +2341,23 @@ class BMGoodSuffixBuffers {
2077
2341
  static int bad_char_occurrence[kBMAlphabetSize];
2078
2342
  static BMGoodSuffixBuffers bmgs_buffers;
2079
2343
 
2344
+ // State of the string match tables.
2345
+ // SIMPLE: No usable content in the buffers.
2346
+ // BOYER_MOORE_HORSPOOL: The bad_char_occurences table has been populated.
2347
+ // BOYER_MOORE: The bmgs_buffers tables have also been populated.
2348
+ // Whenever starting with a new needle, one should call InitializeStringSearch
2349
+ // to determine which search strategy to use, and in the case of a long-needle
2350
+ // strategy, the call also initializes the algorithm to SIMPLE.
2351
+ enum StringSearchAlgorithm { SIMPLE_SEARCH, BOYER_MOORE_HORSPOOL, BOYER_MOORE };
2352
+ static StringSearchAlgorithm algorithm;
2353
+
2354
+
2080
2355
  // Compute the bad-char table for Boyer-Moore in the static buffer.
2081
2356
  template <typename pchar>
2082
- static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern,
2083
- int start) {
2357
+ static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern) {
2358
+ // Only preprocess at most kBMMaxShift last characters of pattern.
2359
+ int start = pattern.length() < kBMMaxShift ? 0
2360
+ : pattern.length() - kBMMaxShift;
2084
2361
  // Run forwards to populate bad_char_table, so that *last* instance
2085
2362
  // of character equivalence class is the one registered.
2086
2363
  // Notice: Doesn't include the last character.
@@ -2100,10 +2377,11 @@ static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern,
2100
2377
  }
2101
2378
  }
2102
2379
 
2380
+
2103
2381
  template <typename pchar>
2104
- static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern,
2105
- int start) {
2382
+ static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern) {
2106
2383
  int m = pattern.length();
2384
+ int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
2107
2385
  int len = m - start;
2108
2386
  // Compute Good Suffix tables.
2109
2387
  bmgs_buffers.init(m);
@@ -2150,6 +2428,7 @@ static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern,
2150
2428
  }
2151
2429
  }
2152
2430
 
2431
+
2153
2432
  template <typename schar, typename pchar>
2154
2433
  static inline int CharOccurrence(int char_code) {
2155
2434
  if (sizeof(schar) == 1) {
@@ -2164,6 +2443,7 @@ static inline int CharOccurrence(int char_code) {
2164
2443
  return bad_char_occurrence[char_code % kBMAlphabetSize];
2165
2444
  }
2166
2445
 
2446
+
2167
2447
  // Restricted simplified Boyer-Moore string matching.
2168
2448
  // Uses only the bad-shift table of Boyer-Moore and only uses it
2169
2449
  // for the character compared to the last character of the needle.
@@ -2172,14 +2452,13 @@ static int BoyerMooreHorspool(Vector<const schar> subject,
2172
2452
  Vector<const pchar> pattern,
2173
2453
  int start_index,
2174
2454
  bool* complete) {
2455
+ ASSERT(algorithm <= BOYER_MOORE_HORSPOOL);
2175
2456
  int n = subject.length();
2176
2457
  int m = pattern.length();
2177
- // Only preprocess at most kBMMaxShift last characters of pattern.
2178
- int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
2179
2458
 
2180
- BoyerMoorePopulateBadCharTable(pattern, start);
2459
+ int badness = -m;
2181
2460
 
2182
- int badness = -m; // How bad we are doing without a good-suffix table.
2461
+ // How bad we are doing without a good-suffix table.
2183
2462
  int idx; // No matches found prior to this index.
2184
2463
  pchar last_char = pattern[m - 1];
2185
2464
  int last_char_shift = m - 1 - CharOccurrence<schar, pchar>(last_char);
@@ -2224,13 +2503,12 @@ template <typename schar, typename pchar>
2224
2503
  static int BoyerMooreIndexOf(Vector<const schar> subject,
2225
2504
  Vector<const pchar> pattern,
2226
2505
  int idx) {
2506
+ ASSERT(algorithm <= BOYER_MOORE);
2227
2507
  int n = subject.length();
2228
2508
  int m = pattern.length();
2229
2509
  // Only preprocess at most kBMMaxShift last characters of pattern.
2230
2510
  int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
2231
2511
 
2232
- // Build the Good Suffix table and continue searching.
2233
- BoyerMoorePopulateGoodSuffixTable(pattern, start);
2234
2512
  pchar last_char = pattern[m - 1];
2235
2513
  // Continue search from i.
2236
2514
  while (idx <= n - m) {
@@ -2266,9 +2544,17 @@ static int BoyerMooreIndexOf(Vector<const schar> subject,
2266
2544
 
2267
2545
 
2268
2546
  template <typename schar>
2269
- static int SingleCharIndexOf(Vector<const schar> string,
2270
- schar pattern_char,
2271
- int start_index) {
2547
+ static inline int SingleCharIndexOf(Vector<const schar> string,
2548
+ schar pattern_char,
2549
+ int start_index) {
2550
+ if (sizeof(schar) == 1) {
2551
+ const schar* pos = reinterpret_cast<const schar*>(
2552
+ memchr(string.start() + start_index,
2553
+ pattern_char,
2554
+ string.length() - start_index));
2555
+ if (pos == NULL) return -1;
2556
+ return static_cast<int>(pos - string.start());
2557
+ }
2272
2558
  for (int i = start_index, n = string.length(); i < n; i++) {
2273
2559
  if (pattern_char == string[i]) {
2274
2560
  return i;
@@ -2277,6 +2563,20 @@ static int SingleCharIndexOf(Vector<const schar> string,
2277
2563
  return -1;
2278
2564
  }
2279
2565
 
2566
+
2567
+ template <typename schar>
2568
+ static int SingleCharLastIndexOf(Vector<const schar> string,
2569
+ schar pattern_char,
2570
+ int start_index) {
2571
+ for (int i = start_index; i >= 0; i--) {
2572
+ if (pattern_char == string[i]) {
2573
+ return i;
2574
+ }
2575
+ }
2576
+ return -1;
2577
+ }
2578
+
2579
+
2280
2580
  // Trivial string search for shorter strings.
2281
2581
  // On return, if "complete" is set to true, the return value is the
2282
2582
  // final result of searching for the patter in the subject.
@@ -2292,17 +2592,29 @@ static int SimpleIndexOf(Vector<const schar> subject,
2292
2592
  // done enough work we decide it's probably worth switching to a better
2293
2593
  // algorithm.
2294
2594
  int badness = -10 - (pattern.length() << 2);
2595
+
2295
2596
  // We know our pattern is at least 2 characters, we cache the first so
2296
2597
  // the common case of the first character not matching is faster.
2297
2598
  pchar pattern_first_char = pattern[0];
2298
-
2299
2599
  for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) {
2300
2600
  badness++;
2301
2601
  if (badness > 0) {
2302
2602
  *complete = false;
2303
2603
  return i;
2304
2604
  }
2305
- if (subject[i] != pattern_first_char) continue;
2605
+ if (sizeof(schar) == 1 && sizeof(pchar) == 1) {
2606
+ const schar* pos = reinterpret_cast<const schar*>(
2607
+ memchr(subject.start() + i,
2608
+ pattern_first_char,
2609
+ n - i + 1));
2610
+ if (pos == NULL) {
2611
+ *complete = true;
2612
+ return -1;
2613
+ }
2614
+ i = static_cast<int>(pos - subject.start());
2615
+ } else {
2616
+ if (subject[i] != pattern_first_char) continue;
2617
+ }
2306
2618
  int j = 1;
2307
2619
  do {
2308
2620
  if (pattern[j] != subject[i+j]) {
@@ -2327,7 +2639,16 @@ static int SimpleIndexOf(Vector<const schar> subject,
2327
2639
  int idx) {
2328
2640
  pchar pattern_first_char = pattern[0];
2329
2641
  for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) {
2330
- if (subject[i] != pattern_first_char) continue;
2642
+ if (sizeof(schar) == 1 && sizeof(pchar) == 1) {
2643
+ const schar* pos = reinterpret_cast<const schar*>(
2644
+ memchr(subject.start() + i,
2645
+ pattern_first_char,
2646
+ n - i + 1));
2647
+ if (pos == NULL) return -1;
2648
+ i = static_cast<int>(pos - subject.start());
2649
+ } else {
2650
+ if (subject[i] != pattern_first_char) continue;
2651
+ }
2331
2652
  int j = 1;
2332
2653
  do {
2333
2654
  if (pattern[j] != subject[i+j]) {
@@ -2343,39 +2664,84 @@ static int SimpleIndexOf(Vector<const schar> subject,
2343
2664
  }
2344
2665
 
2345
2666
 
2346
- // Dispatch to different algorithms.
2347
- template <typename schar, typename pchar>
2348
- static int StringMatchStrategy(Vector<const schar> sub,
2349
- Vector<const pchar> pat,
2350
- int start_index) {
2351
- ASSERT(pat.length() > 1);
2667
+ // Strategy for searching for a string in another string.
2668
+ enum StringSearchStrategy { SEARCH_FAIL, SEARCH_SHORT, SEARCH_LONG };
2352
2669
 
2670
+
2671
+ template <typename pchar>
2672
+ static inline StringSearchStrategy InitializeStringSearch(
2673
+ Vector<const pchar> pat, bool ascii_subject) {
2674
+ ASSERT(pat.length() > 1);
2353
2675
  // We have an ASCII haystack and a non-ASCII needle. Check if there
2354
2676
  // really is a non-ASCII character in the needle and bail out if there
2355
2677
  // is.
2356
- if (sizeof(pchar) > 1 && sizeof(schar) == 1) {
2678
+ if (ascii_subject && sizeof(pchar) > 1) {
2357
2679
  for (int i = 0; i < pat.length(); i++) {
2358
2680
  uc16 c = pat[i];
2359
2681
  if (c > String::kMaxAsciiCharCode) {
2360
- return -1;
2682
+ return SEARCH_FAIL;
2361
2683
  }
2362
2684
  }
2363
2685
  }
2364
2686
  if (pat.length() < kBMMinPatternLength) {
2365
- // We don't believe fancy searching can ever be more efficient.
2366
- // The max shift of Boyer-Moore on a pattern of this length does
2367
- // not compensate for the overhead.
2368
- return SimpleIndexOf(sub, pat, start_index);
2687
+ return SEARCH_SHORT;
2369
2688
  }
2689
+ algorithm = SIMPLE_SEARCH;
2690
+ return SEARCH_LONG;
2691
+ }
2692
+
2693
+
2694
+ // Dispatch long needle searches to different algorithms.
2695
+ template <typename schar, typename pchar>
2696
+ static int ComplexIndexOf(Vector<const schar> sub,
2697
+ Vector<const pchar> pat,
2698
+ int start_index) {
2699
+ ASSERT(pat.length() >= kBMMinPatternLength);
2370
2700
  // Try algorithms in order of increasing setup cost and expected performance.
2371
2701
  bool complete;
2372
- int idx = SimpleIndexOf(sub, pat, start_index, &complete);
2373
- if (complete) return idx;
2374
- idx = BoyerMooreHorspool(sub, pat, idx, &complete);
2375
- if (complete) return idx;
2376
- return BoyerMooreIndexOf(sub, pat, idx);
2702
+ int idx = start_index;
2703
+ switch (algorithm) {
2704
+ case SIMPLE_SEARCH:
2705
+ idx = SimpleIndexOf(sub, pat, idx, &complete);
2706
+ if (complete) return idx;
2707
+ BoyerMoorePopulateBadCharTable(pat);
2708
+ algorithm = BOYER_MOORE_HORSPOOL;
2709
+ // FALLTHROUGH.
2710
+ case BOYER_MOORE_HORSPOOL:
2711
+ idx = BoyerMooreHorspool(sub, pat, idx, &complete);
2712
+ if (complete) return idx;
2713
+ // Build the Good Suffix table and continue searching.
2714
+ BoyerMoorePopulateGoodSuffixTable(pat);
2715
+ algorithm = BOYER_MOORE;
2716
+ // FALLTHROUGH.
2717
+ case BOYER_MOORE:
2718
+ return BoyerMooreIndexOf(sub, pat, idx);
2719
+ }
2720
+ UNREACHABLE();
2721
+ return -1;
2722
+ }
2723
+
2724
+
2725
+ // Dispatch to different search strategies for a single search.
2726
+ // If searching multiple times on the same needle, the search
2727
+ // strategy should only be computed once and then dispatch to different
2728
+ // loops.
2729
+ template <typename schar, typename pchar>
2730
+ static int StringSearch(Vector<const schar> sub,
2731
+ Vector<const pchar> pat,
2732
+ int start_index) {
2733
+ bool ascii_subject = (sizeof(schar) == 1);
2734
+ StringSearchStrategy strategy = InitializeStringSearch(pat, ascii_subject);
2735
+ switch (strategy) {
2736
+ case SEARCH_FAIL: return -1;
2737
+ case SEARCH_SHORT: return SimpleIndexOf(sub, pat, start_index);
2738
+ case SEARCH_LONG: return ComplexIndexOf(sub, pat, start_index);
2739
+ }
2740
+ UNREACHABLE();
2741
+ return -1;
2377
2742
  }
2378
2743
 
2744
+
2379
2745
  // Perform string match of pattern on subject, starting at start index.
2380
2746
  // Caller must ensure that 0 <= start_index <= sub->length(),
2381
2747
  // and should check that pat->length() + start_index <= sub->length()
@@ -2394,6 +2760,7 @@ int Runtime::StringMatch(Handle<String> sub,
2394
2760
  if (!sub->IsFlat()) {
2395
2761
  FlattenString(sub);
2396
2762
  }
2763
+
2397
2764
  // Searching for one specific character is common. For one
2398
2765
  // character patterns linear search is necessary, so any smart
2399
2766
  // algorithm is unnecessary overhead.
@@ -2427,15 +2794,15 @@ int Runtime::StringMatch(Handle<String> sub,
2427
2794
  if (pat->IsAsciiRepresentation()) {
2428
2795
  Vector<const char> pat_vector = pat->ToAsciiVector();
2429
2796
  if (sub->IsAsciiRepresentation()) {
2430
- return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index);
2797
+ return StringSearch(sub->ToAsciiVector(), pat_vector, start_index);
2431
2798
  }
2432
- return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index);
2799
+ return StringSearch(sub->ToUC16Vector(), pat_vector, start_index);
2433
2800
  }
2434
2801
  Vector<const uc16> pat_vector = pat->ToUC16Vector();
2435
2802
  if (sub->IsAsciiRepresentation()) {
2436
- return StringMatchStrategy(sub->ToAsciiVector(), pat_vector, start_index);
2803
+ return StringSearch(sub->ToAsciiVector(), pat_vector, start_index);
2437
2804
  }
2438
- return StringMatchStrategy(sub->ToUC16Vector(), pat_vector, start_index);
2805
+ return StringSearch(sub->ToUC16Vector(), pat_vector, start_index);
2439
2806
  }
2440
2807
 
2441
2808
 
@@ -2456,47 +2823,123 @@ static Object* Runtime_StringIndexOf(Arguments args) {
2456
2823
  }
2457
2824
 
2458
2825
 
2826
+ template <typename schar, typename pchar>
2827
+ static int StringMatchBackwards(Vector<const schar> sub,
2828
+ Vector<const pchar> pat,
2829
+ int idx) {
2830
+ ASSERT(pat.length() >= 1);
2831
+ ASSERT(idx + pat.length() <= sub.length());
2832
+
2833
+ if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
2834
+ for (int i = 0; i < pat.length(); i++) {
2835
+ uc16 c = pat[i];
2836
+ if (c > String::kMaxAsciiCharCode) {
2837
+ return -1;
2838
+ }
2839
+ }
2840
+ }
2841
+
2842
+ pchar pattern_first_char = pat[0];
2843
+ for (int i = idx; i >= 0; i--) {
2844
+ if (sub[i] != pattern_first_char) continue;
2845
+ int j = 1;
2846
+ while (j < pat.length()) {
2847
+ if (pat[j] != sub[i+j]) {
2848
+ break;
2849
+ }
2850
+ j++;
2851
+ }
2852
+ if (j == pat.length()) {
2853
+ return i;
2854
+ }
2855
+ }
2856
+ return -1;
2857
+ }
2858
+
2459
2859
  static Object* Runtime_StringLastIndexOf(Arguments args) {
2460
- NoHandleAllocation ha;
2860
+ HandleScope scope; // create a new handle scope
2461
2861
  ASSERT(args.length() == 3);
2462
2862
 
2463
- CONVERT_CHECKED(String, sub, args[0]);
2464
- CONVERT_CHECKED(String, pat, args[1]);
2465
- Object* index = args[2];
2466
-
2467
- sub->TryFlattenIfNotFlat();
2468
- pat->TryFlattenIfNotFlat();
2863
+ CONVERT_ARG_CHECKED(String, sub, 0);
2864
+ CONVERT_ARG_CHECKED(String, pat, 1);
2469
2865
 
2866
+ Object* index = args[2];
2470
2867
  uint32_t start_index;
2471
2868
  if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
2472
2869
 
2473
- uint32_t pattern_length = pat->length();
2870
+ uint32_t pat_length = pat->length();
2474
2871
  uint32_t sub_length = sub->length();
2475
2872
 
2476
- if (start_index + pattern_length > sub_length) {
2477
- start_index = sub_length - pattern_length;
2873
+ if (start_index + pat_length > sub_length) {
2874
+ start_index = sub_length - pat_length;
2478
2875
  }
2479
2876
 
2480
- for (int i = start_index; i >= 0; i--) {
2481
- bool found = true;
2482
- for (uint32_t j = 0; j < pattern_length; j++) {
2483
- if (sub->Get(i + j) != pat->Get(j)) {
2484
- found = false;
2485
- break;
2877
+ if (pat_length == 0) {
2878
+ return Smi::FromInt(start_index);
2879
+ }
2880
+
2881
+ if (!sub->IsFlat()) {
2882
+ FlattenString(sub);
2883
+ }
2884
+
2885
+ if (pat_length == 1) {
2886
+ AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
2887
+ if (sub->IsAsciiRepresentation()) {
2888
+ uc16 pchar = pat->Get(0);
2889
+ if (pchar > String::kMaxAsciiCharCode) {
2890
+ return Smi::FromInt(-1);
2486
2891
  }
2892
+ return Smi::FromInt(SingleCharLastIndexOf(sub->ToAsciiVector(),
2893
+ static_cast<char>(pat->Get(0)),
2894
+ start_index));
2895
+ } else {
2896
+ return Smi::FromInt(SingleCharLastIndexOf(sub->ToUC16Vector(),
2897
+ pat->Get(0),
2898
+ start_index));
2487
2899
  }
2488
- if (found) return Smi::FromInt(i);
2489
2900
  }
2490
2901
 
2491
- return Smi::FromInt(-1);
2492
- }
2902
+ if (!pat->IsFlat()) {
2903
+ FlattenString(pat);
2904
+ }
2493
2905
 
2906
+ AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
2494
2907
 
2495
- static Object* Runtime_StringLocaleCompare(Arguments args) {
2496
- NoHandleAllocation ha;
2497
- ASSERT(args.length() == 2);
2908
+ int position = -1;
2498
2909
 
2499
- CONVERT_CHECKED(String, str1, args[0]);
2910
+ if (pat->IsAsciiRepresentation()) {
2911
+ Vector<const char> pat_vector = pat->ToAsciiVector();
2912
+ if (sub->IsAsciiRepresentation()) {
2913
+ position = StringMatchBackwards(sub->ToAsciiVector(),
2914
+ pat_vector,
2915
+ start_index);
2916
+ } else {
2917
+ position = StringMatchBackwards(sub->ToUC16Vector(),
2918
+ pat_vector,
2919
+ start_index);
2920
+ }
2921
+ } else {
2922
+ Vector<const uc16> pat_vector = pat->ToUC16Vector();
2923
+ if (sub->IsAsciiRepresentation()) {
2924
+ position = StringMatchBackwards(sub->ToAsciiVector(),
2925
+ pat_vector,
2926
+ start_index);
2927
+ } else {
2928
+ position = StringMatchBackwards(sub->ToUC16Vector(),
2929
+ pat_vector,
2930
+ start_index);
2931
+ }
2932
+ }
2933
+
2934
+ return Smi::FromInt(position);
2935
+ }
2936
+
2937
+
2938
+ static Object* Runtime_StringLocaleCompare(Arguments args) {
2939
+ NoHandleAllocation ha;
2940
+ ASSERT(args.length() == 2);
2941
+
2942
+ CONVERT_CHECKED(String, str1, args[0]);
2500
2943
  CONVERT_CHECKED(String, str2, args[1]);
2501
2944
 
2502
2945
  if (str1 == str2) return Smi::FromInt(0); // Equal.
@@ -2519,8 +2962,8 @@ static Object* Runtime_StringLocaleCompare(Arguments args) {
2519
2962
  int d = str1->Get(0) - str2->Get(0);
2520
2963
  if (d != 0) return Smi::FromInt(d);
2521
2964
 
2522
- str1->TryFlattenIfNotFlat();
2523
- str2->TryFlattenIfNotFlat();
2965
+ str1->TryFlatten();
2966
+ str2->TryFlatten();
2524
2967
 
2525
2968
  static StringInputBuffer buf1;
2526
2969
  static StringInputBuffer buf2;
@@ -2616,6 +3059,476 @@ static Object* Runtime_StringMatch(Arguments args) {
2616
3059
  }
2617
3060
 
2618
3061
 
3062
+ // Two smis before and after the match, for very long strings.
3063
+ const int kMaxBuilderEntriesPerRegExpMatch = 5;
3064
+
3065
+
3066
+ static void SetLastMatchInfoNoCaptures(Handle<String> subject,
3067
+ Handle<JSArray> last_match_info,
3068
+ int match_start,
3069
+ int match_end) {
3070
+ // Fill last_match_info with a single capture.
3071
+ last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead);
3072
+ AssertNoAllocation no_gc;
3073
+ FixedArray* elements = FixedArray::cast(last_match_info->elements());
3074
+ RegExpImpl::SetLastCaptureCount(elements, 2);
3075
+ RegExpImpl::SetLastInput(elements, *subject);
3076
+ RegExpImpl::SetLastSubject(elements, *subject);
3077
+ RegExpImpl::SetCapture(elements, 0, match_start);
3078
+ RegExpImpl::SetCapture(elements, 1, match_end);
3079
+ }
3080
+
3081
+
3082
+ template <typename schar>
3083
+ static bool SearchCharMultiple(Vector<schar> subject,
3084
+ String* pattern,
3085
+ schar pattern_char,
3086
+ FixedArrayBuilder* builder,
3087
+ int* match_pos) {
3088
+ // Position of last match.
3089
+ int pos = *match_pos;
3090
+ int subject_length = subject.length();
3091
+ while (pos < subject_length) {
3092
+ int match_end = pos + 1;
3093
+ if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
3094
+ *match_pos = pos;
3095
+ return false;
3096
+ }
3097
+ int new_pos = SingleCharIndexOf(subject, pattern_char, match_end);
3098
+ if (new_pos >= 0) {
3099
+ // Match has been found.
3100
+ if (new_pos > match_end) {
3101
+ ReplacementStringBuilder::AddSubjectSlice(builder, match_end, new_pos);
3102
+ }
3103
+ pos = new_pos;
3104
+ builder->Add(pattern);
3105
+ } else {
3106
+ break;
3107
+ }
3108
+ }
3109
+ if (pos + 1 < subject_length) {
3110
+ ReplacementStringBuilder::AddSubjectSlice(builder, pos + 1, subject_length);
3111
+ }
3112
+ *match_pos = pos;
3113
+ return true;
3114
+ }
3115
+
3116
+
3117
+ static bool SearchCharMultiple(Handle<String> subject,
3118
+ Handle<String> pattern,
3119
+ Handle<JSArray> last_match_info,
3120
+ FixedArrayBuilder* builder) {
3121
+ ASSERT(subject->IsFlat());
3122
+ ASSERT_EQ(1, pattern->length());
3123
+ uc16 pattern_char = pattern->Get(0);
3124
+ // Treating position before first as initial "previous match position".
3125
+ int match_pos = -1;
3126
+
3127
+ for (;;) { // Break when search complete.
3128
+ builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3129
+ AssertNoAllocation no_gc;
3130
+ if (subject->IsAsciiRepresentation()) {
3131
+ if (pattern_char > String::kMaxAsciiCharCode) {
3132
+ break;
3133
+ }
3134
+ Vector<const char> subject_vector = subject->ToAsciiVector();
3135
+ char pattern_ascii_char = static_cast<char>(pattern_char);
3136
+ bool complete = SearchCharMultiple<const char>(subject_vector,
3137
+ *pattern,
3138
+ pattern_ascii_char,
3139
+ builder,
3140
+ &match_pos);
3141
+ if (complete) break;
3142
+ } else {
3143
+ Vector<const uc16> subject_vector = subject->ToUC16Vector();
3144
+ bool complete = SearchCharMultiple<const uc16>(subject_vector,
3145
+ *pattern,
3146
+ pattern_char,
3147
+ builder,
3148
+ &match_pos);
3149
+ if (complete) break;
3150
+ }
3151
+ }
3152
+
3153
+ if (match_pos >= 0) {
3154
+ SetLastMatchInfoNoCaptures(subject,
3155
+ last_match_info,
3156
+ match_pos,
3157
+ match_pos + 1);
3158
+ return true;
3159
+ }
3160
+ return false; // No matches at all.
3161
+ }
3162
+
3163
+
3164
+ template <typename schar, typename pchar>
3165
+ static bool SearchStringMultiple(Vector<schar> subject,
3166
+ String* pattern,
3167
+ Vector<pchar> pattern_string,
3168
+ FixedArrayBuilder* builder,
3169
+ int* match_pos) {
3170
+ int pos = *match_pos;
3171
+ int subject_length = subject.length();
3172
+ int pattern_length = pattern_string.length();
3173
+ int max_search_start = subject_length - pattern_length;
3174
+ bool is_ascii = (sizeof(schar) == 1);
3175
+ StringSearchStrategy strategy =
3176
+ InitializeStringSearch(pattern_string, is_ascii);
3177
+ switch (strategy) {
3178
+ case SEARCH_FAIL: break;
3179
+ case SEARCH_SHORT:
3180
+ while (pos <= max_search_start) {
3181
+ if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
3182
+ *match_pos = pos;
3183
+ return false;
3184
+ }
3185
+ // Position of end of previous match.
3186
+ int match_end = pos + pattern_length;
3187
+ int new_pos = SimpleIndexOf(subject, pattern_string, match_end);
3188
+ if (new_pos >= 0) {
3189
+ // A match.
3190
+ if (new_pos > match_end) {
3191
+ ReplacementStringBuilder::AddSubjectSlice(builder,
3192
+ match_end,
3193
+ new_pos);
3194
+ }
3195
+ pos = new_pos;
3196
+ builder->Add(pattern);
3197
+ } else {
3198
+ break;
3199
+ }
3200
+ }
3201
+ break;
3202
+ case SEARCH_LONG:
3203
+ while (pos <= max_search_start) {
3204
+ if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
3205
+ *match_pos = pos;
3206
+ return false;
3207
+ }
3208
+ int match_end = pos + pattern_length;
3209
+ int new_pos = ComplexIndexOf(subject, pattern_string, match_end);
3210
+ if (new_pos >= 0) {
3211
+ // A match has been found.
3212
+ if (new_pos > match_end) {
3213
+ ReplacementStringBuilder::AddSubjectSlice(builder,
3214
+ match_end,
3215
+ new_pos);
3216
+ }
3217
+ pos = new_pos;
3218
+ builder->Add(pattern);
3219
+ } else {
3220
+ break;
3221
+ }
3222
+ }
3223
+ break;
3224
+ }
3225
+ if (pos < max_search_start) {
3226
+ ReplacementStringBuilder::AddSubjectSlice(builder,
3227
+ pos + pattern_length,
3228
+ subject_length);
3229
+ }
3230
+ *match_pos = pos;
3231
+ return true;
3232
+ }
3233
+
3234
+
3235
+ static bool SearchStringMultiple(Handle<String> subject,
3236
+ Handle<String> pattern,
3237
+ Handle<JSArray> last_match_info,
3238
+ FixedArrayBuilder* builder) {
3239
+ ASSERT(subject->IsFlat());
3240
+ ASSERT(pattern->IsFlat());
3241
+ ASSERT(pattern->length() > 1);
3242
+
3243
+ // Treating as if a previous match was before first character.
3244
+ int match_pos = -pattern->length();
3245
+
3246
+ for (;;) { // Break when search complete.
3247
+ builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3248
+ AssertNoAllocation no_gc;
3249
+ if (subject->IsAsciiRepresentation()) {
3250
+ Vector<const char> subject_vector = subject->ToAsciiVector();
3251
+ if (pattern->IsAsciiRepresentation()) {
3252
+ if (SearchStringMultiple(subject_vector,
3253
+ *pattern,
3254
+ pattern->ToAsciiVector(),
3255
+ builder,
3256
+ &match_pos)) break;
3257
+ } else {
3258
+ if (SearchStringMultiple(subject_vector,
3259
+ *pattern,
3260
+ pattern->ToUC16Vector(),
3261
+ builder,
3262
+ &match_pos)) break;
3263
+ }
3264
+ } else {
3265
+ Vector<const uc16> subject_vector = subject->ToUC16Vector();
3266
+ if (pattern->IsAsciiRepresentation()) {
3267
+ if (SearchStringMultiple(subject_vector,
3268
+ *pattern,
3269
+ pattern->ToAsciiVector(),
3270
+ builder,
3271
+ &match_pos)) break;
3272
+ } else {
3273
+ if (SearchStringMultiple(subject_vector,
3274
+ *pattern,
3275
+ pattern->ToUC16Vector(),
3276
+ builder,
3277
+ &match_pos)) break;
3278
+ }
3279
+ }
3280
+ }
3281
+
3282
+ if (match_pos >= 0) {
3283
+ SetLastMatchInfoNoCaptures(subject,
3284
+ last_match_info,
3285
+ match_pos,
3286
+ match_pos + pattern->length());
3287
+ return true;
3288
+ }
3289
+ return false; // No matches at all.
3290
+ }
3291
+
3292
+
3293
+ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
3294
+ Handle<String> subject,
3295
+ Handle<JSRegExp> regexp,
3296
+ Handle<JSArray> last_match_array,
3297
+ FixedArrayBuilder* builder) {
3298
+ ASSERT(subject->IsFlat());
3299
+ int match_start = -1;
3300
+ int match_end = 0;
3301
+ int pos = 0;
3302
+ int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
3303
+ if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
3304
+
3305
+ OffsetsVector registers(required_registers);
3306
+ Vector<int> register_vector(registers.vector(), registers.length());
3307
+ int subject_length = subject->length();
3308
+
3309
+ for (;;) { // Break on failure, return on exception.
3310
+ RegExpImpl::IrregexpResult result =
3311
+ RegExpImpl::IrregexpExecOnce(regexp,
3312
+ subject,
3313
+ pos,
3314
+ register_vector);
3315
+ if (result == RegExpImpl::RE_SUCCESS) {
3316
+ match_start = register_vector[0];
3317
+ builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3318
+ if (match_end < match_start) {
3319
+ ReplacementStringBuilder::AddSubjectSlice(builder,
3320
+ match_end,
3321
+ match_start);
3322
+ }
3323
+ match_end = register_vector[1];
3324
+ HandleScope loop_scope;
3325
+ builder->Add(*Factory::NewSubString(subject, match_start, match_end));
3326
+ if (match_start != match_end) {
3327
+ pos = match_end;
3328
+ } else {
3329
+ pos = match_end + 1;
3330
+ if (pos > subject_length) break;
3331
+ }
3332
+ } else if (result == RegExpImpl::RE_FAILURE) {
3333
+ break;
3334
+ } else {
3335
+ ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
3336
+ return result;
3337
+ }
3338
+ }
3339
+
3340
+ if (match_start >= 0) {
3341
+ if (match_end < subject_length) {
3342
+ ReplacementStringBuilder::AddSubjectSlice(builder,
3343
+ match_end,
3344
+ subject_length);
3345
+ }
3346
+ SetLastMatchInfoNoCaptures(subject,
3347
+ last_match_array,
3348
+ match_start,
3349
+ match_end);
3350
+ return RegExpImpl::RE_SUCCESS;
3351
+ } else {
3352
+ return RegExpImpl::RE_FAILURE; // No matches at all.
3353
+ }
3354
+ }
3355
+
3356
+
3357
+ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
3358
+ Handle<String> subject,
3359
+ Handle<JSRegExp> regexp,
3360
+ Handle<JSArray> last_match_array,
3361
+ FixedArrayBuilder* builder) {
3362
+
3363
+ ASSERT(subject->IsFlat());
3364
+ int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
3365
+ if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
3366
+
3367
+ OffsetsVector registers(required_registers);
3368
+ Vector<int> register_vector(registers.vector(), registers.length());
3369
+
3370
+ RegExpImpl::IrregexpResult result =
3371
+ RegExpImpl::IrregexpExecOnce(regexp,
3372
+ subject,
3373
+ 0,
3374
+ register_vector);
3375
+
3376
+ int capture_count = regexp->CaptureCount();
3377
+ int subject_length = subject->length();
3378
+
3379
+ // Position to search from.
3380
+ int pos = 0;
3381
+ // End of previous match. Differs from pos if match was empty.
3382
+ int match_end = 0;
3383
+ if (result == RegExpImpl::RE_SUCCESS) {
3384
+ // Need to keep a copy of the previous match for creating last_match_info
3385
+ // at the end, so we have two vectors that we swap between.
3386
+ OffsetsVector registers2(required_registers);
3387
+ Vector<int> prev_register_vector(registers2.vector(), registers2.length());
3388
+
3389
+ do {
3390
+ int match_start = register_vector[0];
3391
+ builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3392
+ if (match_end < match_start) {
3393
+ ReplacementStringBuilder::AddSubjectSlice(builder,
3394
+ match_end,
3395
+ match_start);
3396
+ }
3397
+ match_end = register_vector[1];
3398
+
3399
+ {
3400
+ // Avoid accumulating new handles inside loop.
3401
+ HandleScope temp_scope;
3402
+ // Arguments array to replace function is match, captures, index and
3403
+ // subject, i.e., 3 + capture count in total.
3404
+ Handle<FixedArray> elements = Factory::NewFixedArray(3 + capture_count);
3405
+ elements->set(0, *Factory::NewSubString(subject,
3406
+ match_start,
3407
+ match_end));
3408
+ for (int i = 1; i <= capture_count; i++) {
3409
+ int start = register_vector[i * 2];
3410
+ if (start >= 0) {
3411
+ int end = register_vector[i * 2 + 1];
3412
+ ASSERT(start <= end);
3413
+ Handle<String> substring = Factory::NewSubString(subject,
3414
+ start,
3415
+ end);
3416
+ elements->set(i, *substring);
3417
+ } else {
3418
+ ASSERT(register_vector[i * 2 + 1] < 0);
3419
+ elements->set(i, Heap::undefined_value());
3420
+ }
3421
+ }
3422
+ elements->set(capture_count + 1, Smi::FromInt(match_start));
3423
+ elements->set(capture_count + 2, *subject);
3424
+ builder->Add(*Factory::NewJSArrayWithElements(elements));
3425
+ }
3426
+ // Swap register vectors, so the last successful match is in
3427
+ // prev_register_vector.
3428
+ Vector<int> tmp = prev_register_vector;
3429
+ prev_register_vector = register_vector;
3430
+ register_vector = tmp;
3431
+
3432
+ if (match_end > match_start) {
3433
+ pos = match_end;
3434
+ } else {
3435
+ pos = match_end + 1;
3436
+ if (pos > subject_length) {
3437
+ break;
3438
+ }
3439
+ }
3440
+
3441
+ result = RegExpImpl::IrregexpExecOnce(regexp,
3442
+ subject,
3443
+ pos,
3444
+ register_vector);
3445
+ } while (result == RegExpImpl::RE_SUCCESS);
3446
+
3447
+ if (result != RegExpImpl::RE_EXCEPTION) {
3448
+ // Finished matching, with at least one match.
3449
+ if (match_end < subject_length) {
3450
+ ReplacementStringBuilder::AddSubjectSlice(builder,
3451
+ match_end,
3452
+ subject_length);
3453
+ }
3454
+
3455
+ int last_match_capture_count = (capture_count + 1) * 2;
3456
+ int last_match_array_size =
3457
+ last_match_capture_count + RegExpImpl::kLastMatchOverhead;
3458
+ last_match_array->EnsureSize(last_match_array_size);
3459
+ AssertNoAllocation no_gc;
3460
+ FixedArray* elements = FixedArray::cast(last_match_array->elements());
3461
+ RegExpImpl::SetLastCaptureCount(elements, last_match_capture_count);
3462
+ RegExpImpl::SetLastSubject(elements, *subject);
3463
+ RegExpImpl::SetLastInput(elements, *subject);
3464
+ for (int i = 0; i < last_match_capture_count; i++) {
3465
+ RegExpImpl::SetCapture(elements, i, prev_register_vector[i]);
3466
+ }
3467
+ return RegExpImpl::RE_SUCCESS;
3468
+ }
3469
+ }
3470
+ // No matches at all, return failure or exception result directly.
3471
+ return result;
3472
+ }
3473
+
3474
+
3475
+ static Object* Runtime_RegExpExecMultiple(Arguments args) {
3476
+ ASSERT(args.length() == 4);
3477
+ HandleScope handles;
3478
+
3479
+ CONVERT_ARG_CHECKED(String, subject, 1);
3480
+ if (!subject->IsFlat()) { FlattenString(subject); }
3481
+ CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
3482
+ CONVERT_ARG_CHECKED(JSArray, last_match_info, 2);
3483
+ CONVERT_ARG_CHECKED(JSArray, result_array, 3);
3484
+
3485
+ ASSERT(last_match_info->HasFastElements());
3486
+ ASSERT(regexp->GetFlags().is_global());
3487
+ Handle<FixedArray> result_elements;
3488
+ if (result_array->HasFastElements()) {
3489
+ result_elements =
3490
+ Handle<FixedArray>(FixedArray::cast(result_array->elements()));
3491
+ } else {
3492
+ result_elements = Factory::NewFixedArrayWithHoles(16);
3493
+ }
3494
+ FixedArrayBuilder builder(result_elements);
3495
+
3496
+ if (regexp->TypeTag() == JSRegExp::ATOM) {
3497
+ Handle<String> pattern(
3498
+ String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex)));
3499
+ int pattern_length = pattern->length();
3500
+ if (pattern_length == 1) {
3501
+ if (SearchCharMultiple(subject, pattern, last_match_info, &builder)) {
3502
+ return *builder.ToJSArray(result_array);
3503
+ }
3504
+ return Heap::null_value();
3505
+ }
3506
+
3507
+ if (!pattern->IsFlat()) FlattenString(pattern);
3508
+ if (SearchStringMultiple(subject, pattern, last_match_info, &builder)) {
3509
+ return *builder.ToJSArray(result_array);
3510
+ }
3511
+ return Heap::null_value();
3512
+ }
3513
+
3514
+ ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
3515
+
3516
+ RegExpImpl::IrregexpResult result;
3517
+ if (regexp->CaptureCount() == 0) {
3518
+ result = SearchRegExpNoCaptureMultiple(subject,
3519
+ regexp,
3520
+ last_match_info,
3521
+ &builder);
3522
+ } else {
3523
+ result = SearchRegExpMultiple(subject, regexp, last_match_info, &builder);
3524
+ }
3525
+ if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
3526
+ if (result == RegExpImpl::RE_FAILURE) return Heap::null_value();
3527
+ ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
3528
+ return Failure::Exception();
3529
+ }
3530
+
3531
+
2619
3532
  static Object* Runtime_NumberToRadixString(Arguments args) {
2620
3533
  NoHandleAllocation ha;
2621
3534
  ASSERT(args.length() == 2);
@@ -2729,7 +3642,7 @@ static Object* Runtime_NumberToPrecision(Arguments args) {
2729
3642
  // string->Get(index).
2730
3643
  static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
2731
3644
  if (index < static_cast<uint32_t>(string->length())) {
2732
- string->TryFlattenIfNotFlat();
3645
+ string->TryFlatten();
2733
3646
  return LookupSingleCharacterStringFromCode(
2734
3647
  string->Get(index));
2735
3648
  }
@@ -2757,6 +3670,11 @@ Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) {
2757
3670
  return prototype->GetElement(index);
2758
3671
  }
2759
3672
 
3673
+ return GetElement(object, index);
3674
+ }
3675
+
3676
+
3677
+ Object* Runtime::GetElement(Handle<Object> object, uint32_t index) {
2760
3678
  return object->GetElement(index);
2761
3679
  }
2762
3680
 
@@ -2845,7 +3763,7 @@ static Object* Runtime_KeyedGetProperty(Arguments args) {
2845
3763
  // Lookup cache miss. Perform lookup and update the cache if appropriate.
2846
3764
  LookupResult result;
2847
3765
  receiver->LocalLookup(key, &result);
2848
- if (result.IsProperty() && result.IsLoaded() && result.type() == FIELD) {
3766
+ if (result.IsProperty() && result.type() == FIELD) {
2849
3767
  int offset = result.GetFieldIndex();
2850
3768
  KeyedLookupCache::Update(receiver_map, key, offset);
2851
3769
  return receiver->FastPropertyAt(offset);
@@ -2878,6 +3796,67 @@ static Object* Runtime_KeyedGetProperty(Arguments args) {
2878
3796
  }
2879
3797
 
2880
3798
 
3799
+ static Object* Runtime_DefineOrRedefineAccessorProperty(Arguments args) {
3800
+ ASSERT(args.length() == 5);
3801
+ HandleScope scope;
3802
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
3803
+ CONVERT_CHECKED(String, name, args[1]);
3804
+ CONVERT_CHECKED(Smi, flag_setter, args[2]);
3805
+ CONVERT_CHECKED(JSFunction, fun, args[3]);
3806
+ CONVERT_CHECKED(Smi, flag_attr, args[4]);
3807
+ int unchecked = flag_attr->value();
3808
+ RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
3809
+ RUNTIME_ASSERT(!obj->IsNull());
3810
+ LookupResult result;
3811
+ obj->LocalLookupRealNamedProperty(name, &result);
3812
+
3813
+ PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
3814
+ // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
3815
+ // delete it to avoid running into trouble in DefineAccessor, which
3816
+ // handles this incorrectly if the property is readonly (does nothing)
3817
+ if (result.IsProperty() &&
3818
+ (result.type() == FIELD || result.type() == NORMAL
3819
+ || result.type() == CONSTANT_FUNCTION)) {
3820
+ obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
3821
+ }
3822
+ return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr);
3823
+ }
3824
+
3825
+ static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) {
3826
+ ASSERT(args.length() == 4);
3827
+ HandleScope scope;
3828
+ CONVERT_ARG_CHECKED(JSObject, js_object, 0);
3829
+ CONVERT_ARG_CHECKED(String, name, 1);
3830
+ Handle<Object> obj_value = args.at<Object>(2);
3831
+
3832
+ CONVERT_CHECKED(Smi, flag, args[3]);
3833
+ int unchecked = flag->value();
3834
+ RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
3835
+
3836
+ LookupResult result;
3837
+ js_object->LocalLookupRealNamedProperty(*name, &result);
3838
+
3839
+ PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
3840
+
3841
+ // Take special care when attributes are different and there is already
3842
+ // a property. For simplicity we normalize the property which enables us
3843
+ // to not worry about changing the instance_descriptor and creating a new
3844
+ // map. The current version of SetObjectProperty does not handle attributes
3845
+ // correctly in the case where a property is a field and is reset with
3846
+ // new attributes.
3847
+ if (result.IsProperty() && attr != result.GetAttributes()) {
3848
+ // New attributes - normalize to avoid writing to instance descriptor
3849
+ js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
3850
+ // Use IgnoreAttributes version since a readonly property may be
3851
+ // overridden and SetProperty does not allow this.
3852
+ return js_object->IgnoreAttributesAndSetLocalProperty(*name,
3853
+ *obj_value,
3854
+ attr);
3855
+ }
3856
+ return Runtime::SetObjectProperty(js_object, name, obj_value, attr);
3857
+ }
3858
+
3859
+
2881
3860
  Object* Runtime::SetObjectProperty(Handle<Object> object,
2882
3861
  Handle<Object> key,
2883
3862
  Handle<Object> value,
@@ -2900,8 +3879,6 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
2900
3879
  // Check if the given key is an array index.
2901
3880
  uint32_t index;
2902
3881
  if (Array::IndexFromObject(*key, &index)) {
2903
- ASSERT(attr == NONE);
2904
-
2905
3882
  // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
2906
3883
  // of a string using [] notation. We need to support this too in
2907
3884
  // JavaScript.
@@ -2921,11 +3898,10 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
2921
3898
  if (key->IsString()) {
2922
3899
  Handle<Object> result;
2923
3900
  if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
2924
- ASSERT(attr == NONE);
2925
3901
  result = SetElement(js_object, index, value);
2926
3902
  } else {
2927
3903
  Handle<String> key_string = Handle<String>::cast(key);
2928
- key_string->TryFlattenIfNotFlat();
3904
+ key_string->TryFlatten();
2929
3905
  result = SetProperty(js_object, key_string, value, attr);
2930
3906
  }
2931
3907
  if (result.is_null()) return Failure::Exception();
@@ -2939,7 +3915,6 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
2939
3915
  Handle<String> name = Handle<String>::cast(converted);
2940
3916
 
2941
3917
  if (name->AsArrayIndex(&index)) {
2942
- ASSERT(attr == NONE);
2943
3918
  return js_object->SetElement(index, *value);
2944
3919
  } else {
2945
3920
  return js_object->SetProperty(*name, *value, attr);
@@ -2956,8 +3931,6 @@ Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
2956
3931
  // Check if the given key is an array index.
2957
3932
  uint32_t index;
2958
3933
  if (Array::IndexFromObject(*key, &index)) {
2959
- ASSERT(attr == NONE);
2960
-
2961
3934
  // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
2962
3935
  // of a string using [] notation. We need to support this too in
2963
3936
  // JavaScript.
@@ -2974,11 +3947,10 @@ Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
2974
3947
 
2975
3948
  if (key->IsString()) {
2976
3949
  if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
2977
- ASSERT(attr == NONE);
2978
3950
  return js_object->SetElement(index, *value);
2979
3951
  } else {
2980
3952
  Handle<String> key_string = Handle<String>::cast(key);
2981
- key_string->TryFlattenIfNotFlat();
3953
+ key_string->TryFlatten();
2982
3954
  return js_object->IgnoreAttributesAndSetLocalProperty(*key_string,
2983
3955
  *value,
2984
3956
  attr);
@@ -2992,7 +3964,6 @@ Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
2992
3964
  Handle<String> name = Handle<String>::cast(converted);
2993
3965
 
2994
3966
  if (name->AsArrayIndex(&index)) {
2995
- ASSERT(attr == NONE);
2996
3967
  return js_object->SetElement(index, *value);
2997
3968
  } else {
2998
3969
  return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr);
@@ -3031,7 +4002,7 @@ Object* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object,
3031
4002
  key_string = Handle<String>::cast(converted);
3032
4003
  }
3033
4004
 
3034
- key_string->TryFlattenIfNotFlat();
4005
+ key_string->TryFlatten();
3035
4006
  return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION);
3036
4007
  }
3037
4008
 
@@ -3213,6 +4184,169 @@ static Object* Runtime_GetPropertyNamesFast(Arguments args) {
3213
4184
  }
3214
4185
 
3215
4186
 
4187
+ // Find the length of the prototype chain that is to to handled as one. If a
4188
+ // prototype object is hidden it is to be viewed as part of the the object it
4189
+ // is prototype for.
4190
+ static int LocalPrototypeChainLength(JSObject* obj) {
4191
+ int count = 1;
4192
+ Object* proto = obj->GetPrototype();
4193
+ while (proto->IsJSObject() &&
4194
+ JSObject::cast(proto)->map()->is_hidden_prototype()) {
4195
+ count++;
4196
+ proto = JSObject::cast(proto)->GetPrototype();
4197
+ }
4198
+ return count;
4199
+ }
4200
+
4201
+
4202
+ // Return the names of the local named properties.
4203
+ // args[0]: object
4204
+ static Object* Runtime_GetLocalPropertyNames(Arguments args) {
4205
+ HandleScope scope;
4206
+ ASSERT(args.length() == 1);
4207
+ if (!args[0]->IsJSObject()) {
4208
+ return Heap::undefined_value();
4209
+ }
4210
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
4211
+
4212
+ // Skip the global proxy as it has no properties and always delegates to the
4213
+ // real global object.
4214
+ if (obj->IsJSGlobalProxy()) {
4215
+ // Only collect names if access is permitted.
4216
+ if (obj->IsAccessCheckNeeded() &&
4217
+ !Top::MayNamedAccess(*obj, Heap::undefined_value(), v8::ACCESS_KEYS)) {
4218
+ Top::ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS);
4219
+ return *Factory::NewJSArray(0);
4220
+ }
4221
+ obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
4222
+ }
4223
+
4224
+ // Find the number of objects making up this.
4225
+ int length = LocalPrototypeChainLength(*obj);
4226
+
4227
+ // Find the number of local properties for each of the objects.
4228
+ ScopedVector<int> local_property_count(length);
4229
+ int total_property_count = 0;
4230
+ Handle<JSObject> jsproto = obj;
4231
+ for (int i = 0; i < length; i++) {
4232
+ // Only collect names if access is permitted.
4233
+ if (jsproto->IsAccessCheckNeeded() &&
4234
+ !Top::MayNamedAccess(*jsproto,
4235
+ Heap::undefined_value(),
4236
+ v8::ACCESS_KEYS)) {
4237
+ Top::ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS);
4238
+ return *Factory::NewJSArray(0);
4239
+ }
4240
+ int n;
4241
+ n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
4242
+ local_property_count[i] = n;
4243
+ total_property_count += n;
4244
+ if (i < length - 1) {
4245
+ jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
4246
+ }
4247
+ }
4248
+
4249
+ // Allocate an array with storage for all the property names.
4250
+ Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
4251
+
4252
+ // Get the property names.
4253
+ jsproto = obj;
4254
+ int proto_with_hidden_properties = 0;
4255
+ for (int i = 0; i < length; i++) {
4256
+ jsproto->GetLocalPropertyNames(*names,
4257
+ i == 0 ? 0 : local_property_count[i - 1]);
4258
+ if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
4259
+ proto_with_hidden_properties++;
4260
+ }
4261
+ if (i < length - 1) {
4262
+ jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
4263
+ }
4264
+ }
4265
+
4266
+ // Filter out name of hidden propeties object.
4267
+ if (proto_with_hidden_properties > 0) {
4268
+ Handle<FixedArray> old_names = names;
4269
+ names = Factory::NewFixedArray(
4270
+ names->length() - proto_with_hidden_properties);
4271
+ int dest_pos = 0;
4272
+ for (int i = 0; i < total_property_count; i++) {
4273
+ Object* name = old_names->get(i);
4274
+ if (name == Heap::hidden_symbol()) {
4275
+ continue;
4276
+ }
4277
+ names->set(dest_pos++, name);
4278
+ }
4279
+ }
4280
+
4281
+ return *Factory::NewJSArrayWithElements(names);
4282
+ }
4283
+
4284
+
4285
+ // Return the names of the local indexed properties.
4286
+ // args[0]: object
4287
+ static Object* Runtime_GetLocalElementNames(Arguments args) {
4288
+ HandleScope scope;
4289
+ ASSERT(args.length() == 1);
4290
+ if (!args[0]->IsJSObject()) {
4291
+ return Heap::undefined_value();
4292
+ }
4293
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
4294
+
4295
+ int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
4296
+ Handle<FixedArray> names = Factory::NewFixedArray(n);
4297
+ obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
4298
+ return *Factory::NewJSArrayWithElements(names);
4299
+ }
4300
+
4301
+
4302
+ // Return information on whether an object has a named or indexed interceptor.
4303
+ // args[0]: object
4304
+ static Object* Runtime_GetInterceptorInfo(Arguments args) {
4305
+ HandleScope scope;
4306
+ ASSERT(args.length() == 1);
4307
+ if (!args[0]->IsJSObject()) {
4308
+ return Smi::FromInt(0);
4309
+ }
4310
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
4311
+
4312
+ int result = 0;
4313
+ if (obj->HasNamedInterceptor()) result |= 2;
4314
+ if (obj->HasIndexedInterceptor()) result |= 1;
4315
+
4316
+ return Smi::FromInt(result);
4317
+ }
4318
+
4319
+
4320
+ // Return property names from named interceptor.
4321
+ // args[0]: object
4322
+ static Object* Runtime_GetNamedInterceptorPropertyNames(Arguments args) {
4323
+ HandleScope scope;
4324
+ ASSERT(args.length() == 1);
4325
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
4326
+
4327
+ if (obj->HasNamedInterceptor()) {
4328
+ v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
4329
+ if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
4330
+ }
4331
+ return Heap::undefined_value();
4332
+ }
4333
+
4334
+
4335
+ // Return element names from indexed interceptor.
4336
+ // args[0]: object
4337
+ static Object* Runtime_GetIndexedInterceptorElementNames(Arguments args) {
4338
+ HandleScope scope;
4339
+ ASSERT(args.length() == 1);
4340
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
4341
+
4342
+ if (obj->HasIndexedInterceptor()) {
4343
+ v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
4344
+ if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
4345
+ }
4346
+ return Heap::undefined_value();
4347
+ }
4348
+
4349
+
3216
4350
  static Object* Runtime_LocalKeys(Arguments args) {
3217
4351
  ASSERT_EQ(args.length(), 1);
3218
4352
  CONVERT_CHECKED(JSObject, raw_object, args[0]);
@@ -3287,17 +4421,23 @@ static Object* Runtime_GetArgumentsProperty(Arguments args) {
3287
4421
 
3288
4422
 
3289
4423
  static Object* Runtime_ToFastProperties(Arguments args) {
4424
+ HandleScope scope;
4425
+
3290
4426
  ASSERT(args.length() == 1);
3291
4427
  Handle<Object> object = args.at<Object>(0);
3292
4428
  if (object->IsJSObject()) {
3293
4429
  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
3294
- js_object->TransformToFastProperties(0);
4430
+ if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) {
4431
+ js_object->TransformToFastProperties(0);
4432
+ }
3295
4433
  }
3296
4434
  return *object;
3297
4435
  }
3298
4436
 
3299
4437
 
3300
4438
  static Object* Runtime_ToSlowProperties(Arguments args) {
4439
+ HandleScope scope;
4440
+
3301
4441
  ASSERT(args.length() == 1);
3302
4442
  Handle<Object> object = args.at<Object>(0);
3303
4443
  if (object->IsJSObject()) {
@@ -3353,11 +4493,66 @@ static Object* Runtime_Typeof(Arguments args) {
3353
4493
  }
3354
4494
 
3355
4495
 
4496
+ static bool AreDigits(const char*s, int from, int to) {
4497
+ for (int i = from; i < to; i++) {
4498
+ if (s[i] < '0' || s[i] > '9') return false;
4499
+ }
4500
+
4501
+ return true;
4502
+ }
4503
+
4504
+
4505
+ static int ParseDecimalInteger(const char*s, int from, int to) {
4506
+ ASSERT(to - from < 10); // Overflow is not possible.
4507
+ ASSERT(from < to);
4508
+ int d = s[from] - '0';
4509
+
4510
+ for (int i = from + 1; i < to; i++) {
4511
+ d = 10 * d + (s[i] - '0');
4512
+ }
4513
+
4514
+ return d;
4515
+ }
4516
+
4517
+
3356
4518
  static Object* Runtime_StringToNumber(Arguments args) {
3357
4519
  NoHandleAllocation ha;
3358
4520
  ASSERT(args.length() == 1);
3359
4521
  CONVERT_CHECKED(String, subject, args[0]);
3360
- subject->TryFlattenIfNotFlat();
4522
+ subject->TryFlatten();
4523
+
4524
+ // Fast case: short integer or some sorts of junk values.
4525
+ int len = subject->length();
4526
+ if (subject->IsSeqAsciiString()) {
4527
+ if (len == 0) return Smi::FromInt(0);
4528
+
4529
+ char const* data = SeqAsciiString::cast(subject)->GetChars();
4530
+ bool minus = (data[0] == '-');
4531
+ int start_pos = (minus ? 1 : 0);
4532
+
4533
+ if (start_pos == len) {
4534
+ return Heap::nan_value();
4535
+ } else if (data[start_pos] > '9') {
4536
+ // Fast check for a junk value. A valid string may start from a
4537
+ // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
4538
+ // the 'I' character ('Infinity'). All of that have codes not greater than
4539
+ // '9' except 'I'.
4540
+ if (data[start_pos] != 'I') {
4541
+ return Heap::nan_value();
4542
+ }
4543
+ } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
4544
+ // The maximal/minimal smi has 10 digits. If the string has less digits we
4545
+ // know it will fit into the smi-data type.
4546
+ int d = ParseDecimalInteger(data, start_pos, len);
4547
+ if (minus) {
4548
+ if (d == 0) return Heap::minus_zero_value();
4549
+ d = -d;
4550
+ }
4551
+ return Smi::FromInt(d);
4552
+ }
4553
+ }
4554
+
4555
+ // Slower case.
3361
4556
  return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
3362
4557
  }
3363
4558
 
@@ -3439,7 +4634,7 @@ static Object* Runtime_URIEscape(Arguments args) {
3439
4634
  ASSERT(args.length() == 1);
3440
4635
  CONVERT_CHECKED(String, source, args[0]);
3441
4636
 
3442
- source->TryFlattenIfNotFlat();
4637
+ source->TryFlatten();
3443
4638
 
3444
4639
  int escaped_length = 0;
3445
4640
  int length = source->length();
@@ -3552,7 +4747,7 @@ static Object* Runtime_URIUnescape(Arguments args) {
3552
4747
  ASSERT(args.length() == 1);
3553
4748
  CONVERT_CHECKED(String, source, args[0]);
3554
4749
 
3555
- source->TryFlattenIfNotFlat();
4750
+ source->TryFlatten();
3556
4751
 
3557
4752
  bool ascii = true;
3558
4753
  int length = source->length();
@@ -3592,51 +4787,11 @@ static Object* Runtime_StringParseInt(Arguments args) {
3592
4787
  CONVERT_CHECKED(String, s, args[0]);
3593
4788
  CONVERT_SMI_CHECKED(radix, args[1]);
3594
4789
 
3595
- s->TryFlattenIfNotFlat();
3596
-
3597
- int len = s->length();
3598
- int i;
3599
-
3600
- // Skip leading white space.
3601
- for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(i)); i++) ;
3602
- if (i == len) return Heap::nan_value();
3603
-
3604
- // Compute the sign (default to +).
3605
- int sign = 1;
3606
- if (s->Get(i) == '-') {
3607
- sign = -1;
3608
- i++;
3609
- } else if (s->Get(i) == '+') {
3610
- i++;
3611
- }
3612
-
3613
- // Compute the radix if 0.
3614
- if (radix == 0) {
3615
- radix = 10;
3616
- if (i < len && s->Get(i) == '0') {
3617
- radix = 8;
3618
- if (i + 1 < len) {
3619
- int c = s->Get(i + 1);
3620
- if (c == 'x' || c == 'X') {
3621
- radix = 16;
3622
- i += 2;
3623
- }
3624
- }
3625
- }
3626
- } else if (radix == 16) {
3627
- // Allow 0x or 0X prefix if radix is 16.
3628
- if (i + 1 < len && s->Get(i) == '0') {
3629
- int c = s->Get(i + 1);
3630
- if (c == 'x' || c == 'X') i += 2;
3631
- }
3632
- }
4790
+ s->TryFlatten();
3633
4791
 
3634
- RUNTIME_ASSERT(2 <= radix && radix <= 36);
3635
- double value;
3636
- int end_index = StringToInt(s, i, radix, &value);
3637
- if (end_index != i) {
3638
- return Heap::NumberFromDouble(sign * value);
3639
- }
4792
+ RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
4793
+ double value = StringToInt(s, radix);
4794
+ return Heap::NumberFromDouble(value);
3640
4795
  return Heap::nan_value();
3641
4796
  }
3642
4797
 
@@ -3756,18 +4911,83 @@ static Object* ConvertCaseHelper(String* s,
3756
4911
  }
3757
4912
 
3758
4913
 
3759
- template <class Converter>
3760
- static Object* ConvertCase(Arguments args,
3761
- unibrow::Mapping<Converter, 128>* mapping) {
3762
- NoHandleAllocation ha;
4914
+ static inline SeqAsciiString* TryGetSeqAsciiString(String* s) {
4915
+ if (!s->IsFlat() || !s->IsAsciiRepresentation()) return NULL;
4916
+ if (s->IsConsString()) {
4917
+ ASSERT(ConsString::cast(s)->second()->length() == 0);
4918
+ return SeqAsciiString::cast(ConsString::cast(s)->first());
4919
+ }
4920
+ return SeqAsciiString::cast(s);
4921
+ }
4922
+
4923
+
4924
+ namespace {
3763
4925
 
4926
+ struct ToLowerTraits {
4927
+ typedef unibrow::ToLowercase UnibrowConverter;
4928
+
4929
+ static bool ConvertAscii(char* dst, char* src, int length) {
4930
+ bool changed = false;
4931
+ for (int i = 0; i < length; ++i) {
4932
+ char c = src[i];
4933
+ if ('A' <= c && c <= 'Z') {
4934
+ c += ('a' - 'A');
4935
+ changed = true;
4936
+ }
4937
+ dst[i] = c;
4938
+ }
4939
+ return changed;
4940
+ }
4941
+ };
4942
+
4943
+
4944
+ struct ToUpperTraits {
4945
+ typedef unibrow::ToUppercase UnibrowConverter;
4946
+
4947
+ static bool ConvertAscii(char* dst, char* src, int length) {
4948
+ bool changed = false;
4949
+ for (int i = 0; i < length; ++i) {
4950
+ char c = src[i];
4951
+ if ('a' <= c && c <= 'z') {
4952
+ c -= ('a' - 'A');
4953
+ changed = true;
4954
+ }
4955
+ dst[i] = c;
4956
+ }
4957
+ return changed;
4958
+ }
4959
+ };
4960
+
4961
+ } // namespace
4962
+
4963
+
4964
+ template <typename ConvertTraits>
4965
+ static Object* ConvertCase(
4966
+ Arguments args,
4967
+ unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) {
4968
+ NoHandleAllocation ha;
3764
4969
  CONVERT_CHECKED(String, s, args[0]);
3765
- s->TryFlattenIfNotFlat();
4970
+ s->TryFlatten();
3766
4971
 
3767
- int input_string_length = s->length();
4972
+ const int length = s->length();
3768
4973
  // Assume that the string is not empty; we need this assumption later
3769
- if (input_string_length == 0) return s;
3770
- int length = input_string_length;
4974
+ if (length == 0) return s;
4975
+
4976
+ // Simpler handling of ascii strings.
4977
+ //
4978
+ // NOTE: This assumes that the upper/lower case of an ascii
4979
+ // character is also ascii. This is currently the case, but it
4980
+ // might break in the future if we implement more context and locale
4981
+ // dependent upper/lower conversions.
4982
+ SeqAsciiString* seq_ascii = TryGetSeqAsciiString(s);
4983
+ if (seq_ascii != NULL) {
4984
+ Object* o = Heap::AllocateRawAsciiString(length);
4985
+ if (o->IsFailure()) return o;
4986
+ SeqAsciiString* result = SeqAsciiString::cast(o);
4987
+ bool has_changed_character = ConvertTraits::ConvertAscii(
4988
+ result->GetChars(), seq_ascii->GetChars(), length);
4989
+ return has_changed_character ? result : s;
4990
+ }
3771
4991
 
3772
4992
  Object* answer = ConvertCaseHelper(s, length, length, mapping);
3773
4993
  if (answer->IsSmi()) {
@@ -3779,18 +4999,20 @@ static Object* ConvertCase(Arguments args,
3779
4999
 
3780
5000
 
3781
5001
  static Object* Runtime_StringToLowerCase(Arguments args) {
3782
- return ConvertCase<unibrow::ToLowercase>(args, &to_lower_mapping);
5002
+ return ConvertCase<ToLowerTraits>(args, &to_lower_mapping);
3783
5003
  }
3784
5004
 
3785
5005
 
3786
5006
  static Object* Runtime_StringToUpperCase(Arguments args) {
3787
- return ConvertCase<unibrow::ToUppercase>(args, &to_upper_mapping);
5007
+ return ConvertCase<ToUpperTraits>(args, &to_upper_mapping);
3788
5008
  }
3789
5009
 
5010
+
3790
5011
  static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
3791
5012
  return unibrow::WhiteSpace::Is(c) || c == 0x200b;
3792
5013
  }
3793
5014
 
5015
+
3794
5016
  static Object* Runtime_StringTrim(Arguments args) {
3795
5017
  NoHandleAllocation ha;
3796
5018
  ASSERT(args.length() == 3);
@@ -3799,7 +5021,7 @@ static Object* Runtime_StringTrim(Arguments args) {
3799
5021
  CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]);
3800
5022
  CONVERT_BOOLEAN_CHECKED(trimRight, args[2]);
3801
5023
 
3802
- s->TryFlattenIfNotFlat();
5024
+ s->TryFlatten();
3803
5025
  int length = s->length();
3804
5026
 
3805
5027
  int left = 0;
@@ -3818,6 +5040,245 @@ static Object* Runtime_StringTrim(Arguments args) {
3818
5040
  return s->SubString(left, right);
3819
5041
  }
3820
5042
 
5043
+
5044
+ template <typename schar, typename pchar>
5045
+ void FindStringIndices(Vector<const schar> subject,
5046
+ Vector<const pchar> pattern,
5047
+ ZoneList<int>* indices,
5048
+ unsigned int limit) {
5049
+ ASSERT(limit > 0);
5050
+ // Collect indices of pattern in subject, and the end-of-string index.
5051
+ // Stop after finding at most limit values.
5052
+ StringSearchStrategy strategy =
5053
+ InitializeStringSearch(pattern, sizeof(schar) == 1);
5054
+ switch (strategy) {
5055
+ case SEARCH_FAIL: return;
5056
+ case SEARCH_SHORT: {
5057
+ int pattern_length = pattern.length();
5058
+ int index = 0;
5059
+ while (limit > 0) {
5060
+ index = SimpleIndexOf(subject, pattern, index);
5061
+ if (index < 0) return;
5062
+ indices->Add(index);
5063
+ index += pattern_length;
5064
+ limit--;
5065
+ }
5066
+ return;
5067
+ }
5068
+ case SEARCH_LONG: {
5069
+ int pattern_length = pattern.length();
5070
+ int index = 0;
5071
+ while (limit > 0) {
5072
+ index = ComplexIndexOf(subject, pattern, index);
5073
+ if (index < 0) return;
5074
+ indices->Add(index);
5075
+ index += pattern_length;
5076
+ limit--;
5077
+ }
5078
+ return;
5079
+ }
5080
+ default:
5081
+ UNREACHABLE();
5082
+ return;
5083
+ }
5084
+ }
5085
+
5086
+ template <typename schar>
5087
+ inline void FindCharIndices(Vector<const schar> subject,
5088
+ const schar pattern_char,
5089
+ ZoneList<int>* indices,
5090
+ unsigned int limit) {
5091
+ // Collect indices of pattern_char in subject, and the end-of-string index.
5092
+ // Stop after finding at most limit values.
5093
+ int index = 0;
5094
+ while (limit > 0) {
5095
+ index = SingleCharIndexOf(subject, pattern_char, index);
5096
+ if (index < 0) return;
5097
+ indices->Add(index);
5098
+ index++;
5099
+ limit--;
5100
+ }
5101
+ }
5102
+
5103
+
5104
+ static Object* Runtime_StringSplit(Arguments args) {
5105
+ ASSERT(args.length() == 3);
5106
+ HandleScope handle_scope;
5107
+ CONVERT_ARG_CHECKED(String, subject, 0);
5108
+ CONVERT_ARG_CHECKED(String, pattern, 1);
5109
+ CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
5110
+
5111
+ int subject_length = subject->length();
5112
+ int pattern_length = pattern->length();
5113
+ RUNTIME_ASSERT(pattern_length > 0);
5114
+
5115
+ // The limit can be very large (0xffffffffu), but since the pattern
5116
+ // isn't empty, we can never create more parts than ~half the length
5117
+ // of the subject.
5118
+
5119
+ if (!subject->IsFlat()) FlattenString(subject);
5120
+
5121
+ static const int kMaxInitialListCapacity = 16;
5122
+
5123
+ ZoneScope scope(DELETE_ON_EXIT);
5124
+
5125
+ // Find (up to limit) indices of separator and end-of-string in subject
5126
+ int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
5127
+ ZoneList<int> indices(initial_capacity);
5128
+ if (pattern_length == 1) {
5129
+ // Special case, go directly to fast single-character split.
5130
+ AssertNoAllocation nogc;
5131
+ uc16 pattern_char = pattern->Get(0);
5132
+ if (subject->IsTwoByteRepresentation()) {
5133
+ FindCharIndices(subject->ToUC16Vector(), pattern_char,
5134
+ &indices,
5135
+ limit);
5136
+ } else if (pattern_char <= String::kMaxAsciiCharCode) {
5137
+ FindCharIndices(subject->ToAsciiVector(),
5138
+ static_cast<char>(pattern_char),
5139
+ &indices,
5140
+ limit);
5141
+ }
5142
+ } else {
5143
+ if (!pattern->IsFlat()) FlattenString(pattern);
5144
+ AssertNoAllocation nogc;
5145
+ if (subject->IsAsciiRepresentation()) {
5146
+ Vector<const char> subject_vector = subject->ToAsciiVector();
5147
+ if (pattern->IsAsciiRepresentation()) {
5148
+ FindStringIndices(subject_vector,
5149
+ pattern->ToAsciiVector(),
5150
+ &indices,
5151
+ limit);
5152
+ } else {
5153
+ FindStringIndices(subject_vector,
5154
+ pattern->ToUC16Vector(),
5155
+ &indices,
5156
+ limit);
5157
+ }
5158
+ } else {
5159
+ Vector<const uc16> subject_vector = subject->ToUC16Vector();
5160
+ if (pattern->IsAsciiRepresentation()) {
5161
+ FindStringIndices(subject_vector,
5162
+ pattern->ToAsciiVector(),
5163
+ &indices,
5164
+ limit);
5165
+ } else {
5166
+ FindStringIndices(subject_vector,
5167
+ pattern->ToUC16Vector(),
5168
+ &indices,
5169
+ limit);
5170
+ }
5171
+ }
5172
+ }
5173
+ if (static_cast<uint32_t>(indices.length()) < limit) {
5174
+ indices.Add(subject_length);
5175
+ }
5176
+ // The list indices now contains the end of each part to create.
5177
+
5178
+
5179
+ // Create JSArray of substrings separated by separator.
5180
+ int part_count = indices.length();
5181
+
5182
+ Handle<JSArray> result = Factory::NewJSArray(part_count);
5183
+ result->set_length(Smi::FromInt(part_count));
5184
+
5185
+ ASSERT(result->HasFastElements());
5186
+
5187
+ if (part_count == 1 && indices.at(0) == subject_length) {
5188
+ FixedArray::cast(result->elements())->set(0, *subject);
5189
+ return *result;
5190
+ }
5191
+
5192
+ Handle<FixedArray> elements(FixedArray::cast(result->elements()));
5193
+ int part_start = 0;
5194
+ for (int i = 0; i < part_count; i++) {
5195
+ HandleScope local_loop_handle;
5196
+ int part_end = indices.at(i);
5197
+ Handle<String> substring =
5198
+ Factory::NewSubString(subject, part_start, part_end);
5199
+ elements->set(i, *substring);
5200
+ part_start = part_end + pattern_length;
5201
+ }
5202
+
5203
+ return *result;
5204
+ }
5205
+
5206
+
5207
+ // Copies ascii characters to the given fixed array looking up
5208
+ // one-char strings in the cache. Gives up on the first char that is
5209
+ // not in the cache and fills the remainder with smi zeros. Returns
5210
+ // the length of the successfully copied prefix.
5211
+ static int CopyCachedAsciiCharsToArray(const char* chars,
5212
+ FixedArray* elements,
5213
+ int length) {
5214
+ AssertNoAllocation nogc;
5215
+ FixedArray* ascii_cache = Heap::single_character_string_cache();
5216
+ Object* undefined = Heap::undefined_value();
5217
+ int i;
5218
+ for (i = 0; i < length; ++i) {
5219
+ Object* value = ascii_cache->get(chars[i]);
5220
+ if (value == undefined) break;
5221
+ ASSERT(!Heap::InNewSpace(value));
5222
+ elements->set(i, value, SKIP_WRITE_BARRIER);
5223
+ }
5224
+ if (i < length) {
5225
+ ASSERT(Smi::FromInt(0) == 0);
5226
+ memset(elements->data_start() + i, 0, kPointerSize * (length - i));
5227
+ }
5228
+ #ifdef DEBUG
5229
+ for (int j = 0; j < length; ++j) {
5230
+ Object* element = elements->get(j);
5231
+ ASSERT(element == Smi::FromInt(0) ||
5232
+ (element->IsString() && String::cast(element)->LooksValid()));
5233
+ }
5234
+ #endif
5235
+ return i;
5236
+ }
5237
+
5238
+
5239
+ // Converts a String to JSArray.
5240
+ // For example, "foo" => ["f", "o", "o"].
5241
+ static Object* Runtime_StringToArray(Arguments args) {
5242
+ HandleScope scope;
5243
+ ASSERT(args.length() == 1);
5244
+ CONVERT_ARG_CHECKED(String, s, 0);
5245
+
5246
+ s->TryFlatten();
5247
+ const int length = s->length();
5248
+
5249
+ Handle<FixedArray> elements;
5250
+ if (s->IsFlat() && s->IsAsciiRepresentation()) {
5251
+ Object* obj = Heap::AllocateUninitializedFixedArray(length);
5252
+ if (obj->IsFailure()) return obj;
5253
+ elements = Handle<FixedArray>(FixedArray::cast(obj));
5254
+
5255
+ Vector<const char> chars = s->ToAsciiVector();
5256
+ // Note, this will initialize all elements (not only the prefix)
5257
+ // to prevent GC from seeing partially initialized array.
5258
+ int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(),
5259
+ *elements,
5260
+ length);
5261
+
5262
+ for (int i = num_copied_from_cache; i < length; ++i) {
5263
+ elements->set(i, *LookupSingleCharacterStringFromCode(chars[i]));
5264
+ }
5265
+ } else {
5266
+ elements = Factory::NewFixedArray(length);
5267
+ for (int i = 0; i < length; ++i) {
5268
+ elements->set(i, *LookupSingleCharacterStringFromCode(s->Get(i)));
5269
+ }
5270
+ }
5271
+
5272
+ #ifdef DEBUG
5273
+ for (int i = 0; i < length; ++i) {
5274
+ ASSERT(String::cast(elements->get(i))->length() == 1);
5275
+ }
5276
+ #endif
5277
+
5278
+ return *Factory::NewJSArrayWithElements(elements);
5279
+ }
5280
+
5281
+
3821
5282
  bool Runtime::IsUpperCaseChar(uint16_t ch) {
3822
5283
  unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
3823
5284
  int char_length = to_upper_mapping.get(ch, 0, chars);
@@ -3836,13 +5297,27 @@ static Object* Runtime_NumberToString(Arguments args) {
3836
5297
  }
3837
5298
 
3838
5299
 
5300
+ static Object* Runtime_NumberToStringSkipCache(Arguments args) {
5301
+ NoHandleAllocation ha;
5302
+ ASSERT(args.length() == 1);
5303
+
5304
+ Object* number = args[0];
5305
+ RUNTIME_ASSERT(number->IsNumber());
5306
+
5307
+ return Heap::NumberToString(number, false);
5308
+ }
5309
+
5310
+
3839
5311
  static Object* Runtime_NumberToInteger(Arguments args) {
3840
5312
  NoHandleAllocation ha;
3841
5313
  ASSERT(args.length() == 1);
3842
5314
 
3843
- Object* obj = args[0];
3844
- if (obj->IsSmi()) return obj;
3845
- CONVERT_DOUBLE_CHECKED(number, obj);
5315
+ CONVERT_DOUBLE_CHECKED(number, args[0]);
5316
+
5317
+ // We do not include 0 so that we don't have to treat +0 / -0 cases.
5318
+ if (number > 0 && number <= Smi::kMaxValue) {
5319
+ return Smi::FromInt(static_cast<int>(number));
5320
+ }
3846
5321
  return Heap::NumberFromDouble(DoubleToInteger(number));
3847
5322
  }
3848
5323
 
@@ -3851,9 +5326,7 @@ static Object* Runtime_NumberToJSUint32(Arguments args) {
3851
5326
  NoHandleAllocation ha;
3852
5327
  ASSERT(args.length() == 1);
3853
5328
 
3854
- Object* obj = args[0];
3855
- if (obj->IsSmi() && Smi::cast(obj)->value() >= 0) return obj;
3856
- CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, obj);
5329
+ CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
3857
5330
  return Heap::NumberFromUint32(number);
3858
5331
  }
3859
5332
 
@@ -3862,9 +5335,12 @@ static Object* Runtime_NumberToJSInt32(Arguments args) {
3862
5335
  NoHandleAllocation ha;
3863
5336
  ASSERT(args.length() == 1);
3864
5337
 
3865
- Object* obj = args[0];
3866
- if (obj->IsSmi()) return obj;
3867
- CONVERT_DOUBLE_CHECKED(number, obj);
5338
+ CONVERT_DOUBLE_CHECKED(number, args[0]);
5339
+
5340
+ // We do not include 0 so that we don't have to treat +0 / -0 cases.
5341
+ if (number > 0 && number <= Smi::kMaxValue) {
5342
+ return Smi::FromInt(static_cast<int>(number));
5343
+ }
3868
5344
  return Heap::NumberFromInt32(DoubleToInt32(number));
3869
5345
  }
3870
5346
 
@@ -3935,7 +5411,7 @@ static Object* Runtime_NumberDiv(Arguments args) {
3935
5411
 
3936
5412
  CONVERT_DOUBLE_CHECKED(x, args[0]);
3937
5413
  CONVERT_DOUBLE_CHECKED(y, args[1]);
3938
- return Heap::NewNumberFromDouble(x / y);
5414
+ return Heap::NumberFromDouble(x / y);
3939
5415
  }
3940
5416
 
3941
5417
 
@@ -3947,8 +5423,8 @@ static Object* Runtime_NumberMod(Arguments args) {
3947
5423
  CONVERT_DOUBLE_CHECKED(y, args[1]);
3948
5424
 
3949
5425
  x = modulo(x, y);
3950
- // NewNumberFromDouble may return a Smi instead of a Number object
3951
- return Heap::NewNumberFromDouble(x);
5426
+ // NumberFromDouble may return a Smi instead of a Number object
5427
+ return Heap::NumberFromDouble(x);
3952
5428
  }
3953
5429
 
3954
5430
 
@@ -3962,7 +5438,7 @@ static Object* Runtime_StringAdd(Arguments args) {
3962
5438
  }
3963
5439
 
3964
5440
 
3965
- template<typename sinkchar>
5441
+ template <typename sinkchar>
3966
5442
  static inline void StringBuilderConcatHelper(String* special,
3967
5443
  sinkchar* sink,
3968
5444
  FixedArray* fixed_array,
@@ -4033,33 +5509,41 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
4033
5509
 
4034
5510
  bool ascii = special->IsAsciiRepresentation();
4035
5511
  int position = 0;
4036
- int increment = 0;
4037
5512
  for (int i = 0; i < array_length; i++) {
5513
+ int increment = 0;
4038
5514
  Object* elt = fixed_array->get(i);
4039
5515
  if (elt->IsSmi()) {
4040
5516
  // Smi encoding of position and length.
4041
- int len = Smi::cast(elt)->value();
4042
- if (len > 0) {
5517
+ int smi_value = Smi::cast(elt)->value();
5518
+ int pos;
5519
+ int len;
5520
+ if (smi_value > 0) {
4043
5521
  // Position and length encoded in one smi.
4044
- int pos = len >> 11;
4045
- len &= 0x7ff;
4046
- if (pos + len > special_length) {
4047
- return Top::Throw(Heap::illegal_argument_symbol());
4048
- }
4049
- increment = len;
5522
+ pos = StringBuilderSubstringPosition::decode(smi_value);
5523
+ len = StringBuilderSubstringLength::decode(smi_value);
4050
5524
  } else {
4051
5525
  // Position and length encoded in two smis.
4052
- increment = (-len);
4053
- // Get the position and check that it is also a smi.
5526
+ len = -smi_value;
5527
+ // Get the position and check that it is a positive smi.
4054
5528
  i++;
4055
5529
  if (i >= array_length) {
4056
5530
  return Top::Throw(Heap::illegal_argument_symbol());
4057
5531
  }
4058
- Object* pos = fixed_array->get(i);
4059
- if (!pos->IsSmi()) {
5532
+ Object* next_smi = fixed_array->get(i);
5533
+ if (!next_smi->IsSmi()) {
5534
+ return Top::Throw(Heap::illegal_argument_symbol());
5535
+ }
5536
+ pos = Smi::cast(next_smi)->value();
5537
+ if (pos < 0) {
4060
5538
  return Top::Throw(Heap::illegal_argument_symbol());
4061
5539
  }
4062
5540
  }
5541
+ ASSERT(pos >= 0);
5542
+ ASSERT(len >= 0);
5543
+ if (pos > special_length || len > special_length - pos) {
5544
+ return Top::Throw(Heap::illegal_argument_symbol());
5545
+ }
5546
+ increment = len;
4063
5547
  } else if (elt->IsString()) {
4064
5548
  String* element = String::cast(elt);
4065
5549
  int element_length = element->length();
@@ -4267,17 +5751,77 @@ static Object* Runtime_SmiLexicographicCompare(Arguments args) {
4267
5751
  y_value /= 10;
4268
5752
  }
4269
5753
 
4270
- // Loop through the arrays of decimal digits finding the first place
4271
- // where they differ.
4272
- while (--x_index >= 0 && --y_index >= 0) {
4273
- int diff = x_elms[x_index] - y_elms[y_index];
4274
- if (diff != 0) return Smi::FromInt(diff);
5754
+ // Loop through the arrays of decimal digits finding the first place
5755
+ // where they differ.
5756
+ while (--x_index >= 0 && --y_index >= 0) {
5757
+ int diff = x_elms[x_index] - y_elms[y_index];
5758
+ if (diff != 0) return Smi::FromInt(diff);
5759
+ }
5760
+
5761
+ // If one array is a suffix of the other array, the longest array is
5762
+ // the representation of the largest of the Smis in the
5763
+ // lexicographic ordering.
5764
+ return Smi::FromInt(x_index - y_index);
5765
+ }
5766
+
5767
+
5768
+ static Object* StringInputBufferCompare(String* x, String* y) {
5769
+ static StringInputBuffer bufx;
5770
+ static StringInputBuffer bufy;
5771
+ bufx.Reset(x);
5772
+ bufy.Reset(y);
5773
+ while (bufx.has_more() && bufy.has_more()) {
5774
+ int d = bufx.GetNext() - bufy.GetNext();
5775
+ if (d < 0) return Smi::FromInt(LESS);
5776
+ else if (d > 0) return Smi::FromInt(GREATER);
5777
+ }
5778
+
5779
+ // x is (non-trivial) prefix of y:
5780
+ if (bufy.has_more()) return Smi::FromInt(LESS);
5781
+ // y is prefix of x:
5782
+ return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
5783
+ }
5784
+
5785
+
5786
+ static Object* FlatStringCompare(String* x, String* y) {
5787
+ ASSERT(x->IsFlat());
5788
+ ASSERT(y->IsFlat());
5789
+ Object* equal_prefix_result = Smi::FromInt(EQUAL);
5790
+ int prefix_length = x->length();
5791
+ if (y->length() < prefix_length) {
5792
+ prefix_length = y->length();
5793
+ equal_prefix_result = Smi::FromInt(GREATER);
5794
+ } else if (y->length() > prefix_length) {
5795
+ equal_prefix_result = Smi::FromInt(LESS);
5796
+ }
5797
+ int r;
5798
+ if (x->IsAsciiRepresentation()) {
5799
+ Vector<const char> x_chars = x->ToAsciiVector();
5800
+ if (y->IsAsciiRepresentation()) {
5801
+ Vector<const char> y_chars = y->ToAsciiVector();
5802
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
5803
+ } else {
5804
+ Vector<const uc16> y_chars = y->ToUC16Vector();
5805
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
5806
+ }
5807
+ } else {
5808
+ Vector<const uc16> x_chars = x->ToUC16Vector();
5809
+ if (y->IsAsciiRepresentation()) {
5810
+ Vector<const char> y_chars = y->ToAsciiVector();
5811
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
5812
+ } else {
5813
+ Vector<const uc16> y_chars = y->ToUC16Vector();
5814
+ r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
5815
+ }
4275
5816
  }
4276
-
4277
- // If one array is a suffix of the other array, the longest array is
4278
- // the representation of the largest of the Smis in the
4279
- // lexicographic ordering.
4280
- return Smi::FromInt(x_index - y_index);
5817
+ Object* result;
5818
+ if (r == 0) {
5819
+ result = equal_prefix_result;
5820
+ } else {
5821
+ result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
5822
+ }
5823
+ ASSERT(result == StringInputBufferCompare(x, y));
5824
+ return result;
4281
5825
  }
4282
5826
 
4283
5827
 
@@ -4303,38 +5847,20 @@ static Object* Runtime_StringCompare(Arguments args) {
4303
5847
  if (d < 0) return Smi::FromInt(LESS);
4304
5848
  else if (d > 0) return Smi::FromInt(GREATER);
4305
5849
 
4306
- x->TryFlattenIfNotFlat();
4307
- y->TryFlattenIfNotFlat();
4308
-
4309
- static StringInputBuffer bufx;
4310
- static StringInputBuffer bufy;
4311
- bufx.Reset(x);
4312
- bufy.Reset(y);
4313
- while (bufx.has_more() && bufy.has_more()) {
4314
- int d = bufx.GetNext() - bufy.GetNext();
4315
- if (d < 0) return Smi::FromInt(LESS);
4316
- else if (d > 0) return Smi::FromInt(GREATER);
4317
- }
4318
-
4319
- // x is (non-trivial) prefix of y:
4320
- if (bufy.has_more()) return Smi::FromInt(LESS);
4321
- // y is prefix of x:
4322
- return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
4323
- }
4324
-
4325
-
4326
- static Object* Runtime_Math_abs(Arguments args) {
4327
- NoHandleAllocation ha;
4328
- ASSERT(args.length() == 1);
5850
+ Object* obj = Heap::PrepareForCompare(x);
5851
+ if (obj->IsFailure()) return obj;
5852
+ obj = Heap::PrepareForCompare(y);
5853
+ if (obj->IsFailure()) return obj;
4329
5854
 
4330
- CONVERT_DOUBLE_CHECKED(x, args[0]);
4331
- return Heap::AllocateHeapNumber(fabs(x));
5855
+ return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
5856
+ : StringInputBufferCompare(x, y);
4332
5857
  }
4333
5858
 
4334
5859
 
4335
5860
  static Object* Runtime_Math_acos(Arguments args) {
4336
5861
  NoHandleAllocation ha;
4337
5862
  ASSERT(args.length() == 1);
5863
+ Counters::math_acos.Increment();
4338
5864
 
4339
5865
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4340
5866
  return TranscendentalCache::Get(TranscendentalCache::ACOS, x);
@@ -4344,6 +5870,7 @@ static Object* Runtime_Math_acos(Arguments args) {
4344
5870
  static Object* Runtime_Math_asin(Arguments args) {
4345
5871
  NoHandleAllocation ha;
4346
5872
  ASSERT(args.length() == 1);
5873
+ Counters::math_asin.Increment();
4347
5874
 
4348
5875
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4349
5876
  return TranscendentalCache::Get(TranscendentalCache::ASIN, x);
@@ -4353,6 +5880,7 @@ static Object* Runtime_Math_asin(Arguments args) {
4353
5880
  static Object* Runtime_Math_atan(Arguments args) {
4354
5881
  NoHandleAllocation ha;
4355
5882
  ASSERT(args.length() == 1);
5883
+ Counters::math_atan.Increment();
4356
5884
 
4357
5885
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4358
5886
  return TranscendentalCache::Get(TranscendentalCache::ATAN, x);
@@ -4362,6 +5890,7 @@ static Object* Runtime_Math_atan(Arguments args) {
4362
5890
  static Object* Runtime_Math_atan2(Arguments args) {
4363
5891
  NoHandleAllocation ha;
4364
5892
  ASSERT(args.length() == 2);
5893
+ Counters::math_atan2.Increment();
4365
5894
 
4366
5895
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4367
5896
  CONVERT_DOUBLE_CHECKED(y, args[1]);
@@ -4385,6 +5914,7 @@ static Object* Runtime_Math_atan2(Arguments args) {
4385
5914
  static Object* Runtime_Math_ceil(Arguments args) {
4386
5915
  NoHandleAllocation ha;
4387
5916
  ASSERT(args.length() == 1);
5917
+ Counters::math_ceil.Increment();
4388
5918
 
4389
5919
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4390
5920
  return Heap::NumberFromDouble(ceiling(x));
@@ -4394,6 +5924,7 @@ static Object* Runtime_Math_ceil(Arguments args) {
4394
5924
  static Object* Runtime_Math_cos(Arguments args) {
4395
5925
  NoHandleAllocation ha;
4396
5926
  ASSERT(args.length() == 1);
5927
+ Counters::math_cos.Increment();
4397
5928
 
4398
5929
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4399
5930
  return TranscendentalCache::Get(TranscendentalCache::COS, x);
@@ -4403,6 +5934,7 @@ static Object* Runtime_Math_cos(Arguments args) {
4403
5934
  static Object* Runtime_Math_exp(Arguments args) {
4404
5935
  NoHandleAllocation ha;
4405
5936
  ASSERT(args.length() == 1);
5937
+ Counters::math_exp.Increment();
4406
5938
 
4407
5939
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4408
5940
  return TranscendentalCache::Get(TranscendentalCache::EXP, x);
@@ -4412,6 +5944,7 @@ static Object* Runtime_Math_exp(Arguments args) {
4412
5944
  static Object* Runtime_Math_floor(Arguments args) {
4413
5945
  NoHandleAllocation ha;
4414
5946
  ASSERT(args.length() == 1);
5947
+ Counters::math_floor.Increment();
4415
5948
 
4416
5949
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4417
5950
  return Heap::NumberFromDouble(floor(x));
@@ -4421,6 +5954,7 @@ static Object* Runtime_Math_floor(Arguments args) {
4421
5954
  static Object* Runtime_Math_log(Arguments args) {
4422
5955
  NoHandleAllocation ha;
4423
5956
  ASSERT(args.length() == 1);
5957
+ Counters::math_log.Increment();
4424
5958
 
4425
5959
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4426
5960
  return TranscendentalCache::Get(TranscendentalCache::LOG, x);
@@ -4461,6 +5995,7 @@ static double powi(double x, int y) {
4461
5995
  static Object* Runtime_Math_pow(Arguments args) {
4462
5996
  NoHandleAllocation ha;
4463
5997
  ASSERT(args.length() == 2);
5998
+ Counters::math_pow.Increment();
4464
5999
 
4465
6000
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4466
6001
 
@@ -4495,20 +6030,63 @@ static Object* Runtime_Math_pow(Arguments args) {
4495
6030
  }
4496
6031
  }
4497
6032
 
6033
+ // Fast version of Math.pow if we know that y is not an integer and
6034
+ // y is not -0.5 or 0.5. Used as slowcase from codegen.
6035
+ static Object* Runtime_Math_pow_cfunction(Arguments args) {
6036
+ NoHandleAllocation ha;
6037
+ ASSERT(args.length() == 2);
6038
+ CONVERT_DOUBLE_CHECKED(x, args[0]);
6039
+ CONVERT_DOUBLE_CHECKED(y, args[1]);
6040
+ if (y == 0) {
6041
+ return Smi::FromInt(1);
6042
+ } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
6043
+ return Heap::nan_value();
6044
+ } else {
6045
+ return Heap::AllocateHeapNumber(pow(x, y));
6046
+ }
6047
+ }
6048
+
4498
6049
 
4499
- static Object* Runtime_Math_round(Arguments args) {
6050
+ static Object* Runtime_RoundNumber(Arguments args) {
4500
6051
  NoHandleAllocation ha;
4501
6052
  ASSERT(args.length() == 1);
6053
+ Counters::math_round.Increment();
4502
6054
 
4503
- CONVERT_DOUBLE_CHECKED(x, args[0]);
4504
- if (signbit(x) && x >= -0.5) return Heap::minus_zero_value();
4505
- return Heap::NumberFromDouble(floor(x + 0.5));
6055
+ if (!args[0]->IsHeapNumber()) {
6056
+ // Must be smi. Return the argument unchanged for all the other types
6057
+ // to make fuzz-natives test happy.
6058
+ return args[0];
6059
+ }
6060
+
6061
+ HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
6062
+
6063
+ double value = number->value();
6064
+ int exponent = number->get_exponent();
6065
+ int sign = number->get_sign();
6066
+
6067
+ // We compare with kSmiValueSize - 3 because (2^30 - 0.1) has exponent 29 and
6068
+ // should be rounded to 2^30, which is not smi.
6069
+ if (!sign && exponent <= kSmiValueSize - 3) {
6070
+ return Smi::FromInt(static_cast<int>(value + 0.5));
6071
+ }
6072
+
6073
+ // If the magnitude is big enough, there's no place for fraction part. If we
6074
+ // try to add 0.5 to this number, 1.0 will be added instead.
6075
+ if (exponent >= 52) {
6076
+ return number;
6077
+ }
6078
+
6079
+ if (sign && value >= -0.5) return Heap::minus_zero_value();
6080
+
6081
+ // Do not call NumberFromDouble() to avoid extra checks.
6082
+ return Heap::AllocateHeapNumber(floor(value + 0.5));
4506
6083
  }
4507
6084
 
4508
6085
 
4509
6086
  static Object* Runtime_Math_sin(Arguments args) {
4510
6087
  NoHandleAllocation ha;
4511
6088
  ASSERT(args.length() == 1);
6089
+ Counters::math_sin.Increment();
4512
6090
 
4513
6091
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4514
6092
  return TranscendentalCache::Get(TranscendentalCache::SIN, x);
@@ -4518,6 +6096,7 @@ static Object* Runtime_Math_sin(Arguments args) {
4518
6096
  static Object* Runtime_Math_sqrt(Arguments args) {
4519
6097
  NoHandleAllocation ha;
4520
6098
  ASSERT(args.length() == 1);
6099
+ Counters::math_sqrt.Increment();
4521
6100
 
4522
6101
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4523
6102
  return Heap::AllocateHeapNumber(sqrt(x));
@@ -4527,42 +6106,372 @@ static Object* Runtime_Math_sqrt(Arguments args) {
4527
6106
  static Object* Runtime_Math_tan(Arguments args) {
4528
6107
  NoHandleAllocation ha;
4529
6108
  ASSERT(args.length() == 1);
6109
+ Counters::math_tan.Increment();
4530
6110
 
4531
6111
  CONVERT_DOUBLE_CHECKED(x, args[0]);
4532
6112
  return TranscendentalCache::Get(TranscendentalCache::TAN, x);
4533
6113
  }
4534
6114
 
4535
6115
 
4536
- // The NewArguments function is only used when constructing the
4537
- // arguments array when calling non-functions from JavaScript in
4538
- // runtime.js:CALL_NON_FUNCTION.
4539
- static Object* Runtime_NewArguments(Arguments args) {
6116
+ static int MakeDay(int year, int month, int day) {
6117
+ static const int day_from_month[] = {0, 31, 59, 90, 120, 151,
6118
+ 181, 212, 243, 273, 304, 334};
6119
+ static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152,
6120
+ 182, 213, 244, 274, 305, 335};
6121
+
6122
+ year += month / 12;
6123
+ month %= 12;
6124
+ if (month < 0) {
6125
+ year--;
6126
+ month += 12;
6127
+ }
6128
+
6129
+ ASSERT(month >= 0);
6130
+ ASSERT(month < 12);
6131
+
6132
+ // year_delta is an arbitrary number such that:
6133
+ // a) year_delta = -1 (mod 400)
6134
+ // b) year + year_delta > 0 for years in the range defined by
6135
+ // ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of
6136
+ // Jan 1 1970. This is required so that we don't run into integer
6137
+ // division of negative numbers.
6138
+ // c) there shouldn't be an overflow for 32-bit integers in the following
6139
+ // operations.
6140
+ static const int year_delta = 399999;
6141
+ static const int base_day = 365 * (1970 + year_delta) +
6142
+ (1970 + year_delta) / 4 -
6143
+ (1970 + year_delta) / 100 +
6144
+ (1970 + year_delta) / 400;
6145
+
6146
+ int year1 = year + year_delta;
6147
+ int day_from_year = 365 * year1 +
6148
+ year1 / 4 -
6149
+ year1 / 100 +
6150
+ year1 / 400 -
6151
+ base_day;
6152
+
6153
+ if (year % 4 || (year % 100 == 0 && year % 400 != 0)) {
6154
+ return day_from_year + day_from_month[month] + day - 1;
6155
+ }
6156
+
6157
+ return day_from_year + day_from_month_leap[month] + day - 1;
6158
+ }
6159
+
6160
+
6161
+ static Object* Runtime_DateMakeDay(Arguments args) {
4540
6162
  NoHandleAllocation ha;
4541
- ASSERT(args.length() == 1);
6163
+ ASSERT(args.length() == 3);
4542
6164
 
4543
- // ECMA-262, 3rd., 10.1.8, p.39
4544
- CONVERT_CHECKED(JSFunction, callee, args[0]);
6165
+ CONVERT_SMI_CHECKED(year, args[0]);
6166
+ CONVERT_SMI_CHECKED(month, args[1]);
6167
+ CONVERT_SMI_CHECKED(date, args[2]);
6168
+
6169
+ return Smi::FromInt(MakeDay(year, month, date));
6170
+ }
6171
+
6172
+
6173
+ static const int kDays4Years[] = {0, 365, 2 * 365, 3 * 365 + 1};
6174
+ static const int kDaysIn4Years = 4 * 365 + 1;
6175
+ static const int kDaysIn100Years = 25 * kDaysIn4Years - 1;
6176
+ static const int kDaysIn400Years = 4 * kDaysIn100Years + 1;
6177
+ static const int kDays1970to2000 = 30 * 365 + 7;
6178
+ static const int kDaysOffset = 1000 * kDaysIn400Years + 5 * kDaysIn400Years -
6179
+ kDays1970to2000;
6180
+ static const int kYearsOffset = 400000;
6181
+
6182
+ static const char kDayInYear[] = {
6183
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6184
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6185
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6186
+ 22, 23, 24, 25, 26, 27, 28,
6187
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6188
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6189
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6190
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6191
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6192
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6193
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6194
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6195
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6196
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6197
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6198
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6199
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6200
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6201
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6202
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6203
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6204
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6205
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6206
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6207
+
6208
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6209
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6210
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6211
+ 22, 23, 24, 25, 26, 27, 28,
6212
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6213
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6214
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6215
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6216
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6217
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6218
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6219
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6220
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6221
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6222
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6223
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6224
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6225
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6226
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6227
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6228
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6229
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6230
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6231
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6232
+
6233
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6234
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6235
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6236
+ 22, 23, 24, 25, 26, 27, 28, 29,
6237
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6238
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6239
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6240
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6241
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6242
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6243
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6244
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6245
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6246
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6247
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6248
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6249
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6250
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6251
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6252
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6253
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6254
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6255
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6256
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6257
+
6258
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6259
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6260
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6261
+ 22, 23, 24, 25, 26, 27, 28,
6262
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6263
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6264
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6265
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6266
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6267
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6268
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6269
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6270
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6271
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6272
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6273
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6274
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6275
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6276
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6277
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
6278
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6279
+ 22, 23, 24, 25, 26, 27, 28, 29, 30,
6280
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
6281
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
6282
+
6283
+ static const char kMonthInYear[] = {
6284
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6285
+ 0, 0, 0, 0, 0, 0,
6286
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6287
+ 1, 1, 1,
6288
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
6289
+ 2, 2, 2, 2, 2, 2,
6290
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6291
+ 3, 3, 3, 3, 3,
6292
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
6293
+ 4, 4, 4, 4, 4, 4,
6294
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6295
+ 5, 5, 5, 5, 5,
6296
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6297
+ 6, 6, 6, 6, 6, 6,
6298
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
6299
+ 7, 7, 7, 7, 7, 7,
6300
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
6301
+ 8, 8, 8, 8, 8,
6302
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
6303
+ 9, 9, 9, 9, 9, 9,
6304
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6305
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6306
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
6307
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
6308
+
6309
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6310
+ 0, 0, 0, 0, 0, 0,
6311
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6312
+ 1, 1, 1,
6313
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
6314
+ 2, 2, 2, 2, 2, 2,
6315
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6316
+ 3, 3, 3, 3, 3,
6317
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
6318
+ 4, 4, 4, 4, 4, 4,
6319
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6320
+ 5, 5, 5, 5, 5,
6321
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6322
+ 6, 6, 6, 6, 6, 6,
6323
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
6324
+ 7, 7, 7, 7, 7, 7,
6325
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
6326
+ 8, 8, 8, 8, 8,
6327
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
6328
+ 9, 9, 9, 9, 9, 9,
6329
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6330
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6331
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
6332
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
6333
+
6334
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6335
+ 0, 0, 0, 0, 0, 0,
6336
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6337
+ 1, 1, 1, 1,
6338
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
6339
+ 2, 2, 2, 2, 2, 2,
6340
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6341
+ 3, 3, 3, 3, 3,
6342
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
6343
+ 4, 4, 4, 4, 4, 4,
6344
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6345
+ 5, 5, 5, 5, 5,
6346
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6347
+ 6, 6, 6, 6, 6, 6,
6348
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
6349
+ 7, 7, 7, 7, 7, 7,
6350
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
6351
+ 8, 8, 8, 8, 8,
6352
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
6353
+ 9, 9, 9, 9, 9, 9,
6354
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6355
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6356
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
6357
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
6358
+
6359
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6360
+ 0, 0, 0, 0, 0, 0,
6361
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6362
+ 1, 1, 1,
6363
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
6364
+ 2, 2, 2, 2, 2, 2,
6365
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6366
+ 3, 3, 3, 3, 3,
6367
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
6368
+ 4, 4, 4, 4, 4, 4,
6369
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6370
+ 5, 5, 5, 5, 5,
6371
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6372
+ 6, 6, 6, 6, 6, 6,
6373
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
6374
+ 7, 7, 7, 7, 7, 7,
6375
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
6376
+ 8, 8, 8, 8, 8,
6377
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
6378
+ 9, 9, 9, 9, 9, 9,
6379
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6380
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
6381
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
6382
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11};
6383
+
6384
+
6385
+ // This function works for dates from 1970 to 2099.
6386
+ static inline void DateYMDFromTimeAfter1970(int date,
6387
+ int& year, int& month, int& day) {
6388
+ #ifdef DEBUG
6389
+ int save_date = date; // Need this for ASSERT in the end.
6390
+ #endif
4545
6391
 
4546
- // Compute the frame holding the arguments.
4547
- JavaScriptFrameIterator it;
4548
- it.AdvanceToArgumentsFrame();
4549
- JavaScriptFrame* frame = it.frame();
6392
+ year = 1970 + (4 * date + 2) / kDaysIn4Years;
6393
+ date %= kDaysIn4Years;
4550
6394
 
4551
- const int length = frame->GetProvidedParametersCount();
4552
- Object* result = Heap::AllocateArgumentsObject(callee, length);
4553
- if (result->IsFailure()) return result;
4554
- if (length > 0) {
4555
- Object* obj = Heap::AllocateFixedArray(length);
4556
- if (obj->IsFailure()) return obj;
4557
- FixedArray* array = FixedArray::cast(obj);
4558
- ASSERT(array->length() == length);
4559
- WriteBarrierMode mode = array->GetWriteBarrierMode();
4560
- for (int i = 0; i < length; i++) {
4561
- array->set(i, frame->GetParameter(i), mode);
4562
- }
4563
- JSObject::cast(result)->set_elements(array);
6395
+ month = kMonthInYear[date];
6396
+ day = kDayInYear[date];
6397
+
6398
+ ASSERT(MakeDay(year, month, day) == save_date);
6399
+ }
6400
+
6401
+
6402
+ static inline void DateYMDFromTimeSlow(int date,
6403
+ int& year, int& month, int& day) {
6404
+ #ifdef DEBUG
6405
+ int save_date = date; // Need this for ASSERT in the end.
6406
+ #endif
6407
+
6408
+ date += kDaysOffset;
6409
+ year = 400 * (date / kDaysIn400Years) - kYearsOffset;
6410
+ date %= kDaysIn400Years;
6411
+
6412
+ ASSERT(MakeDay(year, 0, 1) + date == save_date);
6413
+
6414
+ date--;
6415
+ int yd1 = date / kDaysIn100Years;
6416
+ date %= kDaysIn100Years;
6417
+ year += 100 * yd1;
6418
+
6419
+ date++;
6420
+ int yd2 = date / kDaysIn4Years;
6421
+ date %= kDaysIn4Years;
6422
+ year += 4 * yd2;
6423
+
6424
+ date--;
6425
+ int yd3 = date / 365;
6426
+ date %= 365;
6427
+ year += yd3;
6428
+
6429
+ bool is_leap = (!yd1 || yd2) && !yd3;
6430
+
6431
+ ASSERT(date >= -1);
6432
+ ASSERT(is_leap || (date >= 0));
6433
+ ASSERT((date < 365) || (is_leap && (date < 366)));
6434
+ ASSERT(is_leap == ((year % 4 == 0) && (year % 100 || (year % 400 == 0))));
6435
+ ASSERT(is_leap || ((MakeDay(year, 0, 1) + date) == save_date));
6436
+ ASSERT(!is_leap || ((MakeDay(year, 0, 1) + date + 1) == save_date));
6437
+
6438
+ if (is_leap) {
6439
+ day = kDayInYear[2*365 + 1 + date];
6440
+ month = kMonthInYear[2*365 + 1 + date];
6441
+ } else {
6442
+ day = kDayInYear[date];
6443
+ month = kMonthInYear[date];
4564
6444
  }
4565
- return result;
6445
+
6446
+ ASSERT(MakeDay(year, month, day) == save_date);
6447
+ }
6448
+
6449
+
6450
+ static inline void DateYMDFromTime(int date,
6451
+ int& year, int& month, int& day) {
6452
+ if (date >= 0 && date < 32 * kDaysIn4Years) {
6453
+ DateYMDFromTimeAfter1970(date, year, month, day);
6454
+ } else {
6455
+ DateYMDFromTimeSlow(date, year, month, day);
6456
+ }
6457
+ }
6458
+
6459
+
6460
+ static Object* Runtime_DateYMDFromTime(Arguments args) {
6461
+ NoHandleAllocation ha;
6462
+ ASSERT(args.length() == 2);
6463
+
6464
+ CONVERT_DOUBLE_CHECKED(t, args[0]);
6465
+ CONVERT_CHECKED(JSArray, res_array, args[1]);
6466
+
6467
+ int year, month, day;
6468
+ DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day);
6469
+
6470
+ res_array->SetElement(0, Smi::FromInt(year));
6471
+ res_array->SetElement(1, Smi::FromInt(month));
6472
+ res_array->SetElement(2, Smi::FromInt(day));
6473
+
6474
+ return Heap::undefined_value();
4566
6475
  }
4567
6476
 
4568
6477
 
@@ -4581,10 +6490,13 @@ static Object* Runtime_NewArgumentsFast(Arguments args) {
4581
6490
  // Allocate the fixed array.
4582
6491
  Object* obj = Heap::AllocateRawFixedArray(length);
4583
6492
  if (obj->IsFailure()) return obj;
6493
+
6494
+ AssertNoAllocation no_gc;
4584
6495
  reinterpret_cast<Array*>(obj)->set_map(Heap::fixed_array_map());
4585
6496
  FixedArray* array = FixedArray::cast(obj);
4586
6497
  array->set_length(length);
4587
- WriteBarrierMode mode = array->GetWriteBarrierMode();
6498
+
6499
+ WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
4588
6500
  for (int i = 0; i < length; i++) {
4589
6501
  array->set(i, *--parameters, mode);
4590
6502
  }
@@ -4598,32 +6510,32 @@ static Object* Runtime_NewClosure(Arguments args) {
4598
6510
  HandleScope scope;
4599
6511
  ASSERT(args.length() == 2);
4600
6512
  CONVERT_ARG_CHECKED(Context, context, 0);
4601
- CONVERT_ARG_CHECKED(JSFunction, boilerplate, 1);
6513
+ CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
4602
6514
 
4603
6515
  PretenureFlag pretenure = (context->global_context() == *context)
4604
6516
  ? TENURED // Allocate global closures in old space.
4605
6517
  : NOT_TENURED; // Allocate local closures in new space.
4606
6518
  Handle<JSFunction> result =
4607
- Factory::NewFunctionFromBoilerplate(boilerplate, context, pretenure);
6519
+ Factory::NewFunctionFromSharedFunctionInfo(shared, context, pretenure);
4608
6520
  return *result;
4609
6521
  }
4610
6522
 
4611
6523
 
4612
- static Code* ComputeConstructStub(Handle<SharedFunctionInfo> shared) {
4613
- // TODO(385): Change this to create a construct stub specialized for
4614
- // the given map to make allocation of simple objects - and maybe
4615
- // arrays - much faster.
4616
- if (FLAG_inline_new
4617
- && shared->has_only_simple_this_property_assignments()) {
6524
+ static Code* ComputeConstructStub(Handle<JSFunction> function) {
6525
+ Handle<Object> prototype = Factory::null_value();
6526
+ if (function->has_instance_prototype()) {
6527
+ prototype = Handle<Object>(function->instance_prototype());
6528
+ }
6529
+ if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
4618
6530
  ConstructStubCompiler compiler;
4619
- Object* code = compiler.CompileConstructStub(*shared);
6531
+ Object* code = compiler.CompileConstructStub(function->shared());
4620
6532
  if (code->IsFailure()) {
4621
6533
  return Builtins::builtin(Builtins::JSConstructStubGeneric);
4622
6534
  }
4623
6535
  return Code::cast(code);
4624
6536
  }
4625
6537
 
4626
- return Builtins::builtin(Builtins::JSConstructStubGeneric);
6538
+ return function->shared()->construct_stub();
4627
6539
  }
4628
6540
 
4629
6541
 
@@ -4642,6 +6554,16 @@ static Object* Runtime_NewObject(Arguments args) {
4642
6554
  }
4643
6555
 
4644
6556
  Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
6557
+
6558
+ // If function should not have prototype, construction is not allowed. In this
6559
+ // case generated code bailouts here, since function has no initial_map.
6560
+ if (!function->should_have_prototype()) {
6561
+ Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
6562
+ Handle<Object> type_error =
6563
+ Factory::NewTypeError("not_constructor", arguments);
6564
+ return Top::Throw(*type_error);
6565
+ }
6566
+
4645
6567
  #ifdef ENABLE_DEBUGGER_SUPPORT
4646
6568
  // Handle stepping into constructors if step into is active.
4647
6569
  if (Debug::StepInActive()) {
@@ -4667,19 +6589,15 @@ static Object* Runtime_NewObject(Arguments args) {
4667
6589
  }
4668
6590
 
4669
6591
  // The function should be compiled for the optimization hints to be available.
4670
- if (!function->shared()->is_compiled()) {
4671
- CompileLazyShared(Handle<SharedFunctionInfo>(function->shared()),
4672
- CLEAR_EXCEPTION,
4673
- 0);
4674
- }
6592
+ Handle<SharedFunctionInfo> shared(function->shared());
6593
+ EnsureCompiled(shared, CLEAR_EXCEPTION);
4675
6594
 
4676
6595
  bool first_allocation = !function->has_initial_map();
4677
6596
  Handle<JSObject> result = Factory::NewJSObject(function);
4678
6597
  if (first_allocation) {
4679
- Handle<Map> map = Handle<Map>(function->initial_map());
4680
6598
  Handle<Code> stub = Handle<Code>(
4681
- ComputeConstructStub(Handle<SharedFunctionInfo>(function->shared())));
4682
- function->shared()->set_construct_stub(*stub);
6599
+ ComputeConstructStub(Handle<JSFunction>(function)));
6600
+ shared->set_construct_stub(*stub);
4683
6601
  }
4684
6602
 
4685
6603
  Counters::constructed_objects.Increment();
@@ -4710,7 +6628,7 @@ static Object* Runtime_LazyCompile(Arguments args) {
4710
6628
  // this means that things called through constructors are never known to
4711
6629
  // be in loops. We compile them as if they are in loops here just in case.
4712
6630
  ASSERT(!function->is_compiled());
4713
- if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) {
6631
+ if (!CompileLazyInLoop(function, Handle<Object>::null(), KEEP_EXCEPTION)) {
4714
6632
  return Failure::Exception();
4715
6633
  }
4716
6634
 
@@ -4718,28 +6636,6 @@ static Object* Runtime_LazyCompile(Arguments args) {
4718
6636
  }
4719
6637
 
4720
6638
 
4721
- static Object* Runtime_GetCalledFunction(Arguments args) {
4722
- HandleScope scope;
4723
- ASSERT(args.length() == 0);
4724
- StackFrameIterator it;
4725
- // Get past the JS-to-C exit frame.
4726
- ASSERT(it.frame()->is_exit());
4727
- it.Advance();
4728
- // Get past the CALL_NON_FUNCTION activation frame.
4729
- ASSERT(it.frame()->is_java_script());
4730
- it.Advance();
4731
- // Argument adaptor frames do not copy the function; we have to skip
4732
- // past them to get to the real calling frame.
4733
- if (it.frame()->is_arguments_adaptor()) it.Advance();
4734
- // Get the function from the top of the expression stack of the
4735
- // calling frame.
4736
- StandardFrame* frame = StandardFrame::cast(it.frame());
4737
- int index = frame->ComputeExpressionsCount() - 1;
4738
- Object* result = frame->GetExpression(index);
4739
- return result;
4740
- }
4741
-
4742
-
4743
6639
  static Object* Runtime_GetFunctionDelegate(Arguments args) {
4744
6640
  HandleScope scope;
4745
6641
  ASSERT(args.length() == 1);
@@ -5190,6 +7086,7 @@ static Object* Runtime_DebugPrint(Arguments args) {
5190
7086
  }
5191
7087
  args[0]->Print();
5192
7088
  if (args[0]->IsHeapObject()) {
7089
+ PrintF("\n");
5193
7090
  HeapObject::cast(args[0])->map()->Print();
5194
7091
  }
5195
7092
  #else
@@ -5281,21 +7178,6 @@ static Object* Runtime_DateDaylightSavingsOffset(Arguments args) {
5281
7178
  }
5282
7179
 
5283
7180
 
5284
- static Object* Runtime_NumberIsFinite(Arguments args) {
5285
- NoHandleAllocation ha;
5286
- ASSERT(args.length() == 1);
5287
-
5288
- CONVERT_DOUBLE_CHECKED(value, args[0]);
5289
- Object* result;
5290
- if (isnan(value) || (fpclassify(value) == FP_INFINITE)) {
5291
- result = Heap::false_value();
5292
- } else {
5293
- result = Heap::true_value();
5294
- }
5295
- return result;
5296
- }
5297
-
5298
-
5299
7181
  static Object* Runtime_GlobalReceiver(Arguments args) {
5300
7182
  ASSERT(args.length() == 1);
5301
7183
  Object* global = args[0];
@@ -5314,13 +7196,13 @@ static Object* Runtime_CompileString(Arguments args) {
5314
7196
  Handle<Context> context(Top::context()->global_context());
5315
7197
  Compiler::ValidationState validate = (is_json->IsTrue())
5316
7198
  ? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON;
5317
- Handle<JSFunction> boilerplate = Compiler::CompileEval(source,
5318
- context,
5319
- true,
5320
- validate);
5321
- if (boilerplate.is_null()) return Failure::Exception();
7199
+ Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
7200
+ context,
7201
+ true,
7202
+ validate);
7203
+ if (shared.is_null()) return Failure::Exception();
5322
7204
  Handle<JSFunction> fun =
5323
- Factory::NewFunctionFromBoilerplate(boilerplate, context, NOT_TENURED);
7205
+ Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED);
5324
7206
  return *fun;
5325
7207
  }
5326
7208
 
@@ -5393,14 +7275,14 @@ static ObjectPair Runtime_ResolvePossiblyDirectEval(Arguments args) {
5393
7275
  // Deal with a normal eval call with a string argument. Compile it
5394
7276
  // and return the compiled function bound in the local context.
5395
7277
  Handle<String> source = args.at<String>(1);
5396
- Handle<JSFunction> boilerplate = Compiler::CompileEval(
7278
+ Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
5397
7279
  source,
5398
7280
  Handle<Context>(Top::context()),
5399
7281
  Top::context()->IsGlobalContext(),
5400
7282
  Compiler::DONT_VALIDATE_JSON);
5401
- if (boilerplate.is_null()) return MakePair(Failure::Exception(), NULL);
5402
- callee = Factory::NewFunctionFromBoilerplate(
5403
- boilerplate,
7283
+ if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
7284
+ callee = Factory::NewFunctionFromSharedFunctionInfo(
7285
+ shared,
5404
7286
  Handle<Context>(Top::context()),
5405
7287
  NOT_TENURED);
5406
7288
  return MakePair(*callee, args[2]);
@@ -5872,7 +7754,7 @@ static Object* Runtime_MoveArrayContents(Arguments args) {
5872
7754
  to->SetContent(FixedArray::cast(from->elements()));
5873
7755
  to->set_length(from->length());
5874
7756
  from->SetContent(Heap::empty_fixed_array());
5875
- from->set_length(0);
7757
+ from->set_length(Smi::FromInt(0));
5876
7758
  return to;
5877
7759
  }
5878
7760
 
@@ -5890,6 +7772,32 @@ static Object* Runtime_EstimateNumberOfElements(Arguments args) {
5890
7772
  }
5891
7773
 
5892
7774
 
7775
+ static Object* Runtime_SwapElements(Arguments args) {
7776
+ HandleScope handle_scope;
7777
+
7778
+ ASSERT_EQ(3, args.length());
7779
+
7780
+ CONVERT_ARG_CHECKED(JSObject, object, 0);
7781
+ Handle<Object> key1 = args.at<Object>(1);
7782
+ Handle<Object> key2 = args.at<Object>(2);
7783
+
7784
+ uint32_t index1, index2;
7785
+ if (!Array::IndexFromObject(*key1, &index1)
7786
+ || !Array::IndexFromObject(*key2, &index2)) {
7787
+ return Top::ThrowIllegalOperation();
7788
+ }
7789
+
7790
+ Handle<JSObject> jsobject = Handle<JSObject>::cast(object);
7791
+ Handle<Object> tmp1 = GetElement(jsobject, index1);
7792
+ Handle<Object> tmp2 = GetElement(jsobject, index2);
7793
+
7794
+ SetElement(jsobject, index1, tmp2);
7795
+ SetElement(jsobject, index2, tmp1);
7796
+
7797
+ return Heap::undefined_value();
7798
+ }
7799
+
7800
+
5893
7801
  // Returns an array that tells you where in the [0, length) interval an array
5894
7802
  // might have elements. Can either return keys or intervals. Keys can have
5895
7803
  // gaps in (undefined). Intervals can also span over some undefined keys.
@@ -5915,9 +7823,7 @@ static Object* Runtime_GetArrayKeys(Arguments args) {
5915
7823
  } else {
5916
7824
  Handle<FixedArray> single_interval = Factory::NewFixedArray(2);
5917
7825
  // -1 means start of array.
5918
- single_interval->set(0,
5919
- Smi::FromInt(-1),
5920
- SKIP_WRITE_BARRIER);
7826
+ single_interval->set(0, Smi::FromInt(-1));
5921
7827
  uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
5922
7828
  uint32_t min_length = actual_length < length ? actual_length : length;
5923
7829
  Handle<Object> length_object =
@@ -6005,21 +7911,6 @@ static Object* Runtime_Break(Arguments args) {
6005
7911
  }
6006
7912
 
6007
7913
 
6008
- // Find the length of the prototype chain that is to to handled as one. If a
6009
- // prototype object is hidden it is to be viewed as part of the the object it
6010
- // is prototype for.
6011
- static int LocalPrototypeChainLength(JSObject* obj) {
6012
- int count = 1;
6013
- Object* proto = obj->GetPrototype();
6014
- while (proto->IsJSObject() &&
6015
- JSObject::cast(proto)->map()->is_hidden_prototype()) {
6016
- count++;
6017
- proto = JSObject::cast(proto)->GetPrototype();
6018
- }
6019
- return count;
6020
- }
6021
-
6022
-
6023
7914
  static Object* DebugLookupResultValue(Object* receiver, String* name,
6024
7915
  LookupResult* result,
6025
7916
  bool* caught_exception) {
@@ -6145,134 +8036,47 @@ static Object* Runtime_DebugGetPropertyDetails(Arguments args) {
6145
8036
  if (raw_value->IsFailure()) return raw_value;
6146
8037
  Handle<Object> value(raw_value);
6147
8038
 
6148
- // If the callback object is a fixed array then it contains JavaScript
6149
- // getter and/or setter.
6150
- bool hasJavaScriptAccessors = result_type == CALLBACKS &&
6151
- result_callback_obj->IsFixedArray();
6152
- Handle<FixedArray> details =
6153
- Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
6154
- details->set(0, *value);
6155
- details->set(1, property_details);
6156
- if (hasJavaScriptAccessors) {
6157
- details->set(2,
6158
- caught_exception ? Heap::true_value()
6159
- : Heap::false_value());
6160
- details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
6161
- details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
6162
- }
6163
-
6164
- return *Factory::NewJSArrayWithElements(details);
6165
- }
6166
- if (i < length - 1) {
6167
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
6168
- }
6169
- }
6170
-
6171
- return Heap::undefined_value();
6172
- }
6173
-
6174
-
6175
- static Object* Runtime_DebugGetProperty(Arguments args) {
6176
- HandleScope scope;
6177
-
6178
- ASSERT(args.length() == 2);
6179
-
6180
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
6181
- CONVERT_ARG_CHECKED(String, name, 1);
6182
-
6183
- LookupResult result;
6184
- obj->Lookup(*name, &result);
6185
- if (result.IsProperty()) {
6186
- return DebugLookupResultValue(*obj, *name, &result, NULL);
6187
- }
6188
- return Heap::undefined_value();
6189
- }
6190
-
6191
-
6192
- // Return the names of the local named properties.
6193
- // args[0]: object
6194
- static Object* Runtime_DebugLocalPropertyNames(Arguments args) {
6195
- HandleScope scope;
6196
- ASSERT(args.length() == 1);
6197
- if (!args[0]->IsJSObject()) {
6198
- return Heap::undefined_value();
6199
- }
6200
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
6201
-
6202
- // Skip the global proxy as it has no properties and always delegates to the
6203
- // real global object.
6204
- if (obj->IsJSGlobalProxy()) {
6205
- obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
6206
- }
6207
-
6208
- // Find the number of objects making up this.
6209
- int length = LocalPrototypeChainLength(*obj);
6210
-
6211
- // Find the number of local properties for each of the objects.
6212
- int* local_property_count = NewArray<int>(length);
6213
- int total_property_count = 0;
6214
- Handle<JSObject> jsproto = obj;
6215
- for (int i = 0; i < length; i++) {
6216
- int n;
6217
- n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
6218
- local_property_count[i] = n;
6219
- total_property_count += n;
6220
- if (i < length - 1) {
6221
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
6222
- }
6223
- }
6224
-
6225
- // Allocate an array with storage for all the property names.
6226
- Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
8039
+ // If the callback object is a fixed array then it contains JavaScript
8040
+ // getter and/or setter.
8041
+ bool hasJavaScriptAccessors = result_type == CALLBACKS &&
8042
+ result_callback_obj->IsFixedArray();
8043
+ Handle<FixedArray> details =
8044
+ Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
8045
+ details->set(0, *value);
8046
+ details->set(1, property_details);
8047
+ if (hasJavaScriptAccessors) {
8048
+ details->set(2,
8049
+ caught_exception ? Heap::true_value()
8050
+ : Heap::false_value());
8051
+ details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
8052
+ details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
8053
+ }
6227
8054
 
6228
- // Get the property names.
6229
- jsproto = obj;
6230
- int proto_with_hidden_properties = 0;
6231
- for (int i = 0; i < length; i++) {
6232
- jsproto->GetLocalPropertyNames(*names,
6233
- i == 0 ? 0 : local_property_count[i - 1]);
6234
- if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
6235
- proto_with_hidden_properties++;
8055
+ return *Factory::NewJSArrayWithElements(details);
6236
8056
  }
6237
8057
  if (i < length - 1) {
6238
8058
  jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
6239
8059
  }
6240
8060
  }
6241
8061
 
6242
- // Filter out name of hidden propeties object.
6243
- if (proto_with_hidden_properties > 0) {
6244
- Handle<FixedArray> old_names = names;
6245
- names = Factory::NewFixedArray(
6246
- names->length() - proto_with_hidden_properties);
6247
- int dest_pos = 0;
6248
- for (int i = 0; i < total_property_count; i++) {
6249
- Object* name = old_names->get(i);
6250
- if (name == Heap::hidden_symbol()) {
6251
- continue;
6252
- }
6253
- names->set(dest_pos++, name);
6254
- }
6255
- }
6256
-
6257
- DeleteArray(local_property_count);
6258
- return *Factory::NewJSArrayWithElements(names);
8062
+ return Heap::undefined_value();
6259
8063
  }
6260
8064
 
6261
8065
 
6262
- // Return the names of the local indexed properties.
6263
- // args[0]: object
6264
- static Object* Runtime_DebugLocalElementNames(Arguments args) {
8066
+ static Object* Runtime_DebugGetProperty(Arguments args) {
6265
8067
  HandleScope scope;
6266
- ASSERT(args.length() == 1);
6267
- if (!args[0]->IsJSObject()) {
6268
- return Heap::undefined_value();
6269
- }
8068
+
8069
+ ASSERT(args.length() == 2);
8070
+
6270
8071
  CONVERT_ARG_CHECKED(JSObject, obj, 0);
8072
+ CONVERT_ARG_CHECKED(String, name, 1);
6271
8073
 
6272
- int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
6273
- Handle<FixedArray> names = Factory::NewFixedArray(n);
6274
- obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
6275
- return *Factory::NewJSArrayWithElements(names);
8074
+ LookupResult result;
8075
+ obj->Lookup(*name, &result);
8076
+ if (result.IsProperty()) {
8077
+ return DebugLookupResultValue(*obj, *name, &result, NULL);
8078
+ }
8079
+ return Heap::undefined_value();
6276
8080
  }
6277
8081
 
6278
8082
 
@@ -6306,54 +8110,6 @@ static Object* Runtime_DebugPropertyIndexFromDetails(Arguments args) {
6306
8110
  }
6307
8111
 
6308
8112
 
6309
- // Return information on whether an object has a named or indexed interceptor.
6310
- // args[0]: object
6311
- static Object* Runtime_DebugInterceptorInfo(Arguments args) {
6312
- HandleScope scope;
6313
- ASSERT(args.length() == 1);
6314
- if (!args[0]->IsJSObject()) {
6315
- return Smi::FromInt(0);
6316
- }
6317
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
6318
-
6319
- int result = 0;
6320
- if (obj->HasNamedInterceptor()) result |= 2;
6321
- if (obj->HasIndexedInterceptor()) result |= 1;
6322
-
6323
- return Smi::FromInt(result);
6324
- }
6325
-
6326
-
6327
- // Return property names from named interceptor.
6328
- // args[0]: object
6329
- static Object* Runtime_DebugNamedInterceptorPropertyNames(Arguments args) {
6330
- HandleScope scope;
6331
- ASSERT(args.length() == 1);
6332
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
6333
-
6334
- if (obj->HasNamedInterceptor()) {
6335
- v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
6336
- if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
6337
- }
6338
- return Heap::undefined_value();
6339
- }
6340
-
6341
-
6342
- // Return element names from indexed interceptor.
6343
- // args[0]: object
6344
- static Object* Runtime_DebugIndexedInterceptorElementNames(Arguments args) {
6345
- HandleScope scope;
6346
- ASSERT(args.length() == 1);
6347
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
6348
-
6349
- if (obj->HasIndexedInterceptor()) {
6350
- v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
6351
- if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
6352
- }
6353
- return Heap::undefined_value();
6354
- }
6355
-
6356
-
6357
8113
  // Return property value from named interceptor.
6358
8114
  // args[0]: object
6359
8115
  // args[1]: property name
@@ -7202,9 +8958,8 @@ Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script,
7202
8958
  Handle<SharedFunctionInfo> last;
7203
8959
  while (!done) {
7204
8960
  HeapIterator iterator;
7205
- while (iterator.has_next()) {
7206
- HeapObject* obj = iterator.next();
7207
- ASSERT(obj != NULL);
8961
+ for (HeapObject* obj = iterator.next();
8962
+ obj != NULL; obj = iterator.next()) {
7208
8963
  if (obj->IsSharedFunctionInfo()) {
7209
8964
  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj));
7210
8965
  if (shared->script() == *script) {
@@ -7269,7 +9024,7 @@ Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script,
7269
9024
  if (!done) {
7270
9025
  // If the candidate is not compiled compile it to reveal any inner
7271
9026
  // functions which might contain the requested source position.
7272
- CompileLazyShared(target, KEEP_EXCEPTION, 0);
9027
+ CompileLazyShared(target, KEEP_EXCEPTION);
7273
9028
  }
7274
9029
  }
7275
9030
 
@@ -7441,7 +9196,9 @@ static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame,
7441
9196
  const int length = frame->GetProvidedParametersCount();
7442
9197
  Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length);
7443
9198
  Handle<FixedArray> array = Factory::NewFixedArray(length);
7444
- WriteBarrierMode mode = array->GetWriteBarrierMode();
9199
+
9200
+ AssertNoAllocation no_gc;
9201
+ WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
7445
9202
  for (int i = 0; i < length; i++) {
7446
9203
  array->set(i, frame->GetParameter(i), mode);
7447
9204
  }
@@ -7533,14 +9290,14 @@ static Object* Runtime_DebugEvaluate(Arguments args) {
7533
9290
  Handle<String> function_source =
7534
9291
  Factory::NewStringFromAscii(Vector<const char>(source_str,
7535
9292
  source_str_length));
7536
- Handle<JSFunction> boilerplate =
9293
+ Handle<SharedFunctionInfo> shared =
7537
9294
  Compiler::CompileEval(function_source,
7538
9295
  context,
7539
9296
  context->IsGlobalContext(),
7540
9297
  Compiler::DONT_VALIDATE_JSON);
7541
- if (boilerplate.is_null()) return Failure::Exception();
9298
+ if (shared.is_null()) return Failure::Exception();
7542
9299
  Handle<JSFunction> compiled_function =
7543
- Factory::NewFunctionFromBoilerplate(boilerplate, context);
9300
+ Factory::NewFunctionFromSharedFunctionInfo(shared, context);
7544
9301
 
7545
9302
  // Invoke the result of the compilation to get the evaluation function.
7546
9303
  bool has_pending_exception;
@@ -7601,15 +9358,15 @@ static Object* Runtime_DebugEvaluateGlobal(Arguments args) {
7601
9358
  Handle<Context> context = Top::global_context();
7602
9359
 
7603
9360
  // Compile the source to be evaluated.
7604
- Handle<JSFunction> boilerplate =
7605
- Handle<JSFunction>(Compiler::CompileEval(source,
7606
- context,
7607
- true,
7608
- Compiler::DONT_VALIDATE_JSON));
7609
- if (boilerplate.is_null()) return Failure::Exception();
9361
+ Handle<SharedFunctionInfo> shared =
9362
+ Compiler::CompileEval(source,
9363
+ context,
9364
+ true,
9365
+ Compiler::DONT_VALIDATE_JSON);
9366
+ if (shared.is_null()) return Failure::Exception();
7610
9367
  Handle<JSFunction> compiled_function =
7611
- Handle<JSFunction>(Factory::NewFunctionFromBoilerplate(boilerplate,
7612
- context));
9368
+ Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared,
9369
+ context));
7613
9370
 
7614
9371
  // Invoke the result of the compilation to get the evaluation function.
7615
9372
  bool has_pending_exception;
@@ -7660,10 +9417,10 @@ static int DebugReferencedBy(JSObject* target,
7660
9417
  int count = 0;
7661
9418
  JSObject* last = NULL;
7662
9419
  HeapIterator iterator;
7663
- while (iterator.has_next() &&
9420
+ HeapObject* heap_obj = NULL;
9421
+ while (((heap_obj = iterator.next()) != NULL) &&
7664
9422
  (max_references == 0 || count < max_references)) {
7665
9423
  // Only look at all JSObjects.
7666
- HeapObject* heap_obj = iterator.next();
7667
9424
  if (heap_obj->IsJSObject()) {
7668
9425
  // Skip context extension objects and argument arrays as these are
7669
9426
  // checked in the context of functions using them.
@@ -7773,10 +9530,10 @@ static int DebugConstructedBy(JSFunction* constructor, int max_references,
7773
9530
  // Iterate the heap.
7774
9531
  int count = 0;
7775
9532
  HeapIterator iterator;
7776
- while (iterator.has_next() &&
9533
+ HeapObject* heap_obj = NULL;
9534
+ while (((heap_obj = iterator.next()) != NULL) &&
7777
9535
  (max_references == 0 || count < max_references)) {
7778
9536
  // Only look at all JSObjects.
7779
- HeapObject* heap_obj = iterator.next();
7780
9537
  if (heap_obj->IsJSObject()) {
7781
9538
  JSObject* obj = JSObject::cast(heap_obj);
7782
9539
  if (obj->map()->constructor() == constructor) {
@@ -7855,7 +9612,8 @@ static Object* Runtime_DebugDisassembleFunction(Arguments args) {
7855
9612
  ASSERT(args.length() == 1);
7856
9613
  // Get the function and make sure it is compiled.
7857
9614
  CONVERT_ARG_CHECKED(JSFunction, func, 0);
7858
- if (!func->is_compiled() && !CompileLazy(func, KEEP_EXCEPTION)) {
9615
+ Handle<SharedFunctionInfo> shared(func->shared());
9616
+ if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
7859
9617
  return Failure::Exception();
7860
9618
  }
7861
9619
  func->code()->PrintLn();
@@ -7870,10 +9628,11 @@ static Object* Runtime_DebugDisassembleConstructor(Arguments args) {
7870
9628
  ASSERT(args.length() == 1);
7871
9629
  // Get the function and make sure it is compiled.
7872
9630
  CONVERT_ARG_CHECKED(JSFunction, func, 0);
7873
- if (!func->is_compiled() && !CompileLazy(func, KEEP_EXCEPTION)) {
9631
+ Handle<SharedFunctionInfo> shared(func->shared());
9632
+ if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
7874
9633
  return Failure::Exception();
7875
9634
  }
7876
- func->shared()->construct_stub()->PrintLn();
9635
+ shared->construct_stub()->PrintLn();
7877
9636
  #endif // DEBUG
7878
9637
  return Heap::undefined_value();
7879
9638
  }
@@ -7887,26 +9646,283 @@ static Object* Runtime_FunctionGetInferredName(Arguments args) {
7887
9646
  return f->shared()->inferred_name();
7888
9647
  }
7889
9648
 
9649
+
9650
+ static int FindSharedFunctionInfosForScript(Script* script,
9651
+ FixedArray* buffer) {
9652
+ AssertNoAllocation no_allocations;
9653
+
9654
+ int counter = 0;
9655
+ int buffer_size = buffer->length();
9656
+ HeapIterator iterator;
9657
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
9658
+ ASSERT(obj != NULL);
9659
+ if (!obj->IsSharedFunctionInfo()) {
9660
+ continue;
9661
+ }
9662
+ SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
9663
+ if (shared->script() != script) {
9664
+ continue;
9665
+ }
9666
+ if (counter < buffer_size) {
9667
+ buffer->set(counter, shared);
9668
+ }
9669
+ counter++;
9670
+ }
9671
+ return counter;
9672
+ }
9673
+
9674
+ // For a script finds all SharedFunctionInfo's in the heap that points
9675
+ // to this script. Returns JSArray of SharedFunctionInfo wrapped
9676
+ // in OpaqueReferences.
9677
+ static Object* Runtime_LiveEditFindSharedFunctionInfosForScript(
9678
+ Arguments args) {
9679
+ ASSERT(args.length() == 1);
9680
+ HandleScope scope;
9681
+ CONVERT_CHECKED(JSValue, script_value, args[0]);
9682
+
9683
+ Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
9684
+
9685
+ const int kBufferSize = 32;
9686
+
9687
+ Handle<FixedArray> array;
9688
+ array = Factory::NewFixedArray(kBufferSize);
9689
+ int number = FindSharedFunctionInfosForScript(*script, *array);
9690
+ if (number > kBufferSize) {
9691
+ array = Factory::NewFixedArray(number);
9692
+ FindSharedFunctionInfosForScript(*script, *array);
9693
+ }
9694
+
9695
+ Handle<JSArray> result = Factory::NewJSArrayWithElements(array);
9696
+ result->set_length(Smi::FromInt(number));
9697
+
9698
+ LiveEdit::WrapSharedFunctionInfos(result);
9699
+
9700
+ return *result;
9701
+ }
9702
+
9703
+ // For a script calculates compilation information about all its functions.
9704
+ // The script source is explicitly specified by the second argument.
9705
+ // The source of the actual script is not used, however it is important that
9706
+ // all generated code keeps references to this particular instance of script.
9707
+ // Returns a JSArray of compilation infos. The array is ordered so that
9708
+ // each function with all its descendant is always stored in a continues range
9709
+ // with the function itself going first. The root function is a script function.
9710
+ static Object* Runtime_LiveEditGatherCompileInfo(Arguments args) {
9711
+ ASSERT(args.length() == 2);
9712
+ HandleScope scope;
9713
+ CONVERT_CHECKED(JSValue, script, args[0]);
9714
+ CONVERT_ARG_CHECKED(String, source, 1);
9715
+ Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
9716
+
9717
+ JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source);
9718
+
9719
+ if (Top::has_pending_exception()) {
9720
+ return Failure::Exception();
9721
+ }
9722
+
9723
+ return result;
9724
+ }
9725
+
9726
+ // Changes the source of the script to a new_source.
9727
+ // If old_script_name is provided (i.e. is a String), also creates a copy of
9728
+ // the script with its original source and sends notification to debugger.
9729
+ static Object* Runtime_LiveEditReplaceScript(Arguments args) {
9730
+ ASSERT(args.length() == 3);
9731
+ HandleScope scope;
9732
+ CONVERT_CHECKED(JSValue, original_script_value, args[0]);
9733
+ CONVERT_ARG_CHECKED(String, new_source, 1);
9734
+ Handle<Object> old_script_name(args[2]);
9735
+
9736
+ CONVERT_CHECKED(Script, original_script_pointer,
9737
+ original_script_value->value());
9738
+ Handle<Script> original_script(original_script_pointer);
9739
+
9740
+ Object* old_script = LiveEdit::ChangeScriptSource(original_script,
9741
+ new_source,
9742
+ old_script_name);
9743
+
9744
+ if (old_script->IsScript()) {
9745
+ Handle<Script> script_handle(Script::cast(old_script));
9746
+ return *(GetScriptWrapper(script_handle));
9747
+ } else {
9748
+ return Heap::null_value();
9749
+ }
9750
+ }
9751
+
9752
+ // Replaces code of SharedFunctionInfo with a new one.
9753
+ static Object* Runtime_LiveEditReplaceFunctionCode(Arguments args) {
9754
+ ASSERT(args.length() == 2);
9755
+ HandleScope scope;
9756
+ CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0);
9757
+ CONVERT_ARG_CHECKED(JSArray, shared_info, 1);
9758
+
9759
+ return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
9760
+ }
9761
+
9762
+ // Connects SharedFunctionInfo to another script.
9763
+ static Object* Runtime_LiveEditFunctionSetScript(Arguments args) {
9764
+ ASSERT(args.length() == 2);
9765
+ HandleScope scope;
9766
+ Handle<Object> function_object(args[0]);
9767
+ Handle<Object> script_object(args[1]);
9768
+
9769
+ if (function_object->IsJSValue()) {
9770
+ Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
9771
+ if (script_object->IsJSValue()) {
9772
+ CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value());
9773
+ script_object = Handle<Object>(script);
9774
+ }
9775
+
9776
+ LiveEdit::SetFunctionScript(function_wrapper, script_object);
9777
+ } else {
9778
+ // Just ignore this. We may not have a SharedFunctionInfo for some functions
9779
+ // and we check it in this function.
9780
+ }
9781
+
9782
+ return Heap::undefined_value();
9783
+ }
9784
+
9785
+
9786
+ // In a code of a parent function replaces original function as embedded object
9787
+ // with a substitution one.
9788
+ static Object* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) {
9789
+ ASSERT(args.length() == 3);
9790
+ HandleScope scope;
9791
+
9792
+ CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0);
9793
+ CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1);
9794
+ CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2);
9795
+
9796
+ LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
9797
+ subst_wrapper);
9798
+
9799
+ return Heap::undefined_value();
9800
+ }
9801
+
9802
+
9803
+ // Updates positions of a shared function info (first parameter) according
9804
+ // to script source change. Text change is described in second parameter as
9805
+ // array of groups of 3 numbers:
9806
+ // (change_begin, change_end, change_end_new_position).
9807
+ // Each group describes a change in text; groups are sorted by change_begin.
9808
+ static Object* Runtime_LiveEditPatchFunctionPositions(Arguments args) {
9809
+ ASSERT(args.length() == 2);
9810
+ HandleScope scope;
9811
+ CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
9812
+ CONVERT_ARG_CHECKED(JSArray, position_change_array, 1);
9813
+
9814
+ return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
9815
+ }
9816
+
9817
+
9818
+ // For array of SharedFunctionInfo's (each wrapped in JSValue)
9819
+ // checks that none of them have activations on stacks (of any thread).
9820
+ // Returns array of the same length with corresponding results of
9821
+ // LiveEdit::FunctionPatchabilityStatus type.
9822
+ static Object* Runtime_LiveEditCheckAndDropActivations(Arguments args) {
9823
+ ASSERT(args.length() == 2);
9824
+ HandleScope scope;
9825
+ CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
9826
+ CONVERT_BOOLEAN_CHECKED(do_drop, args[1]);
9827
+
9828
+ return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
9829
+ }
9830
+
9831
+ // Compares 2 strings line-by-line and returns diff in form of JSArray of
9832
+ // triplets (pos1, pos1_end, pos2_end) describing list of diff chunks.
9833
+ static Object* Runtime_LiveEditCompareStringsLinewise(Arguments args) {
9834
+ ASSERT(args.length() == 2);
9835
+ HandleScope scope;
9836
+ CONVERT_ARG_CHECKED(String, s1, 0);
9837
+ CONVERT_ARG_CHECKED(String, s2, 1);
9838
+
9839
+ return *LiveEdit::CompareStringsLinewise(s1, s2);
9840
+ }
9841
+
9842
+
9843
+
9844
+ // A testing entry. Returns statement position which is the closest to
9845
+ // source_position.
9846
+ static Object* Runtime_GetFunctionCodePositionFromSource(Arguments args) {
9847
+ ASSERT(args.length() == 2);
9848
+ HandleScope scope;
9849
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
9850
+ CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
9851
+
9852
+ Handle<Code> code(function->code());
9853
+
9854
+ RelocIterator it(*code, 1 << RelocInfo::STATEMENT_POSITION);
9855
+ int closest_pc = 0;
9856
+ int distance = kMaxInt;
9857
+ while (!it.done()) {
9858
+ int statement_position = static_cast<int>(it.rinfo()->data());
9859
+ // Check if this break point is closer that what was previously found.
9860
+ if (source_position <= statement_position &&
9861
+ statement_position - source_position < distance) {
9862
+ closest_pc =
9863
+ static_cast<int>(it.rinfo()->pc() - code->instruction_start());
9864
+ distance = statement_position - source_position;
9865
+ // Check whether we can't get any closer.
9866
+ if (distance == 0) break;
9867
+ }
9868
+ it.next();
9869
+ }
9870
+
9871
+ return Smi::FromInt(closest_pc);
9872
+ }
9873
+
9874
+
9875
+ // Calls specified function with or without entering the debugger.
9876
+ // This is used in unit tests to run code as if debugger is entered or simply
9877
+ // to have a stack with C++ frame in the middle.
9878
+ static Object* Runtime_ExecuteInDebugContext(Arguments args) {
9879
+ ASSERT(args.length() == 2);
9880
+ HandleScope scope;
9881
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
9882
+ CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]);
9883
+
9884
+ Handle<Object> result;
9885
+ bool pending_exception;
9886
+ {
9887
+ if (without_debugger) {
9888
+ result = Execution::Call(function, Top::global(), 0, NULL,
9889
+ &pending_exception);
9890
+ } else {
9891
+ EnterDebugger enter_debugger;
9892
+ result = Execution::Call(function, Top::global(), 0, NULL,
9893
+ &pending_exception);
9894
+ }
9895
+ }
9896
+ if (!pending_exception) {
9897
+ return *result;
9898
+ } else {
9899
+ return Failure::Exception();
9900
+ }
9901
+ }
9902
+
9903
+
7890
9904
  #endif // ENABLE_DEBUGGER_SUPPORT
7891
9905
 
7892
9906
  #ifdef ENABLE_LOGGING_AND_PROFILING
7893
9907
 
7894
9908
  static Object* Runtime_ProfilerResume(Arguments args) {
7895
9909
  NoHandleAllocation ha;
7896
- ASSERT(args.length() == 1);
9910
+ ASSERT(args.length() == 2);
7897
9911
 
7898
9912
  CONVERT_CHECKED(Smi, smi_modules, args[0]);
7899
- v8::V8::ResumeProfilerEx(smi_modules->value());
9913
+ CONVERT_CHECKED(Smi, smi_tag, args[1]);
9914
+ v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
7900
9915
  return Heap::undefined_value();
7901
9916
  }
7902
9917
 
7903
9918
 
7904
9919
  static Object* Runtime_ProfilerPause(Arguments args) {
7905
9920
  NoHandleAllocation ha;
7906
- ASSERT(args.length() == 1);
9921
+ ASSERT(args.length() == 2);
7907
9922
 
7908
9923
  CONVERT_CHECKED(Smi, smi_modules, args[0]);
7909
- v8::V8::PauseProfilerEx(smi_modules->value());
9924
+ CONVERT_CHECKED(Smi, smi_tag, args[1]);
9925
+ v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
7910
9926
  return Heap::undefined_value();
7911
9927
  }
7912
9928
 
@@ -7924,8 +9940,8 @@ static Handle<Object> Runtime_GetScriptFromScriptName(
7924
9940
  // script data.
7925
9941
  Handle<Script> script;
7926
9942
  HeapIterator iterator;
7927
- while (script.is_null() && iterator.has_next()) {
7928
- HeapObject* obj = iterator.next();
9943
+ HeapObject* obj = NULL;
9944
+ while (script.is_null() && ((obj = iterator.next()) != NULL)) {
7929
9945
  // If a script is found check if it has the script data requested.
7930
9946
  if (obj->IsScript()) {
7931
9947
  if (Script::cast(obj)->name()->IsString()) {
@@ -8023,7 +10039,7 @@ static Object* Runtime_CollectStackTrace(Arguments args) {
8023
10039
  if (cursor + 2 < elements->length()) {
8024
10040
  elements->set(cursor++, recv);
8025
10041
  elements->set(cursor++, fun);
8026
- elements->set(cursor++, offset, SKIP_WRITE_BARRIER);
10042
+ elements->set(cursor++, offset);
8027
10043
  } else {
8028
10044
  HandleScope scope;
8029
10045
  Handle<Object> recv_handle(recv);
@@ -8036,8 +10052,7 @@ static Object* Runtime_CollectStackTrace(Arguments args) {
8036
10052
  iter.Advance();
8037
10053
  }
8038
10054
 
8039
- result->set_length(Smi::FromInt(cursor), SKIP_WRITE_BARRIER);
8040
-
10055
+ result->set_length(Smi::FromInt(cursor));
8041
10056
  return *result;
8042
10057
  }
8043
10058
 
@@ -8072,6 +10087,91 @@ static Object* Runtime_DeleteHandleScopeExtensions(Arguments args) {
8072
10087
  }
8073
10088
 
8074
10089
 
10090
+ static Object* CacheMiss(FixedArray* cache_obj, int index, Object* key_obj) {
10091
+ ASSERT(index % 2 == 0); // index of the key
10092
+ ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
10093
+ ASSERT(index < cache_obj->length());
10094
+
10095
+ HandleScope scope;
10096
+
10097
+ Handle<FixedArray> cache(cache_obj);
10098
+ Handle<Object> key(key_obj);
10099
+ Handle<JSFunction> factory(JSFunction::cast(
10100
+ cache->get(JSFunctionResultCache::kFactoryIndex)));
10101
+ // TODO(antonm): consider passing a receiver when constructing a cache.
10102
+ Handle<Object> receiver(Top::global_context()->global());
10103
+
10104
+ Handle<Object> value;
10105
+ {
10106
+ // This handle is nor shared, nor used later, so it's safe.
10107
+ Object** argv[] = { key.location() };
10108
+ bool pending_exception = false;
10109
+ value = Execution::Call(factory,
10110
+ receiver,
10111
+ 1,
10112
+ argv,
10113
+ &pending_exception);
10114
+ if (pending_exception) return Failure::Exception();
10115
+ }
10116
+
10117
+ cache->set(index, *key);
10118
+ cache->set(index + 1, *value);
10119
+ cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index));
10120
+
10121
+ return *value;
10122
+ }
10123
+
10124
+
10125
+ static Object* Runtime_GetFromCache(Arguments args) {
10126
+ // This is only called from codegen, so checks might be more lax.
10127
+ CONVERT_CHECKED(FixedArray, cache, args[0]);
10128
+ Object* key = args[1];
10129
+
10130
+ const int finger_index =
10131
+ Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value();
10132
+
10133
+ Object* o = cache->get(finger_index);
10134
+ if (o == key) {
10135
+ // The fastest case: hit the same place again.
10136
+ return cache->get(finger_index + 1);
10137
+ }
10138
+
10139
+ for (int i = finger_index - 2;
10140
+ i >= JSFunctionResultCache::kEntriesIndex;
10141
+ i -= 2) {
10142
+ o = cache->get(i);
10143
+ if (o == key) {
10144
+ cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i));
10145
+ return cache->get(i + 1);
10146
+ }
10147
+ }
10148
+
10149
+ const int size =
10150
+ Smi::cast(cache->get(JSFunctionResultCache::kCacheSizeIndex))->value();
10151
+ ASSERT(size <= cache->length());
10152
+
10153
+ for (int i = size - 2; i > finger_index; i -= 2) {
10154
+ o = cache->get(i);
10155
+ if (o == key) {
10156
+ cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i));
10157
+ return cache->get(i + 1);
10158
+ }
10159
+ }
10160
+
10161
+ // Cache miss. If we have spare room, put new data into it, otherwise
10162
+ // evict post finger entry which must be least recently used.
10163
+ if (size < cache->length()) {
10164
+ cache->set(JSFunctionResultCache::kCacheSizeIndex, Smi::FromInt(size + 2));
10165
+ return CacheMiss(cache, size, key);
10166
+ } else {
10167
+ int target_index = finger_index + JSFunctionResultCache::kEntrySize;
10168
+ if (target_index == cache->length()) {
10169
+ target_index = JSFunctionResultCache::kEntriesIndex;
10170
+ }
10171
+ return CacheMiss(cache, target_index, key);
10172
+ }
10173
+ }
10174
+
8075
10175
  #ifdef DEBUG
8076
10176
  // ListNatives is ONLY used by the fuzz-natives.js in debug mode
8077
10177
  // Exclude the code in release mode.
@@ -8080,18 +10180,28 @@ static Object* Runtime_ListNatives(Arguments args) {
8080
10180
  HandleScope scope;
8081
10181
  Handle<JSArray> result = Factory::NewJSArray(0);
8082
10182
  int index = 0;
10183
+ bool inline_runtime_functions = false;
8083
10184
  #define ADD_ENTRY(Name, argc, ressize) \
8084
10185
  { \
8085
10186
  HandleScope inner; \
8086
- Handle<String> name = \
8087
- Factory::NewStringFromAscii( \
8088
- Vector<const char>(#Name, StrLength(#Name))); \
10187
+ Handle<String> name; \
10188
+ /* Inline runtime functions have an underscore in front of the name. */ \
10189
+ if (inline_runtime_functions) { \
10190
+ name = Factory::NewStringFromAscii( \
10191
+ Vector<const char>("_" #Name, StrLength("_" #Name))); \
10192
+ } else { \
10193
+ name = Factory::NewStringFromAscii( \
10194
+ Vector<const char>(#Name, StrLength(#Name))); \
10195
+ } \
8089
10196
  Handle<JSArray> pair = Factory::NewJSArray(0); \
8090
10197
  SetElement(pair, 0, name); \
8091
10198
  SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \
8092
10199
  SetElement(result, index++, pair); \
8093
10200
  }
10201
+ inline_runtime_functions = false;
8094
10202
  RUNTIME_FUNCTION_LIST(ADD_ENTRY)
10203
+ inline_runtime_functions = true;
10204
+ INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
8095
10205
  #undef ADD_ENTRY
8096
10206
  return *result;
8097
10207
  }
@@ -8118,12 +10228,12 @@ static Object* Runtime_IS_VAR(Arguments args) {
8118
10228
  // Implementation of Runtime
8119
10229
 
8120
10230
  #define F(name, nargs, ressize) \
8121
- { #name, "RuntimeStub_" #name, FUNCTION_ADDR(Runtime_##name), nargs, \
10231
+ { #name, FUNCTION_ADDR(Runtime_##name), nargs, \
8122
10232
  static_cast<int>(Runtime::k##name), ressize },
8123
10233
 
8124
10234
  static Runtime::Function Runtime_functions[] = {
8125
10235
  RUNTIME_FUNCTION_LIST(F)
8126
- { NULL, NULL, NULL, 0, -1, 0 }
10236
+ { NULL, NULL, 0, -1, 0 }
8127
10237
  };
8128
10238
 
8129
10239
  #undef F