| Differences between
and this patch
- Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp -7 / +20 lines
Lines 116-122 ParserError BytecodeGenerator::generate( Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec1
116
    m_codeBlock->shrinkToFit();
116
    m_codeBlock->shrinkToFit();
117
117
118
    if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
118
    if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
119
        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneCapturedNames(*m_codeBlock->vm()));
119
        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneIgnoringStack(*m_codeBlock->vm()));
120
120
121
    if (m_expressionTooDeep)
121
    if (m_expressionTooDeep)
122
        return ParserError(ParserError::OutOfMemory);
122
        return ParserError(ParserError::OutOfMemory);
Lines 124-140 ParserError BytecodeGenerator::generate( Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec2
124
}
124
}
125
125
126
bool BytecodeGenerator::addVar(
126
bool BytecodeGenerator::addVar(
127
    const Identifier& ident, ConstantMode constantMode, WatchMode watchMode, RegisterID*& r0)
127
    const Identifier& ident, ConstantMode constantMode, VarKind varKind, WatchMode watchMode,
128
    RegisterID*& r0)
128
{
129
{
129
    ASSERT(static_cast<size_t>(m_codeBlock->m_numVars) == m_calleeRegisters.size());
130
    ASSERT(static_cast<size_t>(m_codeBlock->m_numVars) == m_calleeRegisters.size());
130
    
131
    
131
    ConcurrentJITLocker locker(symbolTable().m_lock);
132
    ConcurrentJITLocker locker(symbolTable().m_lock);
132
    int index = virtualRegisterForLocal(m_calleeRegisters.size()).offset();
133
    VarOffset varOffset;
133
    SymbolTableEntry newEntry(index, constantMode == IsConstant ? ReadOnly : 0);
134
    if (varKind == HeapVarKind)
135
        varOffset = VarOffset(HeapOffset(m_numCapturedVariables++));
136
    else {
137
        ASSERT(varKind == StackVarKind);
138
        varOffset = VarOffset(virtualRegisterForLocal(m_calleeRegisters.size()));
139
    }
140
    SymbolTableEntry newEntry(varOffset, constantMode == IsConstant ? ReadOnly : 0);
134
    SymbolTable::Map::AddResult result = symbolTable().add(locker, ident.impl(), newEntry);
141
    SymbolTable::Map::AddResult result = symbolTable().add(locker, ident.impl(), newEntry);
135
142
136
    if (!result.isNewEntry) {
143
    if (!result.isNewEntry) {
137
        r0 = &registerFor(result.iterator->value.getIndex());
144
        RELEASE_ASSERT(varKind == result.iterator->value.varOffset().kind());
145
        if (varKind == HeapVarKind)
146
            r0 = nullptr;
147
        else
148
            r0 = &registerFor(result.iterator->value.varOffset());
138
        return false;
149
        return false;
139
    }
150
    }
140
    
151
    
Lines 144-150 bool BytecodeGenerator::addVar( Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec3
144
        m_watchableVariables.append(ident);
155
        m_watchableVariables.append(ident);
145
    }
156
    }
146
    
157
    
147
    r0 = addVar();
158
    if (varKind == HeapVarKind)
159
        r0 = nullptr;
160
    else
161
        r0 = addVar();
148
    
162
    
149
    ASSERT(watchMode == NotWatchable || static_cast<size_t>(m_codeBlock->m_numVars) == m_watchableVariables.size());
163
    ASSERT(watchMode == NotWatchable || static_cast<size_t>(m_codeBlock->m_numVars) == m_watchableVariables.size());
150
    
164
    
Lines 231-237 BytecodeGenerator::BytecodeGenerator(VM& Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp_sec4
231
    }
245
    }
232
    RegisterID* localArgumentsRegister = nullptr;
246
    RegisterID* localArgumentsRegister = nullptr;
233
    RegisterID* scratch = addVar();
247
    RegisterID* scratch = addVar();
234
    m_symbolTable->setCaptureStart(virtualRegisterForLocal(m_codeBlock->m_numVars).offset());
235
248
236
    if (functionNode->usesArguments() || codeBlock->usesEval()) { // May reify arguments object.
249
    if (functionNode->usesArguments() || codeBlock->usesEval()) { // May reify arguments object.
237
        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
250
        RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
- Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h -3 / +4 lines
Lines 613-627 namespace JSC { Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h_sec1
613
613
614
        // Adds a var slot and maps it to the name ident in symbolTable().
614
        // Adds a var slot and maps it to the name ident in symbolTable().
615
        enum WatchMode { IsWatchable, NotWatchable };
615
        enum WatchMode { IsWatchable, NotWatchable };
616
        RegisterID* addVar(const Identifier& ident, ConstantMode constantMode, WatchMode watchMode)
616
        RegisterID* addVar(const Identifier& ident, ConstantMode constantMode, VarKind varKind, WatchMode watchMode)
617
        {
617
        {
618
            RegisterID* local;
618
            RegisterID* local;
619
            addVar(ident, constantMode, watchMode, local);
619
            addVar(ident, constantMode, varKind, watchMode, local);
620
            return local;
620
            return local;
621
        }
621
        }
622
622
623
        // Ditto. Returns true if a new RegisterID was added, false if a pre-existing RegisterID was re-used.
623
        // Ditto. Returns true if a new RegisterID was added, false if a pre-existing RegisterID was re-used.
624
        bool addVar(const Identifier&, ConstantMode, WatchMode, RegisterID*&);
624
        bool addVar(const Identifier&, ConstantMode, VarKind, WatchMode, RegisterID*&);
625
        
625
        
626
        // Adds an anonymous var slot. To give this slot a name, add it to symbolTable().
626
        // Adds an anonymous var slot. To give this slot a name, add it to symbolTable().
627
        RegisterID* addVar()
627
        RegisterID* addVar()
Lines 774-779 namespace JSC { Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h_sec2
774
        Vector<Identifier, 16> m_watchableVariables;
774
        Vector<Identifier, 16> m_watchableVariables;
775
        SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
775
        SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
776
        SegmentedVector<RegisterID, 32> m_calleeRegisters;
776
        SegmentedVector<RegisterID, 32> m_calleeRegisters;
777
        unsigned m_numCapturedVariables;
777
        SegmentedVector<RegisterID, 32> m_parameters;
778
        SegmentedVector<RegisterID, 32> m_parameters;
778
        SegmentedVector<Label, 32> m_labels;
779
        SegmentedVector<Label, 32> m_labels;
779
        LabelScopeStore m_labelScopes;
780
        LabelScopeStore m_labelScopes;
- Source/JavaScriptCore/heap/CopyToken.h -2 / +2 lines
Lines 1-5 Source/JavaScriptCore/heap/CopyToken.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
2
 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 32-38 enum CopyToken { Source/JavaScriptCore/heap/CopyToken.h_sec2
32
    ButterflyCopyToken,
32
    ButterflyCopyToken,
33
    TypedArrayVectorCopyToken,
33
    TypedArrayVectorCopyToken,
34
    MapBackingStoreCopyToken,
34
    MapBackingStoreCopyToken,
35
    ArgumentsSlowArgumentDataCopyToken
35
    DirectArgumentsOverridesCopyToken
36
};
36
};
37
37
38
} // namespace JSC
38
} // namespace JSC
- Source/JavaScriptCore/runtime/ArgumentsMode.h +39 lines
Line 0 Source/JavaScriptCore/runtime/ArgumentsMode.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef ArgumentsMode_h
27
#define ArgumentsMode_h
28
29
namespace JSC {
30
31
enum ArgumentsMode {
32
    ClonedArgumentsCreationMode,
33
    FakeArgumentValuesCreationMode
34
};
35
36
} // namespace JSC
37
38
#endif // ArgumentsMode_h
39
- Source/JavaScriptCore/runtime/CapturedArgumentsOffset.cpp +42 lines
Line 0 Source/JavaScriptCore/runtime/CapturedArgumentsOffset.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "CapturedArgumentsOffset.h"
28
29
namespace JSC {
30
31
void CapturedArgumentsOffset::dump(PrintStream& out) const
32
{
33
    if (!*this) {
34
        out.print("capturedArgumentInvalid");
35
        return;
36
    }
37
38
    out.print("capturedArgument", offset());
39
}
40
41
} // namespace JSC
42
- Source/JavaScriptCore/runtime/CapturedArgumentsOffset.h +53 lines
Line 0 Source/JavaScriptCore/runtime/CapturedArgumentsOffset.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef CapturedArgumentsOffset_h
27
#define CapturedArgumentsOffset_h
28
29
#include "GenericOffset.h"
30
#include <wtf/PrintStream.h>
31
32
namespace JSC {
33
34
// This is an offset into the special arguments object, which captures the arguments to a
35
// function. It only comes into play it the arguments aren't also lifted into the activation.
36
// If they were then accesses to the arguments would resolve to a ScopeOffset and not a
37
// CapturedArgumentsOffset.
38
class CapturedArgumentsOffset : public GenericOffset<CapturedArgumentsOffset> {
39
public:
40
    CapturedArgumentsOffset() { }
41
    
42
    explicit CapturedArgumentsOffset(unsigned offset)
43
        : GenericOffset(offset)
44
    {
45
    }
46
    
47
    void dump(PrintStream&) const;
48
};
49
50
} // namespace JSC
51
52
#endif // CapturedArgumentsOffset_h
53
- Source/JavaScriptCore/runtime/DirectArguments.cpp +269 lines
Line 0 Source/JavaScriptCore/runtime/DirectArguments.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "DirectArguments.h"
28
29
#include "JSArgumentsIterator.h"
30
#include "JSCInlines.h"
31
32
namespace JSC {
33
34
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DirectArguments);
35
36
const ClassInfo DirectArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(DirectArguments) };
37
38
DirectArguments::DirectArguments(VM& vm, Structure* structure, unsigned length)
39
    : Base(vm, structure)
40
    , m_length(length)
41
{
42
}
43
44
DirectArguments* DirectArguments::createUninitialized(VM& vm, Structure* structure, unsigned length)
45
{
46
    DirectArguments* result =
47
        new (NotNull, allocateCell<DirectArguments>(vm.heap, allocationSize(length)))
48
        (vm, structure);
49
    result->finishCreation(vm);
50
    return result;
51
}
52
53
DirectArguments* DirectArguments::create(VM& vm, Structure* structure, unsigned length)
54
{
55
    DirectArguments* result = createUninitialized(vm, structure, length);
56
    
57
    for (unsigned i = length; i--;)
58
        result->storage()[i].clear();
59
    
60
    return result;
61
}
62
63
DirectArguments* DirectArguments::createByCopying(VM& vm, Structure* structure, ExecState* exec)
64
{
65
    unsigned length = exec->argumentCount();
66
    DirectArguments* result = createUninitialized(vm, structure, length);
67
    
68
    for (unsigned i = length; i--;)
69
        result->storage()[i].set(vm, result, exec->uncheckedArgument(i));
70
    
71
    result->callee().set(vm, result, jsCast<JSFunction*>(exec->callee()));
72
    
73
    return result;
74
}
75
76
void DirectArguments::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
77
{
78
    DirectArguments* thisObject = static_cast<DirectArguments*>(thisCell);
79
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
80
    Base::visitChildren(thisObject, visitor);
81
    
82
    visitor.appendValues(thisObject->storage(), thisObject->m_length);
83
}
84
85
Structure* DirectArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
86
{
87
    return Structure::create(vm, globalObject, prototype, TypeInfo(DirectArgumentsType, StructureFlags), info());
88
}
89
90
bool DirectArguments::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName ident, PropertySlot& slot)
91
{
92
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
93
    VM& vm = exec->vm();
94
    
95
    if (!thisObject->m_overrides) {
96
        if (ident == vm.propertyNames->length) {
97
            slot.setValue(thisObject, DontEnum, jsNumber(thisObject->m_length));
98
            return true;
99
        } else if (ident == vm.propertyNames->callee) {
100
            if (!thisObject->isStrictMode()) {
101
                slot.setValue(thisObject, DontEnum, thisObject->callee().get());
102
                return true;
103
            }
104
            thisObject->slowDownAndWasteMemory(vm);
105
        } else if (ident == vm.propertyNames->caller)
106
            thisObject->slowDownAndWasteMemory(vm);
107
    }
108
    
109
    unsigned index = ident.asIndex();
110
    if (thisObject->canAccessIndexQuickly(index)) {
111
        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
112
        return true;
113
    }
114
    
115
    if (Base::getOwnPropertySlot(thisObject, exec, ident, slot))
116
        return true;
117
    
118
    if (ident == vm.propertyNames->iteratorPrivateName) {
119
        JSGlobalObject* globalObject = exec->lexicalGlobalObject();
120
        thisObject->JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsFuncIterator, DontEnum, 0);
121
        if (JSObject::getOwnPropertySlot(thisObject, exec, ident, slot))
122
            return true;
123
    }
