Changeset 846 for trunk/src/script/bridge/qscriptqobject.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/script/bridge/qscriptqobject.cpp
r651 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 36 36 #include "Error.h" 37 37 #include "PrototypeFunction.h" 38 #include "NativeFunctionWrapper.h" 38 39 #include "PropertyNameArray.h" 39 40 #include "JSFunction.h" … … 152 153 { 153 154 return (method.access() != QMetaMethod::Private) 154 && ((index != 2) || !(opt & QScriptEngine::ExcludeDeleteLater)); 155 && ((index != 2) || !(opt & QScriptEngine::ExcludeDeleteLater)) 156 && (!(opt & QScriptEngine::ExcludeSlots) || (method.methodType() != QMetaMethod::Slot)); 155 157 } 156 158 … … 164 166 } 165 167 166 static inline QByteArray methodName(const QMetaMethod &method) 167 { 168 QByteArray signature = method.signature(); 169 return signature.left(signature.indexOf('(')); 170 } 171 172 static QVariant variantFromValue(QScriptEnginePrivate *eng, 173 int targetType, const QScriptValue &value) 168 /*! \internal 169 Calculates the length of the name of the given \a method by looking 170 for the first '(' character. 171 */ 172 static inline int methodNameLength(const QMetaMethod &method) 173 { 174 const char *signature = method.signature(); 175 const char *s = signature; 176 while (*s && (*s != '(')) 177 ++s; 178 return s - signature; 179 } 180 181 /*! \internal 182 Makes a deep copy of the first \a nameLength characters of the given 183 method \a signature and returns the copy. 184 */ 185 static inline QByteArray methodName(const char *signature, int nameLength) 186 { 187 return QByteArray(signature, nameLength); 188 } 189 190 /*! \internal 191 192 Returns true if the name of the given \a method is the same as that 193 specified by the (signature, nameLength) pair, otherwise returns 194 false. 195 */ 196 static inline bool methodNameEquals(const QMetaMethod &method, 197 const char *signature, int nameLength) 198 { 199 const char *otherSignature = method.signature(); 200 return !qstrncmp(otherSignature, signature, nameLength) 201 && (otherSignature[nameLength] == '('); 202 } 203 204 static QVariant variantFromValue(JSC::ExecState *exec, int targetType, JSC::JSValue value) 174 205 { 175 206 QVariant v(targetType, (void *)0); 176 Q_ASSERT(eng); 177 if (QScriptEnginePrivate::convert(value, targetType, v.data(), eng)) 207 if (QScriptEnginePrivate::convertValue(exec, value, targetType, v.data())) 178 208 return v; 179 209 if (uint(targetType) == QVariant::LastType) 180 return value.toVariant();181 if ( value.isVariant()) {182 v = value.toVariant();210 return QScriptEnginePrivate::toVariant(exec, value); 211 if (QScriptEnginePrivate::isVariant(value)) { 212 v = QScriptEnginePrivate::variantValue(value); 183 213 if (v.canConvert(QVariant::Type(targetType))) { 184 214 v.convert(QVariant::Type(targetType)); … … 313 343 return QList<int>(); 314 344 QList<int> result; 315 QString name = functionName();316 345 const QMetaObject *meta = metaObject(); 346 QMetaMethod method = meta->method(initialIndex()); 347 int nameLength = methodNameLength(method); 317 348 for (int index = mostGeneralMethod() - 1; index >= 0; --index) { 318 QString otherName = QString::fromLatin1(methodName(meta->method(index))); 319 if (otherName == name) 349 if (methodNameEquals(meta->method(index), method.signature(), nameLength)) 320 350 result.append(index); 321 351 } 322 352 return result; 323 }324 325 QString QtFunction::functionName() const326 {327 const QMetaObject *meta = metaObject();328 if (!meta)329 return QString();330 QMetaMethod method = meta->method(initialIndex());331 return QLatin1String(methodName(method));332 353 } 333 354 … … 418 439 inline QScriptMetaMethod() 419 440 { } 420 inline QScriptMetaMethod(const Q ByteArray &name, const QVector<QScriptMetaType> &types)421 : m_ name(name), m_types(types), m_firstUnresolvedIndex(-1)441 inline QScriptMetaMethod(const QVector<QScriptMetaType> &types) 442 : m_types(types), m_firstUnresolvedIndex(-1) 422 443 { 423 444 QVector<QScriptMetaType>::const_iterator it; … … 432 453 { return !m_types.isEmpty(); } 433 454 434 QByteArray name() const435 { return m_name; }436 437 455 inline QScriptMetaType returnType() const 438 456 { return m_types.at(0); } … … 463 481 464 482 private: 465 QByteArray m_name;466 483 QVector<QScriptMetaType> m_types; 467 484 int m_firstUnresolvedIndex; … … 500 517 bool maybeOverloaded) 501 518 { 502 QByteArray funName;503 519 QScriptMetaMethod chosenMethod; 504 520 int chosenIndex = -1; … … 509 525 QVector<int> conversionFailed; 510 526 int index; 527 int nameLength = 0; 528 const char *initialMethodSignature = 0; 511 529 exec->clearException(); 512 530 QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(exec); … … 514 532 QMetaMethod method = metaMethod(meta, callType, index); 515 533 516 if (index == initialIndex) 517 funName = methodName(method); 518 else { 519 if (methodName(method) != funName) 534 if (index == initialIndex) { 535 initialMethodSignature = method.signature(); 536 nameLength = methodNameLength(method); 537 } else { 538 if (!methodNameEquals(method, initialMethodSignature, nameLength)) 520 539 continue; 521 540 } 522 541 542 QList<QByteArray> parameterTypeNames = method.parameterTypes(); 543 523 544 QVector<QScriptMetaType> types; 545 types.resize(1 + parameterTypeNames.size()); 546 QScriptMetaType *typesData = types.data(); 524 547 // resolve return type 525 548 QByteArray returnTypeName = method.typeName(); 526 549 int rtype = QMetaType::type(returnTypeName); 527 550 if ((rtype == 0) && !returnTypeName.isEmpty()) { 528 if (returnTypeName == "QVariant") { 529 types.append(QScriptMetaType::variant()); 530 } else { 531 int enumIndex = indexOfMetaEnum(meta, returnTypeName); 532 if (enumIndex != -1) 533 types.append(QScriptMetaType::metaEnum(enumIndex, returnTypeName)); 534 else 535 types.append(QScriptMetaType::unresolved(returnTypeName)); 536 } 551 int enumIndex = indexOfMetaEnum(meta, returnTypeName); 552 if (enumIndex != -1) 553 typesData[0] = QScriptMetaType::metaEnum(enumIndex, returnTypeName); 554 else 555 typesData[0] = QScriptMetaType::unresolved(returnTypeName); 537 556 } else { 538 557 if (callType == QMetaMethod::Constructor) 539 types .append(QScriptMetaType::metaType(QMetaType::QObjectStar, "QObject*"));540 else if (r eturnTypeName == "QVariant")541 types .append(QScriptMetaType::variant());558 typesData[0] = QScriptMetaType::metaType(QMetaType::QObjectStar, "QObject*"); 559 else if (rtype == QMetaType::QVariant) 560 typesData[0] = QScriptMetaType::variant(); 542 561 else 543 types .append(QScriptMetaType::metaType(rtype, returnTypeName));562 typesData[0] = QScriptMetaType::metaType(rtype, returnTypeName); 544 563 } 545 564 546 565 // resolve argument types 547 QList<QByteArray> parameterTypeNames = method.parameterTypes();548 566 for (int i = 0; i < parameterTypeNames.count(); ++i) { 549 567 QByteArray argTypeName = parameterTypeNames.at(i); 550 568 int atype = QMetaType::type(argTypeName); 551 569 if (atype == 0) { 552 if (argTypeName == "QVariant") { 553 types.append(QScriptMetaType::variant()); 554 } else { 555 int enumIndex = indexOfMetaEnum(meta, argTypeName); 556 if (enumIndex != -1) 557 types.append(QScriptMetaType::metaEnum(enumIndex, argTypeName)); 558 else 559 types.append(QScriptMetaType::unresolved(argTypeName)); 560 } 570 int enumIndex = indexOfMetaEnum(meta, argTypeName); 571 if (enumIndex != -1) 572 typesData[1 + i] = QScriptMetaType::metaEnum(enumIndex, argTypeName); 573 else 574 typesData[1 + i] = QScriptMetaType::unresolved(argTypeName); 575 } else if (atype == QMetaType::QVariant) { 576 typesData[1 + i] = QScriptMetaType::variant(); 561 577 } else { 562 if (argTypeName == "QVariant") 563 types.append(QScriptMetaType::variant()); 564 else 565 types.append(QScriptMetaType::metaType(atype, argTypeName)); 566 } 567 } 568 569 QScriptMetaMethod mtd = QScriptMetaMethod(methodName(method), types); 578 typesData[1 + i] = QScriptMetaType::metaType(atype, argTypeName); 579 } 580 } 581 582 QScriptMetaMethod mtd = QScriptMetaMethod(types); 570 583 571 584 if (int(scriptArgs.size()) < mtd.argumentCount()) { … … 592 605 int matchDistance = 0; 593 606 for (int i = 0; converted && i < mtd.argumentCount(); ++i) { 594 QScriptValue actual;607 JSC::JSValue actual; 595 608 if (i < (int)scriptArgs.size()) 596 actual = engine->scriptValueFromJSCValue(scriptArgs.at(i));609 actual = scriptArgs.at(i); 597 610 else 598 actual = QScriptValue(QScriptValue::UndefinedValue);611 actual = JSC::jsUndefined(); 599 612 QScriptMetaType argType = mtd.argumentType(i); 600 613 int tid = -1; … … 602 615 if (argType.isUnresolved()) { 603 616 v = QVariant(QMetaType::QObjectStar, (void *)0); 604 converted = engine->convertToNativeQObject(605 actual, argType.name(), reinterpret_cast<void* *>(v.data()));617 converted = QScriptEnginePrivate::convertToNativeQObject( 618 exec, actual, argType.name(), reinterpret_cast<void* *>(v.data())); 606 619 } else if (argType.isVariant()) { 607 if ( actual.isVariant()) {608 v = actual.toVariant();620 if (QScriptEnginePrivate::isVariant(actual)) { 621 v = QScriptEnginePrivate::variantValue(actual); 609 622 } else { 610 v = actual.toVariant();623 v = QScriptEnginePrivate::toVariant(exec, actual); 611 624 converted = v.isValid() || actual.isUndefined() || actual.isNull(); 612 625 } … … 614 627 tid = argType.typeId(); 615 628 v = QVariant(tid, (void *)0); 616 converted = QScriptEnginePrivate::convert (actual, tid, v.data(), engine);629 converted = QScriptEnginePrivate::convertValue(exec, actual, tid, v.data()); 617 630 if (exec->hadException()) 618 631 return exec->exception(); … … 620 633 621 634 if (!converted) { 622 if ( actual.isVariant()) {635 if (QScriptEnginePrivate::isVariant(actual)) { 623 636 if (tid == -1) 624 637 tid = argType.typeId(); 625 QVariant vv = actual.toVariant();638 QVariant vv = QScriptEnginePrivate::variantValue(actual); 626 639 if (vv.canConvert(QVariant::Type(tid))) { 627 640 v = vv; … … 650 663 if (m.isValid()) { 651 664 if (actual.isNumber()) { 652 int ival = actual.toInt32();665 int ival = QScriptEnginePrivate::toInt32(exec, actual); 653 666 if (m.valueToKey(ival) != 0) { 654 667 qVariantSetValue(v, ival); … … 657 670 } 658 671 } else { 659 QString sval = actual.toString();660 int ival = m.keyToValue( sval.toLatin1());672 JSC::UString sval = QScriptEnginePrivate::toString(exec, actual); 673 int ival = m.keyToValue(convertToLatin1(sval)); 661 674 if (ival != -1) { 662 675 qVariantSetValue(v, ival); … … 719 732 break; 720 733 } 721 } else if ( actual.isDate()) {734 } else if (QScriptEnginePrivate::isDate(actual)) { 722 735 switch (tid) { 723 736 case QMetaType::QDateTime: … … 734 747 break; 735 748 } 736 } else if ( actual.isRegExp()) {749 } else if (QScriptEnginePrivate::isRegExp(actual)) { 737 750 switch (tid) { 738 751 case QMetaType::QRegExp: … … 743 756 break; 744 757 } 745 } else if ( actual.isVariant()) {758 } else if (QScriptEnginePrivate::isVariant(actual)) { 746 759 if (argType.isVariant() 747 || ( actual.toVariant().userType() == tid)) {760 || (QScriptEnginePrivate::toVariant(exec, actual).userType() == tid)) { 748 761 // perfect 749 762 } else { 750 763 matchDistance += 10; 751 764 } 752 } else if ( actual.isArray()) {765 } else if (QScriptEnginePrivate::isArray(actual)) { 753 766 switch (tid) { 754 767 case QMetaType::QStringList: … … 760 773 break; 761 774 } 762 } else if ( actual.isQObject()) {775 } else if (QScriptEnginePrivate::isQObject(actual)) { 763 776 switch (tid) { 764 777 case QMetaType::QObjectStar: … … 842 855 // engine->notifyFunctionEntry(context); 843 856 //#endif 857 QString funName = QString::fromLatin1(methodName(initialMethodSignature, nameLength)); 844 858 if (!conversionFailed.isEmpty()) { 845 859 QString message = QString::fromLatin1("incompatible type of argument(s) in call to %0(); candidates were\n") 846 .arg( QLatin1String(funName));860 .arg(funName); 847 861 for (int i = 0; i < conversionFailed.size(); ++i) { 848 862 if (i > 0) … … 859 873 QString unresolvedTypeName = QString::fromLatin1(unresolvedType.name()); 860 874 QString message = QString::fromLatin1("cannot call %0(): ") 861 .arg( QString::fromLatin1(funName));875 .arg(funName); 862 876 if (unresolvedIndex > 0) { 863 877 message.append(QString::fromLatin1("argument %0 has unknown type `%1'"). … … 871 885 } else { 872 886 QString message = QString::fromLatin1("too few arguments in call to %0(); candidates are\n") 873 .arg( QLatin1String(funName));887 .arg(funName); 874 888 for (int i = 0; i < tooFewArgs.size(); ++i) { 875 889 if (i > 0) … … 887 901 && (metaArgs.matchDistance == candidates.at(1).matchDistance)) { 888 902 // ambiguous call 903 QByteArray funName = methodName(initialMethodSignature, nameLength); 889 904 QString message = QString::fromLatin1("ambiguous call of overloaded function %0(); candidates were\n") 890 905 .arg(QLatin1String(funName)); … … 954 969 QScriptMetaType retType = chosenMethod.returnType(); 955 970 if (retType.isVariant()) { 956 result = engine->jscValueFromVariant(*(QVariant *)params[0]);971 result = QScriptEnginePrivate::jscValueFromVariant(exec, *(QVariant *)params[0]); 957 972 } else if (retType.typeId() != 0) { 958 result = engine->scriptValueToJSCValue(engine->create(retType.typeId(), params[0])); 959 if (!result) { 960 QScriptValue sv = QScriptEnginePrivate::get(engine)->newVariant(QVariant(retType.typeId(), params[0])); 961 result = engine->scriptValueToJSCValue(sv); 962 } 973 result = QScriptEnginePrivate::create(exec, retType.typeId(), params[0]); 974 if (!result) 975 result = engine->newVariant(QVariant(retType.typeId(), params[0])); 963 976 } else { 964 977 result = JSC::jsUndefined(); … … 1050 1063 return throwError(exec, JSC::TypeError, "callee is not a QtPropertyFunction object"); 1051 1064 QtPropertyFunction *qfun = static_cast<QtPropertyFunction*>(callee); 1052 QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); 1053 JSC::ExecState *previousFrame = eng_p->currentFrame; 1054 eng_p->currentFrame = exec; 1055 eng_p->pushContext(exec, thisValue, args, callee); 1056 JSC::JSValue result = qfun->execute(eng_p->currentFrame, thisValue, args); 1057 eng_p->popContext(); 1058 eng_p->currentFrame = previousFrame; 1059 return result; 1065 return qfun->execute(exec, thisValue, args); 1060 1066 } 1061 1067 … … 1066 1072 JSC::JSValue result = JSC::jsUndefined(); 1067 1073 1068 // ### don't go via QScriptValue1069 1074 QScriptEnginePrivate *engine = scriptEngineFromExec(exec); 1070 thisValue = engine->toUsableValue(thisValue); 1071 QScriptValue object = engine->scriptValueFromJSCValue(thisValue); 1072 QObject *qobject = object.toQObject(); 1075 JSC::ExecState *previousFrame = engine->currentFrame; 1076 engine->currentFrame = exec; 1077 1078 JSC::JSValue qobjectValue = engine->toUsableValue(thisValue); 1079 QObject *qobject = QScriptEnginePrivate::toQObject(exec, qobjectValue); 1073 1080 while ((!qobject || (qobject->metaObject() != data->meta)) 1074 && object.prototype().isObject()) {1075 object = object.prototype();1076 qobject = object.toQObject();1081 && JSC::asObject(qobjectValue)->prototype().isObject()) { 1082 qobjectValue = JSC::asObject(qobjectValue)->prototype(); 1083 qobject = QScriptEnginePrivate::toQObject(exec, qobjectValue); 1077 1084 } 1078 1085 Q_ASSERT_X(qobject, Q_FUNC_INFO, "this-object must be a QObject"); … … 1086 1093 QScriptEngine *oldEngine = 0; 1087 1094 if (scriptable) { 1095 engine->pushContext(exec, thisValue, args, this); 1088 1096 oldEngine = QScriptablePrivate::get(scriptable)->engine; 1089 1097 QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(engine); … … 1092 1100 QVariant v = prop.read(qobject); 1093 1101 1094 if (scriptable) 1102 if (scriptable) { 1095 1103 QScriptablePrivate::get(scriptable)->engine = oldEngine; 1096 1097 result = engine->jscValueFromVariant(v); 1104 engine->popContext(); 1105 } 1106 1107 result = QScriptEnginePrivate::jscValueFromVariant(exec, v); 1098 1108 } 1099 1109 } else { … … 1107 1117 v = (QString)arg.toString(exec); 1108 1118 } else { 1109 // ### don't go via QScriptValue 1110 QScriptValue tmp = engine->scriptValueFromJSCValue(arg); 1111 v = variantFromValue(engine, prop.userType(), tmp); 1119 v = variantFromValue(exec, prop.userType(), arg); 1112 1120 } 1113 1121 … … 1115 1123 QScriptEngine *oldEngine = 0; 1116 1124 if (scriptable) { 1125 engine->pushContext(exec, thisValue, args, this); 1117 1126 oldEngine = QScriptablePrivate::get(scriptable)->engine; 1118 1127 QScriptablePrivate::get(scriptable)->engine = QScriptEnginePrivate::get(engine); … … 1121 1130 prop.write(qobject, v); 1122 1131 1123 if (scriptable) 1132 if (scriptable) { 1124 1133 QScriptablePrivate::get(scriptable)->engine = oldEngine; 1134 engine->popContext(); 1135 } 1125 1136 1126 1137 result = arg; 1127 1138 } 1139 engine->currentFrame = previousFrame; 1128 1140 return result; 1129 1141 } … … 1177 1189 //Note: this has to be kept in sync with getOwnPropertyDescriptor 1178 1190 #ifndef QT_NO_PROPERTIES 1179 QByteArray name = QString(propertyName.ustring()).toLatin1();1191 QByteArray name = convertToLatin1(propertyName.ustring()); 1180 1192 QObject *qobject = data->value; 1181 1193 if (!qobject) { … … 1238 1250 val = JSC::jsUndefined(); 1239 1251 else 1240 val = eng->jscValueFromVariant(prop.read(qobject));1252 val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject)); 1241 1253 slot.setValue(val); 1242 1254 } … … 1248 1260 index = qobject->dynamicPropertyNames().indexOf(name); 1249 1261 if (index != -1) { 1250 JSC::JSValue val = eng->jscValueFromVariant(qobject->property(name));1262 JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name)); 1251 1263 slot.setValue(val); 1252 1264 return true; … … 1258 1270 QMetaMethod method = meta->method(index); 1259 1271 if (hasMethodAccess(method, index, opt) 1260 && (methodName(method) == name)) {1272 && methodNameEquals(method, name.constData(), name.length())) { 1261 1273 QtFunction *fun = new (exec)QtFunction( 1262 1274 object, index, /*maybeOverloaded=*/true, … … 1275 1287 if (child->objectName() == QString(propertyName.ustring())) { 1276 1288 QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; 1277 QScriptValue tmp = QScriptEnginePrivate::get(eng)->newQObject(child, QScriptEngine::QtOwnership, opt); 1278 slot.setValue(eng->scriptValueToJSCValue(tmp)); 1289 slot.setValue(eng->newQObject(child, QScriptEngine::QtOwnership, opt)); 1279 1290 return true; 1280 1291 } … … 1293 1304 JSC::PropertyDescriptor &descriptor) 1294 1305 { 1295 //Note: this has to be kept in sync with getOwnPropertySlot abd getPropertyAttributes1306 //Note: this has to be kept in sync with getOwnPropertySlot 1296 1307 #ifndef QT_NO_PROPERTIES 1297 QByteArray name = QString(propertyName.ustring()).toLatin1();1308 QByteArray name = convertToLatin1(propertyName.ustring()); 1298 1309 QObject *qobject = data->value; 1299 1310 if (!qobject) { … … 1371 1382 val = JSC::jsUndefined(); 1372 1383 else 1373 val = eng->jscValueFromVariant(prop.read(qobject));1384 val = QScriptEnginePrivate::jscValueFromVariant(exec, prop.read(qobject)); 1374 1385 descriptor.setDescriptor(val, attributes); 1375 1386 } … … 1381 1392 index = qobject->dynamicPropertyNames().indexOf(name); 1382 1393 if (index != -1) { 1383 JSC::JSValue val = eng->jscValueFromVariant(qobject->property(name));1394 JSC::JSValue val = QScriptEnginePrivate::jscValueFromVariant(exec, qobject->property(name)); 1384 1395 descriptor.setDescriptor(val, QObjectMemberAttribute); 1385 1396 return true; … … 1391 1402 QMetaMethod method = meta->method(index); 1392 1403 if (hasMethodAccess(method, index, opt) 1393 && (methodName(method) == name)) {1404 && methodNameEquals(method, name.constData(), name.length())) { 1394 1405 QtFunction *fun = new (exec)QtFunction( 1395 1406 object, index, /*maybeOverloaded=*/true, … … 1411 1422 if (child->objectName() == QString(propertyName.ustring())) { 1412 1423 QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; 1413 QScriptValue tmp = QScriptEnginePrivate::get(eng)->newQObject(child, QScriptEngine::QtOwnership, opt);1414 descriptor.setDescriptor(eng->scriptValueToJSCValue(tmp),JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum);1424 descriptor.setDescriptor(eng->newQObject(child, QScriptEngine::QtOwnership, opt), 1425 JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum); 1415 1426 return true; 1416 1427 } … … 1429 1440 { 1430 1441 #ifndef QT_NO_PROPERTIES 1431 QByteArray name = ((QString)propertyName.ustring()).toLatin1();1442 QByteArray name = convertToLatin1(propertyName.ustring()); 1432 1443 QObject *qobject = data->value; 1433 1444 if (!qobject) { … … 1491 1502 v = (QString)value.toString(exec); 1492 1503 } else { 1493 v = eng->jscValueToVariant(value, prop.userType());1504 v = QScriptEnginePrivate::jscValueToVariant(exec, value, prop.userType()); 1494 1505 } 1495 1506 (void)prop.write(qobject, v); … … 1505 1516 QMetaMethod method = meta->method(index); 1506 1517 if (hasMethodAccess(method, index, opt) 1507 && (methodName(method) == name)) {1518 && methodNameEquals(method, name.constData(), name.length())) { 1508 1519 data->cachedMembers.insert(name, value); 1509 1520 return; … … 1513 1524 index = qobject->dynamicPropertyNames().indexOf(name); 1514 1525 if ((index != -1) || (opt & QScriptEngine::AutoCreateDynamicProperties)) { 1515 QVariant v = eng->scriptValueFromJSCValue(value).toVariant();1526 QVariant v = QScriptEnginePrivate::toVariant(exec, value); 1516 1527 (void)qobject->setProperty(name, v); 1517 1528 return; … … 1523 1534 1524 1535 bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec, 1525 const JSC::Identifier& propertyName, 1526 bool checkDontDelete) 1536 const JSC::Identifier& propertyName) 1527 1537 { 1528 1538 #ifndef QT_NO_PROPERTIES 1529 QByteArray name = ((QString)propertyName.ustring()).toLatin1();1539 QByteArray name = convertToLatin1(propertyName.ustring()); 1530 1540 QObject *qobject = data->value; 1531 1541 if (!qobject) { … … 1564 1574 } 1565 1575 1566 return QScriptObjectDelegate::deleteProperty(object, exec, propertyName , checkDontDelete);1576 return QScriptObjectDelegate::deleteProperty(object, exec, propertyName); 1567 1577 #else //QT_NO_PROPERTIES 1568 1578 return false; … … 1570 1580 } 1571 1581 1572 bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object,1573 JSC::ExecState *exec,1574 const JSC::Identifier &propertyName,1575 unsigned &attributes) const1576 {1577 #ifndef QT_NO_PROPERTIES1578 //Note: this has to be kept in sync with getOwnPropertyDescriptor and getOwnPropertySlot1579 QByteArray name = ((QString)propertyName.ustring()).toLatin1();1580 QObject *qobject = data->value;1581 if (!qobject)1582 return false;1583 1584 const QScriptEngine::QObjectWrapOptions &opt = data->options;1585 const QMetaObject *meta = qobject->metaObject();1586 int index = -1;1587 if (name.contains('(')) {1588 QByteArray normalized = QMetaObject::normalizedSignature(name);1589 if (-1 != (index = meta->indexOfMethod(normalized))) {1590 QMetaMethod method = meta->method(index);1591 if (hasMethodAccess(method, index, opt)) {1592 if (!(opt & QScriptEngine::ExcludeSuperClassMethods)1593 || (index >= meta->methodOffset())) {1594 attributes = QObjectMemberAttribute;1595 if (opt & QScriptEngine::SkipMethodsInEnumeration)1596 attributes |= JSC::DontEnum;1597 return true;1598 }1599 }1600 }1601 }1602 1603 index = meta->indexOfProperty(name);1604 if (index != -1) {1605 QMetaProperty prop = meta->property(index);1606 if (prop.isScriptable()) {1607 if (!(opt & QScriptEngine::ExcludeSuperClassProperties)1608 || (index >= meta->propertyOffset())) {1609 attributes = flagsForMetaProperty(prop);1610 return true;1611 }1612 }1613 }1614 1615 index = qobject->dynamicPropertyNames().indexOf(name);1616 if (index != -1) {1617 attributes = QObjectMemberAttribute;1618 return true;1619 }1620 1621 const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods)1622 ? meta->methodOffset() : 0;1623 for (index = meta->methodCount() - 1; index >= offset; --index) {1624 QMetaMethod method = meta->method(index);1625 if (hasMethodAccess(method, index, opt)1626 && (methodName(method) == name)) {1627 attributes = QObjectMemberAttribute;1628 if (opt & QScriptEngine::SkipMethodsInEnumeration)1629 attributes |= JSC::DontEnum;1630 return true;1631 }1632 }1633 1634 if (!(opt & QScriptEngine::ExcludeChildObjects)) {1635 QList<QObject*> children = qobject->children();1636 for (index = 0; index < children.count(); ++index) {1637 QObject *child = children.at(index);1638 if (child->objectName() == (QString)(propertyName.ustring())) {1639 attributes = JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum;1640 return true;1641 }1642 }1643 }1644 1645 return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attributes);1646 #else //QT_NO_PROPERTIES1647 return false;1648 #endif //QT_NO_PROPERTIES1649 }1650 1651 1582 void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState *exec, 1652 1583 JSC::PropertyNameArray &propertyNames, 1653 bool includeNonEnumerable)1584 JSC::EnumerationMode mode) 1654 1585 { 1655 1586 #ifndef QT_NO_PROPERTIES … … 1696 1627 } 1697 1628 1698 QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable);1629 QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode); 1699 1630 #endif //QT_NO_PROPERTIES 1700 1631 } … … 1824 1755 | QScriptEngine::ExcludeChildObjects)); 1825 1756 1826 putDirectFunction(exec, new (exec) JSC:: PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/0, exec->propertyNames().toString, qobjectProtoFuncToString), JSC::DontEnum);1827 putDirectFunction(exec, new (exec) JSC:: PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChild"), qobjectProtoFuncFindChild), JSC::DontEnum);1828 putDirectFunction(exec, new (exec) JSC:: PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChildren"), qobjectProtoFuncFindChildren), JSC::DontEnum);1757 putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/0, exec->propertyNames().toString, qobjectProtoFuncToString), JSC::DontEnum); 1758 putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChild"), qobjectProtoFuncFindChild), JSC::DontEnum); 1759 putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/1, JSC::Identifier(exec, "findChildren"), qobjectProtoFuncFindChildren), JSC::DontEnum); 1829 1760 this->structure()->setHasGetterSetterProperties(true); 1830 1761 } … … 1863 1794 } 1864 1795 1865 QByteArray name = QString(propertyName.ustring()).toLatin1();1796 QByteArray name = convertToLatin1(propertyName.ustring()); 1866 1797 1867 1798 for (int i = 0; i < meta->enumeratorCount(); ++i) { … … 1879 1810 } 1880 1811 1812 bool QMetaObjectWrapperObject::getOwnPropertyDescriptor( 1813 JSC::ExecState* exec, const JSC::Identifier& propertyName, 1814 JSC::PropertyDescriptor& descriptor) 1815 { 1816 const QMetaObject *meta = data->value; 1817 if (!meta) 1818 return false; 1819 1820 if (propertyName == exec->propertyNames().prototype) { 1821 descriptor.setDescriptor(data->ctor 1822 ? data->ctor.get(exec, propertyName) 1823 : data->prototype, 1824 JSC::DontDelete | JSC::DontEnum); 1825 return true; 1826 } 1827 1828 QByteArray name = QString(propertyName.ustring()).toLatin1(); 1829 1830 for (int i = 0; i < meta->enumeratorCount(); ++i) { 1831 QMetaEnum e = meta->enumerator(i); 1832 for (int j = 0; j < e.keyCount(); ++j) { 1833 const char *key = e.key(j); 1834 if (!qstrcmp(key, name.constData())) { 1835 descriptor.setDescriptor(JSC::JSValue(exec, e.value(j)), 1836 JSC::ReadOnly | JSC::DontDelete); 1837 return true; 1838 } 1839 } 1840 } 1841 1842 return JSC::JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 1843 } 1844 1881 1845 void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, 1882 1846 JSC::JSValue value, JSC::PutPropertySlot &slot) … … 1891 1855 const QMetaObject *meta = data->value; 1892 1856 if (meta) { 1893 QByteArray name = QString(propertyName.ustring()).toLatin1();1857 QByteArray name = convertToLatin1(propertyName.ustring()); 1894 1858 for (int i = 0; i < meta->enumeratorCount(); ++i) { 1895 1859 QMetaEnum e = meta->enumerator(i); … … 1904 1868 1905 1869 bool QMetaObjectWrapperObject::deleteProperty( 1906 JSC::ExecState *exec, const JSC::Identifier& propertyName, 1907 bool checkDontDelete) 1870 JSC::ExecState *exec, const JSC::Identifier& propertyName) 1908 1871 { 1909 1872 if (propertyName == exec->propertyNames().prototype) … … 1911 1874 const QMetaObject *meta = data->value; 1912 1875 if (meta) { 1913 QByteArray name = QString(propertyName.ustring()).toLatin1();1876 QByteArray name = convertToLatin1(propertyName.ustring()); 1914 1877 for (int i = 0; i < meta->enumeratorCount(); ++i) { 1915 1878 QMetaEnum e = meta->enumerator(i); … … 1920 1883 } 1921 1884 } 1922 return JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete); 1923 } 1924 1925 bool QMetaObjectWrapperObject::getPropertyAttributes(JSC::ExecState *exec, 1926 const JSC::Identifier &propertyName, 1927 unsigned &attributes) const 1928 { 1929 if (propertyName == exec->propertyNames().prototype) { 1930 attributes = JSC::DontDelete; 1931 return true; 1932 } 1933 const QMetaObject *meta = data->value; 1934 if (meta) { 1935 QByteArray name = QString(propertyName.ustring()).toLatin1(); 1936 for (int i = 0; i < meta->enumeratorCount(); ++i) { 1937 QMetaEnum e = meta->enumerator(i); 1938 for (int j = 0; j < e.keyCount(); ++j) { 1939 if (!qstrcmp(e.key(j), name.constData())) { 1940 attributes = JSC::ReadOnly | JSC::DontDelete; 1941 return true; 1942 } 1943 } 1944 } 1945 } 1946 return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); 1885 return JSC::JSObject::deleteProperty(exec, propertyName); 1947 1886 } 1948 1887 1949 1888 void QMetaObjectWrapperObject::getOwnPropertyNames(JSC::ExecState *exec, 1950 1889 JSC::PropertyNameArray &propertyNames, 1951 bool includeNonEnumerable)1890 JSC::EnumerationMode mode) 1952 1891 { 1953 1892 const QMetaObject *meta = data->value; … … 1959 1898 propertyNames.add(JSC::Identifier(exec, e.key(j))); 1960 1899 } 1961 JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable);1900 JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode); 1962 1901 } 1963 1902 … … 2078 2017 : QMetaObjectWrapperObject(exec, StaticQtMetaObject::get(), /*ctor=*/JSC::JSValue(), structure) 2079 2018 { 2080 putDirectFunction(exec, new (exec) JSC:: PrototypeFunction(exec, prototypeFunctionStructure, /*length=*/0, JSC::Identifier(exec, "className"), qmetaobjectProtoFuncClassName), JSC::DontEnum);2019 putDirectFunction(exec, new (exec) JSC::NativeFunctionWrapper(exec, prototypeFunctionStructure, /*length=*/0, JSC::Identifier(exec, "className"), qmetaobjectProtoFuncClassName), JSC::DontEnum); 2081 2020 } 2082 2021 … … 2137 2076 JSC::JSValue senderWrapper; 2138 2077 int signalIndex = -1; 2078 QScript::APIShim shim(engine); 2139 2079 for (int i = 0; i < connections.size(); ++i) { 2140 2080 const QVector<QObjectConnection> &cs = connections.at(i); … … 2179 2119 QVarLengthArray<JSC::JSValue, 8> argsVector(argc); 2180 2120 for (int i = 0; i < argc; ++i) { 2181 // ### optimize -- no need to convert via QScriptValue 2182 QScriptValue actual; 2121 JSC::JSValue actual; 2183 2122 void *arg = argv[i + 1]; 2184 2123 QByteArray typeName = parameterTypes.at(i); 2185 2124 int argType = QMetaType::type(parameterTypes.at(i)); 2186 2125 if (!argType) { 2187 if (typeName == "QVariant") { 2188 actual = engine->scriptValueFromVariant(*reinterpret_cast<QVariant*>(arg)); 2189 } else { 2190 qWarning("QScriptEngine: Unable to handle unregistered datatype '%s' " 2191 "when invoking handler of signal %s::%s", 2192 typeName.constData(), meta->className(), method.signature()); 2193 actual = QScriptValue(QScriptValue::UndefinedValue); 2194 } 2126 qWarning("QScriptEngine: Unable to handle unregistered datatype '%s' " 2127 "when invoking handler of signal %s::%s", 2128 typeName.constData(), meta->className(), method.signature()); 2129 actual = JSC::jsUndefined(); 2130 } else if (argType == QMetaType::QVariant) { 2131 actual = QScriptEnginePrivate::jscValueFromVariant(exec, *reinterpret_cast<QVariant*>(arg)); 2195 2132 } else { 2196 actual = engine->create(argType, arg);2197 } 2198 argsVector[i] = engine->scriptValueToJSCValue(actual);2133 actual = QScriptEnginePrivate::create(exec, argType, arg); 2134 } 2135 argsVector[i] = actual; 2199 2136 } 2200 2137 JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
Note:
See TracChangeset
for help on using the changeset viewer.