| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +124 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2016-03-16  Keith Miller  <keith_miller@apple.com>
2
3
        [ES6] Add support for Symbol.isConcatSpreadable.
4
        https://bugs.webkit.org/show_bug.cgi?id=155351
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        This patch adds support for Symbol.isConcatSpreadable. In order to do so it was necessary to move the
9
        Array.prototype.concat function to JS. A number of different optimizations were needed to make such the move to
10
        a builtin performant. First, four new DFG intrinsics were added.
11
12
        1) IsArrayObject (I would have called it IsArray but we use the same name for an IndexingType): an intrinsic of
13
           the Array.isArray function.
14
        2) IsActualArray: checks the first child is a JSArray object.
15
        3) IsArrayConstructor: checks the first child is an instance of ArrayConstructor.
16
        4) ToObject: Attempts to convert the first child into an object.
17
18
        IsActualObject, IsActualArray, and ToObject can all be converted into constants in the abstract interpreter if
19
        we are able to prove that the first child is an Array or for ToObject an Object.
20
21
        In order to further improve the perfomance we also now cover more indexing types in our fast path memcpy
22
        code. Before we would only memcpy Arrays if they had the same indexing type and did not have Array storage and
23
        were not undecided. Now the memcpy code covers the following additional two cases: One array is undecided and
24
        the other is a non-array storage and the case where one array is Int32 and the other is contiguous (we map this
25
        into a contiguous array).
26
27
        This patch also adds a new fast path for concat with more than one array argument by using memcpy to append
28
        values onto the result array. This works roughly the same as the two array fast path using the same methodology
29
        to decide if we can memcpy the other butterfly into the result butterfly.
30
31
        Two new debugging tools are also added to the jsc cli. One is a version of the print function with a private
32
        name so it can be used for debugging builtins. The other is dumpDataLog, which takes a JSValue and runs our
33
        dataLog function on it.
34
35
        Finally, this patch add a new constructor to JSValueRegsTemporary that allows it to reuse the the registers of a
36
        JSValueOperand if the operand's use count is one.
37
38
        * JavaScriptCore.xcodeproj/project.pbxproj:
39
        * builtins/ArrayPrototype.js:
40
        (concatSlowPath):
41
        (concat):
42
        * bytecode/BytecodeIntrinsicRegistry.cpp:
43
        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
44
        * bytecode/BytecodeIntrinsicRegistry.h:
45
        * dfg/DFGAbstractInterpreterInlines.h:
46
        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
47
        * dfg/DFGByteCodeParser.cpp:
48
        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
49
        (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
50
        * dfg/DFGClobberize.h:
51
        (JSC::DFG::clobberize):
52
        * dfg/DFGDoesGC.cpp:
53
        (JSC::DFG::doesGC):
54
        * dfg/DFGFixupPhase.cpp:
55
        (JSC::DFG::FixupPhase::fixupNode):
56
        * dfg/DFGNodeType.h:
57
        * dfg/DFGOperations.cpp:
58
        * dfg/DFGOperations.h:
59
        * dfg/DFGPredictionPropagationPhase.cpp:
60
        (JSC::DFG::PredictionPropagationPhase::propagate):
61
        * dfg/DFGSafeToExecute.h:
62
        (JSC::DFG::safeToExecute):
63
        * dfg/DFGSpeculativeJIT.cpp:
64
        (JSC::DFG::GPRTemporary::adopt):
65
        (JSC::DFG::GPRTemporary::GPRTemporary):
66
        (JSC::DFG::GPRTemporary::operator=):
67
        (JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
68
        (JSC::DFG::SpeculativeJIT::compileIsActualArray):
69
        (JSC::DFG::SpeculativeJIT::compileIsArrayObject):
70
        (JSC::DFG::SpeculativeJIT::compileIsArrayConstructor):
71
        (JSC::DFG::SpeculativeJIT::compileToObject):
72
        * dfg/DFGSpeculativeJIT.h:
73
        (JSC::DFG::SpeculativeJIT::callOperation):
74
        * dfg/DFGSpeculativeJIT32_64.cpp:
75
        (JSC::DFG::SpeculativeJIT::compile):
76
        * dfg/DFGSpeculativeJIT64.cpp:
77
        (JSC::DFG::SpeculativeJIT::compile):
78
        * ftl/FTLCapabilities.cpp:
79
        (JSC::FTL::canCompile):
80
        * ftl/FTLLowerDFGToB3.cpp:
81
        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
82
        (JSC::FTL::DFG::LowerDFGToB3::compileToObject):
83
        (JSC::FTL::DFG::LowerDFGToB3::compileIsArrayObject):
84
        (JSC::FTL::DFG::LowerDFGToB3::compileIsActualArray):
85
        (JSC::FTL::DFG::LowerDFGToB3::compileIsArrayConstructor):
86
        (JSC::FTL::DFG::LowerDFGToB3::isArray):
87
        * jsc.cpp:
88
        (WTF::RuntimeArray::createStructure):
89
        (GlobalObject::finishCreation):
90
        (functionDataLogValue):
91
        * runtime/ArrayConstructor.cpp:
92
        (JSC::ArrayConstructor::finishCreation):
93
        (JSC::arrayConstructorPrivateFuncIsArrayConstructor):
94
        * runtime/ArrayConstructor.h:
95
        (JSC::isArrayConstructor):
96
        * runtime/ArrayPrototype.cpp:
97
        (JSC::ArrayPrototype::finishCreation):
98
        (JSC::arrayProtoPrivateFuncIsActualArray):
99
        (JSC::moveElements):
100
        (JSC::arrayProtoPrivateFuncConcatMemcpy):
101
        (JSC::arrayProtoPrivateFuncAppendMemcpy):
102
        * runtime/ArrayPrototype.h:
103
        (JSC::ArrayPrototype::createStructure):
104
        * runtime/CommonIdentifiers.h:
105
        * runtime/Intrinsic.h:
106
        * runtime/JSArray.cpp:
107
        (JSC::JSArray::appendMemcpy):
108
        * runtime/JSArray.h:
109
        (JSC::JSArray::createStructure):
110
        * runtime/JSArrayInlines.h: Added.
111
        (JSC::JSArray::memCopyWithIndexingType):
112
        (JSC::JSArray::canFastCopy):
113
        * runtime/JSGlobalObject.cpp:
114
        (JSC::JSGlobalObject::init):
115
        * runtime/JSType.h:
116
        * tests/es6.yaml:
117
        * tests/stress/array-concat-spread-object.js: Added.
118
        (arrayEq):
119
        * tests/stress/array-concat-spread-proxy.js: Added.
120
        (arrayEq):
121
        * tests/stress/array-concat-with-slow-indexingtypes.js: Added.
122
        (arrayEq):
123
        * tests/stress/array-species-config-array-constructor.js:
124
1
2016-03-16  Mark Lam  <mark.lam@apple.com>
125
2016-03-16  Mark Lam  <mark.lam@apple.com>
2
126
3
        Method names should not appear in the lexical scope of the method's body.
127
        Method names should not appear in the lexical scope of the method's body.
- a/Source/WebCore/ChangeLog +12 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2016-03-16  Keith Miller  <keith_miller@apple.com>
2
3
        [ES6] Add support for Symbol.isConcatSpreadable.
4
        https://bugs.webkit.org/show_bug.cgi?id=155351
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Makes runtime arrays have the new ArrayType
9
10
        * bridge/runtime_array.h:
11
        (JSC::RuntimeArray::createStructure):
12
1
2016-03-17  Antti Koivisto  <antti@apple.com>
13
2016-03-17  Antti Koivisto  <antti@apple.com>
2
14
3
        DataURLDecoder::DecodingResultDispatcher may get deleted outside main thread
15
        DataURLDecoder::DecodingResultDispatcher may get deleted outside main thread
- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +4 lines
Lines 1184-1189 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
1184
		5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
1184
		5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
1185
		5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
1185
		5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
1186
		53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
1186
		53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
1187
		539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
1187
		53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
1188
		53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
1188
		5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
1189
		5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
1189
		5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
1190
		5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
Lines 3313-3318 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
3313
		53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
3314
		53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
3314
		53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
3315
		53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
3315
		53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
3316
		53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
3317
		539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = "<group>"; };
3316
		53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = "<group>"; };
3318
		53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = "<group>"; };
3317
		53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = "<group>"; };
3319
		53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = "<group>"; };
3318
		593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; };
3320
		593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; };
Lines 5659-5664 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
5659
				70DC3E081B2DF2C700054299 /* IteratorPrototype.h */,
5661
				70DC3E081B2DF2C700054299 /* IteratorPrototype.h */,
5660
				93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
5662
				93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
5661
				938772E5038BFE19008635CE /* JSArray.h */,
5663
				938772E5038BFE19008635CE /* JSArray.h */,
5664
				539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */,
5662
				0F2B66B417B6B5AB00A7AE3F /* JSArrayBuffer.cpp */,
5665
				0F2B66B417B6B5AB00A7AE3F /* JSArrayBuffer.cpp */,
5663
				0F2B66B517B6B5AB00A7AE3F /* JSArrayBuffer.h */,
5666
				0F2B66B517B6B5AB00A7AE3F /* JSArrayBuffer.h */,
5664
				0F2B66B617B6B5AB00A7AE3F /* JSArrayBufferConstructor.cpp */,
5667
				0F2B66B617B6B5AB00A7AE3F /* JSArrayBufferConstructor.cpp */,
Lines 7501-7506 a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
7501
				0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
7504
				0FB7F39B15ED8E4600F167B2 /* IndexingType.h in Headers */,
7502
				0F0A75231B94BFA900110660 /* InferredType.h in Headers */,
7505
				0F0A75231B94BFA900110660 /* InferredType.h in Headers */,
7503
				0FFC92121B94D4DF0071DD66 /* InferredTypeTable.h in Headers */,
7506
				0FFC92121B94D4DF0071DD66 /* InferredTypeTable.h in Headers */,
7507
				539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */,
7504
				0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */,
7508
				0FF8BDEB1AD4CF7100DFE884 /* InferredValue.h in Headers */,
7505
				BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
7509
				BC18C4100E16F5CD00B34460 /* InitializeThreading.h in Headers */,
7506
				A513E5B8185B8BD3007E95AD /* InjectedScript.h in Headers */,
7510
				A513E5B8185B8BD3007E95AD /* InjectedScript.h in Headers */,
- a/Source/JavaScriptCore/builtins/ArrayPrototype.js +82 lines
Lines 646-651 function sort(comparator) a/Source/JavaScriptCore/builtins/ArrayPrototype.js_sec1
646
    return array;
646
    return array;
647
}
647
}
648
648
649
function concatSlowPath()
650
{
651
    "use strict";
652
653
    var argCount = arguments.length;
654
    var result = new this.species(0);
655
    var resultIsArray = @isActualArray(result);
656
657
    var currentElement = this.array;
658
    var resultIndex = 0;
659
    var argIndex = 0;
660
661
    do {
662
        var spreadable = @isObject(currentElement) && currentElement[@symbolIsConcatSpreadable];
663
        if ((spreadable == @undefined && @isArray(currentElement)) || spreadable) {
664
            var length = @toLength(currentElement.length);
665
            if (resultIsArray && @isActualArray(currentElement)
666
                && @appendMemcpy(result, currentElement)) {
667
668
                resultIndex += length;
669
            } else {
670
                if (length + resultIndex > @MAX_SAFE_INTEGER)
671
                    throw @TypeError("length exceeded the maximum safe integer");
672
                for (var i = 0; i < length; i++) {
673
                    if (i in currentElement)
674
                        @putByValDirect(result, resultIndex, currentElement[i]);
675
                    resultIndex++;
676
                }
677
            }
678
        } else {
679
            if (resultIndex >= @MAX_SAFE_INTEGER)
680
                throw @TypeError("length exceeded the maximum safe integer");
681
            @putByValDirect(result, resultIndex++, currentElement);
682
        }
683
        currentElement = arguments[argIndex];
684
    } while (argIndex++ < argCount);
685
686
    result.length = resultIndex;
687
    return result;
688
}
689
690
function concat(first)
691
{
692
    "use strict";
693
694
    var array = @Object(this);
695
696
    var constructor;
697
    if (@isArray(array)) {
698
        constructor = array.constructor;
699
        // We have this check so that if some array from a different global object
700
        // calls this map they don't get an array with the Array.prototype of the
701
        // other global object.
702
        if (@isArrayConstructor(constructor) && @Array !== constructor)
703
            constructor = @Array;
704
        if (@isObject(constructor)) {
705
            constructor = constructor[@symbolSpecies];
706
            if (constructor === null)
707
                constructor = @Array;
708
        }
709
    }
710
    if (constructor === @undefined)
711
        constructor = @Array;
712
713
    var result;
714
    if (arguments.length === 1
715
        && constructor === @Array
716
        && @isActualArray(array)
717
        && @isActualArray(first)
718
        // FIXME: these get_by_ids should be "in"s but using "in" here is a 10% regression.
719
        // https://bugs.webkit.org/show_bug.cgi?id=155590
720
        && array[@symbolIsConcatSpreadable] == @undefined
721
        && first[@symbolIsConcatSpreadable] == @undefined) {
722
723
        result = @concatMemcpy(array, first);
724
        if (result !== null)
725
            return result;
726
    }
727
728
    return @concatSlowPath.@apply({ array: array, species: constructor }, arguments);
729
}
730
649
function copyWithin(target, start /*, end */)
731
function copyWithin(target, start /*, end */)
650
{
732
{
651
    "use strict";
733
    "use strict";
- a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp +2 lines
Lines 47-55 BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry(VM& vm) a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp_sec1
47
    m_arrayIterationKindKey.set(m_vm, jsNumber(ArrayIterateKey));
47
    m_arrayIterationKindKey.set(m_vm, jsNumber(ArrayIterateKey));
48
    m_arrayIterationKindValue.set(m_vm, jsNumber(ArrayIterateValue));
48
    m_arrayIterationKindValue.set(m_vm, jsNumber(ArrayIterateValue));
49
    m_arrayIterationKindKeyValue.set(m_vm, jsNumber(ArrayIterateKeyValue));
49
    m_arrayIterationKindKeyValue.set(m_vm, jsNumber(ArrayIterateKeyValue));
50
    m_MAX_SAFE_INTEGER.set(m_vm, jsDoubleNumber(9007199254740991.0)); // 2 ^ 53 - 1
50
    m_promiseStatePending.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Pending)));