124
    
125
    return false;
126
}
127
128
bool DirectArguments::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned index, PropertySlot& slot)
129
{
130
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
131
    
132
    if (thisObject->canAccessIndexQuickly(index)) {
133
        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
134
        return true;
135
    }
136
    
137
    return Base::getOwnPropertySlotByIndex(object, exec, index, slot);
138
}
139
140
void DirectArguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& array, EnumerationMode mode)
141
{
142
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
143
    
144
    for (unsigned i = 0; i < thisObject->m_length; ++i) {
145
        if (!thisObject->canAccessIndexQuickly(index))
146
            continue;
147
        array.add(Identifier::from(exec, i));
148
    }
149
    if (shouldIncludeDontEnumProperties(mode) && !m_overrides) {
150
        array.add(exec->propertyNames().callee);
151
        array.add(exec->propertyNames().length);
152
    }
153
    Base::getOwnPropertyNames(thisObject, exec, array, mode);
154
}
155
156
void DirectArguments::put(JSCell* cell, ExecState* exec, PropertyName ident, JSValue value, PutPropertySlot& slot)
157
{
158
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
159
    VM& vm = exec->vm();
160
    
161
    if (!thisObject->m_overrides
162
        && (ident == vm.propertyNames->length
163
            || ident == vm.propertyNames->callee
164
            || ident == vm.propertyNames->caller))
165
        thisObject->slowDownAndWasteMemory(vm);
166
    
167
    unsigned index = ident.asIndex();
168
    if (thisObject->canAccessIndexQuickly(index)) {
169
        setIndexQuickly(vm, index, value);
170
        return;
171
    }
172
    
173
    Base::put(thisObject, exec, ident, value, slot);
174
}
175
176
void DirectArguments::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool shouldThrow)
177
{
178
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
179
    VM& vm = exec->vm();
180
    
181
    if (thisObject->canSetIndexQuickly(index)) {
182
        setIndexQuickly(vm, index, value);
183
        return;
184
    }
185
    
186
    return Base::putByIndex(cell, exec, index, value, shouldThrow);
187
}
188
189
void DirectArguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName ident)
190
{
191
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
192
    VM& vm = exec->vm();
193
    
194
    if (!thisObject->m_overrides
195
        && (ident == vm.propertyNames->length
196
            || ident == vm.propertyNames->callee
197
            || ident == vm.propertyNames->caller))
198
        thisObject->slowDownAndWasteMemory(vm);
199
    
200
    unsigned index = ident.asIndex();
201
    if (thisObject->canAccessIndexQuickly(index)) {
202
        thisObject->slowDownAndWasteMemoryIfNecessary(vm);
203
        thisObject->m_overrides.get()[index] = true;
204
        return;
205
    }
206
    
207
    Base::deleteProperty(thisObject, exec, ident);
208
}
209
210
void DirectArguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned index)
211
{
212
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
213
    VM& vm = exec->vm();
214
    
215
    if (thisObject->canAccessIndexQuickly(index)) {
216
        thisObject->slowDownAndWasteMemoryIfNecessary(vm);
217
        thisObject->m_overrides.get()[index] = true;
218
        return;
219
    }
220
    
221
    return Base::deletePropertyByIndex(cell, exec, index);
222
}
223
224
void DirectArguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName ident, const PropertyDescriptor& descriptor, bool shouldThrow)
225
{
226
    DirectArguments* thisObject = jsCast<DirectArguments*>(object);
227
    VM& vm = exec->vm();
228
    
229
    if (!thisObject->m_overrides
230
        && (ident == vm.propertyNames->length
231
            || ident == vm.propertyNames->callee
232
            || ident == vm.propertyNames->caller))
233
        thisObject->slowDownAndWasteMemory(vm);
234
    
235
    unsigned index = ident.asIndex();
236
    if (index < thisObject->m_length) {
237
        // If this property 
238
        // FIXME: this will be a struggle.
239
        if (!thisObject->canAccessIndexQuickly(index))
240
    }
241
}
242
243
void DirectArguments::slowDownAndWasteMemory(VM& vm)
244
{
245
    RELEASE_ASSERT(!m_overrides);
246
    
247
    putDirect(vm, vm.propertyNames->length, jsNumber(m_length), DontEnum);
248
    
249
    if (isStrictMode()) {
250
        putDirectNonIndexAccessor(vm, vm.propertyNames->callee, globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor);
251
        putDirectNonIndexAccessor(vm, vm.propertyNames->caller, globalObject()->throwTypeErrorGetterSetter(vm), DontEnum | DontDelete | Accessor);
252
    } else
253
        putDirect(vm, vm.propertyNames->callee, m_callee.get(), DontEnum);
254
    
255
    void* backingStore;
256
    RELEASE_ASSERT(vm.heap.tryAllocateStorage(this, m_length), &backingStore);
257
    m_overrides.set(vm, this, static_cast<bool*>(backingStore));
258
    for (unsigned i = m_length; i--;)
259
        m_overrides.get()[i] = false;
260
}
261
262
void DirectArguments::slowDownAndWasteMemoryIfNecessary(VM& vm)
263
{
264
    if (!m_overrides)
265
        slowDownAndWasteMemory(vm);
266
}
267
268
} // namespace JSC
269
- Source/JavaScriptCore/runtime/DirectArguments.h +158 lines
Line 0 Source/JavaScriptCore/runtime/DirectArguments.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef DirectArguments_h
27
#define DirectArguments_h
28
29
#include "JSObject.h"
30
31
namespace JSC {
32
33
// This is an Arguments-class object that we create when you say "arguments" inside a function,
34
// and none of the arguments are captured in the function's activation. The function will copy all
35
// of its arguments into this object, and all subsequent accesses to the arguments will go through
36
// this object thereafter. Special support is in place for mischevious events like the arguments
37
// being deleted (something like "delete arguments[0]") or reconfigured (broadly, we say deletions
38
// and reconfigurations mean that the respective argument was "overridden").
39
//
40
// To speed allocation, this object will hold all of the arguments in-place. The arguments as well
41
// as a table of flags saying which arguments were overridden.
42
class DirectArguments : public JSNonFinalObject {
43
public:
44
    typedef JSNonFinalObject Base;
45
46
private:
47
    DirectArguments(VM&, Structure*, unsigned length);
48
    
49
public:
50
    // Creates an arguments object but leaves it uninitialized.
51
    static DirectArguments* createUninitialized(VM&, Structure*, unsigned length);
52
    
53
    // Creates an arguments object and initializes everything to the empty value.
54
    static DirectArguments* create(VM&, Structure*, unsigned length);
55
    
56
    // Creates an arguments object by copying the argumnets from the stack.
57
    static DirectArguments* createByCopying(VM&, Structure*, ExecState*);
58
    
59
    static void visitChildren(JSCell*, SlotVisitor&);
60
    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
61
    
62
    uint32_t length(ExecState* exec) const
63
    {
64
        if (UNLIKELY(m_overrides))
65
            return get(exec, exec->propertyNames().length).toUInt32(exec);
66
        return m_length;
67
    }
68
    
69
    bool canAccessIndexQuickly(uint32_t i) const
70
    {
71
        return i < m_length && (!m_overrides || !m_overrides.get()[i]);
72
    }
73
    
74
    JSValue getIndexQuickly(uint32_t i) const
75
    {
76
        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
77
        return storage()[i].get();
78
    }
79
    
80
    void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
81
    {
82
        ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
83
        storage()[i].set(vm, this, value);
84
    }
85
    
86
    WriteBarrier<JSFunction>& callee()
87
    {
88
        return m_callee;
89
    }
90
    
91
    WriteBarrier<Unknown>& argument(CapturedArgumentsOffset offset)
92
    {
93
        ASSERT(offset);
94
        ASSERT_WITH_SECURITY_IMPLICATION(offset.offset() < m_length);
95
        return storage()[offset.offset()];
96
    }
97
    
98
    FunctionExecutable* executable()
99
    {
100
        return jsCast<FunctionExecutable*>(callee->executable());
101
    }
102
    
103
    bool isStrictMode()
104
    {
105
        return executable()->isStrictMode();
106
    }
107
    
108
    DECLARE_INFO;
109
    
110
    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
111
    
112
private:
113
    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
114
    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
115
    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
116
    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
117
    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
118
    static void deleteProperty(JSCell*, ExecState*, PropertyName);
119
    static void deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
120
    static void defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
121
    
122
    void slowDownAndWasteMemory(VM&);
123
    void slowDownAndWasteMemoryIfNecessary(VM&);
124
    
125
    static size_t storageOffset()
126
    {
127
        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(DirectArguments));
128
    }
129
    
130
    static size_t overrideFlagsOffset(uint32_t length)
131
    {
132
        return storageOffset() + sizeof(WriteBarrier<Unknown>) * length;
133
    }
134
    
135
    static size_t allocationSize(uint32_t length)
136
    {
137
        return overrideFlagsOffset(length) + WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(length);
138
    }
139
    
140
    WriteBarrier<Unknown>* storage()
141
    {
142
        return bitwise_cast<WriteBarrier<Unknown>*>(bitwise_cast<char*>(this) + storageOffset());
143
    }
144
    
145
    bool* overrideFlags()
146
    {
147
        return bitwise_cast<WriteBarrier<Unknown>*>(bitwise_cast<char*>(this) + overrideFlagsOffset(m_length));
148
    }
149
    
150
    WriteBarrier<JSFunction*> m_callee;
151
    uint32_t m_length; // Always the actual length of captured arguments and never what was stored into the length property.
152
    CopyWriteBarrier<bool> m_overrides; // If non-null, it means that length, callee, and caller are fully materialized properties.
153
};
154
155
} // namespace JSC
156
157
#endif // DirectArguments_h
158
- Source/JavaScriptCore/runtime/ForeignVariableIndex.h +52 lines
Line 0 Source/JavaScriptCore/runtime/ForeignVariableIndex.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef ForeignVariableIndex_h
27
#define ForeignVariableIndex_h
28
29
namespace JSC {
30
31
class ForeignVariableIndex {
32
public:
33
    ForeignVariableIndex()
34
        : m_index(UINT_MAX)
35
    {
36
    }
37
    
38
    explicit ForeignVariableIndex(unsigned index)
39
        : m_index(index)
40
    {
41
    }
42
    
43
    
44
    
45
private:
46
    unsigned m_index;
47
};
48
49
} // namespace JSC
50
51
#endif // ForeignVariableIndex_h
52
- Source/JavaScriptCore/runtime/GenericOffset.h +111 lines
Line 0 Source/JavaScriptCore/runtime/GenericOffset.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef GenericOffset_h
27
#define GenericOffset_h
28
29
#include <wtf/Assertions.h>
30
31
namespace JSC {
32
33
// A mixin for creating the various kinds of variable offsets that our engine supports.
34
template<typename T>
35
class GenericOffset {
36
public:
37
    static const unsigned invalidOffset = UINT_MAX;
38
    
39
    GenericOffset()
40
        : m_offset(invalidOffset)
41
    {
42
    }
43
    
44
    explicit GenericOffset(unsigned offset)
45
        : m_offset(offset)
46
    {
47
    }
48
    
49
    bool operator!() const { return m_offset == invalidOffset; }
50
    
51
    unsigned offsetUnchecked() const
52
    {
53
        return m_offset;
54
    }
55
    
56
    unsigned offset() const
57
    {
58
        ASSERT(m_offset != invalidOffset);
59
        return m_offset;
60
    }
61
    
62
    bool operator==(const T& other) const
63
    {
64
        return m_offset == other.offsetUnchecked();
65
    }
66
    bool operator!=(const T& other) const
67
    {
68
        return m_offset != other.offsetUnchecked();
69
    }
70
    bool operator<(const T& other) const
71
    {
72
        return m_offset < other.offsetUnchecked();
73
    }
74
    bool operator>(const T& other) const
75
    {
76
        return m_offset > other.offsetUnchecked();
77
    }
78
    bool operator<=(const T& other) const
79
    {
80
        return m_offset <= other.offsetUnchecked();
81
    }
82
    bool operator>=(const T& other) const
83
    {
84
        return m_offset >= other.offsetUnchecked();
85
    }
86
    
87
    T operator+(int value) const
88
    {
89
        return T(offset() + value);
90
    }
91
    T operator-(int value) const
92
    {
93
        return T(offset() - value);
94
    }
95
    T& operator+=(int value)
96
    {
97
        return *this = *this + value;
98
    }
99
    T& operator-=(int value)
100
    {
101
        return *this = *this - value;
102
    }
103
    
104
private:
105
    unsigned m_offset;
106
};
107
108
} // namespace JSC
109
110
#endif // GenericOffset_h
111
- Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp -2 / +10 lines
Lines 1-5 Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2013 Apple, Inc. All rights reserved.
2
 * Copyright (C) 2013, 2015 Apple, Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 33-42 namespace JSC { Source/JavaScriptCore/runtime/JSArgumentsIterator.cpp_sec2
33
33
34
const ClassInfo JSArgumentsIterator::s_info = { "ArgumentsIterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArgumentsIterator) };
34
const ClassInfo JSArgumentsIterator::s_info = { "ArgumentsIterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArgumentsIterator) };
35
35
36
void JSArgumentsIterator::finishCreation(VM& vm, Arguments* arguments)
36
void JSArgumentsIterator::finishCreation(VM& vm, JSObject* arguments)
37
{
37
{
38
    Base::finishCreation(vm);
38
    Base::finishCreation(vm);
39
    m_arguments.set(vm, this, arguments);
39
    m_arguments.set(vm, this, arguments);
40
}
40
}
41
41
42
EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState* exec)
43
{
44
    JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
45
    if (!thisObj->inherits(Arguments::info()) && !thisObj->inherits(OutOfBandArguments::info()))
46
        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Attempted to use Arguments iterator on non-Arguments object")));
47
    return JSValue::encode(JSArgumentsIterator::create(exec->vm(), exec->callee()->globalObject()->argumentsIteratorStructure(), thisObj));
48
}
49
42
}
50
}
- Source/JavaScriptCore/runtime/JSArgumentsIterator.h -9 / +11 lines
Lines 1-5 Source/JavaScriptCore/runtime/JSArgumentsIterator.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2013 Apple, Inc. All rights reserved.
2
 * Copyright (C) 2013, 2015 Apple, Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 26-32 Source/JavaScriptCore/runtime/JSArgumentsIterator.h_sec2
