libv8 3.3.10.4 → 3.5.10.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (538) hide show
  1. data/lib/libv8/scons/CHANGES.txt +24 -231
  2. data/lib/libv8/scons/LICENSE.txt +1 -1
  3. data/lib/libv8/scons/MANIFEST +0 -1
  4. data/lib/libv8/scons/PKG-INFO +1 -1
  5. data/lib/libv8/scons/README.txt +9 -9
  6. data/lib/libv8/scons/RELEASE.txt +75 -77
  7. data/lib/libv8/scons/engine/SCons/Action.py +6 -22
  8. data/lib/libv8/scons/engine/SCons/Builder.py +2 -2
  9. data/lib/libv8/scons/engine/SCons/CacheDir.py +2 -2
  10. data/lib/libv8/scons/engine/SCons/Debug.py +2 -2
  11. data/lib/libv8/scons/engine/SCons/Defaults.py +10 -24
  12. data/lib/libv8/scons/engine/SCons/Environment.py +19 -118
  13. data/lib/libv8/scons/engine/SCons/Errors.py +2 -2
  14. data/lib/libv8/scons/engine/SCons/Executor.py +2 -2
  15. data/lib/libv8/scons/engine/SCons/Job.py +2 -2
  16. data/lib/libv8/scons/engine/SCons/Memoize.py +2 -2
  17. data/lib/libv8/scons/engine/SCons/Node/Alias.py +2 -2
  18. data/lib/libv8/scons/engine/SCons/Node/FS.py +121 -281
  19. data/lib/libv8/scons/engine/SCons/Node/Python.py +2 -2
  20. data/lib/libv8/scons/engine/SCons/Node/__init__.py +5 -6
  21. data/lib/libv8/scons/engine/SCons/Options/BoolOption.py +2 -2
  22. data/lib/libv8/scons/engine/SCons/Options/EnumOption.py +2 -2
  23. data/lib/libv8/scons/engine/SCons/Options/ListOption.py +2 -2
  24. data/lib/libv8/scons/engine/SCons/Options/PackageOption.py +2 -2
  25. data/lib/libv8/scons/engine/SCons/Options/PathOption.py +2 -2
  26. data/lib/libv8/scons/engine/SCons/Options/__init__.py +2 -2
  27. data/lib/libv8/scons/engine/SCons/PathList.py +2 -2
  28. data/lib/libv8/scons/engine/SCons/Platform/__init__.py +2 -2
  29. data/lib/libv8/scons/engine/SCons/Platform/aix.py +2 -2
  30. data/lib/libv8/scons/engine/SCons/Platform/cygwin.py +2 -2
  31. data/lib/libv8/scons/engine/SCons/Platform/darwin.py +3 -27
  32. data/lib/libv8/scons/engine/SCons/Platform/hpux.py +2 -2
  33. data/lib/libv8/scons/engine/SCons/Platform/irix.py +2 -2
  34. data/lib/libv8/scons/engine/SCons/Platform/os2.py +2 -2
  35. data/lib/libv8/scons/engine/SCons/Platform/posix.py +2 -2
  36. data/lib/libv8/scons/engine/SCons/Platform/sunos.py +2 -2
  37. data/lib/libv8/scons/engine/SCons/Platform/win32.py +2 -2
  38. data/lib/libv8/scons/engine/SCons/SConf.py +2 -2
  39. data/lib/libv8/scons/engine/SCons/SConsign.py +3 -9
  40. data/lib/libv8/scons/engine/SCons/Scanner/C.py +2 -2
  41. data/lib/libv8/scons/engine/SCons/Scanner/D.py +2 -2
  42. data/lib/libv8/scons/engine/SCons/Scanner/Dir.py +2 -2
  43. data/lib/libv8/scons/engine/SCons/Scanner/Fortran.py +2 -2
  44. data/lib/libv8/scons/engine/SCons/Scanner/IDL.py +2 -2
  45. data/lib/libv8/scons/engine/SCons/Scanner/LaTeX.py +2 -5
  46. data/lib/libv8/scons/engine/SCons/Scanner/Prog.py +2 -2
  47. data/lib/libv8/scons/engine/SCons/Scanner/RC.py +3 -3
  48. data/lib/libv8/scons/engine/SCons/Scanner/__init__.py +2 -2
  49. data/lib/libv8/scons/engine/SCons/Script/Interactive.py +2 -2
  50. data/lib/libv8/scons/engine/SCons/Script/Main.py +11 -82
  51. data/lib/libv8/scons/engine/SCons/Script/SConsOptions.py +5 -5
  52. data/lib/libv8/scons/engine/SCons/Script/SConscript.py +2 -2
  53. data/lib/libv8/scons/engine/SCons/Script/__init__.py +2 -2
  54. data/lib/libv8/scons/engine/SCons/Sig.py +2 -2
  55. data/lib/libv8/scons/engine/SCons/Subst.py +2 -2
  56. data/lib/libv8/scons/engine/SCons/Taskmaster.py +2 -10
  57. data/lib/libv8/scons/engine/SCons/Tool/386asm.py +2 -2
  58. data/lib/libv8/scons/engine/SCons/Tool/BitKeeper.py +2 -2
  59. data/lib/libv8/scons/engine/SCons/Tool/CVS.py +2 -2
  60. data/lib/libv8/scons/engine/SCons/Tool/FortranCommon.py +2 -19
  61. data/lib/libv8/scons/engine/SCons/Tool/JavaCommon.py +2 -2
  62. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/__init__.py +2 -2
  63. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/arch.py +2 -2
  64. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/common.py +2 -2
  65. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/netframework.py +2 -2
  66. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/sdk.py +2 -2
  67. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vc.py +6 -9
  68. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vs.py +2 -29
  69. data/lib/libv8/scons/engine/SCons/Tool/Perforce.py +2 -2
  70. data/lib/libv8/scons/engine/SCons/Tool/PharLapCommon.py +2 -2
  71. data/lib/libv8/scons/engine/SCons/Tool/RCS.py +2 -2
  72. data/lib/libv8/scons/engine/SCons/Tool/SCCS.py +2 -2
  73. data/lib/libv8/scons/engine/SCons/Tool/Subversion.py +2 -2
  74. data/lib/libv8/scons/engine/SCons/Tool/__init__.py +3 -3
  75. data/lib/libv8/scons/engine/SCons/Tool/aixc++.py +2 -2
  76. data/lib/libv8/scons/engine/SCons/Tool/aixcc.py +2 -2
  77. data/lib/libv8/scons/engine/SCons/Tool/aixf77.py +2 -2
  78. data/lib/libv8/scons/engine/SCons/Tool/aixlink.py +2 -2
  79. data/lib/libv8/scons/engine/SCons/Tool/applelink.py +2 -2
  80. data/lib/libv8/scons/engine/SCons/Tool/ar.py +2 -2
  81. data/lib/libv8/scons/engine/SCons/Tool/as.py +2 -2
  82. data/lib/libv8/scons/engine/SCons/Tool/bcc32.py +2 -2
  83. data/lib/libv8/scons/engine/SCons/Tool/c++.py +2 -2
  84. data/lib/libv8/scons/engine/SCons/Tool/cc.py +2 -2
  85. data/lib/libv8/scons/engine/SCons/Tool/cvf.py +2 -2
  86. data/lib/libv8/scons/engine/SCons/Tool/default.py +2 -2
  87. data/lib/libv8/scons/engine/SCons/Tool/dmd.py +7 -24
  88. data/lib/libv8/scons/engine/SCons/Tool/dvi.py +2 -2
  89. data/lib/libv8/scons/engine/SCons/Tool/dvipdf.py +2 -3
  90. data/lib/libv8/scons/engine/SCons/Tool/dvips.py +2 -3
  91. data/lib/libv8/scons/engine/SCons/Tool/f77.py +2 -2
  92. data/lib/libv8/scons/engine/SCons/Tool/f90.py +2 -2
  93. data/lib/libv8/scons/engine/SCons/Tool/f95.py +2 -2
  94. data/lib/libv8/scons/engine/SCons/Tool/filesystem.py +2 -2
  95. data/lib/libv8/scons/engine/SCons/Tool/fortran.py +2 -2
  96. data/lib/libv8/scons/engine/SCons/Tool/g++.py +2 -2
  97. data/lib/libv8/scons/engine/SCons/Tool/g77.py +2 -2
  98. data/lib/libv8/scons/engine/SCons/Tool/gas.py +2 -2
  99. data/lib/libv8/scons/engine/SCons/Tool/gcc.py +2 -2
  100. data/lib/libv8/scons/engine/SCons/Tool/gfortran.py +3 -3
  101. data/lib/libv8/scons/engine/SCons/Tool/gnulink.py +3 -2
  102. data/lib/libv8/scons/engine/SCons/Tool/gs.py +2 -2
  103. data/lib/libv8/scons/engine/SCons/Tool/hpc++.py +2 -2
  104. data/lib/libv8/scons/engine/SCons/Tool/hpcc.py +2 -2
  105. data/lib/libv8/scons/engine/SCons/Tool/hplink.py +2 -2
  106. data/lib/libv8/scons/engine/SCons/Tool/icc.py +2 -2
  107. data/lib/libv8/scons/engine/SCons/Tool/icl.py +2 -2
  108. data/lib/libv8/scons/engine/SCons/Tool/ifl.py +2 -2
  109. data/lib/libv8/scons/engine/SCons/Tool/ifort.py +2 -2
  110. data/lib/libv8/scons/engine/SCons/Tool/ilink.py +2 -2
  111. data/lib/libv8/scons/engine/SCons/Tool/ilink32.py +2 -2
  112. data/lib/libv8/scons/engine/SCons/Tool/install.py +3 -57
  113. data/lib/libv8/scons/engine/SCons/Tool/intelc.py +25 -65
  114. data/lib/libv8/scons/engine/SCons/Tool/ipkg.py +2 -2
  115. data/lib/libv8/scons/engine/SCons/Tool/jar.py +3 -9
  116. data/lib/libv8/scons/engine/SCons/Tool/javac.py +2 -2
  117. data/lib/libv8/scons/engine/SCons/Tool/javah.py +2 -2
  118. data/lib/libv8/scons/engine/SCons/Tool/latex.py +2 -3
  119. data/lib/libv8/scons/engine/SCons/Tool/lex.py +2 -2
  120. data/lib/libv8/scons/engine/SCons/Tool/link.py +5 -6
  121. data/lib/libv8/scons/engine/SCons/Tool/linkloc.py +2 -2
  122. data/lib/libv8/scons/engine/SCons/Tool/m4.py +2 -2
  123. data/lib/libv8/scons/engine/SCons/Tool/masm.py +2 -2
  124. data/lib/libv8/scons/engine/SCons/Tool/midl.py +2 -2
  125. data/lib/libv8/scons/engine/SCons/Tool/mingw.py +10 -31
  126. data/lib/libv8/scons/engine/SCons/Tool/mslib.py +2 -2
  127. data/lib/libv8/scons/engine/SCons/Tool/mslink.py +9 -61
  128. data/lib/libv8/scons/engine/SCons/Tool/mssdk.py +2 -2
  129. data/lib/libv8/scons/engine/SCons/Tool/msvc.py +11 -21
  130. data/lib/libv8/scons/engine/SCons/Tool/msvs.py +59 -477
  131. data/lib/libv8/scons/engine/SCons/Tool/mwcc.py +2 -2
  132. data/lib/libv8/scons/engine/SCons/Tool/mwld.py +2 -2
  133. data/lib/libv8/scons/engine/SCons/Tool/nasm.py +2 -2
  134. data/lib/libv8/scons/engine/SCons/Tool/packaging/__init__.py +2 -2
  135. data/lib/libv8/scons/engine/SCons/Tool/packaging/ipk.py +2 -2
  136. data/lib/libv8/scons/engine/SCons/Tool/packaging/msi.py +2 -2
  137. data/lib/libv8/scons/engine/SCons/Tool/packaging/rpm.py +2 -2
  138. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_tarbz2.py +2 -2
  139. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_targz.py +2 -2
  140. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_zip.py +2 -2
  141. data/lib/libv8/scons/engine/SCons/Tool/packaging/tarbz2.py +2 -2
  142. data/lib/libv8/scons/engine/SCons/Tool/packaging/targz.py +2 -2
  143. data/lib/libv8/scons/engine/SCons/Tool/packaging/zip.py +2 -2
  144. data/lib/libv8/scons/engine/SCons/Tool/pdf.py +2 -2
  145. data/lib/libv8/scons/engine/SCons/Tool/pdflatex.py +2 -3
  146. data/lib/libv8/scons/engine/SCons/Tool/pdftex.py +2 -3
  147. data/lib/libv8/scons/engine/SCons/Tool/qt.py +2 -2
  148. data/lib/libv8/scons/engine/SCons/Tool/rmic.py +3 -9
  149. data/lib/libv8/scons/engine/SCons/Tool/rpcgen.py +2 -2
  150. data/lib/libv8/scons/engine/SCons/Tool/rpm.py +2 -2
  151. data/lib/libv8/scons/engine/SCons/Tool/sgiar.py +2 -2
  152. data/lib/libv8/scons/engine/SCons/Tool/sgic++.py +2 -2
  153. data/lib/libv8/scons/engine/SCons/Tool/sgicc.py +2 -2
  154. data/lib/libv8/scons/engine/SCons/Tool/sgilink.py +3 -2
  155. data/lib/libv8/scons/engine/SCons/Tool/sunar.py +2 -2
  156. data/lib/libv8/scons/engine/SCons/Tool/sunc++.py +2 -2
  157. data/lib/libv8/scons/engine/SCons/Tool/suncc.py +2 -2
  158. data/lib/libv8/scons/engine/SCons/Tool/sunf77.py +2 -2
  159. data/lib/libv8/scons/engine/SCons/Tool/sunf90.py +2 -2
  160. data/lib/libv8/scons/engine/SCons/Tool/sunf95.py +2 -2
  161. data/lib/libv8/scons/engine/SCons/Tool/sunlink.py +3 -2
  162. data/lib/libv8/scons/engine/SCons/Tool/swig.py +5 -6
  163. data/lib/libv8/scons/engine/SCons/Tool/tar.py +2 -2
  164. data/lib/libv8/scons/engine/SCons/Tool/tex.py +43 -96
  165. data/lib/libv8/scons/engine/SCons/Tool/textfile.py +2 -2
  166. data/lib/libv8/scons/engine/SCons/Tool/tlib.py +2 -2
  167. data/lib/libv8/scons/engine/SCons/Tool/wix.py +2 -2
  168. data/lib/libv8/scons/engine/SCons/Tool/yacc.py +2 -12
  169. data/lib/libv8/scons/engine/SCons/Tool/zip.py +2 -2
  170. data/lib/libv8/scons/engine/SCons/Util.py +3 -3
  171. data/lib/libv8/scons/engine/SCons/Variables/BoolVariable.py +2 -2
  172. data/lib/libv8/scons/engine/SCons/Variables/EnumVariable.py +3 -3
  173. data/lib/libv8/scons/engine/SCons/Variables/ListVariable.py +2 -2
  174. data/lib/libv8/scons/engine/SCons/Variables/PackageVariable.py +2 -2
  175. data/lib/libv8/scons/engine/SCons/Variables/PathVariable.py +2 -2
  176. data/lib/libv8/scons/engine/SCons/Variables/__init__.py +2 -2
  177. data/lib/libv8/scons/engine/SCons/Warnings.py +2 -2
  178. data/lib/libv8/scons/engine/SCons/__init__.py +6 -6
  179. data/lib/libv8/scons/engine/SCons/compat/__init__.py +2 -2
  180. data/lib/libv8/scons/engine/SCons/compat/_scons_builtins.py +2 -2
  181. data/lib/libv8/scons/engine/SCons/compat/_scons_collections.py +2 -2
  182. data/lib/libv8/scons/engine/SCons/compat/_scons_dbm.py +2 -2
  183. data/lib/libv8/scons/engine/SCons/compat/_scons_hashlib.py +2 -2
  184. data/lib/libv8/scons/engine/SCons/compat/_scons_io.py +2 -2
  185. data/lib/libv8/scons/engine/SCons/cpp.py +2 -2
  186. data/lib/libv8/scons/engine/SCons/dblite.py +1 -4
  187. data/lib/libv8/scons/engine/SCons/exitfuncs.py +2 -2
  188. data/lib/libv8/scons/scons-time.1 +3 -3
  189. data/lib/libv8/scons/scons.1 +1164 -1170
  190. data/lib/libv8/scons/sconsign.1 +3 -3
  191. data/lib/libv8/scons/script/scons +22 -22
  192. data/lib/libv8/scons/script/scons-time +2 -2
  193. data/lib/libv8/scons/script/scons.bat +4 -7
  194. data/lib/libv8/scons/script/sconsign +20 -21
  195. data/lib/libv8/scons/setup.cfg +1 -0
  196. data/lib/libv8/scons/setup.py +40 -38
  197. data/lib/libv8/v8/.gitignore +1 -1
  198. data/lib/libv8/v8/AUTHORS +2 -0
  199. data/lib/libv8/v8/ChangeLog +387 -0
  200. data/lib/libv8/v8/Makefile +171 -0
  201. data/lib/libv8/v8/SConstruct +124 -51
  202. data/lib/libv8/v8/build/README.txt +31 -14
  203. data/lib/libv8/v8/build/all.gyp +11 -4
  204. data/lib/libv8/v8/build/armu.gypi +6 -2
  205. data/lib/libv8/v8/build/common.gypi +240 -94
  206. data/lib/libv8/v8/build/gyp_v8 +32 -4
  207. data/lib/libv8/v8/build/standalone.gypi +200 -0
  208. data/lib/libv8/v8/include/v8-debug.h +0 -0
  209. data/lib/libv8/v8/include/v8-profiler.h +8 -11
  210. data/lib/libv8/v8/include/v8.h +191 -108
  211. data/lib/libv8/v8/preparser/SConscript +2 -2
  212. data/lib/libv8/v8/preparser/preparser-process.cc +3 -3
  213. data/lib/libv8/v8/preparser/preparser.gyp +42 -0
  214. data/lib/libv8/v8/src/SConscript +33 -8
  215. data/lib/libv8/v8/src/accessors.cc +77 -43
  216. data/lib/libv8/v8/src/api.cc +393 -191
  217. data/lib/libv8/v8/src/api.h +4 -8
  218. data/lib/libv8/v8/src/apinatives.js +15 -3
  219. data/lib/libv8/v8/src/arguments.h +8 -0
  220. data/lib/libv8/v8/src/arm/assembler-arm.cc +120 -120
  221. data/lib/libv8/v8/src/arm/assembler-arm.h +92 -43
  222. data/lib/libv8/v8/src/arm/builtins-arm.cc +32 -39
  223. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +572 -351
  224. data/lib/libv8/v8/src/arm/code-stubs-arm.h +8 -77
  225. data/lib/libv8/v8/src/arm/codegen-arm.h +0 -2
  226. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +50 -30
  227. data/lib/libv8/v8/src/arm/disasm-arm.cc +1 -1
  228. data/lib/libv8/v8/src/arm/frames-arm.h +9 -5
  229. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +331 -432
  230. data/lib/libv8/v8/src/arm/ic-arm.cc +192 -124
  231. data/lib/libv8/v8/src/arm/lithium-arm.cc +216 -232
  232. data/lib/libv8/v8/src/arm/lithium-arm.h +106 -259
  233. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +633 -642
  234. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +4 -4
  235. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +1 -3
  236. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +260 -185
  237. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +45 -25
  238. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +25 -13
  239. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +3 -0
  240. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +413 -226
  241. data/lib/libv8/v8/src/array.js +38 -18
  242. data/lib/libv8/v8/src/assembler.cc +12 -5
  243. data/lib/libv8/v8/src/assembler.h +15 -9
  244. data/lib/libv8/v8/src/ast-inl.h +34 -25
  245. data/lib/libv8/v8/src/ast.cc +141 -72
  246. data/lib/libv8/v8/src/ast.h +255 -181
  247. data/lib/libv8/v8/src/bignum.cc +3 -4
  248. data/lib/libv8/v8/src/bootstrapper.cc +55 -11
  249. data/lib/libv8/v8/src/bootstrapper.h +3 -2
  250. data/lib/libv8/v8/src/builtins.cc +8 -2
  251. data/lib/libv8/v8/src/builtins.h +4 -0
  252. data/lib/libv8/v8/src/cached-powers.cc +8 -4
  253. data/lib/libv8/v8/src/checks.h +3 -3
  254. data/lib/libv8/v8/src/code-stubs.cc +173 -28
  255. data/lib/libv8/v8/src/code-stubs.h +104 -148
  256. data/lib/libv8/v8/src/codegen.cc +8 -8
  257. data/lib/libv8/v8/src/compilation-cache.cc +2 -47
  258. data/lib/libv8/v8/src/compilation-cache.h +0 -10
  259. data/lib/libv8/v8/src/compiler.cc +27 -16
  260. data/lib/libv8/v8/src/compiler.h +13 -18
  261. data/lib/libv8/v8/src/contexts.cc +107 -72
  262. data/lib/libv8/v8/src/contexts.h +70 -34
  263. data/lib/libv8/v8/src/conversions-inl.h +572 -14
  264. data/lib/libv8/v8/src/conversions.cc +9 -707
  265. data/lib/libv8/v8/src/conversions.h +23 -12
  266. data/lib/libv8/v8/src/cpu-profiler-inl.h +2 -19
  267. data/lib/libv8/v8/src/cpu-profiler.cc +4 -21
  268. data/lib/libv8/v8/src/cpu-profiler.h +8 -17
  269. data/lib/libv8/v8/src/d8-debug.cc +5 -3
  270. data/lib/libv8/v8/src/d8-debug.h +6 -7
  271. data/lib/libv8/v8/src/d8-posix.cc +1 -10
  272. data/lib/libv8/v8/src/d8.cc +721 -219
  273. data/lib/libv8/v8/src/d8.gyp +37 -12
  274. data/lib/libv8/v8/src/d8.h +141 -19
  275. data/lib/libv8/v8/src/d8.js +17 -8
  276. data/lib/libv8/v8/src/date.js +16 -5
  277. data/lib/libv8/v8/src/dateparser-inl.h +242 -39
  278. data/lib/libv8/v8/src/dateparser.cc +38 -4
  279. data/lib/libv8/v8/src/dateparser.h +170 -28
  280. data/lib/libv8/v8/src/debug-agent.cc +5 -3
  281. data/lib/libv8/v8/src/debug-agent.h +11 -7
  282. data/lib/libv8/v8/src/debug-debugger.js +65 -34
  283. data/lib/libv8/v8/src/debug.cc +30 -60
  284. data/lib/libv8/v8/src/debug.h +5 -3
  285. data/lib/libv8/v8/src/deoptimizer.cc +227 -10
  286. data/lib/libv8/v8/src/deoptimizer.h +133 -9
  287. data/lib/libv8/v8/src/disassembler.cc +22 -14
  288. data/lib/libv8/v8/src/diy-fp.cc +4 -3
  289. data/lib/libv8/v8/src/diy-fp.h +3 -3
  290. data/lib/libv8/v8/src/elements.cc +634 -0
  291. data/lib/libv8/v8/src/elements.h +95 -0
  292. data/lib/libv8/v8/src/execution.cc +5 -21
  293. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +3 -1
  294. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +1 -1
  295. data/lib/libv8/v8/src/extensions/experimental/collator.cc +6 -2
  296. data/lib/libv8/v8/src/extensions/experimental/collator.h +1 -2
  297. data/lib/libv8/v8/src/extensions/experimental/datetime-format.cc +384 -0
  298. data/lib/libv8/v8/src/extensions/experimental/datetime-format.h +83 -0
  299. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +18 -7
  300. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +12 -16
  301. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +1 -1
  302. data/lib/libv8/v8/src/extensions/experimental/i18n-js2c.py +126 -0
  303. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +3 -4
  304. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +1 -1
  305. data/lib/libv8/v8/src/{shell.h → extensions/experimental/i18n-natives.h} +8 -20
  306. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +45 -1
  307. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +21 -1
  308. data/lib/libv8/v8/src/extensions/experimental/i18n.js +211 -11
  309. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +4 -3
  310. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +1 -1
  311. data/lib/libv8/v8/src/extensions/experimental/number-format.cc +374 -0
  312. data/lib/libv8/v8/src/extensions/experimental/number-format.h +71 -0
  313. data/lib/libv8/v8/src/factory.cc +89 -18
  314. data/lib/libv8/v8/src/factory.h +36 -8
  315. data/lib/libv8/v8/src/flag-definitions.h +11 -44
  316. data/lib/libv8/v8/src/frames-inl.h +8 -1
  317. data/lib/libv8/v8/src/frames.cc +39 -3
  318. data/lib/libv8/v8/src/frames.h +10 -3
  319. data/lib/libv8/v8/src/full-codegen.cc +311 -293
  320. data/lib/libv8/v8/src/full-codegen.h +183 -143
  321. data/lib/libv8/v8/src/func-name-inferrer.cc +29 -15
  322. data/lib/libv8/v8/src/func-name-inferrer.h +19 -9
  323. data/lib/libv8/v8/src/gdb-jit.cc +658 -55
  324. data/lib/libv8/v8/src/gdb-jit.h +6 -2
  325. data/lib/libv8/v8/src/global-handles.cc +368 -312
  326. data/lib/libv8/v8/src/global-handles.h +29 -36
  327. data/lib/libv8/v8/src/globals.h +3 -1
  328. data/lib/libv8/v8/src/handles.cc +43 -69
  329. data/lib/libv8/v8/src/handles.h +21 -16
  330. data/lib/libv8/v8/src/heap-inl.h +11 -13
  331. data/lib/libv8/v8/src/heap-profiler.cc +0 -999
  332. data/lib/libv8/v8/src/heap-profiler.h +0 -303
  333. data/lib/libv8/v8/src/heap.cc +366 -141
  334. data/lib/libv8/v8/src/heap.h +87 -26
  335. data/lib/libv8/v8/src/hydrogen-instructions.cc +192 -81
  336. data/lib/libv8/v8/src/hydrogen-instructions.h +711 -482
  337. data/lib/libv8/v8/src/hydrogen.cc +1146 -629
  338. data/lib/libv8/v8/src/hydrogen.h +100 -64
  339. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +19 -0
  340. data/lib/libv8/v8/src/ia32/assembler-ia32.h +15 -2
  341. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +34 -39
  342. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +675 -377
  343. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +8 -69
  344. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +1 -0
  345. data/lib/libv8/v8/src/ia32/codegen-ia32.h +0 -2
  346. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +3 -2
  347. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +28 -3
  348. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +21 -10
  349. data/lib/libv8/v8/src/ia32/frames-ia32.h +6 -5
  350. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +459 -465
  351. data/lib/libv8/v8/src/ia32/ic-ia32.cc +196 -147
  352. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +575 -650
  353. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +19 -21
  354. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +7 -2
  355. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +261 -256
  356. data/lib/libv8/v8/src/ia32/lithium-ia32.h +234 -335
  357. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +224 -67
  358. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +63 -19
  359. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +22 -8
  360. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +3 -0
  361. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +380 -239
  362. data/lib/libv8/v8/src/ic.cc +198 -234
  363. data/lib/libv8/v8/src/ic.h +32 -30
  364. data/lib/libv8/v8/src/interpreter-irregexp.cc +6 -4
  365. data/lib/libv8/v8/src/isolate.cc +112 -95
  366. data/lib/libv8/v8/src/isolate.h +55 -71
  367. data/lib/libv8/v8/src/json-parser.h +486 -48
  368. data/lib/libv8/v8/src/json.js +28 -23
  369. data/lib/libv8/v8/src/jsregexp.cc +163 -208
  370. data/lib/libv8/v8/src/jsregexp.h +0 -1
  371. data/lib/libv8/v8/src/lithium-allocator-inl.h +29 -27
  372. data/lib/libv8/v8/src/lithium-allocator.cc +22 -17
  373. data/lib/libv8/v8/src/lithium-allocator.h +8 -8
  374. data/lib/libv8/v8/src/lithium.cc +16 -11
  375. data/lib/libv8/v8/src/lithium.h +31 -34
  376. data/lib/libv8/v8/src/liveedit.cc +111 -15
  377. data/lib/libv8/v8/src/liveedit.h +3 -4
  378. data/lib/libv8/v8/src/liveobjectlist.cc +116 -80
  379. data/lib/libv8/v8/src/liveobjectlist.h +2 -2
  380. data/lib/libv8/v8/src/log-inl.h +0 -4
  381. data/lib/libv8/v8/src/log-utils.cc +25 -143
  382. data/lib/libv8/v8/src/log-utils.h +13 -92
  383. data/lib/libv8/v8/src/log.cc +26 -249
  384. data/lib/libv8/v8/src/log.h +6 -17
  385. data/lib/libv8/v8/src/macros.py +9 -6
  386. data/lib/libv8/v8/src/mark-compact.cc +276 -56
  387. data/lib/libv8/v8/src/mark-compact.h +20 -0
  388. data/lib/libv8/v8/src/messages.js +93 -39
  389. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +9 -3
  390. data/lib/libv8/v8/src/mips/assembler-mips.cc +297 -189
  391. data/lib/libv8/v8/src/mips/assembler-mips.h +121 -54
  392. data/lib/libv8/v8/src/mips/builtins-mips.cc +23 -24
  393. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +484 -263
  394. data/lib/libv8/v8/src/mips/code-stubs-mips.h +8 -83
  395. data/lib/libv8/v8/src/mips/codegen-mips.h +0 -2
  396. data/lib/libv8/v8/src/mips/constants-mips.h +37 -11
  397. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +6 -1
  398. data/lib/libv8/v8/src/mips/frames-mips.h +8 -7
  399. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +258 -419
  400. data/lib/libv8/v8/src/mips/ic-mips.cc +181 -121
  401. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +640 -382
  402. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +94 -89
  403. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +23 -10
  404. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +6 -1
  405. data/lib/libv8/v8/src/mips/simulator-mips.cc +249 -49
  406. data/lib/libv8/v8/src/mips/simulator-mips.h +25 -1
  407. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +373 -161
  408. data/lib/libv8/v8/src/mirror-debugger.js +55 -8
  409. data/lib/libv8/v8/src/misc-intrinsics.h +89 -0
  410. data/lib/libv8/v8/src/mksnapshot.cc +36 -4
  411. data/lib/libv8/v8/src/natives.h +5 -2
  412. data/lib/libv8/v8/src/objects-debug.cc +73 -6
  413. data/lib/libv8/v8/src/objects-inl.h +529 -164
  414. data/lib/libv8/v8/src/objects-printer.cc +67 -12
  415. data/lib/libv8/v8/src/objects-visiting.cc +13 -2
  416. data/lib/libv8/v8/src/objects-visiting.h +41 -1
  417. data/lib/libv8/v8/src/objects.cc +2200 -1177
  418. data/lib/libv8/v8/src/objects.h +912 -283
  419. data/lib/libv8/v8/src/parser.cc +566 -371
  420. data/lib/libv8/v8/src/parser.h +35 -33
  421. data/lib/libv8/v8/src/platform-cygwin.cc +10 -25
  422. data/lib/libv8/v8/src/platform-freebsd.cc +4 -29
  423. data/lib/libv8/v8/src/platform-linux.cc +60 -57
  424. data/lib/libv8/v8/src/platform-macos.cc +4 -27
  425. data/lib/libv8/v8/src/platform-nullos.cc +3 -16
  426. data/lib/libv8/v8/src/platform-openbsd.cc +247 -85
  427. data/lib/libv8/v8/src/platform-posix.cc +43 -1
  428. data/lib/libv8/v8/src/platform-solaris.cc +151 -112
  429. data/lib/libv8/v8/src/platform-tls.h +1 -1
  430. data/lib/libv8/v8/src/platform-win32.cc +65 -39
  431. data/lib/libv8/v8/src/platform.h +17 -14
  432. data/lib/libv8/v8/src/preparse-data-format.h +2 -2
  433. data/lib/libv8/v8/src/preparse-data.h +8 -2
  434. data/lib/libv8/v8/src/preparser-api.cc +2 -18
  435. data/lib/libv8/v8/src/preparser.cc +106 -65
  436. data/lib/libv8/v8/src/preparser.h +26 -5
  437. data/lib/libv8/v8/src/prettyprinter.cc +25 -43
  438. data/lib/libv8/v8/src/profile-generator-inl.h +0 -4
  439. data/lib/libv8/v8/src/profile-generator.cc +213 -34
  440. data/lib/libv8/v8/src/profile-generator.h +9 -9
  441. data/lib/libv8/v8/src/property.h +1 -0
  442. data/lib/libv8/v8/src/proxy.js +74 -4
  443. data/lib/libv8/v8/src/regexp-macro-assembler.cc +10 -6
  444. data/lib/libv8/v8/src/regexp.js +16 -11
  445. data/lib/libv8/v8/src/rewriter.cc +24 -133
  446. data/lib/libv8/v8/src/runtime-profiler.cc +27 -151
  447. data/lib/libv8/v8/src/runtime-profiler.h +5 -31
  448. data/lib/libv8/v8/src/runtime.cc +1450 -681
  449. data/lib/libv8/v8/src/runtime.h +47 -31
  450. data/lib/libv8/v8/src/runtime.js +2 -1
  451. data/lib/libv8/v8/src/scanner-base.cc +358 -220
  452. data/lib/libv8/v8/src/scanner-base.h +30 -138
  453. data/lib/libv8/v8/src/scanner.cc +0 -18
  454. data/lib/libv8/v8/src/scanner.h +0 -15
  455. data/lib/libv8/v8/src/scopeinfo.cc +3 -1
  456. data/lib/libv8/v8/src/scopeinfo.h +1 -6
  457. data/lib/libv8/v8/src/scopes.cc +243 -253
  458. data/lib/libv8/v8/src/scopes.h +58 -109
  459. data/lib/libv8/v8/src/serialize.cc +12 -54
  460. data/lib/libv8/v8/src/serialize.h +47 -0
  461. data/lib/libv8/v8/src/small-pointer-list.h +25 -0
  462. data/lib/libv8/v8/src/spaces-inl.h +4 -50
  463. data/lib/libv8/v8/src/spaces.cc +64 -131
  464. data/lib/libv8/v8/src/spaces.h +19 -70
  465. data/lib/libv8/v8/src/string-stream.cc +3 -1
  466. data/lib/libv8/v8/src/string.js +10 -6
  467. data/lib/libv8/v8/src/strtod.cc +7 -3
  468. data/lib/libv8/v8/src/stub-cache.cc +59 -129
  469. data/lib/libv8/v8/src/stub-cache.h +42 -54
  470. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +1447 -1339
  471. data/lib/libv8/v8/src/token.cc +4 -4
  472. data/lib/libv8/v8/src/token.h +6 -5
  473. data/lib/libv8/v8/src/type-info.cc +173 -129
  474. data/lib/libv8/v8/src/type-info.h +40 -22
  475. data/lib/libv8/v8/src/utils.cc +25 -304
  476. data/lib/libv8/v8/src/utils.h +118 -3
  477. data/lib/libv8/v8/src/v8-counters.h +3 -6
  478. data/lib/libv8/v8/src/v8.cc +34 -27
  479. data/lib/libv8/v8/src/v8.h +7 -7
  480. data/lib/libv8/v8/src/v8conversions.cc +129 -0
  481. data/lib/libv8/v8/src/v8conversions.h +60 -0
  482. data/lib/libv8/v8/src/v8globals.h +15 -6
  483. data/lib/libv8/v8/src/v8natives.js +300 -78
  484. data/lib/libv8/v8/src/v8threads.cc +14 -6
  485. data/lib/libv8/v8/src/v8threads.h +4 -1
  486. data/lib/libv8/v8/src/v8utils.cc +360 -0
  487. data/lib/libv8/v8/src/v8utils.h +17 -66
  488. data/lib/libv8/v8/src/variables.cc +7 -12
  489. data/lib/libv8/v8/src/variables.h +12 -10
  490. data/lib/libv8/v8/src/version.cc +2 -2
  491. data/lib/libv8/v8/src/vm-state-inl.h +0 -41
  492. data/lib/libv8/v8/src/vm-state.h +0 -11
  493. data/lib/libv8/v8/src/weakmap.js +103 -0
  494. data/lib/libv8/v8/src/x64/assembler-x64.h +6 -3
  495. data/lib/libv8/v8/src/x64/builtins-x64.cc +25 -22
  496. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +523 -250
  497. data/lib/libv8/v8/src/x64/code-stubs-x64.h +8 -71
  498. data/lib/libv8/v8/src/x64/codegen-x64.cc +1 -0
  499. data/lib/libv8/v8/src/x64/codegen-x64.h +0 -2
  500. data/lib/libv8/v8/src/x64/cpu-x64.cc +2 -1
  501. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +40 -8
  502. data/lib/libv8/v8/src/x64/disasm-x64.cc +12 -10
  503. data/lib/libv8/v8/src/x64/frames-x64.h +7 -6
  504. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +310 -415
  505. data/lib/libv8/v8/src/x64/ic-x64.cc +180 -117
  506. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +411 -523
  507. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +11 -6
  508. data/lib/libv8/v8/src/x64/lithium-x64.cc +191 -216
  509. data/lib/libv8/v8/src/x64/lithium-x64.h +112 -263
  510. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +177 -61
  511. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +23 -7
  512. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +21 -9
  513. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +6 -0
  514. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +273 -107
  515. data/lib/libv8/v8/src/zone.cc +31 -22
  516. data/lib/libv8/v8/src/zone.h +12 -6
  517. data/lib/libv8/v8/tools/codemap.js +8 -0
  518. data/lib/libv8/v8/tools/gcmole/Makefile +43 -0
  519. data/lib/libv8/v8/tools/gcmole/gcmole.lua +0 -2
  520. data/lib/libv8/v8/tools/gdb-v8-support.py +154 -0
  521. data/lib/libv8/v8/tools/grokdump.py +44 -35
  522. data/lib/libv8/v8/tools/gyp/v8.gyp +94 -248
  523. data/lib/libv8/v8/tools/js2c.py +83 -52
  524. data/lib/libv8/v8/tools/linux-tick-processor +4 -6
  525. data/lib/libv8/v8/tools/ll_prof.py +3 -3
  526. data/lib/libv8/v8/tools/oom_dump/README +3 -1
  527. data/lib/libv8/v8/tools/presubmit.py +11 -4
  528. data/lib/libv8/v8/tools/profile.js +46 -2
  529. data/lib/libv8/v8/tools/splaytree.js +11 -0
  530. data/lib/libv8/v8/tools/stats-viewer.py +15 -11
  531. data/lib/libv8/v8/tools/test-wrapper-gypbuild.py +227 -0
  532. data/lib/libv8/v8/tools/test.py +28 -8
  533. data/lib/libv8/v8/tools/tickprocessor.js +0 -16
  534. data/lib/libv8/version.rb +1 -1
  535. data/libv8.gemspec +2 -2
  536. metadata +31 -19
  537. data/lib/libv8/scons/engine/SCons/Tool/f03.py +0 -63
  538. data/lib/libv8/v8/src/json-parser.cc +0 -504
