Modified: trunk/Source/WebCore/bridge/qt/qt_runtime.cpp (125031 => 125032)
--- trunk/Source/WebCore/bridge/qt/qt_runtime.cpp 2012-08-08 13:18:18 UTC (rev 125031)
+++ trunk/Source/WebCore/bridge/qt/qt_runtime.cpp 2012-08-08 13:19:22 UTC (rev 125032)
@@ -122,6 +122,17 @@
}
#endif
+void setException(JSContextRef context, JSValueRef* exception, const QString& text)
+{
+ if (!exception)
+ return;
+
+ JSStringRef errorStr = JSStringCreateWithUTF8CString(text.toUtf8());
+ JSValueRef errorVal[] = { JSValueMakeString(context, errorStr) };
+ *exception = JSObjectMakeError(context, 1, errorVal, 0);
+ JSStringRelease(errorStr);
+}
+
struct RuntimeConversion {
ConvertToJSValueFunction toJSValueFunc;
ConvertToVariantFunction toVariantFunc;
@@ -1141,13 +1152,15 @@
// Helper function for resolving methods
// Largely based on code in QtScript for compatibility reasons
-static int findMethodIndex(ExecState* exec,
+static int findMethodIndex(JSContextRef context,
const QMetaObject* meta,
const QByteArray& signature,
+ int argumentCount,
+ const JSValueRef arguments[],
bool allowPrivate,
QVarLengthArray<QVariant, 10> &vars,
void** vvars,
- JSObject **pError)
+ JSValueRef* exception)
{
QList<int> matchingIndices;
@@ -1169,7 +1182,6 @@
}
int chosenIndex = -1;
- *pError = 0;
QVector<QtMethodMatchType> chosenTypes;
QVarLengthArray<QVariant, 10> args;
@@ -1228,7 +1240,7 @@
}
// If the native method requires more arguments than what was passed from _javascript_
- if (exec->argumentCount() + 1 < static_cast<unsigned>(types.count())) {
+ if (argumentCount + 1 < static_cast<unsigned>(types.count())) {
qMatchDebug() << "Match:too few args for" << method.methodSignature();
tooFewArgs.append(index);
continue;
@@ -1253,10 +1265,10 @@
bool converted = true;
int matchDistance = 0;
for (unsigned i = 0; converted && i + 1 < static_cast<unsigned>(types.count()); ++i) {
- JSValue arg = i < exec->argumentCount() ? exec->argument(i) : jsUndefined();
+ JSValueRef arg = i < argumentCount ? arguments[i] : JSValueMakeUndefined(context);
int argdistance = -1;
- QVariant v = convertValueToQVariant(exec, arg, types.at(i+1).typeId(), &argdistance);
+ QVariant v = convertValueToQVariant(toJS(context), toJS(toJS(context), arg), types.at(i+1).typeId(), &argdistance);
if (argdistance >= 0) {
matchDistance += argdistance;
args[i+1] = v;
@@ -1269,25 +1281,23 @@
qMatchDebug() << "Match: " << method.methodSignature() << (converted ? "converted":"failed to convert") << "distance " << matchDistance;
if (converted) {
- if ((exec->argumentCount() + 1 == static_cast<unsigned>(types.count()))
+ if ((argumentCount + 1 == static_cast<unsigned>(types.count()))
&& (matchDistance == 0)) {
// perfect match, use this one
chosenIndex = index;
break;
- } else {
- QtMethodMatchData currentMatch(matchDistance, index, types, args);
- if (candidates.isEmpty()) {
+ }
+ QtMethodMatchData currentMatch(matchDistance, index, types, args);
+ if (candidates.isEmpty())
+ candidates.append(currentMatch);
+ else {
+ QtMethodMatchData bestMatchSoFar = candidates.at(0);
+ if ((args.count() > bestMatchSoFar.args.count())
+ || ((args.count() == bestMatchSoFar.args.count())
+ && (matchDistance <= bestMatchSoFar.matchDistance)))
+ candidates.prepend(currentMatch);
+ else
candidates.append(currentMatch);
- } else {
- QtMethodMatchData bestMatchSoFar = candidates.at(0);
- if ((args.count() > bestMatchSoFar.args.count())
- || ((args.count() == bestMatchSoFar.args.count())
- && (matchDistance <= bestMatchSoFar.matchDistance))) {
- candidates.prepend(currentMatch);
- } else {
- candidates.append(currentMatch);
- }
- }
}
} else {
conversionFailed.append(index);
@@ -1308,7 +1318,7 @@
QMetaMethod mtd = meta->method(conversionFailed.at(i));
message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.methodSignature()));
}
- *pError = throwError(exec, createTypeError(exec, message.toLatin1().constData()));
+ setException(context, exception, message);
} else if (!unresolved.isEmpty()) {
QtMethodMatchData argsInstance = unresolved.first();
int unresolvedIndex = argsInstance.firstUnresolvedIndex();
@@ -1317,7 +1327,7 @@
QString message = QString::fromLatin1("cannot call %0(): unknown type `%1'")
.arg(QString::fromLatin1(signature))
.arg(QLatin1String(unresolvedType.name()));
- *pError = throwError(exec, createTypeError(exec, message.toLatin1().constData()));
+ setException(context, exception, message);
} else {
QString message = QString::fromLatin1("too few arguments in call to %0(); candidates are\n")
.arg(QString::fromLatin1(signature));
@@ -1327,7 +1337,7 @@
QMetaMethod mtd = meta->method(tooFewArgs.at(i));
message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.methodSignature()));
}
- *pError = throwError(exec, createSyntaxError(exec, message.toLatin1().constData()));
+ setException(context, exception, message);
}
}
@@ -1349,7 +1359,7 @@
message += QString::fromLatin1(" %0").arg(QString::fromLatin1(mtd.methodSignature()));
}
}
- *pError = throwError(exec, createTypeError(exec, message.toLatin1().constData()));
+ setException(context, exception, message);
} else {
chosenIndex = bestMatch.index;
args = bestMatch.args;
@@ -1424,12 +1434,17 @@
QObject *obj = d->m_instance->getObject();
if (obj) {
+ const int argumentCount = static_cast<int>(exec->argumentCount());
+ Vector<JSValueRef, 10> args(argumentCount);
+ for (int i = 0; i < argumentCount; ++i)
+ args[i] = toRef(exec, exec->argument(i));
+
QVarLengthArray<QVariant, 10> vargs;
void *qargs[11];
int methodIndex;
- JSObject* errorObj = 0;
- if ((methodIndex = findMethodIndex(exec, obj->metaObject(), d->m_signature, d->m_allowPrivate, vargs, (void **)qargs, &errorObj)) != -1) {
+ JSValueRef exception = 0;
+ if ((methodIndex = findMethodIndex(toRef(exec), obj->metaObject(), d->m_signature, argumentCount, args.data(), d->m_allowPrivate, vargs, (void **)qargs, &exception)) != -1) {
if (QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, methodIndex, qargs) >= 0)
return JSValue::encode(jsUndefined());
@@ -1437,8 +1452,8 @@
return JSValue::encode(convertQVariantToValue(exec, d->m_instance->rootObject(), vargs[0]));
}
- if (errorObj)
- return JSValue::encode(errorObj);
+ if (exception)
+ return throwVMError(exec, toJS(exec, exception));
} else {
return throwVMError(exec, createError(exec, "cannot call function of deleted QObject"));
}
Modified: trunk/Source/WebKit/qt/tests/qobjectbridge/tst_qobjectbridge.cpp (125031 => 125032)
--- trunk/Source/WebKit/qt/tests/qobjectbridge/tst_qobjectbridge.cpp 2012-08-08 13:18:18 UTC (rev 125031)
+++ trunk/Source/WebKit/qt/tests/qobjectbridge/tst_qobjectbridge.cpp 2012-08-08 13:19:22 UTC (rev 125032)
@@ -1142,7 +1142,7 @@
QString type;
QString ret = evalJS("myObject.myInvokableWithVoidStarArg(123)", type);
QCOMPARE(type, sError);
- QCOMPARE(ret, QLatin1String("TypeError: incompatible type of argument(s) in call to myInvokableWithVoidStarArg(); candidates were\n myInvokableWithVoidStarArg(void*)"));
+ QCOMPARE(ret, QLatin1String("Error: incompatible type of argument(s) in call to myInvokableWithVoidStarArg(); candidates were\n myInvokableWithVoidStarArg(void*)"));
QCOMPARE(m_myObject->qtFunctionInvoked(), -1);
}
@@ -1151,7 +1151,7 @@
QString type;
QString ret = evalJS("myObject.myInvokableWithAmbiguousArg(123)", type);
QCOMPARE(type, sError);
- QCOMPARE(ret, QLatin1String("TypeError: ambiguous call of overloaded function myInvokableWithAmbiguousArg(); candidates were\n myInvokableWithAmbiguousArg(int)\n myInvokableWithAmbiguousArg(uint)"));
+ QCOMPARE(ret, QLatin1String("Error: ambiguous call of overloaded function myInvokableWithAmbiguousArg(); candidates were\n myInvokableWithAmbiguousArg(int)\n myInvokableWithAmbiguousArg(uint)"));
}
m_myObject->resetQtFunctionInvoked();
@@ -1380,7 +1380,7 @@
QString type;
QString ret = evalJS("myObject.myInvokableWithIntArg()", type);
QCOMPARE(type, sError);
- QCOMPARE(ret, QLatin1String("SyntaxError: too few arguments in call to myInvokableWithIntArg(); candidates are\n myInvokableWithIntArg(int,int)\n myInvokableWithIntArg(int)"));
+ QCOMPARE(ret, QLatin1String("Error: too few arguments in call to myInvokableWithIntArg(); candidates are\n myInvokableWithIntArg(int,int)\n myInvokableWithIntArg(int)"));
}
// call function where not all types have been registered
@@ -1389,7 +1389,7 @@
QString type;
QString ret = evalJS("myObject.myInvokableWithBrushStyleArg(0)", type);
QCOMPARE(type, sError);
- QCOMPARE(ret, QLatin1String("TypeError: cannot call myInvokableWithBrushStyleArg(): unknown type `Qt::BrushStyle'"));
+ QCOMPARE(ret, QLatin1String("Error: cannot call myInvokableWithBrushStyleArg(): unknown type `Qt::BrushStyle'"));
QCOMPARE(m_myObject->qtFunctionInvoked(), -1);
}
@@ -1399,7 +1399,7 @@
QString type;
QString ret = evalJS("myObject.myInvokableWithQBrushArg(null)", type);
QCOMPARE(type, sError);
- QCOMPARE(ret, QLatin1String("TypeError: incompatible type of argument(s) in call to myInvokableWithQBrushArg(); candidates were\n myInvokableWithQBrushArg(QBrush)"));
+ QCOMPARE(ret, QLatin1String("Error: incompatible type of argument(s) in call to myInvokableWithQBrushArg(); candidates were\n myInvokableWithQBrushArg(QBrush)"));
QCOMPARE(m_myObject->qtFunctionInvoked(), -1);
}
}