File indexing completed on 2024-05-12 15:43:25
0001 /* 0002 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 0003 * (C) 2008 Maksim Orlovich <maksim@kde.org> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 * 0020 * Portions of this code that are (C) 2007, 2008 Apple Inc. were 0021 * originally distributed under the following terms 0022 * 0023 * Redistribution and use in source and binary forms, with or without 0024 * modification, are permitted provided that the following conditions 0025 * are met: 0026 * 0027 * 1. Redistributions of source code must retain the above copyright 0028 * notice, this list of conditions and the following disclaimer. 0029 * 2. Redistributions in binary form must reproduce the above copyright 0030 * notice, this list of conditions and the following disclaimer in the 0031 * documentation and/or other materials provided with the distribution. 0032 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 0033 * its contributors may be used to endorse or promote products derived 0034 * from this software without specific prior written permission. 0035 * 0036 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 0037 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 0038 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 0039 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 0040 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 0041 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 0042 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 0043 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0044 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0045 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0046 */ 0047 0048 #ifndef JSVariableObject_h 0049 #define JSVariableObject_h 0050 0051 #include "LocalStorage.h" 0052 #include "SymbolTable.h" 0053 #include "object.h" 0054 0055 #include <wtf/Vector.h> 0056 0057 namespace KJS 0058 { 0059 class Interpreter; 0060 0061 class JSVariableObject : public JSObject 0062 { 0063 public: 0064 using KJS::JSObject::deleteProperty; 0065 bool deleteProperty(ExecState *, const Identifier &) override; 0066 0067 void getOwnPropertyNames(ExecState *, PropertyNameArray &, PropertyMap::PropertyMode mode) override; 0068 0069 void mark() override; 0070 0071 enum { 0072 LengthSlot, 0073 TearOffNeeded, // Set when a tearoff is requested; 0074 // the actual tearoff will only happen once the function 0075 // stops running, though 0076 ScopeLink, 0077 NumVarObjectSlots = 3 0078 }; 0079 0080 int32_t &lengthSlot() 0081 { 0082 return localStorage[LengthSlot].val.int32Val; 0083 } 0084 const int32_t &lengthSlot() const 0085 { 0086 return localStorage[LengthSlot].val.int32Val; 0087 } 0088 0089 bool &tearOffNeededSlot() 0090 { 0091 return localStorage[TearOffNeeded].val.boolVal; 0092 } 0093 0094 ScopeChainLink &scopeLink() 0095 { 0096 return localStorage[ScopeLink].val.scopeVal; 0097 } 0098 protected: 0099 JSVariableObject(): localStorage(nullptr), symbolTable(nullptr) { } 0100 ~JSVariableObject() override; 0101 0102 bool symbolTableGet(const Identifier &, PropertySlot &); 0103 bool symbolTablePut(const Identifier &, JSValue *, bool checkReadOnly); 0104 0105 public: 0106 LocalStorageEntry *localStorage; // Storage for variables in the symbol table. 0107 SymbolTable *symbolTable; // Maps name -> index in localStorage. 0108 }; 0109 0110 inline bool JSVariableObject::symbolTableGet(const Identifier &propertyName, PropertySlot &slot) 0111 { 0112 size_t index = symbolTable->get(propertyName.ustring().rep()); 0113 if (index != missingSymbolMarker()) { 0114 slot.setValueSlot(this, &localStorage[index].val.valueVal); 0115 return true; 0116 } 0117 return false; 0118 } 0119 0120 inline bool JSVariableObject::symbolTablePut(const Identifier &propertyName, JSValue *value, bool checkReadOnly) 0121 { 0122 size_t index = symbolTable->get(propertyName.ustring().rep()); 0123 if (index == missingSymbolMarker()) { 0124 return false; 0125 } 0126 LocalStorageEntry &entry = localStorage[index]; 0127 if (checkReadOnly && (entry.attributes & ReadOnly)) { 0128 return true; 0129 } 0130 entry.val.valueVal = value; 0131 return true; 0132 } 0133 0134 inline JSVariableObject::~JSVariableObject() 0135 { 0136 if (localStorage) { 0137 scopeLink().deref(); 0138 if (tearOffNeededSlot()) { 0139 delete[] localStorage; 0140 } 0141 } 0142 } 0143 0144 inline JSObject *ScopeChainLink::object() const 0145 { 0146 if (isToScopeChainNode()) { 0147 return asScopeChainNode()->object; 0148 } else { 0149 return asVariableObject(); 0150 } 0151 } 0152 0153 inline ScopeChainLink ScopeChainLink::next() const 0154 { 0155 if (isToScopeChainNode()) { 0156 return asScopeChainNode()->next; 0157 } else { 0158 return asVariableObject()->scopeLink(); 0159 } 0160 } 0161 0162 inline void ScopeChain::mark() 0163 { 0164 for (ScopeChainLink n = m_top; n.ptr; n = n.next()) { 0165 JSObject *o = n.object(); 0166 if (!o->marked()) { 0167 o->mark(); 0168 } 0169 } 0170 } 0171 0172 inline void ScopeChain::pushVariableObject(JSVariableObject *act) 0173 { 0174 // note: this assumes the new variable object is not in any 0175 // scope chain in the moment. 0176 0177 // Set the item's next pointer to the current top. 0178 // there is no refcount ops since it's transferring a reference 0179 act->scopeLink() = m_top; 0180 0181 // new top! 0182 m_top.set(act); 0183 } 0184 0185 class KJS_EXPORT JSGlobalObject : public JSObject // ### TODO: should inherit off JSVariableObject 0186 { 0187 public: 0188 JSGlobalObject(): m_interpreter(nullptr) {} 0189 JSGlobalObject(JSValue *proto): JSObject(proto), m_interpreter(nullptr) {} 0190 bool isGlobalObject() const override 0191 { 0192 return true; 0193 } 0194 0195 void setInterpreter(Interpreter *intp) 0196 { 0197 m_interpreter = intp; 0198 } 0199 Interpreter *interpreter() const 0200 { 0201 return m_interpreter; 0202 } 0203 private: 0204 Interpreter *m_interpreter; 0205 }; 0206 } // namespace KJS 0207 0208 #endif // JSVariableObject_h