@@ -43,32 +43,6 @@ namespace v8 {
43
43
  namespace internal {
44
44
 
45
45
 
46
- class PendingListNode : public Malloced {
47
- public:
48
- explicit PendingListNode(JSFunction* function);
49
- ~PendingListNode() { Destroy(); }
50
-
51
- PendingListNode* next() const { return next_; }
52
- void set_next(PendingListNode* node) { next_ = node; }
53
- Handle<JSFunction> function() { return Handle<JSFunction>::cast(function_); }
54
-
55
- // If the function is garbage collected before we've had the chance
56
- // to optimize it the weak handle will be null.
57
- bool IsValid() { return !function_.is_null(); }
58
-
59
- // Returns the number of microseconds this node has been pending.
60
- int Delay() const { return static_cast<int>(OS::Ticks() - start_); }
61
-
62
- private:
63
- void Destroy();
64
- static void WeakCallback(v8::Persistent<v8::Value> object, void* data);
65
-
66
- PendingListNode* next_;
67
- Handle<Object> function_; // Weak handle.
68
- int64_t start_;
69
- };
70
-
71
-
72
46
  // Optimization sampler constants.
73
47
  static const int kSamplerFrameCount = 2;
74
48
  static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 };
@@ -80,39 +54,14 @@ static const int kSamplerThresholdMin = 1;
80
54
  static const int kSamplerThresholdDelta = 1;
81
55
 
82
56
  static const int kSamplerThresholdSizeFactorInit = 3;
83
- static const int kSamplerThresholdSizeFactorMin = 1;
84
- static const int kSamplerThresholdSizeFactorDelta = 1;
85
57
 
86
58
  static const int kSizeLimit = 1500;
87
59
 
88
60
 
89
- PendingListNode::PendingListNode(JSFunction* function) : next_(NULL) {
90
- GlobalHandles* global_handles = Isolate::Current()->global_handles();
91
- function_ = global_handles->Create(function);
92
- start_ = OS::Ticks();
93
- global_handles->MakeWeak(function_.location(), this, &WeakCallback);
94
- }
95
-
96
-
97
- void PendingListNode::Destroy() {
98
- if (!IsValid()) return;
99
- GlobalHandles* global_handles = Isolate::Current()->global_handles();
100
- global_handles->Destroy(function_.location());
101
- function_= Handle<Object>::null();
102
- }
103
-
104
-
105
- void PendingListNode::WeakCallback(v8::Persistent<v8::Value>, void* data) {
106
- reinterpret_cast<PendingListNode*>(data)->Destroy();
107
- }
108
-
109
-
110
61
  Atomic32 RuntimeProfiler::state_ = 0;
111
62
  // TODO(isolates): Create the semaphore lazily and clean it up when no
112
63
  // longer required.
113
- #ifdef ENABLE_LOGGING_AND_PROFILING
114
64
  Semaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0);
115
- #endif
116
65
 
117
66
  #ifdef DEBUG
118
67
  bool RuntimeProfiler::has_been_globally_setup_ = false;
@@ -125,16 +74,8 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
125
74
  sampler_threshold_(kSamplerThresholdInit),
126
75
  sampler_threshold_size_factor_(kSamplerThresholdSizeFactorInit),
127
76
  sampler_ticks_until_threshold_adjustment_(
128
- kSamplerTicksBetweenThresholdAdjustment),
129
- js_ratio_(0),
130
- sampler_window_position_(0),
131
- optimize_soon_list_(NULL),
132
- state_window_position_(0),
133
- state_window_ticks_(0) {
134
- state_counts_[IN_NON_JS_STATE] = kStateWindowSize;
135
- state_counts_[IN_JS_STATE] = 0;
136
- STATIC_ASSERT(IN_NON_JS_STATE == 0);
137
- memset(state_window_, 0, sizeof(state_window_));
77
+ kSamplerTicksBetweenThresholdAdjustment),
78
+ sampler_window_position_(0) {
138
79
  ClearSampleBuffer();
139
80
  }
140
81
 
@@ -148,16 +89,13 @@ void RuntimeProfiler::GlobalSetup() {
148
89
  }
149
90
 
150
91
 
151
- void RuntimeProfiler::Optimize(JSFunction* function, bool eager, int delay) {
92
+ void RuntimeProfiler::Optimize(JSFunction* function) {
152
93
  ASSERT(function->IsOptimizable());
153
94
  if (FLAG_trace_opt) {
154
- PrintF("[marking (%s) ", eager ? "eagerly" : "lazily");
95
+ PrintF("[marking ");
155
96
  function->PrintName();
156
97
  PrintF(" 0x%" V8PRIxPTR, reinterpret_cast<intptr_t>(function->address()));
157
98
  PrintF(" for recompilation");
158
- if (delay > 0) {
159
- PrintF(" (delayed %0.3f ms)", static_cast<double>(delay) / 1000);
160
- }
161
99
  PrintF("]\n");
162
100
  }
163
101
 
@@ -185,7 +123,7 @@ void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) {
185
123
  // We are not prepared to do OSR for a function that already has an
186
124
  // allocated arguments object. The optimized code would bypass it for
187
125
  // arguments accesses, which is unsound. Don't try OSR.
188
- if (shared->scope_info()->HasArgumentsShadow()) return;
126
+ if (shared->uses_arguments()) return;
189
127
 
190
128
  // We're using on-stack replacement: patch the unoptimized code so that
191
129
  // any back edge in any unoptimized frame will trigger on-stack
@@ -243,20 +181,6 @@ void RuntimeProfiler::AddSample(JSFunction* function, int weight) {
243
181
 
244
182
  void RuntimeProfiler::OptimizeNow() {
245
183
  HandleScope scope(isolate_);
246
- PendingListNode* current = optimize_soon_list_;
247
- while (current != NULL) {
248
- PendingListNode* next = current->next();
249
- if (current->IsValid()) {
250
- Handle<JSFunction> function = current->function();
251
- int delay = current->Delay();
252
- if (function->IsOptimizable()) {
253
- Optimize(*function, true, delay);
254
- }
255
- }
256
- delete current;
257
- current = next;
258
- }
259
- optimize_soon_list_ = NULL;
260
184
 
261
185
  // Run through the JavaScript frames and collect them. If we already
262
186
  // have a sample of the function, we mark it for optimizations
@@ -303,24 +227,9 @@ void RuntimeProfiler::OptimizeNow() {
303
227
  : 1;
304
228
 
305
229
  int threshold = sampler_threshold_ * threshold_size_factor;
306
- int current_js_ratio = NoBarrier_Load(&js_ratio_);
307
-
308
- // Adjust threshold depending on the ratio of time spent
309
- // in JS code.
310
- if (current_js_ratio < 20) {
311
- // If we spend less than 20% of the time in JS code,
312
- // do not optimize.
313
- continue;
314
- } else if (current_js_ratio < 75) {
315
- // Below 75% of time spent in JS code, only optimize very
316
- // frequently used functions.
317
- threshold *= 3;
318
- }
319
230
 
320
231
  if (LookupSample(function) >= threshold) {
321
- Optimize(function, false, 0);
322
- isolate_->compilation_cache()->MarkForEagerOptimizing(
323
- Handle<JSFunction>(function));
232
+ Optimize(function);
324
233
  }
325
234
  }
326
235
 
@@ -333,42 +242,8 @@ void RuntimeProfiler::OptimizeNow() {
333
242
  }
334
243
 
335
244
 
336
- void RuntimeProfiler::OptimizeSoon(JSFunction* function) {
337
- if (!function->IsOptimizable()) return;
338
- PendingListNode* node = new PendingListNode(function);
339
- node->set_next(optimize_soon_list_);
340
- optimize_soon_list_ = node;
341
- }
342
-
343
-
344
- #ifdef ENABLE_LOGGING_AND_PROFILING
345
- void RuntimeProfiler::UpdateStateRatio(SamplerState current_state) {
346
- SamplerState old_state = state_window_[state_window_position_];
347
- state_counts_[old_state]--;
348
- state_window_[state_window_position_] = current_state;
349
- state_counts_[current_state]++;
350
- ASSERT(IsPowerOf2(kStateWindowSize));
351
- state_window_position_ = (state_window_position_ + 1) &
352
- (kStateWindowSize - 1);
353
- // Note: to calculate correct ratio we have to track how many valid
354
- // ticks are actually in the state window, because on profiler
355
- // startup this number can be less than the window size.
356
- state_window_ticks_ = Min(kStateWindowSize, state_window_ticks_ + 1);
357
- NoBarrier_Store(&js_ratio_, state_counts_[IN_JS_STATE] * 100 /
358
- state_window_ticks_);
359
- }
360
- #endif
361
-
362
-
363
245
  void RuntimeProfiler::NotifyTick() {
364
- #ifdef ENABLE_LOGGING_AND_PROFILING
365
- // Record state sample.
366
- SamplerState state = IsSomeIsolateInJS()
367
- ? IN_JS_STATE
368
- : IN_NON_JS_STATE;
369
- UpdateStateRatio(state);
370
246
  isolate_->stack_guard()->RequestRuntimeProfilerTick();
371
- #endif
372
247
  }
373
248
 
374
249
 
@@ -416,7 +291,6 @@ void RuntimeProfiler::UpdateSamplesAfterScavenge() {
416
291
 
417
292
 
418
293
  void RuntimeProfiler::HandleWakeUp(Isolate* isolate) {
419
- #ifdef ENABLE_LOGGING_AND_PROFILING
420
294
  // The profiler thread must still be waiting.
421
295
  ASSERT(NoBarrier_Load(&state_) >= 0);
422
296
  // In IsolateEnteredJS we have already incremented the counter and
@@ -424,8 +298,6 @@ void RuntimeProfiler::HandleWakeUp(Isolate* isolate) {
424
298
  // to get the right count of active isolates.
425
299
  NoBarrier_AtomicIncrement(&state_, 1);
426
300
  semaphore_->Signal();
427
- isolate->ResetEagerOptimizingData();
428
- #endif
429
301
  }
430
302
 
431
303
 
@@ -435,20 +307,33 @@ bool RuntimeProfiler::IsSomeIsolateInJS() {
435
307
 
436
308
 
437
309
  bool RuntimeProfiler::WaitForSomeIsolateToEnterJS() {
438
- #ifdef ENABLE_LOGGING_AND_PROFILING
439
310
  Atomic32 old_state = NoBarrier_CompareAndSwap(&state_, 0, -1);
440
311
  ASSERT(old_state >= -1);
441
312
  if (old_state != 0) return false;
442
313
  semaphore_->Wait();
443
- #endif
444
314
  return true;
445
315
  }
446
316
 
447
317
 
448
- void RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown() {
449
- #ifdef ENABLE_LOGGING_AND_PROFILING
450
- semaphore_->Signal();
451
- #endif
318
+ void RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(Thread* thread) {
319
+ // Do a fake increment. If the profiler is waiting on the semaphore,
320
+ // the returned state is 0, which can be left as an initial state in
321
+ // case profiling is restarted later. If the profiler is not
322
+ // waiting, the increment will prevent it from waiting, but has to
323
+ // be undone after the profiler is stopped.
324
+ Atomic32 new_state = NoBarrier_AtomicIncrement(&state_, 1);
325
+ ASSERT(new_state >= 0);
326
+ if (new_state == 0) {
327
+ // The profiler thread is waiting. Wake it up. It must check for
328
+ // stop conditions before attempting to wait again.
329
+ semaphore_->Signal();
330
+ }
331
+ thread->Join();
332
+ // The profiler thread is now stopped. Undo the increment in case it
333
+ // was not waiting.
334
+ if (new_state != 0) {
335
+ NoBarrier_AtomicIncrement(&state_, -1);
336
+ }
452
337
  }
453
338
 
454
339
 
@@ -470,18 +355,9 @@ void RuntimeProfiler::UpdateSamplesAfterCompact(ObjectVisitor* visitor) {
470
355
 
471
356
 
472
357
  bool RuntimeProfilerRateLimiter::SuspendIfNecessary() {
473
- #ifdef ENABLE_LOGGING_AND_PROFILING
474
- static const int kNonJSTicksThreshold = 100;
475
- if (RuntimeProfiler::IsSomeIsolateInJS()) {
476
- non_js_ticks_ = 0;
477
- } else {
478
- if (non_js_ticks_ < kNonJSTicksThreshold) {
479
- ++non_js_ticks_;
480
- } else {
481
- return RuntimeProfiler::WaitForSomeIsolateToEnterJS();
482
- }
358
+ if (!RuntimeProfiler::IsSomeIsolateInJS()) {
359
+ return RuntimeProfiler::WaitForSomeIsolateToEnterJS();
483
360
  }
484
- #endif
485
361
  return false;
486
362
  }
487
363
 
@@ -37,7 +37,6 @@ namespace internal {
37
37
  class Isolate;
38
38
  class JSFunction;
39
39
  class Object;
40
- class PendingListNode;
41
40
  class Semaphore;
42
41
 
43
42
  class RuntimeProfiler {
@@ -52,7 +51,6 @@ class RuntimeProfiler {
52
51
  }
53
52
 
54
53
  void OptimizeNow();
55
- void OptimizeSoon(JSFunction* function);
56
54
 
57
55
  void NotifyTick();
58
56
 
@@ -86,10 +84,9 @@ class RuntimeProfiler {
86
84
  static bool IsSomeIsolateInJS();
87
85
  static bool WaitForSomeIsolateToEnterJS();
88
86
 
89
- // When shutting down we join the profiler thread. Doing so while
90
- // it's waiting on a semaphore will cause a deadlock, so we have to
91
- // wake it up first.
92
- static void WakeUpRuntimeProfilerThreadBeforeShutdown();
87
+ // Stops the runtime profiler thread when profiling support is being
88
+ // turned off.
89
+ static void StopRuntimeProfilerThreadBeforeShutdown(Thread* thread);
93
90
 
94
91
  void UpdateSamplesAfterScavenge();
95
92
  void RemoveDeadSamples();
@@ -97,16 +94,10 @@ class RuntimeProfiler {
97
94
 
98
95
  private:
99
96
  static const int kSamplerWindowSize = 16;
100
- static const int kStateWindowSize = 128;
101
-
102
- enum SamplerState {
103
- IN_NON_JS_STATE = 0,
104
- IN_JS_STATE = 1
105
- };
106
97
 
107
98
  static void HandleWakeUp(Isolate* isolate);
108
99
 
109
- void Optimize(JSFunction* function, bool eager, int delay);
100
+ void Optimize(JSFunction* function);
110
101
 
111
102
  void AttemptOnStackReplacement(JSFunction* function);
112
103
 
@@ -118,31 +109,16 @@ class RuntimeProfiler {
118
109
 
119
110
  void AddSample(JSFunction* function, int weight);
120
111
 
121
- #ifdef ENABLE_LOGGING_AND_PROFILING
122
- void UpdateStateRatio(SamplerState current_state);
123
- #endif
124
-
125
112
  Isolate* isolate_;
126
113
 
127
114
  int sampler_threshold_;
128
115
  int sampler_threshold_size_factor_;
129
116
  int sampler_ticks_until_threshold_adjustment_;
130
117
 
131
- // The ratio of ticks spent in JS code in percent.
132
- Atomic32 js_ratio_;
133
-
134
118
  Object* sampler_window_[kSamplerWindowSize];
135
119
  int sampler_window_position_;
136
120
  int sampler_window_weight_[kSamplerWindowSize];
137
121
 
138
- // Support for pending 'optimize soon' requests.
139
- PendingListNode* optimize_soon_list_;
140
-
141
- SamplerState state_window_[kStateWindowSize];
142
- int state_window_position_;
143
- int state_window_ticks_;
144
- int state_counts_[2];
145
-
146
122
  // Possible state values:
147
123
  // -1 => the profiler thread is waiting on the semaphore
148
124
  // 0 or positive => the number of isolates running JavaScript code.
@@ -159,7 +135,7 @@ class RuntimeProfiler {
159
135
  // Rate limiter intended to be used in the profiler thread.
160
136
  class RuntimeProfilerRateLimiter BASE_EMBEDDED {
161
137
  public:
162
- RuntimeProfilerRateLimiter() : non_js_ticks_(0) { }
138
+ RuntimeProfilerRateLimiter() {}
163
139
 
164
140
  // Suspends the current thread (which must be the profiler thread)
165
141
  // when not executing JavaScript to minimize CPU usage. Returns
@@ -170,8 +146,6 @@ class RuntimeProfilerRateLimiter BASE_EMBEDDED {
170
146
  bool SuspendIfNecessary();
171
147
 
172
148
  private:
173
- int non_js_ticks_;
174
-
175
149
  DISALLOW_COPY_AND_ASSIGN(RuntimeProfilerRateLimiter);
176
150
  };
177
151
 
@@ -45,6 +45,7 @@
45
45
  #include "json-parser.h"
46
46
  #include "liveedit.h"
47
47
  #include "liveobjectlist-inl.h"
48
+ #include "misc-intrinsics.h"
48
49
  #include "parser.h"
49
50
  #include "platform.h"
50
51
  #include "runtime-profiler.h"
@@ -81,19 +82,19 @@ namespace internal {
81
82
  RUNTIME_ASSERT(obj->IsBoolean()); \
82
83
  bool name = (obj)->IsTrue();
83
84
 
84
- // Cast the given object to a Smi and store its value in an int variable
85
- // with the given name. If the object is not a Smi call IllegalOperation
85
+ // Cast the given argument to a Smi and store its value in an int variable
86
+ // with the given name. If the argument is not a Smi call IllegalOperation
86
87
  // and return.
87
- #define CONVERT_SMI_CHECKED(name, obj) \
88
- RUNTIME_ASSERT(obj->IsSmi()); \
89
- int name = Smi::cast(obj)->value();
88
+ #define CONVERT_SMI_ARG_CHECKED(name, index) \
89
+ RUNTIME_ASSERT(args[index]->IsSmi()); \
90
+ int name = args.smi_at(index);
90
91
 
91
- // Cast the given object to a double and store it in a variable with
92
- // the given name. If the object is not a number (as opposed to
92
+ // Cast the given argument to a double and store it in a variable with
93
+ // the given name. If the argument is not a number (as opposed to
93
94
  // the number not-a-number) call IllegalOperation and return.
94
- #define CONVERT_DOUBLE_CHECKED(name, obj) \
95
- RUNTIME_ASSERT(obj->IsNumber()); \
96
- double name = (obj)->Number();
95
+ #define CONVERT_DOUBLE_ARG_CHECKED(name, index) \
96
+ RUNTIME_ASSERT(args[index]->IsNumber()); \
97
+ double name = args.number_at(index);
97
98
 
98
99
  // Call the specified converter on the object *comand store the result in
99
100
  // a variable of the specified type with the given name. If the
@@ -218,8 +219,20 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
218
219
  }
219
220
  break;
220
221
  }
221
- default:
222
- UNREACHABLE();
222
+ case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
223
+ UNIMPLEMENTED();
224
+ break;
225
+ case JSObject::EXTERNAL_PIXEL_ELEMENTS:
226
+ case JSObject::EXTERNAL_BYTE_ELEMENTS:
227
+ case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
228
+ case JSObject::EXTERNAL_SHORT_ELEMENTS:
229
+ case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
230
+ case JSObject::EXTERNAL_INT_ELEMENTS:
231
+ case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
232
+ case JSObject::EXTERNAL_FLOAT_ELEMENTS:
233
+ case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
234
+ case JSObject::FAST_DOUBLE_ELEMENTS:
235
+ // No contained objects, nothing to do.
223
236
  break;
224
237
  }
225
238
  return copy;
@@ -482,7 +495,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralBoilerplate) {
482
495
  HandleScope scope(isolate);
483
496
  ASSERT(args.length() == 3);
484
497
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
485
- CONVERT_SMI_CHECKED(literals_index, args[1]);
498
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
486
499
  CONVERT_ARG_CHECKED(FixedArray, elements, 2);
487
500
 
488
501
  Handle<Object> object =
@@ -499,9 +512,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
499
512
  HandleScope scope(isolate);
500
513
  ASSERT(args.length() == 4);
501
514
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
502
- CONVERT_SMI_CHECKED(literals_index, args[1]);
515
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
503
516
  CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
504
- CONVERT_SMI_CHECKED(flags, args[3]);
517
+ CONVERT_SMI_ARG_CHECKED(flags, 3);
505
518
  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
506
519
  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
507
520
 
@@ -525,9 +538,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
525
538
  HandleScope scope(isolate);
526
539
  ASSERT(args.length() == 4);
527
540
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
528
- CONVERT_SMI_CHECKED(literals_index, args[1]);
541
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
529
542
  CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
530
- CONVERT_SMI_CHECKED(flags, args[3]);
543
+ CONVERT_SMI_ARG_CHECKED(flags, 3);
531
544
  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
532
545
  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
533
546
 
@@ -551,7 +564,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
551
564
  HandleScope scope(isolate);
552
565
  ASSERT(args.length() == 3);
553
566
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
554
- CONVERT_SMI_CHECKED(literals_index, args[1]);
567
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
555
568
  CONVERT_ARG_CHECKED(FixedArray, elements, 2);
556
569
 
557
570
  // Check if boilerplate exists. If not, create it first.
@@ -570,7 +583,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
570
583
  HandleScope scope(isolate);
571
584
  ASSERT(args.length() == 3);
572
585
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
573
- CONVERT_SMI_CHECKED(literals_index, args[1]);
586
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
574
587
  CONVERT_ARG_CHECKED(FixedArray, elements, 2);
575
588
 
576
589
  // Check if boilerplate exists. If not, create it first.
@@ -594,34 +607,67 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
594
607
  Object* handler = args[0];
595
608
  Object* prototype = args[1];
596
609
  Object* used_prototype =
597
- (prototype->IsJSObject() || prototype->IsJSProxy()) ? prototype
598
- : isolate->heap()->null_value();
610
+ prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
599
611
  return isolate->heap()->AllocateJSProxy(handler, used_prototype);
600
612
  }
601
613
 
602
614
 
603
- RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) {
615
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
616
+ ASSERT(args.length() == 1);
617
+ Object* obj = args[0];
618
+ return isolate->heap()->ToBoolean(obj->IsJSProxy());
619
+ }
620
+
621
+
622
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
623
+ ASSERT(args.length() == 1);
624
+ CONVERT_CHECKED(JSProxy, proxy, args[0]);
625
+ return proxy->handler();
626
+ }
627
+
628
+
629
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
630
+ ASSERT(args.length() == 1);
631
+ CONVERT_CHECKED(JSProxy, proxy, args[0]);
632
+ proxy->Fix();
633
+ return isolate->heap()->undefined_value();
634
+ }
635
+
636
+
637
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
638
+ HandleScope scope(isolate);
639
+ ASSERT(args.length() == 1);
640
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
641
+ ASSERT(weakmap->map()->inobject_properties() == 0);
642
+ Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
643
+ weakmap->set_table(*table);
644
+ weakmap->set_next(Smi::FromInt(0));
645
+ return *weakmap;
646
+ }
647
+
648
+
649
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
650
+ NoHandleAllocation ha;
604
651
  ASSERT(args.length() == 2);
605
- CONVERT_CHECKED(String, key, args[0]);
606
- Object* value = args[1];
607
- ASSERT(!value->IsFailure());
608
- // Create a catch context extension object.
609
- JSFunction* constructor =
610
- isolate->context()->global_context()->
611
- context_extension_function();
612
- Object* object;
613
- { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor);
614
- if (!maybe_object->ToObject(&object)) return maybe_object;
615
- }
616
- // Assign the exception value to the catch variable and make sure
617
- // that the catch variable is DontDelete.
618
- { MaybeObject* maybe_value =
619
- // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4.
620
- JSObject::cast(object)->SetProperty(
621
- key, value, DONT_DELETE, kNonStrictMode);
622
- if (!maybe_value->ToObject(&value)) return maybe_value;
623
- }
624
- return object;
652
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
653
+ // TODO(mstarzinger): Currently we cannot use JSProxy objects as keys
654
+ // because they cannot be cast to JSObject to get an identity hash code.
655
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
656
+ return weakmap->table()->Lookup(*key);
657
+ }
658
+
659
+
660
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
661
+ HandleScope scope(isolate);
662
+ ASSERT(args.length() == 3);
663
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
664
+ // TODO(mstarzinger): See Runtime_WeakMapGet above.
665
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
666
+ Handle<Object> value(args[2]);
667
+ Handle<ObjectHashTable> table(weakmap->table());
668
+ Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
669
+ weakmap->set_table(*new_table);
670
+ return *value;
625
671
  }
626
672
 
627
673
 
@@ -634,6 +680,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
634
680
  }
635
681
 
636
682
 
683
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
684
+ NoHandleAllocation ha;
685
+ ASSERT(args.length() == 1);
686
+ CONVERT_CHECKED(JSReceiver, input_obj, args[0]);
687
+ Object* obj = input_obj;
688
+ // We don't expect access checks to be needed on JSProxy objects.
689
+ ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
690
+ do {
691
+ if (obj->IsAccessCheckNeeded() &&
692
+ !isolate->MayNamedAccess(JSObject::cast(obj),
693
+ isolate->heap()->Proto_symbol(),
694
+ v8::ACCESS_GET)) {
695
+ isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET);
696
+ return isolate->heap()->undefined_value();
697
+ }
698
+ obj = obj->GetPrototype();
699
+ } while (obj->IsJSObject() &&
700
+ JSObject::cast(obj)->map()->is_hidden_prototype());
701
+ return obj;
702
+ }
703
+
704
+
637
705
  RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
638
706
  NoHandleAllocation ha;
639
707
  ASSERT(args.length() == 2);
@@ -874,7 +942,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
874
942
  ASSERT(proto->IsJSGlobalObject());
875
943
  holder = Handle<JSObject>(JSObject::cast(proto));
876
944
  }
877
- NumberDictionary* dictionary = holder->element_dictionary();
945
+ FixedArray* elements = FixedArray::cast(holder->elements());
946
+ NumberDictionary* dictionary = NULL;
947
+ if (elements->map() == heap->non_strict_arguments_elements_map()) {
948
+ dictionary = NumberDictionary::cast(elements->get(1));
949
+ } else {
950
+ dictionary = NumberDictionary::cast(elements);
951
+ }
878
952
  int entry = dictionary->FindEntry(index);
879
953
  ASSERT(entry != NumberDictionary::kNotFound);
880
954
  PropertyDetails details = dictionary->DetailsAt(entry);
@@ -973,8 +1047,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
973
1047
  ASSERT(proto->IsJSGlobalObject());
974
1048
  obj = JSObject::cast(proto);
975
1049
  }
976
- return obj->map()->is_extensible() ? isolate->heap()->true_value()
977
- : isolate->heap()->false_value();
1050
+ return isolate->heap()->ToBoolean(obj->map()->is_extensible());
978
1051
  }
979
1052
 
980
1053
 
@@ -1040,8 +1113,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
1040
1113
  Map::cast(new_map)->set_is_access_check_needed(false);
1041
1114
  object->set_map(Map::cast(new_map));
1042
1115
  }