26
#ifndef JSArgumentsIterator_h
26
#ifndef JSArgumentsIterator_h
27
#define JSArgumentsIterator_h
27
#define JSArgumentsIterator_h
28
28
29
#include "Arguments.h"
29
#include "JSObject.h"
30
30
31
namespace JSC {
31
namespace JSC {
32
32
Lines 41-47 public: Source/JavaScriptCore/runtime/JSArgumentsIterator.h_sec3
41
        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
41
        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
42
    }
42
    }
43
43
44
    static JSArgumentsIterator* create(VM& vm, Structure* structure, Arguments* arguments)
44
    static JSArgumentsIterator* create(VM& vm, Structure* structure, JSObject* arguments)
45
    {
45
    {
46
        JSArgumentsIterator* instance = new (NotNull, allocateCell<JSArgumentsIterator>(vm.heap)) JSArgumentsIterator(vm, structure);
46
        JSArgumentsIterator* instance = new (NotNull, allocateCell<JSArgumentsIterator>(vm.heap)) JSArgumentsIterator(vm, structure);
47
        instance->finishCreation(vm, arguments);
47
        instance->finishCreation(vm, arguments);
Lines 50-60 public: Source/JavaScriptCore/runtime/JSArgumentsIterator.h_sec4
50
50
51
    bool next(CallFrame* callFrame, JSValue& value)
51
    bool next(CallFrame* callFrame, JSValue& value)
52
    {
52
    {
53
        if (m_nextIndex >= m_arguments->length(callFrame))
53
        unsigned length =
54
            m_arguments->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
55
        if (m_nextIndex >= length)
54
            return false;
56
            return false;
55
        value = m_arguments->tryGetArgument(m_nextIndex++);
57
        value = m_arguments->getIndex(callFrame, m_nextIndex++);
56
        if (!value)
57
            value = jsUndefined();
58
        return true;
58
        return true;
59
    }
59
    }
60
60
Lines 68-79 private: Source/JavaScriptCore/runtime/JSArgumentsIterator.h_sec5
68
    {
68
    {
69
    }
69
    }
70
70
71
    void finishCreation(VM&, Arguments*);
71
    void finishCreation(VM&, JSObject*);
72
    
72
    
73
    WriteBarrier<Arguments> m_arguments;
73
    WriteBarrier<JSObject> m_arguments;
74
    size_t m_nextIndex;
74
    size_t m_nextIndex;
75
};
75
};
76
76
77
EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
78
77
}
79
}
78
80
79
#endif // !defined(JSArgumentsIterator_h)
81
#endif // !defined(JSArgumentsIterator_h)
- Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp -1 / +9 lines
Lines 1-5 Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
2
 * Copyright (C) 2007, 2008, 2012, 2015 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 35-38 namespace JSC { Source/JavaScriptCore/runtime/JSEnvironmentRecord.cpp_sec2
35
35
36
const ClassInfo JSEnvironmentRecord::s_info = { "EnvironmentRecord", &Base::s_info, 0, CREATE_METHOD_TABLE(JSEnvironmentRecord) };
36
const ClassInfo JSEnvironmentRecord::s_info = { "EnvironmentRecord", &Base::s_info, 0, CREATE_METHOD_TABLE(JSEnvironmentRecord) };
37
37
38
void JSEnvironmentRecord::visitChildren(JSCell* cell, SlotVisitor& visitor)
39
{
40
    JSEnvironmentRecord* thisObject = jsCast<JSEnvironmentRecord*>(cell);
41
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
42
    Base::visitChildren(thisObject, visitor);
43
    visitor.appendValues(thisObject->variables(), m_symbolTable->scopeSize());
44
}
45
38
} // namespace JSC
46
} // namespace JSC
- Source/JavaScriptCore/runtime/JSEnvironmentRecord.h -8 / +43 lines
Lines 46-56 class JSEnvironmentRecord : public JSSym Source/JavaScriptCore/runtime/JSEnvironmentRecord.h_sec1
46
public:
46
public:
47
    typedef JSSymbolTableObject Base;
47
    typedef JSSymbolTableObject Base;
48
48
49
    WriteBarrierBase<Unknown>* registers() { return m_registers; }
49
    WriteBarrierBase<Unknown>* variables()
50
    WriteBarrierBase<Unknown>& registerAt(int index) const { return m_registers[index]; }
50
    {
51
        return bitwise_cast<WriteBarrierBase<Unknown>*>(bitwise_cast<char*>(this) + offsetOfVariables());
52
    }
53
    
54
    bool isValid(ScopeOffset offset)
55
    {
56
        return !!offset && offset.offset() < m_symbolTable->scopeSize();
57
    }
58
    
59
    WriteBarrierBase<Unknown>& variableAt(ScopeOffset offset) const
60
    {
61
        ASSERT(isValid(offset));
62
        return variables()[offset.offset()];
63
    }
51
64
52
    WriteBarrierBase<Unknown>* const * addressOfRegisters() const { return &m_registers; }
65
    static size_t offsetOfVariables()
53
    static size_t offsetOfRegisters() { return OBJECT_OFFSETOF(JSEnvironmentRecord, m_registers); }
66
    {
67
        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSEnvironmentRecord));
68
    }
54
69
55
    DECLARE_INFO;
70
    DECLARE_INFO;
56
71
Lines 60-74 protected: Source/JavaScriptCore/runtime/JSEnvironmentRecord.h_sec2
60
    JSEnvironmentRecord(
75
    JSEnvironmentRecord(
61
        VM& vm,
76
        VM& vm,
62
        Structure* structure,
77
        Structure* structure,
63
        Register* registers,
64
        JSScope* scope,
78
        JSScope* scope,
65
        SymbolTable* symbolTable)
79
        SymbolTable* symbolTable)
66
        : Base(vm, structure, scope, symbolTable)
80
        : Base(vm, structure, scope, symbolTable)
67
        , m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers))
68
    {
81
    {
69
    }
82
    }
70
83
    
71
    WriteBarrierBase<Unknown>* m_registers; // "r" in the stack.
84
    static size_t allocationSizeForScopeSize(unsigned scopeSize)
85
    {
86
        return offsetOfVariables() + scopeSize * sizeof(WriteBarrier<Unknown>);
87
    }
88
    
89
    static size_t allocationSize(SymbolTable* symbolTable)
90
    {
91
        return allocationSizeForScopeSize(symbolTable->scopeSize());
92
    }
93
    
94
    void finishCreationUninitialized(VM& vm)
95
    {
96
        Base::finishCreation(vm);
97
    }
98
    
99
    void finishCreation(VM& vm)
100
    {
101
        finishCreationUninitialized(vm);
102
        for (unsigned i = m_symbolTable->scopeSize(); i--;) {
103
            // Filling this with undefined is useful because that's what variables start out as.
104
            variableAt(i).setUndefined();
105
        }
106
    }
72
};
107
};
73
108
74
} // namespace JSC
109
} // namespace JSC
- Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp -21 / +18 lines
Lines 1-5 Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
2
 * Copyright (C) 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 40-66 namespace JSC { Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp_sec2
40
40
41
const ClassInfo JSLexicalEnvironment::s_info = { "JSLexicalEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSLexicalEnvironment) };
41
const ClassInfo JSLexicalEnvironment::s_info = { "JSLexicalEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSLexicalEnvironment) };
42
42
43
void JSLexicalEnvironment::visitChildren(JSCell* cell, SlotVisitor& visitor)
44
{
45
    JSLexicalEnvironment* thisObject = jsCast<JSLexicalEnvironment*>(cell);
46
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
47
    Base::visitChildren(thisObject, visitor);
48
49
    for (int i = 0; i < thisObject->symbolTable()->captureCount(); ++i)
50
        visitor.append(&thisObject->storage()[i]);
51
}
52
53
inline bool JSLexicalEnvironment::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
43
inline bool JSLexicalEnvironment::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
54
{
44
{
55
    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
45
    SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.uid());
56
    if (entry.isNull())
46
    if (entry.isNull())
57
        return false;
47
        return false;
58
48
49
    ScopeOffset offset = entry.scopeOffset();
50
59
    // Defend against the inspector asking for a var after it has been optimized out.
51
    // Defend against the inspector asking for a var after it has been optimized out.
60
    if (!isValid(entry))
52
    if (!isValid(offset))
61
        return false;
53
        return false;
62
54
63
    slot.setValue(this, DontEnum, registerAt(entry.getIndex()).get());
55
    slot.setValue(this, DontEnum, variableAt(offset).get());
64
    return true;
56
    return true;
65
}
57
}
66
58
Lines 70-80 inline bool JSLexicalEnvironment::symbol Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp_sec3
70
    if (entry.isNull())
62
    if (entry.isNull())
71
        return false;
63
        return false;
72
64
65
    ScopeOffset offset = entry.scopeOffset();
66
73
    // Defend against the inspector asking for a var after it has been optimized out.
67
    // Defend against the inspector asking for a var after it has been optimized out.
74
    if (!isValid(entry))
68
    if (!isValid(offset))
75
        return false;
69
        return false;
76
70
77
    descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes());
71
    descriptor.setDescriptor(variableAt(offset).get(), entry.getAttributes());
78
    return true;
72
    return true;
79
}
73
}
80
74
Lines 95-106 inline bool JSLexicalEnvironment::symbol Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp_sec4
95
                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
