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,1621 @@
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
+ #if defined(V8_TARGET_ARCH_IA32)
31
+
32
+ #include "codegen.h"
33
+ #include "deoptimizer.h"
34
+ #include "full-codegen.h"
35
+
36
+ namespace v8 {
37
+ namespace internal {
38
+
39
+
40
+ #define __ ACCESS_MASM(masm)
41
+
42
+
43
+ void Builtins::Generate_Adaptor(MacroAssembler* masm,
44
+ CFunctionId id,
45
+ BuiltinExtraArguments extra_args) {
46
+ // ----------- S t a t e -------------
47
+ // -- eax : number of arguments excluding receiver
48
+ // -- edi : called function (only guaranteed when
49
+ // extra_args requires it)
50
+ // -- esi : context
51
+ // -- esp[0] : return address
52
+ // -- esp[4] : last argument
53
+ // -- ...
54
+ // -- esp[4 * argc] : first argument (argc == eax)
55
+ // -- esp[4 * (argc +1)] : receiver
56
+ // -----------------------------------
57
+
58
+ // Insert extra arguments.
59
+ int num_extra_args = 0;
60
+ if (extra_args == NEEDS_CALLED_FUNCTION) {
61
+ num_extra_args = 1;
62
+ Register scratch = ebx;
63
+ __ pop(scratch); // Save return address.
64
+ __ push(edi);
65
+ __ push(scratch); // Restore return address.
66
+ } else {
67
+ ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
68
+ }
69
+
70
+ // JumpToExternalReference expects eax to contain the number of arguments
71
+ // including the receiver and the extra arguments.
72
+ __ add(Operand(eax), Immediate(num_extra_args + 1));
73
+ __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
74
+ }
75
+
76
+
77
+ void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
78
+ // ----------- S t a t e -------------
79
+ // -- eax: number of arguments
80
+ // -- edi: constructor function
81
+ // -----------------------------------
82
+
83
+ Label non_function_call;
84
+ // Check that function is not a smi.
85
+ __ test(edi, Immediate(kSmiTagMask));
86
+ __ j(zero, &non_function_call);
87
+ // Check that function is a JSFunction.
88
+ __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
89
+ __ j(not_equal, &non_function_call);
90
+
91
+ // Jump to the function-specific construct stub.
92
+ __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
93
+ __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kConstructStubOffset));
94
+ __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize));
95
+ __ jmp(Operand(ebx));
96
+
97
+ // edi: called object
98
+ // eax: number of arguments
99
+ __ bind(&non_function_call);
100
+ // Set expected number of arguments to zero (not changing eax).
101
+ __ Set(ebx, Immediate(0));
102
+ __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
103
+ Handle<Code> arguments_adaptor =
104
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
105
+ __ SetCallKind(ecx, CALL_AS_METHOD);
106
+ __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET);
107
+ }
108
+
109
+
110
+ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
111
+ bool is_api_function,
112
+ bool count_constructions) {
113
+ // Should never count constructions for api objects.
114
+ ASSERT(!is_api_function || !count_constructions);
115
+
116
+ // Enter a construct frame.
117
+ __ EnterConstructFrame();
118
+
119
+ // Store a smi-tagged arguments count on the stack.
120
+ __ SmiTag(eax);
121
+ __ push(eax);
122
+
123
+ // Push the function to invoke on the stack.
124
+ __ push(edi);
125
+
126
+ // Try to allocate the object without transitioning into C code. If any of the
127
+ // preconditions is not met, the code bails out to the runtime call.
128
+ Label rt_call, allocated;
129
+ if (FLAG_inline_new) {
130
+ Label undo_allocation;
131
+ #ifdef ENABLE_DEBUGGER_SUPPORT
132
+ ExternalReference debug_step_in_fp =
133
+ ExternalReference::debug_step_in_fp_address(masm->isolate());
134
+ __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0));
135
+ __ j(not_equal, &rt_call);
136
+ #endif
137
+
138
+ // Verified that the constructor is a JSFunction.
139
+ // Load the initial map and verify that it is in fact a map.
140
+ // edi: constructor
141
+ __ mov(eax, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
142
+ // Will both indicate a NULL and a Smi
143
+ __ test(eax, Immediate(kSmiTagMask));
144
+ __ j(zero, &rt_call);
145
+ // edi: constructor
146
+ // eax: initial map (if proven valid below)
147
+ __ CmpObjectType(eax, MAP_TYPE, ebx);
148
+ __ j(not_equal, &rt_call);
149
+
150
+ // Check that the constructor is not constructing a JSFunction (see comments
151
+ // in Runtime_NewObject in runtime.cc). In which case the initial map's
152
+ // instance type would be JS_FUNCTION_TYPE.
153
+ // edi: constructor
154
+ // eax: initial map
155
+ __ CmpInstanceType(eax, JS_FUNCTION_TYPE);
156
+ __ j(equal, &rt_call);
157
+
158
+ if (count_constructions) {
159
+ Label allocate;
160
+ // Decrease generous allocation count.
161
+ __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
162
+ __ dec_b(FieldOperand(ecx, SharedFunctionInfo::kConstructionCountOffset));
163
+ __ j(not_zero, &allocate);
164
+
165
+ __ push(eax);
166
+ __ push(edi);
167
+
168
+ __ push(edi); // constructor
169
+ // The call will replace the stub, so the countdown is only done once.
170
+ __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
171
+
172
+ __ pop(edi);
173
+ __ pop(eax);
174
+
175
+ __ bind(&allocate);
176
+ }
177
+
178
+ // Now allocate the JSObject on the heap.
179
+ // edi: constructor
180
+ // eax: initial map
181
+ __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
182
+ __ shl(edi, kPointerSizeLog2);
183
+ __ AllocateInNewSpace(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
184
+ // Allocated the JSObject, now initialize the fields.
185
+ // eax: initial map
186
+ // ebx: JSObject
187
+ // edi: start of next object
188
+ __ mov(Operand(ebx, JSObject::kMapOffset), eax);
189
+ Factory* factory = masm->isolate()->factory();
190
+ __ mov(ecx, factory->empty_fixed_array());
191
+ __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);
192
+ __ mov(Operand(ebx, JSObject::kElementsOffset), ecx);
193
+ // Set extra fields in the newly allocated object.
194
+ // eax: initial map
195
+ // ebx: JSObject
196
+ // edi: start of next object
197
+ { Label loop, entry;
198
+ // To allow for truncation.
199
+ if (count_constructions) {
200
+ __ mov(edx, factory->one_pointer_filler_map());
201
+ } else {
202
+ __ mov(edx, factory->undefined_value());
203
+ }
204
+ __ lea(ecx, Operand(ebx, JSObject::kHeaderSize));
205
+ __ jmp(&entry);
206
+ __ bind(&loop);
207
+ __ mov(Operand(ecx, 0), edx);
208
+ __ add(Operand(ecx), Immediate(kPointerSize));
209
+ __ bind(&entry);
210
+ __ cmp(ecx, Operand(edi));
211
+ __ j(less, &loop);
212
+ }
213
+
214
+ // Add the object tag to make the JSObject real, so that we can continue and
215
+ // jump into the continuation code at any time from now on. Any failures
216
+ // need to undo the allocation, so that the heap is in a consistent state
217
+ // and verifiable.
218
+ // eax: initial map
219
+ // ebx: JSObject
220
+ // edi: start of next object
221
+ __ or_(Operand(ebx), Immediate(kHeapObjectTag));
222
+
223
+ // Check if a non-empty properties array is needed.
224
+ // Allocate and initialize a FixedArray if it is.
225
+ // eax: initial map
226
+ // ebx: JSObject
227
+ // edi: start of next object
228
+ // Calculate the total number of properties described by the map.
229
+ __ movzx_b(edx, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
230
+ __ movzx_b(ecx, FieldOperand(eax, Map::kPreAllocatedPropertyFieldsOffset));
231
+ __ add(edx, Operand(ecx));
232
+ // Calculate unused properties past the end of the in-object properties.
233
+ __ movzx_b(ecx, FieldOperand(eax, Map::kInObjectPropertiesOffset));
234
+ __ sub(edx, Operand(ecx));
235
+ // Done if no extra properties are to be allocated.
236
+ __ j(zero, &allocated);
237
+ __ Assert(positive, "Property allocation count failed.");
238
+
239
+ // Scale the number of elements by pointer size and add the header for
240
+ // FixedArrays to the start of the next object calculation from above.
241
+ // ebx: JSObject
242
+ // edi: start of next object (will be start of FixedArray)
243
+ // edx: number of elements in properties array
244
+ __ AllocateInNewSpace(FixedArray::kHeaderSize,
245
+ times_pointer_size,
246
+ edx,
247
+ edi,
248
+ ecx,
249
+ no_reg,
250
+ &undo_allocation,
251
+ RESULT_CONTAINS_TOP);
252
+
253
+ // Initialize the FixedArray.
254
+ // ebx: JSObject
255
+ // edi: FixedArray
256
+ // edx: number of elements
257
+ // ecx: start of next object
258
+ __ mov(eax, factory->fixed_array_map());
259
+ __ mov(Operand(edi, FixedArray::kMapOffset), eax); // setup the map
260
+ __ SmiTag(edx);
261
+ __ mov(Operand(edi, FixedArray::kLengthOffset), edx); // and length
262
+
263
+ // Initialize the fields to undefined.
264
+ // ebx: JSObject
265
+ // edi: FixedArray
266
+ // ecx: start of next object
267
+ { Label loop, entry;
268
+ __ mov(edx, factory->undefined_value());
269
+ __ lea(eax, Operand(edi, FixedArray::kHeaderSize));
270
+ __ jmp(&entry);
271
+ __ bind(&loop);
272
+ __ mov(Operand(eax, 0), edx);
273
+ __ add(Operand(eax), Immediate(kPointerSize));
274
+ __ bind(&entry);
275
+ __ cmp(eax, Operand(ecx));
276
+ __ j(below, &loop);
277
+ }
278
+
279
+ // Store the initialized FixedArray into the properties field of
280
+ // the JSObject
281
+ // ebx: JSObject
282
+ // edi: FixedArray
283
+ __ or_(Operand(edi), Immediate(kHeapObjectTag)); // add the heap tag
284
+ __ mov(FieldOperand(ebx, JSObject::kPropertiesOffset), edi);
285
+
286
+
287
+ // Continue with JSObject being successfully allocated
288
+ // ebx: JSObject
289
+ __ jmp(&allocated);
290
+
291
+ // Undo the setting of the new top so that the heap is verifiable. For
292
+ // example, the map's unused properties potentially do not match the
293
+ // allocated objects unused properties.
294
+ // ebx: JSObject (previous new top)
295
+ __ bind(&undo_allocation);
296
+ __ UndoAllocationInNewSpace(ebx);
297
+ }
298
+
299
+ // Allocate the new receiver object using the runtime call.
300
+ __ bind(&rt_call);
301
+ // Must restore edi (constructor) before calling runtime.
302
+ __ mov(edi, Operand(esp, 0));
303
+ // edi: function (constructor)
304
+ __ push(edi);
305
+ __ CallRuntime(Runtime::kNewObject, 1);
306
+ __ mov(ebx, Operand(eax)); // store result in ebx
307
+
308
+ // New object allocated.
309
+ // ebx: newly allocated object
310
+ __ bind(&allocated);
311
+ // Retrieve the function from the stack.
312
+ __ pop(edi);
313
+
314
+ // Retrieve smi-tagged arguments count from the stack.
315
+ __ mov(eax, Operand(esp, 0));
316
+ __ SmiUntag(eax);
317
+
318
+ // Push the allocated receiver to the stack. We need two copies
319
+ // because we may have to return the original one and the calling
320
+ // conventions dictate that the called function pops the receiver.
321
+ __ push(ebx);
322
+ __ push(ebx);
323
+
324
+ // Setup pointer to last argument.
325
+ __ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset));
326
+
327
+ // Copy arguments and receiver to the expression stack.
328
+ Label loop, entry;
329
+ __ mov(ecx, Operand(eax));
330
+ __ jmp(&entry);
331
+ __ bind(&loop);
332
+ __ push(Operand(ebx, ecx, times_4, 0));
333
+ __ bind(&entry);
334
+ __ dec(ecx);
335
+ __ j(greater_equal, &loop);
336
+
337
+ // Call the function.
338
+ if (is_api_function) {
339
+ __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
340
+ Handle<Code> code =
341
+ masm->isolate()->builtins()->HandleApiCallConstruct();
342
+ ParameterCount expected(0);
343
+ __ InvokeCode(code, expected, expected,
344
+ RelocInfo::CODE_TARGET, CALL_FUNCTION);
345
+ } else {
346
+ ParameterCount actual(eax);
347
+ __ InvokeFunction(edi, actual, CALL_FUNCTION);
348
+ }
349
+
350
+ // Restore context from the frame.
351
+ __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
352
+
353
+ // If the result is an object (in the ECMA sense), we should get rid
354
+ // of the receiver and use the result; see ECMA-262 section 13.2.2-7
355
+ // on page 74.
356
+ Label use_receiver, exit;
357
+
358
+ // If the result is a smi, it is *not* an object in the ECMA sense.
359
+ __ test(eax, Immediate(kSmiTagMask));
360
+ __ j(zero, &use_receiver);
361
+
362
+ // If the type of the result (stored in its map) is less than
363
+ // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
364
+ __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
365
+ __ j(above_equal, &exit);
366
+
367
+ // Throw away the result of the constructor invocation and use the
368
+ // on-stack receiver as the result.
369
+ __ bind(&use_receiver);
370
+ __ mov(eax, Operand(esp, 0));
371
+
372
+ // Restore the arguments count and leave the construct frame.
373
+ __ bind(&exit);
374
+ __ mov(ebx, Operand(esp, kPointerSize)); // get arguments count
375
+ __ LeaveConstructFrame();
376
+
377
+ // Remove caller arguments from the stack and return.
378
+ ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
379
+ __ pop(ecx);
380
+ __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
381
+ __ push(ecx);
382
+ __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
383
+ __ ret(0);
384
+ }
385
+
386
+
387
+ void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
388
+ Generate_JSConstructStubHelper(masm, false, true);
389
+ }
390
+
391
+
392
+ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
393
+ Generate_JSConstructStubHelper(masm, false, false);
394
+ }
395
+
396
+
397
+ void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
398
+ Generate_JSConstructStubHelper(masm, true, false);
399
+ }
400
+
401
+
402
+ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
403
+ bool is_construct) {
404
+ // Clear the context before we push it when entering the JS frame.
405
+ __ Set(esi, Immediate(0));
406
+
407
+ // Enter an internal frame.
408
+ __ EnterInternalFrame();
409
+
410
+ // Load the previous frame pointer (ebx) to access C arguments
411
+ __ mov(ebx, Operand(ebp, 0));
412
+
413
+ // Get the function from the frame and setup the context.
414
+ __ mov(ecx, Operand(ebx, EntryFrameConstants::kFunctionArgOffset));
415
+ __ mov(esi, FieldOperand(ecx, JSFunction::kContextOffset));
416
+
417
+ // Push the function and the receiver onto the stack.
418
+ __ push(ecx);
419
+ __ push(Operand(ebx, EntryFrameConstants::kReceiverArgOffset));
420
+
421
+ // Load the number of arguments and setup pointer to the arguments.
422
+ __ mov(eax, Operand(ebx, EntryFrameConstants::kArgcOffset));
423
+ __ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset));
424
+
425
+ // Copy arguments to the stack in a loop.
426
+ Label loop, entry;
427
+ __ Set(ecx, Immediate(0));
428
+ __ jmp(&entry);
429
+ __ bind(&loop);
430
+ __ mov(edx, Operand(ebx, ecx, times_4, 0)); // push parameter from argv
431
+ __ push(Operand(edx, 0)); // dereference handle
432
+ __ inc(Operand(ecx));
433
+ __ bind(&entry);
434
+ __ cmp(ecx, Operand(eax));
435
+ __ j(not_equal, &loop);
436
+
437
+ // Get the function from the stack and call it.
438
+ __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize)); // +1 ~ receiver
439
+
440
+ // Invoke the code.
441
+ if (is_construct) {
442
+ __ call(masm->isolate()->builtins()->JSConstructCall(),
443
+ RelocInfo::CODE_TARGET);
444
+ } else {
445
+ ParameterCount actual(eax);
446
+ __ InvokeFunction(edi, actual, CALL_FUNCTION);
447
+ }
448
+
449
+ // Exit the JS frame. Notice that this also removes the empty
450
+ // context and the function left on the stack by the code
451
+ // invocation.
452
+ __ LeaveInternalFrame();
453
+ __ ret(1 * kPointerSize); // remove receiver
454
+ }
455
+
456
+
457
+ void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
458
+ Generate_JSEntryTrampolineHelper(masm, false);
459
+ }
460
+
461
+
462
+ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
463
+ Generate_JSEntryTrampolineHelper(masm, true);
464
+ }
465
+
466
+
467
+ void Builtins::Generate_LazyCompile(MacroAssembler* masm) {
468
+ // Enter an internal frame.
469
+ __ EnterInternalFrame();
470
+
471
+ // Push a copy of the function.
472
+ __ push(edi);
473
+ // Push call kind information.
474
+ __ push(ecx);
475
+
476
+ __ push(edi); // Function is also the parameter to the runtime call.
477
+ __ CallRuntime(Runtime::kLazyCompile, 1);
478
+
479
+ // Restore call kind information.
480
+ __ pop(ecx);
481
+ // Restore receiver.
482
+ __ pop(edi);
483
+
484
+ // Tear down temporary frame.
485
+ __ LeaveInternalFrame();
486
+
487
+ // Do a tail-call of the compiled function.
488
+ __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
489
+ __ jmp(Operand(eax));
490
+ }
491
+
492
+
493
+ void Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
494
+ // Enter an internal frame.
495
+ __ EnterInternalFrame();
496
+
497
+ // Push a copy of the function onto the stack.
498
+ __ push(edi);
499
+ // Push call kind information.
500
+ __ push(ecx);
501
+
502
+ __ push(edi); // Function is also the parameter to the runtime call.
503
+ __ CallRuntime(Runtime::kLazyRecompile, 1);
504
+
505
+ // Restore call kind information.
506
+ __ pop(ecx);
507
+ // Restore receiver.
508
+ __ pop(edi);
509
+
510
+ // Tear down temporary frame.
511
+ __ LeaveInternalFrame();
512
+
513
+ // Do a tail-call of the compiled function.
514
+ __ lea(eax, FieldOperand(eax, Code::kHeaderSize));
515
+ __ jmp(Operand(eax));
516
+ }
517
+
518
+
519
+ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
520
+ Deoptimizer::BailoutType type) {
521
+ // Enter an internal frame.
522
+ __ EnterInternalFrame();
523
+
524
+ // Pass the function and deoptimization type to the runtime system.
525
+ __ push(Immediate(Smi::FromInt(static_cast<int>(type))));
526
+ __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
527
+
528
+ // Tear down temporary frame.
529
+ __ LeaveInternalFrame();
530
+
531
+ // Get the full codegen state from the stack and untag it.
532
+ __ mov(ecx, Operand(esp, 1 * kPointerSize));
533
+ __ SmiUntag(ecx);
534
+
535
+ // Switch on the state.
536
+ Label not_no_registers, not_tos_eax;
537
+ __ cmp(ecx, FullCodeGenerator::NO_REGISTERS);
538
+ __ j(not_equal, &not_no_registers, Label::kNear);
539
+ __ ret(1 * kPointerSize); // Remove state.
540
+
541
+ __ bind(&not_no_registers);
542
+ __ mov(eax, Operand(esp, 2 * kPointerSize));
543
+ __ cmp(ecx, FullCodeGenerator::TOS_REG);
544
+ __ j(not_equal, &not_tos_eax, Label::kNear);
545
+ __ ret(2 * kPointerSize); // Remove state, eax.
546
+
547
+ __ bind(&not_tos_eax);
548
+ __ Abort("no cases left");
549
+ }
550
+
551
+
552
+ void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
553
+ Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
554
+ }
555
+
556
+
557
+ void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
558
+ Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
559
+ }
560
+
561
+
562
+ void Builtins::Generate_NotifyOSR(MacroAssembler* masm) {
563
+ // TODO(kasperl): Do we need to save/restore the XMM registers too?
564
+
565
+ // For now, we are relying on the fact that Runtime::NotifyOSR
566
+ // doesn't do any garbage collection which allows us to save/restore
567
+ // the registers without worrying about which of them contain
568
+ // pointers. This seems a bit fragile.
569
+ __ pushad();
570
+ __ EnterInternalFrame();
571
+ __ CallRuntime(Runtime::kNotifyOSR, 0);
572
+ __ LeaveInternalFrame();
573
+ __ popad();
574
+ __ ret(0);
575
+ }
576
+
577
+
578
+ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
579
+ Factory* factory = masm->isolate()->factory();
580
+
581
+ // 1. Make sure we have at least one argument.
582
+ { Label done;
583
+ __ test(eax, Operand(eax));
584
+ __ j(not_zero, &done);
585
+ __ pop(ebx);
586
+ __ push(Immediate(factory->undefined_value()));
587
+ __ push(ebx);
588
+ __ inc(eax);
589
+ __ bind(&done);
590
+ }
591
+
592
+ // 2. Get the function to call (passed as receiver) from the stack, check
593
+ // if it is a function.
594
+ Label non_function;
595
+ // 1 ~ return address.
596
+ __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
597
+ __ test(edi, Immediate(kSmiTagMask));
598
+ __ j(zero, &non_function);
599
+ __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
600
+ __ j(not_equal, &non_function);
601
+
602
+
603
+ // 3a. Patch the first argument if necessary when calling a function.
604
+ Label shift_arguments;
605
+ { Label convert_to_object, use_global_receiver, patch_receiver;
606
+ // Change context eagerly in case we need the global receiver.
607
+ __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
608
+
609
+ // Do not transform the receiver for strict mode functions.
610
+ __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
611
+ __ test_b(FieldOperand(ebx, SharedFunctionInfo::kStrictModeByteOffset),
612
+ 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
613
+ __ j(not_equal, &shift_arguments);
614
+
615
+ // Do not transform the receiver for natives (shared already in ebx).
616
+ __ test_b(FieldOperand(ebx, SharedFunctionInfo::kES5NativeByteOffset),
617
+ 1 << SharedFunctionInfo::kES5NativeBitWithinByte);
618
+ __ j(not_equal, &shift_arguments);
619
+
620
+ // Compute the receiver in non-strict mode.
621
+ __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument.
622
+
623
+ // Call ToObject on the receiver if it is not an object, or use the
624
+ // global object if it is null or undefined.
625
+ __ test(ebx, Immediate(kSmiTagMask));
626
+ __ j(zero, &convert_to_object);
627
+ __ cmp(ebx, factory->null_value());
628
+ __ j(equal, &use_global_receiver);
629
+ __ cmp(ebx, factory->undefined_value());
630
+ __ j(equal, &use_global_receiver);
631
+ STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
632
+ STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
633
+ __ CmpObjectType(ebx, FIRST_JS_OBJECT_TYPE, ecx);
634
+ __ j(above_equal, &shift_arguments);
635
+
636
+ __ bind(&convert_to_object);
637
+ __ EnterInternalFrame(); // In order to preserve argument count.
638
+ __ SmiTag(eax);
639
+ __ push(eax);
640
+
641
+ __ push(ebx);
642
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
643
+ __ mov(ebx, eax);
644
+
645
+ __ pop(eax);
646
+ __ SmiUntag(eax);
647
+ __ LeaveInternalFrame();
648
+ // Restore the function to edi.
649
+ __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
650
+ __ jmp(&patch_receiver);
651
+
652
+ // Use the global receiver object from the called function as the
653
+ // receiver.
654
+ __ bind(&use_global_receiver);
655
+ const int kGlobalIndex =
656
+ Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
657
+ __ mov(ebx, FieldOperand(esi, kGlobalIndex));
658
+ __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalContextOffset));
659
+ __ mov(ebx, FieldOperand(ebx, kGlobalIndex));
660
+ __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
661
+
662
+ __ bind(&patch_receiver);
663
+ __ mov(Operand(esp, eax, times_4, 0), ebx);
664
+
665
+ __ jmp(&shift_arguments);
666
+ }
667
+
668
+ // 3b. Patch the first argument when calling a non-function. The
669
+ // CALL_NON_FUNCTION builtin expects the non-function callee as
670
+ // receiver, so overwrite the first argument which will ultimately
671
+ // become the receiver.
672
+ __ bind(&non_function);
673
+ __ mov(Operand(esp, eax, times_4, 0), edi);
674
+ // Clear edi to indicate a non-function being called.
675
+ __ Set(edi, Immediate(0));
676
+
677
+ // 4. Shift arguments and return address one slot down on the stack
678
+ // (overwriting the original receiver). Adjust argument count to make
679
+ // the original first argument the new receiver.
680
+ __ bind(&shift_arguments);
681
+ { Label loop;
682
+ __ mov(ecx, eax);
683
+ __ bind(&loop);
684
+ __ mov(ebx, Operand(esp, ecx, times_4, 0));
685
+ __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx);
686
+ __ dec(ecx);
687
+ __ j(not_sign, &loop); // While non-negative (to copy return address).
688
+ __ pop(ebx); // Discard copy of return address.
689
+ __ dec(eax); // One fewer argument (first argument is new receiver).
690
+ }
691
+
692
+ // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin.
693
+ { Label function;
694
+ __ test(edi, Operand(edi));
695
+ __ j(not_zero, &function);
696
+ __ Set(ebx, Immediate(0));
697
+ __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
698
+ __ SetCallKind(ecx, CALL_AS_METHOD);
699
+ __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
700
+ RelocInfo::CODE_TARGET);
701
+ __ bind(&function);
702
+ }
703
+
704
+ // 5b. Get the code to call from the function and check that the number of
705
+ // expected arguments matches what we're providing. If so, jump
706
+ // (tail-call) to the code in register edx without checking arguments.
707
+ __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
708
+ __ mov(ebx,
709
+ FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
710
+ __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
711
+ __ SmiUntag(ebx);
712
+ __ SetCallKind(ecx, CALL_AS_METHOD);
713
+ __ cmp(eax, Operand(ebx));
714
+ __ j(not_equal,
715
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline());
716
+
717
+ ParameterCount expected(0);
718
+ __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
719
+ }
720
+
721
+
722
+ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
723
+ __ EnterInternalFrame();
724
+
725
+ __ push(Operand(ebp, 4 * kPointerSize)); // push this
726
+ __ push(Operand(ebp, 2 * kPointerSize)); // push arguments
727
+ __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
728
+
729
+ // Check the stack for overflow. We are not trying need to catch
730
+ // interruptions (e.g. debug break and preemption) here, so the "real stack
731
+ // limit" is checked.
732
+ Label okay;
733
+ ExternalReference real_stack_limit =
734
+ ExternalReference::address_of_real_stack_limit(masm->isolate());
735
+ __ mov(edi, Operand::StaticVariable(real_stack_limit));
736
+ // Make ecx the space we have left. The stack might already be overflowed
737
+ // here which will cause ecx to become negative.
738
+ __ mov(ecx, Operand(esp));
739
+ __ sub(ecx, Operand(edi));
740
+ // Make edx the space we need for the array when it is unrolled onto the
741
+ // stack.
742
+ __ mov(edx, Operand(eax));
743
+ __ shl(edx, kPointerSizeLog2 - kSmiTagSize);
744
+ // Check if the arguments will overflow the stack.
745
+ __ cmp(ecx, Operand(edx));
746
+ __ j(greater, &okay); // Signed comparison.
747
+
748
+ // Out of stack space.
749
+ __ push(Operand(ebp, 4 * kPointerSize)); // push this
750
+ __ push(eax);
751
+ __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
752
+ __ bind(&okay);
753
+ // End of stack check.
754
+
755
+ // Push current index and limit.
756
+ const int kLimitOffset =
757
+ StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
758
+ const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
759
+ __ push(eax); // limit
760
+ __ push(Immediate(0)); // index
761
+
762
+ // Change context eagerly to get the right global object if
763
+ // necessary.
764
+ __ mov(edi, Operand(ebp, 4 * kPointerSize));
765
+ __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
766
+
767
+ // Compute the receiver.
768
+ Label call_to_object, use_global_receiver, push_receiver;
769
+ __ mov(ebx, Operand(ebp, 3 * kPointerSize));
770
+
771
+ // Do not transform the receiver for strict mode functions.
772
+ __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
773
+ __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
774
+ 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
775
+ __ j(not_equal, &push_receiver);
776
+
777
+ Factory* factory = masm->isolate()->factory();
778
+
779
+ // Do not transform the receiver for natives (shared already in ecx).
780
+ __ test_b(FieldOperand(ecx, SharedFunctionInfo::kES5NativeByteOffset),
781
+ 1 << SharedFunctionInfo::kES5NativeBitWithinByte);
782
+ __ j(not_equal, &push_receiver);
783
+
784
+ // Compute the receiver in non-strict mode.
785
+ // Call ToObject on the receiver if it is not an object, or use the
786
+ // global object if it is null or undefined.
787
+ __ test(ebx, Immediate(kSmiTagMask));
788
+ __ j(zero, &call_to_object);
789
+ __ cmp(ebx, factory->null_value());
790
+ __ j(equal, &use_global_receiver);
791
+ __ cmp(ebx, factory->undefined_value());
792
+ __ j(equal, &use_global_receiver);
793
+ STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
794
+ STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
795
+ __ CmpObjectType(ebx, FIRST_JS_OBJECT_TYPE, ecx);
796
+ __ j(above_equal, &push_receiver);
797
+
798
+ __ bind(&call_to_object);
799
+ __ push(ebx);
800
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
801
+ __ mov(ebx, Operand(eax));
802
+ __ jmp(&push_receiver);
803
+
804
+ // Use the current global receiver object as the receiver.
805
+ __ bind(&use_global_receiver);
806
+ const int kGlobalOffset =
807
+ Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
808
+ __ mov(ebx, FieldOperand(esi, kGlobalOffset));
809
+ __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalContextOffset));
810
+ __ mov(ebx, FieldOperand(ebx, kGlobalOffset));
811
+ __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
812
+
813
+ // Push the receiver.
814
+ __ bind(&push_receiver);
815
+ __ push(ebx);
816
+
817
+ // Copy all arguments from the array to the stack.
818
+ Label entry, loop;
819
+ __ mov(eax, Operand(ebp, kIndexOffset));
820
+ __ jmp(&entry);
821
+ __ bind(&loop);
822
+ __ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments
823
+
824
+ // Use inline caching to speed up access to arguments.
825
+ Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize();
826
+ __ call(ic, RelocInfo::CODE_TARGET);
827
+ // It is important that we do not have a test instruction after the
828
+ // call. A test instruction after the call is used to indicate that
829
+ // we have generated an inline version of the keyed load. In this
830
+ // case, we know that we are not generating a test instruction next.
831
+
832
+ // Push the nth argument.
833
+ __ push(eax);
834
+
835
+ // Update the index on the stack and in register eax.
836
+ __ mov(eax, Operand(ebp, kIndexOffset));
837
+ __ add(Operand(eax), Immediate(1 << kSmiTagSize));
838
+ __ mov(Operand(ebp, kIndexOffset), eax);
839
+
840
+ __ bind(&entry);
841
+ __ cmp(eax, Operand(ebp, kLimitOffset));
842
+ __ j(not_equal, &loop);
843
+
844
+ // Invoke the function.
845
+ ParameterCount actual(eax);
846
+ __ SmiUntag(eax);
847
+ __ mov(edi, Operand(ebp, 4 * kPointerSize));
848
+ __ InvokeFunction(edi, actual, CALL_FUNCTION);
849
+
850
+ __ LeaveInternalFrame();
851
+ __ ret(3 * kPointerSize); // remove this, receiver, and arguments
852
+ }
853
+
854
+
855
+ // Number of empty elements to allocate for an empty array.
856
+ static const int kPreallocatedArrayElements = 4;
857
+
858
+
859
+ // Allocate an empty JSArray. The allocated array is put into the result
860
+ // register. If the parameter initial_capacity is larger than zero an elements
861
+ // backing store is allocated with this size and filled with the hole values.
862
+ // Otherwise the elements backing store is set to the empty FixedArray.
863
+ static void AllocateEmptyJSArray(MacroAssembler* masm,
864
+ Register array_function,
865
+ Register result,
866
+ Register scratch1,
867
+ Register scratch2,
868
+ Register scratch3,
869
+ int initial_capacity,
870
+ Label* gc_required) {
871
+ ASSERT(initial_capacity >= 0);
872
+
873
+ // Load the initial map from the array function.
874
+ __ mov(scratch1, FieldOperand(array_function,
875
+ JSFunction::kPrototypeOrInitialMapOffset));
876
+
877
+ // Allocate the JSArray object together with space for a fixed array with the
878
+ // requested elements.
879
+ int size = JSArray::kSize;
880
+ if (initial_capacity > 0) {
881
+ size += FixedArray::SizeFor(initial_capacity);
882
+ }
883
+ __ AllocateInNewSpace(size,
884
+ result,
885
+ scratch2,
886
+ scratch3,
887
+ gc_required,
888
+ TAG_OBJECT);
889
+
890
+ // Allocated the JSArray. Now initialize the fields except for the elements
891
+ // array.
892
+ // result: JSObject
893
+ // scratch1: initial map
894
+ // scratch2: start of next object
895
+ __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1);
896
+ Factory* factory = masm->isolate()->factory();
897
+ __ mov(FieldOperand(result, JSArray::kPropertiesOffset),
898
+ factory->empty_fixed_array());
899
+ // Field JSArray::kElementsOffset is initialized later.
900
+ __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0));
901
+
902
+ // If no storage is requested for the elements array just set the empty
903
+ // fixed array.
904
+ if (initial_capacity == 0) {
905
+ __ mov(FieldOperand(result, JSArray::kElementsOffset),
906
+ factory->empty_fixed_array());
907
+ return;
908
+ }
909
+
910
+ // Calculate the location of the elements array and set elements array member
911
+ // of the JSArray.
912
+ // result: JSObject
913
+ // scratch2: start of next object
914
+ __ lea(scratch1, Operand(result, JSArray::kSize));
915
+ __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1);
916
+
917
+ // Initialize the FixedArray and fill it with holes. FixedArray length is
918
+ // stored as a smi.
919
+ // result: JSObject
920
+ // scratch1: elements array
921
+ // scratch2: start of next object
922
+ __ mov(FieldOperand(scratch1, FixedArray::kMapOffset),
923
+ factory->fixed_array_map());
924
+ __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset),
925
+ Immediate(Smi::FromInt(initial_capacity)));
926
+
927
+ // Fill the FixedArray with the hole value. Inline the code if short.
928
+ // Reconsider loop unfolding if kPreallocatedArrayElements gets changed.
929
+ static const int kLoopUnfoldLimit = 4;
930
+ ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit);
931
+ if (initial_capacity <= kLoopUnfoldLimit) {
932
+ // Use a scratch register here to have only one reloc info when unfolding
933
+ // the loop.
934
+ __ mov(scratch3, factory->the_hole_value());
935
+ for (int i = 0; i < initial_capacity; i++) {
936
+ __ mov(FieldOperand(scratch1,
937
+ FixedArray::kHeaderSize + i * kPointerSize),
938
+ scratch3);
939
+ }
940
+ } else {
941
+ Label loop, entry;
942
+ __ jmp(&entry);
943
+ __ bind(&loop);
944
+ __ mov(Operand(scratch1, 0), factory->the_hole_value());
945
+ __ add(Operand(scratch1), Immediate(kPointerSize));
946
+ __ bind(&entry);
947
+ __ cmp(scratch1, Operand(scratch2));
948
+ __ j(below, &loop);
949
+ }
950
+ }
951
+
952
+
953
+ // Allocate a JSArray with the number of elements stored in a register. The
954
+ // register array_function holds the built-in Array function and the register
955
+ // array_size holds the size of the array as a smi. The allocated array is put
956
+ // into the result register and beginning and end of the FixedArray elements
957
+ // storage is put into registers elements_array and elements_array_end (see
958
+ // below for when that is not the case). If the parameter fill_with_holes is
959
+ // true the allocated elements backing store is filled with the hole values
960
+ // otherwise it is left uninitialized. When the backing store is filled the
961
+ // register elements_array is scratched.
962
+ static void AllocateJSArray(MacroAssembler* masm,
963
+ Register array_function, // Array function.
964
+ Register array_size, // As a smi, cannot be 0.
965
+ Register result,
966
+ Register elements_array,
967
+ Register elements_array_end,
968
+ Register scratch,
969
+ bool fill_with_hole,
970
+ Label* gc_required) {
971
+ ASSERT(scratch.is(edi)); // rep stos destination
972
+ ASSERT(!fill_with_hole || array_size.is(ecx)); // rep stos count
973
+ ASSERT(!fill_with_hole || !result.is(eax)); // result is never eax
974
+
975
+ // Load the initial map from the array function.
976
+ __ mov(elements_array,
977
+ FieldOperand(array_function,
978
+ JSFunction::kPrototypeOrInitialMapOffset));
979
+
980
+ // Allocate the JSArray object together with space for a FixedArray with the
981
+ // requested elements.
982
+ ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
983
+ __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
984
+ times_half_pointer_size, // array_size is a smi.
985
+ array_size,
986
+ result,
987
+ elements_array_end,
988
+ scratch,
989
+ gc_required,
990
+ TAG_OBJECT);
991
+
992
+ // Allocated the JSArray. Now initialize the fields except for the elements
993
+ // array.
994
+ // result: JSObject
995
+ // elements_array: initial map
996
+ // elements_array_end: start of next object
997
+ // array_size: size of array (smi)
998
+ __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array);
999
+ Factory* factory = masm->isolate()->factory();
1000
+ __ mov(elements_array, factory->empty_fixed_array());
1001
+ __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
1002
+ // Field JSArray::kElementsOffset is initialized later.
1003
+ __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size);
1004
+
1005
+ // Calculate the location of the elements array and set elements array member
1006
+ // of the JSArray.
1007
+ // result: JSObject
1008
+ // elements_array_end: start of next object
1009
+ // array_size: size of array (smi)
1010
+ __ lea(elements_array, Operand(result, JSArray::kSize));
1011
+ __ mov(FieldOperand(result, JSArray::kElementsOffset), elements_array);
1012
+
1013
+ // Initialize the fixed array. FixedArray length is stored as a smi.
1014
+ // result: JSObject
1015
+ // elements_array: elements array
1016
+ // elements_array_end: start of next object
1017
+ // array_size: size of array (smi)
1018
+ __ mov(FieldOperand(elements_array, FixedArray::kMapOffset),
1019
+ factory->fixed_array_map());
1020
+ // For non-empty JSArrays the length of the FixedArray and the JSArray is the
1021
+ // same.
1022
+ __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size);
1023
+
1024
+ // Fill the allocated FixedArray with the hole value if requested.
1025
+ // result: JSObject
1026
+ // elements_array: elements array
1027
+ if (fill_with_hole) {
1028
+ __ SmiUntag(array_size);
1029
+ __ lea(edi, Operand(elements_array,
1030
+ FixedArray::kHeaderSize - kHeapObjectTag));
1031
+ __ mov(eax, factory->the_hole_value());
1032
+ __ cld();
1033
+ // Do not use rep stos when filling less than kRepStosThreshold
1034
+ // words.
1035
+ const int kRepStosThreshold = 16;
1036
+ Label loop, entry, done;
1037
+ __ cmp(ecx, kRepStosThreshold);
1038
+ __ j(below, &loop); // Note: ecx > 0.
1039
+ __ rep_stos();
1040
+ __ jmp(&done);
1041
+ __ bind(&loop);
1042
+ __ stos();
1043
+ __ bind(&entry);
1044
+ __ cmp(edi, Operand(elements_array_end));
1045
+ __ j(below, &loop);
1046
+ __ bind(&done);
1047
+ }
1048
+ }
1049
+
1050
+
1051
+ // Create a new array for the built-in Array function. This function allocates
1052
+ // the JSArray object and the FixedArray elements array and initializes these.
1053
+ // If the Array cannot be constructed in native code the runtime is called. This
1054
+ // function assumes the following state:
1055
+ // edi: constructor (built-in Array function)
1056
+ // eax: argc
1057
+ // esp[0]: return address
1058
+ // esp[4]: last argument
1059
+ // This function is used for both construct and normal calls of Array. Whether
1060
+ // it is a construct call or not is indicated by the construct_call parameter.
1061
+ // The only difference between handling a construct call and a normal call is
1062
+ // that for a construct call the constructor function in edi needs to be
1063
+ // preserved for entering the generic code. In both cases argc in eax needs to
1064
+ // be preserved.
1065
+ static void ArrayNativeCode(MacroAssembler* masm,
1066
+ bool construct_call,
1067
+ Label* call_generic_code) {
1068
+ Label argc_one_or_more, argc_two_or_more, prepare_generic_code_call,
1069
+ empty_array, not_empty_array;
1070
+
1071
+ // Push the constructor and argc. No need to tag argc as a smi, as there will
1072
+ // be no garbage collection with this on the stack.
1073
+ int push_count = 0;
1074
+ if (construct_call) {
1075
+ push_count++;
1076
+ __ push(edi);
1077
+ }
1078
+ push_count++;
1079
+ __ push(eax);
1080
+
1081
+ // Check for array construction with zero arguments.
1082
+ __ test(eax, Operand(eax));
1083
+ __ j(not_zero, &argc_one_or_more);
1084
+
1085
+ __ bind(&empty_array);
1086
+ // Handle construction of an empty array.
1087
+ AllocateEmptyJSArray(masm,
1088
+ edi,
1089
+ eax,
1090
+ ebx,
1091
+ ecx,
1092
+ edi,
1093
+ kPreallocatedArrayElements,
1094
+ &prepare_generic_code_call);
1095
+ __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1);
1096
+ __ pop(ebx);
1097
+ if (construct_call) {
1098
+ __ pop(edi);
1099
+ }
1100
+ __ ret(kPointerSize);
1101
+
1102
+ // Check for one argument. Bail out if argument is not smi or if it is
1103
+ // negative.
1104
+ __ bind(&argc_one_or_more);
1105
+ __ cmp(eax, 1);
1106
+ __ j(not_equal, &argc_two_or_more);
1107
+ ASSERT(kSmiTag == 0);
1108
+ __ mov(ecx, Operand(esp, (push_count + 1) * kPointerSize));
1109
+ __ test(ecx, Operand(ecx));
1110
+ __ j(not_zero, &not_empty_array);
1111
+
1112
+ // The single argument passed is zero, so we jump to the code above used to
1113
+ // handle the case of no arguments passed. To adapt the stack for that we move
1114
+ // the return address and the pushed constructor (if pushed) one stack slot up
1115
+ // thereby removing the passed argument. Argc is also on the stack - at the
1116
+ // bottom - and it needs to be changed from 1 to 0 to have the call into the
1117
+ // runtime system work in case a GC is required.
1118
+ for (int i = push_count; i > 0; i--) {
1119
+ __ mov(eax, Operand(esp, i * kPointerSize));
1120
+ __ mov(Operand(esp, (i + 1) * kPointerSize), eax);
1121
+ }
1122
+ __ add(Operand(esp), Immediate(2 * kPointerSize)); // Drop two stack slots.
1123
+ __ push(Immediate(0)); // Treat this as a call with argc of zero.
1124
+ __ jmp(&empty_array);
1125
+
1126
+ __ bind(&not_empty_array);
1127
+ __ test(ecx, Immediate(kIntptrSignBit | kSmiTagMask));
1128
+ __ j(not_zero, &prepare_generic_code_call);
1129
+
1130
+ // Handle construction of an empty array of a certain size. Get the size from
1131
+ // the stack and bail out if size is to large to actually allocate an elements
1132
+ // array.
1133
+ __ cmp(ecx, JSObject::kInitialMaxFastElementArray << kSmiTagSize);
1134
+ __ j(greater_equal, &prepare_generic_code_call);
1135
+
1136
+ // edx: array_size (smi)
1137
+ // edi: constructor
1138
+ // esp[0]: argc (cannot be 0 here)
1139
+ // esp[4]: constructor (only if construct_call)
1140
+ // esp[8]: return address
1141
+ // esp[C]: argument
1142
+ AllocateJSArray(masm,
1143
+ edi,
1144
+ ecx,
1145
+ ebx,
1146
+ eax,
1147
+ edx,
1148
+ edi,
1149
+ true,
1150
+ &prepare_generic_code_call);
1151
+ Counters* counters = masm->isolate()->counters();
1152
+ __ IncrementCounter(counters->array_function_native(), 1);
1153
+ __ mov(eax, ebx);
1154
+ __ pop(ebx);
1155
+ if (construct_call) {
1156
+ __ pop(edi);
1157
+ }
1158
+ __ ret(2 * kPointerSize);
1159
+
1160
+ // Handle construction of an array from a list of arguments.
1161
+ __ bind(&argc_two_or_more);
1162
+ ASSERT(kSmiTag == 0);
1163
+ __ SmiTag(eax); // Convet argc to a smi.
1164
+ // eax: array_size (smi)
1165
+ // edi: constructor
1166
+ // esp[0] : argc
1167
+ // esp[4]: constructor (only if construct_call)
1168
+ // esp[8] : return address
1169
+ // esp[C] : last argument
1170
+ AllocateJSArray(masm,
1171
+ edi,
1172
+ eax,
1173
+ ebx,
1174
+ ecx,
1175
+ edx,
1176
+ edi,
1177
+ false,
1178
+ &prepare_generic_code_call);
1179
+ __ IncrementCounter(counters->array_function_native(), 1);
1180
+ __ mov(eax, ebx);
1181
+ __ pop(ebx);
1182
+ if (construct_call) {
1183
+ __ pop(edi);
1184
+ }
1185
+ __ push(eax);
1186
+ // eax: JSArray
1187
+ // ebx: argc
1188
+ // edx: elements_array_end (untagged)
1189
+ // esp[0]: JSArray
1190
+ // esp[4]: return address
1191
+ // esp[8]: last argument
1192
+
1193
+ // Location of the last argument
1194
+ __ lea(edi, Operand(esp, 2 * kPointerSize));
1195
+
1196
+ // Location of the first array element (Parameter fill_with_holes to
1197
+ // AllocateJSArrayis false, so the FixedArray is returned in ecx).
1198
+ __ lea(edx, Operand(ecx, FixedArray::kHeaderSize - kHeapObjectTag));
1199
+
1200
+ // ebx: argc
1201
+ // edx: location of the first array element
1202
+ // edi: location of the last argument
1203
+ // esp[0]: JSArray
1204
+ // esp[4]: return address
1205
+ // esp[8]: last argument
1206
+ Label loop, entry;
1207
+ __ mov(ecx, ebx);
1208
+ __ jmp(&entry);
1209
+ __ bind(&loop);
1210
+ __ mov(eax, Operand(edi, ecx, times_pointer_size, 0));
1211
+ __ mov(Operand(edx, 0), eax);
1212
+ __ add(Operand(edx), Immediate(kPointerSize));
1213
+ __ bind(&entry);
1214
+ __ dec(ecx);
1215
+ __ j(greater_equal, &loop);
1216
+
1217
+ // Remove caller arguments from the stack and return.
1218
+ // ebx: argc
1219
+ // esp[0]: JSArray
1220
+ // esp[4]: return address
1221
+ // esp[8]: last argument
1222
+ __ pop(eax);
1223
+ __ pop(ecx);
1224
+ __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
1225
+ __ push(ecx);
1226
+ __ ret(0);
1227
+
1228
+ // Restore argc and constructor before running the generic code.
1229
+ __ bind(&prepare_generic_code_call);
1230
+ __ pop(eax);
1231
+ if (construct_call) {
1232
+ __ pop(edi);
1233
+ }
1234
+ __ jmp(call_generic_code);
1235
+ }
1236
+
1237
+
1238
+ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
1239
+ // ----------- S t a t e -------------
1240
+ // -- eax : argc
1241
+ // -- esp[0] : return address
1242
+ // -- esp[4] : last argument
1243
+ // -----------------------------------
1244
+ Label generic_array_code;
1245
+
1246
+ // Get the Array function.
1247
+ __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi);
1248
+
1249
+ if (FLAG_debug_code) {
1250
+ // Initial map for the builtin Array function shoud be a map.
1251
+ __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1252
+ // Will both indicate a NULL and a Smi.
1253
+ __ test(ebx, Immediate(kSmiTagMask));
1254
+ __ Assert(not_zero, "Unexpected initial map for Array function");
1255
+ __ CmpObjectType(ebx, MAP_TYPE, ecx);
1256
+ __ Assert(equal, "Unexpected initial map for Array function");
1257
+ }
1258
+
1259
+ // Run the native code for the Array function called as a normal function.
1260
+ ArrayNativeCode(masm, false, &generic_array_code);
1261
+
1262
+ // Jump to the generic array code in case the specialized code cannot handle
1263
+ // the construction.
1264
+ __ bind(&generic_array_code);
1265
+ Handle<Code> array_code =
1266
+ masm->isolate()->builtins()->ArrayCodeGeneric();
1267
+ __ jmp(array_code, RelocInfo::CODE_TARGET);
1268
+ }
1269
+
1270
+
1271
+ void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) {
1272
+ // ----------- S t a t e -------------
1273
+ // -- eax : argc
1274
+ // -- edi : constructor
1275
+ // -- esp[0] : return address
1276
+ // -- esp[4] : last argument
1277
+ // -----------------------------------
1278
+ Label generic_constructor;
1279
+
1280
+ if (FLAG_debug_code) {
1281
+ // The array construct code is only set for the global and natives
1282
+ // builtin Array functions which always have maps.
1283
+
1284
+ // Initial map for the builtin Array function should be a map.
1285
+ __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1286
+ // Will both indicate a NULL and a Smi.
1287
+ __ test(ebx, Immediate(kSmiTagMask));
1288
+ __ Assert(not_zero, "Unexpected initial map for Array function");
1289
+ __ CmpObjectType(ebx, MAP_TYPE, ecx);
1290
+ __ Assert(equal, "Unexpected initial map for Array function");
1291
+ }
1292
+
1293
+ // Run the native code for the Array function called as constructor.
1294
+ ArrayNativeCode(masm, true, &generic_constructor);
1295
+
1296
+ // Jump to the generic construct code in case the specialized code cannot
1297
+ // handle the construction.
1298
+ __ bind(&generic_constructor);
1299
+ Handle<Code> generic_construct_stub =
1300
+ masm->isolate()->builtins()->JSConstructStubGeneric();
1301
+ __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
1302
+ }
1303
+
1304
+
1305
+ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1306
+ // ----------- S t a t e -------------
1307
+ // -- eax : number of arguments
1308
+ // -- edi : constructor function
1309
+ // -- esp[0] : return address
1310
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1311
+ // -- esp[(argc + 1) * 4] : receiver
1312
+ // -----------------------------------
1313
+ Counters* counters = masm->isolate()->counters();
1314
+ __ IncrementCounter(counters->string_ctor_calls(), 1);
1315
+
1316
+ if (FLAG_debug_code) {
1317
+ __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx);
1318
+ __ cmp(edi, Operand(ecx));
1319
+ __ Assert(equal, "Unexpected String function");
1320
+ }
1321
+
1322
+ // Load the first argument into eax and get rid of the rest
1323
+ // (including the receiver).
1324
+ Label no_arguments;
1325
+ __ test(eax, Operand(eax));
1326
+ __ j(zero, &no_arguments);
1327
+ __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1328
+ __ pop(ecx);
1329
+ __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1330
+ __ push(ecx);
1331
+ __ mov(eax, ebx);
1332
+
1333
+ // Lookup the argument in the number to string cache.
1334
+ Label not_cached, argument_is_string;
1335
+ NumberToStringStub::GenerateLookupNumberStringCache(
1336
+ masm,
1337
+ eax, // Input.
1338
+ ebx, // Result.
1339
+ ecx, // Scratch 1.
1340
+ edx, // Scratch 2.
1341
+ false, // Input is known to be smi?
1342
+ &not_cached);
1343
+ __ IncrementCounter(counters->string_ctor_cached_number(), 1);
1344
+ __ bind(&argument_is_string);
1345
+ // ----------- S t a t e -------------
1346
+ // -- ebx : argument converted to string
1347
+ // -- edi : constructor function
1348
+ // -- esp[0] : return address
1349
+ // -----------------------------------
1350
+
1351
+ // Allocate a JSValue and put the tagged pointer into eax.
1352
+ Label gc_required;
1353
+ __ AllocateInNewSpace(JSValue::kSize,
1354
+ eax, // Result.
1355
+ ecx, // New allocation top (we ignore it).
1356
+ no_reg,
1357
+ &gc_required,
1358
+ TAG_OBJECT);
1359
+
1360
+ // Set the map.
1361
+ __ LoadGlobalFunctionInitialMap(edi, ecx);
1362
+ if (FLAG_debug_code) {
1363
+ __ cmpb(FieldOperand(ecx, Map::kInstanceSizeOffset),
1364
+ JSValue::kSize >> kPointerSizeLog2);
1365
+ __ Assert(equal, "Unexpected string wrapper instance size");
1366
+ __ cmpb(FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset), 0);
1367
+ __ Assert(equal, "Unexpected unused properties of string wrapper");
1368
+ }
1369
+ __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx);
1370
+
1371
+ // Set properties and elements.
1372
+ Factory* factory = masm->isolate()->factory();
1373
+ __ Set(ecx, Immediate(factory->empty_fixed_array()));
1374
+ __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx);
1375
+ __ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx);
1376
+
1377
+ // Set the value.
1378
+ __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx);
1379
+
1380
+ // Ensure the object is fully initialized.
1381
+ STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
1382
+
1383
+ // We're done. Return.
1384
+ __ ret(0);
1385
+
1386
+ // The argument was not found in the number to string cache. Check
1387
+ // if it's a string already before calling the conversion builtin.
1388
+ Label convert_argument;
1389
+ __ bind(&not_cached);
1390
+ STATIC_ASSERT(kSmiTag == 0);
1391
+ __ test(eax, Immediate(kSmiTagMask));
1392
+ __ j(zero, &convert_argument);
1393
+ Condition is_string = masm->IsObjectStringType(eax, ebx, ecx);
1394
+ __ j(NegateCondition(is_string), &convert_argument);
1395
+ __ mov(ebx, eax);
1396
+ __ IncrementCounter(counters->string_ctor_string_value(), 1);
1397
+ __ jmp(&argument_is_string);
1398
+
1399
+ // Invoke the conversion builtin and put the result into ebx.
1400
+ __ bind(&convert_argument);
1401
+ __ IncrementCounter(counters->string_ctor_conversions(), 1);
1402
+ __ EnterInternalFrame();
1403
+ __ push(edi); // Preserve the function.
1404
+ __ push(eax);
1405
+ __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
1406
+ __ pop(edi);
1407
+ __ LeaveInternalFrame();
1408
+ __ mov(ebx, eax);
1409
+ __ jmp(&argument_is_string);
1410
+
1411
+ // Load the empty string into ebx, remove the receiver from the
1412
+ // stack, and jump back to the case where the argument is a string.
1413
+ __ bind(&no_arguments);
1414
+ __ Set(ebx, Immediate(factory->empty_string()));
1415
+ __ pop(ecx);
1416
+ __ lea(esp, Operand(esp, kPointerSize));
1417
+ __ push(ecx);
1418
+ __ jmp(&argument_is_string);
1419
+
1420
+ // At this point the argument is already a string. Call runtime to
1421
+ // create a string wrapper.
1422
+ __ bind(&gc_required);
1423
+ __ IncrementCounter(counters->string_ctor_gc_required(), 1);
1424
+ __ EnterInternalFrame();
1425
+ __ push(ebx);
1426
+ __ CallRuntime(Runtime::kNewStringWrapper, 1);
1427
+ __ LeaveInternalFrame();
1428
+ __ ret(0);
1429
+ }
1430
+
1431
+
1432
+ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1433
+ __ push(ebp);
1434
+ __ mov(ebp, Operand(esp));
1435
+
1436
+ // Store the arguments adaptor context sentinel.
1437
+ __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1438
+
1439
+ // Push the function on the stack.
1440
+ __ push(edi);
1441
+
1442
+ // Preserve the number of arguments on the stack. Must preserve eax,
1443
+ // ebx and ecx because these registers are used when copying the
1444
+ // arguments and the receiver.
1445
+ ASSERT(kSmiTagSize == 1);
1446
+ __ lea(edi, Operand(eax, eax, times_1, kSmiTag));
1447
+ __ push(edi);
1448
+ }
1449
+
1450
+
1451
+ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1452
+ // Retrieve the number of arguments from the stack.
1453
+ __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
1454
+
1455
+ // Leave the frame.
1456
+ __ leave();
1457
+
1458
+ // Remove caller arguments from the stack.
1459
+ ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1460
+ __ pop(ecx);
1461
+ __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
1462
+ __ push(ecx);
1463
+ }
1464
+
1465
+
1466
+ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1467
+ // ----------- S t a t e -------------
1468
+ // -- eax : actual number of arguments
1469
+ // -- ebx : expected number of arguments
1470
+ // -- ecx : call kind information
1471
+ // -- edx : code entry to call
1472
+ // -----------------------------------
1473
+
1474
+ Label invoke, dont_adapt_arguments;
1475
+ __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
1476
+
1477
+ Label enough, too_few;
1478
+ __ cmp(eax, Operand(ebx));
1479
+ __ j(less, &too_few);
1480
+ __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
1481
+ __ j(equal, &dont_adapt_arguments);
1482
+
1483
+ { // Enough parameters: Actual >= expected.
1484
+ __ bind(&enough);
1485
+ EnterArgumentsAdaptorFrame(masm);
1486
+
1487
+ // Copy receiver and all expected arguments.
1488
+ const int offset = StandardFrameConstants::kCallerSPOffset;
1489
+ __ lea(eax, Operand(ebp, eax, times_4, offset));
1490
+ __ mov(edi, -1); // account for receiver
1491
+
1492
+ Label copy;
1493
+ __ bind(&copy);
1494
+ __ inc(edi);
1495
+ __ push(Operand(eax, 0));
1496
+ __ sub(Operand(eax), Immediate(kPointerSize));
1497
+ __ cmp(edi, Operand(ebx));
1498
+ __ j(less, &copy);
1499
+ __ jmp(&invoke);
1500
+ }
1501
+
1502
+ { // Too few parameters: Actual < expected.
1503
+ __ bind(&too_few);
1504
+ EnterArgumentsAdaptorFrame(masm);
1505
+
1506
+ // Copy receiver and all actual arguments.
1507
+ const int offset = StandardFrameConstants::kCallerSPOffset;
1508
+ __ lea(edi, Operand(ebp, eax, times_4, offset));
1509
+ // ebx = expected - actual.
1510
+ __ sub(ebx, Operand(eax));
1511
+ // eax = -actual - 1
1512
+ __ neg(eax);
1513
+ __ sub(Operand(eax), Immediate(1));
1514
+
1515
+ Label copy;
1516
+ __ bind(&copy);
1517
+ __ inc(eax);
1518
+ __ push(Operand(edi, 0));
1519
+ __ sub(Operand(edi), Immediate(kPointerSize));
1520
+ __ test(eax, Operand(eax));
1521
+ __ j(not_zero, &copy);
1522
+
1523
+ // Fill remaining expected arguments with undefined values.
1524
+ Label fill;
1525
+ __ bind(&fill);
1526
+ __ inc(eax);
1527
+ __ push(Immediate(masm->isolate()->factory()->undefined_value()));
1528
+ __ cmp(eax, Operand(ebx));
1529
+ __ j(less, &fill);
1530
+ }
1531
+
1532
+ // Call the entry point.
1533
+ __ bind(&invoke);
1534
+ // Restore function pointer.
1535
+ __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1536
+ __ call(Operand(edx));
1537
+
1538
+ // Leave frame and return.
1539
+ LeaveArgumentsAdaptorFrame(masm);
1540
+ __ ret(0);
1541
+
1542
+ // -------------------------------------------
1543
+ // Dont adapt arguments.
1544
+ // -------------------------------------------
1545
+ __ bind(&dont_adapt_arguments);
1546
+ __ jmp(Operand(edx));
1547
+ }
1548
+
1549
+
1550
+ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1551
+ CpuFeatures::TryForceFeatureScope scope(SSE2);
1552
+ if (!CpuFeatures::IsSupported(SSE2)) {
1553
+ __ Abort("Unreachable code: Cannot optimize without SSE2 support.");
1554
+ return;
1555
+ }
1556
+
1557
+ // Get the loop depth of the stack guard check. This is recorded in
1558
+ // a test(eax, depth) instruction right after the call.
1559
+ Label stack_check;
1560
+ __ mov(ebx, Operand(esp, 0)); // return address
1561
+ if (FLAG_debug_code) {
1562
+ __ cmpb(Operand(ebx, 0), Assembler::kTestAlByte);
1563
+ __ Assert(equal, "test eax instruction not found after loop stack check");
1564
+ }
1565
+ __ movzx_b(ebx, Operand(ebx, 1)); // depth
1566
+
1567
+ // Get the loop nesting level at which we allow OSR from the
1568
+ // unoptimized code and check if we want to do OSR yet. If not we
1569
+ // should perform a stack guard check so we can get interrupts while
1570
+ // waiting for on-stack replacement.
1571
+ __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1572
+ __ mov(ecx, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset));
1573
+ __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kCodeOffset));
1574
+ __ cmpb(ebx, FieldOperand(ecx, Code::kAllowOSRAtLoopNestingLevelOffset));
1575
+ __ j(greater, &stack_check);
1576
+
1577
+ // Pass the function to optimize as the argument to the on-stack
1578
+ // replacement runtime function.
1579
+ __ EnterInternalFrame();
1580
+ __ push(eax);
1581
+ __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
1582
+ __ LeaveInternalFrame();
1583
+
1584
+ // If the result was -1 it means that we couldn't optimize the
1585
+ // function. Just return and continue in the unoptimized version.
1586
+ Label skip;
1587
+ __ cmp(Operand(eax), Immediate(Smi::FromInt(-1)));
1588
+ __ j(not_equal, &skip, Label::kNear);
1589
+ __ ret(0);
1590
+
1591
+ // If we decide not to perform on-stack replacement we perform a
1592
+ // stack guard check to enable interrupts.
1593
+ __ bind(&stack_check);
1594
+ Label ok;
1595
+ ExternalReference stack_limit =
1596
+ ExternalReference::address_of_stack_limit(masm->isolate());
1597
+ __ cmp(esp, Operand::StaticVariable(stack_limit));
1598
+ __ j(above_equal, &ok, Label::kNear);
1599
+ StackCheckStub stub;
1600
+ __ TailCallStub(&stub);
1601
+ __ Abort("Unreachable code: returned from tail call.");
1602
+ __ bind(&ok);
1603
+ __ ret(0);
1604
+
1605
+ __ bind(&skip);
1606
+ // Untag the AST id and push it on the stack.
1607
+ __ SmiUntag(eax);
1608
+ __ push(eax);
1609
+
1610
+ // Generate the code for doing the frame-to-frame translation using
1611
+ // the deoptimizer infrastructure.
1612
+ Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1613
+ generator.Generate();
1614
+ }
1615
+
1616
+
1617
+ #undef __
1618
+ }
1619
+ } // namespace v8::internal
1620
+
1621
+ #endif // V8_TARGET_ARCH_IA32