51
    m_promiseStatePending.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Pending)));
51
    m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Fulfilled)));
52
    m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Fulfilled)));
52
    m_promiseStateRejected.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected)));
53
    m_promiseStateRejected.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Rejected)));
54
    m_symbolIsConcatSpreadable.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->isConcatSpreadableSymbol.impl())));
53
    m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->iteratorSymbol.impl())));
55
    m_symbolIterator.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->iteratorSymbol.impl())));
54
    m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->searchSymbol.impl())));
56
    m_symbolSearch.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->searchSymbol.impl())));
55
    m_symbolSpecies.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->speciesSymbol.impl())));
57
    m_symbolSpecies.set(m_vm, Symbol::create(m_vm, static_cast<SymbolImpl&>(*m_vm.propertyNames->speciesSymbol.impl())));
- a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h +2 lines
Lines 49-57 class Identifier; a/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h_sec1
49
    macro(arrayIterationKindKey) \
49
    macro(arrayIterationKindKey) \
50
    macro(arrayIterationKindValue) \
50
    macro(arrayIterationKindValue) \
51
    macro(arrayIterationKindKeyValue) \
51
    macro(arrayIterationKindKeyValue) \
52
    macro(MAX_SAFE_INTEGER) \
52
    macro(promiseStatePending) \
53
    macro(promiseStatePending) \
53
    macro(promiseStateFulfilled) \
54
    macro(promiseStateFulfilled) \
54
    macro(promiseStateRejected) \
55
    macro(promiseStateRejected) \
56
    macro(symbolIsConcatSpreadable) \
55
    macro(symbolIterator) \
57
    macro(symbolIterator) \
56
    macro(symbolSearch) \
58
    macro(symbolSearch) \
57
    macro(symbolSpecies)
59
    macro(symbolSpecies)
- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h -2 / +44 lines
Lines 28-33 a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec1
28
28
29
#if ENABLE(DFG_JIT)
29
#if ENABLE(DFG_JIT)
30
30
31
#include "ArrayConstructor.h"
31
#include "DFGAbstractInterpreter.h"
32
#include "DFGAbstractInterpreter.h"
32
#include "GetByIdStatus.h"
33
#include "GetByIdStatus.h"
33
#include "GetterSetter.h"
34
#include "GetterSetter.h"
Lines 952-958 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec2
952
        }
953
        }
953
        break;
954
        break;
954
    }
955
    }
955
        
956
957
    case IsArrayObject:
958
    case IsActualArray:
959
    case IsArrayConstructor:
956
    case IsUndefined:
960
    case IsUndefined:
957
    case IsBoolean:
961
    case IsBoolean:
958
    case IsNumber:
962
    case IsNumber:
