therubyracer 0.7.4 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of therubyracer might be problematic. Click here for more details.
- data/History.txt +11 -0
- data/Rakefile +1 -1
- data/ext/v8/extconf.rb +0 -18
- data/ext/v8/rr.cpp +2 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/AUTHORS +1 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/ChangeLog +239 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/LICENSE +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/SConstruct +29 -17
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/include/v8-debug.h +61 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/include/v8-profiler.h +182 -5
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/include/v8.h +458 -257
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/SConscript +2 -5
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/accessors.cc +2 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/accessors.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/allocation.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/allocation.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/api.cc +574 -30
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/api.h +12 -10
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/apinatives.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/apiutils.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arguments.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/assembler-arm-inl.h +38 -15
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/assembler-arm.cc +646 -101
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/assembler-arm.h +174 -15
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/builtins-arm.cc +56 -47
- data/ext/v8/upstream/2.3.3/src/arm/codegen-arm-inl.h +48 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/codegen-arm.cc +2957 -1448
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/codegen-arm.h +230 -74
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/constants-arm.cc +25 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/constants-arm.h +16 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/cpu-arm.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/debug-arm.cc +76 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/disasm-arm.cc +168 -20
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/fast-codegen-arm.cc +5 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/frames-arm.cc +4 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/frames-arm.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/full-codegen-arm.cc +1558 -248
- data/ext/v8/upstream/2.3.3/src/arm/ic-arm.cc +2258 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/jump-target-arm.cc +55 -103
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/macro-assembler-arm.cc +358 -185
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/macro-assembler-arm.h +136 -41
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/regexp-macro-assembler-arm.cc +26 -5
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/regexp-macro-assembler-arm.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/register-allocator-arm-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/register-allocator-arm.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/register-allocator-arm.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/simulator-arm.cc +203 -22
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/simulator-arm.h +7 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/stub-cache-arm.cc +531 -324
- data/ext/v8/upstream/2.3.3/src/arm/virtual-frame-arm-inl.h +59 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/virtual-frame-arm.cc +247 -81
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/arm/virtual-frame-arm.h +99 -83
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/array.js +2 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/assembler.cc +6 -13
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/assembler.h +36 -10
- data/ext/v8/upstream/2.3.3/src/ast-inl.h +81 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ast.cc +14 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ast.h +20 -35
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/bootstrapper.cc +32 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/bootstrapper.h +0 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/builtins.cc +50 -33
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/builtins.h +2 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/bytecodes-irregexp.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cached-powers.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/char-predicates-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/char-predicates.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/checks.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/checks.h +8 -6
- data/ext/v8/upstream/2.3.3/src/circular-queue-inl.h +53 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/circular-queue.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/circular-queue.h +0 -26
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/code-stubs.cc +2 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/code-stubs.h +1 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/code.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/codegen-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/codegen.cc +44 -13
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/codegen.h +310 -31
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compilation-cache.cc +28 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compilation-cache.h +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compiler.cc +45 -14
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/compiler.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/contexts.cc +11 -11
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/contexts.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/conversions-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/conversions.cc +25 -11
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/conversions.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/counters.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/counters.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu-profiler-inl.h +2 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu-profiler.cc +68 -24
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu-profiler.h +19 -11
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/cpu.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-debug.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-debug.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-posix.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-readline.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8-windows.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/d8.js +55 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/data-flow.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/data-flow.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/date.js +68 -137
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dateparser-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dateparser.cc +2 -8
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dateparser.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug-agent.cc +3 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug-agent.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug-debugger.js +81 -23
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug.cc +275 -81
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/debug.h +85 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/disasm.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/disassembler.cc +1 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/disassembler.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/diy-fp.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/diy-fp.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/double.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/dtoa-config.c +0 -0
- data/ext/v8/upstream/2.3.3/src/dtoa.cc +77 -0
- data/ext/v8/upstream/2.3.3/src/dtoa.h +81 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/execution.cc +111 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/execution.h +12 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/factory.cc +25 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/factory.h +16 -9
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-codegen.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-codegen.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-dtoa.cc +2 -9
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/fast-dtoa.h +1 -2
- data/ext/v8/upstream/2.3.3/src/fixed-dtoa.cc +405 -0
- data/ext/v8/upstream/{2.1.10/src/jump-target-light.cc → 2.3.3/src/fixed-dtoa.h} +22 -53
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flag-definitions.h +14 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flags.cc +5 -9
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flags.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flow-graph.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/flow-graph.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frame-element.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frame-element.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frames-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frames.cc +5 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/frames.h +1 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/full-codegen.cc +387 -20
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/full-codegen.h +102 -5
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/func-name-inferrer.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/func-name-inferrer.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/global-handles.cc +8 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/global-handles.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/globals.h +44 -7
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/handles-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/handles.cc +19 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/handles.h +8 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/hashmap.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/hashmap.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap-inl.h +56 -14
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap-profiler.cc +85 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap-profiler.h +45 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap.cc +994 -396
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/heap.h +220 -65
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/assembler-ia32-inl.h +41 -12
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/assembler-ia32.cc +94 -24
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/assembler-ia32.h +32 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/builtins-ia32.cc +42 -30
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/codegen-ia32-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/codegen-ia32.cc +1758 -916
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/codegen-ia32.h +67 -74
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/cpu-ia32.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/debug-ia32.cc +46 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/disasm-ia32.cc +37 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/fast-codegen-ia32.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/fast-codegen-ia32.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/frames-ia32.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/frames-ia32.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/full-codegen-ia32.cc +1465 -198
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/ic-ia32.cc +688 -367
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/jump-target-ia32.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/macro-assembler-ia32.cc +82 -180
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/macro-assembler-ia32.h +41 -25
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/regexp-macro-assembler-ia32.cc +68 -24
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/regexp-macro-assembler-ia32.h +1 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/register-allocator-ia32-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/register-allocator-ia32.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/register-allocator-ia32.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/simulator-ia32.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/simulator-ia32.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/stub-cache-ia32.cc +649 -302
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/virtual-frame-ia32.cc +23 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ia32/virtual-frame-ia32.h +18 -27
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ic-inl.h +30 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ic.cc +384 -66
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/ic.h +65 -24
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/interpreter-irregexp.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/interpreter-irregexp.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/json.js +3 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jsregexp.cc +20 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jsregexp.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-heavy-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-heavy.cc +79 -13
- data/ext/v8/upstream/{2.1.10/src/jump-target.h → 2.3.3/src/jump-target-heavy.h} +5 -47
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target-light-inl.h +16 -2
- data/ext/v8/upstream/2.3.3/src/jump-target-light.cc +110 -0
- data/ext/v8/upstream/2.3.3/src/jump-target-light.h +192 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/jump-target.cc +0 -64
- data/ext/v8/upstream/2.3.3/src/jump-target.h +90 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/list-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/list.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/liveedit-debugger.js +141 -28
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/liveedit.cc +19 -7
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/liveedit.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log-utils.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log-utils.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log.cc +12 -11
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/log.h +12 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/macro-assembler.h +0 -16
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/macros.py +21 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mark-compact.cc +120 -109
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mark-compact.h +25 -37
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/math.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/memory.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/messages.cc +8 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/messages.h +2 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/messages.js +15 -7
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/assembler-mips-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/assembler-mips.cc +12 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/assembler-mips.h +4 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/builtins-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/codegen-mips-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/codegen-mips.cc +9 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/codegen-mips.h +1 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/constants-mips.cc +5 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/constants-mips.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/cpu-mips.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/debug-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/disasm-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/fast-codegen-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/frames-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/frames-mips.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/full-codegen-mips.cc +5 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/ic-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/jump-target-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/macro-assembler-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/macro-assembler-mips.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/register-allocator-mips-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/register-allocator-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/register-allocator-mips.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/simulator-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/simulator-mips.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/stub-cache-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/virtual-frame-mips.cc +3 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mips/virtual-frame-mips.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mirror-debugger.js +46 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/mksnapshot.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/natives.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects-debug.cc +8 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects-inl.h +235 -62
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects.cc +497 -231
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/objects.h +355 -149
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/oprofile-agent.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/oprofile-agent.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/parser.cc +31 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/parser.h +1 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-freebsd.cc +9 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-linux.cc +26 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-macos.cc +11 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-nullos.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-openbsd.cc +6 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-posix.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-solaris.cc +69 -23
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform-win32.cc +15 -11
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/platform.h +10 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/powers-ten.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/prettyprinter.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/prettyprinter.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/profile-generator-inl.h +26 -2
- data/ext/v8/upstream/2.3.3/src/profile-generator.cc +1830 -0
- data/ext/v8/upstream/2.3.3/src/profile-generator.h +853 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/property.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/property.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-irregexp-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-irregexp.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-irregexp.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-tracer.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler-tracer.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler.cc +1 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-macro-assembler.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-stack.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp-stack.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/regexp.js +25 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/register-allocator-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/register-allocator.cc +4 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/register-allocator.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/rewriter.cc +85 -8
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/rewriter.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/runtime.cc +547 -221
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/runtime.h +5 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/runtime.js +23 -31
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scanner.cc +12 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scanner.h +60 -53
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopeinfo.cc +156 -168
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopeinfo.h +58 -62
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopes.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/scopes.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/serialize.cc +320 -242
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/serialize.h +81 -48
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/shell.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/simulator.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/smart-pointer.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/snapshot-common.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/snapshot-empty.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/snapshot.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/spaces-inl.h +177 -74
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/spaces.cc +138 -315
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/spaces.h +155 -124
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/splay-tree-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/splay-tree.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/string-stream.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/string-stream.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/string.js +113 -119
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/stub-cache.cc +242 -97
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/stub-cache.h +118 -55
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/third_party/dtoa/COPYING +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/third_party/dtoa/dtoa.c +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/third_party/valgrind/valgrind.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/token.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/token.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/top.cc +107 -26
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/top.h +9 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/type-info.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/type-info.h +2 -2
- data/ext/v8/upstream/2.3.3/src/unbound-queue-inl.h +95 -0
- data/ext/v8/upstream/2.3.3/src/unbound-queue.h +67 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/unicode-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/unicode.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/unicode.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/uri.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/utils.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/utils.h +83 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8-counters.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8-counters.h +20 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8.cc +5 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8.h +0 -0
- data/ext/v8/upstream/2.3.3/src/v8dll-main.cc +39 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8natives.js +210 -33
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8threads.cc +1 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/v8threads.h +1 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/variables.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/variables.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/version.cc +3 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/version.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-heavy-inl.h +40 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-heavy.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-light-inl.h +106 -5
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame-light.cc +4 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/virtual-frame.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/vm-state-inl.h +6 -3
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/vm-state.cc +1 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/vm-state.h +6 -4
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/assembler-x64-inl.h +42 -5
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/assembler-x64.cc +285 -53
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/assembler-x64.h +54 -18
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/builtins-x64.cc +31 -33
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/codegen-x64-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/codegen-x64.cc +9787 -8722
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/codegen-x64.h +82 -47
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/cpu-x64.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/debug-x64.cc +55 -6
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/disasm-x64.cc +42 -19
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/fast-codegen-x64.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/frames-x64.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/frames-x64.h +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/full-codegen-x64.cc +1487 -210
- data/ext/v8/upstream/2.3.3/src/x64/ic-x64.cc +1907 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/jump-target-x64.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/macro-assembler-x64.cc +366 -338
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/macro-assembler-x64.h +83 -38
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/regexp-macro-assembler-x64.cc +82 -23
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/regexp-macro-assembler-x64.h +1 -2
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/register-allocator-x64-inl.h +6 -5
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/register-allocator-x64.cc +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/register-allocator-x64.h +1 -1
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/simulator-x64.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/simulator-x64.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/stub-cache-x64.cc +556 -377
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/virtual-frame-x64.cc +197 -98
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/x64/virtual-frame-x64.h +37 -28
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/zone-inl.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/zone.cc +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/src/zone.h +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/codemap.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/consarray.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/csvparser.js +0 -0
- data/ext/v8/upstream/2.3.3/tools/gc-nvp-trace-processor.py +317 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/generate-ten-powers.scm +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/gyp/v8.gyp +87 -20
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/js2c.py +19 -15
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/jsmin.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/linux-tick-processor +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/linux-tick-processor.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/logreader.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/mac-nm +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/mac-tick-processor +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/annotate +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/common +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/dump +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/report +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/reset +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/run +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/shutdown +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/oprofile/start +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/presubmit.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/process-heap-prof.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/profile.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/profile_view.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/run-valgrind.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/splaytree.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/splaytree.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/stats-viewer.py +25 -13
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/test.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/tickprocessor-driver.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/tickprocessor.js +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/tickprocessor.py +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/utils.py +0 -0
- data/ext/v8/upstream/2.3.3/tools/v8.xcodeproj/project.pbxproj +1855 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/README.txt +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/arm.vsprops +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/common.vsprops +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8_arm.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/d8js2c.cmd +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/debug.vsprops +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/ia32.vsprops +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/js2c.cmd +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/release.vsprops +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8.sln +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_arm.sln +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_arm.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_base.vcproj +40 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_base_arm.vcproj +20 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_base_x64.vcproj +16 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_cctest.vcproj +4 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_cctest_arm.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_cctest_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_mksnapshot.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_mksnapshot_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_process_sample.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_process_sample_arm.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_process_sample_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_shell_sample.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_shell_sample_arm.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_shell_sample_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot_cc.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot_cc_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_snapshot_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_x64.sln +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/v8_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/visual_studio/x64.vsprops +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/windows-tick-processor.bat +0 -0
- data/ext/v8/upstream/{2.1.10 → 2.3.3}/tools/windows-tick-processor.py +0 -0
- data/ext/v8/upstream/Makefile +1 -1
- data/ext/v8/v8_template.cpp +94 -2
- data/ext/v8/v8_try_catch.cpp +2 -2
- data/lib/v8.rb +1 -1
- data/lib/v8/access.rb +93 -40
- data/lib/v8/cli.rb +1 -1
- data/lib/v8/function.rb +14 -2
- data/spec/redjs/jsapi_spec.rb +231 -42
- data/therubyracer.gemspec +3 -3
- metadata +463 -453
- data/ext/v8/upstream/2.1.10/src/arm/assembler-thumb2-inl.h +0 -263
- data/ext/v8/upstream/2.1.10/src/arm/assembler-thumb2.cc +0 -1878
- data/ext/v8/upstream/2.1.10/src/arm/assembler-thumb2.h +0 -1036
- data/ext/v8/upstream/2.1.10/src/arm/codegen-arm-inl.h +0 -72
- data/ext/v8/upstream/2.1.10/src/arm/ic-arm.cc +0 -1833
- data/ext/v8/upstream/2.1.10/src/circular-queue-inl.h +0 -101
- data/ext/v8/upstream/2.1.10/src/profile-generator.cc +0 -583
- data/ext/v8/upstream/2.1.10/src/profile-generator.h +0 -364
- data/ext/v8/upstream/2.1.10/src/x64/ic-x64.cc +0 -1621
@@ -27,6 +27,8 @@
|
|
27
27
|
|
28
28
|
#include "v8.h"
|
29
29
|
|
30
|
+
#if defined(V8_TARGET_ARCH_X64)
|
31
|
+
|
30
32
|
#include "codegen-inl.h"
|
31
33
|
#include "fast-codegen.h"
|
32
34
|
#include "scopes.h"
|
@@ -244,3 +246,5 @@ void FastCodeGenerator::Generate(CompilationInfo* compilation_info) {
|
|
244
246
|
|
245
247
|
|
246
248
|
} } // namespace v8::internal
|
249
|
+
|
250
|
+
#endif // V8_TARGET_ARCH_X64
|
@@ -27,6 +27,8 @@
|
|
27
27
|
|
28
28
|
#include "v8.h"
|
29
29
|
|
30
|
+
#if defined(V8_TARGET_ARCH_X64)
|
31
|
+
|
30
32
|
#include "frames-inl.h"
|
31
33
|
|
32
34
|
namespace v8 {
|
@@ -107,3 +109,5 @@ byte* ArgumentsAdaptorFrame::GetCallerStackPointer() const {
|
|
107
109
|
|
108
110
|
|
109
111
|
} } // namespace v8::internal
|
112
|
+
|
113
|
+
#endif // V8_TARGET_ARCH_X64
|
@@ -56,7 +56,11 @@ class StackHandlerConstants : public AllStatic {
|
|
56
56
|
|
57
57
|
class EntryFrameConstants : public AllStatic {
|
58
58
|
public:
|
59
|
+
#ifdef _WIN64
|
59
60
|
static const int kCallerFPOffset = -10 * kPointerSize;
|
61
|
+
#else
|
62
|
+
static const int kCallerFPOffset = -8 * kPointerSize;
|
63
|
+
#endif
|
60
64
|
static const int kArgvOffset = 6 * kPointerSize;
|
61
65
|
};
|
62
66
|
|
@@ -27,6 +27,8 @@
|
|
27
27
|
|
28
28
|
#include "v8.h"
|
29
29
|
|
30
|
+
#if defined(V8_TARGET_ARCH_X64)
|
31
|
+
|
30
32
|
#include "codegen-inl.h"
|
31
33
|
#include "compiler.h"
|
32
34
|
#include "debug.h"
|
@@ -79,11 +81,17 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
|
|
79
81
|
bool function_in_register = true;
|
80
82
|
|
81
83
|
// Possibly allocate a local context.
|
82
|
-
|
84
|
+
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
|
85
|
+
if (heap_slots > 0) {
|
83
86
|
Comment cmnt(masm_, "[ Allocate local context");
|
84
87
|
// Argument to NewContext is the function, which is still in rdi.
|
85
88
|
__ push(rdi);
|
86
|
-
|
89
|
+
if (heap_slots <= FastNewContextStub::kMaximumSlots) {
|
90
|
+
FastNewContextStub stub(heap_slots);
|
91
|
+
__ CallStub(&stub);
|
92
|
+
} else {
|
93
|
+
__ CallRuntime(Runtime::kNewContext, 1);
|
94
|
+
}
|
87
95
|
function_in_register = false;
|
88
96
|
// Context is returned in both rax and rsi. It replaces the context
|
89
97
|
// passed to us. It's saved in the stack and kept live in rsi.
|
@@ -143,7 +151,18 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
|
|
143
151
|
}
|
144
152
|
|
145
153
|
{ Comment cmnt(masm_, "[ Declarations");
|
146
|
-
|
154
|
+
// For named function expressions, declare the function name as a
|
155
|
+
// constant.
|
156
|
+
if (scope()->is_function_scope() && scope()->function() != NULL) {
|
157
|
+
EmitDeclaration(scope()->function(), Variable::CONST, NULL);
|
158
|
+
}
|
159
|
+
// Visit all the explicit declarations unless there is an illegal
|
160
|
+
// redeclaration.
|
161
|
+
if (scope()->HasIllegalRedeclaration()) {
|
162
|
+
scope()->VisitIllegalRedeclaration(this);
|
163
|
+
} else {
|
164
|
+
VisitDeclarations(scope()->declarations());
|
165
|
+
}
|
147
166
|
}
|
148
167
|
|
149
168
|
{ Comment cmnt(masm_, "[ Stack check");
|
@@ -168,12 +187,12 @@ void FullCodeGenerator::Generate(CompilationInfo* info, Mode mode) {
|
|
168
187
|
{ Comment cmnt(masm_, "[ return <undefined>;");
|
169
188
|
// Emit a 'return undefined' in case control fell off the end of the body.
|
170
189
|
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
171
|
-
EmitReturnSequence(
|
190
|
+
EmitReturnSequence();
|
172
191
|
}
|
173
192
|
}
|
174
193
|
|
175
194
|
|
176
|
-
void FullCodeGenerator::EmitReturnSequence(
|
195
|
+
void FullCodeGenerator::EmitReturnSequence() {
|
177
196
|
Comment cmnt(masm_, "[ Return sequence");
|
178
197
|
if (return_label_.is_bound()) {
|
179
198
|
__ jmp(&return_label_);
|
@@ -188,7 +207,7 @@ void FullCodeGenerator::EmitReturnSequence(int position) {
|
|
188
207
|
Label check_exit_codesize;
|
189
208
|
masm_->bind(&check_exit_codesize);
|
190
209
|
#endif
|
191
|
-
CodeGenerator::RecordPositions(masm_,
|
210
|
+
CodeGenerator::RecordPositions(masm_, function()->end_position());
|
192
211
|
__ RecordJSReturn();
|
193
212
|
// Do not use the leave instruction here because it is too short to
|
194
213
|
// patch with the code required by the debugger.
|
@@ -427,6 +446,39 @@ void FullCodeGenerator::DropAndApply(int count,
|
|
427
446
|
}
|
428
447
|
|
429
448
|
|
449
|
+
void FullCodeGenerator::PrepareTest(Label* materialize_true,
|
450
|
+
Label* materialize_false,
|
451
|
+
Label** if_true,
|
452
|
+
Label** if_false) {
|
453
|
+
switch (context_) {
|
454
|
+
case Expression::kUninitialized:
|
455
|
+
UNREACHABLE();
|
456
|
+
break;
|
457
|
+
case Expression::kEffect:
|
458
|
+
// In an effect context, the true and the false case branch to the
|
459
|
+
// same label.
|
460
|
+
*if_true = *if_false = materialize_true;
|
461
|
+
break;
|
462
|
+
case Expression::kValue:
|
463
|
+
*if_true = materialize_true;
|
464
|
+
*if_false = materialize_false;
|
465
|
+
break;
|
466
|
+
case Expression::kTest:
|
467
|
+
*if_true = true_label_;
|
468
|
+
*if_false = false_label_;
|
469
|
+
break;
|
470
|
+
case Expression::kValueTest:
|
471
|
+
*if_true = materialize_true;
|
472
|
+
*if_false = false_label_;
|
473
|
+
break;
|
474
|
+
case Expression::kTestValue:
|
475
|
+
*if_true = true_label_;
|
476
|
+
*if_false = materialize_false;
|
477
|
+
break;
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
481
|
+
|
430
482
|
void FullCodeGenerator::Apply(Expression::Context context,
|
431
483
|
Label* materialize_true,
|
432
484
|
Label* materialize_false) {
|
@@ -492,6 +544,61 @@ void FullCodeGenerator::Apply(Expression::Context context,
|
|
492
544
|
}
|
493
545
|
|
494
546
|
|
547
|
+
// Convert constant control flow (true or false) to the result expected for
|
548
|
+
// a given expression context.
|
549
|
+
void FullCodeGenerator::Apply(Expression::Context context, bool flag) {
|
550
|
+
switch (context) {
|
551
|
+
case Expression::kUninitialized:
|
552
|
+
UNREACHABLE();
|
553
|
+
break;
|
554
|
+
case Expression::kEffect:
|
555
|
+
break;
|
556
|
+
case Expression::kValue: {
|
557
|
+
Heap::RootListIndex value_root_index =
|
558
|
+
flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
|
559
|
+
switch (location_) {
|
560
|
+
case kAccumulator:
|
561
|
+
__ LoadRoot(result_register(), value_root_index);
|
562
|
+
break;
|
563
|
+
case kStack:
|
564
|
+
__ PushRoot(value_root_index);
|
565
|
+
break;
|
566
|
+
}
|
567
|
+
break;
|
568
|
+
}
|
569
|
+
case Expression::kTest:
|
570
|
+
__ jmp(flag ? true_label_ : false_label_);
|
571
|
+
break;
|
572
|
+
case Expression::kTestValue:
|
573
|
+
switch (location_) {
|
574
|
+
case kAccumulator:
|
575
|
+
// If value is false it's needed.
|
576
|
+
if (!flag) __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
|
577
|
+
break;
|
578
|
+
case kStack:
|
579
|
+
// If value is false it's needed.
|
580
|
+
if (!flag) __ PushRoot(Heap::kFalseValueRootIndex);
|
581
|
+
break;
|
582
|
+
}
|
583
|
+
__ jmp(flag ? true_label_ : false_label_);
|
584
|
+
break;
|
585
|
+
case Expression::kValueTest:
|
586
|
+
switch (location_) {
|
587
|
+
case kAccumulator:
|
588
|
+
// If value is true it's needed.
|
589
|
+
if (flag) __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
|
590
|
+
break;
|
591
|
+
case kStack:
|
592
|
+
// If value is true it's needed.
|
593
|
+
if (flag) __ PushRoot(Heap::kTrueValueRootIndex);
|
594
|
+
break;
|
595
|
+
}
|
596
|
+
__ jmp(flag ? true_label_ : false_label_);
|
597
|
+
break;
|
598
|
+
}
|
599
|
+
}
|
600
|
+
|
601
|
+
|
495
602
|
void FullCodeGenerator::DoTest(Expression::Context context) {
|
496
603
|
// The value to test is in the accumulator. If the value might be needed
|
497
604
|
// on the stack (value/test and test/value contexts with a stack location
|
@@ -667,22 +774,23 @@ void FullCodeGenerator::Move(Slot* dst,
|
|
667
774
|
}
|
668
775
|
|
669
776
|
|
670
|
-
void FullCodeGenerator::
|
777
|
+
void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
778
|
+
Variable::Mode mode,
|
779
|
+
FunctionLiteral* function) {
|
671
780
|
Comment cmnt(masm_, "[ Declaration");
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
Property* prop = var->AsProperty();
|
781
|
+
ASSERT(variable != NULL); // Must have been resolved.
|
782
|
+
Slot* slot = variable->slot();
|
783
|
+
Property* prop = variable->AsProperty();
|
676
784
|
|
677
785
|
if (slot != NULL) {
|
678
786
|
switch (slot->type()) {
|
679
787
|
case Slot::PARAMETER:
|
680
788
|
case Slot::LOCAL:
|
681
|
-
if (
|
789
|
+
if (mode == Variable::CONST) {
|
682
790
|
__ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
|
683
791
|
__ movq(Operand(rbp, SlotOffset(slot)), kScratchRegister);
|
684
|
-
} else if (
|
685
|
-
VisitForValue(
|
792
|
+
} else if (function != NULL) {
|
793
|
+
VisitForValue(function, kAccumulator);
|
686
794
|
__ movq(Operand(rbp, SlotOffset(slot)), result_register());
|
687
795
|
}
|
688
796
|
break;
|
@@ -692,7 +800,7 @@ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
|
|
692
800
|
// this specific context.
|
693
801
|
|
694
802
|
// The variable in the decl always resides in the current context.
|
695
|
-
ASSERT_EQ(0, scope()->ContextChainLength(
|
803
|
+
ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
|
696
804
|
if (FLAG_debug_code) {
|
697
805
|
// Check if we have the correct context pointer.
|
698
806
|
__ movq(rbx,
|
@@ -700,13 +808,13 @@ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
|
|
700
808
|
__ cmpq(rbx, rsi);
|
701
809
|
__ Check(equal, "Unexpected declaration in current context.");
|
702
810
|
}
|
703
|
-
if (
|
811
|
+
if (mode == Variable::CONST) {
|
704
812
|
__ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
|
705
813
|
__ movq(CodeGenerator::ContextOperand(rsi, slot->index()),
|
706
814
|
kScratchRegister);
|
707
815
|
// No write barrier since the hole value is in old space.
|
708
|
-
} else if (
|
709
|
-
VisitForValue(
|
816
|
+
} else if (function != NULL) {
|
817
|
+
VisitForValue(function, kAccumulator);
|
710
818
|
__ movq(CodeGenerator::ContextOperand(rsi, slot->index()),
|
711
819
|
result_register());
|
712
820
|
int offset = Context::SlotOffset(slot->index());
|
@@ -717,21 +825,19 @@ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
|
|
717
825
|
|
718
826
|
case Slot::LOOKUP: {
|
719
827
|
__ push(rsi);
|
720
|
-
__ Push(
|
828
|
+
__ Push(variable->name());
|
721
829
|
// Declaration nodes are always introduced in one of two modes.
|
722
|
-
ASSERT(
|
723
|
-
|
724
|
-
PropertyAttributes attr =
|
725
|
-
(decl->mode() == Variable::VAR) ? NONE : READ_ONLY;
|
830
|
+
ASSERT(mode == Variable::VAR || mode == Variable::CONST);
|
831
|
+
PropertyAttributes attr = (mode == Variable::VAR) ? NONE : READ_ONLY;
|
726
832
|
__ Push(Smi::FromInt(attr));
|
727
833
|
// Push initial value, if any.
|
728
834
|
// Note: For variables we must not push an initial value (such as
|
729
835
|
// 'undefined') because we may have a (legal) redeclaration and we
|
730
836
|
// must not destroy the current value.
|
731
|
-
if (
|
837
|
+
if (mode == Variable::CONST) {
|
732
838
|
__ PushRoot(Heap::kTheHoleValueRootIndex);
|
733
|
-
} else if (
|
734
|
-
VisitForValue(
|
839
|
+
} else if (function != NULL) {
|
840
|
+
VisitForValue(function, kStack);
|
735
841
|
} else {
|
736
842
|
__ Push(Smi::FromInt(0)); // no initial value!
|
737
843
|
}
|
@@ -741,32 +847,36 @@ void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
|
|
741
847
|
}
|
742
848
|
|
743
849
|
} else if (prop != NULL) {
|
744
|
-
if (
|
850
|
+
if (function != NULL || mode == Variable::CONST) {
|
745
851
|
// We are declaring a function or constant that rewrites to a
|
746
852
|
// property. Use (keyed) IC to set the initial value.
|
747
853
|
VisitForValue(prop->obj(), kStack);
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
854
|
+
if (function != NULL) {
|
855
|
+
VisitForValue(prop->key(), kStack);
|
856
|
+
VisitForValue(function, kAccumulator);
|
857
|
+
__ pop(rcx);
|
752
858
|
} else {
|
859
|
+
VisitForValue(prop->key(), kAccumulator);
|
860
|
+
__ movq(rcx, result_register());
|
753
861
|
__ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex);
|
754
862
|
}
|
863
|
+
__ pop(rdx);
|
755
864
|
|
756
865
|
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
757
866
|
__ call(ic, RelocInfo::CODE_TARGET);
|
758
867
|
// Absence of a test rax instruction following the call
|
759
868
|
// indicates that none of the load was inlined.
|
760
869
|
__ nop();
|
761
|
-
|
762
|
-
// Value in rax is ignored (declarations are statements). Receiver
|
763
|
-
// and key on stack are discarded.
|
764
|
-
__ Drop(2);
|
765
870
|
}
|
766
871
|
}
|
767
872
|
}
|
768
873
|
|
769
874
|
|
875
|
+
void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
|
876
|
+
EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
|
877
|
+
}
|
878
|
+
|
879
|
+
|
770
880
|
void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
|
771
881
|
// Call the runtime to declare the globals.
|
772
882
|
__ push(rsi); // The context is the first argument.
|
@@ -777,19 +887,224 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
|
|
777
887
|
}
|
778
888
|
|
779
889
|
|
780
|
-
void FullCodeGenerator::
|
781
|
-
Comment cmnt(masm_, "[
|
890
|
+
void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
891
|
+
Comment cmnt(masm_, "[ SwitchStatement");
|
892
|
+
Breakable nested_statement(this, stmt);
|
893
|
+
SetStatementPosition(stmt);
|
894
|
+
// Keep the switch value on the stack until a case matches.
|
895
|
+
VisitForValue(stmt->tag(), kStack);
|
896
|
+
|
897
|
+
ZoneList<CaseClause*>* clauses = stmt->cases();
|
898
|
+
CaseClause* default_clause = NULL; // Can occur anywhere in the list.
|
899
|
+
|
900
|
+
Label next_test; // Recycled for each test.
|
901
|
+
// Compile all the tests with branches to their bodies.
|
902
|
+
for (int i = 0; i < clauses->length(); i++) {
|
903
|
+
CaseClause* clause = clauses->at(i);
|
904
|
+
// The default is not a test, but remember it as final fall through.
|
905
|
+
if (clause->is_default()) {
|
906
|
+
default_clause = clause;
|
907
|
+
continue;
|
908
|
+
}
|
909
|
+
|
910
|
+
Comment cmnt(masm_, "[ Case comparison");
|
911
|
+
__ bind(&next_test);
|
912
|
+
next_test.Unuse();
|
913
|
+
|
914
|
+
// Compile the label expression.
|
915
|
+
VisitForValue(clause->label(), kAccumulator);
|
916
|
+
|
917
|
+
// Perform the comparison as if via '==='. The comparison stub expects
|
918
|
+
// the smi vs. smi case to be handled before it is called.
|
919
|
+
Label slow_case;
|
920
|
+
__ movq(rdx, Operand(rsp, 0)); // Switch value.
|
921
|
+
__ JumpIfNotBothSmi(rdx, rax, &slow_case);
|
922
|
+
__ SmiCompare(rdx, rax);
|
923
|
+
__ j(not_equal, &next_test);
|
924
|
+
__ Drop(1); // Switch value is no longer needed.
|
925
|
+
__ jmp(clause->body_target()->entry_label());
|
926
|
+
|
927
|
+
__ bind(&slow_case);
|
928
|
+
CompareStub stub(equal, true);
|
929
|
+
__ CallStub(&stub);
|
930
|
+
__ testq(rax, rax);
|
931
|
+
__ j(not_equal, &next_test);
|
932
|
+
__ Drop(1); // Switch value is no longer needed.
|
933
|
+
__ jmp(clause->body_target()->entry_label());
|
934
|
+
}
|
935
|
+
|
936
|
+
// Discard the test value and jump to the default if present, otherwise to
|
937
|
+
// the end of the statement.
|
938
|
+
__ bind(&next_test);
|
939
|
+
__ Drop(1); // Switch value is no longer needed.
|
940
|
+
if (default_clause == NULL) {
|
941
|
+
__ jmp(nested_statement.break_target());
|
942
|
+
} else {
|
943
|
+
__ jmp(default_clause->body_target()->entry_label());
|
944
|
+
}
|
945
|
+
|
946
|
+
// Compile all the case bodies.
|
947
|
+
for (int i = 0; i < clauses->length(); i++) {
|
948
|
+
Comment cmnt(masm_, "[ Case body");
|
949
|
+
CaseClause* clause = clauses->at(i);
|
950
|
+
__ bind(clause->body_target()->entry_label());
|
951
|
+
VisitStatements(clause->statements());
|
952
|
+
}
|
953
|
+
|
954
|
+
__ bind(nested_statement.break_target());
|
955
|
+
}
|
956
|
+
|
957
|
+
|
958
|
+
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
959
|
+
Comment cmnt(masm_, "[ ForInStatement");
|
960
|
+
SetStatementPosition(stmt);
|
961
|
+
|
962
|
+
Label loop, exit;
|
963
|
+
ForIn loop_statement(this, stmt);
|
964
|
+
increment_loop_depth();
|
782
965
|
|
783
|
-
//
|
784
|
-
//
|
785
|
-
|
786
|
-
|
787
|
-
|
966
|
+
// Get the object to enumerate over. Both SpiderMonkey and JSC
|
967
|
+
// ignore null and undefined in contrast to the specification; see
|
968
|
+
// ECMA-262 section 12.6.4.
|
969
|
+
VisitForValue(stmt->enumerable(), kAccumulator);
|
970
|
+
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
|
971
|
+
__ j(equal, &exit);
|
972
|
+
__ CompareRoot(rax, Heap::kNullValueRootIndex);
|
973
|
+
__ j(equal, &exit);
|
974
|
+
|
975
|
+
// Convert the object to a JS object.
|
976
|
+
Label convert, done_convert;
|
977
|
+
__ JumpIfSmi(rax, &convert);
|
978
|
+
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
|
979
|
+
__ j(above_equal, &done_convert);
|
980
|
+
__ bind(&convert);
|
981
|
+
__ push(rax);
|
982
|
+
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
|
983
|
+
__ bind(&done_convert);
|
984
|
+
__ push(rax);
|
985
|
+
|
986
|
+
// TODO(kasperl): Check cache validity in generated code. This is a
|
987
|
+
// fast case for the JSObject::IsSimpleEnum cache validity
|
988
|
+
// checks. If we cannot guarantee cache validity, call the runtime
|
989
|
+
// system to check cache validity or get the property names in a
|
990
|
+
// fixed array.
|
991
|
+
|
992
|
+
// Get the set of properties to enumerate.
|
993
|
+
__ push(rax); // Duplicate the enumerable object on the stack.
|
994
|
+
__ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
|
995
|
+
|
996
|
+
// If we got a map from the runtime call, we can do a fast
|
997
|
+
// modification check. Otherwise, we got a fixed array, and we have
|
998
|
+
// to do a slow check.
|
999
|
+
Label fixed_array;
|
1000
|
+
__ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
|
1001
|
+
Heap::kMetaMapRootIndex);
|
1002
|
+
__ j(not_equal, &fixed_array);
|
1003
|
+
|
1004
|
+
// We got a map in register rax. Get the enumeration cache from it.
|
1005
|
+
__ movq(rcx, FieldOperand(rax, Map::kInstanceDescriptorsOffset));
|
1006
|
+
__ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset));
|
1007
|
+
__ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset));
|
1008
|
+
|
1009
|
+
// Setup the four remaining stack slots.
|
1010
|
+
__ push(rax); // Map.
|
1011
|
+
__ push(rdx); // Enumeration cache.
|
1012
|
+
__ movq(rax, FieldOperand(rdx, FixedArray::kLengthOffset));
|
1013
|
+
__ push(rax); // Enumeration cache length (as smi).
|
1014
|
+
__ Push(Smi::FromInt(0)); // Initial index.
|
1015
|
+
__ jmp(&loop);
|
1016
|
+
|
1017
|
+
// We got a fixed array in register rax. Iterate through that.
|
1018
|
+
__ bind(&fixed_array);
|
1019
|
+
__ Push(Smi::FromInt(0)); // Map (0) - force slow check.
|
1020
|
+
__ push(rax);
|
1021
|
+
__ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset));
|
1022
|
+
__ push(rax); // Fixed array length (as smi).
|
1023
|
+
__ Push(Smi::FromInt(0)); // Initial index.
|
1024
|
+
|
1025
|
+
// Generate code for doing the condition check.
|
1026
|
+
__ bind(&loop);
|
1027
|
+
__ movq(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index.
|
1028
|
+
__ cmpq(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length.
|
1029
|
+
__ j(above_equal, loop_statement.break_target());
|
1030
|
+
|
1031
|
+
// Get the current entry of the array into register rbx.
|
1032
|
+
__ movq(rbx, Operand(rsp, 2 * kPointerSize));
|
1033
|
+
SmiIndex index = __ SmiToIndex(rax, rax, kPointerSizeLog2);
|
1034
|
+
__ movq(rbx, FieldOperand(rbx,
|
1035
|
+
index.reg,
|
1036
|
+
index.scale,
|
1037
|
+
FixedArray::kHeaderSize));
|
1038
|
+
|
1039
|
+
// Get the expected map from the stack or a zero map in the
|
1040
|
+
// permanent slow case into register rdx.
|
1041
|
+
__ movq(rdx, Operand(rsp, 3 * kPointerSize));
|
1042
|
+
|
1043
|
+
// Check if the expected map still matches that of the enumerable.
|
1044
|
+
// If not, we have to filter the key.
|
1045
|
+
Label update_each;
|
1046
|
+
__ movq(rcx, Operand(rsp, 4 * kPointerSize));
|
1047
|
+
__ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset));
|
1048
|
+
__ j(equal, &update_each);
|
1049
|
+
|
1050
|
+
// Convert the entry to a string or null if it isn't a property
|
1051
|
+
// anymore. If the property has been removed while iterating, we
|
1052
|
+
// just skip it.
|
1053
|
+
__ push(rcx); // Enumerable.
|
1054
|
+
__ push(rbx); // Current entry.
|
1055
|
+
__ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
|
1056
|
+
__ CompareRoot(rax, Heap::kNullValueRootIndex);
|
1057
|
+
__ j(equal, loop_statement.continue_target());
|
1058
|
+
__ movq(rbx, rax);
|
1059
|
+
|
1060
|
+
// Update the 'each' property or variable from the possibly filtered
|
1061
|
+
// entry in register rbx.
|
1062
|
+
__ bind(&update_each);
|
1063
|
+
__ movq(result_register(), rbx);
|
1064
|
+
// Perform the assignment as if via '='.
|
1065
|
+
EmitAssignment(stmt->each());
|
1066
|
+
|
1067
|
+
// Generate code for the body of the loop.
|
1068
|
+
Label stack_limit_hit, stack_check_done;
|
1069
|
+
Visit(stmt->body());
|
1070
|
+
|
1071
|
+
__ StackLimitCheck(&stack_limit_hit);
|
1072
|
+
__ bind(&stack_check_done);
|
1073
|
+
|
1074
|
+
// Generate code for going to the next element by incrementing the
|
1075
|
+
// index (smi) stored on top of the stack.
|
1076
|
+
__ bind(loop_statement.continue_target());
|
1077
|
+
__ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1));
|
1078
|
+
__ jmp(&loop);
|
1079
|
+
|
1080
|
+
// Slow case for the stack limit check.
|
1081
|
+
StackCheckStub stack_check_stub;
|
1082
|
+
__ bind(&stack_limit_hit);
|
1083
|
+
__ CallStub(&stack_check_stub);
|
1084
|
+
__ jmp(&stack_check_done);
|
1085
|
+
|
1086
|
+
// Remove the pointers stored on the stack.
|
1087
|
+
__ bind(loop_statement.break_target());
|
1088
|
+
__ addq(rsp, Immediate(5 * kPointerSize));
|
1089
|
+
|
1090
|
+
// Exit and decrement the loop depth.
|
1091
|
+
__ bind(&exit);
|
1092
|
+
decrement_loop_depth();
|
1093
|
+
}
|
788
1094
|
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
1095
|
+
|
1096
|
+
void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info) {
|
1097
|
+
// Use the fast case closure allocation code that allocates in new
|
1098
|
+
// space for nested functions that don't need literals cloning.
|
1099
|
+
if (scope()->is_function_scope() && info->num_literals() == 0) {
|
1100
|
+
FastNewClosureStub stub;
|
1101
|
+
__ Push(info);
|
1102
|
+
__ CallStub(&stub);
|
1103
|
+
} else {
|
1104
|
+
__ push(rsi);
|
1105
|
+
__ Push(info);
|
1106
|
+
__ CallRuntime(Runtime::kNewClosure, 2);
|
1107
|
+
}
|
793
1108
|
Apply(context_, rax);
|
794
1109
|
}
|
795
1110
|
|
@@ -812,15 +1127,15 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
|
812
1127
|
Comment cmnt(masm_, "Global variable");
|
813
1128
|
// Use inline caching. Variable name is passed in rcx and the global
|
814
1129
|
// object on the stack.
|
815
|
-
__ push(CodeGenerator::GlobalObject());
|
816
1130
|
__ Move(rcx, var->name());
|
1131
|
+
__ movq(rax, CodeGenerator::GlobalObject());
|
817
1132
|
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
818
1133
|
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
819
1134
|
// A test rax instruction following the call is used by the IC to
|
820
1135
|
// indicate that the inobject property case was inlined. Ensure there
|
821
1136
|
// is no test rax instruction here.
|
822
1137
|
__ nop();
|
823
|
-
|
1138
|
+
Apply(context, rax);
|
824
1139
|
|
825
1140
|
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
|
826
1141
|
Comment cmnt(masm_, "Lookup slot");
|
@@ -833,7 +1148,20 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
|
833
1148
|
Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
|
834
1149
|
? "Context slot"
|
835
1150
|
: "Stack slot");
|
836
|
-
|
1151
|
+
if (var->mode() == Variable::CONST) {
|
1152
|
+
// Constants may be the hole value if they have not been initialized.
|
1153
|
+
// Unhole them.
|
1154
|
+
Label done;
|
1155
|
+
MemOperand slot_operand = EmitSlotSearch(slot, rax);
|
1156
|
+
__ movq(rax, slot_operand);
|
1157
|
+
__ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
|
1158
|
+
__ j(not_equal, &done);
|
1159
|
+
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
1160
|
+
__ bind(&done);
|
1161
|
+
Apply(context, rax);
|
1162
|
+
} else {
|
1163
|
+
Apply(context, slot);
|
1164
|
+
}
|
837
1165
|
|
838
1166
|
} else {
|
839
1167
|
Comment cmnt(masm_, "Rewritten parameter");
|
@@ -848,7 +1176,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
|
848
1176
|
|
849
1177
|
// Load the object.
|
850
1178
|
MemOperand object_loc = EmitSlotSearch(object_slot, rax);
|
851
|
-
__
|
1179
|
+
__ movq(rdx, object_loc);
|
852
1180
|
|
853
1181
|
// Assert that the key is a smi.
|
854
1182
|
Literal* key_literal = property->key()->AsLiteral();
|
@@ -856,7 +1184,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
|
856
1184
|
ASSERT(key_literal->handle()->IsSmi());
|
857
1185
|
|
858
1186
|
// Load the key.
|
859
|
-
__
|
1187
|
+
__ Move(rax, key_literal->handle());
|
860
1188
|
|
861
1189
|
// Do a keyed property load.
|
862
1190
|
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
@@ -864,8 +1192,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
|
|
864
1192
|
// Notice: We must not have a "test rax, ..." instruction after the
|
865
1193
|
// call. It is treated specially by the LoadIC code.
|
866
1194
|
__ nop();
|
867
|
-
|
868
|
-
DropAndApply(2, context, rax);
|
1195
|
+
Apply(context, rax);
|
869
1196
|
}
|
870
1197
|
}
|
871
1198
|
|
@@ -969,22 +1296,28 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
|
969
1296
|
|
970
1297
|
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
971
1298
|
Comment cmnt(masm_, "[ ArrayLiteral");
|
1299
|
+
|
1300
|
+
ZoneList<Expression*>* subexprs = expr->values();
|
1301
|
+
int length = subexprs->length();
|
1302
|
+
|
972
1303
|
__ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
|
973
1304
|
__ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
|
974
1305
|
__ Push(Smi::FromInt(expr->literal_index()));
|
975
1306
|
__ Push(expr->constant_elements());
|
976
1307
|
if (expr->depth() > 1) {
|
977
1308
|
__ CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
978
|
-
} else {
|
1309
|
+
} else if (length > FastCloneShallowArrayStub::kMaximumLength) {
|
979
1310
|
__ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
|
1311
|
+
} else {
|
1312
|
+
FastCloneShallowArrayStub stub(length);
|
1313
|
+
__ CallStub(&stub);
|
980
1314
|
}
|
981
1315
|
|
982
1316
|
bool result_saved = false; // Is the result saved to the stack?
|
983
1317
|
|
984
1318
|
// Emit code to evaluate all the non-constant subexpressions and to store
|
985
1319
|
// them into the newly cloned array.
|
986
|
-
|
987
|
-
for (int i = 0, len = subexprs->length(); i < len; i++) {
|
1320
|
+
for (int i = 0; i < length; i++) {
|
988
1321
|
Expression* subexpr = subexprs->at(i);
|
989
1322
|
// If the subexpression is a literal or a simple materialized literal it
|
990
1323
|
// is already set in the cloned array.
|
@@ -1019,7 +1352,13 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
|
1019
1352
|
|
1020
1353
|
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
1021
1354
|
Comment cmnt(masm_, "[ Assignment");
|
1022
|
-
|
1355
|
+
// Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
|
1356
|
+
// on the left-hand side.
|
1357
|
+
if (!expr->target()->IsValidLeftHandSide()) {
|
1358
|
+
VisitForEffect(expr->target());
|
1359
|
+
return;
|
1360
|
+
}
|
1361
|
+
|
1023
1362
|
// Left-hand side can only be a property, a global or a (parameter or local)
|
1024
1363
|
// slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
|
1025
1364
|
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
|
@@ -1045,8 +1384,15 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
1045
1384
|
}
|
1046
1385
|
break;
|
1047
1386
|
case KEYED_PROPERTY:
|
1048
|
-
|
1049
|
-
|
1387
|
+
if (expr->is_compound()) {
|
1388
|
+
VisitForValue(prop->obj(), kStack);
|
1389
|
+
VisitForValue(prop->key(), kAccumulator);
|
1390
|
+
__ movq(rdx, Operand(rsp, 0));
|
1391
|
+
__ push(rax);
|
1392
|
+
} else {
|
1393
|
+
VisitForValue(prop->obj(), kStack);
|
1394
|
+
VisitForValue(prop->key(), kStack);
|
1395
|
+
}
|
1050
1396
|
break;
|
1051
1397
|
}
|
1052
1398
|
|
@@ -1091,6 +1437,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
1091
1437
|
switch (assign_type) {
|
1092
1438
|
case VARIABLE:
|
1093
1439
|
EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
|
1440
|
+
expr->op(),
|
1094
1441
|
context_);
|
1095
1442
|
break;
|
1096
1443
|
case NAMED_PROPERTY:
|
@@ -1132,61 +1479,131 @@ void FullCodeGenerator::EmitBinaryOp(Token::Value op,
|
|
1132
1479
|
}
|
1133
1480
|
|
1134
1481
|
|
1482
|
+
void FullCodeGenerator::EmitAssignment(Expression* expr) {
|
1483
|
+
// Invalid left-hand sides are rewritten to have a 'throw
|
1484
|
+
// ReferenceError' on the left-hand side.
|
1485
|
+
if (!expr->IsValidLeftHandSide()) {
|
1486
|
+
VisitForEffect(expr);
|
1487
|
+
return;
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
// Left-hand side can only be a property, a global or a (parameter or local)
|
1491
|
+
// slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
|
1492
|
+
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
|
1493
|
+
LhsKind assign_type = VARIABLE;
|
1494
|
+
Property* prop = expr->AsProperty();
|
1495
|
+
if (prop != NULL) {
|
1496
|
+
assign_type = (prop->key()->IsPropertyName())
|
1497
|
+
? NAMED_PROPERTY
|
1498
|
+
: KEYED_PROPERTY;
|
1499
|
+
}
|
1500
|
+
|
1501
|
+
switch (assign_type) {
|
1502
|
+
case VARIABLE: {
|
1503
|
+
Variable* var = expr->AsVariableProxy()->var();
|
1504
|
+
EmitVariableAssignment(var, Token::ASSIGN, Expression::kEffect);
|
1505
|
+
break;
|
1506
|
+
}
|
1507
|
+
case NAMED_PROPERTY: {
|
1508
|
+
__ push(rax); // Preserve value.
|
1509
|
+
VisitForValue(prop->obj(), kAccumulator);
|
1510
|
+
__ movq(rdx, rax);
|
1511
|
+
__ pop(rax); // Restore value.
|
1512
|
+
__ Move(rcx, prop->key()->AsLiteral()->handle());
|
1513
|
+
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
1514
|
+
__ call(ic, RelocInfo::CODE_TARGET);
|
1515
|
+
__ nop(); // Signal no inlined code.
|
1516
|
+
break;
|
1517
|
+
}
|
1518
|
+
case KEYED_PROPERTY: {
|
1519
|
+
__ push(rax); // Preserve value.
|
1520
|
+
VisitForValue(prop->obj(), kStack);
|
1521
|
+
VisitForValue(prop->key(), kAccumulator);
|
1522
|
+
__ movq(rcx, rax);
|
1523
|
+
__ pop(rdx);
|
1524
|
+
__ pop(rax);
|
1525
|
+
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
1526
|
+
__ call(ic, RelocInfo::CODE_TARGET);
|
1527
|
+
__ nop(); // Signal no inlined code.
|
1528
|
+
break;
|
1529
|
+
}
|
1530
|
+
}
|
1531
|
+
}
|
1532
|
+
|
1533
|
+
|
1135
1534
|
void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
1535
|
+
Token::Value op,
|
1136
1536
|
Expression::Context context) {
|
1137
|
-
//
|
1138
|
-
//
|
1139
|
-
// to explicit property accesses do not reach here.
|
1537
|
+
// Left-hand sides that rewrite to explicit property accesses do not reach
|
1538
|
+
// here.
|
1140
1539
|
ASSERT(var != NULL);
|
1141
1540
|
ASSERT(var->is_global() || var->slot() != NULL);
|
1142
|
-
|
1541
|
+
|
1143
1542
|
if (var->is_global()) {
|
1144
1543
|
ASSERT(!var->is_this());
|
1145
1544
|
// Assignment to a global variable. Use inline caching for the
|
1146
1545
|
// assignment. Right-hand-side value is passed in rax, variable name in
|
1147
|
-
// rcx, and the global object
|
1546
|
+
// rcx, and the global object on the stack.
|
1148
1547
|
__ Move(rcx, var->name());
|
1149
1548
|
__ movq(rdx, CodeGenerator::GlobalObject());
|
1150
1549
|
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
1151
1550
|
__ Call(ic, RelocInfo::CODE_TARGET);
|
1152
|
-
|
1153
|
-
|
1154
|
-
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
|
1155
|
-
__ push(result_register()); // Value.
|
1156
|
-
__ push(rsi); // Context.
|
1157
|
-
__ Push(var->name());
|
1158
|
-
__ CallRuntime(Runtime::kStoreContextSlot, 3);
|
1159
|
-
Apply(context, rax);
|
1551
|
+
__ nop();
|
1160
1552
|
|
1161
|
-
} else if (var->
|
1553
|
+
} else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
|
1554
|
+
// Perform the assignment for non-const variables and for initialization
|
1555
|
+
// of const variables. Const assignments are simply skipped.
|
1556
|
+
Label done;
|
1557
|
+
Slot* slot = var->slot();
|
1162
1558
|
switch (slot->type()) {
|
1163
|
-
case Slot::LOCAL:
|
1164
1559
|
case Slot::PARAMETER:
|
1165
|
-
|
1560
|
+
case Slot::LOCAL:
|
1561
|
+
if (op == Token::INIT_CONST) {
|
1562
|
+
// Detect const reinitialization by checking for the hole value.
|
1563
|
+
__ movq(rdx, Operand(rbp, SlotOffset(slot)));
|
1564
|
+
__ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
|
1565
|
+
__ j(not_equal, &done);
|
1566
|
+
}
|
1567
|
+
// Perform the assignment.
|
1568
|
+
__ movq(Operand(rbp, SlotOffset(slot)), rax);
|
1166
1569
|
break;
|
1167
1570
|
|
1168
1571
|
case Slot::CONTEXT: {
|
1169
1572
|
MemOperand target = EmitSlotSearch(slot, rcx);
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1573
|
+
if (op == Token::INIT_CONST) {
|
1574
|
+
// Detect const reinitialization by checking for the hole value.
|
1575
|
+
__ movq(rdx, target);
|
1576
|
+
__ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
|
1577
|
+
__ j(not_equal, &done);
|
1578
|
+
}
|
1579
|
+
// Perform the assignment and issue the write barrier.
|
1580
|
+
__ movq(target, rax);
|
1581
|
+
// The value of the assignment is in rax. RecordWrite clobbers its
|
1582
|
+
// register arguments.
|
1583
|
+
__ movq(rdx, rax);
|
1174
1584
|
int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
|
1175
1585
|
__ RecordWrite(rcx, offset, rdx, rbx);
|
1176
1586
|
break;
|
1177
1587
|
}
|
1178
1588
|
|
1179
1589
|
case Slot::LOOKUP:
|
1180
|
-
|
1590
|
+
// Call the runtime for the assignment. The runtime will ignore
|
1591
|
+
// const reinitialization.
|
1592
|
+
__ push(rax); // Value.
|
1593
|
+
__ push(rsi); // Context.
|
1594
|
+
__ Push(var->name());
|
1595
|
+
if (op == Token::INIT_CONST) {
|
1596
|
+
// The runtime will ignore const redeclaration.
|
1597
|
+
__ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
|
1598
|
+
} else {
|
1599
|
+
__ CallRuntime(Runtime::kStoreContextSlot, 3);
|
1600
|
+
}
|
1181
1601
|
break;
|
1182
1602
|
}
|
1183
|
-
|
1184
|
-
|
1185
|
-
} else {
|
1186
|
-
// Variables rewritten as properties are not treated as variables in
|
1187
|
-
// assignments.
|
1188
|
-
UNREACHABLE();
|
1603
|
+
__ bind(&done);
|
1189
1604
|
}
|
1605
|
+
|
1606
|
+
Apply(context, rax);
|
1190
1607
|
}
|
1191
1608
|
|
1192
1609
|
|
@@ -1245,6 +1662,12 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
|
1245
1662
|
__ pop(result_register());
|
1246
1663
|
}
|
1247
1664
|
|
1665
|
+
__ pop(rcx);
|
1666
|
+
if (expr->ends_initialization_block()) {
|
1667
|
+
__ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
|
1668
|
+
} else {
|
1669
|
+
__ pop(rdx);
|
1670
|
+
}
|
1248
1671
|
// Record source code position before IC call.
|
1249
1672
|
SetSourcePosition(expr->position());
|
1250
1673
|
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
@@ -1255,15 +1678,14 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
|
1255
1678
|
|
1256
1679
|
// If the assignment ends an initialization block, revert to fast case.
|
1257
1680
|
if (expr->ends_initialization_block()) {
|
1681
|
+
__ pop(rdx);
|
1258
1682
|
__ push(rax); // Result of assignment, saved even if not needed.
|
1259
|
-
|
1260
|
-
__ push(Operand(rsp, 2 * kPointerSize));
|
1683
|
+
__ push(rdx);
|
1261
1684
|
__ CallRuntime(Runtime::kToFastProperties, 1);
|
1262
1685
|
__ pop(rax);
|
1263
1686
|
}
|
1264
1687
|
|
1265
|
-
|
1266
|
-
DropAndApply(2, context_, rax);
|
1688
|
+
Apply(context_, rax);
|
1267
1689
|
}
|
1268
1690
|
|
1269
1691
|
|
@@ -1271,18 +1693,16 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
|
|
1271
1693
|
Comment cmnt(masm_, "[ Property");
|
1272
1694
|
Expression* key = expr->key();
|
1273
1695
|
|
1274
|
-
// Evaluate receiver.
|
1275
|
-
VisitForValue(expr->obj(), kStack);
|
1276
|
-
|
1277
1696
|
if (key->IsPropertyName()) {
|
1697
|
+
VisitForValue(expr->obj(), kAccumulator);
|
1278
1698
|
EmitNamedPropertyLoad(expr);
|
1279
|
-
|
1280
|
-
DropAndApply(1, context_, rax);
|
1699
|
+
Apply(context_, rax);
|
1281
1700
|
} else {
|
1282
|
-
VisitForValue(expr->
|
1701
|
+
VisitForValue(expr->obj(), kStack);
|
1702
|
+
VisitForValue(expr->key(), kAccumulator);
|
1703
|
+
__ pop(rdx);
|
1283
1704
|
EmitKeyedPropertyLoad(expr);
|
1284
|
-
|
1285
|
-
DropAndApply(2, context_, rax);
|
1705
|
+
Apply(context_, rax);
|
1286
1706
|
}
|
1287
1707
|
}
|
1288
1708
|
|
@@ -1310,6 +1730,30 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
|
1310
1730
|
}
|
1311
1731
|
|
1312
1732
|
|
1733
|
+
void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
1734
|
+
Expression* key,
|
1735
|
+
RelocInfo::Mode mode) {
|
1736
|
+
// Code common for calls using the IC.
|
1737
|
+
ZoneList<Expression*>* args = expr->arguments();
|
1738
|
+
int arg_count = args->length();
|
1739
|
+
for (int i = 0; i < arg_count; i++) {
|
1740
|
+
VisitForValue(args->at(i), kStack);
|
1741
|
+
}
|
1742
|
+
VisitForValue(key, kAccumulator);
|
1743
|
+
__ movq(rcx, rax);
|
1744
|
+
// Record source position for debugger.
|
1745
|
+
SetSourcePosition(expr->position());
|
1746
|
+
// Call the IC initialization code.
|
1747
|
+
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
1748
|
+
Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
|
1749
|
+
in_loop);
|
1750
|
+
__ Call(ic, mode);
|
1751
|
+
// Restore context register.
|
1752
|
+
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
1753
|
+
Apply(context_, rax);
|
1754
|
+
}
|
1755
|
+
|
1756
|
+
|
1313
1757
|
void FullCodeGenerator::EmitCallWithStub(Call* expr) {
|
1314
1758
|
// Code common for calls using the call stub.
|
1315
1759
|
ZoneList<Expression*>* args = expr->arguments();
|
@@ -1319,7 +1763,8 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
|
|
1319
1763
|
}
|
1320
1764
|
// Record source position for debugger.
|
1321
1765
|
SetSourcePosition(expr->position());
|
1322
|
-
|
1766
|
+
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
1767
|
+
CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
|
1323
1768
|
__ CallStub(&stub);
|
1324
1769
|
// Restore context register.
|
1325
1770
|
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
@@ -1334,8 +1779,47 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
1334
1779
|
Variable* var = fun->AsVariableProxy()->AsVariable();
|
1335
1780
|
|
1336
1781
|
if (var != NULL && var->is_possibly_eval()) {
|
1337
|
-
//
|
1338
|
-
|
1782
|
+
// In a call to eval, we first call %ResolvePossiblyDirectEval to
|
1783
|
+
// resolve the function we need to call and the receiver of the
|
1784
|
+
// call. The we call the resolved function using the given
|
1785
|
+
// arguments.
|
1786
|
+
VisitForValue(fun, kStack);
|
1787
|
+
__ PushRoot(Heap::kUndefinedValueRootIndex); // Reserved receiver slot.
|
1788
|
+
|
1789
|
+
// Push the arguments.
|
1790
|
+
ZoneList<Expression*>* args = expr->arguments();
|
1791
|
+
int arg_count = args->length();
|
1792
|
+
for (int i = 0; i < arg_count; i++) {
|
1793
|
+
VisitForValue(args->at(i), kStack);
|
1794
|
+
}
|
1795
|
+
|
1796
|
+
// Push copy of the function - found below the arguments.
|
1797
|
+
__ push(Operand(rsp, (arg_count + 1) * kPointerSize));
|
1798
|
+
|
1799
|
+
// Push copy of the first argument or undefined if it doesn't exist.
|
1800
|
+
if (arg_count > 0) {
|
1801
|
+
__ push(Operand(rsp, arg_count * kPointerSize));
|
1802
|
+
} else {
|
1803
|
+
__ PushRoot(Heap::kUndefinedValueRootIndex);
|
1804
|
+
}
|
1805
|
+
|
1806
|
+
// Push the receiver of the enclosing function and do runtime call.
|
1807
|
+
__ push(Operand(rbp, (2 + scope()->num_parameters()) * kPointerSize));
|
1808
|
+
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
|
1809
|
+
|
1810
|
+
// The runtime call returns a pair of values in rax (function) and
|
1811
|
+
// rdx (receiver). Touch up the stack with the right values.
|
1812
|
+
__ movq(Operand(rsp, (arg_count + 0) * kPointerSize), rdx);
|
1813
|
+
__ movq(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
|
1814
|
+
|
1815
|
+
// Record source position for debugger.
|
1816
|
+
SetSourcePosition(expr->position());
|
1817
|
+
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
1818
|
+
CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
|
1819
|
+
__ CallStub(&stub);
|
1820
|
+
// Restore context register.
|
1821
|
+
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
1822
|
+
DropAndApply(1, context_, rax);
|
1339
1823
|
} else if (var != NULL && !var->is_this() && var->is_global()) {
|
1340
1824
|
// Call to a global variable.
|
1341
1825
|
// Push global object as receiver for the call IC lookup.
|
@@ -1343,8 +1827,15 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
1343
1827
|
EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
|
1344
1828
|
} else if (var != NULL && var->slot() != NULL &&
|
1345
1829
|
var->slot()->type() == Slot::LOOKUP) {
|
1346
|
-
// Call to a lookup slot.
|
1347
|
-
|
1830
|
+
// Call to a lookup slot (dynamically introduced variable). Call
|
1831
|
+
// the runtime to find the function to call (returned in rax) and
|
1832
|
+
// the object holding it (returned in rdx).
|
1833
|
+
__ push(context_register());
|
1834
|
+
__ Push(var->name());
|
1835
|
+
__ CallRuntime(Runtime::kLoadContextSlot, 2);
|
1836
|
+
__ push(rax); // Function.
|
1837
|
+
__ push(rdx); // Receiver.
|
1838
|
+
EmitCallWithStub(expr);
|
1348
1839
|
} else if (fun->AsProperty() != NULL) {
|
1349
1840
|
// Call to an object property.
|
1350
1841
|
Property* prop = fun->AsProperty();
|
@@ -1354,31 +1845,32 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
1354
1845
|
VisitForValue(prop->obj(), kStack);
|
1355
1846
|
EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
|
1356
1847
|
} else {
|
1357
|
-
// Call to a keyed property
|
1358
|
-
// call
|
1848
|
+
// Call to a keyed property.
|
1849
|
+
// For a synthetic property use keyed load IC followed by function call,
|
1850
|
+
// for a regular property use KeyedCallIC.
|
1359
1851
|
VisitForValue(prop->obj(), kStack);
|
1360
|
-
VisitForValue(prop->key(), kStack);
|
1361
|
-
// Record source code position for IC call.
|
1362
|
-
SetSourcePosition(prop->position());
|
1363
|
-
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
1364
|
-
__ call(ic, RelocInfo::CODE_TARGET);
|
1365
|
-
// By emitting a nop we make sure that we do not have a "test rax,..."
|
1366
|
-
// instruction after the call it is treated specially by the LoadIC code.
|
1367
|
-
__ nop();
|
1368
|
-
// Drop key left on the stack by IC.
|
1369
|
-
__ Drop(1);
|
1370
|
-
// Pop receiver.
|
1371
|
-
__ pop(rbx);
|
1372
|
-
// Push result (function).
|
1373
|
-
__ push(rax);
|
1374
|
-
// Push receiver object on stack.
|
1375
1852
|
if (prop->is_synthetic()) {
|
1853
|
+
VisitForValue(prop->key(), kAccumulator);
|
1854
|
+
__ movq(rdx, Operand(rsp, 0));
|
1855
|
+
// Record source code position for IC call.
|
1856
|
+
SetSourcePosition(prop->position());
|
1857
|
+
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
|
1858
|
+
__ call(ic, RelocInfo::CODE_TARGET);
|
1859
|
+
// By emitting a nop we make sure that we do not have a "test rax,..."
|
1860
|
+
// instruction after the call as it is treated specially
|
1861
|
+
// by the LoadIC code.
|
1862
|
+
__ nop();
|
1863
|
+
// Pop receiver.
|
1864
|
+
__ pop(rbx);
|
1865
|
+
// Push result (function).
|
1866
|
+
__ push(rax);
|
1867
|
+
// Push receiver object on stack.
|
1376
1868
|
__ movq(rcx, CodeGenerator::GlobalObject());
|
1377
1869
|
__ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
|
1870
|
+
EmitCallWithStub(expr);
|
1378
1871
|
} else {
|
1379
|
-
|
1872
|
+
EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
|
1380
1873
|
}
|
1381
|
-
EmitCallWithStub(expr);
|
1382
1874
|
}
|
1383
1875
|
} else {
|
1384
1876
|
// Call to some other expression. If the expression is an anonymous
|
@@ -1435,39 +1927,803 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
|
1435
1927
|
}
|
1436
1928
|
|
1437
1929
|
|
1438
|
-
void FullCodeGenerator::
|
1439
|
-
|
1440
|
-
ZoneList<Expression*>* args = expr->arguments();
|
1930
|
+
void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
|
1931
|
+
ASSERT(args->length() == 1);
|
1441
1932
|
|
1442
|
-
|
1443
|
-
// Prepare for calling JS runtime function.
|
1444
|
-
__ movq(rax, CodeGenerator::GlobalObject());
|
1445
|
-
__ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
|
1446
|
-
}
|
1933
|
+
VisitForValue(args->at(0), kAccumulator);
|
1447
1934
|
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
}
|
1935
|
+
Label materialize_true, materialize_false;
|
1936
|
+
Label* if_true = NULL;
|
1937
|
+
Label* if_false = NULL;
|
1938
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
1453
1939
|
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
|
1459
|
-
__ call(ic, RelocInfo::CODE_TARGET);
|
1460
|
-
// Restore context register.
|
1461
|
-
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
1462
|
-
} else {
|
1463
|
-
__ CallRuntime(expr->function(), arg_count);
|
1464
|
-
}
|
1465
|
-
Apply(context_, rax);
|
1940
|
+
__ JumpIfSmi(rax, if_true);
|
1941
|
+
__ jmp(if_false);
|
1942
|
+
|
1943
|
+
Apply(context_, if_true, if_false);
|
1466
1944
|
}
|
1467
1945
|
|
1468
1946
|
|
1469
|
-
void FullCodeGenerator::
|
1470
|
-
|
1947
|
+
void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) {
|
1948
|
+
ASSERT(args->length() == 1);
|
1949
|
+
|
1950
|
+
VisitForValue(args->at(0), kAccumulator);
|
1951
|
+
|
1952
|
+
Label materialize_true, materialize_false;
|
1953
|
+
Label* if_true = NULL;
|
1954
|
+
Label* if_false = NULL;
|
1955
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
1956
|
+
|
1957
|
+
Condition positive_smi = __ CheckPositiveSmi(rax);
|
1958
|
+
__ j(positive_smi, if_true);
|
1959
|
+
__ jmp(if_false);
|
1960
|
+
|
1961
|
+
Apply(context_, if_true, if_false);
|
1962
|
+
}
|
1963
|
+
|
1964
|
+
|
1965
|
+
void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
|
1966
|
+
ASSERT(args->length() == 1);
|
1967
|
+
|
1968
|
+
VisitForValue(args->at(0), kAccumulator);
|
1969
|
+
|
1970
|
+
Label materialize_true, materialize_false;
|
1971
|
+
Label* if_true = NULL;
|
1972
|
+
Label* if_false = NULL;
|
1973
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
1974
|
+
|
1975
|
+
__ JumpIfSmi(rax, if_false);
|
1976
|
+
__ CompareRoot(rax, Heap::kNullValueRootIndex);
|
1977
|
+
__ j(equal, if_true);
|
1978
|
+
__ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
|
1979
|
+
// Undetectable objects behave like undefined when tested with typeof.
|
1980
|
+
__ testb(FieldOperand(rbx, Map::kBitFieldOffset),
|
1981
|
+
Immediate(1 << Map::kIsUndetectable));
|
1982
|
+
__ j(not_zero, if_false);
|
1983
|
+
__ movzxbq(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
|
1984
|
+
__ cmpq(rbx, Immediate(FIRST_JS_OBJECT_TYPE));
|
1985
|
+
__ j(below, if_false);
|
1986
|
+
__ cmpq(rbx, Immediate(LAST_JS_OBJECT_TYPE));
|
1987
|
+
__ j(below_equal, if_true);
|
1988
|
+
__ jmp(if_false);
|
1989
|
+
|
1990
|
+
Apply(context_, if_true, if_false);
|
1991
|
+
}
|
1992
|
+
|
1993
|
+
|
1994
|
+
void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
|
1995
|
+
ASSERT(args->length() == 1);
|
1996
|
+
|
1997
|
+
VisitForValue(args->at(0), kAccumulator);
|
1998
|
+
|
1999
|
+
Label materialize_true, materialize_false;
|
2000
|
+
Label* if_true = NULL;
|
2001
|
+
Label* if_false = NULL;
|
2002
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
2003
|
+
|
2004
|
+
__ JumpIfSmi(rax, if_false);
|
2005
|
+
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
|
2006
|
+
__ j(above_equal, if_true);
|
2007
|
+
__ jmp(if_false);
|
2008
|
+
|
2009
|
+
Apply(context_, if_true, if_false);
|
2010
|
+
}
|
2011
|
+
|
2012
|
+
|
2013
|
+
void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
|
2014
|
+
ASSERT(args->length() == 1);
|
2015
|
+
|
2016
|
+
VisitForValue(args->at(0), kAccumulator);
|
2017
|
+
|
2018
|
+
Label materialize_true, materialize_false;
|
2019
|
+
Label* if_true = NULL;
|
2020
|
+
Label* if_false = NULL;
|
2021
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
2022
|
+
|
2023
|
+
__ JumpIfSmi(rax, if_false);
|
2024
|
+
__ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
|
2025
|
+
__ testb(FieldOperand(rbx, Map::kBitFieldOffset),
|
2026
|
+
Immediate(1 << Map::kIsUndetectable));
|
2027
|
+
__ j(not_zero, if_true);
|
2028
|
+
__ jmp(if_false);
|
2029
|
+
|
2030
|
+
Apply(context_, if_true, if_false);
|
2031
|
+
}
|
2032
|
+
|
2033
|
+
|
2034
|
+
void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
|
2035
|
+
ASSERT(args->length() == 1);
|
2036
|
+
|
2037
|
+
VisitForValue(args->at(0), kAccumulator);
|
2038
|
+
|
2039
|
+
Label materialize_true, materialize_false;
|
2040
|
+
Label* if_true = NULL;
|
2041
|
+
Label* if_false = NULL;
|
2042
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
2043
|
+
|
2044
|
+
__ JumpIfSmi(rax, if_false);
|
2045
|
+
__ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
|
2046
|
+
__ j(equal, if_true);
|
2047
|
+
__ jmp(if_false);
|
2048
|
+
|
2049
|
+
Apply(context_, if_true, if_false);
|
2050
|
+
}
|
2051
|
+
|
2052
|
+
|
2053
|
+
void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
|
2054
|
+
ASSERT(args->length() == 1);
|
2055
|
+
|
2056
|
+
VisitForValue(args->at(0), kAccumulator);
|
2057
|
+
|
2058
|
+
Label materialize_true, materialize_false;
|
2059
|
+
Label* if_true = NULL;
|
2060
|
+
Label* if_false = NULL;
|
2061
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
2062
|
+
|
2063
|
+
__ JumpIfSmi(rax, if_false);
|
2064
|
+
__ CmpObjectType(rax, JS_ARRAY_TYPE, rbx);
|
2065
|
+
__ j(equal, if_true);
|
2066
|
+
__ jmp(if_false);
|
2067
|
+
|
2068
|
+
Apply(context_, if_true, if_false);
|
2069
|
+
}
|
2070
|
+
|
2071
|
+
|
2072
|
+
void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
|
2073
|
+
ASSERT(args->length() == 1);
|
2074
|
+
|
2075
|
+
VisitForValue(args->at(0), kAccumulator);
|
2076
|
+
|
2077
|
+
Label materialize_true, materialize_false;
|
2078
|
+
Label* if_true = NULL;
|
2079
|
+
Label* if_false = NULL;
|
2080
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
2081
|
+
|
2082
|
+
__ JumpIfSmi(rax, if_false);
|
2083
|
+
__ CmpObjectType(rax, JS_REGEXP_TYPE, rbx);
|
2084
|
+
__ j(equal, if_true);
|
2085
|
+
__ jmp(if_false);
|
2086
|
+
|
2087
|
+
Apply(context_, if_true, if_false);
|
2088
|
+
}
|
2089
|
+
|
2090
|
+
|
2091
|
+
|
2092
|
+
void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
|
2093
|
+
ASSERT(args->length() == 0);
|
2094
|
+
|
2095
|
+
Label materialize_true, materialize_false;
|
2096
|
+
Label* if_true = NULL;
|
2097
|
+
Label* if_false = NULL;
|
2098
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
2099
|
+
|
2100
|
+
// Get the frame pointer for the calling frame.
|
2101
|
+
__ movq(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
2102
|
+
|
2103
|
+
// Skip the arguments adaptor frame if it exists.
|
2104
|
+
Label check_frame_marker;
|
2105
|
+
__ SmiCompare(Operand(rax, StandardFrameConstants::kContextOffset),
|
2106
|
+
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
2107
|
+
__ j(not_equal, &check_frame_marker);
|
2108
|
+
__ movq(rax, Operand(rax, StandardFrameConstants::kCallerFPOffset));
|
2109
|
+
|
2110
|
+
// Check the marker in the calling frame.
|
2111
|
+
__ bind(&check_frame_marker);
|
2112
|
+
__ SmiCompare(Operand(rax, StandardFrameConstants::kMarkerOffset),
|
2113
|
+
Smi::FromInt(StackFrame::CONSTRUCT));
|
2114
|
+
__ j(equal, if_true);
|
2115
|
+
__ jmp(if_false);
|
2116
|
+
|
2117
|
+
Apply(context_, if_true, if_false);
|
2118
|
+
}
|
2119
|
+
|
2120
|
+
|
2121
|
+
void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) {
|
2122
|
+
ASSERT(args->length() == 2);
|
2123
|
+
|
2124
|
+
// Load the two objects into registers and perform the comparison.
|
2125
|
+
VisitForValue(args->at(0), kStack);
|
2126
|
+
VisitForValue(args->at(1), kAccumulator);
|
2127
|
+
|
2128
|
+
Label materialize_true, materialize_false;
|
2129
|
+
Label* if_true = NULL;
|
2130
|
+
Label* if_false = NULL;
|
2131
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
2132
|
+
|
2133
|
+
__ pop(rbx);
|
2134
|
+
__ cmpq(rax, rbx);
|
2135
|
+
__ j(equal, if_true);
|
2136
|
+
__ jmp(if_false);
|
2137
|
+
|
2138
|
+
Apply(context_, if_true, if_false);
|
2139
|
+
}
|
2140
|
+
|
2141
|
+
|
2142
|
+
void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) {
|
2143
|
+
ASSERT(args->length() == 1);
|
2144
|
+
|
2145
|
+
// ArgumentsAccessStub expects the key in edx and the formal
|
2146
|
+
// parameter count in eax.
|
2147
|
+
VisitForValue(args->at(0), kAccumulator);
|
2148
|
+
__ movq(rdx, rax);
|
2149
|
+
__ Move(rax, Smi::FromInt(scope()->num_parameters()));
|
2150
|
+
ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
|
2151
|
+
__ CallStub(&stub);
|
2152
|
+
Apply(context_, rax);
|
2153
|
+
}
|
2154
|
+
|
2155
|
+
|
2156
|
+
void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) {
|
2157
|
+
ASSERT(args->length() == 0);
|
2158
|
+
|
2159
|
+
Label exit;
|
2160
|
+
// Get the number of formal parameters.
|
2161
|
+
__ Move(rax, Smi::FromInt(scope()->num_parameters()));
|
2162
|
+
|
2163
|
+
// Check if the calling frame is an arguments adaptor frame.
|
2164
|
+
__ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
2165
|
+
__ SmiCompare(Operand(rbx, StandardFrameConstants::kContextOffset),
|
2166
|
+
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
2167
|
+
__ j(not_equal, &exit);
|
2168
|
+
|
2169
|
+
// Arguments adaptor case: Read the arguments length from the
|
2170
|
+
// adaptor frame.
|
2171
|
+
__ movq(rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
2172
|
+
|
2173
|
+
__ bind(&exit);
|
2174
|
+
if (FLAG_debug_code) __ AbortIfNotSmi(rax);
|
2175
|
+
Apply(context_, rax);
|
2176
|
+
}
|
2177
|
+
|
2178
|
+
|
2179
|
+
void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
|
2180
|
+
ASSERT(args->length() == 1);
|
2181
|
+
Label done, null, function, non_function_constructor;
|
2182
|
+
|
2183
|
+
VisitForValue(args->at(0), kAccumulator);
|
2184
|
+
|
2185
|
+
// If the object is a smi, we return null.
|
2186
|
+
__ JumpIfSmi(rax, &null);
|
2187
|
+
|
2188
|
+
// Check that the object is a JS object but take special care of JS
|
2189
|
+
// functions to make sure they have 'Function' as their class.
|
2190
|
+
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax); // Map is now in rax.
|
2191
|
+
__ j(below, &null);
|
2192
|
+
|
2193
|
+
// As long as JS_FUNCTION_TYPE is the last instance type and it is
|
2194
|
+
// right after LAST_JS_OBJECT_TYPE, we can avoid checking for
|
2195
|
+
// LAST_JS_OBJECT_TYPE.
|
2196
|
+
ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
|
2197
|
+
ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
|
2198
|
+
__ CmpInstanceType(rax, JS_FUNCTION_TYPE);
|
2199
|
+
__ j(equal, &function);
|
2200
|
+
|
2201
|
+
// Check if the constructor in the map is a function.
|
2202
|
+
__ movq(rax, FieldOperand(rax, Map::kConstructorOffset));
|
2203
|
+
__ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
|
2204
|
+
__ j(not_equal, &non_function_constructor);
|
2205
|
+
|
2206
|
+
// rax now contains the constructor function. Grab the
|
2207
|
+
// instance class name from there.
|
2208
|
+
__ movq(rax, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset));
|
2209
|
+
__ movq(rax, FieldOperand(rax, SharedFunctionInfo::kInstanceClassNameOffset));
|
2210
|
+
__ jmp(&done);
|
2211
|
+
|
2212
|
+
// Functions have class 'Function'.
|
2213
|
+
__ bind(&function);
|
2214
|
+
__ Move(rax, Factory::function_class_symbol());
|
2215
|
+
__ jmp(&done);
|
2216
|
+
|
2217
|
+
// Objects with a non-function constructor have class 'Object'.
|
2218
|
+
__ bind(&non_function_constructor);
|
2219
|
+
__ Move(rax, Factory::Object_symbol());
|
2220
|
+
__ jmp(&done);
|
2221
|
+
|
2222
|
+
// Non-JS objects have class null.
|
2223
|
+
__ bind(&null);
|
2224
|
+
__ LoadRoot(rax, Heap::kNullValueRootIndex);
|
2225
|
+
|
2226
|
+
// All done.
|
2227
|
+
__ bind(&done);
|
2228
|
+
|
2229
|
+
Apply(context_, rax);
|
2230
|
+
}
|
2231
|
+
|
2232
|
+
|
2233
|
+
void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
|
2234
|
+
// Conditionally generate a log call.
|
2235
|
+
// Args:
|
2236
|
+
// 0 (literal string): The type of logging (corresponds to the flags).
|
2237
|
+
// This is used to determine whether or not to generate the log call.
|
2238
|
+
// 1 (string): Format string. Access the string at argument index 2
|
2239
|
+
// with '%2s' (see Logger::LogRuntime for all the formats).
|
2240
|
+
// 2 (array): Arguments to the format string.
|
2241
|
+
ASSERT_EQ(args->length(), 3);
|
2242
|
+
#ifdef ENABLE_LOGGING_AND_PROFILING
|
2243
|
+
if (CodeGenerator::ShouldGenerateLog(args->at(0))) {
|
2244
|
+
VisitForValue(args->at(1), kStack);
|
2245
|
+
VisitForValue(args->at(2), kStack);
|
2246
|
+
__ CallRuntime(Runtime::kLog, 2);
|
2247
|
+
}
|
2248
|
+
#endif
|
2249
|
+
// Finally, we're expected to leave a value on the top of the stack.
|
2250
|
+
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
2251
|
+
Apply(context_, rax);
|
2252
|
+
}
|
2253
|
+
|
2254
|
+
|
2255
|
+
void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
|
2256
|
+
ASSERT(args->length() == 0);
|
2257
|
+
|
2258
|
+
Label slow_allocate_heapnumber;
|
2259
|
+
Label heapnumber_allocated;
|
2260
|
+
|
2261
|
+
__ AllocateHeapNumber(rbx, rcx, &slow_allocate_heapnumber);
|
2262
|
+
__ jmp(&heapnumber_allocated);
|
2263
|
+
|
2264
|
+
__ bind(&slow_allocate_heapnumber);
|
2265
|
+
// Allocate a heap number.
|
2266
|
+
__ CallRuntime(Runtime::kNumberAlloc, 0);
|
2267
|
+
__ movq(rbx, rax);
|
2268
|
+
|
2269
|
+
__ bind(&heapnumber_allocated);
|
2270
|
+
|
2271
|
+
// Return a random uint32 number in rax.
|
2272
|
+
// The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs.
|
2273
|
+
__ PrepareCallCFunction(0);
|
2274
|
+
__ CallCFunction(ExternalReference::random_uint32_function(), 0);
|
2275
|
+
|
2276
|
+
// Convert 32 random bits in rax to 0.(32 random bits) in a double
|
2277
|
+
// by computing:
|
2278
|
+
// ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
|
2279
|
+
__ movl(rcx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
|
2280
|
+
__ movd(xmm1, rcx);
|
2281
|
+
__ movd(xmm0, rax);
|
2282
|
+
__ cvtss2sd(xmm1, xmm1);
|
2283
|
+
__ xorpd(xmm0, xmm1);
|
2284
|
+
__ subsd(xmm0, xmm1);
|
2285
|
+
__ movsd(FieldOperand(rbx, HeapNumber::kValueOffset), xmm0);
|
2286
|
+
|
2287
|
+
__ movq(rax, rbx);
|
2288
|
+
Apply(context_, rax);
|
2289
|
+
}
|
2290
|
+
|
2291
|
+
|
2292
|
+
void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
|
2293
|
+
// Load the arguments on the stack and call the stub.
|
2294
|
+
SubStringStub stub;
|
2295
|
+
ASSERT(args->length() == 3);
|
2296
|
+
VisitForValue(args->at(0), kStack);
|
2297
|
+
VisitForValue(args->at(1), kStack);
|
2298
|
+
VisitForValue(args->at(2), kStack);
|
2299
|
+
__ CallStub(&stub);
|
2300
|
+
Apply(context_, rax);
|
2301
|
+
}
|
2302
|
+
|
2303
|
+
|
2304
|
+
void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) {
|
2305
|
+
// Load the arguments on the stack and call the stub.
|
2306
|
+
RegExpExecStub stub;
|
2307
|
+
ASSERT(args->length() == 4);
|
2308
|
+
VisitForValue(args->at(0), kStack);
|
2309
|
+
VisitForValue(args->at(1), kStack);
|
2310
|
+
VisitForValue(args->at(2), kStack);
|
2311
|
+
VisitForValue(args->at(3), kStack);
|
2312
|
+
__ CallStub(&stub);
|
2313
|
+
Apply(context_, rax);
|
2314
|
+
}
|
2315
|
+
|
2316
|
+
|
2317
|
+
void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
|
2318
|
+
ASSERT(args->length() == 1);
|
2319
|
+
|
2320
|
+
VisitForValue(args->at(0), kAccumulator); // Load the object.
|
2321
|
+
|
2322
|
+
Label done;
|
2323
|
+
// If the object is a smi return the object.
|
2324
|
+
__ JumpIfSmi(rax, &done);
|
2325
|
+
// If the object is not a value type, return the object.
|
2326
|
+
__ CmpObjectType(rax, JS_VALUE_TYPE, rbx);
|
2327
|
+
__ j(not_equal, &done);
|
2328
|
+
__ movq(rax, FieldOperand(rax, JSValue::kValueOffset));
|
2329
|
+
|
2330
|
+
__ bind(&done);
|
2331
|
+
Apply(context_, rax);
|
2332
|
+
}
|
2333
|
+
|
2334
|
+
|
2335
|
+
void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
|
2336
|
+
// Load the arguments on the stack and call the runtime function.
|
2337
|
+
ASSERT(args->length() == 2);
|
2338
|
+
VisitForValue(args->at(0), kStack);
|
2339
|
+
VisitForValue(args->at(1), kStack);
|
2340
|
+
__ CallRuntime(Runtime::kMath_pow, 2);
|
2341
|
+
Apply(context_, rax);
|
2342
|
+
}
|
2343
|
+
|
2344
|
+
|
2345
|
+
void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
|
2346
|
+
ASSERT(args->length() == 2);
|
2347
|
+
|
2348
|
+
VisitForValue(args->at(0), kStack); // Load the object.
|
2349
|
+
VisitForValue(args->at(1), kAccumulator); // Load the value.
|
2350
|
+
__ pop(rbx); // rax = value. ebx = object.
|
2351
|
+
|
2352
|
+
Label done;
|
2353
|
+
// If the object is a smi, return the value.
|
2354
|
+
__ JumpIfSmi(rbx, &done);
|
2355
|
+
|
2356
|
+
// If the object is not a value type, return the value.
|
2357
|
+
__ CmpObjectType(rbx, JS_VALUE_TYPE, rcx);
|
2358
|
+
__ j(not_equal, &done);
|
2359
|
+
|
2360
|
+
// Store the value.
|
2361
|
+
__ movq(FieldOperand(rbx, JSValue::kValueOffset), rax);
|
2362
|
+
// Update the write barrier. Save the value as it will be
|
2363
|
+
// overwritten by the write barrier code and is needed afterward.
|
2364
|
+
__ movq(rdx, rax);
|
2365
|
+
__ RecordWrite(rbx, JSValue::kValueOffset, rdx, rcx);
|
2366
|
+
|
2367
|
+
__ bind(&done);
|
2368
|
+
Apply(context_, rax);
|
2369
|
+
}
|
2370
|
+
|
2371
|
+
|
2372
|
+
void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
|
2373
|
+
ASSERT_EQ(args->length(), 1);
|
2374
|
+
|
2375
|
+
// Load the argument on the stack and call the stub.
|
2376
|
+
VisitForValue(args->at(0), kStack);
|
2377
|
+
|
2378
|
+
NumberToStringStub stub;
|
2379
|
+
__ CallStub(&stub);
|
2380
|
+
Apply(context_, rax);
|
2381
|
+
}
|
2382
|
+
|
2383
|
+
|
2384
|
+
void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
|
2385
|
+
ASSERT(args->length() == 1);
|
2386
|
+
|
2387
|
+
VisitForValue(args->at(0), kAccumulator);
|
2388
|
+
|
2389
|
+
Label done;
|
2390
|
+
StringCharFromCodeGenerator generator(rax, rbx);
|
2391
|
+
generator.GenerateFast(masm_);
|
2392
|
+
__ jmp(&done);
|
2393
|
+
|
2394
|
+
NopRuntimeCallHelper call_helper;
|
2395
|
+
generator.GenerateSlow(masm_, call_helper);
|
2396
|
+
|
2397
|
+
__ bind(&done);
|
2398
|
+
Apply(context_, rbx);
|
2399
|
+
}
|
2400
|
+
|
2401
|
+
|
2402
|
+
void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
|
2403
|
+
ASSERT(args->length() == 2);
|
2404
|
+
|
2405
|
+
VisitForValue(args->at(0), kStack);
|
2406
|
+
VisitForValue(args->at(1), kAccumulator);
|
2407
|
+
|
2408
|
+
Register object = rbx;
|
2409
|
+
Register index = rax;
|
2410
|
+
Register scratch = rcx;
|
2411
|
+
Register result = rdx;
|
2412
|
+
|
2413
|
+
__ pop(object);
|
2414
|
+
|
2415
|
+
Label need_conversion;
|
2416
|
+
Label index_out_of_range;
|
2417
|
+
Label done;
|
2418
|
+
StringCharCodeAtGenerator generator(object,
|
2419
|
+
index,
|
2420
|
+
scratch,
|
2421
|
+
result,
|
2422
|
+
&need_conversion,
|
2423
|
+
&need_conversion,
|
2424
|
+
&index_out_of_range,
|
2425
|
+
STRING_INDEX_IS_NUMBER);
|
2426
|
+
generator.GenerateFast(masm_);
|
2427
|
+
__ jmp(&done);
|
2428
|
+
|
2429
|
+
__ bind(&index_out_of_range);
|
2430
|
+
// When the index is out of range, the spec requires us to return
|
2431
|
+
// NaN.
|
2432
|
+
__ LoadRoot(result, Heap::kNanValueRootIndex);
|
2433
|
+
__ jmp(&done);
|
2434
|
+
|
2435
|
+
__ bind(&need_conversion);
|
2436
|
+
// Move the undefined value into the result register, which will
|
2437
|
+
// trigger conversion.
|
2438
|
+
__ LoadRoot(result, Heap::kUndefinedValueRootIndex);
|
2439
|
+
__ jmp(&done);
|
2440
|
+
|
2441
|
+
NopRuntimeCallHelper call_helper;
|
2442
|
+
generator.GenerateSlow(masm_, call_helper);
|
2443
|
+
|
2444
|
+
__ bind(&done);
|
2445
|
+
Apply(context_, result);
|
2446
|
+
}
|
2447
|
+
|
2448
|
+
|
2449
|
+
void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
|
2450
|
+
ASSERT(args->length() == 2);
|
2451
|
+
|
2452
|
+
VisitForValue(args->at(0), kStack);
|
2453
|
+
VisitForValue(args->at(1), kAccumulator);
|
2454
|
+
|
2455
|
+
Register object = rbx;
|
2456
|
+
Register index = rax;
|
2457
|
+
Register scratch1 = rcx;
|
2458
|
+
Register scratch2 = rdx;
|
2459
|
+
Register result = rax;
|
2460
|
+
|
2461
|
+
__ pop(object);
|
2462
|
+
|
2463
|
+
Label need_conversion;
|
2464
|
+
Label index_out_of_range;
|
2465
|
+
Label done;
|
2466
|
+
StringCharAtGenerator generator(object,
|
2467
|
+
index,
|
2468
|
+
scratch1,
|
2469
|
+
scratch2,
|
2470
|
+
result,
|
2471
|
+
&need_conversion,
|
2472
|
+
&need_conversion,
|
2473
|
+
&index_out_of_range,
|
2474
|
+
STRING_INDEX_IS_NUMBER);
|
2475
|
+
generator.GenerateFast(masm_);
|
2476
|
+
__ jmp(&done);
|
2477
|
+
|
2478
|
+
__ bind(&index_out_of_range);
|
2479
|
+
// When the index is out of range, the spec requires us to return
|
2480
|
+
// the empty string.
|
2481
|
+
__ LoadRoot(result, Heap::kEmptyStringRootIndex);
|
2482
|
+
__ jmp(&done);
|
2483
|
+
|
2484
|
+
__ bind(&need_conversion);
|
2485
|
+
// Move smi zero into the result register, which will trigger
|
2486
|
+
// conversion.
|
2487
|
+
__ Move(result, Smi::FromInt(0));
|
2488
|
+
__ jmp(&done);
|
2489
|
+
|
2490
|
+
NopRuntimeCallHelper call_helper;
|
2491
|
+
generator.GenerateSlow(masm_, call_helper);
|
2492
|
+
|
2493
|
+
__ bind(&done);
|
2494
|
+
Apply(context_, result);
|
2495
|
+
}
|
2496
|
+
|
2497
|
+
|
2498
|
+
void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
|
2499
|
+
ASSERT_EQ(2, args->length());
|
2500
|
+
|
2501
|
+
VisitForValue(args->at(0), kStack);
|
2502
|
+
VisitForValue(args->at(1), kStack);
|
2503
|
+
|
2504
|
+
StringAddStub stub(NO_STRING_ADD_FLAGS);
|
2505
|
+
__ CallStub(&stub);
|
2506
|
+
Apply(context_, rax);
|
2507
|
+
}
|
2508
|
+
|
2509
|
+
|
2510
|
+
void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) {
|
2511
|
+
ASSERT_EQ(2, args->length());
|
2512
|
+
|
2513
|
+
VisitForValue(args->at(0), kStack);
|
2514
|
+
VisitForValue(args->at(1), kStack);
|
2515
|
+
|
2516
|
+
StringCompareStub stub;
|
2517
|
+
__ CallStub(&stub);
|
2518
|
+
Apply(context_, rax);
|
2519
|
+
}
|
2520
|
+
|
2521
|
+
|
2522
|
+
void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
|
2523
|
+
// Load the argument on the stack and call the stub.
|
2524
|
+
TranscendentalCacheStub stub(TranscendentalCache::SIN);
|
2525
|
+
ASSERT(args->length() == 1);
|
2526
|
+
VisitForValue(args->at(0), kStack);
|
2527
|
+
__ CallStub(&stub);
|
2528
|
+
Apply(context_, rax);
|
2529
|
+
}
|
2530
|
+
|
2531
|
+
|
2532
|
+
void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
|
2533
|
+
// Load the argument on the stack and call the stub.
|
2534
|
+
TranscendentalCacheStub stub(TranscendentalCache::COS);
|
2535
|
+
ASSERT(args->length() == 1);
|
2536
|
+
VisitForValue(args->at(0), kStack);
|
2537
|
+
__ CallStub(&stub);
|
2538
|
+
Apply(context_, rax);
|
2539
|
+
}
|
2540
|
+
|
2541
|
+
|
2542
|
+
void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
|
2543
|
+
// Load the argument on the stack and call the runtime function.
|
2544
|
+
ASSERT(args->length() == 1);
|
2545
|
+
VisitForValue(args->at(0), kStack);
|
2546
|
+
__ CallRuntime(Runtime::kMath_sqrt, 1);
|
2547
|
+
Apply(context_, rax);
|
2548
|
+
}
|
2549
|
+
|
2550
|
+
|
2551
|
+
void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
|
2552
|
+
ASSERT(args->length() >= 2);
|
2553
|
+
|
2554
|
+
int arg_count = args->length() - 2; // For receiver and function.
|
2555
|
+
VisitForValue(args->at(0), kStack); // Receiver.
|
2556
|
+
for (int i = 0; i < arg_count; i++) {
|
2557
|
+
VisitForValue(args->at(i + 1), kStack);
|
2558
|
+
}
|
2559
|
+
VisitForValue(args->at(arg_count + 1), kAccumulator); // Function.
|
2560
|
+
|
2561
|
+
// InvokeFunction requires function in rdi. Move it in there.
|
2562
|
+
if (!result_register().is(rdi)) __ movq(rdi, result_register());
|
2563
|
+
ParameterCount count(arg_count);
|
2564
|
+
__ InvokeFunction(rdi, count, CALL_FUNCTION);
|
2565
|
+
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
2566
|
+
Apply(context_, rax);
|
2567
|
+
}
|
2568
|
+
|
2569
|
+
|
2570
|
+
void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) {
|
2571
|
+
ASSERT(args->length() == 3);
|
2572
|
+
VisitForValue(args->at(0), kStack);
|
2573
|
+
VisitForValue(args->at(1), kStack);
|
2574
|
+
VisitForValue(args->at(2), kStack);
|
2575
|
+
__ CallRuntime(Runtime::kRegExpConstructResult, 3);
|
2576
|
+
Apply(context_, rax);
|
2577
|
+
}
|
2578
|
+
|
2579
|
+
|
2580
|
+
void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
2581
|
+
ASSERT(args->length() == 3);
|
2582
|
+
VisitForValue(args->at(0), kStack);
|
2583
|
+
VisitForValue(args->at(1), kStack);
|
2584
|
+
VisitForValue(args->at(2), kStack);
|
2585
|
+
__ CallRuntime(Runtime::kSwapElements, 3);
|
2586
|
+
Apply(context_, rax);
|
2587
|
+
}
|
2588
|
+
|
2589
|
+
|
2590
|
+
void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
|
2591
|
+
ASSERT_EQ(2, args->length());
|
2592
|
+
|
2593
|
+
ASSERT_NE(NULL, args->at(0)->AsLiteral());
|
2594
|
+
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
|
2595
|
+
|
2596
|
+
Handle<FixedArray> jsfunction_result_caches(
|
2597
|
+
Top::global_context()->jsfunction_result_caches());
|
2598
|
+
if (jsfunction_result_caches->length() <= cache_id) {
|
2599
|
+
__ Abort("Attempt to use undefined cache.");
|
2600
|
+
__ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
2601
|
+
Apply(context_, rax);
|
2602
|
+
return;
|
2603
|
+
}
|
2604
|
+
|
2605
|
+
VisitForValue(args->at(1), kAccumulator);
|
2606
|
+
|
2607
|
+
Register key = rax;
|
2608
|
+
Register cache = rbx;
|
2609
|
+
Register tmp = rcx;
|
2610
|
+
__ movq(cache, CodeGenerator::ContextOperand(rsi, Context::GLOBAL_INDEX));
|
2611
|
+
__ movq(cache,
|
2612
|
+
FieldOperand(cache, GlobalObject::kGlobalContextOffset));
|
2613
|
+
__ movq(cache,
|
2614
|
+
CodeGenerator::ContextOperand(
|
2615
|
+
cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
|
2616
|
+
__ movq(cache,
|
2617
|
+
FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id)));
|
2618
|
+
|
2619
|
+
Label done, not_found;
|
2620
|
+
// tmp now holds finger offset as a smi.
|
2621
|
+
ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
|
2622
|
+
__ movq(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset));
|
2623
|
+
SmiIndex index =
|
2624
|
+
__ SmiToIndex(kScratchRegister, tmp, kPointerSizeLog2);
|
2625
|
+
__ cmpq(key, FieldOperand(cache,
|
2626
|
+
index.reg,
|
2627
|
+
index.scale,
|
2628
|
+
FixedArray::kHeaderSize));
|
2629
|
+
__ j(not_equal, ¬_found);
|
2630
|
+
__ movq(rax, FieldOperand(cache,
|
2631
|
+
index.reg,
|
2632
|
+
index.scale,
|
2633
|
+
FixedArray::kHeaderSize + kPointerSize));
|
2634
|
+
__ jmp(&done);
|
2635
|
+
|
2636
|
+
__ bind(¬_found);
|
2637
|
+
// Call runtime to perform the lookup.
|
2638
|
+
__ push(cache);
|
2639
|
+
__ push(key);
|
2640
|
+
__ CallRuntime(Runtime::kGetFromCache, 2);
|
2641
|
+
|
2642
|
+
__ bind(&done);
|
2643
|
+
Apply(context_, rax);
|
2644
|
+
}
|
2645
|
+
|
2646
|
+
|
2647
|
+
void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
2648
|
+
Handle<String> name = expr->name();
|
2649
|
+
if (name->length() > 0 && name->Get(0) == '_') {
|
2650
|
+
Comment cmnt(masm_, "[ InlineRuntimeCall");
|
2651
|
+
EmitInlineRuntimeCall(expr);
|
2652
|
+
return;
|
2653
|
+
}
|
2654
|
+
|
2655
|
+
Comment cmnt(masm_, "[ CallRuntime");
|
2656
|
+
ZoneList<Expression*>* args = expr->arguments();
|
2657
|
+
|
2658
|
+
if (expr->is_jsruntime()) {
|
2659
|
+
// Prepare for calling JS runtime function.
|
2660
|
+
__ movq(rax, CodeGenerator::GlobalObject());
|
2661
|
+
__ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
|
2662
|
+
}
|
2663
|
+
|
2664
|
+
// Push the arguments ("left-to-right").
|
2665
|
+
int arg_count = args->length();
|
2666
|
+
for (int i = 0; i < arg_count; i++) {
|
2667
|
+
VisitForValue(args->at(i), kStack);
|
2668
|
+
}
|
2669
|
+
|
2670
|
+
if (expr->is_jsruntime()) {
|
2671
|
+
// Call the JS runtime function using a call IC.
|
2672
|
+
__ Move(rcx, expr->name());
|
2673
|
+
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
2674
|
+
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
|
2675
|
+
__ call(ic, RelocInfo::CODE_TARGET);
|
2676
|
+
// Restore context register.
|
2677
|
+
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
2678
|
+
} else {
|
2679
|
+
__ CallRuntime(expr->function(), arg_count);
|
2680
|
+
}
|
2681
|
+
Apply(context_, rax);
|
2682
|
+
}
|
2683
|
+
|
2684
|
+
|
2685
|
+
void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
2686
|
+
switch (expr->op()) {
|
2687
|
+
case Token::DELETE: {
|
2688
|
+
Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
|
2689
|
+
Property* prop = expr->expression()->AsProperty();
|
2690
|
+
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
|
2691
|
+
if (prop == NULL && var == NULL) {
|
2692
|
+
// Result of deleting non-property, non-variable reference is true.
|
2693
|
+
// The subexpression may have side effects.
|
2694
|
+
VisitForEffect(expr->expression());
|
2695
|
+
Apply(context_, true);
|
2696
|
+
} else if (var != NULL &&
|
2697
|
+
!var->is_global() &&
|
2698
|
+
var->slot() != NULL &&
|
2699
|
+
var->slot()->type() != Slot::LOOKUP) {
|
2700
|
+
// Result of deleting non-global, non-dynamic variables is false.
|
2701
|
+
// The subexpression does not have side effects.
|
2702
|
+
Apply(context_, false);
|
2703
|
+
} else {
|
2704
|
+
// Property or variable reference. Call the delete builtin with
|
2705
|
+
// object and property name as arguments.
|
2706
|
+
if (prop != NULL) {
|
2707
|
+
VisitForValue(prop->obj(), kStack);
|
2708
|
+
VisitForValue(prop->key(), kStack);
|
2709
|
+
} else if (var->is_global()) {
|
2710
|
+
__ push(CodeGenerator::GlobalObject());
|
2711
|
+
__ Push(var->name());
|
2712
|
+
} else {
|
2713
|
+
// Non-global variable. Call the runtime to look up the context
|
2714
|
+
// where the variable was introduced.
|
2715
|
+
__ push(context_register());
|
2716
|
+
__ Push(var->name());
|
2717
|
+
__ CallRuntime(Runtime::kLookupContext, 2);
|
2718
|
+
__ push(rax);
|
2719
|
+
__ Push(var->name());
|
2720
|
+
}
|
2721
|
+
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
|
2722
|
+
Apply(context_, rax);
|
2723
|
+
}
|
2724
|
+
break;
|
2725
|
+
}
|
2726
|
+
|
1471
2727
|
case Token::VOID: {
|
1472
2728
|
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
|
1473
2729
|
VisitForEffect(expr->expression());
|
@@ -1508,33 +2764,15 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
1508
2764
|
|
1509
2765
|
case Token::NOT: {
|
1510
2766
|
Comment cmnt(masm_, "[ UnaryOperation (NOT)");
|
1511
|
-
Label materialize_true, materialize_false
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
UNREACHABLE();
|
1519
|
-
break;
|
1520
|
-
case Expression::kEffect:
|
1521
|
-
if_true = &done;
|
1522
|
-
if_false = &done;
|
1523
|
-
break;
|
1524
|
-
case Expression::kValue:
|
1525
|
-
if_true = &materialize_false;
|
1526
|
-
if_false = &materialize_true;
|
1527
|
-
break;
|
1528
|
-
case Expression::kTest:
|
1529
|
-
break;
|
1530
|
-
case Expression::kValueTest:
|
1531
|
-
if_false = &materialize_true;
|
1532
|
-
break;
|
1533
|
-
case Expression::kTestValue:
|
1534
|
-
if_true = &materialize_false;
|
1535
|
-
break;
|
1536
|
-
}
|
2767
|
+
Label materialize_true, materialize_false;
|
2768
|
+
Label* if_true = NULL;
|
2769
|
+
Label* if_false = NULL;
|
2770
|
+
|
2771
|
+
// Notice that the labels are swapped.
|
2772
|
+
PrepareTest(&materialize_true, &materialize_false, &if_false, &if_true);
|
2773
|
+
|
1537
2774
|
VisitForControl(expr->expression(), if_true, if_false);
|
2775
|
+
|
1538
2776
|
Apply(context_, if_false, if_true); // Labels swapped.
|
1539
2777
|
break;
|
1540
2778
|
}
|
@@ -1546,13 +2784,13 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
1546
2784
|
!proxy->var()->is_this() &&
|
1547
2785
|
proxy->var()->is_global()) {
|
1548
2786
|
Comment cmnt(masm_, "Global variable");
|
1549
|
-
__ push(CodeGenerator::GlobalObject());
|
1550
2787
|
__ Move(rcx, proxy->name());
|
2788
|
+
__ movq(rax, CodeGenerator::GlobalObject());
|
1551
2789
|
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
|
1552
2790
|
// Use a regular load, not a contextual load, to avoid a reference
|
1553
2791
|
// error.
|
1554
2792
|
__ Call(ic, RelocInfo::CODE_TARGET);
|
1555
|
-
__
|
2793
|
+
__ push(rax);
|
1556
2794
|
} else if (proxy != NULL &&
|
1557
2795
|
proxy->var()->slot() != NULL &&
|
1558
2796
|
proxy->var()->slot()->type() == Slot::LOOKUP) {
|
@@ -1585,9 +2823,11 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
1585
2823
|
|
1586
2824
|
case Token::SUB: {
|
1587
2825
|
Comment cmt(masm_, "[ UnaryOperation (SUB)");
|
1588
|
-
bool
|
2826
|
+
bool can_overwrite =
|
1589
2827
|
(expr->expression()->AsBinaryOperation() != NULL &&
|
1590
2828
|
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
|
2829
|
+
UnaryOverwriteMode overwrite =
|
2830
|
+
can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
|
1591
2831
|
GenericUnaryOpStub stub(Token::SUB, overwrite);
|
1592
2832
|
// GenericUnaryOpStub expects the argument to be in the
|
1593
2833
|
// accumulator register rax.
|
@@ -1599,9 +2839,11 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
1599
2839
|
|
1600
2840
|
case Token::BIT_NOT: {
|
1601
2841
|
Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
|
1602
|
-
bool
|
2842
|
+
bool can_overwrite =
|
1603
2843
|
(expr->expression()->AsBinaryOperation() != NULL &&
|
1604
2844
|
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
|
2845
|
+
UnaryOverwriteMode overwrite =
|
2846
|
+
can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
|
1605
2847
|
GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
|
1606
2848
|
// GenericUnaryOpStub expects the argument to be in the
|
1607
2849
|
// accumulator register rax.
|
@@ -1630,6 +2872,13 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
1630
2872
|
void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
1631
2873
|
Comment cmnt(masm_, "[ CountOperation");
|
1632
2874
|
|
2875
|
+
// Invalid left-hand-sides are rewritten to have a 'throw
|
2876
|
+
// ReferenceError' as the left-hand side.
|
2877
|
+
if (!expr->expression()->IsValidLeftHandSide()) {
|
2878
|
+
VisitForEffect(expr->expression());
|
2879
|
+
return;
|
2880
|
+
}
|
2881
|
+
|
1633
2882
|
// Expression can only be a property, a global or a (parameter or local)
|
1634
2883
|
// slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
|
1635
2884
|
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
|
@@ -1650,16 +2899,20 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
1650
2899
|
EmitVariableLoad(expr->expression()->AsVariableProxy()->var(),
|
1651
2900
|
Expression::kValue);
|
1652
2901
|
location_ = saved_location;
|
1653
|
-
} else
|
2902
|
+
} else {
|
1654
2903
|
// Reserve space for result of postfix operation.
|
1655
2904
|
if (expr->is_postfix() && context_ != Expression::kEffect) {
|
1656
2905
|
__ Push(Smi::FromInt(0));
|
1657
2906
|
}
|
1658
|
-
VisitForValue(prop->obj(), kStack);
|
1659
2907
|
if (assign_type == NAMED_PROPERTY) {
|
2908
|
+
VisitForValue(prop->obj(), kAccumulator);
|
2909
|
+
__ push(rax); // Copy of receiver, needed for later store.
|
1660
2910
|
EmitNamedPropertyLoad(prop);
|
1661
2911
|
} else {
|
1662
|
-
VisitForValue(prop->
|
2912
|
+
VisitForValue(prop->obj(), kStack);
|
2913
|
+
VisitForValue(prop->key(), kAccumulator);
|
2914
|
+
__ movq(rdx, Operand(rsp, 0)); // Leave receiver on stack
|
2915
|
+
__ push(rax); // Copy of key, needed for later store.
|
1663
2916
|
EmitKeyedPropertyLoad(prop);
|
1664
2917
|
}
|
1665
2918
|
}
|
@@ -1735,7 +2988,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
1735
2988
|
switch (assign_type) {
|
1736
2989
|
case VARIABLE:
|
1737
2990
|
if (expr->is_postfix()) {
|
2991
|
+
// Perform the assignment as if via '='.
|
1738
2992
|
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
|
2993
|
+
Token::ASSIGN,
|
1739
2994
|
Expression::kEffect);
|
1740
2995
|
// For all contexts except kEffect: We have the result on
|
1741
2996
|
// top of the stack.
|
@@ -1743,7 +2998,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
1743
2998
|
ApplyTOS(context_);
|
1744
2999
|
}
|
1745
3000
|
} else {
|
3001
|
+
// Perform the assignment as if via '='.
|
1746
3002
|
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
|
3003
|
+
Token::ASSIGN,
|
1747
3004
|
context_);
|
1748
3005
|
}
|
1749
3006
|
break;
|
@@ -1765,18 +3022,19 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
1765
3022
|
break;
|
1766
3023
|
}
|
1767
3024
|
case KEYED_PROPERTY: {
|
3025
|
+
__ pop(rcx);
|
3026
|
+
__ pop(rdx);
|
1768
3027
|
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
1769
3028
|
__ call(ic, RelocInfo::CODE_TARGET);
|
1770
3029
|
// This nop signals to the IC that there is no inlined code at the call
|
1771
3030
|
// site for it to patch.
|
1772
3031
|
__ nop();
|
1773
3032
|
if (expr->is_postfix()) {
|
1774
|
-
__ Drop(2); // Result is on the stack under the key and the receiver.
|
1775
3033
|
if (context_ != Expression::kEffect) {
|
1776
3034
|
ApplyTOS(context_);
|
1777
3035
|
}
|
1778
3036
|
} else {
|
1779
|
-
|
3037
|
+
Apply(context_, rax);
|
1780
3038
|
}
|
1781
3039
|
break;
|
1782
3040
|
}
|
@@ -1818,36 +3076,39 @@ void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
|
|
1818
3076
|
}
|
1819
3077
|
|
1820
3078
|
|
3079
|
+
void FullCodeGenerator::EmitNullCompare(bool strict,
|
3080
|
+
Register obj,
|
3081
|
+
Register null_const,
|
3082
|
+
Label* if_true,
|
3083
|
+
Label* if_false,
|
3084
|
+
Register scratch) {
|
3085
|
+
__ cmpq(obj, null_const);
|
3086
|
+
if (strict) {
|
3087
|
+
__ j(equal, if_true);
|
3088
|
+
} else {
|
3089
|
+
__ j(equal, if_true);
|
3090
|
+
__ CompareRoot(obj, Heap::kUndefinedValueRootIndex);
|
3091
|
+
__ j(equal, if_true);
|
3092
|
+
__ JumpIfSmi(obj, if_false);
|
3093
|
+
// It can be an undetectable object.
|
3094
|
+
__ movq(scratch, FieldOperand(obj, HeapObject::kMapOffset));
|
3095
|
+
__ testb(FieldOperand(scratch, Map::kBitFieldOffset),
|
3096
|
+
Immediate(1 << Map::kIsUndetectable));
|
3097
|
+
__ j(not_zero, if_true);
|
3098
|
+
}
|
3099
|
+
__ jmp(if_false);
|
3100
|
+
}
|
3101
|
+
|
3102
|
+
|
1821
3103
|
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
1822
3104
|
Comment cmnt(masm_, "[ CompareOperation");
|
1823
3105
|
|
1824
3106
|
// Always perform the comparison for its control flow. Pack the result
|
1825
3107
|
// into the expression's context after the comparison is performed.
|
1826
|
-
Label materialize_true, materialize_false
|
1827
|
-
|
1828
|
-
Label*
|
1829
|
-
|
1830
|
-
switch (context_) {
|
1831
|
-
case Expression::kUninitialized:
|
1832
|
-
UNREACHABLE();
|
1833
|
-
break;
|
1834
|
-
case Expression::kEffect:
|
1835
|
-
if_true = &done;
|
1836
|
-
if_false = &done;
|
1837
|
-
break;
|
1838
|
-
case Expression::kValue:
|
1839
|
-
if_true = &materialize_true;
|
1840
|
-
if_false = &materialize_false;
|
1841
|
-
break;
|
1842
|
-
case Expression::kTest:
|
1843
|
-
break;
|
1844
|
-
case Expression::kValueTest:
|
1845
|
-
if_true = &materialize_true;
|
1846
|
-
break;
|
1847
|
-
case Expression::kTestValue:
|
1848
|
-
if_false = &materialize_false;
|
1849
|
-
break;
|
1850
|
-
}
|
3108
|
+
Label materialize_true, materialize_false;
|
3109
|
+
Label* if_true = NULL;
|
3110
|
+
Label* if_false = NULL;
|
3111
|
+
PrepareTest(&materialize_true, &materialize_false, &if_true, &if_false);
|
1851
3112
|
|
1852
3113
|
VisitForValue(expr->left(), kStack);
|
1853
3114
|
switch (expr->op()) {
|
@@ -1877,10 +3138,24 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|
1877
3138
|
case Token::EQ_STRICT:
|
1878
3139
|
strict = true;
|
1879
3140
|
// Fall through.
|
1880
|
-
case Token::EQ:
|
3141
|
+
case Token::EQ: {
|
1881
3142
|
cc = equal;
|
1882
3143
|
__ pop(rdx);
|
3144
|
+
// If either operand is constant null we do a fast compare
|
3145
|
+
// against null.
|
3146
|
+
Literal* right_literal = expr->right()->AsLiteral();
|
3147
|
+
Literal* left_literal = expr->left()->AsLiteral();
|
3148
|
+
if (right_literal != NULL && right_literal->handle()->IsNull()) {
|
3149
|
+
EmitNullCompare(strict, rdx, rax, if_true, if_false, rcx);
|
3150
|
+
Apply(context_, if_true, if_false);
|
3151
|
+
return;
|
3152
|
+
} else if (left_literal != NULL && left_literal->handle()->IsNull()) {
|
3153
|
+
EmitNullCompare(strict, rax, rdx, if_true, if_false, rcx);
|
3154
|
+
Apply(context_, if_true, if_false);
|
3155
|
+
return;
|
3156
|
+
}
|
1883
3157
|
break;
|
3158
|
+
}
|
1884
3159
|
case Token::LT:
|
1885
3160
|
cc = less;
|
1886
3161
|
__ pop(rdx);
|
@@ -1991,3 +3266,5 @@ void FullCodeGenerator::ExitFinallyBlock() {
|
|
1991
3266
|
|
1992
3267
|
|
1993
3268
|
} } // namespace v8::internal
|
3269
|
+
|
3270
|
+
#endif // V8_TARGET_ARCH_X64
|