1043
- return needs_access_checks ? isolate->heap()->true_value()
1044
- : isolate->heap()->false_value();
1116
+ return isolate->heap()->ToBoolean(needs_access_checks);
1045
1117
  }
1046
1118
 
1047
1119
 
@@ -1084,9 +1156,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
1084
1156
 
1085
1157
  Handle<Context> context = args.at<Context>(0);
1086
1158
  CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
1087
- bool is_eval = Smi::cast(args[2])->value() == 1;
1088
- StrictModeFlag strict_mode =
1089
- static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
1159
+ bool is_eval = args.smi_at(2) == 1;
1160
+ StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
1090
1161
  ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1091
1162
 
1092
1163
  // Compute the property attributes. According to ECMA-262, section
@@ -1225,19 +1296,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
1225
1296
 
1226
1297
  CONVERT_ARG_CHECKED(Context, context, 0);
1227
1298
  Handle<String> name(String::cast(args[1]));
1228
- PropertyAttributes mode =
1229
- static_cast<PropertyAttributes>(Smi::cast(args[2])->value());
1299
+ PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
1230
1300
  RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
1231
1301
  Handle<Object> initial_value(args[3], isolate);
1232
1302
 
1233
- // Declarations are always done in the function context.
1234
- context = Handle<Context>(context->fcontext());
1303
+ // Declarations are always done in a function or global context.
1304
+ context = Handle<Context>(context->declaration_context());
1235
1305
 
1236
1306
  int index;
1237
1307
  PropertyAttributes attributes;
1238
1308
  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
1309
+ BindingFlags binding_flags;
1239
1310
  Handle<Object> holder =
1240
- context->Lookup(name, flags, &index, &attributes);
1311
+ context->Lookup(name, flags, &index, &attributes, &binding_flags);
1241
1312
 
1242
1313
  if (attributes != ABSENT) {
1243
1314
  // The name was declared before; check for conflicting
@@ -1285,7 +1356,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
1285
1356
  Handle<JSObject> context_ext;
1286
1357
  if (context->has_extension()) {
1287
1358
  // The function context's extension context exists - use it.
1288
- context_ext = Handle<JSObject>(context->extension());
1359
+ context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
1289
1360
  } else {
1290
1361
  // The function context's extension context does not exists - allocate
1291
1362
  // it.
@@ -1339,8 +1410,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
1339
1410
  CONVERT_ARG_CHECKED(String, name, 0);
1340
1411
  GlobalObject* global = isolate->context()->global();
1341
1412
  RUNTIME_ASSERT(args[1]->IsSmi());
1342
- StrictModeFlag strict_mode =
1343
- static_cast<StrictModeFlag>(Smi::cast(args[1])->value());
1413
+ StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(1));
1344
1414
  ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1345
1415
 
1346
1416
  // According to ECMA-262, section 12.2, page 62, the property must
@@ -1519,14 +1589,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1519
1589
  CONVERT_ARG_CHECKED(Context, context, 1);
1520
1590
  Handle<String> name(String::cast(args[2]));
1521
1591
 
1522
- // Initializations are always done in the function context.
1523
- context = Handle<Context>(context->fcontext());
1592
+ // Initializations are always done in a function or global context.
1593
+ context = Handle<Context>(context->declaration_context());
1524
1594
 
1525
1595
  int index;
1526
1596
  PropertyAttributes attributes;
1527
1597
  ContextLookupFlags flags = FOLLOW_CHAINS;
1598
+ BindingFlags binding_flags;
1528
1599
  Handle<Object> holder =
1529
- context->Lookup(name, flags, &index, &attributes);
1600
+ context->Lookup(name, flags, &index, &attributes, &binding_flags);
1530
1601
 
1531
1602
  // In most situations, the property introduced by the const
1532
1603
  // declaration should be present in the context extension object.
@@ -1541,14 +1612,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1541
1612
  // In that case, the initialization behaves like a normal assignment
1542
1613
  // to property 'x'.
1543
1614
  if (index >= 0) {
1544
- // Property was found in a context.
1545
1615
  if (holder->IsContext()) {
1546
- // The holder cannot be the function context. If it is, there
1547
- // should have been a const redeclaration error when declaring
1548
- // the const property.
1549
- ASSERT(!holder.is_identical_to(context));
1550
- if ((attributes & READ_ONLY) == 0) {
1551
- Handle<Context>::cast(holder)->set(index, *value);
1616
+ // Property was found in a context. Perform the assignment if we
1617
+ // found some non-constant or an uninitialized constant.
1618
+ Handle<Context> context = Handle<Context>::cast(holder);
1619
+ if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
1620
+ context->set(index, *value);
1552
1621
  }
1553
1622
  } else {
1554
1623
  // The holder is an arguments object.
@@ -1622,7 +1691,7 @@ RUNTIME_FUNCTION(MaybeObject*,
1622
1691
  HandleScope scope(isolate);
1623
1692
  ASSERT(args.length() == 2);
1624
1693
  CONVERT_ARG_CHECKED(JSObject, object, 0);
1625
- CONVERT_SMI_CHECKED(properties, args[1]);
1694
+ CONVERT_SMI_ARG_CHECKED(properties, 1);
1626
1695
  if (object->HasFastProperties()) {
1627
1696
  NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
1628
1697
  }
@@ -1637,7 +1706,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1637
1706
  CONVERT_ARG_CHECKED(String, subject, 1);
1638
1707
  // Due to the way the JS calls are constructed this must be less than the
1639
1708
  // length of a string, i.e. it is always a Smi. We check anyway for security.
1640
- CONVERT_SMI_CHECKED(index, args[2]);
1709
+ CONVERT_SMI_ARG_CHECKED(index, 2);
1641
1710
  CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
1642
1711
  RUNTIME_ASSERT(last_match_info->HasFastElements());
1643
1712
  RUNTIME_ASSERT(index >= 0);
@@ -1654,8 +1723,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1654
1723
 
1655
1724
  RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
1656
1725
  ASSERT(args.length() == 3);
1657
- CONVERT_SMI_CHECKED(elements_count, args[0]);
1658
- if (elements_count > JSArray::kMaxFastElementsLength) {
1726
+ CONVERT_SMI_ARG_CHECKED(elements_count, 0);
1727
+ if (elements_count < 0 ||
1728
+ elements_count > FixedArray::kMaxLength ||
1729
+ !Smi::IsValid(elements_count)) {
1659
1730
  return isolate->ThrowIllegalOperation();
1660
1731
  }
1661
1732
  Object* new_object;
@@ -1797,10 +1868,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
1797
1868
  }
1798
1869
 
1799
1870
 
1800
- RUNTIME_FUNCTION(MaybeObject*, Runtime_GetGlobalReceiver) {
1801
- // Returns a real global receiver, not one of builtins object.
1871
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
1872
+ NoHandleAllocation handle_free;
1873
+ ASSERT(args.length() == 1);
1874
+ CONVERT_CHECKED(JSFunction, function, args[0]);
1875
+ SharedFunctionInfo* shared = function->shared();
1876
+ if (shared->native() || shared->strict_mode()) {
1877
+ return isolate->heap()->undefined_value();
1878
+ }
1879
+ // Returns undefined for strict or native functions, or
1880
+ // the associated global receiver for "normal" functions.
1881
+
1802
1882
  Context* global_context =
1803
- isolate->context()->global()->global_context();
1883
+ function->context()->global()->global_context();
1804
1884
  return global_context->global()->global_receiver();
1805
1885
  }
1806
1886
 
@@ -1809,7 +1889,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
1809
1889
  HandleScope scope(isolate);
1810
1890
  ASSERT(args.length() == 4);
1811
1891
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
1812
- int index = Smi::cast(args[1])->value();
1892
+ int index = args.smi_at(1);
1813
1893
  Handle<String> pattern = args.at<String>(2);
1814
1894
  Handle<String> flags = args.at<String>(3);
1815
1895
 
@@ -1855,6 +1935,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
1855
1935
  }
1856
1936
 
1857
1937
 
1938
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
1939
+ NoHandleAllocation ha;
1940
+ ASSERT(args.length() == 1);
1941
+ CONVERT_CHECKED(JSFunction, f, args[0]);
1942
+ return isolate->heap()->ToBoolean(
1943
+ f->shared()->name_should_print_as_anonymous());
1944
+ }
1945
+
1946
+
1947
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
1948
+ NoHandleAllocation ha;
1949
+ ASSERT(args.length() == 1);
1950
+ CONVERT_CHECKED(JSFunction, f, args[0]);
1951
+ f->shared()->set_name_should_print_as_anonymous(true);
1952
+ return isolate->heap()->undefined_value();
1953
+ }
1954
+
1955
+
1956
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
1957
+ HandleScope scope(isolate);
1958
+ ASSERT(args.length() == 1);
1959
+
1960
+ CONVERT_CHECKED(JSFunction, fun, args[0]);
1961
+ fun->shared()->set_bound(true);
1962
+ return isolate->heap()->undefined_value();
1963
+ }
1964
+
1858
1965
  RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
1859
1966
  NoHandleAllocation ha;
1860
1967
  ASSERT(args.length() == 1);
@@ -1933,6 +2040,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
1933
2040
  }
1934
2041
 
1935
2042
 
2043
+ // Creates a local, readonly, property called length with the correct
2044
+ // length (when read by the user). This effectively overwrites the
2045
+ // interceptor used to normally provide the length.
2046
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionSetLength) {
2047
+ NoHandleAllocation ha;
2048
+ ASSERT(args.length() == 2);
2049
+ CONVERT_CHECKED(JSFunction, fun, args[0]);
2050
+ CONVERT_CHECKED(Smi, length, args[1]);
2051
+ MaybeObject* maybe_name =
2052
+ isolate->heap()->AllocateStringFromAscii(CStrVector("length"));
2053
+ String* name;
2054
+ if (!maybe_name->To(&name)) return maybe_name;
2055
+ PropertyAttributes attr =
2056
+ static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
2057
+ return fun->AddProperty(name, length, attr, kNonStrictMode);
2058
+ }
2059
+
2060
+
1936
2061
  RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
1937
2062
  NoHandleAllocation ha;
1938
2063
  ASSERT(args.length() == 2);
@@ -1948,13 +2073,67 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
1948
2073
  }
1949
2074
 
1950
2075
 
2076
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
2077
+ NoHandleAllocation ha;
2078
+ RUNTIME_ASSERT(args.length() == 1);
2079
+ CONVERT_CHECKED(JSFunction, function, args[0]);
2080
+
2081
+ MaybeObject* maybe_name =
2082
+ isolate->heap()->AllocateStringFromAscii(CStrVector("prototype"));
2083
+ String* name;
2084
+ if (!maybe_name->To(&name)) return maybe_name;
2085
+
2086
+ if (function->HasFastProperties()) {
2087
+ // Construct a new field descriptor with updated attributes.
2088
+ DescriptorArray* instance_desc = function->map()->instance_descriptors();
2089
+ int index = instance_desc->Search(name);
2090
+ ASSERT(index != DescriptorArray::kNotFound);
2091
+ PropertyDetails details(instance_desc->GetDetails(index));
2092
+ CallbacksDescriptor new_desc(name,
2093
+ instance_desc->GetValue(index),
2094
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
2095
+ details.index());
2096
+ // Construct a new field descriptors array containing the new descriptor.
2097
+ Object* descriptors_unchecked;
2098
+ { MaybeObject* maybe_descriptors_unchecked =
2099
+ instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS);
2100
+ if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
2101
+ return maybe_descriptors_unchecked;
2102
+ }
2103
+ }
2104
+ DescriptorArray* new_descriptors =
2105
+ DescriptorArray::cast(descriptors_unchecked);
2106
+ // Create a new map featuring the new field descriptors array.
2107
+ Object* map_unchecked;
2108
+ { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors();
2109
+ if (!maybe_map_unchecked->ToObject(&map_unchecked)) {
2110
+ return maybe_map_unchecked;
2111
+ }
2112
+ }
2113
+ Map* new_map = Map::cast(map_unchecked);
2114
+ new_map->set_instance_descriptors(new_descriptors);
2115
+ function->set_map(new_map);
2116
+ } else { // Dictionary properties.
2117
+ // Directly manipulate the property details.
2118
+ int entry = function->property_dictionary()->FindEntry(name);
2119
+ ASSERT(entry != StringDictionary::kNotFound);
2120
+ PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
2121
+ PropertyDetails new_details(
2122
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
2123
+ details.type(),
2124
+ details.index());
2125
+ function->property_dictionary()->DetailsAtPut(entry, new_details);
2126
+ }
2127
+ return function;
2128
+ }
2129
+
2130
+
1951
2131
  RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
1952
2132
  NoHandleAllocation ha;
1953
2133
  ASSERT(args.length() == 1);
1954
2134
 
1955
2135
  CONVERT_CHECKED(JSFunction, f, args[0]);
1956
- return f->shared()->IsApiFunction() ? isolate->heap()->true_value()
1957
- : isolate->heap()->false_value();
2136
+ return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
1958
2137
  }
1959
2138
 
1960
2139
 
@@ -1963,8 +2142,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
1963
2142
  ASSERT(args.length() == 1);
1964
2143
 
1965
2144
  CONVERT_CHECKED(JSFunction, f, args[0]);
1966
- return f->IsBuiltin() ? isolate->heap()->true_value() :
1967
- isolate->heap()->false_value();
2145
+ return isolate->heap()->ToBoolean(f->IsBuiltin());
1968
2146
  }
1969
2147
 
1970
2148
 
@@ -2035,7 +2213,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
2035
2213
  HandleScope scope(isolate);
2036
2214
  ASSERT(args.length() == 2);
2037
2215
  CONVERT_ARG_CHECKED(JSFunction, function, 0);
2038
- CONVERT_SMI_CHECKED(num, args[1]);
2216
+ CONVERT_SMI_ARG_CHECKED(num, 1);
2039
2217
  RUNTIME_ASSERT(num >= 0);
2040
2218
  SetExpectedNofProperties(function, num);
2041
2219
  return isolate->heap()->undefined_value();
@@ -2259,24 +2437,24 @@ class ReplacementStringBuilder {
2259
2437
 
2260
2438
  Handle<String> joined_string;
2261
2439
  if (is_ascii_) {
2262
- joined_string = NewRawAsciiString(character_count_);
2440
+ Handle<SeqAsciiString> seq = NewRawAsciiString(character_count_);
2263
2441
  AssertNoAllocation no_alloc;
2264
- SeqAsciiString* seq = SeqAsciiString::cast(*joined_string);
2265
2442
  char* char_buffer = seq->GetChars();
2266
2443
  StringBuilderConcatHelper(*subject_,
2267
2444
  char_buffer,
2268
2445
  *array_builder_.array(),
2269
2446
  array_builder_.length());
2447
+ joined_string = Handle<String>::cast(seq);
2270
2448
  } else {
2271
2449
  // Non-ASCII.
2272
- joined_string = NewRawTwoByteString(character_count_);
2450
+ Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
2273
2451
  AssertNoAllocation no_alloc;
2274
- SeqTwoByteString* seq = SeqTwoByteString::cast(*joined_string);
2275
2452
  uc16* char_buffer = seq->GetChars();
2276
2453
  StringBuilderConcatHelper(*subject_,
2277
2454
  char_buffer,
2278
2455
  *array_builder_.array(),
2279
2456
  array_builder_.length());
2457
+ joined_string = Handle<String>::cast(seq);
2280
2458
  }
2281
2459
  return joined_string;
2282
2460
  }
@@ -2294,15 +2472,13 @@ class ReplacementStringBuilder {
2294
2472
  }
2295
2473
 
2296
2474
  private:
2297
- Handle<String> NewRawAsciiString(int size) {
2298
- CALL_HEAP_FUNCTION(heap_->isolate(),
2299
- heap_->AllocateRawAsciiString(size), String);
2475
+ Handle<SeqAsciiString> NewRawAsciiString(int length) {
2476
+ return heap_->isolate()->factory()->NewRawAsciiString(length);
2300
2477
  }
2301
2478
 
2302
2479
 
2303
- Handle<String> NewRawTwoByteString(int size) {
2304
- CALL_HEAP_FUNCTION(heap_->isolate(),
2305
- heap_->AllocateRawTwoByteString(size), String);
2480
+ Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
2481
+ return heap_->isolate()->factory()->NewRawTwoByteString(length);
2306
2482
  }
2307
2483
 
2308
2484
 
@@ -2338,6 +2514,7 @@ class CompiledReplacement {
2338
2514
  int parts() {
2339
2515
  return parts_.length();
2340
2516
  }
2517
+
2341
2518
  private:
2342
2519
  enum PartType {
2343
2520
  SUBJECT_PREFIX = 1,
@@ -2507,21 +2684,22 @@ class CompiledReplacement {
2507
2684
  void CompiledReplacement::Compile(Handle<String> replacement,
2508
2685
  int capture_count,
2509
2686
  int subject_length) {
2510
- ASSERT(replacement->IsFlat());
2511
- if (replacement->IsAsciiRepresentation()) {
2512
- AssertNoAllocation no_alloc;
2513
- ParseReplacementPattern(&parts_,
2514
- replacement->ToAsciiVector(),
2515
- capture_count,
2516
- subject_length);
2517
- } else {
2518
- ASSERT(replacement->IsTwoByteRepresentation());
2687
+ {
2519
2688
  AssertNoAllocation no_alloc;
2520
-
2521
- ParseReplacementPattern(&parts_,
2522
- replacement->ToUC16Vector(),
2523
- capture_count,
2524
- subject_length);
2689
+ String::FlatContent content = replacement->GetFlatContent();
2690
+ ASSERT(content.IsFlat());
2691
+ if (content.IsAscii()) {
2692
+ ParseReplacementPattern(&parts_,
2693
+ content.ToAsciiVector(),
2694
+ capture_count,
2695
+ subject_length);
2696
+ } else {
2697
+ ASSERT(content.IsTwoByte());
2698
+ ParseReplacementPattern(&parts_,
2699
+ content.ToUC16Vector(),
2700
+ capture_count,
2701
+ subject_length);
2702
+ }
2525
2703
  }
2526
2704
  Isolate* isolate = replacement->GetIsolate();
2527
2705
  // Find substrings of replacement string and create them as String objects.
@@ -2614,7 +2792,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
2614
2792
  int capture_count = regexp_handle->CaptureCount();
2615
2793
 
2616
2794
  // CompiledReplacement uses zone allocation.
2617
- CompilationZoneScope zone(isolate, DELETE_ON_EXIT);
2795
+ ZoneScope zone(isolate, DELETE_ON_EXIT);
2618
2796
  CompiledReplacement compiled_replacement;
2619
2797
  compiled_replacement.Compile(replacement_handle,
2620
2798
  capture_count,
@@ -2893,34 +3071,32 @@ int Runtime::StringMatch(Isolate* isolate,
2893
3071
 
2894
3072
  AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
2895
3073
  // Extract flattened substrings of cons strings before determining asciiness.
2896
- String* seq_sub = *sub;
2897
- if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first();
2898
- String* seq_pat = *pat;
2899
- if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first();
3074
+ String::FlatContent seq_sub = sub->GetFlatContent();
3075
+ String::FlatContent seq_pat = pat->GetFlatContent();
2900
3076
 
2901
3077
  // dispatch on type of strings
2902
- if (seq_pat->IsAsciiRepresentation()) {
2903
- Vector<const char> pat_vector = seq_pat->ToAsciiVector();
2904
- if (seq_sub->IsAsciiRepresentation()) {
3078
+ if (seq_pat.IsAscii()) {
3079
+ Vector<const char> pat_vector = seq_pat.ToAsciiVector();
3080
+ if (seq_sub.IsAscii()) {
2905
3081
  return SearchString(isolate,
2906
- seq_sub->ToAsciiVector(),
3082
+ seq_sub.ToAsciiVector(),
2907
3083
  pat_vector,
2908
3084
  start_index);
2909
3085
  }
2910
3086
  return SearchString(isolate,
2911
- seq_sub->ToUC16Vector(),
3087
+ seq_sub.ToUC16Vector(),
2912
3088
  pat_vector,
2913
3089
  start_index);
2914
3090
  }
2915
- Vector<const uc16> pat_vector = seq_pat->ToUC16Vector();
2916
- if (seq_sub->IsAsciiRepresentation()) {
3091
+ Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
3092
+ if (seq_sub.IsAscii()) {
2917
3093
  return SearchString(isolate,
2918
- seq_sub->ToAsciiVector(),
3094
+ seq_sub.ToAsciiVector(),
2919
3095
  pat_vector,
2920
3096
  start_index);
2921
3097
  }
2922
3098
  return SearchString(isolate,
2923
- seq_sub->ToUC16Vector(),
3099
+ seq_sub.ToUC16Vector(),
2924
3100
  pat_vector,
2925
3101
  start_index);
2926
3102
  }
@@ -3003,29 +3179,31 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
3003
3179
  if (!sub->IsFlat()) FlattenString(sub);
3004
3180
  if (!pat->IsFlat()) FlattenString(pat);
3005
3181
 
3182
+ int position = -1;
3006
3183
  AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
3007
3184
 
3008
- int position = -1;
3185
+ String::FlatContent sub_content = sub->GetFlatContent();
3186
+ String::FlatContent pat_content = pat->GetFlatContent();
3009
3187
 
3010
- if (pat->IsAsciiRepresentation()) {
3011
- Vector<const char> pat_vector = pat->ToAsciiVector();
3012
- if (sub->IsAsciiRepresentation()) {
3013
- position = StringMatchBackwards(sub->ToAsciiVector(),
3188
+ if (pat_content.IsAscii()) {
3189
+ Vector<const char> pat_vector = pat_content.ToAsciiVector();
3190
+ if (sub_content.IsAscii()) {
3191
+ position = StringMatchBackwards(sub_content.ToAsciiVector(),
3014
3192
  pat_vector,
3015
3193
  start_index);
3016
3194
  } else {
3017
- position = StringMatchBackwards(sub->ToUC16Vector(),
3195
+ position = StringMatchBackwards(sub_content.ToUC16Vector(),
3018
3196
  pat_vector,
3019
3197
  start_index);
3020
3198
  }
3021
3199
  } else {
3022
- Vector<const uc16> pat_vector = pat->ToUC16Vector();
3023
- if (sub->IsAsciiRepresentation()) {
3024
- position = StringMatchBackwards(sub->ToAsciiVector(),
3200
+ Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
3201
+ if (sub_content.IsAscii()) {
3202
+ position = StringMatchBackwards(sub_content.ToAsciiVector(),
3025
3203
  pat_vector,
3026
3204
  start_index);
3027
3205
  } else {
3028
- position = StringMatchBackwards(sub->ToUC16Vector(),
3206
+ position = StringMatchBackwards(sub_content.ToUC16Vector(),
3029
3207
  pat_vector,
3030
3208
  start_index);
3031
3209
  }
@@ -3088,17 +3266,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
3088
3266
  ASSERT(args.length() == 3);
3089
3267
 
3090
3268
  CONVERT_CHECKED(String, value, args[0]);
3091
- Object* from = args[1];
3092
- Object* to = args[2];
3093
3269
  int start, end;
3094
3270
  // We have a fast integer-only case here to avoid a conversion to double in
3095
3271
  // the common case where from and to are Smis.
3096
- if (from->IsSmi() && to->IsSmi()) {
3097
- start = Smi::cast(from)->value();
3098
- end = Smi::cast(to)->value();
3272
+ if (args[1]->IsSmi() && args[2]->IsSmi()) {
3273
+ CONVERT_SMI_ARG_CHECKED(from_number, 1);
3274
+ CONVERT_SMI_ARG_CHECKED(to_number, 2);
3275
+ start = from_number;
3276
+ end = to_number;
3099
3277
  } else {
3100
- CONVERT_DOUBLE_CHECKED(from_number, from);
3101
- CONVERT_DOUBLE_CHECKED(to_number, to);
3278
+ CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
3279
+ CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
3102
3280
  start = FastD2I(from_number);
3103
3281
  end = FastD2I(to_number);
3104
3282
  }
@@ -3128,11 +3306,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
3128
3306
  }
3129
3307
  int length = subject->length();
3130
3308
 
3131
- CompilationZoneScope zone_space(isolate, DELETE_ON_EXIT);
3309
+ ZoneScope zone_space(isolate, DELETE_ON_EXIT);
3132
3310
  ZoneList<int> offsets(8);
3311
+ int start;
3312
+ int end;
3133
3313
  do {
3134
- int start;
3135
- int end;
3136
3314
  {
3137
3315
  AssertNoAllocation no_alloc;
3138
3316
  FixedArray* elements = FixedArray::cast(regexp_info->elements());
@@ -3141,20 +3319,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
3141
3319
  }
3142
3320
  offsets.Add(start);
3143
3321
  offsets.Add(end);
3144
- int index = start < end ? end : end + 1;
3145
- if (index > length) break;
3146
- match = RegExpImpl::Exec(regexp, subject, index, regexp_info);
3322
+ if (start == end) if (++end > length) break;
3323
+ match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
3147
3324
  if (match.is_null()) {
3148
3325
  return Failure::Exception();
3149
3326
  }
3150
3327
  } while (!match->IsNull());
3151
3328
  int matches = offsets.length() / 2;
3152
3329
  Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
3153
- for (int i = 0; i < matches ; i++) {
3330
+ Handle<String> substring = isolate->factory()->
3331
+ NewSubString(subject, offsets.at(0), offsets.at(1));
3332
+ elements->set(0, *substring);
3333
+ for (int i = 1; i < matches ; i++) {
3154
3334
  int from = offsets.at(i * 2);
3155
3335
  int to = offsets.at(i * 2 + 1);
3156
- Handle<String> match = isolate->factory()->NewSubString(subject, from, to);
3157
- elements->set(i, *match);
3336
+ Handle<String> substring = isolate->factory()->
3337
+ NewProperSubString(subject, from, to);
3338
+ elements->set(i, *substring);
3158
3339
  }
3159
3340
  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
3160
3341
  result->set_length(Smi::FromInt(matches));
@@ -3240,36 +3421,38 @@ static bool SearchStringMultiple(Isolate* isolate,
3240
3421
  for (;;) { // Break when search complete.
3241
3422
  builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3242
3423
  AssertNoAllocation no_gc;
3243
- if (subject->IsAsciiRepresentation()) {
3244
- Vector<const char> subject_vector = subject->ToAsciiVector();
3245
- if (pattern->IsAsciiRepresentation()) {
3424
+ String::FlatContent subject_content = subject->GetFlatContent();
3425
+ String::FlatContent pattern_content = pattern->GetFlatContent();
3426
+ if (subject_content.IsAscii()) {
3427
+ Vector<const char> subject_vector = subject_content.ToAsciiVector();
3428
+ if (pattern_content.IsAscii()) {
3246
3429
  if (SearchStringMultiple(isolate,
3247
3430
  subject_vector,
3248
- pattern->ToAsciiVector(),
3431
+ pattern_content.ToAsciiVector(),
3249
3432
  *pattern,
3250
3433
  builder,
3251
3434
  &match_pos)) break;
3252
3435
  } else {
3253
3436
  if (SearchStringMultiple(isolate,
3254
3437
  subject_vector,
3255
- pattern->ToUC16Vector(),
3438
+ pattern_content.ToUC16Vector(),
3256
3439
  *pattern,
3257
3440
  builder,
3258
3441
  &match_pos)) break;
3259
3442
  }
3260
3443
  } else {
3261
- Vector<const uc16> subject_vector = subject->ToUC16Vector();
3262
- if (pattern->IsAsciiRepresentation()) {
3444
+ Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
3445
+ if (pattern_content.IsAscii()) {
3263
3446
  if (SearchStringMultiple(isolate,
3264
3447
  subject_vector,
3265
- pattern->ToAsciiVector(),
3448
+ pattern_content.ToAsciiVector(),
3266
3449
  *pattern,
3267
3450
  builder,
3268
3451
  &match_pos)) break;
3269
3452
  } else {
3270
3453
  if (SearchStringMultiple(isolate,
3271
3454
  subject_vector,
3272
- pattern->ToUC16Vector(),
3455
+ pattern_content.ToUC16Vector(),
3273
3456
  *pattern,
3274
3457
  builder,
3275
3458
  &match_pos)) break;
@@ -3304,6 +3487,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
3304
3487
  OffsetsVector registers(required_registers);
3305
3488
  Vector<int32_t> register_vector(registers.vector(), registers.length());
3306
3489
  int subject_length = subject->length();
3490
+ bool first = true;
3307
3491
 
3308
3492
  for (;;) { // Break on failure, return on exception.
3309
3493
  RegExpImpl::IrregexpResult result =
@@ -3321,9 +3505,15 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
3321
3505
  }
3322
3506
  match_end = register_vector[1];
3323
3507
  HandleScope loop_scope(isolate);
3324
- builder->Add(*isolate->factory()->NewSubString(subject,
3325
- match_start,
3326
- match_end));
3508
+ if (!first) {
3509
+ builder->Add(*isolate->factory()->NewProperSubString(subject,
3510
+ match_start,
3511
+ match_end));
3512
+ } else {
3513
+ builder->Add(*isolate->factory()->NewSubString(subject,
3514
+ match_start,
3515
+ match_end));
3516
+ }
3327
3517
  if (match_start != match_end) {
3328
3518
  pos = match_end;
3329
3519
  } else {
@@ -3336,6 +3526,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
3336
3526
  ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
3337
3527
  return result;
3338
3528
  }
3529
+ first = false;
3339
3530
  }
3340
3531
 
3341
3532
  if (match_start >= 0) {
@@ -3387,7 +3578,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
3387
3578
  // at the end, so we have two vectors that we swap between.
3388
3579
  OffsetsVector registers2(required_registers);
3389
3580
  Vector<int> prev_register_vector(registers2.vector(), registers2.length());
3390
-
3581
+ bool first = true;
3391
3582
  do {
3392
3583
  int match_start = register_vector[0];
3393
3584
  builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
@@ -3405,18 +3596,30 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
3405
3596
  // subject, i.e., 3 + capture count in total.
3406
3597
  Handle<FixedArray> elements =
3407
3598
  isolate->factory()->NewFixedArray(3 + capture_count);
3408
- Handle<String> match = isolate->factory()->NewSubString(subject,
3409
- match_start,
3410
- match_end);
3599
+ Handle<String> match;
3600
+ if (!first) {
3601
+ match = isolate->factory()->NewProperSubString(subject,
3602
+ match_start,
3603
+ match_end);
3604
+ } else {
3605
+ match = isolate->factory()->NewSubString(subject,
3606
+ match_start,
3607
+ match_end);
3608
+ }
3411
3609
  elements->set(0, *match);
3412
3610
  for (int i = 1; i <= capture_count; i++) {
3413
3611
  int start = register_vector[i * 2];
3414
3612
  if (start >= 0) {
3415
3613
  int end = register_vector[i * 2 + 1];
3416
3614
  ASSERT(start <= end);
3417
- Handle<String> substring = isolate->factory()->NewSubString(subject,
3418
- start,
3419
- end);
3615
+ Handle<String> substring;
3616
+ if (!first) {
3617
+ substring = isolate->factory()->NewProperSubString(subject,
3618
+ start,
3619
+ end);
3620
+ } else {
3621
+ substring = isolate->factory()->NewSubString(subject, start, end);
3622
+ }
3420
3623
  elements->set(i, *substring);
3421
3624
  } else {
3422
3625
  ASSERT(register_vector[i * 2 + 1] < 0);
@@ -3446,6 +3649,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
3446
3649
  subject,
3447
3650
  pos,
3448
3651
  register_vector);
3652
+ first = false;
3449
3653
  } while (result == RegExpImpl::RE_SUCCESS);
3450
3654
 
3451
3655
  if (result != RegExpImpl::RE_EXCEPTION) {
@@ -3481,7 +3685,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
3481
3685
  HandleScope handles(isolate);
3482
3686
 
3483
3687
  CONVERT_ARG_CHECKED(String, subject, 1);
3484
- if (!subject->IsFlat()) { FlattenString(subject); }
3688
+ if (!subject->IsFlat()) FlattenString(subject);
3485
3689
  CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
3486
3690
  CONVERT_ARG_CHECKED(JSArray, last_match_info, 2);
3487
3691
  CONVERT_ARG_CHECKED(JSArray, result_array, 3);
@@ -3492,7 +3696,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
3492
3696
  if (result_array->HasFastElements()) {
3493
3697
  result_elements =
3494
3698
  Handle<FixedArray>(FixedArray::cast(result_array->elements()));
3495
- } else {
3699
+ }
3700
+ if (result_elements.is_null() || result_elements->length() < 16) {
3496
3701
  result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
3497
3702
  }
3498
3703
  FixedArrayBuilder builder(result_elements);
@@ -3534,13 +3739,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
3534
3739
  RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
3535
3740
  NoHandleAllocation ha;
3536
3741
  ASSERT(args.length() == 2);
3742
+ CONVERT_SMI_ARG_CHECKED(radix, 1);
3743
+ RUNTIME_ASSERT(2 <= radix && radix <= 36);
3537
3744
 
3538
3745
  // Fast case where the result is a one character string.
3539
- if (args[0]->IsSmi() && args[1]->IsSmi()) {
3540
- int value = Smi::cast(args[0])->value();
3541
- int radix = Smi::cast(args[1])->value();
3746
+ if (args[0]->IsSmi()) {
3747
+ int value = args.smi_at(0);
3542
3748
  if (value >= 0 && value < radix) {
3543
- RUNTIME_ASSERT(radix <= 36);
3544
3749
  // Character array used for conversion.
3545
3750
  static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
3546
3751
  return isolate->heap()->
@@ -3549,7 +3754,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
3549
3754
  }
3550
3755
 
3551
3756
  // Slow case.
3552
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3757
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3553
3758
  if (isnan(value)) {
3554
3759
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3555
3760
  }
@@ -3559,9 +3764,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
3559
3764
  }
3560
3765
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3561
3766
  }
3562
- CONVERT_DOUBLE_CHECKED(radix_number, args[1]);
3563
- int radix = FastD2I(radix_number);
3564
- RUNTIME_ASSERT(2 <= radix && radix <= 36);
3565
3767
  char* str = DoubleToRadixCString(value, radix);
3566
3768
  MaybeObject* result =
3567
3769
  isolate->heap()->AllocateStringFromAscii(CStrVector(str));
@@ -3574,7 +3776,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
3574
3776
  NoHandleAllocation ha;
3575
3777
  ASSERT(args.length() == 2);
3576
3778
 
3577
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3779
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3578
3780
  if (isnan(value)) {
3579
3781
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3580
3782
  }
@@ -3584,7 +3786,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
3584
3786
  }
3585
3787
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3586
3788
  }
3587
- CONVERT_DOUBLE_CHECKED(f_number, args[1]);
3789
+ CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3588
3790
  int f = FastD2I(f_number);
3589
3791
  RUNTIME_ASSERT(f >= 0);
3590
3792
  char* str = DoubleToFixedCString(value, f);
@@ -3599,7 +3801,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
3599
3801
  NoHandleAllocation ha;
3600
3802
  ASSERT(args.length() == 2);
3601
3803
 
3602
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3804
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3603
3805
  if (isnan(value)) {
3604
3806
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3605
3807
  }
@@ -3609,7 +3811,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
3609
3811
  }
3610
3812
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3611
3813
  }
3612
- CONVERT_DOUBLE_CHECKED(f_number, args[1]);
3814
+ CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3613
3815
  int f = FastD2I(f_number);
3614
3816
  RUNTIME_ASSERT(f >= -1 && f <= 20);
3615
3817
  char* str = DoubleToExponentialCString(value, f);
@@ -3624,7 +3826,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
3624
3826
  NoHandleAllocation ha;
3625
3827
  ASSERT(args.length() == 2);
3626
3828
 
3627
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3829
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3628
3830
  if (isnan(value)) {
3629
3831
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3630
3832
  }
@@ -3634,7 +3836,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
3634
3836
  }
3635
3837
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3636
3838
  }
3637
- CONVERT_DOUBLE_CHECKED(f_number, args[1]);
3839
+ CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3638
3840
  int f = FastD2I(f_number);
3639
3841
  RUNTIME_ASSERT(f >= 1 && f <= 21);
3640
3842
  char* str = DoubleToPrecisionCString(value, f);
@@ -3724,8 +3926,7 @@ MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
3724
3926
  if (name->AsArrayIndex(&index)) {
3725
3927
  return GetElementOrCharAt(isolate, object, index);
3726
3928
  } else {
3727
- PropertyAttributes attr;
3728
- return object->GetProperty(*name, &attr);
3929
+ return object->GetProperty(*name);
3729
3930
  }
3730
3931
  }
3731
3932
 
@@ -3797,7 +3998,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
3797
3998
  // Fast case for string indexing using [] with a smi index.
3798
3999
  HandleScope scope(isolate);
3799
4000
  Handle<String> str = args.at<String>(0);
3800
- int index = Smi::cast(args[1])->value();
4001
+ int index = args.smi_at(1);
3801
4002
  if (index >= 0 && index < str->length()) {
3802
4003
  Handle<Object> result = GetCharAt(str, index);
3803
4004
  return *result;
@@ -3840,7 +4041,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
3840
4041
  || result.type() == CONSTANT_FUNCTION)) {
3841
4042
  Object* ok;
3842
4043
  { MaybeObject* maybe_ok =
3843
- obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
4044
+ obj->DeleteProperty(name, JSReceiver::NORMAL_DELETION);
3844
4045
  if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3845
4046
  }
3846
4047
  }
@@ -3885,17 +4086,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
3885
4086
  if (proto->IsNull()) return *obj_value;
3886
4087
  js_object = Handle<JSObject>::cast(proto);
3887
4088
  }
3888
- NormalizeElements(js_object);
3889
- Handle<NumberDictionary> dictionary(js_object->element_dictionary());
4089
+ Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
3890
4090
  // Make sure that we never go back to fast case.
3891
4091
  dictionary->set_requires_slow_elements();
3892
4092
  PropertyDetails details = PropertyDetails(attr, NORMAL);
3893
- NumberDictionarySet(dictionary, index, obj_value, details);
4093
+ Handle<NumberDictionary> extended_dictionary =
4094
+ NumberDictionarySet(dictionary, index, obj_value, details);
4095
+ if (*extended_dictionary != *dictionary) {
4096
+ if (js_object->GetElementsKind() ==
4097
+ JSObject::NON_STRICT_ARGUMENTS_ELEMENTS) {
4098
+ FixedArray::cast(js_object->elements())->set(1, *extended_dictionary);
4099
+ } else {
4100
+ js_object->set_elements(*extended_dictionary);
4101
+ }
4102
+ }
3894
4103
  return *obj_value;
3895
4104
  }
3896
4105
 
3897
4106
  LookupResult result;
3898
- js_object->LookupRealNamedProperty(*name, &result);
4107
+ js_object->LocalLookupRealNamedProperty(*name, &result);
3899
4108
 
3900
4109
  // To be compatible with safari we do not change the value on API objects
3901
4110
  // in defineProperty. Firefox disagrees here, and actually changes the value.
@@ -3935,6 +4144,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
3935
4144
  }
3936
4145
 
3937
4146
 
4147
+ // Special case for elements if any of the flags are true.
4148
+ // If elements are in fast case we always implicitly assume that:
4149
+ // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false.
4150
+ static MaybeObject* NormalizeObjectSetElement(Isolate* isolate,
4151
+ Handle<JSObject> js_object,
4152
+ uint32_t index,
4153
+ Handle<Object> value,
4154
+ PropertyAttributes attr) {
4155
+ // Normalize the elements to enable attributes on the property.
4156
+ Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
4157
+ // Make sure that we never go back to fast case.
4158
+ dictionary->set_requires_slow_elements();
4159
+ PropertyDetails details = PropertyDetails(attr, NORMAL);
4160
+ Handle<NumberDictionary> extended_dictionary =
4161
+ NumberDictionarySet(dictionary, index, value, details);
4162
+ if (*extended_dictionary != *dictionary) {
4163
+ js_object->set_elements(*extended_dictionary);
4164
+ }
4165
+ return *value;
4166
+ }
4167
+
4168
+
3938
4169
  MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3939
4170
  Handle<Object> object,
3940
4171
  Handle<Object> key,
@@ -3970,6 +4201,10 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3970
4201
  return *value;
3971
4202
  }
3972
4203
 
4204
+ if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
4205
+ return NormalizeObjectSetElement(isolate, js_object, index, value, attr);
4206
+ }
4207
+
3973
4208
  Handle<Object> result = SetElement(js_object, index, value, strict_mode);
3974
4209
  if (result.is_null()) return Failure::Exception();
3975
4210
  return *value;
@@ -3978,6 +4213,13 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3978
4213
  if (key->IsString()) {
3979
4214
  Handle<Object> result;
3980
4215
  if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
4216
+ if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
4217
+ return NormalizeObjectSetElement(isolate,
4218
+ js_object,
4219
+ index,
4220
+ value,
4221
+ attr);
4222
+ }
3981
4223
  result = SetElement(js_object, index, value, strict_mode);
3982
4224
  } else {
3983
4225
  Handle<String> key_string = Handle<String>::cast(key);
@@ -3995,7 +4237,7 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3995
4237
  Handle<String> name = Handle<String>::cast(converted);
3996
4238
 
3997
4239
  if (name->AsArrayIndex(&index)) {
3998
- return js_object->SetElement(index, *value, strict_mode);
4240
+ return js_object->SetElement(index, *value, strict_mode, true);
3999
4241
  } else {
4000
4242
  return js_object->SetProperty(*name, *value, attr, strict_mode);
4001
4243
  }
@@ -4023,12 +4265,12 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
4023
4265
  return *value;
4024
4266
  }
4025
4267
 
4026
- return js_object->SetElement(index, *value, kNonStrictMode);
4268
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
4027
4269
  }
4028
4270
 
4029
4271
  if (key->IsString()) {
4030
4272
  if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
4031
- return js_object->SetElement(index, *value, kNonStrictMode);
4273
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
4032
4274
  } else {
4033
4275
  Handle<String> key_string = Handle<String>::cast(key);
4034
4276
  key_string->TryFlatten();
@@ -4045,7 +4287,7 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
4045
4287
  Handle<String> name = Handle<String>::cast(converted);
4046
4288
 
4047
4289
  if (name->AsArrayIndex(&index)) {
4048
- return js_object->SetElement(index, *value, kNonStrictMode);
4290
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
4049
4291
  } else {
4050
4292
  return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
4051
4293
  }
@@ -4053,24 +4295,25 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
4053
4295
 
4054
4296
 
4055
4297
  MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
4056
- Handle<JSObject> js_object,
4298
+ Handle<JSReceiver> receiver,
4057
4299
  Handle<Object> key) {
4058
4300
  HandleScope scope(isolate);
4059
4301
 
4060
4302
  // Check if the given key is an array index.
4061
4303
  uint32_t index;
4062
- if (key->ToArrayIndex(&index)) {
4304
+ if (receiver->IsJSObject() && key->ToArrayIndex(&index)) {
4063
4305
  // In Firefox/SpiderMonkey, Safari and Opera you can access the
4064
4306
  // characters of a string using [] notation. In the case of a
4065
4307
  // String object we just need to redirect the deletion to the
4066
4308
  // underlying string if the index is in range. Since the
4067
4309
  // underlying string does nothing with the deletion, we can ignore
4068
4310
  // such deletions.
4069
- if (js_object->IsStringObjectWithCharacterAt(index)) {
4311
+ if (receiver->IsStringObjectWithCharacterAt(index)) {
4070
4312
  return isolate->heap()->true_value();
4071
4313
  }
4072
4314
 
4073
- return js_object->DeleteElement(index, JSObject::FORCE_DELETION);
4315
+ return JSObject::cast(*receiver)->DeleteElement(
4316
+ index, JSReceiver::FORCE_DELETION);
4074
4317
  }
4075
4318
 
4076
4319
  Handle<String> key_string;
@@ -4085,7 +4328,7 @@ MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
4085
4328
  }
4086
4329
 
4087
4330
  key_string->TryFlatten();
4088
- return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION);
4331
+ return receiver->DeleteProperty(*key_string, JSReceiver::FORCE_DELETION);
4089
4332
  }
4090
4333
 
4091
4334
 
@@ -4096,7 +4339,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4096
4339
  Handle<Object> object = args.at<Object>(0);
4097
4340
  Handle<Object> key = args.at<Object>(1);
4098
4341
  Handle<Object> value = args.at<Object>(2);
4099
- CONVERT_SMI_CHECKED(unchecked_attributes, args[3]);
4342
+ CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
4100
4343
  RUNTIME_ASSERT(
4101
4344
  (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4102
4345
  // Compute attributes.
@@ -4105,7 +4348,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4105
4348
 
4106
4349
  StrictModeFlag strict_mode = kNonStrictMode;
4107
4350
  if (args.length() == 5) {
4108
- CONVERT_SMI_CHECKED(strict_unchecked, args[4]);
4351
+ CONVERT_SMI_ARG_CHECKED(strict_unchecked, 4);
4109
4352
  RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
4110
4353
  strict_unchecked == kNonStrictMode);
4111
4354
  strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
@@ -4120,10 +4363,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4120
4363
  }
4121
4364
 
4122
4365
 
4123
- // Set the ES5 native flag on the function.
4366
+ // Set the native flag on the function.
4124
4367
  // This is used to decide if we should transform null and undefined
4125
4368
  // into the global object when doing call and apply.
4126
- RUNTIME_FUNCTION(MaybeObject*, Runtime_SetES5Flag) {
4369
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
4127
4370
  NoHandleAllocation ha;
4128
4371
  RUNTIME_ASSERT(args.length() == 1);
4129
4372
 
@@ -4131,7 +4374,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetES5Flag) {
4131
4374
 
4132
4375
  if (object->IsJSFunction()) {
4133
4376
  JSFunction* func = JSFunction::cast(*object);
4134
- func->shared()->set_es5_native(true);
4377
+ func->shared()->set_native(true);
4135
4378
  }
4136
4379
  return isolate->heap()->undefined_value();
4137
4380
  }
@@ -4164,12 +4407,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
4164
4407
  NoHandleAllocation ha;
4165
4408
  ASSERT(args.length() == 3);
4166
4409
 
4167
- CONVERT_CHECKED(JSObject, object, args[0]);
4410
+ CONVERT_CHECKED(JSReceiver, object, args[0]);
4168
4411
  CONVERT_CHECKED(String, key, args[1]);
4169
- CONVERT_SMI_CHECKED(strict, args[2]);
4412
+ CONVERT_SMI_ARG_CHECKED(strict, 2);
4170
4413
  return object->DeleteProperty(key, (strict == kStrictMode)
4171
- ? JSObject::STRICT_DELETION
4172
- : JSObject::NORMAL_DELETION);
4414
+ ? JSReceiver::STRICT_DELETION
4415
+ : JSReceiver::NORMAL_DELETION);
4173
4416
  }
4174
4417
 
4175
4418
 
@@ -4233,11 +4476,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
4233
4476
  NoHandleAllocation na;
4234
4477
  ASSERT(args.length() == 2);
4235
4478
 
4236
- // Only JS objects can have properties.
4237
- if (args[0]->IsJSObject()) {
4238
- JSObject* object = JSObject::cast(args[0]);
4479
+ // Only JS receivers can have properties.
4480
+ if (args[0]->IsJSReceiver()) {
4481
+ JSReceiver* receiver = JSReceiver::cast(args[0]);
4239
4482
  CONVERT_CHECKED(String, key, args[1]);
4240
- if (object->HasProperty(key)) return isolate->heap()->true_value();
4483
+ if (receiver->HasProperty(key)) return isolate->heap()->true_value();
4241
4484
  }
4242
4485
  return isolate->heap()->false_value();
4243
4486
  }
@@ -4378,10 +4621,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
4378
4621
  // Get the property names.
4379
4622
  jsproto = obj;
4380
4623
  int proto_with_hidden_properties = 0;
4624
+ int next_copy_index = 0;
4381
4625
  for (int i = 0; i < length; i++) {
4382
- jsproto->GetLocalPropertyNames(*names,
4383
- i == 0 ? 0 : local_property_count[i - 1]);
4384
- if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
4626
+ jsproto->GetLocalPropertyNames(*names, next_copy_index);
4627
+ next_copy_index += local_property_count[i];
4628
+ if (jsproto->HasHiddenProperties()) {
4385
4629
  proto_with_hidden_properties++;
4386
4630
  }
4387
4631
  if (i < length - 1) {
@@ -4633,11 +4877,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
4633
4877
  return isolate->heap()->boolean_symbol();
4634
4878
  }
4635
4879
  if (heap_obj->IsNull()) {
4636
- return isolate->heap()->object_symbol();
4880
+ return FLAG_harmony_typeof
4881
+ ? isolate->heap()->null_symbol()
4882
+ : isolate->heap()->object_symbol();
4637
4883
  }
4638
4884
  ASSERT(heap_obj->IsUndefined());
4639
4885
  return isolate->heap()->undefined_symbol();
4640
- case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE:
4886
+ case JS_FUNCTION_TYPE:
4641
4887
  return isolate->heap()->function_symbol();
4642
4888
  default:
4643
4889
  // For any kind of object not handled above, the spec rule for
@@ -5011,6 +5257,8 @@ static const int kMaxGuaranteedNewSpaceString = 32 * 1024;
5011
5257
  // Doing JSON quoting cannot make the string more than this many times larger.
5012
5258
  static const int kJsonQuoteWorstCaseBlowup = 6;
5013
5259
 
5260
+ static const int kSpaceForQuotesAndComma = 3;
5261
+ static const int kSpaceForBrackets = 2;
5014
5262
 
5015
5263
  // Covers the entire ASCII range (all other characters are unchanged by JSON
5016
5264
  // quoting).
@@ -5098,13 +5346,51 @@ static MaybeObject* SlowQuoteJsonString(Isolate* isolate,
5098
5346
  }
5099
5347
 
5100
5348
 
5349
+ template <typename SinkChar, typename SourceChar>
5350
+ static inline SinkChar* WriteQuoteJsonString(
5351
+ Isolate* isolate,
5352
+ SinkChar* write_cursor,
5353
+ Vector<const SourceChar> characters) {
5354
+ // SinkChar is only char if SourceChar is guaranteed to be char.
5355
+ ASSERT(sizeof(SinkChar) >= sizeof(SourceChar));
5356
+ const SourceChar* read_cursor = characters.start();
5357
+ const SourceChar* end = read_cursor + characters.length();
5358
+ *(write_cursor++) = '"';
5359
+ while (read_cursor < end) {
5360
+ SourceChar c = *(read_cursor++);
5361
+ if (sizeof(SourceChar) > 1u &&
5362
+ static_cast<unsigned>(c) >= kQuoteTableLength) {
5363
+ *(write_cursor++) = static_cast<SinkChar>(c);
5364
+ } else {
5365
+ int len = JsonQuoteLengths[static_cast<unsigned>(c)];
5366
+ const char* replacement = JsonQuotes +
5367
+ static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
5368
+ write_cursor[0] = replacement[0];
5369
+ if (len > 1) {
5370
+ write_cursor[1] = replacement[1];
5371
+ if (len > 2) {
5372
+ ASSERT(len == 6);
5373
+ write_cursor[2] = replacement[2];
5374
+ write_cursor[3] = replacement[3];
5375
+ write_cursor[4] = replacement[4];
5376
+ write_cursor[5] = replacement[5];
5377
+ }
5378
+ }
5379
+ write_cursor += len;
5380
+ }
5381
+ }
5382
+ *(write_cursor++) = '"';
5383
+ return write_cursor;
5384
+ }
5385
+
5386
+
5101
5387
  template <typename Char, typename StringType, bool comma>
5102
5388
  static MaybeObject* QuoteJsonString(Isolate* isolate,
5103
5389
  Vector<const Char> characters) {
5104
5390
  int length = characters.length();
5105
5391
  isolate->counters()->quote_json_char_count()->Increment(length);
5106
- const int kSpaceForQuotes = 2 + (comma ? 1 :0);
5107
- int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
5392
+ int worst_case_length =
5393
+ length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotesAndComma;
5108
5394
  if (worst_case_length > kMaxGuaranteedNewSpaceString) {
5109
5395
  return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
5110
5396
  }
@@ -5129,34 +5415,9 @@ static MaybeObject* QuoteJsonString(Isolate* isolate,
5129
5415
  Char* write_cursor = reinterpret_cast<Char*>(
5130
5416
  new_string->address() + SeqAsciiString::kHeaderSize);
5131
5417
  if (comma) *(write_cursor++) = ',';
5132
- *(write_cursor++) = '"';
5133
-
5134
- const Char* read_cursor = characters.start();
5135
- const Char* end = read_cursor + length;
5136
- while (read_cursor < end) {
5137
- Char c = *(read_cursor++);
5138
- if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
5139
- *(write_cursor++) = c;
5140
- } else {
5141
- int len = JsonQuoteLengths[static_cast<unsigned>(c)];
5142
- const char* replacement = JsonQuotes +
5143
- static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
5144
- write_cursor[0] = replacement[0];
5145
- if (len > 1) {
5146
- write_cursor[1] = replacement[1];
5147
- if (len > 2) {
5148
- ASSERT(len == 6);
5149
- write_cursor[2] = replacement[2];
5150
- write_cursor[3] = replacement[3];
5151
- write_cursor[4] = replacement[4];
5152
- write_cursor[5] = replacement[5];
5153
- }
5154
- }
5155
- write_cursor += len;
5156
- }
5157
- }
5158
- *(write_cursor++) = '"';
5159
-
5418
+ write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
5419
+ write_cursor,
5420
+ characters);
5160
5421
  int final_length = static_cast<int>(
5161
5422
  write_cursor - reinterpret_cast<Char*>(
5162
5423
  new_string->address() + SeqAsciiString::kHeaderSize));
@@ -5179,12 +5440,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
5179
5440
  str = String::cast(flat);
5180
5441
  ASSERT(str->IsFlat());
5181
5442
  }
5182
- if (str->IsTwoByteRepresentation()) {
5443
+ String::FlatContent flat = str->GetFlatContent();
5444
+ ASSERT(flat.IsFlat());
5445
+ if (flat.IsTwoByte()) {
5183
5446
  return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate,
5184
- str->ToUC16Vector());
5447
+ flat.ToUC16Vector());
5185
5448
  } else {
5186
5449
  return QuoteJsonString<char, SeqAsciiString, false>(isolate,
5187
- str->ToAsciiVector());
5450
+ flat.ToAsciiVector());
5188
5451
  }
5189
5452
  }
5190
5453
 
@@ -5201,20 +5464,118 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) {
5201
5464
  str = String::cast(flat);
5202
5465
  ASSERT(str->IsFlat());
5203
5466
  }
5204
- if (str->IsTwoByteRepresentation()) {
5467
+ String::FlatContent flat = str->GetFlatContent();
5468
+ if (flat.IsTwoByte()) {
5205
5469
  return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
5206
- str->ToUC16Vector());
5470
+ flat.ToUC16Vector());
5207
5471
  } else {
5208
5472
  return QuoteJsonString<char, SeqAsciiString, true>(isolate,
5209
- str->ToAsciiVector());
5473
+ flat.ToAsciiVector());
5474
+ }
5475
+ }
5476
+
5477
+
5478
+ template <typename Char, typename StringType>
5479
+ static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
5480
+ FixedArray* array,
5481
+ int worst_case_length) {
5482
+ int length = array->length();
5483
+
5484
+ MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
5485
+ worst_case_length);
5486
+ Object* new_object;
5487
+ if (!new_alloc->ToObject(&new_object)) {
5488
+ return new_alloc;
5489
+ }
5490
+ if (!isolate->heap()->new_space()->Contains(new_object)) {
5491
+ // Even if our string is small enough to fit in new space we still have to
5492
+ // handle it being allocated in old space as may happen in the third
5493
+ // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
5494
+ // CEntryStub::GenerateCore.
5495
+ return isolate->heap()->undefined_value();
5496
+ }
5497
+ AssertNoAllocation no_gc;
5498
+ StringType* new_string = StringType::cast(new_object);
5499
+ ASSERT(isolate->heap()->new_space()->Contains(new_string));
5500
+
5501
+ STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
5502
+ Char* write_cursor = reinterpret_cast<Char*>(
5503
+ new_string->address() + SeqAsciiString::kHeaderSize);
5504
+ *(write_cursor++) = '[';
5505
+ for (int i = 0; i < length; i++) {
5506
+ if (i != 0) *(write_cursor++) = ',';
5507
+ String* str = String::cast(array->get(i));
5508
+ String::FlatContent content = str->GetFlatContent();
5509
+ ASSERT(content.IsFlat());
5510
+ if (content.IsTwoByte()) {
5511
+ write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
5512
+ write_cursor,
5513
+ content.ToUC16Vector());
5514
+ } else {
5515
+ write_cursor = WriteQuoteJsonString<Char, char>(isolate,
5516
+ write_cursor,
5517
+ content.ToAsciiVector());
5518
+ }
5519
+ }
5520
+ *(write_cursor++) = ']';
5521
+
5522
+ int final_length = static_cast<int>(
5523
+ write_cursor - reinterpret_cast<Char*>(
5524
+ new_string->address() + SeqAsciiString::kHeaderSize));
5525
+ isolate->heap()->new_space()->
5526
+ template ShrinkStringAtAllocationBoundary<StringType>(
5527
+ new_string, final_length);
5528
+ return new_string;
5529
+ }
5530
+
5531
+
5532
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
5533
+ NoHandleAllocation ha;
5534
+ ASSERT(args.length() == 1);
5535
+ CONVERT_CHECKED(JSArray, array, args[0]);
5536
+
5537
+ if (!array->HasFastElements()) return isolate->heap()->undefined_value();
5538
+ FixedArray* elements = FixedArray::cast(array->elements());
5539
+ int n = elements->length();
5540
+ bool ascii = true;
5541
+ int total_length = 0;
5542
+
5543
+ for (int i = 0; i < n; i++) {
5544
+ Object* elt = elements->get(i);
5545
+ if (!elt->IsString()) return isolate->heap()->undefined_value();
5546
+ String* element = String::cast(elt);
5547
+ if (!element->IsFlat()) return isolate->heap()->undefined_value();
5548
+ total_length += element->length();
5549
+ if (ascii && element->IsTwoByteRepresentation()) {
5550
+ ascii = false;
5551
+ }
5552
+ }
5553
+
5554
+ int worst_case_length =
5555
+ kSpaceForBrackets + n * kSpaceForQuotesAndComma
5556
+ + total_length * kJsonQuoteWorstCaseBlowup;
5557
+
5558
+ if (worst_case_length > kMaxGuaranteedNewSpaceString) {
5559
+ return isolate->heap()->undefined_value();
5560
+ }
5561
+
5562
+ if (ascii) {
5563
+ return QuoteJsonStringArray<char, SeqAsciiString>(isolate,
5564
+ elements,
5565
+ worst_case_length);
5566
+ } else {
5567
+ return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate,
5568
+ elements,
5569
+ worst_case_length);
5210
5570
  }
5211
5571
  }
