JSValue *UserObjectImp::userObjectGetter(ExecState *, JSObject *, const Identifier& propertyName, const PropertySlot& slot)
{
    UserObjectImp *thisObj = static_cast<UserObjectImp *>(slot.slotBase());
    // getOwnPropertySlot should have guarded against a null fJSUserObject.
    assert(thisObj->fJSUserObject);
    
    CFStringRef cfPropName = IdentifierToCFString(propertyName);
    JSUserObject *jsResult = thisObj->fJSUserObject->CopyProperty(cfPropName);
    ReleaseCFType(cfPropName);
    JSValue *result = JSObjectKJSValue(jsResult);
    jsResult->Release();

    return result;
}
JSValue *UserObjectImp::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
{
    JSValue *result = jsUndefined();
    JSUserObject* jsThisObj = KJSValueToJSObject(thisObj, exec);
    if (jsThisObj) {
        CFIndex argCount = args.size();
        CFArrayCallBacks arrayCallBacks;
        JSTypeGetCFArrayCallBacks(&arrayCallBacks);
        CFMutableArrayRef jsArgs = CFArrayCreateMutable(0, 0, &arrayCallBacks);
        if (jsArgs) {
            for (CFIndex i = 0; i < argCount; i++) {
                JSUserObject* jsArg = KJSValueToJSObject(args[i], exec);
                CFArrayAppendValue(jsArgs, (void*)jsArg);
                jsArg->Release();
            }
        }

        JSUserObject* jsResult;
        { // scope
            JSLock::DropAllLocks dropLocks;

            // implementsCall should have guarded against a NULL fJSUserObject.
            assert(fJSUserObject);
            jsResult = fJSUserObject->CallFunction(jsThisObj, jsArgs);
        }

        if (jsResult) {
            result = JSObjectKJSValue(jsResult);
            jsResult->Release();
        }

        ReleaseCFType(jsArgs);
        jsThisObj->Release();
    }
    return result;
}
JSValue UserObjectImp::callAsFunction(ExecState *exec)
{
    JSValue result = jsUndefined();
    JSUserObject* jsThisObj = KJSValueToJSObject(exec->hostThisValue().toThisObject(exec), exec);
    if (jsThisObj) {
        CFIndex argCount = exec->argumentCount();
        CFArrayCallBacks arrayCallBacks;
        JSTypeGetCFArrayCallBacks(&arrayCallBacks);
        CFMutableArrayRef jsArgs = CFArrayCreateMutable(0, 0, &arrayCallBacks);
        if (jsArgs) {
            for (CFIndex i = 0; i < argCount; i++) {
                JSUserObject* jsArg = KJSValueToJSObject(exec->argument(i), exec);
                CFArrayAppendValue(jsArgs, (void*)jsArg);
                jsArg->Release();
            }
        }

        JSUserObject* jsResult;
        { // scope
            JSGlueAPICallback apiCallback(exec);

            // getCallData should have guarded against a NULL fJSUserObject.
            assert(fJSUserObject);
            jsResult = fJSUserObject->CallFunction(jsThisObj, jsArgs);
        }

        if (jsResult) {
            result = JSObjectKJSValue(jsResult);
            jsResult->Release();
        }

        ReleaseCFType(jsArgs);
        jsThisObj->Release();
    }
    return result;
}