| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +72 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2016-11-06  Caio Lima  <ticaiolima@gmail.com>
2
3
        [test262] Fixing mapped arguments object property test case
4
        https://bugs.webkit.org/show_bug.cgi?id=159398
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        This patch fixes ECMAScript test262 suite test cases of
9
        mapped arguments object with non-configurable and non-writable
10
        property. Also it is ensuring that arguments[i]
11
        cannot be deleted when argument "i" is {configurable: false}.
12
13
        The previous implementation is against to the specification for 2 reasons:
14
15
        1. Every argument in arguments object are {writable: true} by default
16
           (http://www.ecma-international.org/ecma-262/7.0/index.html#sec-createunmappedargumentsobject).
17
           It means that we have to stop mapping a defined property index
18
           if the new property descriptor contains writable (i.e writable is
19
           present) and its value is false (also check
20
           https://tc39.github.io/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc).
21
           Previous implementation considers {writable: false} if writable is
22
           not present.
23
24
        2. When a property is overriden, "delete" operation is always returning true. However
25
           delete operations should follow the specification.
26
27
        To fix the issues, we created an auxilary boolean array named
28
        m_modifiedArguments to store wich arguments[i] descriptor was changed
29
        from its default configuration. This modification was necessary because m_overrides
30
        was responsible to check it, using canAccessIndexQuickly, at the same time
31
        of keeping information about arguments mapping. The problem of this apporach was
32
        that we need to call overridesArgument(i) as soon as the ith argument's property
33
        descriptor was changed and it stops the argument's mapping as sideffect, producing
34
        wrong behavior.
35
        The second issue was solved with the isModifiedArgument(i). It is used
36
        to check if arguments[i] property descriptor is different from defaut
37
        and if it returns true, we fallback all operations (e.g.
38
        deleteProperty, deletePropertyByIndex, put, putByIndex, etc) to Base.
39
        This approach also fixed
40
        arguments-bizarre-behaviour-disable-enumerability test case.
41
42
        * dfg/DFGSpeculativeJIT.cpp:
43
        (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
44
        * ftl/FTLAbstractHeapRepository.h:
45
        * ftl/FTLLowerDFGToB3.cpp:
46
        (JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments):
47
        * runtime/DirectArguments.cpp:
48
        (JSC::DirectArguments::estimatedSize):
49
        (JSC::DirectArguments::visitChildren):
50
        * runtime/DirectArguments.h:
51
        (JSC::DirectArguments::initModifiedArgumentsIfNecessary):
52
        (JSC::DirectArguments::setModified):
53
        (JSC::DirectArguments::isModifiedArgument):
54
        (JSC::DirectArguments::offsetOfModifiedArguments):
55
        * runtime/GenericArguments.h:
56
        * runtime/GenericArgumentsInlines.h:
57
        (JSC::GenericArguments<Type>::getOwnPropertySlot):
58
        (JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
59
        (JSC::GenericArguments<Type>::deleteProperty):
60
        (JSC::GenericArguments<Type>::deletePropertyByIndex):
61
        (JSC::GenericArguments<Type>::defineOwnProperty):
62
        (JSC::GenericArguments<Type>::initModifiedArguments):
63
        (JSC::GenericArguments<Type>::initModifiedArgumentsIfNecessary):
64
        (JSC::GenericArguments<Type>::setModified):
65
        (JSC::GenericArguments<Type>::isModifiedArgument):
66
        * runtime/ScopedArguments.cpp:
67
        (JSC::ScopedArguments::visitChildren):
68
        * runtime/ScopedArguments.h:
69
        (JSC::ScopedArguments::initModifiedArgumentsIfNecessary):
70
        (JSC::ScopedArguments::setModified):
71
        (JSC::ScopedArguments::isModifiedArgument):
72
1
2016-11-05  Konstantin Tokarev  <annulen@yandex.ru>
73
2016-11-05  Konstantin Tokarev  <annulen@yandex.ru>
2
74
3
        Fixed compilation of LLInt with MinGW
75
        Fixed compilation of LLInt with MinGW
- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +3 lines
Lines 6683-6688 void SpeculativeJIT::compileCreateDirectArguments(Node* node) a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
6683
        
6683
        
6684
    m_jit.storePtr(
6684
    m_jit.storePtr(
6685
        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfOverrides()));
6685
        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfOverrides()));
6686
6687
    m_jit.storePtr(
6688
        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfModifiedArguments()));
6686
        
6689
        
6687
    if (lengthIsKnown) {
6690
    if (lengthIsKnown) {
6688
        addSlowPathGenerator(
6691
        addSlowPathGenerator(
- a/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h +1 lines
Lines 51-56 namespace JSC { namespace FTL { a/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h_sec1
51
    macro(DirectArguments_length, DirectArguments::offsetOfLength()) \
51
    macro(DirectArguments_length, DirectArguments::offsetOfLength()) \
52
    macro(DirectArguments_minCapacity, DirectArguments::offsetOfMinCapacity()) \
52
    macro(DirectArguments_minCapacity, DirectArguments::offsetOfMinCapacity()) \
53
    macro(DirectArguments_overrides, DirectArguments::offsetOfOverrides()) \
53
    macro(DirectArguments_overrides, DirectArguments::offsetOfOverrides()) \
54
    macro(DirectArguments_modifiedArguments, DirectArguments::offsetOfModifiedArguments()) \
54
    macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
55
    macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
55
    macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
56
    macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
56
    macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \
57
    macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \
- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp +1 lines
Lines 4068-4073 private: a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp_sec1
4068
        m_out.store32(length.value, fastObject, m_heaps.DirectArguments_length);
4068
        m_out.store32(length.value, fastObject, m_heaps.DirectArguments_length);
4069
        m_out.store32(m_out.constInt32(minCapacity), fastObject, m_heaps.DirectArguments_minCapacity);
4069
        m_out.store32(m_out.constInt32(minCapacity), fastObject, m_heaps.DirectArguments_minCapacity);
4070
        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_overrides);
4070
        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_overrides);
4071
        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_modifiedArguments);
4071
        
4072
        
4072
        ValueFromBlock fastResult = m_out.anchor(fastObject);
4073
        ValueFromBlock fastResult = m_out.anchor(fastObject);
4073
        m_out.jump(continuation);
4074
        m_out.jump(continuation);
- a/Source/JavaScriptCore/runtime/DirectArguments.cpp -2 / +5 lines
Lines 86-93 DirectArguments* DirectArguments::createByCopying(ExecState* exec) a/Source/JavaScriptCore/runtime/DirectArguments.cpp_sec1
86
size_t DirectArguments::estimatedSize(JSCell* cell)
86
size_t DirectArguments::estimatedSize(JSCell* cell)
87
{
87
{
88
    DirectArguments* thisObject = jsCast<DirectArguments*>(cell);
88
    DirectArguments* thisObject = jsCast<DirectArguments*>(cell);
89
    size_t overridesSize = thisObject->m_overrides ? thisObject->overridesSize() : 0;
89
    size_t overridesSize = thisObject->m_overrides ? thisObject->overridesSize() * sizeof(bool) : 0;
90
    return Base::estimatedSize(cell) + overridesSize;
90
    size_t modifiedArgumentsSize = thisObject->m_modifiedArguments ? thisObject->m_length * sizeof(bool) : 0;
91
    return Base::estimatedSize(cell) + overridesSize + modifiedArgumentsSize;
91
}
92
}
92
93
93
void DirectArguments::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
94
void DirectArguments::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
Lines 101-106 void DirectArguments::visitChildren(JSCell* thisCell, SlotVisitor& visitor) a/Source/JavaScriptCore/runtime/DirectArguments.cpp_sec2
101
    
102
    
102
    if (thisObject->m_overrides)
103
    if (thisObject->m_overrides)
103
        visitor.markAuxiliary(thisObject->m_overrides.get());
104
        visitor.markAuxiliary(thisObject->m_overrides.get());
105
    if (thisObject->m_modifiedArguments)
106
        visitor.markAuxiliary(thisObject->m_modifiedArguments.get());
104
}
107
}
105
108
106
Structure* DirectArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
109
Structure* DirectArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
- a/Source/JavaScriptCore/runtime/DirectArguments.h -1 / +17 lines
Lines 110-116 public: a/Source/JavaScriptCore/runtime/DirectArguments.h_sec1
110
    void overrideThings(VM&);
110
    void overrideThings(VM&);
111
    void overrideThingsIfNecessary(VM&);
111
    void overrideThingsIfNecessary(VM&);
112
    void overrideArgument(VM&, unsigned index);
112
    void overrideArgument(VM&, unsigned index);
113
    
113
114
    void initModifiedArgumentsIfNecessary(VM& vm)
115
    {
116
        GenericArguments<DirectArguments>::initModifiedArgumentsIfNecessary(vm, m_length);
117
    }
118
119
    void setModified(VM& vm, unsigned index)
120
    {
121
        GenericArguments<DirectArguments>::setModified(vm, index, m_length);
122
    }
123
124
    bool isModifiedArgument(unsigned index)
125
    {
126
        return GenericArguments<DirectArguments>::isModifiedArgument(index, m_length);
127
    }
128
114
    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
129
    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
115
130
116
    DECLARE_INFO;
131
    DECLARE_INFO;
Lines 121-126 public: a/Source/JavaScriptCore/runtime/DirectArguments.h_sec2
121
    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(DirectArguments, m_length); }
136
    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(DirectArguments, m_length); }
