45 #include "private/qdeclarativecompiledbindings_p.h" 47 #include <QtDeclarative/qdeclarativeinfo.h> 48 #include <private/qdeclarativecontext_p.h> 49 #include <private/qdeclarativejsast_p.h> 50 #include <private/qdeclarativejsengine_p.h> 51 #include <private/qdeclarativeexpression_p.h> 52 #include <QtCore/qcoreapplication.h> 53 #include <QtCore/qdebug.h> 54 #include <QtCore/qnumeric.h> 55 #include <private/qdeclarativeanchors_p_p.h> 56 #include <private/qdeclarativeglobal_p.h> 57 #include <private/qdeclarativefastproperties_p.h> 58 #include <private/qdeclarativedebugtrace_p.h> 69 #if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200) 70 # define QML_THREADED_INTERPRETER 73 #define FOR_EACH_QML_INSTR(F) \ 78 F(FetchAndSubscribe) \ 113 F(FindGenericTerminal) \ 115 F(FindPropertyTerminal) \ 117 F(ConvertGenericToReal) \ 118 F(ConvertGenericToBool) \ 119 F(ConvertGenericToString) \ 120 F(ConvertGenericToUrl) 122 #define QML_INSTR_ENUM(I) I, 123 #define QML_INSTR_ADDR(I) &&op_##I, 125 #ifdef QML_THREADED_INTERPRETER 126 # define QML_BEGIN_INSTR(I) op_##I: 127 # define QML_END_INSTR(I) ++instr; goto *instr->common.code; 128 # define QML_INSTR_HEADER void *code; 130 # define QML_BEGIN_INSTR(I) case Instr::I: 131 # define QML_END_INSTR(I) break; 132 # define QML_INSTR_HEADER 141 void setUndefined() {
type = 0; }
142 void setUnknownButDefined() {
type = -1; }
143 void setNaN() { setqreal(
qSNaN()); }
144 bool isUndefined()
const {
return type == 0; }
147 QObject *getQObject()
const {
return qobjectValue; }
150 qreal getqreal()
const {
return qrealValue; }
153 int getint()
const {
return intValue; }
156 bool getbool()
const {
return boolValue; }
160 QUrl *geturlptr() {
return (
QUrl *)typeDataPtr(); }
162 const QString *getstringptr()
const {
return (
QString *)typeDataPtr(); }
163 const QUrl *geturlptr()
const {
return (
QUrl *)typeDataPtr(); }
165 void *typeDataPtr() {
return (
void *)&
data; }
166 void *typeMemory() {
return (
void *)
data; }
167 const void *typeDataPtr()
const {
return (
void *)&
data; }
168 const void *typeMemory()
const {
return (
void *)
data; }
170 int gettype()
const {
return type; }
171 void settype(
int t) {
type = t; }
181 double q_for_alignment_2;
184 #ifdef REGISTER_CLEANUP_DEBUG 191 bool found = (type == 0);
192 int *ctype = allowedTypes;
193 while (!found && *ctype) {
194 found = (*ctype ==
type);
198 qWarning(
"Register leaked of type %d", type);
214 scope(0), target(0), parent(0) {}
217 virtual void setEnabled(
bool, QDeclarativePropertyPrivate::WriteFlags flags);
218 virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
236 void run(
Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
252 inline void subscribe(
QObject *o,
int notifyIndex,
int subIndex);
253 inline void disconnectAll();
254 inline void disconnectOne(
Binding *bindingToDisconnect);
260 bool findproperty(
QObject *obj,
266 void findgeneric(Register *output,
274 : subscriptions(0), identifiers(0), programData(0), dataRef(0), m_bindings(0), m_signalTable(0),
275 m_bindingsDisconnected(false)
297 if (
d->methodCount == -1)
300 d->programData = program;
301 d->dataRef = dataRef;
302 if (
d->dataRef)
d->dataRef->addref();
313 delete []
d->m_bindings;
339 if (e) update(flags);
352 if (mode == DisconnectBinding)
358 parent->q_func()->release();
366 parent->disconnectOne(
this);
374 id -=
d->methodCount;
376 quint32 *reeval =
d->m_signalTable +
d->m_signalTable[id];
379 for (
quint32 ii = 0; ii < count; ++ii) {
394 if (!context || !context->
isValid())
399 if (binding->
property & 0xFFFF0000) {
416 if (binding->
property & 0xFFFF0000) {
424 run(binding->
index, context, binding, binding->
scope, target, flags);
605 const char *
data()
const {
return ((
const char *)
this) +
sizeof(Program); }
606 const Instr *instructions()
const {
return (
const Instr *)(
data() + dataLength); }
621 return !(*
this == o);
633 void resetInstanceState();
674 int acquireReg(
int cleanup = Instr::Noop,
int cleanupType = 0);
675 void registerCleanup(
int reg,
int cleanup,
int cleanupType = 0);
676 void releaseReg(
int);
678 int registerLiteralString(
const QString &);
679 int registerString(
const QString &);
707 int count()
const {
return offsets.
count(); }
745 if (m_bindingsDisconnected)
750 Program *program = (Program *)programData;
751 for (
int subIndex = 0; subIndex < program->subscriptions; ++subIndex) {
756 m_bindingsDisconnected =
true;
764 Program *program = (Program *)programData;
765 for (
int subIndex = 0; subIndex < program->subscriptions; ++subIndex) {
767 quint32 *reeval = m_signalTable + m_signalTable[subIndex];
768 quint32 bindingCount = *reeval;
770 for (
quint32 bindingIndex = 0; bindingIndex < bindingCount; ++bindingIndex) {
771 Binding *
const binding = m_bindings + reeval[bindingIndex];
772 if (binding == bindingToDisconnect)
784 return reg->getqreal();
785 }
else if (type == qMetaTypeId<QVariant>()) {
786 return reg->getvariantptr()->toReal();
801 }
else if (type == qMetaTypeId<QVariant>()) {
802 return reg->getvariantptr()->toString();
804 return *reg->getstringptr();
811 inline static bool toBool(Register *reg,
int type,
bool *ok = 0)
816 return reg->getbool();
817 }
else if (type == qMetaTypeId<QVariant>()) {
818 return reg->getvariantptr()->toBool();
830 if (type == qMetaTypeId<QVariant>()) {
831 QVariant *var = reg->getvariantptr();
832 int vt = var->
type();
844 base =
QUrl(*reg->getstringptr());
874 output->setUndefined();
884 subscribe(obj,
property->notifyIndex, subIdx);
887 void *args[] = { output->typeDataPtr(), 0 };
890 }
else if (
property->propType == qMetaTypeId<QVariant>()) {
892 void *args[] = { &v, 0 };
896 new (output->typeDataPtr())
QVariant(v);
897 output->settype(qMetaTypeId<QVariant>());
902 output->setUndefined();
909 output->setUndefined();
911 void *args[] = { output->typeDataPtr(), 0 };
915 void *args[] = { output->typeDataPtr(), 0 };
919 void *args[] = { output->typeDataPtr(), 0 };
923 new (output->typeDataPtr())
QString();
924 void *args[] = { output->typeDataPtr(), 0 };
928 new (output->typeDataPtr())
930 output->settype(qMetaTypeId<QVariant>());
936 output->setUndefined();
954 if (contextPropertyIndex != -1) {
956 if (contextPropertyIndex < context->idValueCount) {
957 output->setQObject(context->
idValues[contextPropertyIndex]);
961 subscribeId(context, contextPropertyIndex, subIdx);
968 new (output->typeDataPtr())
QVariant(value);
969 output->settype(qMetaTypeId<QVariant>());
973 if (!ok) { output->setUndefined(); }
989 if (findproperty(root, output, enginePriv, subIdx, name, isTerminal))
994 context = context->
parent;
997 output->setUndefined();
1002 Program *program = (Program *)programData;
1003 if (program->subscriptions)
1005 if (program->identifiers)
1008 m_signalTable = (
quint32 *)(program->data() + program->signalTableOffset);
1017 if (description.isEmpty())
1022 quint64 e = *((
quint64 *)(program->data() + program->exceptionDataOffset) +
id);
1035 switch (instr->common.type) {
1037 qWarning().nospace() <<
"\t" <<
"Noop";
1039 case Instr::BindingId:
1040 qWarning().nospace() << instr->id.line <<
":" << instr->id.column <<
":";
1042 case Instr::Subscribe:
1043 qWarning().nospace() <<
"\t" <<
"Subscribe" <<
"\t\t" << instr->subscribe.offset <<
"\t" << instr->subscribe.reg <<
"\t" << instr->subscribe.index;
1045 case Instr::SubscribeId:
1046 qWarning().nospace() <<
"\t" <<
"SubscribeId" <<
"\t\t" << instr->subscribe.offset <<
"\t" << instr->subscribe.reg <<
"\t" << instr->subscribe.index;
1048 case Instr::FetchAndSubscribe:
1049 qWarning().nospace() <<
"\t" <<
"FetchAndSubscribe" <<
"\t" << instr->fetchAndSubscribe.output <<
"\t" << instr->fetchAndSubscribe.objectReg <<
"\t" << instr->fetchAndSubscribe.subscription;
1052 qWarning().nospace() <<
"\t" <<
"LoadId" <<
"\t\t\t" << instr->load.index <<
"\t" << instr->load.reg;
1054 case Instr::LoadScope:
1055 qWarning().nospace() <<
"\t" <<
"LoadScope" <<
"\t\t" << instr->load.index <<
"\t" << instr->load.reg;
1057 case Instr::LoadRoot:
1058 qWarning().nospace() <<
"\t" <<
"LoadRoot" <<
"\t\t" << instr->load.index <<
"\t" << instr->load.reg;
1060 case Instr::LoadAttached:
1061 qWarning().nospace() <<
"\t" <<
"LoadAttached" <<
"\t\t" << instr->attached.output <<
"\t" << instr->attached.reg <<
"\t" << instr->attached.id;
1063 case Instr::ConvertIntToReal:
1064 qWarning().nospace() <<
"\t" <<
"ConvertIntToReal" <<
"\t" << instr->unaryop.output <<
"\t" << instr->unaryop.src;
1066 case Instr::ConvertRealToInt:
1067 qWarning().nospace() <<
"\t" <<
"ConvertRealToInt" <<
"\t" << instr->unaryop.output <<
"\t" << instr->unaryop.src;
1070 qWarning().nospace() <<
"\t" <<
"Real" <<
"\t\t\t" << instr->real_value.reg <<
"\t" << instr->real_value.value;
1073 qWarning().nospace() <<
"\t" <<
"Int" <<
"\t\t\t" << instr->int_value.reg <<
"\t" << instr->int_value.value;
1076 qWarning().nospace() <<
"\t" <<
"Bool" <<
"\t\t\t" << instr->bool_value.reg <<
"\t" << instr->bool_value.value;
1079 qWarning().nospace() <<
"\t" <<
"String" <<
"\t\t\t" << instr->string_value.reg <<
"\t" << instr->string_value.offset <<
"\t" << instr->string_value.length;
1081 case Instr::AddReal:
1082 qWarning().nospace() <<
"\t" <<
"AddReal" <<
"\t\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1085 qWarning().nospace() <<
"\t" <<
"AddInt" <<
"\t\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1087 case Instr::AddString:
1088 qWarning().nospace() <<
"\t" <<
"AddString" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1090 case Instr::MinusReal:
1091 qWarning().nospace() <<
"\t" <<
"MinusReal" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1093 case Instr::MinusInt:
1094 qWarning().nospace() <<
"\t" <<
"MinusInt" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1096 case Instr::CompareReal:
1097 qWarning().nospace() <<
"\t" <<
"CompareReal" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1099 case Instr::CompareString:
1100 qWarning().nospace() <<
"\t" <<
"CompareString" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1102 case Instr::NotCompareReal:
1103 qWarning().nospace() <<
"\t" <<
"NotCompareReal" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1105 case Instr::NotCompareString:
1106 qWarning().nospace() <<
"\t" <<
"NotCompareString" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1108 case Instr::GreaterThanReal:
1109 qWarning().nospace() <<
"\t" <<
"GreaterThanReal" <<
"\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1111 case Instr::MaxReal:
1112 qWarning().nospace() <<
"\t" <<
"MaxReal" <<
"\t\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1114 case Instr::MinReal:
1115 qWarning().nospace() <<
"\t" <<
"MinReal" <<
"\t\t\t" << instr->binaryop.output <<
"\t" << instr->binaryop.src1 <<
"\t" << instr->binaryop.src2;
1117 case Instr::NewString:
1118 qWarning().nospace() <<
"\t" <<
"NewString" <<
"\t\t" << instr->construct.reg;
1121 qWarning().nospace() <<
"\t" <<
"NewUrl" <<
"\t\t\t" << instr->construct.reg;
1123 case Instr::CleanupString:
1124 qWarning().nospace() <<
"\t" <<
"CleanupString" <<
"\t\t" << instr->cleanup.reg;
1126 case Instr::CleanupUrl:
1127 qWarning().nospace() <<
"\t" <<
"CleanupUrl" <<
"\t\t" << instr->cleanup.reg;
1130 qWarning().nospace() <<
"\t" <<
"Fetch" <<
"\t\t\t" << instr->fetch.output <<
"\t" << instr->fetch.index <<
"\t" << instr->fetch.objectReg;
1133 qWarning().nospace() <<
"\t" <<
"Store" <<
"\t\t\t" << instr->store.output <<
"\t" << instr->store.index <<
"\t" << instr->store.reg;
1136 qWarning().nospace() <<
"\t" <<
"Copy" <<
"\t\t\t" << instr->copy.reg <<
"\t" << instr->copy.src;
1139 qWarning().nospace() <<
"\t" <<
"Skip" <<
"\t\t\t" << instr->skip.reg <<
"\t" << instr->skip.count;
1142 qWarning().nospace() <<
"\t" <<
"Done";
1144 case Instr::InitString:
1145 qWarning().nospace() <<
"\t" <<
"InitString" <<
"\t\t" << instr->initstring.offset <<
"\t" << instr->initstring.dataIdx;
1147 case Instr::FindGeneric:
1148 qWarning().nospace() <<
"\t" <<
"FindGeneric" <<
"\t\t" << instr->find.reg <<
"\t" << instr->find.name;
1150 case Instr::FindGenericTerminal:
1151 qWarning().nospace() <<
"\t" <<
"FindGenericTerminal" <<
"\t" << instr->find.reg <<
"\t" << instr->find.name;
1153 case Instr::FindProperty:
1154 qWarning().nospace() <<
"\t" <<
"FindProperty" <<
"\t\t" << instr->find.reg <<
"\t" << instr->find.src <<
"\t" << instr->find.name;
1156 case Instr::FindPropertyTerminal:
1157 qWarning().nospace() <<
"\t" <<
"FindPropertyTerminal" <<
"\t" << instr->find.reg <<
"\t" << instr->find.src <<
"\t" << instr->find.name;
1159 case Instr::CleanupGeneric:
1160 qWarning().nospace() <<
"\t" <<
"CleanupGeneric" <<
"\t\t" << instr->cleanup.reg;
1162 case Instr::ConvertGenericToReal:
1163 qWarning().nospace() <<
"\t" <<
"ConvertGenericToReal" <<
"\t" << instr->unaryop.output <<
"\t" << instr->unaryop.src;
1165 case Instr::ConvertGenericToBool:
1166 qWarning().nospace() <<
"\t" <<
"ConvertGenericToBool" <<
"\t" << instr->unaryop.output <<
"\t" << instr->unaryop.src;
1168 case Instr::ConvertGenericToString:
1169 qWarning().nospace() <<
"\t" <<
"ConvertGenericToString" <<
"\t" << instr->unaryop.output <<
"\t" << instr->unaryop.src;
1171 case Instr::ConvertGenericToUrl:
1172 qWarning().nospace() <<
"\t" <<
"ConvertGenericToUrl" <<
"\t" << instr->unaryop.output <<
"\t" << instr->unaryop.src;
1175 qWarning().nospace() <<
"\t" <<
"Unknown";
1182 QObject *scope,
QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags)
1188 Register registers[32];
1191 Program *program = (Program *)programData;
1192 const Instr *instr = program->instructions();
1193 instr += instrIndex;
1194 const char *
data = program->data();
1196 #ifdef QML_THREADED_INTERPRETER 1197 static void *decode_instr[] = {
1201 if (!program->compiled) {
1202 program->compiled =
true;
1203 const Instr *inop = program->instructions();
1204 for (
int i = 0; i < program->instructionCount; ++i) {
1205 Instr *op = (Instr *) inop++;
1206 op->common.code = decode_instr[op->common.type];
1210 goto *instr->common.code;
1214 #ifdef COMPILEDBINDINGS_DEBUG 1215 qWarning().nospace() <<
"Begin binding run";
1219 switch (instr->common.type) {
1221 #ifdef COMPILEDBINDINGS_DEBUG 1234 subscribeId(context, instr->subscribe.index, instr->subscribe.offset);
1240 const Register &
object = registers[instr->subscribe.reg];
1241 if (!
object.isUndefined()) o =
object.getQObject();
1242 subscribe(o, instr->subscribe.index, instr->subscribe.offset);
1248 const Register &input = registers[instr->fetchAndSubscribe.objectReg];
1249 Register &output = registers[instr->fetchAndSubscribe.output];
1251 if (input.isUndefined()) {
1252 throwException(instr->fetchAndSubscribe.exceptionId, error, program, context);
1256 QObject *
object = input.getQObject();
1258 output.setUndefined();
1260 int subIdx = instr->fetchAndSubscribe.subscription;
1263 sub = (subscriptions + subIdx);
1267 fastProperties()->accessor(instr->fetchAndSubscribe.function)(object, output.typeDataPtr(), sub);
1273 registers[instr->load.reg].setQObject(context->
idValues[instr->load.index].
data());
1277 registers[instr->load.reg].setQObject(scope);
1281 registers[instr->load.reg].setQObject(context->
contextObject);
1286 const Register &input = registers[instr->attached.reg];
1287 Register &output = registers[instr->attached.output];
1288 if (input.isUndefined()) {
1289 throwException(instr->attached.exceptionId, error, program, context);
1293 QObject *
object = registers[instr->attached.reg].getQObject();
1295 output.setUndefined();
1299 registers[instr->attached.reg].getQObject(),
1302 output.setQObject(attached);
1309 const Register &input = registers[instr->unaryop.src];
1310 Register &output = registers[instr->unaryop.output];
1311 if (input.isUndefined()) output.setUndefined();
1312 else output.setqreal(
qreal(input.getint()));
1318 const Register &input = registers[instr->unaryop.src];
1319 Register &output = registers[instr->unaryop.output];
1320 if (input.isUndefined()) output.setUndefined();
1321 else output.setint(
qRound(input.getqreal()));
1326 registers[instr->real_value.reg].setqreal(instr->real_value.value);
1330 registers[instr->int_value.reg].setint(instr->int_value.value);
1334 registers[instr->bool_value.reg].setbool(instr->bool_value.value);
1339 Register &output = registers[instr->string_value.reg];
1340 new (output.getstringptr())
1341 QString((
QChar *)(data + instr->string_value.offset), instr->string_value.length);
1348 const Register &lhs = registers[instr->binaryop.src1];
1349 const Register &rhs = registers[instr->binaryop.src2];
1350 Register &output = registers[instr->binaryop.output];
1351 if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
1352 else output.setqreal(lhs.getqreal() + rhs.getqreal());
1358 const Register &lhs = registers[instr->binaryop.src1];
1359 const Register &rhs = registers[instr->binaryop.src2];
1360 Register &output = registers[instr->binaryop.output];
1361 if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
1362 else output.setint(lhs.getint() + rhs.getint());
1368 const Register &lhs = registers[instr->binaryop.src1];
1369 const Register &rhs = registers[instr->binaryop.src2];
1370 Register &output = registers[instr->binaryop.output];
1371 if (lhs.isUndefined() && rhs.isUndefined()) { output.setNaN(); }
1373 if (lhs.isUndefined())
1374 new (output.getstringptr())
1376 else if (rhs.isUndefined())
1377 new (output.getstringptr())
1380 new (output.getstringptr())
1381 QString(*registers[instr->binaryop.src1].getstringptr() +
1382 *registers[instr->binaryop.src2].getstringptr());
1390 const Register &lhs = registers[instr->binaryop.src1];
1391 const Register &rhs = registers[instr->binaryop.src2];
1392 Register &output = registers[instr->binaryop.output];
1393 if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
1394 else output.setqreal(lhs.getqreal() - rhs.getqreal());
1400 const Register &lhs = registers[instr->binaryop.src1];
1401 const Register &rhs = registers[instr->binaryop.src2];
1402 Register &output = registers[instr->binaryop.output];
1403 if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
1404 else output.setint(lhs.getint() - rhs.getint());
1410 const Register &lhs = registers[instr->binaryop.src1];
1411 const Register &rhs = registers[instr->binaryop.src2];
1412 Register &output = registers[instr->binaryop.output];
1413 if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() == rhs.isUndefined());
1414 else output.setbool(lhs.getqreal() == rhs.getqreal());
1420 const Register &lhs = registers[instr->binaryop.src1];
1421 const Register &rhs = registers[instr->binaryop.src2];
1422 Register &output = registers[instr->binaryop.output];
1423 if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() == rhs.isUndefined());
1424 else output.setbool(*lhs.getstringptr() == *rhs.getstringptr());
1430 const Register &lhs = registers[instr->binaryop.src1];
1431 const Register &rhs = registers[instr->binaryop.src2];
1432 Register &output = registers[instr->binaryop.output];
1433 if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() != rhs.isUndefined());
1434 else output.setbool(lhs.getqreal() != rhs.getqreal());
1440 const Register &lhs = registers[instr->binaryop.src1];
1441 const Register &rhs = registers[instr->binaryop.src2];
1442 Register &output = registers[instr->binaryop.output];
1443 if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() != rhs.isUndefined());
1444 else output.setbool(*lhs.getstringptr() != *rhs.getstringptr());
1450 const Register &lhs = registers[instr->binaryop.src1];
1451 const Register &rhs = registers[instr->binaryop.src2];
1452 Register &output = registers[instr->binaryop.output];
1453 if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(
false);
1454 else output.setbool(lhs.getqreal() > rhs.getqreal());
1460 const Register &lhs = registers[instr->binaryop.src1];
1461 const Register &rhs = registers[instr->binaryop.src2];
1462 Register &output = registers[instr->binaryop.output];
1463 if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
1464 else output.setqreal(
qMax(lhs.getqreal(), rhs.getqreal()));
1470 const Register &lhs = registers[instr->binaryop.src1];
1471 const Register &rhs = registers[instr->binaryop.src2];
1472 Register &output = registers[instr->binaryop.output];
1473 if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
1474 else output.setqreal(
qMin(lhs.getqreal(), rhs.getqreal()));
1480 Register &output = registers[instr->construct.reg];
1481 new (output.getstringptr())
QString;
1488 Register &output = registers[instr->construct.reg];
1489 new (output.geturlptr())
QUrl;
1495 registers[instr->cleanup.reg].getstringptr()->~QString();
1496 #ifdef REGISTER_CLEANUP_DEBUG 1497 registers[instr->cleanup.reg].setUndefined();
1502 registers[instr->cleanup.reg].geturlptr()->~QUrl();
1503 #ifdef REGISTER_CLEANUP_DEBUG 1504 registers[instr->cleanup.reg].setUndefined();
1510 const Register &input = registers[instr->fetch.objectReg];
1511 Register &output = registers[instr->fetch.output];
1513 if (input.isUndefined()) {
1514 throwException(instr->fetch.exceptionId, error, program, context);
1518 QObject *
object = input.getQObject();
1520 output.setUndefined();
1522 void *argv[] = { output.typeDataPtr(), 0 };
1530 Register &data = registers[instr->store.reg];
1531 if (data.isUndefined()) {
1532 throwException(instr->store.exceptionId, error, program, context,
1538 void *argv[] = { data.typeDataPtr(), 0, &
status, &storeFlags };
1540 instr->store.index, argv);
1545 registers[instr->copy.reg] = registers[instr->copy.src];
1549 if (instr->skip.reg == -1 || !registers[instr->skip.reg].getbool())
1550 instr += instr->skip.count;
1558 if (!identifiers[instr->initstring.offset].identifier) {
1572 findgeneric(registers + instr->find.reg, instr->find.subscribeIndex,
1574 identifiers[instr->find.name].identifier,
1575 instr->common.type == Instr::FindGenericTerminal);
1582 findgeneric(registers + instr->find.reg, instr->find.subscribeIndex,
1584 identifiers[instr->find.name].identifier,
1585 instr->common.type == Instr::FindGenericTerminal);
1590 const Register &
object = registers[instr->find.src];
1591 if (
object.isUndefined()) {
1592 throwException(instr->find.exceptionId, error, program, context);
1596 findproperty(
object.getQObject(), registers + instr->find.reg,
1598 instr->find.subscribeIndex, identifiers[instr->find.name].identifier,
1599 instr->common.type == Instr::FindPropertyTerminal);
1605 const Register &
object = registers[instr->find.src];
1606 if (
object.isUndefined()) {
1607 throwException(instr->find.exceptionId, error, program, context);
1611 findproperty(
object.getQObject(), registers + instr->find.reg,
1613 instr->find.subscribeIndex, identifiers[instr->find.name].identifier,
1614 instr->common.type == Instr::FindPropertyTerminal);
1620 int type = registers[instr->cleanup.reg].gettype();
1621 if (type == qMetaTypeId<QVariant>()) {
1622 registers[instr->cleanup.reg].getvariantptr()->~QVariant();
1623 #ifdef REGISTER_CLEANUP_DEBUG 1624 registers[instr->cleanup.reg].setUndefined();
1627 registers[instr->cleanup.reg].getstringptr()->~QString();
1628 #ifdef REGISTER_CLEANUP_DEBUG 1629 registers[instr->cleanup.reg].setUndefined();
1632 registers[instr->cleanup.reg].geturlptr()->~QUrl();
1633 #ifdef REGISTER_CLEANUP_DEBUG 1634 registers[instr->cleanup.reg].setUndefined();
1642 Register &output = registers[instr->unaryop.output];
1643 Register &input = registers[instr->unaryop.src];
1645 output.setqreal(
toReal(&input, input.gettype(), &ok));
1646 if (!ok) output.setUndefined();
1652 Register &output = registers[instr->unaryop.output];
1653 Register &input = registers[instr->unaryop.src];
1655 output.setbool(
toBool(&input, input.gettype(), &ok));
1656 if (!ok) output.setUndefined();
1662 Register &output = registers[instr->unaryop.output];
1663 Register &input = registers[instr->unaryop.src];
1667 else { output.setUndefined(); }
1673 Register &output = registers[instr->unaryop.output];
1674 Register &input = registers[instr->unaryop.src];
1678 else { output.setUndefined(); }
1682 #ifdef QML_THREADED_INTERPRETER 1697 const Program *program = (
const Program *)programData.
constData();
1699 qWarning() <<
"Program.bindings:" << program->bindings;
1700 qWarning() <<
"Program.dataLength:" << program->dataLength;
1701 qWarning() <<
"Program.subscriptions:" << program->subscriptions;
1702 qWarning() <<
"Program.indentifiers:" << program->identifiers;
1704 int count = program->instructionCount;
1705 const Instr *instr = program->instructions();
1721 registerCleanups.clear();
1722 data = committed.data;
1723 exceptions = committed.exceptions;
1724 usedSubscriptionIds.clear();
1725 subscriptionSet.clear();
1726 subscriptionIds = committed.subscriptionIds;
1727 registeredStrings = committed.registeredStrings;
1739 int rv = committed.count();
1740 committed.offsets << committed.bytecode.count();
1741 committed.dependencies << usedSubscriptionIds;
1742 committed.bytecode << bytecode;
1743 committed.data =
data;
1744 committed.exceptions = exceptions;
1745 committed.subscriptionIds = subscriptionIds;
1746 committed.registeredStrings = registeredStrings;
1752 resetInstanceState();
1754 if (destination->type == -1)
1757 if (bindingsDump()) {
1761 id.common.type = Instr::BindingId;
1770 if (!parseExpression(node, type))
1773 if (subscriptionSet.count() > 0xFFFF ||
1774 registeredStrings.count() > 0xFFFF)
1778 if (!qmlExperimental())
1787 int convertReg = acquireReg();
1788 if (convertReg == -1)
1793 convert.common.type = Instr::ConvertGenericToReal;
1794 convert.unaryop.output = convertReg;
1795 convert.unaryop.src = type.
reg;
1799 convert.common.type = Instr::ConvertGenericToString;
1800 convert.unaryop.output = convertReg;
1801 convert.unaryop.src = type.
reg;
1805 convert.common.type = Instr::ConvertGenericToBool;
1806 convert.unaryop.output = convertReg;
1807 convert.unaryop.src = type.
reg;
1811 convert.common.type = Instr::ConvertGenericToUrl;
1812 convert.unaryop.output = convertReg;
1813 convert.unaryop.src = type.
reg;
1818 cleanup.common.type = Instr::CleanupGeneric;
1819 cleanup.cleanup.reg = type.
reg;
1823 instr.common.type = Instr::Store;
1824 instr.store.output = 0;
1825 instr.store.index = destination->index;
1826 instr.store.reg = convertReg;
1832 cleanup.common.type = Instr::CleanupString;
1833 cleanup.cleanup.reg = convertReg;
1837 cleanup.common.type = Instr::CleanupUrl;
1838 cleanup.cleanup.reg = convertReg;
1842 releaseReg(convertReg);
1845 done.common.type = Instr::Done;
1853 instr.common.type = Instr::ConvertIntToReal;
1854 instr.unaryop.output = type.
reg;
1855 instr.unaryop.src = type.
reg;
1861 instr.common.type = Instr::ConvertRealToInt;
1862 instr.unaryop.output = type.
reg;
1863 instr.unaryop.src = type.
reg;
1866 }
else if (type.
type == destination->type) {
1869 const QMetaObject *to = engine->rawMetaObjectForType(destination->type);
1872 type.
type = destination->type;
1875 if (type.
type == destination->type) {
1877 instr.common.type = Instr::Store;
1878 instr.store.output = 0;
1879 instr.store.index = destination->index;
1880 instr.store.reg = type.
reg;
1884 releaseReg(type.
reg);
1887 done.common.type = Instr::Done;
1899 while (node->
kind == AST::Node::Kind_NestedExpression)
1902 if (tryArith(node)) {
1903 if (!parseArith(node, type))
return false;
1904 }
else if (tryLogic(node)) {
1905 if (!parseLogic(node, type))
return false;
1906 }
else if (tryConditional(node)) {
1907 if (!parseConditional(node, type))
return false;
1908 }
else if (tryName(node)) {
1909 if (!parseName(node, type))
return false;
1910 }
else if (tryConstant(node)) {
1911 if (!parseConstant(node, type))
return false;
1912 }
else if (tryMethod(node)) {
1913 if (!parseMethod(node, type))
return false;
1922 return node->
kind == AST::Node::Kind_IdentifierExpression ||
1923 node->
kind == AST::Node::Kind_FieldMemberExpression;
1930 if (!buildName(nameParts, node, &nameNodes))
1933 int reg = acquireReg();
1942 bool wasAttachedObject =
false;
1944 for (
int ii = 0; ii < nameParts.
count(); ++ii) {
1955 if (ii == nameParts.
count() - 1)
1961 if (!imports.resolveType(name.
toUtf8(), &attachType, 0, 0, 0, &ns))
1966 wasAttachedObject =
true;
1973 instr.common.type = Instr::LoadScope;
1974 instr.load.index = 0;
1975 instr.load.reg = reg;
1979 attach.common.type = Instr::LoadAttached;
1980 attach.attached.output = reg;
1981 attach.attached.reg = reg;
1983 attach.attached.exceptionId = exceptionId(nameNodes.
at(ii));
1986 subscribeName << contextName();
1993 }
else if (ids.contains(name)) {
2002 instr.common.type = Instr::LoadRoot;
2003 instr.load.index = 0;
2004 instr.load.reg = reg;
2006 }
else if (idObject == context) {
2008 instr.common.type = Instr::LoadScope;
2009 instr.load.index = 0;
2010 instr.load.reg = reg;
2014 instr.common.type = Instr::LoadId;
2015 instr.load.index = idObject->
idIndex;
2016 instr.load.reg = reg;
2021 if (subscription(subscribeName, &type)) {
2023 sub.common.type = Instr::SubscribeId;
2024 sub.subscribe.offset = subscriptionIndex(subscribeName);
2025 sub.subscribe.reg = reg;
2026 sub.subscribe.index = instr.load.index;
2034 const char *cname = utf8Name.
constData();
2036 int d0Idx = (context ==
component)?-1:context->metaObject()->indexOfProperty(cname);
2039 d1Idx =
component->metaObject()->indexOfProperty(cname);
2043 instr.common.type = Instr::LoadScope;
2044 instr.load.index = 0;
2045 instr.load.reg = reg;
2048 subscribeName << contextName();
2049 subscribeName <<
name;
2051 if (!fetch(type, context->metaObject(), reg, d0Idx, subscribeName, nameNodes.
at(ii)))
2053 }
else if(d1Idx != -1) {
2055 instr.common.type = Instr::LoadRoot;
2056 instr.load.index = 0;
2057 instr.load.reg = reg;
2061 subscribeName <<
name;
2063 if (!fetch(type,
component->metaObject(), reg, d1Idx, subscribeName, nameNodes.
at(ii)))
2065 }
else if (qmlExperimental()) {
2067 if (nameParts.
count() == 1)
2068 find.common.type = Instr::FindGenericTerminal;
2070 find.common.type = Instr::FindGeneric;
2072 find.find.reg = reg;
2074 find.find.name = registerString(name);
2075 find.find.exceptionId = exceptionId(nameNodes.
at(ii));
2078 if (subscription(subscribeName, &type))
2079 find.find.subscribeIndex = subscriptionIndex(subscribeName);
2081 find.find.subscribeIndex = -1;
2095 attach.common.type = Instr::LoadAttached;
2096 attach.attached.output = reg;
2097 attach.attached.reg = reg;
2115 const char *cname = utf8Name.
constData();
2117 if (absType && idx == -1)
2120 subscribeName <<
name;
2122 if (absType || (wasAttachedObject && idx != -1) || (mo && mo->
property(idx).
isFinal())) {
2124 if (!fetch(type, mo, reg, idx, subscribeName, nameNodes.
at(ii)))
2129 if (ii == nameParts.
count() -1 )
2130 prop.common.type = Instr::FindPropertyTerminal;
2132 prop.common.type = Instr::FindProperty;
2134 prop.find.reg = reg;
2135 prop.find.src = reg;
2136 prop.find.name = registerString(name);
2137 prop.find.exceptionId = exceptionId(nameNodes.
at(ii));
2139 if (subscription(subscribeName, &type))
2140 prop.find.subscribeIndex = subscriptionIndex(subscribeName);
2142 prop.find.subscribeIndex = -1;
2152 wasAttachedObject =
false;
2160 if (node->
kind != AST::Node::Kind_BinaryExpression)
2175 type.
reg = acquireReg();
2182 if (!parseExpression(expression->
left, lhs))
return false;
2183 if (!parseExpression(expression->
right, rhs))
return false;
2207 convert.common.type = Instr::ConvertIntToReal;
2208 convert.unaryop.output = lhs.
reg;
2209 convert.unaryop.src = lhs.
reg;
2215 convert.common.type = Instr::ConvertIntToReal;
2216 convert.unaryop.output = rhs.
reg;
2217 convert.unaryop.src = rhs.
reg;
2225 if (!qmlExperimental())
2228 lhsTmp = acquireReg();
2233 conv.common.type = Instr::ConvertGenericToReal;
2234 conv.unaryop.output = lhsTmp;
2235 conv.unaryop.src = lhs.
reg;
2240 if (!qmlExperimental())
2243 rhsTmp = acquireReg();
2248 conv.common.type = Instr::ConvertGenericToReal;
2249 conv.unaryop.output = rhsTmp;
2250 conv.unaryop.src = rhs.
reg;
2256 arith.common.type = nativeReal?Instr::AddReal:Instr::AddInt;
2258 arith.common.type = nativeReal?Instr::MinusReal:Instr::MinusInt;
2260 qFatal(
"Unsupported arithmetic operator");
2263 arith.binaryop.output = type.
reg;
2264 arith.binaryop.src1 = (lhsTmp == -1)?lhs.
reg:lhsTmp;
2265 arith.binaryop.src2 = (rhsTmp == -1)?rhs.
reg:rhsTmp;
2273 if (lhsTmp != -1) releaseReg(lhsTmp);
2274 if (rhsTmp != -1) releaseReg(rhsTmp);
2275 releaseReg(lhs.
reg);
2276 releaseReg(rhs.
reg);
2290 if (!qmlExperimental())
2293 lhsTmp = acquireReg(Instr::CleanupString);
2298 convert.common.type = Instr::ConvertGenericToString;
2299 convert.unaryop.output = lhsTmp;
2300 convert.unaryop.src = lhs.
reg;
2305 if (!qmlExperimental())
2308 rhsTmp = acquireReg(Instr::CleanupString);
2313 convert.common.type = Instr::ConvertGenericToString;
2314 convert.unaryop.output = rhsTmp;
2315 convert.unaryop.src = rhs.
reg;
2319 type.
reg = acquireReg(Instr::CleanupString);
2326 add.common.type = Instr::AddString;
2327 add.binaryop.output = type.
reg;
2328 add.binaryop.src1 = (lhsTmp == -1)?lhs.
reg:lhsTmp;
2329 add.binaryop.src2 = (rhsTmp == -1)?rhs.
reg:rhsTmp;
2332 if (lhsTmp != -1) releaseReg(lhsTmp);
2333 if (rhsTmp != -1) releaseReg(rhsTmp);
2334 releaseReg(lhs.
reg);
2335 releaseReg(rhs.
reg);
2342 if (node->
kind != AST::Node::Kind_BinaryExpression)
2361 if (!parseExpression(expression->
left, lhs))
return false;
2362 if (!parseExpression(expression->
right, rhs))
return false;
2364 type.
reg = acquireReg();
2375 op.common.type = Instr::GreaterThanReal;
2377 op.common.type = Instr::CompareReal;
2379 op.common.type = Instr::NotCompareReal;
2382 op.binaryop.output = type.
reg;
2383 op.binaryop.src1 = lhs.
reg;
2384 op.binaryop.src2 = rhs.
reg;
2392 op.common.type = Instr::CompareString;
2394 op.common.type = Instr::NotCompareString;
2397 op.binaryop.output = type.
reg;
2398 op.binaryop.src1 = lhs.
reg;
2399 op.binaryop.src2 = rhs.
reg;
2406 releaseReg(lhs.
reg);
2407 releaseReg(rhs.
reg);
2414 return (node->
kind == AST::Node::Kind_ConditionalExpression);
2422 if (test->
kind == AST::Node::Kind_NestedExpression)
2426 if (!parseExpression(test, etype))
return false;
2432 skip.common.type = Instr::Skip;
2433 skip.skip.reg = etype.
reg;
2434 skip.skip.count = 0;
2435 int skipIdx = bytecode.count();
2439 releaseReg(etype.
reg);
2446 if (!parseExpression(expression->
ok, ok))
return false;
2449 int skipIdx2 = bytecode.count();
2455 bytecode[skipIdx].skip.count = bytecode.count() - skipIdx - 1;
2457 subscriptionSet = preSubSet;
2460 if (!parseExpression(expression->
ko, ko))
return false;
2464 bytecode[skipIdx2].skip.count = bytecode.count() - skipIdx2 - 1;
2469 subscriptionSet = preSubSet;
2481 return node->
kind == AST::Node::Kind_TrueLiteral ||
2482 node->
kind == AST::Node::Kind_FalseLiteral ||
2483 node->
kind == AST::Node::Kind_NumericLiteral ||
2484 node->
kind == AST::Node::Kind_StringLiteral;
2491 type.
reg = acquireReg();
2495 if (node->
kind == AST::Node::Kind_TrueLiteral) {
2498 instr.common.type = Instr::Bool;
2499 instr.bool_value.reg = type.
reg;
2500 instr.bool_value.value =
true;
2503 }
else if (node->
kind == AST::Node::Kind_FalseLiteral) {
2506 instr.common.type = Instr::Bool;
2507 instr.bool_value.reg = type.
reg;
2508 instr.bool_value.value =
false;
2511 }
else if (node->
kind == AST::Node::Kind_NumericLiteral) {
2512 qreal value =
qreal(static_cast<AST::NumericLiteral *>(node)->value);
2514 if (
qreal(
float(value)) != value)
2519 instr.common.type = Instr::Real;
2520 instr.real_value.reg = type.
reg;
2521 instr.real_value.value = float(value);
2524 }
else if (node->
kind == AST::Node::Kind_StringLiteral) {
2527 type.
reg = registerLiteralString(str);
2536 return node->
kind == AST::Node::Kind_CallExpression;
2544 if (!buildName(name, expr->
base))
2553 if (!args)
return false;
2556 if (!args)
return false;
2558 if (args->
next != 0)
return false;
2559 if (!arg0 || !arg1)
return false;
2562 if (!parseExpression(arg0, r0))
return false;
2564 if (!parseExpression(arg1, r1))
return false;
2571 op.common.type = Instr::MaxReal;
2573 op.common.type = Instr::MinReal;
2581 op.binaryop.output = acquireReg();
2582 if (op.binaryop.output == -1)
2585 op.binaryop.src1 = r0.
reg;
2586 op.binaryop.src2 = r1.
reg;
2590 result.
reg = op.binaryop.output;
2599 if (node->
kind == AST::Node::Kind_IdentifierExpression) {
2600 name << static_cast<AST::IdentifierExpression*>(node)->name->asString();
2601 if (nodes) *nodes << static_cast<AST::IdentifierExpression*>(node);
2602 }
else if (node->
kind == AST::Node::Kind_FieldMemberExpression) {
2606 if (!buildName(name, expr->
base, nodes))
2610 if (nodes) *nodes << expr;
2630 int fastFetchIndex = fastProperties()->accessorIndexForProperty(mo, idx);
2634 if (!qmlDisableFastProperties() && fastFetchIndex != -1) {
2635 fetch.common.type = Instr::FetchAndSubscribe;
2636 fetch.fetchAndSubscribe.objectReg = reg;
2637 fetch.fetchAndSubscribe.output = reg;
2638 fetch.fetchAndSubscribe.function = fastFetchIndex;
2639 fetch.fetchAndSubscribe.subscription = subscriptionIndex(subName);
2640 fetch.fetchAndSubscribe.exceptionId = exceptionId(node);
2644 sub.common.type = Instr::Subscribe;
2645 sub.subscribe.offset = subscriptionIndex(subName);
2646 sub.subscribe.reg = reg;
2651 fetch.common.type = Instr::Fetch;
2652 fetch.fetch.objectReg = reg;
2653 fetch.fetch.index = idx;
2654 fetch.fetch.output = reg;
2655 fetch.fetch.exceptionId = exceptionId(node);
2663 int tmp = acquireReg();
2667 copy.common.type = Instr::Copy;
2668 copy.copy.reg = tmp;
2669 copy.copy.src = reg;
2672 fetch.fetch.objectReg = tmp;
2675 setup.common.type = Instr::NewString;
2676 setup.construct.reg = reg;
2678 registerCleanup(reg, Instr::CleanupString);
2687 rv.
type != qMetaTypeId<QDeclarativeAnchorLine>() &&
2699 registerCleanups.insert(reg,
qMakePair(cleanup, cleanupType));
2704 for (
int ii = 0; ii < 32; ++ii) {
2705 if (!(registers & (1 << ii))) {
2706 registers |= (1 << ii);
2708 if (cleanup != Instr::Noop)
2709 registerCleanup(ii, cleanup, cleanupType);
2721 if (registerCleanups.contains(reg)) {
2723 registerCleanups.remove(reg);
2726 cleanup.cleanup.reg = reg;
2727 bytecode << cleanup;
2738 int offset =
data.count();
2741 int reg = acquireReg(Instr::CleanupString);
2747 string.string_value.reg = reg;
2748 string.string_value.offset = offset;
2749 string.string_value.length = str.
length();
2762 if (iter == registeredStrings.
end()) {
2763 quint32 len =
string.length();
2765 QByteArray strdata((
const char *)
string.constData(),
string.length() *
sizeof(
QChar));
2767 int rv =
data.count();
2770 iter = registeredStrings.
insert(
string,
qMakePair(registeredStrings.count(), rv));
2774 reg.common.type = Instr::InitString;
2775 reg.initstring.offset = iter->first;
2776 reg.initstring.dataIdx = iter->second;
2778 return reg.initstring.offset;
2786 if (subscriptionSet.contains(str)) {
2789 subscriptionSet.insert(str);
2798 if (iter == subscriptionIds.
end())
2799 iter = subscriptionIds.
insert(str, subscriptionIds.
count());
2800 usedSubscriptionIds.insert(*iter);
2817 difflhs.
unite(diffrhs);
2826 if (n && exceptions.count() < 0xFF) {
2827 rv = (
quint8)exceptions.count();
2832 exceptions.append(e);
2865 if (qmlDisableOptimizer())
2887 for (
int ii = 0; ii < committed.count(); ++ii) {
2888 const QSet<int> &deps = committed.dependencies.at(ii);
2890 table[*iter].append(ii);
2895 for (
int ii = 0; ii < committed.subscriptionIds.count(); ++ii) {
2896 header.
append(committed.subscriptionIds.count() + data.
count());
2899 for (
int jj = 0; jj < bindings.
count(); ++jj)
2911 ::memcpy(rv.
data(), committed.exceptions.constData(), rv.
size());
2928 skip.common.type = Instr::Skip;
2930 for (
int ii = 0; ii <
d->
committed.count(); ++ii) {
2931 skip.skip.count =
d->
committed.count() - ii - 1;
2939 prog.signalTableOffset = data.
count();
2942 prog.exceptionDataOffset = data.
count();
2945 prog.dataLength = 4 * ((data.
size() + 3) / 4);
2948 prog.instructionCount = bytecode.
count();
2949 prog.compiled =
false;
2950 int size =
sizeof(Program) + bytecode.
count() *
sizeof(Instr);
2951 size += prog.dataLength;
2953 programData.
resize(size);
2954 memcpy(programData.
data(), &prog,
sizeof(Program));
2955 if (prog.dataLength)
2958 memcpy((
char *)((Program *)programData.
data())->instructions(), bytecode.
constData(),
2959 bytecode.
count() *
sizeof(Instr));
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
The QVariant class acts like a union for the most common Qt data types.
static void dump(const QByteArray &)
QDeclarativeParser::Object * context
bool tryName(QDeclarativeJS::AST::Node *)
const QString asString() const
const QMetaObject * metaObject
QSet< T > & unite(const QSet< T > &other)
void disconnectOne(Binding *bindingToDisconnect)
QDeclarativeImports imports
#define QML_INSTR_ENUM(I)
QIntegerForSizeof< void * >::Unsigned quintptr
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
#define QT_END_NAMESPACE
This macro expands to.
void setDescription(const QString &)
Sets the error description.
char * data()
Returns a pointer to the data stored in the byte array.
bool tryConditional(QDeclarativeJS::AST::Node *)
const QChar at(int i) const
Returns the character at the given index position in the string.
QDeclarativeEngine * engine
QSet< QString > subscriptionSet
int count(const T &t) const
Returns the number of occurrences of value in the vector.
QByteArray & append(char c)
Appends the character ch to this byte array.
bool fetch(Result &type, const QMetaObject *, int reg, int idx, const QStringList &, QDeclarativeJS::AST::ExpressionNode *)
QScriptDeclarativeClass::PersistentIdentifier * identifiers
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
void subscribe(QObject *o, int notifyIndex, int subIndex)
bool compile(QDeclarativeJS::AST::Node *)
QDeclarativeAbstractBinding * configBinding(int index, QObject *target, QObject *scope, int property)
bool tryMethod(QDeclarativeJS::AST::Node *)
The QByteArray class provides an array of bytes.
void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
int length() const
Returns the number of characters in this string.
virtual SourceLocation firstSourceLocation() const =0
void setColumn(int)
Sets the error column number.
static void clear(QVariant::Private *d)
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
static void throwException(int id, QDeclarativeDelayedError *error, Program *program, QDeclarativeContextData *context, const QString &description=QString())
bool m_bindingsDisconnected
ExpressionNode * expression
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
QList< QVariant > propertyValues
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
static LibLoadStatus status
void registerCleanup(int reg, int cleanup, int cleanupType=0)
void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags)
const QMetaObject * metaObject() const
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QDeclarativeParser::Object * component
virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags flags)=0
int count(const T &t) const
Returns the number of occurrences of value in the list.
virtual void disconnect(DisconnectMode disconnectMode)
QDeclarativeParser::Property * property
int attachedPropertiesId() const
bool operator==(const Result &o) const
bool parseExpression(QDeclarativeJS::AST::Node *, Result &)
QHash< int, QPair< int, int > > registerCleanups
QDeclarativeBindingCompilerPrivate()
QByteArray & prepend(char c)
Prepends the character ch to this byte array.
bool parseLogic(QDeclarativeJS::AST::Node *, Result &)
bool buildName(QStringList &, QDeclarativeJS::AST::Node *, QList< QDeclarativeJS::AST::ExpressionNode *> *nodes=0)
#define QML_INSTR_ADDR(I)
The QUrl class provides a convenient interface for working with URLs.
The QString class provides a Unicode character string.
The QHash class is a template class that provides a hash-table-based dictionary.
QDeclarativeContextData * parent
int registerLiteralString(const QString &)
void connect(QObject *source, int sourceSignal)
The QObject class is the base class of all Qt objects.
static QDeclarativeEnginePrivate * get(QDeclarativeEngine *e)
PersistentIdentifier createPersistentIdentifier(const QString &)
bool isRelative() const
Returns true if the URL is relative; otherwise returns false.
The QChar class provides a 16-bit Unicode character.
static QString fromRawData(const QChar *, int size)
Constructs a QString that uses the first size Unicode characters in the array unicode.
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
QDeclarativeCompiledBindingsPrivate * parent
int commitCompile()
Mark the last compile as successful, and add it to the "committed data" section.
int acquireReg(int cleanup=Instr::Noop, int cleanupType=0)
The QDeclarativeImports class encapsulates one QML document's import statements.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
static QString translate(const char *context, const char *key, const char *disambiguation=0, Encoding encoding=CodecForTr)
QDeclarativeBindingCompiler()
bool parseMethod(QDeclarativeJS::AST::Node *, Result &)
Q_DECLARATIVE_EXPORT QObject * qmlAttachedPropertiesObjectById(int, const QObject *, bool create=true)
int property
The property to be updated.
static bool toBool(Register *reg, int type, bool *ok=0)
bool tryArith(QDeclarativeJS::AST::Node *)
bool stringArith(Result &, const Result &, const Result &, QSOperator::Op op)
static QString toString(Register *reg, int type, bool *ok=0)
QDeclarativeContextPrivate * asQDeclarativeContextPrivate()
#define QT_BEGIN_NAMESPACE
This macro expands to.
bool subscriptionNeutral(const QSet< QString > &base, const QSet< QString > &lhs, const QSet< QString > &rhs)
virtual ~QDeclarativeCompiledBindings()
QHash< QString, QDeclarativeParser::Object * > ids
struct QDeclarativeBindingCompilerPrivate::@134 committed
static bool isEmpty(const char *str)
QDeclarativeImports imports
QSet< int > usedSubscriptionIds
static QString unknownType()
Centralizes a translation string for the purpose of increasing consistency.
QHash< QString, QPair< int, int > > registeredStrings
const T & at(int i) const
Returns the item at index position i in the list.
virtual void destroy(DestroyMode mode)
Destroy the binding.
The QStringList class provides a list of strings.
Data * property(const QScriptDeclarativeClass::Identifier &id) const
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
void append(const T &t)
Inserts value at the end of the vector.
virtual ~QDeclarativeCompiledBindingsPrivate()
Q_GLOBAL_STATIC(QDeclarativeFastProperties, fastProperties)
Q_CORE_EXPORT void qWarning(const char *,...)
const_iterator insert(const T &value)
QDeclarativeParser::Property * destination
static const char * data(const QByteArray &arr)
static QObject * variantToQObject(const QVariant &value, bool *ok)
QList< QSet< int > > dependencies
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
QString contextName() const
Subscription * subscriptions
int compile(const Expression &, QDeclarativeEnginePrivate *)
static qreal component(const QPointF &point, unsigned int i)
QDeclarativeRefCount * dataRef
QUrl toUrl() const
Returns the variant as a QUrl if the variant has type() Url ; otherwise returns an invalid QUrl...
QSet< T > & subtract(const QSet< T > &other)
bool parseName(QDeclarativeJS::AST::Node *, Result &)
QDeclarativePropertyCache::Data * findproperty(QObject *obj, const QScriptDeclarativeClass::Identifier &name, QDeclarativeEnginePrivate *enginePriv, QDeclarativePropertyCache::Data &local)
void resetInstanceState()
Clear the state associated with attempting to compile a specific binding.
QDeclarativeIntegerCache * propertyNames
Q_CORE_EXPORT double qSNaN()
Returns the bit pattern of a signalling NaN as a double.
bool isUpper() const
Returns true if the character is an uppercase letter, i.
QDeclarativeObjectScriptClass * objectClass
static void endRange(RangeType)
static void startRange(RangeType)
const char * constData() const
Returns a pointer to the data stored in the byte array.
void setLine(int)
Sets the error line number.
QDeclarativeNotifier bindings
static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, bool *ok)
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Disconnects signal in object sender from method in object receiver.
QString join(const QString &sep) const
Joins all the string list's strings into a single string with each element separated by the given sep...
QDeclarativeParser::Variant expression
int qt_metacall(QMetaObject::Call, int, void **)
Q_CORE_EXPORT void qFatal(const char *,...)
bool operator!=(const Result &o) const
DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL)
QDeclarativeCompiledBindingsPrivate()
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
int userType() const
Returns the storage type of the value stored in the variant.
virtual ExpressionNode * expressionCast()
QVector< quint64 > exceptions
#define Q_DECLARE_PUBLIC(Class)
static void dumpInstruction(const Instr *instr)
QDeclarativeJS::AST::Node * asAST() const
QString & append(QChar c)
const QMetaObject * attachedPropertiesType() const
QHash< QString, int > subscriptionIds
int count(char c) const
Returns the number of occurrences of character ch in the byte array.
QObject * target
The object to be updated.
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
void setUrl(const QUrl &)
Sets the url for the file that caused this error.
static void construct(QVariant::Private *x, const void *copy)
QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context, QDeclarativeRefCount *)
QDeclarativeValueTypeFactory valueTypes
QByteArray buildSignalTable() const
Type type() const
Returns the storage type of the value stored in the variant.
QDeclarativeContext * asQDeclarativeContext()
int registerString(const QString &)
QObject * parent() const
Returns a pointer to the parent object.
Q_OUTOFLINE_TEMPLATE QPair< T1, T2 > qMakePair(const T1 &x, const T2 &y)
bool numberArith(Result &, const Result &, const Result &, QSOperator::Op op)
void resize(int size)
Sets the size of the byte array to size bytes.
bool parseConstant(QDeclarativeJS::AST::Node *, Result &)
void setContext(QDeclarativeContextData *)
QDeclarativeBindingCompilerPrivate * d
ExpressionNode * expression
QDeclarativeParser::Object * context
T qvariant_cast(const QVariant &)
QDeclarativeContextData * context() const
int size() const
Returns the number of bytes in this byte array.
bool isValueTypeSubProperty
QVariant property(const char *name) const
Returns the value of the object's name property.
QFuture< T > run(Function function,...)
bool tryLogic(QDeclarativeJS::AST::Node *)
bool parseArith(QDeclarativeJS::AST::Node *, Result &)
static bool canConvert(const QMetaObject *from, const QMetaObject *to)
Returns true if from inherits to.
QVector< Instr > bytecode
int count(const Key &key) const
Returns the number of items associated with the key.
QSet< QString > subscriptionSet
~QDeclarativeBindingCompiler()
#define QML_BEGIN_INSTR(I)
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
int subscriptionIndex(const QStringList &)
const T * constData() const
Returns a const pointer to the data stored in the vector.
int value(const QString &)
quint8 exceptionId(QDeclarativeJS::AST::ExpressionNode *)
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags)
QDeclarativeInfo qmlInfo(const QObject *me)
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
QByteArray program() const
void warning(const QDeclarativeError &)
bool addError(QDeclarativeEnginePrivate *)
static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok=0)
bool parseConditional(QDeclarativeJS::AST::Node *, Result &)
bool tryConstant(QDeclarativeJS::AST::Node *)
#define FOR_EACH_QML_INSTR(F)
QDeclarativeParser::Object * component
QHash< QString, QDeclarativeParser::Object * > ids
const QChar * constData() const
Returns a pointer to the data stored in the QString.
bool subscription(const QStringList &, Result *)
QByteArray buildExceptionData() const
Q_DECL_CONSTEXPR int qRound(qreal d)
QDeclarativeEnginePrivate * engine
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
static qreal toReal(Register *reg, int type, bool *ok=0)
QDeclarativeNotifierEndpoint Subscription
The QList class is a template class that provides lists.
void findgeneric(Register *output, int subIdx, QDeclarativeContextData *context, const QScriptDeclarativeClass::Identifier &name, bool isTerminal)
virtual void read(QObject *, int)=0