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 <wtf/UnusedParam.h>
36 #include <wtf/OwnArrayPtr.h>
37 #include <wtf/UnusedParam.h>
41 class LLIntOffsetsExtractor
;
44 class JSVariableObject
: public JSNonFinalObject
{
46 friend class LLIntOffsetsExtractor
;
49 typedef JSNonFinalObject Base
;
51 SymbolTable
& symbolTable() const { return *m_symbolTable
; }
53 JS_EXPORT_PRIVATE
static void destroy(JSCell
*);
55 static NO_RETURN_DUE_TO_ASSERT
void putDirectVirtual(JSObject
*, ExecState
*, const Identifier
&, JSValue
, unsigned attributes
);
57 JS_EXPORT_PRIVATE
static bool deleteProperty(JSCell
*, ExecState
*, const Identifier
&);
58 JS_EXPORT_PRIVATE
static void getOwnPropertyNames(JSObject
*, ExecState
*, PropertyNameArray
&, EnumerationMode
);
60 bool isDynamicScope(bool& requiresDynamicChecks
) const;
62 WriteBarrier
<Unknown
>& registerAt(int index
) const { return m_registers
[index
]; }
64 WriteBarrier
<Unknown
>* const * addressOfRegisters() const { return &m_registers
; }
65 static size_t offsetOfRegisters() { return OBJECT_OFFSETOF(JSVariableObject
, m_registers
); }
67 static Structure
* createStructure(JSGlobalData
& globalData
, JSGlobalObject
* globalObject
, JSValue prototype
)
69 return Structure::create(globalData
, globalObject
, prototype
, TypeInfo(VariableObjectType
, StructureFlags
), &s_info
);
73 static const unsigned StructureFlags
= OverridesGetPropertyNames
| JSNonFinalObject::StructureFlags
;
75 JSVariableObject(JSGlobalData
& globalData
, Structure
* structure
, SymbolTable
* symbolTable
, Register
* registers
)
76 : JSNonFinalObject(globalData
, structure
)
77 , m_symbolTable(symbolTable
)
78 , m_registers(reinterpret_cast<WriteBarrier
<Unknown
>*>(registers
))
82 void finishCreation(JSGlobalData
& globalData
)
84 Base::finishCreation(globalData
);
85 ASSERT(m_symbolTable
);
86 COMPILE_ASSERT(sizeof(WriteBarrier
<Unknown
>) == sizeof(Register
), Register_should_be_same_size_as_WriteBarrier
);
89 PassOwnArrayPtr
<WriteBarrier
<Unknown
> > copyRegisterArray(JSGlobalData
&, WriteBarrier
<Unknown
>* src
, size_t count
, size_t callframeStarts
);
90 void setRegisters(WriteBarrier
<Unknown
>* registers
, PassOwnArrayPtr
<WriteBarrier
<Unknown
> > registerArray
);
92 bool symbolTableGet(const Identifier
&, PropertySlot
&);
93 JS_EXPORT_PRIVATE
bool symbolTableGet(const Identifier
&, PropertyDescriptor
&);
94 bool symbolTableGet(const Identifier
&, PropertySlot
&, bool& slotIsWriteable
);
95 bool symbolTablePut(ExecState
*, const Identifier
&, JSValue
, bool shouldThrow
);
96 bool symbolTablePutWithAttributes(JSGlobalData
&, const Identifier
&, JSValue
, unsigned attributes
);
98 SymbolTable
* m_symbolTable
; // Maps name -> offset from "r" in register file.
99 WriteBarrier
<Unknown
>* m_registers
; // "r" in the register file.
100 OwnArrayPtr
<WriteBarrier
<Unknown
> > m_registerArray
; // Independent copy of registers, used when a variable object copies its registers out of the register file.
103 inline bool JSVariableObject::symbolTableGet(const Identifier
& propertyName
, PropertySlot
& slot
)
105 SymbolTableEntry entry
= symbolTable().inlineGet(propertyName
.impl());
106 if (!entry
.isNull()) {
107 slot
.setValue(registerAt(entry
.getIndex()).get());
113 inline bool JSVariableObject::symbolTableGet(const Identifier
& propertyName
, PropertySlot
& slot
, bool& slotIsWriteable
)
115 SymbolTableEntry entry
= symbolTable().inlineGet(propertyName
.impl());
116 if (!entry
.isNull()) {
117 slot
.setValue(registerAt(entry
.getIndex()).get());
118 slotIsWriteable
= !entry
.isReadOnly();
124 inline bool JSVariableObject::symbolTablePut(ExecState
* exec
, const Identifier
& propertyName
, JSValue value
, bool shouldThrow
)
126 JSGlobalData
& globalData
= exec
->globalData();
127 ASSERT(!Heap::heap(value
) || Heap::heap(value
) == Heap::heap(this));
129 SymbolTableEntry entry
= symbolTable().inlineGet(propertyName
.impl());
132 if (entry
.isReadOnly()) {
134 throwTypeError(exec
, StrictModeReadonlyPropertyWriteError
);
137 registerAt(entry
.getIndex()).set(globalData
, this, value
);
141 inline bool JSVariableObject::symbolTablePutWithAttributes(JSGlobalData
& globalData
, const Identifier
& propertyName
, JSValue value
, unsigned attributes
)
143 ASSERT(!Heap::heap(value
) || Heap::heap(value
) == Heap::heap(this));
145 SymbolTable::iterator iter
= symbolTable().find(propertyName
.impl());
146 if (iter
== symbolTable().end())
148 SymbolTableEntry
& entry
= iter
->second
;
149 ASSERT(!entry
.isNull());
150 entry
.setAttributes(attributes
);
151 registerAt(entry
.getIndex()).set(globalData
, this, value
);
155 inline PassOwnArrayPtr
<WriteBarrier
<Unknown
> > JSVariableObject::copyRegisterArray(JSGlobalData
& globalData
, WriteBarrier
<Unknown
>* src
, size_t count
, size_t callframeStarts
)
157 OwnArrayPtr
<WriteBarrier
<Unknown
> > registerArray
= adoptArrayPtr(new WriteBarrier
<Unknown
>[count
]);
158 for (size_t i
= 0; i
< callframeStarts
; i
++)
159 registerArray
[i
].set(globalData
, this, src
[i
].get());
160 for (size_t i
= callframeStarts
+ RegisterFile::CallFrameHeaderSize
; i
< count
; i
++)
161 registerArray
[i
].set(globalData
, this, src
[i
].get());
163 return registerArray
.release();
166 inline void JSVariableObject::setRegisters(WriteBarrier
<Unknown
>* registers
, PassOwnArrayPtr
<WriteBarrier
<Unknown
> > registerArray
)
168 ASSERT(registerArray
!= m_registerArray
);
169 m_registerArray
= registerArray
;
170 m_registers
= registers
;
175 #endif // JSVariableObject_h