2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef JSVariableObject_h
30 #define JSVariableObject_h
34 #include "SymbolTable.h"
35 #include "UnusedParam.h"
36 #include <wtf/OwnArrayPtr.h>
37 #include <wtf/UnusedParam.h>
43 class JSVariableObject : public JSNonFinalObject {
47 typedef JSNonFinalObject Base;
49 SymbolTable& symbolTable() const { return *m_symbolTable; }
51 virtual ~JSVariableObject();
53 static NO_RETURN_DUE_TO_ASSERT void putWithAttributes(JSObject*, ExecState*, const Identifier&, JSValue, unsigned attributes);
55 static bool deleteProperty(JSCell*, ExecState*, const Identifier&);
56 static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
58 bool isDynamicScope(bool& requiresDynamicChecks) const;
60 WriteBarrier<Unknown>& registerAt(int index) const { return m_registers[index]; }
62 WriteBarrier<Unknown>* const * addressOfRegisters() const { return &m_registers; }
63 static size_t offsetOfRegisters() { return OBJECT_OFFSETOF(JSVariableObject, m_registers); }
65 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
67 return Structure::create(globalData, globalObject, prototype, TypeInfo(VariableObjectType, StructureFlags), &s_info);
71 static const unsigned StructureFlags = OverridesGetPropertyNames | JSNonFinalObject::StructureFlags;
73 JSVariableObject(JSGlobalData& globalData, Structure* structure, SymbolTable* symbolTable, Register* registers)
74 : JSNonFinalObject(globalData, structure)
75 , m_symbolTable(symbolTable)
76 , m_registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers))
80 void finishCreation(JSGlobalData& globalData)
82 Base::finishCreation(globalData);
83 ASSERT(m_symbolTable);
84 COMPILE_ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrier);
87 PassOwnArrayPtr<WriteBarrier<Unknown> > copyRegisterArray(JSGlobalData&, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts);
88 void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray);
90 bool symbolTableGet(const Identifier&, PropertySlot&);
91 bool symbolTableGet(const Identifier&, PropertyDescriptor&);
92 bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
93 bool symbolTablePut(JSGlobalData&, const Identifier&, JSValue);
94 bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes);
96 SymbolTable* m_symbolTable; // Maps name -> offset from "r" in register file.
97 WriteBarrier<Unknown>* m_registers; // "r" in the register file.
98 OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
101 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
103 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
104 if (!entry.isNull()) {
105 slot.setValue(registerAt(entry.getIndex()).get());
111 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
113 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
114 if (!entry.isNull()) {
115 slot.setValue(registerAt(entry.getIndex()).get());
116 slotIsWriteable = !entry.isReadOnly();
122 inline bool JSVariableObject::symbolTablePut(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
124 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
126 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
129 if (entry.isReadOnly())
131 registerAt(entry.getIndex()).set(globalData, this, value);
135 inline bool JSVariableObject::symbolTablePutWithAttributes(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
137 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
139 SymbolTable::iterator iter = symbolTable().find(propertyName.impl());
140 if (iter == symbolTable().end())
142 SymbolTableEntry& entry = iter->second;
143 ASSERT(!entry.isNull());
144 entry.setAttributes(attributes);
145 registerAt(entry.getIndex()).set(globalData, this, value);
149 inline PassOwnArrayPtr<WriteBarrier<Unknown> > JSVariableObject::copyRegisterArray(JSGlobalData& globalData, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts)
151 OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[count]);
152 for (size_t i = 0; i < callframeStarts; i++)
153 registerArray[i].set(globalData, this, src[i].get());
154 for (size_t i = callframeStarts + RegisterFile::CallFrameHeaderSize; i < count; i++)
155 registerArray[i].set(globalData, this, src[i].get());
157 return registerArray.release();
160 inline void JSVariableObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray)
162 ASSERT(registerArray != m_registerArray);
163 m_registerArray = registerArray;
164 m_registers = registers;
169 #endif // JSVariableObject_h