122
    static ptrdiff_t offsetOfMinCapacity() { return OBJECT_OFFSETOF(DirectArguments, m_minCapacity); }
137
    static ptrdiff_t offsetOfMinCapacity() { return OBJECT_OFFSETOF(DirectArguments, m_minCapacity); }
123
    static ptrdiff_t offsetOfOverrides() { return OBJECT_OFFSETOF(DirectArguments, m_overrides); }
138
    static ptrdiff_t offsetOfOverrides() { return OBJECT_OFFSETOF(DirectArguments, m_overrides); }
139
    static ptrdiff_t offsetOfModifiedArguments() { return OBJECT_OFFSETOF(DirectArguments, m_modifiedArguments); }
124
    
140
    
125
    static size_t storageOffset()
141
    static size_t storageOffset()
126
    {
142
    {
- a/Source/JavaScriptCore/runtime/GenericArguments.h +7 lines
Lines 52-58 protected: a/Source/JavaScriptCore/runtime/GenericArguments.h_sec1
52
    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
52
    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
53
    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
53
    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
54
    
54
    
55
    void initModifiedArguments(VM&, unsigned length);
56
    void initModifiedArgumentsIfNecessary(VM&, unsigned length);
57
    void setModified(VM&, unsigned index, unsigned length);
58
    bool isModifiedArgument(unsigned index, unsigned length);
59
55
    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
60
    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
61
    
62
    AuxiliaryBarrier<bool*> m_modifiedArguments;
56
};
63
};
57
64
58
} // namespace JSC
65
} // namespace JSC
- a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h -24 / +94 lines
Lines 52-63 bool GenericArguments<Type>::getOwnPropertySlot(JSObject* object, ExecState* exe a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h_sec1
52
    }
