mustang 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Isolate +9 -0
- data/README.md +6 -12
- data/Rakefile +30 -4
- data/TODO.md +9 -0
- data/ext/v8/extconf.rb +56 -0
- data/ext/v8/v8.cpp +37 -0
- data/ext/v8/v8_array.cpp +161 -0
- data/ext/v8/v8_array.h +17 -0
- data/ext/v8/v8_base.cpp +147 -0
- data/ext/v8/v8_base.h +23 -0
- data/ext/v8/v8_cast.cpp +151 -0
- data/ext/v8/v8_cast.h +64 -0
- data/ext/v8/v8_context.cpp +174 -0
- data/ext/v8/v8_context.h +12 -0
- data/ext/v8/v8_date.cpp +61 -0
- data/ext/v8/v8_date.h +16 -0
- data/ext/v8/v8_errors.cpp +147 -0
- data/ext/v8/v8_errors.h +19 -0
- data/ext/v8/v8_external.cpp +66 -0
- data/ext/v8/v8_external.h +16 -0
- data/ext/v8/v8_function.cpp +182 -0
- data/ext/v8/v8_function.h +14 -0
- data/ext/v8/v8_integer.cpp +70 -0
- data/ext/v8/v8_integer.h +16 -0
- data/ext/v8/v8_macros.h +30 -0
- data/ext/v8/v8_main.cpp +53 -0
- data/ext/v8/v8_main.h +13 -0
- data/ext/v8/v8_number.cpp +62 -0
- data/ext/v8/v8_number.h +16 -0
- data/ext/v8/v8_object.cpp +172 -0
- data/ext/v8/v8_object.h +17 -0
- data/ext/v8/v8_ref.cpp +72 -0
- data/ext/v8/v8_ref.h +43 -0
- data/ext/v8/v8_regexp.cpp +148 -0
- data/ext/v8/v8_regexp.h +16 -0
- data/ext/v8/v8_string.cpp +78 -0
- data/ext/v8/v8_string.h +16 -0
- data/ext/v8/v8_value.cpp +370 -0
- data/ext/v8/v8_value.h +19 -0
- data/gemspec.yml +2 -1
- data/lib/core_ext/class.rb +14 -0
- data/lib/core_ext/object.rb +12 -0
- data/lib/core_ext/symbol.rb +23 -0
- data/lib/mustang.rb +44 -0
- data/lib/mustang/context.rb +69 -0
- data/lib/mustang/errors.rb +36 -0
- data/lib/support/delegated.rb +25 -0
- data/lib/v8/array.rb +21 -0
- data/lib/v8/context.rb +13 -0
- data/lib/v8/date.rb +20 -0
- data/lib/v8/error.rb +15 -0
- data/lib/v8/external.rb +16 -0
- data/lib/v8/function.rb +11 -0
- data/lib/v8/integer.rb +16 -0
- data/lib/v8/number.rb +16 -0
- data/lib/v8/object.rb +66 -0
- data/lib/v8/regexp.rb +23 -0
- data/lib/v8/string.rb +27 -0
- data/mustang.gemspec +3 -0
- data/spec/core_ext/class_spec.rb +19 -0
- data/spec/core_ext/object_spec.rb +19 -0
- data/spec/core_ext/symbol_spec.rb +27 -0
- data/spec/fixtures/test1.js +2 -0
- data/spec/fixtures/test2.js +2 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/v8/array_spec.rb +88 -0
- data/spec/v8/cast_spec.rb +151 -0
- data/spec/v8/context_spec.rb +78 -0
- data/spec/v8/data_spec.rb +39 -0
- data/spec/v8/date_spec.rb +45 -0
- data/spec/v8/empty_spec.rb +27 -0
- data/spec/v8/errors_spec.rb +142 -0
- data/spec/v8/external_spec.rb +44 -0
- data/spec/v8/function_spec.rb +170 -0
- data/spec/v8/integer_spec.rb +41 -0
- data/spec/v8/main_spec.rb +18 -0
- data/spec/v8/null_spec.rb +27 -0
- data/spec/v8/number_spec.rb +40 -0
- data/spec/v8/object_spec.rb +79 -0
- data/spec/v8/primitive_spec.rb +9 -0
- data/spec/v8/regexp_spec.rb +65 -0
- data/spec/v8/string_spec.rb +48 -0
- data/spec/v8/undefined_spec.rb +27 -0
- data/spec/v8/value_spec.rb +215 -0
- data/vendor/v8/.gitignore +2 -0
- data/vendor/v8/AUTHORS +3 -1
- data/vendor/v8/ChangeLog +117 -0
- data/vendor/v8/SConstruct +334 -53
- data/vendor/v8/include/v8-debug.h +21 -11
- data/vendor/v8/include/v8-preparser.h +1 -1
- data/vendor/v8/include/v8-profiler.h +122 -43
- data/vendor/v8/include/v8-testing.h +5 -0
- data/vendor/v8/include/v8.h +171 -17
- data/vendor/v8/preparser/SConscript +38 -0
- data/vendor/v8/preparser/preparser-process.cc +77 -114
- data/vendor/v8/samples/shell.cc +232 -46
- data/vendor/v8/src/SConscript +29 -5
- data/vendor/v8/src/accessors.cc +70 -211
- data/vendor/v8/{test/cctest/test-mips.cc → src/allocation-inl.h} +15 -18
- data/vendor/v8/src/allocation.cc +0 -82
- data/vendor/v8/src/allocation.h +9 -42
- data/vendor/v8/src/api.cc +1645 -1156
- data/vendor/v8/src/api.h +76 -12
- data/vendor/v8/src/apiutils.h +0 -7
- data/vendor/v8/src/arguments.h +15 -4
- data/vendor/v8/src/arm/assembler-arm-inl.h +10 -9
- data/vendor/v8/src/arm/assembler-arm.cc +62 -23
- data/vendor/v8/src/arm/assembler-arm.h +76 -11
- data/vendor/v8/src/arm/builtins-arm.cc +39 -33
- data/vendor/v8/src/arm/code-stubs-arm.cc +1182 -402
- data/vendor/v8/src/arm/code-stubs-arm.h +20 -54
- data/vendor/v8/src/arm/codegen-arm.cc +159 -106
- data/vendor/v8/src/arm/codegen-arm.h +6 -6
- data/vendor/v8/src/arm/constants-arm.h +16 -1
- data/vendor/v8/src/arm/cpu-arm.cc +7 -5
- data/vendor/v8/src/arm/debug-arm.cc +6 -4
- data/vendor/v8/src/arm/deoptimizer-arm.cc +51 -14
- data/vendor/v8/src/arm/disasm-arm.cc +47 -15
- data/vendor/v8/src/arm/frames-arm.h +1 -1
- data/vendor/v8/src/arm/full-codegen-arm.cc +724 -408
- data/vendor/v8/src/arm/ic-arm.cc +90 -85
- data/vendor/v8/src/arm/lithium-arm.cc +140 -69
- data/vendor/v8/src/arm/lithium-arm.h +161 -46
- data/vendor/v8/src/arm/lithium-codegen-arm.cc +567 -297
- data/vendor/v8/src/arm/lithium-codegen-arm.h +21 -9
- data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +2 -0
- data/vendor/v8/src/arm/macro-assembler-arm.cc +457 -96
- data/vendor/v8/src/arm/macro-assembler-arm.h +115 -18
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +20 -13
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +1 -0
- data/vendor/v8/src/arm/simulator-arm.cc +184 -101
- data/vendor/v8/src/arm/simulator-arm.h +26 -21
- data/vendor/v8/src/arm/stub-cache-arm.cc +450 -467
- data/vendor/v8/src/arm/virtual-frame-arm.cc +14 -12
- data/vendor/v8/src/arm/virtual-frame-arm.h +11 -8
- data/vendor/v8/src/array.js +35 -18
- data/vendor/v8/src/assembler.cc +186 -92
- data/vendor/v8/src/assembler.h +106 -69
- data/vendor/v8/src/ast-inl.h +5 -0
- data/vendor/v8/src/ast.cc +46 -35
- data/vendor/v8/src/ast.h +107 -50
- data/vendor/v8/src/atomicops.h +2 -0
- data/vendor/v8/src/atomicops_internals_mips_gcc.h +169 -0
- data/vendor/v8/src/bootstrapper.cc +649 -399
- data/vendor/v8/src/bootstrapper.h +94 -27
- data/vendor/v8/src/builtins.cc +359 -227
- data/vendor/v8/src/builtins.h +157 -123
- data/vendor/v8/src/checks.cc +2 -2
- data/vendor/v8/src/checks.h +4 -0
- data/vendor/v8/src/code-stubs.cc +27 -17
- data/vendor/v8/src/code-stubs.h +38 -17
- data/vendor/v8/src/codegen-inl.h +5 -1
- data/vendor/v8/src/codegen.cc +27 -17
- data/vendor/v8/src/codegen.h +9 -9
- data/vendor/v8/src/compilation-cache.cc +92 -206
- data/vendor/v8/src/compilation-cache.h +205 -30
- data/vendor/v8/src/compiler.cc +107 -120
- data/vendor/v8/src/compiler.h +17 -2
- data/vendor/v8/src/contexts.cc +22 -15
- data/vendor/v8/src/contexts.h +14 -8
- data/vendor/v8/src/conversions.cc +86 -30
- data/vendor/v8/src/counters.cc +19 -4
- data/vendor/v8/src/counters.h +28 -16
- data/vendor/v8/src/cpu-profiler-inl.h +4 -3
- data/vendor/v8/src/cpu-profiler.cc +123 -72
- data/vendor/v8/src/cpu-profiler.h +33 -19
- data/vendor/v8/src/cpu.h +2 -0
- data/vendor/v8/src/d8-debug.cc +3 -3
- data/vendor/v8/src/d8-debug.h +7 -6
- data/vendor/v8/src/d8-posix.cc +2 -0
- data/vendor/v8/src/d8.cc +22 -12
- data/vendor/v8/src/d8.gyp +3 -0
- data/vendor/v8/src/d8.js +618 -0
- data/vendor/v8/src/data-flow.h +3 -3
- data/vendor/v8/src/dateparser.h +4 -2
- data/vendor/v8/src/debug-agent.cc +10 -9
- data/vendor/v8/src/debug-agent.h +9 -11
- data/vendor/v8/src/debug-debugger.js +121 -0
- data/vendor/v8/src/debug.cc +331 -227
- data/vendor/v8/src/debug.h +248 -219
- data/vendor/v8/src/deoptimizer.cc +173 -62
- data/vendor/v8/src/deoptimizer.h +119 -19
- data/vendor/v8/src/disasm.h +3 -0
- data/vendor/v8/src/disassembler.cc +10 -9
- data/vendor/v8/src/execution.cc +185 -129
- data/vendor/v8/src/execution.h +47 -78
- data/vendor/v8/src/extensions/experimental/break-iterator.cc +250 -0
- data/vendor/v8/src/extensions/experimental/break-iterator.h +89 -0
- data/vendor/v8/src/extensions/experimental/experimental.gyp +2 -0
- data/vendor/v8/src/extensions/experimental/i18n-extension.cc +22 -2
- data/vendor/v8/src/extensions/externalize-string-extension.cc +2 -2
- data/vendor/v8/src/extensions/gc-extension.cc +1 -1
- data/vendor/v8/src/factory.cc +261 -154
- data/vendor/v8/src/factory.h +162 -158
- data/vendor/v8/src/flag-definitions.h +17 -11
- data/vendor/v8/src/frame-element.cc +0 -5
- data/vendor/v8/src/frame-element.h +9 -13
- data/vendor/v8/src/frames-inl.h +7 -0
- data/vendor/v8/src/frames.cc +56 -46
- data/vendor/v8/src/frames.h +36 -25
- data/vendor/v8/src/full-codegen.cc +15 -24
- data/vendor/v8/src/full-codegen.h +13 -41
- data/vendor/v8/src/func-name-inferrer.cc +7 -6
- data/vendor/v8/src/func-name-inferrer.h +1 -1
- data/vendor/v8/src/gdb-jit.cc +1 -0
- data/vendor/v8/src/global-handles.cc +118 -56
- data/vendor/v8/src/global-handles.h +98 -40
- data/vendor/v8/src/globals.h +2 -2
- data/vendor/v8/src/handles-inl.h +106 -9
- data/vendor/v8/src/handles.cc +220 -157
- data/vendor/v8/src/handles.h +38 -59
- data/vendor/v8/src/hashmap.h +3 -3
- data/vendor/v8/src/heap-inl.h +141 -25
- data/vendor/v8/src/heap-profiler.cc +117 -63
- data/vendor/v8/src/heap-profiler.h +38 -21
- data/vendor/v8/src/heap.cc +805 -564
- data/vendor/v8/src/heap.h +640 -594
- data/vendor/v8/src/hydrogen-instructions.cc +216 -73
- data/vendor/v8/src/hydrogen-instructions.h +259 -124
- data/vendor/v8/src/hydrogen.cc +996 -1171
- data/vendor/v8/src/hydrogen.h +163 -144
- data/vendor/v8/src/ia32/assembler-ia32-inl.h +12 -11
- data/vendor/v8/src/ia32/assembler-ia32.cc +85 -39
- data/vendor/v8/src/ia32/assembler-ia32.h +82 -16
- data/vendor/v8/src/ia32/builtins-ia32.cc +64 -58
- data/vendor/v8/src/ia32/code-stubs-ia32.cc +248 -324
- data/vendor/v8/src/ia32/code-stubs-ia32.h +3 -44
- data/vendor/v8/src/ia32/codegen-ia32.cc +217 -165
- data/vendor/v8/src/ia32/codegen-ia32.h +3 -0
- data/vendor/v8/src/ia32/cpu-ia32.cc +6 -5
- data/vendor/v8/src/ia32/debug-ia32.cc +8 -5
- data/vendor/v8/src/ia32/deoptimizer-ia32.cc +124 -14
- data/vendor/v8/src/ia32/disasm-ia32.cc +85 -62
- data/vendor/v8/src/ia32/frames-ia32.h +1 -1
- data/vendor/v8/src/ia32/full-codegen-ia32.cc +348 -435
- data/vendor/v8/src/ia32/ic-ia32.cc +91 -91
- data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +500 -255
- data/vendor/v8/src/ia32/lithium-codegen-ia32.h +13 -4
- data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +6 -0
- data/vendor/v8/src/ia32/lithium-ia32.cc +122 -45
- data/vendor/v8/src/ia32/lithium-ia32.h +128 -41
- data/vendor/v8/src/ia32/macro-assembler-ia32.cc +109 -84
- data/vendor/v8/src/ia32/macro-assembler-ia32.h +18 -9
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +26 -15
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +1 -0
- data/vendor/v8/src/ia32/register-allocator-ia32.cc +30 -30
- data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
- data/vendor/v8/src/ia32/stub-cache-ia32.cc +383 -400
- data/vendor/v8/src/ia32/virtual-frame-ia32.cc +36 -13
- data/vendor/v8/src/ia32/virtual-frame-ia32.h +11 -5
- data/vendor/v8/src/ic-inl.h +12 -2
- data/vendor/v8/src/ic.cc +304 -221
- data/vendor/v8/src/ic.h +115 -58
- data/vendor/v8/src/interpreter-irregexp.cc +25 -21
- data/vendor/v8/src/interpreter-irregexp.h +2 -1
- data/vendor/v8/src/isolate.cc +883 -0
- data/vendor/v8/src/isolate.h +1304 -0
- data/vendor/v8/src/json.js +10 -10
- data/vendor/v8/src/jsregexp.cc +111 -80
- data/vendor/v8/src/jsregexp.h +6 -7
- data/vendor/v8/src/jump-target-heavy.cc +5 -8
- data/vendor/v8/src/jump-target-heavy.h +0 -6
- data/vendor/v8/src/jump-target-inl.h +1 -1
- data/vendor/v8/src/jump-target-light.cc +3 -3
- data/vendor/v8/src/lithium-allocator-inl.h +2 -0
- data/vendor/v8/src/lithium-allocator.cc +42 -30
- data/vendor/v8/src/lithium-allocator.h +8 -22
- data/vendor/v8/src/lithium.cc +1 -0
- data/vendor/v8/src/liveedit.cc +141 -99
- data/vendor/v8/src/liveedit.h +7 -2
- data/vendor/v8/src/liveobjectlist-inl.h +90 -0
- data/vendor/v8/src/liveobjectlist.cc +2537 -1
- data/vendor/v8/src/liveobjectlist.h +245 -35
- data/vendor/v8/src/log-utils.cc +122 -35
- data/vendor/v8/src/log-utils.h +33 -36
- data/vendor/v8/src/log.cc +299 -241
- data/vendor/v8/src/log.h +177 -110
- data/vendor/v8/src/mark-compact.cc +612 -470
- data/vendor/v8/src/mark-compact.h +153 -80
- data/vendor/v8/src/messages.cc +16 -14
- data/vendor/v8/src/messages.js +30 -7
- data/vendor/v8/src/mips/assembler-mips-inl.h +155 -35
- data/vendor/v8/src/mips/assembler-mips.cc +1093 -219
- data/vendor/v8/src/mips/assembler-mips.h +552 -153
- data/vendor/v8/src/mips/builtins-mips.cc +43 -100
- data/vendor/v8/src/mips/code-stubs-mips.cc +752 -0
- data/vendor/v8/src/mips/code-stubs-mips.h +511 -0
- data/vendor/v8/src/mips/codegen-mips-inl.h +8 -14
- data/vendor/v8/src/mips/codegen-mips.cc +672 -896
- data/vendor/v8/src/mips/codegen-mips.h +271 -69
- data/vendor/v8/src/mips/constants-mips.cc +44 -20
- data/vendor/v8/src/mips/constants-mips.h +238 -40
- data/vendor/v8/src/mips/cpu-mips.cc +20 -3
- data/vendor/v8/src/mips/debug-mips.cc +35 -7
- data/vendor/v8/src/mips/deoptimizer-mips.cc +91 -0
- data/vendor/v8/src/mips/disasm-mips.cc +329 -93
- data/vendor/v8/src/mips/frames-mips.cc +2 -50
- data/vendor/v8/src/mips/frames-mips.h +24 -9
- data/vendor/v8/src/mips/full-codegen-mips.cc +473 -23
- data/vendor/v8/src/mips/ic-mips.cc +81 -45
- data/vendor/v8/src/mips/jump-target-mips.cc +11 -106
- data/vendor/v8/src/mips/lithium-codegen-mips.h +65 -0
- data/vendor/v8/src/mips/lithium-mips.h +304 -0
- data/vendor/v8/src/mips/macro-assembler-mips.cc +2391 -390
- data/vendor/v8/src/mips/macro-assembler-mips.h +718 -121
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +478 -0
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +250 -0
- data/vendor/v8/src/mips/register-allocator-mips-inl.h +0 -3
- data/vendor/v8/src/mips/register-allocator-mips.h +3 -2
- data/vendor/v8/src/mips/simulator-mips.cc +1009 -221
- data/vendor/v8/src/mips/simulator-mips.h +119 -36
- data/vendor/v8/src/mips/stub-cache-mips.cc +331 -148
- data/vendor/v8/src/mips/{fast-codegen-mips.cc → virtual-frame-mips-inl.h} +11 -30
- data/vendor/v8/src/mips/virtual-frame-mips.cc +137 -149
- data/vendor/v8/src/mips/virtual-frame-mips.h +294 -312
- data/vendor/v8/src/mirror-debugger.js +9 -8
- data/vendor/v8/src/mksnapshot.cc +2 -2
- data/vendor/v8/src/objects-debug.cc +16 -16
- data/vendor/v8/src/objects-inl.h +421 -195
- data/vendor/v8/src/objects-printer.cc +7 -7
- data/vendor/v8/src/objects-visiting.cc +1 -1
- data/vendor/v8/src/objects-visiting.h +33 -12
- data/vendor/v8/src/objects.cc +935 -658
- data/vendor/v8/src/objects.h +234 -139
- data/vendor/v8/src/parser.cc +484 -439
- data/vendor/v8/src/parser.h +35 -14
- data/vendor/v8/src/platform-cygwin.cc +173 -107
- data/vendor/v8/src/platform-freebsd.cc +224 -72
- data/vendor/v8/src/platform-linux.cc +234 -95
- data/vendor/v8/src/platform-macos.cc +215 -82
- data/vendor/v8/src/platform-nullos.cc +9 -3
- data/vendor/v8/src/platform-openbsd.cc +22 -7
- data/vendor/v8/src/platform-posix.cc +30 -5
- data/vendor/v8/src/platform-solaris.cc +120 -38
- data/vendor/v8/src/platform-tls-mac.h +62 -0
- data/vendor/v8/src/platform-tls-win32.h +62 -0
- data/vendor/v8/src/platform-tls.h +50 -0
- data/vendor/v8/src/platform-win32.cc +195 -97
- data/vendor/v8/src/platform.h +72 -15
- data/vendor/v8/src/preparse-data.cc +2 -0
- data/vendor/v8/src/preparser-api.cc +8 -2
- data/vendor/v8/src/preparser.cc +1 -1
- data/vendor/v8/src/prettyprinter.cc +43 -52
- data/vendor/v8/src/prettyprinter.h +1 -1
- data/vendor/v8/src/profile-generator-inl.h +0 -28
- data/vendor/v8/src/profile-generator.cc +942 -685
- data/vendor/v8/src/profile-generator.h +210 -176
- data/vendor/v8/src/property.cc +6 -0
- data/vendor/v8/src/property.h +14 -3
- data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +1 -1
- data/vendor/v8/src/regexp-macro-assembler.cc +28 -19
- data/vendor/v8/src/regexp-macro-assembler.h +11 -6
- data/vendor/v8/src/regexp-stack.cc +18 -10
- data/vendor/v8/src/regexp-stack.h +45 -21
- data/vendor/v8/src/regexp.js +3 -3
- data/vendor/v8/src/register-allocator-inl.h +3 -3
- data/vendor/v8/src/register-allocator.cc +1 -7
- data/vendor/v8/src/register-allocator.h +5 -15
- data/vendor/v8/src/rewriter.cc +2 -1
- data/vendor/v8/src/runtime-profiler.cc +158 -128
- data/vendor/v8/src/runtime-profiler.h +131 -15
- data/vendor/v8/src/runtime.cc +2409 -1692
- data/vendor/v8/src/runtime.h +93 -17
- data/vendor/v8/src/safepoint-table.cc +3 -0
- data/vendor/v8/src/safepoint-table.h +9 -3
- data/vendor/v8/src/scanner-base.cc +21 -28
- data/vendor/v8/src/scanner-base.h +22 -11
- data/vendor/v8/src/scanner.cc +3 -5
- data/vendor/v8/src/scanner.h +4 -2
- data/vendor/v8/src/scopeinfo.cc +11 -16
- data/vendor/v8/src/scopeinfo.h +26 -15
- data/vendor/v8/src/scopes.cc +67 -37
- data/vendor/v8/src/scopes.h +26 -12
- data/vendor/v8/src/serialize.cc +193 -154
- data/vendor/v8/src/serialize.h +41 -36
- data/vendor/v8/src/small-pointer-list.h +163 -0
- data/vendor/v8/src/snapshot-common.cc +1 -1
- data/vendor/v8/src/snapshot.h +3 -1
- data/vendor/v8/src/spaces-inl.h +30 -25
- data/vendor/v8/src/spaces.cc +263 -370
- data/vendor/v8/src/spaces.h +178 -166
- data/vendor/v8/src/string-search.cc +4 -3
- data/vendor/v8/src/string-search.h +21 -20
- data/vendor/v8/src/string-stream.cc +32 -24
- data/vendor/v8/src/string.js +7 -7
- data/vendor/v8/src/stub-cache.cc +324 -248
- data/vendor/v8/src/stub-cache.h +181 -155
- data/vendor/v8/src/token.cc +3 -3
- data/vendor/v8/src/token.h +3 -3
- data/vendor/v8/src/top.cc +218 -390
- data/vendor/v8/src/type-info.cc +98 -32
- data/vendor/v8/src/type-info.h +10 -3
- data/vendor/v8/src/unicode.cc +1 -1
- data/vendor/v8/src/unicode.h +1 -1
- data/vendor/v8/src/utils.h +3 -0
- data/vendor/v8/src/v8-counters.cc +18 -11
- data/vendor/v8/src/v8-counters.h +34 -13
- data/vendor/v8/src/v8.cc +66 -121
- data/vendor/v8/src/v8.h +7 -4
- data/vendor/v8/src/v8globals.h +18 -12
- data/vendor/v8/src/{memory.h → v8memory.h} +0 -0
- data/vendor/v8/src/v8natives.js +59 -18
- data/vendor/v8/src/v8threads.cc +127 -114
- data/vendor/v8/src/v8threads.h +42 -35
- data/vendor/v8/src/v8utils.h +2 -39
- data/vendor/v8/src/variables.h +1 -1
- data/vendor/v8/src/version.cc +26 -5
- data/vendor/v8/src/version.h +4 -0
- data/vendor/v8/src/virtual-frame-heavy-inl.h +2 -4
- data/vendor/v8/src/virtual-frame-light-inl.h +5 -4
- data/vendor/v8/src/vm-state-inl.h +21 -17
- data/vendor/v8/src/vm-state.h +7 -5
- data/vendor/v8/src/win32-headers.h +1 -0
- data/vendor/v8/src/x64/assembler-x64-inl.h +12 -11
- data/vendor/v8/src/x64/assembler-x64.cc +80 -40
- data/vendor/v8/src/x64/assembler-x64.h +67 -17
- data/vendor/v8/src/x64/builtins-x64.cc +34 -33
- data/vendor/v8/src/x64/code-stubs-x64.cc +636 -377
- data/vendor/v8/src/x64/code-stubs-x64.h +14 -48
- data/vendor/v8/src/x64/codegen-x64-inl.h +1 -1
- data/vendor/v8/src/x64/codegen-x64.cc +158 -136
- data/vendor/v8/src/x64/codegen-x64.h +4 -1
- data/vendor/v8/src/x64/cpu-x64.cc +7 -5
- data/vendor/v8/src/x64/debug-x64.cc +8 -6
- data/vendor/v8/src/x64/deoptimizer-x64.cc +195 -20
- data/vendor/v8/src/x64/disasm-x64.cc +42 -23
- data/vendor/v8/src/x64/frames-x64.cc +1 -1
- data/vendor/v8/src/x64/frames-x64.h +2 -2
- data/vendor/v8/src/x64/full-codegen-x64.cc +780 -218
- data/vendor/v8/src/x64/ic-x64.cc +77 -79
- data/vendor/v8/src/x64/jump-target-x64.cc +1 -1
- data/vendor/v8/src/x64/lithium-codegen-x64.cc +698 -181
- data/vendor/v8/src/x64/lithium-codegen-x64.h +31 -6
- data/vendor/v8/src/x64/lithium-x64.cc +136 -54
- data/vendor/v8/src/x64/lithium-x64.h +142 -51
- data/vendor/v8/src/x64/macro-assembler-x64.cc +456 -187
- data/vendor/v8/src/x64/macro-assembler-x64.h +166 -34
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +44 -28
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +8 -4
- data/vendor/v8/src/x64/register-allocator-x64-inl.h +3 -3
- data/vendor/v8/src/x64/register-allocator-x64.cc +12 -8
- data/vendor/v8/src/x64/simulator-x64.h +5 -5
- data/vendor/v8/src/x64/stub-cache-x64.cc +299 -344
- data/vendor/v8/src/x64/virtual-frame-x64.cc +37 -13
- data/vendor/v8/src/x64/virtual-frame-x64.h +13 -7
- data/vendor/v8/src/zone-inl.h +49 -3
- data/vendor/v8/src/zone.cc +42 -41
- data/vendor/v8/src/zone.h +37 -34
- data/vendor/v8/test/benchmarks/testcfg.py +100 -0
- data/vendor/v8/test/cctest/SConscript +5 -4
- data/vendor/v8/test/cctest/cctest.h +3 -2
- data/vendor/v8/test/cctest/cctest.status +6 -11
- data/vendor/v8/test/cctest/test-accessors.cc +3 -3
- data/vendor/v8/test/cctest/test-alloc.cc +39 -33
- data/vendor/v8/test/cctest/test-api.cc +1092 -205
- data/vendor/v8/test/cctest/test-assembler-arm.cc +39 -25
- data/vendor/v8/test/cctest/test-assembler-ia32.cc +36 -37
- data/vendor/v8/test/cctest/test-assembler-mips.cc +1098 -40
- data/vendor/v8/test/cctest/test-assembler-x64.cc +32 -25
- data/vendor/v8/test/cctest/test-ast.cc +1 -0
- data/vendor/v8/test/cctest/test-circular-queue.cc +8 -5
- data/vendor/v8/test/cctest/test-compiler.cc +24 -24
- data/vendor/v8/test/cctest/test-cpu-profiler.cc +140 -5
- data/vendor/v8/test/cctest/test-dataflow.cc +1 -0
- data/vendor/v8/test/cctest/test-debug.cc +136 -77
- data/vendor/v8/test/cctest/test-decls.cc +1 -1
- data/vendor/v8/test/cctest/test-deoptimization.cc +25 -24
- data/vendor/v8/test/cctest/test-disasm-arm.cc +9 -4
- data/vendor/v8/test/cctest/test-disasm-ia32.cc +10 -8
- data/vendor/v8/test/cctest/test-func-name-inference.cc +10 -4
- data/vendor/v8/test/cctest/test-heap-profiler.cc +226 -164
- data/vendor/v8/test/cctest/test-heap.cc +240 -217
- data/vendor/v8/test/cctest/test-liveedit.cc +1 -0
- data/vendor/v8/test/cctest/test-log-stack-tracer.cc +18 -20
- data/vendor/v8/test/cctest/test-log.cc +114 -108
- data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +247 -177
- data/vendor/v8/test/cctest/test-mark-compact.cc +129 -90
- data/vendor/v8/test/cctest/test-parsing.cc +15 -14
- data/vendor/v8/test/cctest/test-platform-linux.cc +1 -0
- data/vendor/v8/test/cctest/test-platform-tls.cc +66 -0
- data/vendor/v8/test/cctest/test-platform-win32.cc +1 -0
- data/vendor/v8/test/cctest/test-profile-generator.cc +1 -1
- data/vendor/v8/test/cctest/test-regexp.cc +53 -41
- data/vendor/v8/test/cctest/test-reloc-info.cc +18 -11
- data/vendor/v8/test/cctest/test-serialize.cc +44 -43
- data/vendor/v8/test/cctest/test-sockets.cc +8 -3
- data/vendor/v8/test/cctest/test-spaces.cc +47 -29
- data/vendor/v8/test/cctest/test-strings.cc +20 -20
- data/vendor/v8/test/cctest/test-thread-termination.cc +8 -3
- data/vendor/v8/test/cctest/test-threads.cc +5 -3
- data/vendor/v8/test/cctest/test-utils.cc +5 -4
- data/vendor/v8/test/cctest/testcfg.py +7 -3
- data/vendor/v8/test/es5conform/es5conform.status +2 -77
- data/vendor/v8/test/es5conform/testcfg.py +1 -1
- data/vendor/v8/test/message/testcfg.py +1 -1
- data/vendor/v8/test/mjsunit/accessors-on-global-object.js +3 -3
- data/vendor/v8/test/mjsunit/array-concat.js +43 -1
- data/vendor/v8/test/mjsunit/array-join.js +25 -0
- data/vendor/v8/test/mjsunit/bitops-info.js +7 -1
- data/vendor/v8/test/mjsunit/compiler/array-length.js +2 -2
- data/vendor/v8/test/mjsunit/compiler/global-accessors.js +47 -0
- data/vendor/v8/test/mjsunit/compiler/pic.js +1 -1
- data/vendor/v8/test/mjsunit/compiler/regress-loadfield.js +65 -0
- data/vendor/v8/test/mjsunit/math-sqrt.js +5 -1
- data/vendor/v8/test/mjsunit/mjsunit.js +59 -8
- data/vendor/v8/test/mjsunit/mjsunit.status +0 -12
- data/vendor/v8/test/mjsunit/mul-exhaustive.js +129 -11
- data/vendor/v8/test/mjsunit/negate-zero.js +1 -1
- data/vendor/v8/test/mjsunit/object-freeze.js +5 -13
- data/vendor/v8/test/mjsunit/object-prevent-extensions.js +9 -50
- data/vendor/v8/test/mjsunit/object-seal.js +4 -13
- data/vendor/v8/test/mjsunit/override-eval-with-non-function.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-1145.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-1172-bis.js +37 -0
- data/vendor/v8/test/mjsunit/regress/regress-1181.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-1207.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-1209.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-1210.js +48 -0
- data/vendor/v8/test/mjsunit/regress/regress-1213.js +43 -0
- data/vendor/v8/test/mjsunit/regress/regress-1218.js +29 -0
- data/vendor/v8/test/mjsunit/regress/regress-1229.js +79 -0
- data/vendor/v8/test/mjsunit/regress/regress-1233.js +47 -0
- data/vendor/v8/test/mjsunit/regress/regress-1236.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-1237.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-1240.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-1257.js +58 -0
- data/vendor/v8/test/mjsunit/regress/regress-1278.js +69 -0
- data/vendor/v8/test/mjsunit/regress/regress-create-exception.js +1 -0
- data/vendor/v8/test/mjsunit/regress/regress-lazy-deopt-reloc.js +52 -0
- data/vendor/v8/test/mjsunit/sin-cos.js +15 -10
- data/vendor/v8/test/mjsunit/smi-negative-zero.js +2 -2
- data/vendor/v8/test/mjsunit/str-to-num.js +1 -1
- data/vendor/v8/test/mjsunit/strict-mode.js +435 -0
- data/vendor/v8/test/mjsunit/testcfg.py +23 -6
- data/vendor/v8/test/mozilla/mozilla.status +0 -2
- data/vendor/v8/test/mozilla/testcfg.py +1 -1
- data/vendor/v8/test/preparser/empty.js +28 -0
- data/vendor/v8/test/preparser/functions-only.js +38 -0
- data/vendor/v8/test/preparser/non-alphanum.js +34 -0
- data/vendor/v8/test/preparser/symbols-only.js +49 -0
- data/vendor/v8/test/preparser/testcfg.py +90 -0
- data/vendor/v8/test/sputnik/testcfg.py +1 -1
- data/vendor/v8/test/test262/README +16 -0
- data/vendor/v8/test/test262/harness-adapt.js +80 -0
- data/vendor/v8/test/test262/test262.status +1506 -0
- data/vendor/v8/test/test262/testcfg.py +123 -0
- data/vendor/v8/tools/freebsd-tick-processor +10 -0
- data/vendor/v8/tools/gyp/v8.gyp +8 -33
- data/vendor/v8/tools/linux-tick-processor +5 -3
- data/vendor/v8/tools/test.py +37 -14
- data/vendor/v8/tools/tickprocessor.js +22 -8
- data/vendor/v8/tools/visual_studio/v8_base.vcproj +13 -1
- data/vendor/v8/tools/visual_studio/v8_base_arm.vcproj +5 -1
- data/vendor/v8/tools/visual_studio/v8_base_x64.vcproj +5 -1
- data/vendor/v8/tools/visual_studio/x64.vsprops +1 -0
- metadata +1495 -1341
- data/ext/extconf.rb +0 -22
- data/ext/mustang.cpp +0 -58
- data/vendor/v8/src/top.h +0 -608
@@ -108,7 +108,7 @@ class JavaScriptFrameConstants : public AllStatic {
|
|
108
108
|
public:
|
109
109
|
// FP-relative.
|
110
110
|
static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
|
111
|
-
static const int
|
111
|
+
static const int kLastParameterOffset = +2 * kPointerSize;
|
112
112
|
static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
|
113
113
|
|
114
114
|
// Caller SP-relative.
|
@@ -129,9 +129,9 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
129
129
|
{ Comment cmnt(masm_, "[ Allocate locals");
|
130
130
|
int locals_count = scope()->num_stack_slots();
|
131
131
|
if (locals_count == 1) {
|
132
|
-
__ push(Immediate(
|
132
|
+
__ push(Immediate(isolate()->factory()->undefined_value()));
|
133
133
|
} else if (locals_count > 1) {
|
134
|
-
__ mov(eax, Immediate(
|
134
|
+
__ mov(eax, Immediate(isolate()->factory()->undefined_value()));
|
135
135
|
for (int i = 0; i < locals_count; i++) {
|
136
136
|
__ push(eax);
|
137
137
|
}
|
@@ -197,12 +197,17 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
197
197
|
// function, receiver address, parameter count.
|
198
198
|
// The stub will rewrite receiver and parameter count if the previous
|
199
199
|
// stack frame was an arguments adapter frame.
|
200
|
-
ArgumentsAccessStub stub(
|
200
|
+
ArgumentsAccessStub stub(
|
201
|
+
is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT
|
202
|
+
: ArgumentsAccessStub::NEW_NON_STRICT);
|
201
203
|
__ CallStub(&stub);
|
202
|
-
|
204
|
+
|
205
|
+
Variable* arguments_shadow = scope()->arguments_shadow();
|
206
|
+
if (arguments_shadow != NULL) {
|
207
|
+
__ mov(ecx, eax); // Duplicate result.
|
208
|
+
Move(arguments_shadow->AsSlot(), ecx, ebx, edx);
|
209
|
+
}
|
203
210
|
Move(arguments->AsSlot(), eax, ebx, edx);
|
204
|
-
Slot* dot_arguments_slot = scope()->arguments_shadow()->AsSlot();
|
205
|
-
Move(dot_arguments_slot, ecx, ebx, edx);
|
206
211
|
}
|
207
212
|
|
208
213
|
if (FLAG_trace) {
|
@@ -229,7 +234,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
229
234
|
PrepareForBailout(info->function(), NO_REGISTERS);
|
230
235
|
NearLabel ok;
|
231
236
|
ExternalReference stack_limit =
|
232
|
-
ExternalReference::address_of_stack_limit();
|
237
|
+
ExternalReference::address_of_stack_limit(isolate());
|
233
238
|
__ cmp(esp, Operand::StaticVariable(stack_limit));
|
234
239
|
__ j(above_equal, &ok, taken);
|
235
240
|
StackCheckStub stub;
|
@@ -247,7 +252,7 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
|
|
247
252
|
// Always emit a 'return undefined' in case control fell off the end of
|
248
253
|
// the body.
|
249
254
|
{ Comment cmnt(masm_, "[ return <undefined>;");
|
250
|
-
__ mov(eax,
|
255
|
+
__ mov(eax, isolate()->factory()->undefined_value());
|
251
256
|
EmitReturnSequence();
|
252
257
|
}
|
253
258
|
}
|
@@ -261,7 +266,8 @@ void FullCodeGenerator::ClearAccumulator() {
|
|
261
266
|
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt) {
|
262
267
|
Comment cmnt(masm_, "[ Stack check");
|
263
268
|
NearLabel ok;
|
264
|
-
ExternalReference stack_limit =
|
269
|
+
ExternalReference stack_limit =
|
270
|
+
ExternalReference::address_of_stack_limit(isolate());
|
265
271
|
__ cmp(esp, Operand::StaticVariable(stack_limit));
|
266
272
|
__ j(above_equal, &ok, taken);
|
267
273
|
StackCheckStub stub;
|
@@ -322,23 +328,6 @@ void FullCodeGenerator::EmitReturnSequence() {
|
|
322
328
|
}
|
323
329
|
|
324
330
|
|
325
|
-
FullCodeGenerator::ConstantOperand FullCodeGenerator::GetConstantOperand(
|
326
|
-
Token::Value op, Expression* left, Expression* right) {
|
327
|
-
ASSERT(ShouldInlineSmiCase(op));
|
328
|
-
if (op == Token::DIV || op == Token::MOD || op == Token::MUL) {
|
329
|
-
// We never generate inlined constant smi operations for these.
|
330
|
-
return kNoConstants;
|
331
|
-
} else if (right->IsSmiLiteral()) {
|
332
|
-
return kRightConstant;
|
333
|
-
} else if (left->IsSmiLiteral() && !Token::IsShiftOp(op)) {
|
334
|
-
// Don't inline shifts with constant left hand side.
|
335
|
-
return kLeftConstant;
|
336
|
-
} else {
|
337
|
-
return kNoConstants;
|
338
|
-
}
|
339
|
-
}
|
340
|
-
|
341
|
-
|
342
331
|
void FullCodeGenerator::EffectContext::Plug(Slot* slot) const {
|
343
332
|
}
|
344
333
|
|
@@ -479,10 +468,10 @@ void FullCodeGenerator::AccumulatorValueContext::Plug(
|
|
479
468
|
Label* materialize_false) const {
|
480
469
|
NearLabel done;
|
481
470
|
__ bind(materialize_true);
|
482
|
-
__ mov(result_register(),
|
471
|
+
__ mov(result_register(), isolate()->factory()->true_value());
|
483
472
|
__ jmp(&done);
|
484
473
|
__ bind(materialize_false);
|
485
|
-
__ mov(result_register(),
|
474
|
+
__ mov(result_register(), isolate()->factory()->false_value());
|
486
475
|
__ bind(&done);
|
487
476
|
}
|
488
477
|
|
@@ -492,10 +481,10 @@ void FullCodeGenerator::StackValueContext::Plug(
|
|
492
481
|
Label* materialize_false) const {
|
493
482
|
NearLabel done;
|
494
483
|
__ bind(materialize_true);
|
495
|
-
__ push(Immediate(
|
484
|
+
__ push(Immediate(isolate()->factory()->true_value()));
|
496
485
|
__ jmp(&done);
|
497
486
|
__ bind(materialize_false);
|
498
|
-
__ push(Immediate(
|
487
|
+
__ push(Immediate(isolate()->factory()->false_value()));
|
499
488
|
__ bind(&done);
|
500
489
|
}
|
501
490
|
|
@@ -512,15 +501,17 @@ void FullCodeGenerator::EffectContext::Plug(bool flag) const {
|
|
512
501
|
|
513
502
|
|
514
503
|
void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
|
515
|
-
Handle<Object> value =
|
516
|
-
|
504
|
+
Handle<Object> value = flag
|
505
|
+
? isolate()->factory()->true_value()
|
506
|
+
: isolate()->factory()->false_value();
|
517
507
|
__ mov(result_register(), value);
|
518
508
|
}
|
519
509
|
|
520
510
|
|
521
511
|
void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
|
522
|
-
Handle<Object> value =
|
523
|
-
|
512
|
+
Handle<Object> value = flag
|
513
|
+
? isolate()->factory()->true_value()
|
514
|
+
: isolate()->factory()->false_value();
|
524
515
|
__ push(Immediate(value));
|
525
516
|
}
|
526
517
|
|
@@ -542,13 +533,13 @@ void FullCodeGenerator::DoTest(Label* if_true,
|
|
542
533
|
Label* if_false,
|
543
534
|
Label* fall_through) {
|
544
535
|
// Emit the inlined tests assumed by the stub.
|
545
|
-
__ cmp(result_register(),
|
536
|
+
__ cmp(result_register(), isolate()->factory()->undefined_value());
|
546
537
|
__ j(equal, if_false);
|
547
|
-
__ cmp(result_register(),
|
538
|
+
__ cmp(result_register(), isolate()->factory()->true_value());
|
548
539
|
__ j(equal, if_true);
|
549
|
-
__ cmp(result_register(),
|
540
|
+
__ cmp(result_register(), isolate()->factory()->false_value());
|
550
541
|
__ j(equal, if_false);
|
551
|
-
|
542
|
+
STATIC_ASSERT(kSmiTag == 0);
|
552
543
|
__ test(result_register(), Operand(result_register()));
|
553
544
|
__ j(zero, if_false);
|
554
545
|
__ test(result_register(), Immediate(kSmiTagMask));
|
@@ -641,7 +632,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state,
|
|
641
632
|
}
|
642
633
|
|
643
634
|
if (should_normalize) {
|
644
|
-
__ cmp(eax,
|
635
|
+
__ cmp(eax, isolate()->factory()->true_value());
|
645
636
|
Split(equal, if_true, if_false, NULL);
|
646
637
|
__ bind(&skip);
|
647
638
|
}
|
@@ -655,13 +646,14 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
|
655
646
|
ASSERT(variable != NULL); // Must have been resolved.
|
656
647
|
Slot* slot = variable->AsSlot();
|
657
648
|
Property* prop = variable->AsProperty();
|
649
|
+
|
658
650
|
if (slot != NULL) {
|
659
651
|
switch (slot->type()) {
|
660
652
|
case Slot::PARAMETER:
|
661
653
|
case Slot::LOCAL:
|
662
654
|
if (mode == Variable::CONST) {
|
663
655
|
__ mov(Operand(ebp, SlotOffset(slot)),
|
664
|
-
Immediate(
|
656
|
+
Immediate(isolate()->factory()->the_hole_value()));
|
665
657
|
} else if (function != NULL) {
|
666
658
|
VisitForAccumulatorValue(function);
|
667
659
|
__ mov(Operand(ebp, SlotOffset(slot)), result_register());
|
@@ -683,7 +675,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
|
683
675
|
}
|
684
676
|
if (mode == Variable::CONST) {
|
685
677
|
__ mov(ContextOperand(esi, slot->index()),
|
686
|
-
Immediate(
|
678
|
+
Immediate(isolate()->factory()->the_hole_value()));
|
687
679
|
// No write barrier since the hole value is in old space.
|
688
680
|
} else if (function != NULL) {
|
689
681
|
VisitForAccumulatorValue(function);
|
@@ -706,7 +698,7 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
|
706
698
|
// 'undefined') because we may have a (legal) redeclaration and we
|
707
699
|
// must not destroy the current value.
|
708
700
|
if (mode == Variable::CONST) {
|
709
|
-
__ push(Immediate(
|
701
|
+
__ push(Immediate(isolate()->factory()->the_hole_value()));
|
710
702
|
} else if (function != NULL) {
|
711
703
|
VisitForStackValue(function);
|
712
704
|
} else {
|
@@ -734,13 +726,15 @@ void FullCodeGenerator::EmitDeclaration(Variable* variable,
|
|
734
726
|
__ pop(edx);
|
735
727
|
} else {
|
736
728
|
__ mov(edx, eax);
|
737
|
-
__ mov(eax,
|
729
|
+
__ mov(eax, isolate()->factory()->the_hole_value());
|
738
730
|
}
|
739
731
|
ASSERT(prop->key()->AsLiteral() != NULL &&
|
740
732
|
prop->key()->AsLiteral()->handle()->IsSmi());
|
741
733
|
__ Set(ecx, Immediate(prop->key()->AsLiteral()->handle()));
|
742
734
|
|
743
|
-
Handle<Code> ic(
|
735
|
+
Handle<Code> ic = is_strict_mode()
|
736
|
+
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
737
|
+
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
744
738
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
745
739
|
}
|
746
740
|
}
|
@@ -757,7 +751,8 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
|
|
757
751
|
__ push(esi); // The context is the first argument.
|
758
752
|
__ push(Immediate(pairs));
|
759
753
|
__ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
|
760
|
-
__
|
754
|
+
__ push(Immediate(Smi::FromInt(strict_mode_flag())));
|
755
|
+
__ CallRuntime(Runtime::kDeclareGlobals, 4);
|
761
756
|
// Return value is ignored.
|
762
757
|
}
|
763
758
|
|
@@ -814,7 +809,6 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|
814
809
|
SetSourcePosition(clause->position());
|
815
810
|
Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
|
816
811
|
EmitCallIC(ic, &patch_site);
|
817
|
-
|
818
812
|
__ test(eax, Operand(eax));
|
819
813
|
__ j(not_equal, &next_test);
|
820
814
|
__ Drop(1); // Switch value is no longer needed.
|
@@ -836,6 +830,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|
836
830
|
Comment cmnt(masm_, "[ Case body");
|
837
831
|
CaseClause* clause = clauses->at(i);
|
838
832
|
__ bind(clause->body_target()->entry_label());
|
833
|
+
PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
|
839
834
|
VisitStatements(clause->statements());
|
840
835
|
}
|
841
836
|
|
@@ -856,9 +851,9 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
856
851
|
// ignore null and undefined in contrast to the specification; see
|
857
852
|
// ECMA-262 section 12.6.4.
|
858
853
|
VisitForAccumulatorValue(stmt->enumerable());
|
859
|
-
__ cmp(eax,
|
854
|
+
__ cmp(eax, isolate()->factory()->undefined_value());
|
860
855
|
__ j(equal, &exit);
|
861
|
-
__ cmp(eax,
|
856
|
+
__ cmp(eax, isolate()->factory()->null_value());
|
862
857
|
__ j(equal, &exit);
|
863
858
|
|
864
859
|
// Convert the object to a JS object.
|
@@ -884,7 +879,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
884
879
|
// Check that there are no elements. Register ecx contains the
|
885
880
|
// current JS object we've reached through the prototype chain.
|
886
881
|
__ cmp(FieldOperand(ecx, JSObject::kElementsOffset),
|
887
|
-
|
882
|
+
isolate()->factory()->empty_fixed_array());
|
888
883
|
__ j(not_equal, &call_runtime);
|
889
884
|
|
890
885
|
// Check that instance descriptors are not empty so that we can
|
@@ -892,10 +887,10 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
892
887
|
// prototype load.
|
893
888
|
__ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
|
894
889
|
__ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset));
|
895
|
-
__ cmp(edx,
|
890
|
+
__ cmp(edx, isolate()->factory()->empty_descriptor_array());
|
896
891
|
__ j(equal, &call_runtime);
|
897
892
|
|
898
|
-
// Check that there
|
893
|
+
// Check that there is an enum cache in the non-empty instance
|
899
894
|
// descriptors (edx). This is the case if the next enumeration
|
900
895
|
// index field does not contain a smi.
|
901
896
|
__ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
|
@@ -907,13 +902,13 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
907
902
|
__ cmp(ecx, Operand(eax));
|
908
903
|
__ j(equal, &check_prototype);
|
909
904
|
__ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
|
910
|
-
__ cmp(edx,
|
905
|
+
__ cmp(edx, isolate()->factory()->empty_fixed_array());
|
911
906
|
__ j(not_equal, &call_runtime);
|
912
907
|
|
913
908
|
// Load the prototype from the map and loop if non-null.
|
914
909
|
__ bind(&check_prototype);
|
915
910
|
__ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
|
916
|
-
__ cmp(ecx,
|
911
|
+
__ cmp(ecx, isolate()->factory()->null_value());
|
917
912
|
__ j(not_equal, &next);
|
918
913
|
|
919
914
|
// The enum cache is valid. Load the map of the object being
|
@@ -931,7 +926,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
|
|
931
926
|
// modification check. Otherwise, we got a fixed array, and we have
|
932
927
|
// to do a slow check.
|
933
928
|
NearLabel fixed_array;
|
934
|
-
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
|
929
|
+
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
|
930
|
+
isolate()->factory()->meta_map());
|
935
931
|
__ j(not_equal, &fixed_array);
|
936
932
|
|
937
933
|
// We got a map in register eax. Get the enumeration cache from it.
|
@@ -1027,18 +1023,18 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
|
|
1027
1023
|
// doesn't just get a copy of the existing unoptimized code.
|
1028
1024
|
if (!FLAG_always_opt &&
|
1029
1025
|
!FLAG_prepare_always_opt &&
|
1026
|
+
!pretenure &&
|
1030
1027
|
scope()->is_function_scope() &&
|
1031
|
-
info->num_literals() == 0
|
1032
|
-
|
1033
|
-
FastNewClosureStub stub;
|
1028
|
+
info->num_literals() == 0) {
|
1029
|
+
FastNewClosureStub stub(info->strict_mode() ? kStrictMode : kNonStrictMode);
|
1034
1030
|
__ push(Immediate(info));
|
1035
1031
|
__ CallStub(&stub);
|
1036
1032
|
} else {
|
1037
1033
|
__ push(esi);
|
1038
1034
|
__ push(Immediate(info));
|
1039
1035
|
__ push(Immediate(pretenure
|
1040
|
-
?
|
1041
|
-
:
|
1036
|
+
? isolate()->factory()->true_value()
|
1037
|
+
: isolate()->factory()->false_value()));
|
1042
1038
|
__ CallRuntime(Runtime::kNewClosure, 3);
|
1043
1039
|
}
|
1044
1040
|
context()->Plug(eax);
|
@@ -1090,7 +1086,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
|
1090
1086
|
__ bind(&next);
|
1091
1087
|
// Terminate at global context.
|
1092
1088
|
__ cmp(FieldOperand(temp, HeapObject::kMapOffset),
|
1093
|
-
Immediate(
|
1089
|
+
Immediate(isolate()->factory()->global_context_map()));
|
1094
1090
|
__ j(equal, &fast);
|
1095
1091
|
// Check that extension is NULL.
|
1096
1092
|
__ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
|
@@ -1106,7 +1102,7 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
|
|
1106
1102
|
// load IC call.
|
1107
1103
|
__ mov(eax, GlobalObjectOperand());
|
1108
1104
|
__ mov(ecx, slot->var()->name());
|
1109
|
-
Handle<Code> ic(
|
1105
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
1110
1106
|
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
|
1111
1107
|
? RelocInfo::CODE_TARGET
|
1112
1108
|
: RelocInfo::CODE_TARGET_CONTEXT;
|
@@ -1167,9 +1163,9 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
|
|
1167
1163
|
__ mov(eax,
|
1168
1164
|
ContextSlotOperandCheckExtensions(potential_slot, slow));
|
1169
1165
|
if (potential_slot->var()->mode() == Variable::CONST) {
|
1170
|
-
__ cmp(eax,
|
1166
|
+
__ cmp(eax, isolate()->factory()->the_hole_value());
|
1171
1167
|
__ j(not_equal, done);
|
1172
|
-
__ mov(eax,
|
1168
|
+
__ mov(eax, isolate()->factory()->undefined_value());
|
1173
1169
|
}
|
1174
1170
|
__ jmp(done);
|
1175
1171
|
} else if (rewrite != NULL) {
|
@@ -1189,7 +1185,8 @@ void FullCodeGenerator::EmitDynamicLoadFromSlotFastCase(
|
|
1189
1185
|
ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
|
1190
1186
|
slow));
|
1191
1187
|
__ mov(eax, Immediate(key_literal->handle()));
|
1192
|
-
Handle<Code> ic
|
1188
|
+
Handle<Code> ic =
|
1189
|
+
isolate()->builtins()->KeyedLoadIC_Initialize();
|
1193
1190
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
1194
1191
|
__ jmp(done);
|
1195
1192
|
}
|
@@ -1212,7 +1209,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
|
|
1212
1209
|
// object on the stack.
|
1213
1210
|
__ mov(eax, GlobalObjectOperand());
|
1214
1211
|
__ mov(ecx, var->name());
|
1215
|
-
Handle<Code> ic(
|
1212
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
1216
1213
|
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
1217
1214
|
context()->Plug(eax);
|
1218
1215
|
|
@@ -1242,9 +1239,9 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
|
|
1242
1239
|
NearLabel done;
|
1243
1240
|
MemOperand slot_operand = EmitSlotSearch(slot, eax);
|
1244
1241
|
__ mov(eax, slot_operand);
|
1245
|
-
__ cmp(eax,
|
1242
|
+
__ cmp(eax, isolate()->factory()->the_hole_value());
|
1246
1243
|
__ j(not_equal, &done);
|
1247
|
-
__ mov(eax,
|
1244
|
+
__ mov(eax, isolate()->factory()->undefined_value());
|
1248
1245
|
__ bind(&done);
|
1249
1246
|
context()->Plug(eax);
|
1250
1247
|
} else {
|
@@ -1275,7 +1272,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
|
|
1275
1272
|
__ mov(eax, Immediate(key_literal->handle()));
|
1276
1273
|
|
1277
1274
|
// Do a keyed property load.
|
1278
|
-
Handle<Code> ic(
|
1275
|
+
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
1279
1276
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
1280
1277
|
|
1281
1278
|
// Drop key and object left on the stack by IC.
|
@@ -1297,7 +1294,7 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
|
|
1297
1294
|
int literal_offset =
|
1298
1295
|
FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
|
1299
1296
|
__ mov(ebx, FieldOperand(ecx, literal_offset));
|
1300
|
-
__ cmp(ebx,
|
1297
|
+
__ cmp(ebx, isolate()->factory()->undefined_value());
|
1301
1298
|
__ j(not_equal, &materialized);
|
1302
1299
|
|
1303
1300
|
// Create regexp literal using runtime function
|
@@ -1344,7 +1341,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
|
1344
1341
|
__ push(FieldOperand(edi, JSFunction::kLiteralsOffset));
|
1345
1342
|
__ push(Immediate(Smi::FromInt(expr->literal_index())));
|
1346
1343
|
__ push(Immediate(expr->constant_properties()));
|
1347
|
-
|
1344
|
+
int flags = expr->fast_elements()
|
1345
|
+
? ObjectLiteral::kFastElements
|
1346
|
+
: ObjectLiteral::kNoFlags;
|
1347
|
+
flags |= expr->has_function()
|
1348
|
+
? ObjectLiteral::kHasFunction
|
1349
|
+
: ObjectLiteral::kNoFlags;
|
1350
|
+
__ push(Immediate(Smi::FromInt(flags)));
|
1348
1351
|
if (expr->depth() > 1) {
|
1349
1352
|
__ CallRuntime(Runtime::kCreateObjectLiteral, 4);
|
1350
1353
|
} else {
|
@@ -1380,7 +1383,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
|
1380
1383
|
VisitForAccumulatorValue(value);
|
1381
1384
|
__ mov(ecx, Immediate(key->handle()));
|
1382
1385
|
__ mov(edx, Operand(esp, 0));
|
1383
|
-
Handle<Code> ic(
|
1386
|
+
Handle<Code> ic = is_strict_mode()
|
1387
|
+
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
1388
|
+
: isolate()->builtins()->StoreIC_Initialize();
|
1384
1389
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
1385
1390
|
PrepareForBailoutForId(key->id(), NO_REGISTERS);
|
1386
1391
|
} else {
|
@@ -1394,7 +1399,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
|
1394
1399
|
VisitForStackValue(key);
|
1395
1400
|
VisitForStackValue(value);
|
1396
1401
|
if (property->emit_store()) {
|
1397
|
-
__
|
1402
|
+
__ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes
|
1403
|
+
__ CallRuntime(Runtime::kSetProperty, 4);
|
1398
1404
|
} else {
|
1399
1405
|
__ Drop(3);
|
1400
1406
|
}
|
@@ -1413,6 +1419,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
|
1413
1419
|
}
|
1414
1420
|
}
|
1415
1421
|
|
1422
|
+
if (expr->has_function()) {
|
1423
|
+
ASSERT(result_saved);
|
1424
|
+
__ push(Operand(esp, 0));
|
1425
|
+
__ CallRuntime(Runtime::kToFastProperties, 1);
|
1426
|
+
}
|
1427
|
+
|
1416
1428
|
if (result_saved) {
|
1417
1429
|
context()->PlugTOS();
|
1418
1430
|
} else {
|
@@ -1431,12 +1443,13 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
|
1431
1443
|
__ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
|
1432
1444
|
__ push(Immediate(Smi::FromInt(expr->literal_index())));
|
1433
1445
|
__ push(Immediate(expr->constant_elements()));
|
1434
|
-
if (expr->constant_elements()->map() ==
|
1446
|
+
if (expr->constant_elements()->map() ==
|
1447
|
+
isolate()->heap()->fixed_cow_array_map()) {
|
1435
1448
|
ASSERT(expr->depth() == 1);
|
1436
1449
|
FastCloneShallowArrayStub stub(
|
1437
1450
|
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
|
1438
1451
|
__ CallStub(&stub);
|
1439
|
-
__ IncrementCounter(
|
1452
|
+
__ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(), 1);
|
1440
1453
|
} else if (expr->depth() > 1) {
|
1441
1454
|
__ CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
1442
1455
|
} else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
|
@@ -1550,36 +1563,29 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
1550
1563
|
}
|
1551
1564
|
}
|
1552
1565
|
|
1566
|
+
// For compound assignments we need another deoptimization point after the
|
1567
|
+
// variable/property load.
|
1553
1568
|
if (expr->is_compound()) {
|
1554
1569
|
{ AccumulatorValueContext context(this);
|
1555
1570
|
switch (assign_type) {
|
1556
1571
|
case VARIABLE:
|
1557
1572
|
EmitVariableLoad(expr->target()->AsVariableProxy()->var());
|
1573
|
+
PrepareForBailout(expr->target(), TOS_REG);
|
1558
1574
|
break;
|
1559
1575
|
case NAMED_PROPERTY:
|
1560
1576
|
EmitNamedPropertyLoad(property);
|
1577
|
+
PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
|
1561
1578
|
break;
|
1562
1579
|
case KEYED_PROPERTY:
|
1563
1580
|
EmitKeyedPropertyLoad(property);
|
1581
|
+
PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
|
1564
1582
|
break;
|
1565
1583
|
}
|
1566
1584
|
}
|
1567
1585
|
|
1568
|
-
// For property compound assignments we need another deoptimization
|
1569
|
-
// point after the property load.
|
1570
|
-
if (property != NULL) {
|
1571
|
-
PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
|
1572
|
-
}
|
1573
|
-
|
1574
1586
|
Token::Value op = expr->binary_op();
|
1575
|
-
|
1576
|
-
|
1577
|
-
: kNoConstants;
|
1578
|
-
ASSERT(constant == kRightConstant || constant == kNoConstants);
|
1579
|
-
if (constant == kNoConstants) {
|
1580
|
-
__ push(eax); // Left operand goes on the stack.
|
1581
|
-
VisitForAccumulatorValue(expr->value());
|
1582
|
-
}
|
1587
|
+
__ push(eax); // Left operand goes on the stack.
|
1588
|
+
VisitForAccumulatorValue(expr->value());
|
1583
1589
|
|
1584
1590
|
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
|
1585
1591
|
? OVERWRITE_RIGHT
|
@@ -1591,8 +1597,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
|
1591
1597
|
op,
|
1592
1598
|
mode,
|
1593
1599
|
expr->target(),
|
1594
|
-
expr->value()
|
1595
|
-
constant);
|
1600
|
+
expr->value());
|
1596
1601
|
} else {
|
1597
1602
|
EmitBinaryOp(op, mode);
|
1598
1603
|
}
|
@@ -1628,232 +1633,23 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
|
|
1628
1633
|
SetSourcePosition(prop->position());
|
1629
1634
|
Literal* key = prop->key()->AsLiteral();
|
1630
1635
|
__ mov(ecx, Immediate(key->handle()));
|
1631
|
-
Handle<Code> ic(
|
1636
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
1632
1637
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
1633
1638
|
}
|
1634
1639
|
|
1635
1640
|
|
1636
1641
|
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
|
1637
1642
|
SetSourcePosition(prop->position());
|
1638
|
-
Handle<Code> ic(
|
1643
|
+
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
1639
1644
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
1640
1645
|
}
|
1641
1646
|
|
1642
1647
|
|
1643
|
-
void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr,
|
1644
|
-
OverwriteMode mode,
|
1645
|
-
bool left_is_constant_smi,
|
1646
|
-
Smi* value) {
|
1647
|
-
NearLabel call_stub, done;
|
1648
|
-
// Optimistically add smi value with unknown object. If result overflows or is
|
1649
|
-
// not a smi then we had either a smi overflow or added a smi with a tagged
|
1650
|
-
// pointer.
|
1651
|
-
__ add(Operand(eax), Immediate(value));
|
1652
|
-
__ j(overflow, &call_stub);
|
1653
|
-
JumpPatchSite patch_site(masm_);
|
1654
|
-
patch_site.EmitJumpIfSmi(eax, &done);
|
1655
|
-
|
1656
|
-
// Undo the optimistic add operation and call the shared stub.
|
1657
|
-
__ bind(&call_stub);
|
1658
|
-
__ sub(Operand(eax), Immediate(value));
|
1659
|
-
TypeRecordingBinaryOpStub stub(Token::ADD, mode);
|
1660
|
-
if (left_is_constant_smi) {
|
1661
|
-
__ mov(edx, Immediate(value));
|
1662
|
-
} else {
|
1663
|
-
__ mov(edx, eax);
|
1664
|
-
__ mov(eax, Immediate(value));
|
1665
|
-
}
|
1666
|
-
EmitCallIC(stub.GetCode(), &patch_site);
|
1667
|
-
|
1668
|
-
__ bind(&done);
|
1669
|
-
context()->Plug(eax);
|
1670
|
-
}
|
1671
|
-
|
1672
|
-
|
1673
|
-
void FullCodeGenerator::EmitConstantSmiSub(Expression* expr,
|
1674
|
-
OverwriteMode mode,
|
1675
|
-
bool left_is_constant_smi,
|
1676
|
-
Smi* value) {
|
1677
|
-
NearLabel call_stub, done;
|
1678
|
-
// Optimistically subtract smi value with unknown object. If result overflows
|
1679
|
-
// or is not a smi then we had either a smi overflow or added a smi with a
|
1680
|
-
// tagged pointer.
|
1681
|
-
if (left_is_constant_smi) {
|
1682
|
-
__ mov(ecx, eax);
|
1683
|
-
__ mov(eax, Immediate(value));
|
1684
|
-
__ sub(Operand(eax), ecx);
|
1685
|
-
} else {
|
1686
|
-
__ sub(Operand(eax), Immediate(value));
|
1687
|
-
}
|
1688
|
-
__ j(overflow, &call_stub);
|
1689
|
-
JumpPatchSite patch_site(masm_);
|
1690
|
-
patch_site.EmitJumpIfSmi(eax, &done);
|
1691
|
-
|
1692
|
-
__ bind(&call_stub);
|
1693
|
-
if (left_is_constant_smi) {
|
1694
|
-
__ mov(edx, Immediate(value));
|
1695
|
-
__ mov(eax, ecx);
|
1696
|
-
} else {
|
1697
|
-
__ add(Operand(eax), Immediate(value)); // Undo the subtraction.
|
1698
|
-
__ mov(edx, eax);
|
1699
|
-
__ mov(eax, Immediate(value));
|
1700
|
-
}
|
1701
|
-
TypeRecordingBinaryOpStub stub(Token::SUB, mode);
|
1702
|
-
EmitCallIC(stub.GetCode(), &patch_site);
|
1703
|
-
|
1704
|
-
__ bind(&done);
|
1705
|
-
context()->Plug(eax);
|
1706
|
-
}
|
1707
|
-
|
1708
|
-
|
1709
|
-
void FullCodeGenerator::EmitConstantSmiShiftOp(Expression* expr,
|
1710
|
-
Token::Value op,
|
1711
|
-
OverwriteMode mode,
|
1712
|
-
Smi* value) {
|
1713
|
-
NearLabel call_stub, smi_case, done;
|
1714
|
-
int shift_value = value->value() & 0x1f;
|
1715
|
-
|
1716
|
-
JumpPatchSite patch_site(masm_);
|
1717
|
-
patch_site.EmitJumpIfSmi(eax, &smi_case);
|
1718
|
-
|
1719
|
-
// Call stub.
|
1720
|
-
__ bind(&call_stub);
|
1721
|
-
__ mov(edx, eax);
|
1722
|
-
__ mov(eax, Immediate(value));
|
1723
|
-
TypeRecordingBinaryOpStub stub(op, mode);
|
1724
|
-
EmitCallIC(stub.GetCode(), &patch_site);
|
1725
|
-
__ jmp(&done);
|
1726
|
-
|
1727
|
-
// Smi case.
|
1728
|
-
__ bind(&smi_case);
|
1729
|
-
switch (op) {
|
1730
|
-
case Token::SHL:
|
1731
|
-
if (shift_value != 0) {
|
1732
|
-
__ mov(edx, eax);
|
1733
|
-
if (shift_value > 1) {
|
1734
|
-
__ shl(edx, shift_value - 1);
|
1735
|
-
}
|
1736
|
-
// Convert int result to smi, checking that it is in int range.
|
1737
|
-
STATIC_ASSERT(kSmiTagSize == 1); // Adjust code if not the case.
|
1738
|
-
__ add(edx, Operand(edx));
|
1739
|
-
__ j(overflow, &call_stub);
|
1740
|
-
__ mov(eax, edx); // Put result back into eax.
|
1741
|
-
}
|
1742
|
-
break;
|
1743
|
-
case Token::SAR:
|
1744
|
-
if (shift_value != 0) {
|
1745
|
-
__ sar(eax, shift_value);
|
1746
|
-
__ and_(eax, ~kSmiTagMask);
|
1747
|
-
}
|
1748
|
-
break;
|
1749
|
-
case Token::SHR:
|
1750
|
-
// SHR must return a positive value. When shifting by 0 or 1 we need to
|
1751
|
-
// check that smi tagging the result will not create a negative value.
|
1752
|
-
if (shift_value < 2) {
|
1753
|
-
__ mov(edx, eax);
|
1754
|
-
__ SmiUntag(edx);
|
1755
|
-
__ shr(edx, shift_value);
|
1756
|
-
__ test(edx, Immediate(0xc0000000));
|
1757
|
-
__ j(not_zero, &call_stub);
|
1758
|
-
__ SmiTag(edx);
|
1759
|
-
__ mov(eax, edx); // Put result back into eax.
|
1760
|
-
} else {
|
1761
|
-
__ SmiUntag(eax);
|
1762
|
-
__ shr(eax, shift_value);
|
1763
|
-
__ SmiTag(eax);
|
1764
|
-
}
|
1765
|
-
break;
|
1766
|
-
default:
|
1767
|
-
UNREACHABLE();
|
1768
|
-
}
|
1769
|
-
|
1770
|
-
__ bind(&done);
|
1771
|
-
context()->Plug(eax);
|
1772
|
-
}
|
1773
|
-
|
1774
|
-
|
1775
|
-
void FullCodeGenerator::EmitConstantSmiBitOp(Expression* expr,
|
1776
|
-
Token::Value op,
|
1777
|
-
OverwriteMode mode,
|
1778
|
-
Smi* value) {
|
1779
|
-
NearLabel smi_case, done;
|
1780
|
-
|
1781
|
-
JumpPatchSite patch_site(masm_);
|
1782
|
-
patch_site.EmitJumpIfSmi(eax, &smi_case);
|
1783
|
-
|
1784
|
-
// The order of the arguments does not matter for bit-ops with a
|
1785
|
-
// constant operand.
|
1786
|
-
__ mov(edx, Immediate(value));
|
1787
|
-
TypeRecordingBinaryOpStub stub(op, mode);
|
1788
|
-
EmitCallIC(stub.GetCode(), &patch_site);
|
1789
|
-
__ jmp(&done);
|
1790
|
-
|
1791
|
-
// Smi case.
|
1792
|
-
__ bind(&smi_case);
|
1793
|
-
switch (op) {
|
1794
|
-
case Token::BIT_OR:
|
1795
|
-
__ or_(Operand(eax), Immediate(value));
|
1796
|
-
break;
|
1797
|
-
case Token::BIT_XOR:
|
1798
|
-
__ xor_(Operand(eax), Immediate(value));
|
1799
|
-
break;
|
1800
|
-
case Token::BIT_AND:
|
1801
|
-
__ and_(Operand(eax), Immediate(value));
|
1802
|
-
break;
|
1803
|
-
default:
|
1804
|
-
UNREACHABLE();
|
1805
|
-
}
|
1806
|
-
|
1807
|
-
__ bind(&done);
|
1808
|
-
context()->Plug(eax);
|
1809
|
-
}
|
1810
|
-
|
1811
|
-
|
1812
|
-
void FullCodeGenerator::EmitConstantSmiBinaryOp(Expression* expr,
|
1813
|
-
Token::Value op,
|
1814
|
-
OverwriteMode mode,
|
1815
|
-
bool left_is_constant_smi,
|
1816
|
-
Smi* value) {
|
1817
|
-
switch (op) {
|
1818
|
-
case Token::BIT_OR:
|
1819
|
-
case Token::BIT_XOR:
|
1820
|
-
case Token::BIT_AND:
|
1821
|
-
EmitConstantSmiBitOp(expr, op, mode, value);
|
1822
|
-
break;
|
1823
|
-
case Token::SHL:
|
1824
|
-
case Token::SAR:
|
1825
|
-
case Token::SHR:
|
1826
|
-
ASSERT(!left_is_constant_smi);
|
1827
|
-
EmitConstantSmiShiftOp(expr, op, mode, value);
|
1828
|
-
break;
|
1829
|
-
case Token::ADD:
|
1830
|
-
EmitConstantSmiAdd(expr, mode, left_is_constant_smi, value);
|
1831
|
-
break;
|
1832
|
-
case Token::SUB:
|
1833
|
-
EmitConstantSmiSub(expr, mode, left_is_constant_smi, value);
|
1834
|
-
break;
|
1835
|
-
default:
|
1836
|
-
UNREACHABLE();
|
1837
|
-
}
|
1838
|
-
}
|
1839
|
-
|
1840
|
-
|
1841
1648
|
void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
|
1842
1649
|
Token::Value op,
|
1843
1650
|
OverwriteMode mode,
|
1844
1651
|
Expression* left,
|
1845
|
-
Expression* right
|
1846
|
-
ConstantOperand constant) {
|
1847
|
-
if (constant == kRightConstant) {
|
1848
|
-
Smi* value = Smi::cast(*right->AsLiteral()->handle());
|
1849
|
-
EmitConstantSmiBinaryOp(expr, op, mode, false, value);
|
1850
|
-
return;
|
1851
|
-
} else if (constant == kLeftConstant) {
|
1852
|
-
Smi* value = Smi::cast(*left->AsLiteral()->handle());
|
1853
|
-
EmitConstantSmiBinaryOp(expr, op, mode, true, value);
|
1854
|
-
return;
|
1855
|
-
}
|
1856
|
-
|
1652
|
+
Expression* right) {
|
1857
1653
|
// Do combined smi check of the operands. Left operand is on the
|
1858
1654
|
// stack. Right operand is in eax.
|
1859
1655
|
NearLabel done, smi_case, stub_call;
|
@@ -1985,7 +1781,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
|
|
1985
1781
|
__ mov(edx, eax);
|
1986
1782
|
__ pop(eax); // Restore value.
|
1987
1783
|
__ mov(ecx, prop->key()->AsLiteral()->handle());
|
1988
|
-
Handle<Code> ic(
|
1784
|
+
Handle<Code> ic = is_strict_mode()
|
1785
|
+
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
1786
|
+
: isolate()->builtins()->StoreIC_Initialize();
|
1989
1787
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
1990
1788
|
break;
|
1991
1789
|
}
|
@@ -2006,7 +1804,9 @@ void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
|
|
2006
1804
|
__ pop(edx);
|
2007
1805
|
}
|
2008
1806
|
__ pop(eax); // Restore value.
|
2009
|
-
Handle<Code> ic(
|
1807
|
+
Handle<Code> ic = is_strict_mode()
|
1808
|
+
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
1809
|
+
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
2010
1810
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
2011
1811
|
break;
|
2012
1812
|
}
|
@@ -2030,9 +1830,9 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
|
2030
1830
|
// ecx, and the global object on the stack.
|
2031
1831
|
__ mov(ecx, var->name());
|
2032
1832
|
__ mov(edx, GlobalObjectOperand());
|
2033
|
-
Handle<Code> ic(
|
2034
|
-
|
2035
|
-
|
1833
|
+
Handle<Code> ic = is_strict_mode()
|
1834
|
+
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
1835
|
+
: isolate()->builtins()->StoreIC_Initialize();
|
2036
1836
|
EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
|
2037
1837
|
|
2038
1838
|
} else if (op == Token::INIT_CONST) {
|
@@ -2049,14 +1849,14 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
|
2049
1849
|
break;
|
2050
1850
|
case Slot::LOCAL:
|
2051
1851
|
__ mov(edx, Operand(ebp, SlotOffset(slot)));
|
2052
|
-
__ cmp(edx,
|
1852
|
+
__ cmp(edx, isolate()->factory()->the_hole_value());
|
2053
1853
|
__ j(not_equal, &skip);
|
2054
1854
|
__ mov(Operand(ebp, SlotOffset(slot)), eax);
|
2055
1855
|
break;
|
2056
1856
|
case Slot::CONTEXT: {
|
2057
1857
|
__ mov(ecx, ContextOperand(esi, Context::FCONTEXT_INDEX));
|
2058
1858
|
__ mov(edx, ContextOperand(ecx, slot->index()));
|
2059
|
-
__ cmp(edx,
|
1859
|
+
__ cmp(edx, isolate()->factory()->the_hole_value());
|
2060
1860
|
__ j(not_equal, &skip);
|
2061
1861
|
__ mov(ContextOperand(ecx, slot->index()), eax);
|
2062
1862
|
int offset = Context::SlotOffset(slot->index());
|
@@ -2101,7 +1901,8 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
|
|
2101
1901
|
__ push(eax); // Value.
|
2102
1902
|
__ push(esi); // Context.
|
2103
1903
|
__ push(Immediate(var->name()));
|
2104
|
-
__
|
1904
|
+
__ push(Immediate(Smi::FromInt(strict_mode_flag())));
|
1905
|
+
__ CallRuntime(Runtime::kStoreContextSlot, 4);
|
2105
1906
|
break;
|
2106
1907
|
}
|
2107
1908
|
}
|
@@ -2132,7 +1933,9 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
|
|
2132
1933
|
} else {
|
2133
1934
|
__ pop(edx);
|
2134
1935
|
}
|
2135
|
-
Handle<Code> ic(
|
1936
|
+
Handle<Code> ic = is_strict_mode()
|
1937
|
+
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
1938
|
+
: isolate()->builtins()->StoreIC_Initialize();
|
2136
1939
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
2137
1940
|
|
2138
1941
|
// If the assignment ends an initialization block, revert to fast case.
|
@@ -2170,7 +1973,9 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
|
|
2170
1973
|
}
|
2171
1974
|
// Record source code position before IC call.
|
2172
1975
|
SetSourcePosition(expr->position());
|
2173
|
-
Handle<Code> ic(
|
1976
|
+
Handle<Code> ic = is_strict_mode()
|
1977
|
+
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
1978
|
+
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
2174
1979
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
2175
1980
|
|
2176
1981
|
// If the assignment ends an initialization block, revert to fast case.
|
@@ -2220,7 +2025,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
|
|
2220
2025
|
// Record source position of the IC call.
|
2221
2026
|
SetSourcePosition(expr->position());
|
2222
2027
|
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
2223
|
-
Handle<Code> ic =
|
2028
|
+
Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
|
2029
|
+
arg_count, in_loop);
|
2224
2030
|
EmitCallIC(ic, mode);
|
2225
2031
|
RecordJSReturnSite(expr);
|
2226
2032
|
// Restore context register.
|
@@ -2252,7 +2058,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
|
|
2252
2058
|
// Record source position of the IC call.
|
2253
2059
|
SetSourcePosition(expr->position());
|
2254
2060
|
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
2255
|
-
Handle<Code> ic =
|
2061
|
+
Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
|
2062
|
+
arg_count, in_loop);
|
2256
2063
|
__ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
|
2257
2064
|
EmitCallIC(ic, mode);
|
2258
2065
|
RecordJSReturnSite(expr);
|
@@ -2283,6 +2090,27 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr) {
|
|
2283
2090
|
}
|
2284
2091
|
|
2285
2092
|
|
2093
|
+
void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
|
2094
|
+
int arg_count) {
|
2095
|
+
// Push copy of the first argument or undefined if it doesn't exist.
|
2096
|
+
if (arg_count > 0) {
|
2097
|
+
__ push(Operand(esp, arg_count * kPointerSize));
|
2098
|
+
} else {
|
2099
|
+
__ push(Immediate(isolate()->factory()->undefined_value()));
|
2100
|
+
}
|
2101
|
+
|
2102
|
+
// Push the receiver of the enclosing function.
|
2103
|
+
__ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
|
2104
|
+
|
2105
|
+
// Push the strict mode flag.
|
2106
|
+
__ push(Immediate(Smi::FromInt(strict_mode_flag())));
|
2107
|
+
|
2108
|
+
__ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
|
2109
|
+
? Runtime::kResolvePossiblyDirectEvalNoLookup
|
2110
|
+
: Runtime::kResolvePossiblyDirectEval, 4);
|
2111
|
+
}
|
2112
|
+
|
2113
|
+
|
2286
2114
|
void FullCodeGenerator::VisitCall(Call* expr) {
|
2287
2115
|
#ifdef DEBUG
|
2288
2116
|
// We want to verify that RecordJSReturnSite gets called on all paths
|
@@ -2304,28 +2132,37 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
2304
2132
|
{ PreservePositionScope pos_scope(masm()->positions_recorder());
|
2305
2133
|
VisitForStackValue(fun);
|
2306
2134
|
// Reserved receiver slot.
|
2307
|
-
__ push(Immediate(
|
2135
|
+
__ push(Immediate(isolate()->factory()->undefined_value()));
|
2308
2136
|
|
2309
2137
|
// Push the arguments.
|
2310
2138
|
for (int i = 0; i < arg_count; i++) {
|
2311
2139
|
VisitForStackValue(args->at(i));
|
2312
2140
|
}
|
2313
2141
|
|
2314
|
-
//
|
2315
|
-
|
2316
|
-
|
2317
|
-
//
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
|
2142
|
+
// If we know that eval can only be shadowed by eval-introduced
|
2143
|
+
// variables we attempt to load the global eval function directly
|
2144
|
+
// in generated code. If we succeed, there is no need to perform a
|
2145
|
+
// context lookup in the runtime system.
|
2146
|
+
Label done;
|
2147
|
+
if (var->AsSlot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) {
|
2148
|
+
Label slow;
|
2149
|
+
EmitLoadGlobalSlotCheckExtensions(var->AsSlot(),
|
2150
|
+
NOT_INSIDE_TYPEOF,
|
2151
|
+
&slow);
|
2152
|
+
// Push the function and resolve eval.
|
2153
|
+
__ push(eax);
|
2154
|
+
EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count);
|
2155
|
+
__ jmp(&done);
|
2156
|
+
__ bind(&slow);
|
2322
2157
|
}
|
2323
2158
|
|
2324
|
-
// Push
|
2325
|
-
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2159
|
+
// Push copy of the function (found below the arguments) and
|
2160
|
+
// resolve eval.
|
2161
|
+
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
|
2162
|
+
EmitResolvePossiblyDirectEval(PERFORM_CONTEXT_LOOKUP, arg_count);
|
2163
|
+
if (done.is_linked()) {
|
2164
|
+
__ bind(&done);
|
2165
|
+
}
|
2329
2166
|
|
2330
2167
|
// The runtime call returns a pair of values in eax (function) and
|
2331
2168
|
// edx (receiver). Touch up the stack with the right values.
|
@@ -2390,7 +2227,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
2390
2227
|
Literal* key = prop->key()->AsLiteral();
|
2391
2228
|
if (key != NULL && key->handle()->IsSymbol()) {
|
2392
2229
|
// Call to a named property, use call IC.
|
2393
|
-
|
2230
|
+
{ PreservePositionScope scope(masm()->positions_recorder());
|
2231
|
+
VisitForStackValue(prop->obj());
|
2232
|
+
}
|
2394
2233
|
EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
|
2395
2234
|
} else {
|
2396
2235
|
// Call to a keyed property.
|
@@ -2412,7 +2251,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
2412
2251
|
// Record source code position for IC call.
|
2413
2252
|
SetSourcePosition(prop->position());
|
2414
2253
|
|
2415
|
-
Handle<Code> ic(
|
2254
|
+
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
|
2416
2255
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
2417
2256
|
// Push result (function).
|
2418
2257
|
__ push(eax);
|
@@ -2428,15 +2267,6 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
|
2428
2267
|
}
|
2429
2268
|
}
|
2430
2269
|
} else {
|
2431
|
-
// Call to some other expression. If the expression is an anonymous
|
2432
|
-
// function literal not called in a loop, mark it as one that should
|
2433
|
-
// also use the full code generator.
|
2434
|
-
FunctionLiteral* lit = fun->AsFunctionLiteral();
|
2435
|
-
if (lit != NULL &&
|
2436
|
-
lit->name()->Equals(Heap::empty_string()) &&
|
2437
|
-
loop_depth() == 0) {
|
2438
|
-
lit->set_try_full_codegen(true);
|
2439
|
-
}
|
2440
2270
|
{ PreservePositionScope scope(masm()->positions_recorder());
|
2441
2271
|
VisitForStackValue(fun);
|
2442
2272
|
}
|
@@ -2480,7 +2310,8 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
|
2480
2310
|
__ Set(eax, Immediate(arg_count));
|
2481
2311
|
__ mov(edi, Operand(esp, arg_count * kPointerSize));
|
2482
2312
|
|
2483
|
-
Handle<Code> construct_builtin
|
2313
|
+
Handle<Code> construct_builtin =
|
2314
|
+
isolate()->builtins()->JSConstructCall();
|
2484
2315
|
__ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
|
2485
2316
|
context()->Plug(eax);
|
2486
2317
|
}
|
@@ -2540,7 +2371,7 @@ void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
|
|
2540
2371
|
|
2541
2372
|
__ test(eax, Immediate(kSmiTagMask));
|
2542
2373
|
__ j(zero, if_false);
|
2543
|
-
__ cmp(eax,
|
2374
|
+
__ cmp(eax, isolate()->factory()->null_value());
|
2544
2375
|
__ j(equal, if_true);
|
2545
2376
|
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
2546
2377
|
// Undetectable objects behave like undefined when tested with typeof.
|
@@ -2617,10 +2448,73 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
|
|
2617
2448
|
context()->PrepareTest(&materialize_true, &materialize_false,
|
2618
2449
|
&if_true, &if_false, &fall_through);
|
2619
2450
|
|
2620
|
-
|
2621
|
-
|
2451
|
+
if (FLAG_debug_code) __ AbortIfSmi(eax);
|
2452
|
+
|
2453
|
+
// Check whether this map has already been checked to be safe for default
|
2454
|
+
// valueOf.
|
2455
|
+
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
2456
|
+
__ test_b(FieldOperand(ebx, Map::kBitField2Offset),
|
2457
|
+
1 << Map::kStringWrapperSafeForDefaultValueOf);
|
2458
|
+
__ j(not_zero, if_true);
|
2459
|
+
|
2460
|
+
// Check for fast case object. Return false for slow case objects.
|
2461
|
+
__ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset));
|
2462
|
+
__ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
|
2463
|
+
__ cmp(ecx, FACTORY->hash_table_map());
|
2464
|
+
__ j(equal, if_false);
|
2465
|
+
|
2466
|
+
// Look for valueOf symbol in the descriptor array, and indicate false if
|
2467
|
+
// found. The type is not checked, so if it is a transition it is a false
|
2468
|
+
// negative.
|
2469
|
+
__ mov(ebx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset));
|
2470
|
+
__ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
|
2471
|
+
// ebx: descriptor array
|
2472
|
+
// ecx: length of descriptor array
|
2473
|
+
// Calculate the end of the descriptor array.
|
2474
|
+
STATIC_ASSERT(kSmiTag == 0);
|
2475
|
+
STATIC_ASSERT(kSmiTagSize == 1);
|
2476
|
+
STATIC_ASSERT(kPointerSize == 4);
|
2477
|
+
__ lea(ecx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
|
2478
|
+
// Calculate location of the first key name.
|
2479
|
+
__ add(Operand(ebx),
|
2480
|
+
Immediate(FixedArray::kHeaderSize +
|
2481
|
+
DescriptorArray::kFirstIndex * kPointerSize));
|
2482
|
+
// Loop through all the keys in the descriptor array. If one of these is the
|
2483
|
+
// symbol valueOf the result is false.
|
2484
|
+
Label entry, loop;
|
2485
|
+
__ jmp(&entry);
|
2486
|
+
__ bind(&loop);
|
2487
|
+
__ mov(edx, FieldOperand(ebx, 0));
|
2488
|
+
__ cmp(edx, FACTORY->value_of_symbol());
|
2489
|
+
__ j(equal, if_false);
|
2490
|
+
__ add(Operand(ebx), Immediate(kPointerSize));
|
2491
|
+
__ bind(&entry);
|
2492
|
+
__ cmp(ebx, Operand(ecx));
|
2493
|
+
__ j(not_equal, &loop);
|
2494
|
+
|
2495
|
+
// Reload map as register ebx was used as temporary above.
|
2496
|
+
__ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
2497
|
+
|
2498
|
+
// If a valueOf property is not found on the object check that it's
|
2499
|
+
// prototype is the un-modified String prototype. If not result is false.
|
2500
|
+
__ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
|
2501
|
+
__ test(ecx, Immediate(kSmiTagMask));
|
2502
|
+
__ j(zero, if_false);
|
2503
|
+
__ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
|
2504
|
+
__ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
|
2505
|
+
__ mov(edx,
|
2506
|
+
FieldOperand(edx, GlobalObject::kGlobalContextOffset));
|
2507
|
+
__ cmp(ecx,
|
2508
|
+
ContextOperand(edx,
|
2509
|
+
Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
|
2510
|
+
__ j(not_equal, if_false);
|
2511
|
+
// Set the bit in the map to indicate that it has been checked safe for
|
2512
|
+
// default valueOf and set true result.
|
2513
|
+
__ or_(FieldOperand(ebx, Map::kBitField2Offset),
|
2514
|
+
Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
|
2515
|
+
__ jmp(if_true);
|
2516
|
+
|
2622
2517
|
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
2623
|
-
__ jmp(if_false);
|
2624
2518
|
context()->Plug(if_true, if_false);
|
2625
2519
|
}
|
2626
2520
|
|
@@ -2819,17 +2713,17 @@ void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
|
|
2819
2713
|
|
2820
2714
|
// Functions have class 'Function'.
|
2821
2715
|
__ bind(&function);
|
2822
|
-
__ mov(eax,
|
2716
|
+
__ mov(eax, isolate()->factory()->function_class_symbol());
|
2823
2717
|
__ jmp(&done);
|
2824
2718
|
|
2825
2719
|
// Objects with a non-function constructor have class 'Object'.
|
2826
2720
|
__ bind(&non_function_constructor);
|
2827
|
-
__ mov(eax,
|
2721
|
+
__ mov(eax, isolate()->factory()->Object_symbol());
|
2828
2722
|
__ jmp(&done);
|
2829
2723
|
|
2830
2724
|
// Non-JS objects have class null.
|
2831
2725
|
__ bind(&null);
|
2832
|
-
__ mov(eax,
|
2726
|
+
__ mov(eax, isolate()->factory()->null_value());
|
2833
2727
|
|
2834
2728
|
// All done.
|
2835
2729
|
__ bind(&done);
|
@@ -2855,7 +2749,7 @@ void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) {
|
|
2855
2749
|
}
|
2856
2750
|
#endif
|
2857
2751
|
// Finally, we're expected to leave a value on the top of the stack.
|
2858
|
-
__ mov(eax,
|
2752
|
+
__ mov(eax, isolate()->factory()->undefined_value());
|
2859
2753
|
context()->Plug(eax);
|
2860
2754
|
}
|
2861
2755
|
|
@@ -2876,8 +2770,10 @@ void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) {
|
|
2876
2770
|
|
2877
2771
|
__ bind(&heapnumber_allocated);
|
2878
2772
|
|
2879
|
-
__ PrepareCallCFunction(
|
2880
|
-
__
|
2773
|
+
__ PrepareCallCFunction(1, ebx);
|
2774
|
+
__ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address()));
|
2775
|
+
__ CallCFunction(ExternalReference::random_uint32_function(isolate()),
|
2776
|
+
1);
|
2881
2777
|
|
2882
2778
|
// Convert 32 random bits in eax to 0.(32 random bits) in a double
|
2883
2779
|
// by computing:
|
@@ -2958,8 +2854,12 @@ void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
|
|
2958
2854
|
VisitForStackValue(args->at(0));
|
2959
2855
|
VisitForStackValue(args->at(1));
|
2960
2856
|
|
2961
|
-
|
2962
|
-
|
2857
|
+
if (CpuFeatures::IsSupported(SSE2)) {
|
2858
|
+
MathPowStub stub;
|
2859
|
+
__ CallStub(&stub);
|
2860
|
+
} else {
|
2861
|
+
__ CallRuntime(Runtime::kMath_pow, 2);
|
2862
|
+
}
|
2963
2863
|
context()->Plug(eax);
|
2964
2864
|
}
|
2965
2865
|
|
@@ -3052,13 +2952,13 @@ void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
|
|
3052
2952
|
__ bind(&index_out_of_range);
|
3053
2953
|
// When the index is out of range, the spec requires us to return
|
3054
2954
|
// NaN.
|
3055
|
-
__ Set(result, Immediate(
|
2955
|
+
__ Set(result, Immediate(isolate()->factory()->nan_value()));
|
3056
2956
|
__ jmp(&done);
|
3057
2957
|
|
3058
2958
|
__ bind(&need_conversion);
|
3059
2959
|
// Move the undefined value into the result register, which will
|
3060
2960
|
// trigger conversion.
|
3061
|
-
__ Set(result, Immediate(
|
2961
|
+
__ Set(result, Immediate(isolate()->factory()->undefined_value()));
|
3062
2962
|
__ jmp(&done);
|
3063
2963
|
|
3064
2964
|
NopRuntimeCallHelper call_helper;
|
@@ -3101,7 +3001,7 @@ void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
|
|
3101
3001
|
__ bind(&index_out_of_range);
|
3102
3002
|
// When the index is out of range, the spec requires us to return
|
3103
3003
|
// the empty string.
|
3104
|
-
__ Set(result, Immediate(
|
3004
|
+
__ Set(result, Immediate(isolate()->factory()->empty_string()));
|
3105
3005
|
__ jmp(&done);
|
3106
3006
|
|
3107
3007
|
__ bind(&need_conversion);
|
@@ -3231,8 +3131,8 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
|
3231
3131
|
// Fetch the map and check if array is in fast case.
|
3232
3132
|
// Check that object doesn't require security checks and
|
3233
3133
|
// has no indexed interceptor.
|
3234
|
-
__ CmpObjectType(object,
|
3235
|
-
__ j(
|
3134
|
+
__ CmpObjectType(object, JS_ARRAY_TYPE, temp);
|
3135
|
+
__ j(not_equal, &slow_case);
|
3236
3136
|
__ test_b(FieldOperand(temp, Map::kBitFieldOffset),
|
3237
3137
|
KeyedLoadIC::kSlowCaseBitFieldMask);
|
3238
3138
|
__ j(not_zero, &slow_case);
|
@@ -3240,7 +3140,7 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
|
3240
3140
|
// Check the object's elements are in fast case and writable.
|
3241
3141
|
__ mov(elements, FieldOperand(object, JSObject::kElementsOffset));
|
3242
3142
|
__ cmp(FieldOperand(elements, HeapObject::kMapOffset),
|
3243
|
-
Immediate(
|
3143
|
+
Immediate(isolate()->factory()->fixed_array_map()));
|
3244
3144
|
__ j(not_equal, &slow_case);
|
3245
3145
|
|
3246
3146
|
// Check that both indices are smis.
|
@@ -3278,7 +3178,7 @@ void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) {
|
|
3278
3178
|
__ bind(&new_space);
|
3279
3179
|
// We are done. Drop elements from the stack, and return undefined.
|
3280
3180
|
__ add(Operand(esp), Immediate(3 * kPointerSize));
|
3281
|
-
__ mov(eax,
|
3181
|
+
__ mov(eax, isolate()->factory()->undefined_value());
|
3282
3182
|
__ jmp(&done);
|
3283
3183
|
|
3284
3184
|
__ bind(&slow_case);
|
@@ -3296,10 +3196,10 @@ void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) {
|
|
3296
3196
|
int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
|
3297
3197
|
|
3298
3198
|
Handle<FixedArray> jsfunction_result_caches(
|
3299
|
-
|
3199
|
+
isolate()->global_context()->jsfunction_result_caches());
|
3300
3200
|
if (jsfunction_result_caches->length() <= cache_id) {
|
3301
3201
|
__ Abort("Attempt to use undefined cache.");
|
3302
|
-
__ mov(eax,
|
3202
|
+
__ mov(eax, isolate()->factory()->undefined_value());
|
3303
3203
|
context()->Plug(eax);
|
3304
3204
|
return;
|
3305
3205
|
}
|
@@ -3356,7 +3256,8 @@ void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
|
|
3356
3256
|
__ and_(Operand(tmp), right);
|
3357
3257
|
__ test(Operand(tmp), Immediate(kSmiTagMask));
|
3358
3258
|
__ j(zero, &fail);
|
3359
|
-
__
|
3259
|
+
__ mov(tmp, FieldOperand(left, HeapObject::kMapOffset));
|
3260
|
+
__ CmpInstanceType(tmp, JS_REGEXP_TYPE);
|
3360
3261
|
__ j(not_equal, &fail);
|
3361
3262
|
__ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset));
|
3362
3263
|
__ j(not_equal, &fail);
|
@@ -3364,10 +3265,10 @@ void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) {
|
|
3364
3265
|
__ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
|
3365
3266
|
__ j(equal, &ok);
|
3366
3267
|
__ bind(&fail);
|
3367
|
-
__ mov(eax, Immediate(
|
3268
|
+
__ mov(eax, Immediate(isolate()->factory()->false_value()));
|
3368
3269
|
__ jmp(&done);
|
3369
3270
|
__ bind(&ok);
|
3370
|
-
__ mov(eax, Immediate(
|
3271
|
+
__ mov(eax, Immediate(isolate()->factory()->true_value()));
|
3371
3272
|
__ bind(&done);
|
3372
3273
|
|
3373
3274
|
context()->Plug(eax);
|
@@ -3401,7 +3302,6 @@ void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) {
|
|
3401
3302
|
|
3402
3303
|
void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) {
|
3403
3304
|
ASSERT(args->length() == 1);
|
3404
|
-
|
3405
3305
|
VisitForAccumulatorValue(args->at(0));
|
3406
3306
|
|
3407
3307
|
if (FLAG_debug_code) {
|
@@ -3417,7 +3317,7 @@ void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) {
|
|
3417
3317
|
|
3418
3318
|
void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
3419
3319
|
Label bailout, done, one_char_separator, long_separator,
|
3420
|
-
non_trivial_array, not_size_one_array, loop,
|
3320
|
+
non_trivial_array, not_size_one_array, loop,
|
3421
3321
|
loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry;
|
3422
3322
|
|
3423
3323
|
ASSERT(args->length() == 2);
|
@@ -3459,9 +3359,9 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
|
3459
3359
|
|
3460
3360
|
// If the array has length zero, return the empty string.
|
3461
3361
|
__ mov(array_length, FieldOperand(array, JSArray::kLengthOffset));
|
3462
|
-
__
|
3362
|
+
__ SmiUntag(array_length);
|
3463
3363
|
__ j(not_zero, &non_trivial_array);
|
3464
|
-
__ mov(result_operand,
|
3364
|
+
__ mov(result_operand, isolate()->factory()->empty_string());
|
3465
3365
|
__ jmp(&done);
|
3466
3366
|
|
3467
3367
|
// Save the array length.
|
@@ -3482,14 +3382,15 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
|
3482
3382
|
// Loop condition: while (index < length).
|
3483
3383
|
// Live loop registers: index, array_length, string,
|
3484
3384
|
// scratch, string_length, elements.
|
3485
|
-
|
3385
|
+
if (FLAG_debug_code) {
|
3386
|
+
__ cmp(index, Operand(array_length));
|
3387
|
+
__ Assert(less, "No empty arrays here in EmitFastAsciiArrayJoin");
|
3388
|
+
}
|
3486
3389
|
__ bind(&loop);
|
3487
|
-
__
|
3488
|
-
|
3489
|
-
|
3490
|
-
|
3491
|
-
times_pointer_size,
|
3492
|
-
FixedArray::kHeaderSize));
|
3390
|
+
__ mov(string, FieldOperand(elements,
|
3391
|
+
index,
|
3392
|
+
times_pointer_size,
|
3393
|
+
FixedArray::kHeaderSize));
|
3493
3394
|
__ test(string, Immediate(kSmiTagMask));
|
3494
3395
|
__ j(zero, &bailout);
|
3495
3396
|
__ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
|
@@ -3502,7 +3403,6 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
|
3502
3403
|
FieldOperand(string, SeqAsciiString::kLengthOffset));
|
3503
3404
|
__ j(overflow, &bailout);
|
3504
3405
|
__ add(Operand(index), Immediate(1));
|
3505
|
-
__ bind(&loop_condition);
|
3506
3406
|
__ cmp(index, Operand(array_length));
|
3507
3407
|
__ j(less, &loop);
|
3508
3408
|
|
@@ -3531,7 +3431,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
|
3531
3431
|
__ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
|
3532
3432
|
__ and_(scratch, Immediate(
|
3533
3433
|
kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
|
3534
|
-
__ cmp(scratch,
|
3434
|
+
__ cmp(scratch, ASCII_STRING_TYPE);
|
3535
3435
|
__ j(not_equal, &bailout);
|
3536
3436
|
|
3537
3437
|
// Add (separator length times array_length) - separator length
|
@@ -3672,7 +3572,7 @@ void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
|
|
3672
3572
|
|
3673
3573
|
|
3674
3574
|
__ bind(&bailout);
|
3675
|
-
__ mov(result_operand,
|
3575
|
+
__ mov(result_operand, isolate()->factory()->undefined_value());
|
3676
3576
|
__ bind(&done);
|
3677
3577
|
__ mov(eax, result_operand);
|
3678
3578
|
// Drop temp values from the stack, and restore context register.
|
@@ -3710,7 +3610,8 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
|
|
3710
3610
|
// Call the JS runtime function via a call IC.
|
3711
3611
|
__ Set(ecx, Immediate(expr->name()));
|
3712
3612
|
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
|
3713
|
-
Handle<Code> ic =
|
3613
|
+
Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
|
3614
|
+
arg_count, in_loop);
|
3714
3615
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
3715
3616
|
// Restore context register.
|
3716
3617
|
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
|
@@ -3776,7 +3677,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
3776
3677
|
case Token::VOID: {
|
3777
3678
|
Comment cmnt(masm_, "[ UnaryOperation (VOID)");
|
3778
3679
|
VisitForEffect(expr->expression());
|
3779
|
-
context()->Plug(
|
3680
|
+
context()->Plug(isolate()->factory()->undefined_value());
|
3780
3681
|
break;
|
3781
3682
|
}
|
3782
3683
|
|
@@ -3791,6 +3692,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
|
|
3791
3692
|
Label* if_true = NULL;
|
3792
3693
|
Label* if_false = NULL;
|
3793
3694
|
Label* fall_through = NULL;
|
3695
|
+
|
3794
3696
|
// Notice that the labels are swapped.
|
3795
3697
|
context()->PrepareTest(&materialize_true, &materialize_false,
|
3796
3698
|
&if_false, &if_true, &fall_through);
|
@@ -3930,7 +3832,11 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
3930
3832
|
|
3931
3833
|
// We need a second deoptimization point after loading the value
|
3932
3834
|
// in case evaluating the property load my have a side effect.
|
3933
|
-
|
3835
|
+
if (assign_type == VARIABLE) {
|
3836
|
+
PrepareForBailout(expr->expression(), TOS_REG);
|
3837
|
+
} else {
|
3838
|
+
PrepareForBailout(expr->increment(), TOS_REG);
|
3839
|
+
}
|
3934
3840
|
|
3935
3841
|
// Call ToNumber only if operand is not a smi.
|
3936
3842
|
NearLabel no_conversion;
|
@@ -4023,7 +3929,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
4023
3929
|
case NAMED_PROPERTY: {
|
4024
3930
|
__ mov(ecx, prop->key()->AsLiteral()->handle());
|
4025
3931
|
__ pop(edx);
|
4026
|
-
Handle<Code> ic(
|
3932
|
+
Handle<Code> ic = is_strict_mode()
|
3933
|
+
? isolate()->builtins()->StoreIC_Initialize_Strict()
|
3934
|
+
: isolate()->builtins()->StoreIC_Initialize();
|
4027
3935
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
4028
3936
|
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
|
4029
3937
|
if (expr->is_postfix()) {
|
@@ -4038,7 +3946,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|
4038
3946
|
case KEYED_PROPERTY: {
|
4039
3947
|
__ pop(ecx);
|
4040
3948
|
__ pop(edx);
|
4041
|
-
Handle<Code> ic(
|
3949
|
+
Handle<Code> ic = is_strict_mode()
|
3950
|
+
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
|
3951
|
+
: isolate()->builtins()->KeyedStoreIC_Initialize();
|
4042
3952
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
4043
3953
|
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
|
4044
3954
|
if (expr->is_postfix()) {
|
@@ -4064,7 +3974,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
|
|
4064
3974
|
Comment cmnt(masm_, "Global variable");
|
4065
3975
|
__ mov(eax, GlobalObjectOperand());
|
4066
3976
|
__ mov(ecx, Immediate(proxy->name()));
|
4067
|
-
Handle<Code> ic(
|
3977
|
+
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
|
4068
3978
|
// Use a regular load, not a contextual load, to avoid a reference
|
4069
3979
|
// error.
|
4070
3980
|
EmitCallIC(ic, RelocInfo::CODE_TARGET);
|
@@ -4117,63 +4027,49 @@ bool FullCodeGenerator::TryLiteralCompare(Token::Value op,
|
|
4117
4027
|
}
|
4118
4028
|
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
4119
4029
|
|
4120
|
-
if (check->Equals(
|
4121
|
-
__
|
4122
|
-
__ j(zero, if_true);
|
4030
|
+
if (check->Equals(isolate()->heap()->number_symbol())) {
|
4031
|
+
__ JumpIfSmi(eax, if_true);
|
4123
4032
|
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
|
4124
|
-
|
4033
|
+
isolate()->factory()->heap_number_map());
|
4125
4034
|
Split(equal, if_true, if_false, fall_through);
|
4126
|
-
} else if (check->Equals(
|
4127
|
-
__
|
4128
|
-
__
|
4035
|
+
} else if (check->Equals(isolate()->heap()->string_symbol())) {
|
4036
|
+
__ JumpIfSmi(eax, if_false);
|
4037
|
+
__ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx);
|
4038
|
+
__ j(above_equal, if_false);
|
4129
4039
|
// Check for undetectable objects => false.
|
4130
|
-
__
|
4131
|
-
|
4132
|
-
|
4133
|
-
|
4134
|
-
__
|
4135
|
-
Split(below, if_true, if_false, fall_through);
|
4136
|
-
} else if (check->Equals(Heap::boolean_symbol())) {
|
4137
|
-
__ cmp(eax, Factory::true_value());
|
4040
|
+
__ test_b(FieldOperand(edx, Map::kBitFieldOffset),
|
4041
|
+
1 << Map::kIsUndetectable);
|
4042
|
+
Split(zero, if_true, if_false, fall_through);
|
4043
|
+
} else if (check->Equals(isolate()->heap()->boolean_symbol())) {
|
4044
|
+
__ cmp(eax, isolate()->factory()->true_value());
|
4138
4045
|
__ j(equal, if_true);
|
4139
|
-
__ cmp(eax,
|
4046
|
+
__ cmp(eax, isolate()->factory()->false_value());
|
4140
4047
|
Split(equal, if_true, if_false, fall_through);
|
4141
|
-
} else if (check->Equals(
|
4142
|
-
__ cmp(eax,
|
4048
|
+
} else if (check->Equals(isolate()->heap()->undefined_symbol())) {
|
4049
|
+
__ cmp(eax, isolate()->factory()->undefined_value());
|
4143
4050
|
__ j(equal, if_true);
|
4144
|
-
__
|
4145
|
-
__ j(zero, if_false);
|
4051
|
+
__ JumpIfSmi(eax, if_false);
|
4146
4052
|
// Check for undetectable objects => true.
|
4147
4053
|
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
|
4148
4054
|
__ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
|
4149
4055
|
__ test(ecx, Immediate(1 << Map::kIsUndetectable));
|
4150
4056
|
Split(not_zero, if_true, if_false, fall_through);
|
4151
|
-
} else if (check->Equals(
|
4152
|
-
__
|
4153
|
-
__
|
4154
|
-
|
4057
|
+
} else if (check->Equals(isolate()->heap()->function_symbol())) {
|
4058
|
+
__ JumpIfSmi(eax, if_false);
|
4059
|
+
__ CmpObjectType(eax, FIRST_FUNCTION_CLASS_TYPE, edx);
|
4060
|
+
Split(above_equal, if_true, if_false, fall_through);
|
4061
|
+
} else if (check->Equals(isolate()->heap()->object_symbol())) {
|
4062
|
+
__ JumpIfSmi(eax, if_false);
|
4063
|
+
__ cmp(eax, isolate()->factory()->null_value());
|
4155
4064
|
__ j(equal, if_true);
|
4156
|
-
|
4157
|
-
__
|
4158
|
-
|
4159
|
-
|
4160
|
-
__ test(eax, Immediate(kSmiTagMask));
|
4161
|
-
__ j(zero, if_false);
|
4162
|
-
__ cmp(eax, Factory::null_value());
|
4163
|
-
__ j(equal, if_true);
|
4164
|
-
// Regular expressions => 'function', not 'object'.
|
4165
|
-
__ CmpObjectType(eax, JS_REGEXP_TYPE, edx);
|
4166
|
-
__ j(equal, if_false);
|
4065
|
+
__ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edx);
|
4066
|
+
__ j(below, if_false);
|
4067
|
+
__ CmpInstanceType(edx, FIRST_FUNCTION_CLASS_TYPE);
|
4068
|
+
__ j(above_equal, if_false);
|
4167
4069
|
// Check for undetectable objects => false.
|
4168
|
-
__
|
4169
|
-
|
4170
|
-
|
4171
|
-
// Check for JS objects => true.
|
4172
|
-
__ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
|
4173
|
-
__ cmp(ecx, FIRST_JS_OBJECT_TYPE);
|
4174
|
-
__ j(less, if_false);
|
4175
|
-
__ cmp(ecx, LAST_JS_OBJECT_TYPE);
|
4176
|
-
Split(less_equal, if_true, if_false, fall_through);
|
4070
|
+
__ test_b(FieldOperand(edx, Map::kBitFieldOffset),
|
4071
|
+
1 << Map::kIsUndetectable);
|
4072
|
+
Split(zero, if_true, if_false, fall_through);
|
4177
4073
|
} else {
|
4178
4074
|
if (if_false != fall_through) __ jmp(if_false);
|
4179
4075
|
}
|
@@ -4212,7 +4108,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|
4212
4108
|
VisitForStackValue(expr->right());
|
4213
4109
|
__ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
|
4214
4110
|
PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL);
|
4215
|
-
__ cmp(eax,
|
4111
|
+
__ cmp(eax, isolate()->factory()->true_value());
|
4216
4112
|
Split(equal, if_true, if_false, fall_through);
|
4217
4113
|
break;
|
4218
4114
|
|
@@ -4305,12 +4201,12 @@ void FullCodeGenerator::VisitCompareToNull(CompareToNull* expr) {
|
|
4305
4201
|
VisitForAccumulatorValue(expr->expression());
|
4306
4202
|
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
|
4307
4203
|
|
4308
|
-
__ cmp(eax,
|
4204
|
+
__ cmp(eax, isolate()->factory()->null_value());
|
4309
4205
|
if (expr->is_strict()) {
|
4310
4206
|
Split(equal, if_true, if_false, fall_through);
|
4311
4207
|
} else {
|
4312
4208
|
__ j(equal, if_true);
|
4313
|
-
__ cmp(eax,
|
4209
|
+
__ cmp(eax, isolate()->factory()->undefined_value());
|
4314
4210
|
__ j(equal, if_true);
|
4315
4211
|
__ test(eax, Immediate(kSmiTagMask));
|
4316
4212
|
__ j(zero, if_false);
|
@@ -4345,16 +4241,16 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
|
|
4345
4241
|
mode == RelocInfo::CODE_TARGET_CONTEXT);
|
4346
4242
|
switch (ic->kind()) {
|
4347
4243
|
case Code::LOAD_IC:
|
4348
|
-
__ IncrementCounter(
|
4244
|
+
__ IncrementCounter(isolate()->counters()->named_load_full(), 1);
|
4349
4245
|
break;
|
4350
4246
|
case Code::KEYED_LOAD_IC:
|
4351
|
-
__ IncrementCounter(
|
4247
|
+
__ IncrementCounter(isolate()->counters()->keyed_load_full(), 1);
|
4352
4248
|
break;
|
4353
4249
|
case Code::STORE_IC:
|
4354
|
-
__ IncrementCounter(
|
4250
|
+
__ IncrementCounter(isolate()->counters()->named_store_full(), 1);
|
4355
4251
|
break;
|
4356
4252
|
case Code::KEYED_STORE_IC:
|
4357
|
-
__ IncrementCounter(
|
4253
|
+
__ IncrementCounter(isolate()->counters()->keyed_store_full(), 1);
|
4358
4254
|
default:
|
4359
4255
|
break;
|
4360
4256
|
}
|
@@ -4386,6 +4282,23 @@ void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
|
|
4386
4282
|
|
4387
4283
|
|
4388
4284
|
void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
|
4285
|
+
Counters* counters = isolate()->counters();
|
4286
|
+
switch (ic->kind()) {
|
4287
|
+
case Code::LOAD_IC:
|
4288
|
+
__ IncrementCounter(counters->named_load_full(), 1);
|
4289
|
+
break;
|
4290
|
+
case Code::KEYED_LOAD_IC:
|
4291
|
+
__ IncrementCounter(counters->keyed_load_full(), 1);
|
4292
|
+
break;
|
4293
|
+
case Code::STORE_IC:
|
4294
|
+
__ IncrementCounter(counters->named_store_full(), 1);
|
4295
|
+
break;
|
4296
|
+
case Code::KEYED_STORE_IC:
|
4297
|
+
__ IncrementCounter(counters->keyed_store_full(), 1);
|
4298
|
+
default:
|
4299
|
+
break;
|
4300
|
+
}
|
4301
|
+
|
4389
4302
|
__ call(ic, RelocInfo::CODE_TARGET);
|
4390
4303
|
if (patch_site != NULL && patch_site->is_bound()) {
|
4391
4304
|
patch_site->EmitPatchInfo();
|