source: webkit/trunk/JavaScriptCore/kjs/JSObject.h@ 37845

Last change on this file since 37845 was 37845, checked in by Darin Adler, 17 years ago

JavaScriptCore:

2008-10-24 Darin Adler <Darin Adler>

  • API/APICast.h:
  • API/JSCallbackConstructor.h:
  • API/JSCallbackFunction.cpp:
  • API/JSCallbackFunction.h:
  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h:
  • API/JSContextRef.cpp:
  • API/JSObjectRef.cpp:
  • API/JSValueRef.cpp:
  • VM/CTI.cpp:
  • VM/CTI.h:
  • VM/CodeBlock.cpp:
  • VM/CodeBlock.h:
  • VM/CodeGenerator.cpp:
  • VM/CodeGenerator.h:
  • VM/ExceptionHelpers.cpp:
  • VM/ExceptionHelpers.h:
  • VM/JSPropertyNameIterator.cpp:
  • VM/JSPropertyNameIterator.h:
  • VM/Machine.cpp:
  • VM/Machine.h:
  • VM/Register.h:
  • kjs/ArgList.cpp:
  • kjs/ArgList.h:
  • kjs/Arguments.cpp:
  • kjs/Arguments.h:
  • kjs/ArrayConstructor.cpp:
  • kjs/ArrayPrototype.cpp:
  • kjs/BooleanConstructor.cpp:
  • kjs/BooleanConstructor.h:
  • kjs/BooleanObject.h:
  • kjs/BooleanPrototype.cpp:
  • kjs/CallData.cpp:
  • kjs/CallData.h:
  • kjs/ConstructData.cpp:
  • kjs/ConstructData.h:
  • kjs/DateConstructor.cpp:
  • kjs/DateInstance.h:
  • kjs/DatePrototype.cpp:
  • kjs/DatePrototype.h:
  • kjs/DebuggerCallFrame.cpp:
  • kjs/DebuggerCallFrame.h:
  • kjs/ErrorConstructor.cpp:
  • kjs/ErrorPrototype.cpp:
  • kjs/ExecState.cpp:
  • kjs/ExecState.h:
  • kjs/FunctionConstructor.cpp:
  • kjs/FunctionPrototype.cpp:
  • kjs/FunctionPrototype.h:
  • kjs/GetterSetter.cpp:
  • kjs/GetterSetter.h:
  • kjs/InternalFunction.h:
  • kjs/JSActivation.cpp:
  • kjs/JSActivation.h:
  • kjs/JSArray.cpp:
  • kjs/JSArray.h:
  • kjs/JSCell.cpp:
  • kjs/JSCell.h:
  • kjs/JSFunction.cpp:
  • kjs/JSFunction.h:
  • kjs/JSGlobalData.h:
  • kjs/JSGlobalObject.cpp:
  • kjs/JSGlobalObject.h:
  • kjs/JSGlobalObjectFunctions.cpp:
  • kjs/JSGlobalObjectFunctions.h:
  • kjs/JSImmediate.cpp:
  • kjs/JSImmediate.h:
  • kjs/JSNotAnObject.cpp:
  • kjs/JSNotAnObject.h:
  • kjs/JSNumberCell.cpp:
  • kjs/JSNumberCell.h:
  • kjs/JSObject.cpp:
  • kjs/JSObject.h:
  • kjs/JSStaticScopeObject.cpp:
  • kjs/JSStaticScopeObject.h:
  • kjs/JSString.cpp:
  • kjs/JSString.h:
  • kjs/JSValue.h:
  • kjs/JSVariableObject.h:
  • kjs/JSWrapperObject.h:
  • kjs/MathObject.cpp:
  • kjs/MathObject.h:
  • kjs/NativeErrorConstructor.cpp:
  • kjs/NumberConstructor.cpp:
  • kjs/NumberConstructor.h:
  • kjs/NumberObject.cpp:
  • kjs/NumberObject.h:
  • kjs/NumberPrototype.cpp:
  • kjs/ObjectConstructor.cpp:
  • kjs/ObjectPrototype.cpp:
  • kjs/ObjectPrototype.h:
  • kjs/PropertyMap.h:
  • kjs/PropertySlot.cpp:
  • kjs/PropertySlot.h:
  • kjs/RegExpConstructor.cpp:
  • kjs/RegExpConstructor.h:
  • kjs/RegExpMatchesArray.h:
  • kjs/RegExpObject.cpp:
  • kjs/RegExpObject.h:
  • kjs/RegExpPrototype.cpp:
  • kjs/Shell.cpp:
  • kjs/StringConstructor.cpp:
  • kjs/StringObject.cpp:
  • kjs/StringObject.h:
  • kjs/StringObjectThatMasqueradesAsUndefined.h:
  • kjs/StringPrototype.cpp:
  • kjs/StructureID.cpp:
  • kjs/StructureID.h:
  • kjs/collector.cpp:
  • kjs/collector.h:
  • kjs/completion.h:
  • kjs/grammar.y:
  • kjs/interpreter.cpp:
  • kjs/interpreter.h:
  • kjs/lookup.cpp:
  • kjs/lookup.h:
  • kjs/nodes.h:
  • kjs/operations.cpp:
  • kjs/operations.h:
  • kjs/protect.h:
  • profiler/ProfileGenerator.cpp:
  • profiler/Profiler.cpp:
  • profiler/Profiler.h: Use JSValue* instead of JSValuePtr.