52
    }
53
    
53
    
54
    Optional<uint32_t> index = parseIndex(ident);
54
    Optional<uint32_t> index = parseIndex(ident);
55
    if (index && thisObject->canAccessIndexQuickly(index.value())) {
55
    if (index && !thisObject->isModifiedArgument(index.value()) && thisObject->canAccessIndexQuickly(index.value())) {
56
        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index.value()));
56
        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index.value()));
57
        return true;
57
        return true;
58
    }
58
    }
59
    
59
    
60
    return Base::getOwnPropertySlot(thisObject, exec, ident, slot);
60
    bool result = Base::getOwnPropertySlot(thisObject, exec, ident, slot);
61
    
62
    if (index && thisObject->canAccessIndexQuickly(index.value()))
63
        slot.setValue(thisObject, slot.attributes(), thisObject->getIndexQuickly(index.value()));
64
    
65
    return result;
61
}
66
}
62
67
63
template<typename Type>
68
template<typename Type>
Lines 65-76 bool GenericArguments<Type>::getOwnPropertySlotByIndex(JSObject* object, ExecSta a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h_sec2
65
{
70
{
66
    Type* thisObject = jsCast<Type*>(object);
71
    Type* thisObject = jsCast<Type*>(object);
67
    
72
    
68
    if (thisObject->canAccessIndexQuickly(index)) {
73
    if (!thisObject->isModifiedArgument(index) && thisObject->canAccessIndexQuickly(index)) {
69
        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
74
        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
70
        return true;
75
        return true;
71
    }
76
    }
72
    
77
    
73
    return Base::getOwnPropertySlotByIndex(object, exec, index, slot);
78
    bool result = Base::getOwnPropertySlotByIndex(object, exec, index, slot);
79
    
80
    if (thisObject->canAccessIndexQuickly(index))
81
        slot.setValue(thisObject, slot.attributes(), thisObject->getIndexQuickly(index));
82
    
83
    return result;
74
}
84
}
75
85
76
template<typename Type>
86
template<typename Type>
Lines 149-158 bool GenericArguments<Type>::deleteProperty(JSCell* cell, ExecState* exec, Prope a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h_sec3
149
            || ident == vm.propertyNames->callee
159
            || ident == vm.propertyNames->callee
150
            || ident == vm.propertyNames->iteratorSymbol))
