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
data/lib/libv8/v8/src/parser.cc
CHANGED
|
@@ -411,6 +411,7 @@ Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
|
|
|
411
411
|
return result;
|
|
412
412
|
}
|
|
413
413
|
|
|
414
|
+
|
|
414
415
|
// ----------------------------------------------------------------------------
|
|
415
416
|
// Target is a support class to facilitate manipulation of the
|
|
416
417
|
// Parser's target_stack_ (the stack of potential 'break' and
|
|
@@ -536,7 +537,6 @@ LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate)
|
|
|
536
537
|
|
|
537
538
|
|
|
538
539
|
LexicalScope::~LexicalScope() {
|
|
539
|
-
parser_->top_scope_->Leave();
|
|
540
540
|
parser_->top_scope_ = previous_scope_;
|
|
541
541
|
parser_->lexical_scope_ = lexical_scope_parent_;
|
|
542
542
|
parser_->with_nesting_level_ = previous_with_nesting_level_;
|
|
@@ -584,7 +584,8 @@ Parser::Parser(Handle<Script> script,
|
|
|
584
584
|
pre_data_(pre_data),
|
|
585
585
|
fni_(NULL),
|
|
586
586
|
stack_overflow_(false),
|
|
587
|
-
parenthesized_function_(false)
|
|
587
|
+
parenthesized_function_(false),
|
|
588
|
+
harmony_block_scoping_(false) {
|
|
588
589
|
AstNode::ResetIds();
|
|
589
590
|
}
|
|
590
591
|
|
|
@@ -592,11 +593,11 @@ Parser::Parser(Handle<Script> script,
|
|
|
592
593
|
FunctionLiteral* Parser::ParseProgram(Handle<String> source,
|
|
593
594
|
bool in_global_context,
|
|
594
595
|
StrictModeFlag strict_mode) {
|
|
595
|
-
|
|
596
|
+
ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
|
|
596
597
|
|
|
597
598
|
HistogramTimerScope timer(isolate()->counters()->parse());
|
|
598
599
|
isolate()->counters()->total_parse_size()->Increment(source->length());
|
|
599
|
-
fni_ = new(zone()) FuncNameInferrer();
|
|
600
|
+
fni_ = new(zone()) FuncNameInferrer(isolate());
|
|
600
601
|
|
|
601
602
|
// Initialize parser state.
|
|
602
603
|
source->TryFlatten();
|
|
@@ -648,6 +649,7 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
|
|
|
648
649
|
}
|
|
649
650
|
if (ok) {
|
|
650
651
|
result = new(zone()) FunctionLiteral(
|
|
652
|
+
isolate(),
|
|
651
653
|
no_name,
|
|
652
654
|
top_scope_,
|
|
653
655
|
body,
|
|
@@ -658,7 +660,8 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
|
|
|
658
660
|
0,
|
|
659
661
|
0,
|
|
660
662
|
source->length(),
|
|
661
|
-
|
|
663
|
+
FunctionLiteral::ANONYMOUS_EXPRESSION,
|
|
664
|
+
false); // Does not have duplicate parameters.
|
|
662
665
|
} else if (stack_overflow_) {
|
|
663
666
|
isolate()->StackOverflow();
|
|
664
667
|
}
|
|
@@ -674,7 +677,7 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
|
|
|
674
677
|
}
|
|
675
678
|
|
|
676
679
|
FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
|
|
677
|
-
|
|
680
|
+
ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
|
|
678
681
|
HistogramTimerScope timer(isolate()->counters()->parse_lazy());
|
|
679
682
|
Handle<String> source(String::cast(script_->source()));
|
|
680
683
|
isolate()->counters()->total_parse_size()->Increment(source->length());
|
|
@@ -707,7 +710,7 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
|
|
|
707
710
|
ASSERT(target_stack_ == NULL);
|
|
708
711
|
|
|
709
712
|
Handle<String> name(String::cast(shared_info->name()));
|
|
710
|
-
fni_ = new(zone()) FuncNameInferrer();
|
|
713
|
+
fni_ = new(zone()) FuncNameInferrer(isolate());
|
|
711
714
|
fni_->PushEnclosingName(name);
|
|
712
715
|
|
|
713
716
|
mode_ = PARSE_EAGERLY;
|
|
@@ -717,7 +720,6 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
|
|
|
717
720
|
|
|
718
721
|
{
|
|
719
722
|
// Parse the function literal.
|
|
720
|
-
Handle<String> no_name = isolate()->factory()->empty_symbol();
|
|
721
723
|
Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
|
|
722
724
|
if (!info->closure().is_null()) {
|
|
723
725
|
scope = Scope::DeserializeScopeChain(info, scope);
|
|
@@ -728,12 +730,17 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
|
|
|
728
730
|
top_scope_->EnableStrictMode();
|
|
729
731
|
}
|
|
730
732
|
|
|
731
|
-
|
|
732
|
-
shared_info->
|
|
733
|
+
FunctionLiteral::Type type = shared_info->is_expression()
|
|
734
|
+
? (shared_info->is_anonymous()
|
|
735
|
+
? FunctionLiteral::ANONYMOUS_EXPRESSION
|
|
736
|
+
: FunctionLiteral::NAMED_EXPRESSION)
|
|
737
|
+
: FunctionLiteral::DECLARATION;
|
|
733
738
|
bool ok = true;
|
|
734
739
|
result = ParseFunctionLiteral(name,
|
|
735
|
-
false,
|
|
736
|
-
RelocInfo::kNoPosition,
|
|
740
|
+
false, // Strict mode name already checked.
|
|
741
|
+
RelocInfo::kNoPosition,
|
|
742
|
+
type,
|
|
743
|
+
&ok);
|
|
737
744
|
// Make sure the results agree.
|
|
738
745
|
ASSERT(ok == (result != NULL));
|
|
739
746
|
}
|
|
@@ -803,6 +810,10 @@ void Parser::ReportMessageAt(Scanner::Location source_location,
|
|
|
803
810
|
isolate()->Throw(*result, &location);
|
|
804
811
|
}
|
|
805
812
|
|
|
813
|
+
void Parser::SetHarmonyBlockScoping(bool block_scoping) {
|
|
814
|
+
scanner().SetHarmonyBlockScoping(block_scoping);
|
|
815
|
+
harmony_block_scoping_ = block_scoping;
|
|
816
|
+
}
|
|
806
817
|
|
|
807
818
|
// Base class containing common code for the different finder classes used by
|
|
808
819
|
// the parser.
|
|
@@ -822,14 +833,24 @@ class ParserFinder {
|
|
|
822
833
|
// form expr.a = ...; expr.b = ...; etc.
|
|
823
834
|
class InitializationBlockFinder : public ParserFinder {
|
|
824
835
|
public:
|
|
825
|
-
|
|
826
|
-
|
|
836
|
+
// We find and mark the initialization blocks in top level
|
|
837
|
+
// non-looping code only. This is because the optimization prevents
|
|
838
|
+
// reuse of the map transitions, so it should be used only for code
|
|
839
|
+
// that will only be run once.
|
|
840
|
+
InitializationBlockFinder(Scope* top_scope, Target* target)
|
|
841
|
+
: enabled_(top_scope->DeclarationScope()->is_global_scope() &&
|
|
842
|
+
!IsLoopTarget(target)),
|
|
843
|
+
first_in_block_(NULL),
|
|
844
|
+
last_in_block_(NULL),
|
|
845
|
+
block_size_(0) {}
|
|
827
846
|
|
|
828
847
|
~InitializationBlockFinder() {
|
|
848
|
+
if (!enabled_) return;
|
|
829
849
|
if (InBlock()) EndBlock();
|
|
830
850
|
}
|
|
831
851
|
|
|
832
852
|
void Update(Statement* stat) {
|
|
853
|
+
if (!enabled_) return;
|
|
833
854
|
Assignment* assignment = AsAssignment(stat);
|
|
834
855
|
if (InBlock()) {
|
|
835
856
|
if (BlockContinues(assignment)) {
|
|
@@ -850,6 +871,14 @@ class InitializationBlockFinder : public ParserFinder {
|
|
|
850
871
|
// the overhead exceeds the savings below this limit.
|
|
851
872
|
static const int kMinInitializationBlock = 3;
|
|
852
873
|
|
|
874
|
+
static bool IsLoopTarget(Target* target) {
|
|
875
|
+
while (target != NULL) {
|
|
876
|
+
if (target->node()->AsIterationStatement() != NULL) return true;
|
|
877
|
+
target = target->previous();
|
|
878
|
+
}
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
|
|
853
882
|
// Returns true if the expressions appear to denote the same object.
|
|
854
883
|
// In the context of initialization blocks, we only consider expressions
|
|
855
884
|
// of the form 'expr.x' or expr["x"].
|
|
@@ -912,6 +941,7 @@ class InitializationBlockFinder : public ParserFinder {
|
|
|
912
941
|
|
|
913
942
|
bool InBlock() { return first_in_block_ != NULL; }
|
|
914
943
|
|
|
944
|
+
const bool enabled_;
|
|
915
945
|
Assignment* first_in_block_;
|
|
916
946
|
Assignment* last_in_block_;
|
|
917
947
|
int block_size_;
|
|
@@ -1064,6 +1094,25 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
|
|
|
1064
1094
|
};
|
|
1065
1095
|
|
|
1066
1096
|
|
|
1097
|
+
Statement* Parser::ParseSourceElement(ZoneStringList* labels,
|
|
1098
|
+
bool* ok) {
|
|
1099
|
+
if (peek() == Token::FUNCTION) {
|
|
1100
|
+
// FunctionDeclaration is only allowed in the context of SourceElements
|
|
1101
|
+
// (Ecma 262 5th Edition, clause 14):
|
|
1102
|
+
// SourceElement:
|
|
1103
|
+
// Statement
|
|
1104
|
+
// FunctionDeclaration
|
|
1105
|
+
// Common language extension is to allow function declaration in place
|
|
1106
|
+
// of any statement. This language extension is disabled in strict mode.
|
|
1107
|
+
return ParseFunctionDeclaration(ok);
|
|
1108
|
+
} else if (peek() == Token::LET) {
|
|
1109
|
+
return ParseVariableStatement(kSourceElement, ok);
|
|
1110
|
+
} else {
|
|
1111
|
+
return ParseStatement(labels, ok);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
|
|
1067
1116
|
void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
|
|
1068
1117
|
int end_token,
|
|
1069
1118
|
bool* ok) {
|
|
@@ -1077,7 +1126,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
|
|
|
1077
1126
|
TargetScope scope(&this->target_stack_);
|
|
1078
1127
|
|
|
1079
1128
|
ASSERT(processor != NULL);
|
|
1080
|
-
InitializationBlockFinder block_finder;
|
|
1129
|
+
InitializationBlockFinder block_finder(top_scope_, target_stack_);
|
|
1081
1130
|
ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
|
|
1082
1131
|
bool directive_prologue = true; // Parsing directive prologue.
|
|
1083
1132
|
|
|
@@ -1087,21 +1136,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
|
|
|
1087
1136
|
}
|
|
1088
1137
|
|
|
1089
1138
|
Scanner::Location token_loc = scanner().peek_location();
|
|
1090
|
-
|
|
1091
|
-
Statement* stat;
|
|
1092
|
-
if (peek() == Token::FUNCTION) {
|
|
1093
|
-
// FunctionDeclaration is only allowed in the context of SourceElements
|
|
1094
|
-
// (Ecma 262 5th Edition, clause 14):
|
|
1095
|
-
// SourceElement:
|
|
1096
|
-
// Statement
|
|
1097
|
-
// FunctionDeclaration
|
|
1098
|
-
// Common language extension is to allow function declaration in place
|
|
1099
|
-
// of any statement. This language extension is disabled in strict mode.
|
|
1100
|
-
stat = ParseFunctionDeclaration(CHECK_OK);
|
|
1101
|
-
} else {
|
|
1102
|
-
stat = ParseStatement(NULL, CHECK_OK);
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1139
|
+
Statement* stat = ParseSourceElement(NULL, CHECK_OK);
|
|
1105
1140
|
if (stat == NULL || stat->IsEmpty()) {
|
|
1106
1141
|
directive_prologue = false; // End of directive prologue.
|
|
1107
1142
|
continue;
|
|
@@ -1132,12 +1167,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
|
|
|
1132
1167
|
}
|
|
1133
1168
|
}
|
|
1134
1169
|
|
|
1135
|
-
|
|
1136
|
-
// This is because the optimization prevents reuse of the map transitions,
|
|
1137
|
-
// so it should be used only for code that will only be run once.
|
|
1138
|
-
if (top_scope_->is_global_scope()) {
|
|
1139
|
-
block_finder.Update(stat);
|
|
1140
|
-
}
|
|
1170
|
+
block_finder.Update(stat);
|
|
1141
1171
|
// Find and mark all assignments to named properties in this (this.x =)
|
|
1142
1172
|
if (top_scope_->is_function_scope()) {
|
|
1143
1173
|
this_property_assignment_finder.Update(top_scope_, stat);
|
|
@@ -1194,7 +1224,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
|
|
1194
1224
|
|
|
1195
1225
|
case Token::CONST: // fall through
|
|
1196
1226
|
case Token::VAR:
|
|
1197
|
-
stmt = ParseVariableStatement(ok);
|
|
1227
|
+
stmt = ParseVariableStatement(kStatement, ok);
|
|
1198
1228
|
break;
|
|
1199
1229
|
|
|
1200
1230
|
case Token::SEMICOLON:
|
|
@@ -1247,7 +1277,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
|
|
1247
1277
|
// one must take great care not to treat it as a
|
|
1248
1278
|
// fall-through. It is much easier just to wrap the entire
|
|
1249
1279
|
// try-statement in a statement block and put the labels there
|
|
1250
|
-
Block* result = new(zone()) Block(labels, 1, false);
|
|
1280
|
+
Block* result = new(zone()) Block(isolate(), labels, 1, false);
|
|
1251
1281
|
Target target(&this->target_stack_, result);
|
|
1252
1282
|
TryStatement* statement = ParseTryStatement(CHECK_OK);
|
|
1253
1283
|
if (statement) {
|
|
@@ -1269,9 +1299,6 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
|
|
1269
1299
|
return ParseFunctionDeclaration(ok);
|
|
1270
1300
|
}
|
|
1271
1301
|
|
|
1272
|
-
case Token::NATIVE:
|
|
1273
|
-
return ParseNativeDeclaration(ok);
|
|
1274
|
-
|
|
1275
1302
|
case Token::DEBUGGER:
|
|
1276
1303
|
stmt = ParseDebuggerStatement(ok);
|
|
1277
1304
|
break;
|
|
@@ -1292,9 +1319,9 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
|
|
1292
1319
|
bool resolve,
|
|
1293
1320
|
bool* ok) {
|
|
1294
1321
|
Variable* var = NULL;
|
|
1295
|
-
// If we are inside a function, a declaration of a variable
|
|
1296
|
-
//
|
|
1297
|
-
//
|
|
1322
|
+
// If we are inside a function, a declaration of a var/const variable is a
|
|
1323
|
+
// truly local variable, and the scope of the variable is always the function
|
|
1324
|
+
// scope.
|
|
1298
1325
|
|
|
1299
1326
|
// If a function scope exists, then we can statically declare this
|
|
1300
1327
|
// variable and also set its mode. In any case, a Declaration node
|
|
@@ -1304,29 +1331,34 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
|
|
1304
1331
|
// to the calling function context.
|
|
1305
1332
|
// Similarly, strict mode eval scope does not leak variable declarations to
|
|
1306
1333
|
// the caller's scope so we declare all locals, too.
|
|
1307
|
-
|
|
1308
|
-
|
|
1334
|
+
|
|
1335
|
+
Scope* declaration_scope = mode == Variable::LET ? top_scope_
|
|
1336
|
+
: top_scope_->DeclarationScope();
|
|
1337
|
+
if (declaration_scope->is_function_scope() ||
|
|
1338
|
+
declaration_scope->is_strict_mode_eval_scope() ||
|
|
1339
|
+
declaration_scope->is_block_scope()) {
|
|
1309
1340
|
// Declare the variable in the function scope.
|
|
1310
|
-
var =
|
|
1341
|
+
var = declaration_scope->LocalLookup(name);
|
|
1311
1342
|
if (var == NULL) {
|
|
1312
1343
|
// Declare the name.
|
|
1313
|
-
var =
|
|
1344
|
+
var = declaration_scope->DeclareLocal(name, mode);
|
|
1314
1345
|
} else {
|
|
1315
|
-
// The name was declared before; check for conflicting
|
|
1316
|
-
//
|
|
1317
|
-
//
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
// We only have vars and consts in declarations.
|
|
1346
|
+
// The name was declared before; check for conflicting re-declarations.
|
|
1347
|
+
// We have a conflict if either of the declarations is not a var. There
|
|
1348
|
+
// is similar code in runtime.cc in the Declare functions.
|
|
1349
|
+
if ((mode != Variable::VAR) || (var->mode() != Variable::VAR)) {
|
|
1350
|
+
// We only have vars, consts and lets in declarations.
|
|
1321
1351
|
ASSERT(var->mode() == Variable::VAR ||
|
|
1322
|
-
var->mode() == Variable::CONST
|
|
1323
|
-
|
|
1352
|
+
var->mode() == Variable::CONST ||
|
|
1353
|
+
var->mode() == Variable::LET);
|
|
1354
|
+
const char* type = (var->mode() == Variable::VAR) ? "var" :
|
|
1355
|
+
(var->mode() == Variable::CONST) ? "const" : "let";
|
|
1324
1356
|
Handle<String> type_string =
|
|
1325
1357
|
isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
|
|
1326
1358
|
Expression* expression =
|
|
1327
1359
|
NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
|
|
1328
1360
|
type_string, name);
|
|
1329
|
-
|
|
1361
|
+
declaration_scope->SetIllegalRedeclaration(expression);
|
|
1330
1362
|
}
|
|
1331
1363
|
}
|
|
1332
1364
|
}
|
|
@@ -1347,14 +1379,18 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
|
|
1347
1379
|
// semantic issue as long as we keep the source order, but it may be
|
|
1348
1380
|
// a performance issue since it may lead to repeated
|
|
1349
1381
|
// Runtime::DeclareContextSlot() calls.
|
|
1350
|
-
VariableProxy* proxy =
|
|
1351
|
-
|
|
1382
|
+
VariableProxy* proxy = declaration_scope->NewUnresolved(name, false);
|
|
1383
|
+
declaration_scope->AddDeclaration(new(zone()) Declaration(proxy, mode, fun));
|
|
1352
1384
|
|
|
1353
1385
|
// For global const variables we bind the proxy to a variable.
|
|
1354
|
-
if (mode == Variable::CONST &&
|
|
1386
|
+
if (mode == Variable::CONST && declaration_scope->is_global_scope()) {
|
|
1355
1387
|
ASSERT(resolve); // should be set by all callers
|
|
1356
1388
|
Variable::Kind kind = Variable::NORMAL;
|
|
1357
|
-
var = new(zone()) Variable(
|
|
1389
|
+
var = new(zone()) Variable(declaration_scope,
|
|
1390
|
+
name,
|
|
1391
|
+
Variable::CONST,
|
|
1392
|
+
true,
|
|
1393
|
+
kind);
|
|
1358
1394
|
}
|
|
1359
1395
|
|
|
1360
1396
|
// If requested and we have a local variable, bind the proxy to the variable
|
|
@@ -1392,13 +1428,6 @@ VariableProxy* Parser::Declare(Handle<String> name,
|
|
|
1392
1428
|
// declaration is resolved by looking up the function through a
|
|
1393
1429
|
// callback provided by the extension.
|
|
1394
1430
|
Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
|
1395
|
-
if (extension_ == NULL) {
|
|
1396
|
-
ReportUnexpectedToken(Token::NATIVE);
|
|
1397
|
-
*ok = false;
|
|
1398
|
-
return NULL;
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
Expect(Token::NATIVE, CHECK_OK);
|
|
1402
1431
|
Expect(Token::FUNCTION, CHECK_OK);
|
|
1403
1432
|
Handle<String> name = ParseIdentifier(CHECK_OK);
|
|
1404
1433
|
Expect(Token::LPAREN, CHECK_OK);
|
|
@@ -1417,7 +1446,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
|
|
1417
1446
|
// isn't lazily compiled. The extension structures are only
|
|
1418
1447
|
// accessible while parsing the first time not when reparsing
|
|
1419
1448
|
// because of lazy compilation.
|
|
1420
|
-
top_scope_->ForceEagerCompilation();
|
|
1449
|
+
top_scope_->DeclarationScope()->ForceEagerCompilation();
|
|
1421
1450
|
|
|
1422
1451
|
// Compute the function template for the native function.
|
|
1423
1452
|
v8::Handle<v8::FunctionTemplate> fun_template =
|
|
@@ -1443,10 +1472,10 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
|
|
1443
1472
|
// introduced dynamically when we meet their declarations, whereas
|
|
1444
1473
|
// other functions are setup when entering the surrounding scope.
|
|
1445
1474
|
SharedFunctionInfoLiteral* lit =
|
|
1446
|
-
new(zone()) SharedFunctionInfoLiteral(shared);
|
|
1475
|
+
new(zone()) SharedFunctionInfoLiteral(isolate(), shared);
|
|
1447
1476
|
VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
|
|
1448
1477
|
return new(zone()) ExpressionStatement(new(zone()) Assignment(
|
|
1449
|
-
Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
|
|
1478
|
+
isolate(), Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
|
|
1450
1479
|
}
|
|
1451
1480
|
|
|
1452
1481
|
|
|
@@ -1455,22 +1484,26 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
|
|
|
1455
1484
|
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
|
|
1456
1485
|
Expect(Token::FUNCTION, CHECK_OK);
|
|
1457
1486
|
int function_token_position = scanner().location().beg_pos;
|
|
1458
|
-
bool
|
|
1459
|
-
Handle<String> name =
|
|
1487
|
+
bool is_strict_reserved = false;
|
|
1488
|
+
Handle<String> name = ParseIdentifierOrStrictReservedWord(
|
|
1489
|
+
&is_strict_reserved, CHECK_OK);
|
|
1460
1490
|
FunctionLiteral* fun = ParseFunctionLiteral(name,
|
|
1461
|
-
|
|
1491
|
+
is_strict_reserved,
|
|
1462
1492
|
function_token_position,
|
|
1463
|
-
DECLARATION,
|
|
1493
|
+
FunctionLiteral::DECLARATION,
|
|
1464
1494
|
CHECK_OK);
|
|
1465
1495
|
// Even if we're not at the top-level of the global or a function
|
|
1466
1496
|
// scope, we treat is as such and introduce the function with it's
|
|
1467
1497
|
// initial value upon entering the corresponding scope.
|
|
1468
|
-
|
|
1498
|
+
Variable::Mode mode = harmony_block_scoping_ ? Variable::LET : Variable::VAR;
|
|
1499
|
+
Declare(name, mode, fun, true, CHECK_OK);
|
|
1469
1500
|
return EmptyStatement();
|
|
1470
1501
|
}
|
|
1471
1502
|
|
|
1472
1503
|
|
|
1473
1504
|
Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
|
|
1505
|
+
if (harmony_block_scoping_) return ParseScopedBlock(labels, ok);
|
|
1506
|
+
|
|
1474
1507
|
// Block ::
|
|
1475
1508
|
// '{' Statement* '}'
|
|
1476
1509
|
|
|
@@ -1478,24 +1511,81 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
|
|
|
1478
1511
|
// (ECMA-262, 3rd, 12.2)
|
|
1479
1512
|
//
|
|
1480
1513
|
// Construct block expecting 16 statements.
|
|
1481
|
-
Block* result = new(zone()) Block(labels, 16, false);
|
|
1514
|
+
Block* result = new(zone()) Block(isolate(), labels, 16, false);
|
|
1482
1515
|
Target target(&this->target_stack_, result);
|
|
1483
1516
|
Expect(Token::LBRACE, CHECK_OK);
|
|
1517
|
+
InitializationBlockFinder block_finder(top_scope_, target_stack_);
|
|
1484
1518
|
while (peek() != Token::RBRACE) {
|
|
1485
1519
|
Statement* stat = ParseStatement(NULL, CHECK_OK);
|
|
1486
|
-
if (stat && !stat->IsEmpty())
|
|
1520
|
+
if (stat && !stat->IsEmpty()) {
|
|
1521
|
+
result->AddStatement(stat);
|
|
1522
|
+
block_finder.Update(stat);
|
|
1523
|
+
}
|
|
1487
1524
|
}
|
|
1488
1525
|
Expect(Token::RBRACE, CHECK_OK);
|
|
1489
1526
|
return result;
|
|
1490
1527
|
}
|
|
1491
1528
|
|
|
1492
1529
|
|
|
1493
|
-
Block* Parser::
|
|
1530
|
+
Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
|
|
1531
|
+
// Construct block expecting 16 statements.
|
|
1532
|
+
Block* body = new(zone()) Block(isolate(), labels, 16, false);
|
|
1533
|
+
Scope* saved_scope = top_scope_;
|
|
1534
|
+
Scope* block_scope = NewScope(top_scope_,
|
|
1535
|
+
Scope::BLOCK_SCOPE,
|
|
1536
|
+
inside_with());
|
|
1537
|
+
body->set_block_scope(block_scope);
|
|
1538
|
+
block_scope->DeclareLocal(isolate()->factory()->block_scope_symbol(),
|
|
1539
|
+
Variable::VAR);
|
|
1540
|
+
if (top_scope_->is_strict_mode()) {
|
|
1541
|
+
block_scope->EnableStrictMode();
|
|
1542
|
+
}
|
|
1543
|
+
top_scope_ = block_scope;
|
|
1544
|
+
|
|
1545
|
+
// Parse the statements and collect escaping labels.
|
|
1546
|
+
TargetCollector collector;
|
|
1547
|
+
Target target(&this->target_stack_, &collector);
|
|
1548
|
+
Expect(Token::LBRACE, CHECK_OK);
|
|
1549
|
+
{
|
|
1550
|
+
Target target_body(&this->target_stack_, body);
|
|
1551
|
+
InitializationBlockFinder block_finder(top_scope_, target_stack_);
|
|
1552
|
+
|
|
1553
|
+
while (peek() != Token::RBRACE) {
|
|
1554
|
+
Statement* stat = ParseSourceElement(NULL, CHECK_OK);
|
|
1555
|
+
if (stat && !stat->IsEmpty()) {
|
|
1556
|
+
body->AddStatement(stat);
|
|
1557
|
+
block_finder.Update(stat);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
Expect(Token::RBRACE, CHECK_OK);
|
|
1562
|
+
|
|
1563
|
+
// Create exit block.
|
|
1564
|
+
Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
|
|
1565
|
+
exit->AddStatement(new(zone()) ExitContextStatement());
|
|
1566
|
+
|
|
1567
|
+
// Create a try-finally statement.
|
|
1568
|
+
TryFinallyStatement* try_finally =
|
|
1569
|
+
new(zone()) TryFinallyStatement(body, exit);
|
|
1570
|
+
try_finally->set_escaping_targets(collector.targets());
|
|
1571
|
+
top_scope_ = saved_scope;
|
|
1572
|
+
|
|
1573
|
+
// Create a result block.
|
|
1574
|
+
Block* result = new(zone()) Block(isolate(), NULL, 1, false);
|
|
1575
|
+
result->AddStatement(try_finally);
|
|
1576
|
+
return result;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
|
|
1580
|
+
Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
|
|
1581
|
+
bool* ok) {
|
|
1494
1582
|
// VariableStatement ::
|
|
1495
1583
|
// VariableDeclarations ';'
|
|
1496
1584
|
|
|
1497
|
-
|
|
1498
|
-
Block* result = ParseVariableDeclarations(
|
|
1585
|
+
Handle<String> ignore;
|
|
1586
|
+
Block* result = ParseVariableDeclarations(var_context,
|
|
1587
|
+
&ignore,
|
|
1588
|
+
CHECK_OK);
|
|
1499
1589
|
ExpectSemicolon(CHECK_OK);
|
|
1500
1590
|
return result;
|
|
1501
1591
|
}
|
|
@@ -1512,14 +1602,20 @@ bool Parser::IsEvalOrArguments(Handle<String> string) {
|
|
|
1512
1602
|
// *var is untouched; in particular, it is the caller's responsibility
|
|
1513
1603
|
// to initialize it properly. This mechanism is used for the parsing
|
|
1514
1604
|
// of 'for-in' loops.
|
|
1515
|
-
Block* Parser::ParseVariableDeclarations(
|
|
1516
|
-
|
|
1605
|
+
Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
|
|
1606
|
+
Handle<String>* out,
|
|
1517
1607
|
bool* ok) {
|
|
1518
1608
|
// VariableDeclarations ::
|
|
1519
1609
|
// ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
|
|
1520
1610
|
|
|
1521
1611
|
Variable::Mode mode = Variable::VAR;
|
|
1612
|
+
// True if the binding needs initialization. 'let' and 'const' declared
|
|
1613
|
+
// bindings are created uninitialized by their declaration nodes and
|
|
1614
|
+
// need initialization. 'var' declared bindings are always initialized
|
|
1615
|
+
// immediately by their declaration nodes.
|
|
1616
|
+
bool needs_init = false;
|
|
1522
1617
|
bool is_const = false;
|
|
1618
|
+
Token::Value init_op = Token::INIT_VAR;
|
|
1523
1619
|
if (peek() == Token::VAR) {
|
|
1524
1620
|
Consume(Token::VAR);
|
|
1525
1621
|
} else if (peek() == Token::CONST) {
|
|
@@ -1531,13 +1627,29 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1531
1627
|
}
|
|
1532
1628
|
mode = Variable::CONST;
|
|
1533
1629
|
is_const = true;
|
|
1630
|
+
needs_init = true;
|
|
1631
|
+
init_op = Token::INIT_CONST;
|
|
1632
|
+
} else if (peek() == Token::LET) {
|
|
1633
|
+
Consume(Token::LET);
|
|
1634
|
+
if (var_context != kSourceElement &&
|
|
1635
|
+
var_context != kForStatement) {
|
|
1636
|
+
ASSERT(var_context == kStatement);
|
|
1637
|
+
ReportMessage("unprotected_let", Vector<const char*>::empty());
|
|
1638
|
+
*ok = false;
|
|
1639
|
+
return NULL;
|
|
1640
|
+
}
|
|
1641
|
+
mode = Variable::LET;
|
|
1642
|
+
needs_init = true;
|
|
1643
|
+
init_op = Token::INIT_LET;
|
|
1534
1644
|
} else {
|
|
1535
1645
|
UNREACHABLE(); // by current callers
|
|
1536
1646
|
}
|
|
1537
1647
|
|
|
1538
|
-
|
|
1648
|
+
Scope* declaration_scope = mode == Variable::LET
|
|
1649
|
+
? top_scope_ : top_scope_->DeclarationScope();
|
|
1650
|
+
// The scope of a var/const declared variable anywhere inside a function
|
|
1539
1651
|
// is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
|
|
1540
|
-
// transform a source-level
|
|
1652
|
+
// transform a source-level var/const declaration into a (Function)
|
|
1541
1653
|
// Scope declaration, and rewrite the source-level initialization into an
|
|
1542
1654
|
// assignment statement. We use a block to collect multiple assignments.
|
|
1543
1655
|
//
|
|
@@ -1548,19 +1660,19 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1548
1660
|
// is inside an initializer block, it is ignored.
|
|
1549
1661
|
//
|
|
1550
1662
|
// Create new block with one expected declaration.
|
|
1551
|
-
Block* block = new(zone()) Block(NULL, 1, true);
|
|
1552
|
-
VariableProxy* last_var = NULL; // the last variable declared
|
|
1663
|
+
Block* block = new(zone()) Block(isolate(), NULL, 1, true);
|
|
1553
1664
|
int nvars = 0; // the number of variables declared
|
|
1665
|
+
Handle<String> name;
|
|
1554
1666
|
do {
|
|
1555
1667
|
if (fni_ != NULL) fni_->Enter();
|
|
1556
1668
|
|
|
1557
1669
|
// Parse variable name.
|
|
1558
1670
|
if (nvars > 0) Consume(Token::COMMA);
|
|
1559
|
-
|
|
1671
|
+
name = ParseIdentifier(CHECK_OK);
|
|
1560
1672
|
if (fni_ != NULL) fni_->PushVariableName(name);
|
|
1561
1673
|
|
|
1562
1674
|
// Strict mode variables may not be named eval or arguments
|
|
1563
|
-
if (
|
|
1675
|
+
if (declaration_scope->is_strict_mode() && IsEvalOrArguments(name)) {
|
|
1564
1676
|
ReportMessage("strict_var_name", Vector<const char*>::empty());
|
|
1565
1677
|
*ok = false;
|
|
1566
1678
|
return NULL;
|
|
@@ -1578,11 +1690,10 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1578
1690
|
// If we have a const declaration, in an inner scope, the proxy is always
|
|
1579
1691
|
// bound to the declared variable (independent of possibly surrounding with
|
|
1580
1692
|
// statements).
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
CHECK_OK);
|
|
1693
|
+
Declare(name, mode, NULL, is_const /* always bound for CONST! */,
|
|
1694
|
+
CHECK_OK);
|
|
1584
1695
|
nvars++;
|
|
1585
|
-
if (
|
|
1696
|
+
if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
|
|
1586
1697
|
ReportMessageAt(scanner().location(), "too_many_variables",
|
|
1587
1698
|
Vector<const char*>::empty());
|
|
1588
1699
|
*ok = false;
|
|
@@ -1598,10 +1709,10 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1598
1709
|
//
|
|
1599
1710
|
// var v; v = x;
|
|
1600
1711
|
//
|
|
1601
|
-
// In particular, we need to re-lookup 'v'
|
|
1602
|
-
// different 'v' than the 'v' in the
|
|
1603
|
-
//
|
|
1604
|
-
//
|
|
1712
|
+
// In particular, we need to re-lookup 'v' (in top_scope_, not
|
|
1713
|
+
// declaration_scope) as it may be a different 'v' than the 'v' in the
|
|
1714
|
+
// declaration (e.g., if we are inside a 'with' statement or 'catch'
|
|
1715
|
+
// block).
|
|
1605
1716
|
//
|
|
1606
1717
|
// However, note that const declarations are different! A const
|
|
1607
1718
|
// declaration of the form:
|
|
@@ -1616,19 +1727,23 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1616
1727
|
// one - there is no re-lookup (see the last parameter of the
|
|
1617
1728
|
// Declare() call above).
|
|
1618
1729
|
|
|
1730
|
+
Scope* initialization_scope = is_const ? declaration_scope : top_scope_;
|
|
1619
1731
|
Expression* value = NULL;
|
|
1620
1732
|
int position = -1;
|
|
1621
1733
|
if (peek() == Token::ASSIGN) {
|
|
1622
1734
|
Expect(Token::ASSIGN, CHECK_OK);
|
|
1623
1735
|
position = scanner().location().beg_pos;
|
|
1624
|
-
value = ParseAssignmentExpression(
|
|
1736
|
+
value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
|
|
1625
1737
|
// Don't infer if it is "a = function(){...}();"-like expression.
|
|
1626
|
-
if (fni_ != NULL &&
|
|
1738
|
+
if (fni_ != NULL &&
|
|
1739
|
+
value->AsCall() == NULL &&
|
|
1740
|
+
value->AsCallNew() == NULL) {
|
|
1741
|
+
fni_->Infer();
|
|
1742
|
+
}
|
|
1627
1743
|
}
|
|
1628
1744
|
|
|
1629
|
-
// Make sure that 'const
|
|
1630
|
-
|
|
1631
|
-
if (value == NULL && is_const) {
|
|
1745
|
+
// Make sure that 'const x' and 'let x' initialize 'x' to undefined.
|
|
1746
|
+
if (value == NULL && needs_init) {
|
|
1632
1747
|
value = GetLiteralUndefined();
|
|
1633
1748
|
}
|
|
1634
1749
|
|
|
@@ -1652,11 +1767,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1652
1767
|
// browsers where the global object (window) has lots of
|
|
1653
1768
|
// properties defined in prototype objects.
|
|
1654
1769
|
|
|
1655
|
-
if (
|
|
1770
|
+
if (initialization_scope->is_global_scope()) {
|
|
1656
1771
|
// Compute the arguments for the runtime call.
|
|
1657
1772
|
ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
|
|
1658
1773
|
// We have at least 1 parameter.
|
|
1659
|
-
arguments->Add(
|
|
1774
|
+
arguments->Add(NewLiteral(name));
|
|
1660
1775
|
CallRuntime* initialize;
|
|
1661
1776
|
|
|
1662
1777
|
if (is_const) {
|
|
@@ -1669,14 +1784,17 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1669
1784
|
// the number of arguments (1 or 2).
|
|
1670
1785
|
initialize =
|
|
1671
1786
|
new(zone()) CallRuntime(
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1787
|
+
isolate(),
|
|
1788
|
+
isolate()->factory()->InitializeConstGlobal_symbol(),
|
|
1789
|
+
Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
|
|
1790
|
+
arguments);
|
|
1675
1791
|
} else {
|
|
1676
1792
|
// Add strict mode.
|
|
1677
1793
|
// We may want to pass singleton to avoid Literal allocations.
|
|
1678
|
-
|
|
1679
|
-
|
|
1794
|
+
StrictModeFlag flag = initialization_scope->is_strict_mode()
|
|
1795
|
+
? kStrictMode
|
|
1796
|
+
: kNonStrictMode;
|
|
1797
|
+
arguments->Add(NewNumberLiteral(flag));
|
|
1680
1798
|
|
|
1681
1799
|
// Be careful not to assign a value to the global variable if
|
|
1682
1800
|
// we're in a with. The initialization value should not
|
|
@@ -1693,9 +1811,10 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1693
1811
|
// the number of arguments (2 or 3).
|
|
1694
1812
|
initialize =
|
|
1695
1813
|
new(zone()) CallRuntime(
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1814
|
+
isolate(),
|
|
1815
|
+
isolate()->factory()->InitializeVarGlobal_symbol(),
|
|
1816
|
+
Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
|
|
1817
|
+
arguments);
|
|
1699
1818
|
}
|
|
1700
1819
|
|
|
1701
1820
|
block->AddStatement(new(zone()) ExpressionStatement(initialize));
|
|
@@ -1712,9 +1831,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1712
1831
|
// for constant lookups is always the function context, while it is
|
|
1713
1832
|
// the top context for variables). Sigh...
|
|
1714
1833
|
if (value != NULL) {
|
|
1715
|
-
|
|
1834
|
+
bool in_with = is_const ? false : inside_with();
|
|
1835
|
+
VariableProxy* proxy =
|
|
1836
|
+
initialization_scope->NewUnresolved(name, in_with);
|
|
1716
1837
|
Assignment* assignment =
|
|
1717
|
-
new(zone()) Assignment(
|
|
1838
|
+
new(zone()) Assignment(isolate(), init_op, proxy, value, position);
|
|
1718
1839
|
if (block) {
|
|
1719
1840
|
block->AddStatement(new(zone()) ExpressionStatement(assignment));
|
|
1720
1841
|
}
|
|
@@ -1723,10 +1844,10 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
|
|
|
1723
1844
|
if (fni_ != NULL) fni_->Leave();
|
|
1724
1845
|
} while (peek() == Token::COMMA);
|
|
1725
1846
|
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
*
|
|
1847
|
+
// If there was a single non-const declaration, return it in the output
|
|
1848
|
+
// parameter for possible use by for/in.
|
|
1849
|
+
if (nvars == 1 && !is_const) {
|
|
1850
|
+
*out = name;
|
|
1730
1851
|
}
|
|
1731
1852
|
|
|
1732
1853
|
return block;
|
|
@@ -1751,7 +1872,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
|
|
1751
1872
|
// Identifier ':' Statement
|
|
1752
1873
|
bool starts_with_idenfifier = peek_any_identifier();
|
|
1753
1874
|
Expression* expr = ParseExpression(true, CHECK_OK);
|
|
1754
|
-
if (peek() == Token::COLON && starts_with_idenfifier && expr &&
|
|
1875
|
+
if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
|
|
1755
1876
|
expr->AsVariableProxy() != NULL &&
|
|
1756
1877
|
!expr->AsVariableProxy()->is_this()) {
|
|
1757
1878
|
// Expression is a single identifier, and not, e.g., a parenthesized
|
|
@@ -1781,6 +1902,20 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
|
|
1781
1902
|
return ParseStatement(labels, ok);
|
|
1782
1903
|
}
|
|
1783
1904
|
|
|
1905
|
+
// If we have an extension, we allow a native function declaration.
|
|
1906
|
+
// A native function declaration starts with "native function" with
|
|
1907
|
+
// no line-terminator between the two words.
|
|
1908
|
+
if (extension_ != NULL &&
|
|
1909
|
+
peek() == Token::FUNCTION &&
|
|
1910
|
+
!scanner().HasAnyLineTerminatorBeforeNext() &&
|
|
1911
|
+
expr != NULL &&
|
|
1912
|
+
expr->AsVariableProxy() != NULL &&
|
|
1913
|
+
expr->AsVariableProxy()->name()->Equals(
|
|
1914
|
+
isolate()->heap()->native_symbol()) &&
|
|
1915
|
+
!scanner().literal_contains_escapes()) {
|
|
1916
|
+
return ParseNativeDeclaration(ok);
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1784
1919
|
// Parsed expression statement.
|
|
1785
1920
|
ExpectSemicolon(CHECK_OK);
|
|
1786
1921
|
return new(zone()) ExpressionStatement(expr);
|
|
@@ -1803,7 +1938,8 @@ IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
|
|
|
1803
1938
|
} else {
|
|
1804
1939
|
else_statement = EmptyStatement();
|
|
1805
1940
|
}
|
|
1806
|
-
return new(zone()) IfStatement(
|
|
1941
|
+
return new(zone()) IfStatement(
|
|
1942
|
+
isolate(), condition, then_statement, else_statement);
|
|
1807
1943
|
}
|
|
1808
1944
|
|
|
1809
1945
|
|
|
@@ -1814,7 +1950,7 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
|
|
|
1814
1950
|
Expect(Token::CONTINUE, CHECK_OK);
|
|
1815
1951
|
Handle<String> label = Handle<String>::null();
|
|
1816
1952
|
Token::Value tok = peek();
|
|
1817
|
-
if (!scanner().
|
|
1953
|
+
if (!scanner().HasAnyLineTerminatorBeforeNext() &&
|
|
1818
1954
|
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
|
|
1819
1955
|
label = ParseIdentifier(CHECK_OK);
|
|
1820
1956
|
}
|
|
@@ -1844,7 +1980,7 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
|
|
|
1844
1980
|
Expect(Token::BREAK, CHECK_OK);
|
|
1845
1981
|
Handle<String> label;
|
|
1846
1982
|
Token::Value tok = peek();
|
|
1847
|
-
if (!scanner().
|
|
1983
|
+
if (!scanner().HasAnyLineTerminatorBeforeNext() &&
|
|
1848
1984
|
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
|
|
1849
1985
|
label = ParseIdentifier(CHECK_OK);
|
|
1850
1986
|
}
|
|
@@ -1886,14 +2022,16 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
|
|
1886
2022
|
// function. See ECMA-262, section 12.9, page 67.
|
|
1887
2023
|
//
|
|
1888
2024
|
// To be consistent with KJS we report the syntax error at runtime.
|
|
1889
|
-
|
|
2025
|
+
Scope* declaration_scope = top_scope_->DeclarationScope();
|
|
2026
|
+
if (declaration_scope->is_global_scope() ||
|
|
2027
|
+
declaration_scope->is_eval_scope()) {
|
|
1890
2028
|
Handle<String> type = isolate()->factory()->illegal_return_symbol();
|
|
1891
2029
|
Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
|
|
1892
2030
|
return new(zone()) ExpressionStatement(throw_error);
|
|
1893
2031
|
}
|
|
1894
2032
|
|
|
1895
2033
|
Token::Value tok = peek();
|
|
1896
|
-
if (scanner().
|
|
2034
|
+
if (scanner().HasAnyLineTerminatorBeforeNext() ||
|
|
1897
2035
|
tok == Token::SEMICOLON ||
|
|
1898
2036
|
tok == Token::RBRACE ||
|
|
1899
2037
|
tok == Token::EOS) {
|
|
@@ -1907,45 +2045,6 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
|
|
1907
2045
|
}
|
|
1908
2046
|
|
|
1909
2047
|
|
|
1910
|
-
Block* Parser::WithHelper(Expression* obj,
|
|
1911
|
-
ZoneStringList* labels,
|
|
1912
|
-
bool is_catch_block,
|
|
1913
|
-
bool* ok) {
|
|
1914
|
-
// Parse the statement and collect escaping labels.
|
|
1915
|
-
ZoneList<Label*>* target_list = new(zone()) ZoneList<Label*>(0);
|
|
1916
|
-
TargetCollector collector(target_list);
|
|
1917
|
-
Statement* stat;
|
|
1918
|
-
{ Target target(&this->target_stack_, &collector);
|
|
1919
|
-
with_nesting_level_++;
|
|
1920
|
-
top_scope_->RecordWithStatement();
|
|
1921
|
-
stat = ParseStatement(labels, CHECK_OK);
|
|
1922
|
-
with_nesting_level_--;
|
|
1923
|
-
}
|
|
1924
|
-
// Create resulting block with two statements.
|
|
1925
|
-
// 1: Evaluate the with expression.
|
|
1926
|
-
// 2: The try-finally block evaluating the body.
|
|
1927
|
-
Block* result = new(zone()) Block(NULL, 2, false);
|
|
1928
|
-
|
|
1929
|
-
if (result != NULL) {
|
|
1930
|
-
result->AddStatement(new(zone()) WithEnterStatement(obj, is_catch_block));
|
|
1931
|
-
|
|
1932
|
-
// Create body block.
|
|
1933
|
-
Block* body = new(zone()) Block(NULL, 1, false);
|
|
1934
|
-
body->AddStatement(stat);
|
|
1935
|
-
|
|
1936
|
-
// Create exit block.
|
|
1937
|
-
Block* exit = new(zone()) Block(NULL, 1, false);
|
|
1938
|
-
exit->AddStatement(new(zone()) WithExitStatement());
|
|
1939
|
-
|
|
1940
|
-
// Return a try-finally statement.
|
|
1941
|
-
TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit);
|
|
1942
|
-
wrapper->set_escaping_targets(collector.targets());
|
|
1943
|
-
result->AddStatement(wrapper);
|
|
1944
|
-
}
|
|
1945
|
-
return result;
|
|
1946
|
-
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
2048
|
Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
|
|
1950
2049
|
// WithStatement ::
|
|
1951
2050
|
// 'with' '(' Expression ')' Statement
|
|
@@ -1962,7 +2061,11 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
|
|
|
1962
2061
|
Expression* expr = ParseExpression(true, CHECK_OK);
|
|
1963
2062
|
Expect(Token::RPAREN, CHECK_OK);
|
|
1964
2063
|
|
|
1965
|
-
|
|
2064
|
+
++with_nesting_level_;
|
|
2065
|
+
top_scope_->DeclarationScope()->RecordWithStatement();
|
|
2066
|
+
Statement* stmt = ParseStatement(labels, CHECK_OK);
|
|
2067
|
+
--with_nesting_level_;
|
|
2068
|
+
return new(zone()) WithStatement(expr, stmt);
|
|
1966
2069
|
}
|
|
1967
2070
|
|
|
1968
2071
|
|
|
@@ -1995,7 +2098,7 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
|
|
|
1995
2098
|
statements->Add(stat);
|
|
1996
2099
|
}
|
|
1997
2100
|
|
|
1998
|
-
return new(zone()) CaseClause(label, statements, pos);
|
|
2101
|
+
return new(zone()) CaseClause(isolate(), label, statements, pos);
|
|
1999
2102
|
}
|
|
2000
2103
|
|
|
2001
2104
|
|
|
@@ -2004,7 +2107,7 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
|
|
|
2004
2107
|
// SwitchStatement ::
|
|
2005
2108
|
// 'switch' '(' Expression ')' '{' CaseClause* '}'
|
|
2006
2109
|
|
|
2007
|
-
SwitchStatement* statement = new(zone()) SwitchStatement(labels);
|
|
2110
|
+
SwitchStatement* statement = new(zone()) SwitchStatement(isolate(), labels);
|
|
2008
2111
|
Target target(&this->target_stack_, statement);
|
|
2009
2112
|
|
|
2010
2113
|
Expect(Token::SWITCH, CHECK_OK);
|
|
@@ -2032,7 +2135,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) {
|
|
|
2032
2135
|
|
|
2033
2136
|
Expect(Token::THROW, CHECK_OK);
|
|
2034
2137
|
int pos = scanner().location().beg_pos;
|
|
2035
|
-
if (scanner().
|
|
2138
|
+
if (scanner().HasAnyLineTerminatorBeforeNext()) {
|
|
2036
2139
|
ReportMessage("newline_after_throw", Vector<const char*>::empty());
|
|
2037
2140
|
*ok = false;
|
|
2038
2141
|
return NULL;
|
|
@@ -2040,7 +2143,8 @@ Statement* Parser::ParseThrowStatement(bool* ok) {
|
|
|
2040
2143
|
Expression* exception = ParseExpression(true, CHECK_OK);
|
|
2041
2144
|
ExpectSemicolon(CHECK_OK);
|
|
2042
2145
|
|
|
2043
|
-
return new(zone()) ExpressionStatement(
|
|
2146
|
+
return new(zone()) ExpressionStatement(
|
|
2147
|
+
new(zone()) Throw(isolate(), exception, pos));
|
|
2044
2148
|
}
|
|
2045
2149
|
|
|
2046
2150
|
|
|
@@ -2058,18 +2162,13 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
|
|
2058
2162
|
|
|
2059
2163
|
Expect(Token::TRY, CHECK_OK);
|
|
2060
2164
|
|
|
2061
|
-
|
|
2062
|
-
TargetCollector collector(target_list);
|
|
2165
|
+
TargetCollector try_collector;
|
|
2063
2166
|
Block* try_block;
|
|
2064
2167
|
|
|
2065
|
-
{ Target target(&this->target_stack_, &
|
|
2168
|
+
{ Target target(&this->target_stack_, &try_collector);
|
|
2066
2169
|
try_block = ParseBlock(NULL, CHECK_OK);
|
|
2067
2170
|
}
|
|
2068
2171
|
|
|
2069
|
-
Block* catch_block = NULL;
|
|
2070
|
-
Variable* catch_var = NULL;
|
|
2071
|
-
Block* finally_block = NULL;
|
|
2072
|
-
|
|
2073
2172
|
Token::Value tok = peek();
|
|
2074
2173
|
if (tok != Token::CATCH && tok != Token::FINALLY) {
|
|
2075
2174
|
ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
|
|
@@ -2078,18 +2177,19 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
|
|
2078
2177
|
}
|
|
2079
2178
|
|
|
2080
2179
|
// If we can break out from the catch block and there is a finally block,
|
|
2081
|
-
// then we will need to collect
|
|
2082
|
-
// we don't know yet if there will be a finally block, we
|
|
2083
|
-
// the
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2180
|
+
// then we will need to collect escaping targets from the catch
|
|
2181
|
+
// block. Since we don't know yet if there will be a finally block, we
|
|
2182
|
+
// always collect the targets.
|
|
2183
|
+
TargetCollector catch_collector;
|
|
2184
|
+
Scope* catch_scope = NULL;
|
|
2185
|
+
Variable* catch_variable = NULL;
|
|
2186
|
+
Block* catch_block = NULL;
|
|
2187
|
+
Handle<String> name;
|
|
2087
2188
|
if (tok == Token::CATCH) {
|
|
2088
|
-
has_catch = true;
|
|
2089
2189
|
Consume(Token::CATCH);
|
|
2090
2190
|
|
|
2091
2191
|
Expect(Token::LPAREN, CHECK_OK);
|
|
2092
|
-
|
|
2192
|
+
name = ParseIdentifier(CHECK_OK);
|
|
2093
2193
|
|
|
2094
2194
|
if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
|
|
2095
2195
|
ReportMessage("strict_catch_variable", Vector<const char*>::empty());
|
|
@@ -2100,17 +2200,22 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
|
|
2100
2200
|
Expect(Token::RPAREN, CHECK_OK);
|
|
2101
2201
|
|
|
2102
2202
|
if (peek() == Token::LBRACE) {
|
|
2103
|
-
//
|
|
2104
|
-
//
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
Expression* obj =
|
|
2110
|
-
new(zone()) CatchExtensionObject(name_literal, catch_var_use);
|
|
2111
|
-
{ Target target(&this->target_stack_, &catch_collector);
|
|
2112
|
-
catch_block = WithHelper(obj, NULL, true, CHECK_OK);
|
|
2203
|
+
// Rewrite the catch body { B } to a block:
|
|
2204
|
+
// { { B } ExitContext; }.
|
|
2205
|
+
Target target(&this->target_stack_, &catch_collector);
|
|
2206
|
+
catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
|
|
2207
|
+
if (top_scope_->is_strict_mode()) {
|
|
2208
|
+
catch_scope->EnableStrictMode();
|
|
2113
2209
|
}
|
|
2210
|
+
catch_variable = catch_scope->DeclareLocal(name, Variable::VAR);
|
|
2211
|
+
catch_block = new(zone()) Block(isolate(), NULL, 2, false);
|
|
2212
|
+
|
|
2213
|
+
Scope* saved_scope = top_scope_;
|
|
2214
|
+
top_scope_ = catch_scope;
|
|
2215
|
+
Block* catch_body = ParseBlock(NULL, CHECK_OK);
|
|
2216
|
+
top_scope_ = saved_scope;
|
|
2217
|
+
catch_block->AddStatement(catch_body);
|
|
2218
|
+
catch_block->AddStatement(new(zone()) ExitContextStatement());
|
|
2114
2219
|
} else {
|
|
2115
2220
|
Expect(Token::LBRACE, CHECK_OK);
|
|
2116
2221
|
}
|
|
@@ -2118,45 +2223,48 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
|
|
2118
2223
|
tok = peek();
|
|
2119
2224
|
}
|
|
2120
2225
|
|
|
2121
|
-
|
|
2226
|
+
Block* finally_block = NULL;
|
|
2227
|
+
if (tok == Token::FINALLY || catch_block == NULL) {
|
|
2122
2228
|
Consume(Token::FINALLY);
|
|
2123
|
-
// Declare a variable for holding the finally state while
|
|
2124
|
-
// executing the finally block.
|
|
2125
2229
|
finally_block = ParseBlock(NULL, CHECK_OK);
|
|
2126
2230
|
}
|
|
2127
2231
|
|
|
2128
2232
|
// Simplify the AST nodes by converting:
|
|
2129
|
-
// 'try
|
|
2233
|
+
// 'try B0 catch B1 finally B2'
|
|
2130
2234
|
// to:
|
|
2131
|
-
// 'try { try
|
|
2235
|
+
// 'try { try B0 catch B1 } finally B2'
|
|
2132
2236
|
|
|
2133
2237
|
if (catch_block != NULL && finally_block != NULL) {
|
|
2134
|
-
|
|
2238
|
+
// If we have both, create an inner try/catch.
|
|
2239
|
+
ASSERT(catch_scope != NULL && catch_variable != NULL);
|
|
2135
2240
|
TryCatchStatement* statement =
|
|
2136
|
-
new(zone()) TryCatchStatement(try_block,
|
|
2137
|
-
|
|
2138
|
-
|
|
2241
|
+
new(zone()) TryCatchStatement(try_block,
|
|
2242
|
+
catch_scope,
|
|
2243
|
+
catch_variable,
|
|
2244
|
+
catch_block);
|
|
2245
|
+
statement->set_escaping_targets(try_collector.targets());
|
|
2246
|
+
try_block = new(zone()) Block(isolate(), NULL, 1, false);
|
|
2139
2247
|
try_block->AddStatement(statement);
|
|
2140
|
-
catch_block = NULL;
|
|
2248
|
+
catch_block = NULL; // Clear to indicate it's been handled.
|
|
2141
2249
|
}
|
|
2142
2250
|
|
|
2143
2251
|
TryStatement* result = NULL;
|
|
2144
2252
|
if (catch_block != NULL) {
|
|
2145
2253
|
ASSERT(finally_block == NULL);
|
|
2146
|
-
|
|
2254
|
+
ASSERT(catch_scope != NULL && catch_variable != NULL);
|
|
2147
2255
|
result =
|
|
2148
|
-
new(zone()) TryCatchStatement(try_block,
|
|
2149
|
-
|
|
2256
|
+
new(zone()) TryCatchStatement(try_block,
|
|
2257
|
+
catch_scope,
|
|
2258
|
+
catch_variable,
|
|
2259
|
+
catch_block);
|
|
2150
2260
|
} else {
|
|
2151
2261
|
ASSERT(finally_block != NULL);
|
|
2152
2262
|
result = new(zone()) TryFinallyStatement(try_block, finally_block);
|
|
2153
|
-
//
|
|
2154
|
-
|
|
2155
|
-
catch_collector.AddTarget(collector.targets()->at(i));
|
|
2156
|
-
}
|
|
2157
|
-
result->set_escaping_targets(catch_collector.targets());
|
|
2263
|
+
// Combine the jump targets of the try block and the possible catch block.
|
|
2264
|
+
try_collector.targets()->AddAll(*catch_collector.targets());
|
|
2158
2265
|
}
|
|
2159
2266
|
|
|
2267
|
+
result->set_escaping_targets(try_collector.targets());
|
|
2160
2268
|
return result;
|
|
2161
2269
|
}
|
|
2162
2270
|
|
|
@@ -2166,7 +2274,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
|
|
|
2166
2274
|
// DoStatement ::
|
|
2167
2275
|
// 'do' Statement 'while' '(' Expression ')' ';'
|
|
2168
2276
|
|
|
2169
|
-
DoWhileStatement* loop = new(zone()) DoWhileStatement(labels);
|
|
2277
|
+
DoWhileStatement* loop = new(zone()) DoWhileStatement(isolate(), labels);
|
|
2170
2278
|
Target target(&this->target_stack_, loop);
|
|
2171
2279
|
|
|
2172
2280
|
Expect(Token::DO, CHECK_OK);
|
|
@@ -2197,7 +2305,7 @@ WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
|
|
|
2197
2305
|
// WhileStatement ::
|
|
2198
2306
|
// 'while' '(' Expression ')' Statement
|
|
2199
2307
|
|
|
2200
|
-
WhileStatement* loop = new(zone()) WhileStatement(labels);
|
|
2308
|
+
WhileStatement* loop = new(zone()) WhileStatement(isolate(), labels);
|
|
2201
2309
|
Target target(&this->target_stack_, loop);
|
|
2202
2310
|
|
|
2203
2311
|
Expect(Token::WHILE, CHECK_OK);
|
|
@@ -2221,11 +2329,13 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
|
|
2221
2329
|
Expect(Token::LPAREN, CHECK_OK);
|
|
2222
2330
|
if (peek() != Token::SEMICOLON) {
|
|
2223
2331
|
if (peek() == Token::VAR || peek() == Token::CONST) {
|
|
2224
|
-
|
|
2332
|
+
Handle<String> name;
|
|
2225
2333
|
Block* variable_statement =
|
|
2226
|
-
ParseVariableDeclarations(
|
|
2227
|
-
|
|
2228
|
-
|
|
2334
|
+
ParseVariableDeclarations(kForStatement, &name, CHECK_OK);
|
|
2335
|
+
|
|
2336
|
+
if (peek() == Token::IN && !name.is_null()) {
|
|
2337
|
+
VariableProxy* each = top_scope_->NewUnresolved(name, inside_with());
|
|
2338
|
+
ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
|
|
2229
2339
|
Target target(&this->target_stack_, loop);
|
|
2230
2340
|
|
|
2231
2341
|
Expect(Token::IN, CHECK_OK);
|
|
@@ -2234,7 +2344,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
|
|
2234
2344
|
|
|
2235
2345
|
Statement* body = ParseStatement(NULL, CHECK_OK);
|
|
2236
2346
|
loop->Initialize(each, enumerable, body);
|
|
2237
|
-
Block* result = new(zone()) Block(NULL, 2, false);
|
|
2347
|
+
Block* result = new(zone()) Block(isolate(), NULL, 2, false);
|
|
2238
2348
|
result->AddStatement(variable_statement);
|
|
2239
2349
|
result->AddStatement(loop);
|
|
2240
2350
|
// Parsed for-in loop w/ variable/const declaration.
|
|
@@ -2255,7 +2365,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
|
|
2255
2365
|
isolate()->factory()->invalid_lhs_in_for_in_symbol();
|
|
2256
2366
|
expression = NewThrowReferenceError(type);
|
|
2257
2367
|
}
|
|
2258
|
-
ForInStatement* loop = new(zone()) ForInStatement(labels);
|
|
2368
|
+
ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels);
|
|
2259
2369
|
Target target(&this->target_stack_, loop);
|
|
2260
2370
|
|
|
2261
2371
|
Expect(Token::IN, CHECK_OK);
|
|
@@ -2274,7 +2384,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
|
|
2274
2384
|
}
|
|
2275
2385
|
|
|
2276
2386
|
// Standard 'for' loop
|
|
2277
|
-
ForStatement* loop = new(zone()) ForStatement(labels);
|
|
2387
|
+
ForStatement* loop = new(zone()) ForStatement(isolate(), labels);
|
|
2278
2388
|
Target target(&this->target_stack_, loop);
|
|
2279
2389
|
|
|
2280
2390
|
// Parsed initializer at this point.
|
|
@@ -2310,7 +2420,8 @@ Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
|
|
|
2310
2420
|
Expect(Token::COMMA, CHECK_OK);
|
|
2311
2421
|
int position = scanner().location().beg_pos;
|
|
2312
2422
|
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
|
|
2313
|
-
result = new(zone()) BinaryOperation(
|
|
2423
|
+
result = new(zone()) BinaryOperation(
|
|
2424
|
+
isolate(), Token::COMMA, result, right, position);
|
|
2314
2425
|
}
|
|
2315
2426
|
return result;
|
|
2316
2427
|
}
|
|
@@ -2376,13 +2487,13 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
|
|
|
2376
2487
|
if ((op == Token::INIT_VAR
|
|
2377
2488
|
|| op == Token::INIT_CONST
|
|
2378
2489
|
|| op == Token::ASSIGN)
|
|
2379
|
-
&& (right->AsCall() == NULL)) {
|
|
2490
|
+
&& (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
|
|
2380
2491
|
fni_->Infer();
|
|
2381
2492
|
}
|
|
2382
2493
|
fni_->Leave();
|
|
2383
2494
|
}
|
|
2384
2495
|
|
|
2385
|
-
return new(zone()) Assignment(op, expression, right, pos);
|
|
2496
|
+
return new(zone()) Assignment(isolate(), op, expression, right, pos);
|
|
2386
2497
|
}
|
|
2387
2498
|
|
|
2388
2499
|
|
|
@@ -2404,8 +2515,8 @@ Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
|
|
|
2404
2515
|
Expect(Token::COLON, CHECK_OK);
|
|
2405
2516
|
int right_position = scanner().peek_location().beg_pos;
|
|
2406
2517
|
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
|
|
2407
|
-
return new(zone()) Conditional(
|
|
2408
|
-
|
|
2518
|
+
return new(zone()) Conditional(
|
|
2519
|
+
isolate(), expression, left, right, left_position, right_position);
|
|
2409
2520
|
}
|
|
2410
2521
|
|
|
2411
2522
|
|
|
@@ -2492,12 +2603,12 @@ Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
|
|
|
2492
2603
|
x = NewCompareNode(cmp, x, y, position);
|
|
2493
2604
|
if (cmp != op) {
|
|
2494
2605
|
// The comparison was negated - add a NOT.
|
|
2495
|
-
x = new(zone()) UnaryOperation(Token::NOT, x, position);
|
|
2606
|
+
x = new(zone()) UnaryOperation(isolate(), Token::NOT, x, position);
|
|
2496
2607
|
}
|
|
2497
2608
|
|
|
2498
2609
|
} else {
|
|
2499
2610
|
// We have a "normal" binary operation.
|
|
2500
|
-
x = new(zone()) BinaryOperation(op, x, y, position);
|
|
2611
|
+
x = new(zone()) BinaryOperation(isolate(), op, x, y, position);
|
|
2501
2612
|
}
|
|
2502
2613
|
}
|
|
2503
2614
|
}
|
|
@@ -2514,15 +2625,15 @@ Expression* Parser::NewCompareNode(Token::Value op,
|
|
|
2514
2625
|
bool is_strict = (op == Token::EQ_STRICT);
|
|
2515
2626
|
Literal* x_literal = x->AsLiteral();
|
|
2516
2627
|
if (x_literal != NULL && x_literal->IsNull()) {
|
|
2517
|
-
return new(zone()) CompareToNull(is_strict, y);
|
|
2628
|
+
return new(zone()) CompareToNull(isolate(), is_strict, y);
|
|
2518
2629
|
}
|
|
2519
2630
|
|
|
2520
2631
|
Literal* y_literal = y->AsLiteral();
|
|
2521
2632
|
if (y_literal != NULL && y_literal->IsNull()) {
|
|
2522
|
-
return new(zone()) CompareToNull(is_strict, x);
|
|
2633
|
+
return new(zone()) CompareToNull(isolate(), is_strict, x);
|
|
2523
2634
|
}
|
|
2524
2635
|
}
|
|
2525
|
-
return new(zone()) CompareOperation(op, x, y, position);
|
|
2636
|
+
return new(zone()) CompareOperation(isolate(), op, x, y, position);
|
|
2526
2637
|
}
|
|
2527
2638
|
|
|
2528
2639
|
|
|
@@ -2545,18 +2656,26 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
|
|
|
2545
2656
|
int position = scanner().location().beg_pos;
|
|
2546
2657
|
Expression* expression = ParseUnaryExpression(CHECK_OK);
|
|
2547
2658
|
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2659
|
+
if (expression != NULL && (expression->AsLiteral() != NULL)) {
|
|
2660
|
+
Handle<Object> literal = expression->AsLiteral()->handle();
|
|
2661
|
+
if (op == Token::NOT) {
|
|
2662
|
+
// Convert the literal to a boolean condition and negate it.
|
|
2663
|
+
bool condition = literal->ToBoolean()->IsTrue();
|
|
2664
|
+
Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
|
|
2665
|
+
return NewLiteral(result);
|
|
2666
|
+
} else if (literal->IsNumber()) {
|
|
2667
|
+
// Compute some expressions involving only number literals.
|
|
2668
|
+
double value = literal->Number();
|
|
2669
|
+
switch (op) {
|
|
2670
|
+
case Token::ADD:
|
|
2671
|
+
return expression;
|
|
2672
|
+
case Token::SUB:
|
|
2673
|
+
return NewNumberLiteral(-value);
|
|
2674
|
+
case Token::BIT_NOT:
|
|
2675
|
+
return NewNumberLiteral(~DoubleToInt32(value));
|
|
2676
|
+
default:
|
|
2677
|
+
break;
|
|
2678
|
+
}
|
|
2560
2679
|
}
|
|
2561
2680
|
}
|
|
2562
2681
|
|
|
@@ -2570,7 +2689,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
|
|
|
2570
2689
|
}
|
|
2571
2690
|
}
|
|
2572
2691
|
|
|
2573
|
-
return new(zone()) UnaryOperation(op, expression, position);
|
|
2692
|
+
return new(zone()) UnaryOperation(isolate(), op, expression, position);
|
|
2574
2693
|
|
|
2575
2694
|
} else if (Token::IsCountOp(op)) {
|
|
2576
2695
|
op = Next();
|
|
@@ -2591,7 +2710,8 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
|
|
|
2591
2710
|
}
|
|
2592
2711
|
|
|
2593
2712
|
int position = scanner().location().beg_pos;
|
|
2594
|
-
return new(zone()) CountOperation(
|
|
2713
|
+
return new(zone()) CountOperation(isolate(),
|
|
2714
|
+
op,
|
|
2595
2715
|
true /* prefix */,
|
|
2596
2716
|
expression,
|
|
2597
2717
|
position);
|
|
@@ -2607,7 +2727,7 @@ Expression* Parser::ParsePostfixExpression(bool* ok) {
|
|
|
2607
2727
|
// LeftHandSideExpression ('++' | '--')?
|
|
2608
2728
|
|
|
2609
2729
|
Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
|
|
2610
|
-
if (!scanner().
|
|
2730
|
+
if (!scanner().HasAnyLineTerminatorBeforeNext() &&
|
|
2611
2731
|
Token::IsCountOp(peek())) {
|
|
2612
2732
|
// Signal a reference error if the expression is an invalid
|
|
2613
2733
|
// left-hand side expression. We could report this as a syntax
|
|
@@ -2627,7 +2747,8 @@ Expression* Parser::ParsePostfixExpression(bool* ok) {
|
|
|
2627
2747
|
Token::Value next = Next();
|
|
2628
2748
|
int position = scanner().location().beg_pos;
|
|
2629
2749
|
expression =
|
|
2630
|
-
new(zone()) CountOperation(
|
|
2750
|
+
new(zone()) CountOperation(isolate(),
|
|
2751
|
+
next,
|
|
2631
2752
|
false /* postfix */,
|
|
2632
2753
|
expression,
|
|
2633
2754
|
position);
|
|
@@ -2653,7 +2774,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
|
|
|
2653
2774
|
Consume(Token::LBRACK);
|
|
2654
2775
|
int pos = scanner().location().beg_pos;
|
|
2655
2776
|
Expression* index = ParseExpression(true, CHECK_OK);
|
|
2656
|
-
result = new(zone()) Property(result, index, pos);
|
|
2777
|
+
result = new(zone()) Property(isolate(), result, index, pos);
|
|
2657
2778
|
Expect(Token::RBRACK, CHECK_OK);
|
|
2658
2779
|
break;
|
|
2659
2780
|
}
|
|
@@ -2680,7 +2801,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
|
|
|
2680
2801
|
Handle<String> name = callee->name();
|
|
2681
2802
|
Variable* var = top_scope_->Lookup(name);
|
|
2682
2803
|
if (var == NULL) {
|
|
2683
|
-
top_scope_->RecordEvalCall();
|
|
2804
|
+
top_scope_->DeclarationScope()->RecordEvalCall();
|
|
2684
2805
|
}
|
|
2685
2806
|
}
|
|
2686
2807
|
result = NewCall(result, args, pos);
|
|
@@ -2691,7 +2812,10 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
|
|
|
2691
2812
|
Consume(Token::PERIOD);
|
|
2692
2813
|
int pos = scanner().location().beg_pos;
|
|
2693
2814
|
Handle<String> name = ParseIdentifierName(CHECK_OK);
|
|
2694
|
-
result = new(zone()) Property(
|
|
2815
|
+
result = new(zone()) Property(isolate(),
|
|
2816
|
+
result,
|
|
2817
|
+
NewLiteral(name),
|
|
2818
|
+
pos);
|
|
2695
2819
|
if (fni_ != NULL) fni_->PushLiteralName(name);
|
|
2696
2820
|
break;
|
|
2697
2821
|
}
|
|
@@ -2727,7 +2851,8 @@ Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
|
|
|
2727
2851
|
|
|
2728
2852
|
if (!stack->is_empty()) {
|
|
2729
2853
|
int last = stack->pop();
|
|
2730
|
-
result = new(zone()) CallNew(
|
|
2854
|
+
result = new(zone()) CallNew(isolate(),
|
|
2855
|
+
result,
|
|
2731
2856
|
new(zone()) ZoneList<Expression*>(0),
|
|
2732
2857
|
last);
|
|
2733
2858
|
}
|
|
@@ -2758,12 +2883,19 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
|
|
|
2758
2883
|
Expect(Token::FUNCTION, CHECK_OK);
|
|
2759
2884
|
int function_token_position = scanner().location().beg_pos;
|
|
2760
2885
|
Handle<String> name;
|
|
2761
|
-
bool
|
|
2886
|
+
bool is_strict_reserved_name = false;
|
|
2762
2887
|
if (peek_any_identifier()) {
|
|
2763
|
-
|
|
2888
|
+
name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
|
|
2889
|
+
CHECK_OK);
|
|
2764
2890
|
}
|
|
2765
|
-
|
|
2766
|
-
|
|
2891
|
+
FunctionLiteral::Type type = name.is_null()
|
|
2892
|
+
? FunctionLiteral::ANONYMOUS_EXPRESSION
|
|
2893
|
+
: FunctionLiteral::NAMED_EXPRESSION;
|
|
2894
|
+
result = ParseFunctionLiteral(name,
|
|
2895
|
+
is_strict_reserved_name,
|
|
2896
|
+
function_token_position,
|
|
2897
|
+
type,
|
|
2898
|
+
CHECK_OK);
|
|
2767
2899
|
} else {
|
|
2768
2900
|
result = ParsePrimaryExpression(CHECK_OK);
|
|
2769
2901
|
}
|
|
@@ -2774,7 +2906,15 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
|
|
|
2774
2906
|
Consume(Token::LBRACK);
|
|
2775
2907
|
int pos = scanner().location().beg_pos;
|
|
2776
2908
|
Expression* index = ParseExpression(true, CHECK_OK);
|
|
2777
|
-
result = new(zone()) Property(result, index, pos);
|
|
2909
|
+
result = new(zone()) Property(isolate(), result, index, pos);
|
|
2910
|
+
if (fni_ != NULL) {
|
|
2911
|
+
if (index->IsPropertyName()) {
|
|
2912
|
+
fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
|
|
2913
|
+
} else {
|
|
2914
|
+
fni_->PushLiteralName(
|
|
2915
|
+
isolate()->factory()->anonymous_function_symbol());
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2778
2918
|
Expect(Token::RBRACK, CHECK_OK);
|
|
2779
2919
|
break;
|
|
2780
2920
|
}
|
|
@@ -2782,7 +2922,10 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
|
|
|
2782
2922
|
Consume(Token::PERIOD);
|
|
2783
2923
|
int pos = scanner().location().beg_pos;
|
|
2784
2924
|
Handle<String> name = ParseIdentifierName(CHECK_OK);
|
|
2785
|
-
result = new(zone()) Property(
|
|
2925
|
+
result = new(zone()) Property(isolate(),
|
|
2926
|
+
result,
|
|
2927
|
+
NewLiteral(name),
|
|
2928
|
+
pos);
|
|
2786
2929
|
if (fni_ != NULL) fni_->PushLiteralName(name);
|
|
2787
2930
|
break;
|
|
2788
2931
|
}
|
|
@@ -2791,7 +2934,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
|
|
|
2791
2934
|
// Consume one of the new prefixes (already parsed).
|
|
2792
2935
|
ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
|
|
2793
2936
|
int last = stack->pop();
|
|
2794
|
-
result = new CallNew(result, args, last);
|
|
2937
|
+
result = new(zone()) CallNew(isolate(), result, args, last);
|
|
2795
2938
|
break;
|
|
2796
2939
|
}
|
|
2797
2940
|
default:
|
|
@@ -2833,6 +2976,9 @@ void Parser::ReportUnexpectedToken(Token::Value token) {
|
|
|
2833
2976
|
return ReportMessage("unexpected_token_identifier",
|
|
2834
2977
|
Vector<const char*>::empty());
|
|
2835
2978
|
case Token::FUTURE_RESERVED_WORD:
|
|
2979
|
+
return ReportMessage("unexpected_reserved",
|
|
2980
|
+
Vector<const char*>::empty());
|
|
2981
|
+
case Token::FUTURE_STRICT_RESERVED_WORD:
|
|
2836
2982
|
return ReportMessage(top_scope_->is_strict_mode() ?
|
|
2837
2983
|
"unexpected_strict_reserved" :
|
|
2838
2984
|
"unexpected_token_identifier",
|
|
@@ -2872,28 +3018,30 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
|
|
|
2872
3018
|
switch (peek()) {
|
|
2873
3019
|
case Token::THIS: {
|
|
2874
3020
|
Consume(Token::THIS);
|
|
2875
|
-
|
|
2876
|
-
result = recv;
|
|
3021
|
+
result = new(zone()) VariableProxy(isolate(), top_scope_->receiver());
|
|
2877
3022
|
break;
|
|
2878
3023
|
}
|
|
2879
3024
|
|
|
2880
3025
|
case Token::NULL_LITERAL:
|
|
2881
3026
|
Consume(Token::NULL_LITERAL);
|
|
2882
|
-
result = new(zone()) Literal(
|
|
3027
|
+
result = new(zone()) Literal(
|
|
3028
|
+
isolate(), isolate()->factory()->null_value());
|
|
2883
3029
|
break;
|
|
2884
3030
|
|
|
2885
3031
|
case Token::TRUE_LITERAL:
|
|
2886
3032
|
Consume(Token::TRUE_LITERAL);
|
|
2887
|
-
result = new(zone()) Literal(
|
|
3033
|
+
result = new(zone()) Literal(
|
|
3034
|
+
isolate(), isolate()->factory()->true_value());
|
|
2888
3035
|
break;
|
|
2889
3036
|
|
|
2890
3037
|
case Token::FALSE_LITERAL:
|
|
2891
3038
|
Consume(Token::FALSE_LITERAL);
|
|
2892
|
-
result = new(zone()) Literal(
|
|
3039
|
+
result = new(zone()) Literal(
|
|
3040
|
+
isolate(), isolate()->factory()->false_value());
|
|
2893
3041
|
break;
|
|
2894
3042
|
|
|
2895
3043
|
case Token::IDENTIFIER:
|
|
2896
|
-
case Token::
|
|
3044
|
+
case Token::FUTURE_STRICT_RESERVED_WORD: {
|
|
2897
3045
|
Handle<String> name = ParseIdentifier(CHECK_OK);
|
|
2898
3046
|
if (fni_ != NULL) fni_->PushVariableName(name);
|
|
2899
3047
|
result = top_scope_->NewUnresolved(name,
|
|
@@ -2915,7 +3063,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
|
|
|
2915
3063
|
case Token::STRING: {
|
|
2916
3064
|
Consume(Token::STRING);
|
|
2917
3065
|
Handle<String> symbol = GetSymbol(CHECK_OK);
|
|
2918
|
-
result =
|
|
3066
|
+
result = NewLiteral(symbol);
|
|
2919
3067
|
if (fni_ != NULL) fni_->PushLiteralName(symbol);
|
|
2920
3068
|
break;
|
|
2921
3069
|
}
|
|
@@ -3042,8 +3190,8 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
|
|
|
3042
3190
|
literals->set_map(isolate()->heap()->fixed_cow_array_map());
|
|
3043
3191
|
}
|
|
3044
3192
|
|
|
3045
|
-
return new(zone()) ArrayLiteral(
|
|
3046
|
-
|
|
3193
|
+
return new(zone()) ArrayLiteral(
|
|
3194
|
+
isolate(), literals, values, literal_index, is_simple, depth);
|
|
3047
3195
|
}
|
|
3048
3196
|
|
|
3049
3197
|
|
|
@@ -3304,6 +3452,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
|
|
|
3304
3452
|
bool is_keyword = Token::IsKeyword(next);
|
|
3305
3453
|
if (next == Token::IDENTIFIER || next == Token::NUMBER ||
|
|
3306
3454
|
next == Token::FUTURE_RESERVED_WORD ||
|
|
3455
|
+
next == Token::FUTURE_STRICT_RESERVED_WORD ||
|
|
3307
3456
|
next == Token::STRING || is_keyword) {
|
|
3308
3457
|
Handle<String> name;
|
|
3309
3458
|
if (is_keyword) {
|
|
@@ -3315,7 +3464,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
|
|
|
3315
3464
|
ParseFunctionLiteral(name,
|
|
3316
3465
|
false, // reserved words are allowed here
|
|
3317
3466
|
RelocInfo::kNoPosition,
|
|
3318
|
-
|
|
3467
|
+
FunctionLiteral::ANONYMOUS_EXPRESSION,
|
|
3319
3468
|
CHECK_OK);
|
|
3320
3469
|
// Allow any number of parameters for compatiabilty with JSC.
|
|
3321
3470
|
// Specification only allows zero parameters for get and one for set.
|
|
@@ -3345,7 +3494,6 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
|
|
3345
3494
|
ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode());
|
|
3346
3495
|
|
|
3347
3496
|
Expect(Token::LBRACE, CHECK_OK);
|
|
3348
|
-
Scanner::Location loc = scanner().location();
|
|
3349
3497
|
|
|
3350
3498
|
while (peek() != Token::RBRACE) {
|
|
3351
3499
|
if (fni_ != NULL) fni_->Enter();
|
|
@@ -3358,11 +3506,12 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
|
|
3358
3506
|
|
|
3359
3507
|
switch (next) {
|
|
3360
3508
|
case Token::FUTURE_RESERVED_WORD:
|
|
3509
|
+
case Token::FUTURE_STRICT_RESERVED_WORD:
|
|
3361
3510
|
case Token::IDENTIFIER: {
|
|
3362
3511
|
bool is_getter = false;
|
|
3363
3512
|
bool is_setter = false;
|
|
3364
3513
|
Handle<String> id =
|
|
3365
|
-
|
|
3514
|
+
ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
|
|
3366
3515
|
if (fni_ != NULL) fni_->PushLiteralName(id);
|
|
3367
3516
|
|
|
3368
3517
|
if ((is_getter || is_setter) && peek() != Token::COLON) {
|
|
@@ -3386,7 +3535,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
|
|
3386
3535
|
}
|
|
3387
3536
|
// Failed to parse as get/set property, so it's just a property
|
|
3388
3537
|
// called "get" or "set".
|
|
3389
|
-
key =
|
|
3538
|
+
key = NewLiteral(id);
|
|
3390
3539
|
break;
|
|
3391
3540
|
}
|
|
3392
3541
|
case Token::STRING: {
|
|
@@ -3398,7 +3547,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
|
|
3398
3547
|
key = NewNumberLiteral(index);
|
|
3399
3548
|
break;
|
|
3400
3549
|
}
|
|
3401
|
-
key =
|
|
3550
|
+
key = NewLiteral(string);
|
|
3402
3551
|
break;
|
|
3403
3552
|
}
|
|
3404
3553
|
case Token::NUMBER: {
|
|
@@ -3414,7 +3563,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
|
|
3414
3563
|
if (Token::IsKeyword(next)) {
|
|
3415
3564
|
Consume(next);
|
|
3416
3565
|
Handle<String> string = GetSymbol(CHECK_OK);
|
|
3417
|
-
key =
|
|
3566
|
+
key = NewLiteral(string);
|
|
3418
3567
|
} else {
|
|
3419
3568
|
// Unexpected token.
|
|
3420
3569
|
Token::Value next = Next();
|
|
@@ -3467,13 +3616,14 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
|
|
3467
3616
|
&is_simple,
|
|
3468
3617
|
&fast_elements,
|
|
3469
3618
|
&depth);
|
|
3470
|
-
return new(zone()) ObjectLiteral(
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3619
|
+
return new(zone()) ObjectLiteral(isolate(),
|
|
3620
|
+
constant_properties,
|
|
3621
|
+
properties,
|
|
3622
|
+
literal_index,
|
|
3623
|
+
is_simple,
|
|
3624
|
+
fast_elements,
|
|
3625
|
+
depth,
|
|
3626
|
+
has_function);
|
|
3477
3627
|
}
|
|
3478
3628
|
|
|
3479
3629
|
|
|
@@ -3492,7 +3642,8 @@ Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
|
|
|
3492
3642
|
Handle<String> js_flags = NextLiteralString(TENURED);
|
|
3493
3643
|
Next();
|
|
3494
3644
|
|
|
3495
|
-
return new(zone()) RegExpLiteral(
|
|
3645
|
+
return new(zone()) RegExpLiteral(
|
|
3646
|
+
isolate(), js_pattern, js_flags, literal_index);
|
|
3496
3647
|
}
|
|
3497
3648
|
|
|
3498
3649
|
|
|
@@ -3506,6 +3657,12 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
|
|
|
3506
3657
|
while (!done) {
|
|
3507
3658
|
Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
|
|
3508
3659
|
result->Add(argument);
|
|
3660
|
+
if (result->length() > kMaxNumFunctionParameters) {
|
|
3661
|
+
ReportMessageAt(scanner().location(), "too_many_arguments",
|
|
3662
|
+
Vector<const char*>::empty());
|
|
3663
|
+
*ok = false;
|
|
3664
|
+
return NULL;
|
|
3665
|
+
}
|
|
3509
3666
|
done = (peek() == Token::RPAREN);
|
|
3510
3667
|
if (!done) Expect(Token::COMMA, CHECK_OK);
|
|
3511
3668
|
}
|
|
@@ -3514,29 +3671,32 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
|
|
|
3514
3671
|
}
|
|
3515
3672
|
|
|
3516
3673
|
|
|
3517
|
-
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String>
|
|
3518
|
-
bool
|
|
3674
|
+
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
|
|
3675
|
+
bool name_is_strict_reserved,
|
|
3519
3676
|
int function_token_position,
|
|
3520
|
-
|
|
3677
|
+
FunctionLiteral::Type type,
|
|
3521
3678
|
bool* ok) {
|
|
3522
3679
|
// Function ::
|
|
3523
3680
|
// '(' FormalParameterList? ')' '{' FunctionBody '}'
|
|
3524
|
-
bool is_named = !var_name.is_null();
|
|
3525
3681
|
|
|
3526
|
-
//
|
|
3527
|
-
//
|
|
3528
|
-
//
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
if (is_named && (type == EXPRESSION || type == NESTED)) {
|
|
3535
|
-
function_name = name;
|
|
3682
|
+
// Anonymous functions were passed either the empty symbol or a null
|
|
3683
|
+
// handle as the function name. Remember if we were passed a non-empty
|
|
3684
|
+
// handle to decide whether to invoke function name inference.
|
|
3685
|
+
bool should_infer_name = function_name.is_null();
|
|
3686
|
+
|
|
3687
|
+
// We want a non-null handle as the function name.
|
|
3688
|
+
if (should_infer_name) {
|
|
3689
|
+
function_name = isolate()->factory()->empty_symbol();
|
|
3536
3690
|
}
|
|
3537
3691
|
|
|
3538
3692
|
int num_parameters = 0;
|
|
3539
|
-
|
|
3693
|
+
// Function declarations are function scoped in normal mode, so they are
|
|
3694
|
+
// hoisted. In harmony block scoping mode they are block scoped, so they
|
|
3695
|
+
// are not hoisted.
|
|
3696
|
+
Scope* scope = (type == FunctionLiteral::DECLARATION &&
|
|
3697
|
+
!harmony_block_scoping_)
|
|
3698
|
+
? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false)
|
|
3699
|
+
: NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
|
|
3540
3700
|
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
|
|
3541
3701
|
int materialized_literal_count;
|
|
3542
3702
|
int expected_property_count;
|
|
@@ -3544,9 +3704,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
3544
3704
|
int end_pos;
|
|
3545
3705
|
bool only_simple_this_property_assignments;
|
|
3546
3706
|
Handle<FixedArray> this_property_assignments;
|
|
3707
|
+
bool has_duplicate_parameters = false;
|
|
3547
3708
|
// Parse function body.
|
|
3548
3709
|
{ LexicalScope lexical_scope(this, scope, isolate());
|
|
3549
|
-
top_scope_->SetScopeName(
|
|
3710
|
+
top_scope_->SetScopeName(function_name);
|
|
3550
3711
|
|
|
3551
3712
|
// FormalParameterList ::
|
|
3552
3713
|
// '(' (Identifier)*[','] ')'
|
|
@@ -3558,25 +3719,24 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
3558
3719
|
|
|
3559
3720
|
bool done = (peek() == Token::RPAREN);
|
|
3560
3721
|
while (!done) {
|
|
3561
|
-
bool
|
|
3722
|
+
bool is_strict_reserved = false;
|
|
3562
3723
|
Handle<String> param_name =
|
|
3563
|
-
|
|
3724
|
+
ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
|
|
3725
|
+
CHECK_OK);
|
|
3564
3726
|
|
|
3565
3727
|
// Store locations for possible future error reports.
|
|
3566
3728
|
if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
|
|
3567
3729
|
name_loc = scanner().location();
|
|
3568
3730
|
}
|
|
3569
3731
|
if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
|
|
3732
|
+
has_duplicate_parameters = true;
|
|
3570
3733
|
dupe_loc = scanner().location();
|
|
3571
3734
|
}
|
|
3572
|
-
if (!reserved_loc.IsValid() &&
|
|
3735
|
+
if (!reserved_loc.IsValid() && is_strict_reserved) {
|
|
3573
3736
|
reserved_loc = scanner().location();
|
|
3574
3737
|
}
|
|
3575
3738
|
|
|
3576
|
-
|
|
3577
|
-
Variable::VAR,
|
|
3578
|
-
Scope::PARAMETER);
|
|
3579
|
-
top_scope_->AddParameter(parameter);
|
|
3739
|
+
top_scope_->DeclareParameter(param_name);
|
|
3580
3740
|
num_parameters++;
|
|
3581
3741
|
if (num_parameters > kMaxNumFunctionParameters) {
|
|
3582
3742
|
ReportMessageAt(scanner().location(), "too_many_parameters",
|
|
@@ -3597,46 +3757,56 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
3597
3757
|
// NOTE: We create a proxy and resolve it here so that in the
|
|
3598
3758
|
// future we can change the AST to only refer to VariableProxies
|
|
3599
3759
|
// instead of Variables and Proxis as is the case now.
|
|
3600
|
-
if (
|
|
3760
|
+
if (type == FunctionLiteral::NAMED_EXPRESSION) {
|
|
3601
3761
|
Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
|
|
3602
3762
|
VariableProxy* fproxy =
|
|
3603
3763
|
top_scope_->NewUnresolved(function_name, inside_with());
|
|
3604
3764
|
fproxy->BindTo(fvar);
|
|
3605
3765
|
body->Add(new(zone()) ExpressionStatement(
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3766
|
+
new(zone()) Assignment(isolate(),
|
|
3767
|
+
Token::INIT_CONST,
|
|
3768
|
+
fproxy,
|
|
3769
|
+
new(zone()) ThisFunction(isolate()),
|
|
3770
|
+
RelocInfo::kNoPosition)));
|
|
3609
3771
|
}
|
|
3610
3772
|
|
|
3611
|
-
// Determine if the function will be lazily compiled. The mode can
|
|
3612
|
-
//
|
|
3773
|
+
// Determine if the function will be lazily compiled. The mode can only
|
|
3774
|
+
// be PARSE_LAZILY if the --lazy flag is true. We will not lazily
|
|
3775
|
+
// compile if we do not have preparser data for the function.
|
|
3613
3776
|
bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
|
|
3614
3777
|
top_scope_->outer_scope()->is_global_scope() &&
|
|
3615
3778
|
top_scope_->HasTrivialOuterContext() &&
|
|
3616
|
-
!parenthesized_function_
|
|
3779
|
+
!parenthesized_function_ &&
|
|
3780
|
+
pre_data() != NULL);
|
|
3617
3781
|
parenthesized_function_ = false; // The bit was set for this function only.
|
|
3618
3782
|
|
|
3619
|
-
|
|
3620
|
-
|
|
3783
|
+
if (is_lazily_compiled) {
|
|
3784
|
+
int function_block_pos = scanner().location().beg_pos;
|
|
3621
3785
|
FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
|
|
3622
3786
|
if (!entry.is_valid()) {
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3787
|
+
// There is no preparser data for the function, we will not lazily
|
|
3788
|
+
// compile after all.
|
|
3789
|
+
is_lazily_compiled = false;
|
|
3790
|
+
} else {
|
|
3791
|
+
end_pos = entry.end_pos();
|
|
3792
|
+
if (end_pos <= function_block_pos) {
|
|
3793
|
+
// End position greater than end of stream is safe, and hard to check.
|
|
3794
|
+
ReportInvalidPreparseData(function_name, CHECK_OK);
|
|
3795
|
+
}
|
|
3796
|
+
isolate()->counters()->total_preparse_skipped()->Increment(
|
|
3797
|
+
end_pos - function_block_pos);
|
|
3798
|
+
// Seek to position just before terminal '}'.
|
|
3799
|
+
scanner().SeekForward(end_pos - 1);
|
|
3800
|
+
materialized_literal_count = entry.literal_count();
|
|
3801
|
+
expected_property_count = entry.property_count();
|
|
3802
|
+
if (entry.strict_mode()) top_scope_->EnableStrictMode();
|
|
3803
|
+
only_simple_this_property_assignments = false;
|
|
3804
|
+
this_property_assignments = isolate()->factory()->empty_fixed_array();
|
|
3805
|
+
Expect(Token::RBRACE, CHECK_OK);
|
|
3629
3806
|
}
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
scanner().SeekForward(end_pos - 1);
|
|
3634
|
-
materialized_literal_count = entry.literal_count();
|
|
3635
|
-
expected_property_count = entry.property_count();
|
|
3636
|
-
only_simple_this_property_assignments = false;
|
|
3637
|
-
this_property_assignments = isolate()->factory()->empty_fixed_array();
|
|
3638
|
-
Expect(Token::RBRACE, CHECK_OK);
|
|
3639
|
-
} else {
|
|
3807
|
+
}
|
|
3808
|
+
|
|
3809
|
+
if (!is_lazily_compiled) {
|
|
3640
3810
|
ParseSourceElements(body, Token::RBRACE, CHECK_OK);
|
|
3641
3811
|
|
|
3642
3812
|
materialized_literal_count = lexical_scope.materialized_literal_count();
|
|
@@ -3651,7 +3821,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
3651
3821
|
|
|
3652
3822
|
// Validate strict mode.
|
|
3653
3823
|
if (top_scope_->is_strict_mode()) {
|
|
3654
|
-
if (IsEvalOrArguments(
|
|
3824
|
+
if (IsEvalOrArguments(function_name)) {
|
|
3655
3825
|
int position = function_token_position != RelocInfo::kNoPosition
|
|
3656
3826
|
? function_token_position
|
|
3657
3827
|
: (start_pos > 0 ? start_pos - 1 : start_pos);
|
|
@@ -3673,7 +3843,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
3673
3843
|
*ok = false;
|
|
3674
3844
|
return NULL;
|
|
3675
3845
|
}
|
|
3676
|
-
if (
|
|
3846
|
+
if (name_is_strict_reserved) {
|
|
3677
3847
|
int position = function_token_position != RelocInfo::kNoPosition
|
|
3678
3848
|
? function_token_position
|
|
3679
3849
|
: (start_pos > 0 ? start_pos - 1 : start_pos);
|
|
@@ -3694,7 +3864,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
3694
3864
|
}
|
|
3695
3865
|
|
|
3696
3866
|
FunctionLiteral* function_literal =
|
|
3697
|
-
new(zone()) FunctionLiteral(
|
|
3867
|
+
new(zone()) FunctionLiteral(isolate(),
|
|
3868
|
+
function_name,
|
|
3698
3869
|
scope,
|
|
3699
3870
|
body,
|
|
3700
3871
|
materialized_literal_count,
|
|
@@ -3704,10 +3875,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
|
|
|
3704
3875
|
num_parameters,
|
|
3705
3876
|
start_pos,
|
|
3706
3877
|
end_pos,
|
|
3707
|
-
|
|
3878
|
+
type,
|
|
3879
|
+
has_duplicate_parameters);
|
|
3708
3880
|
function_literal->set_function_token_position(function_token_position);
|
|
3709
3881
|
|
|
3710
|
-
if (fni_ != NULL &&
|
|
3882
|
+
if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
|
|
3711
3883
|
return function_literal;
|
|
3712
3884
|
}
|
|
3713
3885
|
|
|
@@ -3723,7 +3895,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
|
|
3723
3895
|
if (extension_ != NULL) {
|
|
3724
3896
|
// The extension structures are only accessible while parsing the
|
|
3725
3897
|
// very first time not when reparsing because of lazy compilation.
|
|
3726
|
-
top_scope_->ForceEagerCompilation();
|
|
3898
|
+
top_scope_->DeclarationScope()->ForceEagerCompilation();
|
|
3727
3899
|
}
|
|
3728
3900
|
|
|
3729
3901
|
const Runtime::Function* function = Runtime::FunctionForSymbol(name);
|
|
@@ -3754,14 +3926,15 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
|
|
3754
3926
|
}
|
|
3755
3927
|
|
|
3756
3928
|
// We have a valid intrinsics call or a call to a builtin.
|
|
3757
|
-
return new(zone()) CallRuntime(name, function, args);
|
|
3929
|
+
return new(zone()) CallRuntime(isolate(), name, function, args);
|
|
3758
3930
|
}
|
|
3759
3931
|
|
|
3760
3932
|
|
|
3761
3933
|
bool Parser::peek_any_identifier() {
|
|
3762
3934
|
Token::Value next = peek();
|
|
3763
3935
|
return next == Token::IDENTIFIER ||
|
|
3764
|
-
next == Token::FUTURE_RESERVED_WORD
|
|
3936
|
+
next == Token::FUTURE_RESERVED_WORD ||
|
|
3937
|
+
next == Token::FUTURE_STRICT_RESERVED_WORD;
|
|
3765
3938
|
}
|
|
3766
3939
|
|
|
3767
3940
|
|
|
@@ -3799,7 +3972,7 @@ void Parser::ExpectSemicolon(bool* ok) {
|
|
|
3799
3972
|
Next();
|
|
3800
3973
|
return;
|
|
3801
3974
|
}
|
|
3802
|
-
if (scanner().
|
|
3975
|
+
if (scanner().HasAnyLineTerminatorBeforeNext() ||
|
|
3803
3976
|
tok == Token::RBRACE ||
|
|
3804
3977
|
tok == Token::EOS) {
|
|
3805
3978
|
return;
|
|
@@ -3809,12 +3982,12 @@ void Parser::ExpectSemicolon(bool* ok) {
|
|
|
3809
3982
|
|
|
3810
3983
|
|
|
3811
3984
|
Literal* Parser::GetLiteralUndefined() {
|
|
3812
|
-
return
|
|
3985
|
+
return NewLiteral(isolate()->factory()->undefined_value());
|
|
3813
3986
|
}
|
|
3814
3987
|
|
|
3815
3988
|
|
|
3816
3989
|
Literal* Parser::GetLiteralTheHole() {
|
|
3817
|
-
return
|
|
3990
|
+
return NewLiteral(isolate()->factory()->the_hole_value());
|
|
3818
3991
|
}
|
|
3819
3992
|
|
|
3820
3993
|
|
|
@@ -3823,22 +3996,27 @@ Literal* Parser::GetLiteralNumber(double value) {
|
|
|
3823
3996
|
}
|
|
3824
3997
|
|
|
3825
3998
|
|
|
3999
|
+
// Parses an identifier that is valid for the current scope, in particular it
|
|
4000
|
+
// fails on strict mode future reserved keywords in a strict scope.
|
|
3826
4001
|
Handle<String> Parser::ParseIdentifier(bool* ok) {
|
|
3827
|
-
|
|
3828
|
-
|
|
4002
|
+
if (top_scope_->is_strict_mode()) {
|
|
4003
|
+
Expect(Token::IDENTIFIER, ok);
|
|
4004
|
+
} else if (!Check(Token::IDENTIFIER)) {
|
|
4005
|
+
Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
|
|
4006
|
+
}
|
|
4007
|
+
if (!*ok) return Handle<String>();
|
|
4008
|
+
return GetSymbol(ok);
|
|
3829
4009
|
}
|
|
3830
4010
|
|
|
3831
4011
|
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
*is_reserved = true;
|
|
3841
|
-
}
|
|
4012
|
+
// Parses and identifier or a strict mode future reserved word, and indicate
|
|
4013
|
+
// whether it is strict mode future reserved.
|
|
4014
|
+
Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
|
|
4015
|
+
bool* is_strict_reserved, bool* ok) {
|
|
4016
|
+
*is_strict_reserved = false;
|
|
4017
|
+
if (!Check(Token::IDENTIFIER)) {
|
|
4018
|
+
Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
|
|
4019
|
+
*is_strict_reserved = true;
|
|
3842
4020
|
}
|
|
3843
4021
|
if (!*ok) return Handle<String>();
|
|
3844
4022
|
return GetSymbol(ok);
|
|
@@ -3848,8 +4026,9 @@ Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
|
|
|
3848
4026
|
Handle<String> Parser::ParseIdentifierName(bool* ok) {
|
|
3849
4027
|
Token::Value next = Next();
|
|
3850
4028
|
if (next != Token::IDENTIFIER &&
|
|
3851
|
-
|
|
3852
|
-
|
|
4029
|
+
next != Token::FUTURE_RESERVED_WORD &&
|
|
4030
|
+
next != Token::FUTURE_STRICT_RESERVED_WORD &&
|
|
4031
|
+
!Token::IsKeyword(next)) {
|
|
3853
4032
|
ReportUnexpectedToken(next);
|
|
3854
4033
|
*ok = false;
|
|
3855
4034
|
return Handle<String>();
|
|
@@ -3890,12 +4069,12 @@ void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
|
|
|
3890
4069
|
}
|
|
3891
4070
|
|
|
3892
4071
|
|
|
3893
|
-
// This function reads an identifier and determines whether or not it
|
|
4072
|
+
// This function reads an identifier name and determines whether or not it
|
|
3894
4073
|
// is 'get' or 'set'.
|
|
3895
|
-
Handle<String> Parser::
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
Handle<String> result =
|
|
4074
|
+
Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
|
|
4075
|
+
bool* is_set,
|
|
4076
|
+
bool* ok) {
|
|
4077
|
+
Handle<String> result = ParseIdentifierName(ok);
|
|
3899
4078
|
if (!*ok) return Handle<String>();
|
|
3900
4079
|
if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
|
|
3901
4080
|
const char* token = scanner().literal_ascii_string().start();
|
|
@@ -3964,7 +4143,7 @@ void Parser::RegisterTargetUse(Label* target, Target* stop) {
|
|
|
3964
4143
|
|
|
3965
4144
|
|
|
3966
4145
|
Literal* Parser::NewNumberLiteral(double number) {
|
|
3967
|
-
return
|
|
4146
|
+
return NewLiteral(isolate()->factory()->NewNumber(number, TENURED));
|
|
3968
4147
|
}
|
|
3969
4148
|
|
|
3970
4149
|
|
|
@@ -4011,10 +4190,15 @@ Expression* Parser::NewThrowError(Handle<String> constructor,
|
|
|
4011
4190
|
TENURED);
|
|
4012
4191
|
|
|
4013
4192
|
ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2);
|
|
4014
|
-
args->Add(
|
|
4015
|
-
args->Add(
|
|
4016
|
-
|
|
4017
|
-
|
|
4193
|
+
args->Add(NewLiteral(type));
|
|
4194
|
+
args->Add(NewLiteral(array));
|
|
4195
|
+
CallRuntime* call_constructor = new(zone()) CallRuntime(isolate(),
|
|
4196
|
+
constructor,
|
|
4197
|
+
NULL,
|
|
4198
|
+
args);
|
|
4199
|
+
return new(zone()) Throw(isolate(),
|
|
4200
|
+
call_constructor,
|
|
4201
|
+
scanner().location().beg_pos);
|
|
4018
4202
|
}
|
|
4019
4203
|
|
|
4020
4204
|
// ----------------------------------------------------------------------------
|
|
@@ -4893,9 +5077,11 @@ int ScriptDataImpl::ReadNumber(byte** source) {
|
|
|
4893
5077
|
// Create a Scanner for the preparser to use as input, and preparse the source.
|
|
4894
5078
|
static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
|
|
4895
5079
|
bool allow_lazy,
|
|
4896
|
-
ParserRecorder* recorder
|
|
5080
|
+
ParserRecorder* recorder,
|
|
5081
|
+
bool harmony_block_scoping) {
|
|
4897
5082
|
Isolate* isolate = Isolate::Current();
|
|
4898
|
-
|
|
5083
|
+
JavaScriptScanner scanner(isolate->unicode_cache());
|
|
5084
|
+
scanner.SetHarmonyBlockScoping(harmony_block_scoping);
|
|
4899
5085
|
scanner.Initialize(source);
|
|
4900
5086
|
intptr_t stack_limit = isolate->stack_guard()->real_climit();
|
|
4901
5087
|
if (!preparser::PreParser::PreParseProgram(&scanner,
|
|
@@ -4916,7 +5102,8 @@ static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
|
|
|
4916
5102
|
// Preparse, but only collect data that is immediately useful,
|
|
4917
5103
|
// even if the preparser data is only used once.
|
|
4918
5104
|
ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source,
|
|
4919
|
-
v8::Extension* extension
|
|
5105
|
+
v8::Extension* extension,
|
|
5106
|
+
bool harmony_block_scoping) {
|
|
4920
5107
|
bool allow_lazy = FLAG_lazy && (extension == NULL);
|
|
4921
5108
|
if (!allow_lazy) {
|
|
4922
5109
|
// Partial preparsing is only about lazily compiled functions.
|
|
@@ -4924,16 +5111,17 @@ ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source,
|
|
|
4924
5111
|
return NULL;
|
|
4925
5112
|
}
|
|
4926
5113
|
PartialParserRecorder recorder;
|
|
4927
|
-
return DoPreParse(source, allow_lazy, &recorder);
|
|
5114
|
+
return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping);
|
|
4928
5115
|
}
|
|
4929
5116
|
|
|
4930
5117
|
|
|
4931
5118
|
ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source,
|
|
4932
|
-
v8::Extension* extension
|
|
5119
|
+
v8::Extension* extension,
|
|
5120
|
+
bool harmony_block_scoping) {
|
|
4933
5121
|
Handle<Script> no_script;
|
|
4934
5122
|
bool allow_lazy = FLAG_lazy && (extension == NULL);
|
|
4935
5123
|
CompleteParserRecorder recorder;
|
|
4936
|
-
return DoPreParse(source, allow_lazy, &recorder);
|
|
5124
|
+
return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping);
|
|
4937
5125
|
}
|
|
4938
5126
|
|
|
4939
5127
|
|
|
@@ -4963,14 +5151,22 @@ bool ParserApi::Parse(CompilationInfo* info) {
|
|
|
4963
5151
|
ASSERT(info->function() == NULL);
|
|
4964
5152
|
FunctionLiteral* result = NULL;
|
|
4965
5153
|
Handle<Script> script = info->script();
|
|
5154
|
+
bool harmony_block_scoping = !info->is_native() &&
|
|
5155
|
+
FLAG_harmony_block_scoping;
|
|
4966
5156
|
if (info->is_lazy()) {
|
|
4967
5157
|
Parser parser(script, true, NULL, NULL);
|
|
5158
|
+
parser.SetHarmonyBlockScoping(harmony_block_scoping);
|
|
4968
5159
|
result = parser.ParseLazy(info);
|
|
4969
5160
|
} else {
|
|
5161
|
+
// Whether we allow %identifier(..) syntax.
|
|
4970
5162
|
bool allow_natives_syntax =
|
|
4971
5163
|
info->allows_natives_syntax() || FLAG_allow_natives_syntax;
|
|
4972
5164
|
ScriptDataImpl* pre_data = info->pre_parse_data();
|
|
4973
|
-
Parser parser(script,
|
|
5165
|
+
Parser parser(script,
|
|
5166
|
+
allow_natives_syntax,
|
|
5167
|
+
info->extension(),
|
|
5168
|
+
pre_data);
|
|
5169
|
+
parser.SetHarmonyBlockScoping(harmony_block_scoping);
|
|
4974
5170
|
if (pre_data != NULL && pre_data->has_error()) {
|
|
4975
5171
|
Scanner::Location loc = pre_data->MessageLocation();
|
|
4976
5172
|
const char* message = pre_data->BuildMessage();
|
|
@@ -4989,7 +5185,6 @@ bool ParserApi::Parse(CompilationInfo* info) {
|
|
|
4989
5185
|
info->StrictMode());
|
|
4990
5186
|
}
|
|
4991
5187
|
}
|
|
4992
|
-
|
|
4993
5188
|
info->SetFunction(result);
|
|
4994
5189
|
return (result != NULL);
|
|
4995
5190
|
}
|