JavaScriptGlue:

2008-10-24 Darin Adler <Darin Adler>

  • JSObject.cpp: (nativeCallFunction):
  • JSUtils.cpp: (KJSValueToJSObject): (JSObjectKJSValue): (KJSValueToCFTypeInternal): (KJSValueToCFType):
  • JSUtils.h:
  • JSValueWrapper.cpp: (JSValueWrapper::JSValueWrapper): (JSValueWrapper::GetValue): (JSValueWrapper::JSObjectCopyProperty): (JSValueWrapper::JSObjectSetProperty): (JSValueWrapper::JSObjectCallFunction):
  • JSValueWrapper.h:
  • UserObjectImp.cpp: (UserObjectImp::callAsFunction): (UserObjectImp::userObjectGetter): (UserObjectImp::getOwnPropertySlot): (UserObjectImp::put): (UserObjectImp::toPrimitive):
  • UserObjectImp.h: (UserObjectImp::createStructureID): Use JSValue* instead of JSValuePtr.

WebCore:

2008-10-24 Darin Adler <Darin Adler>

  • bindings/js/JSAttrCustom.cpp:
  • bindings/js/JSCSSRuleCustom.cpp:
  • bindings/js/JSCSSStyleDeclarationCustom.cpp:
  • bindings/js/JSCSSValueCustom.cpp:
  • bindings/js/JSCanvasPixelArrayCustom.h:
  • bindings/js/JSCanvasRenderingContext2DCustom.cpp:
  • bindings/js/JSClipboardCustom.cpp:
  • bindings/js/JSConsoleCustom.cpp:
  • bindings/js/JSCustomSQLStatementCallback.cpp:
  • bindings/js/JSCustomSQLStatementErrorCallback.cpp:
  • bindings/js/JSCustomSQLTransactionCallback.cpp:
  • bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
  • bindings/js/JSCustomVoidCallback.cpp:
  • bindings/js/JSCustomVoidCallback.h:
  • bindings/js/JSCustomXPathNSResolver.cpp:
  • bindings/js/JSCustomXPathNSResolver.h:
  • bindings/js/JSDOMApplicationCacheCustom.cpp:
  • bindings/js/JSDOMBinding.cpp:
  • bindings/js/JSDOMBinding.h:
  • bindings/js/JSDOMWindowBase.cpp:
  • bindings/js/JSDOMWindowBase.h:
  • bindings/js/JSDOMWindowCustom.cpp:
  • bindings/js/JSDOMWindowCustom.h:
  • bindings/js/JSDOMWindowShell.cpp:
  • bindings/js/JSDOMWindowShell.h:
  • bindings/js/JSDatabaseCustom.cpp:
  • bindings/js/JSDedicatedWorkerCustom.cpp:
  • bindings/js/JSDocumentCustom.cpp:
  • bindings/js/JSElementCustom.cpp:
  • bindings/js/JSEventCustom.cpp:
  • bindings/js/JSEventListener.cpp:
  • bindings/js/JSEventTarget.cpp:
  • bindings/js/JSEventTarget.h:
  • bindings/js/JSEventTargetBase.h:
  • bindings/js/JSEventTargetNodeCustom.cpp:
  • bindings/js/JSHTMLAllCollection.h:
  • bindings/js/JSHTMLAppletElementCustom.cpp:
  • bindings/js/JSHTMLCollectionCustom.cpp:
  • bindings/js/JSHTMLDocumentCustom.cpp:
  • bindings/js/JSHTMLEmbedElementCustom.cpp:
  • bindings/js/JSHTMLFormElementCustom.cpp:
  • bindings/js/JSHTMLFrameElementCustom.cpp:
  • bindings/js/JSHTMLFrameSetElementCustom.cpp:
  • bindings/js/JSHTMLIFrameElementCustom.cpp:
  • bindings/js/JSHTMLInputElementCustom.cpp:
  • bindings/js/JSHTMLObjectElementCustom.cpp:
  • bindings/js/JSHTMLOptionsCollectionCustom.cpp:
  • bindings/js/JSHTMLSelectElementCustom.cpp:
  • bindings/js/JSHTMLSelectElementCustom.h:
  • bindings/js/JSHistoryCustom.cpp:
  • bindings/js/JSImageDataCustom.cpp:
  • bindings/js/JSInspectedObjectWrapper.cpp:
  • bindings/js/JSInspectedObjectWrapper.h:
  • bindings/js/JSInspectorCallbackWrapper.cpp:
  • bindings/js/JSInspectorCallbackWrapper.h:
  • bindings/js/JSJavaScriptCallFrameCustom.cpp:
  • bindings/js/JSLocationCustom.cpp:
  • bindings/js/JSMessagePortCustom.cpp:
  • bindings/js/JSMimeTypeArrayCustom.cpp:
  • bindings/js/JSNamedNodeMapCustom.cpp:
  • bindings/js/JSNamedNodesCollection.cpp:
  • bindings/js/JSNamedNodesCollection.h:
  • bindings/js/JSNavigatorCustom.cpp:
  • bindings/js/JSNodeCustom.cpp:
  • bindings/js/JSNodeFilterCondition.cpp:
  • bindings/js/JSNodeFilterCondition.h:
  • bindings/js/JSNodeFilterCustom.cpp:
  • bindings/js/JSNodeIteratorCustom.cpp:
  • bindings/js/JSNodeListCustom.cpp:
  • bindings/js/JSPluginArrayCustom.cpp:
  • bindings/js/JSPluginCustom.cpp:
  • bindings/js/JSPluginElementFunctions.cpp:
  • bindings/js/JSPluginElementFunctions.h:
  • bindings/js/JSQuarantinedObjectWrapper.cpp:
  • bindings/js/JSQuarantinedObjectWrapper.h:
  • bindings/js/JSRGBColor.cpp:
  • bindings/js/JSRGBColor.h:
  • bindings/js/JSSQLResultSetRowListCustom.cpp:
  • bindings/js/JSSQLTransactionCustom.cpp:
  • bindings/js/JSSVGElementInstanceCustom.cpp:
  • bindings/js/JSSVGLengthCustom.cpp:
  • bindings/js/JSSVGMatrixCustom.cpp:
  • bindings/js/JSSVGPathSegCustom.cpp:
  • bindings/js/JSSVGPathSegListCustom.cpp:
  • bindings/js/JSSVGPointListCustom.cpp:
  • bindings/js/JSSVGTransformListCustom.cpp:
  • bindings/js/JSStorageCustom.cpp:
  • bindings/js/JSStyleSheetCustom.cpp:
  • bindings/js/JSStyleSheetListCustom.cpp:
  • bindings/js/JSTextCustom.cpp:
  • bindings/js/JSTreeWalkerCustom.cpp:
  • bindings/js/JSXMLHttpRequestCustom.cpp:
  • bindings/js/JSXMLHttpRequestUploadCustom.cpp:
  • bindings/js/JSXSLTProcessorCustom.cpp:
  • bindings/js/ScheduledAction.cpp:
  • bindings/js/ScheduledAction.h:
  • bindings/js/ScriptController.cpp:
  • bindings/js/ScriptController.h:
  • bindings/objc/WebScriptObject.mm:
  • bindings/objc/WebScriptObjectPrivate.h:
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/NP_jsobject.cpp:
  • bridge/c/c_instance.cpp:
  • bridge/c/c_instance.h:
  • bridge/c/c_runtime.cpp:
  • bridge/c/c_runtime.h:
  • bridge/c/c_utility.cpp:
  • bridge/c/c_utility.h:
  • bridge/jni/jni_instance.cpp:
  • bridge/jni/jni_instance.h:
  • bridge/jni/jni_jsobject.h:
  • bridge/jni/jni_jsobject.mm:
  • bridge/jni/jni_objc.mm:
  • bridge/jni/jni_runtime.cpp:
  • bridge/jni/jni_runtime.h:
  • bridge/jni/jni_utility.cpp:
  • bridge/jni/jni_utility.h:
  • bridge/objc/WebScriptObject.h:
  • bridge/objc/objc_class.h:
  • bridge/objc/objc_class.mm:
  • bridge/objc/objc_instance.h:
  • bridge/objc/objc_instance.mm:
  • bridge/objc/objc_runtime.h:
  • bridge/objc/objc_runtime.mm:
  • bridge/objc/objc_utility.h:
  • bridge/objc/objc_utility.mm:
  • bridge/qt/qt_class.cpp:
  • bridge/qt/qt_class.h:
  • bridge/qt/qt_instance.cpp:
  • bridge/qt/qt_instance.h:
  • bridge/qt/qt_runtime.cpp:
  • bridge/qt/qt_runtime.h:
  • bridge/runtime.cpp:
  • bridge/runtime.h:
  • bridge/runtime_array.cpp:
  • bridge/runtime_array.h:
  • bridge/runtime_method.cpp:
  • bridge/runtime_method.h:
  • bridge/runtime_object.cpp:
  • bridge/runtime_object.h:
  • bridge/testqtbindings.cpp:
  • inspector/JavaScriptCallFrame.cpp:
  • inspector/JavaScriptCallFrame.h:
  • inspector/JavaScriptProfile.cpp:
  • inspector/JavaScriptProfile.h:
  • inspector/JavaScriptProfileNode.cpp:
  • inspector/JavaScriptProfileNode.h:
  • loader/FrameLoader.cpp:
  • loader/FrameLoader.h:
  • page/Console.cpp:
  • page/Console.h:
  • plugins/MimeTypeArray.h:
  • plugins/Plugin.h:
  • plugins/PluginArray.h:
  • plugins/PluginView.cpp:
  • xml/XMLHttpRequest.cpp: Use JSValue* instead of JSValuePtr.