89
                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
96
            return true;
90
            return true;
97
        }
91
        }
92
        ScopeOffset offset = iter->value.scopeOffset();
98
        // Defend against the inspector asking for a var after it has been optimized out.
93
        // Defend against the inspector asking for a var after it has been optimized out.
99
        if (!isValid(iter->value))
94
        if (!isValid(offset))
100
            return false;
95
            return false;
101
        if (VariableWatchpointSet* set = iter->value.watchpointSet())
96
        if (VariableWatchpointSet* set = iter->value.watchpointSet())
102
            set->invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invcalidated it.
97
            set->invalidate(VariableWriteFireDetail(this, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it.
103
        reg = &registerAt(iter->value.getIndex());
98
        reg = &variableAt(offset);
104
    }
99
    }
105
    reg->set(vm, this, value);
100
    reg->set(vm, this, value);
106
    return true;
101
    return true;
Lines 116-122 void JSLexicalEnvironment::getOwnNonInde Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp_sec5
116
        for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) {
111
        for (SymbolTable::Map::iterator it = thisObject->symbolTable()->begin(locker); it != end; ++it) {
117
            if (it->value.getAttributes() & DontEnum && !shouldIncludeDontEnumProperties(mode))
112
            if (it->value.getAttributes() & DontEnum && !shouldIncludeDontEnumProperties(mode))
118
                continue;
113
                continue;
119
            if (!thisObject->isValid(it->value))
114
            if (!thisObject->isValid(it->value.scopeOffset()))
120
                continue;
115
                continue;
121
            propertyNames.add(Identifier(exec, it->key.get()));
116
            propertyNames.add(Identifier(exec, it->key.get()));
122
        }
117
        }
Lines 137-147 inline bool JSLexicalEnvironment::symbol Source/JavaScriptCore/runtime/JSLexicalEnvironment.cpp_sec6
137
            return false;
132
            return false;
138
        SymbolTableEntry& entry = iter->value;
133
        SymbolTableEntry& entry = iter->value;
139
        ASSERT(!entry.isNull());
134
        ASSERT(!entry.isNull());
140
        if (!isValid(entry))
135
        
136
        ScopeOffset offset = entry.scopeOffset();
137
        if (!isValid(offset))
141
            return false;
138
            return false;
142
        
139
        
143
        entry.setAttributes(attributes);
140
        entry.setAttributes(attributes);
144
        reg = &registerAt(entry.getIndex());
141
        reg = &variableAt(offset);
145
    }
142
    }
146
    reg->set(vm, this, value);
143
    reg->set(vm, this, value);
147
    return true;
144
    return true;
- Source/JavaScriptCore/runtime/JSLexicalEnvironment.h -89 / +15 lines
Lines 1-5 Source/JavaScriptCore/runtime/JSLexicalEnvironment.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2008, 2009, 2013, 2014 Apple Inc. All rights reserved.
2
 * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 41-73 class Register; Source/JavaScriptCore/runtime/JSLexicalEnvironment.h_sec2
41
    
41
    
42
class JSLexicalEnvironment : public JSEnvironmentRecord {
42
class JSLexicalEnvironment : public JSEnvironmentRecord {
43
private:
43
private:
44
    JSLexicalEnvironment(VM&, CallFrame*, Register*, JSScope*, CodeBlock*);
44
    JSLexicalEnvironment(VM&, Structure*, JSScope*, SymbolTable*);
45
    
45
    
46
public:
46
public:
47
    typedef JSEnvironmentRecord Base;
47
    typedef JSEnvironmentRecord Base;
48
48
49
    static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, Register* registers, JSScope* currentScope, CodeBlock* codeBlock)
49
    static JSLexicalEnvironment* create(
50
        VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable)
50
    {
51
    {
51
        SymbolTable* symbolTable = codeBlock->symbolTable();
52
        JSLexicalEnvironment* result =
52
        ASSERT(codeBlock->codeType() == FunctionCode);
53
            new (NotNull, allocationSize(symbolTable))
53
        JSLexicalEnvironment* lexicalEnvironment = new (
54
            JSLexicalEnvironment(vm, globalObject->activationStructure(), currentScope, symbolTable);
54
            NotNull,
55
        result->finishCreation(vm);
55
            allocateCell<JSLexicalEnvironment>(
56
                vm.heap,
57
                allocationSize(symbolTable)
58
            )
59
        ) JSLexicalEnvironment(vm, callFrame, registers, currentScope, codeBlock);
60
        lexicalEnvironment->finishCreation(vm);
61
        return lexicalEnvironment;
62
    }
56
    }
63
        
57
    
64
    static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, JSScope* currentScope, CodeBlock* codeBlock)
58
    static JSLexicalEnvironment* create(VM& vm, CallFrame* callFrame, JSScope* currentScope, CodeBlock* codeBlock)
65
    {
59
    {
66
        return create(vm, callFrame, callFrame->registers() + codeBlock->framePointerOffsetToGetActivationRegisters(), currentScope, codeBlock);
60
        JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
61
        SymbolTable* symbolTable = codeBlock->symbolTable();
62
        return create(vm, globalObject, currentScope, symboltable);
67
    }
63
    }
68
64
        
69
    static void visitChildren(JSCell*, SlotVisitor&);
70
71
    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
65
    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
72
    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
66
    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
73
67
Lines 81-92 public: Source/JavaScriptCore/runtime/JSLexicalEnvironment.h_sec3
81
75
82
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
76
    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) { return Structure::create(vm, globalObject, jsNull(), TypeInfo(ActivationObjectType, StructureFlags), info()); }
83
77
84
    WriteBarrierBase<Unknown>& registerAt(int) const;
85
    bool isValidIndex(int) const;
86
    bool isValid(const SymbolTableEntry&) const;
87
    int registersOffset();
88
    static int registersOffset(SymbolTable*);
89
90
protected:
78
protected:
91
    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
79
    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
92
80
Lines 96-127 private: Source/JavaScriptCore/runtime/JSLexicalEnvironment.h_sec4
96
    bool symbolTableGet(PropertyName, PropertySlot&, bool& slotIsWriteable);
84
    bool symbolTableGet(PropertyName, PropertySlot&, bool& slotIsWriteable);
97
    bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow);
85
    bool symbolTablePut(ExecState*, PropertyName, JSValue, bool shouldThrow);
98
    bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes);
86
    bool symbolTablePutWithAttributes(VM&, PropertyName, JSValue, unsigned attributes);
99
100
    static size_t allocationSize(SymbolTable*);
101
    static size_t storageOffset();
102
103
    WriteBarrier<Unknown>* storage(); // captureCount() number of registers.
104
};
87
};
105
88
106
inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, CallFrame* callFrame, Register* registers, JSScope* currentScope, CodeBlock* codeBlock)
89
inline JSLexicalEnvironment::JSLexicalEnvironment(VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable)
107
    : Base(
90
    : Base(vm, structure, currentScope, symbolTable)
108
        vm,
109
        callFrame->lexicalGlobalObject()->activationStructure(),
110
        registers,
111
        currentScope,
112
        codeBlock->symbolTable())
113
{
91
{
114
    SymbolTable* symbolTable = codeBlock->symbolTable();
115
    WriteBarrier<Unknown>* storage = this->storage();
116
    size_t captureCount = symbolTable->captureCount();
117
    for (size_t i = 0; i < captureCount; ++i)
118
        new (NotNull, &storage[i]) WriteBarrier<Unknown>(UndefinedWriteBarrierTag);
119
    m_registers = reinterpret_cast_ptr<WriteBarrierBase<Unknown>*>(
120
        reinterpret_cast<char*>(this) + registersOffset(symbolTable));
121
}
92
}
122
93
123
JSLexicalEnvironment* asActivation(JSValue);
124
125
inline JSLexicalEnvironment* asActivation(JSValue value)
94
inline JSLexicalEnvironment* asActivation(JSValue value)
126
{
95
{
127
    ASSERT(asObject(value)->inherits(JSLexicalEnvironment::info()));
96
    ASSERT(asObject(value)->inherits(JSLexicalEnvironment::info()));
Lines 133-181 ALWAYS_INLINE JSLexicalEnvironment* Regi Source/JavaScriptCore/runtime/JSLexicalEnvironment.h_sec5
133
    return asActivation(jsValue());
102
    return asActivation(jsValue());
134
}
103
}
135
104
136
inline int JSLexicalEnvironment::registersOffset(SymbolTable* symbolTable)
137
{
138
    return storageOffset() + ((symbolTable->captureCount() - symbolTable->captureStart()  - 1) * sizeof(WriteBarrier<Unknown>));
139
}
140
141
inline size_t JSLexicalEnvironment::storageOffset()
142
{
143
    return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSLexicalEnvironment));
144
}
145
146
inline WriteBarrier<Unknown>* JSLexicalEnvironment::storage()
147
{
148
    return reinterpret_cast_ptr<WriteBarrier<Unknown>*>(
149
        reinterpret_cast<char*>(this) + storageOffset());
150
}
151
152
inline size_t JSLexicalEnvironment::allocationSize(SymbolTable* symbolTable)
153
{
154
    size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSLexicalEnvironment));
155
    size_t storageSizeInBytes = symbolTable->captureCount() * sizeof(WriteBarrier<Unknown>);
156
    return objectSizeInBytes + storageSizeInBytes;