160
            || ident == vm.propertyNames->iteratorSymbol))
151
        thisObject->overrideThings(vm);
161
        thisObject->overrideThings(vm);
152
    
162
153
    Optional<uint32_t> index = parseIndex(ident);
163
    Optional<uint32_t> index = parseIndex(ident);
154
    if (index && thisObject->canAccessIndexQuickly(index.value())) {
164
    if (index && !thisObject->isModifiedArgument(index.value()) && thisObject->canAccessIndexQuickly(index.value())) {
155
        thisObject->overrideArgument(vm, index.value());
165
        thisObject->overrideArgument(vm, index.value());
166
        thisObject->setModified(vm, index.value());
156
        return true;
167
        return true;
157
    }
168
    }
158
    
169
    
Lines 164-175 bool GenericArguments<Type>::deletePropertyByIndex(JSCell* cell, ExecState* exec a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h_sec4
164
{
175
{
165
    Type* thisObject = jsCast<Type*>(cell);
176
    Type* thisObject = jsCast<Type*>(cell);
166
    VM& vm = exec->vm();
177
    VM& vm = exec->vm();
167
    
178
168
    if (thisObject->canAccessIndexQuickly(index)) {
179
    if (!thisObject->isModifiedArgument(index) && thisObject->canAccessIndexQuickly(index)) {
169
        thisObject->overrideArgument(vm, index);
180
        thisObject->overrideArgument(vm, index);
181
        thisObject->setModified(vm, index);
170
        return true;
182
        return true;
171
    }
183
    }
172
    
184
173
    return Base::deletePropertyByIndex(cell, exec, index);
185
    return Base::deletePropertyByIndex(cell, exec, index);
174
}
186
}
175
187
Lines 185-221 bool GenericArguments<Type>::defineOwnProperty(JSObject* object, ExecState* exec a/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h_sec5
185
        thisObject->overrideThingsIfNecessary(vm);
197
        thisObject->overrideThingsIfNecessary(vm);
186
    else {
198
    else {
187
        Optional<uint32_t> optionalIndex = parseIndex(ident);
199
        Optional<uint32_t> optionalIndex = parseIndex(ident);
188
        if (optionalIndex && thisObject->canAccessIndexQuickly(optionalIndex.value())) {
200
201
        if (optionalIndex) {
189
            uint32_t index = optionalIndex.value();
202
            uint32_t index = optionalIndex.value();
190
            if (!descriptor.isAccessorDescriptor()) {
203
            if (!descriptor.isAccessorDescriptor() && thisObject->canAccessIndexQuickly(optionalIndex.value())) {
191
                // If the property is not deleted and we are using a non-accessor descriptor, then
204
                // If the property is not deleted and we are using a non-accessor descriptor, then
192
                // make sure that the aliased argument sees the value.
205
                // make sure that the aliased argument sees the value.
193
                if (descriptor.value())
206
                if (descriptor.value())
194
                    thisObject->setIndexQuickly(vm, index, descriptor.value());
207
                    thisObject->setIndexQuickly(vm, index, descriptor.value());
195
            
208
            
196
                // If the property is not deleted and we are using a non-accessor, writable
209
                // If the property is not deleted and we are using a non-accessor, writable,
197
                // descriptor, then we are done. The argument continues to be aliased. Note that we
210
                // configurable and enumerable descriptor and isn't modified, then we are done.
198
                // ignore the request to change enumerability. We appear to have always done so, in
211
                // The argument continues to be aliased.
199
                // cases where the argument was still aliased.
212
                if (descriptor.writable() && descriptor.configurable() && descriptor.enumerable() && !thisObject->isModifiedArgument(index))
200
                // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141952
201
                if (descriptor.writable())
202
                    return true;
213
                    return true;
214
                
215
                if (!thisObject->isModifiedArgument(index)) {
216
                    // If it is a new entry, we need to put direct to initialize argument[i] descriptor properly
217
                    JSValue value = thisObject->getIndexQuickly(index);
218
                    ASSERT(value);
219
                    object->putDirectMayBeIndex(exec, ident, value);
220
                    
221
                    thisObject->setModified(vm, index);
222
                }
203
            }
223
            }
224
        }
204
        
225
        
205
            // If the property is a non-deleted argument, then move it into the base object and
226
        if (optionalIndex && thisObject->canAccessIndexQuickly(optionalIndex.value())) {
206
            // then delete it.
227
            uint32_t index = optionalIndex.value();
207
            JSValue value = thisObject->getIndexQuickly(index);
228
            
208
            ASSERT(value);
229
            // Just overrride arguments (i.e stop mapping) if its descriptor contains {writable: false}.
209
            object->putDirectMayBeIndex(exec, ident, value);
230
            // Check https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject
210
            thisObject->overrideArgument(vm, index);
231
            // and https://tc39.github.io/ecma262/#sec-createmappedargumentsobject to verify that all data
232
            // property from arguments object are {writable: true, configurable: true, enumerable: true} by default
233
            if ((descriptor.writablePresent() && !descriptor.writable()) || descriptor.isAccessorDescriptor()) {
234
                if (!descriptor.isAccessorDescriptor()) {
235
                    JSValue value = thisObject->getIndexQuickly(index);
236
                    ASSERT(value);
237
                    object->putDirectMayBeIndex(exec, ident, value);
238
                }
239
                thisObject->overrideArgument(vm, index);
240
            }
211
        }
241
        }
212
    }
242
    }
213
    
243
214
    // Now just let the normal object machinery do its thing.
244
    // Now just let the normal object machinery do its thing.
215
    return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow);
245
    return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow);
