1/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * (C) 2008 Maksim Orlovich <maksim@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 * Portions of this code that are (C) 2007, 2008 Apple Inc. were
21 * originally distributed under the following terms
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
33 * its contributors may be used to endorse or promote products derived
34 * from this software without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
37 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
40 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
45 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 */
47
48#ifndef JSVariableObject_h
49#define JSVariableObject_h
50
51#include "LocalStorage.h"
52#include "SymbolTable.h"
53#include "object.h"
54
55#include <wtf/Vector.h>
56
57namespace KJS {
58 class Interpreter;
59
60 class JSVariableObject : public JSObject {
61 public:
62 using KJS::JSObject::deleteProperty;
63 virtual bool deleteProperty(ExecState*, const Identifier&);
64
65 virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, PropertyMap::PropertyMode mode);
66
67 virtual void mark();
68
69 enum {
70 LengthSlot,
71 TearOffNeeded, // Set when a tearoff is requested;
72 // the actual tearoff will only happen once the function
73 // stops running, though
74 ScopeLink,
75 NumVarObjectSlots = 3
76 };
77
78 int32_t& lengthSlot() { return localStorage[LengthSlot].val.int32Val; }
79 const int32_t& lengthSlot() const { return localStorage[LengthSlot].val.int32Val; }
80
81 bool& tearOffNeededSlot() { return localStorage[TearOffNeeded].val.boolVal; }
82
83 ScopeChainLink& scopeLink() { return localStorage[ScopeLink].val.scopeVal; }
84 protected:
85 JSVariableObject(): localStorage(0), symbolTable(0) { }
86 ~JSVariableObject();
87
88 bool symbolTableGet(const Identifier&, PropertySlot&);
89 bool symbolTablePut(const Identifier&, JSValue*, bool checkReadOnly);
90
91 public:
92 LocalStorageEntry* localStorage; // Storage for variables in the symbol table.
93 SymbolTable* symbolTable; // Maps name -> index in localStorage.
94 };
95
96 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
97 {
98 size_t index = symbolTable->get(propertyName.ustring().rep());
99 if (index != missingSymbolMarker()) {
100 slot.setValueSlot(this, &localStorage[index].val.valueVal);
101 return true;
102 }
103 return false;
104 }
105
106 inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value, bool checkReadOnly)
107 {
108 size_t index = symbolTable->get(propertyName.ustring().rep());
109 if (index == missingSymbolMarker())
110 return false;
111 LocalStorageEntry& entry = localStorage[index];
112 if (checkReadOnly && (entry.attributes & ReadOnly))
113 return true;
114 entry.val.valueVal = value;
115 return true;
116 }
117
118 inline JSVariableObject::~JSVariableObject()
119 {
120 if (localStorage) {
121 scopeLink().deref();
122 if (tearOffNeededSlot())
123 delete[] localStorage;
124 }
125 }
126
127 inline JSObject* ScopeChainLink::object() const
128 {
129 if (isToScopeChainNode())
130 return asScopeChainNode()->object;
131 else
132 return asVariableObject();
133 }
134
135 inline ScopeChainLink ScopeChainLink::next() const
136 {
137 if (isToScopeChainNode())
138 return asScopeChainNode()->next;
139 else
140 return asVariableObject()->scopeLink();
141 }
142
143 inline void ScopeChain::mark()
144 {
145 for (ScopeChainLink n = m_top; n.ptr; n = n.next()) {
146 JSObject *o = n.object();
147 if (!o->marked())
148 o->mark();
149 }
150 }
151
152 inline void ScopeChain::pushVariableObject(JSVariableObject* act)
153 {
154 // note: this assumes the new variable object is not in any
155 // scope chain in the moment.
156
157 // Set the item's next pointer to the current top.
158 // there is no refcount ops since it's transferring a reference
159 act->scopeLink() = m_top;
160
161 // new top!
162 m_top.set(act);
163 }
164
165
166 class KJS_EXPORT JSGlobalObject : public JSObject // ### TODO: should inherit off JSVariableObject
167 {
168 public:
169 JSGlobalObject(): m_interpreter(0) {}
170 JSGlobalObject(JSValue* proto): JSObject(proto), m_interpreter(0) {}
171 virtual bool isGlobalObject() const { return true; }
172
173 void setInterpreter(Interpreter* intp) { m_interpreter = intp; }
174 Interpreter* interpreter() const { return m_interpreter; }
175 private:
176 Interpreter* m_interpreter;
177 };
178} // namespace KJS
179
180#endif // JSVariableObject_h
181// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
182