157
}
158
159
inline bool JSLexicalEnvironment::isValidIndex(int index) const
160
{
161
    if (index > symbolTable()->captureStart())
162
        return false;
163
    if (index <= symbolTable()->captureEnd())
164
        return false;
165
    return true;
166
}
167
168
inline bool JSLexicalEnvironment::isValid(const SymbolTableEntry& entry) const
169
{
170
    return isValidIndex(entry.getIndex());
171
}
172
173
inline WriteBarrierBase<Unknown>& JSLexicalEnvironment::registerAt(int index) const
174
{
175
    ASSERT(isValidIndex(index));
176
    return Base::registerAt(index);
177
}
178
179
} // namespace JSC
105
} // namespace JSC
180
106
181
#endif // JSLexicalEnvironment_h
107
#endif // JSLexicalEnvironment_h
- Source/JavaScriptCore/runtime/JSNameScope.cpp -8 lines
Lines 47-60 JSNameScope* JSNameScope::create(VM& vm, Source/JavaScriptCore/runtime/JSNameScope.cpp_sec1
47
    return nullptr;
47
    return nullptr;
48
}
48
}
49
49
50
void JSNameScope::visitChildren(JSCell* cell, SlotVisitor& visitor)
51
{
52
    JSNameScope* thisObject = jsCast<JSNameScope*>(cell);
53
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
54
    Base::visitChildren(thisObject, visitor);
55
    visitor.append(&thisObject->m_registerStore);
56
}
57
58
JSValue JSNameScope::toThis(JSCell*, ExecState* exec, ECMAMode ecmaMode)
50
JSValue JSNameScope::toThis(JSCell*, ExecState* exec, ECMAMode ecmaMode)
59
{
51
{
60
    if (ecmaMode == StrictMode)
52
    if (ecmaMode == StrictMode)
- Source/JavaScriptCore/runtime/JSNameScope.h -9 / +8 lines
Lines 44-81 public: Source/JavaScriptCore/runtime/JSNameScope.h_sec1
44
    template<typename T>
44
    template<typename T>
45
    static T* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
45
    static T* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
46
    {
46
    {
47
        T* scopeObject = new (NotNull, allocateCell<T>(vm.heap)) T(vm, globalObject, currentScope, symbolTable);
47
        T* scopeObject = new (
48
            NotNull, allocateCell<T>(vm.heap, allocationSizeForScopeSize(1))
49
            T(vm, globalObject, currentScope, symbolTable);
48
        scopeObject->finishCreation(vm, value);
50
        scopeObject->finishCreation(vm, value);
49
        return scopeObject;
51
        return scopeObject;
50
    }
52
    }
51
    
53
    
52
    static JSNameScope* create(VM&, JSGlobalObject*, JSScope* currentScope, SymbolTable*, JSValue, Type);
54
    static JSNameScope* create(VM&, JSGlobalObject*, JSScope* currentScope, SymbolTable*, JSValue, Type);
53
55
54
    static void visitChildren(JSCell*, SlotVisitor&);
55
    static JSValue toThis(JSCell*, ExecState*, ECMAMode);
56
    static JSValue toThis(JSCell*, ExecState*, ECMAMode);
56
    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
57
    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
57
    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
58
    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
58
59
59
    DECLARE_INFO;
60
    DECLARE_INFO;
60
61
61
    JSValue value() const { return m_registerStore.get(); }
62
    JSValue value() const { return variableAt(0).get(); }
62
63
63
protected:
64
protected:
64
    void finishCreation(VM& vm, JSValue value)
65
    void finishCreation(VM& vm, JSValue value)
65
    {
66
    {
66
        Base::finishCreation(vm);
67
        Base::finishCreationUninitialized(vm);
67
        m_registerStore.set(vm, this, value);
68
        variableAt(0).set(vm, this, value);
68
    }
69
    }
69
70
70
    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
71
    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
71
72
72
    JSNameScope(VM& vm, Structure* structure, JSScope* next, SymbolTable* symbolTable)
73
    JSNameScope(VM& vm, Structure* structure, JSScope* next, SymbolTable* symbolTable)
73
        : Base(vm, structure, reinterpret_cast<Register*>(&m_registerStore + 1), next, symbolTable)
74
        : Base(vm, structure, next, symbolTable)
74
    {
75
    {
76
        ASSERT(symbolTable->scopeSize() == 1);
75
    }
77
    }
76
77
private:
78
    WriteBarrier<Unknown> m_registerStore;
79
};
78
};
80
79
81
}
80
}
- Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp -9 / +7 lines
Lines 1-5 Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
2
 * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 33-64 Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp_sec2
33
33
34
namespace JSC {
34
namespace JSC {
35
35
36
int JSSegmentedVariableObject::findRegisterIndex(void* registerAddress)
36
ScopeOffset JSSegmentedVariableObject::findRegisterIndex(void* registerAddress)
37
{
37
{
38
    ConcurrentJITLocker locker(m_lock);
38
    ConcurrentJITLocker locker(m_lock);
39
    
39
    
40
    for (int i = m_registers.size(); i--;) {
40
    for (unsigned i = m_registers.size(); i--;) {
41
        if (&m_registers[i] != registerAddress)
41
        if (&m_registers[i] != registerAddress)
42
            continue;
42
            continue;
43
        return i;
43
        return ScopeOffset(i);
44
    }
44
    }
45
    CRASH();
45
    CRASH();
46
    return -1;
46
    return ScopeOffset();
47
}
47
}
48
48
49
int JSSegmentedVariableObject::addRegisters(int numberOfRegistersToAdd)
49
ScopeOffset JSSegmentedVariableObject::addRegisters(unsigned numberOfRegistersToAdd)
50
{
50
{
51
    ConcurrentJITLocker locker(m_lock);
51
    ConcurrentJITLocker locker(m_lock);
52
    
52
    
53
    ASSERT(numberOfRegistersToAdd >= 0);
54
    
55
    size_t oldSize = m_registers.size();
53
    size_t oldSize = m_registers.size();
56
    m_registers.grow(oldSize + numberOfRegistersToAdd);
54
    m_registers.grow(oldSize + numberOfRegistersToAdd);
57
    
55
    
58
    for (size_t i = numberOfRegistersToAdd; i--;)
56
    for (size_t i = numberOfRegistersToAdd; i--;)
59
        m_registers[oldSize + i].setWithoutWriteBarrier(jsUndefined());
57
        m_registers[oldSize + i].setWithoutWriteBarrier(jsUndefined());
60
    
58
    
61
    return static_cast<int>(oldSize);
59
    return ScopeOffset(oldSize);
62
}
60
}
63
61
64
void JSSegmentedVariableObject::visitChildren(JSCell* cell, SlotVisitor& slotVisitor)
62
void JSSegmentedVariableObject::visitChildren(JSCell* cell, SlotVisitor& slotVisitor)
- Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h -7 / +6 lines
Lines 57-80 class JSSegmentedVariableObject : public Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h_sec1
57
public:
57
public:
58
    typedef JSSymbolTableObject Base;
58
    typedef JSSymbolTableObject Base;
59
59
60
    WriteBarrier<Unknown>& registerAt(int index) { return m_registers[index]; }
60
    WriteBarrier<Unknown>& variableAt(ScopeOffset offset) { return m_variables[offset.offset()]; }
61
    
61
    
62
    // This is a slow method call, which searches the register bank to find the index
62
    // This is a slow method call, which searches the register bank to find the index
63
    // given a pointer. It will CRASH() if it does not find the register. Only use this
63
    // given a pointer. It will CRASH() if it does not find the register. Only use this
64
    // in debug code (like bytecode dumping).
64
    // in debug code (like bytecode dumping).
65
    JS_EXPORT_PRIVATE int findRegisterIndex(void*);
65
    JS_EXPORT_PRIVATE ScopeOffset findRegisterIndex(void*);
66
    
66
    
67
    WriteBarrier<Unknown>* assertRegisterIsInThisObject(WriteBarrier<Unknown>* registerPointer)
67
    WriteBarrier<Unknown>* assertVariableIsInThisObject(WriteBarrier<Unknown>* variablePointer)
68
    {
68
    {
69
#if !ASSERT_DISABLED
69
        if (!ASSERT_DISABLED)
70
        findRegisterIndex(registerPointer);
70
            findRegisterIndex(registerPointer);
71
#endif
72
        return registerPointer;
71
        return registerPointer;
73
    }
72
    }
74
    
73
    
75
    // Adds numberOfRegistersToAdd registers, initializes them to Undefined, and returns
74
    // Adds numberOfRegistersToAdd registers, initializes them to Undefined, and returns
76
    // the index of the first one added.
75
    // the index of the first one added.
77
    JS_EXPORT_PRIVATE int addRegisters(int numberOfRegistersToAdd);
76
    JS_EXPORT_PRIVATE ScopeOffset addRegisters(unsigned numberOfRegistersToAdd);
78
    
77
    
79
    JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
78
    JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
80
79
- Source/JavaScriptCore/runtime/JSSymbolTableObject.h -5 / +5 lines
Lines 78-84 inline bool symbolTableGet( Source/JavaScriptCore/runtime/JSSymbolTableObject.h_sec1
78
        return false;
78
        return false;
79
    SymbolTableEntry::Fast entry = iter->value;
79
    SymbolTableEntry::Fast entry = iter->value;
80
    ASSERT(!entry.isNull());
80
    ASSERT(!entry.isNull());
81
    slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
81
    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
82
    return true;
82
    return true;
83
}
83
}
84
84
Lines 94-100 inline bool symbolTableGet( Source/JavaScriptCore/runtime/JSSymbolTableObject.h_sec2
94
    SymbolTableEntry::Fast entry = iter->value;
94
    SymbolTableEntry::Fast entry = iter->value;
95
    ASSERT(!entry.isNull());
95
    ASSERT(!entry.isNull());
96
    descriptor.setDescriptor(
96
    descriptor.setDescriptor(
97
        object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete);
97
        object->variableAt(entry.scopeOffset()).get(), entry.getAttributes() | DontDelete);
98
    return true;
98
    return true;
99
}
99
}
100
100
Lines 110-116 inline bool symbolTableGet( Source/JavaScriptCore/runtime/JSSymbolTableObject.h_sec3
110
        return false;
110
        return false;
111
    SymbolTableEntry::Fast entry = iter->value;
111
    SymbolTableEntry::Fast entry = iter->value;
112
    ASSERT(!entry.isNull());
112
    ASSERT(!entry.isNull());
113
    slot.setValue(object, entry.getAttributes() | DontDelete, object->registerAt(entry.getIndex()).get());
113
    slot.setValue(object, entry.getAttributes() | DontDelete, object->variableAt(entry.scopeOffset()).get());
114
    slotIsWriteable = !entry.isReadOnly();
114
    slotIsWriteable = !entry.isReadOnly();
115
    return true;
115
    return true;
116
}
116
}
Lines 145-151 inline bool symbolTablePut( Source/JavaScriptCore/runtime/JSSymbolTableObject.h_sec4
145
            // https://bugs.webkit.org/show_bug.cgi?id=134601
145
            // https://bugs.webkit.org/show_bug.cgi?id=134601
146
            set->notifyWrite(vm, value, object, propertyName);
146
            set->notifyWrite(vm, value, object, propertyName);
147
        }
147
        }
148
        reg = &object->registerAt(fastEntry.getIndex());
148
        reg = &object->variableAt(fastEntry.scopeOffset());
149
    }
149
    }
150
    // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
150
    // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
151
    // the right for barriers to be able to trigger GC. And I don't want to hold VM
151
    // the right for barriers to be able to trigger GC. And I don't want to hold VM
Lines 173-179 inline bool symbolTablePutWithAttributes Source/JavaScriptCore/runtime/JSSymbolTableObject.h_sec5
173
        if (VariableWatchpointSet* set = entry.watchpointSet())
173
        if (VariableWatchpointSet* set = entry.watchpointSet())
174
            set->notifyWrite(vm, value, object, propertyName);
174
            set->notifyWrite(vm, value, object, propertyName);
175
        entry.setAttributes(attributes);
175
        entry.setAttributes(attributes);
176
        reg = &object->registerAt(entry.getIndex());
176
        reg = &object->variableAt(entry.scopeOffset());
177
    }
177
    }
178
    reg->set(vm, object, value);
178
    reg->set(vm, object, value);
179
    return true;
179
    return true;
