1 /* 2 * Copyright (C) 2007, 2008 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 * 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. 16 * 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. 27 */ 28 29 #ifndef JSVariableObject_h 30 #define JSVariableObject_h 31 32 #include "JSObject.h" 33 #include "Register.h" 34 #include "SymbolTable.h" 35 #include "UnusedParam.h" 36 #include <wtf/OwnArrayPtr.h> 37 #include <wtf/UnusedParam.h> 38 39 namespace JSC { 40 41 class Register; 42 43 class JSVariableObject : public JSObject { 44 friend class JIT; 45 46 public: symbolTable()47 SymbolTable& symbolTable() const { return *d->symbolTable; } 48 49 virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0; 50 51 virtual bool deleteProperty(ExecState*, const Identifier&); 52 virtual void getPropertyNames(ExecState*, PropertyNameArray&); 53 54 virtual bool isVariableObject() const; 55 virtual bool isDynamicScope() const = 0; 56 57 virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const; 58 registerAt(int index)59 Register& registerAt(int index) const { return d->registers[index]; } 60 61 protected: 62 // Subclasses of JSVariableObject can subclass this struct to add data 63 // without increasing their own size (since there's a hard limit on the 64 // size of a JSCell). 65 struct JSVariableObjectData { JSVariableObjectDataJSVariableObjectData66 JSVariableObjectData(SymbolTable* symbolTable, Register* registers) 67 : symbolTable(symbolTable) 68 , registers(registers) 69 { 70 ASSERT(symbolTable); 71 } 72 73 SymbolTable* symbolTable; // Maps name -> offset from "r" in register file. 74 Register* registers; // "r" in the register file. 75 OwnArrayPtr<Register> registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file. 76 77 private: 78 JSVariableObjectData(const JSVariableObjectData&); 79 JSVariableObjectData& operator=(const JSVariableObjectData&); 80 }; 81 JSVariableObject(PassRefPtr<Structure> structure,JSVariableObjectData * data)82 JSVariableObject(PassRefPtr<Structure> structure, JSVariableObjectData* data) 83 : JSObject(structure) 84 , d(data) // Subclass owns this pointer. 85 { 86 } 87 88 Register* copyRegisterArray(Register* src, size_t count); 89 void setRegisters(Register* r, Register* registerArray); 90 91 bool symbolTableGet(const Identifier&, PropertySlot&); 92 bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable); 93 bool symbolTablePut(const Identifier&, JSValue); 94 bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes); 95 96 JSVariableObjectData* d; 97 }; 98 symbolTableGet(const Identifier & propertyName,PropertySlot & slot)99 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot) 100 { 101 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 102 if (!entry.isNull()) { 103 slot.setRegisterSlot(®isterAt(entry.getIndex())); 104 return true; 105 } 106 return false; 107 } 108 symbolTableGet(const Identifier & propertyName,PropertySlot & slot,bool & slotIsWriteable)109 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable) 110 { 111 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 112 if (!entry.isNull()) { 113 slot.setRegisterSlot(®isterAt(entry.getIndex())); 114 slotIsWriteable = !entry.isReadOnly(); 115 return true; 116 } 117 return false; 118 } 119 symbolTablePut(const Identifier & propertyName,JSValue value)120 inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue value) 121 { 122 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 123 124 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 125 if (entry.isNull()) 126 return false; 127 if (entry.isReadOnly()) 128 return true; 129 registerAt(entry.getIndex()) = value; 130 return true; 131 } 132 symbolTablePutWithAttributes(const Identifier & propertyName,JSValue value,unsigned attributes)133 inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes) 134 { 135 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 136 137 SymbolTable::iterator iter = symbolTable().find(propertyName.ustring().rep()); 138 if (iter == symbolTable().end()) 139 return false; 140 SymbolTableEntry& entry = iter->second; 141 ASSERT(!entry.isNull()); 142 entry.setAttributes(attributes); 143 registerAt(entry.getIndex()) = value; 144 return true; 145 } 146 copyRegisterArray(Register * src,size_t count)147 inline Register* JSVariableObject::copyRegisterArray(Register* src, size_t count) 148 { 149 Register* registerArray = new Register[count]; 150 memcpy(registerArray, src, count * sizeof(Register)); 151 152 return registerArray; 153 } 154 setRegisters(Register * registers,Register * registerArray)155 inline void JSVariableObject::setRegisters(Register* registers, Register* registerArray) 156 { 157 ASSERT(registerArray != d->registerArray.get()); 158 d->registerArray.set(registerArray); 159 d->registers = registers; 160 } 161 162 } // namespace JSC 163 164 #endif // JSVariableObject_h 165