Lines 964-969 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec3
964
        if (child.value()) {
968
        if (child.value()) {
965
            bool constantWasSet = true;
969
            bool constantWasSet = true;
966
            switch (node->op()) {
970
            switch (node->op()) {
971
            case IsArrayObject:
972
                if (child.value().isObject() && child.value().getObject()->type() == ArrayType)
973
                    setConstant(node, jsBoolean(true));
974
                else {
975
                    // This could be a proxy and we don't handle that here.
976
                    constantWasSet = false;
977
                }
978
                break;
979
            case IsActualArray:
980
                setConstant(node, jsBoolean(child.value().isObject() && child.value().getObject()->type() == ArrayType));
981
                break;
982
            case IsArrayConstructor:
983
                setConstant(node, jsBoolean(child.value().isObject() && child.value().getObject()->classInfo() == ArrayConstructor::info()));
984
                break;
967
            case IsUndefined:
985
            case IsUndefined:
968
                setConstant(node, jsBoolean(
986
                setConstant(node, jsBoolean(
969
                    child.value().isCell()
987
                    child.value().isCell()
Lines 1026-1031 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec4
1026
        
1044
        
1027
        bool constantWasSet = false;
1045
        bool constantWasSet = false;
1028
        switch (node->op()) {
1046
        switch (node->op()) {
1047
        case IsActualArray:
1048
        case IsArrayObject:
1049
            if (!(child.m_type & ~SpecArray)) {
1050
                setConstant(node, jsBoolean(true));
1051
                constantWasSet = true;
1052
                break;
1053
            }
1054
1055
            break;
1029
        case IsUndefined:
1056
        case IsUndefined:
1030
            // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1057
            // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1031
            // https://bugs.webkit.org/show_bug.cgi?id=144456
1058
            // https://bugs.webkit.org/show_bug.cgi?id=144456
Lines 1779-1785 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h_sec5
1779
        ASSERT(node->structure());
1806
        ASSERT(node->structure());
1780
        forNode(node).set(m_graph, node->structure());
1807
        forNode(node).set(m_graph, node->structure());
1781
        break;
1808
        break;
1782
        
1809
1810
    case ToObject: {
1811
        AbstractValue& source = forNode(node->child1());
1812
        AbstractValue& destination = forNode(node);
1813
1814
        if (!(source.m_type & ~SpecObject)) {
1815
            m_state.setFoundConstants(true);
1816
            destination = source;
1817
            break;
1818
        }
1819
1820
        destination = source;
1821
        destination.merge(SpecObject);
1822
        break;
1823
    }
1824
1783
    case PhantomNewObject:
1825
    case PhantomNewObject:
1784
    case PhantomNewFunction:
1826
    case PhantomNewFunction:
1785
    case PhantomNewGeneratorFunction:
1827
    case PhantomNewGeneratorFunction:
- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp -1 / +38 lines
Lines 43-48 a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec1
43
#include "JSLexicalEnvironment.h"
43
#include "JSLexicalEnvironment.h"
44
#include "JSCInlines.h"
44
#include "JSCInlines.h"
45
#include "JSModuleEnvironment.h"
45
#include "JSModuleEnvironment.h"
46
#include "ObjectConstructor.h"
46
#include "PreciseJumpTargets.h"
47
#include "PreciseJumpTargets.h"
47
#include "PutByIdFlags.h"
48
#include "PutByIdFlags.h"
48
#include "PutByIdStatus.h"
49
#include "PutByIdStatus.h"
Lines 2119-2124 bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec2
2119
        }
2120
        }
2120
    }
2121
    }
2121
2122
2123
    case IsArrayIntrinsic: {
2124
        ASSERT(argumentCountIncludingThis == 2);
2125
2126
        insertChecks();
2127
        Node* isArray = addToGraph(IsArrayObject, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));
2128
        set(VirtualRegister(resultOperand), isArray);
2129
        return true;
2130
    }
2131
2132
    case IsActualArrayIntrinsic: {
2133
        ASSERT(argumentCountIncludingThis == 2);
2134
2135
        insertChecks();
2136
        Node* isArray = addToGraph(IsActualArray, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));
2137
        set(VirtualRegister(resultOperand), isArray);
2138
        return true;
2139
    }
2140
2141
    case IsArrayConstructorIntrinsic: {
2142
        ASSERT(argumentCountIncludingThis == 2);
2143
2144
        insertChecks();
2145
        Node* isArray = addToGraph(IsArrayConstructor, OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset)));
2146
        set(VirtualRegister(resultOperand), isArray);
2147
        return true;
2148
    }
2149
2122
    case CharCodeAtIntrinsic: {
2150
    case CharCodeAtIntrinsic: {
2123
        if (argumentCountIncludingThis != 2)
2151
        if (argumentCountIncludingThis != 2)
2124
            return false;
2152
            return false;
Lines 2491-2497 bool ByteCodeParser::handleConstantInternalFunction( a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec3
2491
        set(VirtualRegister(resultOperand), result);
2519
        set(VirtualRegister(resultOperand), result);
2492
        return true;
2520
        return true;
2493
    }
2521
    }
2494
    
2522
2523
    // FIXME: This should handle construction as well. https://bugs.webkit.org/show_bug.cgi?id=155591
2524
    if (function->classInfo() == ObjectConstructor::info() && kind == CodeForCall) {
2525
        insertChecks();
2526
2527
        Node* result = addToGraph(ToObject, get(virtualRegisterForArgument(1, registerOffset)));
2528
        set(VirtualRegister(resultOperand), result);
2529
        return true;
2530
    }
2531
2495
    for (unsigned typeIndex = 0; typeIndex < NUMBER_OF_TYPED_ARRAY_TYPES; ++typeIndex) {
2532
    for (unsigned typeIndex = 0; typeIndex < NUMBER_OF_TYPED_ARRAY_TYPES; ++typeIndex) {
2496
        bool result = handleTypedArrayConstructor(
2533
        bool result = handleTypedArrayConstructor(
2497
            resultOperand, function, registerOffset, argumentCountIncludingThis,
2534
            resultOperand, function, registerOffset, argumentCountIncludingThis,
- a/Source/JavaScriptCore/dfg/DFGClobberize.h -3 / +7 lines
Lines 142-147 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu a/Source/JavaScriptCore/dfg/DFGClobberize.h_sec1
142
    case GetGlobalObject:
142
    case GetGlobalObject:
143
    case StringCharCodeAt:
143
    case StringCharCodeAt:
144
    case CompareStrictEq:
144
    case CompareStrictEq:
145
    case IsActualArray:
146
    case IsArrayConstructor:
145
    case IsUndefined:
147
    case IsUndefined:
146
    case IsBoolean:
148
    case IsBoolean:
147
    case IsNumber:
149
    case IsNumber:
Lines 181-187 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu a/Source/JavaScriptCore/dfg/DFGClobberize.h_sec2
181
        read(MathDotRandomState);
183
        read(MathDotRandomState);
182
        write(MathDotRandomState);
184
        write(MathDotRandomState);
183
        return;
185
        return;
184
        
186
187
    case IsArrayObject:
185
    case HasGenericProperty:
188
    case HasGenericProperty:
186
    case HasStructureProperty:
189
    case HasStructureProperty:
187
    case GetEnumerableLength:
190
    case GetEnumerableLength:
Lines 323-329 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu a/Source/JavaScriptCore/dfg/DFGClobberize.h_sec3
323
    case ConstantStoragePointer:
326
    case ConstantStoragePointer:
324
        def(PureValue(node, node->storagePointer()));
327
        def(PureValue(node, node->storagePointer()));
325
        return;
328
        return;
326
         
329
327
    case MovHint:
330
    case MovHint:
328
    case ZombieHint:
331
    case ZombieHint:
329
    case ExitOK:
332
    case ExitOK:
Lines 398-403 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu a/Source/JavaScriptCore/dfg/DFGClobberize.h_sec4
398
        write(HeapObjectCount);
401
        write(HeapObjectCount);
399
        return;
402
        return;
400
403
404
    case ToObject:
401
    case ToThis:
405
    case ToThis:
402
    case CreateThis:
406
    case CreateThis:
403
        read(MiscFields);
407
        read(MiscFields);
Lines 419-425 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu a/Source/JavaScriptCore/dfg/DFGClobberize.h_sec5
419
        read(MiscFields);
423
        read(MiscFields);
420
        def(HeapLocation(IsFunctionLoc, MiscFields, node->child1()), LazyNode(node));
424
        def(HeapLocation(IsFunctionLoc, MiscFields, node->child1()), LazyNode(node));
421
        return;
425
        return;
422
        
426
423
    case GetById:
427
    case GetById:
424
    case GetByIdFlush:
428
    case GetByIdFlush:
425
    case PutById:
429
    case PutById:
- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp +4 lines
Lines 150-155 bool doesGC(Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp_sec1
150
    case OverridesHasInstance:
150
    case OverridesHasInstance:
151
    case InstanceOf:
151
    case InstanceOf:
152
    case InstanceOfCustom:
152
    case InstanceOfCustom:
153
    case IsArrayObject:
154
    case IsActualArray:
155
    case IsArrayConstructor:
153
    case IsUndefined:
156
    case IsUndefined:
154
    case IsBoolean:
157
    case IsBoolean:
155
    case IsNumber:
158
    case IsNumber:
Lines 239-244 bool doesGC(Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp_sec2
239
    case CreateDirectArguments:
242
    case CreateDirectArguments:
240
    case CreateScopedArguments:
243
    case CreateScopedArguments:
241
    case CreateClonedArguments:
244
    case CreateClonedArguments:
245
    case ToObject:
242
    case ToThis:
246
    case ToThis:
243
    case CreateThis:
247
    case CreateThis:
244
    case AllocatePropertyStorage:
248
    case AllocatePropertyStorage:
- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp -1 / +15 lines
Lines 1028-1034 private: a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp_sec1
1028
            fixEdge<Int32Use>(node->child1());
1028
            fixEdge<Int32Use>(node->child1());
1029
            break;
1029
            break;
1030
        }
1030
        }
1031
            
1031
1032
        case ToObject: {
1033
            if (node->child1()->shouldSpeculateObject()) {
1034
                fixEdge<ObjectUse>(node->child1());
1035
                node->convertToIdentity();
1036
                break;
1037
            }
1038
1039
            fixEdge<UntypedUse>(node->child1());
1040
            break;
1041
        }
1042
1032
        case ToThis: {
1043
        case ToThis: {
1033
            fixupToThis(node);
1044
            fixupToThis(node);
1034
            break;
1045
            break;
Lines 1489-1494 private: a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp_sec2
1489
        case Breakpoint:
1500
        case Breakpoint:
1490
        case ProfileWillCall:
1501
        case ProfileWillCall:
1491
        case ProfileDidCall:
1502
        case ProfileDidCall:
1503
        case IsArrayObject:
1504
        case IsActualArray:
1505
        case IsArrayConstructor:
1492
        case IsUndefined:
1506
        case IsUndefined:
1493
        case IsBoolean:
1507
        case IsBoolean:
1494
        case IsNumber:
1508
        case IsNumber:
- a/Source/JavaScriptCore/dfg/DFGNodeType.h +6 lines
Lines 291-296 namespace JSC { namespace DFG { a/Source/JavaScriptCore/dfg/DFGNodeType.h_sec1
291
    macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
291
    macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
292
    macro(InstanceOf, NodeResultBoolean) \
292
    macro(InstanceOf, NodeResultBoolean) \
293
    macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
293
    macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
294
    \
295
    /* I'd like to call this IsArray but then we get namespace problems with the indexing type name. Also, it is marked must generate because it can throw. */ \
296
    macro(IsArrayObject, NodeMustGenerate | NodeResultBoolean) \
297
    macro(IsActualArray, NodeResultBoolean) \
298
    macro(IsArrayConstructor, NodeResultBoolean) \
294
    macro(IsUndefined, NodeResultBoolean) \
299
    macro(IsUndefined, NodeResultBoolean) \
295
    macro(IsBoolean, NodeResultBoolean) \
300
    macro(IsBoolean, NodeResultBoolean) \
296
    macro(IsNumber, NodeResultBoolean) \
301
    macro(IsNumber, NodeResultBoolean) \
Lines 302-307 namespace JSC { namespace DFG { a/Source/JavaScriptCore/dfg/DFGNodeType.h_sec2
302
    macro(LogicalNot, NodeResultBoolean) \
307
    macro(LogicalNot, NodeResultBoolean) \
303
    macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
308
    macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
304
    macro(ToString, NodeResultJS | NodeMustGenerate) \
309
    macro(ToString, NodeResultJS | NodeMustGenerate) \
310
    macro(ToObject, NodeResultJS) \
305
    macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
311
    macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
306
    macro(NewStringObject, NodeResultJS) \
312
    macro(NewStringObject, NodeResultJS) \
307
    macro(MakeRope, NodeResultJS) \
313
    macro(MakeRope, NodeResultJS) \
- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +17 lines
Lines 26-31 a/Source/JavaScriptCore/dfg/DFGOperations.cpp_sec1
26
#include "config.h"
26
#include "config.h"
27
#include "DFGOperations.h"
27
#include "DFGOperations.h"
28
28
29
#include "ArrayConstructor.h"
29
#include "ButterflyInlines.h"
30
#include "ButterflyInlines.h"
30
#include "ClonedArguments.h"
31
#include "ClonedArguments.h"
31
#include "CodeBlock.h"
32
#include "CodeBlock.h"
Lines 697-702 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* a/Source/JavaScriptCore/dfg/DFGOperations.cpp_sec2
697
    return asRegExpObject(base)->test(exec, globalObject, input);
698
    return asRegExpObject(base)->test(exec, globalObject, input);
698
}
699
}
699
700
701
size_t JIT_OPERATION operationIsArrayConstructor(ExecState* exec, EncodedJSValue encodedTarget)
702
{
703
    VM& vm = exec->vm();
704
    NativeCallFrameTracer tracer(&vm, exec);
705
706
    return isArrayConstructor(JSValue::decode(encodedTarget));
707
}
708
709
size_t JIT_OPERATION operationIsArrayObject(ExecState* exec, EncodedJSValue encodedTarget)
710
{
711
    VM& vm = exec->vm();
712
    NativeCallFrameTracer tracer(&vm, exec);
713
714
    return isArray(exec, JSValue::decode(encodedTarget));
715
}
716
700
size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
717
size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
701
{
718
{
702
    VM* vm = &exec->vm();
719
    VM* vm = &exec->vm();
- a/Source/JavaScriptCore/dfg/DFGOperations.h +2 lines
Lines 110-115 size_t JIT_OPERATION operationRegExpTest(ExecState*, JSGlobalObject*, RegExpObje a/Source/JavaScriptCore/dfg/DFGOperations.h_sec1
110
size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
110
size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
111
size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
111
size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
112
size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
112
size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
113
size_t JIT_OPERATION operationIsArrayConstructor(ExecState*, EncodedJSValue);
114
size_t JIT_OPERATION operationIsArrayObject(ExecState*, EncodedJSValue);
113
JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*, EncodedJSValue);
115
JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*, EncodedJSValue);
114
JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState*, Structure*, int32_t length, int32_t minCapacity);
116
JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState*, Structure*, int32_t length, int32_t minCapacity);
115
JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
117
JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState*, InlineCallFrame*, JSFunction*, int32_t argumentCount);
- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp +8 lines
Lines 417-422 private: a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp_sec1
417
        case OverridesHasInstance:
417
        case OverridesHasInstance:
418
        case InstanceOf:
418
        case InstanceOf:
419
        case InstanceOfCustom:
419
        case InstanceOfCustom:
420
        case IsArrayObject:
421
        case IsActualArray:
422
        case IsArrayConstructor:
420
        case IsUndefined:
423
        case IsUndefined:
421
        case IsBoolean:
424
        case IsBoolean:
422
        case IsNumber:
425
        case IsNumber:
Lines 490-495 private: a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp_sec2
490
            break;
493
            break;
491
        }
494
        }
492
495
496
        case ToObject: {
497
            changed |= setPrediction(SpecObject);
498
            break;
499
        }
500
493
        case ToThis: {
501
        case ToThis: {
494
            // ToThis in methods for primitive types should speculate primitive types in strict mode.
502
            // ToThis in methods for primitive types should speculate primitive types in strict mode.
495
            ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
503
            ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h +4 lines
Lines 251-256 bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h_sec1
251
    case OverridesHasInstance:
251
    case OverridesHasInstance:
252
    case InstanceOf:
252
    case InstanceOf:
253
    case InstanceOfCustom:
253
    case InstanceOfCustom:
254
    case IsArrayObject:
255
    case IsActualArray:
256
    case IsArrayConstructor:
254
    case IsUndefined:
257
    case IsUndefined:
255
    case IsBoolean:
258
    case IsBoolean:
256
    case IsNumber:
259
    case IsNumber:
Lines 260-265 bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node) a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h_sec2
260
    case IsFunction:
263
    case IsFunction:
261
    case TypeOf:
264
    case TypeOf:
262
    case LogicalNot:
265
    case LogicalNot:
266
    case ToObject:
263
    case ToPrimitive:
267
    case ToPrimitive:
264
    case ToString:
268
    case ToString:
265
    case SetFunctionName:
269
    case SetFunctionName:
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp -12 / +141 lines
Lines 1132-1137 GPRTemporary::GPRTemporary( a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
1132
}
1132
}
1133
#endif // USE(JSVALUE32_64)
1133
#endif // USE(JSVALUE32_64)
1134
1134
1135
void GPRTemporary::adopt(GPRTemporary& other)
1136
{
1137
    ASSERT(!m_jit);
1138
    ASSERT(m_gpr == InvalidGPRReg);
1139
    ASSERT(other.m_jit);
1140
    ASSERT(other.m_gpr != InvalidGPRReg);
1141
    std::swap(m_jit, other.m_jit);
1142
    std::swap(m_gpr, other.m_gpr);
1143
}
1144
1145
GPRTemporary::GPRTemporary(GPRTemporary&& other)
1146
{
1147
    ASSERT(!m_jit);
1148
    ASSERT(m_gpr == InvalidGPRReg);
1149
    ASSERT(other.m_jit);
1150
    ASSERT(other.m_gpr != InvalidGPRReg);
1151
    std::swap(m_jit, other.m_jit);
1152
    std::swap(m_gpr, other.m_gpr);
1153
}
1154
1155
GPRTemporary& GPRTemporary::operator=(GPRTemporary&& other)
1156
{
1157
    ASSERT(!m_jit);
1158
    ASSERT(m_gpr == InvalidGPRReg);
1159
    ASSERT(other.m_jit);
1160
    ASSERT(other.m_gpr != InvalidGPRReg);
1161
    std::swap(m_jit, other.m_jit);
1162
    std::swap(m_gpr, other.m_gpr);
1163
    return *this;
1164
}
1165
1135
JSValueRegsTemporary::JSValueRegsTemporary() { }
1166
JSValueRegsTemporary::JSValueRegsTemporary() { }
1136
1167
1137
JSValueRegsTemporary::JSValueRegsTemporary(SpeculativeJIT* jit)
1168
JSValueRegsTemporary::JSValueRegsTemporary(SpeculativeJIT* jit)
Lines 1143-1148 JSValueRegsTemporary::JSValueRegsTemporary(SpeculativeJIT* jit) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec2
1143
#endif
1174
#endif
1144
{
1175
{
1145
}
1176
}
1177
#if USE(JSVALUE64)
1178
JSValueRegsTemporary::JSValueRegsTemporary(SpeculativeJIT* jit, JSValueOperand& op)
1179
    : m_gpr(jit, Reuse, op)
1180
{
1181
}
1182
#else
1183
JSValueRegsTemporary::JSValueRegsTemporary(SpeculativeJIT* jit, JSValueOperand& op)
1184
    : m_payloadGPR()
1185
    , m_tagGPR()
1186
{
1187
    if (jit->canReuse(op.node())) {
1188
        m_payloadGPR = GPRTemporary(jit, op.payloadGPR());
1189
        m_tagGPR = GPRTemporary(jit, op.tagGPR());
1190
    } else {
1191
        m_payloadGPR = GPRTemporary(jit);
1192
        m_tagGPR = GPRTemporary(jit);
1193
    }
1194
}
1195
#endif
1196
1146
1197
1147
JSValueRegsTemporary::~JSValueRegsTemporary() { }
1198
JSValueRegsTemporary::~JSValueRegsTemporary() { }
1148
1199
Lines 1155-1172 JSValueRegs JSValueRegsTemporary::regs() a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec3
1155
#endif
1206
#endif
1156
}
1207
}
1157
1208
1158
void GPRTemporary::adopt(GPRTemporary& other)
1159
{
1160
    ASSERT(!m_jit);
1161
    ASSERT(m_gpr == InvalidGPRReg);
1162
    ASSERT(other.m_jit);
1163
    ASSERT(other.m_gpr != InvalidGPRReg);
1164
    m_jit = other.m_jit;
1165
    m_gpr = other.m_gpr;
1166
    other.m_jit = 0;
1167
    other.m_gpr = InvalidGPRReg;
1168
}
1169
1170
FPRTemporary::FPRTemporary(SpeculativeJIT* jit)
1209
FPRTemporary::FPRTemporary(SpeculativeJIT* jit)
1171
    : m_jit(jit)
1210
    : m_jit(jit)
1172
    , m_fpr(InvalidFPRReg)
1211
    , m_fpr(InvalidFPRReg)
Lines 3248-3253 void SpeculativeJIT::compileInstanceOfCustom(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec4
3248
    unblessedBooleanResult(resultGPR, node);
3287
    unblessedBooleanResult(resultGPR, node);
3249
}
3288
}
3250
3289
3290
void SpeculativeJIT::compileIsActualArray(Node* node)
3291
{
3292
    JSValueOperand value(this, node->child1());
3293
    GPRFlushedCallResult result(this);
3294
3295
    JSValueRegs valueRegs = value.jsValueRegs();
3296
    GPRReg resultGPR = result.gpr();
3297
3298
    JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs);
3299
3300
    m_jit.compare8(JITCompiler::Equal,
3301
        JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()),
3302
        TrustedImm32(ArrayType),
3303
        resultGPR);
3304
    blessBoolean(resultGPR);
3305
    JITCompiler::Jump done = m_jit.jump();
3306
3307
    isNotCell.link(&m_jit);
3308
    moveFalseTo(resultGPR);
3309
3310
    done.link(&m_jit);
3311
    blessedBooleanResult(resultGPR, node);
3312
}
3313
3314
void SpeculativeJIT::compileIsArrayObject(Node* node)
3315
{
3316
    JSValueOperand value(this, node->child1());
3317
    GPRFlushedCallResult result(this);
3318
3319
    JSValueRegs valueRegs = value.jsValueRegs();
3320
    GPRReg resultGPR = result.gpr();
3321
3322
    JITCompiler::Jump isNotCell = m_jit.branchIfNotCell(valueRegs);
3323
3324
    JITCompiler::Jump notArray = m_jit.branch8(JITCompiler::NotEqual,
3325
        JITCompiler::Address(valueRegs.payloadGPR(), JSCell::typeInfoTypeOffset()),
3326
        TrustedImm32(ArrayType));
3327
    moveTrueTo(resultGPR);
3328
    JITCompiler::Jump isArrayObject = m_jit.jump();
3329
3330
    notArray.link(&m_jit);
3331
    flushRegisters();
3332
    callOperation(operationIsArrayObject, resultGPR, valueRegs);
3333
    blessBoolean(resultGPR);
3334
    JITCompiler::Jump isProxyObject = m_jit.jump();
3335
3336
    isNotCell.link(&m_jit);
3337
    moveFalseTo(resultGPR);
3338
3339
    isProxyObject.link(&m_jit);
3340
    isArrayObject.link(&m_jit);
3341
    blessedBooleanResult(resultGPR, node);
3342
}
3343
3344
void SpeculativeJIT::compileIsArrayConstructor(Node* node)
3345
{
3346
    JSValueOperand value(this, node->child1());
3347
    GPRFlushedCallResult result(this);
3348
3349
    JSValueRegs valueRegs = value.jsValueRegs();
3350
    GPRReg resultGPR = result.gpr();
3351
3352
    flushRegisters();
3353
    callOperation(operationIsArrayConstructor, resultGPR, valueRegs);
3354
    unblessedBooleanResult(resultGPR, node);
3355
}
3356
3357
void SpeculativeJIT::compileToObject(Node* node)
3358
{
3359
    RELEASE_ASSERT(node->child1().useKind() == UntypedUse);
3360
    JSValueOperand value(this, node->child1());
3361
    JSValueRegsTemporary result(this, value);
3362
3363
    JSValueRegs valueRegs = value.jsValueRegs();
3364
    JSValueRegs resultRegs = result.regs();
3365
3366
    MacroAssembler::JumpList slowCases;
3367
    slowCases.append(m_jit.branchIfNotCell(valueRegs));
3368
    slowCases.append(m_jit.branchIfNotObject(valueRegs.payloadGPR()));
3369
#if USE(JSVALUE64)
3370
    m_jit.move(valueRegs.gpr(), resultRegs.gpr());
3371
#else
3372
    m_jit.move(valueRegs.payloadGPR(), resultRegs.payloadGPR());
3373
    m_jit.move(valueRegs.tagGPR(), resultRegs.tagGPR());
3374
#endif
3375
3376
    addSlowPathGenerator(slowPathCall(slowCases, this, operationToObject, resultRegs, valueRegs));
3377
    jsValueResult(resultRegs, node);
3378
}
3379
3251
void SpeculativeJIT::compileArithAdd(Node* node)
3380
void SpeculativeJIT::compileArithAdd(Node* node)
3252
{
3381
{
3253
    switch (node->binaryUseKind()) {
3382
    switch (node->binaryUseKind()) {
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h -1 / +23 lines
Lines 729-734 public: a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec1
729
    void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
729
    void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
730
    void compileInstanceOf(Node*);
730
    void compileInstanceOf(Node*);
731
    void compileInstanceOfCustom(Node*);
731
    void compileInstanceOfCustom(Node*);
732
733
    void compileIsActualArray(Node*);
734
    void compileIsArrayConstructor(Node*);
735
    void compileIsArrayObject(Node*);
732
    
736
    
733
    void emitCall(Node*);
737
    void emitCall(Node*);
734
    
738
    
Lines 1432-1441 public: a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec2
1432
        m_jit.setupArgumentsWithExecState(arg1);
1436
        m_jit.setupArgumentsWithExecState(arg1);
1433
        return appendCallSetResult(operation, result);
1437
        return appendCallSetResult(operation, result);
1434
    }
1438
    }
1439
    JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
1440
    {
1441
        return callOperation(operation, result, arg1.gpr());
1442
    }
1435
    JITCompiler::Call callOperation(J_JITOperation_EJ operation, JSValueRegs result, JSValueRegs arg1)
1443
    JITCompiler::Call callOperation(J_JITOperation_EJ operation, JSValueRegs result, JSValueRegs arg1)
1436
    {
1444
    {
1437
        return callOperation(operation, result.payloadGPR(), arg1.payloadGPR());
1445
        return callOperation(operation, result.payloadGPR(), arg1.payloadGPR());
1438
    }
1446
    }
1447
    JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
1448
    {
1449
        return callOperation(operation, result, arg1.payloadGPR());
1450
    }
1439
    JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1451
    JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1440
    {
1452
    {
1441
        m_jit.setupArgumentsWithExecState(arg1);
1453
        m_jit.setupArgumentsWithExecState(arg1);
Lines 1839-1844 public: a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec3
1839
        return appendCallSetResult(operation, result);
1851
        return appendCallSetResult(operation, result);
1840
    }
1852
    }
1841
1853
1854
    JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
1855
    {
1856
        return callOperation(operation, result, arg1.tagGPR(), arg1.payloadGPR());
1857
    }
1858
1842
    JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1859
    JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1843
    {
1860
    {
1844
        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1861
        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
Lines 2412-2418 public: a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec4
2412
    void compileGetRegExpObjectLastIndex(Node*);
2429
    void compileGetRegExpObjectLastIndex(Node*);
2413
    void compileSetRegExpObjectLastIndex(Node*);
2430
    void compileSetRegExpObjectLastIndex(Node*);
2414
    void compileLazyJSConstant(Node*);
2431
    void compileLazyJSConstant(Node*);
2415
    
2432
2433
    void compileToObject(Node*);
2434
2416
    void moveTrueTo(GPRReg);
2435
    void moveTrueTo(GPRReg);
2417
    void moveFalseTo(GPRReg);
2436
    void moveFalseTo(GPRReg);
2418
    void blessBoolean(GPRReg);
2437
    void blessBoolean(GPRReg);
Lines 2940-2945 public: a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec5
2940
    GPRTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&, WhichValueWord);
2959
    GPRTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&, WhichValueWord);
2941
#endif
2960
#endif
2942
2961
2962
    GPRTemporary(GPRTemporary&&);
2963
    GPRTemporary& operator=(GPRTemporary&&);
2943
    void adopt(GPRTemporary&);
2964
    void adopt(GPRTemporary&);
2944
2965
2945
    ~GPRTemporary()
2966
    ~GPRTemporary()
Lines 2962-2967 class JSValueRegsTemporary { a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h_sec6
2962
public:
2983
public:
2963
    JSValueRegsTemporary();
2984
    JSValueRegsTemporary();
2964
    JSValueRegsTemporary(SpeculativeJIT*);
2985
    JSValueRegsTemporary(SpeculativeJIT*);
2986
    JSValueRegsTemporary(SpeculativeJIT*, JSValueOperand&);
2965
    ~JSValueRegsTemporary();
2987
    ~JSValueRegsTemporary();
2966
    
2988
    
2967
    JSValueRegs regs();
2989
    JSValueRegs regs();
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +20 lines
Lines 3807-3812 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp_sec1
3807
        cellResult(resultPayload.gpr(), node);
3807
        cellResult(resultPayload.gpr(), node);
3808
        break;
3808
        break;
3809
    }
3809
    }
3810
3811
    case ToObject: {
3812
        compileToObject(node);
3813
        break;
3814
    }
3810
        
3815
        
3811
    case ToThis: {
3816
    case ToThis: {
3812
        ASSERT(node->child1().useKind() == UntypedUse);
3817
        ASSERT(node->child1().useKind() == UntypedUse);
Lines 4458-4463 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp_sec2
4458
        break;
4463
        break;
4459
    }
4464
    }
4460
4465
4466
    case IsActualArray: {
4467
        compileIsActualArray(node);
4468
        break;
4469
    }
4470
4471
    case IsArrayObject: {
4472
        compileIsArrayObject(node);
4473
        break;
4474
    }
4475
4476
    case IsArrayConstructor: {
4477
        compileIsArrayConstructor(node);
4478
        break;
4479
    }
4480
4461
    case IsObject: {
4481
    case IsObject: {
4462
        JSValueOperand value(this, node->child1());
4482
        JSValueOperand value(this, node->child1());
4463
        GPRTemporary result(this, Reuse, value, TagWord);
4483
        GPRTemporary result(this, Reuse, value, TagWord);
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp -1 / +21 lines
Lines 3846-3852 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp_sec1
3846
        cellResult(result.gpr(), node);
3846
        cellResult(result.gpr(), node);
3847
        break;
3847
        break;
3848
    }
3848
    }
3849
        
3849
3850
    case ToObject: {
3851
        compileToObject(node);
3852
        break;
3853
    }
3854
3850
    case ToThis: {
3855
    case ToThis: {
3851
        ASSERT(node->child1().useKind() == UntypedUse);
3856
        ASSERT(node->child1().useKind() == UntypedUse);
3852
        JSValueOperand thisValue(this, node->child1());
3857
        JSValueOperand thisValue(this, node->child1());
Lines 4449-4454 void SpeculativeJIT::compile(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp_sec2
4449
        break;
4454
        break;
4450
    }
4455
    }
4451
4456
4457
    case IsActualArray: {
4458
        compileIsActualArray(node);
4459
        break;
4460
    }
4461
4462
    case IsArrayObject: {
4463
        compileIsArrayObject(node);
4464
        break;
4465
    }
4466
4467
    case IsArrayConstructor: {
4468
        compileIsArrayConstructor(node);
4469
        break;
4470
    }
4471
4452
    case IsObject: {
4472
    case IsObject: {
4453
        JSValueOperand value(this, node->child1());
4473
        JSValueOperand value(this, node->child1());
4454
        GPRTemporary result(this, Reuse, value);
4474
        GPRTemporary result(this, Reuse, value);
- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp +4 lines
Lines 161-166 inline CapabilityLevel canCompile(Node* node) a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp_sec1
161
    case GetScope:
161
    case GetScope:
162
    case GetCallee:
162
    case GetCallee:
163
    case GetArgumentCount:
163
    case GetArgumentCount:
164
    case ToObject:
164
    case ToString:
165
    case ToString:
165
    case CallStringConstructor:
166
    case CallStringConstructor:
166
    case MakeRope:
167
    case MakeRope:
Lines 174-179 inline CapabilityLevel canCompile(Node* node) a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp_sec2
174
    case Throw:
175
    case Throw:
175
    case ThrowReferenceError:
176
    case ThrowReferenceError:
176
    case Unreachable:
177
    case Unreachable:
178
    case IsArrayObject:
179
    case IsActualArray:
180
    case IsArrayConstructor:
177
    case IsUndefined:
181
    case IsUndefined:
178
    case IsBoolean:
182
    case IsBoolean:
179
    case IsNumber:
183
    case IsNumber:
- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp +92 lines
Lines 479-484 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec1
479
        case DFG::Check:
479
        case DFG::Check:
480
            compileNoOp();
480
            compileNoOp();
481
            break;
481
            break;
482
        case ToObject:
483
            compileToObject();
484
            break;
482
        case ToThis:
485
        case ToThis:
483
            compileToThis();
486
            compileToThis();
484
            break;
487
            break;
Lines 842-847 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec2
842
        case IsString:
845
        case IsString:
843
            compileIsString();
846
            compileIsString();
844
            break;
847
            break;
848
        case IsArrayObject:
849
            compileIsArrayObject();
850
            break;
851
        case IsActualArray:
852
            compileIsActualArray();
853
            break;
854
        case IsArrayConstructor:
855
            compileIsArrayConstructor();
856
            break;
845
        case IsObject:
857
        case IsObject:
846
            compileIsObject();
858
            compileIsObject();
847
            break;
859
            break;
Lines 1397-1402 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec3
1397
    {
1409
    {
1398
        DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1410
        DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1399
    }
1411
    }
1412
1413
    void compileToObject()
1414
    {
1415
        LValue value = lowJSValue(m_node->child1());
1416
1417
        LBasicBlock isCellCase = m_out.newBlock();
1418
        LBasicBlock slowCase = m_out.newBlock();
1419
        LBasicBlock continuation = m_out.newBlock();
1420
1421
        m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1422
1423
        LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1424
        ValueFromBlock fastResult = m_out.anchor(value);
1425
        m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1426
1427
        m_out.appendTo(slowCase, continuation);
1428
        ValueFromBlock slowResult = m_out.anchor(vmCall(m_out.int64, m_out.operation(operationToObject), m_callFrame, value));
1429
        m_out.jump(continuation);
1430
1431
        m_out.appendTo(continuation, lastNext);
1432
        setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
1433
    }
1400
    
1434
    
1401
    void compileToThis()
1435
    void compileToThis()
1402
    {
1436
    {
Lines 5692-5697 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec4
5692
        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
5726
        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
5693
    }
5727
    }
5694
5728
5729
    void compileIsArrayObject()
5730
    {
5731
        LValue value = lowJSValue(m_node->child1());
5732
5733
        LBasicBlock cellCase = m_out.newBlock();
5734
        LBasicBlock notArrayCase = m_out.newBlock();
5735
        LBasicBlock continuation = m_out.newBlock();
5736
5737
        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
5738
        m_out.branch(isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(continuation));
5739
5740
        LBasicBlock lastNext = m_out.appendTo(cellCase, notArrayCase);
5741
        ValueFromBlock arrayResult = m_out.anchor(m_out.booleanTrue);
5742
        m_out.branch(isArray(value, provenType(m_node->child1())), unsure(continuation), unsure(notArrayCase));
5743
5744
        m_out.appendTo(notArrayCase, continuation);
5745
        ValueFromBlock notArrayResult = m_out.anchor(vmCall(m_out.boolean, m_out.operation(operationIsArrayObject), m_callFrame, value));
5746
        m_out.jump(continuation);
5747
5748
        m_out.appendTo(continuation, lastNext);
5749
        setBoolean(m_out.phi(m_out.boolean, notCellResult, arrayResult, notArrayResult));
5750
    }
5751
5752
    void compileIsActualArray()
5753
    {
5754
        LValue value = lowJSValue(m_node->child1());
5755
5756
        LBasicBlock isCellCase = m_out.newBlock();
5757
        LBasicBlock continuation = m_out.newBlock();
5758
5759
        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
5760
        m_out.branch(
5761
            isCell(value, provenType(m_node->child1())), unsure(isCellCase), unsure(continuation));
5762
5763
        LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);
5764
        ValueFromBlock cellResult = m_out.anchor(isArray(value, provenType(m_node->child1())));
5765
        m_out.jump(continuation);
5766
5767
        m_out.appendTo(continuation, lastNext);
5768
        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
5769
    }
5770
5771
    void compileIsArrayConstructor()
5772
    {
5773
        LValue value = lowJSValue(m_node->child1());
5774
5775
        setBoolean(vmCall(m_out.boolean, m_out.operation(operationIsArrayConstructor), m_callFrame, value));
5776
    }
5777
5695
    void compileIsObject()
5778
    void compileIsObject()
5696
    {
5779
    {
5697
        LValue value = lowJSValue(m_node->child1());
5780
        LValue value = lowJSValue(m_node->child1());
Lines 9459-9464 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec5
9459
        
9542
        
9460
        jsValueToStrictInt52(edge, lowJSValue(edge, ManualOperandSpeculation));
9543
        jsValueToStrictInt52(edge, lowJSValue(edge, ManualOperandSpeculation));
9461
    }
9544
    }
9545
9546
    LValue isArray(LValue cell, SpeculatedType type = SpecFullTop)
9547
    {
9548
        if (LValue proven = isProvenValue(type & SpecCell, SpecArray))
9549
            return proven;
9550
        return m_out.equal(
9551
            m_out.load8ZeroExt32(cell, m_heaps.JSCell_typeInfoType),
9552
            m_out.constInt32(ArrayType));
9553
    }
9462
    
9554
    
9463
    LValue isObject(LValue cell, SpeculatedType type = SpecFullTop)
9555
    LValue isObject(LValue cell, SpeculatedType type = SpecFullTop)
9464
    {
9556
    {
- a/Source/JavaScriptCore/jsc.cpp -2 / +11 lines
Lines 437-443 public: a/Source/JavaScriptCore/jsc.cpp_sec1
437
437
438
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
438
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
439
    {
439
    {
440
        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
440
        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), ArrayClass);
441
    }
441
    }
442
442
443
protected:
443
protected:
Lines 558-563 static EncodedJSValue JSC_HOST_CALL functionGetHiddenValue(ExecState*); a/Source/JavaScriptCore/jsc.cpp_sec2
558
static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState*);
558
static EncodedJSValue JSC_HOST_CALL functionSetHiddenValue(ExecState*);
559
static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*);
559
static EncodedJSValue JSC_HOST_CALL functionPrint(ExecState*);
560
static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
560
static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*);
561
static EncodedJSValue JSC_HOST_CALL functionDataLogValue(ExecState*);
561
static EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState*);
562
static EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState*);
562
static EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState*);
563
static EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState*);
563
static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
564
static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*);
Lines 723-729 protected: a/Source/JavaScriptCore/jsc.cpp_sec3
723
    void finishCreation(VM& vm, const Vector<String>& arguments)
