bool pluginElementCustomPut(ExecState* exec, PropertyName propertyName, JSValue value, JSHTMLElement* element, PutPropertySlot& slot, bool& putResult)
{
    JSObject* scriptObject = pluginScriptObject(exec, element);
    if (!scriptObject)
        return false;
    if (!scriptObject->hasProperty(exec, propertyName))
        return false;
    putResult = scriptObject->methodTable()->put(scriptObject, exec, propertyName, value, slot);
    return true;
}
bool runtimeObjectCustomPut(ExecState* exec, const Identifier& propertyName, JSValue value, JSHTMLElement* element, PutPropertySlot& slot)
{
    JSObject* scriptObject = pluginScriptObject(exec, element);
    if (!scriptObject)
        return 0;
    if (!scriptObject->hasProperty(exec, propertyName))
        return false;
    scriptObject->methodTable()->put(scriptObject, exec, propertyName, value, slot);
    return true;
}
Beispiel #3
0
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    JSLock lock(exec);

    JSObject* jsObject = toJS(object);
    
    return jsObject->hasProperty(exec, propertyName->identifier(&exec->globalData()));
}
Beispiel #4
0
bool runtimeObjectCustomGetOwnPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot, JSHTMLElement* element)
{
    JSObject* scriptObject = pluginScriptObject(exec, element);
    if (!scriptObject)
        return false;

    if (!scriptObject->hasProperty(exec, propertyName))
        return false;
    slot.setCustom(element, runtimeObjectPropertyGetter);
    return true;
}
Beispiel #5
0
JSValue VM::throwException(ExecState* exec, JSValue error)
{
    if (Options::breakOnThrow()) {
        dataLog("In call frame ", RawPointer(exec), " for code block ", *exec->codeBlock(), "\n");
        CRASH();
    }

    ASSERT(exec == topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->vmEntryGlobalObject()->globalExec());

    Vector<StackFrame> stackTrace;
    interpreter->getStackTrace(stackTrace);
    m_exceptionStack = RefCountedArray<StackFrame>(stackTrace);
    m_exception = error;

    if (stackTrace.isEmpty() || !error.isObject())
        return error;
    JSObject* exception = asObject(error);

    StackFrame stackFrame;
    for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
        stackFrame = stackTrace.at(i);
        if (stackFrame.bytecodeOffset)
            break;
    }
    if (!hasErrorInfo(exec, exception)) {
        // FIXME: We should only really be adding these properties to VM generated exceptions,
        // but the inspector currently requires these for all thrown objects.
        unsigned line;
        unsigned column;
        stackFrame.computeLineAndColumn(line, column);
        exception->putDirect(*this, Identifier(this, "line"), jsNumber(line), ReadOnly | DontDelete);
        exception->putDirect(*this, Identifier(this, "column"), jsNumber(column), ReadOnly | DontDelete);
        if (!stackFrame.sourceURL.isEmpty())
            exception->putDirect(*this, Identifier(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
    }
    if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) {
        FindFirstCallerFrameWithCodeblockFunctor functor(exec);
        topCallFrame->iterate(functor);
        CallFrame* callFrame = functor.foundCallFrame();
        unsigned stackIndex = functor.index();

        if (callFrame && callFrame->codeBlock()) {
            stackFrame = stackTrace.at(stackIndex);
            appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), stackFrame.bytecodeOffset);
        }
    }

    if (exception->hasProperty(exec, this->propertyNames->stack))
        return error;

    exception->putDirect(*this, propertyNames->stack, interpreter->stackTraceAsString(topCallFrame, stackTrace), DontEnum);
    return error;
}
Beispiel #6
0
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
{
    if (!ctx) {
        ASSERT_NOT_REACHED();
        return false;
    }
    ExecState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    JSObject* jsObject = toJS(object);
    
    return jsObject->hasProperty(exec, propertyName->identifier(&exec->vm()));
}
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
{
    if (!ctx) {
        ASSERT_NOT_REACHED();
        return false;
    }
    ExecState* exec = toJS(ctx);
    VM& vm = exec->vm();
    JSLockHolder locker(vm);

    JSObject* jsObject = toJS(object);
    
    return jsObject->hasProperty(exec, propertyName->identifier(&vm));
}
Beispiel #8
0
JSValue JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
{
    ScopeChainIterator end = scope->end();
    ScopeChainIterator it = scope->begin();
    while (1) {
        JSObject* object = it.get();

        if (++it == end) // Global scope.
            return object;

        if (object->hasProperty(exec, ident))
            return object;
    }
}
Beispiel #9
0
JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
{
    VM& vm = exec->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    ScopeChainIterator end = scope->end();
    ScopeChainIterator it = scope->begin();
    while (1) {
        JSScope* scope = it.scope();
        JSObject* object = it.get();

        // Global scope.
        if (++it == end) {
            JSScope* globalScopeExtension = scope->globalObject(vm)->globalScopeExtension();
            if (UNLIKELY(globalScopeExtension)) {
                bool hasProperty = object->hasProperty(exec, ident);
                RETURN_IF_EXCEPTION(throwScope, nullptr);
                if (hasProperty)
                    return object;
                JSObject* extensionScopeObject = JSScope::objectAtScope(globalScopeExtension);
                hasProperty = extensionScopeObject->hasProperty(exec, ident);
                RETURN_IF_EXCEPTION(throwScope, nullptr);
                if (hasProperty)
                    return extensionScopeObject;
            }
            return object;
        }

        bool hasProperty = object->hasProperty(exec, ident);
        RETURN_IF_EXCEPTION(throwScope, nullptr);
        if (hasProperty) {
            bool unscopable = isUnscopable(exec, scope, object, ident);
            ASSERT(!throwScope.exception() || !unscopable);
            if (!unscopable)
                return object;
        }
    }
}
Beispiel #10
0
JSValue VM::throwException(ExecState* exec, JSValue error)
{
    ASSERT(exec == topCallFrame || exec == exec->lexicalGlobalObject()->globalExec() || exec == exec->dynamicGlobalObject()->globalExec());
    
    Vector<StackFrame> stackTrace;
    interpreter->getStackTrace(stackTrace);
    m_exceptionStack = RefCountedArray<StackFrame>(stackTrace);
    m_exception = error;
    
    if (stackTrace.isEmpty() || !error.isObject())
        return error;
    JSObject* exception = asObject(error);
    
    StackFrame stackFrame;
    for (unsigned i = 0 ; i < stackTrace.size(); ++i) {
        stackFrame = stackTrace.at(i);
        if (stackFrame.bytecodeOffset)
            break;
    }
    unsigned bytecodeOffset = stackFrame.bytecodeOffset;
    if (!hasErrorInfo(exec, exception)) {
        // FIXME: We should only really be adding these properties to VM generated exceptions,
        // but the inspector currently requires these for all thrown objects.
        unsigned line;
        unsigned column;
        stackFrame.computeLineAndColumn(line, column);
        exception->putDirect(*this, Identifier(this, "line"), jsNumber(line), ReadOnly | DontDelete);
        exception->putDirect(*this, Identifier(this, "column"), jsNumber(column), ReadOnly | DontDelete);
        if (!stackFrame.sourceURL.isEmpty())
            exception->putDirect(*this, Identifier(this, "sourceURL"), jsString(this, stackFrame.sourceURL), ReadOnly | DontDelete);
    }
    if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage()) {
        unsigned stackIndex = 0;
        CallFrame* callFrame;
        for (callFrame = exec; callFrame && !callFrame->codeBlock(); callFrame = callFrame->callerFrame()->removeHostCallFrameFlag())
            stackIndex++;
        if (callFrame && callFrame->codeBlock()) {
            stackFrame = stackTrace.at(stackIndex);
            bytecodeOffset = stackFrame.bytecodeOffset;
            appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);
        }
    }

    if (exception->hasProperty(exec, this->propertyNames->stack))
        return error;
    
    exception->putDirect(*this, propertyNames->stack, interpreter->stackTraceAsString(topCallFrame, stackTrace), DontEnum);
    return error;
}
Beispiel #11
0
bool runtimeObjectCustomGetOwnPropertyDescriptor(ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, JSHTMLElement* element)
{
    JSObject* scriptObject = pluginScriptObject(exec, element);
    if (!scriptObject)
        return false;
    if (!scriptObject->hasProperty(exec, propertyName))
        return false;
    PropertySlot slot(element);
    slot.setCustom(element, runtimeObjectPropertyGetter);
    // While we don't know what the plugin allows, we do know that we prevent
    // enumeration or deletion of properties, so we mark plugin properties
    // as DontEnum | DontDelete
    descriptor.setDescriptor(slot.getValue(exec, propertyName), DontEnum | DontDelete);
    return true;
}
Beispiel #12
0
static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyTable(ExecState* exec)
{
    VM& vm = exec->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);

    JSObject* memoryDescriptor;
    {
        JSValue argument = exec->argument(0);
        if (!argument.isObject())
            return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Table expects its first argument to be an object"))));
        memoryDescriptor = jsCast<JSObject*>(argument);
    }

    {
        Identifier elementIdent = Identifier::fromString(&vm, "element");
        JSValue elementValue = memoryDescriptor->get(exec, elementIdent);
        RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
        String elementString = elementValue.toWTFString(exec);
        RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
        if (elementString != "anyfunc")
            return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Table expects its 'element' field to be the string 'anyfunc'"))));
    }

    Identifier initialIdent = Identifier::fromString(&vm, "initial");
    JSValue initialSizeValue = memoryDescriptor->get(exec, initialIdent);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    uint32_t initial = toNonWrappingUint32(exec, initialSizeValue);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());

    std::optional<uint32_t> maximum;
    Identifier maximumIdent = Identifier::fromString(&vm, "maximum");
    bool hasProperty = memoryDescriptor->hasProperty(exec, maximumIdent);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    if (hasProperty) {
        JSValue maxSizeValue = memoryDescriptor->get(exec, maximumIdent);
        RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
        maximum = toNonWrappingUint32(exec, maxSizeValue);
        RETURN_IF_EXCEPTION(throwScope, encodedJSValue());

        if (initial > *maximum) {
            return JSValue::encode(throwException(exec, throwScope,
                createRangeError(exec, ASCIILiteral("'maximum' property must be greater than or equal to the 'initial' property"))));
        }
    }

    throwScope.release();
    return JSValue::encode(JSWebAssemblyTable::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyTableStructure(), initial, maximum));
}
Beispiel #13
0
JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
{
    ScopeChainIterator end = scope->end();
    ScopeChainIterator it = scope->begin();
    while (1) {
        JSScope* scope = it.scope();
        JSObject* object = it.get();

        if (++it == end) // Global scope.
            return object;

        if (object->hasProperty(exec, ident)) {
            if (!isUnscopable(exec, scope, object, ident))
                return object;
            ASSERT_WITH_MESSAGE(!exec->hadException(), "When an exception occurs, the result of isUnscopable becomes false");
        }
    }
}
Beispiel #14
0
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
{
    JSLock lock;
    ExecState* exec = toJS(ctx);
    JSObject* jsObject = toJS(object);
    Identifier name(exec, toJS(propertyName));
    JSValue* jsValue = toJS(value);

    if (attributes && !jsObject->hasProperty(exec, name))
        jsObject->putWithAttributes(exec, name, jsValue, attributes);
    else
        jsObject->put(exec, name, jsValue);

    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
    }
}
bool JSObjectHasPropertyForKey(JSContextRef ctx, JSObjectRef object, JSValueRef key, JSValueRef* exception)
{
    if (!ctx) {
        ASSERT_NOT_REACHED();
        return false;
    }
    ExecState* exec = toJS(ctx);
    VM& vm = exec->vm();
    JSLockHolder locker(vm);
    auto scope = DECLARE_CATCH_SCOPE(vm);

    JSObject* jsObject = toJS(object);
    Identifier ident = toJS(exec, key).toPropertyKey(exec);
    if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
        return false;

    bool result = jsObject->hasProperty(exec, ident);
    handleExceptionIfNeeded(scope, exec, exception);
    return result;
}
Beispiel #16
0
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    JSObject* jsObject = toJS(object);
    Identifier name(propertyName->identifier(&exec->globalData()));
    JSValue jsValue = toJS(exec, value);

    if (attributes && !jsObject->hasProperty(exec, name))
        jsObject->methodTable()->putDirectVirtual(jsObject, exec, name, jsValue, attributes);
    else {
        PutPropertySlot slot;
        jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot);
    }

    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec, exec->exception());
        exec->clearException();
    }
}
Beispiel #17
0
JSValue JSHTMLCanvasElement::getContext(ExecState* exec)
{
    HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(impl());
    const UString& contextId = exec->argument(0).toString(exec)->value(exec);
    RefPtr<CanvasContextAttributes> attrs;
#if ENABLE(WEBGL)
    if (contextId == "experimental-webgl" || contextId == "webkit-3d") {
        attrs = WebGLContextAttributes::create();
        WebGLContextAttributes* webGLAttrs = static_cast<WebGLContextAttributes*>(attrs.get());
        if (exec->argumentCount() > 1 && exec->argument(1).isObject()) {
            JSObject* jsAttrs = exec->argument(1).getObject();
            Identifier alpha(exec, "alpha");
            if (jsAttrs->hasProperty(exec, alpha))
                webGLAttrs->setAlpha(jsAttrs->get(exec, alpha).toBoolean(exec));
            Identifier depth(exec, "depth");
            if (jsAttrs->hasProperty(exec, depth))
                webGLAttrs->setDepth(jsAttrs->get(exec, depth).toBoolean(exec));
            Identifier stencil(exec, "stencil");
            if (jsAttrs->hasProperty(exec, stencil))
                webGLAttrs->setStencil(jsAttrs->get(exec, stencil).toBoolean(exec));
            Identifier antialias(exec, "antialias");
            if (jsAttrs->hasProperty(exec, antialias))
                webGLAttrs->setAntialias(jsAttrs->get(exec, antialias).toBoolean(exec));
            Identifier premultipliedAlpha(exec, "premultipliedAlpha");
            if (jsAttrs->hasProperty(exec, premultipliedAlpha))
                webGLAttrs->setPremultipliedAlpha(jsAttrs->get(exec, premultipliedAlpha).toBoolean(exec));
            Identifier preserveDrawingBuffer(exec, "preserveDrawingBuffer");
            if (jsAttrs->hasProperty(exec, preserveDrawingBuffer))
                webGLAttrs->setPreserveDrawingBuffer(jsAttrs->get(exec, preserveDrawingBuffer).toBoolean(exec));
        }
    }
#endif
    CanvasRenderingContext* context = canvas->getContext(ustringToString(contextId), attrs.get());
    if (!context)
        return jsNull();
    JSValue jsValue = toJS(exec, globalObject(), WTF::getPtr(context));
#if ENABLE(WEBGL)
    if (context->is3d() && InspectorInstrumentation::hasFrontends()) {
        ScriptObject glContext(exec, jsValue.getObject());
        ScriptObject wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(canvas->document(), glContext);
        if (!wrapped.hasNoValue())
            return wrapped.jsValue();
    }
#endif
    return jsValue;
}
Beispiel #18
0
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
{
    if (!ctx) {
        ASSERT_NOT_REACHED();
        return;
    }
    ExecState* exec = toJS(ctx);
    JSLockHolder locker(exec);

    JSObject* jsObject = toJS(object);
    Identifier name(propertyName->identifier(&exec->vm()));
    JSValue jsValue = toJS(exec, value);

    if (attributes && !jsObject->hasProperty(exec, name)) {
        PropertyDescriptor desc(jsValue, attributes);
        jsObject->methodTable()->defineOwnProperty(jsObject, exec, name, desc, false);
    } else {
        PutPropertySlot slot(jsObject);
        jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot);
    }

    handleExceptionIfNeeded(exec, exception);
}
Beispiel #19
0
void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap->registerThread();
    JSLock lock(exec);

    JSObject* jsObject = toJS(object);
    Identifier name(propertyName->identifier(exec));
    JSValue* jsValue = toJS(value);

    if (attributes && !jsObject->hasProperty(exec, name))
        jsObject->putWithAttributes(exec, name, jsValue, attributes);
    else {
        PutPropertySlot slot;
        jsObject->put(exec, name, jsValue, slot);
    }

    if (exec->hadException()) {
        if (exception)
            *exception = toRef(exec->exception());
        exec->clearException();
    }
}
Beispiel #20
0
//--------------------------------------------------------------------------
// KJSValueToCFTypeInternal
//--------------------------------------------------------------------------
// Caller is responsible for releasing the returned CFTypeRef
CFTypeRef KJSValueToCFTypeInternal(JSValue inValue, ExecState *exec, ObjectImpList* inImps)
{
    if (!inValue)
        return 0;

    CFTypeRef result = 0;

    JSGlueAPIEntry entry;

        if (inValue.isBoolean())
            {
                result = inValue.toBoolean(exec) ? kCFBooleanTrue : kCFBooleanFalse;
                RetainCFType(result);
                return result;
            }

        if (inValue.isString())
            {
                UString uString = inValue.toString(exec);
                result = UStringToCFString(uString);
                return result;
            }

        if (inValue.isNumber())
            {
                double number1 = inValue.toNumber(exec);
                double number2 = (double)inValue.toInteger(exec);
                if (number1 ==  number2)
                {
                    int intValue = (int)number2;
                    result = CFNumberCreate(0, kCFNumberIntType, &intValue);
                }
                else
                {
                    result = CFNumberCreate(0, kCFNumberDoubleType, &number1);
                }
                return result;
            }

        if (inValue.isObject())
            {
                if (inValue.inherits(&UserObjectImp::info)) {
                    UserObjectImp* userObjectImp = static_cast<UserObjectImp *>(asObject(inValue));
                    JSUserObject* ptr = userObjectImp->GetJSUserObject();
                    if (ptr)
                    {
                        result = ptr->CopyCFValue();
                    }
                }
                else
                {
                    JSObject *object = inValue.toObject(exec);
                    UInt8 isArray = false;

                    // if two objects reference each
                    JSObject* imp = object;
                    ObjectImpList* temp = inImps;
                    while (temp) {
                        if (imp == temp->imp) {
                            return CFRetain(GetCFNull());
                        }
                        temp = temp->next;
                    }

                    ObjectImpList imps;
                    imps.next = inImps;
                    imps.imp = imp;


//[...] HACK since we do not have access to the class info we use class name instead
#if 0
                    if (object->inherits(&ArrayInstanceImp::info))
#else
                    if (object->className() == "Array")
#endif
                    {
                        isArray = true;
                        JSGlueGlobalObject* globalObject = static_cast<JSGlueGlobalObject*>(exec->dynamicGlobalObject());
                        if (globalObject && (globalObject->Flags() & kJSFlagConvertAssociativeArray)) {
                            PropertyNameArray propNames(exec);
                            object->getPropertyNames(exec, propNames);
                            PropertyNameArray::const_iterator iter = propNames.begin();
                            PropertyNameArray::const_iterator end = propNames.end();
                            while(iter != end && isArray)
                            {
                                Identifier propName = *iter;
                                UString ustr = propName.ustring();
                                const UniChar* uniChars = (const UniChar*)ustr.characters();
                                int size = ustr.length();
                                while (size--) {
                                    if (uniChars[size] < '0' || uniChars[size] > '9') {
                                        isArray = false;
                                        break;
                                    }
                                }
                                iter++;
                            }
                        }
                    }

                    if (isArray)
                    {
                        // This is an KJS array
                        unsigned int length = object->get(exec, Identifier(exec, "length")).toUInt32(exec);
                        result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks);
                        if (result)
                        {
                            for (unsigned i = 0; i < length; i++)
                            {
                                CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, i), exec, &imps);
                                CFArrayAppendValue((CFMutableArrayRef)result, cfValue);
                                ReleaseCFType(cfValue);
                            }
                        }
                    }
                    else
                    {
                        // Not an array, just treat it like a dictionary which contains (property name, property value) pairs
                        PropertyNameArray propNames(exec);
                        object->getPropertyNames(exec, propNames);
                        {
                            result = CFDictionaryCreateMutable(0,
                                                               0,
                                                               &kCFTypeDictionaryKeyCallBacks,
                                                               &kCFTypeDictionaryValueCallBacks);
                            if (result)
                            {
                                PropertyNameArray::const_iterator iter = propNames.begin();
                                PropertyNameArray::const_iterator end = propNames.end();
                                while(iter != end)
                                {
                                    Identifier propName = *iter;
                                    if (object->hasProperty(exec, propName))
                                    {
                                        CFStringRef cfKey = IdentifierToCFString(propName);
                                        CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, propName), exec, &imps);
                                        if (cfKey && cfValue)
                                        {
                                            CFDictionaryAddValue((CFMutableDictionaryRef)result, cfKey, cfValue);
                                        }
                                        ReleaseCFType(cfKey);
                                        ReleaseCFType(cfValue);
                                    }
                                    iter++;
                                }
                            }
                        }
                    }
                }
                return result;
            }

    if (inValue.isUndefinedOrNull())
        {
            result = RetainCFType(GetCFNull());
            return result;
        }

    ASSERT_NOT_REACHED();
    return 0;
}