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
|
@@ -58,35 +58,14 @@ class TranscendentalCacheStub: public CodeStub {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
class ToBooleanStub: public CodeStub {
|
|
62
|
-
public:
|
|
63
|
-
explicit ToBooleanStub(Register tos) : tos_(tos) { }
|
|
64
|
-
|
|
65
|
-
void Generate(MacroAssembler* masm);
|
|
66
|
-
|
|
67
|
-
private:
|
|
68
|
-
Register tos_;
|
|
69
|
-
Major MajorKey() { return ToBoolean; }
|
|
70
|
-
int MinorKey() { return tos_.code(); }
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
|
|
74
61
|
class UnaryOpStub: public CodeStub {
|
|
75
62
|
public:
|
|
76
|
-
UnaryOpStub(Token::Value op,
|
|
63
|
+
UnaryOpStub(Token::Value op,
|
|
64
|
+
UnaryOverwriteMode mode,
|
|
65
|
+
UnaryOpIC::TypeInfo operand_type = UnaryOpIC::UNINITIALIZED)
|
|
77
66
|
: op_(op),
|
|
78
67
|
mode_(mode),
|
|
79
|
-
operand_type_(
|
|
80
|
-
name_(NULL) {
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
UnaryOpStub(
|
|
84
|
-
int key,
|
|
85
|
-
UnaryOpIC::TypeInfo operand_type)
|
|
86
|
-
: op_(OpBits::decode(key)),
|
|
87
|
-
mode_(ModeBits::decode(key)),
|
|
88
|
-
operand_type_(operand_type),
|
|
89
|
-
name_(NULL) {
|
|
68
|
+
operand_type_(operand_type) {
|
|
90
69
|
}
|
|
91
70
|
|
|
92
71
|
private:
|
|
@@ -96,20 +75,7 @@ class UnaryOpStub: public CodeStub {
|
|
|
96
75
|
// Operand type information determined at runtime.
|
|
97
76
|
UnaryOpIC::TypeInfo operand_type_;
|
|
98
77
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const char* GetName();
|
|
102
|
-
|
|
103
|
-
#ifdef DEBUG
|
|
104
|
-
void Print() {
|
|
105
|
-
PrintF("UnaryOpStub %d (op %s), "
|
|
106
|
-
"(mode %d, runtime_type_info %s)\n",
|
|
107
|
-
MinorKey(),
|
|
108
|
-
Token::String(op_),
|
|
109
|
-
static_cast<int>(mode_),
|
|
110
|
-
UnaryOpIC::GetName(operand_type_));
|
|
111
|
-
}
|
|
112
|
-
#endif
|
|
78
|
+
virtual void PrintName(StringStream* stream);
|
|
113
79
|
|
|
114
80
|
class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
|
|
115
81
|
class OpBits: public BitField<Token::Value, 1, 7> {};
|
|
@@ -163,8 +129,7 @@ class BinaryOpStub: public CodeStub {
|
|
|
163
129
|
: op_(op),
|
|
164
130
|
mode_(mode),
|
|
165
131
|
operands_type_(BinaryOpIC::UNINITIALIZED),
|
|
166
|
-
result_type_(BinaryOpIC::UNINITIALIZED)
|
|
167
|
-
name_(NULL) {
|
|
132
|
+
result_type_(BinaryOpIC::UNINITIALIZED) {
|
|
168
133
|
use_vfp3_ = CpuFeatures::IsSupported(VFP3);
|
|
169
134
|
ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
|
|
170
135
|
}
|
|
@@ -177,8 +142,7 @@ class BinaryOpStub: public CodeStub {
|
|
|
177
142
|
mode_(ModeBits::decode(key)),
|
|
178
143
|
use_vfp3_(VFP3Bits::decode(key)),
|
|
179
144
|
operands_type_(operands_type),
|
|
180
|
-
result_type_(result_type)
|
|
181
|
-
name_(NULL) { }
|
|
145
|
+
result_type_(result_type) { }
|
|
182
146
|
|
|
183
147
|
private:
|
|
184
148
|
enum SmiCodeGenerateHeapNumberResults {
|
|
@@ -194,20 +158,7 @@ class BinaryOpStub: public CodeStub {
|
|
|
194
158
|
BinaryOpIC::TypeInfo operands_type_;
|
|
195
159
|
BinaryOpIC::TypeInfo result_type_;
|
|
196
160
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const char* GetName();
|
|
200
|
-
|
|
201
|
-
#ifdef DEBUG
|
|
202
|
-
void Print() {
|
|
203
|
-
PrintF("BinaryOpStub %d (op %s), "
|
|
204
|
-
"(mode %d, runtime_type_info %s)\n",
|
|
205
|
-
MinorKey(),
|
|
206
|
-
Token::String(op_),
|
|
207
|
-
static_cast<int>(mode_),
|
|
208
|
-
BinaryOpIC::GetName(operands_type_));
|
|
209
|
-
}
|
|
210
|
-
#endif
|
|
161
|
+
virtual void PrintName(StringStream* stream);
|
|
211
162
|
|
|
212
163
|
// Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
|
|
213
164
|
class ModeBits: public BitField<OverwriteMode, 0, 2> {};
|
|
@@ -391,12 +342,6 @@ class WriteInt32ToHeapNumberStub : public CodeStub {
|
|
|
391
342
|
}
|
|
392
343
|
|
|
393
344
|
void Generate(MacroAssembler* masm);
|
|
394
|
-
|
|
395
|
-
const char* GetName() { return "WriteInt32ToHeapNumberStub"; }
|
|
396
|
-
|
|
397
|
-
#ifdef DEBUG
|
|
398
|
-
void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); }
|
|
399
|
-
#endif
|
|
400
345
|
};
|
|
401
346
|
|
|
402
347
|
|
|
@@ -423,8 +368,6 @@ class NumberToStringStub: public CodeStub {
|
|
|
423
368
|
int MinorKey() { return 0; }
|
|
424
369
|
|
|
425
370
|
void Generate(MacroAssembler* masm);
|
|
426
|
-
|
|
427
|
-
const char* GetName() { return "NumberToStringStub"; }
|
|
428
371
|
};
|
|
429
372
|
|
|
430
373
|
|
|
@@ -442,8 +385,6 @@ class RegExpCEntryStub: public CodeStub {
|
|
|
442
385
|
int MinorKey() { return 0; }
|
|
443
386
|
|
|
444
387
|
bool NeedsImmovableCode() { return true; }
|
|
445
|
-
|
|
446
|
-
const char* GetName() { return "RegExpCEntryStub"; }
|
|
447
388
|
};
|
|
448
389
|
|
|
449
390
|
|
|
@@ -464,14 +405,11 @@ class DirectCEntryStub: public CodeStub {
|
|
|
464
405
|
int MinorKey() { return 0; }
|
|
465
406
|
|
|
466
407
|
bool NeedsImmovableCode() { return true; }
|
|
467
|
-
|
|
468
|
-
const char* GetName() { return "DirectCEntryStub"; }
|
|
469
408
|
};
|
|
470
409
|
|
|
471
410
|
|
|
472
411
|
class FloatingPointHelper : public AllStatic {
|
|
473
412
|
public:
|
|
474
|
-
|
|
475
413
|
enum Destination {
|
|
476
414
|
kVFPRegisters,
|
|
477
415
|
kCoreRegisters
|
|
@@ -649,13 +587,6 @@ class StringDictionaryLookupStub: public CodeStub {
|
|
|
649
587
|
StringDictionary::kHeaderSize +
|
|
650
588
|
StringDictionary::kElementsStartIndex * kPointerSize;
|
|
651
589
|
|
|
652
|
-
|
|
653
|
-
#ifdef DEBUG
|
|
654
|
-
void Print() {
|
|
655
|
-
PrintF("StringDictionaryLookupStub\n");
|
|
656
|
-
}
|
|
657
|
-
#endif
|
|
658
|
-
|
|
659
590
|
Major MajorKey() { return StringDictionaryNegativeLookup; }
|
|
660
591
|
|
|
661
592
|
int MinorKey() {
|
|
@@ -58,9 +58,7 @@ class CodeGenerator: public AstVisitor {
|
|
|
58
58
|
// Print the code after compiling it.
|
|
59
59
|
static void PrintCode(Handle<Code> code, CompilationInfo* info);
|
|
60
60
|
|
|
61
|
-
#ifdef ENABLE_LOGGING_AND_PROFILING
|
|
62
61
|
static bool ShouldGenerateLog(Expression* type);
|
|
63
|
-
#endif
|
|
64
62
|
|
|
65
63
|
static void SetFunctionInfo(Handle<JSFunction> fun,
|
|
66
64
|
FunctionLiteral* lit,
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
namespace v8 {
|
|
36
36
|
namespace internal {
|
|
37
37
|
|
|
38
|
-
int Deoptimizer::table_entry_size_ = 16;
|
|
38
|
+
const int Deoptimizer::table_entry_size_ = 16;
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
int Deoptimizer::patch_size() {
|
|
@@ -65,8 +65,6 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
|
|
|
65
65
|
|
|
66
66
|
// For each return after a safepoint insert an absolute call to the
|
|
67
67
|
// corresponding deoptimization entry.
|
|
68
|
-
ASSERT(patch_size() % Assembler::kInstrSize == 0);
|
|
69
|
-
int call_size_in_words = patch_size() / Assembler::kInstrSize;
|
|
70
68
|
unsigned last_pc_offset = 0;
|
|
71
69
|
SafepointTable table(function->code());
|
|
72
70
|
for (unsigned i = 0; i < table.length(); i++) {
|
|
@@ -87,13 +85,18 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
|
|
|
87
85
|
#endif
|
|
88
86
|
last_pc_offset = pc_offset;
|
|
89
87
|
if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
|
|
88
|
+
Address deoptimization_entry = Deoptimizer::GetDeoptimizationEntry(
|
|
89
|
+
deoptimization_index, Deoptimizer::LAZY);
|
|
90
90
|
last_pc_offset += gap_code_size;
|
|
91
|
+
int call_size_in_bytes = MacroAssembler::CallSize(deoptimization_entry,
|
|
92
|
+
RelocInfo::NONE);
|
|
93
|
+
int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize;
|
|
94
|
+
ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0);
|
|
95
|
+
ASSERT(call_size_in_bytes <= patch_size());
|
|
91
96
|
CodePatcher patcher(code->instruction_start() + last_pc_offset,
|
|
92
97
|
call_size_in_words);
|
|
93
|
-
Address deoptimization_entry = Deoptimizer::GetDeoptimizationEntry(
|
|
94
|
-
deoptimization_index, Deoptimizer::LAZY);
|
|
95
98
|
patcher.masm()->Call(deoptimization_entry, RelocInfo::NONE);
|
|
96
|
-
last_pc_offset +=
|
|
99
|
+
last_pc_offset += call_size_in_bytes;
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
|
|
@@ -267,6 +270,9 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
|
|
|
267
270
|
output_ = new FrameDescription*[1];
|
|
268
271
|
output_[0] = new(output_frame_size) FrameDescription(
|
|
269
272
|
output_frame_size, function_);
|
|
273
|
+
#ifdef DEBUG
|
|
274
|
+
output_[0]->SetKind(Code::OPTIMIZED_FUNCTION);
|
|
275
|
+
#endif
|
|
270
276
|
|
|
271
277
|
// Clear the incoming parameters in the optimized frame to avoid
|
|
272
278
|
// confusing the garbage collector.
|
|
@@ -382,6 +388,9 @@ void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
|
|
|
382
388
|
// Allocate and store the output frame description.
|
|
383
389
|
FrameDescription* output_frame =
|
|
384
390
|
new(output_frame_size) FrameDescription(output_frame_size, function);
|
|
391
|
+
#ifdef DEBUG
|
|
392
|
+
output_frame->SetKind(Code::FUNCTION);
|
|
393
|
+
#endif
|
|
385
394
|
|
|
386
395
|
bool is_bottommost = (0 == frame_index);
|
|
387
396
|
bool is_topmost = (output_count_ - 1 == frame_index);
|
|
@@ -516,7 +525,7 @@ void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
|
|
|
516
525
|
|
|
517
526
|
|
|
518
527
|
// Set the continuation for the topmost frame.
|
|
519
|
-
if (is_topmost) {
|
|
528
|
+
if (is_topmost && bailout_type_ != DEBUGGER) {
|
|
520
529
|
Builtins* builtins = isolate_->builtins();
|
|
521
530
|
Code* continuation = (bailout_type_ == EAGER)
|
|
522
531
|
? builtins->builtin(Builtins::kNotifyDeoptimized)
|
|
@@ -524,14 +533,32 @@ void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
|
|
|
524
533
|
output_frame->SetContinuation(
|
|
525
534
|
reinterpret_cast<uint32_t>(continuation->entry()));
|
|
526
535
|
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
|
|
540
|
+
// Set the register values. The values are not important as there are no
|
|
541
|
+
// callee saved registers in JavaScript frames, so all registers are
|
|
542
|
+
// spilled. Registers fp and sp are set to the correct values though.
|
|
543
|
+
|
|
544
|
+
for (int i = 0; i < Register::kNumRegisters; i++) {
|
|
545
|
+
input_->SetRegister(i, i * 4);
|
|
546
|
+
}
|
|
547
|
+
input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
|
|
548
|
+
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
|
|
549
|
+
for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) {
|
|
550
|
+
input_->SetDoubleRegister(i, 0.0);
|
|
551
|
+
}
|
|
527
552
|
|
|
528
|
-
|
|
553
|
+
// Fill the frame content from the actual data on the frame.
|
|
554
|
+
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
|
|
555
|
+
input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
|
|
556
|
+
}
|
|
529
557
|
}
|
|
530
558
|
|
|
531
559
|
|
|
532
560
|
#define __ masm()->
|
|
533
561
|
|
|
534
|
-
|
|
535
562
|
// This code tries to be close to ia32 code so that any changes can be
|
|
536
563
|
// easily ported.
|
|
537
564
|
void Deoptimizer::EntryGenerator::Generate() {
|
|
@@ -566,6 +593,8 @@ void Deoptimizer::EntryGenerator::Generate() {
|
|
|
566
593
|
__ vstm(db_w, sp, first, last);
|
|
567
594
|
|
|
568
595
|
// Push all 16 registers (needed to populate FrameDescription::registers_).
|
|
596
|
+
// TODO(1588) Note that using pc with stm is deprecated, so we should perhaps
|
|
597
|
+
// handle this a bit differently.
|
|
569
598
|
__ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
|
|
570
599
|
|
|
571
600
|
const int kSavedRegistersAreaSize =
|
|
@@ -611,30 +640,21 @@ void Deoptimizer::EntryGenerator::Generate() {
|
|
|
611
640
|
|
|
612
641
|
// Copy core registers into FrameDescription::registers_[kNumRegisters].
|
|
613
642
|
ASSERT(Register::kNumRegisters == kNumberOfRegisters);
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
__ mov(r4, Operand(kNumberOfRegisters / 2));
|
|
620
|
-
|
|
621
|
-
__ bind(&arm_loop);
|
|
622
|
-
__ Ldrd(r2, r3, MemOperand(r5, kPointerSize * 2, PostIndex));
|
|
623
|
-
__ sub(r4, r4, Operand(1), SetCC);
|
|
624
|
-
__ Strd(r2, r3, MemOperand(r6, kPointerSize * 2, PostIndex));
|
|
625
|
-
__ b(gt, &arm_loop);
|
|
643
|
+
for (int i = 0; i < kNumberOfRegisters; i++) {
|
|
644
|
+
int offset = (i * kPointerSize) + FrameDescription::registers_offset();
|
|
645
|
+
__ ldr(r2, MemOperand(sp, i * kPointerSize));
|
|
646
|
+
__ str(r2, MemOperand(r1, offset));
|
|
647
|
+
}
|
|
626
648
|
|
|
627
649
|
// Copy VFP registers to
|
|
628
650
|
// double_registers_[DoubleRegister::kNumAllocatableRegisters]
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
__ Strd(r2, r3, MemOperand(r6, kDoubleSize, PostIndex));
|
|
637
|
-
__ b(gt, &vfp_loop);
|
|
651
|
+
int double_regs_offset = FrameDescription::double_registers_offset();
|
|
652
|
+
for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; ++i) {
|
|
653
|
+
int dst_offset = i * kDoubleSize + double_regs_offset;
|
|
654
|
+
int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
|
|
655
|
+
__ vldr(d0, sp, src_offset);
|
|
656
|
+
__ vstr(d0, r1, dst_offset);
|
|
657
|
+
}
|
|
638
658
|
|
|
639
659
|
// Remove the bailout id, eventually return address, and the saved registers
|
|
640
660
|
// from the stack.
|
|
@@ -200,7 +200,7 @@ void Decoder::PrintDRegister(int reg) {
|
|
|
200
200
|
|
|
201
201
|
// These shift names are defined in a way to match the native disassembler
|
|
202
202
|
// formatting. See for example the command "objdump -d <binary file>".
|
|
203
|
-
static const char* shift_names[kNumberOfShifts] = {
|
|
203
|
+
static const char* const shift_names[kNumberOfShifts] = {
|
|
204
204
|
"lsl", "lsr", "asr", "ror"
|
|
205
205
|
};
|
|
206
206
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright
|
|
1
|
+
// Copyright 2011 the V8 project authors. All rights reserved.
|
|
2
2
|
// Redistribution and use in source and binary forms, with or without
|
|
3
3
|
// modification, are permitted provided that the following conditions are
|
|
4
4
|
// met:
|
|
@@ -72,6 +72,9 @@ static const RegList kCalleeSaved =
|
|
|
72
72
|
|
|
73
73
|
static const int kNumCalleeSaved = 7 + kR9Available;
|
|
74
74
|
|
|
75
|
+
// Double registers d8 to d15 are callee-saved.
|
|
76
|
+
static const int kNumDoubleCalleeSaved = 8;
|
|
77
|
+
|
|
75
78
|
|
|
76
79
|
// Number of registers for which space is reserved in safepoints. Must be a
|
|
77
80
|
// multiple of 8.
|
|
@@ -90,10 +93,11 @@ static const int kNumSafepointSavedRegisters =
|
|
|
90
93
|
|
|
91
94
|
class StackHandlerConstants : public AllStatic {
|
|
92
95
|
public:
|
|
93
|
-
static const int kNextOffset
|
|
94
|
-
static const int kStateOffset
|
|
95
|
-
static const int
|
|
96
|
-
static const int
|
|
96
|
+
static const int kNextOffset = 0 * kPointerSize;
|
|
97
|
+
static const int kStateOffset = 1 * kPointerSize;
|
|
98
|
+
static const int kContextOffset = 2 * kPointerSize;
|
|
99
|
+
static const int kFPOffset = 3 * kPointerSize;
|
|
100
|
+
static const int kPCOffset = 4 * kPointerSize;
|
|
97
101
|
|
|
98
102
|
static const int kSize = kPCOffset + kPointerSize;
|
|
99
103
|
};
|
|
@@ -47,7 +47,6 @@ namespace internal {
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
static unsigned GetPropertyId(Property* property) {
|
|
50
|
-
if (property->is_synthetic()) return AstNode::kNoNumber;
|
|
51
50
|
return property->id();
|
|
52
51
|
}
|
|
53
52
|
|
|
@@ -92,17 +91,19 @@ class JumpPatchSite BASE_EMBEDDED {
|
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
void EmitPatchInfo() {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
if (patch_site_.is_bound()) {
|
|
95
|
+
int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
|
|
96
|
+
Register reg;
|
|
97
|
+
reg.set_code(delta_to_patch_site / kOff12Mask);
|
|
98
|
+
__ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
|
|
99
99
|
#ifdef DEBUG
|
|
100
|
-
|
|
100
|
+
info_emitted_ = true;
|
|
101
101
|
#endif
|
|
102
|
+
} else {
|
|
103
|
+
__ nop(); // Signals no inlined code.
|
|
104
|
+
}
|
|
102
105
|
}
|
|
103
106
|
|
|
104
|
-
bool is_bound() const { return patch_site_.is_bound(); }
|
|
105
|
-
|
|
106
107
|
private:
|
|
107
108
|
MacroAssembler* masm_;
|
|
108
109
|
Label patch_site_;
|
|
@@ -129,6 +130,7 @@ class JumpPatchSite BASE_EMBEDDED {
|
|
|
129
130
|
void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
130
131
|
ASSERT(info_ == NULL);
|
|
131
132
|
info_ = info;
|
|
133
|
+
scope_ = info->scope();
|
|
132
134
|
SetFunctionPosition(function());
|
|
133
135
|
Comment cmnt(masm_, "[ function compiled by full code generator");
|
|
134
136
|
|
|
@@ -139,21 +141,21 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
|
139
141
|
}
|
|
140
142
|
#endif
|
|
141
143
|
|
|
142
|
-
// Strict mode functions need to replace the receiver
|
|
143
|
-
// when called as functions (without an explicit
|
|
144
|
-
// object). r5 is zero for method calls and non-zero for
|
|
145
|
-
// calls.
|
|
146
|
-
if (info->is_strict_mode()) {
|
|
144
|
+
// Strict mode functions and builtins need to replace the receiver
|
|
145
|
+
// with undefined when called as functions (without an explicit
|
|
146
|
+
// receiver object). r5 is zero for method calls and non-zero for
|
|
147
|
+
// function calls.
|
|
148
|
+
if (info->is_strict_mode() || info->is_native()) {
|
|
147
149
|
Label ok;
|
|
148
150
|
__ cmp(r5, Operand(0));
|
|
149
151
|
__ b(eq, &ok);
|
|
150
|
-
int receiver_offset = scope()->num_parameters() * kPointerSize;
|
|
152
|
+
int receiver_offset = info->scope()->num_parameters() * kPointerSize;
|
|
151
153
|
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
|
152
154
|
__ str(r2, MemOperand(sp, receiver_offset));
|
|
153
155
|
__ bind(&ok);
|
|
154
156
|
}
|
|
155
157
|
|
|
156
|
-
int locals_count = scope()->num_stack_slots();
|
|
158
|
+
int locals_count = info->scope()->num_stack_slots();
|
|
157
159
|
|
|
158
160
|
__ Push(lr, fp, cp, r1);
|
|
159
161
|
if (locals_count > 0) {
|
|
@@ -173,7 +175,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
|
173
175
|
bool function_in_register = true;
|
|
174
176
|
|
|
175
177
|
// Possibly allocate a local context.
|
|
176
|
-
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
|
|
178
|
+
int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
|
|
177
179
|
if (heap_slots > 0) {
|
|
178
180
|
Comment cmnt(masm_, "[ Allocate local context");
|
|
179
181
|
// Argument to NewContext is the function, which is in r1.
|
|
@@ -182,14 +184,14 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
|
182
184
|
FastNewContextStub stub(heap_slots);
|
|
183
185
|
__ CallStub(&stub);
|
|
184
186
|
} else {
|
|
185
|
-
__ CallRuntime(Runtime::
|
|
187
|
+
__ CallRuntime(Runtime::kNewFunctionContext, 1);
|
|
186
188
|
}
|
|
187
189
|
function_in_register = false;
|
|
188
190
|
// Context is returned in both r0 and cp. It replaces the context
|
|
189
191
|
// passed to us. It's saved in the stack and kept live in cp.
|
|
190
192
|
__ str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
|
191
193
|
// Copy any necessary parameters into the context.
|
|
192
|
-
int num_parameters = scope()->num_parameters();
|
|
194
|
+
int num_parameters = info->scope()->num_parameters();
|
|
193
195
|
for (int i = 0; i < num_parameters; i++) {
|
|
194
196
|
Slot* slot = scope()->parameter(i)->AsSlot();
|
|
195
197
|
if (slot != NULL && slot->type() == Slot::CONTEXT) {
|
|
@@ -220,27 +222,28 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
|
220
222
|
__ mov(r3, r1);
|
|
221
223
|
}
|
|
222
224
|
// Receiver is just before the parameters on the caller's stack.
|
|
223
|
-
int
|
|
225
|
+
int num_parameters = info->scope()->num_parameters();
|
|
226
|
+
int offset = num_parameters * kPointerSize;
|
|
224
227
|
__ add(r2, fp,
|
|
225
228
|
Operand(StandardFrameConstants::kCallerSPOffset + offset));
|
|
226
|
-
__ mov(r1, Operand(Smi::FromInt(
|
|
229
|
+
__ mov(r1, Operand(Smi::FromInt(num_parameters)));
|
|
227
230
|
__ Push(r3, r2, r1);
|
|
228
231
|
|
|
229
232
|
// Arguments to ArgumentsAccessStub:
|
|
230
233
|
// function, receiver address, parameter count.
|
|
231
234
|
// The stub will rewrite receiever and parameter count if the previous
|
|
232
235
|
// stack frame was an arguments adapter frame.
|
|
233
|
-
ArgumentsAccessStub
|
|
234
|
-
|
|
235
|
-
|
|
236
|
+
ArgumentsAccessStub::Type type;
|
|
237
|
+
if (is_strict_mode()) {
|
|
238
|
+
type = ArgumentsAccessStub::NEW_STRICT;
|
|
239
|
+
} else if (function()->has_duplicate_parameters()) {
|
|
240
|
+
type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
|
|
241
|
+
} else {
|
|
242
|
+
type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
|
|
243
|
+
}
|
|
244
|
+
ArgumentsAccessStub stub(type);
|
|
236
245
|
__ CallStub(&stub);
|
|
237
246
|
|
|
238
|
-
Variable* arguments_shadow = scope()->arguments_shadow();
|
|
239
|
-
if (arguments_shadow != NULL) {
|
|
240
|
-
// Duplicate the value; move-to-slot operation might clobber registers.
|
|
241
|
-
__ mov(r3, r0);
|
|
242
|
-
Move(arguments_shadow->AsSlot(), r3, r1, r2);
|
|
243
|
-
}
|
|
244
247
|
Move(arguments->AsSlot(), r0, r1, r2);
|
|
245
248
|
}
|
|
246
249
|
|
|
@@ -345,7 +348,7 @@ void FullCodeGenerator::EmitReturnSequence() {
|
|
|
345
348
|
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
|
|
346
349
|
// Here we use masm_-> instead of the __ macro to avoid the code coverage
|
|
347
350
|
// tool from instrumenting as we rely on the code size here.
|
|
348
|
-
int32_t sp_delta = (scope()->num_parameters() + 1) * kPointerSize;
|
|
351
|
+
int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
|
|
349
352
|
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
|
|
350
353
|
__ RecordJSReturn();
|
|
351
354
|
masm_->mov(sp, fp);
|
|
@@ -383,7 +386,7 @@ void FullCodeGenerator::TestContext::Plug(Slot* slot) const {
|
|
|
383
386
|
// For simplicity we always test the accumulator register.
|
|
384
387
|
codegen()->Move(result_register(), slot);
|
|
385
388
|
codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
|
|
386
|
-
codegen()->DoTest(
|
|
389
|
+
codegen()->DoTest(this);
|
|
387
390
|
}
|
|
388
391
|
|
|
389
392
|
|
|
@@ -417,7 +420,7 @@ void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
|
|
|
417
420
|
if (true_label_ != fall_through_) __ b(true_label_);
|
|
418
421
|
} else {
|
|
419
422
|
__ LoadRoot(result_register(), index);
|
|
420
|
-
codegen()->DoTest(
|
|
423
|
+
codegen()->DoTest(this);
|
|
421
424
|
}
|
|
422
425
|
}
|
|
423
426
|
|
|
@@ -464,7 +467,7 @@ void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
|
|
|
464
467
|
} else {
|
|
465
468
|
// For simplicity we always test the accumulator register.
|
|
466
469
|
__ mov(result_register(), Operand(lit));
|
|
467
|
-
codegen()->DoTest(
|
|
470
|
+
codegen()->DoTest(this);
|
|
468
471
|
}
|
|
469
472
|
}
|
|
470
473
|
|
|
@@ -500,7 +503,7 @@ void FullCodeGenerator::TestContext::DropAndPlug(int count,
|
|
|
500
503
|
__ Drop(count);
|
|
501
504
|
__ Move(result_register(), reg);
|
|
502
505
|
codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
|
|
503
|
-
codegen()->DoTest(
|
|
506
|
+
codegen()->DoTest(this);
|
|
504
507
|
}
|
|
505
508
|
|
|
506
509
|
|
|
@@ -578,7 +581,8 @@ void FullCodeGenerator::TestContext::Plug(bool flag) const {
|
|
|
578
581
|
}
|
|
579
582
|
|
|
580
583
|
|
|
581
|
-
void FullCodeGenerator::DoTest(
|
|
584
|
+
void FullCodeGenerator::DoTest(Expression* condition,
|
|
585
|
+
Label* if_true,
|
|
582
586
|
Label* if_false,
|
|
583
587
|
Label* fall_through) {
|
|
584
588
|
if (CpuFeatures::IsSupported(VFP3)) {
|
|
@@ -689,102 +693,73 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
|
|
689
693
|
Comment cmnt(masm_, "[ Declaration");
|
|
690
694
|
ASSERT(variable != NULL); // Must have been resolved.
|
|
691
695
|
Slot* slot = variable->AsSlot();
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
VisitForAccumulatorValue(function);
|
|
703
|
-
__ str(result_register(), MemOperand(fp, SlotOffset(slot)));
|
|
704
|
-
}
|
|
705
|
-
break;
|
|
706
|
-
|
|
707
|
-
case Slot::CONTEXT:
|
|
708
|
-
// We bypass the general EmitSlotSearch because we know more about
|
|
709
|
-
// this specific context.
|
|
710
|
-
|
|
711
|
-
// The variable in the decl always resides in the current function
|
|
712
|
-
// context.
|
|
713
|
-
ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
|
|
714
|
-
if (FLAG_debug_code) {
|
|
715
|
-
// Check that we're not inside a 'with'.
|
|
716
|
-
__ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX));
|
|
717
|
-
__ cmp(r1, cp);
|
|
718
|
-
__ Check(eq, "Unexpected declaration in current context.");
|
|
719
|
-
}
|
|
720
|
-
if (mode == Variable::CONST) {
|
|
721
|
-
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
|
722
|
-
__ str(ip, ContextOperand(cp, slot->index()));
|
|
723
|
-
// No write barrier since the_hole_value is in old space.
|
|
724
|
-
} else if (function != NULL) {
|
|
725
|
-
VisitForAccumulatorValue(function);
|
|
726
|
-
__ str(result_register(), ContextOperand(cp, slot->index()));
|
|
727
|
-
int offset = Context::SlotOffset(slot->index());
|
|
728
|
-
// We know that we have written a function, which is not a smi.
|
|
729
|
-
__ mov(r1, Operand(cp));
|
|
730
|
-
__ RecordWrite(r1, Operand(offset), r2, result_register());
|
|
731
|
-
}
|
|
732
|
-
break;
|
|
733
|
-
|
|
734
|
-
case Slot::LOOKUP: {
|
|
735
|
-
__ mov(r2, Operand(variable->name()));
|
|
736
|
-
// Declaration nodes are always introduced in one of two modes.
|
|
737
|
-
ASSERT(mode == Variable::VAR ||
|
|
738
|
-
mode == Variable::CONST);
|
|
739
|
-
PropertyAttributes attr =
|
|
740
|
-
(mode == Variable::VAR) ? NONE : READ_ONLY;
|
|
741
|
-
__ mov(r1, Operand(Smi::FromInt(attr)));
|
|
742
|
-
// Push initial value, if any.
|
|
743
|
-
// Note: For variables we must not push an initial value (such as
|
|
744
|
-
// 'undefined') because we may have a (legal) redeclaration and we
|
|
745
|
-
// must not destroy the current value.
|
|
746
|
-
if (mode == Variable::CONST) {
|
|
747
|
-
__ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
|
|
748
|
-
__ Push(cp, r2, r1, r0);
|
|
749
|
-
} else if (function != NULL) {
|
|
750
|
-
__ Push(cp, r2, r1);
|
|
751
|
-
// Push initial value for function declaration.
|
|
752
|
-
VisitForStackValue(function);
|
|
753
|
-
} else {
|
|
754
|
-
__ mov(r0, Operand(Smi::FromInt(0))); // No initial value!
|
|
755
|
-
__ Push(cp, r2, r1, r0);
|
|
756
|
-
}
|
|
757
|
-
__ CallRuntime(Runtime::kDeclareContextSlot, 4);
|
|
758
|
-
break;
|
|
696
|
+
ASSERT(slot != NULL);
|
|
697
|
+
switch (slot->type()) {
|
|
698
|
+
case Slot::PARAMETER:
|
|
699
|
+
case Slot::LOCAL:
|
|
700
|
+
if (function != NULL) {
|
|
701
|
+
VisitForAccumulatorValue(function);
|
|
702
|
+
__ str(result_register(), MemOperand(fp, SlotOffset(slot)));
|
|
703
|
+
} else if (mode == Variable::CONST || mode == Variable::LET) {
|
|
704
|
+
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
|
705
|
+
__ str(ip, MemOperand(fp, SlotOffset(slot)));
|
|
759
706
|
}
|
|
760
|
-
|
|
707
|
+
break;
|
|
761
708
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
//
|
|
767
|
-
//
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
709
|
+
case Slot::CONTEXT:
|
|
710
|
+
// We bypass the general EmitSlotSearch because we know more about
|
|
711
|
+
// this specific context.
|
|
712
|
+
|
|
713
|
+
// The variable in the decl always resides in the current function
|
|
714
|
+
// context.
|
|
715
|
+
ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
|
|
716
|
+
if (FLAG_debug_code) {
|
|
717
|
+
// Check that we're not inside a with or catch context.
|
|
718
|
+
__ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
|
|
719
|
+
__ CompareRoot(r1, Heap::kWithContextMapRootIndex);
|
|
720
|
+
__ Check(ne, "Declaration in with context.");
|
|
721
|
+
__ CompareRoot(r1, Heap::kCatchContextMapRootIndex);
|
|
722
|
+
__ Check(ne, "Declaration in catch context.");
|
|
773
723
|
}
|
|
724
|
+
if (function != NULL) {
|
|
725
|
+
VisitForAccumulatorValue(function);
|
|
726
|
+
__ str(result_register(), ContextOperand(cp, slot->index()));
|
|
727
|
+
int offset = Context::SlotOffset(slot->index());
|
|
728
|
+
// We know that we have written a function, which is not a smi.
|
|
729
|
+
__ mov(r1, Operand(cp));
|
|
730
|
+
__ RecordWrite(r1, Operand(offset), r2, result_register());
|
|
731
|
+
} else if (mode == Variable::CONST || mode == Variable::LET) {
|
|
732
|
+
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
|
733
|
+
__ str(ip, ContextOperand(cp, slot->index()));
|
|
734
|
+
// No write barrier since the_hole_value is in old space.
|
|
735
|
+
}
|
|
736
|
+
break;
|
|
774
737
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
738
|
+
case Slot::LOOKUP: {
|
|
739
|
+
__ mov(r2, Operand(variable->name()));
|
|
740
|
+
// Declaration nodes are always introduced in one of two modes.
|
|
741
|
+
ASSERT(mode == Variable::VAR ||
|
|
742
|
+
mode == Variable::CONST ||
|
|
743
|
+
mode == Variable::LET);
|
|
744
|
+
PropertyAttributes attr = (mode == Variable::CONST) ? READ_ONLY : NONE;
|
|
745
|
+
__ mov(r1, Operand(Smi::FromInt(attr)));
|
|
746
|
+
// Push initial value, if any.
|
|
747
|
+
// Note: For variables we must not push an initial value (such as
|
|
748
|
+
// 'undefined') because we may have a (legal) redeclaration and we
|
|
749
|
+
// must not destroy the current value.
|
|
750
|
+
if (function != NULL) {
|
|
751
|
+
__ Push(cp, r2, r1);
|
|
752
|
+
// Push initial value for function declaration.
|
|
753
|
+
VisitForStackValue(function);
|
|
754
|
+
} else if (mode == Variable::CONST || mode == Variable::LET) {
|
|
755
|
+
__ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
|
|
756
|
+
__ Push(cp, r2, r1, r0);
|
|
757
|
+
} else {
|
|
758
|
+
__ mov(r0, Operand(Smi::FromInt(0))); // No initial value!
|
|
759
|
+
__ Push(cp, r2, r1, r0);
|
|
760
|
+
}
|
|
761
|
+
__ CallRuntime(Runtime::kDeclareContextSlot, 4);
|
|
762
|
+
break;
|
|
788
763
|
}
|
|
789
764
|
}
|
|
790
765
|
}
|
|
@@ -857,7 +832,8 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|
|
857
832
|
// Record position before stub call for type feedback.
|
|
858
833
|
SetSourcePosition(clause->position());
|
|
859
834
|
Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
|
|
860
|
-
|
|
835
|
+
__ Call(ic, RelocInfo::CODE_TARGET, clause->CompareId());
|
|
836
|
+
patch_site.EmitPatchInfo();
|
|
861
837
|
|
|
862
838
|
__ cmp(r0, Operand(0));
|
|
863
839
|
__ b(ne, &next_test);
|
|
@@ -870,7 +846,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|
|
870
846
|
__ bind(&next_test);
|
|
871
847
|
__ Drop(1); // Switch value is no longer needed.
|
|
872
848
|
if (default_clause == NULL) {
|
|
873
|
-
__ b(nested_statement.
|
|
849
|
+
__ b(nested_statement.break_label());
|
|
874
850
|
} else {
|
|
875
851
|
__ b(default_clause->body_target());
|
|
876
852
|
}
|
|
@@ -884,7 +860,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|
|
884
860
|
VisitStatements(clause->statements());
|
|
885
861
|
}
|
|
886
862
|
|
|
887
|
-
__ bind(nested_statement.
|
|
863
|
+
__ bind(nested_statement.break_label());
|
|
888
864
|
PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
|
|
889
865
|
}
|
|
890
866
|
|
|
@@ -912,8 +888,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
|
912
888
|
// Convert the object to a JS object.
|
|
913
889
|
Label convert, done_convert;
|
|
914
890
|
__ JumpIfSmi(r0, &convert);
|
|
915
|
-
__ CompareObjectType(r0, r1, r1,
|
|
916
|
-
__ b(
|
|
891
|
+
__ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
|
|
892
|
+
__ b(ge, &done_convert);
|
|
917
893
|
__ bind(&convert);
|
|
918
894
|
__ push(r0);
|
|
919
895
|
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
|
|
@@ -1015,7 +991,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
|
1015
991
|
// Load the current count to r0, load the length to r1.
|
|
1016
992
|
__ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
|
|
1017
993
|
__ cmp(r0, r1); // Compare to the array length.
|
|
1018
|
-
__ b(hs, loop_statement.
|
|
994
|
+
__ b(hs, loop_statement.break_label());
|
|
1019
995
|
|
|
1020
996
|
// Get the current entry of the array into register r3.
|
|
1021
997
|
__ ldr(r2, MemOperand(sp, 2 * kPointerSize));
|
|
@@ -1041,7 +1017,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
|
1041
1017
|
__ push(r3); // Current entry.
|
|
1042
1018
|
__ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
|
|
1043
1019
|
__ mov(r3, Operand(r0), SetCC);
|
|
1044
|
-
__ b(eq, loop_statement.
|
|
1020
|
+
__ b(eq, loop_statement.continue_label());
|
|
1045
1021
|
|
|
1046
1022
|
// Update the 'each' property or variable from the possibly filtered
|
|
1047
1023
|
// entry in register r3.
|
|
@@ -1057,7 +1033,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
|
1057
1033
|
|
|
1058
1034
|
// Generate code for the going to the next element by incrementing
|
|
1059
1035
|
// the index (smi) stored on top of the stack.
|
|
1060
|
-
__ bind(loop_statement.
|
|
1036
|
+
__ bind(loop_statement.continue_label());
|
|
1061
1037
|
__ pop(r0);
|
|
1062
1038
|
__ add(r0, r0, Operand(Smi::FromInt(1)));
|
|
1063
1039
|
__ push(r0);
|
|
@@ -1066,7 +1042,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
|
1066
1042
|
__ b(&loop);
|
|
1067
1043
|
|
|
1068
1044
|
// Remove the pointers stored on the stack.
|
|
1069
|
-
__ bind(loop_statement.
|
|
1045
|
+
__ bind(loop_statement.break_label());
|
|
1070
1046
|
__ Drop(5);
|
|
1071
1047
|
|
|
1072
1048
|
// Exit and decrement the loop depth.
|
|
@@ -1105,7 +1081,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
|
|
|
1105
1081
|
|
|
1106
1082
|
void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
|
|
1107
1083
|
Comment cmnt(masm_, "[ VariableProxy");
|
|
1108
|
-
EmitVariableLoad(expr
|
|
1084
|
+
EmitVariableLoad(expr);
|
|
1109
1085
|
}
|
|
1110
1086
|
|
|
1111
1087
|
|
|
@@ -1127,8 +1103,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
|
|
1127
1103
|
__ b(ne, slow);
|
|
1128
1104
|
}
|
|
1129
1105
|
// Load next context in chain.
|
|
1130
|
-
__ ldr(next, ContextOperand(current, Context::
|
|
1131
|
-
__ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
|
|
1106
|
+
__ ldr(next, ContextOperand(current, Context::PREVIOUS_INDEX));
|
|
1132
1107
|
// Walk the rest of the chain without clobbering cp.
|
|
1133
1108
|
current = next;
|
|
1134
1109
|
}
|
|
@@ -1154,8 +1129,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
|
|
1154
1129
|
__ tst(temp, temp);
|
|
1155
1130
|
__ b(ne, slow);
|
|
1156
1131
|
// Load next context in chain.
|
|
1157
|
-
__ ldr(next, ContextOperand(next, Context::
|
|
1158
|
-
__ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
|
|
1132
|
+
__ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX));
|
|
1159
1133
|
__ b(&loop);
|
|
1160
1134
|
__ bind(&fast);
|
|
1161
1135
|
}
|
|
@@ -1166,7 +1140,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
|
|
1166
1140
|
? RelocInfo::CODE_TARGET
|
|
1167
1141
|
: RelocInfo::CODE_TARGET_CONTEXT;
|
|
1168
1142
|
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
|
1169
|
-
|
|
1143
|
+
__ Call(ic, mode);
|
|
1170
1144
|
}
|
|
1171
1145
|
|
|
1172
1146
|
|
|
@@ -1186,8 +1160,7 @@ MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
|
|
|
1186
1160
|
__ tst(temp, temp);
|
|
1187
1161
|
__ b(ne, slow);
|
|
1188
1162
|
}
|
|
1189
|
-
__ ldr(next, ContextOperand(context, Context::
|
|
1190
|
-
__ ldr(next, FieldMemOperand(next, JSFunction::kContextOffset));
|
|
1163
|
+
__ ldr(next, ContextOperand(context, Context::PREVIOUS_INDEX));
|
|
1191
1164
|
// Walk the rest of the chain without clobbering cp.
|
|
1192
1165
|
context = next;
|
|
1193
1166
|
}
|
|
@@ -1248,7 +1221,7 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
|
|
|
1248
1221
|
__ mov(r0, Operand(key_literal->handle()));
|
|
1249
1222
|
Handle<Code> ic =
|
|
1250
1223
|
isolate()->builtins()->KeyedLoadIC_Initialize();
|
|
1251
|
-
|
|
1224
|
+
__ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
|
|
1252
1225
|
__ jmp(done);
|
|
1253
1226
|
}
|
|
1254
1227
|
}
|
|
@@ -1257,24 +1230,27 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
|
|
|
1257
1230
|
}
|
|
1258
1231
|
|
|
1259
1232
|
|
|
1260
|
-
void FullCodeGenerator::EmitVariableLoad(
|
|
1261
|
-
//
|
|
1262
|
-
|
|
1263
|
-
|
|
1233
|
+
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
|
|
1234
|
+
// Record position before possible IC call.
|
|
1235
|
+
SetSourcePosition(proxy->position());
|
|
1236
|
+
Variable* var = proxy->var();
|
|
1237
|
+
|
|
1238
|
+
// Three cases: non-this global variables, lookup slots, and all other
|
|
1239
|
+
// types of slots.
|
|
1264
1240
|
Slot* slot = var->AsSlot();
|
|
1265
|
-
|
|
1241
|
+
ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
|
|
1266
1242
|
|
|
1267
|
-
if (
|
|
1243
|
+
if (slot == NULL) {
|
|
1268
1244
|
Comment cmnt(masm_, "Global variable");
|
|
1269
1245
|
// Use inline caching. Variable name is passed in r2 and the global
|
|
1270
1246
|
// object (receiver) in r0.
|
|
1271
1247
|
__ ldr(r0, GlobalObjectOperand());
|
|
1272
1248
|
__ mov(r2, Operand(var->name()));
|
|
1273
1249
|
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
|
1274
|
-
|
|
1250
|
+
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
|
1275
1251
|
context()->Plug(r0);
|
|
1276
1252
|
|
|
1277
|
-
} else if (slot
|
|
1253
|
+
} else if (slot->type() == Slot::LOOKUP) {
|
|
1278
1254
|
Label done, slow;
|
|
1279
1255
|
|
|
1280
1256
|
// Generate code for loading from variables potentially shadowed
|
|
@@ -1290,7 +1266,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
|
|
|
1290
1266
|
|
|
1291
1267
|
context()->Plug(r0);
|
|
1292
1268
|
|
|
1293
|
-
} else
|
|
1269
|
+
} else {
|
|
1294
1270
|
Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
|
|
1295
1271
|
? "Context slot"
|
|
1296
1272
|
: "Stack slot");
|
|
@@ -1303,35 +1279,23 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
|
|
|
1303
1279
|
__ cmp(r0, ip);
|
|
1304
1280
|
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
|
|
1305
1281
|
context()->Plug(r0);
|
|
1282
|
+
} else if (var->mode() == Variable::LET) {
|
|
1283
|
+
// Let bindings may be the hole value if they have not been initialized.
|
|
1284
|
+
// Throw a type error in this case.
|
|
1285
|
+
Label done;
|
|
1286
|
+
MemOperand slot_operand = EmitSlotSearch(slot, r0);
|
|
1287
|
+
__ ldr(r0, slot_operand);
|
|
1288
|
+
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
|
1289
|
+
__ cmp(r0, ip);
|
|
1290
|
+
__ b(ne, &done);
|
|
1291
|
+
__ mov(r0, Operand(var->name()));
|
|
1292
|
+
__ push(r0);
|
|
1293
|
+
__ CallRuntime(Runtime::kThrowReferenceError, 1);
|
|
1294
|
+
__ bind(&done);
|
|
1295
|
+
context()->Plug(r0);
|
|
1306
1296
|
} else {
|
|
1307
1297
|
context()->Plug(slot);
|
|
1308
1298
|
}
|
|
1309
|
-
} else {
|
|
1310
|
-
Comment cmnt(masm_, "Rewritten parameter");
|
|
1311
|
-
ASSERT_NOT_NULL(property);
|
|
1312
|
-
// Rewritten parameter accesses are of the form "slot[literal]".
|
|
1313
|
-
|
|
1314
|
-
// Assert that the object is in a slot.
|
|
1315
|
-
Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
|
|
1316
|
-
ASSERT_NOT_NULL(object_var);
|
|
1317
|
-
Slot* object_slot = object_var->AsSlot();
|
|
1318
|
-
ASSERT_NOT_NULL(object_slot);
|
|
1319
|
-
|
|
1320
|
-
// Load the object.
|
|
1321
|
-
Move(r1, object_slot);
|
|
1322
|
-
|
|
1323
|
-
// Assert that the key is a smi.
|
|
1324
|
-
Literal* key_literal = property->key()->AsLiteral();
|
|
1325
|
-
ASSERT_NOT_NULL(key_literal);
|
|
1326
|
-
ASSERT(key_literal->handle()->IsSmi());
|
|
1327
|
-
|
|
1328
|
-
// Load the key.
|
|
1329
|
-
__ mov(r0, Operand(key_literal->handle()));
|
|
1330
|
-
|
|
1331
|
-
// Call keyed load IC. It has arguments key and receiver in r0 and r1.
|
|
1332
|
-
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
|
1333
|
-
EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
|
|
1334
|
-
context()->Plug(r0);
|
|
1335
1299
|
}
|
|
1336
1300
|
}
|
|
1337
1301
|
|
|
@@ -1441,7 +1405,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
|
|
1441
1405
|
Handle<Code> ic = is_strict_mode()
|
|
1442
1406
|
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
|
1443
1407
|
: isolate()->builtins()->StoreIC_Initialize();
|
|
1444
|
-
|
|
1408
|
+
__ Call(ic, RelocInfo::CODE_TARGET, key->id());
|
|
1445
1409
|
PrepareForBailoutForId(key->id(), NO_REGISTERS);
|
|
1446
1410
|
} else {
|
|
1447
1411
|
VisitForEffect(value);
|
|
@@ -1572,7 +1536,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
|
1572
1536
|
}
|
|
1573
1537
|
|
|
1574
1538
|
// Left-hand side can only be a property, a global or a (parameter or local)
|
|
1575
|
-
// slot.
|
|
1539
|
+
// slot.
|
|
1576
1540
|
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
|
|
1577
1541
|
LhsKind assign_type = VARIABLE;
|
|
1578
1542
|
Property* property = expr->target()->AsProperty();
|
|
@@ -1598,27 +1562,13 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
|
1598
1562
|
break;
|
|
1599
1563
|
case KEYED_PROPERTY:
|
|
1600
1564
|
if (expr->is_compound()) {
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
__ ldr(r0, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
|
|
1604
|
-
__ push(r0);
|
|
1605
|
-
__ mov(r0, Operand(property->key()->AsLiteral()->handle()));
|
|
1606
|
-
} else {
|
|
1607
|
-
VisitForStackValue(property->obj());
|
|
1608
|
-
VisitForAccumulatorValue(property->key());
|
|
1609
|
-
}
|
|
1565
|
+
VisitForStackValue(property->obj());
|
|
1566
|
+
VisitForAccumulatorValue(property->key());
|
|
1610
1567
|
__ ldr(r1, MemOperand(sp, 0));
|
|
1611
1568
|
__ push(r0);
|
|
1612
1569
|
} else {
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
__ ldr(r1, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
|
|
1616
|
-
__ mov(r0, Operand(property->key()->AsLiteral()->handle()));
|
|
1617
|
-
__ Push(r1, r0);
|
|
1618
|
-
} else {
|
|
1619
|
-
VisitForStackValue(property->obj());
|
|
1620
|
-
VisitForStackValue(property->key());
|
|
1621
|
-
}
|
|
1570
|
+
VisitForStackValue(property->obj());
|
|
1571
|
+
VisitForStackValue(property->key());
|
|
1622
1572
|
}
|
|
1623
1573
|
break;
|
|
1624
1574
|
}
|
|
@@ -1629,7 +1579,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
|
1629
1579
|
{ AccumulatorValueContext context(this);
|
|
1630
1580
|
switch (assign_type) {
|
|
1631
1581
|
case VARIABLE:
|
|
1632
|
-
EmitVariableLoad(expr->target()->AsVariableProxy()
|
|
1582
|
+
EmitVariableLoad(expr->target()->AsVariableProxy());
|
|
1633
1583
|
PrepareForBailout(expr->target(), TOS_REG);
|
|
1634
1584
|
break;
|
|
1635
1585
|
case NAMED_PROPERTY:
|
|
@@ -1695,7 +1645,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
|
|
1695
1645
|
__ mov(r2, Operand(key->handle()));
|
|
1696
1646
|
// Call load IC. It has arguments receiver and property name r0 and r2.
|
|
1697
1647
|
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
|
1698
|
-
|
|
1648
|
+
__ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
|
|
1699
1649
|
}
|
|
1700
1650
|
|
|
1701
1651
|
|
|
@@ -1703,7 +1653,7 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
|
|
1703
1653
|
SetSourcePosition(prop->position());
|
|
1704
1654
|
// Call keyed load IC. It has arguments key and receiver in r0 and r1.
|
|
1705
1655
|
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
|
1706
|
-
|
|
1656
|
+
__ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
|
|
1707
1657
|
}
|
|
1708
1658
|
|
|
1709
1659
|
|
|
@@ -1730,7 +1680,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|
|
1730
1680
|
|
|
1731
1681
|
__ bind(&stub_call);
|
|
1732
1682
|
BinaryOpStub stub(op, mode);
|
|
1733
|
-
|
|
1683
|
+
__ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
|
|
1684
|
+
patch_site.EmitPatchInfo();
|
|
1734
1685
|
__ jmp(&done);
|
|
1735
1686
|
|
|
1736
1687
|
__ bind(&smi_case);
|
|
@@ -1811,7 +1762,9 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
|
|
|
1811
1762
|
OverwriteMode mode) {
|
|
1812
1763
|
__ pop(r1);
|
|
1813
1764
|
BinaryOpStub stub(op, mode);
|
|
1814
|
-
|
|
1765
|
+
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
|
1766
|
+
__ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
|
|
1767
|
+
patch_site.EmitPatchInfo();
|
|
1815
1768
|
context()->Plug(r0);
|
|
1816
1769
|
}
|
|
1817
1770
|
|
|
@@ -1825,7 +1778,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
|
|
|
1825
1778
|
}
|
|
1826
1779
|
|
|
1827
1780
|
// Left-hand side can only be a property, a global or a (parameter or local)
|
|
1828
|
-
// slot.
|
|
1781
|
+
// slot.
|
|
1829
1782
|
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
|
|
1830
1783
|
LhsKind assign_type = VARIABLE;
|
|
1831
1784
|
Property* prop = expr->AsProperty();
|
|
@@ -1851,30 +1804,20 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
|
|
|
1851
1804
|
Handle<Code> ic = is_strict_mode()
|
|
1852
1805
|
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
|
1853
1806
|
: isolate()->builtins()->StoreIC_Initialize();
|
|
1854
|
-
|
|
1807
|
+
__ Call(ic);
|
|
1855
1808
|
break;
|
|
1856
1809
|
}
|
|
1857
1810
|
case KEYED_PROPERTY: {
|
|
1858
1811
|
__ push(r0); // Preserve value.
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
|
|
1864
|
-
}
|
|
1865
|
-
__ mov(r2, r0);
|
|
1866
|
-
__ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
|
|
1867
|
-
} else {
|
|
1868
|
-
VisitForStackValue(prop->obj());
|
|
1869
|
-
VisitForAccumulatorValue(prop->key());
|
|
1870
|
-
__ mov(r1, r0);
|
|
1871
|
-
__ pop(r2);
|
|
1872
|
-
}
|
|
1812
|
+
VisitForStackValue(prop->obj());
|
|
1813
|
+
VisitForAccumulatorValue(prop->key());
|
|
1814
|
+
__ mov(r1, r0);
|
|
1815
|
+
__ pop(r2);
|
|
1873
1816
|
__ pop(r0); // Restore value.
|
|
1874
1817
|
Handle<Code> ic = is_strict_mode()
|
|
1875
1818
|
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
|
1876
1819
|
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
|
1877
|
-
|
|
1820
|
+
__ Call(ic);
|
|
1878
1821
|
break;
|
|
1879
1822
|
}
|
|
1880
1823
|
}
|
|
@@ -1885,8 +1828,6 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
|
|
|
1885
1828
|
|
|
1886
1829
|
void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
|
1887
1830
|
Token::Value op) {
|
|
1888
|
-
// Left-hand sides that rewrite to explicit property accesses do not reach
|
|
1889
|
-
// here.
|
|
1890
1831
|
ASSERT(var != NULL);
|
|
1891
1832
|
ASSERT(var->is_global() || var->AsSlot() != NULL);
|
|
1892
1833
|
|
|
@@ -1900,7 +1841,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
|
|
1900
1841
|
Handle<Code> ic = is_strict_mode()
|
|
1901
1842
|
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
|
1902
1843
|
: isolate()->builtins()->StoreIC_Initialize();
|
|
1903
|
-
|
|
1844
|
+
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
|
1904
1845
|
|
|
1905
1846
|
} else if (op == Token::INIT_CONST) {
|
|
1906
1847
|
// Like var declarations, const declarations are hoisted to function
|
|
@@ -1922,18 +1863,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
|
|
1922
1863
|
__ b(ne, &skip);
|
|
1923
1864
|
__ str(result_register(), MemOperand(fp, SlotOffset(slot)));
|
|
1924
1865
|
break;
|
|
1925
|
-
case Slot::CONTEXT:
|
|
1926
|
-
__ ldr(r1, ContextOperand(cp, Context::FCONTEXT_INDEX));
|
|
1927
|
-
__ ldr(r2, ContextOperand(r1, slot->index()));
|
|
1928
|
-
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
|
1929
|
-
__ cmp(r2, ip);
|
|
1930
|
-
__ b(ne, &skip);
|
|
1931
|
-
__ str(r0, ContextOperand(r1, slot->index()));
|
|
1932
|
-
int offset = Context::SlotOffset(slot->index());
|
|
1933
|
-
__ mov(r3, r0); // Preserve the stored value in r0.
|
|
1934
|
-
__ RecordWrite(r1, Operand(offset), r3, r2);
|
|
1935
|
-
break;
|
|
1936
|
-
}
|
|
1866
|
+
case Slot::CONTEXT:
|
|
1937
1867
|
case Slot::LOOKUP:
|
|
1938
1868
|
__ push(r0);
|
|
1939
1869
|
__ mov(r0, Operand(slot->var()->name()));
|
|
@@ -1943,6 +1873,59 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
|
|
1943
1873
|
}
|
|
1944
1874
|
__ bind(&skip);
|
|
1945
1875
|
|
|
1876
|
+
} else if (var->mode() == Variable::LET && op != Token::INIT_LET) {
|
|
1877
|
+
// Perform the assignment for non-const variables. Const assignments
|
|
1878
|
+
// are simply skipped.
|
|
1879
|
+
Slot* slot = var->AsSlot();
|
|
1880
|
+
switch (slot->type()) {
|
|
1881
|
+
case Slot::PARAMETER:
|
|
1882
|
+
case Slot::LOCAL: {
|
|
1883
|
+
Label assign;
|
|
1884
|
+
// Check for an initialized let binding.
|
|
1885
|
+
__ ldr(r1, MemOperand(fp, SlotOffset(slot)));
|
|
1886
|
+
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
|
1887
|
+
__ cmp(r1, ip);
|
|
1888
|
+
__ b(ne, &assign);
|
|
1889
|
+
__ mov(r1, Operand(var->name()));
|
|
1890
|
+
__ push(r1);
|
|
1891
|
+
__ CallRuntime(Runtime::kThrowReferenceError, 1);
|
|
1892
|
+
// Perform the assignment.
|
|
1893
|
+
__ bind(&assign);
|
|
1894
|
+
__ str(result_register(), MemOperand(fp, SlotOffset(slot)));
|
|
1895
|
+
break;
|
|
1896
|
+
}
|
|
1897
|
+
case Slot::CONTEXT: {
|
|
1898
|
+
// Let variables may be the hole value if they have not been
|
|
1899
|
+
// initialized. Throw a type error in this case.
|
|
1900
|
+
Label assign;
|
|
1901
|
+
MemOperand target = EmitSlotSearch(slot, r1);
|
|
1902
|
+
// Check for an initialized let binding.
|
|
1903
|
+
__ ldr(r3, target);
|
|
1904
|
+
__ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
|
1905
|
+
__ cmp(r3, ip);
|
|
1906
|
+
__ b(ne, &assign);
|
|
1907
|
+
__ mov(r3, Operand(var->name()));
|
|
1908
|
+
__ push(r3);
|
|
1909
|
+
__ CallRuntime(Runtime::kThrowReferenceError, 1);
|
|
1910
|
+
// Perform the assignment.
|
|
1911
|
+
__ bind(&assign);
|
|
1912
|
+
__ str(result_register(), target);
|
|
1913
|
+
// RecordWrite may destroy all its register arguments.
|
|
1914
|
+
__ mov(r3, result_register());
|
|
1915
|
+
int offset = Context::SlotOffset(slot->index());
|
|
1916
|
+
__ RecordWrite(r1, Operand(offset), r2, r3);
|
|
1917
|
+
break;
|
|
1918
|
+
}
|
|
1919
|
+
case Slot::LOOKUP:
|
|
1920
|
+
// Call the runtime for the assignment.
|
|
1921
|
+
__ push(r0); // Value.
|
|
1922
|
+
__ mov(r1, Operand(slot->var()->name()));
|
|
1923
|
+
__ mov(r0, Operand(Smi::FromInt(strict_mode_flag())));
|
|
1924
|
+
__ Push(cp, r1, r0); // Context, name, strict mode.
|
|
1925
|
+
__ CallRuntime(Runtime::kStoreContextSlot, 4);
|
|
1926
|
+
break;
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1946
1929
|
} else if (var->mode() != Variable::CONST) {
|
|
1947
1930
|
// Perform the assignment for non-const variables. Const assignments
|
|
1948
1931
|
// are simply skipped.
|
|
@@ -2009,7 +1992,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
|
|
|
2009
1992
|
Handle<Code> ic = is_strict_mode()
|
|
2010
1993
|
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
|
2011
1994
|
: isolate()->builtins()->StoreIC_Initialize();
|
|
2012
|
-
|
|
1995
|
+
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
|
2013
1996
|
|
|
2014
1997
|
// If the assignment ends an initialization block, revert to fast case.
|
|
2015
1998
|
if (expr->ends_initialization_block()) {
|
|
@@ -2055,7 +2038,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
|
|
2055
2038
|
Handle<Code> ic = is_strict_mode()
|
|
2056
2039
|
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
|
2057
2040
|
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
|
2058
|
-
|
|
2041
|
+
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
|
2059
2042
|
|
|
2060
2043
|
// If the assignment ends an initialization block, revert to fast case.
|
|
2061
2044
|
if (expr->ends_initialization_block()) {
|
|
@@ -2107,7 +2090,7 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
|
|
2107
2090
|
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
|
2108
2091
|
Handle<Code> ic =
|
|
2109
2092
|
isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode);
|
|
2110
|
-
|
|
2093
|
+
__ Call(ic, mode, expr->id());
|
|
2111
2094
|
RecordJSReturnSite(expr);
|
|
2112
2095
|
// Restore context register.
|
|
2113
2096
|
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
|
@@ -2141,7 +2124,7 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
|
|
2141
2124
|
Handle<Code> ic =
|
|
2142
2125
|
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
|
|
2143
2126
|
__ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
|
|
2144
|
-
|
|
2127
|
+
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
|
2145
2128
|
RecordJSReturnSite(expr);
|
|
2146
2129
|
// Restore context register.
|
|
2147
2130
|
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
|
@@ -2181,7 +2164,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
|
|
|
2181
2164
|
__ push(r1);
|
|
2182
2165
|
|
|
2183
2166
|
// Push the receiver of the enclosing function and do runtime call.
|
|
2184
|
-
|
|
2167
|
+
int receiver_offset = 2 + info_->scope()->num_parameters();
|
|
2168
|
+
__ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize));
|
|
2185
2169
|
__ push(r1);
|
|
2186
2170
|
// Push the strict mode flag.
|
|
2187
2171
|
__ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
|
|
@@ -2300,9 +2284,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
|
2300
2284
|
__ bind(&done);
|
|
2301
2285
|
// Push function.
|
|
2302
2286
|
__ push(r0);
|
|
2303
|
-
//
|
|
2304
|
-
|
|
2305
|
-
__
|
|
2287
|
+
// The receiver is implicitly the global receiver. Indicate this
|
|
2288
|
+
// by passing the hole to the call function stub.
|
|
2289
|
+
__ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
|
|
2306
2290
|
__ push(r1);
|
|
2307
2291
|
__ bind(&call);
|
|
2308
2292
|
}
|
|
@@ -2323,36 +2307,10 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
|
2323
2307
|
EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
|
|
2324
2308
|
} else {
|
|
2325
2309
|
// Call to a keyed property.
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
if (prop->is_synthetic()) {
|
|
2329
|
-
// Do not visit the object and key subexpressions (they are shared
|
|
2330
|
-
// by all occurrences of the same rewritten parameter).
|
|
2331
|
-
ASSERT(prop->obj()->AsVariableProxy() != NULL);
|
|
2332
|
-
ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL);
|
|
2333
|
-
Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot();
|
|
2334
|
-
MemOperand operand = EmitSlotSearch(slot, r1);
|
|
2335
|
-
__ ldr(r1, operand);
|
|
2336
|
-
|
|
2337
|
-
ASSERT(prop->key()->AsLiteral() != NULL);
|
|
2338
|
-
ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
|
|
2339
|
-
__ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
|
|
2340
|
-
|
|
2341
|
-
// Record source code position for IC call.
|
|
2342
|
-
SetSourcePosition(prop->position());
|
|
2343
|
-
|
|
2344
|
-
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
|
2345
|
-
EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop));
|
|
2346
|
-
__ ldr(r1, GlobalObjectOperand());
|
|
2347
|
-
__ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
|
|
2348
|
-
__ Push(r0, r1); // Function, receiver.
|
|
2349
|
-
EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
|
|
2350
|
-
} else {
|
|
2351
|
-
{ PreservePositionScope scope(masm()->positions_recorder());
|
|
2352
|
-
VisitForStackValue(prop->obj());
|
|
2353
|
-
}
|
|
2354
|
-
EmitKeyedCallWithIC(expr, prop->key());
|
|
2310
|
+
{ PreservePositionScope scope(masm()->positions_recorder());
|
|
2311
|
+
VisitForStackValue(prop->obj());
|
|
2355
2312
|
}
|
|
2313
|
+
EmitKeyedCallWithIC(expr, prop->key());
|
|
2356
2314
|
}
|
|
2357
2315
|
} else {
|
|
2358
2316
|
{ PreservePositionScope scope(masm()->positions_recorder());
|
|
@@ -2468,9 +2426,9 @@ void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
|
|
|
2468
2426
|
__ tst(r1, Operand(1 << Map::kIsUndetectable));
|
|
2469
2427
|
__ b(ne, if_false);
|
|
2470
2428
|
__ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset));
|
|
2471
|
-
__ cmp(r1, Operand(
|
|
2429
|
+
__ cmp(r1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
|
2472
2430
|
__ b(lt, if_false);
|
|
2473
|
-
__ cmp(r1, Operand(
|
|
2431
|
+
__ cmp(r1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
|
|
2474
2432
|
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
|
2475
2433
|
Split(le, if_true, if_false, fall_through);
|
|
2476
2434
|
|
|
@@ -2491,7 +2449,7 @@ void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
|
|
|
2491
2449
|
&if_true, &if_false, &fall_through);
|
|
2492
2450
|
|
|
2493
2451
|
__ JumpIfSmi(r0, if_false);
|
|
2494
|
-
__ CompareObjectType(r0, r1, r1,
|
|
2452
|
+
__ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
|
|
2495
2453
|
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
|
2496
2454
|
Split(ge, if_true, if_false, fall_through);
|
|
2497
2455
|
|
|
@@ -2588,8 +2546,7 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
|
|
|
2588
2546
|
// If a valueOf property is not found on the object check that it's
|
|
2589
2547
|
// prototype is the un-modified String prototype. If not result is false.
|
|
2590
2548
|
__ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset));
|
|
2591
|
-
__
|
|
2592
|
-
__ b(eq, if_false);
|
|
2549
|
+
__ JumpIfSmi(r2, if_false);
|
|
2593
2550
|
__ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
|
|
2594
2551
|
__ ldr(r3, ContextOperand(cp, Context::GLOBAL_INDEX));
|
|
2595
2552
|
__ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset));
|
|
@@ -2734,7 +2691,7 @@ void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
|
|
|
2734
2691
|
// parameter count in r0.
|
|
2735
2692
|
VisitForAccumulatorValue(args->at(0));
|
|
2736
2693
|
__ mov(r1, r0);
|
|
2737
|
-
__ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
|
|
2694
|
+
__ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
|
|
2738
2695
|
ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
|
|
2739
2696
|
__ CallStub(&stub);
|
|
2740
2697
|
context()->Plug(r0);
|
|
@@ -2746,7 +2703,7 @@ void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
|
|
|
2746
2703
|
|
|
2747
2704
|
Label exit;
|
|
2748
2705
|
// Get the number of formal parameters.
|
|
2749
|
-
__ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
|
|
2706
|
+
__ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters())));
|
|
2750
2707
|
|
|
2751
2708
|
// Check if the calling frame is an arguments adaptor frame.
|
|
2752
2709
|
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
|
@@ -2774,16 +2731,18 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
|
|
|
2774
2731
|
|
|
2775
2732
|
// Check that the object is a JS object but take special care of JS
|
|
2776
2733
|
// functions to make sure they have 'Function' as their class.
|
|
2777
|
-
__ CompareObjectType(r0, r0, r1,
|
|
2734
|
+
__ CompareObjectType(r0, r0, r1, FIRST_SPEC_OBJECT_TYPE);
|
|
2735
|
+
// Map is now in r0.
|
|
2778
2736
|
__ b(lt, &null);
|
|
2779
2737
|
|
|
2780
|
-
// As long as
|
|
2781
|
-
// right after
|
|
2782
|
-
//
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
__
|
|
2738
|
+
// As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
|
|
2739
|
+
// FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
|
|
2740
|
+
// LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
|
|
2741
|
+
STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
|
|
2742
|
+
STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
|
|
2743
|
+
LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
|
|
2744
|
+
__ cmp(r1, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE));
|
|
2745
|
+
__ b(ge, &function);
|
|
2787
2746
|
|
|
2788
2747
|
// Check if the constructor in the map is a function.
|
|
2789
2748
|
__ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset));
|
|
@@ -2803,7 +2762,7 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
|
|
|
2803
2762
|
|
|
2804
2763
|
// Objects with a non-function constructor have class 'Object'.
|
|
2805
2764
|
__ bind(&non_function_constructor);
|
|
2806
|
-
__ LoadRoot(r0, Heap::
|
|
2765
|
+
__ LoadRoot(r0, Heap::kObject_symbolRootIndex);
|
|
2807
2766
|
__ jmp(&done);
|
|
2808
2767
|
|
|
2809
2768
|
// Non-JS objects have class null.
|
|
@@ -2826,13 +2785,12 @@ void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
|
|
|
2826
2785
|
// with '%2s' (see Logger::LogRuntime for all the formats).
|
|
2827
2786
|
// 2 (array): Arguments to the format string.
|
|
2828
2787
|
ASSERT_EQ(args->length(), 3);
|
|
2829
|
-
#ifdef ENABLE_LOGGING_AND_PROFILING
|
|
2830
2788
|
if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
|
|
2831
2789
|
VisitForStackValue(args->at(1));
|
|
2832
2790
|
VisitForStackValue(args->at(2));
|
|
2833
2791
|
__ CallRuntime(Runtime::kLog, 2);
|
|
2834
2792
|
}
|
|
2835
|
-
|
|
2793
|
+
|
|
2836
2794
|
// Finally, we're expected to leave a value on the top of the stack.
|
|
2837
2795
|
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
|
|
2838
2796
|
context()->Plug(r0);
|
|
@@ -3175,7 +3133,8 @@ void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
|
|
|
3175
3133
|
// InvokeFunction requires the function in r1. Move it in there.
|
|
3176
3134
|
__ mov(r1, result_register());
|
|
3177
3135
|
ParameterCount count(arg_count);
|
|
3178
|
-
__ InvokeFunction(r1, count, CALL_FUNCTION
|
|
3136
|
+
__ InvokeFunction(r1, count, CALL_FUNCTION,
|
|
3137
|
+
NullCallWrapper(), CALL_AS_METHOD);
|
|
3179
3138
|
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
|
3180
3139
|
context()->Plug(r0);
|
|
3181
3140
|
}
|
|
@@ -3302,7 +3261,7 @@ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
|
|
|
3302
3261
|
|
|
3303
3262
|
Label done, not_found;
|
|
3304
3263
|
// tmp now holds finger offset as a smi.
|
|
3305
|
-
|
|
3264
|
+
STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
|
|
3306
3265
|
__ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset));
|
|
3307
3266
|
// r2 now holds finger offset as a smi.
|
|
3308
3267
|
__ add(r3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
|
@@ -3342,8 +3301,7 @@ void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
|
|
|
3342
3301
|
__ b(eq, &ok);
|
|
3343
3302
|
// Fail if either is a non-HeapObject.
|
|
3344
3303
|
__ and_(tmp, left, Operand(right));
|
|
3345
|
-
__
|
|
3346
|
-
__ b(eq, &fail);
|
|
3304
|
+
__ JumpIfSmi(tmp, &fail);
|
|
3347
3305
|
__ ldr(tmp, FieldMemOperand(left, HeapObject::kMapOffset));
|
|
3348
3306
|
__ ldrb(tmp2, FieldMemOperand(tmp, Map::kInstanceTypeOffset));
|
|
3349
3307
|
__ cmp(tmp2, Operand(JS_REGEXP_TYPE));
|
|
@@ -3433,9 +3391,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
|
|
3433
3391
|
__ b(ne, &bailout);
|
|
3434
3392
|
|
|
3435
3393
|
// Check that the array has fast elements.
|
|
3436
|
-
__
|
|
3437
|
-
__ tst(scratch2, Operand(1 << Map::kHasFastElements));
|
|
3438
|
-
__ b(eq, &bailout);
|
|
3394
|
+
__ CheckFastElements(scratch1, scratch2, &bailout);
|
|
3439
3395
|
|
|
3440
3396
|
// If the array has length zero, return the empty string.
|
|
3441
3397
|
__ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
|
|
@@ -3665,7 +3621,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
|
|
3665
3621
|
isolate()->stub_cache()->ComputeCallInitialize(arg_count,
|
|
3666
3622
|
NOT_IN_LOOP,
|
|
3667
3623
|
mode);
|
|
3668
|
-
|
|
3624
|
+
__ Call(ic, mode, expr->id());
|
|
3669
3625
|
// Restore context register.
|
|
3670
3626
|
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
|
3671
3627
|
} else {
|
|
@@ -3684,18 +3640,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
|
3684
3640
|
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
|
|
3685
3641
|
|
|
3686
3642
|
if (prop != NULL) {
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
VisitForStackValue(prop->key());
|
|
3694
|
-
__ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
|
|
3695
|
-
__ push(r1);
|
|
3696
|
-
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
|
|
3697
|
-
context()->Plug(r0);
|
|
3698
|
-
}
|
|
3643
|
+
VisitForStackValue(prop->obj());
|
|
3644
|
+
VisitForStackValue(prop->key());
|
|
3645
|
+
__ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
|
|
3646
|
+
__ push(r1);
|
|
3647
|
+
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
|
|
3648
|
+
context()->Plug(r0);
|
|
3699
3649
|
} else if (var != NULL) {
|
|
3700
3650
|
// Delete of an unqualified identifier is disallowed in strict mode
|
|
3701
3651
|
// but "delete this" is.
|
|
@@ -3773,8 +3723,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
|
3773
3723
|
Comment cmt(masm_, "[ UnaryOperation (ADD)");
|
|
3774
3724
|
VisitForAccumulatorValue(expr->expression());
|
|
3775
3725
|
Label no_conversion;
|
|
3776
|
-
__
|
|
3777
|
-
__ b(eq, &no_conversion);
|
|
3726
|
+
__ JumpIfSmi(result_register(), &no_conversion);
|
|
3778
3727
|
ToNumberStub convert_stub;
|
|
3779
3728
|
__ CallStub(&convert_stub);
|
|
3780
3729
|
__ bind(&no_conversion);
|
|
@@ -3808,7 +3757,7 @@ void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
|
|
|
3808
3757
|
// accumulator register r0.
|
|
3809
3758
|
VisitForAccumulatorValue(expr->expression());
|
|
3810
3759
|
SetSourcePosition(expr->position());
|
|
3811
|
-
|
|
3760
|
+
__ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id());
|
|
3812
3761
|
context()->Plug(r0);
|
|
3813
3762
|
}
|
|
3814
3763
|
|
|
@@ -3825,7 +3774,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
|
3825
3774
|
}
|
|
3826
3775
|
|
|
3827
3776
|
// Expression can only be a property, a global or a (parameter or local)
|
|
3828
|
-
// slot.
|
|
3777
|
+
// slot.
|
|
3829
3778
|
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
|
|
3830
3779
|
LhsKind assign_type = VARIABLE;
|
|
3831
3780
|
Property* prop = expr->expression()->AsProperty();
|
|
@@ -3840,7 +3789,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
|
3840
3789
|
if (assign_type == VARIABLE) {
|
|
3841
3790
|
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
|
|
3842
3791
|
AccumulatorValueContext context(this);
|
|
3843
|
-
EmitVariableLoad(expr->expression()->AsVariableProxy()
|
|
3792
|
+
EmitVariableLoad(expr->expression()->AsVariableProxy());
|
|
3844
3793
|
} else {
|
|
3845
3794
|
// Reserve space for result of postfix operation.
|
|
3846
3795
|
if (expr->is_postfix() && !context()->IsEffect()) {
|
|
@@ -3853,15 +3802,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
|
3853
3802
|
__ push(r0);
|
|
3854
3803
|
EmitNamedPropertyLoad(prop);
|
|
3855
3804
|
} else {
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
__ ldr(r0, EmitSlotSearch(obj_proxy->var()->AsSlot(), r0));
|
|
3859
|
-
__ push(r0);
|
|
3860
|
-
__ mov(r0, Operand(prop->key()->AsLiteral()->handle()));
|
|
3861
|
-
} else {
|
|
3862
|
-
VisitForStackValue(prop->obj());
|
|
3863
|
-
VisitForAccumulatorValue(prop->key());
|
|
3864
|
-
}
|
|
3805
|
+
VisitForStackValue(prop->obj());
|
|
3806
|
+
VisitForAccumulatorValue(prop->key());
|
|
3865
3807
|
__ ldr(r1, MemOperand(sp, 0));
|
|
3866
3808
|
__ push(r0);
|
|
3867
3809
|
EmitKeyedPropertyLoad(prop);
|
|
@@ -3926,7 +3868,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
|
3926
3868
|
SetSourcePosition(expr->position());
|
|
3927
3869
|
|
|
3928
3870
|
BinaryOpStub stub(Token::ADD, NO_OVERWRITE);
|
|
3929
|
-
|
|
3871
|
+
__ Call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId());
|
|
3872
|
+
patch_site.EmitPatchInfo();
|
|
3930
3873
|
__ bind(&done);
|
|
3931
3874
|
|
|
3932
3875
|
// Store the value returned in r0.
|
|
@@ -3957,7 +3900,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
|
3957
3900
|
Handle<Code> ic = is_strict_mode()
|
|
3958
3901
|
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
|
3959
3902
|
: isolate()->builtins()->StoreIC_Initialize();
|
|
3960
|
-
|
|
3903
|
+
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
|
3961
3904
|
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
|
|
3962
3905
|
if (expr->is_postfix()) {
|
|
3963
3906
|
if (!context()->IsEffect()) {
|
|
@@ -3974,7 +3917,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
|
3974
3917
|
Handle<Code> ic = is_strict_mode()
|
|
3975
3918
|
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
|
3976
3919
|
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
|
3977
|
-
|
|
3920
|
+
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
|
3978
3921
|
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
|
|
3979
3922
|
if (expr->is_postfix()) {
|
|
3980
3923
|
if (!context()->IsEffect()) {
|
|
@@ -4000,7 +3943,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
|
|
4000
3943
|
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
|
4001
3944
|
// Use a regular load, not a contextual load, to avoid a reference
|
|
4002
3945
|
// error.
|
|
4003
|
-
|
|
3946
|
+
__ Call(ic);
|
|
4004
3947
|
PrepareForBailout(expr, TOS_REG);
|
|
4005
3948
|
context()->Plug(r0);
|
|
4006
3949
|
} else if (proxy != NULL &&
|
|
@@ -4023,30 +3966,18 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
|
|
4023
3966
|
context()->Plug(r0);
|
|
4024
3967
|
} else {
|
|
4025
3968
|
// This expression cannot throw a reference error at the top level.
|
|
4026
|
-
|
|
3969
|
+
VisitInCurrentContext(expr);
|
|
4027
3970
|
}
|
|
4028
3971
|
}
|
|
4029
3972
|
|
|
4030
3973
|
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
Label* fall_through) {
|
|
4037
|
-
if (op != Token::EQ && op != Token::EQ_STRICT) return false;
|
|
4038
|
-
|
|
4039
|
-
// Check for the pattern: typeof <expression> == <string literal>.
|
|
4040
|
-
Literal* right_literal = right->AsLiteral();
|
|
4041
|
-
if (right_literal == NULL) return false;
|
|
4042
|
-
Handle<Object> right_literal_value = right_literal->handle();
|
|
4043
|
-
if (!right_literal_value->IsString()) return false;
|
|
4044
|
-
UnaryOperation* left_unary = left->AsUnaryOperation();
|
|
4045
|
-
if (left_unary == NULL || left_unary->op() != Token::TYPEOF) return false;
|
|
4046
|
-
Handle<String> check = Handle<String>::cast(right_literal_value);
|
|
4047
|
-
|
|
3974
|
+
void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
|
|
3975
|
+
Handle<String> check,
|
|
3976
|
+
Label* if_true,
|
|
3977
|
+
Label* if_false,
|
|
3978
|
+
Label* fall_through) {
|
|
4048
3979
|
{ AccumulatorValueContext context(this);
|
|
4049
|
-
VisitForTypeofValue(
|
|
3980
|
+
VisitForTypeofValue(expr);
|
|
4050
3981
|
}
|
|
4051
3982
|
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
|
4052
3983
|
|
|
@@ -4069,6 +4000,10 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
|
|
|
4069
4000
|
__ b(eq, if_true);
|
|
4070
4001
|
__ CompareRoot(r0, Heap::kFalseValueRootIndex);
|
|
4071
4002
|
Split(eq, if_true, if_false, fall_through);
|
|
4003
|
+
} else if (FLAG_harmony_typeof &&
|
|
4004
|
+
check->Equals(isolate()->heap()->null_symbol())) {
|
|
4005
|
+
__ CompareRoot(r0, Heap::kNullValueRootIndex);
|
|
4006
|
+
Split(eq, if_true, if_false, fall_through);
|
|
4072
4007
|
} else if (check->Equals(isolate()->heap()->undefined_symbol())) {
|
|
4073
4008
|
__ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
|
|
4074
4009
|
__ b(eq, if_true);
|
|
@@ -4081,18 +4016,20 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
|
|
|
4081
4016
|
|
|
4082
4017
|
} else if (check->Equals(isolate()->heap()->function_symbol())) {
|
|
4083
4018
|
__ JumpIfSmi(r0, if_false);
|
|
4084
|
-
__ CompareObjectType(r0, r1, r0,
|
|
4019
|
+
__ CompareObjectType(r0, r1, r0, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
|
|
4085
4020
|
Split(ge, if_true, if_false, fall_through);
|
|
4086
4021
|
|
|
4087
4022
|
} else if (check->Equals(isolate()->heap()->object_symbol())) {
|
|
4088
4023
|
__ JumpIfSmi(r0, if_false);
|
|
4089
|
-
|
|
4090
|
-
|
|
4024
|
+
if (!FLAG_harmony_typeof) {
|
|
4025
|
+
__ CompareRoot(r0, Heap::kNullValueRootIndex);
|
|
4026
|
+
__ b(eq, if_true);
|
|
4027
|
+
}
|
|
4091
4028
|
// Check for JS objects => true.
|
|
4092
|
-
__ CompareObjectType(r0, r0, r1,
|
|
4093
|
-
__ b(
|
|
4094
|
-
__ CompareInstanceType(r0, r1,
|
|
4095
|
-
__ b(
|
|
4029
|
+
__ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
|
|
4030
|
+
__ b(lt, if_false);
|
|
4031
|
+
__ CompareInstanceType(r0, r1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
|
|
4032
|
+
__ b(gt, if_false);
|
|
4096
4033
|
// Check for undetectable objects => false.
|
|
4097
4034
|
__ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
|
|
4098
4035
|
__ tst(r1, Operand(1 << Map::kIsUndetectable));
|
|
@@ -4100,8 +4037,18 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
|
|
|
4100
4037
|
} else {
|
|
4101
4038
|
if (if_false != fall_through) __ jmp(if_false);
|
|
4102
4039
|
}
|
|
4040
|
+
}
|
|
4041
|
+
|
|
4103
4042
|
|
|
4104
|
-
|
|
4043
|
+
void FullCodeGenerator::EmitLiteralCompareUndefined(Expression* expr,
|
|
4044
|
+
Label* if_true,
|
|
4045
|
+
Label* if_false,
|
|
4046
|
+
Label* fall_through) {
|
|
4047
|
+
VisitForAccumulatorValue(expr);
|
|
4048
|
+
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
|
4049
|
+
|
|
4050
|
+
__ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
|
|
4051
|
+
Split(eq, if_true, if_false, fall_through);
|
|
4105
4052
|
}
|
|
4106
4053
|
|
|
4107
4054
|
|
|
@@ -4121,14 +4068,12 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|
|
4121
4068
|
|
|
4122
4069
|
// First we try a fast inlined version of the compare when one of
|
|
4123
4070
|
// the operands is a literal.
|
|
4124
|
-
|
|
4125
|
-
Expression* left = expr->left();
|
|
4126
|
-
Expression* right = expr->right();
|
|
4127
|
-
if (TryLiteralCompare(op, left, right, if_true, if_false, fall_through)) {
|
|
4071
|
+
if (TryLiteralCompare(expr, if_true, if_false, fall_through)) {
|
|
4128
4072
|
context()->Plug(if_true, if_false);
|
|
4129
4073
|
return;
|
|
4130
4074
|
}
|
|
4131
4075
|
|
|
4076
|
+
Token::Value op = expr->op();
|
|
4132
4077
|
VisitForStackValue(expr->left());
|
|
4133
4078
|
switch (op) {
|
|
4134
4079
|
case Token::IN:
|
|
@@ -4154,11 +4099,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|
|
4154
4099
|
default: {
|
|
4155
4100
|
VisitForAccumulatorValue(expr->right());
|
|
4156
4101
|
Condition cond = eq;
|
|
4157
|
-
bool strict = false;
|
|
4158
4102
|
switch (op) {
|
|
4159
4103
|
case Token::EQ_STRICT:
|
|
4160
|
-
strict = true;
|
|
4161
|
-
// Fall through
|
|
4162
4104
|
case Token::EQ:
|
|
4163
4105
|
cond = eq;
|
|
4164
4106
|
__ pop(r1);
|
|
@@ -4203,7 +4145,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|
|
4203
4145
|
// Record position and call the compare IC.
|
|
4204
4146
|
SetSourcePosition(expr->position());
|
|
4205
4147
|
Handle<Code> ic = CompareIC::GetUninitialized(op);
|
|
4206
|
-
|
|
4148
|
+
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
|
|
4149
|
+
patch_site.EmitPatchInfo();
|
|
4207
4150
|
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
|
4208
4151
|
__ cmp(r0, Operand(0));
|
|
4209
4152
|
Split(cond, if_true, if_false, fall_through);
|
|
@@ -4236,8 +4179,7 @@ void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) {
|
|
|
4236
4179
|
__ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
|
|
4237
4180
|
__ cmp(r0, r1);
|
|
4238
4181
|
__ b(eq, if_true);
|
|
4239
|
-
__
|
|
4240
|
-
__ b(eq, if_false);
|
|
4182
|
+
__ JumpIfSmi(r0, if_false);
|
|
4241
4183
|
// It can be an undetectable object.
|
|
4242
4184
|
__ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
|
|
4243
4185
|
__ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset));
|
|
@@ -4265,70 +4207,6 @@ Register FullCodeGenerator::context_register() {
|
|
|
4265
4207
|
}
|
|
4266
4208
|
|
|
4267
4209
|
|
|
4268
|
-
void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
|
|
4269
|
-
RelocInfo::Mode mode,
|
|
4270
|
-
unsigned ast_id) {
|
|
4271
|
-
ASSERT(mode == RelocInfo::CODE_TARGET ||
|
|
4272
|
-
mode == RelocInfo::CODE_TARGET_CONTEXT);
|
|
4273
|
-
Counters* counters = isolate()->counters();
|
|
4274
|
-
switch (ic->kind()) {
|
|
4275
|
-
case Code::LOAD_IC:
|
|
4276
|
-
__ IncrementCounter(counters->named_load_full(), 1, r1, r2);
|
|
4277
|
-
break;
|
|
4278
|
-
case Code::KEYED_LOAD_IC:
|
|
4279
|
-
__ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
|
|
4280
|
-
break;
|
|
4281
|
-
case Code::STORE_IC:
|
|
4282
|
-
__ IncrementCounter(counters->named_store_full(), 1, r1, r2);
|
|
4283
|
-
break;
|
|
4284
|
-
case Code::KEYED_STORE_IC:
|
|
4285
|
-
__ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
|
|
4286
|
-
default:
|
|
4287
|
-
break;
|
|
4288
|
-
}
|
|
4289
|
-
if (ast_id == kNoASTId || mode == RelocInfo::CODE_TARGET_CONTEXT) {
|
|
4290
|
-
__ Call(ic, mode);
|
|
4291
|
-
} else {
|
|
4292
|
-
ASSERT(mode == RelocInfo::CODE_TARGET);
|
|
4293
|
-
mode = RelocInfo::CODE_TARGET_WITH_ID;
|
|
4294
|
-
__ CallWithAstId(ic, mode, ast_id);
|
|
4295
|
-
}
|
|
4296
|
-
}
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
void FullCodeGenerator::EmitCallIC(Handle<Code> ic,
|
|
4300
|
-
JumpPatchSite* patch_site,
|
|
4301
|
-
unsigned ast_id) {
|
|
4302
|
-
Counters* counters = isolate()->counters();
|
|
4303
|
-
switch (ic->kind()) {
|
|
4304
|
-
case Code::LOAD_IC:
|
|
4305
|
-
__ IncrementCounter(counters->named_load_full(), 1, r1, r2);
|
|
4306
|
-
break;
|
|
4307
|
-
case Code::KEYED_LOAD_IC:
|
|
4308
|
-
__ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
|
|
4309
|
-
break;
|
|
4310
|
-
case Code::STORE_IC:
|
|
4311
|
-
__ IncrementCounter(counters->named_store_full(), 1, r1, r2);
|
|
4312
|
-
break;
|
|
4313
|
-
case Code::KEYED_STORE_IC:
|
|
4314
|
-
__ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
|
|
4315
|
-
default:
|
|
4316
|
-
break;
|
|
4317
|
-
}
|
|
4318
|
-
|
|
4319
|
-
if (ast_id == kNoASTId) {
|
|
4320
|
-
__ Call(ic, RelocInfo::CODE_TARGET);
|
|
4321
|
-
} else {
|
|
4322
|
-
__ CallWithAstId(ic, RelocInfo::CODE_TARGET_WITH_ID, ast_id);
|
|
4323
|
-
}
|
|
4324
|
-
if (patch_site != NULL && patch_site->is_bound()) {
|
|
4325
|
-
patch_site->EmitPatchInfo();
|
|
4326
|
-
} else {
|
|
4327
|
-
__ nop(); // Signals no inlined code.
|
|
4328
|
-
}
|
|
4329
|
-
}
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
4210
|
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
|
|
4333
4211
|
ASSERT_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
|
|
4334
4212
|
__ str(value, MemOperand(fp, frame_offset));
|
|
@@ -4340,6 +4218,27 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
|
|
|
4340
4218
|
}
|
|
4341
4219
|
|
|
4342
4220
|
|
|
4221
|
+
void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
|
|
4222
|
+
Scope* declaration_scope = scope()->DeclarationScope();
|
|
4223
|
+
if (declaration_scope->is_global_scope()) {
|
|
4224
|
+
// Contexts nested in the global context have a canonical empty function
|
|
4225
|
+
// as their closure, not the anonymous closure containing the global
|
|
4226
|
+
// code. Pass a smi sentinel and let the runtime look up the empty
|
|
4227
|
+
// function.
|
|
4228
|
+
__ mov(ip, Operand(Smi::FromInt(0)));
|
|
4229
|
+
} else if (declaration_scope->is_eval_scope()) {
|
|
4230
|
+
// Contexts created by a call to eval have the same closure as the
|
|
4231
|
+
// context calling eval, not the anonymous closure containing the eval
|
|
4232
|
+
// code. Fetch it from the context.
|
|
4233
|
+
__ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX));
|
|
4234
|
+
} else {
|
|
4235
|
+
ASSERT(declaration_scope->is_function_scope());
|
|
4236
|
+
__ ldr(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
|
4237
|
+
}
|
|
4238
|
+
__ push(ip);
|
|
4239
|
+
}
|
|
4240
|
+
|
|
4241
|
+
|
|
4343
4242
|
// ----------------------------------------------------------------------------
|
|
4344
4243
|
// Non-local control flow support.
|
|
4345
4244
|
|
|
@@ -4350,7 +4249,7 @@ void FullCodeGenerator::EnterFinallyBlock() {
|
|
|
4350
4249
|
// Cook return address in link register to stack (smi encoded Code* delta)
|
|
4351
4250
|
__ sub(r1, lr, Operand(masm_->CodeObject()));
|
|
4352
4251
|
ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize);
|
|
4353
|
-
|
|
4252
|
+
STATIC_ASSERT(kSmiTag == 0);
|
|
4354
4253
|
__ add(r1, r1, Operand(r1)); // Convert to smi.
|
|
4355
4254
|
__ push(r1);
|
|
4356
4255
|
}
|