source: webkit/trunk/JavaScriptCore/runtime/JSVariableObject.h@ 48083

Last change on this file since 48083 was 47780, checked in by [email protected], 16 years ago

[ES5] Implement getOwnPropertyDescriptor
https://bugs.webkit.org/show_bug.cgi?id=28724

Reviewed by Gavin Barraclough.

JavaScriptCore:
Implement the core runtime support for getOwnPropertyDescriptor.
This adds a virtual getOwnPropertyDescriptor method to every class
that implements getOwnPropertySlot that shadows the behaviour of
getOwnPropertySlot. The alternative would be to make getOwnPropertySlot
(or PropertySlots in general) provide property attribute information,
but quick testing showed this to be a regression.

WebCore:
Implement the WebCore side of getOwnPropertyDescriptor. This
requires a custom implementation of getOwnPropertyDescriptor
for every class with a custom implementation of getOwnPropertySlot.

The bindings generator has been updated to generate appropriate
versions of getOwnPropertyDescriptor for the general case where
a custom getOwnPropertyDescriptor is not needed. ES5 is vague
about how getOwnPropertyDescriptor should work in the context of
"host" functions with polymorphic GetOwnProperty, so it seems
okay that occasionally we "guess" what attributes -- eg. determining
whether a property is writable.

Test: fast/js/getOwnPropertyDescriptor.html

  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
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
39namespace 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 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
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 {
66 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
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&, PropertyDescriptor&);
93 bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
94 bool symbolTablePut(const Identifier&, JSValue);
95 bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes);
96
97 JSVariableObjectData* d;
98 };
99
100 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
101 {
102 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
103 if (!entry.isNull()) {
104 slot.setRegisterSlot(&registerAt(entry.getIndex()));
105 return true;
106 }
107 return false;
108 }
109
110 inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
111 {
112 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
113 if (!entry.isNull()) {
114 slot.setRegisterSlot(&registerAt(entry.getIndex()));
115 slotIsWriteable = !entry.isReadOnly();
116 return true;
117 }
118 return false;
119 }
120
121 inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue value)
122 {
123 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
124
125 SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
126 if (entry.isNull())
127 return false;
128 if (entry.isReadOnly())
129 return true;
130 registerAt(entry.getIndex()) = value;
131 return true;
132 }
133
134 inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes)
135 {
136 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
137
138 SymbolTable::iterator iter = symbolTable().find(propertyName.ustring().rep());
139 if (iter == symbolTable().end())
140 return false;
141 SymbolTableEntry& entry = iter->second;
142 ASSERT(!entry.isNull());
143 entry.setAttributes(attributes);
144 registerAt(entry.getIndex()) = value;
145 return true;
146 }
147
148 inline Register* JSVariableObject::copyRegisterArray(Register* src, size_t count)
149 {
150 Register* registerArray = new Register[count];
151 memcpy(registerArray, src, count * sizeof(Register));
152
153 return registerArray;
154 }
155
156 inline void JSVariableObject::setRegisters(Register* registers, Register* registerArray)
157 {
158 ASSERT(registerArray != d->registerArray.get());
159 d->registerArray.set(registerArray);
160 d->registers = registers;
161 }
162
163} // namespace JSC
164
165#endif // JSVariableObject_h
Note: See TracBrowser for help on using the repository browser.