libv8 3.3.10.4 → 3.5.10.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|