2 * Copyright (C) 2003 Apple Computer, 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 "runtime_method.h"
30 #include "runtime_root.h"
33 using namespace Bindings;
35 const ClassInfo RuntimeObjectImp::info = { "RuntimeObject", 0, 0 };
37 RuntimeObjectImp::RuntimeObjectImp(PassRefPtr<Bindings::Instance> i)
40 instance->rootObject()->addRuntimeObject(this);
41 Collector::collectOnMainThreadOnly(this);
44 RuntimeObjectImp::~RuntimeObjectImp()
47 instance->rootObject()->removeRuntimeObject(this);
50 void RuntimeObjectImp::invalidate()
56 JSValue *RuntimeObjectImp::fallbackObjectGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
58 RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
59 RefPtr<Bindings::Instance> instance = thisObj->instance;
62 return throwInvalidAccessError(exec);
66 Class *aClass = instance->getClass();
67 JSValue* result = aClass->fallbackObject(exec, instance.get(), propertyName);
74 JSValue *RuntimeObjectImp::fieldGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
76 RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
77 RefPtr<Bindings::Instance> instance = thisObj->instance;
80 return throwInvalidAccessError(exec);
84 Class *aClass = instance->getClass();
85 Field* aField = aClass->fieldNamed(propertyName, instance.get());
86 JSValue *result = instance->getValueOfField(exec, aField);
93 JSValue *RuntimeObjectImp::methodGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
95 RuntimeObjectImp *thisObj = static_cast<RuntimeObjectImp *>(slot.slotBase());
96 RefPtr<Bindings::Instance> instance = thisObj->instance;
99 return throwInvalidAccessError(exec);
103 Class *aClass = instance->getClass();
104 MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
105 JSValue *result = new RuntimeMethod(exec, propertyName, methodList);
112 bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
115 throwInvalidAccessError(exec);
121 Class *aClass = instance->getClass();
124 // See if the instance has a field with the specified name.
125 Field *aField = aClass->fieldNamed(propertyName, instance.get());
127 slot.setCustom(this, fieldGetter);
131 // Now check if a method with specified name exists, if so return a function object for
133 MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
134 if (methodList.size() > 0) {
135 slot.setCustom(this, methodGetter);
142 // Try a fallback object.
143 if (!aClass->fallbackObject(exec, instance.get(), propertyName)->isUndefined()) {
144 slot.setCustom(this, fallbackObjectGetter);
152 // don't call superclass, because runtime objects can't have custom properties or a prototype
156 void RuntimeObjectImp::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
159 throwInvalidAccessError(exec);
163 RefPtr<Bindings::Instance> protector(instance);
166 // Set the value of the property.
167 Field *aField = instance->getClass()->fieldNamed(propertyName, instance.get());
169 instance->setValueOfField(exec, aField, value);
170 else if (instance->supportsSetValueOfUndefinedField())
171 instance->setValueOfUndefinedField(exec, propertyName, value);
176 bool RuntimeObjectImp::deleteProperty(ExecState*, const Identifier&)
178 // Can never remove a property of a RuntimeObject.
182 JSValue *RuntimeObjectImp::defaultValue(ExecState* exec, JSType hint) const
185 return throwInvalidAccessError(exec);
189 RefPtr<Bindings::Instance> protector(instance);
192 result = instance->defaultValue(hint);
199 bool RuntimeObjectImp::implementsCall() const
204 return instance->implementsCall();
207 JSValue *RuntimeObjectImp::callAsFunction(ExecState* exec, JSObject*, const List& args)
210 return throwInvalidAccessError(exec);
212 RefPtr<Bindings::Instance> protector(instance);
215 JSValue *aValue = instance->invokeDefaultMethod(exec, args);
222 void RuntimeObjectImp::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
225 throwInvalidAccessError(exec);
230 instance->getPropertyNames(exec, propertyNames);
234 JSObject* RuntimeObjectImp::throwInvalidAccessError(ExecState* exec)
236 return throwError(exec, ReferenceError, "Trying to access object from destroyed plug-in.");