216
}
246
}
217
247
218
template<typename Type>
248
template<typename Type>
249
void GenericArguments<Type>::initModifiedArguments(VM& vm, unsigned argsLength)
250
{
251
    RELEASE_ASSERT(!m_modifiedArguments);
252
253
    if (argsLength) {
254
        void* backingStore = vm.heap.tryAllocateAuxiliary(this, WTF::roundUpToMultipleOf<8>(argsLength));
255
        RELEASE_ASSERT(backingStore);
256
        bool* modifiedArguments = static_cast<bool*>(backingStore);
257
        m_modifiedArguments.set(vm, this, modifiedArguments);
258
        for (unsigned i = argsLength; i--;)
259
            modifiedArguments[i] = false;
260
    }
261
}
262
263
template<typename Type>
264
void GenericArguments<Type>::initModifiedArgumentsIfNecessary(VM& vm, unsigned argsLength)
265
{
266
    if (!m_modifiedArguments)
267
        initModifiedArguments(vm, argsLength);
268
}
269
270
template<typename Type>
271
void GenericArguments<Type>::setModified(VM& vm, unsigned index, unsigned length)
272
{
273
    initModifiedArgumentsIfNecessary(vm, length);
274
    if (index < length)
275
        m_modifiedArguments.get()[index] = true;
276
}
277
278
template<typename Type>
279
bool GenericArguments<Type>::isModifiedArgument(unsigned index, unsigned length)
280
{
281
    if (!m_modifiedArguments)
282
        return false;
283
    if (index < length)
284
        return m_modifiedArguments.get()[index];
285
    return false;
286
}
287
288
template<typename Type>
219
void GenericArguments<Type>::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
289
void GenericArguments<Type>::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
220
{
290
{
221
    VM& vm = exec->vm();
291
    VM& vm = exec->vm();
- a/Source/JavaScriptCore/runtime/PropertyDescriptor.h +1 lines
Lines 79-84 public: a/Source/JavaScriptCore/runtime/PropertyDescriptor.h_sec1
79
    bool getterPresent() const { return !!m_getter; }
79
    bool getterPresent() const { return !!m_getter; }
80
    bool equalTo(ExecState*, const PropertyDescriptor& other) const;
80
    bool equalTo(ExecState*, const PropertyDescriptor& other) const;
81
    bool attributesEqual(const PropertyDescriptor& other) const;
81
    bool attributesEqual(const PropertyDescriptor& other) const;
82
82
    unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
83
    unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
83
84
84
private:
85
private:
- a/Source/JavaScriptCore/runtime/ScopedArguments.cpp +3 lines
Lines 111-116 void ScopedArguments::visitChildren(JSCell* cell, SlotVisitor& visitor) a/Source/JavaScriptCore/runtime/ScopedArguments.cpp_sec1
111
        visitor.appendValues(
111
        visitor.appendValues(
112
            thisObject->overflowStorage(), thisObject->m_totalLength - thisObject->m_table->length());
112
            thisObject->overflowStorage(), thisObject->m_totalLength - thisObject->m_table->length());
113
    }
113
    }
