Example #1
0
/**
 * This function does all the dirty qt stuff to call any given signal or slot manually. This function is for internal use only
 * @sa callCallback emitSignal
 * @param sig Signature of the function to be called
 * @param args Arguments list for the function
 * @return Returns the ReturnValue from the function, or an error.
 */
ReturnValue ProxyBase::callMetacall(Signature sig, Arguments args)
{
	// Test to make sure the argument list matches the signature... this is important else the void*'s will contain the wrong types (breaking everything)
	QString test = sig.test(args);
	if (!test.isEmpty())
	{
		return(ReturnValue(2, test));
	}

	// Create the return value
	ReturnValue ret;
	QList<QByteArray> bagarbageCollector;
	QList<QSharedPointer<const char*> > garbageCollector;

	// Create an array of void pointers and place the QVariants into it... I don't know why this works, but it does.
	void *param[] = {(void *)&ret, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

	for (int i = 0; i < sig.numArgs(); i++)
	{
		if (sig.arg(i) == "char*" || sig.arg(i) == "const char*")
		{
			garbageCollector.append(QSharedPointer<const char*>(new const char*));
			bagarbageCollector.append(args[i].toString().toLocal8Bit());
			*garbageCollector.last().data() = bagarbageCollector.last().constData();
			param[i+1] = garbageCollector.last().data();
		}
		else if (sig.arg(i) != "QVariant" && args.at(i).type() == QVariant::UserType)
		{
			param[i+1] = args[i].data();
		}
		else
		{
			param[i+1] = static_cast<void*>(&args[i]);
		}
	}

	// Check the make sure the signature is a valid string...
	if (sig.name().isEmpty())
		return(ReturnValue(3, "Failed to call " + sig.toString() + ": Sig is not valid (" + sig.name() + ")"));

	// Get the ID number of the function, if it fails normalize the string and try again...
	int id = metaObject()->indexOfMethod(qPrintable(sig.toString()));
	if (id < 0)
		id = metaObject()->indexOfMethod(QMetaObject::normalizedSignature(qPrintable(sig.toString())).constData()); //try again

	if (id < 0) // failed to find the id number of the function
		return(ReturnValue(4, "Failed to call " + sig.toString() + ": Could not find the index of the slot (id=" + QString("%1)").arg(id)));

	// the return from qt_metacall SHOULD be negative if the slot was found...
	int retid = qt_metacall(QMetaObject::InvokeMetaMethod, id, param);
	if (retid > 0) // return error
		return(ReturnValue(5, "Failed to call " + sig.toString() + ": Failed to find it in metacall (" + QString("id=%1 retid= %2 ret=%3)").arg(id).arg(retid).arg(ret.toString())));

	// return the return value. It's data was filled via the *param[] object...
	return(ret);
}
// static
std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(double timestampMS, MessageType type, MessageLevel level, const String16& messageText, std::vector<v8::Local<v8::Value>>* arguments, std::unique_ptr<V8StackTrace> stackTrace, InspectedContext* context)
{
    v8::Isolate* isolate = context->isolate();
    int contextId = context->contextId();
    int contextGroupId = context->contextGroupId();
    V8DebuggerImpl* debugger = context->debugger();

    String16 url;
    unsigned lineNumber = 0;
    unsigned columnNumber = 0;
    if (stackTrace && !stackTrace->isEmpty()) {
        url = stackTrace->topSourceURL();
        lineNumber = stackTrace->topLineNumber();
        columnNumber = stackTrace->topColumnNumber();
    }

    String16 actualMessage = messageText;

    Arguments messageArguments;
    if (arguments && arguments->size()) {
        for (size_t i = 0; i < arguments->size(); ++i)
            messageArguments.push_back(wrapUnique(new v8::Global<v8::Value>(isolate, arguments->at(i))));
        if (actualMessage.isEmpty())
            actualMessage = V8ValueStringBuilder::toString(messageArguments.at(0)->Get(isolate), isolate);
    }

    std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage(timestampMS, ConsoleAPIMessageSource, level, actualMessage, url, lineNumber, columnNumber, std::move(stackTrace), 0 /* scriptId */, String16() /* requestIdentifier */));
    message->m_type = type;
    if (messageArguments.size()) {
        message->m_contextId = contextId;
        message->m_arguments.swap(messageArguments);
    }

    debugger->client()->messageAddedToConsole(contextGroupId, message->m_source, message->m_level, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get());
    return message;
}