JSCallbackObjectFunctions.h revision 2fc2651226baac27029e38c9d6ef883fa32084db
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "APIShims.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "APICast.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Error.h"
30545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "ExceptionHelpers.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSCallbackFunction.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSClassRef.h"
335af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke#include "JSFunction.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSGlobalObject.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSLock.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSObjectRef.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSString.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSStringRef.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "OpaqueJSString.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PropertyNameArray.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h>
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianinline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValue value)
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(asObject(value)->inherits(&info));
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<JSCallbackObject*>(asObject(value));
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
53e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockJSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, JSClassRef jsClass, void* data)
54e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    : Base(globalObject, structure)
55e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(data, jsClass)))
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    init(exec);
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Global object constructor.
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
63e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockJSCallbackObject<Base>::JSCallbackObject(JSClassRef jsClass, NonNullPassRefPtr<Structure> structure)
64e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block    : Base(structure)
65e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass)))
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(Base::isGlobalObject());
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    init(static_cast<JSGlobalObject*>(this)->globalExec());
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid JSCallbackObject<Base>::init(ExecState* exec)
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(exec);
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<JSObjectInitializeCallback, 16> initRoutines;
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassRef jsClass = classRef();
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectInitializeCallback initialize = jsClass->initialize)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            initRoutines.append(initialize);
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while ((jsClass = jsClass->parentClass));
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // initialize from base to derived
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) {
85d0825bca7fe65beaee391d30da42e937db621564Steve Block        APICallbackShim callbackShim(exec);
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSObjectInitializeCallback initialize = initRoutines[i];
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initialize(toRef(exec), toRef(this));
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectJSCallbackObject<Base>::~JSCallbackObject()
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectFinalizeCallback finalize = jsClass->finalize)
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            finalize(thisRef);
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString JSCallbackObject<Base>::className() const
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UString thisClassName = classRef()->className();
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!thisClassName.isEmpty())
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return thisClassName;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::className();
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // optional optimization to bypass getProperty in cases when we only need to know if the property exists
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
123d0825bca7fe65beaee391d30da42e937db621564Steve Block            APICallbackShim callbackShim(exec);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                slot.setCustom(this, callbackGetter);
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
1318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
1335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
134d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
1365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (exception) {
138545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                slot.setValue(jsUndefined());
1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return true;
1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (value) {
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                slot.setValue(toJS(exec, value));
144643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return true;
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
149f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (staticValues->contains(propertyName.impl())) {
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                slot.setCustom(this, staticValueGetter);
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
156f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (staticFunctions->contains(propertyName.impl())) {
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                slot.setCustom(this, staticFunctionGetter);
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::getOwnPropertySlot(exec, propertyName, slot);
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
167d0825bca7fe65beaee391d30da42e937db621564Steve Blockbool JSCallbackObject<Base>::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
168d0825bca7fe65beaee391d30da42e937db621564Steve Block{
169d0825bca7fe65beaee391d30da42e937db621564Steve Block    PropertySlot slot;
170d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (getOwnPropertySlot(exec, propertyName, slot)) {
171d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Ideally we should return an access descriptor, but returning a value descriptor is better than nothing.
172d0825bca7fe65beaee391d30da42e937db621564Steve Block        JSValue value = slot.getValue(exec, propertyName);
173d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!exec->hadException())
174d0825bca7fe65beaee391d30da42e937db621564Steve Block            descriptor.setValue(value);
175d0825bca7fe65beaee391d30da42e937db621564Steve Block        // We don't know whether the property is configurable, but assume it is.
176d0825bca7fe65beaee391d30da42e937db621564Steve Block        descriptor.setConfigurable(true);
177d0825bca7fe65beaee391d30da42e937db621564Steve Block        // We don't know whether the property is enumerable (we could call getOwnPropertyNames() to find out), but assume it isn't.
178d0825bca7fe65beaee391d30da42e937db621564Steve Block        descriptor.setEnumerable(false);
179d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
180d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
181d0825bca7fe65beaee391d30da42e937db621564Steve Block
182d0825bca7fe65beaee391d30da42e937db621564Steve Block    return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
183d0825bca7fe65beaee391d30da42e937db621564Steve Block}
184d0825bca7fe65beaee391d30da42e937db621564Steve Block
185d0825bca7fe65beaee391d30da42e937db621564Steve Blocktemplate <class Base>
1865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
1915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSValueRef valueRef = toRef(exec, value);
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
1978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
1985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            bool result;
1995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
200d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
2015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
204545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (result || exception)
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
210f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeReadOnly)
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return;
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!propertyNameRef)
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
2168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    JSValueRef exception = 0;
2175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    bool result;
2185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    {
219d0825bca7fe65beaee391d30da42e937db621564Steve Block                        APICallbackShim callbackShim(exec);
2205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
2215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    }
222643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    if (exception)
223545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                        throwError(exec, toJS(exec, exception));
2248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (result || exception)
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return;
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
227545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                    throwError(exec, createReferenceError(exec, "Attempt to set a property that is not settable."));
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
232f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeReadOnly)
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return;
2352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                JSCallbackObject<Base>::putDirect(exec->globalData(), propertyName, value); // put as override property
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::put(exec, propertyName, value, slot);
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& propertyName)
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
2565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            bool result;
2575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
258d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
2595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
261643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
262545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (result || exception)
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
268f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeDontDelete)
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
276f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeDontDelete)
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::deleteProperty(exec, propertyName);
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyName)
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return deleteProperty(exec, Identifier::from(exec, propertyName));
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectConstructType JSCallbackObject<Base>::getConstructData(ConstructData& constructData)
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (jsClass->callAsConstructor) {
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            constructData.native.function = construct;
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return ConstructTypeHost;
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ConstructTypeNone;
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
306545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSCallbackObject<Base>::construct(ExecState* exec)
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
308545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    JSObject* constructor = exec->callee();
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef constructorRef = toRef(constructor);
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
314545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            int argumentCount = static_cast<int>(exec->argumentCount());
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Vector<JSValueRef, 16> arguments(argumentCount);
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i = 0; i < argumentCount; i++)
317545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                arguments[i] = toRef(exec, exec->argument(i));
3188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
3195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSObject* result;
3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
321d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
325545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
326545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return JSValue::encode(result);
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here
331545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(JSValue());
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
3355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValue value, JSValue)
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
3420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JSValueRef valueRef = toRef(exec, value);
3438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
3445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            bool result;
3455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
346d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
3470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                result = hasInstance(execRef, thisRef, valueRef, &exception);
3485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
349643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
350545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
3518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return result;
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCallType JSCallbackObject<Base>::getCallData(CallData& callData)
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (jsClass->callAsFunction) {
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            callData.native.function = call;
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return CallTypeHost;
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return CallTypeNone;
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
370545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSCallbackObject<Base>::call(ExecState* exec)
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
3735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectRef functionRef = toRef(exec->callee());
3745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
3785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            int argumentCount = static_cast<int>(exec->argumentCount());
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Vector<JSValueRef, 16> arguments(argumentCount);
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i = 0; i < argumentCount; i++)
3815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                arguments[i] = toRef(exec, exec->argument(i));
3828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
3835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValue result;
3845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
385d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
3875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
388643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
389545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
390545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return JSValue::encode(result);
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
395545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(JSValue());
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
399d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) {
406d0825bca7fe65beaee391d30da42e937db621564Steve Block            APICallbackShim callbackShim(exec);
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            getPropertyNames(execRef, thisRef, toRef(&propertyNames));
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            typedef OpaqueJSClassStaticValuesTable::const_iterator iterator;
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            iterator end = staticValues->end();
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (iterator it = staticValues->begin(); it != end; ++it) {
414f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                StringImpl* name = it->first.get();
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                StaticValueEntry* entry = it->second;
416d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    propertyNames.add(Identifier(exec, name));
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            typedef OpaqueJSClassStaticFunctionsTable::const_iterator iterator;
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            iterator end = staticFunctions->end();
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (iterator it = staticFunctions->begin(); it != end; ++it) {
425f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                StringImpl* name = it->first.get();
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                StaticFunctionEntry* entry = it->second;
427d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    propertyNames.add(Identifier(exec, name));
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
433d0825bca7fe65beaee391d30da42e937db621564Steve Block    Base::getOwnPropertyNames(exec, propertyNames, mode);
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble JSCallbackObject<Base>::toNumber(ExecState* exec) const
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need this check to guard against the case where this object is rhs of
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a binary expression where lhs threw an exception in its conversion to
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // primitive
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (exec->hadException())
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NaN;
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
4498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
4505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
4515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
452d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
4535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                value = convertToType(ctx, thisRef, kJSTypeNumber, &exception);
4545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
4550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (exception) {
456545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
4570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                return 0;
458635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
4590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            double dValue;
461643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (value)
462643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return toJS(exec, value).getNumber(dValue) ? dValue : NaN;
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::toNumber(exec);
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString JSCallbackObject<Base>::toString(ExecState* exec) const
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
4768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
4775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
479d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
4808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                value = convertToType(ctx, thisRef, kJSTypeString, &exception);
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (exception) {
483545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
4848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return "";
4850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
486643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (value)
487643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return toJS(exec, value).getString(exec);
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::toString(exec);
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid JSCallbackObject<Base>::setPrivate(void* data)
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_callbackObjectData->privateData = data;
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid* JSCallbackObject<Base>::getPrivate()
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_callbackObjectData->privateData;
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::inherits(JSClassRef c) const
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (jsClass == c)
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
516dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
518dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSCallbackObject* thisObj = asCallbackObject(slotBase);
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(thisObj);
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass)
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec))
525f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticValueEntry* entry = staticValues->get(propertyName.impl()))
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!propertyNameRef)
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
5298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    JSValueRef exception = 0;
5305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    JSValueRef value;
5315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    {
532d0825bca7fe65beaee391d30da42e937db621564Steve Block                        APICallbackShim callbackShim(exec);
5335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
5345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    }
535643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    if (exception) {
536545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                        throwError(exec, toJS(exec, exception));
537643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        return jsUndefined();
538643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    }
5398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (value)
5405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        return toJS(exec, value);
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
542643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
543545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return throwError(exec, createReferenceError(exec, "Static value property defined with NULL getProperty callback."));
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
547dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
549dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSCallbackObject* thisObj = asCallbackObject(slotBase);
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check for cached or override property.
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PropertySlot slot2(thisObj);
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (thisObj->Base::getOwnPropertySlot(exec, propertyName, slot2))
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return slot2.getValue(exec, propertyName);
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
558f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
560e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
561e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                    JSObject* o = new (exec) JSCallbackFunction(exec, asGlobalObject(thisObj->getAnonymousValue(0)), callAsFunction, propertyName);
5622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    thisObj->putDirect(exec->globalData(), propertyName, o, entry->attributes);
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return o;
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
569545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return throwError(exec, createReferenceError(exec, "Static function property defined with NULL callAsFunction callback."));
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
573dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
575dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSCallbackObject* thisObj = asCallbackObject(slotBase);
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(thisObj);
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass)
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
5848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
5855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
5865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
587d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
5895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
590643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception) {
591545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
592643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return jsUndefined();
593643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
5948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (value)
5955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return toJS(exec, value);
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
598545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return throwError(exec, createReferenceError(exec, "hasProperty callback returned true for a property that doesn't exist."));
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
602