bool PluginControllerProxy::tryToShortCircuitInvoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result)
{
    // Only try to short circuit evaluate for plug-ins that have the quirk specified.
#if PLUGIN_ARCHITECTURE(MAC)
    if (!PluginProcess::shared().netscapePluginModule()->pluginQuirks().contains(PluginQuirks::CanShortCircuitSomeNPRuntimeCallsDuringInitialization))
        return false;
#else
    return false;
#endif

    // And only when we're in initialize.
    if (!inInitialize())
        return false;
    
    // And only when the NPObject is the window NPObject.
    if (npObject != m_windowNPObject)
        return false;

    // And only when we don't have any arguments.
    if (argumentCount)
        return false;

    IdentifierRep* methodNameRep = static_cast<IdentifierRep*>(methodName);
    if (!methodNameRep->isString())
        return false;

    if (!strcmp(methodNameRep->string(), "__flash_getWindowLocation")) {
        result.type = NPVariantType_String;
        result.value.stringValue = createNPString(m_pluginCreationParameters->parameters.documentURL.utf8()); 
        returnValue = true;
        return true;
    }
    
    if (!strcmp(methodNameRep->string(), "__flash_getTopLocation")) {
        if (m_pluginCreationParameters->parameters.toplevelDocumentURL.isNull()) {
            // If the toplevel document is URL it means that the frame that the plug-in is in doesn't have access to the toplevel document.
            // In this case, just pass the string "[object]" to Flash.
            result.type = NPVariantType_String;
            result.value.stringValue = createNPString("[object]");
            returnValue = true;
            return true;
        }

        result.type = NPVariantType_String;
        result.value.stringValue = createNPString(m_pluginCreationParameters->parameters.toplevelDocumentURL.utf8()); 
        returnValue = true;
        return true;
    }

    return false;
}
NPVariant NPRemoteObjectMap::npVariantDataToNPVariant(const NPVariantData& npVariantData, Plugin* plugin)
{
    NPVariant npVariant;

    switch (npVariantData.type()) {
    case NPVariantData::Void:
        VOID_TO_NPVARIANT(npVariant);
        break;
    case NPVariantData::Null:
        NULL_TO_NPVARIANT(npVariant);
        break;
    case NPVariantData::Bool:
        BOOLEAN_TO_NPVARIANT(npVariantData.boolValue(), npVariant);
        break;
    case NPVariantData::Int32:
        INT32_TO_NPVARIANT(npVariantData.int32Value(), npVariant);
        break;
    case NPVariantData::Double:
        DOUBLE_TO_NPVARIANT(npVariantData.doubleValue(), npVariant);
        break;
    case NPVariantData::String: {
        NPString npString = createNPString(npVariantData.stringValue());
        STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, npVariant);
        break;
    }
    case NPVariantData::LocalNPObjectID: {
        uint64_t npObjectID = npVariantData.localNPObjectIDValue();
        ASSERT(npObjectID);

        NPObjectMessageReceiver* npObjectMessageReceiver = m_registeredNPObjects.get(npObjectID);
        if (!npObjectMessageReceiver) {
            ASSERT_NOT_REACHED();
            VOID_TO_NPVARIANT(npVariant);
            break;
        }

        NPObject* npObject = npObjectMessageReceiver->npObject();
        ASSERT(npObject);

        retainNPObject(npObject);
        OBJECT_TO_NPVARIANT(npObject, npVariant);
        break;
    }
    case NPVariantData::RemoteNPObjectID: {
        NPObject* npObjectProxy = createNPObjectProxy(npVariantData.remoteNPObjectIDValue(), plugin);
        OBJECT_TO_NPVARIANT(npObjectProxy, npVariant);
        break;
    }
    }

    return npVariant;
}
void NPRuntimeObjectMap::convertJSValueToNPVariant(ExecState* exec, JSValue value, NPVariant& variant)
{
    JSLockHolder lock(exec);

    VOID_TO_NPVARIANT(variant);
    
    if (value.isNull()) {
        NULL_TO_NPVARIANT(variant);
        return;
    }

    if (value.isUndefined()) {
        VOID_TO_NPVARIANT(variant);
        return;
    }

    if (value.isBoolean()) {
        BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), variant);
        return;
    }

    if (value.isNumber()) {
        DOUBLE_TO_NPVARIANT(value.toNumber(exec), variant);
        return;
    }

    if (value.isString()) {
        NPString npString = createNPString(value.toString(exec)->value(exec).utf8());
        STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, variant);
        return;
    }

    if (value.isObject()) {
        NPObject* npObject = getOrCreateNPObject(exec->vm(), asObject(value));
        OBJECT_TO_NPVARIANT(npObject, variant);
        return;
    }

    ASSERT_NOT_REACHED();
}