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