- Source/JavaScriptCore/runtime/OutOfBandArguments.cpp +126 lines
Line 0 Source/JavaScriptCore/runtime/OutOfBandArguments.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "OutOfBandArguments.h"
28
29
#include "JSArgumentsIterator.h"
30
#include "JSCInlines.h"
31
32
namespace JSC {
33
34
STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(OutOfBandArguments);
35
36
const ClassInfo OutOfBandArguments::s_info = { "Arguments", &Base::s_info, 0, CREATE_METHOD_TABLE(OutOfBandArguments) };
37
38
OutOfBandArguments::OutOfBandArguments(VM& vm, Structure* structure)
39
    : Base(vm, structure, nullptr)
40
{
41
}
42
43
OutOfBandArguments* OutOfBandArguments::createEmpty(VM& vm, JSGlobalObject* globalObject)
44
{
45
    OutOfBandArguments* result = new (NotNull, allocateCell<OutOfBandArguments>(vm.heap))
46
        OutOfBandArguments(vm, globalObject->outOfBandArgumentsStructure());
47
    result->finishCreation(vm);
48
    return result;
49
}
50
51
OutOfBandArguments* OutOfBandArguments::createEmpty(ExecState* exec)
52
{
53
    // NB. Some clients might expect that the global object of of this object is the global object
54
    // of the callee. We don't do this for now, but maybe we should.
55
    return createEmpty(exec->vm(), exec->lexicalGlobalObject());
56
}
57
58
OutOfBandArguments* OutOfBandArguments::createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
59
{
60
    VM& vm = myFrame->vm();
61
    
62
    JSFunction* callee;
63
    FunctionExecutable* executable;
64
    
65
    if (inlineCallFrame) {
66
        callee = jsCast<JSFunction*>(inlineCallFrame->calleeRecovery.recover(targetFrame));
67
        executable = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get());
68
    } else {
69
        callee = jsCast<JSFunction*>(targetFrame->callee());
70
        executable = jsCast<FunctionExecutable*>(targetFrame->codeBlock()->ownerExecutable());
71
    }
72
    
73
    // NB. It's somewhat arbitrary that we tie the strictness of this object to the strictness of
74
    // the callee.
75
    bool isStrictMode = executable->isStrictMode();
76
77
    OutOfBandArguments* result = createEmpty(myFrame);
78
    
79
    unsigned length;
80
    switch (mode) {
81
    case ClonedArgumentsCreationMode: {
82
        if (inlineCallFrame) {
83
            if (inlineCallFrame->argumentCountRegister.isValid())
84
                length = exec->r(inlineCallFrame->argumentCountRegister).unboxedInt32();
85
            else
86
                length = inlineCallFrame->arguments.size();
87
            length--;
88
            
89
            for (unsigned i = length; i--;)
90
                result->putDirectIndex(myFrame, i, inlineCallFrame->arguments[i].recover(targetFrame));
91
        } else {
92
            length = targetFrame->argumentCount();
93
            
94
            for (unsigned i = length; i--;)
95
                result->putDirectIndex(myFrame, i, targetFrame->uncheckedArgument(i));
96
        }
97
        break;
98
    }
99
        
100
    case FakeArgumentValuesCreationMode: {
101
        length = 0;
102
        break;
103
    } }
104
    
105
    result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
106
    if (isStrictMode) {
107
        result->putDirectAccessor(exec, vm.propertyNames->callee, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor);
108
        result->putDirectAccessor(exec, vm.propertyNames->callee, thisObject->globalObject()->throwTypeErrorGetterSetter(exec->vm()), DontDelete | DontEnum | Accessor);
109
    } else
110
        result->putDirect(vm, vm.propertyNames->callee, JSValue(callee));
111
    
112
    result->JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorPrivateName, argumentsFuncIterator, DontEnum, 0);
113
}
114
115
OutOfBandArguments* OutOfBandArguments::createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode mode)
116
{
117
    return createWithInlineFrame(myFrame, targetFrame, nullptr, mode);
118
}
119
120
Structure* OutOfBandArguments::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
121
{
122
    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
123
}
124
125
} // namespace JSC
126
- Source/JavaScriptCore/runtime/OutOfBandArguments.h +64 lines
Line 0 Source/JavaScriptCore/runtime/OutOfBandArguments.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef OutOfBandArguments_h
27
#define OutOfBandArguments_h
28
29
#include "ArgumentsMode.h"
30
#include "JSObject.h"
31
32
namespace JSC {
33
34
// This is an Arguments-class object that we create when you do function.arguments. It behaves
35
// entirely like an ordinary JavaScript object. All of the arguments values are simply copied from
36
// the stack (possibly via some sophisticated ValueRecovery's if an optimizing compiler is in
37
// play) and the appropriate properties of the object are populated. The only reason why we need
38
// a special class is to make the object claim to be "Arguments" from a toString standpoint.
39
//
40
// Note that this class does a bad job of being fast. That's somewhat intentional. We expect uses
41
// of function.arguments to be rare on the modern web. You will get particularly bad performance
42
// if you use function.arguments in strict mode.
43
class OutOfBandArguments : public JSNonFinalObject {
44
public:
45
    typedef JSNonFinalObject Base;
46
    
47
private:
48
    OutOfBandArguments(VM&, Structure*);
49
50
public:
51
    static OutOfBandArguments* createEmpty(VM&, JSGlobalObject*);
52
    static OutOfBandArguments* createEmpty(ExecState*);
53
    static OutOfBandArguments* createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame*, ArgumentsMode);
54
    static OutOfBandArguments* createWithMachineFrame(ExecState* myFrame, ExecState* targetFrame, ArgumentsMode);
55
    
56
    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
57
    
58
    DECLARE_INFO;
59
};
60
61
} // namespace JSC
62
63
#endif // OutOfBandArguments_h
64
- Source/JavaScriptCore/runtime/ScopeOffset.cpp +42 lines
Line 0 Source/JavaScriptCore/runtime/ScopeOffset.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "ScopeOffset.h"
28
29
namespace JSC {
30
31
void ScopeOffset::dump(PrintStream& out) const
32
{
33
    if (!*this) {
34
        out.print("scopeInvalid");
35
        return;
36
    }
37
    
38
    out.print("scope", offset());
39
}
40
41
} // namespace JSC
42
- Source/JavaScriptCore/runtime/ScopeOffset.h +51 lines
Line 0 Source/JavaScriptCore/runtime/ScopeOffset.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef ScopeOffset_h
27
#define ScopeOffset_h
28
29
#include "GenericOffset.h"
30
#include <wtf/PrintStream.h>
31
32
namespace JSC {
33
34
// This is an offset into a scope of some kind. It could be an activation scope or it could be a
35
// global object.
36
class ScopeOffset : public GenericOffset<ScopeOffset> {
37
public:
38
    ScopeOffset() { }
39
    
40
    explicit ScopeOffset(unsigned offset)
41
        : GenericOffset(offset)
42
    {
43
    }
44
    
45
    void dump(PrintStream&) const;
46
};
47
48
} // namespace JSC
49
50
#endif // ScopeOffset_h
51
- Source/JavaScriptCore/runtime/ScopedArguments.h +95 lines
Line 0 Source/JavaScriptCore/runtime/ScopedArguments.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef ScopedArguments_h
27
#define ScopedArguments_h
28
29
#include "JSObject.h"
30
31
namespace JSC {
32
33
// This is an Arguments-class object that we create when you say "arguments" inside a function,
34
// and one or more of the arguments may be captured in the function's activation. The function
35
// will copy all of its arguments into the activation and then create this object. This object
36
// will use the symbol table's ScopedArgumentsTable and the activation to handle all indexed
37
// lookups.
38
class ScopedArguments : public JSNonFinalObject {
39
public:
40
    typedef JSNonFinalObject Base;
41
42
private:
43
    ScopedArguments(VM&, Structure*);
44
45
public:
46
    static ScopedArguments* create(VM&, Structure*, ScopedArgumentsTable*, JSLexicalEnvironment*);
47
    
48
    static void visitChildren(JSCell*, SlotVisitor&);
49
    
50
    uint32_t length(ExecState* exec) const
51
    {
52
        if (UNLIKELY(m_overrodeLength))
53
            return get(exec, exec->propertyNames().length).toUInt32(exec);
54
        return m_table->length();
55
    }
56
    
57
    bool canGetIndexQuickly(uint32_t i) const
58
    {
59
        return i < m_length && !!m_table->get(i);
60
    }
61
    
62
    JSValue getIndexQuickly(uint32_t i) const
63
    {
64
        ASSERT_WITH_SECURITY_IMPLICATION(canGetIndexQuickly(i));
65
        return m_scope->variableAt(m_table->get(i)).get();
66
    }
67
68
    DECLARE_INFO;
69
    
70
    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
71
72
private:
73
    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
74
    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
75
    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
76
    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
77
    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
78
    static void deleteProperty(JSCell*, ExecState*, PropertyName);
79
    static void deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
80
    static void defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
81
    
82
    void overrideArgument(VM& vm, uint32_t i)
83
    {
84
        m_table.set(vm, this, m_table->set(vm, i, ScopeOffset()));
85
    }
86
    
87
    bool m_overrodeLength;
88
    WriteBarrier<ScopedArgumentsTable> m_table;
89
    WriteBarrier<JSLexicalEnvironment> m_scope;
90
};
91
92
} // namespace JSC
93
94
#endif // ScopedArguments_h
95
- Source/JavaScriptCore/runtime/ScopedArgumentsTable.h +91 lines
Line 0 Source/JavaScriptCore/runtime/ScopedArgumentsTable.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef ScopedArgumentsTable_h
27
#define ScopedArgumentsTable_h
28
29
#include "JSCell.h"
30
31
namespace JSC {
32
33
// This class's only job is to hold onto the list of ScopeOffsets for each argument that a
34
// function has. Most of the time, the BytecodeGenerator will create one of these and it will
35
// never be modified subsequently. There is a rare case where a ScopedArguments object is created
36
// and aliases one of these and then decides to modify it; in that case we do copy-on-write. This
37
// makes sense because such modifications are so uncommon. You'd have to do something crazy like
38
// "delete arguments[i]" or some variant of defineOwnProperty.
39
class ScopedArguments : public JSCell {
40
public:
41
    typedef JSCell Base;
42
    
43
    static const bool needsDestruction = true;
44
    static const bool hasImmortalStructure = true;
45
46
private:
47
    ScopedArgumentsTable(VM&);
48
    ~ScopedArgumentsTable();
49
50
public:
51
    static ScopedArgumentsTable* create(VM&);
52
    
53
    ScopedArguments* clone(VM&);
54
    
55
    uint32_t length() const { return m_length; }
56
    ScopedArgumentsTable* setLength(VM&, uint32_t newLength);
57
    
58
    ScopeOffset get(uint32_t i) const
59
    {
60
        ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
61
        return m_arguments[i];
62
    }
63
    
64
    void lock()
65
    {
66
        m_locked = true;
67
    }
68
    
69
    ScopedArguments* set(VM& vm, uint32_t i, ScopeOffset value)
70
    {
71
        ScopedArguments* result;
72
        if (UNLIKELY(m_locked))
73
            result = clone(vm);
74
        else
75
            result = this;
76
        result->setDirect(i, value);
77
        return result;
78
    }
79
    
80
    DECLARE_INFO;
81
82
private:
83
    uint32_t m_length;
84
    bool m_locked; // Being locked means that there are multiple references to this object and none of them expect to see the others' modifications. This means that modifications need to make a copy first.
85
    std::unique_ptr<ScopeOffset[]> m_arguments;
86
};
87
88
} // namespace JSC
89
90
#endif // ScopedArgumentsTable_h
91
- Source/JavaScriptCore/runtime/SymbolTable.cpp -13 / +6 lines
Lines 1-5 Source/JavaScriptCore/runtime/SymbolTable.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
2
 * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 137-165 void SymbolTable::WatchpointCleanup::fin Source/JavaScriptCore/runtime/SymbolTable.cpp_sec2
137
    }
137
    }