114
115
    if (thisObject->m_modifiedArguments)
116
        visitor.markAuxiliary(thisObject->m_modifiedArguments.get());
114
}
117
}
115
118
116
Structure* ScopedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
119
Structure* ScopedArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
- a/Source/JavaScriptCore/runtime/ScopedArguments.h -1 / +16 lines
Lines 108-119 public: a/Source/JavaScriptCore/runtime/ScopedArguments.h_sec1
108
    {
108
    {
109
        return m_callee;
109
        return m_callee;
110
    }
110
    }
111
    
111
112
    bool overrodeThings() const { return m_overrodeThings; }
112
    bool overrodeThings() const { return m_overrodeThings; }
113
    void overrideThings(VM&);
113
    void overrideThings(VM&);
114
    void overrideThingsIfNecessary(VM&);
114
    void overrideThingsIfNecessary(VM&);
115
    void overrideArgument(VM&, uint32_t index);
115
    void overrideArgument(VM&, uint32_t index);
116
    
116
    
117
    void initModifiedArgumentsIfNecessary(VM& vm)
118
    {
119
        GenericArguments<ScopedArguments>::initModifiedArgumentsIfNecessary(vm, m_table->length());
120
    }
121
122
    void setModified(VM& vm, unsigned index)
123
    {
124
        GenericArguments<ScopedArguments>::setModified(vm, index, m_table->length());
125
    }
126
127
    bool isModifiedArgument(unsigned index)
128
    {
129
        return GenericArguments<ScopedArguments>::isModifiedArgument(index, m_table->length());
130
    }
131
117
    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
132
    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
118
133
119
    DECLARE_INFO;
134
    DECLARE_INFO;
- a/JSTests/ChangeLog +19 lines
Lines 1-3 a/JSTests/ChangeLog_sec1
1
2016-11-06  Caio Lima  <ticaiolima@gmail.com>
2
3
        [test262] Fixing mapped arguments object property test case
4
        https://bugs.webkit.org/show_bug.cgi?id=159398
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * stress/arguments-bizarre-behaviour-disable-enumerability.js: Fixed
9
        bizarre behavior.
10
        * stress/arguments-define-property.js: Added.
11
        (assert):
12
        (testProperties):
13
        * stress/arguments-non-configurable.js: Added.
14
        (assert):
15
        (tryChangeNonConfigurableDescriptor):
16
        (set tryChangeNonConfigurableDescriptor):
17
        (tryChangeWritableOfNonConfigurableDescriptor):
18
        * test262.yaml:
19
1
2016-11-04  Mark Lam  <mark.lam@apple.com>
20
2016-11-04  Mark Lam  <mark.lam@apple.com>
2
21
3
        Error description code should be able to handle Symbol values.
22
        Error description code should be able to handle Symbol values.
- a/JSTests/stress/arguments-bizarre-behaviour-disable-enumerability.js -3 / +1 lines
Lines 24-30 if (array.join(",") != "0") a/JSTests/stress/arguments-bizarre-behaviour-disable-enumerability.js_sec1
24
if (Object.keys(result[2]).join(",") != "0")
24
if (Object.keys(result[2]).join(",") != "0")
25
    throw new Error();
25
    throw new Error();
26
26
27
// FIXME: This is totally weird!
27
if (Object.getOwnPropertyDescriptor(result[2], 0).enumerable === true)
28
// https://bugs.webkit.org/show_bug.cgi?id=141952
29
if (Object.getOwnPropertyDescriptor(result[2], 0).enumerable !== true)
30
    throw new Error();
28
    throw new Error();
