libv8 3.3.10.4 → 3.5.10.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/libv8/scons/CHANGES.txt +24 -231
- data/lib/libv8/scons/LICENSE.txt +1 -1
- data/lib/libv8/scons/MANIFEST +0 -1
- data/lib/libv8/scons/PKG-INFO +1 -1
- data/lib/libv8/scons/README.txt +9 -9
- data/lib/libv8/scons/RELEASE.txt +75 -77
- data/lib/libv8/scons/engine/SCons/Action.py +6 -22
- data/lib/libv8/scons/engine/SCons/Builder.py +2 -2
- data/lib/libv8/scons/engine/SCons/CacheDir.py +2 -2
- data/lib/libv8/scons/engine/SCons/Debug.py +2 -2
- data/lib/libv8/scons/engine/SCons/Defaults.py +10 -24
- data/lib/libv8/scons/engine/SCons/Environment.py +19 -118
- data/lib/libv8/scons/engine/SCons/Errors.py +2 -2
- data/lib/libv8/scons/engine/SCons/Executor.py +2 -2
- data/lib/libv8/scons/engine/SCons/Job.py +2 -2
- data/lib/libv8/scons/engine/SCons/Memoize.py +2 -2
- data/lib/libv8/scons/engine/SCons/Node/Alias.py +2 -2
- data/lib/libv8/scons/engine/SCons/Node/FS.py +121 -281
- data/lib/libv8/scons/engine/SCons/Node/Python.py +2 -2
- data/lib/libv8/scons/engine/SCons/Node/__init__.py +5 -6
- data/lib/libv8/scons/engine/SCons/Options/BoolOption.py +2 -2
- data/lib/libv8/scons/engine/SCons/Options/EnumOption.py +2 -2
- data/lib/libv8/scons/engine/SCons/Options/ListOption.py +2 -2
- data/lib/libv8/scons/engine/SCons/Options/PackageOption.py +2 -2
- data/lib/libv8/scons/engine/SCons/Options/PathOption.py +2 -2
- data/lib/libv8/scons/engine/SCons/Options/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/PathList.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/aix.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/cygwin.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/darwin.py +3 -27
- data/lib/libv8/scons/engine/SCons/Platform/hpux.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/irix.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/os2.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/posix.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/sunos.py +2 -2
- data/lib/libv8/scons/engine/SCons/Platform/win32.py +2 -2
- data/lib/libv8/scons/engine/SCons/SConf.py +2 -2
- data/lib/libv8/scons/engine/SCons/SConsign.py +3 -9
- data/lib/libv8/scons/engine/SCons/Scanner/C.py +2 -2
- data/lib/libv8/scons/engine/SCons/Scanner/D.py +2 -2
- data/lib/libv8/scons/engine/SCons/Scanner/Dir.py +2 -2
- data/lib/libv8/scons/engine/SCons/Scanner/Fortran.py +2 -2
- data/lib/libv8/scons/engine/SCons/Scanner/IDL.py +2 -2
- data/lib/libv8/scons/engine/SCons/Scanner/LaTeX.py +2 -5
- data/lib/libv8/scons/engine/SCons/Scanner/Prog.py +2 -2
- data/lib/libv8/scons/engine/SCons/Scanner/RC.py +3 -3
- data/lib/libv8/scons/engine/SCons/Scanner/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/Script/Interactive.py +2 -2
- data/lib/libv8/scons/engine/SCons/Script/Main.py +11 -82
- data/lib/libv8/scons/engine/SCons/Script/SConsOptions.py +5 -5
- data/lib/libv8/scons/engine/SCons/Script/SConscript.py +2 -2
- data/lib/libv8/scons/engine/SCons/Script/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/Sig.py +2 -2
- data/lib/libv8/scons/engine/SCons/Subst.py +2 -2
- data/lib/libv8/scons/engine/SCons/Taskmaster.py +2 -10
- data/lib/libv8/scons/engine/SCons/Tool/386asm.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/BitKeeper.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/CVS.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/FortranCommon.py +2 -19
- data/lib/libv8/scons/engine/SCons/Tool/JavaCommon.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/MSCommon/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/MSCommon/arch.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/MSCommon/common.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/MSCommon/netframework.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/MSCommon/sdk.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vc.py +6 -9
- data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vs.py +2 -29
- data/lib/libv8/scons/engine/SCons/Tool/Perforce.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/PharLapCommon.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/RCS.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/SCCS.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/Subversion.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/__init__.py +3 -3
- data/lib/libv8/scons/engine/SCons/Tool/aixc++.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/aixcc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/aixf77.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/aixlink.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/applelink.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/ar.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/as.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/bcc32.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/c++.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/cc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/cvf.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/default.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/dmd.py +7 -24
- data/lib/libv8/scons/engine/SCons/Tool/dvi.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/dvipdf.py +2 -3
- data/lib/libv8/scons/engine/SCons/Tool/dvips.py +2 -3
- data/lib/libv8/scons/engine/SCons/Tool/f77.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/f90.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/f95.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/filesystem.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/fortran.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/g++.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/g77.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/gas.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/gcc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/gfortran.py +3 -3
- data/lib/libv8/scons/engine/SCons/Tool/gnulink.py +3 -2
- data/lib/libv8/scons/engine/SCons/Tool/gs.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/hpc++.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/hpcc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/hplink.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/icc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/icl.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/ifl.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/ifort.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/ilink.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/ilink32.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/install.py +3 -57
- data/lib/libv8/scons/engine/SCons/Tool/intelc.py +25 -65
- data/lib/libv8/scons/engine/SCons/Tool/ipkg.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/jar.py +3 -9
- data/lib/libv8/scons/engine/SCons/Tool/javac.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/javah.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/latex.py +2 -3
- data/lib/libv8/scons/engine/SCons/Tool/lex.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/link.py +5 -6
- data/lib/libv8/scons/engine/SCons/Tool/linkloc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/m4.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/masm.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/midl.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/mingw.py +10 -31
- data/lib/libv8/scons/engine/SCons/Tool/mslib.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/mslink.py +9 -61
- data/lib/libv8/scons/engine/SCons/Tool/mssdk.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/msvc.py +11 -21
- data/lib/libv8/scons/engine/SCons/Tool/msvs.py +59 -477
- data/lib/libv8/scons/engine/SCons/Tool/mwcc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/mwld.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/nasm.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/ipk.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/msi.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/rpm.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/src_tarbz2.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/src_targz.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/src_zip.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/tarbz2.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/targz.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/packaging/zip.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/pdf.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/pdflatex.py +2 -3
- data/lib/libv8/scons/engine/SCons/Tool/pdftex.py +2 -3
- data/lib/libv8/scons/engine/SCons/Tool/qt.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/rmic.py +3 -9
- data/lib/libv8/scons/engine/SCons/Tool/rpcgen.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/rpm.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sgiar.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sgic++.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sgicc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sgilink.py +3 -2
- data/lib/libv8/scons/engine/SCons/Tool/sunar.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sunc++.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/suncc.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sunf77.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sunf90.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sunf95.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/sunlink.py +3 -2
- data/lib/libv8/scons/engine/SCons/Tool/swig.py +5 -6
- data/lib/libv8/scons/engine/SCons/Tool/tar.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/tex.py +43 -96
- data/lib/libv8/scons/engine/SCons/Tool/textfile.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/tlib.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/wix.py +2 -2
- data/lib/libv8/scons/engine/SCons/Tool/yacc.py +2 -12
- data/lib/libv8/scons/engine/SCons/Tool/zip.py +2 -2
- data/lib/libv8/scons/engine/SCons/Util.py +3 -3
- data/lib/libv8/scons/engine/SCons/Variables/BoolVariable.py +2 -2
- data/lib/libv8/scons/engine/SCons/Variables/EnumVariable.py +3 -3
- data/lib/libv8/scons/engine/SCons/Variables/ListVariable.py +2 -2
- data/lib/libv8/scons/engine/SCons/Variables/PackageVariable.py +2 -2
- data/lib/libv8/scons/engine/SCons/Variables/PathVariable.py +2 -2
- data/lib/libv8/scons/engine/SCons/Variables/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/Warnings.py +2 -2
- data/lib/libv8/scons/engine/SCons/__init__.py +6 -6
- data/lib/libv8/scons/engine/SCons/compat/__init__.py +2 -2
- data/lib/libv8/scons/engine/SCons/compat/_scons_builtins.py +2 -2
- data/lib/libv8/scons/engine/SCons/compat/_scons_collections.py +2 -2
- data/lib/libv8/scons/engine/SCons/compat/_scons_dbm.py +2 -2
- data/lib/libv8/scons/engine/SCons/compat/_scons_hashlib.py +2 -2
- data/lib/libv8/scons/engine/SCons/compat/_scons_io.py +2 -2
- data/lib/libv8/scons/engine/SCons/cpp.py +2 -2
- data/lib/libv8/scons/engine/SCons/dblite.py +1 -4
- data/lib/libv8/scons/engine/SCons/exitfuncs.py +2 -2
- data/lib/libv8/scons/scons-time.1 +3 -3
- data/lib/libv8/scons/scons.1 +1164 -1170
- data/lib/libv8/scons/sconsign.1 +3 -3
- data/lib/libv8/scons/script/scons +22 -22
- data/lib/libv8/scons/script/scons-time +2 -2
- data/lib/libv8/scons/script/scons.bat +4 -7
- data/lib/libv8/scons/script/sconsign +20 -21
- data/lib/libv8/scons/setup.cfg +1 -0
- data/lib/libv8/scons/setup.py +40 -38
- data/lib/libv8/v8/.gitignore +1 -1
- data/lib/libv8/v8/AUTHORS +2 -0
- data/lib/libv8/v8/ChangeLog +387 -0
- data/lib/libv8/v8/Makefile +171 -0
- data/lib/libv8/v8/SConstruct +124 -51
- data/lib/libv8/v8/build/README.txt +31 -14
- data/lib/libv8/v8/build/all.gyp +11 -4
- data/lib/libv8/v8/build/armu.gypi +6 -2
- data/lib/libv8/v8/build/common.gypi +240 -94
- data/lib/libv8/v8/build/gyp_v8 +32 -4
- data/lib/libv8/v8/build/standalone.gypi +200 -0
- data/lib/libv8/v8/include/v8-debug.h +0 -0
- data/lib/libv8/v8/include/v8-profiler.h +8 -11
- data/lib/libv8/v8/include/v8.h +191 -108
- data/lib/libv8/v8/preparser/SConscript +2 -2
- data/lib/libv8/v8/preparser/preparser-process.cc +3 -3
- data/lib/libv8/v8/preparser/preparser.gyp +42 -0
- data/lib/libv8/v8/src/SConscript +33 -8
- data/lib/libv8/v8/src/accessors.cc +77 -43
- data/lib/libv8/v8/src/api.cc +393 -191
- data/lib/libv8/v8/src/api.h +4 -8
- data/lib/libv8/v8/src/apinatives.js +15 -3
- data/lib/libv8/v8/src/arguments.h +8 -0
- data/lib/libv8/v8/src/arm/assembler-arm.cc +120 -120
- data/lib/libv8/v8/src/arm/assembler-arm.h +92 -43
- data/lib/libv8/v8/src/arm/builtins-arm.cc +32 -39
- data/lib/libv8/v8/src/arm/code-stubs-arm.cc +572 -351
- data/lib/libv8/v8/src/arm/code-stubs-arm.h +8 -77
- data/lib/libv8/v8/src/arm/codegen-arm.h +0 -2
- data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +50 -30
- data/lib/libv8/v8/src/arm/disasm-arm.cc +1 -1
- data/lib/libv8/v8/src/arm/frames-arm.h +9 -5
- data/lib/libv8/v8/src/arm/full-codegen-arm.cc +331 -432
- data/lib/libv8/v8/src/arm/ic-arm.cc +192 -124
- data/lib/libv8/v8/src/arm/lithium-arm.cc +216 -232
- data/lib/libv8/v8/src/arm/lithium-arm.h +106 -259
- data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +633 -642
- data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +4 -4
- data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +1 -3
- data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +260 -185
- data/lib/libv8/v8/src/arm/macro-assembler-arm.h +45 -25
- data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +25 -13
- data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +3 -0
- data/lib/libv8/v8/src/arm/stub-cache-arm.cc +413 -226
- data/lib/libv8/v8/src/array.js +38 -18
- data/lib/libv8/v8/src/assembler.cc +12 -5
- data/lib/libv8/v8/src/assembler.h +15 -9
- data/lib/libv8/v8/src/ast-inl.h +34 -25
- data/lib/libv8/v8/src/ast.cc +141 -72
- data/lib/libv8/v8/src/ast.h +255 -181
- data/lib/libv8/v8/src/bignum.cc +3 -4
- data/lib/libv8/v8/src/bootstrapper.cc +55 -11
- data/lib/libv8/v8/src/bootstrapper.h +3 -2
- data/lib/libv8/v8/src/builtins.cc +8 -2
- data/lib/libv8/v8/src/builtins.h +4 -0
- data/lib/libv8/v8/src/cached-powers.cc +8 -4
- data/lib/libv8/v8/src/checks.h +3 -3
- data/lib/libv8/v8/src/code-stubs.cc +173 -28
- data/lib/libv8/v8/src/code-stubs.h +104 -148
- data/lib/libv8/v8/src/codegen.cc +8 -8
- data/lib/libv8/v8/src/compilation-cache.cc +2 -47
- data/lib/libv8/v8/src/compilation-cache.h +0 -10
- data/lib/libv8/v8/src/compiler.cc +27 -16
- data/lib/libv8/v8/src/compiler.h +13 -18
- data/lib/libv8/v8/src/contexts.cc +107 -72
- data/lib/libv8/v8/src/contexts.h +70 -34
- data/lib/libv8/v8/src/conversions-inl.h +572 -14
- data/lib/libv8/v8/src/conversions.cc +9 -707
- data/lib/libv8/v8/src/conversions.h +23 -12
- data/lib/libv8/v8/src/cpu-profiler-inl.h +2 -19
- data/lib/libv8/v8/src/cpu-profiler.cc +4 -21
- data/lib/libv8/v8/src/cpu-profiler.h +8 -17
- data/lib/libv8/v8/src/d8-debug.cc +5 -3
- data/lib/libv8/v8/src/d8-debug.h +6 -7
- data/lib/libv8/v8/src/d8-posix.cc +1 -10
- data/lib/libv8/v8/src/d8.cc +721 -219
- data/lib/libv8/v8/src/d8.gyp +37 -12
- data/lib/libv8/v8/src/d8.h +141 -19
- data/lib/libv8/v8/src/d8.js +17 -8
- data/lib/libv8/v8/src/date.js +16 -5
- data/lib/libv8/v8/src/dateparser-inl.h +242 -39
- data/lib/libv8/v8/src/dateparser.cc +38 -4
- data/lib/libv8/v8/src/dateparser.h +170 -28
- data/lib/libv8/v8/src/debug-agent.cc +5 -3
- data/lib/libv8/v8/src/debug-agent.h +11 -7
- data/lib/libv8/v8/src/debug-debugger.js +65 -34
- data/lib/libv8/v8/src/debug.cc +30 -60
- data/lib/libv8/v8/src/debug.h +5 -3
- data/lib/libv8/v8/src/deoptimizer.cc +227 -10
- data/lib/libv8/v8/src/deoptimizer.h +133 -9
- data/lib/libv8/v8/src/disassembler.cc +22 -14
- data/lib/libv8/v8/src/diy-fp.cc +4 -3
- data/lib/libv8/v8/src/diy-fp.h +3 -3
- data/lib/libv8/v8/src/elements.cc +634 -0
- data/lib/libv8/v8/src/elements.h +95 -0
- data/lib/libv8/v8/src/execution.cc +5 -21
- data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +3 -1
- data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +1 -1
- data/lib/libv8/v8/src/extensions/experimental/collator.cc +6 -2
- data/lib/libv8/v8/src/extensions/experimental/collator.h +1 -2
- data/lib/libv8/v8/src/extensions/experimental/datetime-format.cc +384 -0
- data/lib/libv8/v8/src/extensions/experimental/datetime-format.h +83 -0
- data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +18 -7
- data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +12 -16
- data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +1 -1
- data/lib/libv8/v8/src/extensions/experimental/i18n-js2c.py +126 -0
- data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +3 -4
- data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +1 -1
- data/lib/libv8/v8/src/{shell.h → extensions/experimental/i18n-natives.h} +8 -20
- data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +45 -1
- data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +21 -1
- data/lib/libv8/v8/src/extensions/experimental/i18n.js +211 -11
- data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +4 -3
- data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +1 -1
- data/lib/libv8/v8/src/extensions/experimental/number-format.cc +374 -0
- data/lib/libv8/v8/src/extensions/experimental/number-format.h +71 -0
- data/lib/libv8/v8/src/factory.cc +89 -18
- data/lib/libv8/v8/src/factory.h +36 -8
- data/lib/libv8/v8/src/flag-definitions.h +11 -44
- data/lib/libv8/v8/src/frames-inl.h +8 -1
- data/lib/libv8/v8/src/frames.cc +39 -3
- data/lib/libv8/v8/src/frames.h +10 -3
- data/lib/libv8/v8/src/full-codegen.cc +311 -293
- data/lib/libv8/v8/src/full-codegen.h +183 -143
- data/lib/libv8/v8/src/func-name-inferrer.cc +29 -15
- data/lib/libv8/v8/src/func-name-inferrer.h +19 -9
- data/lib/libv8/v8/src/gdb-jit.cc +658 -55
- data/lib/libv8/v8/src/gdb-jit.h +6 -2
- data/lib/libv8/v8/src/global-handles.cc +368 -312
- data/lib/libv8/v8/src/global-handles.h +29 -36
- data/lib/libv8/v8/src/globals.h +3 -1
- data/lib/libv8/v8/src/handles.cc +43 -69
- data/lib/libv8/v8/src/handles.h +21 -16
- data/lib/libv8/v8/src/heap-inl.h +11 -13
- data/lib/libv8/v8/src/heap-profiler.cc +0 -999
- data/lib/libv8/v8/src/heap-profiler.h +0 -303
- data/lib/libv8/v8/src/heap.cc +366 -141
- data/lib/libv8/v8/src/heap.h +87 -26
- data/lib/libv8/v8/src/hydrogen-instructions.cc +192 -81
- data/lib/libv8/v8/src/hydrogen-instructions.h +711 -482
- data/lib/libv8/v8/src/hydrogen.cc +1146 -629
- data/lib/libv8/v8/src/hydrogen.h +100 -64
- data/lib/libv8/v8/src/ia32/assembler-ia32.cc +19 -0
- data/lib/libv8/v8/src/ia32/assembler-ia32.h +15 -2
- data/lib/libv8/v8/src/ia32/builtins-ia32.cc +34 -39
- data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +675 -377
- data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +8 -69
- data/lib/libv8/v8/src/ia32/codegen-ia32.cc +1 -0
- data/lib/libv8/v8/src/ia32/codegen-ia32.h +0 -2
- data/lib/libv8/v8/src/ia32/cpu-ia32.cc +3 -2
- data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +28 -3
- data/lib/libv8/v8/src/ia32/disasm-ia32.cc +21 -10
- data/lib/libv8/v8/src/ia32/frames-ia32.h +6 -5
- data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +459 -465
- data/lib/libv8/v8/src/ia32/ic-ia32.cc +196 -147
- data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +575 -650
- data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +19 -21
- data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +7 -2
- data/lib/libv8/v8/src/ia32/lithium-ia32.cc +261 -256
- data/lib/libv8/v8/src/ia32/lithium-ia32.h +234 -335
- data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +224 -67
- data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +63 -19
- data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +22 -8
- data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +3 -0
- data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +380 -239
- data/lib/libv8/v8/src/ic.cc +198 -234
- data/lib/libv8/v8/src/ic.h +32 -30
- data/lib/libv8/v8/src/interpreter-irregexp.cc +6 -4
- data/lib/libv8/v8/src/isolate.cc +112 -95
- data/lib/libv8/v8/src/isolate.h +55 -71
- data/lib/libv8/v8/src/json-parser.h +486 -48
- data/lib/libv8/v8/src/json.js +28 -23
- data/lib/libv8/v8/src/jsregexp.cc +163 -208
- data/lib/libv8/v8/src/jsregexp.h +0 -1
- data/lib/libv8/v8/src/lithium-allocator-inl.h +29 -27
- data/lib/libv8/v8/src/lithium-allocator.cc +22 -17
- data/lib/libv8/v8/src/lithium-allocator.h +8 -8
- data/lib/libv8/v8/src/lithium.cc +16 -11
- data/lib/libv8/v8/src/lithium.h +31 -34
- data/lib/libv8/v8/src/liveedit.cc +111 -15
- data/lib/libv8/v8/src/liveedit.h +3 -4
- data/lib/libv8/v8/src/liveobjectlist.cc +116 -80
- data/lib/libv8/v8/src/liveobjectlist.h +2 -2
- data/lib/libv8/v8/src/log-inl.h +0 -4
- data/lib/libv8/v8/src/log-utils.cc +25 -143
- data/lib/libv8/v8/src/log-utils.h +13 -92
- data/lib/libv8/v8/src/log.cc +26 -249
- data/lib/libv8/v8/src/log.h +6 -17
- data/lib/libv8/v8/src/macros.py +9 -6
- data/lib/libv8/v8/src/mark-compact.cc +276 -56
- data/lib/libv8/v8/src/mark-compact.h +20 -0
- data/lib/libv8/v8/src/messages.js +93 -39
- data/lib/libv8/v8/src/mips/assembler-mips-inl.h +9 -3
- data/lib/libv8/v8/src/mips/assembler-mips.cc +297 -189
- data/lib/libv8/v8/src/mips/assembler-mips.h +121 -54
- data/lib/libv8/v8/src/mips/builtins-mips.cc +23 -24
- data/lib/libv8/v8/src/mips/code-stubs-mips.cc +484 -263
- data/lib/libv8/v8/src/mips/code-stubs-mips.h +8 -83
- data/lib/libv8/v8/src/mips/codegen-mips.h +0 -2
- data/lib/libv8/v8/src/mips/constants-mips.h +37 -11
- data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +6 -1
- data/lib/libv8/v8/src/mips/frames-mips.h +8 -7
- data/lib/libv8/v8/src/mips/full-codegen-mips.cc +258 -419
- data/lib/libv8/v8/src/mips/ic-mips.cc +181 -121
- data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +640 -382
- data/lib/libv8/v8/src/mips/macro-assembler-mips.h +94 -89
- data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +23 -10
- data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +6 -1
- data/lib/libv8/v8/src/mips/simulator-mips.cc +249 -49
- data/lib/libv8/v8/src/mips/simulator-mips.h +25 -1
- data/lib/libv8/v8/src/mips/stub-cache-mips.cc +373 -161
- data/lib/libv8/v8/src/mirror-debugger.js +55 -8
- data/lib/libv8/v8/src/misc-intrinsics.h +89 -0
- data/lib/libv8/v8/src/mksnapshot.cc +36 -4
- data/lib/libv8/v8/src/natives.h +5 -2
- data/lib/libv8/v8/src/objects-debug.cc +73 -6
- data/lib/libv8/v8/src/objects-inl.h +529 -164
- data/lib/libv8/v8/src/objects-printer.cc +67 -12
- data/lib/libv8/v8/src/objects-visiting.cc +13 -2
- data/lib/libv8/v8/src/objects-visiting.h +41 -1
- data/lib/libv8/v8/src/objects.cc +2200 -1177
- data/lib/libv8/v8/src/objects.h +912 -283
- data/lib/libv8/v8/src/parser.cc +566 -371
- data/lib/libv8/v8/src/parser.h +35 -33
- data/lib/libv8/v8/src/platform-cygwin.cc +10 -25
- data/lib/libv8/v8/src/platform-freebsd.cc +4 -29
- data/lib/libv8/v8/src/platform-linux.cc +60 -57
- data/lib/libv8/v8/src/platform-macos.cc +4 -27
- data/lib/libv8/v8/src/platform-nullos.cc +3 -16
- data/lib/libv8/v8/src/platform-openbsd.cc +247 -85
- data/lib/libv8/v8/src/platform-posix.cc +43 -1
- data/lib/libv8/v8/src/platform-solaris.cc +151 -112
- data/lib/libv8/v8/src/platform-tls.h +1 -1
- data/lib/libv8/v8/src/platform-win32.cc +65 -39
- data/lib/libv8/v8/src/platform.h +17 -14
- data/lib/libv8/v8/src/preparse-data-format.h +2 -2
- data/lib/libv8/v8/src/preparse-data.h +8 -2
- data/lib/libv8/v8/src/preparser-api.cc +2 -18
- data/lib/libv8/v8/src/preparser.cc +106 -65
- data/lib/libv8/v8/src/preparser.h +26 -5
- data/lib/libv8/v8/src/prettyprinter.cc +25 -43
- data/lib/libv8/v8/src/profile-generator-inl.h +0 -4
- data/lib/libv8/v8/src/profile-generator.cc +213 -34
- data/lib/libv8/v8/src/profile-generator.h +9 -9
- data/lib/libv8/v8/src/property.h +1 -0
- data/lib/libv8/v8/src/proxy.js +74 -4
- data/lib/libv8/v8/src/regexp-macro-assembler.cc +10 -6
- data/lib/libv8/v8/src/regexp.js +16 -11
- data/lib/libv8/v8/src/rewriter.cc +24 -133
- data/lib/libv8/v8/src/runtime-profiler.cc +27 -151
- data/lib/libv8/v8/src/runtime-profiler.h +5 -31
- data/lib/libv8/v8/src/runtime.cc +1450 -681
- data/lib/libv8/v8/src/runtime.h +47 -31
- data/lib/libv8/v8/src/runtime.js +2 -1
- data/lib/libv8/v8/src/scanner-base.cc +358 -220
- data/lib/libv8/v8/src/scanner-base.h +30 -138
- data/lib/libv8/v8/src/scanner.cc +0 -18
- data/lib/libv8/v8/src/scanner.h +0 -15
- data/lib/libv8/v8/src/scopeinfo.cc +3 -1
- data/lib/libv8/v8/src/scopeinfo.h +1 -6
- data/lib/libv8/v8/src/scopes.cc +243 -253
- data/lib/libv8/v8/src/scopes.h +58 -109
- data/lib/libv8/v8/src/serialize.cc +12 -54
- data/lib/libv8/v8/src/serialize.h +47 -0
- data/lib/libv8/v8/src/small-pointer-list.h +25 -0
- data/lib/libv8/v8/src/spaces-inl.h +4 -50
- data/lib/libv8/v8/src/spaces.cc +64 -131
- data/lib/libv8/v8/src/spaces.h +19 -70
- data/lib/libv8/v8/src/string-stream.cc +3 -1
- data/lib/libv8/v8/src/string.js +10 -6
- data/lib/libv8/v8/src/strtod.cc +7 -3
- data/lib/libv8/v8/src/stub-cache.cc +59 -129
- data/lib/libv8/v8/src/stub-cache.h +42 -54
- data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +1447 -1339
- data/lib/libv8/v8/src/token.cc +4 -4
- data/lib/libv8/v8/src/token.h +6 -5
- data/lib/libv8/v8/src/type-info.cc +173 -129
- data/lib/libv8/v8/src/type-info.h +40 -22
- data/lib/libv8/v8/src/utils.cc +25 -304
- data/lib/libv8/v8/src/utils.h +118 -3
- data/lib/libv8/v8/src/v8-counters.h +3 -6
- data/lib/libv8/v8/src/v8.cc +34 -27
- data/lib/libv8/v8/src/v8.h +7 -7
- data/lib/libv8/v8/src/v8conversions.cc +129 -0
- data/lib/libv8/v8/src/v8conversions.h +60 -0
- data/lib/libv8/v8/src/v8globals.h +15 -6
- data/lib/libv8/v8/src/v8natives.js +300 -78
- data/lib/libv8/v8/src/v8threads.cc +14 -6
- data/lib/libv8/v8/src/v8threads.h +4 -1
- data/lib/libv8/v8/src/v8utils.cc +360 -0
- data/lib/libv8/v8/src/v8utils.h +17 -66
- data/lib/libv8/v8/src/variables.cc +7 -12
- data/lib/libv8/v8/src/variables.h +12 -10
- data/lib/libv8/v8/src/version.cc +2 -2
- data/lib/libv8/v8/src/vm-state-inl.h +0 -41
- data/lib/libv8/v8/src/vm-state.h +0 -11
- data/lib/libv8/v8/src/weakmap.js +103 -0
- data/lib/libv8/v8/src/x64/assembler-x64.h +6 -3
- data/lib/libv8/v8/src/x64/builtins-x64.cc +25 -22
- data/lib/libv8/v8/src/x64/code-stubs-x64.cc +523 -250
- data/lib/libv8/v8/src/x64/code-stubs-x64.h +8 -71
- data/lib/libv8/v8/src/x64/codegen-x64.cc +1 -0
- data/lib/libv8/v8/src/x64/codegen-x64.h +0 -2
- data/lib/libv8/v8/src/x64/cpu-x64.cc +2 -1
- data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +40 -8
- data/lib/libv8/v8/src/x64/disasm-x64.cc +12 -10
- data/lib/libv8/v8/src/x64/frames-x64.h +7 -6
- data/lib/libv8/v8/src/x64/full-codegen-x64.cc +310 -415
- data/lib/libv8/v8/src/x64/ic-x64.cc +180 -117
- data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +411 -523
- data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +11 -6
- data/lib/libv8/v8/src/x64/lithium-x64.cc +191 -216
- data/lib/libv8/v8/src/x64/lithium-x64.h +112 -263
- data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +177 -61
- data/lib/libv8/v8/src/x64/macro-assembler-x64.h +23 -7
- data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +21 -9
- data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +6 -0
- data/lib/libv8/v8/src/x64/stub-cache-x64.cc +273 -107
- data/lib/libv8/v8/src/zone.cc +31 -22
- data/lib/libv8/v8/src/zone.h +12 -6
- data/lib/libv8/v8/tools/codemap.js +8 -0
- data/lib/libv8/v8/tools/gcmole/Makefile +43 -0
- data/lib/libv8/v8/tools/gcmole/gcmole.lua +0 -2
- data/lib/libv8/v8/tools/gdb-v8-support.py +154 -0
- data/lib/libv8/v8/tools/grokdump.py +44 -35
- data/lib/libv8/v8/tools/gyp/v8.gyp +94 -248
- data/lib/libv8/v8/tools/js2c.py +83 -52
- data/lib/libv8/v8/tools/linux-tick-processor +4 -6
- data/lib/libv8/v8/tools/ll_prof.py +3 -3
- data/lib/libv8/v8/tools/oom_dump/README +3 -1
- data/lib/libv8/v8/tools/presubmit.py +11 -4
- data/lib/libv8/v8/tools/profile.js +46 -2
- data/lib/libv8/v8/tools/splaytree.js +11 -0
- data/lib/libv8/v8/tools/stats-viewer.py +15 -11
- data/lib/libv8/v8/tools/test-wrapper-gypbuild.py +227 -0
- data/lib/libv8/v8/tools/test.py +28 -8
- data/lib/libv8/v8/tools/tickprocessor.js +0 -16
- data/lib/libv8/version.rb +1 -1
- data/libv8.gemspec +2 -2
- metadata +31 -19
- data/lib/libv8/scons/engine/SCons/Tool/f03.py +0 -63
- 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
|
-
|
129
|
-
|
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
|
92
|
+
void RuntimeProfiler::Optimize(JSFunction* function) {
|
152
93
|
ASSERT(function->IsOptimizable());
|
153
94
|
if (FLAG_trace_opt) {
|
154
|
-
PrintF("[marking
|
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->
|
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
|
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::
|
449
|
-
|
450
|
-
|
451
|
-
|
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
|
-
|
474
|
-
|
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
|
-
//
|
90
|
-
//
|
91
|
-
|
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
|
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()
|
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
|
|
data/lib/libv8/v8/src/runtime.cc
CHANGED
@@ -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
|
85
|
-
// with the given name. If the
|
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
|
88
|
-
RUNTIME_ASSERT(
|
89
|
-
int name =
|
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
|
92
|
-
// the given name. If the
|
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
|
95
|
-
RUNTIME_ASSERT(
|
96
|
-
double name = (
|
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
|
-
|
222
|
-
|
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
|
-
|
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
|
-
|
515
|
+
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
|
503
516
|
CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
|
504
|
-
|
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
|
-
|
541
|
+
CONVERT_SMI_ARG_CHECKED(literals_index, 1);
|
529
542
|
CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
|
530
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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*,
|
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
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
//
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
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
|
-
|
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
|
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
|
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 =
|
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
|
1234
|
-
context = Handle<Context>(context->
|
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
|
1523
|
-
context = Handle<Context>(context->
|
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
|
-
//
|
1547
|
-
//
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1658
|
-
if (elements_count
|
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*,
|
1801
|
-
|
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
|
-
|
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 =
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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<
|
2298
|
-
|
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<
|
2304
|
-
|
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
|
-
|
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
|
-
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
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
|
-
|
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
|
2897
|
-
|
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
|
2903
|
-
Vector<const char> pat_vector = seq_pat
|
2904
|
-
if (seq_sub
|
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
|
3082
|
+
seq_sub.ToAsciiVector(),
|
2907
3083
|
pat_vector,
|
2908
3084
|
start_index);
|
2909
3085
|
}
|
2910
3086
|
return SearchString(isolate,
|
2911
|
-
seq_sub
|
3087
|
+
seq_sub.ToUC16Vector(),
|
2912
3088
|
pat_vector,
|
2913
3089
|
start_index);
|
2914
3090
|
}
|
2915
|
-
Vector<const uc16> pat_vector = seq_pat
|
2916
|
-
if (seq_sub
|
3091
|
+
Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
|
3092
|
+
if (seq_sub.IsAscii()) {
|
2917
3093
|
return SearchString(isolate,
|
2918
|
-
seq_sub
|
3094
|
+
seq_sub.ToAsciiVector(),
|
2919
3095
|
pat_vector,
|
2920
3096
|
start_index);
|
2921
3097
|
}
|
2922
3098
|
return SearchString(isolate,
|
2923
|
-
seq_sub
|
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
|
-
|
3185
|
+
String::FlatContent sub_content = sub->GetFlatContent();
|
3186
|
+
String::FlatContent pat_content = pat->GetFlatContent();
|
3009
3187
|
|
3010
|
-
if (
|
3011
|
-
Vector<const char> pat_vector =
|
3012
|
-
if (
|
3013
|
-
position = StringMatchBackwards(
|
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(
|
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 =
|
3023
|
-
if (
|
3024
|
-
position = StringMatchBackwards(
|
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(
|
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 (
|
3097
|
-
|
3098
|
-
|
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
|
-
|
3101
|
-
|
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
|
-
|
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
|
-
|
3145
|
-
|
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
|
-
|
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>
|
3157
|
-
|
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
|
-
|
3244
|
-
|
3245
|
-
|
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
|
-
|
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
|
-
|
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 =
|
3262
|
-
if (
|
3444
|
+
Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
|
3445
|
+
if (pattern_content.IsAscii()) {
|
3263
3446
|
if (SearchStringMultiple(isolate,
|
3264
3447
|
subject_vector,
|
3265
|
-
|
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
|
-
|
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
|
-
|
3325
|
-
|
3326
|
-
|
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
|
3409
|
-
|
3410
|
-
|
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
|
3418
|
-
|
3419
|
-
|
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())
|
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
|
-
}
|
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()
|
3540
|
-
int 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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
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,
|
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
|
-
|
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->
|
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<
|
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 (
|
4311
|
+
if (receiver->IsStringObjectWithCharacterAt(index)) {
|
4070
4312
|
return isolate->heap()->true_value();
|
4071
4313
|
}
|
4072
4314
|
|
4073
|
-
return
|
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
|
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
|
-
|
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
|
-
|
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
|
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*,
|
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()->
|
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(
|
4410
|
+
CONVERT_CHECKED(JSReceiver, object, args[0]);
|
4168
4411
|
CONVERT_CHECKED(String, key, args[1]);
|
4169
|
-
|
4412
|
+
CONVERT_SMI_ARG_CHECKED(strict, 2);
|
4170
4413
|
return object->DeleteProperty(key, (strict == kStrictMode)
|
4171
|
-
?
|
4172
|
-
:
|
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
|
4237
|
-
if (args[0]->
|
4238
|
-
|
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 (
|
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
|
-
|
4384
|
-
if (
|
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
|
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:
|
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
|
-
|
5107
|
-
|
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
|
-
|
5133
|
-
|
5134
|
-
|
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
|
-
|
5443
|
+
String::FlatContent flat = str->GetFlatContent();
|
5444
|
+
ASSERT(flat.IsFlat());
|
5445
|
+
if (flat.IsTwoByte()) {
|
5183
5446
|
return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate,
|
5184
|
-
|
5447
|
+
flat.ToUC16Vector());
|
5185
5448
|
} else {
|
5186
5449
|
return QuoteJsonString<char, SeqAsciiString, false>(isolate,
|
5187
|
-
|
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
|
-
|
5467
|
+
String::FlatContent flat = str->GetFlatContent();
|
5468
|
+
if (flat.IsTwoByte()) {
|
5205
5469
|
return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
|
5206
|
-
|
5470
|
+
flat.ToUC16Vector());
|
5207
5471
|
} else {
|
5208
5472
|
return QuoteJsonString<char, SeqAsciiString, true>(isolate,
|
5209
|
-
|
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
|
-
|
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
|
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
|
5615
|
-
|
5616
|
-
|
5617
|
-
|
5618
|
-
|
5619
|
-
|
5620
|
-
|
5621
|
-
|
5622
|
-
|
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
|
-
|
6020
|
+
pattern_content.ToUC16Vector(),
|
5627
6021
|
&indices,
|
5628
6022
|
limit);
|
5629
6023
|
}
|
5630
6024
|
} else {
|
5631
|
-
Vector<const uc16> subject_vector =
|
6025
|
+
Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
|
5632
6026
|
if (pattern->IsAsciiRepresentation()) {
|
5633
6027
|
FindStringIndices(isolate,
|
5634
6028
|
subject_vector,
|
5635
|
-
|
6029
|
+
pattern_content.ToAsciiVector(),
|
5636
6030
|
&indices,
|
5637
6031
|
limit);
|
5638
6032
|
} else {
|
5639
6033
|
FindStringIndices(isolate,
|
5640
6034
|
subject_vector,
|
5641
|
-
|
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()->
|
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
|
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
|
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
|
-
|
5736
|
-
|
5737
|
-
|
5738
|
-
|
5739
|
-
|
5740
|
-
|
5741
|
-
|
5742
|
-
|
5743
|
-
|
5744
|
-
|
5745
|
-
|
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
|
-
|
5750
|
-
|
5751
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
5891
|
-
|
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
|
-
|
5901
|
-
|
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
|
-
|
5911
|
-
|
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
|
-
|
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
|
-
|
5938
|
-
|
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
|
-
|
5948
|
-
|
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 =
|
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 =
|
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
|
-
|
6405
|
-
|
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
|
-
|
6442
|
-
|
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
|
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)
|
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
|
-
|
6476
|
-
|
6878
|
+
x_scaled = -x_value;
|
6879
|
+
y_scaled = -y_value;
|
6477
6880
|
}
|
6478
6881
|
|
6479
|
-
|
6480
|
-
|
6481
|
-
|
6482
|
-
|
6483
|
-
|
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
|
-
//
|
6487
|
-
int
|
6488
|
-
int
|
6489
|
-
|
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
|
-
|
6499
|
-
|
6500
|
-
|
6501
|
-
|
6502
|
-
|
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
|
-
|
6506
|
-
|
6507
|
-
|
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
|
-
|
6545
|
-
|
6546
|
-
|
6547
|
-
|
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 =
|
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 =
|
6555
|
-
if (
|
6556
|
-
Vector<const char> y_chars =
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
6649
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =
|
7144
|
+
int y = args.smi_at(1);
|
6727
7145
|
return isolate->heap()->NumberFromDouble(power_double_int(x, y));
|
6728
7146
|
}
|
6729
7147
|
|
6730
|
-
|
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
|
-
|
6740
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
6874
|
-
|
6875
|
-
|
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
|
-
|
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 =
|
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
|
-
//
|
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>(
|
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()->
|
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*,
|
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
|
-
|
7767
|
-
|
7768
|
-
|
7769
|
-
|
7770
|
-
|
7771
|
-
|
7772
|
-
|
7773
|
-
|
7774
|
-
|
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
|
-
|
7787
|
-
|
7788
|
-
|
7789
|
-
|
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
|
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*,
|
8331
|
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
|
7800
8332
|
NoHandleAllocation ha;
|
7801
|
-
ASSERT(args.length() ==
|
7802
|
-
|
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*,
|
8357
|
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
|
7807
8358
|
NoHandleAllocation ha;
|
7808
|
-
ASSERT(args.length() ==
|
7809
|
-
|
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
|
-
|
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,
|
8417
|
+
return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
|
7845
8418
|
} else {
|
7846
|
-
return object->DeleteProperty(*name,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
8291
|
-
|
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(
|
8296
|
-
result = DateParser::Parse(
|
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
|
-
|
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
|
-
|
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<
|
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,
|
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
|
-
|
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 =
|
8588
|
-
|
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->
|
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->
|
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->
|
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->
|
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
|
-
|
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>(
|
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
|
-
|
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
|
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:
|
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
|
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
|
-
|
9675
|
-
|
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
|
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<
|
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
|
9712
|
-
|
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
|
-
|
9717
|
-
|
9718
|
-
|
9719
|
-
|
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
|
-
|
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 (!
|
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.
|
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 <
|
9790
|
-
argument_count =
|
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,
|
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
|
9826
|
-
|
9827
|
-
|
9828
|
-
|
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.
|
9843
|
-
|
9844
|
-
|
9845
|
-
|
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
|
9871
|
-
//
|
9872
|
-
//
|
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
|
-
|
9903
|
-
|
9904
|
-
|
9905
|
-
|
9906
|
-
|
9907
|
-
|
9908
|
-
|
9909
|
-
|
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(
|
9923
|
-
|
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>(
|
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>(
|
10636
|
+
Handle<Object>(frame_inspector.GetExpression(i)),
|
9953
10637
|
NONE,
|
9954
10638
|
kNonStrictMode),
|
9955
10639
|
Handle<JSObject>());
|
9956
10640
|
}
|
9957
10641
|
|
9958
|
-
|
9959
|
-
|
9960
|
-
|
9961
|
-
|
9962
|
-
|
9963
|
-
|
9964
|
-
|
9965
|
-
|
9966
|
-
|
9967
|
-
|
9968
|
-
|
9969
|
-
|
9970
|
-
if (function_context->
|
9971
|
-
|
9972
|
-
|
9973
|
-
|
9974
|
-
|
9975
|
-
|
9976
|
-
|
9977
|
-
|
9978
|
-
|
9979
|
-
|
9980
|
-
|
9981
|
-
|
9982
|
-
|
9983
|
-
|
9984
|
-
|
9985
|
-
|
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->
|
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
|
-
|
10073
|
-
|
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,
|
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_->
|
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_->
|
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
|
-
|
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() ||
|
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_->
|
10860
|
+
if (context_->IsFunctionContext()) {
|
10154
10861
|
return ScopeTypeClosure;
|
10155
10862
|
}
|
10156
|
-
|
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
|
-
|
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
|
-
|
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<
|
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
|
-
|
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
|
-
|
10238
|
-
|
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<
|
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
|
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:
|
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() ==
|
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,
|
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
|
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(
|
10722
|
-
Handle<
|
10723
|
-
|
10724
|
-
|
10725
|
-
|
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
|
-
|
10730
|
-
Handle<
|
10731
|
-
Handle<Context>
|
10732
|
-
|
10733
|
-
|
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
|
-
|
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,
|
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() ==
|
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
|
-
|
10809
|
-
|
10810
|
-
|
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(
|
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
|
10862
|
-
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
|
-
|
10866
|
-
|
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,
|
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
|
-
|
12329
|
+
CONVERT_SMI_ARG_CHECKED(id, 0);
|
11589
12330
|
bool success = LiveObjectList::Delete(id);
|
11590
|
-
return
|
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
|
-
|
11607
|
-
|
11608
|
-
|
11609
|
-
|
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
|
-
|
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
|
-
|
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 =
|
12407
|
+
start = args.smi_at(3);
|
11668
12408
|
}
|
11669
12409
|
int limit = Smi::kMaxValue;
|
11670
12410
|
if (args[4]->IsSmi()) {
|
11671
|
-
limit =
|
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
|
-
|
11691
|
-
|
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
|
-
|
11713
|
-
|
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
|
-
|
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
|
-
|
11755
|
-
|
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
|
-
|
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
|
-
|
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,
|
11848
|
-
|
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.
|
11862
|
-
|
11863
|
-
//
|
11864
|
-
//
|
11865
|
-
|
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",
|
11946
|
-
|
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
|
-
|
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
|
|