5212
5572
 
5573
+
5213
5574
  RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
5214
5575
  NoHandleAllocation ha;
5215
5576
 
5216
5577
  CONVERT_CHECKED(String, s, args[0]);
5217
- CONVERT_SMI_CHECKED(radix, args[1]);
5578
+ CONVERT_SMI_ARG_CHECKED(radix, 1);
5218
5579
 
5219
5580
  s->TryFlatten();
5220
5581
 
@@ -5561,6 +5922,27 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
5561
5922
  }
5562
5923
 
5563
5924
 
5925
+ void FindAsciiStringIndices(Vector<const char> subject,
5926
+ char pattern,
5927
+ ZoneList<int>* indices,
5928
+ unsigned int limit) {
5929
+ ASSERT(limit > 0);
5930
+ // Collect indices of pattern in subject using memchr.
5931
+ // Stop after finding at most limit values.
5932
+ const char* subject_start = reinterpret_cast<const char*>(subject.start());
5933
+ const char* subject_end = subject_start + subject.length();
5934
+ const char* pos = subject_start;
5935
+ while (limit > 0) {
5936
+ pos = reinterpret_cast<const char*>(
5937
+ memchr(pos, pattern, subject_end - pos));
5938
+ if (pos == NULL) return;
5939
+ indices->Add(static_cast<int>(pos - subject_start));
5940
+ pos++;
5941
+ limit--;
5942
+ }
5943
+ }
5944
+
5945
+
5564
5946
  template <typename SubjectChar, typename PatternChar>
5565
5947
  void FindStringIndices(Isolate* isolate,
5566
5948
  Vector<const SubjectChar> subject,
@@ -5568,11 +5950,11 @@ void FindStringIndices(Isolate* isolate,
5568
5950
  ZoneList<int>* indices,
5569
5951
  unsigned int limit) {
5570
5952
  ASSERT(limit > 0);
5571
- // Collect indices of pattern in subject, and the end-of-string index.
5953
+ // Collect indices of pattern in subject.
5572
5954
  // Stop after finding at most limit values.
5573
- StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
5574
5955
  int pattern_length = pattern.length();
5575
5956
  int index = 0;
5957
+ StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
5576
5958
  while (limit > 0) {
5577
5959
  index = search.Search(subject, index);
5578
5960
  if (index < 0) return;
@@ -5611,34 +5993,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
5611
5993
 
5612
5994
  // No allocation block.
5613
5995
  {
5614
- AssertNoAllocation nogc;
5615
- if (subject->IsAsciiRepresentation()) {
5616
- Vector<const char> subject_vector = subject->ToAsciiVector();
5617
- if (pattern->IsAsciiRepresentation()) {
5618
- FindStringIndices(isolate,
5619
- subject_vector,
5620
- pattern->ToAsciiVector(),
5621
- &indices,
5622
- limit);
5996
+ AssertNoAllocation no_gc;
5997
+ String::FlatContent subject_content = subject->GetFlatContent();
5998
+ String::FlatContent pattern_content = pattern->GetFlatContent();
5999
+ ASSERT(subject_content.IsFlat());
6000
+ ASSERT(pattern_content.IsFlat());
6001
+ if (subject_content.IsAscii()) {
6002
+ Vector<const char> subject_vector = subject_content.ToAsciiVector();
6003
+ if (pattern_content.IsAscii()) {
6004
+ Vector<const char> pattern_vector = pattern_content.ToAsciiVector();
6005
+ if (pattern_vector.length() == 1) {
6006
+ FindAsciiStringIndices(subject_vector,
6007
+ pattern_vector[0],
6008
+ &indices,
6009
+ limit);
6010
+ } else {
6011
+ FindStringIndices(isolate,
6012
+ subject_vector,
6013
+ pattern_vector,
6014
+ &indices,
6015
+ limit);
6016
+ }
5623
6017
  } else {
5624
6018
  FindStringIndices(isolate,
5625
6019
  subject_vector,
5626
- pattern->ToUC16Vector(),
6020
+ pattern_content.ToUC16Vector(),
5627
6021
  &indices,
5628
6022
  limit);
5629
6023
  }
5630
6024
  } else {
5631
- Vector<const uc16> subject_vector = subject->ToUC16Vector();
6025
+ Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
5632
6026
  if (pattern->IsAsciiRepresentation()) {
5633
6027
  FindStringIndices(isolate,
5634
6028
  subject_vector,
5635
- pattern->ToAsciiVector(),
6029
+ pattern_content.ToAsciiVector(),
5636
6030
  &indices,
5637
6031
  limit);
5638
6032
  } else {
5639
6033
  FindStringIndices(isolate,
5640
6034
  subject_vector,
5641
- pattern->ToUC16Vector(),
6035
+ pattern_content.ToUC16Vector(),
5642
6036
  &indices,
5643
6037
  limit);
5644
6038
  }
@@ -5670,7 +6064,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
5670
6064
  HandleScope local_loop_handle;
5671
6065
  int part_end = indices.at(i);
5672
6066
  Handle<String> substring =
5673
- isolate->factory()->NewSubString(subject, part_start, part_end);
6067
+ isolate->factory()->NewProperSubString(subject, part_start, part_end);
5674
6068
  elements->set(i, *substring);
5675
6069
  part_start = part_end + pattern_length;
5676
6070
  }
@@ -5687,7 +6081,7 @@ static int CopyCachedAsciiCharsToArray(Heap* heap,
5687
6081
  const char* chars,
5688
6082
  FixedArray* elements,
5689
6083
  int length) {
5690
- AssertNoAllocation nogc;
6084
+ AssertNoAllocation no_gc;
5691
6085
  FixedArray* ascii_cache = heap->single_character_string_cache();
5692
6086
  Object* undefined = heap->undefined_value();
5693
6087
  int i;
@@ -5720,36 +6114,39 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
5720
6114
  CONVERT_ARG_CHECKED(String, s, 0);
5721
6115
  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
5722
6116
 
5723
- s->TryFlatten();
6117
+ s = FlattenGetString(s);
5724
6118
  const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
5725
6119
 
5726
6120
  Handle<FixedArray> elements;
6121
+ int position = 0;
5727
6122
  if (s->IsFlat() && s->IsAsciiRepresentation()) {
6123
+ // Try using cached chars where possible.
5728
6124
  Object* obj;
5729
6125
  { MaybeObject* maybe_obj =
5730
6126
  isolate->heap()->AllocateUninitializedFixedArray(length);
5731
6127
  if (!maybe_obj->ToObject(&obj)) return maybe_obj;
5732
6128
  }
5733
6129
  elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
5734
-
5735
- Vector<const char> chars = s->ToAsciiVector();
5736
- // Note, this will initialize all elements (not only the prefix)
5737
- // to prevent GC from seeing partially initialized array.
5738
- int num_copied_from_cache = CopyCachedAsciiCharsToArray(isolate->heap(),
5739
- chars.start(),
5740
- *elements,
5741
- length);
5742
-
5743
- for (int i = num_copied_from_cache; i < length; ++i) {
5744
- Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]);
5745
- elements->set(i, *str);
6130
+ String::FlatContent content = s->GetFlatContent();
6131
+ if (content.IsAscii()) {
6132
+ Vector<const char> chars = content.ToAsciiVector();
6133
+ // Note, this will initialize all elements (not only the prefix)
6134
+ // to prevent GC from seeing partially initialized array.
6135
+ position = CopyCachedAsciiCharsToArray(isolate->heap(),
6136
+ chars.start(),
6137
+ *elements,
6138
+ length);
6139
+ } else {
6140
+ MemsetPointer(elements->data_start(),
6141
+ isolate->heap()->undefined_value(),
6142
+ length);
5746
6143
  }
5747
6144
  } else {
5748
6145
  elements = isolate->factory()->NewFixedArray(length);
5749
- for (int i = 0; i < length; ++i) {
5750
- Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i));
5751
- elements->set(i, *str);
5752
- }
6146
+ }
6147
+ for (int i = position; i < length; ++i) {
6148
+ Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i));
6149
+ elements->set(i, *str);
5753
6150
  }
5754
6151
 
5755
6152
  #ifdef DEBUG
@@ -5803,7 +6200,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
5803
6200
  NoHandleAllocation ha;
5804
6201
  ASSERT(args.length() == 1);
5805
6202
 
5806
- CONVERT_DOUBLE_CHECKED(number, args[0]);
6203
+ CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5807
6204
 
5808
6205
  // We do not include 0 so that we don't have to treat +0 / -0 cases.
5809
6206
  if (number > 0 && number <= Smi::kMaxValue) {
@@ -5817,7 +6214,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
5817
6214
  NoHandleAllocation ha;
5818
6215
  ASSERT(args.length() == 1);
5819
6216
 
5820
- CONVERT_DOUBLE_CHECKED(number, args[0]);
6217
+ CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5821
6218
 
5822
6219
  // We do not include 0 so that we don't have to treat +0 / -0 cases.
5823
6220
  if (number > 0 && number <= Smi::kMaxValue) {
@@ -5845,7 +6242,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
5845
6242
  NoHandleAllocation ha;
5846
6243
  ASSERT(args.length() == 1);
5847
6244
 
5848
- CONVERT_DOUBLE_CHECKED(number, args[0]);
6245
+ CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5849
6246
 
5850
6247
  // We do not include 0 so that we don't have to treat +0 / -0 cases.
5851
6248
  if (number > 0 && number <= Smi::kMaxValue) {
@@ -5887,8 +6284,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
5887
6284
  NoHandleAllocation ha;
5888
6285
  ASSERT(args.length() == 2);
5889
6286
 
5890
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5891
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6287
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6288
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5892
6289
  return isolate->heap()->NumberFromDouble(x + y);
5893
6290
  }
5894
6291
 
@@ -5897,8 +6294,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
5897
6294
  NoHandleAllocation ha;
5898
6295
  ASSERT(args.length() == 2);
5899
6296
 
5900
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5901
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6297
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6298
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5902
6299
  return isolate->heap()->NumberFromDouble(x - y);
5903
6300
  }
5904
6301
 
@@ -5907,8 +6304,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
5907
6304
  NoHandleAllocation ha;
5908
6305
  ASSERT(args.length() == 2);
5909
6306
 
5910
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5911
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6307
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6308
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5912
6309
  return isolate->heap()->NumberFromDouble(x * y);
5913
6310
  }
5914
6311
 
@@ -5917,7 +6314,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
5917
6314
  NoHandleAllocation ha;
5918
6315
  ASSERT(args.length() == 1);
5919
6316
 
5920
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6317
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5921
6318
  return isolate->heap()->NumberFromDouble(-x);
5922
6319
  }
5923
6320
 
@@ -5934,8 +6331,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
5934
6331
  NoHandleAllocation ha;
5935
6332
  ASSERT(args.length() == 2);
5936
6333
 
5937
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5938
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6334
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6335
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5939
6336
  return isolate->heap()->NumberFromDouble(x / y);
5940
6337
  }
5941
6338
 
@@ -5944,8 +6341,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
5944
6341
  NoHandleAllocation ha;
5945
6342
  ASSERT(args.length() == 2);
5946
6343
 
5947
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5948
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6344
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6345
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5949
6346
 
5950
6347
  x = modulo(x, y);
5951
6348
  // NumberFromDouble may return a Smi instead of a Number object
@@ -6010,7 +6407,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
6010
6407
  isolate->context()->mark_out_of_memory();
6011
6408
  return Failure::OutOfMemoryException();
6012
6409
  }
6013
- int array_length = Smi::cast(args[1])->value();
6410
+ int array_length = args.smi_at(1);
6014
6411
  CONVERT_CHECKED(String, special, args[2]);
6015
6412
 
6016
6413
  // This assumption is used by the slice encoding in one or two smis.
@@ -6123,7 +6520,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
6123
6520
  isolate->context()->mark_out_of_memory();
6124
6521
  return Failure::OutOfMemoryException();
6125
6522
  }
6126
- int array_length = Smi::cast(args[1])->value();
6523
+ int array_length = args.smi_at(1);
6127
6524
  CONVERT_CHECKED(String, separator, args[2]);
6128
6525
 
6129
6526
  if (!array->HasFastElements()) {
@@ -6401,8 +6798,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
6401
6798
  NoHandleAllocation ha;
6402
6799
  ASSERT(args.length() == 2);
6403
6800
 
6404
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6405
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6801
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6802
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6406
6803
  if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
6407
6804
  if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
6408
6805
  if (x == y) return Smi::FromInt(EQUAL);
@@ -6438,8 +6835,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
6438
6835
  NoHandleAllocation ha;
6439
6836
  ASSERT(args.length() == 3);
6440
6837
 
6441
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6442
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6838
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6839
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6443
6840
  if (isnan(x) || isnan(y)) return args[2];
6444
6841
  if (x == y) return Smi::FromInt(EQUAL);
6445
6842
  if (isless(x, y)) return Smi::FromInt(LESS);
@@ -6462,50 +6859,69 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
6462
6859
  // If the integers are equal so are the string representations.
6463
6860
  if (x_value == y_value) return Smi::FromInt(EQUAL);
6464
6861
 
6465
- // If one of the integers are zero the normal integer order is the
6862
+ // If one of the integers is zero the normal integer order is the
6466
6863
  // same as the lexicographic order of the string representations.
6467
- if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value);
6864
+ if (x_value == 0 || y_value == 0)
6865
+ return Smi::FromInt(x_value < y_value ? LESS : GREATER);
6468
6866
 
6469
6867
  // If only one of the integers is negative the negative number is
6470
6868
  // smallest because the char code of '-' is less than the char code
6471
6869
  // of any digit. Otherwise, we make both values positive.
6870
+
6871
+ // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
6872
+ // architectures using 32-bit Smis.
6873
+ uint32_t x_scaled = x_value;
6874
+ uint32_t y_scaled = y_value;
6472
6875
  if (x_value < 0 || y_value < 0) {
6473
6876
  if (y_value >= 0) return Smi::FromInt(LESS);
6474
6877
  if (x_value >= 0) return Smi::FromInt(GREATER);
6475
- x_value = -x_value;
6476
- y_value = -y_value;
6878
+ x_scaled = -x_value;
6879
+ y_scaled = -y_value;
6477
6880
  }
6478
6881
 
6479
- // Arrays for the individual characters of the two Smis. Smis are
6480
- // 31 bit integers and 10 decimal digits are therefore enough.
6481
- // TODO(isolates): maybe we should simply allocate 20 bytes on the stack.
6482
- int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms();
6483
- int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms();
6882
+ static const uint32_t kPowersOf10[] = {
6883
+ 1, 10, 100, 1000, 10*1000, 100*1000,
6884
+ 1000*1000, 10*1000*1000, 100*1000*1000,
6885
+ 1000*1000*1000
6886
+ };
6484
6887
 
6888
+ // If the integers have the same number of decimal digits they can be
6889
+ // compared directly as the numeric order is the same as the
6890
+ // lexicographic order. If one integer has fewer digits, it is scaled
6891
+ // by some power of 10 to have the same number of digits as the longer
6892
+ // integer. If the scaled integers are equal it means the shorter
6893
+ // integer comes first in the lexicographic order.
6485
6894
 
6486
- // Convert the integers to arrays of their decimal digits.
6487
- int x_index = 0;
6488
- int y_index = 0;
6489
- while (x_value > 0) {
6490
- x_elms[x_index++] = x_value % 10;
6491
- x_value /= 10;
6492
- }
6493
- while (y_value > 0) {
6494
- y_elms[y_index++] = y_value % 10;
6495
- y_value /= 10;
6496
- }
6895
+ // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
6896
+ int x_log2 = IntegerLog2(x_scaled);
6897
+ int x_log10 = ((x_log2 + 1) * 1233) >> 12;
6898
+ x_log10 -= x_scaled < kPowersOf10[x_log10];
6497
6899
 
6498
- // Loop through the arrays of decimal digits finding the first place
6499
- // where they differ.
6500
- while (--x_index >= 0 && --y_index >= 0) {
6501
- int diff = x_elms[x_index] - y_elms[y_index];
6502
- if (diff != 0) return Smi::FromInt(diff);
6900
+ int y_log2 = IntegerLog2(y_scaled);
6901
+ int y_log10 = ((y_log2 + 1) * 1233) >> 12;
6902
+ y_log10 -= y_scaled < kPowersOf10[y_log10];
6903
+
6904
+ int tie = EQUAL;
6905
+
6906
+ if (x_log10 < y_log10) {
6907
+ // X has fewer digits. We would like to simply scale up X but that
6908
+ // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
6909
+ // be scaled up to 9_000_000_000. So we scale up by the next
6910
+ // smallest power and scale down Y to drop one digit. It is OK to
6911
+ // drop one digit from the longer integer since the final digit is
6912
+ // past the length of the shorter integer.
6913
+ x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
6914
+ y_scaled /= 10;
6915
+ tie = LESS;
6916
+ } else if (y_log10 < x_log10) {
6917
+ y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
6918
+ x_scaled /= 10;
6919
+ tie = GREATER;
6503
6920
  }
6504
6921
 
6505
- // If one array is a suffix of the other array, the longest array is
6506
- // the representation of the largest of the Smis in the
6507
- // lexicographic ordering.
6508
- return Smi::FromInt(x_index - y_index);
6922
+ if (x_scaled < y_scaled) return Smi::FromInt(LESS);
6923
+ if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
6924
+ return Smi::FromInt(tie);
6509
6925
  }