724
    void finishCreation(VM& vm, const Vector<String>& arguments)
724
    {
725
    {
725
        Base::finishCreation(vm);
726
        Base::finishCreation(vm);
726
        
727
728
        addFunction(vm, "dataLogValue", functionDataLogValue, 1);
727
        addFunction(vm, "debug", functionDebug, 1);
729
        addFunction(vm, "debug", functionDebug, 1);
728
        addFunction(vm, "describe", functionDescribe, 1);
730
        addFunction(vm, "describe", functionDescribe, 1);
729
        addFunction(vm, "describeArray", functionDescribeArray, 1);
731
        addFunction(vm, "describeArray", functionDescribeArray, 1);
Lines 821-826 protected: a/Source/JavaScriptCore/jsc.cpp_sec4
821
        }
823
        }
822
824
823
        putDirect(vm, Identifier::fromString(globalExec(), "console"), jsUndefined());
825
        putDirect(vm, Identifier::fromString(globalExec(), "console"), jsUndefined());
826
        putDirect(vm, vm.propertyNames->printPrivateName, JSFunction::create(vm, this, 1, vm.propertyNames->printPrivateName.string(), functionPrint));
824
    }
827
    }
825
828
826
    void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
829
    void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments)
Lines 1120-1125 EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec) a/Source/JavaScriptCore/jsc.cpp_sec5
1120
    return JSValue::encode(jsUndefined());
