/** * 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; }