WebKit/mac:

2008-10-24 Darin Adler <Darin Adler>

  • WebView/WebFrame.mm: (-[WebFrame _stringByEvaluatingJavaScriptFromString:forceUserGesture:]):
  • WebView/WebScriptDebugDelegate.mm: (-[WebScriptCallFrame _convertValueToObjcValue:]): (-[WebScriptCallFrame exception]): (-[WebScriptCallFrame evaluateWebScript:]):
  • WebView/WebView.mm: (aeDescFromJSValue): (-[WebView aeDescByEvaluatingJavaScriptFromString:]): Use JSValue* instead of JSValuePtr.

WebKit/qt:

2008-10-24 Darin Adler <Darin Adler>

  • Api/qwebframe.cpp: (QWebFrame::evaluateJavaScript): Use JSValue* instead of JSValuePtr.

WebKit/win:

2008-10-24 Darin Adler <Darin Adler>

  • WebScriptCallFrame.cpp: (WebScriptCallFrame::jsValueToString): (WebScriptCallFrame::stringByEvaluatingJavaScriptFromString): (WebScriptCallFrame::valueForVariable): (WebScriptCallFrame::valueByEvaluatingJavaScriptFromString):
  • WebScriptCallFrame.h:
  • WebView.cpp: (WebView::stringByEvaluatingJavaScriptFromString): Use JSValue* instead of JSValuePtr.