1123
    return JSValue::encode(jsUndefined());
1121
}
1124
}
1122
1125
1126
EncodedJSValue JSC_HOST_CALL functionDataLogValue(ExecState* exec)
1127
{
1128
    dataLog("value is: ", exec->argument(0), "\n");
1129
    return JSValue::encode(jsUndefined());
1130
}
1131
1123
EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState* exec)
1132
EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState* exec)
1124
{
1133
{
1125
    if (exec->argumentCount() < 1)
1134
    if (exec->argumentCount() < 1)
- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp -2 / +2 lines
Lines 68-74 void ArrayConstructor::finishCreation(VM& vm, JSGlobalObject* globalObject, Arra a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp_sec1
68
    putDirectWithoutTransition(vm, vm.propertyNames->prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
68
    putDirectWithoutTransition(vm, vm.propertyNames->prototype, arrayPrototype, DontEnum | DontDelete | ReadOnly);
69
    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
69
    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
70
    putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, Accessor | ReadOnly | DontEnum);
70
    putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, Accessor | ReadOnly | DontEnum);
71
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->isArray, arrayConstructorIsArray, DontEnum, 1);
71
    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->isArray, arrayConstructorIsArray, DontEnum, 1, IsArrayIntrinsic);
72
}
72
}
73
73
74
bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
74
bool ArrayConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
Lines 135-141 EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState* exec) a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp_sec2
135
135
136
EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArrayConstructor(ExecState* exec)
136
EncodedJSValue JSC_HOST_CALL arrayConstructorPrivateFuncIsArrayConstructor(ExecState* exec)
137
{
137
{
138
    return JSValue::encode(jsBoolean(jsDynamicCast<ArrayConstructor*>(exec->uncheckedArgument(0))));
138
    return JSValue::encode(jsBoolean(isArrayConstructor(exec->uncheckedArgument(0))));
139
}
139
}
140
140
141
} // namespace JSC
141
} // namespace JSC
- a/Source/JavaScriptCore/runtime/ArrayConstructor.h +8 lines
Lines 91-96 inline bool isArray(ExecState* exec, JSValue argumentValue) a/Source/JavaScriptCore/runtime/ArrayConstructor.h_sec1
91
    ASSERT_NOT_REACHED();
91
    ASSERT_NOT_REACHED();
92
}
92
}
93
93
94
inline bool isArrayConstructor(JSValue argumentValue)
95
    {
96
        if (!argumentValue.isObject())
97
            return false;
98
99
        return jsCast<JSObject*>(argumentValue)->classInfo() == ArrayConstructor::info();
100
    }
101
94
} // namespace JSC
102
} // namespace JSC
95
103
96
#endif // ArrayConstructor_h
104
#endif // ArrayConstructor_h
- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp -83 / +90 lines
Lines 34-39 a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp_sec1
34
#include "Error.h"
34
#include "Error.h"
35
#include "Interpreter.h"
35
#include "Interpreter.h"
36
#include "JIT.h"
36
#include "JIT.h"
37
#include "JSArrayInlines.h"
37
#include "JSArrayIterator.h"
38
#include "JSArrayIterator.h"
38
#include "JSCBuiltins.h"
39
#include "JSCBuiltins.h"
39
#include "JSCInlines.h"
40
#include "JSCInlines.h"
Lines 50-56 a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp_sec2
50
namespace JSC {
51
namespace JSC {
51
52
52
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
53
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*);
53
EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*);
54
EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*);
54
EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*);
55
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*);
55
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*);
56
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*);
56
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*);
Lines 93-99 void ArrayPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp_sec3
93
    
93
    
94
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, arrayProtoFuncToString, DontEnum, 0);
94
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toString, arrayProtoFuncToString, DontEnum, 0);
95
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0);
95
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->toLocaleString, arrayProtoFuncToLocaleString, DontEnum, 0);
96
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("concat", arrayProtoFuncConcat, DontEnum, 1);
96
    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("concat", arrayPrototypeConcatCodeGenerator, DontEnum);
97
    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("fill", arrayPrototypeFillCodeGenerator, DontEnum);
97
    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("fill", arrayPrototypeFillCodeGenerator, DontEnum);
98
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->join, arrayProtoFuncJoin, DontEnum, 1);
98
    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->join, arrayProtoFuncJoin, DontEnum, 1);
99
    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("pop", arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic);
99
    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("pop", arrayProtoFuncPop, DontEnum, 0, ArrayPopIntrinsic);
Lines 584-670 EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp_sec4
584
    return JSValue::encode(join(*exec, thisObject, separator->view(exec).get()));
584
    return JSValue::encode(join(*exec, thisObject, separator->view(exec).get()));
585
}
585
}
586
586
587
EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
588
{
589
    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
590
    unsigned argCount = exec->argumentCount();
591
    JSValue curArg = thisValue.toObject(exec);
592
    if (!curArg)
593
        return JSValue::encode(JSValue());
594
    Checked<unsigned, RecordOverflow> finalArraySize = 0;
595
596
    // We need to do species construction before geting the rest of the elements.
597
    std::pair<SpeciesConstructResult, JSObject*> speciesResult = speciesConstructArray(exec, curArg.getObject(), 0);
598
    if (speciesResult.first == SpeciesConstructResult::Exception)
599
        return JSValue::encode(jsUndefined());
600
601
    JSArray* currentArray = nullptr;
602
    JSArray* previousArray = nullptr;
603
    for (unsigned i = 0; ; ++i) {
604
        previousArray = currentArray;
605
        currentArray = jsDynamicCast<JSArray*>(curArg);
606
        if (currentArray) {
607
            // Can't use JSArray::length here because this might be a RuntimeArray!
608
            finalArraySize += getLength(exec, currentArray);
609
            if (exec->hadException())
610
                return JSValue::encode(jsUndefined());
611
        } else
612
            ++finalArraySize;
613
        if (i == argCount)
614
            break;
615
        curArg = exec->uncheckedArgument(i);
616
    }
617
618
    if (finalArraySize.hasOverflowed())
619
        return JSValue::encode(throwOutOfMemoryError(exec));
620
621
    if (speciesResult.first == SpeciesConstructResult::FastPath && argCount == 1 && previousArray && currentArray && finalArraySize.unsafeGet() < MIN_SPARSE_ARRAY_INDEX) {
622
        IndexingType type = JSArray::fastConcatType(exec->vm(), *previousArray, *currentArray);
623
        if (type != NonArray)
624
            return previousArray->fastConcatWith(*exec, *currentArray);
625
    }
626
627
    ASSERT(speciesResult.first != SpeciesConstructResult::Exception);
628
629
    JSObject* result;
630
    if (speciesResult.first == SpeciesConstructResult::CreatedObject)
631
        result = speciesResult.second;
632
    else {
633
        // We add the newTarget because the compiler gets confused between 0 being a number and a pointer.
634
        result = constructEmptyArray(exec, nullptr, 0, JSValue());
635
        if (exec->hadException())
636
            return JSValue::encode(jsUndefined());
637
    }
638
639
    curArg = thisValue.toObject(exec);
640
    ASSERT(!exec->hadException());
641
    unsigned n = 0;
642
    for (unsigned i = 0; ; ++i) {
643
        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
644
            // Can't use JSArray::length here because this might be a RuntimeArray!
645
            unsigned length = getLength(exec, currentArray);
646
            if (exec->hadException())
647
                return JSValue::encode(jsUndefined());
648
            for (unsigned k = 0; k < length; ++k) {
649
                JSValue v = getProperty(exec, currentArray, k);
650
                if (exec->hadException())
651
                    return JSValue::encode(jsUndefined());
652
                if (v)
653
                    result->putDirectIndex(exec, n, v);
654
                n++;
655
            }
656
        } else {
657
            result->putDirectIndex(exec, n, curArg);
658
            n++;
659
        }
660
        if (i == argCount)
661
            break;
662
        curArg = exec->uncheckedArgument(i);
663
    }