138
}
138
}
139
139
140
SymbolTable* SymbolTable::cloneCapturedNames(VM& vm)
140
SymbolTable* SymbolTable::cloneScopePart(VM& vm)
141
{
141
{
142
    SymbolTable* result = SymbolTable::create(vm);
142
    SymbolTable* result = SymbolTable::create(vm);
143
    
143
    
144
    result->m_parameterCountIncludingThis = m_parameterCountIncludingThis;
145
    result->m_usesNonStrictEval = m_usesNonStrictEval;
144
    result->m_usesNonStrictEval = m_usesNonStrictEval;
146
    result->m_captureStart = m_captureStart;
147
    result->m_captureEnd = m_captureEnd;
148
145
149
    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
146
    for (auto iter = m_map.begin(), end = m_map.end(); iter != end; ++iter) {
150
        if (!isCaptured(iter->value.getIndex()))
147
        if (!iter->value.varOffset().isScope())
151
            continue;
148
            continue;
152
        result->m_map.add(
149
        result->m_map.add(
153
            iter->key,
150
            iter->key,
154
            SymbolTableEntry(iter->value.getIndex(), iter->value.getAttributes()));
151
            SymbolTableEntry(iter->value.varOffset(), iter->value.getAttributes()));
155
    }
152
    }
156
    
153
    
157
    if (m_slowArguments) {
154
    result->m_arguments = arguments();
158
        result->m_slowArguments = std::make_unique<SlowArgument[]>(parameterCount());
155
    
159
        for (unsigned i = parameterCount(); i--;)
160
            result->m_slowArguments[i] = m_slowArguments[i];
161
    }
162
163
    if (m_typeProfilingRareData) {
156
    if (m_typeProfilingRareData) {
164
        result->m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
157
        result->m_typeProfilingRareData = std::make_unique<TypeProfilingRareData>();
165
158
- Source/JavaScriptCore/runtime/SymbolTable.h -65 / +139 lines
Lines 1-5 Source/JavaScriptCore/runtime/SymbolTable.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2007, 2008, 2012-2014 Apple Inc. All rights reserved.
2
 * Copyright (C) 2007, 2008, 2012-2015 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 31-36 Source/JavaScriptCore/runtime/SymbolTable.h_sec2
31
31
32
#include "ConcurrentJITLock.h"
32
#include "ConcurrentJITLock.h"
33
#include "JSObject.h"
33
#include "JSObject.h"
34
#include "ScopedArgumentsTable.h"
34
#include "TypeLocation.h"
35
#include "TypeLocation.h"
35
#include "VariableWatchpointSet.h"
36
#include "VariableWatchpointSet.h"
36
#include <memory>
37
#include <memory>
Lines 39-62 Source/JavaScriptCore/runtime/SymbolTable.h_sec3
39
40
40
namespace JSC {
41
namespace JSC {
41
42
42
struct SlowArgument {
43
public:
44
    enum Status {
45
        Normal = 0,
46
        Captured = 1,
47
        Deleted = 2
48
    };
49
50
    SlowArgument()
51
        : status(Normal)
52
        , index(0)
53
    {
54
    }
55
56
    Status status;
57
    int index; // If status is 'Deleted', index is bogus.
58
};
59
60
static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
43
static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
61
44
62
// The bit twiddling in this class assumes that every register index is a
45
// The bit twiddling in this class assumes that every register index is a
Lines 86-91 static ALWAYS_INLINE int missingSymbolMa Source/JavaScriptCore/runtime/SymbolTable.h_sec4
86
// copy:     SymbolTableEntry --> FatEntry -----^
69
// copy:     SymbolTableEntry --> FatEntry -----^
87
70
88
struct SymbolTableEntry {
71
struct SymbolTableEntry {
72
private:
73
    static VarOffset varOffsetFromBits(intptr_t bits)
74
    {
75
        VarKind kind;
76
        if (bits & StackFlag)
77
            kind = StackVarKind;
78
        else if (bits & CapturedArgumentFlag)
79
            kind = CapturedArgumentKind;
80
        else
81
            kind = ScopeVarKind;
82
        return VarOffset::assemble(kind, static_cast<int>(bits >> FlagBits));
83
    }
84
    
85
    static ScopeOffset scopeOffsetFromBits(intptr_t bits)
86
    {
87
        ASSERT(!(bits & StackFlag));
88
        ASSERT(!(bits & CapturedArgumentFlag));
89
        return ScopeOffset(static_cast<int>(bits >> FlagBits));
90
    }
91
92
public:
93
    
89
    // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
94
    // Use the SymbolTableEntry::Fast class, either via implicit cast or by calling
90
    // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
95
    // getFast(), when you (1) only care about isNull(), getIndex(), and isReadOnly(),
91
    // and (2) you are in a hot path where you need to minimize the number of times
96
    // and (2) you are in a hot path where you need to minimize the number of times
Lines 107-117 struct SymbolTableEntry { Source/JavaScriptCore/runtime/SymbolTable.h_sec5
107
            return !(m_bits & ~SlimFlag);
112
            return !(m_bits & ~SlimFlag);
108
        }
113
        }
109
114
110
        int getIndex() const
115
        VarOffset varOffset() const
111
        {
116
        {
112
            return static_cast<int>(m_bits >> FlagBits);
117
            return varOffsetFromBits(m_bits);
113
        }
118
        }
114
    
119
        
120
        // Asserts if the offset is anything but a scope offset. This structures the assertions
121
        // in a way that may result in better code, even in release, than doing
122
        // varOffset().scopeOffset().
123
        ScopeOffset scopeOffset() const
124
        {
125
            return scopeOffsetFromBits(m_bits);
126
        }
127
        
115
        bool isReadOnly() const
128
        bool isReadOnly() const
116
        {
129
        {
117
            return m_bits & ReadOnlyFlag;
130
            return m_bits & ReadOnlyFlag;
Lines 142-159 struct SymbolTableEntry { Source/JavaScriptCore/runtime/SymbolTable.h_sec6
142
    {
155
    {
143
    }
156
    }
144
157
145
    SymbolTableEntry(int index)
158
    SymbolTableEntry(VarOffset offset)
146
        : m_bits(SlimFlag)
159
        : m_bits(SlimFlag)
147
    {
160
    {
148
        ASSERT(isValidIndex(index));
161
        ASSERT(isValidVarOffset(offset));
149
        pack(index, false, false);
162
        pack(offset, false, false);
150
    }
163
    }
151
164
152
    SymbolTableEntry(int index, unsigned attributes)
165
    SymbolTableEntry(VarOffset offset, unsigned attributes)
153
        : m_bits(SlimFlag)
166
        : m_bits(SlimFlag)
154
    {
167
    {
155
        ASSERT(isValidIndex(index));
168
        ASSERT(isValidVarOffset(offset));
156
        pack(index, attributes & ReadOnly, attributes & DontEnum);
169
        pack(offset, attributes & ReadOnly, attributes & DontEnum);
157
    }
170
    }
158
    
171
    
159
    ~SymbolTableEntry()
172
    ~SymbolTableEntry()
Lines 181-189 struct SymbolTableEntry { Source/JavaScriptCore/runtime/SymbolTable.h_sec7
181
        return !(bits() & ~SlimFlag);
194
        return !(bits() & ~SlimFlag);
182
    }
195
    }
183
196
184
    int getIndex() const
197
    VarOffset varOffset() const
198
    {
199
        return varOffsetFromBits(bits());
200
    }
201
    
202
    // Asserts if the offset is anything but a scope offset. This structures the assertions
203
    // in a way that may result in better code, even in release, than doing
204
    // varOffset().scopeOffset().
205
    ScopeOffset scopeOffset() const
185
    {
206
    {
186
        return static_cast<int>(bits() >> FlagBits);
207
        return scopeOffsetFromBits(bits());
187
    }
208
    }
188
    
209
    
189
    ALWAYS_INLINE Fast getFast() const
210
    ALWAYS_INLINE Fast getFast() const
Lines 209-215 struct SymbolTableEntry { Source/JavaScriptCore/runtime/SymbolTable.h_sec8
209
230
210
    void setAttributes(unsigned attributes)
231
    void setAttributes(unsigned attributes)
211
    {
232
    {
212
        pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
233
        pack(varOffset(), attributes & ReadOnly, attributes & DontEnum);
213
    }
234
    }
214
235
215
    bool isReadOnly() const
236
    bool isReadOnly() const
Lines 242-248 private: Source/JavaScriptCore/runtime/SymbolTable.h_sec9
242
    static const intptr_t ReadOnlyFlag = 0x2;
263
    static const intptr_t ReadOnlyFlag = 0x2;
243
    static const intptr_t DontEnumFlag = 0x4;
264
    static const intptr_t DontEnumFlag = 0x4;
244
    static const intptr_t NotNullFlag = 0x8;
265
    static const intptr_t NotNullFlag = 0x8;
245
    static const intptr_t FlagBits = 4;
266
    static const intptr_t StackFlag = 0x10;
267
    static const intptr_t CapturedArgumentFlag = 0x20;
268
    static const intptr_t FlagBits = 6;
246
    
269
    
247
    class FatEntry {
270
    class FatEntry {
248
        WTF_MAKE_FAST_ALLOCATED;
271
        WTF_MAKE_FAST_ALLOCATED;
Lines 309-328 private: Source/JavaScriptCore/runtime/SymbolTable.h_sec10
309
332
310
    JS_EXPORT_PRIVATE void freeFatEntrySlow();
333
    JS_EXPORT_PRIVATE void freeFatEntrySlow();
311
334
312
    void pack(int index, bool readOnly, bool dontEnum)
335
    void pack(VarOffset offset, bool readOnly, bool dontEnum)
313
    {
336
    {
314
        ASSERT(!isFat());
337
        ASSERT(!isFat());
315
        intptr_t& bitsRef = bits();
338
        intptr_t& bitsRef = bits();
316
        bitsRef = (static_cast<intptr_t>(index) << FlagBits) | NotNullFlag | SlimFlag;
339
        bitsRef =
340
            (static_cast<intptr_t>(offset.rawOffset()) << FlagBits) | NotNullFlag | SlimFlag;
317
        if (readOnly)
341
        if (readOnly)
318
            bitsRef |= ReadOnlyFlag;
342
            bitsRef |= ReadOnlyFlag;
319
        if (dontEnum)
343
        if (dontEnum)
320
            bitsRef |= DontEnumFlag;
344
            bitsRef |= DontEnumFlag;
345
        switch (offset.kind()) {
346
        case ScopeVarKind:
347
            break;
348
        case StackVarKind:
349
            bitsRef |= StackFlag;
350
            break;
351
        case CapturedArgumentKind:
352
            bitsRef |= CapturedArgumentFlag;
353
            break;
354
        default:
355
            RELEASE_ASSERT_NOT_REACHED();
356
            break;
357
        }
321
    }
358
    }
322
    
359
    
323
    bool isValidIndex(int index)
360
    static bool isValidVarOffset(VarOffset offset)
324
    {
361
    {
325
        return ((static_cast<intptr_t>(index) << FlagBits) >> FlagBits) == static_cast<intptr_t>(index);
362
        return ((static_cast<intptr_t>(offset.rawOffset()) << FlagBits) >> FlagBits) == static_cast<intptr_t>(offset.rawOffset());
326
    }
363
    }
327
364
328
    intptr_t m_bits;
365
    intptr_t m_bits;
Lines 351-357 public: Source/JavaScriptCore/runtime/SymbolTable.h_sec11
351
    static SymbolTable* createNameScopeTable(VM& vm, const Identifier& ident, unsigned attributes)
388
    static SymbolTable* createNameScopeTable(VM& vm, const Identifier& ident, unsigned attributes)
352
    {
389
    {
353
        SymbolTable* result = create(vm);
390
        SymbolTable* result = create(vm);
354
        result->add(ident.impl(), SymbolTableEntry(-1, attributes));
391
        result->add(ident.impl(), SymbolTableEntry(VarOffset(ScopeOffset(0)), attributes));
355
        return result;
392
        return result;
356
    }
393
    }
357
    
394
    
Lines 423-430 public: Source/JavaScriptCore/runtime/SymbolTable.h_sec12
423
        return size(locker);
460
        return size(locker);
424
    }
461
    }
425
    
462
    
463
    ScopeOffset maxScopeOffset() const
464
    {
465
        return m_maxScopeOffset;
466
    }
467
    
468
    unsigned scopeSize() const
469
    {
470
        ScopeOffset maxScopeOffset = this->maxScopeOffset();
471
        
472
        // Do some calculation that relies on invalid scope offset plus one being zero.
473
        unsigned fastResult = maxScopeOffset.offsetUnchecked() + 1;
474
        
475
        // Assert that this works.
476
        ASSERT(fastResult == (!maxScopeOffset ? 0 : maxScopeOffset.offset() + 1));
477
        
478
        return fastResult;
479
    }
480
    
426
    Map::AddResult add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
481
    Map::AddResult add(const ConcurrentJITLocker&, StringImpl* key, const SymbolTableEntry& entry)
427
    {
482
    {
483
        if (entry.varOffset().isScope()
484
            && (!m_maxScopeOffset || m_maxScopeOffset < entry.scopeOffset()))
485
            m_maxScopeOffset = entry.scopeOffset();
428
        return m_map.add(key, entry);
486
        return m_map.add(key, entry);
429
    }
487
    }
430
    
488
    
Lines 456-461 public: Source/JavaScriptCore/runtime/SymbolTable.h_sec13
456
        return contains(locker, key);
514
        return contains(locker, key);
457
    }
515
    }
458
    
516
    
517
    // The principle behind ScopedArgumentsTable modifications is that we will create one and
518
    // leave it unlocked - thereby allowing in-place changes - until someone asks for a pointer to
519
    // the table. Then, we will lock it. Then both our future changes and their future changes
520
    // will first have to make a copy. This discipline means that usually when we create a
521
    // ScopedArguments object, we don't have to make a copy of the ScopedArgumentsTable - instead
522
    // we just take a reference to one that we already have.
523
    
524
    uint32_t argumentsLength() const
525
    {
526
        if (!m_arguments)
527
            return 0;
528
        return m_arguments->length();
529
    }
530
    
531
    void setArgumentsLength(VM& vm, uint32_t length)
532
    {
533
        if (UNLIKELY(!m_arguments))
534
            m_arguments.set(vm, this, ScopedArgumentsTable::create(vm));
535
        m_arguments.set(vm, this, m_arguments->setLength(vm, length));
536
    }
537
    
538
    ScopeOffset argumentOffset(uint32_t i) const
539
    {
540
        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
541
        return m_arguments->get(i);
542
    }
543
    
544
    void setArgumentOffset(VM& vm, uint32_t i, ScopeOffset offset)
545
    {
546
        ASSERT_WITH_SECURITY_IMPLICATION(m_arguments);
547
        m_arguments.set(vm, this, m_arguments->set(vm, i, offset));
548
    }
549
    
550
    ScopedArgumentsTable* arguments() const
551
    {
552
        m_arguments->lock();
553
        return m_arguments.get();
554
    }
555
    
459
    GlobalVariableID uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM& vm);
556
    GlobalVariableID uniqueIDForVariable(const ConcurrentJITLocker&, StringImpl* key, VM& vm);
460
    GlobalVariableID uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
557
    GlobalVariableID uniqueIDForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
461
    RefPtr<TypeSet> globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
558
    RefPtr<TypeSet> globalTypeSetForRegister(const ConcurrentJITLocker& locker, int registerIndex, VM& vm);
Lines 464-491 public: Source/JavaScriptCore/runtime/SymbolTable.h_sec14
464
    bool usesNonStrictEval() { return m_usesNonStrictEval; }
561
    bool usesNonStrictEval() { return m_usesNonStrictEval; }
465
    void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
562
    void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
466
563
467
    int captureStart() const { return m_captureStart; }
564
    SymbolTable* cloneScopePart(VM&);
468
    void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
469
470
    int captureEnd() const { return m_captureEnd; }
471
    void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
472
473
    int captureCount() const { return -(m_captureEnd - m_captureStart); }
474
    
475
    bool isCaptured(int operand)
476
    {
477
        return operand <= captureStart() && operand > captureEnd();
478
    }
479
480
    int parameterCount() { return m_parameterCountIncludingThis - 1; }
481
    int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
482
    void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
483
484
    // 0 if we don't capture any arguments; parameterCount() in length if we do.
485
    const SlowArgument* slowArguments() { return m_slowArguments.get(); }
486
    void setSlowArguments(std::unique_ptr<SlowArgument[]> slowArguments) { m_slowArguments = WTF::move(slowArguments); }
487
    
488
    SymbolTable* cloneCapturedNames(VM&);
489
565
490
    void prepareForTypeProfiling(const ConcurrentJITLocker&);
566
    void prepareForTypeProfiling(const ConcurrentJITLocker&);
491
567
Lines 513-518 private: Source/JavaScriptCore/runtime/SymbolTable.h_sec15
513
    ~SymbolTable();
589
    ~SymbolTable();
514
590
515
    Map m_map;
591
    Map m_map;
592
    ScopeOffset m_maxScopeOffset;
593
    
516
    struct TypeProfilingRareData {
594
    struct TypeProfilingRareData {
517
        UniqueIDMap m_uniqueIDMap;
595
        UniqueIDMap m_uniqueIDMap;
518
        RegisterToVariableMap m_registerToVariableMap;
596
        RegisterToVariableMap m_registerToVariableMap;
Lines 520-532 private: Source/JavaScriptCore/runtime/SymbolTable.h_sec16
520
    };
598
    };
521
    std::unique_ptr<TypeProfilingRareData> m_typeProfilingRareData;
599
    std::unique_ptr<TypeProfilingRareData> m_typeProfilingRareData;
522
600
523
    int m_parameterCountIncludingThis;
524
    bool m_usesNonStrictEval;
601
    bool m_usesNonStrictEval;
525
602
    
526
    int m_captureStart;
603
    WriteBarrier<ScopedArgumentsTable> m_arguments;
527
    int m_captureEnd;
528
529
    std::unique_ptr<SlowArgument[]> m_slowArguments;
530
    
604
    
531
    std::unique_ptr<WatchpointCleanup> m_watchpointCleanup;
605
    std::unique_ptr<WatchpointCleanup> m_watchpointCleanup;
532
606
- Source/JavaScriptCore/runtime/VarOffset.cpp +76 lines
Line 0 Source/JavaScriptCore/runtime/VarOffset.cpp_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "VarOffset.h"
28
29
namespace JSC {
30
31
void VarOffset::dump(PrintStream& out) const
32
{
33
    switch (m_kind) {
34
    case InvalidVarKind:
35
        out.print("invalid");
36
        return;
37
    case ScopeVarKind:
38
        out.print(scopeOffset());
39
        return;
40
    case StackVarKind:
41
        out.print(stackOffset());
42
        return;
43
    case CapturedArgumentKind:
44
        out.print(capturedArgumentOffset());
45
        return;
46
    }
47
    RELEASE_ASSERT_NOT_REACHED();
48
}
49
50
} // namespace JSC
51
52
namespace WTF {
53
54
using namespace JSC;
55
56
void printInternal(PrintStream& out, VarKind varKind)
57
{
58
    switch (varKind) {
59
    case InvalidVarKind:
60
        out.print("Invalid");
61
        return;
62
    case ScopeVarKind:
63
        out.print("Scope");
64
        return;
65
    case StackVarKind:
66
        out.print("Stack");
67
        return;
68
    case CapturedArgumentKind:
69
        out.print("CapturedArgument");
70
        return;
71
    }
72
    RELEASE_ASSERT_NOT_REACHED();
73
}
74
75
} // namespace WTF
76
- Source/JavaScriptCore/runtime/VarOffset.h +214 lines
Line 0 Source/JavaScriptCore/runtime/VarOffset.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef VarOffset_h
27
#define VarOffset_h
28
29
#include "CapturedArgumentOffset.h"
30
#include "ScopeOffset.h"
31
#include "VirtualRegister.h"
32
33
namespace JSC {
34
35
enum VarKind : uint8_t {
36
    InvalidVarKind,
37
    ScopeVarKind,
38
    StackVarKind,
39
    CapturedArgumentKind
40
};
41
42
class VarOffset {
43
public:
44
    VarOffset()
45
        : m_kind(InvalidVarKind)
46
        , m_offset(UINT_MAX)
47
    {
48
    }
49
    
50
    explicit VarOffset(VirtualRegister stackOffset)
51
    {
52
        if (!stackOffset.isValid()) {
53
            m_kind = InvalidVarKind;
54
            m_offset = UINT_MAX;
55
        } else {
56
            m_kind = StackVarKind;
57
            m_offset = stackOffset.offset();
58
        }
59
    }
60
    
61
    explicit VarOffset(ScopeOffset scopeOffset)
62
    {
63
        if (!scopeOffset) {
64
            m_kind = InvalidVarKind;
65
            m_offset = UINT_MAX;
66
        } else {
67
            m_kind = ScopeVarKind;
68
            m_offset = scopeOffset.offset();
69
        }
70
    }
71
    
72
    explicit VarOffset(CapturedArgumentOffset capturedArgumentOffset)
73
    {
74
        if (!capturedArgumentOffset) {
75
            m_kind = InvalidVarKind;
76
            m_offset = UINT_MAX;
77
        } else {
78
            m_kind = CapturedArgumentKind;
79
            m_offset = capturedArgumentOffset.offset();
80
        }
81
    }
82
    
83
    static VarOffset assemble(VarKind kind, unsigned offset)
84
    {
85
        VarOffset result;
86
        result.m_kind = kind;
87
        result.m_offset = offset;
88
        result.checkSanity();
89
        return result;
90
    }
91
    
92
    bool isValid() const
93
    {
94
        return m_kind != InvalidVarKind;
95
    }
96
    
97
    bool operator!() const
98
    {
99
        return !isValid();
100
    }
101
    
102
    VarKind kind() const { return m_kind; }
103
    
104
    bool isStack() const
105
    {
106
        return m_kind == StackVarKind;
107
    }
108
    
109
    bool isScope() const
110
    {
111
        return m_kind == ScopeVarKind;
112
    }
113
    
114
    bool isCapturedArgument() const
115
    {
116
        return m_kind == CapturedArgumentKind;
117
    }
118
    
119
    VirtualRegister stackOffsetUnchecked() const
120
    {
121
        if (!isStack())
122
            return VirtualRegister();
123
        return VirtualRegister(m_offset);
124
    }
125
    
126
    ScopeOffset scopeOffsetUnchecked() const
127
    {
128
        if (!isScope())
129
            return ScopeOffset();
130
        return ScopeOffset(m_offset);
131
    }
132
    
133
    CapturedArgumentOffset capturedArgumentOffsetUnchecked() const
134
    {
135
        if (!isCapturedArgument())
136
            return CapturedArgumentOffset();
137
        return CapturedArgumentOffset(m_offset);
138
    }
139
    
140
    VirtualRegister stackOffset() const
141
    {
142
        ASSERT(isStack());
143
        return VirtualRegister(m_offset);
144
    }
145
    
146
    ScopeOffset scopeOffset() const
147
    {
148
        ASSERT(isScope());
149
        return ScopeOffset(m_offset);
150
    }
151
    
152
    CapturedArgumentOffset capturedArgumentOffset() const
153
    {
154
        ASSERT(isCapturedArgument());
155
        return CapturedArgumentOffset(m_offset);
156
    }
157
    
158
    unsigned rawOffset() const
159
    {
160
        ASSERT(isValid());
161
        return m_offset;
162
    }
163
    
164
    void checkSanity() const
165
    {
166
        if (ASSERT_DISABLED)
167
            return;
168
        
169
        switch (m_kind) {
170
        case InvalidVarKind:
171
            ASSERT(m_offset == UINT_MAX);
172
            return;
173
        case ScopeVarKind:
174
            ASSERT(scopeOffset());
175
            return;
176
        case StackVarKind:
177
            ASSERT(stackOffset());
178
            return;
179
        case CapturedArgumentKind:
180
            ASSERT(capturedArgumentOffset());
181
            return;
182
        }
183
        
184
        ASSERT_NOT_REACHED();
185
    }
186
    
187
    bool operator==(const VarOffset& other) const
188
    {
189
        return m_kind == other.m_kind
190
            && m_offset == other.m_offset;
191
    }
192
    
193
    bool operator!=(const VarOffset& other) const
194
    {
195
        return !(*this == other);
196
    }
197
    
198
    void dump(PrintStream&) const;
199
    
200
private:
201
    VarKind m_kind;
202
    unsigned m_offset;
203
};
204
205
} // namespace JSC
206
207
namespace WTF {
208
209
void printInternal(PrintStream&, JSC::VarKind);
210
211
} // namespace WTF
212
213
#endif // VarOffset_h
214
- Source/JavaScriptCore/runtime/VariableLocation.h +38 lines
Line 0 Source/JavaScriptCore/runtime/VariableLocation.h_sec1
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef VariableLocation_h
27
#define VariableLocation_h
28
29
#include "VirtualRegister.h"
30
31
namespace JSC {
32
33
34
35
} // namespace JSC
36
37
#endif // VariableLocation_h
38

Return to Bug 141951