therubyracer 0.6.3 → 0.7.0.pre
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of therubyracer might be problematic. Click here for more details.
- data/Rakefile +10 -9
- data/ext/v8/callbacks.cpp +15 -8
- data/ext/v8/converters.cpp +7 -8
- data/ext/v8/converters.h +0 -2
- data/ext/v8/extconf.rb +2 -0
- data/ext/v8/rr.cpp +169 -0
- data/ext/v8/rr.h +34 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/AUTHORS +8 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/ChangeLog +198 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/LICENSE +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/SConstruct +152 -38
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/include/v8-debug.h +52 -4
- data/ext/v8/upstream/2.1.10/include/v8-profiler.h +176 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/include/v8.h +227 -48
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/SConscript +60 -10
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/accessors.cc +5 -39
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/accessors.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/allocation.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/allocation.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/api.cc +477 -57
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/api.h +8 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/apinatives.js +1 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/apiutils.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arguments.h +5 -6
- data/ext/v8/upstream/{2.0.6/src/arm/assembler-thumb2-inl.h → 2.1.10/src/arm/assembler-arm-inl.h} +42 -27
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-arm.cc +430 -216
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-arm.h +199 -110
- data/ext/v8/upstream/{2.0.6/src/arm/assembler-arm-inl.h → 2.1.10/src/arm/assembler-thumb2-inl.h} +4 -18
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-thumb2.cc +142 -85
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/assembler-thumb2.h +18 -9
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/builtins-arm.cc +127 -87
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/codegen-arm-inl.h +3 -5
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/codegen-arm.cc +4634 -1427
- data/ext/v8/upstream/2.1.10/src/arm/codegen-arm.h +946 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/constants-arm.cc +21 -3
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/constants-arm.h +39 -13
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/cpu-arm.cc +9 -3
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/debug-arm.cc +34 -8
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/disasm-arm.cc +262 -117
- data/ext/v8/upstream/2.1.10/src/arm/fast-codegen-arm.cc +238 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/frames-arm.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/frames-arm.h +0 -0
- data/ext/v8/upstream/{2.0.6/src/arm/fast-codegen-arm.cc → 2.1.10/src/arm/full-codegen-arm.cc} +453 -283
- data/ext/v8/upstream/2.1.10/src/arm/ic-arm.cc +1833 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/jump-target-arm.cc +3 -29
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/macro-assembler-arm.cc +564 -104
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/macro-assembler-arm.h +255 -46
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/regexp-macro-assembler-arm.cc +78 -104
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/regexp-macro-assembler-arm.h +6 -22
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/register-allocator-arm-inl.h +0 -3
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/register-allocator-arm.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/register-allocator-arm.h +2 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/simulator-arm.cc +557 -180
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/simulator-arm.h +52 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/arm/stub-cache-arm.cc +904 -240
- data/ext/v8/upstream/2.1.10/src/arm/virtual-frame-arm.cc +668 -0
- data/ext/v8/upstream/2.1.10/src/arm/virtual-frame-arm.h +503 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/array.js +82 -109
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/assembler.cc +49 -13
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/assembler.h +27 -5
- data/ext/v8/upstream/2.1.10/src/ast.cc +1138 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ast.h +354 -53
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/bootstrapper.cc +609 -501
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/bootstrapper.h +27 -8
- data/ext/v8/upstream/2.1.10/src/builtins.cc +1512 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/builtins.h +41 -25
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/bytecodes-irregexp.h +0 -0
- data/ext/v8/upstream/2.1.10/src/cached-powers.h +119 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/char-predicates-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/char-predicates.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/checks.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/checks.h +25 -1
- data/ext/v8/upstream/2.1.10/src/circular-queue-inl.h +101 -0
- data/ext/v8/upstream/2.1.10/src/circular-queue.cc +121 -0
- data/ext/v8/upstream/2.1.10/src/circular-queue.h +129 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/code-stubs.cc +23 -8
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/code-stubs.h +16 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/code.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/codegen-inl.h +6 -34
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/codegen.cc +73 -92
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/codegen.h +164 -68
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/compilation-cache.cc +117 -73
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/compilation-cache.h +18 -17
- data/ext/v8/upstream/2.1.10/src/compiler.cc +623 -0
- data/ext/v8/upstream/2.1.10/src/compiler.h +299 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/contexts.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/contexts.h +8 -11
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/conversions-inl.h +28 -13
- data/ext/v8/upstream/2.1.10/src/conversions.cc +1105 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/conversions.h +9 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/counters.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/counters.h +1 -1
- data/ext/v8/upstream/2.1.10/src/cpu-profiler-inl.h +99 -0
- data/ext/v8/upstream/2.1.10/src/cpu-profiler.cc +494 -0
- data/ext/v8/upstream/2.1.10/src/cpu-profiler.h +277 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/cpu.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-debug.cc +15 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-debug.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-posix.cc +18 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-readline.cc +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8-windows.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8.cc +10 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8.h +2 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/d8.js +43 -38
- data/ext/v8/upstream/2.1.10/src/data-flow.cc +755 -0
- data/ext/v8/upstream/2.1.10/src/data-flow.h +278 -0
- data/ext/v8/upstream/{2.0.6/src/date-delay.js → 2.1.10/src/date.js} +100 -110
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dateparser-inl.h +11 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dateparser.cc +24 -26
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dateparser.h +8 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug-agent.cc +3 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug-agent.h +0 -0
- data/ext/v8/upstream/{2.0.6/src/debug-delay.js → 2.1.10/src/debug-debugger.js} +111 -15
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug.cc +156 -96
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/debug.h +53 -5
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/disasm.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/disassembler.cc +2 -8
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/disassembler.h +0 -0
- data/ext/v8/upstream/2.1.10/src/diy-fp.cc +58 -0
- data/ext/v8/upstream/2.1.10/src/diy-fp.h +117 -0
- data/ext/v8/upstream/2.1.10/src/double.h +169 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/dtoa-config.c +4 -3
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/execution.cc +22 -22
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/execution.h +17 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/factory.cc +70 -46
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/factory.h +27 -17
- data/ext/v8/upstream/2.1.10/src/fast-codegen.cc +746 -0
- data/ext/v8/upstream/2.1.10/src/fast-codegen.h +161 -0
- data/ext/v8/upstream/2.1.10/src/fast-dtoa.cc +512 -0
- data/ext/v8/upstream/2.1.10/src/fast-dtoa.h +59 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/flag-definitions.h +32 -11
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/flags.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/flags.h +0 -0
- data/ext/v8/upstream/2.1.10/src/flow-graph.cc +763 -0
- data/ext/v8/upstream/2.1.10/src/flow-graph.h +180 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frame-element.cc +1 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frame-element.h +49 -11
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frames-inl.h +2 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frames.cc +91 -17
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/frames.h +24 -2
- data/ext/v8/upstream/{2.0.6/src/fast-codegen.cc → 2.1.10/src/full-codegen.cc} +549 -198
- data/ext/v8/upstream/{2.0.6/src/fast-codegen.h → 2.1.10/src/full-codegen.h} +109 -29
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/func-name-inferrer.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/func-name-inferrer.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/global-handles.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/global-handles.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/globals.h +67 -43
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/handles-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/handles.cc +124 -129
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/handles.h +33 -15
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/hashmap.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/hashmap.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap-inl.h +56 -12
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap-profiler.cc +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap-profiler.h +2 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap.cc +413 -221
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/heap.h +192 -67
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/assembler-ia32-inl.h +6 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/assembler-ia32.cc +187 -32
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/assembler-ia32.h +31 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/builtins-ia32.cc +160 -133
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/codegen-ia32-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/codegen-ia32.cc +5533 -2177
- data/ext/v8/upstream/{2.0.6/src/x64/codegen-x64.h → 2.1.10/src/ia32/codegen-ia32.h} +453 -134
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/cpu-ia32.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/debug-ia32.cc +63 -8
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/disasm-ia32.cc +99 -16
- data/ext/v8/upstream/2.1.10/src/ia32/fast-codegen-ia32.cc +950 -0
- data/ext/v8/upstream/2.1.10/src/ia32/fast-codegen-ia32.h +155 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/frames-ia32.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/frames-ia32.h +0 -0
- data/ext/v8/upstream/{2.0.6/src/ia32/fast-codegen-ia32.cc → 2.1.10/src/ia32/full-codegen-ia32.cc} +454 -253
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/ic-ia32.cc +545 -390
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/jump-target-ia32.cc +1 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/macro-assembler-ia32.cc +330 -139
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/macro-assembler-ia32.h +96 -30
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/regexp-macro-assembler-ia32.cc +73 -89
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/regexp-macro-assembler-ia32.h +6 -21
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/register-allocator-ia32-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/register-allocator-ia32.cc +59 -5
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/register-allocator-ia32.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/simulator-ia32.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/simulator-ia32.h +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/stub-cache-ia32.cc +745 -303
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/virtual-frame-ia32.cc +278 -71
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ia32/virtual-frame-ia32.h +78 -22
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ic-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ic.cc +172 -89
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/ic.h +51 -20
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/interpreter-irregexp.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/interpreter-irregexp.h +0 -0
- data/ext/v8/upstream/{2.0.6/src/json-delay.js → 2.1.10/src/json.js} +26 -12
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jsregexp.cc +151 -118
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jsregexp.h +31 -7
- data/ext/v8/upstream/2.1.10/src/jump-target-heavy-inl.h +51 -0
- data/ext/v8/upstream/{2.0.6/src/jump-target.cc → 2.1.10/src/jump-target-heavy.cc} +164 -184
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jump-target-inl.h +8 -9
- data/ext/v8/upstream/{2.0.6/src/usage-analyzer.h → 2.1.10/src/jump-target-light-inl.h} +9 -7
- data/ext/v8/upstream/2.1.10/src/jump-target-light.cc +86 -0
- data/ext/v8/upstream/2.1.10/src/jump-target.cc +155 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/jump-target.h +6 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/list-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/list.h +2 -1
- data/ext/v8/upstream/2.1.10/src/liveedit-debugger.js +944 -0
- data/ext/v8/upstream/2.1.10/src/liveedit.cc +1468 -0
- data/ext/v8/upstream/2.1.10/src/liveedit.h +170 -0
- data/ext/v8/upstream/2.1.10/src/log-inl.h +59 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log-utils.cc +3 -9
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log-utils.h +1 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log.cc +198 -95
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/log.h +50 -49
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/macro-assembler.h +9 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/macros.py +30 -11
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/mark-compact.cc +464 -152
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/mark-compact.h +41 -20
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/math.js +9 -8
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/memory.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/messages.cc +1 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/messages.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/messages.js +46 -9
- data/ext/v8/upstream/2.1.10/src/mips/assembler-mips-inl.h +215 -0
- data/ext/v8/upstream/2.1.10/src/mips/assembler-mips.cc +1208 -0
- data/ext/v8/upstream/2.1.10/src/mips/assembler-mips.h +665 -0
- data/ext/v8/upstream/2.1.10/src/mips/builtins-mips.cc +202 -0
- data/ext/v8/upstream/2.1.10/src/mips/codegen-mips-inl.h +70 -0
- data/ext/v8/upstream/2.1.10/src/mips/codegen-mips.cc +1428 -0
- data/ext/v8/upstream/{2.0.6/src/arm/codegen-arm.h → 2.1.10/src/mips/codegen-mips.h} +103 -205
- data/ext/v8/upstream/2.1.10/src/mips/constants-mips.cc +323 -0
- data/ext/v8/upstream/2.1.10/src/mips/constants-mips.h +525 -0
- data/ext/v8/upstream/2.1.10/src/mips/cpu-mips.cc +69 -0
- data/ext/v8/upstream/2.1.10/src/mips/debug-mips.cc +128 -0
- data/ext/v8/upstream/2.1.10/src/mips/disasm-mips.cc +784 -0
- data/ext/v8/upstream/2.1.10/src/mips/fast-codegen-mips.cc +74 -0
- data/ext/v8/upstream/2.1.10/src/mips/frames-mips.cc +99 -0
- data/ext/v8/upstream/2.1.10/src/mips/frames-mips.h +164 -0
- data/ext/v8/upstream/2.1.10/src/mips/full-codegen-mips.cc +273 -0
- data/ext/v8/upstream/2.1.10/src/mips/ic-mips.cc +217 -0
- data/ext/v8/upstream/2.1.10/src/mips/jump-target-mips.cc +172 -0
- data/ext/v8/upstream/2.1.10/src/mips/macro-assembler-mips.cc +1323 -0
- data/ext/v8/upstream/2.1.10/src/mips/macro-assembler-mips.h +461 -0
- data/ext/v8/upstream/2.1.10/src/mips/register-allocator-mips-inl.h +137 -0
- data/ext/v8/upstream/2.1.10/src/mips/register-allocator-mips.cc +60 -0
- data/ext/v8/upstream/2.1.10/src/mips/register-allocator-mips.h +46 -0
- data/ext/v8/upstream/2.1.10/src/mips/simulator-mips.cc +1648 -0
- data/ext/v8/upstream/2.1.10/src/mips/simulator-mips.h +311 -0
- data/ext/v8/upstream/2.1.10/src/mips/stub-cache-mips.cc +400 -0
- data/ext/v8/upstream/2.1.10/src/mips/virtual-frame-mips.cc +316 -0
- data/ext/v8/upstream/{2.0.6/src/arm/virtual-frame-arm.h → 2.1.10/src/mips/virtual-frame-mips.h} +87 -71
- data/ext/v8/upstream/{2.0.6/src/mirror-delay.js → 2.1.10/src/mirror-debugger.js} +51 -45
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/mksnapshot.cc +97 -10
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/natives.h +6 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects-debug.cc +47 -5
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects-inl.h +154 -38
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects.cc +528 -280
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/objects.h +302 -95
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/oprofile-agent.cc +25 -33
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/oprofile-agent.h +9 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/parser.cc +444 -72
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/parser.h +4 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-freebsd.cc +32 -13
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-linux.cc +59 -25
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-macos.cc +30 -13
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-nullos.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-openbsd.cc +21 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-posix.cc +0 -18
- data/ext/v8/upstream/2.1.10/src/platform-solaris.cc +607 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform-win32.cc +16 -17
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/platform.h +25 -8
- data/ext/v8/upstream/2.1.10/src/powers-ten.h +2461 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/prettyprinter.cc +49 -29
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/prettyprinter.h +3 -1
- data/ext/v8/upstream/2.1.10/src/profile-generator-inl.h +124 -0
- data/ext/v8/upstream/2.1.10/src/profile-generator.cc +583 -0
- data/ext/v8/upstream/2.1.10/src/profile-generator.h +364 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/property.cc +1 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/property.h +12 -24
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-irregexp-inl.h +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-irregexp.cc +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-irregexp.h +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-tracer.cc +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler-tracer.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler.cc +33 -10
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-macro-assembler.h +12 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-stack.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/regexp-stack.h +0 -0
- data/ext/v8/upstream/{2.0.6/src/regexp-delay.js → 2.1.10/src/regexp.js} +180 -58
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/register-allocator-inl.h +68 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/register-allocator.cc +5 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/register-allocator.h +42 -17
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/rewriter.cc +110 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/rewriter.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/runtime.cc +2733 -623
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/runtime.h +43 -20
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/runtime.js +46 -35
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scanner.cc +278 -36
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scanner.h +97 -26
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopeinfo.cc +3 -3
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopeinfo.h +1 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopes.cc +11 -12
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/scopes.h +0 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/serialize.cc +298 -175
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/serialize.h +184 -40
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/shell.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/simulator.h +2 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/smart-pointer.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/snapshot-common.cc +16 -31
- data/ext/v8/upstream/2.1.10/src/snapshot-empty.cc +50 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/snapshot.h +13 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/spaces-inl.h +35 -27
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/spaces.cc +256 -42
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/spaces.h +136 -42
- data/ext/v8/upstream/{2.0.6/src/zone-inl.h → 2.1.10/src/splay-tree-inl.h} +102 -89
- data/ext/v8/upstream/2.1.10/src/splay-tree.h +203 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/string-stream.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/string-stream.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/string.js +260 -149
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/stub-cache.cc +195 -69
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/stub-cache.h +127 -12
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/third_party/dtoa/COPYING +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/third_party/dtoa/dtoa.c +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/third_party/valgrind/valgrind.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/token.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/token.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/top.cc +26 -31
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/top.h +3 -4
- data/ext/v8/upstream/2.1.10/src/type-info.cc +53 -0
- data/ext/v8/upstream/2.1.10/src/type-info.h +244 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/unicode-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/unicode.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/unicode.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/uri.js +6 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/utils.cc +0 -37
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/utils.h +121 -50
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8-counters.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8-counters.h +130 -98
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8.cc +42 -11
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8.h +4 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8natives.js +202 -37
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8threads.cc +11 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/v8threads.h +15 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/variables.cc +7 -51
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/variables.h +5 -35
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/version.cc +3 -3
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/version.h +0 -0
- data/ext/v8/upstream/2.1.10/src/virtual-frame-heavy-inl.h +152 -0
- data/ext/v8/upstream/{2.0.6/src/virtual-frame.cc → 2.1.10/src/virtual-frame-heavy.cc} +107 -176
- data/ext/v8/upstream/2.1.10/src/virtual-frame-inl.h +39 -0
- data/ext/v8/upstream/2.1.10/src/virtual-frame-light-inl.h +69 -0
- data/ext/v8/upstream/2.1.10/src/virtual-frame-light.cc +49 -0
- data/ext/v8/upstream/2.1.10/src/virtual-frame.cc +49 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/virtual-frame.h +2 -0
- data/ext/v8/upstream/{2.0.6/src/log-inl.h → 2.1.10/src/vm-state-inl.h} +28 -20
- data/ext/v8/upstream/{2.0.6/src/snapshot-empty.cc → 2.1.10/src/vm-state.cc} +5 -6
- data/ext/v8/upstream/2.1.10/src/vm-state.h +75 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/assembler-x64-inl.h +11 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/assembler-x64.cc +285 -93
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/assembler-x64.h +81 -78
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/builtins-x64.cc +130 -87
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/codegen-x64-inl.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/codegen-x64.cc +4520 -1317
- data/ext/v8/upstream/{2.0.6/src/ia32/codegen-ia32.h → 2.1.10/src/x64/codegen-x64.h} +362 -141
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/cpu-x64.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/debug-x64.cc +20 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/disasm-x64.cc +121 -44
- data/ext/v8/upstream/2.1.10/src/x64/fast-codegen-x64.cc +246 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/frames-x64.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/frames-x64.h +0 -0
- data/ext/v8/upstream/{2.0.6/src/x64/fast-codegen-x64.cc → 2.1.10/src/x64/full-codegen-x64.cc} +404 -231
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/ic-x64.cc +346 -117
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/jump-target-x64.cc +1 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/macro-assembler-x64.cc +537 -181
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/macro-assembler-x64.h +140 -34
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/regexp-macro-assembler-x64.cc +74 -96
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/regexp-macro-assembler-x64.h +8 -25
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/register-allocator-x64-inl.h +1 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/register-allocator-x64.cc +3 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/register-allocator-x64.h +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/simulator-x64.cc +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/simulator-x64.h +2 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/stub-cache-x64.cc +785 -288
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/virtual-frame-x64.cc +128 -52
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/x64/virtual-frame-x64.h +40 -19
- data/ext/v8/upstream/2.1.10/src/zone-inl.h +82 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/zone.cc +1 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/src/zone.h +6 -90
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/codemap.js +12 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/consarray.js +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/csvparser.js +22 -37
- data/ext/v8/upstream/2.1.10/tools/generate-ten-powers.scm +286 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/gyp/v8.gyp +86 -24
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/js2c.py +22 -22
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/jsmin.py +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/linux-tick-processor +10 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/linux-tick-processor.py +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/logreader.js +34 -16
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/mac-nm +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/mac-tick-processor +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/annotate +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/common +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/dump +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/report +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/reset +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/run +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/shutdown +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/oprofile/start +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/presubmit.py +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/process-heap-prof.py +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/profile.js +70 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/profile_view.js +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/run-valgrind.py +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/splaytree.js +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/splaytree.py +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/stats-viewer.py +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/test.py +7 -7
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/tickprocessor-driver.js +7 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/tickprocessor.js +140 -9
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/tickprocessor.py +40 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/utils.py +6 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/README.txt +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/arm.vsprops +1 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/common.vsprops +1 -2
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8.vcproj +0 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8_arm.vcproj +193 -199
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8_x64.vcproj +16 -8
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/d8js2c.cmd +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/debug.vsprops +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/ia32.vsprops +5 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/js2c.cmd +1 -1
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/release.vsprops +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8.sln +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8.vcproj +11 -7
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_arm.sln +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_arm.vcproj +227 -223
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_base.vcproj +137 -5
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_base_arm.vcproj +116 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_base_x64.vcproj +125 -4
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_cctest.vcproj +12 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_cctest_arm.vcproj +12 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_cctest_x64.vcproj +11 -11
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_mksnapshot.vcproj +0 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_mksnapshot_x64.vcproj +0 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_process_sample.vcproj +0 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_process_sample_arm.vcproj +145 -151
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_process_sample_x64.vcproj +16 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_shell_sample.vcproj +0 -6
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_shell_sample_arm.vcproj +145 -151
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_shell_sample_x64.vcproj +16 -8
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot.vcproj +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot_cc.vcproj +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot_cc_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_snapshot_x64.vcproj +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_x64.sln +0 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/v8_x64.vcproj +11 -7
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/visual_studio/x64.vsprops +5 -1
- data/ext/v8/upstream/2.1.10/tools/windows-tick-processor.bat +29 -0
- data/ext/v8/upstream/{2.0.6 → 2.1.10}/tools/windows-tick-processor.py +0 -0
- data/ext/v8/upstream/Makefile +8 -2
- data/ext/v8/v8.cpp +21 -73
- data/ext/v8/v8_array.cpp +56 -0
- data/ext/v8/v8_array.h +8 -0
- data/ext/v8/v8_callbacks.cpp +121 -0
- data/ext/v8/v8_callbacks.h +8 -0
- data/ext/v8/v8_cxt.cpp +74 -77
- data/ext/v8/v8_cxt.h +2 -9
- data/ext/v8/v8_date.cpp +26 -0
- data/ext/v8/v8_date.h +6 -0
- data/ext/v8/v8_exception.cpp +55 -0
- data/ext/v8/v8_exception.h +6 -0
- data/ext/v8/v8_external.cpp +50 -0
- data/ext/v8/v8_external.h +8 -0
- data/ext/v8/v8_func.cpp +76 -18
- data/ext/v8/v8_func.h +5 -4
- data/ext/v8/v8_msg.cpp +55 -46
- data/ext/v8/v8_msg.h +3 -11
- data/ext/v8/v8_obj.cpp +67 -36
- data/ext/v8/v8_obj.h +6 -8
- data/ext/v8/v8_ref.cpp +25 -9
- data/ext/v8/v8_ref.h +3 -5
- data/ext/v8/v8_script.cpp +17 -10
- data/ext/v8/v8_script.h +3 -3
- data/ext/v8/v8_str.cpp +34 -6
- data/ext/v8/v8_str.h +4 -2
- data/ext/v8/v8_template.cpp +195 -33
- data/ext/v8/v8_template.h +4 -5
- data/ext/v8/v8_try_catch.cpp +99 -0
- data/ext/v8/v8_try_catch.h +5 -0
- data/ext/v8/v8_value.cpp +164 -0
- data/ext/v8/v8_value.h +10 -0
- data/lib/v8.rb +3 -1
- data/lib/v8/access.rb +60 -0
- data/lib/v8/array.rb +15 -0
- data/lib/v8/callbacks.rb +88 -0
- data/lib/v8/cli.rb +1 -1
- data/lib/v8/context.rb +55 -66
- data/lib/v8/function.rb +20 -2
- data/lib/v8/object.rb +14 -12
- data/lib/v8/ruby_error.rb +3 -0
- data/lib/v8/to.rb +59 -7
- data/spec/ext/cxt_spec.rb +2 -15
- data/spec/ext/func_spec.rb +17 -10
- data/spec/ext/try_catch_spec.rb +32 -0
- data/spec/foo.rb +17 -0
- data/spec/redjs/jsapi_spec.rb +173 -96
- data/spec/spec_helper.rb +7 -0
- data/spec/v8/to_spec.rb +0 -1
- data/therubyracer.gemspec +6 -6
- metadata +493 -386
- data/ext/v8/upstream/2.0.6/src/arm/ic-arm.cc +0 -849
- data/ext/v8/upstream/2.0.6/src/arm/virtual-frame-arm.cc +0 -412
- data/ext/v8/upstream/2.0.6/src/ast.cc +0 -512
- data/ext/v8/upstream/2.0.6/src/builtins.cc +0 -851
- data/ext/v8/upstream/2.0.6/src/compiler.cc +0 -1132
- data/ext/v8/upstream/2.0.6/src/compiler.h +0 -107
- data/ext/v8/upstream/2.0.6/src/conversions.cc +0 -709
- data/ext/v8/upstream/2.0.6/src/usage-analyzer.cc +0 -426
- data/ext/v8/upstream/2.0.6/tools/windows-tick-processor.bat +0 -5
- data/ext/v8/upstream/no-strict-aliasing.patch +0 -13
- data/ext/v8/v8_standalone.cpp +0 -69
- data/ext/v8/v8_standalone.h +0 -31
- data/spec/ext/obj_spec.rb +0 -13
File without changes
|
@@ -32,12 +32,14 @@
|
|
32
32
|
#include "accessors.h"
|
33
33
|
#include "api.h"
|
34
34
|
#include "arguments.h"
|
35
|
+
#include "codegen.h"
|
35
36
|
#include "compiler.h"
|
36
37
|
#include "cpu.h"
|
37
38
|
#include "dateparser-inl.h"
|
38
39
|
#include "debug.h"
|
39
40
|
#include "execution.h"
|
40
41
|
#include "jsregexp.h"
|
42
|
+
#include "liveedit.h"
|
41
43
|
#include "parser.h"
|
42
44
|
#include "platform.h"
|
43
45
|
#include "runtime.h"
|
@@ -107,25 +109,23 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
|
|
107
109
|
// Deep copy local properties.
|
108
110
|
if (copy->HasFastProperties()) {
|
109
111
|
FixedArray* properties = copy->properties();
|
110
|
-
WriteBarrierMode mode = properties->GetWriteBarrierMode();
|
111
112
|
for (int i = 0; i < properties->length(); i++) {
|
112
113
|
Object* value = properties->get(i);
|
113
114
|
if (value->IsJSObject()) {
|
114
|
-
JSObject*
|
115
|
-
result = DeepCopyBoilerplate(
|
115
|
+
JSObject* js_object = JSObject::cast(value);
|
116
|
+
result = DeepCopyBoilerplate(js_object);
|
116
117
|
if (result->IsFailure()) return result;
|
117
|
-
properties->set(i, result
|
118
|
+
properties->set(i, result);
|
118
119
|
}
|
119
120
|
}
|
120
|
-
mode = copy->GetWriteBarrierMode();
|
121
121
|
int nof = copy->map()->inobject_properties();
|
122
122
|
for (int i = 0; i < nof; i++) {
|
123
123
|
Object* value = copy->InObjectPropertyAt(i);
|
124
124
|
if (value->IsJSObject()) {
|
125
|
-
JSObject*
|
126
|
-
result = DeepCopyBoilerplate(
|
125
|
+
JSObject* js_object = JSObject::cast(value);
|
126
|
+
result = DeepCopyBoilerplate(js_object);
|
127
127
|
if (result->IsFailure()) return result;
|
128
|
-
copy->InObjectPropertyAtPut(i, result
|
128
|
+
copy->InObjectPropertyAtPut(i, result);
|
129
129
|
}
|
130
130
|
}
|
131
131
|
} else {
|
@@ -135,20 +135,20 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
|
|
135
135
|
copy->GetLocalPropertyNames(names, 0);
|
136
136
|
for (int i = 0; i < names->length(); i++) {
|
137
137
|
ASSERT(names->get(i)->IsString());
|
138
|
-
String*
|
138
|
+
String* key_string = String::cast(names->get(i));
|
139
139
|
PropertyAttributes attributes =
|
140
|
-
|
140
|
+
copy->GetLocalPropertyAttribute(key_string);
|
141
141
|
// Only deep copy fields from the object literal expression.
|
142
142
|
// In particular, don't try to copy the length attribute of
|
143
143
|
// an array.
|
144
144
|
if (attributes != NONE) continue;
|
145
|
-
Object* value = copy->GetProperty(
|
145
|
+
Object* value = copy->GetProperty(key_string, &attributes);
|
146
146
|
ASSERT(!value->IsFailure());
|
147
147
|
if (value->IsJSObject()) {
|
148
|
-
JSObject*
|
149
|
-
result = DeepCopyBoilerplate(
|
148
|
+
JSObject* js_object = JSObject::cast(value);
|
149
|
+
result = DeepCopyBoilerplate(js_object);
|
150
150
|
if (result->IsFailure()) return result;
|
151
|
-
result = copy->SetProperty(
|
151
|
+
result = copy->SetProperty(key_string, result, NONE);
|
152
152
|
if (result->IsFailure()) return result;
|
153
153
|
}
|
154
154
|
}
|
@@ -160,14 +160,13 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
|
|
160
160
|
switch (copy->GetElementsKind()) {
|
161
161
|
case JSObject::FAST_ELEMENTS: {
|
162
162
|
FixedArray* elements = FixedArray::cast(copy->elements());
|
163
|
-
WriteBarrierMode mode = elements->GetWriteBarrierMode();
|
164
163
|
for (int i = 0; i < elements->length(); i++) {
|
165
164
|
Object* value = elements->get(i);
|
166
165
|
if (value->IsJSObject()) {
|
167
|
-
JSObject*
|
168
|
-
result = DeepCopyBoilerplate(
|
166
|
+
JSObject* js_object = JSObject::cast(value);
|
167
|
+
result = DeepCopyBoilerplate(js_object);
|
169
168
|
if (result->IsFailure()) return result;
|
170
|
-
elements->set(i, result
|
169
|
+
elements->set(i, result);
|
171
170
|
}
|
172
171
|
}
|
173
172
|
break;
|
@@ -180,8 +179,8 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
|
|
180
179
|
if (element_dictionary->IsKey(k)) {
|
181
180
|
Object* value = element_dictionary->ValueAt(i);
|
182
181
|
if (value->IsJSObject()) {
|
183
|
-
JSObject*
|
184
|
-
result = DeepCopyBoilerplate(
|
182
|
+
JSObject* js_object = JSObject::cast(value);
|
183
|
+
result = DeepCopyBoilerplate(js_object);
|
185
184
|
if (result->IsFailure()) return result;
|
186
185
|
element_dictionary->ValueAtPut(i, result);
|
187
186
|
}
|
@@ -249,7 +248,8 @@ static Handle<Object> CreateLiteralBoilerplate(
|
|
249
248
|
|
250
249
|
static Handle<Object> CreateObjectLiteralBoilerplate(
|
251
250
|
Handle<FixedArray> literals,
|
252
|
-
Handle<FixedArray> constant_properties
|
251
|
+
Handle<FixedArray> constant_properties,
|
252
|
+
bool should_have_fast_elements) {
|
253
253
|
// Get the global context from the literals array. This is the
|
254
254
|
// context in which the function was created and we use the object
|
255
255
|
// function from this context to create the object literal. We do
|
@@ -265,6 +265,10 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
|
|
265
265
|
&is_result_from_cache);
|
266
266
|
|
267
267
|
Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map);
|
268
|
+
|
269
|
+
// Normalize the elements of the boilerplate to save space if needed.
|
270
|
+
if (!should_have_fast_elements) NormalizeElements(boilerplate);
|
271
|
+
|
268
272
|
{ // Add the constant properties to the boilerplate.
|
269
273
|
int length = constant_properties->length();
|
270
274
|
OptimizedObjectForAddingMultipleProperties opt(boilerplate,
|
@@ -346,8 +350,10 @@ static Handle<Object> CreateLiteralBoilerplate(
|
|
346
350
|
Handle<FixedArray> array) {
|
347
351
|
Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
|
348
352
|
switch (CompileTimeValue::GetType(array)) {
|
349
|
-
case CompileTimeValue::
|
350
|
-
return CreateObjectLiteralBoilerplate(literals, elements);
|
353
|
+
case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
|
354
|
+
return CreateObjectLiteralBoilerplate(literals, elements, true);
|
355
|
+
case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
|
356
|
+
return CreateObjectLiteralBoilerplate(literals, elements, false);
|
351
357
|
case CompileTimeValue::ARRAY_LITERAL:
|
352
358
|
return CreateArrayLiteralBoilerplate(literals, elements);
|
353
359
|
default:
|
@@ -357,26 +363,6 @@ static Handle<Object> CreateLiteralBoilerplate(
|
|
357
363
|
}
|
358
364
|
|
359
365
|
|
360
|
-
static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) {
|
361
|
-
HandleScope scope;
|
362
|
-
ASSERT(args.length() == 3);
|
363
|
-
// Copy the arguments.
|
364
|
-
CONVERT_ARG_CHECKED(FixedArray, literals, 0);
|
365
|
-
CONVERT_SMI_CHECKED(literals_index, args[1]);
|
366
|
-
CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
|
367
|
-
|
368
|
-
Handle<Object> result =
|
369
|
-
CreateObjectLiteralBoilerplate(literals, constant_properties);
|
370
|
-
|
371
|
-
if (result.is_null()) return Failure::Exception();
|
372
|
-
|
373
|
-
// Update the functions literal and return the boilerplate.
|
374
|
-
literals->set(literals_index, *result);
|
375
|
-
|
376
|
-
return *result;
|
377
|
-
}
|
378
|
-
|
379
|
-
|
380
366
|
static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) {
|
381
367
|
// Takes a FixedArray of elements containing the literal elements of
|
382
368
|
// the array literal and produces JSArray with those elements.
|
@@ -400,15 +386,19 @@ static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) {
|
|
400
386
|
|
401
387
|
static Object* Runtime_CreateObjectLiteral(Arguments args) {
|
402
388
|
HandleScope scope;
|
403
|
-
ASSERT(args.length() ==
|
389
|
+
ASSERT(args.length() == 4);
|
404
390
|
CONVERT_ARG_CHECKED(FixedArray, literals, 0);
|
405
391
|
CONVERT_SMI_CHECKED(literals_index, args[1]);
|
406
392
|
CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
|
393
|
+
CONVERT_SMI_CHECKED(fast_elements, args[3]);
|
394
|
+
bool should_have_fast_elements = fast_elements == 1;
|
407
395
|
|
408
396
|
// Check if boilerplate exists. If not, create it first.
|
409
397
|
Handle<Object> boilerplate(literals->get(literals_index));
|
410
398
|
if (*boilerplate == Heap::undefined_value()) {
|
411
|
-
boilerplate = CreateObjectLiteralBoilerplate(literals,
|
399
|
+
boilerplate = CreateObjectLiteralBoilerplate(literals,
|
400
|
+
constant_properties,
|
401
|
+
should_have_fast_elements);
|
412
402
|
if (boilerplate.is_null()) return Failure::Exception();
|
413
403
|
// Update the functions literal and return the boilerplate.
|
414
404
|
literals->set(literals_index, *boilerplate);
|
@@ -419,15 +409,19 @@ static Object* Runtime_CreateObjectLiteral(Arguments args) {
|
|
419
409
|
|
420
410
|
static Object* Runtime_CreateObjectLiteralShallow(Arguments args) {
|
421
411
|
HandleScope scope;
|
422
|
-
ASSERT(args.length() ==
|
412
|
+
ASSERT(args.length() == 4);
|
423
413
|
CONVERT_ARG_CHECKED(FixedArray, literals, 0);
|
424
414
|
CONVERT_SMI_CHECKED(literals_index, args[1]);
|
425
415
|
CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
|
416
|
+
CONVERT_SMI_CHECKED(fast_elements, args[3]);
|
417
|
+
bool should_have_fast_elements = fast_elements == 1;
|
426
418
|
|
427
419
|
// Check if boilerplate exists. If not, create it first.
|
428
420
|
Handle<Object> boilerplate(literals->get(literals_index));
|
429
421
|
if (*boilerplate == Heap::undefined_value()) {
|
430
|
-
boilerplate = CreateObjectLiteralBoilerplate(literals,
|
422
|
+
boilerplate = CreateObjectLiteralBoilerplate(literals,
|
423
|
+
constant_properties,
|
424
|
+
should_have_fast_elements);
|
431
425
|
if (boilerplate.is_null()) return Failure::Exception();
|
432
426
|
// Update the functions literal and return the boilerplate.
|
433
427
|
literals->set(literals_index, *boilerplate);
|
@@ -583,6 +577,7 @@ static void GetOwnPropertyImplementation(JSObject* obj,
|
|
583
577
|
// if args[1] is an accessor on args[0]
|
584
578
|
// [true, GetFunction, SetFunction, Enumerable, Configurable]
|
585
579
|
static Object* Runtime_GetOwnProperty(Arguments args) {
|
580
|
+
ASSERT(args.length() == 2);
|
586
581
|
HandleScope scope;
|
587
582
|
Handle<FixedArray> elms = Factory::NewFixedArray(5);
|
588
583
|
Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms);
|
@@ -598,8 +593,9 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
|
|
598
593
|
|
599
594
|
if (result.type() == CALLBACKS) {
|
600
595
|
Object* structure = result.GetCallbackObject();
|
601
|
-
if (structure->IsProxy()) {
|
602
|
-
// Property that is internally implemented as a callback
|
596
|
+
if (structure->IsProxy() || structure->IsAccessorInfo()) {
|
597
|
+
// Property that is internally implemented as a callback or
|
598
|
+
// an API defined callback.
|
603
599
|
Object* value = obj->GetPropertyWithCallback(
|
604
600
|
obj, structure, name, result.holder());
|
605
601
|
elms->set(0, Heap::false_value());
|
@@ -611,7 +607,6 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
|
|
611
607
|
elms->set(1, FixedArray::cast(structure)->get(0));
|
612
608
|
elms->set(2, FixedArray::cast(structure)->get(1));
|
613
609
|
} else {
|
614
|
-
// TODO(ricow): Handle API callbacks.
|
615
610
|
return Heap::undefined_value();
|
616
611
|
}
|
617
612
|
} else {
|
@@ -621,11 +616,19 @@ static Object* Runtime_GetOwnProperty(Arguments args) {
|
|
621
616
|
}
|
622
617
|
|
623
618
|
elms->set(3, Heap::ToBoolean(!result.IsDontEnum()));
|
624
|
-
elms->set(4, Heap::ToBoolean(!result.
|
619
|
+
elms->set(4, Heap::ToBoolean(!result.IsDontDelete()));
|
625
620
|
return *desc;
|
626
621
|
}
|
627
622
|
|
628
623
|
|
624
|
+
static Object* Runtime_IsExtensible(Arguments args) {
|
625
|
+
ASSERT(args.length() == 1);
|
626
|
+
CONVERT_CHECKED(JSObject, obj, args[0]);
|
627
|
+
return obj->map()->is_extensible() ? Heap::true_value()
|
628
|
+
: Heap::false_value();
|
629
|
+
}
|
630
|
+
|
631
|
+
|
629
632
|
static Object* Runtime_RegExpCompile(Arguments args) {
|
630
633
|
HandleScope scope;
|
631
634
|
ASSERT(args.length() == 3);
|
@@ -785,9 +788,10 @@ static Object* Runtime_DeclareGlobals(Arguments args) {
|
|
785
788
|
}
|
786
789
|
} else {
|
787
790
|
// Copy the function and update its context. Use it as value.
|
788
|
-
Handle<
|
791
|
+
Handle<SharedFunctionInfo> shared =
|
792
|
+
Handle<SharedFunctionInfo>::cast(value);
|
789
793
|
Handle<JSFunction> function =
|
790
|
-
Factory::
|
794
|
+
Factory::NewFunctionFromSharedFunctionInfo(shared, context, TENURED);
|
791
795
|
value = function;
|
792
796
|
}
|
793
797
|
|
@@ -1202,17 +1206,6 @@ static Object* Runtime_OptimizeObjectForAddingMultipleProperties(
|
|
1202
1206
|
}
|
1203
1207
|
|
1204
1208
|
|
1205
|
-
static Object* Runtime_TransformToFastProperties(Arguments args) {
|
1206
|
-
HandleScope scope;
|
1207
|
-
ASSERT(args.length() == 1);
|
1208
|
-
CONVERT_ARG_CHECKED(JSObject, object, 0);
|
1209
|
-
if (!object->HasFastProperties() && !object->IsGlobalObject()) {
|
1210
|
-
TransformToFastProperties(object, 0);
|
1211
|
-
}
|
1212
|
-
return *object;
|
1213
|
-
}
|
1214
|
-
|
1215
|
-
|
1216
1209
|
static Object* Runtime_RegExpExec(Arguments args) {
|
1217
1210
|
HandleScope scope;
|
1218
1211
|
ASSERT(args.length() == 4);
|
@@ -1235,6 +1228,178 @@ static Object* Runtime_RegExpExec(Arguments args) {
|
|
1235
1228
|
}
|
1236
1229
|
|
1237
1230
|
|
1231
|
+
static Object* Runtime_RegExpConstructResult(Arguments args) {
|
1232
|
+
ASSERT(args.length() == 3);
|
1233
|
+
CONVERT_SMI_CHECKED(elements_count, args[0]);
|
1234
|
+
if (elements_count > JSArray::kMaxFastElementsLength) {
|
1235
|
+
return Top::ThrowIllegalOperation();
|
1236
|
+
}
|
1237
|
+
Object* new_object = Heap::AllocateFixedArrayWithHoles(elements_count);
|
1238
|
+
if (new_object->IsFailure()) return new_object;
|
1239
|
+
FixedArray* elements = FixedArray::cast(new_object);
|
1240
|
+
new_object = Heap::AllocateRaw(JSRegExpResult::kSize,
|
1241
|
+
NEW_SPACE,
|
1242
|
+
OLD_POINTER_SPACE);
|
1243
|
+
if (new_object->IsFailure()) return new_object;
|
1244
|
+
{
|
1245
|
+
AssertNoAllocation no_gc;
|
1246
|
+
HandleScope scope;
|
1247
|
+
reinterpret_cast<HeapObject*>(new_object)->
|
1248
|
+
set_map(Top::global_context()->regexp_result_map());
|
1249
|
+
}
|
1250
|
+
JSArray* array = JSArray::cast(new_object);
|
1251
|
+
array->set_properties(Heap::empty_fixed_array());
|
1252
|
+
array->set_elements(elements);
|
1253
|
+
array->set_length(Smi::FromInt(elements_count));
|
1254
|
+
// Write in-object properties after the length of the array.
|
1255
|
+
array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
|
1256
|
+
array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
|
1257
|
+
return array;
|
1258
|
+
}
|
1259
|
+
|
1260
|
+
|
1261
|
+
static Object* Runtime_RegExpInitializeObject(Arguments args) {
|
1262
|
+
AssertNoAllocation no_alloc;
|
1263
|
+
ASSERT(args.length() == 5);
|
1264
|
+
CONVERT_CHECKED(JSRegExp, regexp, args[0]);
|
1265
|
+
CONVERT_CHECKED(String, source, args[1]);
|
1266
|
+
|
1267
|
+
Object* global = args[2];
|
1268
|
+
if (!global->IsTrue()) global = Heap::false_value();
|
1269
|
+
|
1270
|
+
Object* ignoreCase = args[3];
|
1271
|
+
if (!ignoreCase->IsTrue()) ignoreCase = Heap::false_value();
|
1272
|
+
|
1273
|
+
Object* multiline = args[4];
|
1274
|
+
if (!multiline->IsTrue()) multiline = Heap::false_value();
|
1275
|
+
|
1276
|
+
Map* map = regexp->map();
|
1277
|
+
Object* constructor = map->constructor();
|
1278
|
+
if (constructor->IsJSFunction() &&
|
1279
|
+
JSFunction::cast(constructor)->initial_map() == map) {
|
1280
|
+
// If we still have the original map, set in-object properties directly.
|
1281
|
+
regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source);
|
1282
|
+
// TODO(lrn): Consider skipping write barrier on booleans as well.
|
1283
|
+
// Both true and false should be in oldspace at all times.
|
1284
|
+
regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, global);
|
1285
|
+
regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, ignoreCase);
|
1286
|
+
regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, multiline);
|
1287
|
+
regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
|
1288
|
+
Smi::FromInt(0),
|
1289
|
+
SKIP_WRITE_BARRIER);
|
1290
|
+
return regexp;
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
// Map has changed, so use generic, but slower, method.
|
1294
|
+
PropertyAttributes final =
|
1295
|
+
static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
|
1296
|
+
PropertyAttributes writable =
|
1297
|
+
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
|
1298
|
+
regexp->IgnoreAttributesAndSetLocalProperty(Heap::source_symbol(),
|
1299
|
+
source,
|
1300
|
+
final);
|
1301
|
+
regexp->IgnoreAttributesAndSetLocalProperty(Heap::global_symbol(),
|
1302
|
+
global,
|
1303
|
+
final);
|
1304
|
+
regexp->IgnoreAttributesAndSetLocalProperty(Heap::ignore_case_symbol(),
|
1305
|
+
ignoreCase,
|
1306
|
+
final);
|
1307
|
+
regexp->IgnoreAttributesAndSetLocalProperty(Heap::multiline_symbol(),
|
1308
|
+
multiline,
|
1309
|
+
final);
|
1310
|
+
regexp->IgnoreAttributesAndSetLocalProperty(Heap::last_index_symbol(),
|
1311
|
+
Smi::FromInt(0),
|
1312
|
+
writable);
|
1313
|
+
return regexp;
|
1314
|
+
}
|
1315
|
+
|
1316
|
+
|
1317
|
+
static Object* Runtime_FinishArrayPrototypeSetup(Arguments args) {
|
1318
|
+
HandleScope scope;
|
1319
|
+
ASSERT(args.length() == 1);
|
1320
|
+
CONVERT_ARG_CHECKED(JSArray, prototype, 0);
|
1321
|
+
// This is necessary to enable fast checks for absence of elements
|
1322
|
+
// on Array.prototype and below.
|
1323
|
+
prototype->set_elements(Heap::empty_fixed_array());
|
1324
|
+
return Smi::FromInt(0);
|
1325
|
+
}
|
1326
|
+
|
1327
|
+
|
1328
|
+
static void SetCustomCallGenerator(Handle<JSFunction> function,
|
1329
|
+
ExternalReference* generator) {
|
1330
|
+
if (function->shared()->function_data()->IsUndefined()) {
|
1331
|
+
function->shared()->set_function_data(*FromCData(generator->address()));
|
1332
|
+
}
|
1333
|
+
}
|
1334
|
+
|
1335
|
+
|
1336
|
+
static Handle<JSFunction> InstallBuiltin(Handle<JSObject> holder,
|
1337
|
+
const char* name,
|
1338
|
+
Builtins::Name builtin_name,
|
1339
|
+
ExternalReference* generator = NULL) {
|
1340
|
+
Handle<String> key = Factory::LookupAsciiSymbol(name);
|
1341
|
+
Handle<Code> code(Builtins::builtin(builtin_name));
|
1342
|
+
Handle<JSFunction> optimized = Factory::NewFunction(key,
|
1343
|
+
JS_OBJECT_TYPE,
|
1344
|
+
JSObject::kHeaderSize,
|
1345
|
+
code,
|
1346
|
+
false);
|
1347
|
+
optimized->shared()->DontAdaptArguments();
|
1348
|
+
if (generator != NULL) {
|
1349
|
+
SetCustomCallGenerator(optimized, generator);
|
1350
|
+
}
|
1351
|
+
SetProperty(holder, key, optimized, NONE);
|
1352
|
+
return optimized;
|
1353
|
+
}
|
1354
|
+
|
1355
|
+
|
1356
|
+
Object* CompileArrayPushCall(CallStubCompiler* compiler,
|
1357
|
+
Object* object,
|
1358
|
+
JSObject* holder,
|
1359
|
+
JSFunction* function,
|
1360
|
+
String* name,
|
1361
|
+
StubCompiler::CheckType check) {
|
1362
|
+
return compiler->CompileArrayPushCall(object, holder, function, name, check);
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
|
1366
|
+
Object* CompileArrayPopCall(CallStubCompiler* compiler,
|
1367
|
+
Object* object,
|
1368
|
+
JSObject* holder,
|
1369
|
+
JSFunction* function,
|
1370
|
+
String* name,
|
1371
|
+
StubCompiler::CheckType check) {
|
1372
|
+
return compiler->CompileArrayPopCall(object, holder, function, name, check);
|
1373
|
+
}
|
1374
|
+
|
1375
|
+
|
1376
|
+
static Object* Runtime_SpecialArrayFunctions(Arguments args) {
|
1377
|
+
HandleScope scope;
|
1378
|
+
ASSERT(args.length() == 1);
|
1379
|
+
CONVERT_ARG_CHECKED(JSObject, holder, 0);
|
1380
|
+
|
1381
|
+
ExternalReference pop = ExternalReference::compile_array_pop_call();
|
1382
|
+
ExternalReference push = ExternalReference::compile_array_push_call();
|
1383
|
+
|
1384
|
+
InstallBuiltin(holder, "pop", Builtins::ArrayPop, &pop);
|
1385
|
+
InstallBuiltin(holder, "push", Builtins::ArrayPush, &push);
|
1386
|
+
InstallBuiltin(holder, "shift", Builtins::ArrayShift);
|
1387
|
+
InstallBuiltin(holder, "unshift", Builtins::ArrayUnshift);
|
1388
|
+
InstallBuiltin(holder, "slice", Builtins::ArraySlice);
|
1389
|
+
InstallBuiltin(holder, "splice", Builtins::ArraySplice);
|
1390
|
+
InstallBuiltin(holder, "concat", Builtins::ArrayConcat);
|
1391
|
+
|
1392
|
+
return *holder;
|
1393
|
+
}
|
1394
|
+
|
1395
|
+
|
1396
|
+
static Object* Runtime_GetGlobalReceiver(Arguments args) {
|
1397
|
+
// Returns a real global receiver, not one of builtins object.
|
1398
|
+
Context* global_context = Top::context()->global()->global_context();
|
1399
|
+
return global_context->global()->global_receiver();
|
1400
|
+
}
|
1401
|
+
|
1402
|
+
|
1238
1403
|
static Object* Runtime_MaterializeRegExpLiteral(Arguments args) {
|
1239
1404
|
HandleScope scope;
|
1240
1405
|
ASSERT(args.length() == 4);
|
@@ -1285,6 +1450,18 @@ static Object* Runtime_FunctionSetName(Arguments args) {
|
|
1285
1450
|
}
|
1286
1451
|
|
1287
1452
|
|
1453
|
+
static Object* Runtime_FunctionRemovePrototype(Arguments args) {
|
1454
|
+
NoHandleAllocation ha;
|
1455
|
+
ASSERT(args.length() == 1);
|
1456
|
+
|
1457
|
+
CONVERT_CHECKED(JSFunction, f, args[0]);
|
1458
|
+
Object* obj = f->RemovePrototype();
|
1459
|
+
if (obj->IsFailure()) return obj;
|
1460
|
+
|
1461
|
+
return Heap::undefined_value();
|
1462
|
+
}
|
1463
|
+
|
1464
|
+
|
1288
1465
|
static Object* Runtime_FunctionGetScript(Arguments args) {
|
1289
1466
|
HandleScope scope;
|
1290
1467
|
ASSERT(args.length() == 1);
|
@@ -1358,6 +1535,7 @@ static Object* Runtime_FunctionSetPrototype(Arguments args) {
|
|
1358
1535
|
ASSERT(args.length() == 2);
|
1359
1536
|
|
1360
1537
|
CONVERT_CHECKED(JSFunction, fun, args[0]);
|
1538
|
+
ASSERT(fun->should_have_prototype());
|
1361
1539
|
Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL);
|
1362
1540
|
if (obj->IsFailure()) return obj;
|
1363
1541
|
return args[0]; // return TOS
|
@@ -1369,10 +1547,8 @@ static Object* Runtime_FunctionIsAPIFunction(Arguments args) {
|
|
1369
1547
|
ASSERT(args.length() == 1);
|
1370
1548
|
|
1371
1549
|
CONVERT_CHECKED(JSFunction, f, args[0]);
|
1372
|
-
|
1373
|
-
|
1374
|
-
return !f->shared()->function_data()->IsUndefined() ? Heap::true_value()
|
1375
|
-
: Heap::false_value();
|
1550
|
+
return f->shared()->IsApiFunction() ? Heap::true_value()
|
1551
|
+
: Heap::false_value();
|
1376
1552
|
}
|
1377
1553
|
|
1378
1554
|
static Object* Runtime_FunctionIsBuiltin(Arguments args) {
|
@@ -1396,16 +1572,18 @@ static Object* Runtime_SetCode(Arguments args) {
|
|
1396
1572
|
if (!code->IsNull()) {
|
1397
1573
|
RUNTIME_ASSERT(code->IsJSFunction());
|
1398
1574
|
Handle<JSFunction> fun = Handle<JSFunction>::cast(code);
|
1399
|
-
|
1400
|
-
|
1575
|
+
Handle<SharedFunctionInfo> shared(fun->shared());
|
1576
|
+
SetExpectedNofProperties(target, shared->expected_nof_properties());
|
1577
|
+
|
1578
|
+
if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
1401
1579
|
return Failure::Exception();
|
1402
1580
|
}
|
1403
1581
|
// Set the code, formal parameter count, and the length of the target
|
1404
1582
|
// function.
|
1405
1583
|
target->set_code(fun->code());
|
1406
|
-
target->shared()->set_length(
|
1584
|
+
target->shared()->set_length(shared->length());
|
1407
1585
|
target->shared()->set_formal_parameter_count(
|
1408
|
-
|
1586
|
+
shared->formal_parameter_count());
|
1409
1587
|
// Set the source code of the target function to undefined.
|
1410
1588
|
// SetCode is only used for built-in constructors like String,
|
1411
1589
|
// Array, and Object, and some web code
|
@@ -1428,6 +1606,8 @@ static Object* Runtime_SetCode(Arguments args) {
|
|
1428
1606
|
literals->set(JSFunction::kLiteralGlobalContextIndex,
|
1429
1607
|
context->global_context());
|
1430
1608
|
}
|
1609
|
+
// It's okay to skip the write barrier here because the literals
|
1610
|
+
// are guaranteed to be in old space.
|
1431
1611
|
target->set_literals(*literals, SKIP_WRITE_BARRIER);
|
1432
1612
|
}
|
1433
1613
|
|
@@ -1493,9 +1673,91 @@ static Object* Runtime_CharFromCode(Arguments args) {
|
|
1493
1673
|
return CharFromCode(args[0]);
|
1494
1674
|
}
|
1495
1675
|
|
1676
|
+
|
1677
|
+
class FixedArrayBuilder {
|
1678
|
+
public:
|
1679
|
+
explicit FixedArrayBuilder(int initial_capacity)
|
1680
|
+
: array_(Factory::NewFixedArrayWithHoles(initial_capacity)),
|
1681
|
+
length_(0) {
|
1682
|
+
// Require a non-zero initial size. Ensures that doubling the size to
|
1683
|
+
// extend the array will work.
|
1684
|
+
ASSERT(initial_capacity > 0);
|
1685
|
+
}
|
1686
|
+
|
1687
|
+
explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
|
1688
|
+
: array_(backing_store),
|
1689
|
+
length_(0) {
|
1690
|
+
// Require a non-zero initial size. Ensures that doubling the size to
|
1691
|
+
// extend the array will work.
|
1692
|
+
ASSERT(backing_store->length() > 0);
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
bool HasCapacity(int elements) {
|
1696
|
+
int length = array_->length();
|
1697
|
+
int required_length = length_ + elements;
|
1698
|
+
return (length >= required_length);
|
1699
|
+
}
|
1700
|
+
|
1701
|
+
void EnsureCapacity(int elements) {
|
1702
|
+
int length = array_->length();
|
1703
|
+
int required_length = length_ + elements;
|
1704
|
+
if (length < required_length) {
|
1705
|
+
int new_length = length;
|
1706
|
+
do {
|
1707
|
+
new_length *= 2;
|
1708
|
+
} while (new_length < required_length);
|
1709
|
+
Handle<FixedArray> extended_array =
|
1710
|
+
Factory::NewFixedArrayWithHoles(new_length);
|
1711
|
+
array_->CopyTo(0, *extended_array, 0, length_);
|
1712
|
+
array_ = extended_array;
|
1713
|
+
}
|
1714
|
+
}
|
1715
|
+
|
1716
|
+
void Add(Object* value) {
|
1717
|
+
ASSERT(length_ < capacity());
|
1718
|
+
array_->set(length_, value);
|
1719
|
+
length_++;
|
1720
|
+
}
|
1721
|
+
|
1722
|
+
void Add(Smi* value) {
|
1723
|
+
ASSERT(length_ < capacity());
|
1724
|
+
array_->set(length_, value);
|
1725
|
+
length_++;
|
1726
|
+
}
|
1727
|
+
|
1728
|
+
Handle<FixedArray> array() {
|
1729
|
+
return array_;
|
1730
|
+
}
|
1731
|
+
|
1732
|
+
int length() {
|
1733
|
+
return length_;
|
1734
|
+
}
|
1735
|
+
|
1736
|
+
int capacity() {
|
1737
|
+
return array_->length();
|
1738
|
+
}
|
1739
|
+
|
1740
|
+
Handle<JSArray> ToJSArray() {
|
1741
|
+
Handle<JSArray> result_array = Factory::NewJSArrayWithElements(array_);
|
1742
|
+
result_array->set_length(Smi::FromInt(length_));
|
1743
|
+
return result_array;
|
1744
|
+
}
|
1745
|
+
|
1746
|
+
Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
|
1747
|
+
target_array->set_elements(*array_);
|
1748
|
+
target_array->set_length(Smi::FromInt(length_));
|
1749
|
+
return target_array;
|
1750
|
+
}
|
1751
|
+
|
1752
|
+
private:
|
1753
|
+
Handle<FixedArray> array_;
|
1754
|
+
int length_;
|
1755
|
+
};
|
1756
|
+
|
1757
|
+
|
1496
1758
|
// Forward declarations.
|
1497
|
-
|
1498
|
-
|
1759
|
+
const int kStringBuilderConcatHelperLengthBits = 11;
|
1760
|
+
const int kStringBuilderConcatHelperPositionBits = 19;
|
1499
1761
|
|
1500
1762
|
template <typename schar>
|
1501
1763
|
static inline void StringBuilderConcatHelper(String*,
|
@@ -1503,15 +1765,19 @@ static inline void StringBuilderConcatHelper(String*,
|
|
1503
1765
|
FixedArray*,
|
1504
1766
|
int);
|
1505
1767
|
|
1506
|
-
typedef BitField<int, 0,
|
1507
|
-
|
1768
|
+
typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
|
1769
|
+
StringBuilderSubstringLength;
|
1770
|
+
typedef BitField<int,
|
1771
|
+
kStringBuilderConcatHelperLengthBits,
|
1772
|
+
kStringBuilderConcatHelperPositionBits>
|
1773
|
+
StringBuilderSubstringPosition;
|
1774
|
+
|
1508
1775
|
|
1509
1776
|
class ReplacementStringBuilder {
|
1510
1777
|
public:
|
1511
1778
|
ReplacementStringBuilder(Handle<String> subject, int estimated_part_count)
|
1512
|
-
:
|
1513
|
-
|
1514
|
-
part_count_(0),
|
1779
|
+
: array_builder_(estimated_part_count),
|
1780
|
+
subject_(subject),
|
1515
1781
|
character_count_(0),
|
1516
1782
|
is_ascii_(subject->IsAsciiRepresentation()) {
|
1517
1783
|
// Require a non-zero initial size. Ensures that doubling the size to
|
@@ -1519,38 +1785,33 @@ class ReplacementStringBuilder {
|
|
1519
1785
|
ASSERT(estimated_part_count > 0);
|
1520
1786
|
}
|
1521
1787
|
|
1522
|
-
void
|
1523
|
-
|
1524
|
-
|
1525
|
-
if (length < required_length) {
|
1526
|
-
int new_length = length;
|
1527
|
-
do {
|
1528
|
-
new_length *= 2;
|
1529
|
-
} while (new_length < required_length);
|
1530
|
-
Handle<FixedArray> extended_array =
|
1531
|
-
Factory::NewFixedArray(new_length);
|
1532
|
-
parts_->CopyTo(0, *extended_array, 0, part_count_);
|
1533
|
-
parts_ = extended_array;
|
1534
|
-
}
|
1535
|
-
}
|
1536
|
-
|
1537
|
-
void AddSubjectSlice(int from, int to) {
|
1788
|
+
static inline void AddSubjectSlice(FixedArrayBuilder* builder,
|
1789
|
+
int from,
|
1790
|
+
int to) {
|
1538
1791
|
ASSERT(from >= 0);
|
1539
1792
|
int length = to - from;
|
1540
1793
|
ASSERT(length > 0);
|
1541
|
-
// Can we encode the slice in 11 bits for length and 19 bits for
|
1542
|
-
// start position - as used by StringBuilderConcatHelper?
|
1543
1794
|
if (StringBuilderSubstringLength::is_valid(length) &&
|
1544
1795
|
StringBuilderSubstringPosition::is_valid(from)) {
|
1545
1796
|
int encoded_slice = StringBuilderSubstringLength::encode(length) |
|
1546
1797
|
StringBuilderSubstringPosition::encode(from);
|
1547
|
-
|
1798
|
+
builder->Add(Smi::FromInt(encoded_slice));
|
1548
1799
|
} else {
|
1549
1800
|
// Otherwise encode as two smis.
|
1550
|
-
|
1551
|
-
|
1801
|
+
builder->Add(Smi::FromInt(-length));
|
1802
|
+
builder->Add(Smi::FromInt(from));
|
1552
1803
|
}
|
1553
|
-
|
1804
|
+
}
|
1805
|
+
|
1806
|
+
|
1807
|
+
void EnsureCapacity(int elements) {
|
1808
|
+
array_builder_.EnsureCapacity(elements);
|
1809
|
+
}
|
1810
|
+
|
1811
|
+
|
1812
|
+
void AddSubjectSlice(int from, int to) {
|
1813
|
+
AddSubjectSlice(&array_builder_, from, to);
|
1814
|
+
IncrementCharacterCount(to - from);
|
1554
1815
|
}
|
1555
1816
|
|
1556
1817
|
|
@@ -1566,7 +1827,7 @@ class ReplacementStringBuilder {
|
|
1566
1827
|
|
1567
1828
|
|
1568
1829
|
Handle<String> ToString() {
|
1569
|
-
if (
|
1830
|
+
if (array_builder_.length() == 0) {
|
1570
1831
|
return Factory::empty_string();
|
1571
1832
|
}
|
1572
1833
|
|
@@ -1578,8 +1839,8 @@ class ReplacementStringBuilder {
|
|
1578
1839
|
char* char_buffer = seq->GetChars();
|
1579
1840
|
StringBuilderConcatHelper(*subject_,
|
1580
1841
|
char_buffer,
|
1581
|
-
*
|
1582
|
-
|
1842
|
+
*array_builder_.array(),
|
1843
|
+
array_builder_.length());
|
1583
1844
|
} else {
|
1584
1845
|
// Non-ASCII.
|
1585
1846
|
joined_string = NewRawTwoByteString(character_count_);
|
@@ -1588,8 +1849,8 @@ class ReplacementStringBuilder {
|
|
1588
1849
|
uc16* char_buffer = seq->GetChars();
|
1589
1850
|
StringBuilderConcatHelper(*subject_,
|
1590
1851
|
char_buffer,
|
1591
|
-
*
|
1592
|
-
|
1852
|
+
*array_builder_.array(),
|
1853
|
+
array_builder_.length());
|
1593
1854
|
}
|
1594
1855
|
return joined_string;
|
1595
1856
|
}
|
@@ -1602,8 +1863,14 @@ class ReplacementStringBuilder {
|
|
1602
1863
|
character_count_ += by;
|
1603
1864
|
}
|
1604
1865
|
|
1605
|
-
|
1866
|
+
Handle<JSArray> GetParts() {
|
1867
|
+
Handle<JSArray> result =
|
1868
|
+
Factory::NewJSArrayWithElements(array_builder_.array());
|
1869
|
+
result->set_length(Smi::FromInt(array_builder_.length()));
|
1870
|
+
return result;
|
1871
|
+
}
|
1606
1872
|
|
1873
|
+
private:
|
1607
1874
|
Handle<String> NewRawAsciiString(int size) {
|
1608
1875
|
CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(size), String);
|
1609
1876
|
}
|
@@ -1616,14 +1883,12 @@ class ReplacementStringBuilder {
|
|
1616
1883
|
|
1617
1884
|
void AddElement(Object* element) {
|
1618
1885
|
ASSERT(element->IsSmi() || element->IsString());
|
1619
|
-
ASSERT(
|
1620
|
-
|
1621
|
-
part_count_++;
|
1886
|
+
ASSERT(array_builder_.capacity() > array_builder_.length());
|
1887
|
+
array_builder_.Add(element);
|
1622
1888
|
}
|
1623
1889
|
|
1890
|
+
FixedArrayBuilder array_builder_;
|
1624
1891
|
Handle<String> subject_;
|
1625
|
-
Handle<FixedArray> parts_;
|
1626
|
-
int part_count_;
|
1627
1892
|
int character_count_;
|
1628
1893
|
bool is_ascii_;
|
1629
1894
|
};
|
@@ -2031,7 +2296,6 @@ static Object* Runtime_StringReplaceRegExpWithString(Arguments args) {
|
|
2031
2296
|
}
|
2032
2297
|
|
2033
2298
|
|
2034
|
-
|
2035
2299
|
// Cap on the maximal shift in the Boyer-Moore implementation. By setting a
|
2036
2300
|
// limit, we can fix the size of tables.
|
2037
2301
|
static const int kBMMaxShift = 0xff;
|
@@ -2077,10 +2341,23 @@ class BMGoodSuffixBuffers {
|
|
2077
2341
|
static int bad_char_occurrence[kBMAlphabetSize];
|
2078
2342
|
static BMGoodSuffixBuffers bmgs_buffers;
|
2079
2343
|
|
2344
|
+
// State of the string match tables.
|
2345
|
+
// SIMPLE: No usable content in the buffers.
|
2346
|
+
// BOYER_MOORE_HORSPOOL: The bad_char_occurences table has been populated.
|
2347
|
+
// BOYER_MOORE: The bmgs_buffers tables have also been populated.
|
2348
|
+
// Whenever starting with a new needle, one should call InitializeStringSearch
|
2349
|
+
// to determine which search strategy to use, and in the case of a long-needle
|
2350
|
+
// strategy, the call also initializes the algorithm to SIMPLE.
|
2351
|
+
enum StringSearchAlgorithm { SIMPLE_SEARCH, BOYER_MOORE_HORSPOOL, BOYER_MOORE };
|
2352
|
+
static StringSearchAlgorithm algorithm;
|
2353
|
+
|
2354
|
+
|
2080
2355
|
// Compute the bad-char table for Boyer-Moore in the static buffer.
|
2081
2356
|
template <typename pchar>
|
2082
|
-
static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern
|
2083
|
-
|
2357
|
+
static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern) {
|
2358
|
+
// Only preprocess at most kBMMaxShift last characters of pattern.
|
2359
|
+
int start = pattern.length() < kBMMaxShift ? 0
|
2360
|
+
: pattern.length() - kBMMaxShift;
|
2084
2361
|
// Run forwards to populate bad_char_table, so that *last* instance
|
2085
2362
|
// of character equivalence class is the one registered.
|
2086
2363
|
// Notice: Doesn't include the last character.
|
@@ -2100,10 +2377,11 @@ static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern,
|
|
2100
2377
|
}
|
2101
2378
|
}
|
2102
2379
|
|
2380
|
+
|
2103
2381
|
template <typename pchar>
|
2104
|
-
static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern
|
2105
|
-
int start) {
|
2382
|
+
static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern) {
|
2106
2383
|
int m = pattern.length();
|
2384
|
+
int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
|
2107
2385
|
int len = m - start;
|
2108
2386
|
// Compute Good Suffix tables.
|
2109
2387
|
bmgs_buffers.init(m);
|
@@ -2150,6 +2428,7 @@ static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern,
|
|
2150
2428
|
}
|
2151
2429
|
}
|
2152
2430
|
|
2431
|
+
|
2153
2432
|
template <typename schar, typename pchar>
|
2154
2433
|
static inline int CharOccurrence(int char_code) {
|
2155
2434
|
if (sizeof(schar) == 1) {
|
@@ -2164,6 +2443,7 @@ static inline int CharOccurrence(int char_code) {
|
|
2164
2443
|
return bad_char_occurrence[char_code % kBMAlphabetSize];
|
2165
2444
|
}
|
2166
2445
|
|
2446
|
+
|
2167
2447
|
// Restricted simplified Boyer-Moore string matching.
|
2168
2448
|
// Uses only the bad-shift table of Boyer-Moore and only uses it
|
2169
2449
|
// for the character compared to the last character of the needle.
|
@@ -2172,14 +2452,13 @@ static int BoyerMooreHorspool(Vector<const schar> subject,
|
|
2172
2452
|
Vector<const pchar> pattern,
|
2173
2453
|
int start_index,
|
2174
2454
|
bool* complete) {
|
2455
|
+
ASSERT(algorithm <= BOYER_MOORE_HORSPOOL);
|
2175
2456
|
int n = subject.length();
|
2176
2457
|
int m = pattern.length();
|
2177
|
-
// Only preprocess at most kBMMaxShift last characters of pattern.
|
2178
|
-
int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
|
2179
2458
|
|
2180
|
-
|
2459
|
+
int badness = -m;
|
2181
2460
|
|
2182
|
-
|
2461
|
+
// How bad we are doing without a good-suffix table.
|
2183
2462
|
int idx; // No matches found prior to this index.
|
2184
2463
|
pchar last_char = pattern[m - 1];
|
2185
2464
|
int last_char_shift = m - 1 - CharOccurrence<schar, pchar>(last_char);
|
@@ -2224,13 +2503,12 @@ template <typename schar, typename pchar>
|
|
2224
2503
|
static int BoyerMooreIndexOf(Vector<const schar> subject,
|
2225
2504
|
Vector<const pchar> pattern,
|
2226
2505
|
int idx) {
|
2506
|
+
ASSERT(algorithm <= BOYER_MOORE);
|
2227
2507
|
int n = subject.length();
|
2228
2508
|
int m = pattern.length();
|
2229
2509
|
// Only preprocess at most kBMMaxShift last characters of pattern.
|
2230
2510
|
int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
|
2231
2511
|
|
2232
|
-
// Build the Good Suffix table and continue searching.
|
2233
|
-
BoyerMoorePopulateGoodSuffixTable(pattern, start);
|
2234
2512
|
pchar last_char = pattern[m - 1];
|
2235
2513
|
// Continue search from i.
|
2236
2514
|
while (idx <= n - m) {
|
@@ -2266,9 +2544,17 @@ static int BoyerMooreIndexOf(Vector<const schar> subject,
|
|
2266
2544
|
|
2267
2545
|
|
2268
2546
|
template <typename schar>
|
2269
|
-
static int SingleCharIndexOf(Vector<const schar> string,
|
2270
|
-
|
2271
|
-
|
2547
|
+
static inline int SingleCharIndexOf(Vector<const schar> string,
|
2548
|
+
schar pattern_char,
|
2549
|
+
int start_index) {
|
2550
|
+
if (sizeof(schar) == 1) {
|
2551
|
+
const schar* pos = reinterpret_cast<const schar*>(
|
2552
|
+
memchr(string.start() + start_index,
|
2553
|
+
pattern_char,
|
2554
|
+
string.length() - start_index));
|
2555
|
+
if (pos == NULL) return -1;
|
2556
|
+
return static_cast<int>(pos - string.start());
|
2557
|
+
}
|
2272
2558
|
for (int i = start_index, n = string.length(); i < n; i++) {
|
2273
2559
|
if (pattern_char == string[i]) {
|
2274
2560
|
return i;
|
@@ -2277,6 +2563,20 @@ static int SingleCharIndexOf(Vector<const schar> string,
|
|
2277
2563
|
return -1;
|
2278
2564
|
}
|
2279
2565
|
|
2566
|
+
|
2567
|
+
template <typename schar>
|
2568
|
+
static int SingleCharLastIndexOf(Vector<const schar> string,
|
2569
|
+
schar pattern_char,
|
2570
|
+
int start_index) {
|
2571
|
+
for (int i = start_index; i >= 0; i--) {
|
2572
|
+
if (pattern_char == string[i]) {
|
2573
|
+
return i;
|
2574
|
+
}
|
2575
|
+
}
|
2576
|
+
return -1;
|
2577
|
+
}
|
2578
|
+
|
2579
|
+
|
2280
2580
|
// Trivial string search for shorter strings.
|
2281
2581
|
// On return, if "complete" is set to true, the return value is the
|
2282
2582
|
// final result of searching for the patter in the subject.
|
@@ -2292,17 +2592,29 @@ static int SimpleIndexOf(Vector<const schar> subject,
|
|
2292
2592
|
// done enough work we decide it's probably worth switching to a better
|
2293
2593
|
// algorithm.
|
2294
2594
|
int badness = -10 - (pattern.length() << 2);
|
2595
|
+
|
2295
2596
|
// We know our pattern is at least 2 characters, we cache the first so
|
2296
2597
|
// the common case of the first character not matching is faster.
|
2297
2598
|
pchar pattern_first_char = pattern[0];
|
2298
|
-
|
2299
2599
|
for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) {
|
2300
2600
|
badness++;
|
2301
2601
|
if (badness > 0) {
|
2302
2602
|
*complete = false;
|
2303
2603
|
return i;
|
2304
2604
|
}
|
2305
|
-
if (
|
2605
|
+
if (sizeof(schar) == 1 && sizeof(pchar) == 1) {
|
2606
|
+
const schar* pos = reinterpret_cast<const schar*>(
|
2607
|
+
memchr(subject.start() + i,
|
2608
|
+
pattern_first_char,
|
2609
|
+
n - i + 1));
|
2610
|
+
if (pos == NULL) {
|
2611
|
+
*complete = true;
|
2612
|
+
return -1;
|
2613
|
+
}
|
2614
|
+
i = static_cast<int>(pos - subject.start());
|
2615
|
+
} else {
|
2616
|
+
if (subject[i] != pattern_first_char) continue;
|
2617
|
+
}
|
2306
2618
|
int j = 1;
|
2307
2619
|
do {
|
2308
2620
|
if (pattern[j] != subject[i+j]) {
|
@@ -2327,7 +2639,16 @@ static int SimpleIndexOf(Vector<const schar> subject,
|
|
2327
2639
|
int idx) {
|
2328
2640
|
pchar pattern_first_char = pattern[0];
|
2329
2641
|
for (int i = idx, n = subject.length() - pattern.length(); i <= n; i++) {
|
2330
|
-
if (
|
2642
|
+
if (sizeof(schar) == 1 && sizeof(pchar) == 1) {
|
2643
|
+
const schar* pos = reinterpret_cast<const schar*>(
|
2644
|
+
memchr(subject.start() + i,
|
2645
|
+
pattern_first_char,
|
2646
|
+
n - i + 1));
|
2647
|
+
if (pos == NULL) return -1;
|
2648
|
+
i = static_cast<int>(pos - subject.start());
|
2649
|
+
} else {
|
2650
|
+
if (subject[i] != pattern_first_char) continue;
|
2651
|
+
}
|
2331
2652
|
int j = 1;
|
2332
2653
|
do {
|
2333
2654
|
if (pattern[j] != subject[i+j]) {
|
@@ -2343,39 +2664,84 @@ static int SimpleIndexOf(Vector<const schar> subject,
|
|
2343
2664
|
}
|
2344
2665
|
|
2345
2666
|
|
2346
|
-
//
|
2347
|
-
|
2348
|
-
static int StringMatchStrategy(Vector<const schar> sub,
|
2349
|
-
Vector<const pchar> pat,
|
2350
|
-
int start_index) {
|
2351
|
-
ASSERT(pat.length() > 1);
|
2667
|
+
// Strategy for searching for a string in another string.
|
2668
|
+
enum StringSearchStrategy { SEARCH_FAIL, SEARCH_SHORT, SEARCH_LONG };
|
2352
2669
|
|
2670
|
+
|
2671
|
+
template <typename pchar>
|
2672
|
+
static inline StringSearchStrategy InitializeStringSearch(
|
2673
|
+
Vector<const pchar> pat, bool ascii_subject) {
|
2674
|
+
ASSERT(pat.length() > 1);
|
2353
2675
|
// We have an ASCII haystack and a non-ASCII needle. Check if there
|
2354
2676
|
// really is a non-ASCII character in the needle and bail out if there
|
2355
2677
|
// is.
|
2356
|
-
if (
|
2678
|
+
if (ascii_subject && sizeof(pchar) > 1) {
|
2357
2679
|
for (int i = 0; i < pat.length(); i++) {
|
2358
2680
|
uc16 c = pat[i];
|
2359
2681
|
if (c > String::kMaxAsciiCharCode) {
|
2360
|
-
return
|
2682
|
+
return SEARCH_FAIL;
|
2361
2683
|
}
|
2362
2684
|
}
|
2363
2685
|
}
|
2364
2686
|
if (pat.length() < kBMMinPatternLength) {
|
2365
|
-
|
2366
|
-
// The max shift of Boyer-Moore on a pattern of this length does
|
2367
|
-
// not compensate for the overhead.
|
2368
|
-
return SimpleIndexOf(sub, pat, start_index);
|
2687
|
+
return SEARCH_SHORT;
|
2369
2688
|
}
|
2689
|
+
algorithm = SIMPLE_SEARCH;
|
2690
|
+
return SEARCH_LONG;
|
2691
|
+
}
|
2692
|
+
|
2693
|
+
|
2694
|
+
// Dispatch long needle searches to different algorithms.
|
2695
|
+
template <typename schar, typename pchar>
|
2696
|
+
static int ComplexIndexOf(Vector<const schar> sub,
|
2697
|
+
Vector<const pchar> pat,
|
2698
|
+
int start_index) {
|
2699
|
+
ASSERT(pat.length() >= kBMMinPatternLength);
|
2370
2700
|
// Try algorithms in order of increasing setup cost and expected performance.
|
2371
2701
|
bool complete;
|
2372
|
-
int idx =
|
2373
|
-
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2702
|
+
int idx = start_index;
|
2703
|
+
switch (algorithm) {
|
2704
|
+
case SIMPLE_SEARCH:
|
2705
|
+
idx = SimpleIndexOf(sub, pat, idx, &complete);
|
2706
|
+
if (complete) return idx;
|
2707
|
+
BoyerMoorePopulateBadCharTable(pat);
|
2708
|
+
algorithm = BOYER_MOORE_HORSPOOL;
|
2709
|
+
// FALLTHROUGH.
|
2710
|
+
case BOYER_MOORE_HORSPOOL:
|
2711
|
+
idx = BoyerMooreHorspool(sub, pat, idx, &complete);
|
2712
|
+
if (complete) return idx;
|
2713
|
+
// Build the Good Suffix table and continue searching.
|
2714
|
+
BoyerMoorePopulateGoodSuffixTable(pat);
|
2715
|
+
algorithm = BOYER_MOORE;
|
2716
|
+
// FALLTHROUGH.
|
2717
|
+
case BOYER_MOORE:
|
2718
|
+
return BoyerMooreIndexOf(sub, pat, idx);
|
2719
|
+
}
|
2720
|
+
UNREACHABLE();
|
2721
|
+
return -1;
|
2722
|
+
}
|
2723
|
+
|
2724
|
+
|
2725
|
+
// Dispatch to different search strategies for a single search.
|
2726
|
+
// If searching multiple times on the same needle, the search
|
2727
|
+
// strategy should only be computed once and then dispatch to different
|
2728
|
+
// loops.
|
2729
|
+
template <typename schar, typename pchar>
|
2730
|
+
static int StringSearch(Vector<const schar> sub,
|
2731
|
+
Vector<const pchar> pat,
|
2732
|
+
int start_index) {
|
2733
|
+
bool ascii_subject = (sizeof(schar) == 1);
|
2734
|
+
StringSearchStrategy strategy = InitializeStringSearch(pat, ascii_subject);
|
2735
|
+
switch (strategy) {
|
2736
|
+
case SEARCH_FAIL: return -1;
|
2737
|
+
case SEARCH_SHORT: return SimpleIndexOf(sub, pat, start_index);
|
2738
|
+
case SEARCH_LONG: return ComplexIndexOf(sub, pat, start_index);
|
2739
|
+
}
|
2740
|
+
UNREACHABLE();
|
2741
|
+
return -1;
|
2377
2742
|
}
|
2378
2743
|
|
2744
|
+
|
2379
2745
|
// Perform string match of pattern on subject, starting at start index.
|
2380
2746
|
// Caller must ensure that 0 <= start_index <= sub->length(),
|
2381
2747
|
// and should check that pat->length() + start_index <= sub->length()
|
@@ -2394,6 +2760,7 @@ int Runtime::StringMatch(Handle<String> sub,
|
|
2394
2760
|
if (!sub->IsFlat()) {
|
2395
2761
|
FlattenString(sub);
|
2396
2762
|
}
|
2763
|
+
|
2397
2764
|
// Searching for one specific character is common. For one
|
2398
2765
|
// character patterns linear search is necessary, so any smart
|
2399
2766
|
// algorithm is unnecessary overhead.
|
@@ -2427,15 +2794,15 @@ int Runtime::StringMatch(Handle<String> sub,
|
|
2427
2794
|
if (pat->IsAsciiRepresentation()) {
|
2428
2795
|
Vector<const char> pat_vector = pat->ToAsciiVector();
|
2429
2796
|
if (sub->IsAsciiRepresentation()) {
|
2430
|
-
return
|
2797
|
+
return StringSearch(sub->ToAsciiVector(), pat_vector, start_index);
|
2431
2798
|
}
|
2432
|
-
return
|
2799
|
+
return StringSearch(sub->ToUC16Vector(), pat_vector, start_index);
|
2433
2800
|
}
|
2434
2801
|
Vector<const uc16> pat_vector = pat->ToUC16Vector();
|
2435
2802
|
if (sub->IsAsciiRepresentation()) {
|
2436
|
-
return
|
2803
|
+
return StringSearch(sub->ToAsciiVector(), pat_vector, start_index);
|
2437
2804
|
}
|
2438
|
-
return
|
2805
|
+
return StringSearch(sub->ToUC16Vector(), pat_vector, start_index);
|
2439
2806
|
}
|
2440
2807
|
|
2441
2808
|
|
@@ -2456,47 +2823,123 @@ static Object* Runtime_StringIndexOf(Arguments args) {
|
|
2456
2823
|
}
|
2457
2824
|
|
2458
2825
|
|
2826
|
+
template <typename schar, typename pchar>
|
2827
|
+
static int StringMatchBackwards(Vector<const schar> sub,
|
2828
|
+
Vector<const pchar> pat,
|
2829
|
+
int idx) {
|
2830
|
+
ASSERT(pat.length() >= 1);
|
2831
|
+
ASSERT(idx + pat.length() <= sub.length());
|
2832
|
+
|
2833
|
+
if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
|
2834
|
+
for (int i = 0; i < pat.length(); i++) {
|
2835
|
+
uc16 c = pat[i];
|
2836
|
+
if (c > String::kMaxAsciiCharCode) {
|
2837
|
+
return -1;
|
2838
|
+
}
|
2839
|
+
}
|
2840
|
+
}
|
2841
|
+
|
2842
|
+
pchar pattern_first_char = pat[0];
|
2843
|
+
for (int i = idx; i >= 0; i--) {
|
2844
|
+
if (sub[i] != pattern_first_char) continue;
|
2845
|
+
int j = 1;
|
2846
|
+
while (j < pat.length()) {
|
2847
|
+
if (pat[j] != sub[i+j]) {
|
2848
|
+
break;
|
2849
|
+
}
|
2850
|
+
j++;
|
2851
|
+
}
|
2852
|
+
if (j == pat.length()) {
|
2853
|
+
return i;
|
2854
|
+
}
|
2855
|
+
}
|
2856
|
+
return -1;
|
2857
|
+
}
|
2858
|
+
|
2459
2859
|
static Object* Runtime_StringLastIndexOf(Arguments args) {
|
2460
|
-
|
2860
|
+
HandleScope scope; // create a new handle scope
|
2461
2861
|
ASSERT(args.length() == 3);
|
2462
2862
|
|
2463
|
-
|
2464
|
-
|
2465
|
-
Object* index = args[2];
|
2466
|
-
|
2467
|
-
sub->TryFlattenIfNotFlat();
|
2468
|
-
pat->TryFlattenIfNotFlat();
|
2863
|
+
CONVERT_ARG_CHECKED(String, sub, 0);
|
2864
|
+
CONVERT_ARG_CHECKED(String, pat, 1);
|
2469
2865
|
|
2866
|
+
Object* index = args[2];
|
2470
2867
|
uint32_t start_index;
|
2471
2868
|
if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
|
2472
2869
|
|
2473
|
-
uint32_t
|
2870
|
+
uint32_t pat_length = pat->length();
|
2474
2871
|
uint32_t sub_length = sub->length();
|
2475
2872
|
|
2476
|
-
if (start_index +
|
2477
|
-
start_index = sub_length -
|
2873
|
+
if (start_index + pat_length > sub_length) {
|
2874
|
+
start_index = sub_length - pat_length;
|
2478
2875
|
}
|
2479
2876
|
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2877
|
+
if (pat_length == 0) {
|
2878
|
+
return Smi::FromInt(start_index);
|
2879
|
+
}
|
2880
|
+
|
2881
|
+
if (!sub->IsFlat()) {
|
2882
|
+
FlattenString(sub);
|
2883
|
+
}
|
2884
|
+
|
2885
|
+
if (pat_length == 1) {
|
2886
|
+
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
|
2887
|
+
if (sub->IsAsciiRepresentation()) {
|
2888
|
+
uc16 pchar = pat->Get(0);
|
2889
|
+
if (pchar > String::kMaxAsciiCharCode) {
|
2890
|
+
return Smi::FromInt(-1);
|
2486
2891
|
}
|
2892
|
+
return Smi::FromInt(SingleCharLastIndexOf(sub->ToAsciiVector(),
|
2893
|
+
static_cast<char>(pat->Get(0)),
|
2894
|
+
start_index));
|
2895
|
+
} else {
|
2896
|
+
return Smi::FromInt(SingleCharLastIndexOf(sub->ToUC16Vector(),
|
2897
|
+
pat->Get(0),
|
2898
|
+
start_index));
|
2487
2899
|
}
|
2488
|
-
if (found) return Smi::FromInt(i);
|
2489
2900
|
}
|
2490
2901
|
|
2491
|
-
|
2492
|
-
|
2902
|
+
if (!pat->IsFlat()) {
|
2903
|
+
FlattenString(pat);
|
2904
|
+
}
|
2493
2905
|
|
2906
|
+
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
|
2494
2907
|
|
2495
|
-
|
2496
|
-
NoHandleAllocation ha;
|
2497
|
-
ASSERT(args.length() == 2);
|
2908
|
+
int position = -1;
|
2498
2909
|
|
2499
|
-
|
2910
|
+
if (pat->IsAsciiRepresentation()) {
|
2911
|
+
Vector<const char> pat_vector = pat->ToAsciiVector();
|
2912
|
+
if (sub->IsAsciiRepresentation()) {
|
2913
|
+
position = StringMatchBackwards(sub->ToAsciiVector(),
|
2914
|
+
pat_vector,
|
2915
|
+
start_index);
|
2916
|
+
} else {
|
2917
|
+
position = StringMatchBackwards(sub->ToUC16Vector(),
|
2918
|
+
pat_vector,
|
2919
|
+
start_index);
|
2920
|
+
}
|
2921
|
+
} else {
|
2922
|
+
Vector<const uc16> pat_vector = pat->ToUC16Vector();
|
2923
|
+
if (sub->IsAsciiRepresentation()) {
|
2924
|
+
position = StringMatchBackwards(sub->ToAsciiVector(),
|
2925
|
+
pat_vector,
|
2926
|
+
start_index);
|
2927
|
+
} else {
|
2928
|
+
position = StringMatchBackwards(sub->ToUC16Vector(),
|
2929
|
+
pat_vector,
|
2930
|
+
start_index);
|
2931
|
+
}
|
2932
|
+
}
|
2933
|
+
|
2934
|
+
return Smi::FromInt(position);
|
2935
|
+
}
|
2936
|
+
|
2937
|
+
|
2938
|
+
static Object* Runtime_StringLocaleCompare(Arguments args) {
|
2939
|
+
NoHandleAllocation ha;
|
2940
|
+
ASSERT(args.length() == 2);
|
2941
|
+
|
2942
|
+
CONVERT_CHECKED(String, str1, args[0]);
|
2500
2943
|
CONVERT_CHECKED(String, str2, args[1]);
|
2501
2944
|
|
2502
2945
|
if (str1 == str2) return Smi::FromInt(0); // Equal.
|
@@ -2519,8 +2962,8 @@ static Object* Runtime_StringLocaleCompare(Arguments args) {
|
|
2519
2962
|
int d = str1->Get(0) - str2->Get(0);
|
2520
2963
|
if (d != 0) return Smi::FromInt(d);
|
2521
2964
|
|
2522
|
-
str1->
|
2523
|
-
str2->
|
2965
|
+
str1->TryFlatten();
|
2966
|
+
str2->TryFlatten();
|
2524
2967
|
|
2525
2968
|
static StringInputBuffer buf1;
|
2526
2969
|
static StringInputBuffer buf2;
|
@@ -2616,6 +3059,476 @@ static Object* Runtime_StringMatch(Arguments args) {
|
|
2616
3059
|
}
|
2617
3060
|
|
2618
3061
|
|
3062
|
+
// Two smis before and after the match, for very long strings.
|
3063
|
+
const int kMaxBuilderEntriesPerRegExpMatch = 5;
|
3064
|
+
|
3065
|
+
|
3066
|
+
static void SetLastMatchInfoNoCaptures(Handle<String> subject,
|
3067
|
+
Handle<JSArray> last_match_info,
|
3068
|
+
int match_start,
|
3069
|
+
int match_end) {
|
3070
|
+
// Fill last_match_info with a single capture.
|
3071
|
+
last_match_info->EnsureSize(2 + RegExpImpl::kLastMatchOverhead);
|
3072
|
+
AssertNoAllocation no_gc;
|
3073
|
+
FixedArray* elements = FixedArray::cast(last_match_info->elements());
|
3074
|
+
RegExpImpl::SetLastCaptureCount(elements, 2);
|
3075
|
+
RegExpImpl::SetLastInput(elements, *subject);
|
3076
|
+
RegExpImpl::SetLastSubject(elements, *subject);
|
3077
|
+
RegExpImpl::SetCapture(elements, 0, match_start);
|
3078
|
+
RegExpImpl::SetCapture(elements, 1, match_end);
|
3079
|
+
}
|
3080
|
+
|
3081
|
+
|
3082
|
+
template <typename schar>
|
3083
|
+
static bool SearchCharMultiple(Vector<schar> subject,
|
3084
|
+
String* pattern,
|
3085
|
+
schar pattern_char,
|
3086
|
+
FixedArrayBuilder* builder,
|
3087
|
+
int* match_pos) {
|
3088
|
+
// Position of last match.
|
3089
|
+
int pos = *match_pos;
|
3090
|
+
int subject_length = subject.length();
|
3091
|
+
while (pos < subject_length) {
|
3092
|
+
int match_end = pos + 1;
|
3093
|
+
if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
|
3094
|
+
*match_pos = pos;
|
3095
|
+
return false;
|
3096
|
+
}
|
3097
|
+
int new_pos = SingleCharIndexOf(subject, pattern_char, match_end);
|
3098
|
+
if (new_pos >= 0) {
|
3099
|
+
// Match has been found.
|
3100
|
+
if (new_pos > match_end) {
|
3101
|
+
ReplacementStringBuilder::AddSubjectSlice(builder, match_end, new_pos);
|
3102
|
+
}
|
3103
|
+
pos = new_pos;
|
3104
|
+
builder->Add(pattern);
|
3105
|
+
} else {
|
3106
|
+
break;
|
3107
|
+
}
|
3108
|
+
}
|
3109
|
+
if (pos + 1 < subject_length) {
|
3110
|
+
ReplacementStringBuilder::AddSubjectSlice(builder, pos + 1, subject_length);
|
3111
|
+
}
|
3112
|
+
*match_pos = pos;
|
3113
|
+
return true;
|
3114
|
+
}
|
3115
|
+
|
3116
|
+
|
3117
|
+
static bool SearchCharMultiple(Handle<String> subject,
|
3118
|
+
Handle<String> pattern,
|
3119
|
+
Handle<JSArray> last_match_info,
|
3120
|
+
FixedArrayBuilder* builder) {
|
3121
|
+
ASSERT(subject->IsFlat());
|
3122
|
+
ASSERT_EQ(1, pattern->length());
|
3123
|
+
uc16 pattern_char = pattern->Get(0);
|
3124
|
+
// Treating position before first as initial "previous match position".
|
3125
|
+
int match_pos = -1;
|
3126
|
+
|
3127
|
+
for (;;) { // Break when search complete.
|
3128
|
+
builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
|
3129
|
+
AssertNoAllocation no_gc;
|
3130
|
+
if (subject->IsAsciiRepresentation()) {
|
3131
|
+
if (pattern_char > String::kMaxAsciiCharCode) {
|
3132
|
+
break;
|
3133
|
+
}
|
3134
|
+
Vector<const char> subject_vector = subject->ToAsciiVector();
|
3135
|
+
char pattern_ascii_char = static_cast<char>(pattern_char);
|
3136
|
+
bool complete = SearchCharMultiple<const char>(subject_vector,
|
3137
|
+
*pattern,
|
3138
|
+
pattern_ascii_char,
|
3139
|
+
builder,
|
3140
|
+
&match_pos);
|
3141
|
+
if (complete) break;
|
3142
|
+
} else {
|
3143
|
+
Vector<const uc16> subject_vector = subject->ToUC16Vector();
|
3144
|
+
bool complete = SearchCharMultiple<const uc16>(subject_vector,
|
3145
|
+
*pattern,
|
3146
|
+
pattern_char,
|
3147
|
+
builder,
|
3148
|
+
&match_pos);
|
3149
|
+
if (complete) break;
|
3150
|
+
}
|
3151
|
+
}
|
3152
|
+
|
3153
|
+
if (match_pos >= 0) {
|
3154
|
+
SetLastMatchInfoNoCaptures(subject,
|
3155
|
+
last_match_info,
|
3156
|
+
match_pos,
|
3157
|
+
match_pos + 1);
|
3158
|
+
return true;
|
3159
|
+
}
|
3160
|
+
return false; // No matches at all.
|
3161
|
+
}
|
3162
|
+
|
3163
|
+
|
3164
|
+
template <typename schar, typename pchar>
|
3165
|
+
static bool SearchStringMultiple(Vector<schar> subject,
|
3166
|
+
String* pattern,
|
3167
|
+
Vector<pchar> pattern_string,
|
3168
|
+
FixedArrayBuilder* builder,
|
3169
|
+
int* match_pos) {
|
3170
|
+
int pos = *match_pos;
|
3171
|
+
int subject_length = subject.length();
|
3172
|
+
int pattern_length = pattern_string.length();
|
3173
|
+
int max_search_start = subject_length - pattern_length;
|
3174
|
+
bool is_ascii = (sizeof(schar) == 1);
|
3175
|
+
StringSearchStrategy strategy =
|
3176
|
+
InitializeStringSearch(pattern_string, is_ascii);
|
3177
|
+
switch (strategy) {
|
3178
|
+
case SEARCH_FAIL: break;
|
3179
|
+
case SEARCH_SHORT:
|
3180
|
+
while (pos <= max_search_start) {
|
3181
|
+
if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
|
3182
|
+
*match_pos = pos;
|
3183
|
+
return false;
|
3184
|
+
}
|
3185
|
+
// Position of end of previous match.
|
3186
|
+
int match_end = pos + pattern_length;
|
3187
|
+
int new_pos = SimpleIndexOf(subject, pattern_string, match_end);
|
3188
|
+
if (new_pos >= 0) {
|
3189
|
+
// A match.
|
3190
|
+
if (new_pos > match_end) {
|
3191
|
+
ReplacementStringBuilder::AddSubjectSlice(builder,
|
3192
|
+
match_end,
|
3193
|
+
new_pos);
|
3194
|
+
}
|
3195
|
+
pos = new_pos;
|
3196
|
+
builder->Add(pattern);
|
3197
|
+
} else {
|
3198
|
+
break;
|
3199
|
+
}
|
3200
|
+
}
|
3201
|
+
break;
|
3202
|
+
case SEARCH_LONG:
|
3203
|
+
while (pos <= max_search_start) {
|
3204
|
+
if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
|
3205
|
+
*match_pos = pos;
|
3206
|
+
return false;
|
3207
|
+
}
|
3208
|
+
int match_end = pos + pattern_length;
|
3209
|
+
int new_pos = ComplexIndexOf(subject, pattern_string, match_end);
|
3210
|
+
if (new_pos >= 0) {
|
3211
|
+
// A match has been found.
|
3212
|
+
if (new_pos > match_end) {
|
3213
|
+
ReplacementStringBuilder::AddSubjectSlice(builder,
|
3214
|
+
match_end,
|
3215
|
+
new_pos);
|
3216
|
+
}
|
3217
|
+
pos = new_pos;
|
3218
|
+
builder->Add(pattern);
|
3219
|
+
} else {
|
3220
|
+
break;
|
3221
|
+
}
|
3222
|
+
}
|
3223
|
+
break;
|
3224
|
+
}
|
3225
|
+
if (pos < max_search_start) {
|
3226
|
+
ReplacementStringBuilder::AddSubjectSlice(builder,
|
3227
|
+
pos + pattern_length,
|
3228
|
+
subject_length);
|
3229
|
+
}
|
3230
|
+
*match_pos = pos;
|
3231
|
+
return true;
|
3232
|
+
}
|
3233
|
+
|
3234
|
+
|
3235
|
+
static bool SearchStringMultiple(Handle<String> subject,
|
3236
|
+
Handle<String> pattern,
|
3237
|
+
Handle<JSArray> last_match_info,
|
3238
|
+
FixedArrayBuilder* builder) {
|
3239
|
+
ASSERT(subject->IsFlat());
|
3240
|
+
ASSERT(pattern->IsFlat());
|
3241
|
+
ASSERT(pattern->length() > 1);
|
3242
|
+
|
3243
|
+
// Treating as if a previous match was before first character.
|
3244
|
+
int match_pos = -pattern->length();
|
3245
|
+
|
3246
|
+
for (;;) { // Break when search complete.
|
3247
|
+
builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
|
3248
|
+
AssertNoAllocation no_gc;
|
3249
|
+
if (subject->IsAsciiRepresentation()) {
|
3250
|
+
Vector<const char> subject_vector = subject->ToAsciiVector();
|
3251
|
+
if (pattern->IsAsciiRepresentation()) {
|
3252
|
+
if (SearchStringMultiple(subject_vector,
|
3253
|
+
*pattern,
|
3254
|
+
pattern->ToAsciiVector(),
|
3255
|
+
builder,
|
3256
|
+
&match_pos)) break;
|
3257
|
+
} else {
|
3258
|
+
if (SearchStringMultiple(subject_vector,
|
3259
|
+
*pattern,
|
3260
|
+
pattern->ToUC16Vector(),
|
3261
|
+
builder,
|
3262
|
+
&match_pos)) break;
|
3263
|
+
}
|
3264
|
+
} else {
|
3265
|
+
Vector<const uc16> subject_vector = subject->ToUC16Vector();
|
3266
|
+
if (pattern->IsAsciiRepresentation()) {
|
3267
|
+
if (SearchStringMultiple(subject_vector,
|
3268
|
+
*pattern,
|
3269
|
+
pattern->ToAsciiVector(),
|
3270
|
+
builder,
|
3271
|
+
&match_pos)) break;
|
3272
|
+
} else {
|
3273
|
+
if (SearchStringMultiple(subject_vector,
|
3274
|
+
*pattern,
|
3275
|
+
pattern->ToUC16Vector(),
|
3276
|
+
builder,
|
3277
|
+
&match_pos)) break;
|
3278
|
+
}
|
3279
|
+
}
|
3280
|
+
}
|
3281
|
+
|
3282
|
+
if (match_pos >= 0) {
|
3283
|
+
SetLastMatchInfoNoCaptures(subject,
|
3284
|
+
last_match_info,
|
3285
|
+
match_pos,
|
3286
|
+
match_pos + pattern->length());
|
3287
|
+
return true;
|
3288
|
+
}
|
3289
|
+
return false; // No matches at all.
|
3290
|
+
}
|
3291
|
+
|
3292
|
+
|
3293
|
+
static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
|
3294
|
+
Handle<String> subject,
|
3295
|
+
Handle<JSRegExp> regexp,
|
3296
|
+
Handle<JSArray> last_match_array,
|
3297
|
+
FixedArrayBuilder* builder) {
|
3298
|
+
ASSERT(subject->IsFlat());
|
3299
|
+
int match_start = -1;
|
3300
|
+
int match_end = 0;
|
3301
|
+
int pos = 0;
|
3302
|
+
int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
|
3303
|
+
if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
|
3304
|
+
|
3305
|
+
OffsetsVector registers(required_registers);
|
3306
|
+
Vector<int> register_vector(registers.vector(), registers.length());
|
3307
|
+
int subject_length = subject->length();
|
3308
|
+
|
3309
|
+
for (;;) { // Break on failure, return on exception.
|
3310
|
+
RegExpImpl::IrregexpResult result =
|
3311
|
+
RegExpImpl::IrregexpExecOnce(regexp,
|
3312
|
+
subject,
|
3313
|
+
pos,
|
3314
|
+
register_vector);
|
3315
|
+
if (result == RegExpImpl::RE_SUCCESS) {
|
3316
|
+
match_start = register_vector[0];
|
3317
|
+
builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
|
3318
|
+
if (match_end < match_start) {
|
3319
|
+
ReplacementStringBuilder::AddSubjectSlice(builder,
|
3320
|
+
match_end,
|
3321
|
+
match_start);
|
3322
|
+
}
|
3323
|
+
match_end = register_vector[1];
|
3324
|
+
HandleScope loop_scope;
|
3325
|
+
builder->Add(*Factory::NewSubString(subject, match_start, match_end));
|
3326
|
+
if (match_start != match_end) {
|
3327
|
+
pos = match_end;
|
3328
|
+
} else {
|
3329
|
+
pos = match_end + 1;
|
3330
|
+
if (pos > subject_length) break;
|
3331
|
+
}
|
3332
|
+
} else if (result == RegExpImpl::RE_FAILURE) {
|
3333
|
+
break;
|
3334
|
+
} else {
|
3335
|
+
ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
|
3336
|
+
return result;
|
3337
|
+
}
|
3338
|
+
}
|
3339
|
+
|
3340
|
+
if (match_start >= 0) {
|
3341
|
+
if (match_end < subject_length) {
|
3342
|
+
ReplacementStringBuilder::AddSubjectSlice(builder,
|
3343
|
+
match_end,
|
3344
|
+
subject_length);
|
3345
|
+
}
|
3346
|
+
SetLastMatchInfoNoCaptures(subject,
|
3347
|
+
last_match_array,
|
3348
|
+
match_start,
|
3349
|
+
match_end);
|
3350
|
+
return RegExpImpl::RE_SUCCESS;
|
3351
|
+
} else {
|
3352
|
+
return RegExpImpl::RE_FAILURE; // No matches at all.
|
3353
|
+
}
|
3354
|
+
}
|
3355
|
+
|
3356
|
+
|
3357
|
+
static RegExpImpl::IrregexpResult SearchRegExpMultiple(
|
3358
|
+
Handle<String> subject,
|
3359
|
+
Handle<JSRegExp> regexp,
|
3360
|
+
Handle<JSArray> last_match_array,
|
3361
|
+
FixedArrayBuilder* builder) {
|
3362
|
+
|
3363
|
+
ASSERT(subject->IsFlat());
|
3364
|
+
int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
|
3365
|
+
if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
|
3366
|
+
|
3367
|
+
OffsetsVector registers(required_registers);
|
3368
|
+
Vector<int> register_vector(registers.vector(), registers.length());
|
3369
|
+
|
3370
|
+
RegExpImpl::IrregexpResult result =
|
3371
|
+
RegExpImpl::IrregexpExecOnce(regexp,
|
3372
|
+
subject,
|
3373
|
+
0,
|
3374
|
+
register_vector);
|
3375
|
+
|
3376
|
+
int capture_count = regexp->CaptureCount();
|
3377
|
+
int subject_length = subject->length();
|
3378
|
+
|
3379
|
+
// Position to search from.
|
3380
|
+
int pos = 0;
|
3381
|
+
// End of previous match. Differs from pos if match was empty.
|
3382
|
+
int match_end = 0;
|
3383
|
+
if (result == RegExpImpl::RE_SUCCESS) {
|
3384
|
+
// Need to keep a copy of the previous match for creating last_match_info
|
3385
|
+
// at the end, so we have two vectors that we swap between.
|
3386
|
+
OffsetsVector registers2(required_registers);
|
3387
|
+
Vector<int> prev_register_vector(registers2.vector(), registers2.length());
|
3388
|
+
|
3389
|
+
do {
|
3390
|
+
int match_start = register_vector[0];
|
3391
|
+
builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
|
3392
|
+
if (match_end < match_start) {
|
3393
|
+
ReplacementStringBuilder::AddSubjectSlice(builder,
|
3394
|
+
match_end,
|
3395
|
+
match_start);
|
3396
|
+
}
|
3397
|
+
match_end = register_vector[1];
|
3398
|
+
|
3399
|
+
{
|
3400
|
+
// Avoid accumulating new handles inside loop.
|
3401
|
+
HandleScope temp_scope;
|
3402
|
+
// Arguments array to replace function is match, captures, index and
|
3403
|
+
// subject, i.e., 3 + capture count in total.
|
3404
|
+
Handle<FixedArray> elements = Factory::NewFixedArray(3 + capture_count);
|
3405
|
+
elements->set(0, *Factory::NewSubString(subject,
|
3406
|
+
match_start,
|
3407
|
+
match_end));
|
3408
|
+
for (int i = 1; i <= capture_count; i++) {
|
3409
|
+
int start = register_vector[i * 2];
|
3410
|
+
if (start >= 0) {
|
3411
|
+
int end = register_vector[i * 2 + 1];
|
3412
|
+
ASSERT(start <= end);
|
3413
|
+
Handle<String> substring = Factory::NewSubString(subject,
|
3414
|
+
start,
|
3415
|
+
end);
|
3416
|
+
elements->set(i, *substring);
|
3417
|
+
} else {
|
3418
|
+
ASSERT(register_vector[i * 2 + 1] < 0);
|
3419
|
+
elements->set(i, Heap::undefined_value());
|
3420
|
+
}
|
3421
|
+
}
|
3422
|
+
elements->set(capture_count + 1, Smi::FromInt(match_start));
|
3423
|
+
elements->set(capture_count + 2, *subject);
|
3424
|
+
builder->Add(*Factory::NewJSArrayWithElements(elements));
|
3425
|
+
}
|
3426
|
+
// Swap register vectors, so the last successful match is in
|
3427
|
+
// prev_register_vector.
|
3428
|
+
Vector<int> tmp = prev_register_vector;
|
3429
|
+
prev_register_vector = register_vector;
|
3430
|
+
register_vector = tmp;
|
3431
|
+
|
3432
|
+
if (match_end > match_start) {
|
3433
|
+
pos = match_end;
|
3434
|
+
} else {
|
3435
|
+
pos = match_end + 1;
|
3436
|
+
if (pos > subject_length) {
|
3437
|
+
break;
|
3438
|
+
}
|
3439
|
+
}
|
3440
|
+
|
3441
|
+
result = RegExpImpl::IrregexpExecOnce(regexp,
|
3442
|
+
subject,
|
3443
|
+
pos,
|
3444
|
+
register_vector);
|
3445
|
+
} while (result == RegExpImpl::RE_SUCCESS);
|
3446
|
+
|
3447
|
+
if (result != RegExpImpl::RE_EXCEPTION) {
|
3448
|
+
// Finished matching, with at least one match.
|
3449
|
+
if (match_end < subject_length) {
|
3450
|
+
ReplacementStringBuilder::AddSubjectSlice(builder,
|
3451
|
+
match_end,
|
3452
|
+
subject_length);
|
3453
|
+
}
|
3454
|
+
|
3455
|
+
int last_match_capture_count = (capture_count + 1) * 2;
|
3456
|
+
int last_match_array_size =
|
3457
|
+
last_match_capture_count + RegExpImpl::kLastMatchOverhead;
|
3458
|
+
last_match_array->EnsureSize(last_match_array_size);
|
3459
|
+
AssertNoAllocation no_gc;
|
3460
|
+
FixedArray* elements = FixedArray::cast(last_match_array->elements());
|
3461
|
+
RegExpImpl::SetLastCaptureCount(elements, last_match_capture_count);
|
3462
|
+
RegExpImpl::SetLastSubject(elements, *subject);
|
3463
|
+
RegExpImpl::SetLastInput(elements, *subject);
|
3464
|
+
for (int i = 0; i < last_match_capture_count; i++) {
|
3465
|
+
RegExpImpl::SetCapture(elements, i, prev_register_vector[i]);
|
3466
|
+
}
|
3467
|
+
return RegExpImpl::RE_SUCCESS;
|
3468
|
+
}
|
3469
|
+
}
|
3470
|
+
// No matches at all, return failure or exception result directly.
|
3471
|
+
return result;
|
3472
|
+
}
|
3473
|
+
|
3474
|
+
|
3475
|
+
static Object* Runtime_RegExpExecMultiple(Arguments args) {
|
3476
|
+
ASSERT(args.length() == 4);
|
3477
|
+
HandleScope handles;
|
3478
|
+
|
3479
|
+
CONVERT_ARG_CHECKED(String, subject, 1);
|
3480
|
+
if (!subject->IsFlat()) { FlattenString(subject); }
|
3481
|
+
CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
|
3482
|
+
CONVERT_ARG_CHECKED(JSArray, last_match_info, 2);
|
3483
|
+
CONVERT_ARG_CHECKED(JSArray, result_array, 3);
|
3484
|
+
|
3485
|
+
ASSERT(last_match_info->HasFastElements());
|
3486
|
+
ASSERT(regexp->GetFlags().is_global());
|
3487
|
+
Handle<FixedArray> result_elements;
|
3488
|
+
if (result_array->HasFastElements()) {
|
3489
|
+
result_elements =
|
3490
|
+
Handle<FixedArray>(FixedArray::cast(result_array->elements()));
|
3491
|
+
} else {
|
3492
|
+
result_elements = Factory::NewFixedArrayWithHoles(16);
|
3493
|
+
}
|
3494
|
+
FixedArrayBuilder builder(result_elements);
|
3495
|
+
|
3496
|
+
if (regexp->TypeTag() == JSRegExp::ATOM) {
|
3497
|
+
Handle<String> pattern(
|
3498
|
+
String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex)));
|
3499
|
+
int pattern_length = pattern->length();
|
3500
|
+
if (pattern_length == 1) {
|
3501
|
+
if (SearchCharMultiple(subject, pattern, last_match_info, &builder)) {
|
3502
|
+
return *builder.ToJSArray(result_array);
|
3503
|
+
}
|
3504
|
+
return Heap::null_value();
|
3505
|
+
}
|
3506
|
+
|
3507
|
+
if (!pattern->IsFlat()) FlattenString(pattern);
|
3508
|
+
if (SearchStringMultiple(subject, pattern, last_match_info, &builder)) {
|
3509
|
+
return *builder.ToJSArray(result_array);
|
3510
|
+
}
|
3511
|
+
return Heap::null_value();
|
3512
|
+
}
|
3513
|
+
|
3514
|
+
ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
|
3515
|
+
|
3516
|
+
RegExpImpl::IrregexpResult result;
|
3517
|
+
if (regexp->CaptureCount() == 0) {
|
3518
|
+
result = SearchRegExpNoCaptureMultiple(subject,
|
3519
|
+
regexp,
|
3520
|
+
last_match_info,
|
3521
|
+
&builder);
|
3522
|
+
} else {
|
3523
|
+
result = SearchRegExpMultiple(subject, regexp, last_match_info, &builder);
|
3524
|
+
}
|
3525
|
+
if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
|
3526
|
+
if (result == RegExpImpl::RE_FAILURE) return Heap::null_value();
|
3527
|
+
ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
|
3528
|
+
return Failure::Exception();
|
3529
|
+
}
|
3530
|
+
|
3531
|
+
|
2619
3532
|
static Object* Runtime_NumberToRadixString(Arguments args) {
|
2620
3533
|
NoHandleAllocation ha;
|
2621
3534
|
ASSERT(args.length() == 2);
|
@@ -2729,7 +3642,7 @@ static Object* Runtime_NumberToPrecision(Arguments args) {
|
|
2729
3642
|
// string->Get(index).
|
2730
3643
|
static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
|
2731
3644
|
if (index < static_cast<uint32_t>(string->length())) {
|
2732
|
-
string->
|
3645
|
+
string->TryFlatten();
|
2733
3646
|
return LookupSingleCharacterStringFromCode(
|
2734
3647
|
string->Get(index));
|
2735
3648
|
}
|
@@ -2757,6 +3670,11 @@ Object* Runtime::GetElementOrCharAt(Handle<Object> object, uint32_t index) {
|
|
2757
3670
|
return prototype->GetElement(index);
|
2758
3671
|
}
|
2759
3672
|
|
3673
|
+
return GetElement(object, index);
|
3674
|
+
}
|
3675
|
+
|
3676
|
+
|
3677
|
+
Object* Runtime::GetElement(Handle<Object> object, uint32_t index) {
|
2760
3678
|
return object->GetElement(index);
|
2761
3679
|
}
|
2762
3680
|
|
@@ -2845,7 +3763,7 @@ static Object* Runtime_KeyedGetProperty(Arguments args) {
|
|
2845
3763
|
// Lookup cache miss. Perform lookup and update the cache if appropriate.
|
2846
3764
|
LookupResult result;
|
2847
3765
|
receiver->LocalLookup(key, &result);
|
2848
|
-
if (result.IsProperty() && result.
|
3766
|
+
if (result.IsProperty() && result.type() == FIELD) {
|
2849
3767
|
int offset = result.GetFieldIndex();
|
2850
3768
|
KeyedLookupCache::Update(receiver_map, key, offset);
|
2851
3769
|
return receiver->FastPropertyAt(offset);
|
@@ -2878,6 +3796,67 @@ static Object* Runtime_KeyedGetProperty(Arguments args) {
|
|
2878
3796
|
}
|
2879
3797
|
|
2880
3798
|
|
3799
|
+
static Object* Runtime_DefineOrRedefineAccessorProperty(Arguments args) {
|
3800
|
+
ASSERT(args.length() == 5);
|
3801
|
+
HandleScope scope;
|
3802
|
+
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
3803
|
+
CONVERT_CHECKED(String, name, args[1]);
|
3804
|
+
CONVERT_CHECKED(Smi, flag_setter, args[2]);
|
3805
|
+
CONVERT_CHECKED(JSFunction, fun, args[3]);
|
3806
|
+
CONVERT_CHECKED(Smi, flag_attr, args[4]);
|
3807
|
+
int unchecked = flag_attr->value();
|
3808
|
+
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
|
3809
|
+
RUNTIME_ASSERT(!obj->IsNull());
|
3810
|
+
LookupResult result;
|
3811
|
+
obj->LocalLookupRealNamedProperty(name, &result);
|
3812
|
+
|
3813
|
+
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
|
3814
|
+
// If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
|
3815
|
+
// delete it to avoid running into trouble in DefineAccessor, which
|
3816
|
+
// handles this incorrectly if the property is readonly (does nothing)
|
3817
|
+
if (result.IsProperty() &&
|
3818
|
+
(result.type() == FIELD || result.type() == NORMAL
|
3819
|
+
|| result.type() == CONSTANT_FUNCTION)) {
|
3820
|
+
obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
|
3821
|
+
}
|
3822
|
+
return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr);
|
3823
|
+
}
|
3824
|
+
|
3825
|
+
static Object* Runtime_DefineOrRedefineDataProperty(Arguments args) {
|
3826
|
+
ASSERT(args.length() == 4);
|
3827
|
+
HandleScope scope;
|
3828
|
+
CONVERT_ARG_CHECKED(JSObject, js_object, 0);
|
3829
|
+
CONVERT_ARG_CHECKED(String, name, 1);
|
3830
|
+
Handle<Object> obj_value = args.at<Object>(2);
|
3831
|
+
|
3832
|
+
CONVERT_CHECKED(Smi, flag, args[3]);
|
3833
|
+
int unchecked = flag->value();
|
3834
|
+
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
|
3835
|
+
|
3836
|
+
LookupResult result;
|
3837
|
+
js_object->LocalLookupRealNamedProperty(*name, &result);
|
3838
|
+
|
3839
|
+
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
|
3840
|
+
|
3841
|
+
// Take special care when attributes are different and there is already
|
3842
|
+
// a property. For simplicity we normalize the property which enables us
|
3843
|
+
// to not worry about changing the instance_descriptor and creating a new
|
3844
|
+
// map. The current version of SetObjectProperty does not handle attributes
|
3845
|
+
// correctly in the case where a property is a field and is reset with
|
3846
|
+
// new attributes.
|
3847
|
+
if (result.IsProperty() && attr != result.GetAttributes()) {
|
3848
|
+
// New attributes - normalize to avoid writing to instance descriptor
|
3849
|
+
js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
3850
|
+
// Use IgnoreAttributes version since a readonly property may be
|
3851
|
+
// overridden and SetProperty does not allow this.
|
3852
|
+
return js_object->IgnoreAttributesAndSetLocalProperty(*name,
|
3853
|
+
*obj_value,
|
3854
|
+
attr);
|
3855
|
+
}
|
3856
|
+
return Runtime::SetObjectProperty(js_object, name, obj_value, attr);
|
3857
|
+
}
|
3858
|
+
|
3859
|
+
|
2881
3860
|
Object* Runtime::SetObjectProperty(Handle<Object> object,
|
2882
3861
|
Handle<Object> key,
|
2883
3862
|
Handle<Object> value,
|
@@ -2900,8 +3879,6 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
|
|
2900
3879
|
// Check if the given key is an array index.
|
2901
3880
|
uint32_t index;
|
2902
3881
|
if (Array::IndexFromObject(*key, &index)) {
|
2903
|
-
ASSERT(attr == NONE);
|
2904
|
-
|
2905
3882
|
// In Firefox/SpiderMonkey, Safari and Opera you can access the characters
|
2906
3883
|
// of a string using [] notation. We need to support this too in
|
2907
3884
|
// JavaScript.
|
@@ -2921,11 +3898,10 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
|
|
2921
3898
|
if (key->IsString()) {
|
2922
3899
|
Handle<Object> result;
|
2923
3900
|
if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
|
2924
|
-
ASSERT(attr == NONE);
|
2925
3901
|
result = SetElement(js_object, index, value);
|
2926
3902
|
} else {
|
2927
3903
|
Handle<String> key_string = Handle<String>::cast(key);
|
2928
|
-
key_string->
|
3904
|
+
key_string->TryFlatten();
|
2929
3905
|
result = SetProperty(js_object, key_string, value, attr);
|
2930
3906
|
}
|
2931
3907
|
if (result.is_null()) return Failure::Exception();
|
@@ -2939,7 +3915,6 @@ Object* Runtime::SetObjectProperty(Handle<Object> object,
|
|
2939
3915
|
Handle<String> name = Handle<String>::cast(converted);
|
2940
3916
|
|
2941
3917
|
if (name->AsArrayIndex(&index)) {
|
2942
|
-
ASSERT(attr == NONE);
|
2943
3918
|
return js_object->SetElement(index, *value);
|
2944
3919
|
} else {
|
2945
3920
|
return js_object->SetProperty(*name, *value, attr);
|
@@ -2956,8 +3931,6 @@ Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
|
|
2956
3931
|
// Check if the given key is an array index.
|
2957
3932
|
uint32_t index;
|
2958
3933
|
if (Array::IndexFromObject(*key, &index)) {
|
2959
|
-
ASSERT(attr == NONE);
|
2960
|
-
|
2961
3934
|
// In Firefox/SpiderMonkey, Safari and Opera you can access the characters
|
2962
3935
|
// of a string using [] notation. We need to support this too in
|
2963
3936
|
// JavaScript.
|
@@ -2974,11 +3947,10 @@ Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
|
|
2974
3947
|
|
2975
3948
|
if (key->IsString()) {
|
2976
3949
|
if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
|
2977
|
-
ASSERT(attr == NONE);
|
2978
3950
|
return js_object->SetElement(index, *value);
|
2979
3951
|
} else {
|
2980
3952
|
Handle<String> key_string = Handle<String>::cast(key);
|
2981
|
-
key_string->
|
3953
|
+
key_string->TryFlatten();
|
2982
3954
|
return js_object->IgnoreAttributesAndSetLocalProperty(*key_string,
|
2983
3955
|
*value,
|
2984
3956
|
attr);
|
@@ -2992,7 +3964,6 @@ Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object,
|
|
2992
3964
|
Handle<String> name = Handle<String>::cast(converted);
|
2993
3965
|
|
2994
3966
|
if (name->AsArrayIndex(&index)) {
|
2995
|
-
ASSERT(attr == NONE);
|
2996
3967
|
return js_object->SetElement(index, *value);
|
2997
3968
|
} else {
|
2998
3969
|
return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr);
|
@@ -3031,7 +4002,7 @@ Object* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object,
|
|
3031
4002
|
key_string = Handle<String>::cast(converted);
|
3032
4003
|
}
|
3033
4004
|
|
3034
|
-
key_string->
|
4005
|
+
key_string->TryFlatten();
|
3035
4006
|
return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION);
|
3036
4007
|
}
|
3037
4008
|
|
@@ -3213,6 +4184,169 @@ static Object* Runtime_GetPropertyNamesFast(Arguments args) {
|
|
3213
4184
|
}
|
3214
4185
|
|
3215
4186
|
|
4187
|
+
// Find the length of the prototype chain that is to to handled as one. If a
|
4188
|
+
// prototype object is hidden it is to be viewed as part of the the object it
|
4189
|
+
// is prototype for.
|
4190
|
+
static int LocalPrototypeChainLength(JSObject* obj) {
|
4191
|
+
int count = 1;
|
4192
|
+
Object* proto = obj->GetPrototype();
|
4193
|
+
while (proto->IsJSObject() &&
|
4194
|
+
JSObject::cast(proto)->map()->is_hidden_prototype()) {
|
4195
|
+
count++;
|
4196
|
+
proto = JSObject::cast(proto)->GetPrototype();
|
4197
|
+
}
|
4198
|
+
return count;
|
4199
|
+
}
|
4200
|
+
|
4201
|
+
|
4202
|
+
// Return the names of the local named properties.
|
4203
|
+
// args[0]: object
|
4204
|
+
static Object* Runtime_GetLocalPropertyNames(Arguments args) {
|
4205
|
+
HandleScope scope;
|
4206
|
+
ASSERT(args.length() == 1);
|
4207
|
+
if (!args[0]->IsJSObject()) {
|
4208
|
+
return Heap::undefined_value();
|
4209
|
+
}
|
4210
|
+
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
4211
|
+
|
4212
|
+
// Skip the global proxy as it has no properties and always delegates to the
|
4213
|
+
// real global object.
|
4214
|
+
if (obj->IsJSGlobalProxy()) {
|
4215
|
+
// Only collect names if access is permitted.
|
4216
|
+
if (obj->IsAccessCheckNeeded() &&
|
4217
|
+
!Top::MayNamedAccess(*obj, Heap::undefined_value(), v8::ACCESS_KEYS)) {
|
4218
|
+
Top::ReportFailedAccessCheck(*obj, v8::ACCESS_KEYS);
|
4219
|
+
return *Factory::NewJSArray(0);
|
4220
|
+
}
|
4221
|
+
obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
|
4222
|
+
}
|
4223
|
+
|
4224
|
+
// Find the number of objects making up this.
|
4225
|
+
int length = LocalPrototypeChainLength(*obj);
|
4226
|
+
|
4227
|
+
// Find the number of local properties for each of the objects.
|
4228
|
+
ScopedVector<int> local_property_count(length);
|
4229
|
+
int total_property_count = 0;
|
4230
|
+
Handle<JSObject> jsproto = obj;
|
4231
|
+
for (int i = 0; i < length; i++) {
|
4232
|
+
// Only collect names if access is permitted.
|
4233
|
+
if (jsproto->IsAccessCheckNeeded() &&
|
4234
|
+
!Top::MayNamedAccess(*jsproto,
|
4235
|
+
Heap::undefined_value(),
|
4236
|
+
v8::ACCESS_KEYS)) {
|
4237
|
+
Top::ReportFailedAccessCheck(*jsproto, v8::ACCESS_KEYS);
|
4238
|
+
return *Factory::NewJSArray(0);
|
4239
|
+
}
|
4240
|
+
int n;
|
4241
|
+
n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
|
4242
|
+
local_property_count[i] = n;
|
4243
|
+
total_property_count += n;
|
4244
|
+
if (i < length - 1) {
|
4245
|
+
jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
4246
|
+
}
|
4247
|
+
}
|
4248
|
+
|
4249
|
+
// Allocate an array with storage for all the property names.
|
4250
|
+
Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
|
4251
|
+
|
4252
|
+
// Get the property names.
|
4253
|
+
jsproto = obj;
|
4254
|
+
int proto_with_hidden_properties = 0;
|
4255
|
+
for (int i = 0; i < length; i++) {
|
4256
|
+
jsproto->GetLocalPropertyNames(*names,
|
4257
|
+
i == 0 ? 0 : local_property_count[i - 1]);
|
4258
|
+
if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
|
4259
|
+
proto_with_hidden_properties++;
|
4260
|
+
}
|
4261
|
+
if (i < length - 1) {
|
4262
|
+
jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
4263
|
+
}
|
4264
|
+
}
|
4265
|
+
|
4266
|
+
// Filter out name of hidden propeties object.
|
4267
|
+
if (proto_with_hidden_properties > 0) {
|
4268
|
+
Handle<FixedArray> old_names = names;
|
4269
|
+
names = Factory::NewFixedArray(
|
4270
|
+
names->length() - proto_with_hidden_properties);
|
4271
|
+
int dest_pos = 0;
|
4272
|
+
for (int i = 0; i < total_property_count; i++) {
|
4273
|
+
Object* name = old_names->get(i);
|
4274
|
+
if (name == Heap::hidden_symbol()) {
|
4275
|
+
continue;
|
4276
|
+
}
|
4277
|
+
names->set(dest_pos++, name);
|
4278
|
+
}
|
4279
|
+
}
|
4280
|
+
|
4281
|
+
return *Factory::NewJSArrayWithElements(names);
|
4282
|
+
}
|
4283
|
+
|
4284
|
+
|
4285
|
+
// Return the names of the local indexed properties.
|
4286
|
+
// args[0]: object
|
4287
|
+
static Object* Runtime_GetLocalElementNames(Arguments args) {
|
4288
|
+
HandleScope scope;
|
4289
|
+
ASSERT(args.length() == 1);
|
4290
|
+
if (!args[0]->IsJSObject()) {
|
4291
|
+
return Heap::undefined_value();
|
4292
|
+
}
|
4293
|
+
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
4294
|
+
|
4295
|
+
int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
|
4296
|
+
Handle<FixedArray> names = Factory::NewFixedArray(n);
|
4297
|
+
obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
|
4298
|
+
return *Factory::NewJSArrayWithElements(names);
|
4299
|
+
}
|
4300
|
+
|
4301
|
+
|
4302
|
+
// Return information on whether an object has a named or indexed interceptor.
|
4303
|
+
// args[0]: object
|
4304
|
+
static Object* Runtime_GetInterceptorInfo(Arguments args) {
|
4305
|
+
HandleScope scope;
|
4306
|
+
ASSERT(args.length() == 1);
|
4307
|
+
if (!args[0]->IsJSObject()) {
|
4308
|
+
return Smi::FromInt(0);
|
4309
|
+
}
|
4310
|
+
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
4311
|
+
|
4312
|
+
int result = 0;
|
4313
|
+
if (obj->HasNamedInterceptor()) result |= 2;
|
4314
|
+
if (obj->HasIndexedInterceptor()) result |= 1;
|
4315
|
+
|
4316
|
+
return Smi::FromInt(result);
|
4317
|
+
}
|
4318
|
+
|
4319
|
+
|
4320
|
+
// Return property names from named interceptor.
|
4321
|
+
// args[0]: object
|
4322
|
+
static Object* Runtime_GetNamedInterceptorPropertyNames(Arguments args) {
|
4323
|
+
HandleScope scope;
|
4324
|
+
ASSERT(args.length() == 1);
|
4325
|
+
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
4326
|
+
|
4327
|
+
if (obj->HasNamedInterceptor()) {
|
4328
|
+
v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
|
4329
|
+
if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
|
4330
|
+
}
|
4331
|
+
return Heap::undefined_value();
|
4332
|
+
}
|
4333
|
+
|
4334
|
+
|
4335
|
+
// Return element names from indexed interceptor.
|
4336
|
+
// args[0]: object
|
4337
|
+
static Object* Runtime_GetIndexedInterceptorElementNames(Arguments args) {
|
4338
|
+
HandleScope scope;
|
4339
|
+
ASSERT(args.length() == 1);
|
4340
|
+
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
4341
|
+
|
4342
|
+
if (obj->HasIndexedInterceptor()) {
|
4343
|
+
v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
|
4344
|
+
if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
|
4345
|
+
}
|
4346
|
+
return Heap::undefined_value();
|
4347
|
+
}
|
4348
|
+
|
4349
|
+
|
3216
4350
|
static Object* Runtime_LocalKeys(Arguments args) {
|
3217
4351
|
ASSERT_EQ(args.length(), 1);
|
3218
4352
|
CONVERT_CHECKED(JSObject, raw_object, args[0]);
|
@@ -3287,17 +4421,23 @@ static Object* Runtime_GetArgumentsProperty(Arguments args) {
|
|
3287
4421
|
|
3288
4422
|
|
3289
4423
|
static Object* Runtime_ToFastProperties(Arguments args) {
|
4424
|
+
HandleScope scope;
|
4425
|
+
|
3290
4426
|
ASSERT(args.length() == 1);
|
3291
4427
|
Handle<Object> object = args.at<Object>(0);
|
3292
4428
|
if (object->IsJSObject()) {
|
3293
4429
|
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
|
3294
|
-
js_object->
|
4430
|
+
if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) {
|
4431
|
+
js_object->TransformToFastProperties(0);
|
4432
|
+
}
|
3295
4433
|
}
|
3296
4434
|
return *object;
|
3297
4435
|
}
|
3298
4436
|
|
3299
4437
|
|
3300
4438
|
static Object* Runtime_ToSlowProperties(Arguments args) {
|
4439
|
+
HandleScope scope;
|
4440
|
+
|
3301
4441
|
ASSERT(args.length() == 1);
|
3302
4442
|
Handle<Object> object = args.at<Object>(0);
|
3303
4443
|
if (object->IsJSObject()) {
|
@@ -3353,11 +4493,66 @@ static Object* Runtime_Typeof(Arguments args) {
|
|
3353
4493
|
}
|
3354
4494
|
|
3355
4495
|
|
4496
|
+
static bool AreDigits(const char*s, int from, int to) {
|
4497
|
+
for (int i = from; i < to; i++) {
|
4498
|
+
if (s[i] < '0' || s[i] > '9') return false;
|
4499
|
+
}
|
4500
|
+
|
4501
|
+
return true;
|
4502
|
+
}
|
4503
|
+
|
4504
|
+
|
4505
|
+
static int ParseDecimalInteger(const char*s, int from, int to) {
|
4506
|
+
ASSERT(to - from < 10); // Overflow is not possible.
|
4507
|
+
ASSERT(from < to);
|
4508
|
+
int d = s[from] - '0';
|
4509
|
+
|
4510
|
+
for (int i = from + 1; i < to; i++) {
|
4511
|
+
d = 10 * d + (s[i] - '0');
|
4512
|
+
}
|
4513
|
+
|
4514
|
+
return d;
|
4515
|
+
}
|
4516
|
+
|
4517
|
+
|
3356
4518
|
static Object* Runtime_StringToNumber(Arguments args) {
|
3357
4519
|
NoHandleAllocation ha;
|
3358
4520
|
ASSERT(args.length() == 1);
|
3359
4521
|
CONVERT_CHECKED(String, subject, args[0]);
|
3360
|
-
subject->
|
4522
|
+
subject->TryFlatten();
|
4523
|
+
|
4524
|
+
// Fast case: short integer or some sorts of junk values.
|
4525
|
+
int len = subject->length();
|
4526
|
+
if (subject->IsSeqAsciiString()) {
|
4527
|
+
if (len == 0) return Smi::FromInt(0);
|
4528
|
+
|
4529
|
+
char const* data = SeqAsciiString::cast(subject)->GetChars();
|
4530
|
+
bool minus = (data[0] == '-');
|
4531
|
+
int start_pos = (minus ? 1 : 0);
|
4532
|
+
|
4533
|
+
if (start_pos == len) {
|
4534
|
+
return Heap::nan_value();
|
4535
|
+
} else if (data[start_pos] > '9') {
|
4536
|
+
// Fast check for a junk value. A valid string may start from a
|
4537
|
+
// whitespace, a sign ('+' or '-'), the decimal point, a decimal digit or
|
4538
|
+
// the 'I' character ('Infinity'). All of that have codes not greater than
|
4539
|
+
// '9' except 'I'.
|
4540
|
+
if (data[start_pos] != 'I') {
|
4541
|
+
return Heap::nan_value();
|
4542
|
+
}
|
4543
|
+
} else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
|
4544
|
+
// The maximal/minimal smi has 10 digits. If the string has less digits we
|
4545
|
+
// know it will fit into the smi-data type.
|
4546
|
+
int d = ParseDecimalInteger(data, start_pos, len);
|
4547
|
+
if (minus) {
|
4548
|
+
if (d == 0) return Heap::minus_zero_value();
|
4549
|
+
d = -d;
|
4550
|
+
}
|
4551
|
+
return Smi::FromInt(d);
|
4552
|
+
}
|
4553
|
+
}
|
4554
|
+
|
4555
|
+
// Slower case.
|
3361
4556
|
return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
|
3362
4557
|
}
|
3363
4558
|
|
@@ -3439,7 +4634,7 @@ static Object* Runtime_URIEscape(Arguments args) {
|
|
3439
4634
|
ASSERT(args.length() == 1);
|
3440
4635
|
CONVERT_CHECKED(String, source, args[0]);
|
3441
4636
|
|
3442
|
-
source->
|
4637
|
+
source->TryFlatten();
|
3443
4638
|
|
3444
4639
|
int escaped_length = 0;
|
3445
4640
|
int length = source->length();
|
@@ -3552,7 +4747,7 @@ static Object* Runtime_URIUnescape(Arguments args) {
|
|
3552
4747
|
ASSERT(args.length() == 1);
|
3553
4748
|
CONVERT_CHECKED(String, source, args[0]);
|
3554
4749
|
|
3555
|
-
source->
|
4750
|
+
source->TryFlatten();
|
3556
4751
|
|
3557
4752
|
bool ascii = true;
|
3558
4753
|
int length = source->length();
|
@@ -3592,51 +4787,11 @@ static Object* Runtime_StringParseInt(Arguments args) {
|
|
3592
4787
|
CONVERT_CHECKED(String, s, args[0]);
|
3593
4788
|
CONVERT_SMI_CHECKED(radix, args[1]);
|
3594
4789
|
|
3595
|
-
s->
|
3596
|
-
|
3597
|
-
int len = s->length();
|
3598
|
-
int i;
|
3599
|
-
|
3600
|
-
// Skip leading white space.
|
3601
|
-
for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(i)); i++) ;
|
3602
|
-
if (i == len) return Heap::nan_value();
|
3603
|
-
|
3604
|
-
// Compute the sign (default to +).
|
3605
|
-
int sign = 1;
|
3606
|
-
if (s->Get(i) == '-') {
|
3607
|
-
sign = -1;
|
3608
|
-
i++;
|
3609
|
-
} else if (s->Get(i) == '+') {
|
3610
|
-
i++;
|
3611
|
-
}
|
3612
|
-
|
3613
|
-
// Compute the radix if 0.
|
3614
|
-
if (radix == 0) {
|
3615
|
-
radix = 10;
|
3616
|
-
if (i < len && s->Get(i) == '0') {
|
3617
|
-
radix = 8;
|
3618
|
-
if (i + 1 < len) {
|
3619
|
-
int c = s->Get(i + 1);
|
3620
|
-
if (c == 'x' || c == 'X') {
|
3621
|
-
radix = 16;
|
3622
|
-
i += 2;
|
3623
|
-
}
|
3624
|
-
}
|
3625
|
-
}
|
3626
|
-
} else if (radix == 16) {
|
3627
|
-
// Allow 0x or 0X prefix if radix is 16.
|
3628
|
-
if (i + 1 < len && s->Get(i) == '0') {
|
3629
|
-
int c = s->Get(i + 1);
|
3630
|
-
if (c == 'x' || c == 'X') i += 2;
|
3631
|
-
}
|
3632
|
-
}
|
4790
|
+
s->TryFlatten();
|
3633
4791
|
|
3634
|
-
RUNTIME_ASSERT(2 <= radix && radix <= 36);
|
3635
|
-
double value;
|
3636
|
-
|
3637
|
-
if (end_index != i) {
|
3638
|
-
return Heap::NumberFromDouble(sign * value);
|
3639
|
-
}
|
4792
|
+
RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
|
4793
|
+
double value = StringToInt(s, radix);
|
4794
|
+
return Heap::NumberFromDouble(value);
|
3640
4795
|
return Heap::nan_value();
|
3641
4796
|
}
|
3642
4797
|
|
@@ -3756,18 +4911,83 @@ static Object* ConvertCaseHelper(String* s,
|
|
3756
4911
|
}
|
3757
4912
|
|
3758
4913
|
|
3759
|
-
|
3760
|
-
|
3761
|
-
|
3762
|
-
|
4914
|
+
static inline SeqAsciiString* TryGetSeqAsciiString(String* s) {
|
4915
|
+
if (!s->IsFlat() || !s->IsAsciiRepresentation()) return NULL;
|
4916
|
+
if (s->IsConsString()) {
|
4917
|
+
ASSERT(ConsString::cast(s)->second()->length() == 0);
|
4918
|
+
return SeqAsciiString::cast(ConsString::cast(s)->first());
|
4919
|
+
}
|
4920
|
+
return SeqAsciiString::cast(s);
|
4921
|
+
}
|
4922
|
+
|
4923
|
+
|
4924
|
+
namespace {
|
3763
4925
|
|
4926
|
+
struct ToLowerTraits {
|
4927
|
+
typedef unibrow::ToLowercase UnibrowConverter;
|
4928
|
+
|
4929
|
+
static bool ConvertAscii(char* dst, char* src, int length) {
|
4930
|
+
bool changed = false;
|
4931
|
+
for (int i = 0; i < length; ++i) {
|
4932
|
+
char c = src[i];
|
4933
|
+
if ('A' <= c && c <= 'Z') {
|
4934
|
+
c += ('a' - 'A');
|
4935
|
+
changed = true;
|
4936
|
+
}
|
4937
|
+
dst[i] = c;
|
4938
|
+
}
|
4939
|
+
return changed;
|
4940
|
+
}
|
4941
|
+
};
|
4942
|
+
|
4943
|
+
|
4944
|
+
struct ToUpperTraits {
|
4945
|
+
typedef unibrow::ToUppercase UnibrowConverter;
|
4946
|
+
|
4947
|
+
static bool ConvertAscii(char* dst, char* src, int length) {
|
4948
|
+
bool changed = false;
|
4949
|
+
for (int i = 0; i < length; ++i) {
|
4950
|
+
char c = src[i];
|
4951
|
+
if ('a' <= c && c <= 'z') {
|
4952
|
+
c -= ('a' - 'A');
|
4953
|
+
changed = true;
|
4954
|
+
}
|
4955
|
+
dst[i] = c;
|
4956
|
+
}
|
4957
|
+
return changed;
|
4958
|
+
}
|
4959
|
+
};
|
4960
|
+
|
4961
|
+
} // namespace
|
4962
|
+
|
4963
|
+
|
4964
|
+
template <typename ConvertTraits>
|
4965
|
+
static Object* ConvertCase(
|
4966
|
+
Arguments args,
|
4967
|
+
unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) {
|
4968
|
+
NoHandleAllocation ha;
|
3764
4969
|
CONVERT_CHECKED(String, s, args[0]);
|
3765
|
-
s->
|
4970
|
+
s->TryFlatten();
|
3766
4971
|
|
3767
|
-
int
|
4972
|
+
const int length = s->length();
|
3768
4973
|
// Assume that the string is not empty; we need this assumption later
|
3769
|
-
if (
|
3770
|
-
|
4974
|
+
if (length == 0) return s;
|
4975
|
+
|
4976
|
+
// Simpler handling of ascii strings.
|
4977
|
+
//
|
4978
|
+
// NOTE: This assumes that the upper/lower case of an ascii
|
4979
|
+
// character is also ascii. This is currently the case, but it
|
4980
|
+
// might break in the future if we implement more context and locale
|
4981
|
+
// dependent upper/lower conversions.
|
4982
|
+
SeqAsciiString* seq_ascii = TryGetSeqAsciiString(s);
|
4983
|
+
if (seq_ascii != NULL) {
|
4984
|
+
Object* o = Heap::AllocateRawAsciiString(length);
|
4985
|
+
if (o->IsFailure()) return o;
|
4986
|
+
SeqAsciiString* result = SeqAsciiString::cast(o);
|
4987
|
+
bool has_changed_character = ConvertTraits::ConvertAscii(
|
4988
|
+
result->GetChars(), seq_ascii->GetChars(), length);
|
4989
|
+
return has_changed_character ? result : s;
|
4990
|
+
}
|
3771
4991
|
|
3772
4992
|
Object* answer = ConvertCaseHelper(s, length, length, mapping);
|
3773
4993
|
if (answer->IsSmi()) {
|
@@ -3779,18 +4999,20 @@ static Object* ConvertCase(Arguments args,
|
|
3779
4999
|
|
3780
5000
|
|
3781
5001
|
static Object* Runtime_StringToLowerCase(Arguments args) {
|
3782
|
-
return ConvertCase<
|
5002
|
+
return ConvertCase<ToLowerTraits>(args, &to_lower_mapping);
|
3783
5003
|
}
|
3784
5004
|
|
3785
5005
|
|
3786
5006
|
static Object* Runtime_StringToUpperCase(Arguments args) {
|
3787
|
-
return ConvertCase<
|
5007
|
+
return ConvertCase<ToUpperTraits>(args, &to_upper_mapping);
|
3788
5008
|
}
|
3789
5009
|
|
5010
|
+
|
3790
5011
|
static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
|
3791
5012
|
return unibrow::WhiteSpace::Is(c) || c == 0x200b;
|
3792
5013
|
}
|
3793
5014
|
|
5015
|
+
|
3794
5016
|
static Object* Runtime_StringTrim(Arguments args) {
|
3795
5017
|
NoHandleAllocation ha;
|
3796
5018
|
ASSERT(args.length() == 3);
|
@@ -3799,7 +5021,7 @@ static Object* Runtime_StringTrim(Arguments args) {
|
|
3799
5021
|
CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]);
|
3800
5022
|
CONVERT_BOOLEAN_CHECKED(trimRight, args[2]);
|
3801
5023
|
|
3802
|
-
s->
|
5024
|
+
s->TryFlatten();
|
3803
5025
|
int length = s->length();
|
3804
5026
|
|
3805
5027
|
int left = 0;
|
@@ -3818,6 +5040,245 @@ static Object* Runtime_StringTrim(Arguments args) {
|
|
3818
5040
|
return s->SubString(left, right);
|
3819
5041
|
}
|
3820
5042
|
|
5043
|
+
|
5044
|
+
template <typename schar, typename pchar>
|
5045
|
+
void FindStringIndices(Vector<const schar> subject,
|
5046
|
+
Vector<const pchar> pattern,
|
5047
|
+
ZoneList<int>* indices,
|
5048
|
+
unsigned int limit) {
|
5049
|
+
ASSERT(limit > 0);
|
5050
|
+
// Collect indices of pattern in subject, and the end-of-string index.
|
5051
|
+
// Stop after finding at most limit values.
|
5052
|
+
StringSearchStrategy strategy =
|
5053
|
+
InitializeStringSearch(pattern, sizeof(schar) == 1);
|
5054
|
+
switch (strategy) {
|
5055
|
+
case SEARCH_FAIL: return;
|
5056
|
+
case SEARCH_SHORT: {
|
5057
|
+
int pattern_length = pattern.length();
|
5058
|
+
int index = 0;
|
5059
|
+
while (limit > 0) {
|
5060
|
+
index = SimpleIndexOf(subject, pattern, index);
|
5061
|
+
if (index < 0) return;
|
5062
|
+
indices->Add(index);
|
5063
|
+
index += pattern_length;
|
5064
|
+
limit--;
|
5065
|
+
}
|
5066
|
+
return;
|
5067
|
+
}
|
5068
|
+
case SEARCH_LONG: {
|
5069
|
+
int pattern_length = pattern.length();
|
5070
|
+
int index = 0;
|
5071
|
+
while (limit > 0) {
|
5072
|
+
index = ComplexIndexOf(subject, pattern, index);
|
5073
|
+
if (index < 0) return;
|
5074
|
+
indices->Add(index);
|
5075
|
+
index += pattern_length;
|
5076
|
+
limit--;
|
5077
|
+
}
|
5078
|
+
return;
|
5079
|
+
}
|
5080
|
+
default:
|
5081
|
+
UNREACHABLE();
|
5082
|
+
return;
|
5083
|
+
}
|
5084
|
+
}
|
5085
|
+
|
5086
|
+
template <typename schar>
|
5087
|
+
inline void FindCharIndices(Vector<const schar> subject,
|
5088
|
+
const schar pattern_char,
|
5089
|
+
ZoneList<int>* indices,
|
5090
|
+
unsigned int limit) {
|
5091
|
+
// Collect indices of pattern_char in subject, and the end-of-string index.
|
5092
|
+
// Stop after finding at most limit values.
|
5093
|
+
int index = 0;
|
5094
|
+
while (limit > 0) {
|
5095
|
+
index = SingleCharIndexOf(subject, pattern_char, index);
|
5096
|
+
if (index < 0) return;
|
5097
|
+
indices->Add(index);
|
5098
|
+
index++;
|
5099
|
+
limit--;
|
5100
|
+
}
|
5101
|
+
}
|
5102
|
+
|
5103
|
+
|
5104
|
+
static Object* Runtime_StringSplit(Arguments args) {
|
5105
|
+
ASSERT(args.length() == 3);
|
5106
|
+
HandleScope handle_scope;
|
5107
|
+
CONVERT_ARG_CHECKED(String, subject, 0);
|
5108
|
+
CONVERT_ARG_CHECKED(String, pattern, 1);
|
5109
|
+
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
|
5110
|
+
|
5111
|
+
int subject_length = subject->length();
|
5112
|
+
int pattern_length = pattern->length();
|
5113
|
+
RUNTIME_ASSERT(pattern_length > 0);
|
5114
|
+
|
5115
|
+
// The limit can be very large (0xffffffffu), but since the pattern
|
5116
|
+
// isn't empty, we can never create more parts than ~half the length
|
5117
|
+
// of the subject.
|
5118
|
+
|
5119
|
+
if (!subject->IsFlat()) FlattenString(subject);
|
5120
|
+
|
5121
|
+
static const int kMaxInitialListCapacity = 16;
|
5122
|
+
|
5123
|
+
ZoneScope scope(DELETE_ON_EXIT);
|
5124
|
+
|
5125
|
+
// Find (up to limit) indices of separator and end-of-string in subject
|
5126
|
+
int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
|
5127
|
+
ZoneList<int> indices(initial_capacity);
|
5128
|
+
if (pattern_length == 1) {
|
5129
|
+
// Special case, go directly to fast single-character split.
|
5130
|
+
AssertNoAllocation nogc;
|
5131
|
+
uc16 pattern_char = pattern->Get(0);
|
5132
|
+
if (subject->IsTwoByteRepresentation()) {
|
5133
|
+
FindCharIndices(subject->ToUC16Vector(), pattern_char,
|
5134
|
+
&indices,
|
5135
|
+
limit);
|
5136
|
+
} else if (pattern_char <= String::kMaxAsciiCharCode) {
|
5137
|
+
FindCharIndices(subject->ToAsciiVector(),
|
5138
|
+
static_cast<char>(pattern_char),
|
5139
|
+
&indices,
|
5140
|
+
limit);
|
5141
|
+
}
|
5142
|
+
} else {
|
5143
|
+
if (!pattern->IsFlat()) FlattenString(pattern);
|
5144
|
+
AssertNoAllocation nogc;
|
5145
|
+
if (subject->IsAsciiRepresentation()) {
|
5146
|
+
Vector<const char> subject_vector = subject->ToAsciiVector();
|
5147
|
+
if (pattern->IsAsciiRepresentation()) {
|
5148
|
+
FindStringIndices(subject_vector,
|
5149
|
+
pattern->ToAsciiVector(),
|
5150
|
+
&indices,
|
5151
|
+
limit);
|
5152
|
+
} else {
|
5153
|
+
FindStringIndices(subject_vector,
|
5154
|
+
pattern->ToUC16Vector(),
|
5155
|
+
&indices,
|
5156
|
+
limit);
|
5157
|
+
}
|
5158
|
+
} else {
|
5159
|
+
Vector<const uc16> subject_vector = subject->ToUC16Vector();
|
5160
|
+
if (pattern->IsAsciiRepresentation()) {
|
5161
|
+
FindStringIndices(subject_vector,
|
5162
|
+
pattern->ToAsciiVector(),
|
5163
|
+
&indices,
|
5164
|
+
limit);
|
5165
|
+
} else {
|
5166
|
+
FindStringIndices(subject_vector,
|
5167
|
+
pattern->ToUC16Vector(),
|
5168
|
+
&indices,
|
5169
|
+
limit);
|
5170
|
+
}
|
5171
|
+
}
|
5172
|
+
}
|
5173
|
+
if (static_cast<uint32_t>(indices.length()) < limit) {
|
5174
|
+
indices.Add(subject_length);
|
5175
|
+
}
|
5176
|
+
// The list indices now contains the end of each part to create.
|
5177
|
+
|
5178
|
+
|
5179
|
+
// Create JSArray of substrings separated by separator.
|
5180
|
+
int part_count = indices.length();
|
5181
|
+
|
5182
|
+
Handle<JSArray> result = Factory::NewJSArray(part_count);
|
5183
|
+
result->set_length(Smi::FromInt(part_count));
|
5184
|
+
|
5185
|
+
ASSERT(result->HasFastElements());
|
5186
|
+
|
5187
|
+
if (part_count == 1 && indices.at(0) == subject_length) {
|
5188
|
+
FixedArray::cast(result->elements())->set(0, *subject);
|
5189
|
+
return *result;
|
5190
|
+
}
|
5191
|
+
|
5192
|
+
Handle<FixedArray> elements(FixedArray::cast(result->elements()));
|
5193
|
+
int part_start = 0;
|
5194
|
+
for (int i = 0; i < part_count; i++) {
|
5195
|
+
HandleScope local_loop_handle;
|
5196
|
+
int part_end = indices.at(i);
|
5197
|
+
Handle<String> substring =
|
5198
|
+
Factory::NewSubString(subject, part_start, part_end);
|
5199
|
+
elements->set(i, *substring);
|
5200
|
+
part_start = part_end + pattern_length;
|
5201
|
+
}
|
5202
|
+
|
5203
|
+
return *result;
|
5204
|
+
}
|
5205
|
+
|
5206
|
+
|
5207
|
+
// Copies ascii characters to the given fixed array looking up
|
5208
|
+
// one-char strings in the cache. Gives up on the first char that is
|
5209
|
+
// not in the cache and fills the remainder with smi zeros. Returns
|
5210
|
+
// the length of the successfully copied prefix.
|
5211
|
+
static int CopyCachedAsciiCharsToArray(const char* chars,
|
5212
|
+
FixedArray* elements,
|
5213
|
+
int length) {
|
5214
|
+
AssertNoAllocation nogc;
|
5215
|
+
FixedArray* ascii_cache = Heap::single_character_string_cache();
|
5216
|
+
Object* undefined = Heap::undefined_value();
|
5217
|
+
int i;
|
5218
|
+
for (i = 0; i < length; ++i) {
|
5219
|
+
Object* value = ascii_cache->get(chars[i]);
|
5220
|
+
if (value == undefined) break;
|
5221
|
+
ASSERT(!Heap::InNewSpace(value));
|
5222
|
+
elements->set(i, value, SKIP_WRITE_BARRIER);
|
5223
|
+
}
|
5224
|
+
if (i < length) {
|
5225
|
+
ASSERT(Smi::FromInt(0) == 0);
|
5226
|
+
memset(elements->data_start() + i, 0, kPointerSize * (length - i));
|
5227
|
+
}
|
5228
|
+
#ifdef DEBUG
|
5229
|
+
for (int j = 0; j < length; ++j) {
|
5230
|
+
Object* element = elements->get(j);
|
5231
|
+
ASSERT(element == Smi::FromInt(0) ||
|
5232
|
+
(element->IsString() && String::cast(element)->LooksValid()));
|
5233
|
+
}
|
5234
|
+
#endif
|
5235
|
+
return i;
|
5236
|
+
}
|
5237
|
+
|
5238
|
+
|
5239
|
+
// Converts a String to JSArray.
|
5240
|
+
// For example, "foo" => ["f", "o", "o"].
|
5241
|
+
static Object* Runtime_StringToArray(Arguments args) {
|
5242
|
+
HandleScope scope;
|
5243
|
+
ASSERT(args.length() == 1);
|
5244
|
+
CONVERT_ARG_CHECKED(String, s, 0);
|
5245
|
+
|
5246
|
+
s->TryFlatten();
|
5247
|
+
const int length = s->length();
|
5248
|
+
|
5249
|
+
Handle<FixedArray> elements;
|
5250
|
+
if (s->IsFlat() && s->IsAsciiRepresentation()) {
|
5251
|
+
Object* obj = Heap::AllocateUninitializedFixedArray(length);
|
5252
|
+
if (obj->IsFailure()) return obj;
|
5253
|
+
elements = Handle<FixedArray>(FixedArray::cast(obj));
|
5254
|
+
|
5255
|
+
Vector<const char> chars = s->ToAsciiVector();
|
5256
|
+
// Note, this will initialize all elements (not only the prefix)
|
5257
|
+
// to prevent GC from seeing partially initialized array.
|
5258
|
+
int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(),
|
5259
|
+
*elements,
|
5260
|
+
length);
|
5261
|
+
|
5262
|
+
for (int i = num_copied_from_cache; i < length; ++i) {
|
5263
|
+
elements->set(i, *LookupSingleCharacterStringFromCode(chars[i]));
|
5264
|
+
}
|
5265
|
+
} else {
|
5266
|
+
elements = Factory::NewFixedArray(length);
|
5267
|
+
for (int i = 0; i < length; ++i) {
|
5268
|
+
elements->set(i, *LookupSingleCharacterStringFromCode(s->Get(i)));
|
5269
|
+
}
|
5270
|
+
}
|
5271
|
+
|
5272
|
+
#ifdef DEBUG
|
5273
|
+
for (int i = 0; i < length; ++i) {
|
5274
|
+
ASSERT(String::cast(elements->get(i))->length() == 1);
|
5275
|
+
}
|
5276
|
+
#endif
|
5277
|
+
|
5278
|
+
return *Factory::NewJSArrayWithElements(elements);
|
5279
|
+
}
|
5280
|
+
|
5281
|
+
|
3821
5282
|
bool Runtime::IsUpperCaseChar(uint16_t ch) {
|
3822
5283
|
unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
|
3823
5284
|
int char_length = to_upper_mapping.get(ch, 0, chars);
|
@@ -3836,13 +5297,27 @@ static Object* Runtime_NumberToString(Arguments args) {
|
|
3836
5297
|
}
|
3837
5298
|
|
3838
5299
|
|
5300
|
+
static Object* Runtime_NumberToStringSkipCache(Arguments args) {
|
5301
|
+
NoHandleAllocation ha;
|
5302
|
+
ASSERT(args.length() == 1);
|
5303
|
+
|
5304
|
+
Object* number = args[0];
|
5305
|
+
RUNTIME_ASSERT(number->IsNumber());
|
5306
|
+
|
5307
|
+
return Heap::NumberToString(number, false);
|
5308
|
+
}
|
5309
|
+
|
5310
|
+
|
3839
5311
|
static Object* Runtime_NumberToInteger(Arguments args) {
|
3840
5312
|
NoHandleAllocation ha;
|
3841
5313
|
ASSERT(args.length() == 1);
|
3842
5314
|
|
3843
|
-
|
3844
|
-
|
3845
|
-
|
5315
|
+
CONVERT_DOUBLE_CHECKED(number, args[0]);
|
5316
|
+
|
5317
|
+
// We do not include 0 so that we don't have to treat +0 / -0 cases.
|
5318
|
+
if (number > 0 && number <= Smi::kMaxValue) {
|
5319
|
+
return Smi::FromInt(static_cast<int>(number));
|
5320
|
+
}
|
3846
5321
|
return Heap::NumberFromDouble(DoubleToInteger(number));
|
3847
5322
|
}
|
3848
5323
|
|
@@ -3851,9 +5326,7 @@ static Object* Runtime_NumberToJSUint32(Arguments args) {
|
|
3851
5326
|
NoHandleAllocation ha;
|
3852
5327
|
ASSERT(args.length() == 1);
|
3853
5328
|
|
3854
|
-
|
3855
|
-
if (obj->IsSmi() && Smi::cast(obj)->value() >= 0) return obj;
|
3856
|
-
CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, obj);
|
5329
|
+
CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
|
3857
5330
|
return Heap::NumberFromUint32(number);
|
3858
5331
|
}
|
3859
5332
|
|
@@ -3862,9 +5335,12 @@ static Object* Runtime_NumberToJSInt32(Arguments args) {
|
|
3862
5335
|
NoHandleAllocation ha;
|
3863
5336
|
ASSERT(args.length() == 1);
|
3864
5337
|
|
3865
|
-
|
3866
|
-
|
3867
|
-
|
5338
|
+
CONVERT_DOUBLE_CHECKED(number, args[0]);
|
5339
|
+
|
5340
|
+
// We do not include 0 so that we don't have to treat +0 / -0 cases.
|
5341
|
+
if (number > 0 && number <= Smi::kMaxValue) {
|
5342
|
+
return Smi::FromInt(static_cast<int>(number));
|
5343
|
+
}
|
3868
5344
|
return Heap::NumberFromInt32(DoubleToInt32(number));
|
3869
5345
|
}
|
3870
5346
|
|
@@ -3935,7 +5411,7 @@ static Object* Runtime_NumberDiv(Arguments args) {
|
|
3935
5411
|
|
3936
5412
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
3937
5413
|
CONVERT_DOUBLE_CHECKED(y, args[1]);
|
3938
|
-
return Heap::
|
5414
|
+
return Heap::NumberFromDouble(x / y);
|
3939
5415
|
}
|
3940
5416
|
|
3941
5417
|
|
@@ -3947,8 +5423,8 @@ static Object* Runtime_NumberMod(Arguments args) {
|
|
3947
5423
|
CONVERT_DOUBLE_CHECKED(y, args[1]);
|
3948
5424
|
|
3949
5425
|
x = modulo(x, y);
|
3950
|
-
//
|
3951
|
-
return Heap::
|
5426
|
+
// NumberFromDouble may return a Smi instead of a Number object
|
5427
|
+
return Heap::NumberFromDouble(x);
|
3952
5428
|
}
|
3953
5429
|
|
3954
5430
|
|
@@ -3962,7 +5438,7 @@ static Object* Runtime_StringAdd(Arguments args) {
|
|
3962
5438
|
}
|
3963
5439
|
|
3964
5440
|
|
3965
|
-
template<typename sinkchar>
|
5441
|
+
template <typename sinkchar>
|
3966
5442
|
static inline void StringBuilderConcatHelper(String* special,
|
3967
5443
|
sinkchar* sink,
|
3968
5444
|
FixedArray* fixed_array,
|
@@ -4033,33 +5509,41 @@ static Object* Runtime_StringBuilderConcat(Arguments args) {
|
|
4033
5509
|
|
4034
5510
|
bool ascii = special->IsAsciiRepresentation();
|
4035
5511
|
int position = 0;
|
4036
|
-
int increment = 0;
|
4037
5512
|
for (int i = 0; i < array_length; i++) {
|
5513
|
+
int increment = 0;
|
4038
5514
|
Object* elt = fixed_array->get(i);
|
4039
5515
|
if (elt->IsSmi()) {
|
4040
5516
|
// Smi encoding of position and length.
|
4041
|
-
int
|
4042
|
-
|
5517
|
+
int smi_value = Smi::cast(elt)->value();
|
5518
|
+
int pos;
|
5519
|
+
int len;
|
5520
|
+
if (smi_value > 0) {
|
4043
5521
|
// Position and length encoded in one smi.
|
4044
|
-
|
4045
|
-
len
|
4046
|
-
if (pos + len > special_length) {
|
4047
|
-
return Top::Throw(Heap::illegal_argument_symbol());
|
4048
|
-
}
|
4049
|
-
increment = len;
|
5522
|
+
pos = StringBuilderSubstringPosition::decode(smi_value);
|
5523
|
+
len = StringBuilderSubstringLength::decode(smi_value);
|
4050
5524
|
} else {
|
4051
5525
|
// Position and length encoded in two smis.
|
4052
|
-
|
4053
|
-
// Get the position and check that it is
|
5526
|
+
len = -smi_value;
|
5527
|
+
// Get the position and check that it is a positive smi.
|
4054
5528
|
i++;
|
4055
5529
|
if (i >= array_length) {
|
4056
5530
|
return Top::Throw(Heap::illegal_argument_symbol());
|
4057
5531
|
}
|
4058
|
-
Object*
|
4059
|
-
if (!
|
5532
|
+
Object* next_smi = fixed_array->get(i);
|
5533
|
+
if (!next_smi->IsSmi()) {
|
5534
|
+
return Top::Throw(Heap::illegal_argument_symbol());
|
5535
|
+
}
|
5536
|
+
pos = Smi::cast(next_smi)->value();
|
5537
|
+
if (pos < 0) {
|
4060
5538
|
return Top::Throw(Heap::illegal_argument_symbol());
|
4061
5539
|
}
|
4062
5540
|
}
|
5541
|
+
ASSERT(pos >= 0);
|
5542
|
+
ASSERT(len >= 0);
|
5543
|
+
if (pos > special_length || len > special_length - pos) {
|
5544
|
+
return Top::Throw(Heap::illegal_argument_symbol());
|
5545
|
+
}
|
5546
|
+
increment = len;
|
4063
5547
|
} else if (elt->IsString()) {
|
4064
5548
|
String* element = String::cast(elt);
|
4065
5549
|
int element_length = element->length();
|
@@ -4267,17 +5751,77 @@ static Object* Runtime_SmiLexicographicCompare(Arguments args) {
|
|
4267
5751
|
y_value /= 10;
|
4268
5752
|
}
|
4269
5753
|
|
4270
|
-
// Loop through the arrays of decimal digits finding the first place
|
4271
|
-
// where they differ.
|
4272
|
-
while (--x_index >= 0 && --y_index >= 0) {
|
4273
|
-
int diff = x_elms[x_index] - y_elms[y_index];
|
4274
|
-
if (diff != 0) return Smi::FromInt(diff);
|
5754
|
+
// Loop through the arrays of decimal digits finding the first place
|
5755
|
+
// where they differ.
|
5756
|
+
while (--x_index >= 0 && --y_index >= 0) {
|
5757
|
+
int diff = x_elms[x_index] - y_elms[y_index];
|
5758
|
+
if (diff != 0) return Smi::FromInt(diff);
|
5759
|
+
}
|
5760
|
+
|
5761
|
+
// If one array is a suffix of the other array, the longest array is
|
5762
|
+
// the representation of the largest of the Smis in the
|
5763
|
+
// lexicographic ordering.
|
5764
|
+
return Smi::FromInt(x_index - y_index);
|
5765
|
+
}
|
5766
|
+
|
5767
|
+
|
5768
|
+
static Object* StringInputBufferCompare(String* x, String* y) {
|
5769
|
+
static StringInputBuffer bufx;
|
5770
|
+
static StringInputBuffer bufy;
|
5771
|
+
bufx.Reset(x);
|
5772
|
+
bufy.Reset(y);
|
5773
|
+
while (bufx.has_more() && bufy.has_more()) {
|
5774
|
+
int d = bufx.GetNext() - bufy.GetNext();
|
5775
|
+
if (d < 0) return Smi::FromInt(LESS);
|
5776
|
+
else if (d > 0) return Smi::FromInt(GREATER);
|
5777
|
+
}
|
5778
|
+
|
5779
|
+
// x is (non-trivial) prefix of y:
|
5780
|
+
if (bufy.has_more()) return Smi::FromInt(LESS);
|
5781
|
+
// y is prefix of x:
|
5782
|
+
return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
|
5783
|
+
}
|
5784
|
+
|
5785
|
+
|
5786
|
+
static Object* FlatStringCompare(String* x, String* y) {
|
5787
|
+
ASSERT(x->IsFlat());
|
5788
|
+
ASSERT(y->IsFlat());
|
5789
|
+
Object* equal_prefix_result = Smi::FromInt(EQUAL);
|
5790
|
+
int prefix_length = x->length();
|
5791
|
+
if (y->length() < prefix_length) {
|
5792
|
+
prefix_length = y->length();
|
5793
|
+
equal_prefix_result = Smi::FromInt(GREATER);
|
5794
|
+
} else if (y->length() > prefix_length) {
|
5795
|
+
equal_prefix_result = Smi::FromInt(LESS);
|
5796
|
+
}
|
5797
|
+
int r;
|
5798
|
+
if (x->IsAsciiRepresentation()) {
|
5799
|
+
Vector<const char> x_chars = x->ToAsciiVector();
|
5800
|
+
if (y->IsAsciiRepresentation()) {
|
5801
|
+
Vector<const char> y_chars = y->ToAsciiVector();
|
5802
|
+
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
|
5803
|
+
} else {
|
5804
|
+
Vector<const uc16> y_chars = y->ToUC16Vector();
|
5805
|
+
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
|
5806
|
+
}
|
5807
|
+
} else {
|
5808
|
+
Vector<const uc16> x_chars = x->ToUC16Vector();
|
5809
|
+
if (y->IsAsciiRepresentation()) {
|
5810
|
+
Vector<const char> y_chars = y->ToAsciiVector();
|
5811
|
+
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
|
5812
|
+
} else {
|
5813
|
+
Vector<const uc16> y_chars = y->ToUC16Vector();
|
5814
|
+
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
|
5815
|
+
}
|
4275
5816
|
}
|
4276
|
-
|
4277
|
-
|
4278
|
-
|
4279
|
-
|
4280
|
-
|
5817
|
+
Object* result;
|
5818
|
+
if (r == 0) {
|
5819
|
+
result = equal_prefix_result;
|
5820
|
+
} else {
|
5821
|
+
result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
|
5822
|
+
}
|
5823
|
+
ASSERT(result == StringInputBufferCompare(x, y));
|
5824
|
+
return result;
|
4281
5825
|
}
|
4282
5826
|
|
4283
5827
|
|
@@ -4303,38 +5847,20 @@ static Object* Runtime_StringCompare(Arguments args) {
|
|
4303
5847
|
if (d < 0) return Smi::FromInt(LESS);
|
4304
5848
|
else if (d > 0) return Smi::FromInt(GREATER);
|
4305
5849
|
|
4306
|
-
x
|
4307
|
-
|
4308
|
-
|
4309
|
-
|
4310
|
-
static StringInputBuffer bufy;
|
4311
|
-
bufx.Reset(x);
|
4312
|
-
bufy.Reset(y);
|
4313
|
-
while (bufx.has_more() && bufy.has_more()) {
|
4314
|
-
int d = bufx.GetNext() - bufy.GetNext();
|
4315
|
-
if (d < 0) return Smi::FromInt(LESS);
|
4316
|
-
else if (d > 0) return Smi::FromInt(GREATER);
|
4317
|
-
}
|
4318
|
-
|
4319
|
-
// x is (non-trivial) prefix of y:
|
4320
|
-
if (bufy.has_more()) return Smi::FromInt(LESS);
|
4321
|
-
// y is prefix of x:
|
4322
|
-
return Smi::FromInt(bufx.has_more() ? GREATER : EQUAL);
|
4323
|
-
}
|
4324
|
-
|
4325
|
-
|
4326
|
-
static Object* Runtime_Math_abs(Arguments args) {
|
4327
|
-
NoHandleAllocation ha;
|
4328
|
-
ASSERT(args.length() == 1);
|
5850
|
+
Object* obj = Heap::PrepareForCompare(x);
|
5851
|
+
if (obj->IsFailure()) return obj;
|
5852
|
+
obj = Heap::PrepareForCompare(y);
|
5853
|
+
if (obj->IsFailure()) return obj;
|
4329
5854
|
|
4330
|
-
|
4331
|
-
|
5855
|
+
return (x->IsFlat() && y->IsFlat()) ? FlatStringCompare(x, y)
|
5856
|
+
: StringInputBufferCompare(x, y);
|
4332
5857
|
}
|
4333
5858
|
|
4334
5859
|
|
4335
5860
|
static Object* Runtime_Math_acos(Arguments args) {
|
4336
5861
|
NoHandleAllocation ha;
|
4337
5862
|
ASSERT(args.length() == 1);
|
5863
|
+
Counters::math_acos.Increment();
|
4338
5864
|
|
4339
5865
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4340
5866
|
return TranscendentalCache::Get(TranscendentalCache::ACOS, x);
|
@@ -4344,6 +5870,7 @@ static Object* Runtime_Math_acos(Arguments args) {
|
|
4344
5870
|
static Object* Runtime_Math_asin(Arguments args) {
|
4345
5871
|
NoHandleAllocation ha;
|
4346
5872
|
ASSERT(args.length() == 1);
|
5873
|
+
Counters::math_asin.Increment();
|
4347
5874
|
|
4348
5875
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4349
5876
|
return TranscendentalCache::Get(TranscendentalCache::ASIN, x);
|
@@ -4353,6 +5880,7 @@ static Object* Runtime_Math_asin(Arguments args) {
|
|
4353
5880
|
static Object* Runtime_Math_atan(Arguments args) {
|
4354
5881
|
NoHandleAllocation ha;
|
4355
5882
|
ASSERT(args.length() == 1);
|
5883
|
+
Counters::math_atan.Increment();
|
4356
5884
|
|
4357
5885
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4358
5886
|
return TranscendentalCache::Get(TranscendentalCache::ATAN, x);
|
@@ -4362,6 +5890,7 @@ static Object* Runtime_Math_atan(Arguments args) {
|
|
4362
5890
|
static Object* Runtime_Math_atan2(Arguments args) {
|
4363
5891
|
NoHandleAllocation ha;
|
4364
5892
|
ASSERT(args.length() == 2);
|
5893
|
+
Counters::math_atan2.Increment();
|
4365
5894
|
|
4366
5895
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4367
5896
|
CONVERT_DOUBLE_CHECKED(y, args[1]);
|
@@ -4385,6 +5914,7 @@ static Object* Runtime_Math_atan2(Arguments args) {
|
|
4385
5914
|
static Object* Runtime_Math_ceil(Arguments args) {
|
4386
5915
|
NoHandleAllocation ha;
|
4387
5916
|
ASSERT(args.length() == 1);
|
5917
|
+
Counters::math_ceil.Increment();
|
4388
5918
|
|
4389
5919
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4390
5920
|
return Heap::NumberFromDouble(ceiling(x));
|
@@ -4394,6 +5924,7 @@ static Object* Runtime_Math_ceil(Arguments args) {
|
|
4394
5924
|
static Object* Runtime_Math_cos(Arguments args) {
|
4395
5925
|
NoHandleAllocation ha;
|
4396
5926
|
ASSERT(args.length() == 1);
|
5927
|
+
Counters::math_cos.Increment();
|
4397
5928
|
|
4398
5929
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4399
5930
|
return TranscendentalCache::Get(TranscendentalCache::COS, x);
|
@@ -4403,6 +5934,7 @@ static Object* Runtime_Math_cos(Arguments args) {
|
|
4403
5934
|
static Object* Runtime_Math_exp(Arguments args) {
|
4404
5935
|
NoHandleAllocation ha;
|
4405
5936
|
ASSERT(args.length() == 1);
|
5937
|
+
Counters::math_exp.Increment();
|
4406
5938
|
|
4407
5939
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4408
5940
|
return TranscendentalCache::Get(TranscendentalCache::EXP, x);
|
@@ -4412,6 +5944,7 @@ static Object* Runtime_Math_exp(Arguments args) {
|
|
4412
5944
|
static Object* Runtime_Math_floor(Arguments args) {
|
4413
5945
|
NoHandleAllocation ha;
|
4414
5946
|
ASSERT(args.length() == 1);
|
5947
|
+
Counters::math_floor.Increment();
|
4415
5948
|
|
4416
5949
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4417
5950
|
return Heap::NumberFromDouble(floor(x));
|
@@ -4421,6 +5954,7 @@ static Object* Runtime_Math_floor(Arguments args) {
|
|
4421
5954
|
static Object* Runtime_Math_log(Arguments args) {
|
4422
5955
|
NoHandleAllocation ha;
|
4423
5956
|
ASSERT(args.length() == 1);
|
5957
|
+
Counters::math_log.Increment();
|
4424
5958
|
|
4425
5959
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4426
5960
|
return TranscendentalCache::Get(TranscendentalCache::LOG, x);
|
@@ -4461,6 +5995,7 @@ static double powi(double x, int y) {
|
|
4461
5995
|
static Object* Runtime_Math_pow(Arguments args) {
|
4462
5996
|
NoHandleAllocation ha;
|
4463
5997
|
ASSERT(args.length() == 2);
|
5998
|
+
Counters::math_pow.Increment();
|
4464
5999
|
|
4465
6000
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4466
6001
|
|
@@ -4495,20 +6030,63 @@ static Object* Runtime_Math_pow(Arguments args) {
|
|
4495
6030
|
}
|
4496
6031
|
}
|
4497
6032
|
|
6033
|
+
// Fast version of Math.pow if we know that y is not an integer and
|
6034
|
+
// y is not -0.5 or 0.5. Used as slowcase from codegen.
|
6035
|
+
static Object* Runtime_Math_pow_cfunction(Arguments args) {
|
6036
|
+
NoHandleAllocation ha;
|
6037
|
+
ASSERT(args.length() == 2);
|
6038
|
+
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
6039
|
+
CONVERT_DOUBLE_CHECKED(y, args[1]);
|
6040
|
+
if (y == 0) {
|
6041
|
+
return Smi::FromInt(1);
|
6042
|
+
} else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
|
6043
|
+
return Heap::nan_value();
|
6044
|
+
} else {
|
6045
|
+
return Heap::AllocateHeapNumber(pow(x, y));
|
6046
|
+
}
|
6047
|
+
}
|
6048
|
+
|
4498
6049
|
|
4499
|
-
static Object*
|
6050
|
+
static Object* Runtime_RoundNumber(Arguments args) {
|
4500
6051
|
NoHandleAllocation ha;
|
4501
6052
|
ASSERT(args.length() == 1);
|
6053
|
+
Counters::math_round.Increment();
|
4502
6054
|
|
4503
|
-
|
4504
|
-
|
4505
|
-
|
6055
|
+
if (!args[0]->IsHeapNumber()) {
|
6056
|
+
// Must be smi. Return the argument unchanged for all the other types
|
6057
|
+
// to make fuzz-natives test happy.
|
6058
|
+
return args[0];
|
6059
|
+
}
|
6060
|
+
|
6061
|
+
HeapNumber* number = reinterpret_cast<HeapNumber*>(args[0]);
|
6062
|
+
|
6063
|
+
double value = number->value();
|
6064
|
+
int exponent = number->get_exponent();
|
6065
|
+
int sign = number->get_sign();
|
6066
|
+
|
6067
|
+
// We compare with kSmiValueSize - 3 because (2^30 - 0.1) has exponent 29 and
|
6068
|
+
// should be rounded to 2^30, which is not smi.
|
6069
|
+
if (!sign && exponent <= kSmiValueSize - 3) {
|
6070
|
+
return Smi::FromInt(static_cast<int>(value + 0.5));
|
6071
|
+
}
|
6072
|
+
|
6073
|
+
// If the magnitude is big enough, there's no place for fraction part. If we
|
6074
|
+
// try to add 0.5 to this number, 1.0 will be added instead.
|
6075
|
+
if (exponent >= 52) {
|
6076
|
+
return number;
|
6077
|
+
}
|
6078
|
+
|
6079
|
+
if (sign && value >= -0.5) return Heap::minus_zero_value();
|
6080
|
+
|
6081
|
+
// Do not call NumberFromDouble() to avoid extra checks.
|
6082
|
+
return Heap::AllocateHeapNumber(floor(value + 0.5));
|
4506
6083
|
}
|
4507
6084
|
|
4508
6085
|
|
4509
6086
|
static Object* Runtime_Math_sin(Arguments args) {
|
4510
6087
|
NoHandleAllocation ha;
|
4511
6088
|
ASSERT(args.length() == 1);
|
6089
|
+
Counters::math_sin.Increment();
|
4512
6090
|
|
4513
6091
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4514
6092
|
return TranscendentalCache::Get(TranscendentalCache::SIN, x);
|
@@ -4518,6 +6096,7 @@ static Object* Runtime_Math_sin(Arguments args) {
|
|
4518
6096
|
static Object* Runtime_Math_sqrt(Arguments args) {
|
4519
6097
|
NoHandleAllocation ha;
|
4520
6098
|
ASSERT(args.length() == 1);
|
6099
|
+
Counters::math_sqrt.Increment();
|
4521
6100
|
|
4522
6101
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4523
6102
|
return Heap::AllocateHeapNumber(sqrt(x));
|
@@ -4527,42 +6106,372 @@ static Object* Runtime_Math_sqrt(Arguments args) {
|
|
4527
6106
|
static Object* Runtime_Math_tan(Arguments args) {
|
4528
6107
|
NoHandleAllocation ha;
|
4529
6108
|
ASSERT(args.length() == 1);
|
6109
|
+
Counters::math_tan.Increment();
|
4530
6110
|
|
4531
6111
|
CONVERT_DOUBLE_CHECKED(x, args[0]);
|
4532
6112
|
return TranscendentalCache::Get(TranscendentalCache::TAN, x);
|
4533
6113
|
}
|
4534
6114
|
|
4535
6115
|
|
4536
|
-
|
4537
|
-
|
4538
|
-
|
4539
|
-
static
|
6116
|
+
static int MakeDay(int year, int month, int day) {
|
6117
|
+
static const int day_from_month[] = {0, 31, 59, 90, 120, 151,
|
6118
|
+
181, 212, 243, 273, 304, 334};
|
6119
|
+
static const int day_from_month_leap[] = {0, 31, 60, 91, 121, 152,
|
6120
|
+
182, 213, 244, 274, 305, 335};
|
6121
|
+
|
6122
|
+
year += month / 12;
|
6123
|
+
month %= 12;
|
6124
|
+
if (month < 0) {
|
6125
|
+
year--;
|
6126
|
+
month += 12;
|
6127
|
+
}
|
6128
|
+
|
6129
|
+
ASSERT(month >= 0);
|
6130
|
+
ASSERT(month < 12);
|
6131
|
+
|
6132
|
+
// year_delta is an arbitrary number such that:
|
6133
|
+
// a) year_delta = -1 (mod 400)
|
6134
|
+
// b) year + year_delta > 0 for years in the range defined by
|
6135
|
+
// ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of
|
6136
|
+
// Jan 1 1970. This is required so that we don't run into integer
|
6137
|
+
// division of negative numbers.
|
6138
|
+
// c) there shouldn't be an overflow for 32-bit integers in the following
|
6139
|
+
// operations.
|
6140
|
+
static const int year_delta = 399999;
|
6141
|
+
static const int base_day = 365 * (1970 + year_delta) +
|
6142
|
+
(1970 + year_delta) / 4 -
|
6143
|
+
(1970 + year_delta) / 100 +
|
6144
|
+
(1970 + year_delta) / 400;
|
6145
|
+
|
6146
|
+
int year1 = year + year_delta;
|
6147
|
+
int day_from_year = 365 * year1 +
|
6148
|
+
year1 / 4 -
|
6149
|
+
year1 / 100 +
|
6150
|
+
year1 / 400 -
|
6151
|
+
base_day;
|
6152
|
+
|
6153
|
+
if (year % 4 || (year % 100 == 0 && year % 400 != 0)) {
|
6154
|
+
return day_from_year + day_from_month[month] + day - 1;
|
6155
|
+
}
|
6156
|
+
|
6157
|
+
return day_from_year + day_from_month_leap[month] + day - 1;
|
6158
|
+
}
|
6159
|
+
|
6160
|
+
|
6161
|
+
static Object* Runtime_DateMakeDay(Arguments args) {
|
4540
6162
|
NoHandleAllocation ha;
|
4541
|
-
ASSERT(args.length() ==
|
6163
|
+
ASSERT(args.length() == 3);
|
4542
6164
|
|
4543
|
-
|
4544
|
-
|
6165
|
+
CONVERT_SMI_CHECKED(year, args[0]);
|
6166
|
+
CONVERT_SMI_CHECKED(month, args[1]);
|
6167
|
+
CONVERT_SMI_CHECKED(date, args[2]);
|
6168
|
+
|
6169
|
+
return Smi::FromInt(MakeDay(year, month, date));
|
6170
|
+
}
|
6171
|
+
|
6172
|
+
|
6173
|
+
static const int kDays4Years[] = {0, 365, 2 * 365, 3 * 365 + 1};
|
6174
|
+
static const int kDaysIn4Years = 4 * 365 + 1;
|
6175
|
+
static const int kDaysIn100Years = 25 * kDaysIn4Years - 1;
|
6176
|
+
static const int kDaysIn400Years = 4 * kDaysIn100Years + 1;
|
6177
|
+
static const int kDays1970to2000 = 30 * 365 + 7;
|
6178
|
+
static const int kDaysOffset = 1000 * kDaysIn400Years + 5 * kDaysIn400Years -
|
6179
|
+
kDays1970to2000;
|
6180
|
+
static const int kYearsOffset = 400000;
|
6181
|
+
|
6182
|
+
static const char kDayInYear[] = {
|
6183
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6184
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6185
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6186
|
+
22, 23, 24, 25, 26, 27, 28,
|
6187
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6188
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6189
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6190
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6191
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6192
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6193
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6194
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6195
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6196
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6197
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6198
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6199
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6200
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6201
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6202
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6203
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6204
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6205
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6206
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6207
|
+
|
6208
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6209
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6210
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6211
|
+
22, 23, 24, 25, 26, 27, 28,
|
6212
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6213
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6214
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6215
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6216
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6217
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6218
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6219
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6220
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6221
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6222
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6223
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6224
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6225
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6226
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6227
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6228
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6229
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6230
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6231
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6232
|
+
|
6233
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6234
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6235
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6236
|
+
22, 23, 24, 25, 26, 27, 28, 29,
|
6237
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6238
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6239
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6240
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6241
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6242
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6243
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6244
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6245
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6246
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6247
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6248
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6249
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6250
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6251
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6252
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6253
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6254
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6255
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6256
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6257
|
+
|
6258
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6259
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6260
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6261
|
+
22, 23, 24, 25, 26, 27, 28,
|
6262
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6263
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6264
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6265
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6266
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6267
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6268
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6269
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6270
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6271
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6272
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6273
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6274
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6275
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6276
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6277
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
6278
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6279
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30,
|
6280
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
6281
|
+
22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
6282
|
+
|
6283
|
+
static const char kMonthInYear[] = {
|
6284
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
6285
|
+
0, 0, 0, 0, 0, 0,
|
6286
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
6287
|
+
1, 1, 1,
|
6288
|
+
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
6289
|
+
2, 2, 2, 2, 2, 2,
|
6290
|
+
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
6291
|
+
3, 3, 3, 3, 3,
|
6292
|
+
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
6293
|
+
4, 4, 4, 4, 4, 4,
|
6294
|
+
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
6295
|
+
5, 5, 5, 5, 5,
|
6296
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
6297
|
+
6, 6, 6, 6, 6, 6,
|
6298
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
6299
|
+
7, 7, 7, 7, 7, 7,
|
6300
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
6301
|
+
8, 8, 8, 8, 8,
|
6302
|
+
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
6303
|
+
9, 9, 9, 9, 9, 9,
|
6304
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6305
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6306
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
6307
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
6308
|
+
|
6309
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
6310
|
+
0, 0, 0, 0, 0, 0,
|
6311
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
6312
|
+
1, 1, 1,
|
6313
|
+
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
6314
|
+
2, 2, 2, 2, 2, 2,
|
6315
|
+
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
6316
|
+
3, 3, 3, 3, 3,
|
6317
|
+
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
6318
|
+
4, 4, 4, 4, 4, 4,
|
6319
|
+
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
6320
|
+
5, 5, 5, 5, 5,
|
6321
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
6322
|
+
6, 6, 6, 6, 6, 6,
|
6323
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
6324
|
+
7, 7, 7, 7, 7, 7,
|
6325
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
6326
|
+
8, 8, 8, 8, 8,
|
6327
|
+
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
6328
|
+
9, 9, 9, 9, 9, 9,
|
6329
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6330
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6331
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
6332
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
6333
|
+
|
6334
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
6335
|
+
0, 0, 0, 0, 0, 0,
|
6336
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
6337
|
+
1, 1, 1, 1,
|
6338
|
+
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
6339
|
+
2, 2, 2, 2, 2, 2,
|
6340
|
+
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
6341
|
+
3, 3, 3, 3, 3,
|
6342
|
+
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
6343
|
+
4, 4, 4, 4, 4, 4,
|
6344
|
+
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
6345
|
+
5, 5, 5, 5, 5,
|
6346
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
6347
|
+
6, 6, 6, 6, 6, 6,
|
6348
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
6349
|
+
7, 7, 7, 7, 7, 7,
|
6350
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
6351
|
+
8, 8, 8, 8, 8,
|
6352
|
+
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
6353
|
+
9, 9, 9, 9, 9, 9,
|
6354
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6355
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6356
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
6357
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
6358
|
+
|
6359
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
6360
|
+
0, 0, 0, 0, 0, 0,
|
6361
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
6362
|
+
1, 1, 1,
|
6363
|
+
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
6364
|
+
2, 2, 2, 2, 2, 2,
|
6365
|
+
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
6366
|
+
3, 3, 3, 3, 3,
|
6367
|
+
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
6368
|
+
4, 4, 4, 4, 4, 4,
|
6369
|
+
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
6370
|
+
5, 5, 5, 5, 5,
|
6371
|
+
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
6372
|
+
6, 6, 6, 6, 6, 6,
|
6373
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
6374
|
+
7, 7, 7, 7, 7, 7,
|
6375
|
+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
6376
|
+
8, 8, 8, 8, 8,
|
6377
|
+
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
|
6378
|
+
9, 9, 9, 9, 9, 9,
|
6379
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6380
|
+
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
6381
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
6382
|
+
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11};
|
6383
|
+
|
6384
|
+
|
6385
|
+
// This function works for dates from 1970 to 2099.
|
6386
|
+
static inline void DateYMDFromTimeAfter1970(int date,
|
6387
|
+
int& year, int& month, int& day) {
|
6388
|
+
#ifdef DEBUG
|
6389
|
+
int save_date = date; // Need this for ASSERT in the end.
|
6390
|
+
#endif
|
4545
6391
|
|
4546
|
-
|
4547
|
-
|
4548
|
-
it.AdvanceToArgumentsFrame();
|
4549
|
-
JavaScriptFrame* frame = it.frame();
|
6392
|
+
year = 1970 + (4 * date + 2) / kDaysIn4Years;
|
6393
|
+
date %= kDaysIn4Years;
|
4550
6394
|
|
4551
|
-
|
4552
|
-
|
4553
|
-
|
4554
|
-
|
4555
|
-
|
4556
|
-
|
4557
|
-
|
4558
|
-
|
4559
|
-
|
4560
|
-
|
4561
|
-
|
4562
|
-
|
4563
|
-
|
6395
|
+
month = kMonthInYear[date];
|
6396
|
+
day = kDayInYear[date];
|
6397
|
+
|
6398
|
+
ASSERT(MakeDay(year, month, day) == save_date);
|
6399
|
+
}
|
6400
|
+
|
6401
|
+
|
6402
|
+
static inline void DateYMDFromTimeSlow(int date,
|
6403
|
+
int& year, int& month, int& day) {
|
6404
|
+
#ifdef DEBUG
|
6405
|
+
int save_date = date; // Need this for ASSERT in the end.
|
6406
|
+
#endif
|
6407
|
+
|
6408
|
+
date += kDaysOffset;
|
6409
|
+
year = 400 * (date / kDaysIn400Years) - kYearsOffset;
|
6410
|
+
date %= kDaysIn400Years;
|
6411
|
+
|
6412
|
+
ASSERT(MakeDay(year, 0, 1) + date == save_date);
|
6413
|
+
|
6414
|
+
date--;
|
6415
|
+
int yd1 = date / kDaysIn100Years;
|
6416
|
+
date %= kDaysIn100Years;
|
6417
|
+
year += 100 * yd1;
|
6418
|
+
|
6419
|
+
date++;
|
6420
|
+
int yd2 = date / kDaysIn4Years;
|
6421
|
+
date %= kDaysIn4Years;
|
6422
|
+
year += 4 * yd2;
|
6423
|
+
|
6424
|
+
date--;
|
6425
|
+
int yd3 = date / 365;
|
6426
|
+
date %= 365;
|
6427
|
+
year += yd3;
|
6428
|
+
|
6429
|
+
bool is_leap = (!yd1 || yd2) && !yd3;
|
6430
|
+
|
6431
|
+
ASSERT(date >= -1);
|
6432
|
+
ASSERT(is_leap || (date >= 0));
|
6433
|
+
ASSERT((date < 365) || (is_leap && (date < 366)));
|
6434
|
+
ASSERT(is_leap == ((year % 4 == 0) && (year % 100 || (year % 400 == 0))));
|
6435
|
+
ASSERT(is_leap || ((MakeDay(year, 0, 1) + date) == save_date));
|
6436
|
+
ASSERT(!is_leap || ((MakeDay(year, 0, 1) + date + 1) == save_date));
|
6437
|
+
|
6438
|
+
if (is_leap) {
|
6439
|
+
day = kDayInYear[2*365 + 1 + date];
|
6440
|
+
month = kMonthInYear[2*365 + 1 + date];
|
6441
|
+
} else {
|
6442
|
+
day = kDayInYear[date];
|
6443
|
+
month = kMonthInYear[date];
|
4564
6444
|
}
|
4565
|
-
|
6445
|
+
|
6446
|
+
ASSERT(MakeDay(year, month, day) == save_date);
|
6447
|
+
}
|
6448
|
+
|
6449
|
+
|
6450
|
+
static inline void DateYMDFromTime(int date,
|
6451
|
+
int& year, int& month, int& day) {
|
6452
|
+
if (date >= 0 && date < 32 * kDaysIn4Years) {
|
6453
|
+
DateYMDFromTimeAfter1970(date, year, month, day);
|
6454
|
+
} else {
|
6455
|
+
DateYMDFromTimeSlow(date, year, month, day);
|
6456
|
+
}
|
6457
|
+
}
|
6458
|
+
|
6459
|
+
|
6460
|
+
static Object* Runtime_DateYMDFromTime(Arguments args) {
|
6461
|
+
NoHandleAllocation ha;
|
6462
|
+
ASSERT(args.length() == 2);
|
6463
|
+
|
6464
|
+
CONVERT_DOUBLE_CHECKED(t, args[0]);
|
6465
|
+
CONVERT_CHECKED(JSArray, res_array, args[1]);
|
6466
|
+
|
6467
|
+
int year, month, day;
|
6468
|
+
DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day);
|
6469
|
+
|
6470
|
+
res_array->SetElement(0, Smi::FromInt(year));
|
6471
|
+
res_array->SetElement(1, Smi::FromInt(month));
|
6472
|
+
res_array->SetElement(2, Smi::FromInt(day));
|
6473
|
+
|
6474
|
+
return Heap::undefined_value();
|
4566
6475
|
}
|
4567
6476
|
|
4568
6477
|
|
@@ -4581,10 +6490,13 @@ static Object* Runtime_NewArgumentsFast(Arguments args) {
|
|
4581
6490
|
// Allocate the fixed array.
|
4582
6491
|
Object* obj = Heap::AllocateRawFixedArray(length);
|
4583
6492
|
if (obj->IsFailure()) return obj;
|
6493
|
+
|
6494
|
+
AssertNoAllocation no_gc;
|
4584
6495
|
reinterpret_cast<Array*>(obj)->set_map(Heap::fixed_array_map());
|
4585
6496
|
FixedArray* array = FixedArray::cast(obj);
|
4586
6497
|
array->set_length(length);
|
4587
|
-
|
6498
|
+
|
6499
|
+
WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
|
4588
6500
|
for (int i = 0; i < length; i++) {
|
4589
6501
|
array->set(i, *--parameters, mode);
|
4590
6502
|
}
|
@@ -4598,32 +6510,32 @@ static Object* Runtime_NewClosure(Arguments args) {
|
|
4598
6510
|
HandleScope scope;
|
4599
6511
|
ASSERT(args.length() == 2);
|
4600
6512
|
CONVERT_ARG_CHECKED(Context, context, 0);
|
4601
|
-
CONVERT_ARG_CHECKED(
|
6513
|
+
CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
|
4602
6514
|
|
4603
6515
|
PretenureFlag pretenure = (context->global_context() == *context)
|
4604
6516
|
? TENURED // Allocate global closures in old space.
|
4605
6517
|
: NOT_TENURED; // Allocate local closures in new space.
|
4606
6518
|
Handle<JSFunction> result =
|
4607
|
-
Factory::
|
6519
|
+
Factory::NewFunctionFromSharedFunctionInfo(shared, context, pretenure);
|
4608
6520
|
return *result;
|
4609
6521
|
}
|
4610
6522
|
|
4611
6523
|
|
4612
|
-
static Code* ComputeConstructStub(Handle<
|
4613
|
-
|
4614
|
-
|
4615
|
-
|
4616
|
-
|
4617
|
-
|
6524
|
+
static Code* ComputeConstructStub(Handle<JSFunction> function) {
|
6525
|
+
Handle<Object> prototype = Factory::null_value();
|
6526
|
+
if (function->has_instance_prototype()) {
|
6527
|
+
prototype = Handle<Object>(function->instance_prototype());
|
6528
|
+
}
|
6529
|
+
if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
|
4618
6530
|
ConstructStubCompiler compiler;
|
4619
|
-
Object* code = compiler.CompileConstructStub(
|
6531
|
+
Object* code = compiler.CompileConstructStub(function->shared());
|
4620
6532
|
if (code->IsFailure()) {
|
4621
6533
|
return Builtins::builtin(Builtins::JSConstructStubGeneric);
|
4622
6534
|
}
|
4623
6535
|
return Code::cast(code);
|
4624
6536
|
}
|
4625
6537
|
|
4626
|
-
return
|
6538
|
+
return function->shared()->construct_stub();
|
4627
6539
|
}
|
4628
6540
|
|
4629
6541
|
|
@@ -4642,6 +6554,16 @@ static Object* Runtime_NewObject(Arguments args) {
|
|
4642
6554
|
}
|
4643
6555
|
|
4644
6556
|
Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
|
6557
|
+
|
6558
|
+
// If function should not have prototype, construction is not allowed. In this
|
6559
|
+
// case generated code bailouts here, since function has no initial_map.
|
6560
|
+
if (!function->should_have_prototype()) {
|
6561
|
+
Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
|
6562
|
+
Handle<Object> type_error =
|
6563
|
+
Factory::NewTypeError("not_constructor", arguments);
|
6564
|
+
return Top::Throw(*type_error);
|
6565
|
+
}
|
6566
|
+
|
4645
6567
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
4646
6568
|
// Handle stepping into constructors if step into is active.
|
4647
6569
|
if (Debug::StepInActive()) {
|
@@ -4667,19 +6589,15 @@ static Object* Runtime_NewObject(Arguments args) {
|
|
4667
6589
|
}
|
4668
6590
|
|
4669
6591
|
// The function should be compiled for the optimization hints to be available.
|
4670
|
-
|
4671
|
-
|
4672
|
-
CLEAR_EXCEPTION,
|
4673
|
-
0);
|
4674
|
-
}
|
6592
|
+
Handle<SharedFunctionInfo> shared(function->shared());
|
6593
|
+
EnsureCompiled(shared, CLEAR_EXCEPTION);
|
4675
6594
|
|
4676
6595
|
bool first_allocation = !function->has_initial_map();
|
4677
6596
|
Handle<JSObject> result = Factory::NewJSObject(function);
|
4678
6597
|
if (first_allocation) {
|
4679
|
-
Handle<Map> map = Handle<Map>(function->initial_map());
|
4680
6598
|
Handle<Code> stub = Handle<Code>(
|
4681
|
-
ComputeConstructStub(Handle<
|
4682
|
-
|
6599
|
+
ComputeConstructStub(Handle<JSFunction>(function)));
|
6600
|
+
shared->set_construct_stub(*stub);
|
4683
6601
|
}
|
4684
6602
|
|
4685
6603
|
Counters::constructed_objects.Increment();
|
@@ -4710,7 +6628,7 @@ static Object* Runtime_LazyCompile(Arguments args) {
|
|
4710
6628
|
// this means that things called through constructors are never known to
|
4711
6629
|
// be in loops. We compile them as if they are in loops here just in case.
|
4712
6630
|
ASSERT(!function->is_compiled());
|
4713
|
-
if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) {
|
6631
|
+
if (!CompileLazyInLoop(function, Handle<Object>::null(), KEEP_EXCEPTION)) {
|
4714
6632
|
return Failure::Exception();
|
4715
6633
|
}
|
4716
6634
|
|
@@ -4718,28 +6636,6 @@ static Object* Runtime_LazyCompile(Arguments args) {
|
|
4718
6636
|
}
|
4719
6637
|
|
4720
6638
|
|
4721
|
-
static Object* Runtime_GetCalledFunction(Arguments args) {
|
4722
|
-
HandleScope scope;
|
4723
|
-
ASSERT(args.length() == 0);
|
4724
|
-
StackFrameIterator it;
|
4725
|
-
// Get past the JS-to-C exit frame.
|
4726
|
-
ASSERT(it.frame()->is_exit());
|
4727
|
-
it.Advance();
|
4728
|
-
// Get past the CALL_NON_FUNCTION activation frame.
|
4729
|
-
ASSERT(it.frame()->is_java_script());
|
4730
|
-
it.Advance();
|
4731
|
-
// Argument adaptor frames do not copy the function; we have to skip
|
4732
|
-
// past them to get to the real calling frame.
|
4733
|
-
if (it.frame()->is_arguments_adaptor()) it.Advance();
|
4734
|
-
// Get the function from the top of the expression stack of the
|
4735
|
-
// calling frame.
|
4736
|
-
StandardFrame* frame = StandardFrame::cast(it.frame());
|
4737
|
-
int index = frame->ComputeExpressionsCount() - 1;
|
4738
|
-
Object* result = frame->GetExpression(index);
|
4739
|
-
return result;
|
4740
|
-
}
|
4741
|
-
|
4742
|
-
|
4743
6639
|
static Object* Runtime_GetFunctionDelegate(Arguments args) {
|
4744
6640
|
HandleScope scope;
|
4745
6641
|
ASSERT(args.length() == 1);
|
@@ -5190,6 +7086,7 @@ static Object* Runtime_DebugPrint(Arguments args) {
|
|
5190
7086
|
}
|
5191
7087
|
args[0]->Print();
|
5192
7088
|
if (args[0]->IsHeapObject()) {
|
7089
|
+
PrintF("\n");
|
5193
7090
|
HeapObject::cast(args[0])->map()->Print();
|
5194
7091
|
}
|
5195
7092
|
#else
|
@@ -5281,21 +7178,6 @@ static Object* Runtime_DateDaylightSavingsOffset(Arguments args) {
|
|
5281
7178
|
}
|
5282
7179
|
|
5283
7180
|
|
5284
|
-
static Object* Runtime_NumberIsFinite(Arguments args) {
|
5285
|
-
NoHandleAllocation ha;
|
5286
|
-
ASSERT(args.length() == 1);
|
5287
|
-
|
5288
|
-
CONVERT_DOUBLE_CHECKED(value, args[0]);
|
5289
|
-
Object* result;
|
5290
|
-
if (isnan(value) || (fpclassify(value) == FP_INFINITE)) {
|
5291
|
-
result = Heap::false_value();
|
5292
|
-
} else {
|
5293
|
-
result = Heap::true_value();
|
5294
|
-
}
|
5295
|
-
return result;
|
5296
|
-
}
|
5297
|
-
|
5298
|
-
|
5299
7181
|
static Object* Runtime_GlobalReceiver(Arguments args) {
|
5300
7182
|
ASSERT(args.length() == 1);
|
5301
7183
|
Object* global = args[0];
|
@@ -5314,13 +7196,13 @@ static Object* Runtime_CompileString(Arguments args) {
|
|
5314
7196
|
Handle<Context> context(Top::context()->global_context());
|
5315
7197
|
Compiler::ValidationState validate = (is_json->IsTrue())
|
5316
7198
|
? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON;
|
5317
|
-
Handle<
|
5318
|
-
|
5319
|
-
|
5320
|
-
|
5321
|
-
if (
|
7199
|
+
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
|
7200
|
+
context,
|
7201
|
+
true,
|
7202
|
+
validate);
|
7203
|
+
if (shared.is_null()) return Failure::Exception();
|
5322
7204
|
Handle<JSFunction> fun =
|
5323
|
-
Factory::
|
7205
|
+
Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED);
|
5324
7206
|
return *fun;
|
5325
7207
|
}
|
5326
7208
|
|
@@ -5393,14 +7275,14 @@ static ObjectPair Runtime_ResolvePossiblyDirectEval(Arguments args) {
|
|
5393
7275
|
// Deal with a normal eval call with a string argument. Compile it
|
5394
7276
|
// and return the compiled function bound in the local context.
|
5395
7277
|
Handle<String> source = args.at<String>(1);
|
5396
|
-
Handle<
|
7278
|
+
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
|
5397
7279
|
source,
|
5398
7280
|
Handle<Context>(Top::context()),
|
5399
7281
|
Top::context()->IsGlobalContext(),
|
5400
7282
|
Compiler::DONT_VALIDATE_JSON);
|
5401
|
-
if (
|
5402
|
-
callee = Factory::
|
5403
|
-
|
7283
|
+
if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
|
7284
|
+
callee = Factory::NewFunctionFromSharedFunctionInfo(
|
7285
|
+
shared,
|
5404
7286
|
Handle<Context>(Top::context()),
|
5405
7287
|
NOT_TENURED);
|
5406
7288
|
return MakePair(*callee, args[2]);
|
@@ -5872,7 +7754,7 @@ static Object* Runtime_MoveArrayContents(Arguments args) {
|
|
5872
7754
|
to->SetContent(FixedArray::cast(from->elements()));
|
5873
7755
|
to->set_length(from->length());
|
5874
7756
|
from->SetContent(Heap::empty_fixed_array());
|
5875
|
-
from->set_length(0);
|
7757
|
+
from->set_length(Smi::FromInt(0));
|
5876
7758
|
return to;
|
5877
7759
|
}
|
5878
7760
|
|
@@ -5890,6 +7772,32 @@ static Object* Runtime_EstimateNumberOfElements(Arguments args) {
|
|
5890
7772
|
}
|
5891
7773
|
|
5892
7774
|
|
7775
|
+
static Object* Runtime_SwapElements(Arguments args) {
|
7776
|
+
HandleScope handle_scope;
|
7777
|
+
|
7778
|
+
ASSERT_EQ(3, args.length());
|
7779
|
+
|
7780
|
+
CONVERT_ARG_CHECKED(JSObject, object, 0);
|
7781
|
+
Handle<Object> key1 = args.at<Object>(1);
|
7782
|
+
Handle<Object> key2 = args.at<Object>(2);
|
7783
|
+
|
7784
|
+
uint32_t index1, index2;
|
7785
|
+
if (!Array::IndexFromObject(*key1, &index1)
|
7786
|
+
|| !Array::IndexFromObject(*key2, &index2)) {
|
7787
|
+
return Top::ThrowIllegalOperation();
|
7788
|
+
}
|
7789
|
+
|
7790
|
+
Handle<JSObject> jsobject = Handle<JSObject>::cast(object);
|
7791
|
+
Handle<Object> tmp1 = GetElement(jsobject, index1);
|
7792
|
+
Handle<Object> tmp2 = GetElement(jsobject, index2);
|
7793
|
+
|
7794
|
+
SetElement(jsobject, index1, tmp2);
|
7795
|
+
SetElement(jsobject, index2, tmp1);
|
7796
|
+
|
7797
|
+
return Heap::undefined_value();
|
7798
|
+
}
|
7799
|
+
|
7800
|
+
|
5893
7801
|
// Returns an array that tells you where in the [0, length) interval an array
|
5894
7802
|
// might have elements. Can either return keys or intervals. Keys can have
|
5895
7803
|
// gaps in (undefined). Intervals can also span over some undefined keys.
|
@@ -5915,9 +7823,7 @@ static Object* Runtime_GetArrayKeys(Arguments args) {
|
|
5915
7823
|
} else {
|
5916
7824
|
Handle<FixedArray> single_interval = Factory::NewFixedArray(2);
|
5917
7825
|
// -1 means start of array.
|
5918
|
-
single_interval->set(0,
|
5919
|
-
Smi::FromInt(-1),
|
5920
|
-
SKIP_WRITE_BARRIER);
|
7826
|
+
single_interval->set(0, Smi::FromInt(-1));
|
5921
7827
|
uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
|
5922
7828
|
uint32_t min_length = actual_length < length ? actual_length : length;
|
5923
7829
|
Handle<Object> length_object =
|
@@ -6005,21 +7911,6 @@ static Object* Runtime_Break(Arguments args) {
|
|
6005
7911
|
}
|
6006
7912
|
|
6007
7913
|
|
6008
|
-
// Find the length of the prototype chain that is to to handled as one. If a
|
6009
|
-
// prototype object is hidden it is to be viewed as part of the the object it
|
6010
|
-
// is prototype for.
|
6011
|
-
static int LocalPrototypeChainLength(JSObject* obj) {
|
6012
|
-
int count = 1;
|
6013
|
-
Object* proto = obj->GetPrototype();
|
6014
|
-
while (proto->IsJSObject() &&
|
6015
|
-
JSObject::cast(proto)->map()->is_hidden_prototype()) {
|
6016
|
-
count++;
|
6017
|
-
proto = JSObject::cast(proto)->GetPrototype();
|
6018
|
-
}
|
6019
|
-
return count;
|
6020
|
-
}
|
6021
|
-
|
6022
|
-
|
6023
7914
|
static Object* DebugLookupResultValue(Object* receiver, String* name,
|
6024
7915
|
LookupResult* result,
|
6025
7916
|
bool* caught_exception) {
|
@@ -6145,134 +8036,47 @@ static Object* Runtime_DebugGetPropertyDetails(Arguments args) {
|
|
6145
8036
|
if (raw_value->IsFailure()) return raw_value;
|
6146
8037
|
Handle<Object> value(raw_value);
|
6147
8038
|
|
6148
|
-
// If the callback object is a fixed array then it contains JavaScript
|
6149
|
-
// getter and/or setter.
|
6150
|
-
bool hasJavaScriptAccessors = result_type == CALLBACKS &&
|
6151
|
-
result_callback_obj->IsFixedArray();
|
6152
|
-
Handle<FixedArray> details =
|
6153
|
-
Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
|
6154
|
-
details->set(0, *value);
|
6155
|
-
details->set(1, property_details);
|
6156
|
-
if (hasJavaScriptAccessors) {
|
6157
|
-
details->set(2,
|
6158
|
-
caught_exception ? Heap::true_value()
|
6159
|
-
: Heap::false_value());
|
6160
|
-
details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
|
6161
|
-
details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
|
6162
|
-
}
|
6163
|
-
|
6164
|
-
return *Factory::NewJSArrayWithElements(details);
|
6165
|
-
}
|
6166
|
-
if (i < length - 1) {
|
6167
|
-
jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
6168
|
-
}
|
6169
|
-
}
|
6170
|
-
|
6171
|
-
return Heap::undefined_value();
|
6172
|
-
}
|
6173
|
-
|
6174
|
-
|
6175
|
-
static Object* Runtime_DebugGetProperty(Arguments args) {
|
6176
|
-
HandleScope scope;
|
6177
|
-
|
6178
|
-
ASSERT(args.length() == 2);
|
6179
|
-
|
6180
|
-
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
6181
|
-
CONVERT_ARG_CHECKED(String, name, 1);
|
6182
|
-
|
6183
|
-
LookupResult result;
|
6184
|
-
obj->Lookup(*name, &result);
|
6185
|
-
if (result.IsProperty()) {
|
6186
|
-
return DebugLookupResultValue(*obj, *name, &result, NULL);
|
6187
|
-
}
|
6188
|
-
return Heap::undefined_value();
|
6189
|
-
}
|
6190
|
-
|
6191
|
-
|
6192
|
-
// Return the names of the local named properties.
|
6193
|
-
// args[0]: object
|
6194
|
-
static Object* Runtime_DebugLocalPropertyNames(Arguments args) {
|
6195
|
-
HandleScope scope;
|
6196
|
-
ASSERT(args.length() == 1);
|
6197
|
-
if (!args[0]->IsJSObject()) {
|
6198
|
-
return Heap::undefined_value();
|
6199
|
-
}
|
6200
|
-
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
6201
|
-
|
6202
|
-
// Skip the global proxy as it has no properties and always delegates to the
|
6203
|
-
// real global object.
|
6204
|
-
if (obj->IsJSGlobalProxy()) {
|
6205
|
-
obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
|
6206
|
-
}
|
6207
|
-
|
6208
|
-
// Find the number of objects making up this.
|
6209
|
-
int length = LocalPrototypeChainLength(*obj);
|
6210
|
-
|
6211
|
-
// Find the number of local properties for each of the objects.
|
6212
|
-
int* local_property_count = NewArray<int>(length);
|
6213
|
-
int total_property_count = 0;
|
6214
|
-
Handle<JSObject> jsproto = obj;
|
6215
|
-
for (int i = 0; i < length; i++) {
|
6216
|
-
int n;
|
6217
|
-
n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
|
6218
|
-
local_property_count[i] = n;
|
6219
|
-
total_property_count += n;
|
6220
|
-
if (i < length - 1) {
|
6221
|
-
jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
6222
|
-
}
|
6223
|
-
}
|
6224
|
-
|
6225
|
-
// Allocate an array with storage for all the property names.
|
6226
|
-
Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
|
8039
|
+
// If the callback object is a fixed array then it contains JavaScript
|
8040
|
+
// getter and/or setter.
|
8041
|
+
bool hasJavaScriptAccessors = result_type == CALLBACKS &&
|
8042
|
+
result_callback_obj->IsFixedArray();
|
8043
|
+
Handle<FixedArray> details =
|
8044
|
+
Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
|
8045
|
+
details->set(0, *value);
|
8046
|
+
details->set(1, property_details);
|
8047
|
+
if (hasJavaScriptAccessors) {
|
8048
|
+
details->set(2,
|
8049
|
+
caught_exception ? Heap::true_value()
|
8050
|
+
: Heap::false_value());
|
8051
|
+
details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
|
8052
|
+
details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
|
8053
|
+
}
|
6227
8054
|
|
6228
|
-
|
6229
|
-
jsproto = obj;
|
6230
|
-
int proto_with_hidden_properties = 0;
|
6231
|
-
for (int i = 0; i < length; i++) {
|
6232
|
-
jsproto->GetLocalPropertyNames(*names,
|
6233
|
-
i == 0 ? 0 : local_property_count[i - 1]);
|
6234
|
-
if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
|
6235
|
-
proto_with_hidden_properties++;
|
8055
|
+
return *Factory::NewJSArrayWithElements(details);
|
6236
8056
|
}
|
6237
8057
|
if (i < length - 1) {
|
6238
8058
|
jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
|
6239
8059
|
}
|
6240
8060
|
}
|
6241
8061
|
|
6242
|
-
|
6243
|
-
if (proto_with_hidden_properties > 0) {
|
6244
|
-
Handle<FixedArray> old_names = names;
|
6245
|
-
names = Factory::NewFixedArray(
|
6246
|
-
names->length() - proto_with_hidden_properties);
|
6247
|
-
int dest_pos = 0;
|
6248
|
-
for (int i = 0; i < total_property_count; i++) {
|
6249
|
-
Object* name = old_names->get(i);
|
6250
|
-
if (name == Heap::hidden_symbol()) {
|
6251
|
-
continue;
|
6252
|
-
}
|
6253
|
-
names->set(dest_pos++, name);
|
6254
|
-
}
|
6255
|
-
}
|
6256
|
-
|
6257
|
-
DeleteArray(local_property_count);
|
6258
|
-
return *Factory::NewJSArrayWithElements(names);
|
8062
|
+
return Heap::undefined_value();
|
6259
8063
|
}
|
6260
8064
|
|
6261
8065
|
|
6262
|
-
|
6263
|
-
// args[0]: object
|
6264
|
-
static Object* Runtime_DebugLocalElementNames(Arguments args) {
|
8066
|
+
static Object* Runtime_DebugGetProperty(Arguments args) {
|
6265
8067
|
HandleScope scope;
|
6266
|
-
|
6267
|
-
|
6268
|
-
|
6269
|
-
}
|
8068
|
+
|
8069
|
+
ASSERT(args.length() == 2);
|
8070
|
+
|
6270
8071
|
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
8072
|
+
CONVERT_ARG_CHECKED(String, name, 1);
|
6271
8073
|
|
6272
|
-
|
6273
|
-
|
6274
|
-
|
6275
|
-
|
8074
|
+
LookupResult result;
|
8075
|
+
obj->Lookup(*name, &result);
|
8076
|
+
if (result.IsProperty()) {
|
8077
|
+
return DebugLookupResultValue(*obj, *name, &result, NULL);
|
8078
|
+
}
|
8079
|
+
return Heap::undefined_value();
|
6276
8080
|
}
|
6277
8081
|
|
6278
8082
|
|
@@ -6306,54 +8110,6 @@ static Object* Runtime_DebugPropertyIndexFromDetails(Arguments args) {
|
|
6306
8110
|
}
|
6307
8111
|
|
6308
8112
|
|
6309
|
-
// Return information on whether an object has a named or indexed interceptor.
|
6310
|
-
// args[0]: object
|
6311
|
-
static Object* Runtime_DebugInterceptorInfo(Arguments args) {
|
6312
|
-
HandleScope scope;
|
6313
|
-
ASSERT(args.length() == 1);
|
6314
|
-
if (!args[0]->IsJSObject()) {
|
6315
|
-
return Smi::FromInt(0);
|
6316
|
-
}
|
6317
|
-
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
6318
|
-
|
6319
|
-
int result = 0;
|
6320
|
-
if (obj->HasNamedInterceptor()) result |= 2;
|
6321
|
-
if (obj->HasIndexedInterceptor()) result |= 1;
|
6322
|
-
|
6323
|
-
return Smi::FromInt(result);
|
6324
|
-
}
|
6325
|
-
|
6326
|
-
|
6327
|
-
// Return property names from named interceptor.
|
6328
|
-
// args[0]: object
|
6329
|
-
static Object* Runtime_DebugNamedInterceptorPropertyNames(Arguments args) {
|
6330
|
-
HandleScope scope;
|
6331
|
-
ASSERT(args.length() == 1);
|
6332
|
-
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
6333
|
-
|
6334
|
-
if (obj->HasNamedInterceptor()) {
|
6335
|
-
v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
|
6336
|
-
if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
|
6337
|
-
}
|
6338
|
-
return Heap::undefined_value();
|
6339
|
-
}
|
6340
|
-
|
6341
|
-
|
6342
|
-
// Return element names from indexed interceptor.
|
6343
|
-
// args[0]: object
|
6344
|
-
static Object* Runtime_DebugIndexedInterceptorElementNames(Arguments args) {
|
6345
|
-
HandleScope scope;
|
6346
|
-
ASSERT(args.length() == 1);
|
6347
|
-
CONVERT_ARG_CHECKED(JSObject, obj, 0);
|
6348
|
-
|
6349
|
-
if (obj->HasIndexedInterceptor()) {
|
6350
|
-
v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
|
6351
|
-
if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
|
6352
|
-
}
|
6353
|
-
return Heap::undefined_value();
|
6354
|
-
}
|
6355
|
-
|
6356
|
-
|
6357
8113
|
// Return property value from named interceptor.
|
6358
8114
|
// args[0]: object
|
6359
8115
|
// args[1]: property name
|
@@ -7202,9 +8958,8 @@ Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script,
|
|
7202
8958
|
Handle<SharedFunctionInfo> last;
|
7203
8959
|
while (!done) {
|
7204
8960
|
HeapIterator iterator;
|
7205
|
-
|
7206
|
-
|
7207
|
-
ASSERT(obj != NULL);
|
8961
|
+
for (HeapObject* obj = iterator.next();
|
8962
|
+
obj != NULL; obj = iterator.next()) {
|
7208
8963
|
if (obj->IsSharedFunctionInfo()) {
|
7209
8964
|
Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj));
|
7210
8965
|
if (shared->script() == *script) {
|
@@ -7269,7 +9024,7 @@ Object* Runtime::FindSharedFunctionInfoInScript(Handle<Script> script,
|
|
7269
9024
|
if (!done) {
|
7270
9025
|
// If the candidate is not compiled compile it to reveal any inner
|
7271
9026
|
// functions which might contain the requested source position.
|
7272
|
-
CompileLazyShared(target, KEEP_EXCEPTION
|
9027
|
+
CompileLazyShared(target, KEEP_EXCEPTION);
|
7273
9028
|
}
|
7274
9029
|
}
|
7275
9030
|
|
@@ -7441,7 +9196,9 @@ static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame,
|
|
7441
9196
|
const int length = frame->GetProvidedParametersCount();
|
7442
9197
|
Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length);
|
7443
9198
|
Handle<FixedArray> array = Factory::NewFixedArray(length);
|
7444
|
-
|
9199
|
+
|
9200
|
+
AssertNoAllocation no_gc;
|
9201
|
+
WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
|
7445
9202
|
for (int i = 0; i < length; i++) {
|
7446
9203
|
array->set(i, frame->GetParameter(i), mode);
|
7447
9204
|
}
|
@@ -7533,14 +9290,14 @@ static Object* Runtime_DebugEvaluate(Arguments args) {
|
|
7533
9290
|
Handle<String> function_source =
|
7534
9291
|
Factory::NewStringFromAscii(Vector<const char>(source_str,
|
7535
9292
|
source_str_length));
|
7536
|
-
Handle<
|
9293
|
+
Handle<SharedFunctionInfo> shared =
|
7537
9294
|
Compiler::CompileEval(function_source,
|
7538
9295
|
context,
|
7539
9296
|
context->IsGlobalContext(),
|
7540
9297
|
Compiler::DONT_VALIDATE_JSON);
|
7541
|
-
if (
|
9298
|
+
if (shared.is_null()) return Failure::Exception();
|
7542
9299
|
Handle<JSFunction> compiled_function =
|
7543
|
-
Factory::
|
9300
|
+
Factory::NewFunctionFromSharedFunctionInfo(shared, context);
|
7544
9301
|
|
7545
9302
|
// Invoke the result of the compilation to get the evaluation function.
|
7546
9303
|
bool has_pending_exception;
|
@@ -7601,15 +9358,15 @@ static Object* Runtime_DebugEvaluateGlobal(Arguments args) {
|
|
7601
9358
|
Handle<Context> context = Top::global_context();
|
7602
9359
|
|
7603
9360
|
// Compile the source to be evaluated.
|
7604
|
-
Handle<
|
7605
|
-
|
7606
|
-
|
7607
|
-
|
7608
|
-
|
7609
|
-
if (
|
9361
|
+
Handle<SharedFunctionInfo> shared =
|
9362
|
+
Compiler::CompileEval(source,
|
9363
|
+
context,
|
9364
|
+
true,
|
9365
|
+
Compiler::DONT_VALIDATE_JSON);
|
9366
|
+
if (shared.is_null()) return Failure::Exception();
|
7610
9367
|
Handle<JSFunction> compiled_function =
|
7611
|
-
Handle<JSFunction>(Factory::
|
7612
|
-
|
9368
|
+
Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared,
|
9369
|
+
context));
|
7613
9370
|
|
7614
9371
|
// Invoke the result of the compilation to get the evaluation function.
|
7615
9372
|
bool has_pending_exception;
|
@@ -7660,10 +9417,10 @@ static int DebugReferencedBy(JSObject* target,
|
|
7660
9417
|
int count = 0;
|
7661
9418
|
JSObject* last = NULL;
|
7662
9419
|
HeapIterator iterator;
|
7663
|
-
|
9420
|
+
HeapObject* heap_obj = NULL;
|
9421
|
+
while (((heap_obj = iterator.next()) != NULL) &&
|
7664
9422
|
(max_references == 0 || count < max_references)) {
|
7665
9423
|
// Only look at all JSObjects.
|
7666
|
-
HeapObject* heap_obj = iterator.next();
|
7667
9424
|
if (heap_obj->IsJSObject()) {
|
7668
9425
|
// Skip context extension objects and argument arrays as these are
|
7669
9426
|
// checked in the context of functions using them.
|
@@ -7773,10 +9530,10 @@ static int DebugConstructedBy(JSFunction* constructor, int max_references,
|
|
7773
9530
|
// Iterate the heap.
|
7774
9531
|
int count = 0;
|
7775
9532
|
HeapIterator iterator;
|
7776
|
-
|
9533
|
+
HeapObject* heap_obj = NULL;
|
9534
|
+
while (((heap_obj = iterator.next()) != NULL) &&
|
7777
9535
|
(max_references == 0 || count < max_references)) {
|
7778
9536
|
// Only look at all JSObjects.
|
7779
|
-
HeapObject* heap_obj = iterator.next();
|
7780
9537
|
if (heap_obj->IsJSObject()) {
|
7781
9538
|
JSObject* obj = JSObject::cast(heap_obj);
|
7782
9539
|
if (obj->map()->constructor() == constructor) {
|
@@ -7855,7 +9612,8 @@ static Object* Runtime_DebugDisassembleFunction(Arguments args) {
|
|
7855
9612
|
ASSERT(args.length() == 1);
|
7856
9613
|
// Get the function and make sure it is compiled.
|
7857
9614
|
CONVERT_ARG_CHECKED(JSFunction, func, 0);
|
7858
|
-
|
9615
|
+
Handle<SharedFunctionInfo> shared(func->shared());
|
9616
|
+
if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
7859
9617
|
return Failure::Exception();
|
7860
9618
|
}
|
7861
9619
|
func->code()->PrintLn();
|
@@ -7870,10 +9628,11 @@ static Object* Runtime_DebugDisassembleConstructor(Arguments args) {
|
|
7870
9628
|
ASSERT(args.length() == 1);
|
7871
9629
|
// Get the function and make sure it is compiled.
|
7872
9630
|
CONVERT_ARG_CHECKED(JSFunction, func, 0);
|
7873
|
-
|
9631
|
+
Handle<SharedFunctionInfo> shared(func->shared());
|
9632
|
+
if (!EnsureCompiled(shared, KEEP_EXCEPTION)) {
|
7874
9633
|
return Failure::Exception();
|
7875
9634
|
}
|
7876
|
-
|
9635
|
+
shared->construct_stub()->PrintLn();
|
7877
9636
|
#endif // DEBUG
|
7878
9637
|
return Heap::undefined_value();
|
7879
9638
|
}
|
@@ -7887,26 +9646,283 @@ static Object* Runtime_FunctionGetInferredName(Arguments args) {
|
|
7887
9646
|
return f->shared()->inferred_name();
|
7888
9647
|
}
|
7889
9648
|
|
9649
|
+
|
9650
|
+
static int FindSharedFunctionInfosForScript(Script* script,
|
9651
|
+
FixedArray* buffer) {
|
9652
|
+
AssertNoAllocation no_allocations;
|
9653
|
+
|
9654
|
+
int counter = 0;
|
9655
|
+
int buffer_size = buffer->length();
|
9656
|
+
HeapIterator iterator;
|
9657
|
+
for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
|
9658
|
+
ASSERT(obj != NULL);
|
9659
|
+
if (!obj->IsSharedFunctionInfo()) {
|
9660
|
+
continue;
|
9661
|
+
}
|
9662
|
+
SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
|
9663
|
+
if (shared->script() != script) {
|
9664
|
+
continue;
|
9665
|
+
}
|
9666
|
+
if (counter < buffer_size) {
|
9667
|
+
buffer->set(counter, shared);
|
9668
|
+
}
|
9669
|
+
counter++;
|
9670
|
+
}
|
9671
|
+
return counter;
|
9672
|
+
}
|
9673
|
+
|
9674
|
+
// For a script finds all SharedFunctionInfo's in the heap that points
|
9675
|
+
// to this script. Returns JSArray of SharedFunctionInfo wrapped
|
9676
|
+
// in OpaqueReferences.
|
9677
|
+
static Object* Runtime_LiveEditFindSharedFunctionInfosForScript(
|
9678
|
+
Arguments args) {
|
9679
|
+
ASSERT(args.length() == 1);
|
9680
|
+
HandleScope scope;
|
9681
|
+
CONVERT_CHECKED(JSValue, script_value, args[0]);
|
9682
|
+
|
9683
|
+
Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
|
9684
|
+
|
9685
|
+
const int kBufferSize = 32;
|
9686
|
+
|
9687
|
+
Handle<FixedArray> array;
|
9688
|
+
array = Factory::NewFixedArray(kBufferSize);
|
9689
|
+
int number = FindSharedFunctionInfosForScript(*script, *array);
|
9690
|
+
if (number > kBufferSize) {
|
9691
|
+
array = Factory::NewFixedArray(number);
|
9692
|
+
FindSharedFunctionInfosForScript(*script, *array);
|
9693
|
+
}
|
9694
|
+
|
9695
|
+
Handle<JSArray> result = Factory::NewJSArrayWithElements(array);
|
9696
|
+
result->set_length(Smi::FromInt(number));
|
9697
|
+
|
9698
|
+
LiveEdit::WrapSharedFunctionInfos(result);
|
9699
|
+
|
9700
|
+
return *result;
|
9701
|
+
}
|
9702
|
+
|
9703
|
+
// For a script calculates compilation information about all its functions.
|
9704
|
+
// The script source is explicitly specified by the second argument.
|
9705
|
+
// The source of the actual script is not used, however it is important that
|
9706
|
+
// all generated code keeps references to this particular instance of script.
|
9707
|
+
// Returns a JSArray of compilation infos. The array is ordered so that
|
9708
|
+
// each function with all its descendant is always stored in a continues range
|
9709
|
+
// with the function itself going first. The root function is a script function.
|
9710
|
+
static Object* Runtime_LiveEditGatherCompileInfo(Arguments args) {
|
9711
|
+
ASSERT(args.length() == 2);
|
9712
|
+
HandleScope scope;
|
9713
|
+
CONVERT_CHECKED(JSValue, script, args[0]);
|
9714
|
+
CONVERT_ARG_CHECKED(String, source, 1);
|
9715
|
+
Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
|
9716
|
+
|
9717
|
+
JSArray* result = LiveEdit::GatherCompileInfo(script_handle, source);
|
9718
|
+
|
9719
|
+
if (Top::has_pending_exception()) {
|
9720
|
+
return Failure::Exception();
|
9721
|
+
}
|
9722
|
+
|
9723
|
+
return result;
|
9724
|
+
}
|
9725
|
+
|
9726
|
+
// Changes the source of the script to a new_source.
|
9727
|
+
// If old_script_name is provided (i.e. is a String), also creates a copy of
|
9728
|
+
// the script with its original source and sends notification to debugger.
|
9729
|
+
static Object* Runtime_LiveEditReplaceScript(Arguments args) {
|
9730
|
+
ASSERT(args.length() == 3);
|
9731
|
+
HandleScope scope;
|
9732
|
+
CONVERT_CHECKED(JSValue, original_script_value, args[0]);
|
9733
|
+
CONVERT_ARG_CHECKED(String, new_source, 1);
|
9734
|
+
Handle<Object> old_script_name(args[2]);
|
9735
|
+
|
9736
|
+
CONVERT_CHECKED(Script, original_script_pointer,
|
9737
|
+
original_script_value->value());
|
9738
|
+
Handle<Script> original_script(original_script_pointer);
|
9739
|
+
|
9740
|
+
Object* old_script = LiveEdit::ChangeScriptSource(original_script,
|
9741
|
+
new_source,
|
9742
|
+
old_script_name);
|
9743
|
+
|
9744
|
+
if (old_script->IsScript()) {
|
9745
|
+
Handle<Script> script_handle(Script::cast(old_script));
|
9746
|
+
return *(GetScriptWrapper(script_handle));
|
9747
|
+
} else {
|
9748
|
+
return Heap::null_value();
|
9749
|
+
}
|
9750
|
+
}
|
9751
|
+
|
9752
|
+
// Replaces code of SharedFunctionInfo with a new one.
|
9753
|
+
static Object* Runtime_LiveEditReplaceFunctionCode(Arguments args) {
|
9754
|
+
ASSERT(args.length() == 2);
|
9755
|
+
HandleScope scope;
|
9756
|
+
CONVERT_ARG_CHECKED(JSArray, new_compile_info, 0);
|
9757
|
+
CONVERT_ARG_CHECKED(JSArray, shared_info, 1);
|
9758
|
+
|
9759
|
+
return LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
|
9760
|
+
}
|
9761
|
+
|
9762
|
+
// Connects SharedFunctionInfo to another script.
|
9763
|
+
static Object* Runtime_LiveEditFunctionSetScript(Arguments args) {
|
9764
|
+
ASSERT(args.length() == 2);
|
9765
|
+
HandleScope scope;
|
9766
|
+
Handle<Object> function_object(args[0]);
|
9767
|
+
Handle<Object> script_object(args[1]);
|
9768
|
+
|
9769
|
+
if (function_object->IsJSValue()) {
|
9770
|
+
Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
|
9771
|
+
if (script_object->IsJSValue()) {
|
9772
|
+
CONVERT_CHECKED(Script, script, JSValue::cast(*script_object)->value());
|
9773
|
+
script_object = Handle<Object>(script);
|
9774
|
+
}
|
9775
|
+
|
9776
|
+
LiveEdit::SetFunctionScript(function_wrapper, script_object);
|
9777
|
+
} else {
|
9778
|
+
// Just ignore this. We may not have a SharedFunctionInfo for some functions
|
9779
|
+
// and we check it in this function.
|
9780
|
+
}
|
9781
|
+
|
9782
|
+
return Heap::undefined_value();
|
9783
|
+
}
|
9784
|
+
|
9785
|
+
|
9786
|
+
// In a code of a parent function replaces original function as embedded object
|
9787
|
+
// with a substitution one.
|
9788
|
+
static Object* Runtime_LiveEditReplaceRefToNestedFunction(Arguments args) {
|
9789
|
+
ASSERT(args.length() == 3);
|
9790
|
+
HandleScope scope;
|
9791
|
+
|
9792
|
+
CONVERT_ARG_CHECKED(JSValue, parent_wrapper, 0);
|
9793
|
+
CONVERT_ARG_CHECKED(JSValue, orig_wrapper, 1);
|
9794
|
+
CONVERT_ARG_CHECKED(JSValue, subst_wrapper, 2);
|
9795
|
+
|
9796
|
+
LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
|
9797
|
+
subst_wrapper);
|
9798
|
+
|
9799
|
+
return Heap::undefined_value();
|
9800
|
+
}
|
9801
|
+
|
9802
|
+
|
9803
|
+
// Updates positions of a shared function info (first parameter) according
|
9804
|
+
// to script source change. Text change is described in second parameter as
|
9805
|
+
// array of groups of 3 numbers:
|
9806
|
+
// (change_begin, change_end, change_end_new_position).
|
9807
|
+
// Each group describes a change in text; groups are sorted by change_begin.
|
9808
|
+
static Object* Runtime_LiveEditPatchFunctionPositions(Arguments args) {
|
9809
|
+
ASSERT(args.length() == 2);
|
9810
|
+
HandleScope scope;
|
9811
|
+
CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
|
9812
|
+
CONVERT_ARG_CHECKED(JSArray, position_change_array, 1);
|
9813
|
+
|
9814
|
+
return LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
|
9815
|
+
}
|
9816
|
+
|
9817
|
+
|
9818
|
+
// For array of SharedFunctionInfo's (each wrapped in JSValue)
|
9819
|
+
// checks that none of them have activations on stacks (of any thread).
|
9820
|
+
// Returns array of the same length with corresponding results of
|
9821
|
+
// LiveEdit::FunctionPatchabilityStatus type.
|
9822
|
+
static Object* Runtime_LiveEditCheckAndDropActivations(Arguments args) {
|
9823
|
+
ASSERT(args.length() == 2);
|
9824
|
+
HandleScope scope;
|
9825
|
+
CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
|
9826
|
+
CONVERT_BOOLEAN_CHECKED(do_drop, args[1]);
|
9827
|
+
|
9828
|
+
return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
|
9829
|
+
}
|
9830
|
+
|
9831
|
+
// Compares 2 strings line-by-line and returns diff in form of JSArray of
|
9832
|
+
// triplets (pos1, pos1_end, pos2_end) describing list of diff chunks.
|
9833
|
+
static Object* Runtime_LiveEditCompareStringsLinewise(Arguments args) {
|
9834
|
+
ASSERT(args.length() == 2);
|
9835
|
+
HandleScope scope;
|
9836
|
+
CONVERT_ARG_CHECKED(String, s1, 0);
|
9837
|
+
CONVERT_ARG_CHECKED(String, s2, 1);
|
9838
|
+
|
9839
|
+
return *LiveEdit::CompareStringsLinewise(s1, s2);
|
9840
|
+
}
|
9841
|
+
|
9842
|
+
|
9843
|
+
|
9844
|
+
// A testing entry. Returns statement position which is the closest to
|
9845
|
+
// source_position.
|
9846
|
+
static Object* Runtime_GetFunctionCodePositionFromSource(Arguments args) {
|
9847
|
+
ASSERT(args.length() == 2);
|
9848
|
+
HandleScope scope;
|
9849
|
+
CONVERT_ARG_CHECKED(JSFunction, function, 0);
|
9850
|
+
CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
|
9851
|
+
|
9852
|
+
Handle<Code> code(function->code());
|
9853
|
+
|
9854
|
+
RelocIterator it(*code, 1 << RelocInfo::STATEMENT_POSITION);
|
9855
|
+
int closest_pc = 0;
|
9856
|
+
int distance = kMaxInt;
|
9857
|
+
while (!it.done()) {
|
9858
|
+
int statement_position = static_cast<int>(it.rinfo()->data());
|
9859
|
+
// Check if this break point is closer that what was previously found.
|
9860
|
+
if (source_position <= statement_position &&
|
9861
|
+
statement_position - source_position < distance) {
|
9862
|
+
closest_pc =
|
9863
|
+
static_cast<int>(it.rinfo()->pc() - code->instruction_start());
|
9864
|
+
distance = statement_position - source_position;
|
9865
|
+
// Check whether we can't get any closer.
|
9866
|
+
if (distance == 0) break;
|
9867
|
+
}
|
9868
|
+
it.next();
|
9869
|
+
}
|
9870
|
+
|
9871
|
+
return Smi::FromInt(closest_pc);
|
9872
|
+
}
|
9873
|
+
|
9874
|
+
|
9875
|
+
// Calls specified function with or without entering the debugger.
|
9876
|
+
// This is used in unit tests to run code as if debugger is entered or simply
|
9877
|
+
// to have a stack with C++ frame in the middle.
|
9878
|
+
static Object* Runtime_ExecuteInDebugContext(Arguments args) {
|
9879
|
+
ASSERT(args.length() == 2);
|
9880
|
+
HandleScope scope;
|
9881
|
+
CONVERT_ARG_CHECKED(JSFunction, function, 0);
|
9882
|
+
CONVERT_BOOLEAN_CHECKED(without_debugger, args[1]);
|
9883
|
+
|
9884
|
+
Handle<Object> result;
|
9885
|
+
bool pending_exception;
|
9886
|
+
{
|
9887
|
+
if (without_debugger) {
|
9888
|
+
result = Execution::Call(function, Top::global(), 0, NULL,
|
9889
|
+
&pending_exception);
|
9890
|
+
} else {
|
9891
|
+
EnterDebugger enter_debugger;
|
9892
|
+
result = Execution::Call(function, Top::global(), 0, NULL,
|
9893
|
+
&pending_exception);
|
9894
|
+
}
|
9895
|
+
}
|
9896
|
+
if (!pending_exception) {
|
9897
|
+
return *result;
|
9898
|
+
} else {
|
9899
|
+
return Failure::Exception();
|
9900
|
+
}
|
9901
|
+
}
|
9902
|
+
|
9903
|
+
|
7890
9904
|
#endif // ENABLE_DEBUGGER_SUPPORT
|
7891
9905
|
|
7892
9906
|
#ifdef ENABLE_LOGGING_AND_PROFILING
|
7893
9907
|
|
7894
9908
|
static Object* Runtime_ProfilerResume(Arguments args) {
|
7895
9909
|
NoHandleAllocation ha;
|
7896
|
-
ASSERT(args.length() ==
|
9910
|
+
ASSERT(args.length() == 2);
|
7897
9911
|
|
7898
9912
|
CONVERT_CHECKED(Smi, smi_modules, args[0]);
|
7899
|
-
|
9913
|
+
CONVERT_CHECKED(Smi, smi_tag, args[1]);
|
9914
|
+
v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
|
7900
9915
|
return Heap::undefined_value();
|
7901
9916
|
}
|
7902
9917
|
|
7903
9918
|
|
7904
9919
|
static Object* Runtime_ProfilerPause(Arguments args) {
|
7905
9920
|
NoHandleAllocation ha;
|
7906
|
-
ASSERT(args.length() ==
|
9921
|
+
ASSERT(args.length() == 2);
|
7907
9922
|
|
7908
9923
|
CONVERT_CHECKED(Smi, smi_modules, args[0]);
|
7909
|
-
|
9924
|
+
CONVERT_CHECKED(Smi, smi_tag, args[1]);
|
9925
|
+
v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
|
7910
9926
|
return Heap::undefined_value();
|
7911
9927
|
}
|
7912
9928
|
|
@@ -7924,8 +9940,8 @@ static Handle<Object> Runtime_GetScriptFromScriptName(
|
|
7924
9940
|
// script data.
|
7925
9941
|
Handle<Script> script;
|
7926
9942
|
HeapIterator iterator;
|
7927
|
-
|
7928
|
-
|
9943
|
+
HeapObject* obj = NULL;
|
9944
|
+
while (script.is_null() && ((obj = iterator.next()) != NULL)) {
|
7929
9945
|
// If a script is found check if it has the script data requested.
|
7930
9946
|
if (obj->IsScript()) {
|
7931
9947
|
if (Script::cast(obj)->name()->IsString()) {
|
@@ -8023,7 +10039,7 @@ static Object* Runtime_CollectStackTrace(Arguments args) {
|
|
8023
10039
|
if (cursor + 2 < elements->length()) {
|
8024
10040
|
elements->set(cursor++, recv);
|
8025
10041
|
elements->set(cursor++, fun);
|
8026
|
-
elements->set(cursor++, offset
|
10042
|
+
elements->set(cursor++, offset);
|
8027
10043
|
} else {
|
8028
10044
|
HandleScope scope;
|
8029
10045
|
Handle<Object> recv_handle(recv);
|
@@ -8036,8 +10052,7 @@ static Object* Runtime_CollectStackTrace(Arguments args) {
|
|
8036
10052
|
iter.Advance();
|
8037
10053
|
}
|
8038
10054
|
|
8039
|
-
result->set_length(Smi::FromInt(cursor)
|
8040
|
-
|
10055
|
+
result->set_length(Smi::FromInt(cursor));
|
8041
10056
|
return *result;
|
8042
10057
|
}
|
8043
10058
|
|
@@ -8072,6 +10087,91 @@ static Object* Runtime_DeleteHandleScopeExtensions(Arguments args) {
|
|
8072
10087
|
}
|
8073
10088
|
|
8074
10089
|
|
10090
|
+
static Object* CacheMiss(FixedArray* cache_obj, int index, Object* key_obj) {
|
10091
|
+
ASSERT(index % 2 == 0); // index of the key
|
10092
|
+
ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
|
10093
|
+
ASSERT(index < cache_obj->length());
|
10094
|
+
|
10095
|
+
HandleScope scope;
|
10096
|
+
|
10097
|
+
Handle<FixedArray> cache(cache_obj);
|
10098
|
+
Handle<Object> key(key_obj);
|
10099
|
+
Handle<JSFunction> factory(JSFunction::cast(
|
10100
|
+
cache->get(JSFunctionResultCache::kFactoryIndex)));
|
10101
|
+
// TODO(antonm): consider passing a receiver when constructing a cache.
|
10102
|
+
Handle<Object> receiver(Top::global_context()->global());
|
10103
|
+
|
10104
|
+
Handle<Object> value;
|
10105
|
+
{
|
10106
|
+
// This handle is nor shared, nor used later, so it's safe.
|
10107
|
+
Object** argv[] = { key.location() };
|
10108
|
+
bool pending_exception = false;
|
10109
|
+
value = Execution::Call(factory,
|
10110
|
+
receiver,
|
10111
|
+
1,
|
10112
|
+
argv,
|
10113
|
+
&pending_exception);
|
10114
|
+
if (pending_exception) return Failure::Exception();
|
10115
|
+
}
|
10116
|
+
|
10117
|
+
cache->set(index, *key);
|
10118
|
+
cache->set(index + 1, *value);
|
10119
|
+
cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index));
|
10120
|
+
|
10121
|
+
return *value;
|
10122
|
+
}
|
10123
|
+
|
10124
|
+
|
10125
|
+
static Object* Runtime_GetFromCache(Arguments args) {
|
10126
|
+
// This is only called from codegen, so checks might be more lax.
|
10127
|
+
CONVERT_CHECKED(FixedArray, cache, args[0]);
|
10128
|
+
Object* key = args[1];
|
10129
|
+
|
10130
|
+
const int finger_index =
|
10131
|
+
Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value();
|
10132
|
+
|
10133
|
+
Object* o = cache->get(finger_index);
|
10134
|
+
if (o == key) {
|
10135
|
+
// The fastest case: hit the same place again.
|
10136
|
+
return cache->get(finger_index + 1);
|
10137
|
+
}
|
10138
|
+
|
10139
|
+
for (int i = finger_index - 2;
|
10140
|
+
i >= JSFunctionResultCache::kEntriesIndex;
|
10141
|
+
i -= 2) {
|
10142
|
+
o = cache->get(i);
|
10143
|
+
if (o == key) {
|
10144
|
+
cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i));
|
10145
|
+
return cache->get(i + 1);
|
10146
|
+
}
|
10147
|
+
}
|
10148
|
+
|
10149
|
+
const int size =
|
10150
|
+
Smi::cast(cache->get(JSFunctionResultCache::kCacheSizeIndex))->value();
|
10151
|
+
ASSERT(size <= cache->length());
|
10152
|
+
|
10153
|
+
for (int i = size - 2; i > finger_index; i -= 2) {
|
10154
|
+
o = cache->get(i);
|
10155
|
+
if (o == key) {
|
10156
|
+
cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i));
|
10157
|
+
return cache->get(i + 1);
|
10158
|
+
}
|
10159
|
+
}
|
10160
|
+
|
10161
|
+
// Cache miss. If we have spare room, put new data into it, otherwise
|
10162
|
+
// evict post finger entry which must be least recently used.
|
10163
|
+
if (size < cache->length()) {
|
10164
|
+
cache->set(JSFunctionResultCache::kCacheSizeIndex, Smi::FromInt(size + 2));
|
10165
|
+
return CacheMiss(cache, size, key);
|
10166
|
+
} else {
|
10167
|
+
int target_index = finger_index + JSFunctionResultCache::kEntrySize;
|
10168
|
+
if (target_index == cache->length()) {
|
10169
|
+
target_index = JSFunctionResultCache::kEntriesIndex;
|
10170
|
+
}
|
10171
|
+
return CacheMiss(cache, target_index, key);
|
10172
|
+
}
|
10173
|
+
}
|
10174
|
+
|
8075
10175
|
#ifdef DEBUG
|
8076
10176
|
// ListNatives is ONLY used by the fuzz-natives.js in debug mode
|
8077
10177
|
// Exclude the code in release mode.
|
@@ -8080,18 +10180,28 @@ static Object* Runtime_ListNatives(Arguments args) {
|
|
8080
10180
|
HandleScope scope;
|
8081
10181
|
Handle<JSArray> result = Factory::NewJSArray(0);
|
8082
10182
|
int index = 0;
|
10183
|
+
bool inline_runtime_functions = false;
|
8083
10184
|
#define ADD_ENTRY(Name, argc, ressize) \
|
8084
10185
|
{ \
|
8085
10186
|
HandleScope inner; \
|
8086
|
-
Handle<String> name
|
8087
|
-
|
8088
|
-
|
10187
|
+
Handle<String> name; \
|
10188
|
+
/* Inline runtime functions have an underscore in front of the name. */ \
|
10189
|
+
if (inline_runtime_functions) { \
|
10190
|
+
name = Factory::NewStringFromAscii( \
|
10191
|
+
Vector<const char>("_" #Name, StrLength("_" #Name))); \
|
10192
|
+
} else { \
|
10193
|
+
name = Factory::NewStringFromAscii( \
|
10194
|
+
Vector<const char>(#Name, StrLength(#Name))); \
|
10195
|
+
} \
|
8089
10196
|
Handle<JSArray> pair = Factory::NewJSArray(0); \
|
8090
10197
|
SetElement(pair, 0, name); \
|
8091
10198
|
SetElement(pair, 1, Handle<Smi>(Smi::FromInt(argc))); \
|
8092
10199
|
SetElement(result, index++, pair); \
|
8093
10200
|
}
|
10201
|
+
inline_runtime_functions = false;
|
8094
10202
|
RUNTIME_FUNCTION_LIST(ADD_ENTRY)
|
10203
|
+
inline_runtime_functions = true;
|
10204
|
+
INLINE_RUNTIME_FUNCTION_LIST(ADD_ENTRY)
|
8095
10205
|
#undef ADD_ENTRY
|
8096
10206
|
return *result;
|
8097
10207
|
}
|
@@ -8118,12 +10228,12 @@ static Object* Runtime_IS_VAR(Arguments args) {
|
|
8118
10228
|
// Implementation of Runtime
|
8119
10229
|
|
8120
10230
|
#define F(name, nargs, ressize) \
|
8121
|
-
{ #name,
|
10231
|
+
{ #name, FUNCTION_ADDR(Runtime_##name), nargs, \
|
8122
10232
|
static_cast<int>(Runtime::k##name), ressize },
|
8123
10233
|
|
8124
10234
|
static Runtime::Function Runtime_functions[] = {
|
8125
10235
|
RUNTIME_FUNCTION_LIST(F)
|
8126
|
-
{ NULL, NULL,
|
10236
|
+
{ NULL, NULL, 0, -1, 0 }
|
8127
10237
|
};
|
8128
10238
|
|
8129
10239
|
#undef F
|