- a/JSTests/stress/arguments-define-property.js +35 lines
Line 0 a/JSTests/stress/arguments-define-property.js_sec1
1
function assert(a) {
2
    if (!a)
3
        throw Error("Bad assertion!");
4
}
5
6
function testProperties(o, initProperty, testProperty, shouldThrow) {
7
    Object.defineProperty(arguments, 0, initProperty);
8
9
    if (shouldThrow) {
10
        try {
11
            Object.defineProperty(arguments, 0, testProperty);
12
            assert(false);
13
        } catch(e) {
14
            assert(e instanceof TypeError);
15
        }
16
    } else {
17
        assert(Object.defineProperty(arguments, 0, testProperty));
18
    }
19
    
20
}
21
22
testProperties("foo", {configurable: false}, {writable: true}, false);
23
testProperties("foo", {configurable: false}, {configurable: true}, true);
24
testProperties("foo", {configurable: false, enumareble: true}, {enumerable: false}, true);
25
testProperties("foo", {configurable: false, writable: false}, {writable: false}, false);
26
testProperties("foo", {configurable: false, writable: false}, {writable: true}, true);
27
testProperties("foo", {configurable: false, writable: false, value: 50}, {value: 30}, true);
28
testProperties("foo", {configurable: false, writable: false, value: 30}, {value: 30}, false);
29
testProperties("foo", {configurable: false, get: () => {return 0}}, {get: () => {return 10}}, true);
30
let getterFoo = () => {return 0};
31
testProperties("foo", {configurable: false, get: getterFoo}, {get: getterFoo}, false);
32
testProperties("foo", {configurable: false, set: (x) => {return 0}}, {get: (x) => {return 10}}, true);
33
let setterFoo = (x) => {return 0};
34
testProperties("foo", {configurable: false, set: setterFoo}, {set: setterFoo}, false);
35
- a/JSTests/stress/arguments-non-configurable.js +27 lines
Line 0 a/JSTests/stress/arguments-non-configurable.js_sec1
1
function assert(a) {
2
    if (!a)
3
        throw Error("Bad assertion!");
4
}
5
6
function tryChangeNonConfigurableDescriptor(x) {
7
    Object.defineProperty(arguments, 0, {configurable: false});
8
    try {
9
        Object.defineProperty(arguments, 0, x);
10
        assert(false);
11
    } catch(e) {
12
        assert(e instanceof TypeError);
13
    }
14
}
15
16
tryChangeNonConfigurableDescriptor({get: () => {return 50;} });
17
tryChangeNonConfigurableDescriptor({set: (x) => {}});
18
tryChangeNonConfigurableDescriptor({writable: true, enumerable: false});
19
20
function tryChangeWritableOfNonConfigurableDescriptor(x) {
21
    Object.defineProperty(arguments, 0, {configurable: false});
22
    Object.defineProperty(arguments, 0, {writable: true});
23
    assert(Object.defineProperty(arguments, 0, {writable: false}));
24
}
25
26
tryChangeWritableOfNonConfigurableDescriptor("foo");
27
- a/JSTests/test262.yaml -12 / +12 lines
Lines 51364-51400 a/JSTests/test262.yaml_sec1
51364
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-1.js
51364
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-1.js
51365
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51365
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51366
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-2.js
51366
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-2.js
51367
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51367
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51368
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-3.js
51368
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-3.js
51369
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51369
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51370
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-4.js
51370
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-4.js
51371
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51371
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51372
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-1.js
51372
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-1.js
51373
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51373
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51374
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-2.js
51374
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-2.js
51375
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51375
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51376
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-3.js
51376
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-3.js
51377
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51377
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51378
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-4.js
51378
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-4.js
51379
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51379
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51380
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-1.js
51380
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-1.js
51381
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51381
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51382
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-2.js
51382
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-2.js
51383
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51383
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51384
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-3.js
51384
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-3.js
51385
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51385
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51386
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-4.js
51386
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-4.js
51387
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51387
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51388
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-5.js
51388
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-5.js
51389
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51389
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51390
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-1.js
51390
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-1.js
51391
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51391
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51392
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-2.js
51392
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-2.js
51393
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51393
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51394
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-3.js
51394
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-3.js
51395
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51395
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51396
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-4.js
51396
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-4.js
51397
  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51397
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51398
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonwritable-nonconfigurable-1.js
51398
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonwritable-nonconfigurable-1.js
51399
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51399
  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
51400
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonwritable-nonconfigurable-2.js
51400
- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonwritable-nonconfigurable-2.js

Return to Bug 159398