2 * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "runtime_object.h"
29 #include "JSDOMBinding.h"
30 #include "runtime_method.h"
31 #include <runtime/Error.h>
32 #include <runtime/ObjectPrototype.h>
34 using namespace WebCore
;
38 using namespace Bindings
;
40 const ClassInfo
RuntimeObjectImp::s_info
= { "RuntimeObject", 0, 0, 0 };
42 RuntimeObjectImp::RuntimeObjectImp(ExecState
* exec
, PassRefPtr
<Instance
> instance
)
43 // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object
44 // We need to pass in the right global object for "i".
45 : JSObject(deprecatedGetDOMStructure
<RuntimeObjectImp
>(exec
))
46 , m_instance(instance
)
50 RuntimeObjectImp::RuntimeObjectImp(ExecState
*, NonNullPassRefPtr
<Structure
> structure
, PassRefPtr
<Instance
> instance
)
52 , m_instance(instance
)
56 RuntimeObjectImp::~RuntimeObjectImp()
59 m_instance
->willDestroyRuntimeObject();
62 void RuntimeObjectImp::invalidate()
66 m_instance
->willInvalidateRuntimeObject();
70 JSValue
RuntimeObjectImp::fallbackObjectGetter(ExecState
* exec
, const Identifier
& propertyName
, const PropertySlot
& slot
)
72 RuntimeObjectImp
* thisObj
= static_cast<RuntimeObjectImp
*>(asObject(slot
.slotBase()));
73 RefPtr
<Instance
> instance
= thisObj
->m_instance
;
76 return throwInvalidAccessError(exec
);
80 Class
*aClass
= instance
->getClass();
81 JSValue result
= aClass
->fallbackObject(exec
, instance
.get(), propertyName
);
88 JSValue
RuntimeObjectImp::fieldGetter(ExecState
* exec
, const Identifier
& propertyName
, const PropertySlot
& slot
)
90 RuntimeObjectImp
* thisObj
= static_cast<RuntimeObjectImp
*>(asObject(slot
.slotBase()));
91 RefPtr
<Instance
> instance
= thisObj
->m_instance
;
94 return throwInvalidAccessError(exec
);
98 Class
*aClass
= instance
->getClass();
99 Field
* aField
= aClass
->fieldNamed(propertyName
, instance
.get());
100 JSValue result
= aField
->valueFromInstance(exec
, instance
.get());
107 JSValue
RuntimeObjectImp::methodGetter(ExecState
* exec
, const Identifier
& propertyName
, const PropertySlot
& slot
)
109 RuntimeObjectImp
* thisObj
= static_cast<RuntimeObjectImp
*>(asObject(slot
.slotBase()));
110 RefPtr
<Instance
> instance
= thisObj
->m_instance
;
113 return throwInvalidAccessError(exec
);
117 Class
*aClass
= instance
->getClass();
118 MethodList methodList
= aClass
->methodsNamed(propertyName
, instance
.get());
119 JSValue result
= new (exec
) RuntimeMethod(exec
, propertyName
, methodList
);
126 bool RuntimeObjectImp::getOwnPropertySlot(ExecState
*exec
, const Identifier
& propertyName
, PropertySlot
& slot
)
129 throwInvalidAccessError(exec
);
133 RefPtr
<Instance
> instance
= m_instance
;
137 Class
*aClass
= instance
->getClass();
140 // See if the instance has a field with the specified name.
141 Field
*aField
= aClass
->fieldNamed(propertyName
, instance
.get());
143 slot
.setCustom(this, fieldGetter
);
147 // Now check if a method with specified name exists, if so return a function object for
149 MethodList methodList
= aClass
->methodsNamed(propertyName
, instance
.get());
150 if (methodList
.size() > 0) {
151 slot
.setCustom(this, methodGetter
);
158 // Try a fallback object.
159 if (!aClass
->fallbackObject(exec
, instance
.get(), propertyName
).isUndefined()) {
160 slot
.setCustom(this, fallbackObjectGetter
);
168 return instance
->getOwnPropertySlot(this, exec
, propertyName
, slot
);
171 bool RuntimeObjectImp::getOwnPropertyDescriptor(ExecState
*exec
, const Identifier
& propertyName
, PropertyDescriptor
& descriptor
)
174 throwInvalidAccessError(exec
);
178 RefPtr
<Instance
> instance
= m_instance
;
181 Class
*aClass
= instance
->getClass();
184 // See if the instance has a field with the specified name.
185 Field
*aField
= aClass
->fieldNamed(propertyName
, instance
.get());
188 slot
.setCustom(this, fieldGetter
);
190 descriptor
.setDescriptor(slot
.getValue(exec
, propertyName
), DontDelete
);
193 // Now check if a method with specified name exists, if so return a function object for
195 MethodList methodList
= aClass
->methodsNamed(propertyName
, instance
.get());
196 if (methodList
.size() > 0) {
198 slot
.setCustom(this, methodGetter
);
200 descriptor
.setDescriptor(slot
.getValue(exec
, propertyName
), DontDelete
| ReadOnly
);
205 // Try a fallback object.
206 if (!aClass
->fallbackObject(exec
, instance
.get(), propertyName
).isUndefined()) {
208 slot
.setCustom(this, fallbackObjectGetter
);
210 descriptor
.setDescriptor(slot
.getValue(exec
, propertyName
), DontDelete
| ReadOnly
| DontEnum
);
217 return instance
->getOwnPropertyDescriptor(this, exec
, propertyName
, descriptor
);
220 void RuntimeObjectImp::put(ExecState
* exec
, const Identifier
& propertyName
, JSValue value
, PutPropertySlot
& slot
)
223 throwInvalidAccessError(exec
);
227 RefPtr
<Instance
> instance
= m_instance
;
230 // Set the value of the property.
231 Field
*aField
= instance
->getClass()->fieldNamed(propertyName
, instance
.get());
233 aField
->setValueToInstance(exec
, instance
.get(), value
);
234 else if (!instance
->setValueOfUndefinedField(exec
, propertyName
, value
))
235 instance
->put(this, exec
, propertyName
, value
, slot
);
240 bool RuntimeObjectImp::deleteProperty(ExecState
*, const Identifier
&)
242 // Can never remove a property of a RuntimeObject.
246 JSValue
RuntimeObjectImp::defaultValue(ExecState
* exec
, PreferredPrimitiveType hint
) const
249 return throwInvalidAccessError(exec
);
251 RefPtr
<Instance
> instance
= m_instance
;
254 JSValue result
= instance
->defaultValue(exec
, hint
);
259 static JSValue JSC_HOST_CALL
callRuntimeObject(ExecState
* exec
, JSObject
* function
, JSValue
, const ArgList
& args
)
261 RefPtr
<Instance
> instance(static_cast<RuntimeObjectImp
*>(function
)->getInternalInstance());
263 JSValue result
= instance
->invokeDefaultMethod(exec
, args
);
268 CallType
RuntimeObjectImp::getCallData(CallData
& callData
)
273 RefPtr
<Instance
> instance
= m_instance
;
274 if (!instance
->supportsInvokeDefaultMethod())
277 callData
.native
.function
= callRuntimeObject
;
281 static JSObject
* callRuntimeConstructor(ExecState
* exec
, JSObject
* constructor
, const ArgList
& args
)
283 RefPtr
<Instance
> instance(static_cast<RuntimeObjectImp
*>(constructor
)->getInternalInstance());
285 JSValue result
= instance
->invokeConstruct(exec
, args
);
289 return result
.isObject() ? static_cast<JSObject
*>(result
.asCell()) : constructor
;
292 ConstructType
RuntimeObjectImp::getConstructData(ConstructData
& constructData
)
295 return ConstructTypeNone
;
297 RefPtr
<Instance
> instance
= m_instance
;
298 if (!instance
->supportsConstruct())
299 return ConstructTypeNone
;
301 constructData
.native
.function
= callRuntimeConstructor
;
302 return ConstructTypeHost
;
305 void RuntimeObjectImp::getPropertyNames(ExecState
* exec
, PropertyNameArray
& propertyNames
)
308 throwInvalidAccessError(exec
);
312 RefPtr
<Instance
> instance
= m_instance
;
315 instance
->getPropertyNames(exec
, propertyNames
);
319 void RuntimeObjectImp::getOwnPropertyNames(ExecState
* exec
, PropertyNameArray
& propertyNames
)
321 getOwnPropertyNames(exec
, propertyNames
);
324 JSObject
* RuntimeObjectImp::throwInvalidAccessError(ExecState
* exec
)
326 return throwError(exec
, ReferenceError
, "Trying to access object from destroyed plug-in.");