664
    setLength(exec, result, n);
665
    return JSValue::encode(result);
666
}
667
668
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
587
EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec)
669
{
588
{
670
    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
589
    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
Lines 1089-1094 EncodedJSValue JSC_HOST_CALL arrayProtoFuncKeys(ExecState* exec) a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp_sec5
1089
    return JSValue::encode(JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), ArrayIterateKey, thisObj));
1008
    return JSValue::encode(JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), ArrayIterateKey, thisObj));
1090
}
1009
}
1091
1010
1011
EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncIsActualArray(ExecState* exec)
1012
{
1013
    JSValue value = exec->uncheckedArgument(0);
1014
    if (value.isObject())
1015
        return JSValue::encode(jsBoolean(value.getObject()->type() == ArrayType));
1016
    return JSValue::encode(jsBoolean(false));
1017
}
1018
1019
inline bool moveElements(ExecState* exec, VM& vm, JSArray* target, unsigned targetOffset, JSArray* source, unsigned sourceLength)
1020
{
1021
    ASSERT(!hasAnyArrayStorage(source->indexingType()));
1022
    for (unsigned i = 0; i < sourceLength; ++i) {
1023
        // We can
1024
        JSValue value = getProperty(exec, source, i);
1025
        if (vm.exception())
1026
            return false;
1027
        if (value) {
1028
            target->putDirectIndex(exec, targetOffset + i, value);
1029
            if (vm.exception())
1030
                return false;
1031
        }
1032
    }
1033
    return true;
1034
}
1035
1036
EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState* exec)
1037
{
1038
    ASSERT(exec->argumentCount() == 2);
1039
    VM& vm = exec->vm();
1040
1041
    JSArray* firstArray = jsCast<JSArray*>(exec->uncheckedArgument(0));
1042
    JSArray* secondArray = jsCast<JSArray*>(exec->uncheckedArgument(1));
1043
1044
    if (!firstArray->canFastCopy(vm, secondArray))
1045
        return JSValue::encode(jsNull());
1046
1047
    Butterfly* firstButterfly = firstArray->butterfly();
1048
    Butterfly* secondButterfly = secondArray->butterfly();
1049
1050
    unsigned firstArraySize = firstButterfly->publicLength();
1051
    unsigned secondArraySize = secondButterfly->publicLength();
1052
1053
    IndexingType type = firstArray->memCopyWithIndexingType(secondArray->indexingType());
1054
    if (type == NonArray || firstArraySize + secondArraySize >= MIN_SPARSE_ARRAY_INDEX) {
1055
        JSArray* result = constructEmptyArray(exec, nullptr, firstArraySize + secondArraySize);
1056
        if (vm.exception())
1057
            return JSValue::encode(JSValue());
1058
1059
        if (!moveElements(exec, vm, result, 0, firstArray, firstArraySize)
1060
            || !moveElements(exec, vm, result, firstArraySize, secondArray, secondArraySize)) {
1061
            ASSERT(vm.exception());
1062
            return JSValue::encode(JSValue());
1063
        }
1064
1065
        return JSValue::encode(result);
1066
    }
1067
    ASSERT((type == ArrayWithUndecided) == !(firstArraySize + secondArraySize));
1068
1069
    Structure* resultStructure = exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(type);
1070
    JSArray* result = JSArray::tryCreateUninitialized(vm, resultStructure, firstArraySize + secondArraySize);
1071
    if (!result)
1072
        return JSValue::encode(throwOutOfMemoryError(exec));
1073
1074
    if (type == ArrayWithDouble) {
1075
        auto buffer = result->butterfly()->contiguousDouble().data();
1076
        memcpy(buffer, firstButterfly->contiguousDouble().data(), sizeof(JSValue) * firstArraySize);
1077
        memcpy(buffer + firstArraySize, secondButterfly->contiguousDouble().data(), sizeof(JSValue) * secondArraySize);
1078
    } else {
1079
        auto buffer = result->butterfly()->contiguous().data();
1080
        memcpy(buffer, firstButterfly->contiguous().data(), sizeof(JSValue) * firstArraySize);
1081
        memcpy(buffer + firstArraySize, secondButterfly->contiguous().data(), sizeof(JSValue) * secondArraySize);
1082
    }
1083
1084
    result->butterfly()->setPublicLength(firstArraySize + secondArraySize);
1085
    return JSValue::encode(result);
1086
}
1087
1088
EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncAppendMemcpy(ExecState* exec)
1089
{
1090
    ASSERT(exec->argumentCount() == 2);
1091
1092
    JSArray* resultArray = jsCast<JSArray*>(exec->uncheckedArgument(0));
1093
    JSArray* otherArray = jsCast<JSArray*>(exec->uncheckedArgument(1));
1094
1095
    return JSValue::encode(jsBoolean(resultArray->appendMemcpy(exec, exec->vm(), otherArray)));
1096
}
1097
1098
1092
// -------------------- ArrayPrototype.constructor Watchpoint ------------------
1099
// -------------------- ArrayPrototype.constructor Watchpoint ------------------
1093
1100
1094
class ArrayPrototypeAdaptiveInferredPropertyWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
1101
class ArrayPrototypeAdaptiveInferredPropertyWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
- a/Source/JavaScriptCore/runtime/ArrayPrototype.h -1 / +4 lines
Lines 41-47 public: a/Source/JavaScriptCore/runtime/ArrayPrototype.h_sec1
41
41
42
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
42
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
43
    {
43
    {
44
        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
44
        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), ArrayClass);
45
    }
45
    }
46
46
47
    void setConstructor(VM&, JSObject* constructorProperty, unsigned attributes);
47
    void setConstructor(VM&, JSObject* constructorProperty, unsigned attributes);
Lines 65-70 private: a/Source/JavaScriptCore/runtime/ArrayPrototype.h_sec2
65
65
66
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
66
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
67
EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*);
67
EncodedJSValue JSC_HOST_CALL arrayProtoFuncValues(ExecState*);
68
EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncIsActualArray(ExecState*);
69
EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState*);
70
EncodedJSValue JSC_HOST_CALL arrayProtoPrivateFuncAppendMemcpy(ExecState*);
68
71
69
} // namespace JSC
72
} // namespace JSC
70
73
- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h -1 / +6 lines
Lines 273-285 a/Source/JavaScriptCore/runtime/CommonIdentifiers.h_sec1
273
    macro(yield)
273
    macro(yield)
274
274
275
#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\
275
#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL_NOT_IMPLEMENTED_YET(macro)\
276
    macro(isConcatSpreadable) \
277
    macro(match) \
276
    macro(match) \
278
    macro(replace) \
277
    macro(replace) \
279
    macro(split) \
278
    macro(split) \
280
279
281
#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \
280
#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(macro) \
282
    macro(hasInstance) \
281
    macro(hasInstance) \
282
    macro(isConcatSpreadable) \
283
    macro(iterator) \
283
    macro(iterator) \
284
    macro(search) \
284
    macro(search) \
285
    macro(species) \
285
    macro(species) \
Lines 370-376 a/Source/JavaScriptCore/runtime/CommonIdentifiers.h_sec2
370
    macro(hasInstanceBoundFunction) \
370
    macro(hasInstanceBoundFunction) \
371
    macro(instanceOf) \
371
    macro(instanceOf) \
372
    macro(isArray) \
372
    macro(isArray) \
373
    macro(isActualArray) \
373
    macro(isArrayConstructor) \
374
    macro(isArrayConstructor) \
375
    macro(concatMemcpy) \
376
    macro(appendMemcpy) \
377
    macro(predictFinalLengthFromArgumunts) \
378
    macro(print) \
374
    macro(isSet) \
379
    macro(isSet) \
375
    macro(isMap) \
380
    macro(isMap) \
376
    macro(SetIterator) \
381
    macro(SetIterator) \
- a/Source/JavaScriptCore/runtime/Intrinsic.h +3 lines
Lines 56-61 enum Intrinsic { a/Source/JavaScriptCore/runtime/Intrinsic.h_sec1
56
    IMulIntrinsic,
56
    IMulIntrinsic,
57
    RandomIntrinsic,
57
    RandomIntrinsic,
58
    FRoundIntrinsic,
58
    FRoundIntrinsic,
59
    IsArrayIntrinsic,
60
    IsArrayConstructorIntrinsic,
61
    IsActualArrayIntrinsic,
59
62
60
    // Getter intrinsics.
63
    // Getter intrinsics.
61
    TypedArrayLengthIntrinsic,
64
    TypedArrayLengthIntrinsic,
- a/Source/JavaScriptCore/runtime/JSArray.cpp -32 / +30 lines
Lines 392-397 bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, boo a/Source/JavaScriptCore/runtime/JSArray.cpp_sec1
392
    return true;
392
    return true;
393
}
393
}
394
394
395
bool JSArray::appendMemcpy(ExecState* exec, VM& vm, JSC::JSArray* otherArray)
396
{
397
    if (!canFastCopy(vm, otherArray))
398
        return false;
399
400
    IndexingType type = indexingType();
401
    if (type != memCopyWithIndexingType(otherArray->indexingType()))
402
        return false;
403
404
    unsigned oldLength = length();
405
    unsigned otherLength = otherArray->length();
406
    unsigned newLength = oldLength + otherLength;
407
    if (newLength >= MIN_SPARSE_ARRAY_INDEX)
408
        return false;
409
410
    ensureLength(vm, newLength);
411
    ASSERT(type == indexingType());
412
    if (length() != newLength) {
413
        throwOutOfMemoryError(exec);
414
        return false;
415
    }
416
417
    if (type == ArrayWithDouble)
418
        memcpy(butterfly()->contiguousDouble().data() + oldLength, otherArray->butterfly()->contiguousDouble().data(), sizeof(JSValue) * otherLength);
419
    else
420
        memcpy(butterfly()->contiguous().data() + oldLength, otherArray->butterfly()->contiguous().data(), sizeof(JSValue) * otherLength);
421
422
    return true;
423
}
424
395
bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException)
425
bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException)
396
{
426
{
397
    Butterfly* butterfly = m_butterfly.get();
427
    Butterfly* butterfly = m_butterfly.get();
Lines 716-753 JSArray* JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count a/Source/JavaScriptCore/runtime/JSArray.cpp_sec2
716
    }
746
    }
