libv8-sgonyea 3.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (500) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +76 -0
  5. data/Rakefile +113 -0
  6. data/ext/libv8/extconf.rb +28 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +30 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  11. data/lib/libv8/v8/.gitignore +35 -0
  12. data/lib/libv8/v8/AUTHORS +44 -0
  13. data/lib/libv8/v8/ChangeLog +2839 -0
  14. data/lib/libv8/v8/LICENSE +52 -0
  15. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  16. data/lib/libv8/v8/LICENSE.v8 +26 -0
  17. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  18. data/lib/libv8/v8/SConstruct +1478 -0
  19. data/lib/libv8/v8/build/README.txt +49 -0
  20. data/lib/libv8/v8/build/all.gyp +18 -0
  21. data/lib/libv8/v8/build/armu.gypi +32 -0
  22. data/lib/libv8/v8/build/common.gypi +144 -0
  23. data/lib/libv8/v8/build/gyp_v8 +145 -0
  24. data/lib/libv8/v8/include/v8-debug.h +395 -0
  25. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  26. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  27. data/lib/libv8/v8/include/v8-testing.h +104 -0
  28. data/lib/libv8/v8/include/v8.h +4124 -0
  29. data/lib/libv8/v8/include/v8stdint.h +53 -0
  30. data/lib/libv8/v8/preparser/SConscript +38 -0
  31. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  32. data/lib/libv8/v8/src/SConscript +368 -0
  33. data/lib/libv8/v8/src/accessors.cc +767 -0
  34. data/lib/libv8/v8/src/accessors.h +123 -0
  35. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  36. data/lib/libv8/v8/src/allocation.cc +122 -0
  37. data/lib/libv8/v8/src/allocation.h +143 -0
  38. data/lib/libv8/v8/src/api.cc +5845 -0
  39. data/lib/libv8/v8/src/api.h +574 -0
  40. data/lib/libv8/v8/src/apinatives.js +110 -0
  41. data/lib/libv8/v8/src/apiutils.h +73 -0
  42. data/lib/libv8/v8/src/arguments.h +118 -0
  43. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  44. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  45. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  46. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  47. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  48. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  49. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  50. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  51. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  52. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  53. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  54. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  55. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  56. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  57. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  58. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  59. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  60. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  61. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  62. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  63. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  64. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  65. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  66. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  67. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  68. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  69. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  70. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  71. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  72. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  73. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  74. data/lib/libv8/v8/src/array.js +1366 -0
  75. data/lib/libv8/v8/src/assembler.cc +1207 -0
  76. data/lib/libv8/v8/src/assembler.h +858 -0
  77. data/lib/libv8/v8/src/ast-inl.h +112 -0
  78. data/lib/libv8/v8/src/ast.cc +1146 -0
  79. data/lib/libv8/v8/src/ast.h +2188 -0
  80. data/lib/libv8/v8/src/atomicops.h +167 -0
  81. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  82. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  83. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  84. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  85. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  86. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  87. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  88. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  89. data/lib/libv8/v8/src/bignum.cc +768 -0
  90. data/lib/libv8/v8/src/bignum.h +140 -0
  91. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  92. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  93. data/lib/libv8/v8/src/builtins.cc +1707 -0
  94. data/lib/libv8/v8/src/builtins.h +371 -0
  95. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  96. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  97. data/lib/libv8/v8/src/cached-powers.h +65 -0
  98. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  99. data/lib/libv8/v8/src/char-predicates.h +67 -0
  100. data/lib/libv8/v8/src/checks.cc +110 -0
  101. data/lib/libv8/v8/src/checks.h +296 -0
  102. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  103. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  104. data/lib/libv8/v8/src/circular-queue.h +103 -0
  105. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  106. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  107. data/lib/libv8/v8/src/code.h +70 -0
  108. data/lib/libv8/v8/src/codegen.cc +231 -0
  109. data/lib/libv8/v8/src/codegen.h +84 -0
  110. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  111. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  112. data/lib/libv8/v8/src/compiler.cc +786 -0
  113. data/lib/libv8/v8/src/compiler.h +312 -0
  114. data/lib/libv8/v8/src/contexts.cc +347 -0
  115. data/lib/libv8/v8/src/contexts.h +391 -0
  116. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  117. data/lib/libv8/v8/src/conversions.cc +1131 -0
  118. data/lib/libv8/v8/src/conversions.h +135 -0
  119. data/lib/libv8/v8/src/counters.cc +93 -0
  120. data/lib/libv8/v8/src/counters.h +254 -0
  121. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  122. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  123. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  124. data/lib/libv8/v8/src/cpu.h +69 -0
  125. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  126. data/lib/libv8/v8/src/d8-debug.h +158 -0
  127. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  128. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  129. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  130. data/lib/libv8/v8/src/d8.cc +803 -0
  131. data/lib/libv8/v8/src/d8.gyp +91 -0
  132. data/lib/libv8/v8/src/d8.h +235 -0
  133. data/lib/libv8/v8/src/d8.js +2798 -0
  134. data/lib/libv8/v8/src/data-flow.cc +66 -0
  135. data/lib/libv8/v8/src/data-flow.h +205 -0
  136. data/lib/libv8/v8/src/date.js +1103 -0
  137. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  138. data/lib/libv8/v8/src/dateparser.cc +178 -0
  139. data/lib/libv8/v8/src/dateparser.h +266 -0
  140. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  141. data/lib/libv8/v8/src/debug-agent.h +129 -0
  142. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  143. data/lib/libv8/v8/src/debug.cc +3165 -0
  144. data/lib/libv8/v8/src/debug.h +1057 -0
  145. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  146. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  147. data/lib/libv8/v8/src/disasm.h +80 -0
  148. data/lib/libv8/v8/src/disassembler.cc +343 -0
  149. data/lib/libv8/v8/src/disassembler.h +58 -0
  150. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  151. data/lib/libv8/v8/src/diy-fp.h +117 -0
  152. data/lib/libv8/v8/src/double.h +238 -0
  153. data/lib/libv8/v8/src/dtoa.cc +103 -0
  154. data/lib/libv8/v8/src/dtoa.h +85 -0
  155. data/lib/libv8/v8/src/execution.cc +849 -0
  156. data/lib/libv8/v8/src/execution.h +297 -0
  157. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  158. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  159. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  160. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  161. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  162. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  163. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  164. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  165. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  166. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  167. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  168. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  169. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  170. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  171. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  172. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  173. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  174. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  175. data/lib/libv8/v8/src/factory.cc +1222 -0
  176. data/lib/libv8/v8/src/factory.h +442 -0
  177. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  178. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  179. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  180. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  181. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  182. data/lib/libv8/v8/src/flags.cc +551 -0
  183. data/lib/libv8/v8/src/flags.h +79 -0
  184. data/lib/libv8/v8/src/frames-inl.h +247 -0
  185. data/lib/libv8/v8/src/frames.cc +1243 -0
  186. data/lib/libv8/v8/src/frames.h +870 -0
  187. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  188. data/lib/libv8/v8/src/full-codegen.h +771 -0
  189. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  190. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  191. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  192. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  193. data/lib/libv8/v8/src/global-handles.cc +665 -0
  194. data/lib/libv8/v8/src/global-handles.h +284 -0
  195. data/lib/libv8/v8/src/globals.h +325 -0
  196. data/lib/libv8/v8/src/handles-inl.h +177 -0
  197. data/lib/libv8/v8/src/handles.cc +987 -0
  198. data/lib/libv8/v8/src/handles.h +382 -0
  199. data/lib/libv8/v8/src/hashmap.cc +230 -0
  200. data/lib/libv8/v8/src/hashmap.h +123 -0
  201. data/lib/libv8/v8/src/heap-inl.h +704 -0
  202. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  203. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  204. data/lib/libv8/v8/src/heap.cc +5930 -0
  205. data/lib/libv8/v8/src/heap.h +2268 -0
  206. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  207. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  208. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  209. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  210. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  211. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  212. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  213. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  214. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  215. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  216. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  217. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  218. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  219. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  220. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  221. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  222. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  223. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  224. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  225. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  226. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  227. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  228. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  229. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  230. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  231. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  232. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  233. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  234. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  235. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  236. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  237. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  238. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  239. data/lib/libv8/v8/src/ic-inl.h +130 -0
  240. data/lib/libv8/v8/src/ic.cc +2577 -0
  241. data/lib/libv8/v8/src/ic.h +736 -0
  242. data/lib/libv8/v8/src/inspector.cc +63 -0
  243. data/lib/libv8/v8/src/inspector.h +62 -0
  244. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  245. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  246. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  247. data/lib/libv8/v8/src/isolate.cc +1869 -0
  248. data/lib/libv8/v8/src/isolate.h +1382 -0
  249. data/lib/libv8/v8/src/json-parser.cc +504 -0
  250. data/lib/libv8/v8/src/json-parser.h +161 -0
  251. data/lib/libv8/v8/src/json.js +342 -0
  252. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  253. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  254. data/lib/libv8/v8/src/list-inl.h +212 -0
  255. data/lib/libv8/v8/src/list.h +174 -0
  256. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  257. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  258. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  259. data/lib/libv8/v8/src/lithium.cc +190 -0
  260. data/lib/libv8/v8/src/lithium.h +597 -0
  261. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  262. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  263. data/lib/libv8/v8/src/liveedit.h +180 -0
  264. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  265. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  266. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  267. data/lib/libv8/v8/src/log-inl.h +59 -0
  268. data/lib/libv8/v8/src/log-utils.cc +428 -0
  269. data/lib/libv8/v8/src/log-utils.h +231 -0
  270. data/lib/libv8/v8/src/log.cc +1993 -0
  271. data/lib/libv8/v8/src/log.h +476 -0
  272. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  273. data/lib/libv8/v8/src/macros.py +178 -0
  274. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  275. data/lib/libv8/v8/src/mark-compact.h +506 -0
  276. data/lib/libv8/v8/src/math.js +264 -0
  277. data/lib/libv8/v8/src/messages.cc +179 -0
  278. data/lib/libv8/v8/src/messages.h +113 -0
  279. data/lib/libv8/v8/src/messages.js +1096 -0
  280. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  281. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  282. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  283. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  284. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  285. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  286. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  287. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  288. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  289. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  290. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  291. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  292. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  293. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  294. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  295. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  296. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  297. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  298. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  299. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  300. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  301. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  302. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  303. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  304. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  305. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  306. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  307. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  308. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  309. data/lib/libv8/v8/src/natives.h +64 -0
  310. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  311. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  312. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  313. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  314. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  315. data/lib/libv8/v8/src/objects.cc +10585 -0
  316. data/lib/libv8/v8/src/objects.h +6838 -0
  317. data/lib/libv8/v8/src/parser.cc +4997 -0
  318. data/lib/libv8/v8/src/parser.h +765 -0
  319. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  320. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  321. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  322. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  323. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  324. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  325. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  326. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  327. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  328. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  329. data/lib/libv8/v8/src/platform-tls.h +50 -0
  330. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  331. data/lib/libv8/v8/src/platform.h +667 -0
  332. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  333. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  334. data/lib/libv8/v8/src/preparse-data.h +225 -0
  335. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  336. data/lib/libv8/v8/src/preparser.cc +1450 -0
  337. data/lib/libv8/v8/src/preparser.h +493 -0
  338. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  339. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  340. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  341. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  342. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  343. data/lib/libv8/v8/src/property.cc +105 -0
  344. data/lib/libv8/v8/src/property.h +365 -0
  345. data/lib/libv8/v8/src/proxy.js +83 -0
  346. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  347. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  348. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  349. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  350. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  351. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  352. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  353. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  354. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  355. data/lib/libv8/v8/src/regexp.js +483 -0
  356. data/lib/libv8/v8/src/rewriter.cc +360 -0
  357. data/lib/libv8/v8/src/rewriter.h +50 -0
  358. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  359. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  360. data/lib/libv8/v8/src/runtime.cc +12227 -0
  361. data/lib/libv8/v8/src/runtime.h +652 -0
  362. data/lib/libv8/v8/src/runtime.js +649 -0
  363. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  364. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  365. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  366. data/lib/libv8/v8/src/scanner-base.h +670 -0
  367. data/lib/libv8/v8/src/scanner.cc +345 -0
  368. data/lib/libv8/v8/src/scanner.h +146 -0
  369. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  370. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  371. data/lib/libv8/v8/src/scopes.cc +1150 -0
  372. data/lib/libv8/v8/src/scopes.h +507 -0
  373. data/lib/libv8/v8/src/serialize.cc +1574 -0
  374. data/lib/libv8/v8/src/serialize.h +589 -0
  375. data/lib/libv8/v8/src/shell.h +55 -0
  376. data/lib/libv8/v8/src/simulator.h +43 -0
  377. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  378. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  379. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  380. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  381. data/lib/libv8/v8/src/snapshot.h +91 -0
  382. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  383. data/lib/libv8/v8/src/spaces.cc +3145 -0
  384. data/lib/libv8/v8/src/spaces.h +2369 -0
  385. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  386. data/lib/libv8/v8/src/splay-tree.h +205 -0
  387. data/lib/libv8/v8/src/string-search.cc +41 -0
  388. data/lib/libv8/v8/src/string-search.h +568 -0
  389. data/lib/libv8/v8/src/string-stream.cc +592 -0
  390. data/lib/libv8/v8/src/string-stream.h +191 -0
  391. data/lib/libv8/v8/src/string.js +994 -0
  392. data/lib/libv8/v8/src/strtod.cc +440 -0
  393. data/lib/libv8/v8/src/strtod.h +40 -0
  394. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  395. data/lib/libv8/v8/src/stub-cache.h +924 -0
  396. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  397. data/lib/libv8/v8/src/token.cc +63 -0
  398. data/lib/libv8/v8/src/token.h +288 -0
  399. data/lib/libv8/v8/src/type-info.cc +507 -0
  400. data/lib/libv8/v8/src/type-info.h +272 -0
  401. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  402. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  403. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  404. data/lib/libv8/v8/src/unicode.cc +1624 -0
  405. data/lib/libv8/v8/src/unicode.h +280 -0
  406. data/lib/libv8/v8/src/uri.js +408 -0
  407. data/lib/libv8/v8/src/utils-inl.h +48 -0
  408. data/lib/libv8/v8/src/utils.cc +371 -0
  409. data/lib/libv8/v8/src/utils.h +800 -0
  410. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  411. data/lib/libv8/v8/src/v8-counters.h +314 -0
  412. data/lib/libv8/v8/src/v8.cc +213 -0
  413. data/lib/libv8/v8/src/v8.h +131 -0
  414. data/lib/libv8/v8/src/v8checks.h +64 -0
  415. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  416. data/lib/libv8/v8/src/v8globals.h +512 -0
  417. data/lib/libv8/v8/src/v8memory.h +82 -0
  418. data/lib/libv8/v8/src/v8natives.js +1310 -0
  419. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  420. data/lib/libv8/v8/src/v8threads.cc +464 -0
  421. data/lib/libv8/v8/src/v8threads.h +165 -0
  422. data/lib/libv8/v8/src/v8utils.h +319 -0
  423. data/lib/libv8/v8/src/variables.cc +114 -0
  424. data/lib/libv8/v8/src/variables.h +167 -0
  425. data/lib/libv8/v8/src/version.cc +116 -0
  426. data/lib/libv8/v8/src/version.h +68 -0
  427. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  428. data/lib/libv8/v8/src/vm-state.h +71 -0
  429. data/lib/libv8/v8/src/win32-headers.h +96 -0
  430. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  431. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  432. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  433. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  434. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  435. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  436. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  437. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  438. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  439. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  440. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  441. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  442. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  443. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  444. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  445. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  446. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  447. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  448. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  449. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  450. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  451. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  452. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  453. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  454. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  455. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  456. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  457. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  458. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  459. data/lib/libv8/v8/src/zone-inl.h +140 -0
  460. data/lib/libv8/v8/src/zone.cc +196 -0
  461. data/lib/libv8/v8/src/zone.h +240 -0
  462. data/lib/libv8/v8/tools/codemap.js +265 -0
  463. data/lib/libv8/v8/tools/consarray.js +93 -0
  464. data/lib/libv8/v8/tools/csvparser.js +78 -0
  465. data/lib/libv8/v8/tools/disasm.py +92 -0
  466. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  467. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  468. data/lib/libv8/v8/tools/gcmole/README +62 -0
  469. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  470. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  471. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  472. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  473. data/lib/libv8/v8/tools/grokdump.py +841 -0
  474. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  475. data/lib/libv8/v8/tools/js2c.py +364 -0
  476. data/lib/libv8/v8/tools/jsmin.py +280 -0
  477. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  478. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  479. data/lib/libv8/v8/tools/logreader.js +185 -0
  480. data/lib/libv8/v8/tools/mac-nm +18 -0
  481. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  482. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  483. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  484. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  485. data/lib/libv8/v8/tools/presubmit.py +305 -0
  486. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  487. data/lib/libv8/v8/tools/profile.js +751 -0
  488. data/lib/libv8/v8/tools/profile_view.js +219 -0
  489. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  490. data/lib/libv8/v8/tools/splaytree.js +316 -0
  491. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  492. data/lib/libv8/v8/tools/test.py +1510 -0
  493. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  494. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  495. data/lib/libv8/v8/tools/utils.py +96 -0
  496. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  497. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  498. data/lib/libv8/version.rb +5 -0
  499. data/libv8.gemspec +36 -0
  500. metadata +578 -0
