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{
4881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(asObject(value)->inherits(&s_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>
532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochJSCallbackObject<Base>::JSCallbackObject(ExecState* exec, JSGlobalObject* globalObject, 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{
5781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(Base::inherits(&s_info));
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    init(exec);
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Global object constructor.
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one.
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochJSCallbackObject<Base>::JSCallbackObject(JSGlobalData& globalData, JSClassRef jsClass, Structure* structure)
652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    : Base(globalData, structure)
66e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass)))
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(Base::inherits(&s_info));
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(Base::isGlobalObject());
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    init(static_cast<JSGlobalObject*>(this)->globalExec());
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid JSCallbackObject<Base>::init(ExecState* exec)
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(exec);
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<JSObjectInitializeCallback, 16> initRoutines;
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassRef jsClass = classRef();
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    do {
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectInitializeCallback initialize = jsClass->initialize)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            initRoutines.append(initialize);
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } while ((jsClass = jsClass->parentClass));
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // initialize from base to derived
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) {
87d0825bca7fe65beaee391d30da42e937db621564Steve Block        APICallbackShim callbackShim(exec);
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSObjectInitializeCallback initialize = initRoutines[i];
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        initialize(toRef(exec), toRef(this));
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool needsFinalizer = false;
932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    for (JSClassRef jsClassPtr = classRef(); jsClassPtr && !needsFinalizer; jsClassPtr = jsClassPtr->parentClass)
942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        needsFinalizer = jsClassPtr->finalize;
952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (needsFinalizer) {
962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        HandleSlot slot = exec->globalData().allocateGlobalHandle();
972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        HandleHeap::heapFor(slot)->makeWeak(slot, m_callbackObjectData.get(), classRef());
982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        HandleHeap::heapFor(slot)->writeBarrier(slot, this);
992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        *slot = this;
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString JSCallbackObject<Base>::className() const
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UString thisClassName = classRef()->className();
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!thisClassName.isEmpty())
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return thisClassName;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::className();
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // optional optimization to bypass getProperty in cases when we only need to know if the property exists
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
125d0825bca7fe65beaee391d30da42e937db621564Steve Block            APICallbackShim callbackShim(exec);
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                slot.setCustom(this, callbackGetter);
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
1338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
136d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
1375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
1385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (exception) {
140545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                slot.setValue(jsUndefined());
1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return true;
1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
144643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (value) {
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                slot.setValue(toJS(exec, value));
146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return true;
147643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
151f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (staticValues->contains(propertyName.impl())) {
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                slot.setCustom(this, staticValueGetter);
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
158f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (staticFunctions->contains(propertyName.impl())) {
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                slot.setCustom(this, staticFunctionGetter);
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::getOwnPropertySlot(exec, propertyName, slot);
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
169d0825bca7fe65beaee391d30da42e937db621564Steve Blockbool JSCallbackObject<Base>::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
170d0825bca7fe65beaee391d30da42e937db621564Steve Block{
171d0825bca7fe65beaee391d30da42e937db621564Steve Block    PropertySlot slot;
172d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (getOwnPropertySlot(exec, propertyName, slot)) {
173d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Ideally we should return an access descriptor, but returning a value descriptor is better than nothing.
174d0825bca7fe65beaee391d30da42e937db621564Steve Block        JSValue value = slot.getValue(exec, propertyName);
175d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!exec->hadException())
176d0825bca7fe65beaee391d30da42e937db621564Steve Block            descriptor.setValue(value);
177d0825bca7fe65beaee391d30da42e937db621564Steve Block        // We don't know whether the property is configurable, but assume it is.
178d0825bca7fe65beaee391d30da42e937db621564Steve Block        descriptor.setConfigurable(true);
179d0825bca7fe65beaee391d30da42e937db621564Steve Block        // We don't know whether the property is enumerable (we could call getOwnPropertyNames() to find out), but assume it isn't.
180d0825bca7fe65beaee391d30da42e937db621564Steve Block        descriptor.setEnumerable(false);
181d0825bca7fe65beaee391d30da42e937db621564Steve Block        return true;
182d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
183d0825bca7fe65beaee391d30da42e937db621564Steve Block
184d0825bca7fe65beaee391d30da42e937db621564Steve Block    return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
185d0825bca7fe65beaee391d30da42e937db621564Steve Block}
186d0825bca7fe65beaee391d30da42e937db621564Steve Block
187d0825bca7fe65beaee391d30da42e937db621564Steve Blocktemplate <class Base>
1885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSValueRef valueRef = toRef(exec, value);
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
2005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            bool result;
2015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
202d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
2045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
205643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
206545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
2078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (result || exception)
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
212f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeReadOnly)
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!propertyNameRef)
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
2188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    JSValueRef exception = 0;
2195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    bool result;
2205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    {
221d0825bca7fe65beaee391d30da42e937db621564Steve Block                        APICallbackShim callbackShim(exec);
2225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
2235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    }
224643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    if (exception)
225545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                        throwError(exec, toJS(exec, exception));
2268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (result || exception)
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return;
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
229545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                    throwError(exec, createReferenceError(exec, "Attempt to set a property that is not settable."));
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
234f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeReadOnly)
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return;
2372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                JSCallbackObject<Base>::putDirect(exec->globalData(), propertyName, value); // put as override property
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::put(exec, propertyName, value, slot);
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& propertyName)
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
2585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            bool result;
2595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
260d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
2615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
2625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
263643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
264545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (result || exception)
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
270f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) {
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeDontDelete)
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
278f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (entry->attributes & kJSPropertyAttributeDontDelete)
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::deleteProperty(exec, propertyName);
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::deleteProperty(ExecState* exec, unsigned propertyName)
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return deleteProperty(exec, Identifier::from(exec, propertyName));
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectConstructType JSCallbackObject<Base>::getConstructData(ConstructData& constructData)
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (jsClass->callAsConstructor) {
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            constructData.native.function = construct;
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return ConstructTypeHost;
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return ConstructTypeNone;
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
308545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSCallbackObject<Base>::construct(ExecState* exec)
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
310545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    JSObject* constructor = exec->callee();
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef constructorRef = toRef(constructor);
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
316545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            int argumentCount = static_cast<int>(exec->argumentCount());
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Vector<JSValueRef, 16> arguments(argumentCount);
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i = 0; i < argumentCount; i++)
319545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                arguments[i] = toRef(exec, exec->argument(i));
3208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSObject* result;
3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
323d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
3255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
326643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
327545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
328545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return JSValue::encode(result);
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED(); // getConstructData should prevent us from reaching here
333545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(JSValue());
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValue value, JSValue)
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JSValueRef valueRef = toRef(exec, value);
3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            bool result;
3475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
348d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
3490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                result = hasInstance(execRef, thisRef, valueRef, &exception);
3505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
351643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
352545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return result;
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCallType JSCallbackObject<Base>::getCallData(CallData& callData)
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (jsClass->callAsFunction) {
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            callData.native.function = call;
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return CallTypeHost;
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return CallTypeNone;
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
372545e470e52f0ac6a3a072bf559c796b42c6066b6Ben MurdochEncodedJSValue JSCallbackObject<Base>::call(ExecState* exec)
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
3755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectRef functionRef = toRef(exec->callee());
3765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
3805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            int argumentCount = static_cast<int>(exec->argumentCount());
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Vector<JSValueRef, 16> arguments(argumentCount);
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i = 0; i < argumentCount; i++)
3835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                arguments[i] = toRef(exec, exec->argument(i));
3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
3855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValue result;
3865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
387d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
3885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
390643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception)
391545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
392545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            return JSValue::encode(result);
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
397545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return JSValue::encode(JSValue());
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
401d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef execRef = toRef(exec);
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) {
408d0825bca7fe65beaee391d30da42e937db621564Steve Block            APICallbackShim callbackShim(exec);
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            getPropertyNames(execRef, thisRef, toRef(&propertyNames));
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            typedef OpaqueJSClassStaticValuesTable::const_iterator iterator;
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            iterator end = staticValues->end();
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (iterator it = staticValues->begin(); it != end; ++it) {
416f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                StringImpl* name = it->first.get();
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                StaticValueEntry* entry = it->second;
418d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)))
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    propertyNames.add(Identifier(exec, name));
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            typedef OpaqueJSClassStaticFunctionsTable::const_iterator iterator;
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            iterator end = staticFunctions->end();
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (iterator it = staticFunctions->begin(); it != end; ++it) {
427f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                StringImpl* name = it->first.get();
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                StaticFunctionEntry* entry = it->second;
429d0825bca7fe65beaee391d30da42e937db621564Steve Block                if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    propertyNames.add(Identifier(exec, name));
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
435d0825bca7fe65beaee391d30da42e937db621564Steve Block    Base::getOwnPropertyNames(exec, propertyNames, mode);
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectdouble JSCallbackObject<Base>::toNumber(ExecState* exec) const
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We need this check to guard against the case where this object is rhs of
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a binary expression where lhs threw an exception in its conversion to
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // primitive
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (exec->hadException())
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NaN;
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
4518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
4525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
4535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
454d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
4555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                value = convertToType(ctx, thisRef, kJSTypeNumber, &exception);
4565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
4570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (exception) {
458545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
4590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                return 0;
460635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
4610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            double dValue;
463643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (value)
464643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return toJS(exec, value).getNumber(dValue) ? dValue : NaN;
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::toNumber(exec);
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUString JSCallbackObject<Base>::toString(ExecState* exec) const
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSContextRef ctx = toRef(exec);
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(this);
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
4788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
4795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            {
481d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
4828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                value = convertToType(ctx, thisRef, kJSTypeString, &exception);
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (exception) {
485545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
4868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return "";
4870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
488643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (value)
489643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return toJS(exec, value).getString(exec);
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Base::toString(exec);
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid JSCallbackObject<Base>::setPrivate(void* data)
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_callbackObjectData->privateData = data;
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid* JSCallbackObject<Base>::getPrivate()
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_callbackObjectData->privateData;
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JSCallbackObject<Base>::inherits(JSClassRef c) const
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (jsClass == c)
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
518dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
520dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSCallbackObject* thisObj = asCallbackObject(slotBase);
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(thisObj);
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass)
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec))
527f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticValueEntry* entry = staticValues->get(propertyName.impl()))
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!propertyNameRef)
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
5318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    JSValueRef exception = 0;
5325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    JSValueRef value;
5335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    {
534d0825bca7fe65beaee391d30da42e937db621564Steve Block                        APICallbackShim callbackShim(exec);
5355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
5365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    }
537643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    if (exception) {
538545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                        throwError(exec, toJS(exec, exception));
539643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                        return jsUndefined();
540643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    }
5418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (value)
5425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        return toJS(exec, value);
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
544643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
545545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return throwError(exec, createReferenceError(exec, "Static value property defined with NULL getProperty callback."));
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
549dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
551dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSCallbackObject* thisObj = asCallbackObject(slotBase);
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check for cached or override property.
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    PropertySlot slot2(thisObj);
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (thisObj->Base::getOwnPropertySlot(exec, propertyName, slot2))
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return slot2.getValue(exec, propertyName);
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) {
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) {
560f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) {
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
562e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block
563e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block                    JSObject* o = new (exec) JSCallbackFunction(exec, asGlobalObject(thisObj->getAnonymousValue(0)), callAsFunction, propertyName);
5642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                    thisObj->putDirect(exec->globalData(), propertyName, o, entry->attributes);
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return o;
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
571545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return throwError(exec, createReferenceError(exec, "Static function property defined with NULL callAsFunction callback."));
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttemplate <class Base>
575dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
577dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSCallbackObject* thisObj = asCallbackObject(slotBase);
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef thisRef = toRef(thisObj);
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<OpaqueJSString> propertyNameRef;
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass)
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!propertyNameRef)
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
5868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            JSValueRef exception = 0;
5875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            JSValueRef value;
5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            {
589d0825bca7fe65beaee391d30da42e937db621564Steve Block                APICallbackShim callbackShim(exec);
5905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
5915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
592643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (exception) {
593545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch                throwError(exec, toJS(exec, exception));
594643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return jsUndefined();
595643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
5968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (value)
5975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return toJS(exec, value);
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
600545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    return throwError(exec, createReferenceError(exec, "hasProperty callback returned true for a property that doesn't exist."));
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC
604