717
}
747
}
718
748
719
EncodedJSValue JSArray::fastConcatWith(ExecState& exec, JSArray& otherArray)
720
{
721
    auto newArrayType = indexingType();
722
723
    VM& vm = exec.vm();
724
    ASSERT(newArrayType == fastConcatType(vm, *this, otherArray));
725
726
    unsigned thisArraySize = m_butterfly.get()->publicLength();
727
    unsigned otherArraySize = otherArray.m_butterfly.get()->publicLength();
728
    ASSERT(thisArraySize + otherArraySize < MIN_SPARSE_ARRAY_INDEX);
729
730
    Structure* resultStructure = exec.lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(newArrayType);
731
    JSArray* resultArray = JSArray::tryCreateUninitialized(vm, resultStructure, thisArraySize + otherArraySize);
732
    if (!resultArray)
733
        return JSValue::encode(throwOutOfMemoryError(&exec));
734
735
    auto& resultButterfly = *resultArray->butterfly();
736
    auto& otherButterfly = *otherArray.butterfly();
737
    if (newArrayType == ArrayWithDouble) {
738
        auto buffer = resultButterfly.contiguousDouble().data();
739
        memcpy(buffer, m_butterfly.get()->contiguousDouble().data(), sizeof(JSValue) * thisArraySize);
740
        memcpy(buffer + thisArraySize, otherButterfly.contiguousDouble().data(), sizeof(JSValue) * otherArraySize);
741
    } else {
742
        auto buffer = resultButterfly.contiguous().data();
743
        memcpy(buffer, m_butterfly.get()->contiguous().data(), sizeof(JSValue) * thisArraySize);
744
        memcpy(buffer + thisArraySize, otherButterfly.contiguous().data(), sizeof(JSValue) * otherArraySize);
745
    }
746
747
    resultButterfly.setPublicLength(thisArraySize + otherArraySize);
748
    return JSValue::encode(resultArray);
749
}
750
751
bool JSArray::shiftCountWithArrayStorage(VM& vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
749
bool JSArray::shiftCountWithArrayStorage(VM& vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
752
{
750
{
753
    unsigned oldLength = storage->length();
751
    unsigned oldLength = storage->length();
- a/Source/JavaScriptCore/runtime/JSArray.h -14 / +6 lines
Lines 23-28 a/Source/JavaScriptCore/runtime/JSArray.h_sec1
23
23
24
#include "ArrayConventions.h"
24
#include "ArrayConventions.h"
25
#include "ButterflyInlines.h"
25
#include "ButterflyInlines.h"
26
#include "JSCellInlines.h"
26
#include "JSObject.h"
27
#include "JSObject.h"
27
28
28
namespace JSC {
29
namespace JSC {
Lines 78-96 public: a/Source/JavaScriptCore/runtime/JSArray.h_sec2
78
79
79
    JSArray* fastSlice(ExecState&, unsigned startIndex, unsigned count);
80
    JSArray* fastSlice(ExecState&, unsigned startIndex, unsigned count);
80
81
81
    static IndexingType fastConcatType(VM& vm, JSArray& firstArray, JSArray& secondArray)
82
    bool canFastCopy(VM&, JSArray* otherArray);
82
    {
83
    // This function returns NonArray if the indexing types are not compatable for memcpying.
83
        IndexingType type = firstArray.indexingType();
84
    IndexingType memCopyWithIndexingType(IndexingType other);
84
        if (type != secondArray.indexingType())
85
    bool appendMemcpy(ExecState*, VM&, JSArray* otherArray);
85
            return NonArray;
86
        if (type != ArrayWithDouble && type != ArrayWithInt32 && type != ArrayWithContiguous)
87
            return NonArray;
88
        if (firstArray.structure(vm)->holesMustForwardToPrototype(vm)
89
            || secondArray.structure(vm)->holesMustForwardToPrototype(vm))
90
            return NonArray;
91
        return type;
92
    }
93
    EncodedJSValue fastConcatWith(ExecState&, JSArray&);
94
86
95
    enum ShiftCountMode {
87
    enum ShiftCountMode {
96
        // This form of shift hints that we're doing queueing. With this assumption in hand,
88
        // This form of shift hints that we're doing queueing. With this assumption in hand,
Lines 152-158 public: a/Source/JavaScriptCore/runtime/JSArray.h_sec3
152
144
153
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
145
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
154
    {
146
    {
155
        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), indexingType);
147
        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), indexingType);
156
    }
148
    }
157
        
149
        
158
protected:
150
protected:
- a/Source/JavaScriptCore/runtime/JSArrayInlines.h +73 lines
Line 0 a/Source/JavaScriptCore/runtime/JSArrayInlines.h_sec1
1
/*
2
 *  Copyright (C) 2016 Apple Inc. All rights reserved.
3
 *
4
 *  This library is free software; you can redistribute it and/or
5
 *  modify it under the terms of the GNU Lesser General Public
6
 *  License as published by the Free Software Foundation; either
7
 *  version 2 of the License, or (at your option) any later version.
8
 *
9
 *  This library is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 *  Lesser General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU Lesser General Public
15
 *  License along with this library; if not, write to the Free Software
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17
 *
18
 */
19
20
#ifndef JSArrayInlines_h
21
#define JSArrayInlines_h
22
23
#include "JSArray.h"
24
#include "JSCellInlines.h"
25
#include "Structure.h"
26
27
namespace JSC {
28
29
IndexingType JSArray::memCopyWithIndexingType(IndexingType other)
30
{
31
    IndexingType type = indexingType();
32
    if (!(type & IsArray && other & IsArray))
33
        return NonArray;
34
35
    if (hasAnyArrayStorage(type) || hasAnyArrayStorage(other))
36
        return NonArray;
37
38
    if (type == ArrayWithUndecided)
39
        return other;
40
41
    if (other == ArrayWithUndecided)
42
        return type;
43
44
    // We can memcpy an Int32 and a Contiguous into a Contiguous array since
45
    // both share the same memory layout for Int32 numbers.
46
    if ((type == ArrayWithInt32 || type == ArrayWithContiguous)
47
        && (other == ArrayWithInt32 || other == ArrayWithContiguous)) {
48
        if (other == ArrayWithContiguous)
49
            return other;
50
        return type;
51
    }
52
53
    if (type != other)
54
        return NonArray;
55
56
    return type;
57
}
58
59
bool JSArray::canFastCopy(VM& vm, JSArray* otherArray)
60
{
61
    if (hasAnyArrayStorage(this->indexingType()) || hasAnyArrayStorage(otherArray->indexingType()))
62
        return false;
63
    // FIXME: We should have a watchpoint for indexed properties on Array.prototype and Object.prototype
64
    // instead of walking the prototype chain. https://bugs.webkit.org/show_bug.cgi?id=155592
65
    if (otherArray->structure(vm)->holesMustForwardToPrototype(vm)
66
        || otherArray->structure(vm)->holesMustForwardToPrototype(vm))
67
        return false;
68
    return true;
69
}
70
71
} // namespace JSC
72
73
#endif /* JSArrayInlines_h */
- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp -3 / +11 lines
Lines 517-522 putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp_sec1
517
    putDirectWithoutTransition(vm, vm.propertyNames->Uint32ArrayPrivateName, m_typedArrays[toIndex(TypeUint32)].constructor.get(), DontEnum);
517
    putDirectWithoutTransition(vm, vm.propertyNames->Uint32ArrayPrivateName, m_typedArrays[toIndex(TypeUint32)].constructor.get(), DontEnum);
518
    putDirectWithoutTransition(vm, vm.propertyNames->Float32ArrayPrivateName, m_typedArrays[toIndex(TypeFloat32)].constructor.get(), DontEnum);
518
    putDirectWithoutTransition(vm, vm.propertyNames->Float32ArrayPrivateName, m_typedArrays[toIndex(TypeFloat32)].constructor.get(), DontEnum);
519
    putDirectWithoutTransition(vm, vm.propertyNames->Float64ArrayPrivateName, m_typedArrays[toIndex(TypeFloat64)].constructor.get(), DontEnum);
519
    putDirectWithoutTransition(vm, vm.propertyNames->Float64ArrayPrivateName, m_typedArrays[toIndex(TypeFloat64)].constructor.get(), DontEnum);
520
    putDirectWithoutTransition(vm, vm.propertyNames->ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly);
521
    putDirectWithoutTransition(vm, vm.propertyNames->ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly);
520
522
521
    m_moduleLoader.set(vm, this, ModuleLoaderObject::create(vm, this, ModuleLoaderObject::createStructure(vm, this, m_objectPrototype.get())));
523
    m_moduleLoader.set(vm, this, ModuleLoaderObject::create(vm, this, ModuleLoaderObject::createStructure(vm, this, m_objectPrototype.get())));
522
    if (Options::exposeInternalModuleLoader())
524
    if (Options::exposeInternalModuleLoader())
Lines 539-551 putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp_sec2
539
    JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction);
541
    JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction);
540
    JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf);
542
    JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf);
541
    JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime);
543
    JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime);
542
    JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor);
544
    JSFunction* privateFuncIsArrayConstructor = JSFunction::create(vm, this, 0, String(), arrayConstructorPrivateFuncIsArrayConstructor, IsArrayConstructorIntrinsic);
545
    JSFunction* privateFuncIsActualArray = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncIsActualArray, IsActualArrayIntrinsic);
546
    JSFunction* privateFuncConcatMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncConcatMemcpy);
547
    JSFunction* privateFuncAppendMemcpy = JSFunction::create(vm, this, 0, String(), arrayProtoPrivateFuncAppendMemcpy);
548
    JSFunction* privateFuncConcatSlowPath = JSFunction::createBuiltinFunction(vm, arrayPrototypeConcatSlowPathCodeGenerator(vm), this);