WebKit/wx:

2008-10-24 Darin Adler <Darin Adler>

  • WebFrame.cpp: (wxWebFrame::RunScript): Use JSValue* instead of JSValuePtr.
  • Property svn:eol-style set to native
File size: 20.2 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef JSObject_h
24#define JSObject_h
25
26#include "ArgList.h"
27#include "ClassInfo.h"
28#include "CommonIdentifiers.h"
29#include "ExecState.h"
30#include "JSNumberCell.h"
31#include "PropertyMap.h"
32#include "PropertySlot.h"
33#include "PutPropertySlot.h"
34#include "ScopeChain.h"
35#include "StructureID.h"
36
37namespace JSC {
38
39 class InternalFunction;
40 class PropertyNameArray;
41 class StructureID;
42 struct HashEntry;
43 struct HashTable;
44
45 // ECMA 262-3 8.6.1
46 // Property attributes
47 enum Attribute {
48 None = 0,
49 ReadOnly = 1 << 1, // property can be only read, not written
50 DontEnum = 1 << 2, // property doesn't appear in (for .. in ..)
51 DontDelete = 1 << 3, // property can't be deleted
52 Function = 1 << 4, // property is a function - only used by static hashtables
53 };
54
55 class JSObject : public JSCell {
56 friend class BatchedTransitionOptimizer;
57 friend class CTI;
58 friend class JSCell;
59
60 public:
61 explicit JSObject(PassRefPtr<StructureID>);
62
63 virtual void mark();
64
65 // The inline virtual destructor cannot be the first virtual function declared
66 // in the class as it results in the vtable being generated as a weak symbol
67 virtual ~JSObject();
68
69 bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
70
71 JSValue* prototype() const;
72 void setPrototype(JSValue* prototype);
73
74 void setStructureID(PassRefPtr<StructureID>);
75 StructureID* inheritorID();
76
77 PropertyStorage& propertyStorage() { return m_propertyStorage; }
78
79 virtual UString className() const;
80
81 JSValue* get(ExecState*, const Identifier& propertyName) const;
82 JSValue* get(ExecState*, unsigned propertyName) const;
83
84 bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
85 bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
86
87 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
88 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
89
90 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value, PutPropertySlot&);
91 virtual void put(ExecState*, unsigned propertyName, JSValue* value);
92
93 virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
94 virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValue* value, unsigned attributes);
95
96 bool propertyIsEnumerable(ExecState*, const Identifier& propertyName) const;
97
98 bool hasProperty(ExecState*, const Identifier& propertyName) const;
99 bool hasProperty(ExecState*, unsigned propertyName) const;
100 bool hasOwnProperty(ExecState*, const Identifier& propertyName) const;
101
102 virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
103 virtual bool deleteProperty(ExecState*, unsigned propertyName);
104
105 virtual JSValue* defaultValue(ExecState*, PreferredPrimitiveType) const;
106
107 virtual bool hasInstance(ExecState*, JSValue*, JSValue* prototypeProperty);
108
109 virtual void getPropertyNames(ExecState*, PropertyNameArray&);
110
111 virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
112 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
113 virtual bool toBoolean(ExecState*) const;
114 virtual double toNumber(ExecState*) const;
115 virtual UString toString(ExecState*) const;
116 virtual JSObject* toObject(ExecState*) const;
117
118 virtual JSObject* toThisObject(ExecState*) const;
119 virtual JSGlobalObject* toGlobalObject(ExecState*) const;
120
121 virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
122
123 // This get function only looks at the property map.
124 JSValue* getDirect(const Identifier& propertyName) const
125 {
126 size_t offset = m_structureID->propertyMap().get(propertyName);
127 return offset != WTF::notFound ? m_propertyStorage[offset] : noValue();
128 }
129
130 JSValue** getDirectLocation(const Identifier& propertyName)
131 {
132 size_t offset = m_structureID->propertyMap().get(propertyName);
133 return offset != WTF::notFound ? locationForOffset(offset) : 0;
134 }
135
136 JSValue** getDirectLocation(const Identifier& propertyName, unsigned& attributes)
137 {
138 size_t offset = m_structureID->propertyMap().get(propertyName, attributes);
139 return offset != WTF::notFound ? locationForOffset(offset) : 0;
140 }
141
142 size_t offsetForLocation(JSValue** location)
143 {
144 return location - m_propertyStorage;
145 }
146
147 JSValue** locationForOffset(size_t offset)
148 {
149 return &m_propertyStorage[offset];
150 }
151
152 void transitionTo(StructureID*);
153
154 void removeDirect(const Identifier& propertyName);
155 bool hasCustomProperties() { return !m_structureID->propertyMap().isEmpty(); }
156 bool hasGetterSetterProperties() { return m_structureID->hasGetterSetterProperties(); }
157
158 void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
159 void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
160 void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
161 void putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
162 void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
163
164 // Fast access to known property offsets.
165 JSValue* getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
166 void putDirectOffset(size_t offset, JSValue* value) { m_propertyStorage[offset] = value; }
167
168 void fillGetterPropertySlot(PropertySlot&, JSValue** location);
169
170 virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
171 virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
172 virtual JSValue* lookupGetter(ExecState*, const Identifier& propertyName);
173 virtual JSValue* lookupSetter(ExecState*, const Identifier& propertyName);
174
175 virtual bool isGlobalObject() const { return false; }
176 virtual bool isVariableObject() const { return false; }
177 virtual bool isWatchdogException() const { return false; }
178 virtual bool isNotAnObjectErrorStub() const { return false; }
179
180 void allocatePropertyStorage(size_t oldSize, size_t newSize);
181 void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
182 bool usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; }
183
184 static const size_t inlineStorageCapacity = 2;
185 static const size_t nonInlineBaseStorageCapacity = 16;
186
187 static PassRefPtr<StructureID> createStructureID(JSValue* prototype)
188 {
189 return StructureID::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
190 }
191
192 protected:
193 bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
194
195 private:
196 bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
197
198 const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
199 StructureID* createInheritorID();
200
201 RefPtr<StructureID> m_inheritorID;
202
203 PropertyStorage m_propertyStorage;
204 JSValue* m_inlineStorage[inlineStorageCapacity];
205 };
206
207 JSObject* asObject(JSValue*);
208
209 JSObject* constructEmptyObject(ExecState*);
210
211inline JSObject* asObject(JSValue* value)
212{
213 ASSERT(asCell(value)->isObject());
214 return static_cast<JSObject*>(asCell(value));
215}
216
217inline JSObject::JSObject(PassRefPtr<StructureID> structureID)
218 : JSCell(structureID.releaseRef()) // ~JSObject balances this ref()
219 , m_propertyStorage(m_inlineStorage)
220{
221 ASSERT(m_structureID);
222 ASSERT(m_structureID->propertyStorageCapacity() == inlineStorageCapacity);
223 ASSERT(m_structureID->propertyMap().isEmpty());
224 ASSERT(prototype()->isNull() || Heap::heap(this) == Heap::heap(prototype()));
225}
226
227inline JSObject::~JSObject()
228{
229 ASSERT(m_structureID);
230 if (m_propertyStorage != m_inlineStorage)
231 delete [] m_propertyStorage;
232 m_structureID->deref();
233}
234
235inline JSValue* JSObject::prototype() const
236{
237 return m_structureID->storedPrototype();
238}
239
240inline void JSObject::setPrototype(JSValue* prototype)
241{
242 ASSERT(prototype);
243 RefPtr<StructureID> newStructureID = StructureID::changePrototypeTransition(m_structureID, prototype);
244 setStructureID(newStructureID.release());
245}
246
247inline void JSObject::setStructureID(PassRefPtr<StructureID> structureID)
248{
249 m_structureID->deref();
250 m_structureID = structureID.releaseRef(); // ~JSObject balances this ref()
251}
252
253inline StructureID* JSObject::inheritorID()
254{
255 if (m_inheritorID)
256 return m_inheritorID.get();
257 return createInheritorID();
258}
259
260inline bool JSCell::isObject(const ClassInfo* info) const
261{
262 for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) {
263 if (ci == info)
264 return true;
265 }
266 return false;
267}
268
269// this method is here to be after the inline declaration of JSCell::isObject
270inline bool JSValue::isObject(const ClassInfo* classInfo) const
271{
272 return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(classInfo);
273}
274
275ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
276{
277 if (JSValue** location = getDirectLocation(propertyName)) {
278 if (m_structureID->hasGetterSetterProperties() && location[0]->isGetterSetter())
279 fillGetterPropertySlot(slot, location);
280 else
281 slot.setValueSlot(this, location, offsetForLocation(location));
282 return true;
283 }
284
285 // non-standard Netscape extension
286 if (propertyName == exec->propertyNames().underscoreProto) {
287 slot.setValue(prototype());
288 return true;
289 }
290
291 return false;
292}
293
294ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
295{
296 unsigned attributes;
297 if (JSValue** location = getDirectLocation(propertyName, attributes)) {
298 if (m_structureID->hasGetterSetterProperties() && location[0]->isGetterSetter()) {
299 slotIsWriteable = false;
300 fillGetterPropertySlot(slot, location);
301 } else {
302 slotIsWriteable = !(attributes & ReadOnly);
303 slot.setValueSlot(this, location, offsetForLocation(location));
304 }
305 return true;
306 }
307
308 // non-standard Netscape extension
309 if (propertyName == exec->propertyNames().underscoreProto) {
310 slot.setValue(prototype());
311 slotIsWriteable = false;
312 return true;
313 }
314
315 return false;
316}
317
318// It may seem crazy to inline a function this large, especially a virtual function,
319// but it makes a big difference to property lookup that derived classes can inline their
320// base class call to this.
321ALWAYS_INLINE bool JSObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
322{
323 return inlineGetOwnPropertySlot(exec, propertyName, slot);
324}
325
326ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
327{
328 if (structureID()->typeInfo().hasStandardGetOwnPropertySlot())
329 return asObject(this)->inlineGetOwnPropertySlot(exec, propertyName, slot);
330 return getOwnPropertySlot(exec, propertyName, slot);
331}
332
333// It may seem crazy to inline a function this large but it makes a big difference
334// since this is function very hot in variable lookup
335inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
336{
337 JSObject* object = this;
338 while (true) {
339 if (object->fastGetOwnPropertySlot(exec, propertyName, slot))
340 return true;
341 JSValue* prototype = object->prototype();
342 if (!prototype->isObject())
343 return false;
344 object = asObject(prototype);
345 }
346}
347
348inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
349{
350 JSObject* object = this;
351 while (true) {
352 if (object->getOwnPropertySlot(exec, propertyName, slot))
353 return true;
354 JSValue* prototype = object->prototype();
355 if (!prototype->isObject())
356 return false;
357 object = asObject(prototype);
358 }
359}
360
361inline JSValue* JSObject::get(ExecState* exec, const Identifier& propertyName) const
362{
363 PropertySlot slot(this);
364 if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
365 return slot.getValue(exec, propertyName);
366
367 return jsUndefined();
368}
369
370inline JSValue* JSObject::get(ExecState* exec, unsigned propertyName) const
371{
372 PropertySlot slot(this);
373 if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
374 return slot.getValue(exec, propertyName);
375
376 return jsUndefined();
377}
378
379inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attr)
380{
381 PutPropertySlot slot;
382 putDirect(propertyName, value, attr, false, slot);
383}
384
385inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
386{
387 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
388
389 if (m_structureID->isDictionary()) {
390 unsigned currentAttributes;
391 size_t offset = m_structureID->propertyMap().get(propertyName, currentAttributes);
392 if (offset != WTF::notFound) {
393 if (checkReadOnly && currentAttributes & ReadOnly)
394 return;
395 m_propertyStorage[offset] = value;
396 slot.setExistingProperty(this, offset);
397 return;
398 }
399
400 size_t currentCapacity = m_structureID->propertyStorageCapacity();
401 offset = m_structureID->propertyMap().put(propertyName, attributes);
402 if (m_structureID->propertyMap().storageSize() > m_structureID->propertyStorageCapacity()) {
403 m_structureID->growPropertyStorageCapacity();
404 allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
405 }
406
407 m_propertyStorage[offset] = value;
408 slot.setNewProperty(this, offset);
409 m_structureID->clearEnumerationCache();
410 return;
411 }
412
413 unsigned currentAttributes;
414 size_t offset = m_structureID->propertyMap().get(propertyName, currentAttributes);
415 if (offset != WTF::notFound) {
416 if (checkReadOnly && currentAttributes & ReadOnly)
417 return;
418 m_propertyStorage[offset] = value;
419 slot.setExistingProperty(this, offset);
420 return;
421 }
422
423 size_t currentCapacity = m_structureID->propertyStorageCapacity();
424 RefPtr<StructureID> structureID = StructureID::addPropertyTransition(m_structureID, propertyName, attributes, offset);
425 if (currentCapacity != structureID->propertyStorageCapacity())
426 allocatePropertyStorage(currentCapacity, structureID->propertyStorageCapacity());
427
428 ASSERT(offset < structureID->propertyStorageCapacity());
429 m_propertyStorage[offset] = value;
430 slot.setNewProperty(this, offset);
431 slot.setWasTransition(true);
432 setStructureID(structureID.release());
433}
434
435inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attributes)
436{
437 size_t currentCapacity = m_structureID->propertyStorageCapacity();
438 size_t offset = m_structureID->addPropertyWithoutTransition(propertyName, attributes);
439 if (currentCapacity != m_structureID->propertyStorageCapacity())
440 allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
441 m_propertyStorage[offset] = value;
442}
443
444inline void JSObject::transitionTo(StructureID* newStructureID)
445{
446 if (m_structureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity())
447 allocatePropertyStorage(m_structureID->propertyStorageCapacity(), newStructureID->propertyStorageCapacity());
448 setStructureID(newStructureID);
449}
450
451inline JSValue* JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
452{
453 return defaultValue(exec, preferredType);
454}
455
456inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName) const
457{
458 PropertySlot slot(this);
459 return get(exec, propertyName, slot);
460}
461
462inline JSValue* JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
463{
464 if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
465 JSObject* prototype = JSImmediate::prototype(asValue(), exec);
466 if (!prototype->getPropertySlot(exec, propertyName, slot))
467 return jsUndefined();
468 return slot.getValue(exec, propertyName);
469 }
470 JSCell* cell = asCell();
471 while (true) {
472 if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
473 return slot.getValue(exec, propertyName);
474 ASSERT(cell->isObject());
475 JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
476 if (!prototype->isObject())
477 return jsUndefined();
478 cell = asObject(prototype);
479 }
480}
481
482inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName) const
483{
484 PropertySlot slot(this);
485 return get(exec, propertyName, slot);
486}
487
488inline JSValue* JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
489{
490 if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
491 JSObject* prototype = JSImmediate::prototype(asValue(), exec);
492 if (!prototype->getPropertySlot(exec, propertyName, slot))
493 return jsUndefined();
494 return slot.getValue(exec, propertyName);
495 }
496 JSCell* cell = const_cast<JSCell*>(asCell());
497 while (true) {
498 if (cell->getOwnPropertySlot(exec, propertyName, slot))
499 return slot.getValue(exec, propertyName);
500 ASSERT(cell->isObject());
501 JSValue* prototype = static_cast<JSObject*>(cell)->prototype();
502 if (!prototype->isObject())
503 return jsUndefined();
504 cell = prototype->asCell();
505 }
506}
507
508inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue* value, PutPropertySlot& slot)
509{
510 if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
511 JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
512 return;
513 }
514 asCell()->put(exec, propertyName, value, slot);
515}
516
517inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue* value)
518{
519 if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
520 JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
521 return;
522 }
523 asCell()->put(exec, propertyName, value);
524}
525
526ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_t newSize)
527{
528 ASSERT(newSize > oldSize);
529
530 JSValue** oldPropertyStorage = m_propertyStorage;
531 m_propertyStorage = new JSValue*[newSize];
532
533 for (unsigned i = 0; i < oldSize; ++i)
534 m_propertyStorage[i] = oldPropertyStorage[i];
535
536 if (oldPropertyStorage != m_inlineStorage)
537 delete [] oldPropertyStorage;
538}
539
540} // namespace JSC
541
542#endif // JSObject_h
Note: See TracBrowser for help on using the repository browser.