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: 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 getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); 53 54 virtual bool isVariableObject() const; 55 virtual bool isDynamicScope() const = 0; 56 57 Register& registerAt(int index) const { return d->registers[index]; } 58 59 static PassRefPtr<Structure> createStructure(JSValue prototype) 60 { 61 return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); 62 } 63 64 protected: 65 static const unsigned StructureFlags = OverridesGetPropertyNames | JSObject::StructureFlags; 66 // Subclasses of JSVariableObject can subclass this struct to add data 67 // without increasing their own size (since there's a hard limit on the 68 // size of a JSCell). 69 struct JSVariableObjectData { 70 JSVariableObjectData(SymbolTable* symbolTable, Register* registers) 71 : symbolTable(symbolTable) 72 , registers(registers) 73 { 74 ASSERT(symbolTable); 75 } 76 77 SymbolTable* symbolTable; // Maps name -> offset from "r" in register file. 78 Register* registers; // "r" in the register file. 79 OwnArrayPtr<Register> registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file. 80 81 private: 82 JSVariableObjectData(const JSVariableObjectData&); 83 JSVariableObjectData& operator=(const JSVariableObjectData&); 84 }; 85 86 JSVariableObject(NonNullPassRefPtr<Structure> structure, JSVariableObjectData* data) 87 : JSObject(structure) 88 , d(data) // Subclass owns this pointer. 89 { 90 } 91 92 Register* copyRegisterArray(Register* src, size_t count); 93 void setRegisters(Register* r, Register* registerArray); 94 95 bool symbolTableGet(const Identifier&, PropertySlot&); 96 bool symbolTableGet(const Identifier&, PropertyDescriptor&); 97 bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable); 98 bool symbolTablePut(const Identifier&, JSValue); 99 bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes); 100 101 JSVariableObjectData* d; 102 }; 103 104 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot) 105 { 106 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 107 if (!entry.isNull()) { 108 slot.setRegisterSlot(®isterAt(entry.getIndex())); 109 return true; 110 } 111 return false; 112 } 113 114 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable) 115 { 116 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 117 if (!entry.isNull()) { 118 slot.setRegisterSlot(®isterAt(entry.getIndex())); 119 slotIsWriteable = !entry.isReadOnly(); 120 return true; 121 } 122 return false; 123 } 124 125 inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue value) 126 { 127 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 128 129 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); 130 if (entry.isNull()) 131 return false; 132 if (entry.isReadOnly()) 133 return true; 134 registerAt(entry.getIndex()) = value; 135 return true; 136 } 137 138 inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes) 139 { 140 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); 141 142 SymbolTable::iterator iter = symbolTable().find(propertyName.ustring().rep()); 143 if (iter == symbolTable().end()) 144 return false; 145 SymbolTableEntry& entry = iter->second; 146 ASSERT(!entry.isNull()); 147 entry.setAttributes(attributes); 148 registerAt(entry.getIndex()) = value; 149 return true; 150 } 151 152 inline Register* JSVariableObject::copyRegisterArray(Register* src, size_t count) 153 { 154 Register* registerArray = new Register[count]; 155 memcpy(registerArray, src, count * sizeof(Register)); 156 157 return registerArray; 158 } 159 160 inline void JSVariableObject::setRegisters(Register* registers, Register* registerArray) 161 { 162 ASSERT(registerArray != d->registerArray.get()); 163 d->registerArray.set(registerArray); 164 d->registers = registers; 165 } 166 167 } // namespace JSC 168 169 #endif // JSVariableObject_h 170