6510
6926
 
6511
6927
 
@@ -6541,22 +6957,24 @@ static Object* FlatStringCompare(String* x, String* y) {
6541
6957
  equal_prefix_result = Smi::FromInt(LESS);
6542
6958
  }
6543
6959
  int r;
6544
- if (x->IsAsciiRepresentation()) {
6545
- Vector<const char> x_chars = x->ToAsciiVector();
6546
- if (y->IsAsciiRepresentation()) {
6547
- Vector<const char> y_chars = y->ToAsciiVector();
6960
+ String::FlatContent x_content = x->GetFlatContent();
6961
+ String::FlatContent y_content = y->GetFlatContent();
6962
+ if (x_content.IsAscii()) {
6963
+ Vector<const char> x_chars = x_content.ToAsciiVector();
6964
+ if (y_content.IsAscii()) {
6965
+ Vector<const char> y_chars = y_content.ToAsciiVector();
6548
6966
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6549
6967
  } else {
6550
- Vector<const uc16> y_chars = y->ToUC16Vector();
6968
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
6551
6969
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6552
6970
  }
6553
6971
  } else {
6554
- Vector<const uc16> x_chars = x->ToUC16Vector();
6555
- if (y->IsAsciiRepresentation()) {
6556
- Vector<const char> y_chars = y->ToAsciiVector();
6972
+ Vector<const uc16> x_chars = x_content.ToUC16Vector();
6973
+ if (y_content.IsAscii()) {
6974
+ Vector<const char> y_chars = y_content.ToAsciiVector();
6557
6975
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6558
6976
  } else {
6559
- Vector<const uc16> y_chars = y->ToUC16Vector();
6977
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
6560
6978
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6561
6979
  }
6562
6980
  }
@@ -6612,7 +7030,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
6612
7030
  ASSERT(args.length() == 1);
6613
7031
  isolate->counters()->math_acos()->Increment();
6614
7032
 
6615
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7033
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6616
7034
  return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
6617
7035
  }
6618
7036
 
@@ -6622,7 +7040,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) {
6622
7040
  ASSERT(args.length() == 1);
6623
7041
  isolate->counters()->math_asin()->Increment();
6624
7042
 
6625
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7043
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6626
7044
  return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
6627
7045
  }
6628
7046
 
@@ -6632,7 +7050,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) {
6632
7050
  ASSERT(args.length() == 1);
6633
7051
  isolate->counters()->math_atan()->Increment();
6634
7052
 
6635
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7053
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6636
7054
  return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
6637
7055
  }
6638
7056
 
@@ -6645,8 +7063,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
6645
7063
  ASSERT(args.length() == 2);
6646
7064
  isolate->counters()->math_atan2()->Increment();
6647
7065
 
6648
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6649
- CONVERT_DOUBLE_CHECKED(y, args[1]);
7066
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7067
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6650
7068
  double result;
6651
7069
  if (isinf(x) && isinf(y)) {
6652
7070
  // Make sure that the result in case of two infinite arguments
@@ -6668,7 +7086,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) {
6668
7086
  ASSERT(args.length() == 1);
6669
7087
  isolate->counters()->math_ceil()->Increment();
6670
7088
 
6671
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7089
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6672
7090
  return isolate->heap()->NumberFromDouble(ceiling(x));
6673
7091
  }
6674
7092
 
@@ -6678,7 +7096,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
6678
7096
  ASSERT(args.length() == 1);
6679
7097
  isolate->counters()->math_cos()->Increment();
6680
7098
 
6681
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7099
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6682
7100
  return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
6683
7101
  }
6684
7102
 
@@ -6688,7 +7106,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
6688
7106
  ASSERT(args.length() == 1);
6689
7107
  isolate->counters()->math_exp()->Increment();
6690
7108
 
6691
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7109
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6692
7110
  return isolate->transcendental_cache()->Get(TranscendentalCache::EXP, x);
6693
7111
  }
6694
7112
 
@@ -6698,7 +7116,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
6698
7116
  ASSERT(args.length() == 1);
6699
7117
  isolate->counters()->math_floor()->Increment();
6700
7118
 
6701
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7119
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6702
7120
  return isolate->heap()->NumberFromDouble(floor(x));
6703
7121
  }
6704
7122
 
@@ -6708,7 +7126,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) {
6708
7126
  ASSERT(args.length() == 1);
6709
7127
  isolate->counters()->math_log()->Increment();
6710
7128
 
6711
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7129
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6712
7130
  return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
6713
7131
  }
6714
7132
 
@@ -6718,16 +7136,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
6718
7136
  ASSERT(args.length() == 2);
6719
7137
  isolate->counters()->math_pow()->Increment();
6720
7138
 
6721
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7139
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6722
7140
 
6723
7141
  // If the second argument is a smi, it is much faster to call the
6724
7142
  // custom powi() function than the generic pow().
6725
7143
  if (args[1]->IsSmi()) {
6726
- int y = Smi::cast(args[1])->value();
7144
+ int y = args.smi_at(1);
6727
7145
  return isolate->heap()->NumberFromDouble(power_double_int(x, y));
6728
7146
  }
6729
7147
 
6730
- CONVERT_DOUBLE_CHECKED(y, args[1]);
7148
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6731
7149
  return isolate->heap()->AllocateHeapNumber(power_double_double(x, y));
6732
7150
  }
6733
7151
 
@@ -6736,8 +7154,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
6736
7154
  RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
6737
7155
  NoHandleAllocation ha;
6738
7156
  ASSERT(args.length() == 2);
6739
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6740
- CONVERT_DOUBLE_CHECKED(y, args[1]);
7157
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7158
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6741
7159
  if (y == 0) {
6742
7160
  return Smi::FromInt(1);
6743
7161
  } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
@@ -6796,7 +7214,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
6796
7214
  ASSERT(args.length() == 1);
6797
7215
  isolate->counters()->math_sin()->Increment();
6798
7216
 
6799
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7217
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6800
7218
  return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
6801
7219
  }
6802
7220
 
@@ -6806,7 +7224,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
6806
7224
  ASSERT(args.length() == 1);
6807
7225
  isolate->counters()->math_sqrt()->Increment();
6808
7226
 
6809
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7227
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6810
7228
  return isolate->heap()->AllocateHeapNumber(sqrt(x));
6811
7229
  }
6812
7230
 
@@ -6816,7 +7234,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
6816
7234
  ASSERT(args.length() == 1);
6817
7235
  isolate->counters()->math_tan()->Increment();
6818
7236
 
6819
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7237
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6820
7238
  return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
6821
7239
  }
6822
7240
 
@@ -6870,9 +7288,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
6870
7288
  NoHandleAllocation ha;
6871
7289
  ASSERT(args.length() == 3);
6872
7290
 
6873
- CONVERT_SMI_CHECKED(year, args[0]);
6874
- CONVERT_SMI_CHECKED(month, args[1]);
6875
- CONVERT_SMI_CHECKED(date, args[2]);
7291
+ CONVERT_SMI_ARG_CHECKED(year, 0);
7292
+ CONVERT_SMI_ARG_CHECKED(month, 1);
7293
+ CONVERT_SMI_ARG_CHECKED(date, 2);
6876
7294
 
6877
7295
  return Smi::FromInt(MakeDay(year, month, date));
6878
7296
  }
@@ -7169,7 +7587,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) {
7169
7587
  NoHandleAllocation ha;
7170
7588
  ASSERT(args.length() == 2);
7171
7589
 
7172
- CONVERT_DOUBLE_CHECKED(t, args[0]);
7590
+ CONVERT_DOUBLE_ARG_CHECKED(t, 0);
7173
7591
  CONVERT_CHECKED(JSArray, res_array, args[1]);
7174
7592
 
7175
7593
  int year, month, day;
@@ -7189,12 +7607,109 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) {
7189
7607
 
7190
7608
 
7191
7609
  RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
7610
+ HandleScope scope(isolate);
7611
+ ASSERT(args.length() == 3);
7612
+
7613
+ Handle<JSFunction> callee = args.at<JSFunction>(0);
7614
+ Object** parameters = reinterpret_cast<Object**>(args[1]);
7615
+ const int argument_count = Smi::cast(args[2])->value();
7616
+
7617
+ Handle<JSObject> result =
7618
+ isolate->factory()->NewArgumentsObject(callee, argument_count);
7619
+ // Allocate the elements if needed.
7620
+ int parameter_count = callee->shared()->formal_parameter_count();
7621
+ if (argument_count > 0) {
7622
+ if (parameter_count > 0) {
7623
+ int mapped_count = Min(argument_count, parameter_count);
7624
+ Handle<FixedArray> parameter_map =
7625
+ isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
7626
+ parameter_map->set_map(
7627
+ isolate->heap()->non_strict_arguments_elements_map());
7628
+
7629
+ Handle<Map> old_map(result->map());
7630
+ Handle<Map> new_map =
7631
+ isolate->factory()->CopyMapDropTransitions(old_map);
7632
+ new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
7633
+
7634
+ result->set_map(*new_map);
7635
+ result->set_elements(*parameter_map);
7636
+
7637
+ // Store the context and the arguments array at the beginning of the
7638
+ // parameter map.
7639
+ Handle<Context> context(isolate->context());
7640
+ Handle<FixedArray> arguments =
7641
+ isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
7642
+ parameter_map->set(0, *context);
7643
+ parameter_map->set(1, *arguments);
7644
+
7645
+ // Loop over the actual parameters backwards.
7646
+ int index = argument_count - 1;
7647
+ while (index >= mapped_count) {
7648
+ // These go directly in the arguments array and have no
7649
+ // corresponding slot in the parameter map.
7650
+ arguments->set(index, *(parameters - index - 1));
7651
+ --index;
7652
+ }
7653
+
7654
+ ScopeInfo<> scope_info(callee->shared()->scope_info());
7655
+ while (index >= 0) {
7656
+ // Detect duplicate names to the right in the parameter list.
7657
+ Handle<String> name = scope_info.parameter_name(index);
7658
+ int context_slot_count = scope_info.number_of_context_slots();
7659
+ bool duplicate = false;
7660
+ for (int j = index + 1; j < parameter_count; ++j) {
7661
+ if (scope_info.parameter_name(j).is_identical_to(name)) {
7662
+ duplicate = true;
7663
+ break;
7664
+ }
7665
+ }
7666
+
7667
+ if (duplicate) {
7668
+ // This goes directly in the arguments array with a hole in the
7669
+ // parameter map.
7670
+ arguments->set(index, *(parameters - index - 1));
7671
+ parameter_map->set_the_hole(index + 2);
7672
+ } else {
7673
+ // The context index goes in the parameter map with a hole in the
7674
+ // arguments array.
7675
+ int context_index = -1;
7676
+ for (int j = Context::MIN_CONTEXT_SLOTS;
7677
+ j < context_slot_count;
7678
+ ++j) {
7679
+ if (scope_info.context_slot_name(j).is_identical_to(name)) {
7680
+ context_index = j;
7681
+ break;
7682
+ }
7683
+ }
7684
+ ASSERT(context_index >= 0);
7685
+ arguments->set_the_hole(index);
7686
+ parameter_map->set(index + 2, Smi::FromInt(context_index));
7687
+ }
7688
+
7689
+ --index;
7690
+ }
7691
+ } else {
7692
+ // If there is no aliasing, the arguments object elements are not
7693
+ // special in any way.
7694
+ Handle<FixedArray> elements =
7695
+ isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
7696
+ result->set_elements(*elements);
7697
+ for (int i = 0; i < argument_count; ++i) {
7698
+ elements->set(i, *(parameters - i - 1));
7699
+ }
7700
+ }
7701
+ }
7702
+ return *result;
7703
+ }
7704
+
7705
+
7706
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
7192
7707
  NoHandleAllocation ha;
7193
7708
  ASSERT(args.length() == 3);
7194
7709
 
7195
7710
  JSFunction* callee = JSFunction::cast(args[0]);
7196
7711
  Object** parameters = reinterpret_cast<Object**>(args[1]);
7197
- const int length = Smi::cast(args[2])->value();
7712
+ const int length = args.smi_at(2);
7198
7713
 
7199
7714
  Object* result;
7200
7715
  { MaybeObject* maybe_result =
@@ -7231,10 +7746,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
7231
7746
  CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
7232
7747
  CONVERT_BOOLEAN_CHECKED(pretenure, args[2]);
7233
7748
 
7234
- // Allocate global closures in old space and allocate local closures
7235
- // in new space. Additionally pretenure closures that are assigned
7749
+ // The caller ensures that we pretenure closures that are assigned
7236
7750
  // directly to properties.
7237
- pretenure = pretenure || (context->global_context() == *context);
7238
7751
  PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
7239
7752
  Handle<JSFunction> result =
7240
7753
  isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
@@ -7354,7 +7867,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
7354
7867
 
7355
7868
  // If function should not have prototype, construction is not allowed. In this
7356
7869
  // case generated code bailouts here, since function has no initial_map.
7357
- if (!function->should_have_prototype()) {
7870
+ if (!function->should_have_prototype() && !function->shared()->bound()) {
7358
7871
  Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
7359
7872
  Handle<Object> type_error =
7360
7873
  isolate->factory()->NewTypeError("not_constructor", arguments);
@@ -7495,7 +8008,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
7495
8008
  ASSERT(args.length() == 1);
7496
8009
  RUNTIME_ASSERT(args[0]->IsSmi());
7497
8010
  Deoptimizer::BailoutType type =
7498
- static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value());
8011
+ static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
7499
8012
  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
7500
8013
  ASSERT(isolate->heap()->IsAllocationAllowed());
7501
8014
  int frames = deoptimizer->output_count();
@@ -7526,7 +8039,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
7526
8039
  }
7527
8040
  }
7528
8041
 
7529
- isolate->compilation_cache()->MarkForLazyOptimizing(function);
7530
8042
  if (type == Deoptimizer::EAGER) {
7531
8043
  RUNTIME_ASSERT(function->IsOptimized());
7532
8044
  } else {
@@ -7582,6 +8094,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
7582
8094
  }
7583
8095
 
7584
8096
 
8097
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
8098
+ #if defined(USE_SIMULATOR)
8099
+ return isolate->heap()->true_value();
8100
+ #else
8101
+ return isolate->heap()->false_value();
8102
+ #endif
8103
+ }
8104
+
8105
+
7585
8106
  RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
7586
8107
  HandleScope scope(isolate);
7587
8108
  ASSERT(args.length() == 1);
@@ -7621,7 +8142,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
7621
8142
  CONVERT_ARG_CHECKED(JSFunction, function, 0);
7622
8143
 
7623
8144
  // We're not prepared to handle a function with arguments object.
7624
- ASSERT(!function->shared()->scope_info()->HasArgumentsShadow());
8145
+ ASSERT(!function->shared()->uses_arguments());
7625
8146
 
7626
8147
  // We have hit a back edge in an unoptimized frame for a function that was
7627
8148
  // selected for on-stack replacement. Find the unoptimized code object.
@@ -7745,7 +8266,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
7745
8266
  }
7746
8267
 
7747
8268
 
7748
- RUNTIME_FUNCTION(MaybeObject*, Runtime_NewContext) {
8269
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
7749
8270
  NoHandleAllocation ha;
7750
8271
  ASSERT(args.length() == 1);
7751
8272
 
@@ -7763,50 +8284,97 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewContext) {
7763
8284
  }
7764
8285
 
7765
8286
 
7766
- MUST_USE_RESULT static MaybeObject* PushContextHelper(Isolate* isolate,
7767
- Object* object,
7768
- bool is_catch_context) {
7769
- // Convert the object to a proper JavaScript object.
7770
- Object* js_object = object;
7771
- if (!js_object->IsJSObject()) {
7772
- MaybeObject* maybe_js_object = js_object->ToObject();
7773
- if (!maybe_js_object->ToObject(&js_object)) {
7774
- if (!Failure::cast(maybe_js_object)->IsInternalError()) {
8287
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
8288
+ NoHandleAllocation ha;
8289
+ ASSERT(args.length() == 2);
8290
+ JSObject* extension_object;
8291
+ if (args[0]->IsJSObject()) {
8292
+ extension_object = JSObject::cast(args[0]);
8293
+ } else {
8294
+ // Convert the object to a proper JavaScript object.
8295
+ MaybeObject* maybe_js_object = args[0]->ToObject();
8296
+ if (!maybe_js_object->To(&extension_object)) {
8297
+ if (Failure::cast(maybe_js_object)->IsInternalError()) {
8298
+ HandleScope scope(isolate);
8299
+ Handle<Object> handle = args.at<Object>(0);
8300
+ Handle<Object> result =
8301
+ isolate->factory()->NewTypeError("with_expression",
8302
+ HandleVector(&handle, 1));
8303
+ return isolate->Throw(*result);
8304
+ } else {
7775
8305
  return maybe_js_object;
7776
8306
  }
7777
- HandleScope scope(isolate);
7778
- Handle<Object> handle(object, isolate);
7779
- Handle<Object> result =
7780
- isolate->factory()->NewTypeError("with_expression",
7781
- HandleVector(&handle, 1));
7782
- return isolate->Throw(*result);
7783
8307
  }
7784
8308
  }
7785
8309
 
7786
- Object* result;
7787
- { MaybeObject* maybe_result = isolate->heap()->AllocateWithContext(
7788
- isolate->context(), JSObject::cast(js_object), is_catch_context);
7789
- if (!maybe_result->ToObject(&result)) return maybe_result;
8310
+ JSFunction* function;
8311
+ if (args[1]->IsSmi()) {
8312
+ // A smi sentinel indicates a context nested inside global code rather
8313
+ // than some function. There is a canonical empty function that can be
8314
+ // gotten from the global context.
8315
+ function = isolate->context()->global_context()->closure();
8316
+ } else {
8317
+ function = JSFunction::cast(args[1]);
7790
8318
  }
7791
8319
 
7792
- Context* context = Context::cast(result);
8320
+ Context* context;
8321
+ MaybeObject* maybe_context =
8322
+ isolate->heap()->AllocateWithContext(function,
8323
+ isolate->context(),
8324
+ extension_object);
8325
+ if (!maybe_context->To(&context)) return maybe_context;
7793
8326
  isolate->set_context(context);
7794
-
7795
- return result;
8327
+ return context;
7796
8328
  }
7797
8329
 
7798
8330
 
7799
- RUNTIME_FUNCTION(MaybeObject*, Runtime_PushContext) {
8331
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
7800
8332
  NoHandleAllocation ha;
7801
- ASSERT(args.length() == 1);
7802
- return PushContextHelper(isolate, args[0], false);
8333
+ ASSERT(args.length() == 3);
8334
+ String* name = String::cast(args[0]);
8335
+ Object* thrown_object = args[1];
8336
+ JSFunction* function;
8337
+ if (args[2]->IsSmi()) {
8338
+ // A smi sentinel indicates a context nested inside global code rather
8339
+ // than some function. There is a canonical empty function that can be
8340
+ // gotten from the global context.
8341
+ function = isolate->context()->global_context()->closure();
8342
+ } else {
8343
+ function = JSFunction::cast(args[2]);
8344
+ }
8345
+ Context* context;
8346
+ MaybeObject* maybe_context =
8347
+ isolate->heap()->AllocateCatchContext(function,
8348
+ isolate->context(),
8349
+ name,
8350
+ thrown_object);
8351
+ if (!maybe_context->To(&context)) return maybe_context;
8352
+ isolate->set_context(context);
8353
+ return context;
7803
8354
  }
7804
8355
 
7805
8356
 
7806
- RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
8357
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
7807
8358
  NoHandleAllocation ha;
7808
- ASSERT(args.length() == 1);
7809
- return PushContextHelper(isolate, args[0], true);
8359
+ ASSERT(args.length() == 2);
8360
+ SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]);
8361
+ JSFunction* function;
8362
+ if (args[1]->IsSmi()) {
8363
+ // A smi sentinel indicates a context nested inside global code rather
8364
+ // than some function. There is a canonical empty function that can be
8365
+ // gotten from the global context.
8366
+ function = isolate->context()->global_context()->closure();
8367
+ } else {
8368
+ function = JSFunction::cast(args[1]);
8369
+ }
8370
+ Context* context;
8371
+ MaybeObject* maybe_context =
8372
+ isolate->heap()->AllocateBlockContext(function,
8373
+ isolate->context(),
8374
+ scope_info);
8375
+ if (!maybe_context->To(&context)) return maybe_context;
8376
+ isolate->set_context(context);
8377
+ return context;
7810
8378
  }
7811
8379
 
7812
8380
 
@@ -7820,7 +8388,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
7820
8388
  int index;
7821
8389
  PropertyAttributes attributes;
7822
8390
  ContextLookupFlags flags = FOLLOW_CHAINS;
7823
- Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
8391
+ BindingFlags binding_flags;
8392
+ Handle<Object> holder = context->Lookup(name,
8393
+ flags,
8394
+ &index,
8395
+ &attributes,
8396
+ &binding_flags);
7824
8397
 
7825
8398
  // If the slot was not found the result is true.
7826
8399
  if (holder.is_null()) {
@@ -7841,9 +8414,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
7841
8414
  // index is non-negative.
7842
8415
  Handle<JSObject> object = Handle<JSObject>::cast(holder);
7843
8416
  if (index >= 0) {
7844
- return object->DeleteElement(index, JSObject::NORMAL_DELETION);
8417
+ return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
7845
8418
  } else {
7846
- return object->DeleteProperty(*name, JSObject::NORMAL_DELETION);
8419
+ return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
7847
8420
  }
7848
8421
  }
7849
8422
 
@@ -7922,7 +8495,12 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
7922
8495
  int index;
7923
8496
  PropertyAttributes attributes;
7924
8497
  ContextLookupFlags flags = FOLLOW_CHAINS;
7925
- Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
8498
+ BindingFlags binding_flags;
8499
+ Handle<Object> holder = context->Lookup(name,
8500
+ flags,
8501
+ &index,
8502
+ &attributes,
8503
+ &binding_flags);
7926
8504
 
7927
8505
  // If the index is non-negative, the slot has been found in a local
7928
8506
  // variable or a parameter. Read it from the context object or the
@@ -7938,7 +8516,17 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
7938
8516
  MaybeObject* value = (holder->IsContext())
7939
8517
  ? Context::cast(*holder)->get(index)
7940
8518
  : JSObject::cast(*holder)->GetElement(index);
7941
- return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
8519
+ // Check for uninitialized bindings.
8520
+ if (holder->IsContext() &&
8521
+ binding_flags == MUTABLE_CHECK_INITIALIZED &&
8522
+ value->IsTheHole()) {
8523
+ Handle<Object> reference_error =
8524
+ isolate->factory()->NewReferenceError("not_defined",
8525
+ HandleVector(&name, 1));
8526
+ return MakePair(isolate->Throw(*reference_error), NULL);
8527
+ } else {
8528
+ return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
8529
+ }
7942
8530
  }
7943
8531
 
7944
8532
  // If the holder is found, we read the property from it.
@@ -7996,7 +8584,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
7996
8584
  Handle<Object> value(args[0], isolate);
7997
8585
  CONVERT_ARG_CHECKED(Context, context, 1);
7998
8586
  CONVERT_ARG_CHECKED(String, name, 2);
7999
- CONVERT_SMI_CHECKED(strict_unchecked, args[3]);
8587
+ CONVERT_SMI_ARG_CHECKED(strict_unchecked, 3);
8000
8588
  RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
8001
8589
  strict_unchecked == kNonStrictMode);
8002
8590
  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
@@ -8004,14 +8592,27 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
8004
8592
  int index;
8005
8593
  PropertyAttributes attributes;
8006
8594
  ContextLookupFlags flags = FOLLOW_CHAINS;
8007
- Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
8595
+ BindingFlags binding_flags;
8596
+ Handle<Object> holder = context->Lookup(name,
8597
+ flags,
8598
+ &index,
8599
+ &attributes,
8600
+ &binding_flags);
8008
8601
 
8009
8602
  if (index >= 0) {
8010
8603
  if (holder->IsContext()) {
8604
+ Handle<Context> context = Handle<Context>::cast(holder);
8605
+ if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
8606
+ context->get(index)->IsTheHole()) {
8607
+ Handle<Object> error =
8608
+ isolate->factory()->NewReferenceError("not_defined",
8609
+ HandleVector(&name, 1));
8610
+ return isolate->Throw(*error);
8611
+ }
8011
8612
  // Ignore if read_only variable.
8012
8613
  if ((attributes & READ_ONLY) == 0) {
8013
8614
  // Context is a fixed array and set cannot fail.
8014
- Context::cast(*holder)->set(index, *value);
8615
+ context->set(index, *value);
8015
8616
  } else if (strict_mode == kStrictMode) {
8016
8617
  // Setting read only property in strict mode.
8017
8618
  Handle<Object> error =
@@ -8287,13 +8888,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
8287
8888
  FixedArray* output_array = FixedArray::cast(output->elements());
8288
8889
  RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
8289
8890
  bool result;
8290
- if (str->IsAsciiRepresentation()) {
8291
- result = DateParser::Parse(str->ToAsciiVector(),
8891
+ String::FlatContent str_content = str->GetFlatContent();
8892
+ if (str_content.IsAscii()) {
8893
+ result = DateParser::Parse(str_content.ToAsciiVector(),
8292
8894
  output_array,
8293
8895
  isolate->unicode_cache());
8294
8896
  } else {
8295
- ASSERT(str->IsTwoByteRepresentation());
8296
- result = DateParser::Parse(str->ToUC16Vector(),
8897
+ ASSERT(str_content.IsTwoByte());
8898
+ result = DateParser::Parse(str_content.ToUC16Vector(),
8297
8899
  output_array,
8298
8900
  isolate->unicode_cache());
8299
8901
  }
@@ -8310,7 +8912,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
8310
8912
  NoHandleAllocation ha;
8311
8913
  ASSERT(args.length() == 1);
8312
8914
 
8313
- CONVERT_DOUBLE_CHECKED(x, args[0]);
8915
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8314
8916
  const char* zone = OS::LocalTimezone(x);
8315
8917
  return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
8316
8918
  }
@@ -8328,7 +8930,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateDaylightSavingsOffset) {
8328
8930
  NoHandleAllocation ha;
8329
8931
  ASSERT(args.length() == 1);
8330
8932
 
8331
- CONVERT_DOUBLE_CHECKED(x, args[0]);
8933
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8332
8934
  return isolate->heap()->NumberFromDouble(OS::DaylightSavingsOffset(x));
8333
8935
  }
8334
8936
 
@@ -8346,7 +8948,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
8346
8948
  ASSERT_EQ(1, args.length());
8347
8949
  CONVERT_ARG_CHECKED(String, source, 0);
8348
8950
 
8349
- Handle<Object> result = JsonParser::Parse(source);
8951
+ source = Handle<String>(source->TryFlattenGetString());
8952
+ // Optimized fast case where we only have ascii characters.
8953
+ Handle<Object> result;
8954
+ if (source->IsSeqAsciiString()) {
8955
+ result = JsonParser<true>::Parse(source);
8956
+ } else {
8957
+ result = JsonParser<false>::Parse(source);
8958
+ }
8350
8959
  if (result.is_null()) {
8351
8960
  // Syntax error or stack overflow in scanner.
8352
8961
  ASSERT(isolate->has_pending_exception());
@@ -8455,19 +9064,17 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
8455
9064
  // it is bound in the global context.
8456
9065
  int index = -1;
8457
9066
  PropertyAttributes attributes = ABSENT;
9067
+ BindingFlags binding_flags;
8458
9068
  while (true) {
8459
9069
  receiver = context->Lookup(isolate->factory()->eval_symbol(),
8460
9070
  FOLLOW_PROTOTYPE_CHAIN,
8461
- &index, &attributes);
9071
+ &index,
9072
+ &attributes,
9073
+ &binding_flags);
8462
9074
  // Stop search when eval is found or when the global context is
8463
9075
  // reached.
8464
9076
  if (attributes != ABSENT || context->IsGlobalContext()) break;
8465
- if (context->is_function_context()) {
8466
- context = Handle<Context>(Context::cast(context->closure()->context()),
8467
- isolate);
8468
- } else {
8469
- context = Handle<Context>(context->previous(), isolate);
8470
- }
9077
+ context = Handle<Context>(context->previous(), isolate);
8471
9078
  }
8472
9079
 
8473
9080
  // If eval could not be resolved, it has been deleted and we need to
@@ -8500,8 +9107,7 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
8500
9107
  return CompileGlobalEval(isolate,
8501
9108
  args.at<String>(1),
8502
9109
  args.at<Object>(2),
8503
- static_cast<StrictModeFlag>(
8504
- Smi::cast(args[3])->value()));
9110
+ static_cast<StrictModeFlag>(args.smi_at(3)));
8505
9111
  }
8506
9112
 
8507
9113
 
@@ -8522,8 +9128,7 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
8522
9128
  return CompileGlobalEval(isolate,
8523
9129
  args.at<String>(1),
8524
9130
  args.at<Object>(2),
8525
- static_cast<StrictModeFlag>(
8526
- Smi::cast(args[3])->value()));
9131
+ static_cast<StrictModeFlag>(args.smi_at(3)));
8527
9132
  }