@@ -0,0 +1,188 @@
1
+ // Copyright 2006-2008 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+
29
+ #ifndef V8_BOOTSTRAPPER_H_
30
+ #define V8_BOOTSTRAPPER_H_
31
+
32
+ #include "allocation.h"
33
+
34
+ namespace v8 {
35
+ namespace internal {
36
+
37
+
38
+ // A SourceCodeCache uses a FixedArray to store pairs of
39
+ // (AsciiString*, JSFunction*), mapping names of native code files
40
+ // (runtime.js, etc.) to precompiled functions. Instead of mapping
41
+ // names to functions it might make sense to let the JS2C tool
42
+ // generate an index for each native JS file.
43
+ class SourceCodeCache BASE_EMBEDDED {
44
+ public:
45
+ explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { }
46
+
47
+ void Initialize(bool create_heap_objects) {
48
+ cache_ = create_heap_objects ? HEAP->empty_fixed_array() : NULL;
49
+ }
50
+
51
+ void Iterate(ObjectVisitor* v) {
52
+ v->VisitPointer(BitCast<Object**, FixedArray**>(&cache_));
53
+ }
54
+
55
+ bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) {
56
+ for (int i = 0; i < cache_->length(); i+=2) {
57
+ SeqAsciiString* str = SeqAsciiString::cast(cache_->get(i));
58
+ if (str->IsEqualTo(name)) {
59
+ *handle = Handle<SharedFunctionInfo>(
60
+ SharedFunctionInfo::cast(cache_->get(i + 1)));
61
+ return true;
62
+ }
63
+ }
64
+ return false;
65
+ }
66
+
67
+ void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) {
68
+ HandleScope scope;
69
+ int length = cache_->length();
70
+ Handle<FixedArray> new_array =
71
+ FACTORY->NewFixedArray(length + 2, TENURED);
72
+ cache_->CopyTo(0, *new_array, 0, cache_->length());
73
+ cache_ = *new_array;
74
+ Handle<String> str = FACTORY->NewStringFromAscii(name, TENURED);
75
+ cache_->set(length, *str);
76
+ cache_->set(length + 1, *shared);
77
+ Script::cast(shared->script())->set_type(Smi::FromInt(type_));
78
+ }
79
+
80
+ private:
81
+ Script::Type type_;
82
+ FixedArray* cache_;
83
+ DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);
84
+ };
85
+
86
+
87
+ // The Boostrapper is the public interface for creating a JavaScript global
88
+ // context.
89
+ class Bootstrapper {
90
+ public:
91
+ // Requires: Heap::Setup has been called.
92
+ void Initialize(bool create_heap_objects);
93
+ void TearDown();
94
+
95
+ // Creates a JavaScript Global Context with initial object graph.
96
+ // The returned value is a global handle casted to V8Environment*.
97
+ Handle<Context> CreateEnvironment(
98
+ Isolate* isolate,
99
+ Handle<Object> global_object,
100
+ v8::Handle<v8::ObjectTemplate> global_template,
101
+ v8::ExtensionConfiguration* extensions);
102
+
103
+ // Detach the environment from its outer global object.
104
+ void DetachGlobal(Handle<Context> env);
105
+
106
+ // Reattach an outer global object to an environment.
107
+ void ReattachGlobal(Handle<Context> env, Handle<Object> global_object);
108
+
109
+ // Traverses the pointers for memory management.
110
+ void Iterate(ObjectVisitor* v);
111
+
112
+ // Accessor for the native scripts source code.
113
+ Handle<String> NativesSourceLookup(int index);
114
+
115
+ // Tells whether bootstrapping is active.
116
+ bool IsActive() const { return nesting_ != 0; }
117
+
118
+ // Support for thread preemption.
119
+ static int ArchiveSpacePerThread();
120
+ char* ArchiveState(char* to);
121
+ char* RestoreState(char* from);
122
+ void FreeThreadResources();
123
+
124
+ // This will allocate a char array that is deleted when V8 is shut down.
125
+ // It should only be used for strictly finite allocations.
126
+ char* AllocateAutoDeletedArray(int bytes);
127
+
128
+ // Used for new context creation.
129
+ bool InstallExtensions(Handle<Context> global_context,
130
+ v8::ExtensionConfiguration* extensions);
131
+
132
+ SourceCodeCache* extensions_cache() { return &extensions_cache_; }
133
+
134
+ private:
135
+ typedef int NestingCounterType;
136
+ NestingCounterType nesting_;
137
+ SourceCodeCache extensions_cache_;
138
+ // This is for delete, not delete[].
139
+ List<char*>* delete_these_non_arrays_on_tear_down_;
140
+ // This is for delete[]
141
+ List<char*>* delete_these_arrays_on_tear_down_;
142
+
143
+ friend class BootstrapperActive;
144
+ friend class Isolate;
145
+ friend class NativesExternalStringResource;
146
+
147
+ Bootstrapper();
148
+
149
+ DISALLOW_COPY_AND_ASSIGN(Bootstrapper);
150
+ };
151
+
152
+
153
+ class BootstrapperActive BASE_EMBEDDED {
154
+ public:
155
+ BootstrapperActive() {
156
+ ++Isolate::Current()->bootstrapper()->nesting_;
157
+ }
158
+
159
+ ~BootstrapperActive() {
160
+ --Isolate::Current()->bootstrapper()->nesting_;
161
+ }
162
+
163
+ private:
164
+ DISALLOW_COPY_AND_ASSIGN(BootstrapperActive);
165
+ };
166
+
167
+
168
+ class NativesExternalStringResource
169
+ : public v8::String::ExternalAsciiStringResource {
170
+ public:
171
+ explicit NativesExternalStringResource(Bootstrapper* bootstrapper,
172
+ const char* source);
173
+
174
+ const char* data() const {
175
+ return data_;
176
+ }
177
+
178
+ size_t length() const {
179
+ return length_;
180
+ }
181
+ private:
182
+ const char* data_;
183
+ size_t length_;
184
+ };
185
+
186
+ }} // namespace v8::internal
187
+
188
+ #endif // V8_BOOTSTRAPPER_H_
@@ -0,0 +1,1707 @@
1
+ // Copyright 2011 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ #include "v8.h"
29
+
30
+ #include "api.h"
31
+ #include "arguments.h"
32
+ #include "bootstrapper.h"
33
+ #include "builtins.h"
34
+ #include "gdb-jit.h"
35
+ #include "ic-inl.h"
36
+ #include "vm-state-inl.h"
37
+
38
+ namespace v8 {
39
+ namespace internal {
40
+
41
+ namespace {
42
+
43
+ // Arguments object passed to C++ builtins.
44
+ template <BuiltinExtraArguments extra_args>
45
+ class BuiltinArguments : public Arguments {
46
+ public:
47
+ BuiltinArguments(int length, Object** arguments)
48
+ : Arguments(length, arguments) { }
49
+
50
+ Object*& operator[] (int index) {
51
+ ASSERT(index < length());
52
+ return Arguments::operator[](index);
53
+ }
54
+
55
+ template <class S> Handle<S> at(int index) {
56
+ ASSERT(index < length());
57
+ return Arguments::at<S>(index);
58
+ }
59
+
60
+ Handle<Object> receiver() {
61
+ return Arguments::at<Object>(0);
62
+ }
63
+
64
+ Handle<JSFunction> called_function() {
65
+ STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION);
66
+ return Arguments::at<JSFunction>(Arguments::length() - 1);
67
+ }
68
+
69
+ // Gets the total number of arguments including the receiver (but
70
+ // excluding extra arguments).
71
+ int length() const {
72
+ STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
73
+ return Arguments::length();
74
+ }
75
+
76
+ #ifdef DEBUG
77
+ void Verify() {
78
+ // Check we have at least the receiver.
79
+ ASSERT(Arguments::length() >= 1);
80
+ }
81
+ #endif
82
+ };
83
+
84
+
85
+ // Specialize BuiltinArguments for the called function extra argument.
86
+
87
+ template <>
88
+ int BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const {
89
+ return Arguments::length() - 1;
90
+ }
91
+
92
+ #ifdef DEBUG
93
+ template <>
94
+ void BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() {
95
+ // Check we have at least the receiver and the called function.
96
+ ASSERT(Arguments::length() >= 2);
97
+ // Make sure cast to JSFunction succeeds.
98
+ called_function();
99
+ }
100
+ #endif
101
+
102
+
103
+ #define DEF_ARG_TYPE(name, spec) \
104
+ typedef BuiltinArguments<spec> name##ArgumentsType;
105
+ BUILTIN_LIST_C(DEF_ARG_TYPE)
106
+ #undef DEF_ARG_TYPE
107
+
108
+ } // namespace
109
+
110
+ // ----------------------------------------------------------------------------
111
+ // Support macro for defining builtins in C++.
112
+ // ----------------------------------------------------------------------------
113
+ //
114
+ // A builtin function is defined by writing:
115
+ //
116
+ // BUILTIN(name) {
117
+ // ...
118
+ // }
119
+ //
120
+ // In the body of the builtin function the arguments can be accessed
121
+ // through the BuiltinArguments object args.
122
+
123
+ #ifdef DEBUG
124
+
125
+ #define BUILTIN(name) \
126
+ MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
127
+ name##ArgumentsType args, Isolate* isolate); \
128
+ MUST_USE_RESULT static MaybeObject* Builtin_##name( \
129
+ name##ArgumentsType args, Isolate* isolate) { \
130
+ ASSERT(isolate == Isolate::Current()); \
131
+ args.Verify(); \
132
+ return Builtin_Impl_##name(args, isolate); \
133
+ } \
134
+ MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
135
+ name##ArgumentsType args, Isolate* isolate)
136
+
137
+ #else // For release mode.
138
+
139
+ #define BUILTIN(name) \
140
+ static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate)
141
+
142
+ #endif
143
+
144
+
145
+ static inline bool CalledAsConstructor(Isolate* isolate) {
146
+ #ifdef DEBUG
147
+ // Calculate the result using a full stack frame iterator and check
148
+ // that the state of the stack is as we assume it to be in the
149
+ // code below.
150
+ StackFrameIterator it;
151
+ ASSERT(it.frame()->is_exit());
152
+ it.Advance();
153
+ StackFrame* frame = it.frame();
154
+ bool reference_result = frame->is_construct();
155
+ #endif
156
+ Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
157
+ // Because we know fp points to an exit frame we can use the relevant
158
+ // part of ExitFrame::ComputeCallerState directly.
159
+ const int kCallerOffset = ExitFrameConstants::kCallerFPOffset;
160
+ Address caller_fp = Memory::Address_at(fp + kCallerOffset);
161
+ // This inlines the part of StackFrame::ComputeType that grabs the
162
+ // type of the current frame. Note that StackFrame::ComputeType
163
+ // has been specialized for each architecture so if any one of them
164
+ // changes this code has to be changed as well.
165
+ const int kMarkerOffset = StandardFrameConstants::kMarkerOffset;
166
+ const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT);
167
+ Object* marker = Memory::Object_at(caller_fp + kMarkerOffset);
168
+ bool result = (marker == kConstructMarker);
169
+ ASSERT_EQ(result, reference_result);
170
+ return result;
171
+ }
172
+
173
+ // ----------------------------------------------------------------------------
174
+
175
+ BUILTIN(Illegal) {
176
+ UNREACHABLE();
177
+ return isolate->heap()->undefined_value(); // Make compiler happy.
178
+ }
179
+
180
+
181
+ BUILTIN(EmptyFunction) {
182
+ return isolate->heap()->undefined_value();
183
+ }
184
+
185
+
186
+ BUILTIN(ArrayCodeGeneric) {
187
+ Heap* heap = isolate->heap();
188
+ isolate->counters()->array_function_runtime()->Increment();
189
+
190
+ JSArray* array;
191
+ if (CalledAsConstructor(isolate)) {
192
+ array = JSArray::cast(*args.receiver());
193
+ } else {
194
+ // Allocate the JS Array
195
+ JSFunction* constructor =
196
+ isolate->context()->global_context()->array_function();
197
+ Object* obj;
198
+ { MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
199
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
200
+ }
201
+ array = JSArray::cast(obj);
202
+ }
203
+
204
+ // 'array' now contains the JSArray we should initialize.
205
+ ASSERT(array->HasFastElements());
206
+
207
+ // Optimize the case where there is one argument and the argument is a
208
+ // small smi.
209
+ if (args.length() == 2) {
210
+ Object* obj = args[1];
211
+ if (obj->IsSmi()) {
212
+ int len = Smi::cast(obj)->value();
213
+ if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
214
+ Object* obj;
215
+ { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len);
216
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
217
+ }
218
+ array->SetContent(FixedArray::cast(obj));
219
+ return array;
220
+ }
221
+ }
222
+ // Take the argument as the length.
223
+ { MaybeObject* maybe_obj = array->Initialize(0);
224
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
225
+ }
226
+ return array->SetElementsLength(args[1]);
227
+ }
228
+
229
+ // Optimize the case where there are no parameters passed.
230
+ if (args.length() == 1) {
231
+ return array->Initialize(JSArray::kPreallocatedArrayElements);
232
+ }
233
+
234
+ // Take the arguments as elements.
235
+ int number_of_elements = args.length() - 1;
236
+ Smi* len = Smi::FromInt(number_of_elements);
237
+ Object* obj;
238
+ { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len->value());
239
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
240
+ }
241
+
242
+ AssertNoAllocation no_gc;
243
+ FixedArray* elms = FixedArray::cast(obj);
244
+ WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
245
+ // Fill in the content
246
+ for (int index = 0; index < number_of_elements; index++) {
247
+ elms->set(index, args[index+1], mode);
248
+ }
249
+
250
+ // Set length and elements on the array.
251
+ array->set_elements(FixedArray::cast(obj));
252
+ array->set_length(len);
253
+
254
+ return array;
255
+ }
256
+
257
+
258
+ MUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) {
259
+ JSFunction* array_function =
260
+ heap->isolate()->context()->global_context()->array_function();
261
+ Object* result;
262
+ { MaybeObject* maybe_result = heap->AllocateJSObject(array_function);
263
+ if (!maybe_result->ToObject(&result)) return maybe_result;
264
+ }
265
+ return result;
266
+ }
267
+
268
+
269
+ MUST_USE_RESULT static MaybeObject* AllocateEmptyJSArray(Heap* heap) {
270
+ Object* result;
271
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
272
+ if (!maybe_result->ToObject(&result)) return maybe_result;
273
+ }
274
+ JSArray* result_array = JSArray::cast(result);
275
+ result_array->set_length(Smi::FromInt(0));
276
+ result_array->set_elements(heap->empty_fixed_array());
277
+ return result_array;
278
+ }
279
+
280
+
281
+ static void CopyElements(Heap* heap,
282
+ AssertNoAllocation* no_gc,
283
+ FixedArray* dst,
284
+ int dst_index,
285
+ FixedArray* src,
286
+ int src_index,
287
+ int len) {
288
+ ASSERT(dst != src); // Use MoveElements instead.
289
+ ASSERT(dst->map() != HEAP->fixed_cow_array_map());
290
+ ASSERT(len > 0);
291
+ CopyWords(dst->data_start() + dst_index,
292
+ src->data_start() + src_index,
293
+ len);
294
+ WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
295
+ if (mode == UPDATE_WRITE_BARRIER) {
296
+ heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
297
+ }
298
+ }
299
+
300
+
301
+ static void MoveElements(Heap* heap,
302
+ AssertNoAllocation* no_gc,
303
+ FixedArray* dst,
304
+ int dst_index,
305
+ FixedArray* src,
306
+ int src_index,
307
+ int len) {
308
+ ASSERT(dst->map() != HEAP->fixed_cow_array_map());
309
+ memmove(dst->data_start() + dst_index,
310
+ src->data_start() + src_index,
311
+ len * kPointerSize);
312
+ WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
313
+ if (mode == UPDATE_WRITE_BARRIER) {
314
+ heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
315
+ }
316
+ }
317
+
318
+
319
+ static void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
320
+ ASSERT(dst->map() != heap->fixed_cow_array_map());
321
+ MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
322
+ }
323
+
324
+
325
+ static FixedArray* LeftTrimFixedArray(Heap* heap,
326
+ FixedArray* elms,
327
+ int to_trim) {
328
+ ASSERT(elms->map() != HEAP->fixed_cow_array_map());
329
+ // For now this trick is only applied to fixed arrays in new and paged space.
330
+ // In large object space the object's start must coincide with chunk
331
+ // and thus the trick is just not applicable.
332
+ ASSERT(!HEAP->lo_space()->Contains(elms));
333
+
334
+ STATIC_ASSERT(FixedArray::kMapOffset == 0);
335
+ STATIC_ASSERT(FixedArray::kLengthOffset == kPointerSize);
336
+ STATIC_ASSERT(FixedArray::kHeaderSize == 2 * kPointerSize);
337
+
338
+ Object** former_start = HeapObject::RawField(elms, 0);
339
+
340
+ const int len = elms->length();
341
+
342
+ if (to_trim > FixedArray::kHeaderSize / kPointerSize &&
343
+ !heap->new_space()->Contains(elms)) {
344
+ // If we are doing a big trim in old space then we zap the space that was
345
+ // formerly part of the array so that the GC (aided by the card-based
346
+ // remembered set) won't find pointers to new-space there.
347
+ Object** zap = reinterpret_cast<Object**>(elms->address());
348
+ zap++; // Header of filler must be at least one word so skip that.
349
+ for (int i = 1; i < to_trim; i++) {
350
+ *zap++ = Smi::FromInt(0);
351
+ }
352
+ }
353
+ // Technically in new space this write might be omitted (except for
354
+ // debug mode which iterates through the heap), but to play safer
355
+ // we still do it.
356
+ heap->CreateFillerObjectAt(elms->address(), to_trim * kPointerSize);
357
+
358
+ former_start[to_trim] = heap->fixed_array_map();
359
+ former_start[to_trim + 1] = Smi::FromInt(len - to_trim);
360
+
361
+ return FixedArray::cast(HeapObject::FromAddress(
362
+ elms->address() + to_trim * kPointerSize));
363
+ }
364
+
365
+
366
+ static bool ArrayPrototypeHasNoElements(Heap* heap,
367
+ Context* global_context,
368
+ JSObject* array_proto) {
369
+ // This method depends on non writability of Object and Array prototype
370
+ // fields.
371
+ if (array_proto->elements() != heap->empty_fixed_array()) return false;
372
+ // Hidden prototype
373
+ array_proto = JSObject::cast(array_proto->GetPrototype());
374
+ ASSERT(array_proto->elements() == heap->empty_fixed_array());
375
+ // Object.prototype
376
+ Object* proto = array_proto->GetPrototype();
377
+ if (proto == heap->null_value()) return false;
378
+ array_proto = JSObject::cast(proto);
379
+ if (array_proto != global_context->initial_object_prototype()) return false;
380
+ if (array_proto->elements() != heap->empty_fixed_array()) return false;
381
+ return array_proto->GetPrototype()->IsNull();
382
+ }
383
+
384
+
385
+ MUST_USE_RESULT
386
+ static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
387
+ Heap* heap, Object* receiver) {
388
+ if (!receiver->IsJSArray()) return NULL;
389
+ JSArray* array = JSArray::cast(receiver);
390
+ HeapObject* elms = array->elements();
391
+ if (elms->map() == heap->fixed_array_map()) return elms;
392
+ if (elms->map() == heap->fixed_cow_array_map()) {
393
+ return array->EnsureWritableFastElements();
394
+ }
395
+ return NULL;
396
+ }
397
+
398
+
399
+ static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
400
+ JSArray* receiver) {
401
+ Context* global_context = heap->isolate()->context()->global_context();
402
+ JSObject* array_proto =
403
+ JSObject::cast(global_context->array_function()->prototype());
404
+ return receiver->GetPrototype() == array_proto &&
405
+ ArrayPrototypeHasNoElements(heap, global_context, array_proto);
406
+ }
407
+
408
+
409
+ MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
410
+ Isolate* isolate,
411
+ const char* name,
412
+ BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
413
+ HandleScope handleScope(isolate);
414
+
415
+ Handle<Object> js_builtin =
416
+ GetProperty(Handle<JSObject>(
417
+ isolate->global_context()->builtins()),
418
+ name);
419
+ ASSERT(js_builtin->IsJSFunction());
420
+ Handle<JSFunction> function(Handle<JSFunction>::cast(js_builtin));
421
+ ScopedVector<Object**> argv(args.length() - 1);
422
+ int n_args = args.length() - 1;
423
+ for (int i = 0; i < n_args; i++) {
424
+ argv[i] = args.at<Object>(i + 1).location();
425
+ }
426
+ bool pending_exception = false;
427
+ Handle<Object> result = Execution::Call(function,
428
+ args.receiver(),
429
+ n_args,
430
+ argv.start(),
431
+ &pending_exception);
432
+ if (pending_exception) return Failure::Exception();
433
+ return *result;
434
+ }
435
+
436
+
437
+ BUILTIN(ArrayPush) {
438
+ Heap* heap = isolate->heap();
439
+ Object* receiver = *args.receiver();
440
+ Object* elms_obj;
441
+ { MaybeObject* maybe_elms_obj =
442
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
443
+ if (maybe_elms_obj == NULL) {
444
+ return CallJsBuiltin(isolate, "ArrayPush", args);
445
+ }
446
+ if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
447
+ }
448
+ FixedArray* elms = FixedArray::cast(elms_obj);
449
+ JSArray* array = JSArray::cast(receiver);
450
+
451
+ int len = Smi::cast(array->length())->value();
452
+ int to_add = args.length() - 1;
453
+ if (to_add == 0) {
454
+ return Smi::FromInt(len);
455
+ }
456
+ // Currently fixed arrays cannot grow too big, so
457
+ // we should never hit this case.
458
+ ASSERT(to_add <= (Smi::kMaxValue - len));
459
+
460
+ int new_length = len + to_add;
461
+
462
+ if (new_length > elms->length()) {
463
+ // New backing storage is needed.
464
+ int capacity = new_length + (new_length >> 1) + 16;
465
+ Object* obj;
466
+ { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
467
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
468
+ }
469
+ FixedArray* new_elms = FixedArray::cast(obj);
470
+
471
+ AssertNoAllocation no_gc;
472
+ if (len > 0) {
473
+ CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len);
474
+ }
475
+ FillWithHoles(heap, new_elms, new_length, capacity);
476
+
477
+ elms = new_elms;
478
+ array->set_elements(elms);
479
+ }
480
+
481
+ // Add the provided values.
482
+ AssertNoAllocation no_gc;
483
+ WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
484
+ for (int index = 0; index < to_add; index++) {
485
+ elms->set(index + len, args[index + 1], mode);
486
+ }
487
+
488
+ // Set the length.
489
+ array->set_length(Smi::FromInt(new_length));
490
+ return Smi::FromInt(new_length);
491
+ }
492
+
493
+
494
+ BUILTIN(ArrayPop) {
495
+ Heap* heap = isolate->heap();
496
+ Object* receiver = *args.receiver();
497
+ Object* elms_obj;
498
+ { MaybeObject* maybe_elms_obj =
499
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
500
+ if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
501
+ if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
502
+ }
503
+ FixedArray* elms = FixedArray::cast(elms_obj);
504
+ JSArray* array = JSArray::cast(receiver);
505
+
506
+ int len = Smi::cast(array->length())->value();
507
+ if (len == 0) return heap->undefined_value();
508
+
509
+ // Get top element
510
+ MaybeObject* top = elms->get(len - 1);
511
+
512
+ // Set the length.
513
+ array->set_length(Smi::FromInt(len - 1));
514
+
515
+ if (!top->IsTheHole()) {
516
+ // Delete the top element.
517
+ elms->set_the_hole(len - 1);
518
+ return top;
519
+ }
520
+
521
+ top = array->GetPrototype()->GetElement(len - 1);
522
+
523
+ return top;
524
+ }
525
+
526
+
527
+ BUILTIN(ArrayShift) {
528
+ Heap* heap = isolate->heap();
529
+ Object* receiver = *args.receiver();
530
+ Object* elms_obj;
531
+ { MaybeObject* maybe_elms_obj =
532
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
533
+ if (maybe_elms_obj == NULL)
534
+ return CallJsBuiltin(isolate, "ArrayShift", args);
535
+ if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
536
+ }
537
+ if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
538
+ return CallJsBuiltin(isolate, "ArrayShift", args);
539
+ }
540
+ FixedArray* elms = FixedArray::cast(elms_obj);
541
+ JSArray* array = JSArray::cast(receiver);
542
+ ASSERT(array->HasFastElements());
543
+
544
+ int len = Smi::cast(array->length())->value();
545
+ if (len == 0) return heap->undefined_value();
546
+
547
+ // Get first element
548
+ Object* first = elms->get(0);
549
+ if (first->IsTheHole()) {
550
+ first = heap->undefined_value();
551
+ }
552
+
553
+ if (!heap->lo_space()->Contains(elms)) {
554
+ // As elms still in the same space they used to be,
555
+ // there is no need to update region dirty mark.
556
+ array->set_elements(LeftTrimFixedArray(heap, elms, 1), SKIP_WRITE_BARRIER);
557
+ } else {
558
+ // Shift the elements.
559
+ AssertNoAllocation no_gc;
560
+ MoveElements(heap, &no_gc, elms, 0, elms, 1, len - 1);
561
+ elms->set(len - 1, heap->the_hole_value());
562
+ }
563
+
564
+ // Set the length.
565
+ array->set_length(Smi::FromInt(len - 1));
566
+
567
+ return first;
568
+ }
569
+
570
+
571
+ BUILTIN(ArrayUnshift) {
572
+ Heap* heap = isolate->heap();
573
+ Object* receiver = *args.receiver();
574
+ Object* elms_obj;
575
+ { MaybeObject* maybe_elms_obj =
576
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
577
+ if (maybe_elms_obj == NULL)
578
+ return CallJsBuiltin(isolate, "ArrayUnshift", args);
579
+ if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
580
+ }
581
+ if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
582
+ return CallJsBuiltin(isolate, "ArrayUnshift", args);
583
+ }
584
+ FixedArray* elms = FixedArray::cast(elms_obj);
585
+ JSArray* array = JSArray::cast(receiver);
586
+ ASSERT(array->HasFastElements());
587
+
588
+ int len = Smi::cast(array->length())->value();
589
+ int to_add = args.length() - 1;
590
+ int new_length = len + to_add;
591
+ // Currently fixed arrays cannot grow too big, so
592
+ // we should never hit this case.
593
+ ASSERT(to_add <= (Smi::kMaxValue - len));
594
+
595
+ if (new_length > elms->length()) {
596
+ // New backing storage is needed.
597
+ int capacity = new_length + (new_length >> 1) + 16;
598
+ Object* obj;
599
+ { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
600
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
601
+ }
602
+ FixedArray* new_elms = FixedArray::cast(obj);
603
+
604
+ AssertNoAllocation no_gc;
605
+ if (len > 0) {
606
+ CopyElements(heap, &no_gc, new_elms, to_add, elms, 0, len);
607
+ }
608
+ FillWithHoles(heap, new_elms, new_length, capacity);
609
+
610
+ elms = new_elms;
611
+ array->set_elements(elms);
612
+ } else {
613
+ AssertNoAllocation no_gc;
614
+ MoveElements(heap, &no_gc, elms, to_add, elms, 0, len);
615
+ }
616
+
617
+ // Add the provided values.
618
+ AssertNoAllocation no_gc;
619
+ WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
620
+ for (int i = 0; i < to_add; i++) {
621
+ elms->set(i, args[i + 1], mode);
622
+ }
623
+
624
+ // Set the length.
625
+ array->set_length(Smi::FromInt(new_length));
626
+ return Smi::FromInt(new_length);
627
+ }
628
+
629
+
630
+ BUILTIN(ArraySlice) {
631
+ Heap* heap = isolate->heap();
632
+ Object* receiver = *args.receiver();
633
+ FixedArray* elms;
634
+ int len = -1;
635
+ if (receiver->IsJSArray()) {
636
+ JSArray* array = JSArray::cast(receiver);
637
+ if (!array->HasFastElements() ||
638
+ !IsJSArrayFastElementMovingAllowed(heap, array)) {
639
+ return CallJsBuiltin(isolate, "ArraySlice", args);
640
+ }
641
+
642
+ elms = FixedArray::cast(array->elements());
643
+ len = Smi::cast(array->length())->value();
644
+ } else {
645
+ // Array.slice(arguments, ...) is quite a common idiom (notably more
646
+ // than 50% of invocations in Web apps). Treat it in C++ as well.
647
+ Map* arguments_map =
648
+ isolate->context()->global_context()->arguments_boilerplate()->map();
649
+
650
+ bool is_arguments_object_with_fast_elements =
651
+ receiver->IsJSObject()
652
+ && JSObject::cast(receiver)->map() == arguments_map
653
+ && JSObject::cast(receiver)->HasFastElements();
654
+ if (!is_arguments_object_with_fast_elements) {
655
+ return CallJsBuiltin(isolate, "ArraySlice", args);
656
+ }
657
+ elms = FixedArray::cast(JSObject::cast(receiver)->elements());
658
+ Object* len_obj = JSObject::cast(receiver)
659
+ ->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
660
+ if (!len_obj->IsSmi()) {
661
+ return CallJsBuiltin(isolate, "ArraySlice", args);
662
+ }
663
+ len = Smi::cast(len_obj)->value();
664
+ if (len > elms->length()) {
665
+ return CallJsBuiltin(isolate, "ArraySlice", args);
666
+ }
667
+ for (int i = 0; i < len; i++) {
668
+ if (elms->get(i) == heap->the_hole_value()) {
669
+ return CallJsBuiltin(isolate, "ArraySlice", args);
670
+ }
671
+ }
672
+ }
673
+ ASSERT(len >= 0);
674
+ int n_arguments = args.length() - 1;
675
+
676
+ // Note carefully choosen defaults---if argument is missing,
677
+ // it's undefined which gets converted to 0 for relative_start
678
+ // and to len for relative_end.
679
+ int relative_start = 0;
680
+ int relative_end = len;
681
+ if (n_arguments > 0) {
682
+ Object* arg1 = args[1];
683
+ if (arg1->IsSmi()) {
684
+ relative_start = Smi::cast(arg1)->value();
685
+ } else if (!arg1->IsUndefined()) {
686
+ return CallJsBuiltin(isolate, "ArraySlice", args);
687
+ }
688
+ if (n_arguments > 1) {
689
+ Object* arg2 = args[2];
690
+ if (arg2->IsSmi()) {
691
+ relative_end = Smi::cast(arg2)->value();
692
+ } else if (!arg2->IsUndefined()) {
693
+ return CallJsBuiltin(isolate, "ArraySlice", args);
694
+ }
695
+ }
696
+ }
697
+
698
+ // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
699
+ int k = (relative_start < 0) ? Max(len + relative_start, 0)
700
+ : Min(relative_start, len);
701
+
702
+ // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
703
+ int final = (relative_end < 0) ? Max(len + relative_end, 0)
704
+ : Min(relative_end, len);
705
+
706
+ // Calculate the length of result array.
707
+ int result_len = final - k;
708
+ if (result_len <= 0) {
709
+ return AllocateEmptyJSArray(heap);
710
+ }
711
+
712
+ Object* result;
713
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
714
+ if (!maybe_result->ToObject(&result)) return maybe_result;
715
+ }
716
+ JSArray* result_array = JSArray::cast(result);
717
+
718
+ { MaybeObject* maybe_result =
719
+ heap->AllocateUninitializedFixedArray(result_len);
720
+ if (!maybe_result->ToObject(&result)) return maybe_result;
721
+ }
722
+ FixedArray* result_elms = FixedArray::cast(result);
723
+
724
+ AssertNoAllocation no_gc;
725
+ CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len);
726
+
727
+ // Set elements.
728
+ result_array->set_elements(result_elms);
729
+
730
+ // Set the length.
731
+ result_array->set_length(Smi::FromInt(result_len));
732
+ return result_array;
733
+ }
734
+
735
+
736
+ BUILTIN(ArraySplice) {
737
+ Heap* heap = isolate->heap();
738
+ Object* receiver = *args.receiver();
739
+ Object* elms_obj;
740
+ { MaybeObject* maybe_elms_obj =
741
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
742
+ if (maybe_elms_obj == NULL)
743
+ return CallJsBuiltin(isolate, "ArraySplice", args);
744
+ if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
745
+ }
746
+ if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
747
+ return CallJsBuiltin(isolate, "ArraySplice", args);
748
+ }
749
+ FixedArray* elms = FixedArray::cast(elms_obj);
750
+ JSArray* array = JSArray::cast(receiver);
751
+ ASSERT(array->HasFastElements());
752
+
753
+ int len = Smi::cast(array->length())->value();
754
+
755
+ int n_arguments = args.length() - 1;
756
+
757
+ int relative_start = 0;
758
+ if (n_arguments > 0) {
759
+ Object* arg1 = args[1];
760
+ if (arg1->IsSmi()) {
761
+ relative_start = Smi::cast(arg1)->value();
762
+ } else if (!arg1->IsUndefined()) {
763
+ return CallJsBuiltin(isolate, "ArraySplice", args);
764
+ }
765
+ }
766
+ int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
767
+ : Min(relative_start, len);
768
+
769
+ // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
770
+ // given as a request to delete all the elements from the start.
771
+ // And it differs from the case of undefined delete count.
772
+ // This does not follow ECMA-262, but we do the same for
773
+ // compatibility.
774
+ int actual_delete_count;
775
+ if (n_arguments == 1) {
776
+ ASSERT(len - actual_start >= 0);
777
+ actual_delete_count = len - actual_start;
778
+ } else {
779
+ int value = 0; // ToInteger(undefined) == 0
780
+ if (n_arguments > 1) {
781
+ Object* arg2 = args[2];
782
+ if (arg2->IsSmi()) {
783
+ value = Smi::cast(arg2)->value();
784
+ } else {
785
+ return CallJsBuiltin(isolate, "ArraySplice", args);
786
+ }
787
+ }
788
+ actual_delete_count = Min(Max(value, 0), len - actual_start);
789
+ }
790
+
791
+ JSArray* result_array = NULL;
792
+ if (actual_delete_count == 0) {
793
+ Object* result;
794
+ { MaybeObject* maybe_result = AllocateEmptyJSArray(heap);
795
+ if (!maybe_result->ToObject(&result)) return maybe_result;
796
+ }
797
+ result_array = JSArray::cast(result);
798
+ } else {
799
+ // Allocate result array.
800
+ Object* result;
801
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
802
+ if (!maybe_result->ToObject(&result)) return maybe_result;
803
+ }
804
+ result_array = JSArray::cast(result);
805
+
806
+ { MaybeObject* maybe_result =
807
+ heap->AllocateUninitializedFixedArray(actual_delete_count);
808
+ if (!maybe_result->ToObject(&result)) return maybe_result;
809
+ }
810
+ FixedArray* result_elms = FixedArray::cast(result);
811
+
812
+ AssertNoAllocation no_gc;
813
+ // Fill newly created array.
814
+ CopyElements(heap,
815
+ &no_gc,
816
+ result_elms, 0,
817
+ elms, actual_start,
818
+ actual_delete_count);
819
+
820
+ // Set elements.
821
+ result_array->set_elements(result_elms);
822
+
823
+ // Set the length.
824
+ result_array->set_length(Smi::FromInt(actual_delete_count));
825
+ }
826
+
827
+ int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
828
+
829
+ int new_length = len - actual_delete_count + item_count;
830
+
831
+ if (item_count < actual_delete_count) {
832
+ // Shrink the array.
833
+ const bool trim_array = !heap->lo_space()->Contains(elms) &&
834
+ ((actual_start + item_count) <
835
+ (len - actual_delete_count - actual_start));
836
+ if (trim_array) {
837
+ const int delta = actual_delete_count - item_count;
838
+
839
+ if (actual_start > 0) {
840
+ AssertNoAllocation no_gc;
841
+ MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start);
842
+ }
843
+
844
+ elms = LeftTrimFixedArray(heap, elms, delta);
845
+ array->set_elements(elms, SKIP_WRITE_BARRIER);
846
+ } else {
847
+ AssertNoAllocation no_gc;
848
+ MoveElements(heap, &no_gc,
849
+ elms, actual_start + item_count,
850
+ elms, actual_start + actual_delete_count,
851
+ (len - actual_delete_count - actual_start));
852
+ FillWithHoles(heap, elms, new_length, len);
853
+ }
854
+ } else if (item_count > actual_delete_count) {
855
+ // Currently fixed arrays cannot grow too big, so
856
+ // we should never hit this case.
857
+ ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
858
+
859
+ // Check if array need to grow.
860
+ if (new_length > elms->length()) {
861
+ // New backing storage is needed.
862
+ int capacity = new_length + (new_length >> 1) + 16;
863
+ Object* obj;
864
+ { MaybeObject* maybe_obj =
865
+ heap->AllocateUninitializedFixedArray(capacity);
866
+ if (!maybe_obj->ToObject(&obj)) return maybe_obj;
867
+ }
868
+ FixedArray* new_elms = FixedArray::cast(obj);
869
+
870
+ AssertNoAllocation no_gc;
871
+ // Copy the part before actual_start as is.
872
+ if (actual_start > 0) {
873
+ CopyElements(heap, &no_gc, new_elms, 0, elms, 0, actual_start);
874
+ }
875
+ const int to_copy = len - actual_delete_count - actual_start;
876
+ if (to_copy > 0) {
877
+ CopyElements(heap, &no_gc,
878
+ new_elms, actual_start + item_count,
879
+ elms, actual_start + actual_delete_count,
880
+ to_copy);
881
+ }
882
+ FillWithHoles(heap, new_elms, new_length, capacity);
883
+
884
+ elms = new_elms;
885
+ array->set_elements(elms);
886
+ } else {
887
+ AssertNoAllocation no_gc;
888
+ MoveElements(heap, &no_gc,
889
+ elms, actual_start + item_count,
890
+ elms, actual_start + actual_delete_count,
891
+ (len - actual_delete_count - actual_start));
892
+ }
893
+ }
894
+
895
+ AssertNoAllocation no_gc;
896
+ WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
897
+ for (int k = actual_start; k < actual_start + item_count; k++) {
898
+ elms->set(k, args[3 + k - actual_start], mode);
899
+ }
900
+
901
+ // Set the length.
902
+ array->set_length(Smi::FromInt(new_length));
903
+
904
+ return result_array;
905
+ }
906
+
907
+
908
+ BUILTIN(ArrayConcat) {
909
+ Heap* heap = isolate->heap();
910
+ Context* global_context = isolate->context()->global_context();
911
+ JSObject* array_proto =
912
+ JSObject::cast(global_context->array_function()->prototype());
913
+ if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) {
914
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
915
+ }
916
+
917
+ // Iterate through all the arguments performing checks
918
+ // and calculating total length.
919
+ int n_arguments = args.length();
920
+ int result_len = 0;
921
+ for (int i = 0; i < n_arguments; i++) {
922
+ Object* arg = args[i];
923
+ if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements()
924
+ || JSArray::cast(arg)->GetPrototype() != array_proto) {
925
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
926
+ }
927
+
928
+ int len = Smi::cast(JSArray::cast(arg)->length())->value();
929
+
930
+ // We shouldn't overflow when adding another len.
931
+ const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
932
+ STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
933
+ USE(kHalfOfMaxInt);
934
+ result_len += len;
935
+ ASSERT(result_len >= 0);
936
+
937
+ if (result_len > FixedArray::kMaxLength) {
938
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
939
+ }
940
+ }
941
+
942
+ if (result_len == 0) {
943
+ return AllocateEmptyJSArray(heap);
944
+ }
945
+
946
+ // Allocate result.
947
+ Object* result;
948
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
949
+ if (!maybe_result->ToObject(&result)) return maybe_result;
950
+ }
951
+ JSArray* result_array = JSArray::cast(result);
952
+
953
+ { MaybeObject* maybe_result =
954
+ heap->AllocateUninitializedFixedArray(result_len);
955
+ if (!maybe_result->ToObject(&result)) return maybe_result;
956
+ }
957
+ FixedArray* result_elms = FixedArray::cast(result);
958
+
959
+ // Copy data.
960
+ AssertNoAllocation no_gc;
961
+ int start_pos = 0;
962
+ for (int i = 0; i < n_arguments; i++) {
963
+ JSArray* array = JSArray::cast(args[i]);
964
+ int len = Smi::cast(array->length())->value();
965
+ if (len > 0) {
966
+ FixedArray* elms = FixedArray::cast(array->elements());
967
+ CopyElements(heap, &no_gc, result_elms, start_pos, elms, 0, len);
968
+ start_pos += len;
969
+ }
970
+ }
971
+ ASSERT(start_pos == result_len);
972
+
973
+ // Set the length and elements.
974
+ result_array->set_length(Smi::FromInt(result_len));
975
+ result_array->set_elements(result_elms);
976
+
977
+ return result_array;
978
+ }
979
+
980
+
981
+ // -----------------------------------------------------------------------------
982
+ // Strict mode poison pills
983
+
984
+
985
+ BUILTIN(StrictModePoisonPill) {
986
+ HandleScope scope;
987
+ return isolate->Throw(*isolate->factory()->NewTypeError(
988
+ "strict_poison_pill", HandleVector<Object>(NULL, 0)));
989
+ }
990
+
991
+ // -----------------------------------------------------------------------------
992
+ //
993
+
994
+
995
+ // Returns the holder JSObject if the function can legally be called
996
+ // with this receiver. Returns Heap::null_value() if the call is
997
+ // illegal. Any arguments that don't fit the expected type is
998
+ // overwritten with undefined. Arguments that do fit the expected
999
+ // type is overwritten with the object in the prototype chain that
1000
+ // actually has that type.
1001
+ static inline Object* TypeCheck(Heap* heap,
1002
+ int argc,
1003
+ Object** argv,
1004
+ FunctionTemplateInfo* info) {
1005
+ Object* recv = argv[0];
1006
+ // API calls are only supported with JSObject receivers.
1007
+ if (!recv->IsJSObject()) return heap->null_value();
1008
+ Object* sig_obj = info->signature();
1009
+ if (sig_obj->IsUndefined()) return recv;
1010
+ SignatureInfo* sig = SignatureInfo::cast(sig_obj);
1011
+ // If necessary, check the receiver
1012
+ Object* recv_type = sig->receiver();
1013
+
1014
+ Object* holder = recv;
1015
+ if (!recv_type->IsUndefined()) {
1016
+ for (; holder != heap->null_value(); holder = holder->GetPrototype()) {
1017
+ if (holder->IsInstanceOf(FunctionTemplateInfo::cast(recv_type))) {
1018
+ break;
1019
+ }
1020
+ }
1021
+ if (holder == heap->null_value()) return holder;
1022
+ }
1023
+ Object* args_obj = sig->args();
1024
+ // If there is no argument signature we're done
1025
+ if (args_obj->IsUndefined()) return holder;
1026
+ FixedArray* args = FixedArray::cast(args_obj);
1027
+ int length = args->length();
1028
+ if (argc <= length) length = argc - 1;
1029
+ for (int i = 0; i < length; i++) {
1030
+ Object* argtype = args->get(i);
1031
+ if (argtype->IsUndefined()) continue;
1032
+ Object** arg = &argv[-1 - i];
1033
+ Object* current = *arg;
1034
+ for (; current != heap->null_value(); current = current->GetPrototype()) {
1035
+ if (current->IsInstanceOf(FunctionTemplateInfo::cast(argtype))) {
1036
+ *arg = current;
1037
+ break;
1038
+ }
1039
+ }
1040
+ if (current == heap->null_value()) *arg = heap->undefined_value();
1041
+ }
1042
+ return holder;
1043
+ }
1044
+
1045
+
1046
+ template <bool is_construct>
1047
+ MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
1048
+ BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) {
1049
+ ASSERT(is_construct == CalledAsConstructor(isolate));
1050
+ Heap* heap = isolate->heap();
1051
+
1052
+ HandleScope scope(isolate);
1053
+ Handle<JSFunction> function = args.called_function();
1054
+ ASSERT(function->shared()->IsApiFunction());
1055
+
1056
+ FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data();
1057
+ if (is_construct) {
1058
+ Handle<FunctionTemplateInfo> desc(fun_data, isolate);
1059
+ bool pending_exception = false;
1060
+ isolate->factory()->ConfigureInstance(
1061
+ desc, Handle<JSObject>::cast(args.receiver()), &pending_exception);
1062
+ ASSERT(isolate->has_pending_exception() == pending_exception);
1063
+ if (pending_exception) return Failure::Exception();
1064
+ fun_data = *desc;
1065
+ }
1066
+
1067
+ Object* raw_holder = TypeCheck(heap, args.length(), &args[0], fun_data);
1068
+
1069
+ if (raw_holder->IsNull()) {
1070
+ // This function cannot be called with the given receiver. Abort!
1071
+ Handle<Object> obj =
1072
+ isolate->factory()->NewTypeError(
1073
+ "illegal_invocation", HandleVector(&function, 1));
1074
+ return isolate->Throw(*obj);
1075
+ }
1076
+
1077
+ Object* raw_call_data = fun_data->call_code();
1078
+ if (!raw_call_data->IsUndefined()) {
1079
+ CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1080
+ Object* callback_obj = call_data->callback();
1081
+ v8::InvocationCallback callback =
1082
+ v8::ToCData<v8::InvocationCallback>(callback_obj);
1083
+ Object* data_obj = call_data->data();
1084
+ Object* result;
1085
+
1086
+ LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
1087
+ ASSERT(raw_holder->IsJSObject());
1088
+
1089
+ CustomArguments custom(isolate);
1090
+ v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
1091
+ data_obj, *function, raw_holder);
1092
+
1093
+ v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
1094
+ custom.end(),
1095
+ &args[0] - 1,
1096
+ args.length() - 1,
1097
+ is_construct);
1098
+
1099
+ v8::Handle<v8::Value> value;
1100
+ {
1101
+ // Leaving JavaScript.
1102
+ VMState state(isolate, EXTERNAL);
1103
+ ExternalCallbackScope call_scope(isolate,
1104
+ v8::ToCData<Address>(callback_obj));
1105
+ value = callback(new_args);
1106
+ }
1107
+ if (value.IsEmpty()) {
1108
+ result = heap->undefined_value();
1109
+ } else {
1110
+ result = *reinterpret_cast<Object**>(*value);
1111
+ }
1112
+
1113
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1114
+ if (!is_construct || result->IsJSObject()) return result;
1115
+ }
1116
+
1117
+ return *args.receiver();
1118
+ }
1119
+
1120
+
1121
+ BUILTIN(HandleApiCall) {
1122
+ return HandleApiCallHelper<false>(args, isolate);
1123
+ }
1124
+
1125
+
1126
+ BUILTIN(HandleApiCallConstruct) {
1127
+ return HandleApiCallHelper<true>(args, isolate);
1128
+ }
1129
+
1130
+
1131
+ #ifdef DEBUG
1132
+
1133
+ static void VerifyTypeCheck(Handle<JSObject> object,
1134
+ Handle<JSFunction> function) {
1135
+ ASSERT(function->shared()->IsApiFunction());
1136
+ FunctionTemplateInfo* info = function->shared()->get_api_func_data();
1137
+ if (info->signature()->IsUndefined()) return;
1138
+ SignatureInfo* signature = SignatureInfo::cast(info->signature());
1139
+ Object* receiver_type = signature->receiver();
1140
+ if (receiver_type->IsUndefined()) return;
1141
+ FunctionTemplateInfo* type = FunctionTemplateInfo::cast(receiver_type);
1142
+ ASSERT(object->IsInstanceOf(type));
1143
+ }
1144
+
1145
+ #endif
1146
+
1147
+
1148
+ BUILTIN(FastHandleApiCall) {
1149
+ ASSERT(!CalledAsConstructor(isolate));
1150
+ Heap* heap = isolate->heap();
1151
+ const bool is_construct = false;
1152
+
1153
+ // We expect four more arguments: callback, function, call data, and holder.
1154
+ const int args_length = args.length() - 4;
1155
+ ASSERT(args_length >= 0);
1156
+
1157
+ Object* callback_obj = args[args_length];
1158
+
1159
+ v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
1160
+ &args[args_length + 1],
1161
+ &args[0] - 1,
1162
+ args_length - 1,
1163
+ is_construct);
1164
+
1165
+ #ifdef DEBUG
1166
+ VerifyTypeCheck(Utils::OpenHandle(*new_args.Holder()),
1167
+ Utils::OpenHandle(*new_args.Callee()));
1168
+ #endif
1169
+ HandleScope scope(isolate);
1170
+ Object* result;
1171
+ v8::Handle<v8::Value> value;
1172
+ {
1173
+ // Leaving JavaScript.
1174
+ VMState state(isolate, EXTERNAL);
1175
+ ExternalCallbackScope call_scope(isolate,
1176
+ v8::ToCData<Address>(callback_obj));
1177
+ v8::InvocationCallback callback =
1178
+ v8::ToCData<v8::InvocationCallback>(callback_obj);
1179
+
1180
+ value = callback(new_args);
1181
+ }
1182
+ if (value.IsEmpty()) {
1183
+ result = heap->undefined_value();
1184
+ } else {
1185
+ result = *reinterpret_cast<Object**>(*value);
1186
+ }
1187
+
1188
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1189
+ return result;
1190
+ }
1191
+
1192
+
1193
+ // Helper function to handle calls to non-function objects created through the
1194
+ // API. The object can be called as either a constructor (using new) or just as
1195
+ // a function (without new).
1196
+ MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
1197
+ Isolate* isolate,
1198
+ bool is_construct_call,
1199
+ BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
1200
+ // Non-functions are never called as constructors. Even if this is an object
1201
+ // called as a constructor the delegate call is not a construct call.
1202
+ ASSERT(!CalledAsConstructor(isolate));
1203
+ Heap* heap = isolate->heap();
1204
+
1205
+ Handle<Object> receiver = args.at<Object>(0);
1206
+
1207
+ // Get the object called.
1208
+ JSObject* obj = JSObject::cast(*args.receiver());
1209
+
1210
+ // Get the invocation callback from the function descriptor that was
1211
+ // used to create the called object.
1212
+ ASSERT(obj->map()->has_instance_call_handler());
1213
+ JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
1214
+ ASSERT(constructor->shared()->IsApiFunction());
1215
+ Object* handler =
1216
+ constructor->shared()->get_api_func_data()->instance_call_handler();
1217
+ ASSERT(!handler->IsUndefined());
1218
+ CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
1219
+ Object* callback_obj = call_data->callback();
1220
+ v8::InvocationCallback callback =
1221
+ v8::ToCData<v8::InvocationCallback>(callback_obj);
1222
+
1223
+ // Get the data for the call and perform the callback.
1224
+ Object* result;
1225
+ {
1226
+ HandleScope scope(isolate);
1227
+ LOG(isolate, ApiObjectAccess("call non-function", obj));
1228
+
1229
+ CustomArguments custom(isolate);
1230
+ v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
1231
+ call_data->data(), constructor, obj);
1232
+ v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
1233
+ custom.end(),
1234
+ &args[0] - 1,
1235
+ args.length() - 1,
1236
+ is_construct_call);
1237
+ v8::Handle<v8::Value> value;
1238
+ {
1239
+ // Leaving JavaScript.
1240
+ VMState state(isolate, EXTERNAL);
1241
+ ExternalCallbackScope call_scope(isolate,
1242
+ v8::ToCData<Address>(callback_obj));
1243
+ value = callback(new_args);
1244
+ }
1245
+ if (value.IsEmpty()) {
1246
+ result = heap->undefined_value();
1247
+ } else {
1248
+ result = *reinterpret_cast<Object**>(*value);
1249
+ }
1250
+ }
1251
+ // Check for exceptions and return result.
1252
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1253
+ return result;
1254
+ }
1255
+
1256
+
1257
+ // Handle calls to non-function objects created through the API. This delegate
1258
+ // function is used when the call is a normal function call.
1259
+ BUILTIN(HandleApiCallAsFunction) {
1260
+ return HandleApiCallAsFunctionOrConstructor(isolate, false, args);
1261
+ }
1262
+
1263
+
1264
+ // Handle calls to non-function objects created through the API. This delegate
1265
+ // function is used when the call is a construct call.
1266
+ BUILTIN(HandleApiCallAsConstructor) {
1267
+ return HandleApiCallAsFunctionOrConstructor(isolate, true, args);
1268
+ }
1269
+
1270
+
1271
+ static void Generate_LoadIC_ArrayLength(MacroAssembler* masm) {
1272
+ LoadIC::GenerateArrayLength(masm);
1273
+ }
1274
+
1275
+
1276
+ static void Generate_LoadIC_StringLength(MacroAssembler* masm) {
1277
+ LoadIC::GenerateStringLength(masm, false);
1278
+ }
1279
+
1280
+
1281
+ static void Generate_LoadIC_StringWrapperLength(MacroAssembler* masm) {
1282
+ LoadIC::GenerateStringLength(masm, true);
1283
+ }
1284
+
1285
+
1286
+ static void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) {
1287
+ LoadIC::GenerateFunctionPrototype(masm);
1288
+ }
1289
+
1290
+
1291
+ static void Generate_LoadIC_Initialize(MacroAssembler* masm) {
1292
+ LoadIC::GenerateInitialize(masm);
1293
+ }
1294
+
1295
+
1296
+ static void Generate_LoadIC_PreMonomorphic(MacroAssembler* masm) {
1297
+ LoadIC::GeneratePreMonomorphic(masm);
1298
+ }
1299
+
1300
+
1301
+ static void Generate_LoadIC_Miss(MacroAssembler* masm) {
1302
+ LoadIC::GenerateMiss(masm);
1303
+ }
1304
+
1305
+
1306
+ static void Generate_LoadIC_Megamorphic(MacroAssembler* masm) {
1307
+ LoadIC::GenerateMegamorphic(masm);
1308
+ }
1309
+
1310
+
1311
+ static void Generate_LoadIC_Normal(MacroAssembler* masm) {
1312
+ LoadIC::GenerateNormal(masm);
1313
+ }
1314
+
1315
+
1316
+ static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
1317
+ KeyedLoadIC::GenerateInitialize(masm);
1318
+ }
1319
+
1320
+
1321
+ static void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) {
1322
+ KeyedLoadIC::GenerateRuntimeGetProperty(masm);
1323
+ }
1324
+
1325
+
1326
+ static void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
1327
+ KeyedLoadIC::GenerateMiss(masm, false);
1328
+ }
1329
+
1330
+
1331
+ static void Generate_KeyedLoadIC_MissForceGeneric(MacroAssembler* masm) {
1332
+ KeyedLoadIC::GenerateMiss(masm, true);
1333
+ }
1334
+
1335
+
1336
+ static void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) {
1337
+ KeyedLoadIC::GenerateGeneric(masm);
1338
+ }
1339
+
1340
+
1341
+ static void Generate_KeyedLoadIC_String(MacroAssembler* masm) {
1342
+ KeyedLoadIC::GenerateString(masm);
1343
+ }
1344
+
1345
+
1346
+ static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
1347
+ KeyedLoadIC::GeneratePreMonomorphic(masm);
1348
+ }
1349
+
1350
+ static void Generate_KeyedLoadIC_IndexedInterceptor(MacroAssembler* masm) {
1351
+ KeyedLoadIC::GenerateIndexedInterceptor(masm);
1352
+ }
1353
+
1354
+
1355
+ static void Generate_StoreIC_Initialize(MacroAssembler* masm) {
1356
+ StoreIC::GenerateInitialize(masm);
1357
+ }
1358
+
1359
+
1360
+ static void Generate_StoreIC_Initialize_Strict(MacroAssembler* masm) {
1361
+ StoreIC::GenerateInitialize(masm);
1362
+ }
1363
+
1364
+
1365
+ static void Generate_StoreIC_Miss(MacroAssembler* masm) {
1366
+ StoreIC::GenerateMiss(masm);
1367
+ }
1368
+
1369
+
1370
+ static void Generate_StoreIC_Normal(MacroAssembler* masm) {
1371
+ StoreIC::GenerateNormal(masm);
1372
+ }
1373
+
1374
+
1375
+ static void Generate_StoreIC_Normal_Strict(MacroAssembler* masm) {
1376
+ StoreIC::GenerateNormal(masm);
1377
+ }
1378
+
1379
+
1380
+ static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
1381
+ StoreIC::GenerateMegamorphic(masm, kNonStrictMode);
1382
+ }
1383
+
1384
+
1385
+ static void Generate_StoreIC_Megamorphic_Strict(MacroAssembler* masm) {
1386
+ StoreIC::GenerateMegamorphic(masm, kStrictMode);
1387
+ }
1388
+
1389
+
1390
+ static void Generate_StoreIC_ArrayLength(MacroAssembler* masm) {
1391
+ StoreIC::GenerateArrayLength(masm);
1392
+ }
1393
+
1394
+
1395
+ static void Generate_StoreIC_ArrayLength_Strict(MacroAssembler* masm) {
1396
+ StoreIC::GenerateArrayLength(masm);
1397
+ }
1398
+
1399
+
1400
+ static void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) {
1401
+ StoreIC::GenerateGlobalProxy(masm, kNonStrictMode);
1402
+ }
1403
+
1404
+
1405
+ static void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) {
1406
+ StoreIC::GenerateGlobalProxy(masm, kStrictMode);
1407
+ }
1408
+
1409
+
1410
+ static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
1411
+ KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode);
1412
+ }
1413
+
1414
+
1415
+ static void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) {
1416
+ KeyedStoreIC::GenerateGeneric(masm, kStrictMode);
1417
+ }
1418
+
1419
+
1420
+ static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
1421
+ KeyedStoreIC::GenerateMiss(masm, false);
1422
+ }
1423
+
1424
+
1425
+ static void Generate_KeyedStoreIC_MissForceGeneric(MacroAssembler* masm) {
1426
+ KeyedStoreIC::GenerateMiss(masm, true);
1427
+ }
1428
+
1429
+
1430
+ static void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
1431
+ KeyedStoreIC::GenerateSlow(masm);
1432
+ }
1433
+
1434
+
1435
+ static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) {
1436
+ KeyedStoreIC::GenerateInitialize(masm);
1437
+ }
1438
+
1439
+
1440
+ static void Generate_KeyedStoreIC_Initialize_Strict(MacroAssembler* masm) {
1441
+ KeyedStoreIC::GenerateInitialize(masm);
1442
+ }
1443
+
1444
+
1445
+ #ifdef ENABLE_DEBUGGER_SUPPORT
1446
+ static void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
1447
+ Debug::GenerateLoadICDebugBreak(masm);
1448
+ }
1449
+
1450
+
1451
+ static void Generate_StoreIC_DebugBreak(MacroAssembler* masm) {
1452
+ Debug::GenerateStoreICDebugBreak(masm);
1453
+ }
1454
+
1455
+
1456
+ static void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {
1457
+ Debug::GenerateKeyedLoadICDebugBreak(masm);
1458
+ }
1459
+
1460
+
1461
+ static void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
1462
+ Debug::GenerateKeyedStoreICDebugBreak(masm);
1463
+ }
1464
+
1465
+
1466
+ static void Generate_ConstructCall_DebugBreak(MacroAssembler* masm) {
1467
+ Debug::GenerateConstructCallDebugBreak(masm);
1468
+ }
1469
+
1470
+
1471
+ static void Generate_Return_DebugBreak(MacroAssembler* masm) {
1472
+ Debug::GenerateReturnDebugBreak(masm);
1473
+ }
1474
+
1475
+
1476
+ static void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) {
1477
+ Debug::GenerateStubNoRegistersDebugBreak(masm);
1478
+ }
1479
+
1480
+
1481
+ static void Generate_Slot_DebugBreak(MacroAssembler* masm) {
1482
+ Debug::GenerateSlotDebugBreak(masm);
1483
+ }
1484
+
1485
+
1486
+ static void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) {
1487
+ Debug::GeneratePlainReturnLiveEdit(masm);
1488
+ }
1489
+
1490
+
1491
+ static void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) {
1492
+ Debug::GenerateFrameDropperLiveEdit(masm);
1493
+ }
1494
+ #endif
1495
+
1496
+
1497
+ Builtins::Builtins() : initialized_(false) {
1498
+ memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
1499
+ memset(names_, 0, sizeof(names_[0]) * builtin_count);
1500
+ }
1501
+
1502
+
1503
+ Builtins::~Builtins() {
1504
+ }
1505
+
1506
+
1507
+ #define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
1508
+ Address const Builtins::c_functions_[cfunction_count] = {
1509
+ BUILTIN_LIST_C(DEF_ENUM_C)
1510
+ };
1511
+ #undef DEF_ENUM_C
1512
+
1513
+ #define DEF_JS_NAME(name, ignore) #name,
1514
+ #define DEF_JS_ARGC(ignore, argc) argc,
1515
+ const char* const Builtins::javascript_names_[id_count] = {
1516
+ BUILTINS_LIST_JS(DEF_JS_NAME)
1517
+ };
1518
+
1519
+ int const Builtins::javascript_argc_[id_count] = {
1520
+ BUILTINS_LIST_JS(DEF_JS_ARGC)
1521
+ };
1522
+ #undef DEF_JS_NAME
1523
+ #undef DEF_JS_ARGC
1524
+
1525
+ struct BuiltinDesc {
1526
+ byte* generator;
1527
+ byte* c_code;
1528
+ const char* s_name; // name is only used for generating log information.
1529
+ int name;
1530
+ Code::Flags flags;
1531
+ BuiltinExtraArguments extra_args;
1532
+ };
1533
+
1534
+ class BuiltinFunctionTable {
1535
+ public:
1536
+ BuiltinFunctionTable() {
1537
+ Builtins::InitBuiltinFunctionTable();
1538
+ }
1539
+
1540
+ static const BuiltinDesc* functions() { return functions_; }
1541
+
1542
+ private:
1543
+ static BuiltinDesc functions_[Builtins::builtin_count + 1];
1544
+
1545
+ friend class Builtins;
1546
+ };
1547
+
1548
+ BuiltinDesc BuiltinFunctionTable::functions_[Builtins::builtin_count + 1];
1549
+
1550
+ static const BuiltinFunctionTable builtin_function_table_init;
1551
+
1552
+ // Define array of pointers to generators and C builtin functions.
1553
+ // We do this in a sort of roundabout way so that we can do the initialization
1554
+ // within the lexical scope of Builtins:: and within a context where
1555
+ // Code::Flags names a non-abstract type.
1556
+ void Builtins::InitBuiltinFunctionTable() {
1557
+ BuiltinDesc* functions = BuiltinFunctionTable::functions_;
1558
+ functions[builtin_count].generator = NULL;
1559
+ functions[builtin_count].c_code = NULL;
1560
+ functions[builtin_count].s_name = NULL;
1561
+ functions[builtin_count].name = builtin_count;
1562
+ functions[builtin_count].flags = static_cast<Code::Flags>(0);
1563
+ functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS;
1564
+
1565
+ #define DEF_FUNCTION_PTR_C(aname, aextra_args) \
1566
+ functions->generator = FUNCTION_ADDR(Generate_Adaptor); \
1567
+ functions->c_code = FUNCTION_ADDR(Builtin_##aname); \
1568
+ functions->s_name = #aname; \
1569
+ functions->name = c_##aname; \
1570
+ functions->flags = Code::ComputeFlags(Code::BUILTIN); \
1571
+ functions->extra_args = aextra_args; \
1572
+ ++functions;
1573
+
1574
+ #define DEF_FUNCTION_PTR_A(aname, kind, state, extra) \
1575
+ functions->generator = FUNCTION_ADDR(Generate_##aname); \
1576
+ functions->c_code = NULL; \
1577
+ functions->s_name = #aname; \
1578
+ functions->name = k##aname; \
1579
+ functions->flags = Code::ComputeFlags(Code::kind, \
1580
+ NOT_IN_LOOP, \
1581
+ state, \
1582
+ extra); \
1583
+ functions->extra_args = NO_EXTRA_ARGUMENTS; \
1584
+ ++functions;
1585
+
1586
+ BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
1587
+ BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
1588
+ BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
1589
+
1590
+ #undef DEF_FUNCTION_PTR_C
1591
+ #undef DEF_FUNCTION_PTR_A
1592
+ }
1593
+
1594
+ void Builtins::Setup(bool create_heap_objects) {
1595
+ ASSERT(!initialized_);
1596
+ Isolate* isolate = Isolate::Current();
1597
+ Heap* heap = isolate->heap();
1598
+
1599
+ // Create a scope for the handles in the builtins.
1600
+ HandleScope scope(isolate);
1601
+
1602
+ const BuiltinDesc* functions = BuiltinFunctionTable::functions();
1603
+
1604
+ // For now we generate builtin adaptor code into a stack-allocated
1605
+ // buffer, before copying it into individual code objects.
1606
+ byte buffer[4*KB];
1607
+
1608
+ // Traverse the list of builtins and generate an adaptor in a
1609
+ // separate code object for each one.
1610
+ for (int i = 0; i < builtin_count; i++) {
1611
+ if (create_heap_objects) {
1612
+ MacroAssembler masm(isolate, buffer, sizeof buffer);
1613
+ // Generate the code/adaptor.
1614
+ typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments);
1615
+ Generator g = FUNCTION_CAST<Generator>(functions[i].generator);
1616
+ // We pass all arguments to the generator, but it may not use all of
1617
+ // them. This works because the first arguments are on top of the
1618
+ // stack.
1619
+ g(&masm, functions[i].name, functions[i].extra_args);
1620
+ // Move the code into the object heap.
1621
+ CodeDesc desc;
1622
+ masm.GetCode(&desc);
1623
+ Code::Flags flags = functions[i].flags;
1624
+ Object* code = NULL;
1625
+ {
1626
+ // During startup it's OK to always allocate and defer GC to later.
1627
+ // This simplifies things because we don't need to retry.
1628
+ AlwaysAllocateScope __scope__;
1629
+ { MaybeObject* maybe_code =
1630
+ heap->CreateCode(desc, flags, masm.CodeObject());
1631
+ if (!maybe_code->ToObject(&code)) {
1632
+ v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
1633
+ }
1634
+ }
1635
+ }
1636
+ // Log the event and add the code to the builtins array.
1637
+ PROFILE(isolate,
1638
+ CodeCreateEvent(Logger::BUILTIN_TAG,
1639
+ Code::cast(code),
1640
+ functions[i].s_name));
1641
+ GDBJIT(AddCode(GDBJITInterface::BUILTIN,
1642
+ functions[i].s_name,
1643
+ Code::cast(code)));
1644
+ builtins_[i] = code;
1645
+ #ifdef ENABLE_DISASSEMBLER
1646
+ if (FLAG_print_builtin_code) {
1647
+ PrintF("Builtin: %s\n", functions[i].s_name);
1648
+ Code::cast(code)->Disassemble(functions[i].s_name);
1649
+ PrintF("\n");
1650
+ }
1651
+ #endif
1652
+ } else {
1653
+ // Deserializing. The values will be filled in during IterateBuiltins.
1654
+ builtins_[i] = NULL;
1655
+ }
1656
+ names_[i] = functions[i].s_name;
1657
+ }
1658
+
1659
+ // Mark as initialized.
1660
+ initialized_ = true;
1661
+ }
1662
+
1663
+
1664
+ void Builtins::TearDown() {
1665
+ initialized_ = false;
1666
+ }
1667
+
1668
+
1669
+ void Builtins::IterateBuiltins(ObjectVisitor* v) {
1670
+ v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count);
1671
+ }
1672
+
1673
+
1674
+ const char* Builtins::Lookup(byte* pc) {
1675
+ // may be called during initialization (disassembler!)
1676
+ if (initialized_) {
1677
+ for (int i = 0; i < builtin_count; i++) {
1678
+ Code* entry = Code::cast(builtins_[i]);
1679
+ if (entry->contains(pc)) {
1680
+ return names_[i];
1681
+ }
1682
+ }
1683
+ }
1684
+ return NULL;
1685
+ }
1686
+
1687
+
1688
+ #define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \
1689
+ Handle<Code> Builtins::name() { \
1690
+ Code** code_address = \
1691
+ reinterpret_cast<Code**>(builtin_address(k##name)); \
1692
+ return Handle<Code>(code_address); \
1693
+ }
1694
+ #define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
1695
+ Handle<Code> Builtins::name() { \
1696
+ Code** code_address = \
1697
+ reinterpret_cast<Code**>(builtin_address(k##name)); \
1698
+ return Handle<Code>(code_address); \
1699
+ }
1700
+ BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1701
+ BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1702
+ BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1703
+ #undef DEFINE_BUILTIN_ACCESSOR_C
1704
+ #undef DEFINE_BUILTIN_ACCESSOR_A
1705
+
1706
+
1707
+ } } // namespace v8::internal