543
549
544
    GlobalPropertyInfo staticGlobals[] = {
550
    GlobalPropertyInfo staticGlobals[] = {
545
        GlobalPropertyInfo(vm.propertyNames->NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
551
        GlobalPropertyInfo(vm.propertyNames->NaN, jsNaN(), DontEnum | DontDelete | ReadOnly),
546
        GlobalPropertyInfo(vm.propertyNames->Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
552
        GlobalPropertyInfo(vm.propertyNames->Infinity, jsNumber(std::numeric_limits<double>::infinity()), DontEnum | DontDelete | ReadOnly),
547
        GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
553
        GlobalPropertyInfo(vm.propertyNames->undefinedKeyword, jsUndefined(), DontEnum | DontDelete | ReadOnly),
548
        GlobalPropertyInfo(vm.propertyNames->ObjectPrivateName, objectConstructor, DontEnum | DontDelete | ReadOnly),
549
        GlobalPropertyInfo(vm.propertyNames->ownEnumerablePropertyKeysPrivateName, JSFunction::create(vm, this, 0, String(), ownEnumerablePropertyKeys), DontEnum | DontDelete | ReadOnly),
554
        GlobalPropertyInfo(vm.propertyNames->ownEnumerablePropertyKeysPrivateName, JSFunction::create(vm, this, 0, String(), ownEnumerablePropertyKeys), DontEnum | DontDelete | ReadOnly),
550
        GlobalPropertyInfo(vm.propertyNames->getTemplateObjectPrivateName, privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
555
        GlobalPropertyInfo(vm.propertyNames->getTemplateObjectPrivateName, privateFuncGetTemplateObject, DontEnum | DontDelete | ReadOnly),
551
        GlobalPropertyInfo(vm.propertyNames->enqueueJobPrivateName, JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
556
        GlobalPropertyInfo(vm.propertyNames->enqueueJobPrivateName, JSFunction::create(vm, this, 0, String(), enqueueJob), DontEnum | DontDelete | ReadOnly),
Lines 558-564 putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp_sec3
558
        GlobalPropertyInfo(vm.propertyNames->hasInstanceBoundFunctionPrivateName, privateFuncHasInstanceBoundFunction, DontEnum | DontDelete | ReadOnly),
563
        GlobalPropertyInfo(vm.propertyNames->hasInstanceBoundFunctionPrivateName, privateFuncHasInstanceBoundFunction, DontEnum | DontDelete | ReadOnly),
559
        GlobalPropertyInfo(vm.propertyNames->instanceOfPrivateName, privateFuncInstanceOf, DontEnum | DontDelete | ReadOnly),
564
        GlobalPropertyInfo(vm.propertyNames->instanceOfPrivateName, privateFuncInstanceOf, DontEnum | DontDelete | ReadOnly),
560
        GlobalPropertyInfo(vm.propertyNames->BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly),
565
        GlobalPropertyInfo(vm.propertyNames->BuiltinLogPrivateName, builtinLog, DontEnum | DontDelete | ReadOnly),
561
        GlobalPropertyInfo(vm.propertyNames->ArrayPrivateName, arrayConstructor, DontEnum | DontDelete | ReadOnly),
562
        GlobalPropertyInfo(vm.propertyNames->NumberPrivateName, numberConstructor, DontEnum | DontDelete | ReadOnly),
566
        GlobalPropertyInfo(vm.propertyNames->NumberPrivateName, numberConstructor, DontEnum | DontDelete | ReadOnly),
563
        GlobalPropertyInfo(vm.propertyNames->RegExpPrivateName, m_regExpConstructor.get(), DontEnum | DontDelete | ReadOnly),
567
        GlobalPropertyInfo(vm.propertyNames->RegExpPrivateName, m_regExpConstructor.get(), DontEnum | DontDelete | ReadOnly),
564
        GlobalPropertyInfo(vm.propertyNames->StringPrivateName, stringConstructor, DontEnum | DontDelete | ReadOnly),
568
        GlobalPropertyInfo(vm.propertyNames->StringPrivateName, stringConstructor, DontEnum | DontDelete | ReadOnly),
Lines 576-581 putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp_sec4
576
        GlobalPropertyInfo(vm.propertyNames->isMapPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncIsMap), DontEnum | DontDelete | ReadOnly),
580
        GlobalPropertyInfo(vm.propertyNames->isMapPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncIsMap), DontEnum | DontDelete | ReadOnly),
577
        GlobalPropertyInfo(vm.propertyNames->isArrayPrivateName, arrayConstructor->getDirect(vm, vm.propertyNames->isArray), DontEnum | DontDelete | ReadOnly),
581
        GlobalPropertyInfo(vm.propertyNames->isArrayPrivateName, arrayConstructor->getDirect(vm, vm.propertyNames->isArray), DontEnum | DontDelete | ReadOnly),
578
        GlobalPropertyInfo(vm.propertyNames->isArrayConstructorPrivateName, privateFuncIsArrayConstructor, DontEnum | DontDelete | ReadOnly),
582
        GlobalPropertyInfo(vm.propertyNames->isArrayConstructorPrivateName, privateFuncIsArrayConstructor, DontEnum | DontDelete | ReadOnly),
583
        GlobalPropertyInfo(vm.propertyNames->isActualArrayPrivateName, privateFuncIsActualArray, DontEnum | DontDelete | ReadOnly),
584
        GlobalPropertyInfo(vm.propertyNames->concatMemcpyPrivateName, privateFuncConcatMemcpy, DontEnum | DontDelete | ReadOnly),
585
        GlobalPropertyInfo(vm.propertyNames->appendMemcpyPrivateName, privateFuncAppendMemcpy, DontEnum | DontDelete | ReadOnly),
586
        GlobalPropertyInfo(vm.propertyNames->builtinNames().concatSlowPathPrivateName(), privateFuncConcatSlowPath, DontEnum | DontDelete | ReadOnly),
579
        GlobalPropertyInfo(vm.propertyNames->MapIteratorPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncMapIterator), DontEnum | DontDelete | ReadOnly),
587
        GlobalPropertyInfo(vm.propertyNames->MapIteratorPrivateName, JSFunction::create(vm, this, 1, String(), privateFuncMapIterator), DontEnum | DontDelete | ReadOnly),
580
        GlobalPropertyInfo(vm.propertyNames->mapIteratorNextPrivateName, JSFunction::create(vm, this, 0, String(), privateFuncMapIteratorNext), DontEnum | DontDelete | ReadOnly),
588
        GlobalPropertyInfo(vm.propertyNames->mapIteratorNextPrivateName, JSFunction::create(vm, this, 0, String(), privateFuncMapIteratorNext), DontEnum | DontDelete | ReadOnly),
581
589
- a/Source/JavaScriptCore/runtime/JSType.h +1 lines
Lines 61-66 enum JSType : uint8_t { a/Source/JavaScriptCore/runtime/JSType.h_sec1
61
    PureForwardingProxyType,
61
    PureForwardingProxyType,
62
    ImpureProxyType,
62
    ImpureProxyType,
63
    WithScopeType,
63
    WithScopeType,
64
    ArrayType,
64
    DirectArgumentsType,
65
    DirectArgumentsType,
65
    ScopedArgumentsType,
66
    ScopedArgumentsType,
66
67
- a/Source/JavaScriptCore/tests/es6.yaml -2 / +2 lines
Lines 951-957 a/Source/JavaScriptCore/tests/es6.yaml_sec1
951
- path: es6/Proxy_internal_get_calls_Array.from.js
951
- path: es6/Proxy_internal_get_calls_Array.from.js
952
  cmd: runES6 :normal
952
  cmd: runES6 :normal
953
- path: es6/Proxy_internal_get_calls_Array.prototype.concat.js
953
- path: es6/Proxy_internal_get_calls_Array.prototype.concat.js
954
  cmd: runES6 :fail
954
  cmd: runES6 :normal
955
- path: es6/Proxy_internal_get_calls_Array.prototype.pop.js
955
- path: es6/Proxy_internal_get_calls_Array.prototype.pop.js
956
  cmd: runES6 :normal
956
  cmd: runES6 :normal
957
- path: es6/Proxy_internal_get_calls_Array.prototype.reverse.js
957
- path: es6/Proxy_internal_get_calls_Array.prototype.reverse.js
Lines 1189-1195 a/Source/JavaScriptCore/tests/es6.yaml_sec2
1189
- path: es6/well-known_symbols_Symbol.hasInstance.js
1189
- path: es6/well-known_symbols_Symbol.hasInstance.js
1190
  cmd: runES6 :normal
1190
  cmd: runES6 :normal
1191
- path: es6/well-known_symbols_Symbol.isConcatSpreadable.js
1191
- path: es6/well-known_symbols_Symbol.isConcatSpreadable.js
1192
  cmd: runES6 :fail
1192
  cmd: runES6 :normal
1193
- path: es6/well-known_symbols_Symbol.match.js
1193
- path: es6/well-known_symbols_Symbol.match.js
1194
  cmd: runES6 :fail
1194
  cmd: runES6 :fail
1195
- path: es6/well-known_symbols_Symbol.replace.js
1195
- path: es6/well-known_symbols_Symbol.replace.js
- a/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js +48 lines
Line 0 a/Source/JavaScriptCore/tests/stress/array-concat-spread-object.js_sec1
1
// This file tests is concat spreadable.
2
3
function arrayEq(a, b) {
4
    if (a.length !== b.length)
5
        return false;
6
    for (let i = 0; i < a.length; i++) {
7
        if (a[i] !== b[i])
8
            return false;
9
    }
10
    return true;
11
}
12
13
14
{
15
    let o = {0:1, 1:2, 2:3, length:3};
16
17
    // Test it works with proxies by default
18
    for (let i = 0; i < 100000; i++) {
19
        if (!arrayEq(Array.prototype.concat.call(o,o), [o,o]))
20
            throw "failed normally with an object"
21
    }
22
23
    // Test it works with spreadable true
24
    o[Symbol.isConcatSpreadable] = true;
25
    for (let i = 0; i < 100000; i++) {
26
        let result = Array.prototype.concat.call(o,o)
27
        if (!arrayEq(result, [1,2,3,1,2,3]))
28
            throw "failed with spread got: " + result;
29
    }
30
31
    // Test it works with many things
32
    o[Symbol.isConcatSpreadable] = true;
33
    let other = {}
34
    for (let i = 0; i < 100000; i++) {
35
        let result = Array.prototype.concat.call(o,o,true,[1,2],other)
36
        if (!arrayEq(result, [1,2,3,1,2,3,true,1,2,other]))
37
            throw "failed with spread got: " + result;
38
    }
39
40
    // Test it works with strings
41
    String.prototype[Symbol.isConcatSpreadable] = true;
42
    for (let i = 0; i < 100000; i++) {
43
        let result = Array.prototype.concat.call("hi","hi")
44
        // This is what the spec says is the correct answer... D:
45
        if (!arrayEq(result, ["h", "i", "hi"]))
46
            throw "failed with string got: " + result;
47
    }
48
}
- a/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js +30 lines
Line 0 a/Source/JavaScriptCore/tests/stress/array-concat-spread-proxy.js_sec1
1
// This file tests is concat spreadable.
2
3
function arrayEq(a, b) {
4
    if (a.length !== b.length)
5
        return false;
6
    for (let i = 0; i < a.length; i++) {
7
        if (a[i] !== b[i])
8
            return false;
9
    }
10
    return true;
11
}
12
13
14
{
15
    let array = [1,2,3];
16
    let p = new Proxy(array, { get : function(o, k) { return o[k]; } });
17
18
    // Test it works with proxies by default
19
    for (let i = 0; i < 100000; i++) {
20
        if (!arrayEq(Array.prototype.concat.call(p,p), [1,2,3,1,2,3]))
21
            throw "failed normally with a proxy"
22
    }
23
24
    // Test it works with spreadable false.
25
    p[Symbol.isConcatSpreadable] = false;
26
    for (let i = 0; i < 100000; i++) {
27
        if (!arrayEq(Array.prototype.concat.call(p,p), [p,p]))
28
            throw "failed with no spread"
29
    }
30
}
- a/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js +35 lines
Line 0 a/Source/JavaScriptCore/tests/stress/array-concat-with-slow-indexingtypes.js_sec1
1
function arrayEq(a, b) {
2
    if (a.length !== b.length)
3
        return false;
4
    for (let i = 0; i < a.length; i++) {
5
        if (a[i] !== b[i])
6
            return false;
7
    }
8
    return true;
9
}
10
11
12
{
13
14
    array = [1,2];
15
    Object.defineProperty(array, 2, { get: () => { return 1; } });
16
17
    for (let i = 0; i < 100000; i++) {
18
        if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
19
            throw "failed normally with a getter"
20
        if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
21
            throw "failed with undecided and a getter"
22
    }
23
24
    // Test with indexed types on prototype.
25
    array = [1,2];
26
    array.length = 3;
27
    Array.prototype[2] = 1;
28
29
    for (let i = 0; i < 100000; i++) {
30
        if (!arrayEq(Array.prototype.concat.call(array,array), [1,2,1,1,2,1]))
31
            throw "failed normally with an indexed prototype"
32
        if (!arrayEq(Array.prototype.concat.call([],array), [1,2,1]))
33
            throw "failed with undecided and an indexed prototype"
34
    }
35
}
- a/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js +3 lines
Lines 16-21 if (!(result instanceof A)) a/Source/JavaScriptCore/tests/stress/array-species-config-array-constructor.js_sec1
16
16
17
Object.defineProperty(Array, Symbol.species, { value: Int32Array, configurable: true });
17
Object.defineProperty(Array, Symbol.species, { value: Int32Array, configurable: true });
18
18
19
// We can't write to the length property on a typed array by default.
20
Object.defineProperty(Int32Array.prototype, "length", { value: 0, writable: true });
21
19
result = foo.concat([1]);
22
result = foo.concat([1]);
20
if (!(result instanceof Int32Array))
23
if (!(result instanceof Int32Array))
21
    throw "concat failed";
24
    throw "concat failed";
- a/Source/WebCore/bridge/runtime_array.h -1 / +1 lines
Lines 75-81 public: a/Source/WebCore/bridge/runtime_array.h_sec1
75
75
76
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
76
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
77
    {
77
    {
78
        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayClass);
78
        return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), ArrayClass);
79
    }
79
    }
80
80
81
protected:
81
protected:
- a/LayoutTests/ChangeLog +12 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2016-03-16  Keith Miller  <keith_miller@apple.com>
2
3
        [ES6] Add support for Symbol.isConcatSpreadable.
4
        https://bugs.webkit.org/show_bug.cgi?id=155351
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Fix tests for Symbol.isConcatSpreadable on the Symbol object.
9
10
        * js/Object-getOwnPropertyNames-expected.txt:
11
        * js/script-tests/Object-getOwnPropertyNames.js:
12
1
2016-03-17  Ryan Haddad  <ryanhaddad@apple.com>
13
2016-03-17  Ryan Haddad  <ryanhaddad@apple.com>
2
14
3
        Marking http/tests/security/aboutBlank/window-open-self-about-blank.html as flaky on ios-sim-debug
15
        Marking http/tests/security/aboutBlank/window-open-self-about-blank.html as flaky on ios-sim-debug
- a/LayoutTests/js/Object-getOwnPropertyNames-expected.txt -1 / +1 lines
Lines 61-67 PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype'] a/LayoutTests/js/Object-getOwnPropertyNames-expected.txt_sec1
61
PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
61
PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
62
PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
62
PASS getSortedOwnPropertyNames(Math) is ['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']
63
PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
63
PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
64
PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']
64
PASS getSortedOwnPropertyNames(Symbol) is ['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']
65
PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf']
65
PASS getSortedOwnPropertyNames(Symbol.prototype) is ['constructor', 'toString', 'valueOf']
66
PASS getSortedOwnPropertyNames(Map) is ['length', 'name', 'prototype']
66
PASS getSortedOwnPropertyNames(Map) is ['length', 'name', 'prototype']
67
PASS getSortedOwnPropertyNames(Map.prototype) is ['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']
67
PASS getSortedOwnPropertyNames(Map.prototype) is ['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']
- a/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js -1 / +1 lines
Lines 70-76 var expectedPropertyNamesSet = { a/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js_sec1
70
    "Error.prototype": "['constructor', 'message', 'name', 'toString']",
70
    "Error.prototype": "['constructor', 'message', 'name', 'toString']",
71
    "Math": "['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']",
71
    "Math": "['E','LN10','LN2','LOG10E','LOG2E','PI','SQRT1_2','SQRT2','abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','clz32','cos','cosh','exp','expm1','floor','fround','hypot','imul','log','log10','log1p','log2','max','min','pow','random','round','sign','sin','sinh','sqrt','tan','tanh','trunc']",
72
    "JSON": "['parse', 'stringify']",
72
    "JSON": "['parse', 'stringify']",
73
    "Symbol": "['for', 'hasInstance', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']",
73
    "Symbol": "['for', 'hasInstance', 'isConcatSpreadable', 'iterator', 'keyFor', 'length', 'name', 'prototype', 'search', 'species', 'toPrimitive', 'toStringTag', 'unscopables']",
74
    "Symbol.prototype": "['constructor', 'toString', 'valueOf']",
74
    "Symbol.prototype": "['constructor', 'toString', 'valueOf']",
75
    "Map": "['length', 'name', 'prototype']",
75
    "Map": "['length', 'name', 'prototype']",
76
    "Map.prototype": "['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']",
76
    "Map.prototype": "['clear', 'constructor', 'delete', 'entries', 'forEach', 'get', 'has', 'keys', 'set', 'size', 'values']",

Return to Bug 155351