8528
9133
 
8529
9134
 
@@ -8584,8 +9189,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
8584
9189
  }
8585
9190
  Object* obj;
8586
9191
  // Strict not needed. Used for cycle detection in Array join implementation.
8587
- { MaybeObject* maybe_obj = array->SetFastElement(length, element,
8588
- kNonStrictMode);
9192
+ { MaybeObject* maybe_obj =
9193
+ array->SetFastElement(length, element, kNonStrictMode, true);
8589
9194
  if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8590
9195
  }
8591
9196
  return isolate->heap()->true_value();
@@ -8765,13 +9370,13 @@ static void IterateExternalArrayElements(Isolate* isolate,
8765
9370
  if (elements_are_guaranteed_smis) {
8766
9371
  for (uint32_t j = 0; j < len; j++) {
8767
9372
  HandleScope loop_scope;
8768
- Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j))));
9373
+ Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))));
8769
9374
  visitor->visit(j, e);
8770
9375
  }
8771
9376
  } else {
8772
9377
  for (uint32_t j = 0; j < len; j++) {
8773
9378
  HandleScope loop_scope;
8774
- int64_t val = static_cast<int64_t>(array->get(j));
9379
+ int64_t val = static_cast<int64_t>(array->get_scalar(j));
8775
9380
  if (Smi::IsValid(static_cast<intptr_t>(val))) {
8776
9381
  Handle<Smi> e(Smi::FromInt(static_cast<int>(val)));
8777
9382
  visitor->visit(j, e);
@@ -8785,7 +9390,7 @@ static void IterateExternalArrayElements(Isolate* isolate,
8785
9390
  } else {
8786
9391
  for (uint32_t j = 0; j < len; j++) {
8787
9392
  HandleScope loop_scope(isolate);
8788
- Handle<Object> e = isolate->factory()->NewNumber(array->get(j));
9393
+ Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
8789
9394
  visitor->visit(j, e);
8790
9395
  }
8791
9396
  }
@@ -8971,7 +9576,7 @@ static bool IterateElements(Isolate* isolate,
8971
9576
  Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast(
8972
9577
  receiver->elements()));
8973
9578
  for (uint32_t j = 0; j < length; j++) {
8974
- Handle<Smi> e(Smi::FromInt(pixels->get(j)));
9579
+ Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)));
8975
9580
  visitor->visit(j, e);
8976
9581
  }
8977
9582
  break;
@@ -9150,11 +9755,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
9150
9755
  ASSERT(args.length() == 2);
9151
9756
  CONVERT_CHECKED(JSArray, from, args[0]);
9152
9757
  CONVERT_CHECKED(JSArray, to, args[1]);
9153
- HeapObject* new_elements = from->elements();
9758
+ FixedArrayBase* new_elements = from->elements();
9154
9759
  MaybeObject* maybe_new_map;
9155
9760
  if (new_elements->map() == isolate->heap()->fixed_array_map() ||
9156
9761
  new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
9157
9762
  maybe_new_map = to->map()->GetFastElementsMap();
9763
+ } else if (new_elements->map() ==
9764
+ isolate->heap()->fixed_double_array_map()) {
9765
+ maybe_new_map = to->map()->GetFastDoubleElementsMap();
9158
9766
  } else {
9159
9767
  maybe_new_map = to->map()->GetSlowElementsMap();
9160
9768
  }
@@ -9242,12 +9850,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
9242
9850
  }
9243
9851
  return *isolate->factory()->NewJSArrayWithElements(keys);
9244
9852
  } else {
9245
- ASSERT(array->HasFastElements());
9853
+ ASSERT(array->HasFastElements() || array->HasFastDoubleElements());
9246
9854
  Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
9247
9855
  // -1 means start of array.
9248
9856
  single_interval->set(0, Smi::FromInt(-1));
9857
+ FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
9249
9858
  uint32_t actual_length =
9250
- static_cast<uint32_t>(FixedArray::cast(array->elements())->length());
9859
+ static_cast<uint32_t>(elements->length());
9251
9860
  uint32_t min_length = actual_length < length ? actual_length : length;
9252
9861
  Handle<Object> length_object =
9253
9862
  isolate->factory()->NewNumber(static_cast<double>(min_length));
@@ -9485,9 +10094,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
9485
10094
  details->set(0, *value);
9486
10095
  details->set(1, property_details);
9487
10096
  if (hasJavaScriptAccessors) {
9488
- details->set(2,
9489
- caught_exception ? isolate->heap()->true_value()
9490
- : isolate->heap()->false_value());
10097
+ details->set(2, isolate->heap()->ToBoolean(caught_exception));
9491
10098
  details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
9492
10099
  details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
9493
10100
  }
@@ -9611,11 +10218,79 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
9611
10218
  // If there is no JavaScript stack frame count is 0.
9612
10219
  return Smi::FromInt(0);
9613
10220
  }
9614
- for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) n++;
10221
+
10222
+ for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
10223
+ n += it.frame()->GetInlineCount();
10224
+ }
9615
10225
  return Smi::FromInt(n);
9616
10226
  }
9617
10227
 
9618
10228
 
10229
+ class FrameInspector {
10230
+ public:
10231
+ FrameInspector(JavaScriptFrame* frame,
10232
+ int inlined_frame_index,
10233
+ Isolate* isolate)
10234
+ : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
10235
+ // Calculate the deoptimized frame.
10236
+ if (frame->is_optimized()) {
10237
+ deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
10238
+ frame, inlined_frame_index, isolate);
10239
+ }
10240
+ has_adapted_arguments_ = frame_->has_adapted_arguments();
10241
+ is_optimized_ = frame_->is_optimized();
10242
+ }
10243
+
10244
+ ~FrameInspector() {
10245
+ // Get rid of the calculated deoptimized frame if any.
10246
+ if (deoptimized_frame_ != NULL) {
10247
+ Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
10248
+ isolate_);
10249
+ }
10250
+ }
10251
+
10252
+ int GetParametersCount() {
10253
+ return is_optimized_
10254
+ ? deoptimized_frame_->parameters_count()
10255
+ : frame_->ComputeParametersCount();
10256
+ }
10257
+ int expression_count() { return deoptimized_frame_->expression_count(); }
10258
+ Object* GetFunction() {
10259
+ return is_optimized_
10260
+ ? deoptimized_frame_->GetFunction()
10261
+ : frame_->function();
10262
+ }
10263
+ Object* GetParameter(int index) {
10264
+ return is_optimized_
10265
+ ? deoptimized_frame_->GetParameter(index)
10266
+ : frame_->GetParameter(index);
10267
+ }
10268
+ Object* GetExpression(int index) {
10269
+ return is_optimized_
10270
+ ? deoptimized_frame_->GetExpression(index)
10271
+ : frame_->GetExpression(index);
10272
+ }
10273
+
10274
+ // To inspect all the provided arguments the frame might need to be
10275
+ // replaced with the arguments frame.
10276
+ void SetArgumentsFrame(JavaScriptFrame* frame) {
10277
+ ASSERT(has_adapted_arguments_);
10278
+ frame_ = frame;
10279
+ is_optimized_ = frame_->is_optimized();
10280
+ ASSERT(!is_optimized_);
10281
+ }
10282
+
10283
+ private:
10284
+ JavaScriptFrame* frame_;
10285
+ DeoptimizedFrameInfo* deoptimized_frame_;
10286
+ Isolate* isolate_;
10287
+ bool is_optimized_;
10288
+ bool has_adapted_arguments_;
10289
+
10290
+ DISALLOW_COPY_AND_ASSIGN(FrameInspector);
10291
+ };
10292
+
10293
+
9619
10294
  static const int kFrameDetailsFrameIdIndex = 0;
9620
10295
  static const int kFrameDetailsReceiverIndex = 1;
9621
10296
  static const int kFrameDetailsFunctionIndex = 2;
@@ -9624,7 +10299,7 @@ static const int kFrameDetailsLocalCountIndex = 4;
9624
10299
  static const int kFrameDetailsSourcePositionIndex = 5;
9625
10300
  static const int kFrameDetailsConstructCallIndex = 6;
9626
10301
  static const int kFrameDetailsAtReturnIndex = 7;
9627
- static const int kFrameDetailsDebuggerFrameIndex = 8;
10302
+ static const int kFrameDetailsFlagsIndex = 8;
9628
10303
  static const int kFrameDetailsFirstDynamicIndex = 9;
9629
10304
 
9630
10305
  // Return an array with frame details
@@ -9640,7 +10315,7 @@ static const int kFrameDetailsFirstDynamicIndex = 9;
9640
10315
  // 5: Source position
9641
10316
  // 6: Constructor call
9642
10317
  // 7: Is at return
9643
- // 8: Debugger frame
10318
+ // 8: Flags
9644
10319
  // Arguments name, value
9645
10320
  // Locals name, value
9646
10321
  // Return value if any
@@ -9663,16 +10338,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9663
10338
  // If there are no JavaScript stack frames return undefined.
9664
10339
  return heap->undefined_value();
9665
10340
  }
10341
+
10342
+ int inlined_frame_index = 0; // Inlined frame index in optimized frame.
10343
+
9666
10344
  int count = 0;
9667
10345
  JavaScriptFrameIterator it(isolate, id);
9668
10346
  for (; !it.done(); it.Advance()) {
9669
- if (count == index) break;
9670
- count++;
10347
+ if (index < count + it.frame()->GetInlineCount()) break;
10348
+ count += it.frame()->GetInlineCount();
9671
10349
  }
9672
10350
  if (it.done()) return heap->undefined_value();
9673
10351
 
9674
- bool is_optimized_frame =
9675
- it.frame()->LookupCode()->kind() == Code::OPTIMIZED_FUNCTION;
10352
+ if (it.frame()->is_optimized()) {
10353
+ inlined_frame_index =
10354
+ it.frame()->GetInlineCount() - (index - count) - 1;
10355
+ }
10356
+ FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate);
9676
10357
 
9677
10358
  // Traverse the saved contexts chain to find the active context for the
9678
10359
  // selected frame.
@@ -9689,17 +10370,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9689
10370
  int position =
9690
10371
  it.frame()->LookupCode()->SourcePosition(it.frame()->pc());
9691
10372
 
9692
- // Check for constructor frame.
9693
- bool constructor = it.frame()->IsConstructor();
10373
+ // Check for constructor frame. Inlined frames cannot be construct calls.
10374
+ bool inlined_frame =
10375
+ it.frame()->is_optimized() && inlined_frame_index != 0;
10376
+ bool constructor = !inlined_frame && it.frame()->IsConstructor();
9694
10377
 
9695
10378
  // Get scope info and read from it for local variable information.
9696
10379
  Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
9697
- Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
10380
+ Handle<SharedFunctionInfo> shared(function->shared());
10381
+ Handle<SerializedScopeInfo> scope_info(shared->scope_info());
10382
+ ASSERT(*scope_info != SerializedScopeInfo::Empty());
9698
10383
  ScopeInfo<> info(*scope_info);
9699
10384
 
9700
- // Get the context.
9701
- Handle<Context> context(Context::cast(it.frame()->context()));
9702
-
9703
10385
  // Get the locals names and values into a temporary array.
9704
10386
  //
9705
10387
  // TODO(1240907): Hide compiler-introduced stack variables
@@ -9708,31 +10390,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9708
10390
  Handle<FixedArray> locals =
9709
10391
  isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
9710
10392
 
9711
- // Fill in the names of the locals.
9712
- for (int i = 0; i < info.NumberOfLocals(); i++) {
10393
+ // Fill in the values of the locals.
10394
+ int i = 0;
10395
+ for (; i < info.number_of_stack_slots(); ++i) {
10396
+ // Use the value from the stack.
9713
10397
  locals->set(i * 2, *info.LocalName(i));
10398
+ locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
9714
10399
  }
9715
-
9716
- // Fill in the values of the locals.
9717
- for (int i = 0; i < info.NumberOfLocals(); i++) {
9718
- if (is_optimized_frame) {
9719
- // If we are inspecting an optimized frame use undefined as the
9720
- // value for all locals.
9721
- //
9722
- // TODO(1140): We should be able to get the correct values
9723
- // for locals in optimized frames.
9724
- locals->set(i * 2 + 1, isolate->heap()->undefined_value());
9725
- } else if (i < info.number_of_stack_slots()) {
9726
- // Get the value from the stack.
9727
- locals->set(i * 2 + 1, it.frame()->GetExpression(i));
9728
- } else {
9729
- // Traverse the context chain to the function context as all local
9730
- // variables stored in the context will be on the function context.
10400
+ if (i < info.NumberOfLocals()) {
10401
+ // Get the context containing declarations.
10402
+ Handle<Context> context(
10403
+ Context::cast(it.frame()->context())->declaration_context());
10404
+ for (; i < info.NumberOfLocals(); ++i) {
9731
10405
  Handle<String> name = info.LocalName(i);
9732
- while (!context->is_function_context()) {
9733
- context = Handle<Context>(context->previous());
9734
- }
9735
- ASSERT(context->is_function_context());
10406
+ locals->set(i * 2, *name);
9736
10407
  locals->set(i * 2 + 1,
9737
10408
  context->get(scope_info->ContextSlotIndex(*name, NULL)));
9738
10409
  }
@@ -9741,7 +10412,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9741
10412
  // Check whether this frame is positioned at return. If not top
9742
10413
  // frame or if the frame is optimized it cannot be at a return.
9743
10414
  bool at_return = false;
9744
- if (!is_optimized_frame && index == 0) {
10415
+ if (!it.frame()->is_optimized() && index == 0) {
9745
10416
  at_return = isolate->debug()->IsBreakAtReturn(it.frame());
9746
10417
  }
9747
10418
 
@@ -9781,14 +10452,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9781
10452
  // the provided parameters whereas the function frame always have the number
9782
10453
  // of arguments matching the functions parameters. The rest of the
9783
10454
  // information (except for what is collected above) is the same.
9784
- it.AdvanceToArgumentsFrame();
10455
+ if (it.frame()->has_adapted_arguments()) {
10456
+ it.AdvanceToArgumentsFrame();
10457
+ frame_inspector.SetArgumentsFrame(it.frame());
10458
+ }
9785
10459
 
9786
10460
  // Find the number of arguments to fill. At least fill the number of
9787
10461
  // parameters for the function and fill more if more parameters are provided.
9788
10462
  int argument_count = info.number_of_parameters();
9789
- if (argument_count < it.frame()->ComputeParametersCount()) {
9790
- argument_count = it.frame()->ComputeParametersCount();
10463
+ if (argument_count < frame_inspector.GetParametersCount()) {
10464
+ argument_count = frame_inspector.GetParametersCount();
10465
+ }
10466
+ #ifdef DEBUG
10467
+ if (it.frame()->is_optimized()) {
10468
+ ASSERT_EQ(argument_count, frame_inspector.GetParametersCount());
9791
10469
  }
10470
+ #endif
9792
10471
 
9793
10472
  // Calculate the size of the result.
9794
10473
  int details_size = kFrameDetailsFirstDynamicIndex +
@@ -9800,7 +10479,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9800
10479
  details->set(kFrameDetailsFrameIdIndex, *frame_id);
9801
10480
 
9802
10481
  // Add the function (same as in function frame).
9803
- details->set(kFrameDetailsFunctionIndex, it.frame()->function());
10482
+ details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
9804
10483
 
9805
10484
  // Add the arguments count.
9806
10485
  details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
@@ -9822,10 +10501,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9822
10501
  // Add the at return information.
9823
10502
  details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
9824
10503
 
9825
- // Add information on whether this frame is invoked in the debugger context.
9826
- details->set(kFrameDetailsDebuggerFrameIndex,
9827
- heap->ToBoolean(*save->context() ==
9828
- *isolate->debug()->debug_context()));
10504
+ // Add flags to indicate information on whether this frame is
10505
+ // bit 0: invoked in the debugger context.
10506
+ // bit 1: optimized frame.
10507
+ // bit 2: inlined in optimized frame
10508
+ int flags = 0;
10509
+ if (*save->context() == *isolate->debug()->debug_context()) {
10510
+ flags |= 1 << 0;
10511
+ }
10512
+ if (it.frame()->is_optimized()) {
10513
+ flags |= 1 << 1;
10514
+ flags |= inlined_frame_index << 2;
10515
+ }
10516
+ details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
9829
10517
 
9830
10518
  // Fill the dynamic part.
9831
10519
  int details_index = kFrameDetailsFirstDynamicIndex;
@@ -9839,14 +10527,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9839
10527
  details->set(details_index++, heap->undefined_value());
9840
10528
  }
9841
10529
 
9842
- // Parameter value. If we are inspecting an optimized frame, use
9843
- // undefined as the value.
9844
- //
9845
- // TODO(3141533): We should be able to get the actual parameter
9846
- // value for optimized frames.
9847
- if (!is_optimized_frame &&
9848
- (i < it.frame()->ComputeParametersCount())) {
9849
- details->set(details_index++, it.frame()->GetParameter(i));
10530
+ // Parameter value.
10531
+ if (i < it.frame()->ComputeParametersCount()) {
10532
+ // Get the value from the stack.
10533
+ details->set(details_index++, frame_inspector.GetParameter(i));
9850
10534
  } else {
9851
10535
  details->set(details_index++, heap->undefined_value());
9852
10536
  }
@@ -9866,10 +10550,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9866
10550
  // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
9867
10551
  // THE FRAME ITERATOR TO WRAP THE RECEIVER.
9868
10552
  Handle<Object> receiver(it.frame()->receiver(), isolate);
9869
- if (!receiver->IsJSObject()) {
9870
- // If the receiver is NOT a JSObject we have hit an optimization
9871
- // where a value object is not converted into a wrapped JS objects.
9872
- // To hide this optimization from the debugger, we wrap the receiver
10553
+ if (!receiver->IsJSObject() && !shared->strict_mode() && !shared->native()) {
10554
+ // If the receiver is not a JSObject and the function is not a
10555
+ // builtin or strict-mode we have hit an optimization where a
10556
+ // value object is not converted into a wrapped JS objects. To
10557
+ // hide this optimization from the debugger, we wrap the receiver
9873
10558
  // by creating correct wrapper object based on the calling frame's
9874
10559
  // global context.
9875
10560
  it.Advance();
@@ -9899,18 +10584,14 @@ static bool CopyContextLocalsToScopeObject(
9899
10584
  int context_index = serialized_scope_info->ContextSlotIndex(
9900
10585
  *scope_info.context_slot_name(i), NULL);
9901
10586
 
9902
- // Don't include the arguments shadow (.arguments) context variable.
9903
- if (*scope_info.context_slot_name(i) !=
9904
- isolate->heap()->arguments_shadow_symbol()) {
9905
- RETURN_IF_EMPTY_HANDLE_VALUE(
9906
- isolate,
9907
- SetProperty(scope_object,
9908
- scope_info.context_slot_name(i),
9909
- Handle<Object>(context->get(context_index), isolate),
9910
- NONE,
9911
- kNonStrictMode),
9912
- false);
9913
- }
10587
+ RETURN_IF_EMPTY_HANDLE_VALUE(
10588
+ isolate,
10589
+ SetProperty(scope_object,
10590
+ scope_info.context_slot_name(i),
10591
+ Handle<Object>(context->get(context_index), isolate),
10592
+ NONE,
10593
+ kNonStrictMode),
10594
+ false);
9914
10595
  }
9915
10596
 
9916
10597
  return true;
@@ -9919,12 +10600,15 @@ static bool CopyContextLocalsToScopeObject(
9919
10600
 
9920
10601
  // Create a plain JSObject which materializes the local scope for the specified
9921
10602
  // frame.
9922
- static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9923
- JavaScriptFrame* frame) {
10603
+ static Handle<JSObject> MaterializeLocalScope(
10604
+ Isolate* isolate,
10605
+ JavaScriptFrame* frame,
10606
+ int inlined_frame_index) {
9924
10607
  Handle<JSFunction> function(JSFunction::cast(frame->function()));
9925
10608
  Handle<SharedFunctionInfo> shared(function->shared());
9926
10609
  Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
9927
10610
  ScopeInfo<> scope_info(*serialized_scope_info);
10611
+ FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
9928
10612
 
9929
10613
  // Allocate and initialize a JSObject with all the arguments, stack locals
9930
10614
  // heap locals and extension properties of the debugged function.
@@ -9937,55 +10621,58 @@ static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9937
10621
  isolate,
9938
10622
  SetProperty(local_scope,
9939
10623
  scope_info.parameter_name(i),
9940
- Handle<Object>(frame->GetParameter(i), isolate),
10624
+ Handle<Object>(frame_inspector.GetParameter(i)),
9941
10625
  NONE,
9942
10626
  kNonStrictMode),
9943
10627
  Handle<JSObject>());
9944
10628
  }
9945
10629
 
9946
10630
  // Second fill all stack locals.
9947
- for (int i = 0; i < scope_info.number_of_stack_slots(); i++) {
10631
+ for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
9948
10632
  RETURN_IF_EMPTY_HANDLE_VALUE(
9949
10633
  isolate,
9950
10634
  SetProperty(local_scope,
9951
10635
  scope_info.stack_slot_name(i),
9952
- Handle<Object>(frame->GetExpression(i), isolate),
10636
+ Handle<Object>(frame_inspector.GetExpression(i)),
9953
10637
  NONE,
9954
10638
  kNonStrictMode),
9955
10639
  Handle<JSObject>());
9956
10640
  }
9957
10641
 
9958
- // Third fill all context locals.
9959
- Handle<Context> frame_context(Context::cast(frame->context()));
9960
- Handle<Context> function_context(frame_context->fcontext());
9961
- if (!CopyContextLocalsToScopeObject(isolate,
9962
- serialized_scope_info, scope_info,
9963
- function_context, local_scope)) {
9964
- return Handle<JSObject>();
9965
- }
9966
-
9967
- // Finally copy any properties from the function context extension. This will
9968
- // be variables introduced by eval.
9969
- if (function_context->closure() == *function) {
9970
- if (function_context->has_extension() &&
9971
- !function_context->IsGlobalContext()) {
9972
- Handle<JSObject> ext(JSObject::cast(function_context->extension()));
9973
- Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
9974
- for (int i = 0; i < keys->length(); i++) {
9975
- // Names of variables introduced by eval are strings.
9976
- ASSERT(keys->get(i)->IsString());
9977
- Handle<String> key(String::cast(keys->get(i)));
9978
- RETURN_IF_EMPTY_HANDLE_VALUE(
9979
- isolate,
9980
- SetProperty(local_scope,
9981
- key,
9982
- GetProperty(ext, key),
9983
- NONE,
9984
- kNonStrictMode),
9985
- Handle<JSObject>());
10642
+ if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10643
+ // Third fill all context locals.
10644
+ Handle<Context> frame_context(Context::cast(frame->context()));
10645
+ Handle<Context> function_context(frame_context->declaration_context());
10646
+ if (!CopyContextLocalsToScopeObject(isolate,
10647
+ serialized_scope_info, scope_info,
10648
+ function_context, local_scope)) {
10649
+ return Handle<JSObject>();
10650
+ }
10651
+
10652
+ // Finally copy any properties from the function context extension.
10653
+ // These will be variables introduced by eval.
10654
+ if (function_context->closure() == *function) {
10655
+ if (function_context->has_extension() &&
10656
+ !function_context->IsGlobalContext()) {
10657
+ Handle<JSObject> ext(JSObject::cast(function_context->extension()));
10658
+ Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
10659
+ for (int i = 0; i < keys->length(); i++) {
10660
+ // Names of variables introduced by eval are strings.
10661
+ ASSERT(keys->get(i)->IsString());
10662
+ Handle<String> key(String::cast(keys->get(i)));
10663
+ RETURN_IF_EMPTY_HANDLE_VALUE(
10664
+ isolate,
10665
+ SetProperty(local_scope,
10666
+ key,
10667
+ GetProperty(ext, key),
10668
+ NONE,
10669
+ kNonStrictMode),
10670
+ Handle<JSObject>());
10671
+ }
9986
10672
  }
9987
10673
  }
9988
10674
  }
10675
+
9989
10676
  return local_scope;
9990
10677
  }
9991
10678
 
@@ -9994,7 +10681,7 @@ static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9994
10681
  // context.
9995
10682
  static Handle<JSObject> MaterializeClosure(Isolate* isolate,
9996
10683
  Handle<Context> context) {
9997
- ASSERT(context->is_function_context());
10684
+ ASSERT(context->IsFunctionContext());
9998
10685
 
9999
10686
  Handle<SharedFunctionInfo> shared(context->closure()->shared());
10000
10687
  Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
@@ -10005,29 +10692,6 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
10005
10692
  Handle<JSObject> closure_scope =
10006
10693
  isolate->factory()->NewJSObject(isolate->object_function());
10007
10694
 
10008
- // Check whether the arguments shadow object exists.
10009
- int arguments_shadow_index =
10010
- shared->scope_info()->ContextSlotIndex(
10011
- isolate->heap()->arguments_shadow_symbol(), NULL);
10012
- if (arguments_shadow_index >= 0) {
10013
- // In this case all the arguments are available in the arguments shadow
10014
- // object.
10015
- Handle<JSObject> arguments_shadow(
10016
- JSObject::cast(context->get(arguments_shadow_index)));
10017
- for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
10018
- // We don't expect exception-throwing getters on the arguments shadow.
10019
- Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
10020
- RETURN_IF_EMPTY_HANDLE_VALUE(
10021
- isolate,
10022
- SetProperty(closure_scope,
10023
- scope_info.parameter_name(i),
10024
- Handle<Object>(element, isolate),
10025
- NONE,
10026
- kNonStrictMode),
10027
- Handle<JSObject>());
10028
- }
10029
- }
10030
-
10031
10695
  // Fill all context locals to the context extension.
10032
10696
  if (!CopyContextLocalsToScopeObject(isolate,
10033
10697
  serialized_scope_info, scope_info,
@@ -10059,6 +10723,51 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
10059
10723
  }
10060
10724
 
10061
10725
 
10726
+ // Create a plain JSObject which materializes the scope for the specified
10727
+ // catch context.
10728
+ static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
10729
+ Handle<Context> context) {
10730
+ ASSERT(context->IsCatchContext());
10731
+ Handle<String> name(String::cast(context->extension()));
10732
+ Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX));
10733
+ Handle<JSObject> catch_scope =
10734
+ isolate->factory()->NewJSObject(isolate->object_function());
10735
+ RETURN_IF_EMPTY_HANDLE_VALUE(
10736
+ isolate,
10737
+ SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
10738
+ Handle<JSObject>());
10739
+ return catch_scope;
10740
+ }
10741
+
10742
+
10743
+ // Create a plain JSObject which materializes the block scope for the specified
10744
+ // block context.
10745
+ static Handle<JSObject> MaterializeBlockScope(
10746
+ Isolate* isolate,
10747
+ Handle<Context> context) {
10748
+ ASSERT(context->IsBlockContext());
10749
+ Handle<SerializedScopeInfo> serialized_scope_info(
10750
+ SerializedScopeInfo::cast(context->extension()));
10751
+ ScopeInfo<> scope_info(*serialized_scope_info);
10752
+
10753
+ // Allocate and initialize a JSObject with all the arguments, stack locals
10754
+ // heap locals and extension properties of the debugged function.
10755
+ Handle<JSObject> block_scope =
10756
+ isolate->factory()->NewJSObject(isolate->object_function());
10757
+
10758
+ // Fill all context locals.
10759
+ if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10760
+ if (!CopyContextLocalsToScopeObject(isolate,
10761
+ serialized_scope_info, scope_info,
10762
+ context, block_scope)) {
10763
+ return Handle<JSObject>();
10764
+ }
10765
+ }
10766
+
10767
+ return block_scope;
10768
+ }
10769
+
10770
+
10062
10771
  // Iterate over the actual scopes visible from a stack frame. All scopes are
10063
10772
  // backed by an actual context except the local scope, which is inserted
10064
10773
  // "artifically" in the context chain.
@@ -10069,16 +10778,16 @@ class ScopeIterator {
10069
10778
  ScopeTypeLocal,
10070
10779
  ScopeTypeWith,
10071
10780
  ScopeTypeClosure,
10072
- // Every catch block contains an implicit with block (its parameter is
10073
- // a JSContextExtensionObject) that extends current scope with a variable
10074
- // holding exception object. Such with blocks are treated as scopes of their
10075
- // own type.
10076
- ScopeTypeCatch
10781
+ ScopeTypeCatch,
10782
+ ScopeTypeBlock
10077
10783
  };
10078
10784
 
10079
- ScopeIterator(Isolate* isolate, JavaScriptFrame* frame)
10785
+ ScopeIterator(Isolate* isolate,
10786
+ JavaScriptFrame* frame,
10787
+ int inlined_frame_index)
10080
10788
  : isolate_(isolate),
10081
10789
  frame_(frame),
10790
+ inlined_frame_index_(inlined_frame_index),
10082
10791
  function_(JSFunction::cast(frame->function())),
10083
10792
  context_(Context::cast(frame->context())),
10084
10793
  local_done_(false),
@@ -10093,11 +10802,13 @@ class ScopeIterator {
10093
10802
  int index = function_->shared()->scope_info()->
10094
10803
  StackSlotIndex(isolate_->heap()->result_symbol());
10095
10804
  at_local_ = index < 0;
10096
- } else if (context_->is_function_context()) {
10805
+ } else if (context_->IsFunctionContext()) {
10097
10806
  at_local_ = true;
10098
10807
  } else if (context_->closure() != *function_) {
10099
- // The context_ is a with block from the outer function.
10100
- ASSERT(context_->has_extension());
10808
+ // The context_ is a block or with or catch block from the outer function.
10809
+ ASSERT(context_->IsWithContext() ||
10810
+ context_->IsCatchContext() ||
10811
+ context_->IsBlockContext());
10101
10812
  at_local_ = true;
10102
10813
  }
10103
10814
  }
@@ -10127,16 +10838,12 @@ class ScopeIterator {
10127
10838
  }
10128
10839
 
10129
10840
  // Move to the next context.
10130
- if (context_->is_function_context()) {
10131
- context_ = Handle<Context>(Context::cast(context_->closure()->context()));
10132
- } else {
10133
- context_ = Handle<Context>(context_->previous());
10134
- }
10841
+ context_ = Handle<Context>(context_->previous(), isolate_);
10135
10842
 
10136
10843
  // If passing the local scope indicate that the current scope is now the
10137
10844
  // local scope.
10138
10845
  if (!local_done_ &&
10139
- (context_->IsGlobalContext() || (context_->is_function_context()))) {
10846
+ (context_->IsGlobalContext() || context_->IsFunctionContext())) {
10140
10847
  at_local_ = true;
10141
10848
  }
10142
10849
  }
@@ -10150,18 +10857,16 @@ class ScopeIterator {
10150
10857
  ASSERT(context_->global()->IsGlobalObject());
10151
10858
  return ScopeTypeGlobal;
10152
10859
  }
10153
- if (context_->is_function_context()) {
10860
+ if (context_->IsFunctionContext()) {
10154
10861
  return ScopeTypeClosure;
10155
10862
  }
10156
- ASSERT(context_->has_extension());
10157
- // Current scope is either an explicit with statement or a with statement
10158
- // implicitely generated for a catch block.
10159
- // If the extension object here is a JSContextExtensionObject then
10160
- // current with statement is one frome a catch block otherwise it's a
10161
- // regular with statement.
10162
- if (context_->extension()->IsJSContextExtensionObject()) {
10863
+ if (context_->IsCatchContext()) {
10163
10864
  return ScopeTypeCatch;
10164
10865
  }
10866
+ if (context_->IsBlockContext()) {
10867
+ return ScopeTypeBlock;
10868
+ }
10869
+ ASSERT(context_->IsWithContext());
10165
10870
  return ScopeTypeWith;
10166
10871
  }
10167
10872
 
@@ -10170,20 +10875,19 @@ class ScopeIterator {
10170
10875
  switch (Type()) {
10171
10876
  case ScopeIterator::ScopeTypeGlobal:
10172
10877
  return Handle<JSObject>(CurrentContext()->global());
10173
- break;
10174
10878
  case ScopeIterator::ScopeTypeLocal:
10175
10879
  // Materialize the content of the local scope into a JSObject.
10176
- return MaterializeLocalScope(isolate_, frame_);
10177
- break;
10880
+ return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_);
10178
10881
  case ScopeIterator::ScopeTypeWith:
10179
- case ScopeIterator::ScopeTypeCatch:
10180
10882
  // Return the with object.
10181
- return Handle<JSObject>(CurrentContext()->extension());
10182
- break;
10883
+ return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
10884
+ case ScopeIterator::ScopeTypeCatch:
10885
+ return MaterializeCatchScope(isolate_, CurrentContext());
10183
10886
  case ScopeIterator::ScopeTypeClosure:
10184
10887
  // Materialize the content of the closure scope into a JSObject.
10185
10888
  return MaterializeClosure(isolate_, CurrentContext());
10186
- break;
10889
+ case ScopeIterator::ScopeTypeBlock:
10890
+ return MaterializeBlockScope(isolate_, CurrentContext());
10187
10891
  }
10188
10892
  UNREACHABLE();
10189
10893
  return Handle<JSObject>();
@@ -10214,8 +10918,7 @@ class ScopeIterator {
10214
10918
  if (!CurrentContext().is_null()) {
10215
10919
  CurrentContext()->Print();
10216
10920
  if (CurrentContext()->has_extension()) {
10217
- Handle<JSObject> extension =
10218
- Handle<JSObject>(CurrentContext()->extension());
10921
+ Handle<Object> extension(CurrentContext()->extension());
10219
10922
  if (extension->IsJSContextExtensionObject()) {
10220
10923
  extension->Print();
10221
10924
  }
@@ -10224,34 +10927,27 @@ class ScopeIterator {
10224
10927
  break;
10225
10928
  }
10226
10929
 
10227
- case ScopeIterator::ScopeTypeWith: {
10930
+ case ScopeIterator::ScopeTypeWith:
10228
10931
  PrintF("With:\n");
10229
- Handle<JSObject> extension =
10230
- Handle<JSObject>(CurrentContext()->extension());
10231
- extension->Print();
10932
+ CurrentContext()->extension()->Print();
10232
10933
  break;
10233
- }
10234
10934
 
10235
- case ScopeIterator::ScopeTypeCatch: {
10935
+ case ScopeIterator::ScopeTypeCatch:
10236
10936
  PrintF("Catch:\n");
10237
- Handle<JSObject> extension =
10238
- Handle<JSObject>(CurrentContext()->extension());
10239
- extension->Print();
10937
+ CurrentContext()->extension()->Print();
10938
+ CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
10240
10939
  break;
10241
- }
10242
10940
 
10243
- case ScopeIterator::ScopeTypeClosure: {
10941
+ case ScopeIterator::ScopeTypeClosure:
10244
10942
  PrintF("Closure:\n");
10245
10943
  CurrentContext()->Print();
10246
10944
  if (CurrentContext()->has_extension()) {
10247
- Handle<JSObject> extension =
10248
- Handle<JSObject>(CurrentContext()->extension());
10945
+ Handle<Object> extension(CurrentContext()->extension());
10249
10946
  if (extension->IsJSContextExtensionObject()) {
10250
10947
  extension->Print();
10251
10948
  }
10252
10949
  }
10253
10950
  break;
10254
- }
10255
10951
 
10256
10952
  default:
10257
10953
  UNREACHABLE();
@@ -10263,6 +10959,7 @@ class ScopeIterator {
10263
10959
  private:
10264
10960
  Isolate* isolate_;
10265
10961
  JavaScriptFrame* frame_;
10962
+ int inlined_frame_index_;
10266
10963
  Handle<JSFunction> function_;
10267
10964
  Handle<Context> context_;
10268
10965
  bool local_done_;
@@ -10291,7 +10988,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
10291
10988
 
10292
10989
  // Count the visible scopes.
10293
10990
  int n = 0;
10294
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
10991
+ for (ScopeIterator it(isolate, frame, 0);
10992
+ !it.Done();
10993
+ it.Next()) {
10295
10994
  n++;
10296
10995
  }
10297
10996
 
@@ -10306,14 +11005,15 @@ static const int kScopeDetailsSize = 2;
10306
11005
  // Return an array with scope details
10307
11006
  // args[0]: number: break id
10308
11007
  // args[1]: number: frame index
10309
- // args[2]: number: scope index
11008
+ // args[2]: number: inlined frame index
11009
+ // args[3]: number: scope index
10310
11010
  //
10311
11011
  // The array returned contains the following information:
10312
11012
  // 0: Scope type
10313
11013
  // 1: Scope object
10314
11014
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
10315
11015
  HandleScope scope(isolate);
10316
- ASSERT(args.length() == 3);
11016
+ ASSERT(args.length() == 4);
10317
11017
 
10318
11018
  // Check arguments.
10319
11019
  Object* check;
@@ -10322,7 +11022,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
10322
11022
  if (!maybe_check->ToObject(&check)) return maybe_check;
10323
11023
  }
10324
11024
  CONVERT_CHECKED(Smi, wrapped_id, args[1]);
10325
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]);
11025
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
11026
+ CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
10326
11027
 
10327
11028
  // Get the frame where the debugging is performed.
10328
11029
  StackFrame::Id id = UnwrapFrameId(wrapped_id);
@@ -10331,7 +11032,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
10331
11032
 
10332
11033
  // Find the requested scope.
10333
11034
  int n = 0;
10334
- ScopeIterator it(isolate, frame);
11035
+ ScopeIterator it(isolate, frame, inlined_frame_index);
10335
11036
  for (; !it.Done() && n < index; it.Next()) {
10336
11037
  n++;
10337
11038
  }
@@ -10361,7 +11062,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
10361
11062
  // Print the scopes for the top frame.
10362
11063
  StackFrameLocator locator;
10363
11064
  JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
10364
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
11065
+ for (ScopeIterator it(isolate, frame, 0);
11066
+ !it.Done();
11067
+ it.Next()) {
10365
11068
  it.DebugPrint();
10366
11069
  }
10367
11070
  #endif
@@ -10718,19 +11421,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
10718
11421
 
10719
11422
  // Creates a copy of the with context chain. The copy of the context chain is
10720
11423
  // is linked to the function context supplied.
10721
- static Handle<Context> CopyWithContextChain(Handle<Context> context_chain,
10722
- Handle<Context> function_context) {
10723
- // At the bottom of the chain. Return the function context to link to.
10724
- if (context_chain->is_function_context()) {
10725
- return function_context;
11424
+ static Handle<Context> CopyWithContextChain(Isolate* isolate,
11425
+ Handle<JSFunction> function,
11426
+ Handle<Context> current,
11427
+ Handle<Context> base) {
11428
+ // At the end of the chain. Return the base context to link to.
11429
+ if (current->IsFunctionContext() || current->IsGlobalContext()) {
11430
+ return base;
10726
11431
  }
10727
11432
 
10728
- // Recursively copy the with contexts.
10729
- Handle<Context> previous(context_chain->previous());
10730
- Handle<JSObject> extension(JSObject::cast(context_chain->extension()));
10731
- Handle<Context> context = CopyWithContextChain(previous, function_context);
10732
- return context->GetIsolate()->factory()->NewWithContext(
10733
- context, extension, context_chain->IsCatchContext());
11433
+ // Recursively copy the with and catch contexts.
11434
+ HandleScope scope(isolate);
11435
+ Handle<Context> previous(current->previous());
11436
+ Handle<Context> new_previous =
11437
+ CopyWithContextChain(isolate, function, previous, base);
11438
+ Handle<Context> new_current;
11439
+ if (current->IsCatchContext()) {
11440
+ Handle<String> name(String::cast(current->extension()));
11441
+ Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
11442
+ new_current =
11443
+ isolate->factory()->NewCatchContext(function,
11444
+ new_previous,
11445
+ name,
11446
+ thrown_object);
11447
+ } else if (current->IsBlockContext()) {
11448
+ Handle<SerializedScopeInfo> scope_info(
11449
+ SerializedScopeInfo::cast(current->extension()));
11450
+ new_current =
11451
+ isolate->factory()->NewBlockContext(function, new_previous, scope_info);
11452
+ // Copy context slots.
11453
+ int num_context_slots = scope_info->NumberOfContextSlots();
11454
+ for (int i = Context::MIN_CONTEXT_SLOTS; i < num_context_slots; ++i) {
11455
+ new_current->set(i, current->get(i));
11456
+ }
11457
+ } else {
11458
+ ASSERT(current->IsWithContext());
11459
+ Handle<JSObject> extension(JSObject::cast(current->extension()));
11460
+ new_current =
11461
+ isolate->factory()->NewWithContext(function, new_previous, extension);
11462
+ }
11463
+ return scope.CloseAndEscape(new_current);
10734
11464
  }
10735
11465
 
10736
11466
 
@@ -10738,6 +11468,7 @@ static Handle<Context> CopyWithContextChain(Handle<Context> context_chain,
10738
11468
  // Runtime_DebugEvaluate.
10739
11469
  static Handle<Object> GetArgumentsObject(Isolate* isolate,
10740
11470
  JavaScriptFrame* frame,
11471
+ int inlined_frame_index,
10741
11472
  Handle<JSFunction> function,
10742
11473
  Handle<SerializedScopeInfo> scope_info,
10743
11474
  const ScopeInfo<>* sinfo,
@@ -10761,7 +11492,9 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate,
10761
11492
  }
10762
11493
  }
10763
11494
 
10764
- const int length = frame->ComputeParametersCount();
11495
+ FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
11496
+
11497
+ int length = frame_inspector.GetParametersCount();
10765
11498
  Handle<JSObject> arguments =
10766
11499
  isolate->factory()->NewArgumentsObject(function, length);
10767
11500
  Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
@@ -10769,7 +11502,7 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate,
10769
11502
  AssertNoAllocation no_gc;
10770
11503
  WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
10771
11504
  for (int i = 0; i < length; i++) {
10772
- array->set(i, frame->GetParameter(i), mode);
11505
+ array->set(i, frame_inspector.GetParameter(i), mode);
10773
11506
  }
10774
11507
  arguments->set_elements(*array);
10775
11508
  return arguments;
@@ -10796,7 +11529,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10796
11529
 
10797
11530
  // Check the execution state and decode arguments frame and source to be
10798
11531
  // evaluated.
10799
- ASSERT(args.length() == 5);
11532
+ ASSERT(args.length() == 6);
10800
11533
  Object* check_result;
10801
11534
  { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
10802
11535
  RUNTIME_ARGUMENTS(isolate, args));
@@ -10805,9 +11538,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10805
11538
  }
10806
11539
  }
10807
11540
  CONVERT_CHECKED(Smi, wrapped_id, args[1]);
10808
- CONVERT_ARG_CHECKED(String, source, 2);
10809
- CONVERT_BOOLEAN_CHECKED(disable_break, args[3]);
10810
- Handle<Object> additional_context(args[4]);
11541
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
11542
+ CONVERT_ARG_CHECKED(String, source, 3);
11543
+ CONVERT_BOOLEAN_CHECKED(disable_break, args[4]);
11544
+ Handle<Object> additional_context(args[5]);
10811
11545
 
10812
11546
  // Handle the processing of break.
10813
11547
  DisableBreak disable_break_save(disable_break);
@@ -10847,7 +11581,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10847
11581
  #endif
10848
11582
 
10849
11583
  // Materialize the content of the local scope into a JSObject.
10850
- Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame);
11584
+ Handle<JSObject> local_scope = MaterializeLocalScope(
11585
+ isolate, frame, inlined_frame_index);
10851
11586
  RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
10852
11587
 
10853
11588
  // Allocate a new context for the debug evaluation and set the extension
@@ -10858,12 +11593,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10858
11593
  context->set_extension(*local_scope);
10859
11594
  // Copy any with contexts present and chain them in front of this context.
10860
11595
  Handle<Context> frame_context(Context::cast(frame->context()));
10861
- Handle<Context> function_context(frame_context->fcontext());
10862
- context = CopyWithContextChain(frame_context, context);
11596
+ Handle<Context> function_context;
11597
+ // Get the function's context if it has one.
11598
+ if (scope_info->HasHeapAllocatedLocals()) {
11599
+ function_context = Handle<Context>(frame_context->declaration_context());
11600
+ }
11601
+ context = CopyWithContextChain(isolate, go_between, frame_context, context);
10863
11602
 
10864
11603
  if (additional_context->IsJSObject()) {
10865
- context = isolate->factory()->NewWithContext(context,
10866
- Handle<JSObject>::cast(additional_context), false);
11604
+ Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
11605
+ context =
11606
+ isolate->factory()->NewWithContext(go_between, context, extension);
10867
11607
  }
10868
11608
 
10869
11609
  // Wrap the evaluation statement in a new function compiled in the newly
@@ -10895,7 +11635,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10895
11635
  &has_pending_exception);
10896
11636
  if (has_pending_exception) return Failure::Exception();
10897
11637
 
10898
- Handle<Object> arguments = GetArgumentsObject(isolate, frame,
11638
+ Handle<Object> arguments = GetArgumentsObject(isolate,
11639
+ frame, inlined_frame_index,
10899
11640
  function, scope_info,
10900
11641
  &sinfo, function_context);
10901
11642
 
@@ -11585,10 +12326,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CaptureLOL) {
11585
12326
  // Deletes the specified live object list.
11586
12327
  RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
11587
12328
  #ifdef LIVE_OBJECT_LIST
11588
- CONVERT_SMI_CHECKED(id, args[0]);
12329
+ CONVERT_SMI_ARG_CHECKED(id, 0);
11589
12330
  bool success = LiveObjectList::Delete(id);
11590
- return success ? isolate->heap()->true_value() :
11591
- isolate->heap()->false_value();
12331
+ return isolate->heap()->ToBoolean(success);
11592
12332
  #else
11593
12333
  return isolate->heap()->undefined_value();
11594
12334
  #endif
@@ -11603,10 +12343,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
11603
12343
  RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
11604
12344
  #ifdef LIVE_OBJECT_LIST
11605
12345
  HandleScope scope;
11606
- CONVERT_SMI_CHECKED(id1, args[0]);
11607
- CONVERT_SMI_CHECKED(id2, args[1]);
11608
- CONVERT_SMI_CHECKED(start, args[2]);
11609
- CONVERT_SMI_CHECKED(count, args[3]);
12346
+ CONVERT_SMI_ARG_CHECKED(id1, 0);
12347
+ CONVERT_SMI_ARG_CHECKED(id2, 1);
12348
+ CONVERT_SMI_ARG_CHECKED(start, 2);
12349
+ CONVERT_SMI_ARG_CHECKED(count, 3);
11610
12350
  CONVERT_ARG_CHECKED(JSObject, filter_obj, 4);
11611
12351
  EnterDebugger enter_debugger;
11612
12352
  return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
@@ -11620,7 +12360,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
11620
12360
  // This is only used for obj ids shown in live object lists.
11621
12361
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObj) {
11622
12362
  #ifdef LIVE_OBJECT_LIST
11623
- CONVERT_SMI_CHECKED(obj_id, args[0]);
12363
+ CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11624
12364
  Object* result = LiveObjectList::GetObj(obj_id);
11625
12365
  return result;
11626
12366
  #else
@@ -11647,7 +12387,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjId) {
11647
12387
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
11648
12388
  #ifdef LIVE_OBJECT_LIST
11649
12389
  HandleScope scope;
11650
- CONVERT_SMI_CHECKED(obj_id, args[0]);
12390
+ CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11651
12391
  RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject());
11652
12392
  RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
11653
12393
  RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
@@ -11664,11 +12404,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
11664
12404
  }
11665
12405
  int start = 0;
11666
12406
  if (args[3]->IsSmi()) {
11667
- start = Smi::cast(args[3])->value();
12407
+ start = args.smi_at(3);
11668
12408
  }
11669
12409
  int limit = Smi::kMaxValue;
11670
12410
  if (args[4]->IsSmi()) {
11671
- limit = Smi::cast(args[4])->value();
12411
+ limit = args.smi_at(4);
11672
12412
  }
11673
12413
 
11674
12414
  return LiveObjectList::GetObjRetainers(obj_id,
@@ -11687,8 +12427,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
11687
12427
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
11688
12428
  #ifdef LIVE_OBJECT_LIST
11689
12429
  HandleScope scope;
11690
- CONVERT_SMI_CHECKED(obj_id1, args[0]);
11691
- CONVERT_SMI_CHECKED(obj_id2, args[1]);
12430
+ CONVERT_SMI_ARG_CHECKED(obj_id1, 0);
12431
+ CONVERT_SMI_ARG_CHECKED(obj_id2, 1);
11692
12432
  RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject());
11693
12433
 
11694
12434
  Handle<JSObject> instance_filter;
@@ -11709,8 +12449,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
11709
12449
  // previously captured live object lists.
11710
12450
  RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
11711
12451
  #ifdef LIVE_OBJECT_LIST
11712
- CONVERT_SMI_CHECKED(start, args[0]);
11713
- CONVERT_SMI_CHECKED(count, args[1]);
12452
+ CONVERT_SMI_ARG_CHECKED(start, 0);
12453
+ CONVERT_SMI_ARG_CHECKED(count, 1);
11714
12454
  return LiveObjectList::Info(start, count);
11715
12455
  #else
11716
12456
  return isolate->heap()->undefined_value();
@@ -11723,7 +12463,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
11723
12463
  RUNTIME_FUNCTION(MaybeObject*, Runtime_PrintLOLObj) {
11724
12464
  #ifdef LIVE_OBJECT_LIST
11725
12465
  HandleScope scope;
11726
- CONVERT_SMI_CHECKED(obj_id, args[0]);
12466
+ CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11727
12467
  Object* result = LiveObjectList::PrintObj(obj_id);
11728
12468
  return result;
11729
12469
  #else
@@ -11751,8 +12491,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ResetLOL) {
11751
12491
  RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
11752
12492
  #ifdef LIVE_OBJECT_LIST
11753
12493
  HandleScope scope;
11754
- CONVERT_SMI_CHECKED(id1, args[0]);
11755
- CONVERT_SMI_CHECKED(id2, args[1]);
12494
+ CONVERT_SMI_ARG_CHECKED(id1, 0);
12495
+ CONVERT_SMI_ARG_CHECKED(id2, 1);
11756
12496
  CONVERT_ARG_CHECKED(JSObject, filter_obj, 2);
11757
12497
 
11758
12498
  EnterDebugger enter_debugger;
@@ -11765,29 +12505,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
11765
12505
  #endif // ENABLE_DEBUGGER_SUPPORT
11766
12506
 
11767
12507
 
11768
- #ifdef ENABLE_LOGGING_AND_PROFILING
11769
12508
  RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) {
11770
12509
  NoHandleAllocation ha;
11771
- ASSERT(args.length() == 2);
11772
-
11773
- CONVERT_CHECKED(Smi, smi_modules, args[0]);
11774
- CONVERT_CHECKED(Smi, smi_tag, args[1]);
11775
- v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
12510
+ v8::V8::ResumeProfiler();
11776
12511
  return isolate->heap()->undefined_value();
11777
12512
  }
11778
12513
 
11779
12514
 
11780
12515
  RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerPause) {
11781
12516
  NoHandleAllocation ha;
11782
- ASSERT(args.length() == 2);
11783
-
11784
- CONVERT_CHECKED(Smi, smi_modules, args[0]);
11785
- CONVERT_CHECKED(Smi, smi_tag, args[1]);
11786
- v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
12517
+ v8::V8::PauseProfiler();
11787
12518
  return isolate->heap()->undefined_value();
11788
12519
  }
11789
12520
 
11790
- #endif // ENABLE_LOGGING_AND_PROFILING
11791
12521
 
11792
12522
  // Finds the script object from the script data. NOTE: This operation uses
11793
12523
  // heap traversal to find the function generated for the source position
@@ -11844,8 +12574,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
11844
12574
  // call to this function is encountered it is skipped. The seen_caller
11845
12575
  // in/out parameter is used to remember if the caller has been seen
11846
12576
  // yet.
11847
- static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
11848
- bool* seen_caller) {
12577
+ static bool ShowFrameInStackTrace(StackFrame* raw_frame,
12578
+ Object* caller,
12579
+ bool* seen_caller) {
11849
12580
  // Only display JS frames.
11850
12581
  if (!raw_frame->is_java_script())
11851
12582
  return false;
@@ -11858,11 +12589,25 @@ static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
11858
12589
  *seen_caller = true;
11859
12590
  return false;
11860
12591
  }
11861
- // Skip all frames until we've seen the caller. Also, skip the most
11862
- // obvious builtin calls. Some builtin calls (such as Number.ADD
11863
- // which is invoked using 'call') are very difficult to recognize
11864
- // so we're leaving them in for now.
11865
- return *seen_caller && !frame->receiver()->IsJSBuiltinsObject();
12592
+ // Skip all frames until we've seen the caller.
12593
+ if (!(*seen_caller)) return false;
12594
+ // Also, skip the most obvious builtin calls. We recognize builtins
12595
+ // as (1) functions called with the builtins object as the receiver and
12596
+ // as (2) functions from native scripts called with undefined as the
12597
+ // receiver (direct calls to helper functions in the builtins
12598
+ // code). Some builtin calls (such as Number.ADD which is invoked
12599
+ // using 'call') are very difficult to recognize so we're leaving
12600
+ // them in for now.
12601
+ if (frame->receiver()->IsJSBuiltinsObject()) {
12602
+ return false;
12603
+ }
12604
+ JSFunction* fun = JSFunction::cast(raw_fun);
12605
+ Object* raw_script = fun->shared()->script();
12606
+ if (frame->receiver()->IsUndefined() && raw_script->IsScript()) {
12607
+ int script_type = Script::cast(raw_script)->type()->value();
12608
+ return script_type != Script::TYPE_NATIVE;
12609
+ }
12610
+ return true;
11866
12611
  }
11867
12612
 
11868
12613
 
@@ -11942,8 +12687,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
11942
12687
 
11943
12688
  RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
11944
12689
  ASSERT(args.length() == 2);
11945
- OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) +
11946
- Smi::cast(args[1])->value());
12690
+ OS::PrintError("abort: %s\n",
12691
+ reinterpret_cast<char*>(args[0]) + args.smi_at(1));
11947
12692
  isolate->PrintStack();
11948
12693
  OS::Abort();
11949
12694
  UNREACHABLE();
@@ -12133,7 +12878,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
12133
12878
  ASSERT(args.length() == 2);
12134
12879
  CONVERT_CHECKED(String, format, args[0]);
12135
12880
  CONVERT_CHECKED(JSArray, elms, args[1]);
12136
- Vector<const char> chars = format->ToAsciiVector();
12881
+ String::FlatContent format_content = format->GetFlatContent();
12882
+ RUNTIME_ASSERT(format_content.IsAscii());
12883
+ Vector<const char> chars = format_content.ToAsciiVector();
12137
12884
  LOGGER->LogRuntime(chars, elms);
12138
12885
  return isolate->heap()->undefined_value();
12139
12886
  }
@@ -12145,6 +12892,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
12145
12892
  }
12146
12893
 
12147
12894
 
12895
+ #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
12896
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
12897
+ CONVERT_CHECKED(JSObject, obj, args[0]); \
12898
+ return isolate->heap()->ToBoolean(obj->Has##Name()); \
12899
+ }
12900
+
12901
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
12902
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
12903
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
12904
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
12905
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
12906
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
12907
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
12908
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
12909
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
12910
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
12911
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
12912
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
12913
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
12914
+
12915
+ #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
12916
+
12148
12917
  // ----------------------------------------------------------------------------
12149
12918
  // Implementation of Runtime
12150
12919