aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/parser/qdeclarativejs.g53
-rw-r--r--src/declarative/qml/parser/qdeclarativejsast.cpp6
-rw-r--r--src/declarative/qml/parser/qdeclarativejsast_p.h12
-rw-r--r--src/declarative/qml/parser/qdeclarativejsastfwd_p.h2
-rw-r--r--src/declarative/qml/parser/qdeclarativejsastvisitor.cpp2
-rw-r--r--src/declarative/qml/parser/qdeclarativejsastvisitor_p.h4
-rw-r--r--src/declarative/qml/parser/qdeclarativejsengine_p.cpp6
-rw-r--r--src/declarative/qml/parser/qdeclarativejsengine_p.h4
-rw-r--r--src/declarative/qml/parser/qdeclarativejsglobal_p.h2
-rw-r--r--src/declarative/qml/parser/qdeclarativejsgrammar.cpp1490
-rw-r--r--src/declarative/qml/parser/qdeclarativejsgrammar_p.h14
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp8
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer_p.h2
-rw-r--r--src/declarative/qml/parser/qdeclarativejsmemorypool_p.h2
-rw-r--r--src/declarative/qml/parser/qdeclarativejsnodepool_p.h4
-rw-r--r--src/declarative/qml/parser/qdeclarativejsparser.cpp434
-rw-r--r--src/declarative/qml/parser/qdeclarativejsparser_p.h12
-rw-r--r--src/declarative/qml/qdeclarative.h142
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp19
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp2906
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings_p.h116
-rw-r--r--src/declarative/qml/qdeclarativecompileddata.cpp102
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp534
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h24
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp48
-rw-r--r--src/declarative/qml/qdeclarativecomponent.h10
-rw-r--r--src/declarative/qml/qdeclarativecomponent_p.h5
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp84
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h11
-rw-r--r--src/declarative/qml/qdeclarativedirparser.cpp23
-rw-r--r--src/declarative/qml/qdeclarativedirparser_p.h16
-rw-r--r--src/declarative/qml/qdeclarativedom.cpp1835
-rw-r--r--src/declarative/qml/qdeclarativedom_p.h362
-rw-r--r--src/declarative/qml/qdeclarativedom_p_p.h157
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp145
-rw-r--r--src/declarative/qml/qdeclarativeengine.h3
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h25
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp7
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.cpp33
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.h6
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp208
-rw-r--r--src/declarative/qml/qdeclarativeimport_p.h6
-rw-r--r--src/declarative/qml/qdeclarativeinfo.cpp12
-rw-r--r--src/declarative/qml/qdeclarativeinstruction.cpp134
-rw-r--r--src/declarative/qml/qdeclarativeinstruction_p.h479
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp96
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h39
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp27
-rw-r--r--src/declarative/qml/qdeclarativeprivate.h17
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp3
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp2
-rw-r--r--src/declarative/qml/qdeclarativepropertycache_p.h21
-rw-r--r--src/declarative/qml/qdeclarativescarceresourcescriptclass.cpp219
-rw-r--r--src/declarative/qml/qdeclarativescarceresourcescriptclass_p.h163
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp76
-rw-r--r--src/declarative/qml/qdeclarativescriptparser_p.h4
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp244
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h62
-rw-r--r--src/declarative/qml/qdeclarativetypenamecache.cpp8
-rw-r--r--src/declarative/qml/qdeclarativetypenamecache_p.h16
-rw-r--r--src/declarative/qml/qdeclarativetypenamescriptclass.cpp38
-rw-r--r--src/declarative/qml/qdeclarativetypenamescriptclass_p.h1
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp1519
-rw-r--r--src/declarative/qml/qdeclarativevme_p.h11
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp10
-rw-r--r--src/declarative/qml/qdeclarativexmlhttprequest.cpp21
-rw-r--r--src/declarative/qml/qintrusivelist.cpp173
-rw-r--r--src/declarative/qml/qintrusivelist_p.h254
-rw-r--r--src/declarative/qml/qmetaobjectbuilder.cpp57
-rw-r--r--src/declarative/qml/qmetaobjectbuilder_p.h4
-rw-r--r--src/declarative/qml/qml.pri14
-rw-r--r--src/declarative/qml/v4/qdeclarativev4bindings.cpp1530
-rw-r--r--src/declarative/qml/v4/qdeclarativev4bindings_p.h92
-rw-r--r--src/declarative/qml/v4/qdeclarativev4compiler.cpp1340
-rw-r--r--src/declarative/qml/v4/qdeclarativev4compiler_p.h104
-rw-r--r--src/declarative/qml/v4/qdeclarativev4compiler_p_p.h184
-rw-r--r--src/declarative/qml/v4/qdeclarativev4instruction.cpp559
-rw-r--r--src/declarative/qml/v4/qdeclarativev4instruction_p.h444
-rw-r--r--src/declarative/qml/v4/qdeclarativev4ir.cpp832
-rw-r--r--src/declarative/qml/v4/qdeclarativev4ir_p.h546
-rw-r--r--src/declarative/qml/v4/qdeclarativev4irbuilder.cpp1315
-rw-r--r--src/declarative/qml/v4/qdeclarativev4irbuilder_p.h242
-rw-r--r--src/declarative/qml/v4/qdeclarativev4program_p.h122
-rw-r--r--src/declarative/qml/v4/v4.pri17
84 files changed, 11884 insertions, 8051 deletions
diff --git a/src/declarative/qml/parser/qdeclarativejs.g b/src/declarative/qml/parser/qdeclarativejs.g
index 590edf82b8..a57ecba3f9 100644
--- a/src/declarative/qml/parser/qdeclarativejs.g
+++ b/src/declarative/qml/parser/qdeclarativejs.g
@@ -127,10 +127,10 @@
#include <string.h>
-#include "private/qdeclarativejsengine_p.h"
-#include "private/qdeclarativejslexer_p.h"
-#include "private/qdeclarativejsast_p.h"
-#include "private/qdeclarativejsnodepool_p.h"
+#include "qdeclarativejsengine_p.h"
+#include "qdeclarativejslexer_p.h"
+#include "qdeclarativejsast_p.h"
+#include "qdeclarativejsnodepool_p.h"
./
@@ -195,10 +195,10 @@
#ifndef QDECLARATIVEJSPARSER_P_H
#define QDECLARATIVEJSPARSER_P_H
-#include "private/qdeclarativejsglobal_p.h"
-#include "private/qdeclarativejsgrammar_p.h"
-#include "private/qdeclarativejsast_p.h"
-#include "private/qdeclarativejsengine_p.h"
+#include "qdeclarativejsglobal_p.h"
+#include "qdeclarativejsgrammar_p.h"
+#include "qdeclarativejsast_p.h"
+#include "qdeclarativejsengine_p.h"
#include <QtCore/QList>
#include <QtCore/QString>
@@ -375,7 +375,7 @@ protected:
/.
-#include "private/qdeclarativejsparser_p.h"
+#include "qdeclarativejsparser_p.h"
#include <QVarLengthArray>
//
@@ -782,19 +782,14 @@ case $rule_number: {
} break;
./
-UiObjectMember: UiQualifiedId T_COLON Block ;
-/.case $rule_number:./
-
-UiObjectMember: UiQualifiedId T_COLON EmptyStatement ;
-/.case $rule_number:./
-
-UiObjectMember: UiQualifiedId T_COLON ExpressionStatement ;
-/.case $rule_number:./
-
-UiObjectMember: UiQualifiedId T_COLON IfStatement ; --- ### do we really want if statement in a binding?
-/.case $rule_number:./
+UiScriptStatement: Block ;
+UiScriptStatement: EmptyStatement ;
+UiScriptStatement: ExpressionStatement ;
+UiScriptStatement: IfStatement ; --- ### do we really want if statement in a binding?
+UiObjectMember: UiQualifiedId T_COLON UiScriptStatement ;
/.
+case $rule_number:
{
AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(),
sym(1).UiQualifiedId, sym(3).Statement);
@@ -922,51 +917,45 @@ case $rule_number: {
} break;
./
-UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON Expression T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON Expression T_SEMICOLON ;
+UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
/.
case $rule_number: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval,
- sym(5).Expression);
+ sym(5).Statement);
node->propertyToken = loc(1);
node->typeToken = loc(2);
node->identifierToken = loc(3);
node->colonToken = loc(4);
- node->semicolonToken = loc(6);
sym(1).Node = node;
} break;
./
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON Expression T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON Expression T_SEMICOLON ;
+UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
/.
case $rule_number: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
- sym(6).Expression);
+ sym(6).Statement);
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
node->propertyToken = loc(2);
node->typeToken = loc(3);
node->identifierToken = loc(4);
node->colonToken = loc(5);
- node->semicolonToken = loc(7);
sym(1).Node = node;
} break;
./
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_COLON Expression T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_COLON Expression T_SEMICOLON ;
+UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
/.
case $rule_number: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
- sym(6).Expression);
+ sym(6).Statement);
node->isDefaultMember = true;
node->defaultToken = loc(1);
node->propertyToken = loc(2);
node->typeToken = loc(3);
node->identifierToken = loc(4);
node->colonToken = loc(5);
- node->semicolonToken = loc(7);
sym(1).Node = node;
} break;
./
diff --git a/src/declarative/qml/parser/qdeclarativejsast.cpp b/src/declarative/qml/parser/qdeclarativejsast.cpp
index 297130b459..8aff1ad4d0 100644
--- a/src/declarative/qml/parser/qdeclarativejsast.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsast.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativejsast_p.h"
+#include "qdeclarativejsast_p.h"
-#include "private/qdeclarativejsastvisitor_p.h"
+#include "qdeclarativejsastvisitor_p.h"
QT_QML_BEGIN_NAMESPACE
@@ -836,7 +836,7 @@ void UiFormal::accept0(Visitor *visitor)
void UiPublicMember::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
- accept(expression, visitor);
+ accept(statement, visitor);
accept(binding, visitor);
}
diff --git a/src/declarative/qml/parser/qdeclarativejsast_p.h b/src/declarative/qml/parser/qdeclarativejsast_p.h
index 8ff558bde0..69d878af13 100644
--- a/src/declarative/qml/parser/qdeclarativejsast_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsast_p.h
@@ -53,8 +53,8 @@
// We mean it.
//
-#include "private/qdeclarativejsastvisitor_p.h"
-#include "private/qdeclarativejsglobal_p.h"
+#include "qdeclarativejsastvisitor_p.h"
+#include "qdeclarativejsglobal_p.h"
#include <QtCore/QString>
@@ -2342,13 +2342,13 @@ public:
UiPublicMember(NameId *memberType,
NameId *name)
- : type(Property), typeModifier(0), memberType(memberType), name(name), expression(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+ : type(Property), typeModifier(0), memberType(memberType), name(name), statement(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
{ kind = K; }
UiPublicMember(NameId *memberType,
NameId *name,
- ExpressionNode *expression)
- : type(Property), typeModifier(0), memberType(memberType), name(name), expression(expression), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+ Statement *statement)
+ : type(Property), typeModifier(0), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
{ kind = K; }
virtual SourceLocation firstSourceLocation() const
@@ -2376,7 +2376,7 @@ public:
NameId *typeModifier;
NameId *memberType;
NameId *name;
- ExpressionNode *expression; // initialized with a JS expression
+ Statement *statement; // initialized with a JS expression
UiObjectMember *binding; // initialized with a QML object or array.
bool isDefaultMember;
bool isReadonlyMember;
diff --git a/src/declarative/qml/parser/qdeclarativejsastfwd_p.h b/src/declarative/qml/parser/qdeclarativejsastfwd_p.h
index f37459895f..fbc983a7ef 100644
--- a/src/declarative/qml/parser/qdeclarativejsastfwd_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsastfwd_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVEJSAST_FWD_P_H
#define QDECLARATIVEJSAST_FWD_P_H
-#include "private/qdeclarativejsglobal_p.h"
+#include "qdeclarativejsglobal_p.h"
#include <QtCore/qglobal.h>
diff --git a/src/declarative/qml/parser/qdeclarativejsastvisitor.cpp b/src/declarative/qml/parser/qdeclarativejsastvisitor.cpp
index 276b269406..35720e0106 100644
--- a/src/declarative/qml/parser/qdeclarativejsastvisitor.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsastvisitor.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativejsastvisitor_p.h"
+#include "qdeclarativejsastvisitor_p.h"
QT_QML_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/parser/qdeclarativejsastvisitor_p.h b/src/declarative/qml/parser/qdeclarativejsastvisitor_p.h
index df44fdc60d..8f51066e2a 100644
--- a/src/declarative/qml/parser/qdeclarativejsastvisitor_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsastvisitor_p.h
@@ -53,8 +53,8 @@
// We mean it.
//
-#include "private/qdeclarativejsastfwd_p.h"
-#include "private/qdeclarativejsglobal_p.h"
+#include "qdeclarativejsastfwd_p.h"
+#include "qdeclarativejsglobal_p.h"
QT_QML_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/parser/qdeclarativejsengine_p.cpp b/src/declarative/qml/parser/qdeclarativejsengine_p.cpp
index 7f9ad91062..a449f779b7 100644
--- a/src/declarative/qml/parser/qdeclarativejsengine_p.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsengine_p.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativejsengine_p.h"
+#include "qdeclarativejsengine_p.h"
-#include "private/qdeclarativejsglobal_p.h"
-#include "private/qdeclarativejsnodepool_p.h"
+#include "qdeclarativejsglobal_p.h"
+#include "qdeclarativejsnodepool_p.h"
#include <qnumeric.h>
#include <QHash>
diff --git a/src/declarative/qml/parser/qdeclarativejsengine_p.h b/src/declarative/qml/parser/qdeclarativejsengine_p.h
index 409c2a3c53..e366e8b9b3 100644
--- a/src/declarative/qml/parser/qdeclarativejsengine_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsengine_p.h
@@ -53,8 +53,8 @@
// We mean it.
//
-#include "private/qdeclarativejsglobal_p.h"
-#include "private/qdeclarativejsastfwd_p.h"
+#include "qdeclarativejsglobal_p.h"
+#include "qdeclarativejsastfwd_p.h"
#include <QString>
#include <QSet>
diff --git a/src/declarative/qml/parser/qdeclarativejsglobal_p.h b/src/declarative/qml/parser/qdeclarativejsglobal_p.h
index aefc204df3..83b5b95a2f 100644
--- a/src/declarative/qml/parser/qdeclarativejsglobal_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsglobal_p.h
@@ -58,7 +58,7 @@
#else // !QT_CREATOR
# define QT_QML_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
# define QT_QML_END_NAMESPACE QT_END_NAMESPACE
-# define QML_PARSER_EXPORT
+# define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT
#endif // QT_CREATOR
#endif // QDECLARATIVEJSGLOBAL_P_H
diff --git a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
index c48cf2b997..38bd46bfcf 100644
--- a/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsgrammar.cpp
@@ -61,462 +61,469 @@ const short QDeclarativeJSGrammar::lhs [] = {
101, 101, 101, 101, 101, 101, 102, 108, 108, 111,
111, 113, 112, 112, 112, 112, 112, 112, 112, 112,
115, 110, 109, 118, 118, 119, 119, 120, 120, 117,
- 106, 106, 106, 106, 106, 106, 106, 106, 126, 126,
- 126, 127, 127, 128, 128, 106, 106, 106, 106, 106,
+ 106, 106, 106, 106, 122, 122, 122, 122, 106, 127,
+ 127, 127, 128, 128, 129, 129, 106, 106, 106, 106,
106, 106, 106, 106, 106, 106, 106, 106, 106, 106,
- 106, 106, 106, 106, 106, 116, 116, 116, 116, 116,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 121, 133,
- 133, 133, 133, 132, 132, 135, 135, 137, 137, 137,
- 137, 137, 137, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 138, 138, 138, 138, 138, 138,
- 138, 138, 138, 138, 139, 139, 114, 114, 114, 114,
- 114, 142, 142, 143, 143, 143, 143, 141, 141, 144,
- 144, 145, 145, 146, 146, 146, 147, 147, 147, 147,
- 147, 147, 147, 147, 147, 147, 148, 148, 148, 148,
- 149, 149, 149, 150, 150, 150, 150, 151, 151, 151,
- 151, 151, 151, 151, 152, 152, 152, 152, 152, 152,
- 153, 153, 153, 153, 153, 154, 154, 154, 154, 154,
- 155, 155, 156, 156, 157, 157, 158, 158, 159, 159,
- 160, 160, 161, 161, 162, 162, 163, 163, 164, 164,
- 165, 165, 166, 166, 136, 136, 167, 167, 168, 168,
- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
- 104, 104, 169, 169, 170, 170, 171, 171, 103, 103,
+ 106, 106, 106, 116, 116, 116, 116, 116, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 121, 134, 134, 134,
+ 134, 133, 133, 136, 136, 138, 138, 138, 138, 138,
+ 138, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
+ 139, 139, 140, 140, 114, 114, 114, 114, 114, 143,
+ 143, 144, 144, 144, 144, 142, 142, 145, 145, 146,
+ 146, 147, 147, 147, 148, 148, 148, 148, 148, 148,
+ 148, 148, 148, 148, 149, 149, 149, 149, 150, 150,
+ 150, 151, 151, 151, 151, 152, 152, 152, 152, 152,
+ 152, 152, 153, 153, 153, 153, 153, 153, 154, 154,
+ 154, 154, 154, 155, 155, 155, 155, 155, 156, 156,
+ 157, 157, 158, 158, 159, 159, 160, 160, 161, 161,
+ 162, 162, 163, 163, 164, 164, 165, 165, 166, 166,
+ 167, 167, 137, 137, 168, 168, 169, 169, 169, 169,
+ 169, 169, 169, 169, 169, 169, 169, 169, 104, 104,
+ 170, 170, 171, 171, 172, 172, 103, 103, 103, 103,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
- 103, 103, 103, 122, 183, 183, 182, 182, 130, 130,
- 184, 184, 185, 185, 187, 187, 186, 188, 191, 189,
- 189, 192, 190, 190, 123, 124, 124, 125, 125, 172,
- 172, 172, 172, 172, 172, 172, 173, 173, 173, 173,
- 174, 174, 174, 174, 175, 175, 176, 178, 193, 193,
- 196, 196, 194, 194, 197, 195, 177, 177, 177, 179,
- 179, 180, 180, 180, 198, 199, 181, 181, 129, 140,
- 203, 203, 200, 200, 201, 201, 204, 107, 205, 205,
- 105, 105, 202, 202, 134, 134, 206};
+ 103, 123, 184, 184, 183, 183, 131, 131, 185, 185,
+ 186, 186, 188, 188, 187, 189, 192, 190, 190, 193,
+ 191, 191, 124, 125, 125, 126, 126, 173, 173, 173,
+ 173, 173, 173, 173, 174, 174, 174, 174, 175, 175,
+ 175, 175, 176, 176, 177, 179, 194, 194, 197, 197,
+ 195, 195, 198, 196, 178, 178, 178, 180, 180, 181,
+ 181, 181, 199, 200, 182, 182, 130, 141, 204, 204,
+ 201, 201, 202, 202, 205, 107, 206, 206, 105, 105,
+ 203, 203, 135, 135, 207};
const short QDeclarativeJSGrammar::rhs [] = {
2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
2, 1, 2, 2, 3, 3, 5, 5, 4, 4,
2, 0, 1, 1, 2, 1, 3, 2, 3, 2,
- 1, 5, 4, 4, 3, 3, 3, 3, 1, 1,
- 1, 0, 1, 2, 4, 6, 6, 3, 3, 7,
- 7, 4, 4, 5, 5, 6, 6, 7, 7, 7,
- 7, 10, 6, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 4, 4, 1, 1, 1, 1, 3, 1,
+ 1, 1, 0, 1, 2, 4, 6, 6, 3, 3,
+ 7, 7, 4, 4, 5, 5, 5, 6, 6, 10,
+ 6, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 3, 4, 5, 3, 4, 3, 1, 1, 2, 3,
+ 4, 1, 2, 3, 5, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 3, 3, 4, 5, 3, 4, 3, 1, 1,
- 2, 3, 4, 1, 2, 3, 5, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 4, 3,
- 5, 1, 2, 4, 4, 4, 3, 0, 1, 1,
- 3, 1, 1, 1, 2, 2, 1, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 3, 3, 3,
- 1, 3, 3, 1, 3, 3, 3, 1, 3, 3,
- 3, 3, 3, 3, 1, 3, 3, 3, 3, 3,
- 1, 3, 3, 3, 3, 1, 3, 3, 3, 3,
- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
+ 1, 1, 1, 1, 1, 1, 4, 3, 5, 1,
+ 2, 4, 4, 4, 3, 0, 1, 1, 3, 1,
+ 1, 1, 2, 2, 1, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 1, 3, 3, 3, 1, 3,
+ 3, 1, 3, 3, 3, 1, 3, 3, 3, 3,
+ 3, 3, 1, 3, 3, 3, 3, 3, 1, 3,
+ 3, 3, 3, 1, 3, 3, 3, 3, 1, 3,
1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
- 1, 5, 1, 5, 1, 3, 1, 3, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 3, 0, 1, 1, 3, 0, 1, 1, 1,
+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 5,
+ 1, 5, 1, 3, 1, 3, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 0, 1, 1, 3, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 3, 1, 2, 0, 1, 3, 3,
- 1, 1, 1, 3, 1, 3, 2, 2, 2, 0,
- 1, 2, 0, 1, 1, 2, 2, 7, 5, 7,
- 7, 5, 9, 10, 7, 8, 2, 2, 3, 3,
- 2, 2, 3, 3, 3, 3, 5, 5, 3, 5,
- 1, 2, 0, 1, 4, 3, 3, 3, 3, 3,
- 3, 3, 3, 4, 5, 2, 2, 2, 8, 8,
- 1, 3, 0, 1, 0, 1, 1, 1, 1, 2,
- 1, 1, 0, 1, 0, 1, 2};
+ 1, 3, 1, 2, 0, 1, 3, 3, 1, 1,
+ 1, 3, 1, 3, 2, 2, 2, 0, 1, 2,
+ 0, 1, 1, 2, 2, 7, 5, 7, 7, 5,
+ 9, 10, 7, 8, 2, 2, 3, 3, 2, 2,
+ 3, 3, 3, 3, 5, 5, 3, 5, 1, 2,
+ 0, 1, 4, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 5, 2, 2, 2, 8, 8, 1, 3,
+ 0, 1, 0, 1, 1, 1, 1, 2, 1, 1,
+ 0, 1, 0, 1, 2};
const short QDeclarativeJSGrammar::action_default [] = {
- 0, 0, 0, 0, 0, 0, 22, 0, 174, 241,
- 205, 213, 209, 153, 225, 201, 3, 138, 72, 154,
- 217, 221, 142, 171, 152, 157, 137, 191, 178, 0,
- 79, 80, 75, 343, 66, 345, 0, 0, 0, 0,
- 77, 0, 0, 73, 76, 70, 0, 0, 67, 69,
- 68, 78, 71, 0, 74, 0, 0, 167, 0, 0,
- 154, 173, 156, 155, 0, 0, 0, 169, 170, 168,
- 172, 0, 202, 0, 0, 0, 0, 192, 0, 0,
- 0, 0, 0, 0, 182, 0, 0, 0, 176, 177,
- 175, 180, 184, 183, 181, 179, 194, 193, 195, 0,
- 210, 0, 206, 0, 0, 148, 135, 147, 136, 104,
- 105, 106, 131, 107, 132, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 117, 118, 119, 120, 133, 121,
- 122, 123, 124, 125, 126, 127, 128, 129, 130, 134,
- 0, 0, 146, 242, 149, 0, 150, 0, 151, 145,
- 0, 238, 231, 229, 236, 237, 235, 234, 240, 233,
- 232, 230, 239, 226, 0, 214, 0, 0, 218, 0,
- 0, 222, 0, 0, 148, 140, 0, 139, 0, 144,
- 158, 0, 344, 333, 334, 0, 331, 0, 332, 0,
- 335, 249, 256, 255, 263, 251, 0, 252, 336, 0,
- 342, 253, 254, 259, 257, 339, 337, 341, 260, 0,
- 271, 0, 0, 0, 0, 343, 66, 0, 345, 67,
- 243, 285, 68, 0, 0, 0, 272, 0, 0, 261,
- 262, 0, 250, 258, 286, 287, 330, 340, 0, 301,
- 302, 303, 304, 0, 297, 298, 299, 300, 327, 328,
- 0, 0, 0, 0, 0, 290, 291, 247, 245, 207,
- 215, 211, 227, 203, 248, 0, 154, 219, 223, 196,
- 185, 0, 0, 204, 0, 0, 0, 0, 197, 0,
- 0, 0, 0, 0, 189, 187, 190, 188, 186, 199,
- 198, 200, 0, 212, 0, 208, 0, 246, 154, 0,
- 228, 243, 244, 0, 243, 0, 0, 293, 0, 0,
- 0, 295, 0, 216, 0, 0, 220, 0, 0, 224,
- 283, 0, 275, 284, 278, 0, 282, 0, 243, 276,
- 0, 243, 0, 0, 294, 0, 0, 0, 296, 344,
- 333, 0, 0, 335, 0, 329, 0, 319, 0, 0,
- 0, 289, 0, 288, 0, 346, 0, 103, 265, 268,
- 0, 104, 271, 107, 132, 109, 110, 75, 114, 115,
- 66, 116, 119, 73, 76, 67, 243, 68, 78, 122,
- 71, 124, 74, 126, 127, 272, 129, 130, 134, 0,
- 96, 0, 0, 98, 102, 100, 87, 99, 101, 0,
- 97, 86, 266, 264, 142, 143, 148, 0, 141, 0,
- 318, 0, 305, 306, 0, 317, 0, 0, 0, 308,
- 313, 311, 314, 0, 0, 312, 313, 0, 309, 0,
- 310, 267, 316, 0, 267, 315, 0, 320, 321, 0,
- 267, 322, 323, 0, 0, 324, 0, 0, 0, 325,
- 326, 160, 159, 0, 0, 0, 292, 0, 0, 0,
- 307, 280, 273, 0, 281, 277, 0, 279, 269, 0,
- 270, 274, 90, 0, 0, 94, 81, 0, 83, 92,
- 0, 84, 93, 95, 85, 91, 82, 0, 88, 164,
- 162, 166, 163, 161, 165, 6, 338, 4, 2, 64,
- 89, 0, 0, 67, 69, 68, 31, 5, 0, 65,
- 0, 41, 40, 39, 0, 0, 54, 0, 55, 0,
- 60, 61, 0, 41, 0, 0, 0, 0, 0, 50,
- 0, 51, 0, 0, 26, 0, 0, 62, 27, 0,
- 30, 28, 24, 0, 29, 25, 0, 52, 0, 53,
- 0, 142, 0, 56, 57, 63, 0, 0, 0, 0,
- 0, 58, 59, 0, 48, 42, 49, 43, 0, 0,
- 0, 0, 45, 0, 46, 47, 44, 0, 0, 35,
- 36, 37, 38, 142, 267, 0, 0, 104, 271, 107,
- 132, 109, 110, 75, 114, 115, 66, 116, 119, 73,
- 76, 67, 243, 68, 78, 122, 71, 124, 74, 126,
- 127, 272, 129, 130, 134, 0, 32, 33, 0, 34,
- 8, 0, 10, 0, 9, 0, 1, 21, 12, 0,
- 13, 0, 14, 0, 19, 20, 0, 15, 16, 0,
- 17, 18, 11, 23, 7, 347};
+ 0, 0, 0, 0, 0, 0, 22, 0, 172, 239,
+ 203, 211, 207, 151, 223, 199, 3, 136, 70, 152,
+ 215, 219, 140, 169, 150, 155, 135, 189, 176, 0,
+ 77, 78, 73, 341, 64, 343, 0, 0, 0, 0,
+ 75, 0, 0, 71, 74, 68, 0, 0, 65, 67,
+ 66, 76, 69, 0, 72, 0, 0, 165, 0, 0,
+ 152, 171, 154, 153, 0, 0, 0, 167, 168, 166,
+ 170, 0, 200, 0, 0, 0, 0, 190, 0, 0,
+ 0, 0, 0, 0, 180, 0, 0, 0, 174, 175,
+ 173, 178, 182, 181, 179, 177, 192, 191, 193, 0,
+ 208, 0, 204, 0, 0, 146, 133, 145, 134, 102,
+ 103, 104, 129, 105, 130, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118, 131, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 132,
+ 0, 0, 144, 240, 147, 0, 148, 0, 149, 143,
+ 0, 236, 229, 227, 234, 235, 233, 232, 238, 231,
+ 230, 228, 237, 224, 0, 212, 0, 0, 216, 0,
+ 0, 220, 0, 0, 146, 138, 0, 137, 0, 142,
+ 156, 0, 342, 331, 332, 0, 329, 0, 330, 0,
+ 333, 247, 254, 253, 261, 249, 0, 250, 334, 0,
+ 340, 251, 252, 257, 255, 337, 335, 339, 258, 0,
+ 269, 0, 0, 0, 0, 341, 64, 0, 343, 65,
+ 241, 283, 66, 0, 0, 0, 270, 0, 0, 259,
+ 260, 0, 248, 256, 284, 285, 328, 338, 0, 299,
+ 300, 301, 302, 0, 295, 296, 297, 298, 325, 326,
+ 0, 0, 0, 0, 0, 288, 289, 245, 243, 205,
+ 213, 209, 225, 201, 246, 0, 152, 217, 221, 194,
+ 183, 0, 0, 202, 0, 0, 0, 0, 195, 0,
+ 0, 0, 0, 0, 187, 185, 188, 186, 184, 197,
+ 196, 198, 0, 210, 0, 206, 0, 244, 152, 0,
+ 226, 241, 242, 0, 241, 0, 0, 291, 0, 0,
+ 0, 293, 0, 214, 0, 0, 218, 0, 0, 222,
+ 281, 0, 273, 282, 276, 0, 280, 0, 241, 274,
+ 0, 241, 0, 0, 292, 0, 0, 0, 294, 342,
+ 331, 0, 0, 333, 0, 327, 0, 317, 0, 0,
+ 0, 287, 0, 286, 0, 344, 0, 101, 263, 266,
+ 0, 102, 269, 105, 130, 107, 108, 73, 112, 113,
+ 64, 114, 117, 71, 74, 65, 241, 66, 76, 120,
+ 69, 122, 72, 124, 125, 270, 127, 128, 132, 0,
+ 94, 0, 0, 96, 100, 98, 85, 97, 99, 0,
+ 95, 84, 264, 262, 140, 141, 146, 0, 139, 0,
+ 316, 0, 303, 304, 0, 315, 0, 0, 0, 306,
+ 311, 309, 312, 0, 0, 310, 311, 0, 307, 0,
+ 308, 265, 314, 0, 265, 313, 0, 318, 319, 0,
+ 265, 320, 321, 0, 0, 322, 0, 0, 0, 323,
+ 324, 158, 157, 0, 0, 0, 290, 0, 0, 0,
+ 305, 278, 271, 0, 279, 275, 0, 277, 267, 0,
+ 268, 272, 88, 0, 0, 92, 79, 0, 81, 90,
+ 0, 82, 91, 93, 83, 89, 80, 0, 86, 162,
+ 160, 164, 161, 159, 163, 6, 336, 4, 2, 62,
+ 87, 0, 0, 65, 67, 66, 31, 5, 0, 63,
+ 0, 42, 41, 40, 0, 0, 55, 0, 56, 35,
+ 36, 37, 38, 59, 0, 42, 0, 0, 0, 0,
+ 0, 51, 0, 52, 0, 0, 26, 0, 0, 60,
+ 27, 0, 30, 28, 24, 0, 29, 25, 0, 53,
+ 0, 54, 140, 0, 57, 61, 0, 0, 0, 0,
+ 58, 0, 49, 43, 50, 44, 0, 0, 0, 0,
+ 46, 0, 47, 48, 45, 0, 0, 140, 265, 0,
+ 0, 39, 102, 269, 105, 130, 107, 108, 73, 112,
+ 113, 64, 114, 117, 71, 74, 65, 241, 66, 76,
+ 120, 69, 122, 72, 124, 125, 270, 127, 128, 132,
+ 0, 32, 33, 0, 34, 8, 0, 10, 0, 9,
+ 0, 1, 21, 12, 0, 13, 0, 14, 0, 19,
+ 20, 0, 15, 16, 0, 17, 18, 11, 23, 7,
+ 345};
const short QDeclarativeJSGrammar::goto_default [] = {
- 7, 626, 207, 196, 205, 507, 495, 625, 644, 620,
- 624, 622, 627, 22, 623, 18, 506, 543, 533, 540,
- 535, 191, 195, 197, 201, 524, 568, 567, 200, 232,
- 26, 474, 473, 356, 355, 9, 354, 357, 107, 17,
- 145, 24, 13, 144, 19, 25, 57, 23, 8, 28,
- 27, 269, 15, 263, 10, 259, 12, 261, 11, 260,
- 20, 267, 21, 268, 14, 262, 258, 299, 411, 264,
- 265, 202, 193, 192, 204, 233, 203, 208, 229, 230,
- 194, 360, 359, 231, 463, 462, 321, 322, 465, 324,
- 464, 323, 419, 423, 426, 422, 421, 441, 442, 185,
- 199, 181, 184, 198, 206, 0};
+ 7, 621, 207, 196, 205, 507, 495, 620, 639, 615,
+ 619, 617, 622, 22, 618, 18, 506, 545, 535, 542,
+ 537, 523, 191, 195, 197, 201, 526, 566, 565, 200,
+ 232, 26, 474, 473, 356, 355, 9, 354, 357, 107,
+ 17, 145, 24, 13, 144, 19, 25, 57, 23, 8,
+ 28, 27, 269, 15, 263, 10, 259, 12, 261, 11,
+ 260, 20, 267, 21, 268, 14, 262, 258, 299, 411,
+ 264, 265, 202, 193, 192, 204, 233, 203, 208, 229,
+ 230, 194, 360, 359, 231, 463, 462, 321, 322, 465,
+ 324, 464, 323, 419, 423, 426, 422, 421, 441, 442,
+ 185, 199, 181, 184, 198, 206, 0};
const short QDeclarativeJSGrammar::action_index [] = {
- 421, 1288, 2322, 2322, 2419, 1016, -52, 37, 140, -101,
- 35, -13, -40, 190, -101, 272, 34, -101, -101, 658,
- 42, 103, 194, 201, -101, -101, -101, 439, 256, 1288,
- -101, -101, -101, 282, -101, 2128, 1751, 1288, 1288, 1288,
- -101, 917, 1288, -101, -101, -101, 1288, 1288, -101, -101,
- -101, -101, -101, 1288, -101, 1288, 1288, -101, 1288, 1288,
- 109, 245, -101, -101, 1288, 1288, 1288, -101, -101, -101,
- 185, 1288, 295, 1288, 1288, 1288, 1288, 461, 1288, 1288,
- 1288, 1288, 1288, 1288, 256, 1288, 1288, 1288, 155, 119,
- 114, 176, 256, 332, 202, 332, 560, 560, 471, 1288,
- -23, 1288, 53, 2031, 1288, 1288, -101, -101, -101, -101,
+ 350, 1271, 2492, 2492, 2395, 999, 52, 93, 137, -101,
+ 104, 72, 66, 177, -101, 285, 80, -101, -101, 641,
+ 71, 130, 167, 178, -101, -101, -101, 431, 321, 1271,
+ -101, -101, -101, 393, -101, 2201, 2007, 1271, 1271, 1271,
+ -101, 811, 1271, -101, -101, -101, 1271, 1271, -101, -101,
+ -101, -101, -101, 1271, -101, 1271, 1271, -101, 1271, 1271,
+ 87, 188, -101, -101, 1271, 1271, 1271, -101, -101, -101,
+ 179, 1271, 263, 1271, 1271, 1271, 1271, 456, 1271, 1271,
+ 1271, 1271, 1271, 1271, 321, 1271, 1271, 1271, 128, 114,
+ 120, 193, 181, 172, 321, 321, 446, 395, 405, 1271,
+ -8, 1271, 76, 2104, 1271, 1271, -101, -101, -101, -101,
-101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
-101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
-101, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- 100, 1288, -101, -101, 70, 59, -101, 1288, -101, -101,
- 1288, -101, -101, -101, -101, -101, -101, -101, -101, -101,
- -101, -101, -101, -101, 1288, 41, 1288, 1288, 98, 91,
- 1288, -101, 2031, 1288, 1288, -101, 121, -101, 73, -101,
- -101, 39, -101, 385, 180, 78, -101, 391, -101, 64,
- 2322, -101, -101, -101, -101, -101, 208, -101, -101, 82,
- -101, -101, -101, -101, -101, -101, 2322, -101, -101, 538,
- -101, 495, 128, 2419, 54, 358, 62, 44, 2613, 67,
- 1288, -101, 76, 63, 1288, 58, -101, 60, 46, -101,
- -101, 309, -101, -101, -101, -101, -101, -101, 86, -101,
- -101, -101, -101, 107, -101, -101, -101, -101, -101, -101,
- 28, 52, 1288, 101, 102, -101, -101, 1472, -101, 83,
- 75, 79, -101, 287, 84, 80, 585, 69, 89, 321,
- 177, 482, 1288, 297, 1288, 1288, 1288, 1288, 331, 1288,
- 1288, 1288, 1288, 1288, 332, 222, 332, 332, 332, 410,
- 410, 410, 1288, 57, 1288, 72, 1288, -101, 658, 1288,
- -101, 1288, 71, 45, 1288, 61, 2419, -101, 1288, 132,
- 2419, -101, 1288, 47, 1288, 1288, 66, 65, 1288, -101,
- 68, 112, 81, -101, -101, 1288, -101, 369, 1288, -101,
- 85, 1288, 74, 2419, -101, 1288, 122, 2419, -101, 77,
- 294, 16, -29, 2322, -53, -101, 2419, -101, 1288, 127,
- 2419, -15, 2419, -101, 10, 11, -34, -101, -101, 2419,
- -48, 504, 4, 476, 113, 1288, 2419, 2, -28, 420,
- 6, -21, 719, 7, 87, -101, 1382, -101, -4, -16,
- 5, 1288, 3, -27, 1288, 9, 1288, -18, -31, 1288,
- -101, 2225, -7, -101, -101, -101, -101, -101, -101, 1288,
- -101, -101, -101, -101, 246, -101, 1288, -38, -101, 2419,
- -101, 88, -101, -101, 2419, -101, 1288, 106, 26, -101,
- 55, -101, 50, 105, 1288, -101, 48, 38, -101, -8,
- -101, 2419, -101, 94, 2419, -101, 238, -101, -101, 104,
- 2419, 31, -101, 21, 19, -101, 305, 1, 30, -101,
- -101, -101, -101, 1288, 136, 2419, -101, 1288, 134, 2419,
- -101, 49, -101, 173, -101, -101, 1288, -101, -101, 363,
- -101, -101, -101, 137, 1565, -101, -101, 1658, -101, -101,
- 1844, -101, -101, -101, -101, -101, -101, 95, -101, -101,
- -101, -101, -101, -101, -101, -101, 2322, -101, -101, -101,
- 92, 15, 925, 169, 27, -6, -101, -101, 212, -101,
- 191, -101, -101, -101, 323, 211, -101, 1288, -101, 214,
- -101, -101, 216, 40, 317, 210, 43, 259, 236, -101,
- 36, -101, 747, 96, -101, 29, 747, -101, -101, 1198,
- -101, -101, -101, 1107, -101, -101, 231, -101, 1288, -101,
- 217, 286, 32, -101, -101, -101, 188, 340, 51, 1288,
- 175, -101, -101, 171, -101, 179, -101, 56, -11, 351,
- 181, 336, -101, 110, -101, -101, -101, 1934, 647, -101,
- -101, -101, -101, 253, 2516, 1751, -5, 460, 22, 468,
- 138, 1288, 2419, 24, -2, 412, 23, -3, 836, 20,
- 87, -101, 1382, -101, 17, -10, 18, 1288, 25, 8,
- 1288, 33, 1288, 12, 14, 120, -101, -101, 13, -101,
- -101, 747, -101, 248, -47, 828, -101, -101, 152, 482,
- -101, 150, -101, 123, -101, -101, 398, -101, -101, 117,
- -101, -101, -101, -101, -101, -101,
+ 110, 1271, -101, -101, 68, 38, -101, 1271, -101, -101,
+ 1271, -101, -101, -101, -101, -101, -101, -101, -101, -101,
+ -101, -101, -101, -101, 1271, 32, 1271, 1271, 85, 83,
+ 1271, -101, 2104, 1271, 1271, -101, 108, -101, 53, -101,
+ -101, 64, -101, 393, 89, 62, -101, 297, -101, 63,
+ 2492, -101, -101, -101, -101, -101, 154, -101, -101, 47,
+ -101, -101, -101, -101, -101, -101, 2492, -101, -101, 461,
+ -101, 470, 74, 2395, 59, 393, 92, 67, 2686, 152,
+ 1271, -101, 65, 43, 1271, 41, -101, 39, 34, -101,
+ -101, 393, -101, -101, -101, -101, -101, -101, 86, -101,
+ -101, -101, -101, 90, -101, -101, -101, -101, -101, -101,
+ -11, 50, 1271, 103, 82, -101, -101, 1455, -101, 84,
+ 44, 5, -101, 267, 70, 33, 575, 79, 69, 471,
+ 235, 393, 1271, 275, 1271, 1271, 1271, 1271, 305, 1271,
+ 1271, 1271, 1271, 1271, 229, 201, 225, 202, 321, 355,
+ 374, 380, 1271, 35, 1271, 81, 1271, -101, 641, 1271,
+ -101, 1271, 61, 1, 1271, 29, 2395, -101, 1271, 133,
+ 2395, -101, 1271, 73, 1271, 1271, 99, 97, 1271, -101,
+ 51, 153, 60, -101, -101, 1271, -101, 393, 1271, -101,
+ 56, 1271, -25, 2395, -101, 1271, 129, 2395, -101, -35,
+ 309, -56, -31, 2492, -39, -101, 2395, -101, 1271, 245,
+ 2395, -5, 2395, -101, 6, 0, -33, -101, -101, 2395,
+ -43, 543, 7, 488, 112, 1271, 2395, -1, -27, 453,
+ 8, -18, 630, 14, 16, -101, 1365, -101, 12, -19,
+ 3, 1271, 58, -30, 1271, -2, 1271, -29, -36, 1271,
+ -101, 2298, 18, -101, -101, -101, -101, -101, -101, 1271,
+ -101, -101, -101, -101, 223, -101, 1271, -10, -101, 2395,
+ -101, 95, -101, -101, 2395, -101, 1271, 107, 20, -101,
+ 40, -101, 46, 100, 1271, -101, 55, 57, -101, 28,
+ -101, 2395, -101, 118, 2395, -101, 161, -101, -101, 126,
+ 2395, 37, -101, -12, -4, -101, 393, -34, -6, -101,
+ -101, -101, -101, 1271, 98, 2395, -101, 1271, 116, 2395,
+ -101, 19, -101, 186, -101, -101, 1271, -101, -101, 303,
+ -101, -101, -101, 119, 1638, -101, -101, 1821, -101, -101,
+ 1914, -101, -101, -101, -101, -101, -101, 123, -101, -101,
+ -101, -101, -101, -101, -101, -101, 2492, -101, -101, -101,
+ 94, -26, 819, 158, -28, 4, -101, -101, 210, -101,
+ 203, -101, -101, -101, 393, 230, -101, 1545, -101, -101,
+ -101, -101, -101, -101, 234, 2, 393, 232, 17, 393,
+ 163, -101, 10, -101, 908, 125, -101, 13, 908, -101,
+ -101, 1090, -101, -101, -101, 1181, -101, -101, 214, -101,
+ 1545, -101, 262, 9, -101, -101, 180, 318, 30, 1545,
+ -101, 238, -101, 236, -101, 26, -32, 315, 183, 288,
+ -101, 77, -101, -101, -101, 1728, 908, 291, 2589, 2007,
+ -3, -101, 443, 25, 497, 88, 1271, 2395, 24, 11,
+ 384, 36, 27, 702, 48, 49, -101, 1365, -101, 54,
+ 31, 45, 1271, 58, 15, 1271, 42, 1271, 23, 22,
+ 122, -101, -101, 21, -101, -101, 730, -101, 254, -70,
+ 908, -101, -101, 138, 393, -101, 143, -101, 134, -101,
+ -101, 268, -101, -101, 124, -101, -101, -101, -101, -101,
+ -101,
- -106, 6, -92, 10, 5, 278, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -42,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, 109,
- -106, -106, -106, -10, -106, -106, -35, 24, 73, 90,
- -106, 219, 181, -106, -106, -106, 171, 120, -106, -106,
- -106, -106, -106, 174, -106, 170, 167, -106, 175, 163,
- -106, -106, -106, -106, 184, 177, 180, -106, -106, -106,
- -106, 125, -106, 132, 134, 162, 130, -106, 121, 124,
- 123, 141, 142, 152, -106, 154, 161, 160, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, 139,
- -106, 143, -106, 156, 91, 55, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, 32, -106, -106, -106, -106, -106, 33, -106, -106,
- 26, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, 96, -106, 119, 52, -106, -106,
- 66, -106, 220, 69, 71, -106, -106, -106, -106, -106,
- -106, -106, -106, 25, -106, -106, -106, 64, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, 70, -106, -106, 61,
- -106, 41, -106, 39, -106, 37, -106, -106, 42, -106,
- 79, -106, -106, -106, 81, 72, -106, -106, -106, -106,
- -106, -5, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, 21, -106, -106, -106, -106, 112, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, 17, 237, -106, 192, 236, 224, 225, -106, 97,
- 98, 101, 99, 113, -106, -106, -106, -106, -106, -106,
- -106, -106, 204, -106, 223, -106, 235, -106, -106, 239,
- -106, 197, -106, -106, 228, -106, 27, -106, 13, -106,
- 2, -106, 233, -106, 190, 198, -106, -106, 196, -106,
- -106, -106, -106, -106, -106, 200, -106, 107, 135, -106,
- -106, 186, -106, 84, -106, 80, -106, 76, -106, -106,
- 89, -106, -106, -49, -106, -106, 47, -106, 40, -106,
- 44, -106, 68, -106, -106, -106, -106, -106, -106, 53,
- -106, 35, -106, 49, -106, 87, 63, -106, -106, 30,
- -106, -106, 103, -106, -106, -106, 51, -106, -106, -106,
- -106, 86, -106, 67, 114, -106, 74, -106, -106, 65,
- -106, 56, -106, -106, -106, -106, -106, -106, -106, 62,
- -106, -106, -106, -106, -106, -106, 95, -106, -106, 78,
- -106, -106, -106, -106, 75, -106, 88, -106, -106, -106,
- -106, -106, -54, -106, 45, -106, -40, -106, -106, -106,
- -106, 94, -106, -106, 100, -106, -106, -106, -106, -106,
- 150, -41, -106, -106, 54, -106, 43, -106, 48, -106,
- -106, -106, -106, 59, -106, 57, -106, 60, -106, 58,
- -106, -106, -106, -106, -106, -106, 38, -106, -106, 144,
- -106, -106, -106, -106, 31, -106, -106, 202, -106, -106,
- 50, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, 77, -106, -106, -106,
- -106, -106, 82, -106, -106, -106, -106, -106, -106, -106,
- -17, -106, -106, -106, -4, -106, -106, 12, -106, -106,
- -106, -106, -106, -106, -14, 46, -106, -13, -106, -106,
- -106, -106, 108, -106, -106, -106, 243, -106, -106, 295,
- -106, -106, -106, 290, -106, -106, -106, -106, 346, -106,
- -106, -106, 16, -106, -106, -106, 22, 23, -106, 34,
- -106, -106, -106, -106, -106, 11, -106, -106, -106, 7,
- 1, 8, -106, -106, -106, -106, -106, 307, 179, -106,
- -106, -106, -106, -106, 18, 281, 9, 15, -106, 4,
- -106, 83, 29, -106, -106, -2, -106, -106, 85, -106,
- -106, -106, 3, -106, -106, -106, -106, 14, -106, 0,
- 105, -106, 93, -106, -106, -106, -106, -106, -1, -106,
- -106, 20, -106, -106, 28, 92, -106, -106, -106, 19,
- -106, -106, -106, -106, -106, -106, -12, -106, -106, -106,
- -106, -106, -106, -106, -106, -106};
+ -107, 25, -75, 27, 30, 272, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -42,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, 95,
+ -107, -107, -107, 31, -107, -107, 1, 37, 91, 80,
+ -107, 89, 167, -107, -107, -107, 175, 181, -107, -107,
+ -107, -107, -107, 137, -107, 130, 129, -107, 144, 152,
+ -107, -107, -107, -107, 140, 133, 149, -107, -107, -107,
+ -107, 157, -107, 182, 179, 170, 70, -107, 66, 78,
+ 55, 94, 100, 114, -107, 120, 109, 104, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, 172,
+ -107, 128, -107, 122, 58, 34, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, 51, -107, -107, -107, -107, -107, 36, -107, -107,
+ 47, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, 154, -107, 158, -35, -107, -107,
+ 13, -107, 248, 42, 115, -107, -107, -107, -107, -107,
+ -107, -107, -107, 20, -107, -107, -107, 2, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, 61, -107, -107, 67,
+ -107, 64, -107, 76, -107, 43, -107, -107, 57, -107,
+ 60, -107, -107, -107, 85, 69, -107, -107, -107, -107,
+ -107, -5, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, 24, -107, -107, -107, -107, 148, -107, -107,
+ -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, 9, 186, -107, 196, 221, 220, 212, -107, 102,
+ 98, 96, 116, 118, -107, -107, -107, -107, -107, -107,
+ -107, -107, 230, -107, 199, -107, 193, -107, -107, 211,
+ -107, 132, -107, -107, 126, -107, 14, -107, 5, -107,
+ 10, -107, 208, -107, 189, 202, -107, -107, 209, -107,
+ -107, -107, -107, -107, -107, 200, -107, 103, 121, -107,
+ -107, 168, -107, 50, -107, 54, -107, 62, -107, -107,
+ 88, -107, -107, -21, -107, -107, 184, -107, 63, -107,
+ 65, -107, 74, -107, -107, -107, -107, -107, -107, 92,
+ -107, 35, -107, 45, -107, 171, 75, -107, -107, 56,
+ -107, -107, 166, -107, -107, -107, 90, -107, -107, -107,
+ -107, 39, -107, 32, 159, -107, 178, -107, -107, -3,
+ -107, -17, -107, -107, -107, -107, -107, -107, -107, 3,
+ -107, -107, -107, -107, -107, -107, 68, -107, -107, 79,
+ -107, -107, -107, -107, 16, -107, 11, -107, -107, -107,
+ -107, -107, -8, -107, 59, -107, -41, -107, -107, -107,
+ -107, 99, -107, -107, 160, -107, -107, -107, -107, -107,
+ 93, -7, -107, -107, 77, -107, 40, -107, 46, -107,
+ -107, -107, -107, 53, -107, 83, -107, 72, -107, 71,
+ -107, -107, -107, -107, -107, -107, 48, -107, -107, 81,
+ -107, -107, -107, -107, 38, -107, -107, 173, -107, -107,
+ 33, -107, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107, -107, -107, -107, -107, -107, 86, -107, -107, -107,
+ -107, -107, 73, -107, -107, -107, -107, -107, -107, -107,
+ 22, -107, -107, -107, -10, -107, -107, 259, -107, -107,
+ -107, -107, -107, -107, -107, -107, -6, -15, -107, -2,
+ -107, -107, -107, -107, 101, -107, -107, -107, 106, -107,
+ -107, 290, -107, -107, -107, 294, -107, -107, -107, -107,
+ 318, -107, -107, -4, -107, -107, -19, -13, -107, 364,
+ -107, -107, -107, -26, -107, -107, -107, -11, -20, -12,
+ -107, -107, -107, -107, -107, 305, 278, -107, 17, 261,
+ 4, -107, 28, -107, 26, -107, 87, 19, -107, -107,
+ 23, -107, -107, 84, -107, -107, -107, 44, -107, -107,
+ -107, -107, 41, -107, 29, 125, -107, 110, -107, -107,
+ -107, -107, -107, 15, -107, -107, 12, -107, -107, 18,
+ 97, -107, -107, -107, 7, -107, -107, -107, -107, -107,
+ -107, 21, -107, -107, -107, -107, -107, -107, -107, -107,
+ -107};
const short QDeclarativeJSGrammar::action_info [] = {
- 399, 352, 345, -101, 343, 457, 440, 403, 257, -112,
- -125, -131, -123, 346, -120, 348, -128, 389, 453, 391,
- 416, 401, 408, 563, -101, -123, 416, -120, 539, -131,
- 346, -112, -125, 348, 257, 99, 71, 645, 621, 101,
- -128, 440, 141, 621, 164, 431, 539, 430, 453, 573,
- 457, 444, 440, 424, 71, 424, 101, 446, 559, 420,
- 424, 448, 539, 440, 570, 539, 466, 527, 312, 346,
- 532, 312, 318, 272, 409, 183, 342, 525, 147, 141,
- 348, 510, 457, 414, 272, 325, 0, 0, 252, 99,
- 257, 440, 296, 556, -102, 292, 453, 190, 170, 416,
- 164, 434, 141, 141, 536, 251, 304, 172, 141, 141,
- 443, 0, 335, 340, 141, 427, 0, 0, 0, 149,
- 327, 306, 0, 292, 444, 0, 173, 0, 536, 141,
- 141, 0, 0, 179, 333, 141, 294, 236, 189, 314,
- 141, 301, 141, 315, 141, 477, 331, 242, 241, 413,
- 412, 62, 537, 166, 58, 488, 142, 167, 294, 58,
- 428, 254, 63, 256, 255, 59, 418, 172, 247, 246,
- 59, 575, 574, 328, 249, 248, 616, 177, 641, 640,
- 58, 469, 337, 141, 635, 634, 173, 350, 187, 249,
- 248, 59, 310, 478, 459, 58, 455, 64, 523, 249,
- 248, 85, 85, 86, 86, 103, 59, 565, 511, 172,
- 511, 638, 637, 64, 87, 87, 141, 511, 517, 577,
- 511, 0, 141, 0, 104, 141, 105, 85, 173, 86,
- 174, 172, 566, 564, 470, 468, 562, 561, 548, 511,
- 87, 636, 65, 530, 513, 539, 141, 85, 66, 86,
- 173, 0, 406, 0, 513, 512, 513, 64, 65, 0,
- 87, 172, 0, 513, 66, 512, 513, 512, 172, 235,
- 234, 0, 518, 516, 512, 521, 520, 512, 554, 553,
- 173, 85, 406, 86, 0, 513, -89, 173, 34, 174,
- 73, 74, 549, 547, 87, 631, 512, 531, 529, 438,
- 437, 172, 65, 0, 578, 274, 275, 0, 66, 632,
- 630, 34, 0, 73, 74, 274, 275, 75, 76, -89,
- 173, 0, 174, 34, 0, 48, 50, 49, 0, 0,
- 0, 0, 276, 277, 34, 0, 0, 0, 34, 629,
- 75, 76, 276, 277, 279, 280, 34, 0, 48, 50,
- 49, 45, 34, 281, 279, 280, 282, 85, 283, 86,
- 48, 50, 49, 281, 0, 34, 282, 0, 283, 34,
- 87, 48, 50, 49, 45, 48, 50, 49, 0, 0,
- 34, 0, 0, 48, 50, 49, 45, 34, 0, 48,
- 50, 49, 34, 0, 0, 0, 0, 45, 34, 0,
- 0, 45, 48, 50, 49, 0, 48, 50, 49, 45,
- 0, 0, 0, 0, 34, 45, 0, 48, 50, 49,
- 34, 0, 0, 0, 48, 50, 49, 34, 45, 48,
- 50, 49, 45, 279, 280, 48, 50, 49, 0, 0,
- 0, 34, 281, 45, 0, 282, 0, 283, -343, 34,
- 45, 48, 50, 49, 0, 45, -343, 48, 50, 49,
- 0, 45, 78, 79, 48, 50, 49, 0, 0, 0,
- 80, 81, 0, 0, 82, 0, 83, 45, 48, 50,
- 49, 0, 0, 45, 78, 79, 48, 50, 49, 34,
- 45, 0, 80, 81, 78, 79, 82, 34, 83, 0,
- 0, 0, 80, 81, 45, 34, 82, 0, 83, 0,
- 0, 34, 45, 0, 6, 5, 4, 1, 3, 2,
- 0, 240, 239, 0, 34, 0, 48, 50, 49, 245,
- 244, 0, 0, 34, 48, 50, 49, 245, 244, 0,
- 0, 0, 48, 50, 49, 0, 0, 0, 48, 50,
- 49, 0, 45, 0, 0, 0, 245, 244, 0, 0,
- 45, 48, 50, 49, 0, 240, 239, 34, 45, 0,
- 48, 50, 49, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 78, 79, 0, 0, 45, 151, 0,
- 0, 80, 81, 0, 0, 82, 45, 83, 152, 240,
- 239, 0, 153, 0, 48, 50, 49, 0, 0, 0,
- 0, 154, 0, 155, 0, 0, 308, 0, 0, 0,
- 0, 0, 0, 0, 156, 0, 157, 62, 0, 0,
- 45, 0, 0, 0, 158, 0, 0, 159, 63, 0,
- 0, 0, 0, 160, 0, 0, 0, 0, 0, 161,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
- 31, 151, 0, 0, 0, 162, 0, 0, 0, 33,
- 0, 152, 0, 0, 0, 153, 34, 0, 0, 0,
- 35, 36, 0, 37, 154, 0, 155, 0, 0, 0,
- 502, 0, 0, 0, 44, 0, 0, 156, 0, 157,
- 62, 0, 0, 0, 0, 0, 0, 158, 0, 0,
- 159, 63, 51, 48, 50, 49, 160, 52, 0, 0,
- 0, 0, 161, 0, 0, 0, 0, 0, 43, 54,
- 32, 30, 31, 0, 40, 0, 0, 0, 162, 45,
- 0, 33, 0, 0, 0, 0, 0, 0, 34, 0,
- 0, 0, 35, 36, 0, 37, 0, 0, 0, 30,
- 31, 0, 41, 0, 0, 0, 44, 0, 0, 33,
- 0, 0, 0, 0, 0, 0, 34, 0, 0, 0,
- 35, 36, 0, 37, 51, 48, 50, 49, 0, 52,
- 502, 0, 0, 0, 44, 0, 0, 0, 0, 0,
- 43, 54, 32, 0, 0, 0, 40, 0, 0, 0,
- 0, 45, 51, 48, 50, 49, 0, 52, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 43, 54,
- 32, 0, 0, 0, 40, 0, 0, 0, 0, 45,
- 30, 31, 0, 0, 0, 0, 0, 0, 30, 31,
- 33, 0, 0, 0, 0, 0, 0, 34, 33, 0,
- 0, 35, 36, 0, 37, 34, 0, 0, 0, 35,
- 36, 502, 37, 0, 0, 44, 0, 0, 0, 41,
- 0, 0, 0, 44, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
- 0, 51, 48, 50, 49, 0, 52, 0, 0, 43,
- 54, 32, 0, 0, 0, 40, 0, 43, 54, 32,
- 45, 0, 0, 40, 0, 0, 0, 0, 45, 30,
- 31, 0, 0, 0, 0, 0, 0, 30, 31, 33,
- 0, 0, 0, 0, 0, 0, 34, 33, 0, 0,
- 35, 36, 0, 37, 34, 0, 0, 0, 35, 36,
- 41, 37, 0, 0, 44, 0, 0, 0, 502, 0,
- 0, 0, 44, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 51, 48, 50, 49, 0, 52, 0, 0,
- 51, 48, 50, 49, 0, 52, 0, 0, 43, 54,
- 32, 0, 0, 0, 40, 0, 43, 54, 32, 45,
- 0, 0, 40, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 501, 0, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 215, 0,
- 0, 0, 0, 0, 0, 34, 0, 0, 0, 35,
- 36, 0, 37, 0, 0, 0, 0, 0, 0, 502,
- 0, 0, 0, 44, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 51, 503, 505, 504, 0, 52, 0, 0, 0,
- 0, 226, 0, 0, 0, 0, 0, 43, 54, 32,
- 210, 0, 0, 40, 0, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 0, 501, 0, 30,
- 31, 0, 0, 0, 0, 0, 0, 0, 0, 215,
- 0, 0, 0, 0, 0, 0, 34, 0, 0, 0,
- 35, 36, 0, 37, 0, 0, 0, 0, 0, 0,
- 502, 0, 0, 0, 44, 0, 0, 0, 0, 0,
- 0, 0, 544, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 51, 503, 505, 504, 0, 52, 0, 0,
- 0, 0, 226, 0, 0, 0, 0, 0, 43, 54,
- 32, 210, 0, 0, 40, 0, 0, 0, 0, 45,
- 0, 0, 0, 0, 0, 0, 0, 0, 501, 0,
+ 457, 340, 343, 440, 342, -126, -110, 453, 391, 257,
+ -121, 352, 403, 389, -129, 346, 345, 416, 348, -99,
+ 616, -118, 401, -100, 446, 399, 448, 440, 571, 440,
+ 541, -110, -129, 561, 568, 333, 466, 559, 556, 527,
+ 510, 529, 541, 346, 534, 424, 541, 257, 440, -126,
+ 408, 424, -121, 420, 541, -118, -100, 444, 457, 453,
+ 424, -99, 304, 348, 431, -123, 251, 416, 325, 141,
+ 457, 101, 414, 164, 440, 453, 147, 71, 296, 416,
+ 99, 312, 272, 430, 294, 272, 252, 164, 141, 306,
+ 170, 335, 292, 640, 301, 257, 190, 187, 149, 346,
+ 183, 312, 236, 348, 318, 71, 141, 0, 0, 172,
+ 427, 141, 0, 179, 294, 141, 141, 331, 141, 314,
+ 99, 292, 189, 315, 141, 434, 141, 477, 173, 62,
+ 538, 141, 443, 538, 0, 249, 248, 141, 573, 572,
+ 63, 141, 616, 256, 255, 101, 444, 242, 241, 249,
+ 248, 247, 246, 172, 58, 428, 413, 412, 455, 409,
+ 58, 327, 141, 254, 177, 59, 142, 418, 58, 141,
+ 532, 59, 173, 249, 248, 478, 459, 58, 611, 59,
+ 166, 539, 172, 488, 167, 636, 635, 525, 59, 337,
+ 64, 64, 103, 310, 469, 630, 629, 85, 0, 86,
+ 64, 173, 0, 174, 633, 632, 85, 0, 86, 511,
+ 87, 104, 511, 105, 328, 235, 234, 575, 85, 87,
+ 86, 550, 438, 437, 533, 531, 85, 85, 86, 86,
+ 0, 87, 511, 513, 631, 65, 65, 517, 172, 87,
+ 87, 66, 66, 541, 512, 65, 0, 470, 468, 172,
+ 85, 66, 86, 141, 85, 513, 86, 173, 513, 406,
+ 85, 511, 86, 87, 0, 511, 512, 87, 173, 512,
+ 406, 0, 0, 87, 563, 551, 549, 172, 513, 0,
+ 0, 73, 74, 0, 0, 274, 275, 0, 0, 512,
+ 0, 518, 516, 274, 275, -87, 173, 34, 174, 564,
+ 562, 626, 576, 73, 74, 350, 172, 513, 75, 76,
+ 0, 513, 276, 277, 0, 627, 625, 34, 512, 0,
+ 276, 277, 512, 0, -87, 173, 34, 174, 279, 280,
+ 75, 76, 34, 0, 48, 50, 49, 281, 34, 0,
+ 282, 0, 283, 0, 34, 624, 85, 34, 86, 0,
+ 0, 0, 0, 0, 48, 50, 49, 0, 0, 87,
+ 45, 0, 0, 48, 50, 49, 0, 0, 0, 48,
+ 50, 49, 0, 0, 0, 48, 50, 49, 279, 280,
+ 45, 48, 50, 49, 48, 50, 49, 281, 0, 45,
+ 282, 0, 283, 0, 0, 45, 0, 279, 280, 0,
+ 0, 45, 0, 279, 280, 0, 281, 45, 0, 282,
+ 45, 283, 281, 34, 0, 282, 0, 283, 78, 79,
+ -341, 0, 34, 0, 0, 0, 80, 81, 78, 79,
+ 82, 0, 83, 0, 0, 0, 80, 81, 0, 0,
+ 82, 0, 83, 6, 5, 4, 1, 3, 2, 0,
+ 48, 50, 49, 0, 78, 79, 0, 0, 0, 48,
+ 50, 49, 80, 81, 0, 0, 82, 0, 83, 78,
+ 79, 0, 34, 0, 0, 0, 45, 80, 81, 78,
+ 79, 82, 34, 83, 0, 45, 0, 80, 81, -341,
+ 34, 82, 0, 83, 279, 280, 0, 0, 0, 34,
+ 0, 0, 0, 281, 240, 239, 282, 0, 283, 48,
+ 50, 49, 0, 0, 0, 0, 0, 34, 0, 48,
+ 50, 49, 240, 239, 0, 0, 34, 48, 50, 49,
+ 0, 245, 244, 0, 0, 45, 48, 50, 49, 0,
+ 0, 0, 0, 0, 0, 45, 0, 0, 0, 245,
+ 244, 0, 0, 45, 48, 50, 49, 0, 245, 244,
+ 0, 0, 45, 48, 50, 49, 0, 0, 0, 0,
+ 0, 0, 34, 0, 0, 0, 0, 0, 151, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 152, 45,
+ 0, 0, 153, 0, 0, 0, 0, 0, 0, 0,
+ 0, 154, 0, 155, 240, 239, 308, 0, 0, 48,
+ 50, 49, 0, 0, 156, 0, 157, 62, 0, 0,
+ 0, 0, 0, 0, 158, 0, 0, 159, 63, 0,
+ 0, 0, 0, 160, 0, 45, 0, 0, 0, 161,
+ 0, 0, 30, 31, 151, 0, 0, 0, 0, 0,
+ 0, 0, 33, 0, 152, 162, 0, 0, 153, 34,
+ 0, 0, 0, 35, 36, 0, 37, 154, 0, 155,
+ 0, 0, 0, 41, 0, 0, 0, 44, 0, 0,
+ 156, 0, 157, 62, 0, 0, 0, 0, 0, 0,
+ 158, 0, 0, 159, 63, 51, 48, 50, 49, 160,
+ 52, 0, 0, 0, 0, 161, 0, 0, 0, 0,
+ 0, 43, 54, 32, 30, 31, 0, 40, 0, 0,
+ 0, 162, 45, 0, 33, 0, 0, 0, 0, 0,
+ 0, 34, 0, 0, 0, 35, 36, 0, 37, 0,
+ 0, 0, 30, 31, 0, 41, 0, 0, 0, 44,
+ 0, 0, 33, 0, 0, 0, 0, 0, 0, 34,
+ 0, 0, 0, 35, 36, 0, 37, 51, 48, 50,
+ 49, 0, 52, 502, 0, 0, 0, 44, 0, 0,
+ 0, 0, 0, 43, 54, 32, 0, 0, 0, 40,
+ 0, 0, 0, 0, 45, 51, 48, 50, 49, 0,
+ 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 43, 54, 32, 0, 0, 0, 40, 0, 0,
+ 0, 0, 45, 30, 31, 0, 0, 0, 0, 0,
+ 0, 30, 31, 33, 0, 0, 0, 0, 0, 0,
+ 34, 33, 0, 0, 35, 36, 0, 37, 34, 0,
+ 0, 0, 35, 36, 41, 37, 0, 0, 44, 0,
+ 0, 0, 502, 0, 0, 0, 44, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
+ 0, 52, 0, 0, 51, 48, 50, 49, 0, 52,
+ 0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
+ 43, 54, 32, 45, 0, 0, 40, 0, 0, 0,
+ 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 215, 0, 0, 0, 0, 0, 0, 34, 0, 0,
+ 33, 0, 0, 0, 0, 0, 0, 34, 0, 0,
0, 35, 36, 0, 37, 0, 0, 0, 0, 0,
0, 502, 0, 0, 0, 44, 0, 0, 0, 0,
- 0, 0, 0, 541, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 51, 503, 505, 504, 0, 52, 0,
- 0, 0, 0, 226, 0, 0, 0, 0, 0, 43,
- 54, 32, 210, 0, 0, 40, 0, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, 29,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 34, 0, 0,
- 0, 35, 36, 0, 37, 0, 0, 0, 38, 0,
- 39, 41, 42, 0, 0, 44, 0, 0, 0, 46,
- 0, 47, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
- 53, 0, 55, 0, 56, 0, 0, 0, 0, 43,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 43,
54, 32, 0, 0, 0, 40, 0, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 0, -121,
- 0, 0, 0, 29, 30, 31, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
- 0, 34, 0, 0, 0, 35, 36, 0, 37, 0,
- 0, 0, 38, 0, 39, 41, 42, 0, 0, 44,
- 0, 0, 0, 46, 0, 47, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 51, 48, 50,
- 49, 0, 52, 0, 53, 0, 55, 0, 56, 0,
- 0, 0, 0, 43, 54, 32, 0, 0, 0, 40,
- 0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 29, 30, 31, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
- 0, 34, 0, 0, 0, 35, 36, 0, 37, 0,
- 0, 0, 38, 0, 39, 41, 42, 0, 0, 44,
- 0, 0, 0, 46, 0, 47, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 51, 48, 50,
- 49, 0, 52, 0, 53, 0, 55, 271, 56, 0,
- 0, 0, 0, 43, 54, 32, 0, 0, 0, 40,
- 0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 483, 0, 0, 29, 30, 31, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 501,
+ 0, 30, 31, 0, 0, 0, 0, 0, 0, 0,
+ 0, 215, 0, 0, 0, 0, 0, 0, 34, 0,
+ 0, 0, 35, 36, 0, 37, 0, 0, 0, 0,
+ 0, 0, 502, 0, 0, 0, 44, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 51, 503, 505, 504, 0, 52,
+ 0, 0, 0, 0, 226, 0, 0, 0, 0, 0,
+ 43, 54, 32, 210, 0, 0, 40, 0, 0, 0,
+ 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
+ 501, 0, 30, 31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 215, 0, 0, 0, 0, 0, 0, 34,
+ 0, 0, 0, 35, 36, 0, 37, 0, 0, 0,
+ 0, 0, 0, 502, 0, 0, 0, 44, 0, 0,
+ 0, 0, 0, 0, 0, 543, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 51, 503, 505, 504, 0,
+ 52, 0, 0, 0, 0, 226, 0, 0, 0, 0,
+ 0, 43, 54, 32, 210, 0, 0, 40, 0, 0,
+ 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
+ 0, 501, 0, 30, 31, 0, 0, 0, 0, 0,
+ 0, 0, 0, 215, 0, 0, 0, 0, 0, 0,
+ 34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
+ 0, 0, 0, 0, 502, 0, 0, 0, 44, 0,
+ 0, 0, 0, 0, 0, 0, 546, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 51, 503, 505, 504,
+ 0, 52, 0, 0, 0, 0, 226, 0, 0, 0,
+ 0, 0, 43, 54, 32, 210, 0, 0, 40, 0,
+ 0, 0, 0, 45, 0, 0, 0, 0, 0, 0,
+ 0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
+ 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+ 34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
+ 0, 38, 0, 39, 41, 42, 0, 0, 44, 0,
+ 0, 0, 46, 0, 47, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
+ 0, 52, 0, 53, 0, 55, 0, 56, 0, 0,
+ 0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
+ 0, 0, 0, 45, 0, 0, 0, 0, 0, 0,
+ 0, 0, -119, 0, 0, 0, 29, 30, 31, 0,
0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
0, 0, 0, 0, 34, 0, 0, 0, 35, 36,
0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
- 0, 486, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51, 48, 50, 49, 0, 52, 0, 53, 0, 55,
0, 56, 0, 0, 0, 0, 43, 54, 32, 0,
0, 0, 40, 0, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 0, 475, 0, 0, 29,
+ 0, 0, 0, 0, 0, 0, 29, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
+ 0, 0, 0, 0, 34, 0, 0, 0, 35, 36,
+ 0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
+ 0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 51, 48, 50, 49, 0, 52, 0, 53, 0, 55,
+ 271, 56, 0, 0, 0, 0, 43, 54, 32, 0,
+ 0, 0, 40, 0, 0, 0, 0, 45, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
+ 0, 0, 0, 0, 34, 217, 0, 0, 218, 36,
+ 0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
+ 0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
+ 0, 0, 0, 0, 0, 0, 221, 0, 0, 0,
+ 51, 48, 50, 49, 0, 52, 0, 53, 0, 55,
+ 0, 56, 0, 0, 0, 0, 43, 54, 32, 0,
+ 0, 0, 40, 0, 0, 0, 0, 45, 0, 0,
+ 0, 0, 0, 0, 0, 0, 483, 0, 0, 29,
30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
33, 0, 0, 0, 0, 0, 0, 34, 0, 0,
0, 35, 36, 0, 37, 0, 0, 0, 38, 0,
39, 41, 42, 0, 0, 44, 0, 0, 0, 46,
- 0, 47, 0, 0, 481, 0, 0, 0, 0, 0,
+ 0, 47, 0, 0, 486, 0, 0, 0, 0, 0,
+ 0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
+ 53, 0, 55, 0, 56, 0, 0, 0, 0, 43,
+ 54, 32, 0, 0, 0, 40, 0, 0, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 0, 29,
+ 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 0, 0, 34, 217, 0,
+ 0, 578, 579, 0, 37, 0, 0, 0, 38, 0,
+ 39, 41, 42, 0, 0, 44, 0, 0, 0, 46,
+ 0, 47, 0, 0, 0, 0, 0, 0, 0, 221,
0, 0, 0, 51, 48, 50, 49, 0, 52, 0,
53, 0, 55, 0, 56, 0, 0, 0, 0, 43,
54, 32, 0, 0, 0, 40, 0, 0, 0, 0,
@@ -525,7 +532,7 @@ const short QDeclarativeJSGrammar::action_info [] = {
0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
34, 0, 0, 0, 35, 36, 0, 37, 0, 0,
0, 38, 0, 39, 41, 42, 0, 0, 44, 0,
- 0, 0, 46, 0, 47, 0, 0, 476, 0, 0,
+ 0, 0, 46, 0, 47, 0, 0, 481, 0, 0,
0, 0, 0, 0, 0, 0, 51, 48, 50, 49,
0, 52, 0, 53, 0, 55, 0, 56, 0, 0,
0, 0, 43, 54, 32, 0, 0, 0, 40, 0,
@@ -539,44 +546,54 @@ const short QDeclarativeJSGrammar::action_info [] = {
48, 50, 49, 0, 52, 0, 53, 0, 55, 0,
56, 0, 0, 0, 0, 43, 54, 32, 0, 0,
0, 40, 0, 0, 0, 0, 45, 0, 0, 0,
- 0, 0, 0, 0, 0, 29, 30, 31, 0, 0,
- 0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
- 0, 0, 0, 34, 217, 0, 0, 584, 585, 0,
- 37, 0, 0, 0, 38, 0, 39, 41, 42, 0,
- 0, 44, 0, 0, 0, 46, 0, 47, 0, 0,
- 0, 0, 0, 0, 0, 221, 0, 0, 0, 51,
- 48, 50, 49, 0, 52, 0, 53, 0, 55, 0,
- 56, 0, 0, 0, 0, 43, 54, 32, 0, 0,
- 0, 40, 0, 0, 0, 0, 45, 0, 0, 0,
+ 0, 0, 0, 0, 0, 475, 0, 0, 29, 30,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 0, 0, 0, 0, 34, 0, 0, 0,
+ 35, 36, 0, 37, 0, 0, 0, 38, 0, 39,
+ 41, 42, 0, 0, 44, 0, 0, 0, 46, 0,
+ 47, 0, 0, 476, 0, 0, 0, 0, 0, 0,
+ 0, 0, 51, 48, 50, 49, 0, 52, 0, 53,
+ 0, 55, 0, 56, 0, 0, 0, 0, 43, 54,
+ 32, 0, 0, 0, 40, 0, 0, 0, 0, 45,
+ 0, 0, 0, 0, 0, 0, 0, 0, 109, 110,
+ 111, 0, 0, 113, 115, 116, 0, 0, 117, 0,
+ 118, 0, 0, 0, 120, 121, 122, 0, 0, 0,
+ 0, 0, 0, 34, 123, 124, 125, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 126, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 129, 0, 0, 0, 0, 0, 0,
+ 48, 50, 49, 130, 131, 132, 0, 134, 135, 136,
+ 137, 138, 139, 0, 0, 127, 133, 119, 112, 114,
+ 128, 0, 0, 0, 0, 0, 45, 0, 0, 0,
0, 0, 0, 0, 0, 109, 110, 111, 0, 0,
113, 115, 116, 0, 0, 117, 0, 118, 0, 0,
0, 120, 121, 122, 0, 0, 0, 0, 0, 0,
- 34, 123, 124, 125, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 126, 0, 0, 0, 0, 0,
+ 393, 123, 124, 125, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 126, 0, 0, 0, 394, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 129, 0, 0, 0, 0, 0, 0, 48, 50, 49,
+ 129, 0, 0, 0, 0, 0, 398, 395, 397, 0,
130, 131, 132, 0, 134, 135, 136, 137, 138, 139,
0, 0, 127, 133, 119, 112, 114, 128, 0, 0,
- 0, 0, 0, 45, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 109, 110, 111, 0, 0, 113, 115, 116,
0, 0, 117, 0, 118, 0, 0, 0, 120, 121,
122, 0, 0, 0, 0, 0, 0, 393, 123, 124,
125, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 126, 0, 0, 0, 394, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 129, 0, 0,
+ 0, 0, 0, 396, 0, 0, 0, 129, 0, 0,
0, 0, 0, 398, 395, 397, 0, 130, 131, 132,
0, 134, 135, 136, 137, 138, 139, 0, 0, 127,
133, 119, 112, 114, 128, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 109,
- 110, 111, 0, 0, 113, 115, 116, 0, 0, 117,
- 0, 118, 0, 0, 0, 120, 121, 122, 0, 0,
- 0, 0, 0, 0, 393, 123, 124, 125, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 126, 0,
- 0, 0, 394, 0, 0, 0, 0, 0, 0, 0,
- 396, 0, 0, 0, 129, 0, 0, 0, 0, 0,
- 398, 395, 397, 0, 130, 131, 132, 0, 134, 135,
- 136, 137, 138, 139, 0, 0, 127, 133, 119, 112,
- 114, 128, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 209,
+ 0, 0, 0, 0, 211, 0, 29, 30, 31, 213,
+ 0, 0, 0, 0, 0, 0, 214, 33, 0, 0,
+ 0, 0, 0, 0, 216, 217, 0, 0, 218, 36,
+ 0, 37, 0, 0, 0, 38, 0, 39, 41, 42,
+ 0, 0, 44, 0, 0, 0, 46, 0, 47, 0,
+ 0, 0, 0, 0, 220, 0, 221, 0, 0, 0,
+ 51, 219, 222, 49, 223, 52, 224, 53, 225, 55,
+ 226, 56, 227, 228, 0, 0, 43, 54, 32, 210,
+ 212, 0, 40, 0, 0, 0, 0, 45, 0, 0,
0, 0, 0, 0, 0, 0, 209, 0, 0, 0,
0, 211, 0, 29, 30, 31, 213, 0, 0, 0,
0, 0, 0, 214, 215, 0, 0, 0, 0, 0,
@@ -587,248 +604,238 @@ const short QDeclarativeJSGrammar::action_info [] = {
49, 223, 52, 224, 53, 225, 55, 226, 56, 227,
228, 0, 0, 43, 54, 32, 210, 212, 0, 40,
0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 209, 0, 0, 0, 0, 211, 0,
- 29, 30, 31, 213, 0, 0, 0, 0, 0, 0,
- 214, 33, 0, 0, 0, 0, 0, 0, 216, 217,
- 0, 0, 218, 36, 0, 37, 0, 0, 0, 38,
- 0, 39, 41, 42, 0, 0, 44, 0, 0, 0,
- 46, 0, 47, 0, 0, 0, 0, 0, 220, 0,
- 221, 0, 0, 0, 51, 219, 222, 49, 223, 52,
- 224, 53, 225, 55, 226, 56, 227, 228, 0, 0,
- 43, 54, 32, 210, 212, 0, 40, 0, 0, 0,
+ 0, 0, 0, 582, 110, 111, 0, 0, 584, 115,
+ 586, 30, 31, 587, 0, 118, 0, 0, 0, 120,
+ 589, 590, 0, 0, 0, 0, 0, 0, 591, 592,
+ 124, 125, 218, 36, 0, 37, 0, 0, 0, 38,
+ 0, 39, 593, 42, 0, 0, 595, 0, 0, 0,
+ 46, 0, 47, 0, 0, 0, 0, 0, 597, 0,
+ 221, 0, 0, 0, 599, 596, 598, 49, 600, 601,
+ 602, 53, 604, 605, 606, 607, 608, 609, 0, 0,
+ 594, 603, 588, 583, 585, 128, 40, 0, 0, 0,
0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
- 587, 110, 111, 0, 0, 589, 115, 591, 30, 31,
- 592, 0, 118, 0, 0, 0, 120, 594, 595, 0,
- 0, 0, 0, 0, 0, 596, 597, 124, 125, 218,
- 36, 0, 37, 0, 0, 0, 38, 0, 39, 598,
- 42, 0, 0, 600, 0, 0, 0, 46, 0, 47,
- 0, 0, 0, 0, 0, 602, 0, 221, 0, 0,
- 0, 604, 601, 603, 49, 605, 606, 607, 53, 609,
- 610, 611, 612, 613, 614, 0, 0, 599, 608, 593,
- 588, 590, 128, 40, 0, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 0, 361, 110, 111,
- 0, 0, 363, 115, 365, 30, 31, 366, 0, 118,
- 0, 0, 0, 120, 368, 369, 0, 0, 0, 0,
- 0, 0, 370, 371, 124, 125, 218, 36, 0, 37,
- 0, 0, 0, 38, 0, 39, 372, 42, 0, 0,
- 374, 0, 0, 0, 46, 0, 47, 0, -267, 0,
- 0, 0, 376, 0, 221, 0, 0, 0, 378, 375,
- 377, 49, 379, 380, 381, 53, 383, 384, 385, 386,
- 387, 388, 0, 0, 373, 382, 367, 362, 364, 128,
- 40, 0, 0, 0, 0, 45, 0, 0, 0, 0,
- 0, 0, 0, 0,
+ 361, 110, 111, 0, 0, 363, 115, 365, 30, 31,
+ 366, 0, 118, 0, 0, 0, 120, 368, 369, 0,
+ 0, 0, 0, 0, 0, 370, 371, 124, 125, 218,
+ 36, 0, 37, 0, 0, 0, 38, 0, 39, 372,
+ 42, 0, 0, 374, 0, 0, 0, 46, 0, 47,
+ 0, -265, 0, 0, 0, 376, 0, 221, 0, 0,
+ 0, 378, 375, 377, 49, 379, 380, 381, 53, 383,
+ 384, 385, 386, 387, 388, 0, 0, 373, 382, 367,
+ 362, 364, 128, 40, 0, 0, 0, 0, 45, 0,
+ 0, 0, 0, 0, 0, 0, 0,
- 472, 546, 528, 639, 311, 182, 302, 498, 514, 16,
- 461, 515, 496, 182, 497, 519, 309, 436, 619, 243,
- 358, 439, 576, 572, 253, 150, 571, 487, 617, 307,
- 238, 250, 320, 628, 633, 555, 569, 560, 558, 642,
- 186, 250, 425, 349, 358, 182, 351, 557, 433, 347,
- 238, 344, 339, 429, 302, 402, 243, 445, 447, 456,
- 460, 163, 454, 458, 243, 250, 485, 143, 148, 449,
- 353, 526, 176, 467, 237, 450, 238, 415, 338, 188,
- 410, 237, 302, 336, 436, 482, 334, 169, 439, 436,
- 146, 417, 392, 439, 140, 522, 358, 400, 404, 0,
- 390, 171, 358, 0, 186, 500, 146, 0, 643, 0,
- 0, 178, 0, 0, 0, 0, 404, 60, 60, 489,
- 452, 500, 320, 0, 534, 0, 405, 60, 0, 180,
- 146, 60, 0, 180, 60, 407, 490, 60, 302, 452,
- 60, 60, 60, 60, 405, 60, 284, 285, 287, 60,
- 286, 451, 358, 60, 165, 180, 266, 60, 60, 461,
- 451, 270, 288, 60, 60, 60, 493, 60, 60, 60,
- 84, 106, 92, 91, 60, 432, 60, 72, 60, 168,
- 98, 435, 77, 60, 96, 60, 60, 60, 341, 302,
- 93, 94, 500, 108, 329, 100, 60, 102, 60, 618,
- 302, 95, 88, 330, 60, 60, 60, 60, 90, 89,
- 70, 60, 97, 452, 60, 60, 451, 492, 60, 60,
- 494, 60, 61, 68, 60, 60, 69, 491, 60, 471,
- 67, 302, 404, 480, 60, 106, 60, 479, 0, 270,
- 298, 270, 298, 278, 298, 270, 0, 270, 60, 270,
- 0, 316, 0, 270, 332, 0, 500, 108, 175, 538,
- 405, 293, 319, 0, 317, 303, 326, 60, 60, 60,
- 0, 0, 270, 270, 270, 290, 291, 60, 295, 298,
- 60, 60, 270, 298, 270, 270, 270, 289, 270, 0,
- 273, 500, 313, 0, 551, 545, 305, 534, 508, 615,
- 542, 297, 0, 500, 0, 300, 499, 509, 500, 0,
- 508, 0, 0, 0, 0, 508, 472, 0, 499, 509,
- 583, 0, 0, 499, 509, 0, 0, 586, 579, 580,
- 581, 582, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 550,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 551,
- 0, 0, 0, 0, 0, 0, 552, 0, 0, 0,
+ 567, 169, 558, 570, 574, 515, 569, 557, 309, 548,
+ 461, 528, 311, 530, 417, 555, 307, 188, 415, 358,
+ 392, 250, 628, 612, 320, 623, 150, 253, 16, 637,
+ 496, 497, 498, 390, 614, 186, 634, 472, 182, 400,
+ 487, 243, 436, 238, 436, 176, 182, 302, 514, 171,
+ 238, 439, 334, 429, 439, 447, 454, 336, 339, 358,
+ 243, 140, 433, 302, 338, 237, 349, 351, 449, 482,
+ 146, 182, 148, 460, 485, 458, 353, 250, 250, 243,
+ 344, 410, 238, 163, 467, 456, 524, 143, 436, 425,
+ 237, 439, 445, 302, 402, 358, 461, 404, 0, 450,
+ 60, 358, 404, 186, 146, 92, 0, 0, 0, 407,
+ 500, 60, 0, 638, 500, 60, 84, 536, 320, 500,
+ 0, 98, 540, 60, 302, 60, 405, 490, 91, 302,
+ 0, 405, 60, 0, 180, 302, 60, 106, 489, 60,
+ 60, 60, 180, 60, 93, 60, 286, 60, 285, 60,
+ 94, 146, 284, 90, 60, 60, 178, 452, 89, 60,
+ 108, 60, 358, 60, 95, 60, 287, 471, 288, 88,
+ 60, 302, 451, 60, 60, 60, 452, 451, 60, 404,
+ 68, 432, 60, 102, 494, 60, 347, 67, 341, 60,
+ 330, 329, 61, 266, 60, 305, 69, 60, 270, 60,
+ 70, 303, 60, 60, 60, 480, 451, 0, 405, 479,
+ 72, 0, 60, 165, 491, 60, 60, 60, 180, 168,
+ 60, 97, 492, 60, 60, 452, 60, 60, 493, 100,
+ 96, 60, 0, 77, 60, 0, 270, 332, 298, 270,
+ 273, 60, 435, 270, 60, 298, 270, 298, 278, 270,
+ 270, 316, 270, 60, 298, 295, 298, 60, 270, 270,
+ 297, 270, 270, 106, 291, 60, 60, 326, 313, 317,
+ 270, 270, 290, 289, 552, 60, 319, 536, 300, 610,
+ 270, 519, 520, 521, 522, 500, 108, 175, 293, 0,
+ 0, 500, 508, 0, 0, 544, 0, 472, 613, 547,
+ 0, 499, 509, 500, 0, 0, 0, 500, 0, 0,
+ 508, 0, 0, 0, 508, 0, 0, 0, 577, 499,
+ 509, 0, 0, 499, 509, 580, 581, 519, 520, 521,
+ 522, 552, 0, 0, 0, 0, 0, 0, 553, 554,
+ 519, 520, 521, 522, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 560, 519, 520, 521, 522,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0};
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0};
const short QDeclarativeJSGrammar::action_check [] = {
- 7, 16, 55, 7, 33, 36, 33, 55, 36, 7,
- 7, 7, 7, 7, 7, 36, 7, 7, 36, 8,
- 36, 55, 60, 29, 7, 7, 36, 7, 33, 7,
- 7, 7, 7, 36, 36, 48, 1, 0, 90, 79,
- 7, 33, 8, 90, 2, 7, 33, 55, 36, 60,
- 36, 20, 33, 5, 1, 5, 79, 36, 7, 33,
- 5, 60, 33, 33, 8, 33, 17, 24, 2, 7,
- 34, 2, 7, 1, 7, 36, 60, 37, 8, 8,
- 36, 66, 36, 7, 1, 17, -1, -1, 36, 48,
- 36, 33, 8, 66, 7, 48, 36, 33, 7, 36,
- 2, 7, 8, 8, 8, 77, 61, 15, 8, 8,
- 6, -1, 31, 36, 8, 10, -1, -1, -1, 60,
- 8, 60, -1, 48, 20, -1, 34, -1, 8, 8,
- 8, -1, -1, 60, 60, 8, 79, 55, 60, 50,
- 8, 61, 8, 54, 8, 8, 61, 61, 62, 61,
- 62, 42, 56, 50, 40, 60, 56, 54, 79, 40,
- 55, 60, 53, 61, 62, 51, 60, 15, 61, 62,
- 51, 61, 62, 61, 61, 62, 56, 56, 61, 62,
- 40, 8, 60, 8, 61, 62, 34, 60, 8, 61,
- 62, 51, 60, 56, 60, 40, 60, 12, 29, 61,
- 62, 25, 25, 27, 27, 15, 51, 36, 29, 15,
- 29, 61, 62, 12, 38, 38, 8, 29, 7, 7,
- 29, -1, 8, -1, 34, 8, 36, 25, 34, 27,
- 36, 15, 61, 62, 61, 62, 61, 62, 7, 29,
- 38, 91, 57, 7, 75, 33, 8, 25, 63, 27,
- 34, -1, 36, -1, 75, 86, 75, 12, 57, -1,
- 38, 15, -1, 75, 63, 86, 75, 86, 15, 61,
- 62, -1, 61, 62, 86, 61, 62, 86, 61, 62,
- 34, 25, 36, 27, -1, 75, 33, 34, 29, 36,
- 18, 19, 61, 62, 38, 47, 86, 61, 62, 61,
- 62, 15, 57, -1, 92, 18, 19, -1, 63, 61,
- 62, 29, -1, 18, 19, 18, 19, 45, 46, 33,
- 34, -1, 36, 29, -1, 66, 67, 68, -1, -1,
- -1, -1, 45, 46, 29, -1, -1, -1, 29, 91,
- 45, 46, 45, 46, 23, 24, 29, -1, 66, 67,
- 68, 92, 29, 32, 23, 24, 35, 25, 37, 27,
- 66, 67, 68, 32, -1, 29, 35, -1, 37, 29,
- 38, 66, 67, 68, 92, 66, 67, 68, -1, -1,
- 29, -1, -1, 66, 67, 68, 92, 29, -1, 66,
- 67, 68, 29, -1, -1, -1, -1, 92, 29, -1,
- -1, 92, 66, 67, 68, -1, 66, 67, 68, 92,
- -1, -1, -1, -1, 29, 92, -1, 66, 67, 68,
- 29, -1, -1, -1, 66, 67, 68, 29, 92, 66,
- 67, 68, 92, 23, 24, 66, 67, 68, -1, -1,
- -1, 29, 32, 92, -1, 35, -1, 37, 36, 29,
- 92, 66, 67, 68, -1, 92, 36, 66, 67, 68,
- -1, 92, 23, 24, 66, 67, 68, -1, -1, -1,
- 31, 32, -1, -1, 35, -1, 37, 92, 66, 67,
- 68, -1, -1, 92, 23, 24, 66, 67, 68, 29,
- 92, -1, 31, 32, 23, 24, 35, 29, 37, -1,
- -1, -1, 31, 32, 92, 29, 35, -1, 37, -1,
- -1, 29, 92, -1, 93, 94, 95, 96, 97, 98,
- -1, 61, 62, -1, 29, -1, 66, 67, 68, 61,
- 62, -1, -1, 29, 66, 67, 68, 61, 62, -1,
- -1, -1, 66, 67, 68, -1, -1, -1, 66, 67,
- 68, -1, 92, -1, -1, -1, 61, 62, -1, -1,
- 92, 66, 67, 68, -1, 61, 62, 29, 92, -1,
- 66, 67, 68, -1, 92, -1, -1, -1, -1, -1,
- -1, -1, -1, 23, 24, -1, -1, 92, 3, -1,
- -1, 31, 32, -1, -1, 35, 92, 37, 13, 61,
- 62, -1, 17, -1, 66, 67, 68, -1, -1, -1,
- -1, 26, -1, 28, -1, -1, 31, -1, -1, -1,
- -1, -1, -1, -1, 39, -1, 41, 42, -1, -1,
- 92, -1, -1, -1, 49, -1, -1, 52, 53, -1,
- -1, -1, -1, 58, -1, -1, -1, -1, -1, 64,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 12,
- 13, 3, -1, -1, -1, 80, -1, -1, -1, 22,
- -1, 13, -1, -1, -1, 17, 29, -1, -1, -1,
- 33, 34, -1, 36, 26, -1, 28, -1, -1, -1,
- 43, -1, -1, -1, 47, -1, -1, 39, -1, 41,
- 42, -1, -1, -1, -1, -1, -1, 49, -1, -1,
- 52, 53, 65, 66, 67, 68, 58, 70, -1, -1,
- -1, -1, 64, -1, -1, -1, -1, -1, 81, 82,
- 83, 12, 13, -1, 87, -1, -1, -1, 80, 92,
- -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, 12,
- 13, -1, 43, -1, -1, -1, 47, -1, -1, 22,
- -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
- 33, 34, -1, 36, 65, 66, 67, 68, -1, 70,
- 43, -1, -1, -1, 47, -1, -1, -1, -1, -1,
- 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
- -1, 92, 65, 66, 67, 68, -1, 70, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 81, 82,
- 83, -1, -1, -1, 87, -1, -1, -1, -1, 92,
- 12, 13, -1, -1, -1, -1, -1, -1, 12, 13,
- 22, -1, -1, -1, -1, -1, -1, 29, 22, -1,
- -1, 33, 34, -1, 36, 29, -1, -1, -1, 33,
- 34, 43, 36, -1, -1, 47, -1, -1, -1, 43,
- -1, -1, -1, 47, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, -1, 81,
- 82, 83, -1, -1, -1, 87, -1, 81, 82, 83,
- 92, -1, -1, 87, -1, -1, -1, -1, 92, 12,
- 13, -1, -1, -1, -1, -1, -1, 12, 13, 22,
- -1, -1, -1, -1, -1, -1, 29, 22, -1, -1,
- 33, 34, -1, 36, 29, -1, -1, -1, 33, 34,
- 43, 36, -1, -1, 47, -1, -1, -1, 43, -1,
- -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 65, 66, 67, 68, -1, 70, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, -1, 81, 82,
- 83, -1, -1, -1, 87, -1, 81, 82, 83, 92,
- -1, -1, 87, -1, -1, -1, -1, 92, -1, -1,
- -1, -1, -1, -1, -1, -1, 10, -1, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, -1, -1, -1, 43,
- -1, -1, -1, 47, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, -1, -1,
- -1, 75, -1, -1, -1, -1, -1, 81, 82, 83,
- 84, -1, -1, 87, -1, -1, -1, -1, 92, -1,
- -1, -1, -1, -1, -1, -1, -1, 10, -1, 12,
- 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
- -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
- 33, 34, -1, 36, -1, -1, -1, -1, -1, -1,
- 43, -1, -1, -1, 47, -1, -1, -1, -1, -1,
- -1, -1, 55, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 65, 66, 67, 68, -1, 70, -1, -1,
- -1, -1, 75, -1, -1, -1, -1, -1, 81, 82,
- 83, 84, -1, -1, 87, -1, -1, -1, -1, 92,
- -1, -1, -1, -1, -1, -1, -1, -1, 10, -1,
+ 36, 36, 33, 33, 60, 7, 7, 36, 8, 36,
+ 7, 16, 55, 7, 7, 7, 55, 36, 36, 7,
+ 90, 7, 55, 7, 36, 7, 60, 33, 60, 33,
+ 33, 7, 7, 29, 8, 60, 17, 7, 66, 37,
+ 66, 24, 33, 7, 34, 5, 33, 36, 33, 7,
+ 60, 5, 7, 33, 33, 7, 7, 20, 36, 36,
+ 5, 7, 61, 36, 7, 7, 77, 36, 17, 8,
+ 36, 79, 7, 2, 33, 36, 8, 1, 8, 36,
+ 48, 2, 1, 55, 79, 1, 36, 2, 8, 60,
+ 7, 31, 48, 0, 61, 36, 33, 8, 60, 7,
+ 36, 2, 55, 36, 7, 1, 8, -1, -1, 15,
+ 10, 8, -1, 60, 79, 8, 8, 61, 8, 50,
+ 48, 48, 60, 54, 8, 7, 8, 8, 34, 42,
+ 8, 8, 6, 8, -1, 61, 62, 8, 61, 62,
+ 53, 8, 90, 61, 62, 79, 20, 61, 62, 61,
+ 62, 61, 62, 15, 40, 55, 61, 62, 60, 7,
+ 40, 8, 8, 60, 56, 51, 56, 60, 40, 8,
+ 7, 51, 34, 61, 62, 56, 60, 40, 56, 51,
+ 50, 56, 15, 60, 54, 61, 62, 29, 51, 60,
+ 12, 12, 15, 60, 8, 61, 62, 25, -1, 27,
+ 12, 34, -1, 36, 61, 62, 25, -1, 27, 29,
+ 38, 34, 29, 36, 61, 61, 62, 7, 25, 38,
+ 27, 7, 61, 62, 61, 62, 25, 25, 27, 27,
+ -1, 38, 29, 75, 91, 57, 57, 7, 15, 38,
+ 38, 63, 63, 33, 86, 57, -1, 61, 62, 15,
+ 25, 63, 27, 8, 25, 75, 27, 34, 75, 36,
+ 25, 29, 27, 38, -1, 29, 86, 38, 34, 86,
+ 36, -1, -1, 38, 36, 61, 62, 15, 75, -1,
+ -1, 18, 19, -1, -1, 18, 19, -1, -1, 86,
+ -1, 61, 62, 18, 19, 33, 34, 29, 36, 61,
+ 62, 47, 92, 18, 19, 60, 15, 75, 45, 46,
+ -1, 75, 45, 46, -1, 61, 62, 29, 86, -1,
+ 45, 46, 86, -1, 33, 34, 29, 36, 23, 24,
+ 45, 46, 29, -1, 66, 67, 68, 32, 29, -1,
+ 35, -1, 37, -1, 29, 91, 25, 29, 27, -1,
+ -1, -1, -1, -1, 66, 67, 68, -1, -1, 38,
+ 92, -1, -1, 66, 67, 68, -1, -1, -1, 66,
+ 67, 68, -1, -1, -1, 66, 67, 68, 23, 24,
+ 92, 66, 67, 68, 66, 67, 68, 32, -1, 92,
+ 35, -1, 37, -1, -1, 92, -1, 23, 24, -1,
+ -1, 92, -1, 23, 24, -1, 32, 92, -1, 35,
+ 92, 37, 32, 29, -1, 35, -1, 37, 23, 24,
+ 36, -1, 29, -1, -1, -1, 31, 32, 23, 24,
+ 35, -1, 37, -1, -1, -1, 31, 32, -1, -1,
+ 35, -1, 37, 93, 94, 95, 96, 97, 98, -1,
+ 66, 67, 68, -1, 23, 24, -1, -1, -1, 66,
+ 67, 68, 31, 32, -1, -1, 35, -1, 37, 23,
+ 24, -1, 29, -1, -1, -1, 92, 31, 32, 23,
+ 24, 35, 29, 37, -1, 92, -1, 31, 32, 36,
+ 29, 35, -1, 37, 23, 24, -1, -1, -1, 29,
+ -1, -1, -1, 32, 61, 62, 35, -1, 37, 66,
+ 67, 68, -1, -1, -1, -1, -1, 29, -1, 66,
+ 67, 68, 61, 62, -1, -1, 29, 66, 67, 68,
+ -1, 61, 62, -1, -1, 92, 66, 67, 68, -1,
+ -1, -1, -1, -1, -1, 92, -1, -1, -1, 61,
+ 62, -1, -1, 92, 66, 67, 68, -1, 61, 62,
+ -1, -1, 92, 66, 67, 68, -1, -1, -1, -1,
+ -1, -1, 29, -1, -1, -1, -1, -1, 3, -1,
+ 92, -1, -1, -1, -1, -1, -1, -1, 13, 92,
+ -1, -1, 17, -1, -1, -1, -1, -1, -1, -1,
+ -1, 26, -1, 28, 61, 62, 31, -1, -1, 66,
+ 67, 68, -1, -1, 39, -1, 41, 42, -1, -1,
+ -1, -1, -1, -1, 49, -1, -1, 52, 53, -1,
+ -1, -1, -1, 58, -1, 92, -1, -1, -1, 64,
+ -1, -1, 12, 13, 3, -1, -1, -1, -1, -1,
+ -1, -1, 22, -1, 13, 80, -1, -1, 17, 29,
+ -1, -1, -1, 33, 34, -1, 36, 26, -1, 28,
+ -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
+ 39, -1, 41, 42, -1, -1, -1, -1, -1, -1,
+ 49, -1, -1, 52, 53, 65, 66, 67, 68, 58,
+ 70, -1, -1, -1, -1, 64, -1, -1, -1, -1,
+ -1, 81, 82, 83, 12, 13, -1, 87, -1, -1,
+ -1, 80, 92, -1, 22, -1, -1, -1, -1, -1,
+ -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
+ -1, -1, 12, 13, -1, 43, -1, -1, -1, 47,
+ -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
+ -1, -1, -1, 33, 34, -1, 36, 65, 66, 67,
+ 68, -1, 70, 43, -1, -1, -1, 47, -1, -1,
+ -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
+ -1, -1, -1, -1, 92, 65, 66, 67, 68, -1,
+ 70, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 81, 82, 83, -1, -1, -1, 87, -1, -1,
+ -1, -1, 92, 12, 13, -1, -1, -1, -1, -1,
+ -1, 12, 13, 22, -1, -1, -1, -1, -1, -1,
+ 29, 22, -1, -1, 33, 34, -1, 36, 29, -1,
+ -1, -1, 33, 34, 43, 36, -1, -1, 47, -1,
+ -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, -1, -1, 65, 66, 67, 68, -1, 70,
+ -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
+ 81, 82, 83, 92, -1, -1, 87, -1, -1, -1,
+ -1, 92, -1, -1, -1, -1, -1, -1, -1, -1,
12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
-1, 33, 34, -1, 36, -1, -1, -1, -1, -1,
-1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
- -1, -1, -1, 55, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- -1, -1, -1, 75, -1, -1, -1, -1, -1, 81,
- 82, 83, 84, -1, -1, 87, -1, -1, -1, -1,
- 92, -1, -1, -1, -1, -1, -1, -1, -1, 11,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
- 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 81,
82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
- 92, -1, -1, -1, -1, -1, -1, -1, -1, 7,
- -1, -1, -1, 11, 12, 13, -1, -1, -1, -1,
- -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
- -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
- -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
- -1, -1, -1, 51, -1, 53, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, -1, 70, -1, 72, -1, 74, -1, 76, -1,
- -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
- -1, -1, -1, -1, 92, -1, -1, -1, -1, -1,
- -1, -1, -1, 11, 12, 13, -1, -1, -1, -1,
- -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
- -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
- -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
- -1, -1, -1, 51, -1, 53, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, -1, 70, -1, 72, -1, 74, 75, 76, -1,
- -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
- -1, -1, -1, -1, 92, -1, -1, -1, -1, -1,
- -1, -1, -1, 8, -1, -1, 11, 12, 13, -1,
+ 92, -1, -1, -1, -1, -1, -1, -1, -1, 10,
+ -1, 12, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
+ -1, -1, 33, 34, -1, 36, -1, -1, -1, -1,
+ -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
+ -1, -1, -1, -1, 75, -1, -1, -1, -1, -1,
+ 81, 82, 83, 84, -1, -1, 87, -1, -1, -1,
+ -1, 92, -1, -1, -1, -1, -1, -1, -1, -1,
+ 10, -1, 12, 13, -1, -1, -1, -1, -1, -1,
+ -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
+ -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
+ -1, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
+ 70, -1, -1, -1, -1, 75, -1, -1, -1, -1,
+ -1, 81, 82, 83, 84, -1, -1, 87, -1, -1,
+ -1, -1, 92, -1, -1, -1, -1, -1, -1, -1,
+ -1, 10, -1, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
+ -1, -1, -1, -1, -1, -1, 55, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, -1, -1, -1, -1, 75, -1, -1, -1,
+ -1, -1, 81, 82, 83, 84, -1, -1, 87, -1,
+ -1, -1, -1, 92, -1, -1, -1, -1, -1, -1,
+ -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
+ -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, -1, 72, -1, 74, -1, 76, -1, -1,
+ -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
+ -1, -1, -1, 92, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7, -1, -1, -1, 11, 12, 13, -1,
-1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
-1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
-1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
-1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
- -1, 56, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
+ -1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
+ -1, -1, 87, -1, -1, -1, -1, 92, -1, -1,
+ -1, -1, -1, -1, -1, -1, 11, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
+ -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
+ -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
+ 75, 76, -1, -1, -1, -1, 81, 82, 83, -1,
+ -1, -1, 87, -1, -1, -1, -1, 92, -1, -1,
+ -1, -1, -1, -1, -1, -1, 11, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
+ -1, -1, -1, -1, 29, 30, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
+ -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ -1, -1, -1, -1, -1, -1, 61, -1, -1, -1,
65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
-1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
-1, -1, 87, -1, -1, -1, -1, 92, -1, -1,
@@ -841,6 +848,15 @@ const short QDeclarativeJSGrammar::action_check [] = {
-1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
+ 92, -1, -1, -1, -1, -1, -1, -1, -1, 11,
+ 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 22, -1, -1, -1, -1, -1, -1, 29, 30, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
+ 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
+ -1, 53, -1, -1, -1, -1, -1, -1, -1, 61,
+ -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
+ 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
+ 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
92, -1, -1, -1, -1, -1, -1, -1, -1, 8,
-1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
-1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
@@ -860,44 +876,54 @@ const short QDeclarativeJSGrammar::action_check [] = {
66, 67, 68, -1, 70, -1, 72, -1, 74, -1,
76, -1, -1, -1, -1, 81, 82, 83, -1, -1,
-1, 87, -1, -1, -1, -1, 92, -1, -1, -1,
- -1, -1, -1, -1, -1, 11, 12, 13, -1, -1,
- -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
- -1, -1, -1, 29, 30, -1, -1, 33, 34, -1,
- 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
- -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
- -1, -1, -1, -1, -1, 61, -1, -1, -1, 65,
- 66, 67, 68, -1, 70, -1, 72, -1, 74, -1,
- 76, -1, -1, -1, -1, 81, 82, 83, -1, -1,
- -1, 87, -1, -1, -1, -1, 92, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8, -1, -1, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
+ -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
+ 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
+ 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
+ 53, -1, -1, 56, -1, -1, -1, -1, -1, -1,
+ -1, -1, 65, 66, 67, 68, -1, 70, -1, 72,
+ -1, 74, -1, 76, -1, -1, -1, -1, 81, 82,
+ 83, -1, -1, -1, 87, -1, -1, -1, -1, 92,
+ -1, -1, -1, -1, -1, -1, -1, -1, 4, 5,
+ 6, -1, -1, 9, 10, 11, -1, -1, 14, -1,
+ 16, -1, -1, -1, 20, 21, 22, -1, -1, -1,
+ -1, -1, -1, 29, 30, 31, 32, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 43, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 59, -1, -1, -1, -1, -1, -1,
+ 66, 67, 68, 69, 70, 71, -1, 73, 74, 75,
+ 76, 77, 78, -1, -1, 81, 82, 83, 84, 85,
+ 86, -1, -1, -1, -1, -1, 92, -1, -1, -1,
-1, -1, -1, -1, -1, 4, 5, 6, -1, -1,
9, 10, 11, -1, -1, 14, -1, 16, -1, -1,
-1, 20, 21, 22, -1, -1, -1, -1, -1, -1,
29, 30, 31, 32, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 43, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 59, -1, -1, -1, -1, -1, -1, 66, 67, 68,
+ 59, -1, -1, -1, -1, -1, 65, 66, 67, -1,
69, 70, 71, -1, 73, 74, 75, 76, 77, 78,
-1, -1, 81, 82, 83, 84, 85, 86, -1, -1,
- -1, -1, -1, 92, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 4, 5, 6, -1, -1, 9, 10, 11,
-1, -1, 14, -1, 16, -1, -1, -1, 20, 21,
22, -1, -1, -1, -1, -1, -1, 29, 30, 31,
32, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 59, -1, -1,
+ -1, -1, -1, 55, -1, -1, -1, 59, -1, -1,
-1, -1, -1, 65, 66, 67, -1, 69, 70, 71,
-1, 73, 74, 75, 76, 77, 78, -1, -1, 81,
82, 83, 84, 85, 86, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
- 5, 6, -1, -1, 9, 10, 11, -1, -1, 14,
- -1, 16, -1, -1, -1, 20, 21, 22, -1, -1,
- -1, -1, -1, -1, 29, 30, 31, 32, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 43, -1,
- -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
- 55, -1, -1, -1, 59, -1, -1, -1, -1, -1,
- 65, 66, 67, -1, 69, 70, 71, -1, 73, 74,
+ -1, -1, -1, -1, 9, -1, 11, 12, 13, 14,
+ -1, -1, -1, -1, -1, -1, 21, 22, -1, -1,
+ -1, -1, -1, -1, 29, 30, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
+ -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ -1, -1, -1, -1, 59, -1, 61, -1, -1, -1,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
75, 76, 77, 78, -1, -1, 81, 82, 83, 84,
- 85, 86, -1, -1, -1, -1, -1, -1, -1, -1,
+ 85, -1, 87, -1, -1, -1, -1, 92, -1, -1,
-1, -1, -1, -1, -1, -1, 4, -1, -1, -1,
-1, 9, -1, 11, 12, 13, 14, -1, -1, -1,
-1, -1, -1, 21, 22, -1, -1, -1, -1, -1,
@@ -908,74 +934,66 @@ const short QDeclarativeJSGrammar::action_check [] = {
68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, -1, -1, 81, 82, 83, 84, 85, -1, 87,
-1, -1, -1, -1, 92, -1, -1, -1, -1, -1,
- -1, -1, -1, 4, -1, -1, -1, -1, 9, -1,
- 11, 12, 13, 14, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 4, 5, 6, -1, -1, 9, 10,
+ 11, 12, 13, 14, -1, 16, -1, -1, -1, 20,
21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
+ 31, 32, 33, 34, -1, 36, -1, -1, -1, 40,
-1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
51, -1, 53, -1, -1, -1, -1, -1, 59, -1,
61, -1, -1, -1, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, -1, -1,
- 81, 82, 83, 84, 85, -1, 87, -1, -1, -1,
+ 81, 82, 83, 84, 85, 86, 87, -1, -1, -1,
-1, 92, -1, -1, -1, -1, -1, -1, -1, -1,
4, 5, 6, -1, -1, 9, 10, 11, 12, 13,
14, -1, 16, -1, -1, -1, 20, 21, 22, -1,
-1, -1, -1, -1, -1, 29, 30, 31, 32, 33,
34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, -1, -1, -1, 59, -1, 61, -1, -1,
+ -1, 55, -1, -1, -1, 59, -1, 61, -1, -1,
-1, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, -1, -1, 81, 82, 83,
84, 85, 86, 87, -1, -1, -1, -1, 92, -1,
- -1, -1, -1, -1, -1, -1, -1, 4, 5, 6,
- -1, -1, 9, 10, 11, 12, 13, 14, -1, 16,
- -1, -1, -1, 20, 21, 22, -1, -1, -1, -1,
- -1, -1, 29, 30, 31, 32, 33, 34, -1, 36,
- -1, -1, -1, 40, -1, 42, 43, 44, -1, -1,
- 47, -1, -1, -1, 51, -1, 53, -1, 55, -1,
- -1, -1, 59, -1, 61, -1, -1, -1, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 78, -1, -1, 81, 82, 83, 84, 85, 86,
- 87, -1, -1, -1, -1, 92, -1, -1, -1, -1,
- -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
- 35, 15, 15, 15, 2, 15, 3, 2, 25, 3,
- 15, 15, 104, 15, 4, 3, 3, 3, 19, 15,
- 2, 21, 15, 15, 3, 67, 25, 3, 19, 2,
- 15, 2, 15, 13, 15, 19, 25, 3, 15, 11,
- 15, 2, 96, 3, 2, 15, 2, 25, 3, 2,
- 15, 100, 15, 93, 3, 2, 15, 98, 15, 2,
- 2, 35, 3, 3, 15, 2, 35, 35, 35, 21,
- 2, 25, 3, 35, 4, 21, 15, 2, 2, 15,
- 2, 4, 3, 3, 3, 35, 2, 35, 21, 3,
- 35, 3, 36, 21, 3, 13, 2, 35, 13, -1,
- 35, 35, 2, -1, 15, 13, 35, -1, 16, -1,
- -1, 40, -1, -1, -1, -1, 13, 44, 44, 46,
- 46, 13, 15, -1, 16, -1, 41, 44, -1, 46,
- 35, 44, -1, 46, 44, 40, 46, 44, 3, 46,
- 44, 44, 44, 44, 41, 44, 49, 49, 49, 44,
- 49, 46, 2, 44, 58, 46, 44, 44, 44, 15,
- 46, 49, 49, 44, 44, 44, 46, 44, 44, 44,
- 49, 15, 49, 49, 44, 81, 44, 52, 44, 60,
- 50, 81, 50, 44, 50, 44, 44, 44, 99, 3,
- 49, 49, 13, 37, 87, 56, 44, 54, 44, 20,
- 3, 49, 48, 68, 44, 44, 44, 44, 48, 48,
- 47, 44, 50, 46, 44, 44, 46, 46, 44, 44,
- 46, 44, 47, 46, 44, 44, 46, 46, 44, 85,
- 46, 3, 13, 31, 44, 15, 44, 35, -1, 49,
- 44, 49, 44, 51, 44, 49, -1, 49, 44, 49,
- -1, 61, -1, 49, 68, -1, 13, 37, 38, 16,
- 41, 57, 66, -1, 66, 68, 66, 44, 44, 44,
- -1, -1, 49, 49, 49, 51, 51, 44, 55, 44,
- 44, 44, 49, 44, 49, 49, 49, 51, 49, -1,
- 53, 13, 59, -1, 13, 5, 68, 16, 20, 18,
- 5, 66, -1, 13, -1, 66, 28, 29, 13, -1,
- 20, -1, -1, -1, -1, 20, 35, -1, 28, 29,
- 13, -1, -1, 28, 29, -1, -1, 20, 21, 22,
- 23, 24, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 3,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 13,
- -1, -1, -1, -1, -1, -1, 20, -1, -1, -1,
+ 26, 36, 15, 15, 15, 15, 26, 26, 3, 15,
+ 15, 26, 2, 15, 3, 19, 2, 15, 2, 2,
+ 37, 2, 15, 19, 15, 13, 68, 3, 3, 11,
+ 105, 4, 2, 36, 19, 15, 15, 36, 15, 36,
+ 3, 15, 3, 15, 3, 3, 15, 3, 26, 36,
+ 15, 22, 2, 94, 22, 15, 3, 3, 15, 2,
+ 15, 3, 3, 3, 2, 4, 3, 2, 22, 36,
+ 36, 15, 36, 2, 36, 3, 2, 2, 2, 15,
+ 101, 2, 15, 36, 36, 2, 13, 36, 3, 97,
+ 4, 22, 99, 3, 2, 2, 15, 13, -1, 22,
+ 45, 2, 13, 15, 36, 50, -1, -1, -1, 41,
+ 13, 45, -1, 16, 13, 45, 50, 16, 15, 13,
+ -1, 51, 16, 45, 3, 45, 42, 47, 50, 3,
+ -1, 42, 45, -1, 47, 3, 45, 15, 47, 45,
+ 45, 45, 47, 45, 50, 45, 50, 45, 50, 45,
+ 50, 36, 50, 49, 45, 45, 41, 47, 49, 45,
+ 38, 45, 2, 45, 50, 45, 50, 86, 50, 49,
+ 45, 3, 47, 45, 45, 45, 47, 47, 45, 13,
+ 47, 82, 45, 55, 47, 45, 2, 47, 100, 45,
+ 69, 88, 48, 45, 45, 69, 47, 45, 50, 45,
+ 48, 69, 45, 45, 45, 32, 47, -1, 42, 36,
+ 53, -1, 45, 59, 47, 45, 45, 45, 47, 61,
+ 45, 51, 47, 45, 45, 47, 45, 45, 47, 57,
+ 51, 45, -1, 51, 45, -1, 50, 69, 45, 50,
+ 54, 45, 82, 50, 45, 45, 50, 45, 52, 50,
+ 50, 62, 50, 45, 45, 56, 45, 45, 50, 50,
+ 67, 50, 50, 15, 52, 45, 45, 67, 60, 67,
+ 50, 50, 52, 52, 13, 45, 67, 16, 67, 18,
+ 50, 22, 23, 24, 25, 13, 38, 39, 58, -1,
+ -1, 13, 20, -1, -1, 5, -1, 36, 20, 5,
+ -1, 29, 30, 13, -1, -1, -1, 13, -1, -1,
+ 20, -1, -1, -1, 20, -1, -1, -1, 13, 29,
+ 30, -1, -1, 29, 30, 20, 21, 22, 23, 24,
+ 25, 13, -1, -1, -1, -1, -1, -1, 20, 21,
+ 22, 23, 24, 25, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 21, 22, 23, 24, 25,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -984,6 +1002,6 @@ const short QDeclarativeJSGrammar::action_check [] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1};
+ -1};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/parser/qdeclarativejsgrammar_p.h b/src/declarative/qml/parser/qdeclarativejsgrammar_p.h
index dda1659d26..a093bc25d9 100644
--- a/src/declarative/qml/parser/qdeclarativejsgrammar_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsgrammar_p.h
@@ -164,15 +164,15 @@ public:
T_XOR = 79,
T_XOR_EQ = 80,
- ACCEPT_STATE = 645,
- RULE_COUNT = 347,
- STATE_COUNT = 646,
+ ACCEPT_STATE = 640,
+ RULE_COUNT = 345,
+ STATE_COUNT = 641,
TERMINAL_COUNT = 101,
- NON_TERMINAL_COUNT = 106,
+ NON_TERMINAL_COUNT = 107,
- GOTO_INDEX_OFFSET = 646,
- GOTO_INFO_OFFSET = 2714,
- GOTO_CHECK_OFFSET = 2714
+ GOTO_INDEX_OFFSET = 641,
+ GOTO_INFO_OFFSET = 2787,
+ GOTO_CHECK_OFFSET = 2787
};
static const char *const spell [];
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index b718c0fbf0..4d68f289bc 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -43,11 +43,11 @@
#include <config.h>
#endif
-#include "private/qdeclarativejslexer_p.h"
+#include "qdeclarativejslexer_p.h"
-#include "private/qdeclarativejsglobal_p.h"
-#include "private/qdeclarativejsengine_p.h"
-#include "private/qdeclarativejsgrammar_p.h"
+#include "qdeclarativejsglobal_p.h"
+#include "qdeclarativejsengine_p.h"
+#include "qdeclarativejsgrammar_p.h"
#include <QtCore/qcoreapplication.h>
diff --git a/src/declarative/qml/parser/qdeclarativejslexer_p.h b/src/declarative/qml/parser/qdeclarativejslexer_p.h
index fbbd8f5684..5147df17e4 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer_p.h
+++ b/src/declarative/qml/parser/qdeclarativejslexer_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "private/qdeclarativejsglobal_p.h"
+#include "qdeclarativejsglobal_p.h"
#include <QtCore/QString>
diff --git a/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h b/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h
index 6d81e7565c..8d61dbe714 100644
--- a/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsmemorypool_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "private/qdeclarativejsglobal_p.h"
+#include "qdeclarativejsglobal_p.h"
#include <QtCore/qglobal.h>
#include <QtCore/qshareddata.h>
diff --git a/src/declarative/qml/parser/qdeclarativejsnodepool_p.h b/src/declarative/qml/parser/qdeclarativejsnodepool_p.h
index bc7d1017e9..401500c57c 100644
--- a/src/declarative/qml/parser/qdeclarativejsnodepool_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsnodepool_p.h
@@ -53,8 +53,8 @@
// We mean it.
//
-#include "private/qdeclarativejsglobal_p.h"
-#include "private/qdeclarativejsmemorypool_p.h"
+#include "qdeclarativejsglobal_p.h"
+#include "qdeclarativejsmemorypool_p.h"
#include <QtCore/QHash>
#include <QtCore/QString>
diff --git a/src/declarative/qml/parser/qdeclarativejsparser.cpp b/src/declarative/qml/parser/qdeclarativejsparser.cpp
index f709843c43..d820c5d67a 100644
--- a/src/declarative/qml/parser/qdeclarativejsparser.cpp
+++ b/src/declarative/qml/parser/qdeclarativejsparser.cpp
@@ -44,14 +44,14 @@
#include <string.h>
-#include "private/qdeclarativejsengine_p.h"
-#include "private/qdeclarativejslexer_p.h"
-#include "private/qdeclarativejsast_p.h"
-#include "private/qdeclarativejsnodepool_p.h"
+#include "qdeclarativejsengine_p.h"
+#include "qdeclarativejslexer_p.h"
+#include "qdeclarativejsast_p.h"
+#include "qdeclarativejsnodepool_p.h"
-#include "private/qdeclarativejsparser_p.h"
+#include "qdeclarativejsparser_p.h"
#include <QVarLengthArray>
//
@@ -361,7 +361,8 @@ case 33: {
node->hasOnToken = true;
sym(1).Node = node;
} break;
-case 34:case 35:case 36:case 37:
+
+case 38:
{
AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(),
sym(1).UiQualifiedId, sym(3).Statement);
@@ -369,35 +370,35 @@ case 34:case 35:case 36:case 37:
sym(1).Node = node;
} break;
-case 38:
+case 39:
-case 39: {
+case 40: {
sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
break;
}
-case 41: {
+case 42: {
sym(1).Node = 0;
} break;
-case 42: {
+case 43: {
sym(1).Node = sym(1).UiParameterList->finish ();
} break;
-case 43: {
+case 44: {
AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).sval, sym(2).sval);
node->identifierToken = loc(2);
sym(1).Node = node;
} break;
-case 44: {
+case 45: {
AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).UiParameterList, sym(3).sval, sym(4).sval);
node->commaToken = loc(2);
node->identifierToken = loc(4);
sym(1).Node = node;
} break;
-case 46: {
+case 47: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
node->type = AST::UiPublicMember::Signal;
node->propertyToken = loc(1);
@@ -408,7 +409,7 @@ case 46: {
sym(1).Node = node;
} break;
-case 48: {
+case 49: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
node->type = AST::UiPublicMember::Signal;
node->propertyToken = loc(1);
@@ -418,7 +419,7 @@ case 48: {
sym(1).Node = node;
} break;
-case 50: {
+case 51: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
node->typeModifier = sym(2).sval;
node->propertyToken = loc(1);
@@ -429,7 +430,7 @@ case 50: {
sym(1).Node = node;
} break;
-case 52: {
+case 53: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -438,7 +439,7 @@ case 52: {
sym(1).Node = node;
} break;
-case 54: {
+case 55: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval);
node->isDefaultMember = true;
node->defaultToken = loc(1);
@@ -451,42 +452,39 @@ case 54: {
case 56: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval,
- sym(5).Expression);
+ sym(5).Statement);
node->propertyToken = loc(1);
node->typeToken = loc(2);
node->identifierToken = loc(3);
node->colonToken = loc(4);
- node->semicolonToken = loc(6);
sym(1).Node = node;
} break;
-case 58: {
+case 57: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
- sym(6).Expression);
+ sym(6).Statement);
node->isReadonlyMember = true;
node->readonlyToken = loc(1);
node->propertyToken = loc(2);
node->typeToken = loc(3);
node->identifierToken = loc(4);
node->colonToken = loc(5);
- node->semicolonToken = loc(7);
sym(1).Node = node;
} break;
-case 60: {
+case 58: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
- sym(6).Expression);
+ sym(6).Statement);
node->isDefaultMember = true;
node->defaultToken = loc(1);
node->propertyToken = loc(2);
node->typeToken = loc(3);
node->identifierToken = loc(4);
node->colonToken = loc(5);
- node->semicolonToken = loc(7);
sym(1).Node = node;
} break;
-case 61: {
+case 59: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
node->typeModifier = sym(2).sval;
node->propertyToken = loc(1);
@@ -510,7 +508,7 @@ case 61: {
sym(1).Node = node;
} break;
-case 62: {
+case 60: {
AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
node->propertyToken = loc(1);
node->typeToken = loc(2);
@@ -530,81 +528,81 @@ case 62: {
sym(1).Node = node;
} break;
-case 63: {
+case 61: {
sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
} break;
-case 64: {
+case 62: {
sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
} break;
-case 66: {
+case 64: {
QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_PROPERTY]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
-case 67: {
+case 65: {
QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_SIGNAL]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
-case 68: {
+case 66: {
QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_READONLY]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
-case 69: {
+case 67: {
QString s = QLatin1String(QDeclarativeJSGrammar::spell[T_ON]);
sym(1).sval = driver->intern(s.constData(), s.length());
break;
}
-case 70: {
+case 68: {
AST::ThisExpression *node = makeAstNode<AST::ThisExpression> (driver->nodePool());
node->thisToken = loc(1);
sym(1).Node = node;
} break;
-case 71: {
+case 69: {
AST::IdentifierExpression *node = makeAstNode<AST::IdentifierExpression> (driver->nodePool(), sym(1).sval);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 72: {
+case 70: {
AST::NullExpression *node = makeAstNode<AST::NullExpression> (driver->nodePool());
node->nullToken = loc(1);
sym(1).Node = node;
} break;
-case 73: {
+case 71: {
AST::TrueLiteral *node = makeAstNode<AST::TrueLiteral> (driver->nodePool());
node->trueToken = loc(1);
sym(1).Node = node;
} break;
-case 74: {
+case 72: {
AST::FalseLiteral *node = makeAstNode<AST::FalseLiteral> (driver->nodePool());
node->falseToken = loc(1);
sym(1).Node = node;
} break;
-case 75: {
+case 73: {
AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval);
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 76:
-case 77: {
+case 74:
+case 75: {
AST::StringLiteral *node = makeAstNode<AST::StringLiteral> (driver->nodePool(), sym(1).sval);
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 78: {
+case 76: {
bool rx = lexer->scanRegExp(Lexer::NoPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -618,7 +616,7 @@ case 78: {
sym(1).Node = node;
} break;
-case 79: {
+case 77: {
bool rx = lexer->scanRegExp(Lexer::EqualPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -632,28 +630,28 @@ case 79: {
sym(1).Node = node;
} break;
-case 80: {
+case 78: {
AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), (AST::Elision *) 0);
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
} break;
-case 81: {
+case 79: {
AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision->finish());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 82: {
+case 80: {
AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 83: {
+case 81: {
AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
(AST::Elision *) 0);
node->lbracketToken = loc(1);
@@ -662,7 +660,7 @@ case 83: {
sym(1).Node = node;
} break;
-case 84: {
+case 82: {
AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
sym(4).Elision->finish());
node->lbracketToken = loc(1);
@@ -671,7 +669,7 @@ case 84: {
sym(1).Node = node;
} break;
-case 85: {
+case 83: {
AST::ObjectLiteral *node = 0;
if (sym(2).Node)
node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
@@ -683,7 +681,7 @@ case 85: {
sym(1).Node = node;
} break;
-case 86: {
+case 84: {
AST::ObjectLiteral *node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
sym(2).PropertyNameAndValueList->finish ());
node->lbraceToken = loc(1);
@@ -691,14 +689,14 @@ case 86: {
sym(1).Node = node;
} break;
-case 87: {
+case 85: {
AST::NestedExpression *node = makeAstNode<AST::NestedExpression>(driver->nodePool(), sym(2).Expression);
node->lparenToken = loc(1);
node->rparenToken = loc(3);
sym(1).Node = node;
} break;
-case 88: {
+case 86: {
if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken,
QLatin1String("Ignored annotation")));
@@ -718,48 +716,48 @@ case 88: {
}
} break;
-case 89: {
+case 87: {
sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), (AST::Elision *) 0, sym(1).Expression);
} break;
-case 90: {
+case 88: {
sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).Elision->finish(), sym(2).Expression);
} break;
-case 91: {
+case 89: {
AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList,
(AST::Elision *) 0, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 92: {
+case 90: {
AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision->finish(),
sym(4).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 93: {
+case 91: {
AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool());
node->commaToken = loc(1);
sym(1).Node = node;
} break;
-case 94: {
+case 92: {
AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool(), sym(1).Elision);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 95: {
+case 93: {
AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
sym(1).PropertyName, sym(3).Expression);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 96: {
+case 94: {
AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
node->commaToken = loc(2);
@@ -767,36 +765,40 @@ case 96: {
sym(1).Node = node;
} break;
-case 97: {
+case 95: {
AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 98:
-case 99: {
+case 96:
+case 97: {
AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 100: {
+case 98: {
AST::StringLiteralPropertyName *node = makeAstNode<AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 101: {
+case 99: {
AST::NumericLiteralPropertyName *node = makeAstNode<AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 102: {
+case 100: {
AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
+case 101:
+
+case 102:
+
case 103:
case 104:
@@ -854,29 +856,25 @@ case 129:
case 130:
case 131:
-
-case 132:
-
-case 133:
{
sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
} break;
-case 138: {
+case 136: {
AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 139: {
+case 137: {
AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 140: {
+case 138: {
AST::NewMemberExpression *node = makeAstNode<AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList);
node->newToken = loc(1);
node->lparenToken = loc(3);
@@ -884,384 +882,384 @@ case 140: {
sym(1).Node = node;
} break;
-case 142: {
+case 140: {
AST::NewExpression *node = makeAstNode<AST::NewExpression> (driver->nodePool(), sym(2).Expression);
node->newToken = loc(1);
sym(1).Node = node;
} break;
-case 143: {
+case 141: {
AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 144: {
+case 142: {
AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 145: {
+case 143: {
AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 146: {
+case 144: {
AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 147: {
+case 145: {
sym(1).Node = 0;
} break;
-case 148: {
+case 146: {
sym(1).Node = sym(1).ArgumentList->finish();
} break;
-case 149: {
+case 147: {
sym(1).Node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).Expression);
} break;
-case 150: {
+case 148: {
AST::ArgumentList *node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 154: {
+case 152: {
AST::PostIncrementExpression *node = makeAstNode<AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression);
node->incrementToken = loc(2);
sym(1).Node = node;
} break;
-case 155: {
+case 153: {
AST::PostDecrementExpression *node = makeAstNode<AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression);
node->decrementToken = loc(2);
sym(1).Node = node;
} break;
-case 157: {
+case 155: {
AST::DeleteExpression *node = makeAstNode<AST::DeleteExpression> (driver->nodePool(), sym(2).Expression);
node->deleteToken = loc(1);
sym(1).Node = node;
} break;
-case 158: {
+case 156: {
AST::VoidExpression *node = makeAstNode<AST::VoidExpression> (driver->nodePool(), sym(2).Expression);
node->voidToken = loc(1);
sym(1).Node = node;
} break;
-case 159: {
+case 157: {
AST::TypeOfExpression *node = makeAstNode<AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression);
node->typeofToken = loc(1);
sym(1).Node = node;
} break;
-case 160: {
+case 158: {
AST::PreIncrementExpression *node = makeAstNode<AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression);
node->incrementToken = loc(1);
sym(1).Node = node;
} break;
-case 161: {
+case 159: {
AST::PreDecrementExpression *node = makeAstNode<AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression);
node->decrementToken = loc(1);
sym(1).Node = node;
} break;
-case 162: {
+case 160: {
AST::UnaryPlusExpression *node = makeAstNode<AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression);
node->plusToken = loc(1);
sym(1).Node = node;
} break;
-case 163: {
+case 161: {
AST::UnaryMinusExpression *node = makeAstNode<AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression);
node->minusToken = loc(1);
sym(1).Node = node;
} break;
-case 164: {
+case 162: {
AST::TildeExpression *node = makeAstNode<AST::TildeExpression> (driver->nodePool(), sym(2).Expression);
node->tildeToken = loc(1);
sym(1).Node = node;
} break;
-case 165: {
+case 163: {
AST::NotExpression *node = makeAstNode<AST::NotExpression> (driver->nodePool(), sym(2).Expression);
node->notToken = loc(1);
sym(1).Node = node;
} break;
-case 167: {
+case 165: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Mul, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 168: {
+case 166: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Div, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 169: {
+case 167: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Mod, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 171: {
+case 169: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Add, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 172: {
+case 170: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Sub, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 174: {
+case 172: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::LShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 175: {
+case 173: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::RShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 176: {
+case 174: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::URShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 178: {
+case 176: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 179: {
+case 177: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 180: {
+case 178: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 181: {
+case 179: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 182: {
+case 180: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 183: {
+case 181: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::In, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 185: {
+case 183: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 186: {
+case 184: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 187: {
+case 185: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 188: {
+case 186: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 189: {
+case 187: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 191: {
+case 189: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 192: {
+case 190: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 193: {
+case 191: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 194: {
+case 192: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 196: {
+case 194: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 197: {
+case 195: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 198: {
+case 196: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 199: {
+case 197: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 201: {
+case 199: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 203: {
+case 201: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 205: {
+case 203: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 207: {
+case 205: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 209: {
+case 207: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 211: {
+case 209: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 213: {
+case 211: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 215: {
+case 213: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 217: {
+case 215: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 219: {
+case 217: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 221: {
+case 219: {
AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1269,7 +1267,7 @@ case 221: {
sym(1).Node = node;
} break;
-case 223: {
+case 221: {
AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1277,112 +1275,112 @@ case 223: {
sym(1).Node = node;
} break;
-case 225: {
+case 223: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 227: {
+case 225: {
AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 228: {
+case 226: {
sym(1).ival = QSOperator::Assign;
} break;
-case 229: {
+case 227: {
sym(1).ival = QSOperator::InplaceMul;
} break;
-case 230: {
+case 228: {
sym(1).ival = QSOperator::InplaceDiv;
} break;
-case 231: {
+case 229: {
sym(1).ival = QSOperator::InplaceMod;
} break;
-case 232: {
+case 230: {
sym(1).ival = QSOperator::InplaceAdd;
} break;
-case 233: {
+case 231: {
sym(1).ival = QSOperator::InplaceSub;
} break;
-case 234: {
+case 232: {
sym(1).ival = QSOperator::InplaceLeftShift;
} break;
-case 235: {
+case 233: {
sym(1).ival = QSOperator::InplaceRightShift;
} break;
-case 236: {
+case 234: {
sym(1).ival = QSOperator::InplaceURightShift;
} break;
-case 237: {
+case 235: {
sym(1).ival = QSOperator::InplaceAnd;
} break;
-case 238: {
+case 236: {
sym(1).ival = QSOperator::InplaceXor;
} break;
-case 239: {
+case 237: {
sym(1).ival = QSOperator::InplaceOr;
} break;
-case 241: {
+case 239: {
AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 242: {
+case 240: {
sym(1).Node = 0;
} break;
-case 245: {
+case 243: {
AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 246: {
+case 244: {
sym(1).Node = 0;
} break;
-case 263: {
+case 261: {
AST::Block *node = makeAstNode<AST::Block> (driver->nodePool(), sym(2).StatementList);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 264: {
+case 262: {
sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).Statement);
} break;
-case 265: {
+case 263: {
sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement);
} break;
-case 266: {
+case 264: {
sym(1).Node = 0;
} break;
-case 267: {
+case 265: {
sym(1).Node = sym(1).StatementList->finish ();
} break;
-case 269: {
+case 267: {
AST::VariableStatement *node = makeAstNode<AST::VariableStatement> (driver->nodePool(),
sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
node->declarationKindToken = loc(1);
@@ -1390,76 +1388,76 @@ case 269: {
sym(1).Node = node;
} break;
-case 270: {
+case 268: {
sym(1).ival = T_CONST;
} break;
-case 271: {
+case 269: {
sym(1).ival = T_VAR;
} break;
-case 272: {
+case 270: {
sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
} break;
-case 273: {
+case 271: {
AST::VariableDeclarationList *node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(),
sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 274: {
+case 272: {
sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
} break;
-case 275: {
+case 273: {
sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
} break;
-case 276: {
+case 274: {
AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 277: {
+case 275: {
AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 278: {
+case 276: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 279: {
+case 277: {
sym(1).Node = 0;
} break;
-case 281: {
+case 279: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 282: {
+case 280: {
sym(1).Node = 0;
} break;
-case 284: {
+case 282: {
AST::EmptyStatement *node = makeAstNode<AST::EmptyStatement> (driver->nodePool());
node->semicolonToken = loc(1);
sym(1).Node = node;
} break;
-case 286: {
+case 284: {
AST::ExpressionStatement *node = makeAstNode<AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 287: {
+case 285: {
AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1468,7 +1466,7 @@ case 287: {
sym(1).Node = node;
} break;
-case 288: {
+case 286: {
AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1476,7 +1474,7 @@ case 288: {
sym(1).Node = node;
} break;
-case 290: {
+case 288: {
AST::DoWhileStatement *node = makeAstNode<AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression);
node->doToken = loc(1);
node->whileToken = loc(3);
@@ -1486,7 +1484,7 @@ case 290: {
sym(1).Node = node;
} break;
-case 291: {
+case 289: {
AST::WhileStatement *node = makeAstNode<AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
node->whileToken = loc(1);
node->lparenToken = loc(2);
@@ -1494,7 +1492,7 @@ case 291: {
sym(1).Node = node;
} break;
-case 292: {
+case 290: {
AST::ForStatement *node = makeAstNode<AST::ForStatement> (driver->nodePool(), sym(3).Expression,
sym(5).Expression, sym(7).Expression, sym(9).Statement);
node->forToken = loc(1);
@@ -1505,7 +1503,7 @@ case 292: {
sym(1).Node = node;
} break;
-case 293: {
+case 291: {
AST::LocalForStatement *node = makeAstNode<AST::LocalForStatement> (driver->nodePool(),
sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
sym(8).Expression, sym(10).Statement);
@@ -1518,7 +1516,7 @@ case 293: {
sym(1).Node = node;
} break;
-case 294: {
+case 292: {
AST:: ForEachStatement *node = makeAstNode<AST::ForEachStatement> (driver->nodePool(), sym(3).Expression,
sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
@@ -1528,7 +1526,7 @@ case 294: {
sym(1).Node = node;
} break;
-case 295: {
+case 293: {
AST::LocalForEachStatement *node = makeAstNode<AST::LocalForEachStatement> (driver->nodePool(),
sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
node->forToken = loc(1);
@@ -1539,14 +1537,14 @@ case 295: {
sym(1).Node = node;
} break;
-case 297: {
+case 295: {
AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool());
node->continueToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 299: {
+case 297: {
AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool(), sym(2).sval);
node->continueToken = loc(1);
node->identifierToken = loc(2);
@@ -1554,14 +1552,14 @@ case 299: {
sym(1).Node = node;
} break;
-case 301: {
+case 299: {
AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool());
node->breakToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 303: {
+case 301: {
AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool(), sym(2).sval);
node->breakToken = loc(1);
node->identifierToken = loc(2);
@@ -1569,14 +1567,14 @@ case 303: {
sym(1).Node = node;
} break;
-case 305: {
+case 303: {
AST::ReturnStatement *node = makeAstNode<AST::ReturnStatement> (driver->nodePool(), sym(2).Expression);
node->returnToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 306: {
+case 304: {
AST::WithStatement *node = makeAstNode<AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
node->withToken = loc(1);
node->lparenToken = loc(2);
@@ -1584,7 +1582,7 @@ case 306: {
sym(1).Node = node;
} break;
-case 307: {
+case 305: {
AST::SwitchStatement *node = makeAstNode<AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock);
node->switchToken = loc(1);
node->lparenToken = loc(2);
@@ -1592,90 +1590,90 @@ case 307: {
sym(1).Node = node;
} break;
-case 308: {
+case 306: {
AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 309: {
+case 307: {
AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(5);
sym(1).Node = node;
} break;
-case 310: {
+case 308: {
sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause);
} break;
-case 311: {
+case 309: {
sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause);
} break;
-case 312: {
+case 310: {
sym(1).Node = 0;
} break;
-case 313: {
+case 311: {
sym(1).Node = sym(1).CaseClauses->finish ();
} break;
-case 314: {
+case 312: {
AST::CaseClause *node = makeAstNode<AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList);
node->caseToken = loc(1);
node->colonToken = loc(3);
sym(1).Node = node;
} break;
-case 315: {
+case 313: {
AST::DefaultClause *node = makeAstNode<AST::DefaultClause> (driver->nodePool(), sym(3).StatementList);
node->defaultToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 316:
-case 317: {
+case 314:
+case 315: {
AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 318: {
+case 316: {
AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 320: {
+case 318: {
AST::ThrowStatement *node = makeAstNode<AST::ThrowStatement> (driver->nodePool(), sym(2).Expression);
node->throwToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 321: {
+case 319: {
AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 322: {
+case 320: {
AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 323: {
+case 321: {
AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 324: {
+case 322: {
AST::Catch *node = makeAstNode<AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Block);
node->catchToken = loc(1);
node->lparenToken = loc(2);
@@ -1684,20 +1682,20 @@ case 324: {
sym(1).Node = node;
} break;
-case 325: {
+case 323: {
AST::Finally *node = makeAstNode<AST::Finally> (driver->nodePool(), sym(2).Block);
node->finallyToken = loc(1);
sym(1).Node = node;
} break;
-case 327: {
+case 325: {
AST::DebuggerStatement *node = makeAstNode<AST::DebuggerStatement> (driver->nodePool());
node->debuggerToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 328: {
+case 326: {
AST::FunctionDeclaration *node = makeAstNode<AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
node->identifierToken = loc(2);
@@ -1708,7 +1706,7 @@ case 328: {
sym(1).Node = node;
} break;
-case 329: {
+case 327: {
AST::FunctionExpression *node = makeAstNode<AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
if (sym(2).sval)
@@ -1720,60 +1718,60 @@ case 329: {
sym(1).Node = node;
} break;
-case 330: {
+case 328: {
AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).sval);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 331: {
+case 329: {
AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval);
node->commaToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 332: {
+case 330: {
sym(1).Node = 0;
} break;
-case 333: {
+case 331: {
sym(1).Node = sym(1).FormalParameterList->finish ();
} break;
-case 334: {
+case 332: {
sym(1).Node = 0;
} break;
-case 336: {
+case 334: {
sym(1).Node = makeAstNode<AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ());
} break;
-case 337: {
+case 335: {
sym(1).Node = makeAstNode<AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ());
} break;
-case 338: {
+case 336: {
sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElement);
} break;
-case 339: {
+case 337: {
sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement);
} break;
-case 340: {
+case 338: {
sym(1).Node = makeAstNode<AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement);
} break;
-case 341: {
+case 339: {
sym(1).Node = makeAstNode<AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration);
} break;
-case 342: {
+case 340: {
sym(1).sval = 0;
} break;
-case 344: {
+case 342: {
sym(1).Node = 0;
} break;
diff --git a/src/declarative/qml/parser/qdeclarativejsparser_p.h b/src/declarative/qml/parser/qdeclarativejsparser_p.h
index 70611aa110..0cbd76adfc 100644
--- a/src/declarative/qml/parser/qdeclarativejsparser_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsparser_p.h
@@ -59,10 +59,10 @@
#ifndef QDECLARATIVEJSPARSER_P_H
#define QDECLARATIVEJSPARSER_P_H
-#include "private/qdeclarativejsglobal_p.h"
-#include "private/qdeclarativejsgrammar_p.h"
-#include "private/qdeclarativejsast_p.h"
-#include "private/qdeclarativejsengine_p.h"
+#include "qdeclarativejsglobal_p.h"
+#include "qdeclarativejsgrammar_p.h"
+#include "qdeclarativejsast_p.h"
+#include "qdeclarativejsengine_p.h"
#include <QtCore/QList>
#include <QtCore/QString>
@@ -235,9 +235,9 @@ protected:
-#define J_SCRIPT_REGEXPLITERAL_RULE1 78
+#define J_SCRIPT_REGEXPLITERAL_RULE1 76
-#define J_SCRIPT_REGEXPLITERAL_RULE2 79
+#define J_SCRIPT_REGEXPLITERAL_RULE2 77
QT_QML_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index 399c20709b..da9fc76f4a 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -53,6 +53,9 @@
QT_BEGIN_HEADER
+#define QML_VERSION 0x020000
+#define QML_VERSION_STR "2.0"
+
#define QML_DECLARE_TYPE(TYPE) \
Q_DECLARE_METATYPE(TYPE *) \
Q_DECLARE_METATYPE(QDeclarativeListProperty<TYPE>)
@@ -392,6 +395,8 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
class QDeclarativeContext;
class QDeclarativeEngine;
+class QScriptValue;
+class QScriptEngine;
Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *);
Q_DECLARATIVE_EXPORT QDeclarativeContext *qmlContext(const QObject *);
Q_DECLARATIVE_EXPORT QDeclarativeEngine *qmlEngine(const QObject *);
@@ -405,6 +410,143 @@ QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
return qmlAttachedPropertiesObject(&idx, obj, &T::staticMetaObject, create);
}
+/*!
+ This function may be used to register a module API provider \a callback in a particular \a uri
+ with a version specified in \a versionMajor and \a versionMinor.
+
+ Installing a module API into a uri allows developers to provide arbitrary functionality
+ (methods and properties) in a namespace that doesn't necessarily contain elements.
+
+ A module API may be either a QObject or a QScriptValue. Only one module API provider
+ may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion).
+ This function should be used to register a module API provider function which returns a QScriptValue as a module API.
+
+ Usage:
+ \code
+ // first, define the module API provider function (callback).
+ static QScriptValue *example_qscriptvalue_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine)
+ {
+ Q_UNUSED(engine)
+
+ static int seedValue = 5;
+ QScriptValue example = scriptEngine->newObject();
+ example.setProperty("someProperty", seedValue++);
+ return example;
+ }
+
+ // second, register the module API provider with QML by calling this function in an initialization function.
+ ...
+ qmlRegisterModuleApi("Qt.example.qscriptvalueApi", 1, 0, example_qscriptvalue_module_api_provider);
+ ...
+ \endcode
+
+ In order to use the registered module API in QML, you must import the module API.
+ \qml
+ import QtQuick 2.0
+ import Qt.example.qscriptvalueApi 1.0 as ExampleApi
+ Item {
+ id: root
+ property int someValue: ExampleApi.someProperty
+ }
+ \endqml
+ */
+inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
+ QScriptValue (*callback)(QDeclarativeEngine *, QScriptEngine *))
+{
+ QDeclarativePrivate::RegisterModuleApi api = {
+ 0,
+
+ uri, versionMajor, versionMinor,
+
+ callback, 0
+ };
+
+ return QDeclarativePrivate::qmlregister(QDeclarativePrivate::ModuleApiRegistration, &api);
+}
+
+/*!
+ This function may be used to register a module API provider \a callback in a particular \a uri
+ with a version specified in \a versionMajor and \a versionMinor.
+
+ Installing a module API into a uri allows developers to provide arbitrary functionality
+ (methods and properties) in a namespace that doesn't necessarily contain elements.
+
+ A module API may be either a QObject or a QScriptValue. Only one module API provider
+ may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion).
+ This function should be used to register a module API provider function which returns a QObject as a module API.
+
+ Usage:
+ \code
+ // first, define your QObject which provides the functionality.
+ class ModuleApiExample : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)
+
+ public:
+ ModuleApiExample(QObject* parent = 0)
+ : QObject(parent), m_someProperty(0)
+ {
+ }
+
+ ~ModuleApiExample() {}
+
+ Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; }
+
+ int someProperty() const { return m_someProperty; }
+ void setSomeProperty(int val) { m_someProperty = val; emit somePropertyChanged(val); }
+
+ signals:
+ void somePropertyChanged(int newValue);
+
+ private:
+ int m_someProperty;
+ };
+
+ // second, define the module API provider function (callback).
+ static QObject *example_qobject_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine)
+ {
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
+
+ ModuleApiExample *example = new ModuleApiExample();
+ return example;
+ }
+
+ // third, register the module API provider with QML by calling this function in an initialization function.
+ ...
+ qmlRegisterModuleApi("Qt.example.qobjectApi", 1, 0, example_qobject_module_api_provider);
+ ...
+ \endcode
+
+ In order to use the registered module API in QML, you must import the module API.
+ \qml
+ import QtQuick 2.0
+ import Qt.example.qobjectApi 1.0 as ExampleApi
+ Item {
+ id: root
+ property int someValue: ExampleApi.someProperty
+
+ Component.onCompleted: {
+ someValue = ExampleApi.doSomething()
+ }
+ }
+ \endqml
+ */
+inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
+ QObject *(*callback)(QDeclarativeEngine *, QScriptEngine *))
+{
+ QDeclarativePrivate::RegisterModuleApi api = {
+ 0,
+
+ uri, versionMajor, versionMinor,
+
+ 0, callback
+ };
+
+ return QDeclarativePrivate::qmlregister(QDeclarativePrivate::ModuleApiRegistration, &api);
+}
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QObject)
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index ca3bc37ab4..6c46de69e4 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -357,13 +357,17 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
} else {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context()->engine);
+ ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
bool isUndefined = false;
QVariant value;
QScriptValue scriptValue = d->scriptValue(0, &isUndefined);
- if (wasDeleted)
+
+ if (wasDeleted) {
+ ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
return;
+ }
if (d->property.propertyTypeCategory() == QDeclarativeProperty::List) {
value = ep->scriptValueToVariant(scriptValue, qMetaTypeId<QList<QObject *> >());
@@ -420,8 +424,10 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
} else if (d->property.object() &&
!QDeclarativePropertyPrivate::write(d->property, value, flags)) {
- if (wasDeleted)
+ if (wasDeleted) {
+ ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
return;
+ }
QUrl url = QUrl(d->url);
int line = d->line;
@@ -440,14 +446,21 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
QLatin1String(QMetaType::typeName(d->property.propertyType())));
}
- if (wasDeleted)
+ if (wasDeleted) {
+ ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
return;
+ }
if (d->error.isValid()) {
if (!d->addError(ep)) ep->warning(this->error());
} else {
d->removeError();
}
+
+ // at this point, the binding has been evaluated. If any scarce
+ // resources were copied during the evaluation of the binding,
+ // we need to release those copies.
+ ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
d->updating = false;
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
deleted file mode 100644
index 313fe5896c..0000000000
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ /dev/null
@@ -1,2906 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// #define COMPILEDBINDINGS_DEBUG
-// #define REGISTER_CLEANUP_DEBUG
-
-#include "private/qdeclarativecompiledbindings_p.h"
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <private/qdeclarativecontext_p.h>
-#include <private/qdeclarativejsast_p.h>
-#include <private/qdeclarativejsengine_p.h>
-#include <private/qdeclarativeexpression_p.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qnumeric.h>
-#include <private/qdeclarativeanchors_p_p.h>
-#include <private/qdeclarativeglobal_p.h>
-#include <private/qdeclarativefastproperties_p.h>
-#include <private/qdeclarativedebugtrace_p.h>
-
-QT_BEGIN_NAMESPACE
-
-DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL);
-DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER);
-DEFINE_BOOL_CONFIG_OPTION(qmlDisableFastProperties, QML_DISABLE_FAST_PROPERTIES);
-DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP);
-
-Q_GLOBAL_STATIC(QDeclarativeFastProperties, fastProperties);
-
-#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
-# define QML_THREADED_INTERPRETER
-#endif
-
-#define FOR_EACH_QML_INSTR(F) \
- F(Noop) /* Nop */ \
- F(BindingId) /* id */ \
- F(Subscribe) /* subscribe */ \
- F(SubscribeId) /* subscribe */ \
- F(FetchAndSubscribe) /* fetchAndSubscribe */ \
- F(LoadId) /* load */ \
- F(LoadScope) /* load */ \
- F(LoadRoot) /* load */ \
- F(LoadAttached) /* attached */ \
- F(ConvertIntToReal) /* unaryop */ \
- F(ConvertRealToInt) /* unaryop */ \
- F(Real) /* real_value */ \
- F(Int) /* int_value */ \
- F(Bool) /* bool_value */ \
- F(String) /* string_value */ \
- F(AddReal) /* binaryop */ \
- F(AddInt) /* binaryop */ \
- F(AddString) /* binaryop */ \
- F(MinusReal) /* binaryop */ \
- F(MinusInt) /* binaryop */ \
- F(CompareReal) /* binaryop */ \
- F(CompareString) /* binaryop */ \
- F(NotCompareReal) /* binaryop */ \
- F(NotCompareString) /* binaryop */ \
- F(GreaterThanReal) /* binaryop */ \
- F(MaxReal) /* binaryop */ \
- F(MinReal) /* binaryop */ \
- F(NewString) /* construct */ \
- F(NewUrl) /* construct */ \
- F(CleanupUrl) /* cleanup */ \
- F(CleanupString) /* cleanup */ \
- F(Copy) /* copy */ \
- F(Fetch) /* fetch */ \
- F(Store) /* store */ \
- F(Skip) /* skip */ \
- F(Done) /* done */ \
- /* Speculative property resolution */ \
- F(InitString) /* initstring */ \
- F(FindGeneric) /* find */ \
- F(FindGenericTerminal) /* find */ \
- F(FindProperty) /* find */ \
- F(FindPropertyTerminal) /* find */ \
- F(CleanupGeneric) /* cleanup */ \
- F(ConvertGenericToReal) /* unaryop */ \
- F(ConvertGenericToBool) /* unaryop */ \
- F(ConvertGenericToString) /* unaryop */ \
- F(ConvertGenericToUrl) /* unaryop */
-
-#define QML_INSTR_ENUM(I) I,
-#define QML_INSTR_ADDR(I) &&op_##I,
-
-#ifdef QML_THREADED_INTERPRETER
-# define QML_BEGIN_INSTR(I) op_##I:
-# define QML_END_INSTR(I) ++instr; goto *instr->common.code;
-# define QML_INSTR_HEADER void *code;
-#else
-# define QML_BEGIN_INSTR(I) case Instr::I:
-# define QML_END_INSTR(I) break;
-# define QML_INSTR_HEADER
-#endif
-
-
-using namespace QDeclarativeJS;
-
-namespace {
-// Supported types: int, qreal, QString (needs constr/destr), QObject*, bool
-struct Register {
- void setUndefined() { type = 0; }
- void setUnknownButDefined() { type = -1; }
- void setNaN() { setqreal(qSNaN()); }
- bool isUndefined() const { return type == 0; }
-
- void setQObject(QObject *o) { *((QObject **)data) = o; type = QMetaType::QObjectStar; }
- QObject *getQObject() const { return *((QObject **)data); }
-
- void setqreal(qreal v) { *((qreal *)data) = v; type = QMetaType::QReal; }
- qreal getqreal() const { return *((qreal *)data); }
-
- void setint(int v) { *((int *)data) = v; type = QMetaType::Int; }
- int getint() const { return *((int *)data); }
-
- void setbool(bool v) { *((bool *)data) = v; type = QMetaType::Bool; }
- bool getbool() const { return *((bool *)data); }
-
- QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
- QString *getstringptr() { return (QString *)typeDataPtr(); }
- QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
- const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
- const QString *getstringptr() const { return (QString *)typeDataPtr(); }
- const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
-
- void *typeDataPtr() { return (void *)&data; }
- void *typeMemory() { return (void *)data; }
- const void *typeDataPtr() const { return (void *)&data; }
- const void *typeMemory() const { return (void *)data; }
-
- int gettype() const { return type; }
- void settype(int t) { type = t; }
-
- int type; // Optional type
- void *data[2]; // Object stored here
-
-#ifdef REGISTER_CLEANUP_DEBUG
- Register() {
- type = 0;
- }
-
- ~Register() {
- int allowedTypes[] = { QMetaType::QObjectStar, QMetaType::QReal, QMetaType::Int, QMetaType::Bool, 0 };
- bool found = (type == 0);
- int *ctype = allowedTypes;
- while (!found && *ctype) {
- found = (*ctype == type);
- ++ctype;
- }
- if (!found)
- qWarning("Register leaked of type %d", type);
- }
-#endif
-};
-}
-
-class QDeclarativeCompiledBindingsPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeCompiledBindings)
-
-public:
- QDeclarativeCompiledBindingsPrivate();
- virtual ~QDeclarativeCompiledBindingsPrivate();
-
- struct Binding : public QDeclarativeAbstractBinding, public QDeclarativeDelayedError {
- Binding() : enabled(false), updating(0), property(0),
- scope(0), target(0), parent(0) {}
-
- // Inherited from QDeclarativeAbstractBinding
- virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void destroy();
-
- int index:30;
- bool enabled:1;
- bool updating:1;
- int property;
- QObject *scope;
- QObject *target;
-
- QDeclarativeCompiledBindingsPrivate *parent;
- };
-
- typedef QDeclarativeNotifierEndpoint Subscription;
- Subscription *subscriptions;
- QScriptDeclarativeClass::PersistentIdentifier *identifiers;
-
- void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
-
- const char *programData;
- Binding *m_bindings;
- quint32 *m_signalTable;
-
- static int methodCount;
-
- void init();
- void run(int instr, QDeclarativeContextData *context,
- QDeclarativeDelayedError *error, QObject *scope, QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags);
-
-
- inline void unsubscribe(int subIndex);
- inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex);
- inline void subscribe(QObject *o, int notifyIndex, int subIndex);
-
- QDeclarativePropertyCache::Data *findproperty(QObject *obj,
- const QScriptDeclarativeClass::Identifier &name,
- QDeclarativeEnginePrivate *enginePriv,
- QDeclarativePropertyCache::Data &local);
- bool findproperty(QObject *obj,
- Register *output,
- QDeclarativeEnginePrivate *enginePriv,
- int subIdx,
- const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal);
- void findgeneric(Register *output, // value output
- int subIdx, // Subscription index in config
- QDeclarativeContextData *context, // Context to search in
- const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal);
-};
-
-QDeclarativeCompiledBindingsPrivate::QDeclarativeCompiledBindingsPrivate()
-: subscriptions(0), identifiers(0)
-{
-}
-
-QDeclarativeCompiledBindingsPrivate::~QDeclarativeCompiledBindingsPrivate()
-{
- delete [] subscriptions; subscriptions = 0;
- delete [] identifiers; identifiers = 0;
-}
-
-int QDeclarativeCompiledBindingsPrivate::methodCount = -1;
-
-QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context)
-: QObject(*(new QDeclarativeCompiledBindingsPrivate))
-{
- Q_D(QDeclarativeCompiledBindings);
-
- if (d->methodCount == -1)
- d->methodCount = QDeclarativeCompiledBindings::staticMetaObject.methodCount();
-
- d->programData = program;
-
- d->init();
-
- QDeclarativeAbstractExpression::setContext(context);
-}
-
-QDeclarativeCompiledBindings::~QDeclarativeCompiledBindings()
-{
- Q_D(QDeclarativeCompiledBindings);
-
- delete [] d->m_bindings;
-}
-
-QDeclarativeAbstractBinding *QDeclarativeCompiledBindings::configBinding(int index, QObject *target,
- QObject *scope, int property)
-{
- Q_D(QDeclarativeCompiledBindings);
-
- QDeclarativeCompiledBindingsPrivate::Binding *rv = d->m_bindings + index;
-
- rv->index = index;
- rv->property = property;
- rv->target = target;
- rv->scope = scope;
- rv->parent = d;
-
- addref(); // This is decremented in Binding::destroy()
-
- return rv;
-}
-
-void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- if (enabled != e) {
- enabled = e;
-
- if (e) update(flags);
- }
-}
-
-void QDeclarativeCompiledBindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
-{
- QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
- parent->run(this, flags);
- QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
-}
-
-void QDeclarativeCompiledBindingsPrivate::Binding::destroy()
-{
- enabled = false;
- removeFromObject();
- clear();
- parent->q_func()->release();
-}
-
-int QDeclarativeCompiledBindings::qt_metacall(QMetaObject::Call c, int id, void **)
-{
- Q_D(QDeclarativeCompiledBindings);
-
- if (c == QMetaObject::InvokeMetaMethod && id >= d->methodCount) {
- id -= d->methodCount;
-
- quint32 *reeval = d->m_signalTable + d->m_signalTable[id];
- quint32 count = *reeval;
- ++reeval;
- for (quint32 ii = 0; ii < count; ++ii) {
- d->run(d->m_bindings + reeval[ii], QDeclarativePropertyPrivate::DontRemoveBinding);
- }
- }
- return -1;
-}
-
-void QDeclarativeCompiledBindingsPrivate::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags)
-{
- Q_Q(QDeclarativeCompiledBindings);
-
- if (!binding->enabled)
- return;
-
- QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context();
- if (!context || !context->isValid())
- return;
-
- if (binding->updating) {
- QString name;
- if (binding->property & 0xFFFF0000) {
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
-
- QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
- Q_ASSERT(vt);
-
- name = QLatin1String(binding->target->metaObject()->property(binding->property & 0xFFFF).name());
- name.append(QLatin1String("."));
- name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name()));
- } else {
- name = QLatin1String(binding->target->metaObject()->property(binding->property).name());
- }
- qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeCompiledBindings", "Binding loop detected for property \"%1\"").arg(name);
- return;
- }
-
- binding->updating = true;
- if (binding->property & 0xFFFF0000) {
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
-
- QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
- Q_ASSERT(vt);
- vt->read(binding->target, binding->property & 0xFFFF);
-
- QObject *target = vt;
- run(binding->index, context, binding, binding->scope, target, flags);
-
- vt->write(binding->target, binding->property & 0xFFFF, flags);
- } else {
- run(binding->index, context, binding, binding->scope, binding->target, flags);
- }
- binding->updating = false;
-}
-
-namespace {
-// This structure is exactly 8-bytes in size
-struct Instr {
- enum {
- FOR_EACH_QML_INSTR(QML_INSTR_ENUM)
- };
-
- union {
- struct {
- QML_INSTR_HEADER
- quint8 type;
- quint8 packing[7];
- } common;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- quint8 packing;
- quint16 column;
- quint32 line;
- } id;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- quint8 packing[3];
- quint16 subscriptions;
- quint16 identifiers;
- } init;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint16 offset;
- quint32 index;
- } subscribe;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint8 packing[2];
- quint32 index;
- } load;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 output;
- qint8 reg;
- quint8 exceptionId;
- quint32 id;
- } attached;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 output;
- qint8 reg;
- quint8 exceptionId;
- quint32 index;
- } store;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 output;
- qint8 objectReg;
- quint8 exceptionId;
- quint16 subscription;
- quint16 function;
- } fetchAndSubscribe;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 output;
- qint8 objectReg;
- quint8 exceptionId;
- quint32 index;
- } fetch;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- qint8 src;
- quint8 packing[5];
- } copy;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint8 packing[6];
- } construct;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint8 packing[2];
- float value;
- } real_value;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint8 packing[2];
- int value;
- } int_value;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- bool value;
- quint8 packing[5];
- } bool_value;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint16 length;
- quint32 offset;
- } string_value;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 output;
- qint8 src1;
- qint8 src2;
- quint8 packing[4];
- } binaryop;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 output;
- qint8 src;
- quint8 packing[5];
- } unaryop;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint8 packing[2];
- quint32 count;
- } skip;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- qint8 src;
- quint8 exceptionId;
- quint16 name;
- quint16 subscribeIndex;
- } find;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- qint8 reg;
- quint8 packing[6];
- } cleanup;
- struct {
- QML_INSTR_HEADER
- quint8 type;
- quint8 packing[1];
- quint16 offset;
- quint32 dataIdx;
- } initstring;
- };
-};
-
-struct Program {
- quint32 bindings;
- quint32 dataLength;
- quint32 signalTableOffset;
- quint32 exceptionDataOffset;
- quint16 subscriptions;
- quint16 identifiers;
- quint16 instructionCount;
- quint16 compiled;
-
- const char *data() const { return ((const char *)this) + sizeof(Program); }
- const Instr *instructions() const { return (const Instr *)(data() + dataLength); }
-};
-}
-
-struct QDeclarativeBindingCompilerPrivate
-{
- struct Result {
- Result() : unknownType(false), metaObject(0), type(-1), reg(-1) {}
- bool operator==(const Result &o) const {
- return unknownType == o.unknownType &&
- metaObject == o.metaObject &&
- type == o.type &&
- reg == o.reg;
- }
- bool operator!=(const Result &o) const {
- return !(*this == o);
- }
- bool unknownType;
- const QMetaObject *metaObject;
- int type;
- int reg;
-
- QSet<QString> subscriptionSet;
- };
-
- QDeclarativeBindingCompilerPrivate() : registers(0) {}
-
- void resetInstanceState();
- int commitCompile();
-
- QDeclarativeParser::Object *context;
- QDeclarativeParser::Object *component;
- QDeclarativeParser::Property *destination;
- QHash<QString, QDeclarativeParser::Object *> ids;
- QDeclarativeImports imports;
- QDeclarativeEnginePrivate *engine;
-
- QString contextName() const { return QLatin1String("$$$SCOPE_") + QString::number((quintptr)context, 16); }
-
- bool compile(QDeclarativeJS::AST::Node *);
-
- bool parseExpression(QDeclarativeJS::AST::Node *, Result &);
-
- bool tryName(QDeclarativeJS::AST::Node *);
- bool parseName(QDeclarativeJS::AST::Node *, Result &);
-
- bool tryArith(QDeclarativeJS::AST::Node *);
- bool parseArith(QDeclarativeJS::AST::Node *, Result &);
- bool numberArith(Result &, const Result &, const Result &, QSOperator::Op op);
- bool stringArith(Result &, const Result &, const Result &, QSOperator::Op op);
-
- bool tryLogic(QDeclarativeJS::AST::Node *);
- bool parseLogic(QDeclarativeJS::AST::Node *, Result &);
-
- bool tryConditional(QDeclarativeJS::AST::Node *);
- bool parseConditional(QDeclarativeJS::AST::Node *, Result &);
-
- bool tryConstant(QDeclarativeJS::AST::Node *);
- bool parseConstant(QDeclarativeJS::AST::Node *, Result &);
-
- bool tryMethod(QDeclarativeJS::AST::Node *);
- bool parseMethod(QDeclarativeJS::AST::Node *, Result &);
-
- bool buildName(QStringList &, QDeclarativeJS::AST::Node *, QList<QDeclarativeJS::AST::ExpressionNode *> *nodes = 0);
- bool fetch(Result &type, const QMetaObject *, int reg, int idx, const QStringList &, QDeclarativeJS::AST::ExpressionNode *);
-
- quint32 registers;
- QHash<int, QPair<int, int> > registerCleanups;
- int acquireReg(int cleanup = Instr::Noop, int cleanupType = 0);
- void registerCleanup(int reg, int cleanup, int cleanupType = 0);
- void releaseReg(int);
-
- int registerLiteralString(const QString &);
- int registerString(const QString &);
- QHash<QString, QPair<int, int> > registeredStrings;
- QByteArray data;
-
- bool subscription(const QStringList &, Result *);
- int subscriptionIndex(const QStringList &);
- bool subscriptionNeutral(const QSet<QString> &base, const QSet<QString> &lhs, const QSet<QString> &rhs);
-
- quint8 exceptionId(QDeclarativeJS::AST::ExpressionNode *);
- QVector<quint64> exceptions;
-
- QSet<int> usedSubscriptionIds;
- QSet<QString> subscriptionSet;
- QHash<QString, int> subscriptionIds;
- QVector<Instr> bytecode;
-
- // Committed binding data
- struct {
- QList<int> offsets;
- QList<QSet<int> > dependencies;
-
- QVector<Instr> bytecode;
- QByteArray data;
- QHash<QString, int> subscriptionIds;
- QVector<quint64> exceptions;
-
- QHash<QString, QPair<int, int> > registeredStrings;
-
- int count() const { return offsets.count(); }
- } committed;
-
- QByteArray buildSignalTable() const;
- QByteArray buildExceptionData() const;
-};
-
-void QDeclarativeCompiledBindingsPrivate::unsubscribe(int subIndex)
-{
- QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- sub->disconnect();
-}
-
-void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
-{
- Q_Q(QDeclarativeCompiledBindings);
-
- unsubscribe(subIndex);
-
- if (p->idValues[idIndex]) {
- QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- sub->target = q;
- sub->targetMethod = methodCount + subIndex;
- sub->connect(&p->idValues[idIndex].bindings);
- }
-}
-
-void QDeclarativeCompiledBindingsPrivate::subscribe(QObject *o, int notifyIndex, int subIndex)
-{
- Q_Q(QDeclarativeCompiledBindings);
-
- QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- sub->target = q;
- sub->targetMethod = methodCount + subIndex;
- if (o)
- sub->connect(o, notifyIndex);
- else
- sub->disconnect();
-}
-
-// Conversion functions - these MUST match the QtScript expression path
-inline static qreal toReal(Register *reg, int type, bool *ok = 0)
-{
- if (ok) *ok = true;
-
- if (type == QMetaType::QReal) {
- return reg->getqreal();
- } else if (type == qMetaTypeId<QVariant>()) {
- return reg->getvariantptr()->toReal();
- } else {
- if (ok) *ok = false;
- return 0;
- }
-}
-
-inline static QString toString(Register *reg, int type, bool *ok = 0)
-{
- if (ok) *ok = true;
-
- if (type == QMetaType::QReal) {
- return QString::number(reg->getqreal());
- } else if (type == QMetaType::Int) {
- return QString::number(reg->getint());
- } else if (type == qMetaTypeId<QVariant>()) {
- return reg->getvariantptr()->toString();
- } else if (type == QMetaType::QString) {
- return *reg->getstringptr();
- } else {
- if (ok) *ok = false;
- return QString();
- }
-}
-
-inline static bool toBool(Register *reg, int type, bool *ok = 0)
-{
- if (ok) *ok = true;
-
- if (type == QMetaType::Bool) {
- return reg->getbool();
- } else if (type == qMetaTypeId<QVariant>()) {
- return reg->getvariantptr()->toBool();
- } else {
- if (ok) *ok = false;
- return false;
- }
-}
-
-inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok = 0)
-{
- if (ok) *ok = true;
-
- QUrl base;
- if (type == qMetaTypeId<QVariant>()) {
- QVariant *var = reg->getvariantptr();
- int vt = var->type();
- if (vt == QVariant::Url) {
- base = var->toUrl();
- } else if (vt == QVariant::ByteArray) {
- base = QUrl(QString::fromUtf8(var->toByteArray()));
- } else if (vt == QVariant::String) {
- base = QUrl(var->toString());
- } else {
- if (ok) *ok = false;
- return QUrl();
- }
- } else if (type == QMetaType::QString) {
- base = QUrl(*reg->getstringptr());
- } else {
- if (ok) *ok = false;
- return QUrl();
- }
-
- if (!base.isEmpty() && base.isRelative())
- return context->url.resolved(base);
- else
- return base;
-}
-
-static QObject *variantToQObject(const QVariant &value, bool *ok)
-{
- if (ok) *ok = true;
-
- if (value.userType() == QMetaType::QObjectStar) {
- return qvariant_cast<QObject*>(value);
- } else {
- if (ok) *ok = false;
- return 0;
- }
-}
-
-bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *output,
- QDeclarativeEnginePrivate *enginePriv,
- int subIdx, const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal)
-{
- if (!obj) {
- output->setUndefined();
- return false;
- }
-
- QDeclarativePropertyCache::Data local;
- QDeclarativePropertyCache::Data *property =
- QDeclarativePropertyCache::property(QDeclarativeEnginePrivate::get(enginePriv), obj, name, local);
-
- if (property) {
- if (subIdx != -1)
- subscribe(obj, property->notifyIndex, subIdx);
-
- if (property->flags & QDeclarativePropertyCache::Data::IsQObjectDerived) {
- void *args[] = { output->typeDataPtr(), 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, property->coreIndex, args);
- output->settype(QMetaType::QObjectStar);
- } else if (property->propType == qMetaTypeId<QVariant>()) {
- QVariant v;
- void *args[] = { &v, 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, property->coreIndex, args);
-
- if (isTerminal) {
- new (output->typeDataPtr()) QVariant(v);
- output->settype(qMetaTypeId<QVariant>());
- } else {
- bool ok;
- output->setQObject(variantToQObject(v, &ok));
- if (!ok)
- output->setUndefined();
- else
- output->settype(QMetaType::QObjectStar);
- }
-
- } else {
- if (!isTerminal) {
- output->setUndefined();
- } else if (property->propType == QMetaType::QReal) {
- void *args[] = { output->typeDataPtr(), 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, property->coreIndex, args);
- output->settype(QMetaType::QReal);
- } else if (property->propType == QMetaType::Int) {
- void *args[] = { output->typeDataPtr(), 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, property->coreIndex, args);
- output->settype(QMetaType::Int);
- } else if (property->propType == QMetaType::Bool) {
- void *args[] = { output->typeDataPtr(), 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, property->coreIndex, args);
- output->settype(QMetaType::Bool);
- } else if (property->propType == QMetaType::QString) {
- new (output->typeDataPtr()) QString();
- void *args[] = { output->typeDataPtr(), 0 };
- QMetaObject::metacall(obj, QMetaObject::ReadProperty, property->coreIndex, args);
- output->settype(QMetaType::QString);
- } else {
- new (output->typeDataPtr())
- QVariant(obj->metaObject()->property(property->coreIndex).read(obj));
- output->settype(qMetaTypeId<QVariant>());
- }
- }
-
- return true;
- } else {
- output->setUndefined();
- return false;
- }
-}
-
-void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output,
- int subIdx,
- QDeclarativeContextData *context,
- const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal)
-{
- QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context->engine);
-
- while (context) {
-
- int contextPropertyIndex = context->propertyNames?context->propertyNames->value(name):-1;
-
-
- if (contextPropertyIndex != -1) {
-
- if (contextPropertyIndex < context->idValueCount) {
- output->setQObject(context->idValues[contextPropertyIndex]);
- output->settype(QMetaType::QObjectStar);
-
- if (subIdx != -1)
- subscribeId(context, contextPropertyIndex, subIdx);
-
- } else {
- QDeclarativeContextPrivate *cp = context->asQDeclarativeContextPrivate();
- const QVariant &value = cp->propertyValues.at(contextPropertyIndex);
-
- if (isTerminal) {
- new (output->typeDataPtr()) QVariant(value);
- output->settype(qMetaTypeId<QVariant>());
- } else {
- bool ok;
- output->setQObject(variantToQObject(value, &ok));
- if (!ok) { output->setUndefined(); }
- else { output->settype(QMetaType::QObjectStar); }
- return;
- }
-
- if (subIdx != -1)
- subscribe(context->asQDeclarativeContext(), contextPropertyIndex + cp->notifyIndex, subIdx);
-
-
- }
-
- return;
- }
-
- if (QObject *root = context->contextObject) {
-
- if (findproperty(root, output, enginePriv, subIdx, name, isTerminal))
- return;
-
- }
-
- context = context->parent;
- }
-
- output->setUndefined();
-}
-
-void QDeclarativeCompiledBindingsPrivate::init()
-{
- Program *program = (Program *)programData;
- if (program->subscriptions)
- subscriptions = new QDeclarativeCompiledBindingsPrivate::Subscription[program->subscriptions];
- if (program->identifiers)
- identifiers = new QScriptDeclarativeClass::PersistentIdentifier[program->identifiers];
-
- m_signalTable = (quint32 *)(program->data() + program->signalTableOffset);
- m_bindings = new QDeclarativeCompiledBindingsPrivate::Binding[program->bindings];
-}
-
-static void throwException(int id, QDeclarativeDelayedError *error,
- Program *program, QDeclarativeContextData *context,
- const QString &description = QString())
-{
- error->error.setUrl(context->url);
- if (description.isEmpty())
- error->error.setDescription(QLatin1String("TypeError: Result of expression is not an object"));
- else
- error->error.setDescription(description);
- if (id != 0xFF) {
- quint64 e = *((quint64 *)(program->data() + program->exceptionDataOffset) + id);
- error->error.setLine((e >> 32) & 0xFFFFFFFF);
- error->error.setColumn(e & 0xFFFFFFFF);
- } else {
- error->error.setLine(-1);
- error->error.setColumn(-1);
- }
- if (!context->engine || !error->addError(QDeclarativeEnginePrivate::get(context->engine)))
- QDeclarativeEnginePrivate::warning(context->engine, error->error);
-}
-
-static void dumpInstruction(const Instr *instr)
-{
- switch (instr->common.type) {
- case Instr::Noop:
- qWarning().nospace() << "\t" << "Noop";
- break;
- case Instr::BindingId:
- qWarning().nospace() << instr->id.line << ":" << instr->id.column << ":";
- break;
- case Instr::Subscribe:
- qWarning().nospace() << "\t" << "Subscribe" << "\t\t" << instr->subscribe.offset << "\t" << instr->subscribe.reg << "\t" << instr->subscribe.index;
- break;
- case Instr::SubscribeId:
- qWarning().nospace() << "\t" << "SubscribeId" << "\t\t" << instr->subscribe.offset << "\t" << instr->subscribe.reg << "\t" << instr->subscribe.index;
- break;
- case Instr::FetchAndSubscribe:
- qWarning().nospace() << "\t" << "FetchAndSubscribe" << "\t" << instr->fetchAndSubscribe.output << "\t" << instr->fetchAndSubscribe.objectReg << "\t" << instr->fetchAndSubscribe.subscription;
- break;
- case Instr::LoadId:
- qWarning().nospace() << "\t" << "LoadId" << "\t\t\t" << instr->load.index << "\t" << instr->load.reg;
- break;
- case Instr::LoadScope:
- qWarning().nospace() << "\t" << "LoadScope" << "\t\t" << instr->load.index << "\t" << instr->load.reg;
- break;
- case Instr::LoadRoot:
- qWarning().nospace() << "\t" << "LoadRoot" << "\t\t" << instr->load.index << "\t" << instr->load.reg;
- break;
- case Instr::LoadAttached:
- qWarning().nospace() << "\t" << "LoadAttached" << "\t\t" << instr->attached.output << "\t" << instr->attached.reg << "\t" << instr->attached.id;
- break;
- case Instr::ConvertIntToReal:
- qWarning().nospace() << "\t" << "ConvertIntToReal" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
- break;
- case Instr::ConvertRealToInt:
- qWarning().nospace() << "\t" << "ConvertRealToInt" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
- break;
- case Instr::Real:
- qWarning().nospace() << "\t" << "Real" << "\t\t\t" << instr->real_value.reg << "\t" << instr->real_value.value;
- break;
- case Instr::Int:
- qWarning().nospace() << "\t" << "Int" << "\t\t\t" << instr->int_value.reg << "\t" << instr->int_value.value;
- break;
- case Instr::Bool:
- qWarning().nospace() << "\t" << "Bool" << "\t\t\t" << instr->bool_value.reg << "\t" << instr->bool_value.value;
- break;
- case Instr::String:
- qWarning().nospace() << "\t" << "String" << "\t\t\t" << instr->string_value.reg << "\t" << instr->string_value.offset << "\t" << instr->string_value.length;
- break;
- case Instr::AddReal:
- qWarning().nospace() << "\t" << "AddReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::AddInt:
- qWarning().nospace() << "\t" << "AddInt" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::AddString:
- qWarning().nospace() << "\t" << "AddString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::MinusReal:
- qWarning().nospace() << "\t" << "MinusReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::MinusInt:
- qWarning().nospace() << "\t" << "MinusInt" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::CompareReal:
- qWarning().nospace() << "\t" << "CompareReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::CompareString:
- qWarning().nospace() << "\t" << "CompareString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::NotCompareReal:
- qWarning().nospace() << "\t" << "NotCompareReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::NotCompareString:
- qWarning().nospace() << "\t" << "NotCompareString" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::GreaterThanReal:
- qWarning().nospace() << "\t" << "GreaterThanReal" << "\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::MaxReal:
- qWarning().nospace() << "\t" << "MaxReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::MinReal:
- qWarning().nospace() << "\t" << "MinReal" << "\t\t\t" << instr->binaryop.output << "\t" << instr->binaryop.src1 << "\t" << instr->binaryop.src2;
- break;
- case Instr::NewString:
- qWarning().nospace() << "\t" << "NewString" << "\t\t" << instr->construct.reg;
- break;
- case Instr::NewUrl:
- qWarning().nospace() << "\t" << "NewUrl" << "\t\t\t" << instr->construct.reg;
- break;
- case Instr::CleanupString:
- qWarning().nospace() << "\t" << "CleanupString" << "\t\t" << instr->cleanup.reg;
- break;
- case Instr::CleanupUrl:
- qWarning().nospace() << "\t" << "CleanupUrl" << "\t\t" << instr->cleanup.reg;
- break;
- case Instr::Fetch:
- qWarning().nospace() << "\t" << "Fetch" << "\t\t\t" << instr->fetch.output << "\t" << instr->fetch.index << "\t" << instr->fetch.objectReg;
- break;
- case Instr::Store:
- qWarning().nospace() << "\t" << "Store" << "\t\t\t" << instr->store.output << "\t" << instr->store.index << "\t" << instr->store.reg;
- break;
- case Instr::Copy:
- qWarning().nospace() << "\t" << "Copy" << "\t\t\t" << instr->copy.reg << "\t" << instr->copy.src;
- break;
- case Instr::Skip:
- qWarning().nospace() << "\t" << "Skip" << "\t\t\t" << instr->skip.reg << "\t" << instr->skip.count;
- break;
- case Instr::Done:
- qWarning().nospace() << "\t" << "Done";
- break;
- case Instr::InitString:
- qWarning().nospace() << "\t" << "InitString" << "\t\t" << instr->initstring.offset << "\t" << instr->initstring.dataIdx;
- break;
- case Instr::FindGeneric:
- qWarning().nospace() << "\t" << "FindGeneric" << "\t\t" << instr->find.reg << "\t" << instr->find.name;
- break;
- case Instr::FindGenericTerminal:
- qWarning().nospace() << "\t" << "FindGenericTerminal" << "\t" << instr->find.reg << "\t" << instr->find.name;
- break;
- case Instr::FindProperty:
- qWarning().nospace() << "\t" << "FindProperty" << "\t\t" << instr->find.reg << "\t" << instr->find.src << "\t" << instr->find.name;
- break;
- case Instr::FindPropertyTerminal:
- qWarning().nospace() << "\t" << "FindPropertyTerminal" << "\t" << instr->find.reg << "\t" << instr->find.src << "\t" << instr->find.name;
- break;
- case Instr::CleanupGeneric:
- qWarning().nospace() << "\t" << "CleanupGeneric" << "\t\t" << instr->cleanup.reg;
- break;
- case Instr::ConvertGenericToReal:
- qWarning().nospace() << "\t" << "ConvertGenericToReal" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
- break;
- case Instr::ConvertGenericToBool:
- qWarning().nospace() << "\t" << "ConvertGenericToBool" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
- break;
- case Instr::ConvertGenericToString:
- qWarning().nospace() << "\t" << "ConvertGenericToString" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
- break;
- case Instr::ConvertGenericToUrl:
- qWarning().nospace() << "\t" << "ConvertGenericToUrl" << "\t" << instr->unaryop.output << "\t" << instr->unaryop.src;
- break;
- default:
- qWarning().nospace() << "\t" << "Unknown";
- break;
- }
-}
-
-void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
- QDeclarativeContextData *context, QDeclarativeDelayedError *error,
- QObject *scope, QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags)
-{
- Q_Q(QDeclarativeCompiledBindings);
-
- error->removeError();
-
- Register registers[32];
-
- QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(context->engine);
- Program *program = (Program *)programData;
- const Instr *instr = program->instructions();
- instr += instrIndex;
- const char *data = program->data();
-
-#ifdef QML_THREADED_INTERPRETER
- static void *decode_instr[] = {
- FOR_EACH_QML_INSTR(QML_INSTR_ADDR)
- };
-
- if (!program->compiled) {
- program->compiled = true;
- const Instr *inop = program->instructions();
- for (int i = 0; i < program->instructionCount; ++i) {
- Instr *op = (Instr *) inop++;
- op->common.code = decode_instr[op->common.type];
- }
- }
-
- goto *instr->common.code;
-#else
- // return;
-
-#ifdef COMPILEDBINDINGS_DEBUG
- qWarning().nospace() << "Begin binding run";
-#endif
-
- while (instr) {
- switch (instr->common.type) {
-
-#ifdef COMPILEDBINDINGS_DEBUG
- dumpInstruction(instr);
-#endif
-
-#endif
-
- QML_BEGIN_INSTR(Noop)
- QML_END_INSTR(Noop)
-
- QML_BEGIN_INSTR(BindingId)
- QML_END_INSTR(BindingId)
-
- QML_BEGIN_INSTR(SubscribeId)
- subscribeId(context, instr->subscribe.index, instr->subscribe.offset);
- QML_END_INSTR(SubscribeId)
-
- QML_BEGIN_INSTR(Subscribe)
- {
- QObject *o = 0;
- const Register &object = registers[instr->subscribe.reg];
- if (!object.isUndefined()) o = object.getQObject();
- subscribe(o, instr->subscribe.index, instr->subscribe.offset);
- }
- QML_END_INSTR(Subscribe)
-
- QML_BEGIN_INSTR(FetchAndSubscribe)
- {
- const Register &input = registers[instr->fetchAndSubscribe.objectReg];
- Register &output = registers[instr->fetchAndSubscribe.output];
-
- if (input.isUndefined()) {
- throwException(instr->fetchAndSubscribe.exceptionId, error, program, context);
- return;
- }
-
- QObject *object = input.getQObject();
- if (!object) {
- output.setUndefined();
- } else {
- int subIdx = instr->fetchAndSubscribe.subscription;
- QDeclarativeCompiledBindingsPrivate::Subscription *sub = 0;
- if (subIdx != -1) {
- sub = (subscriptions + subIdx);
- sub->target = q;
- sub->targetMethod = methodCount + subIdx;
- }
- fastProperties()->accessor(instr->fetchAndSubscribe.function)(object, output.typeDataPtr(), sub);
- }
- }
- QML_END_INSTR(FetchAndSubscribe)
-
- QML_BEGIN_INSTR(LoadId)
- registers[instr->load.reg].setQObject(context->idValues[instr->load.index].data());
- QML_END_INSTR(LoadId)
-
- QML_BEGIN_INSTR(LoadScope)
- registers[instr->load.reg].setQObject(scope);
- QML_END_INSTR(LoadScope)
-
- QML_BEGIN_INSTR(LoadRoot)
- registers[instr->load.reg].setQObject(context->contextObject);
- QML_END_INSTR(LoadRoot)
-
- QML_BEGIN_INSTR(LoadAttached)
- {
- const Register &input = registers[instr->attached.reg];
- Register &output = registers[instr->attached.output];
- if (input.isUndefined()) {
- throwException(instr->attached.exceptionId, error, program, context);
- return;
- }
-
- QObject *object = registers[instr->attached.reg].getQObject();
- if (!object) {
- output.setUndefined();
- } else {
- QObject *attached =
- qmlAttachedPropertiesObjectById(instr->attached.id,
- registers[instr->attached.reg].getQObject(),
- true);
- Q_ASSERT(attached);
- output.setQObject(attached);
- }
- }
- QML_END_INSTR(LoadAttached)
-
- QML_BEGIN_INSTR(ConvertIntToReal)
- {
- const Register &input = registers[instr->unaryop.src];
- Register &output = registers[instr->unaryop.output];
- if (input.isUndefined()) output.setUndefined();
- else output.setqreal(qreal(input.getint()));
- }
- QML_END_INSTR(ConvertIntToReal)
-
- QML_BEGIN_INSTR(ConvertRealToInt)
- {
- const Register &input = registers[instr->unaryop.src];
- Register &output = registers[instr->unaryop.output];
- if (input.isUndefined()) output.setUndefined();
- else output.setint(qRound(input.getqreal()));
- }
- QML_END_INSTR(ConvertRealToInt)
-
- QML_BEGIN_INSTR(Real)
- registers[instr->real_value.reg].setqreal(instr->real_value.value);
- QML_END_INSTR(Real)
-
- QML_BEGIN_INSTR(Int)
- registers[instr->int_value.reg].setint(instr->int_value.value);
- QML_END_INSTR(Int)
-
- QML_BEGIN_INSTR(Bool)
- registers[instr->bool_value.reg].setbool(instr->bool_value.value);
- QML_END_INSTR(Bool)
-
- QML_BEGIN_INSTR(String)
- {
- Register &output = registers[instr->string_value.reg];
- new (output.getstringptr())
- QString((QChar *)(data + instr->string_value.offset), instr->string_value.length);
- output.settype(QMetaType::QString);
- }
- QML_END_INSTR(String)
-
- QML_BEGIN_INSTR(AddReal)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
- else output.setqreal(lhs.getqreal() + rhs.getqreal());
- }
- QML_END_INSTR(AddReal)
-
- QML_BEGIN_INSTR(AddInt)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
- else output.setint(lhs.getint() + rhs.getint());
- }
- QML_END_INSTR(AddInt)
-
- QML_BEGIN_INSTR(AddString)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() && rhs.isUndefined()) { output.setNaN(); }
- else {
- if (lhs.isUndefined())
- new (output.getstringptr())
- QString(QLatin1String("undefined") + *registers[instr->binaryop.src2].getstringptr());
- else if (rhs.isUndefined())
- new (output.getstringptr())
- QString(*registers[instr->binaryop.src1].getstringptr() + QLatin1String("undefined"));
- else
- new (output.getstringptr())
- QString(*registers[instr->binaryop.src1].getstringptr() +
- *registers[instr->binaryop.src2].getstringptr());
- output.settype(QMetaType::QString);
- }
- }
- QML_END_INSTR(AddString)
-
- QML_BEGIN_INSTR(MinusReal)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
- else output.setqreal(lhs.getqreal() - rhs.getqreal());
- }
- QML_END_INSTR(MinusReal)
-
- QML_BEGIN_INSTR(MinusInt)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
- else output.setint(lhs.getint() - rhs.getint());
- }
- QML_END_INSTR(MinusInt)
-
- QML_BEGIN_INSTR(CompareReal)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() == rhs.isUndefined());
- else output.setbool(lhs.getqreal() == rhs.getqreal());
- }
- QML_END_INSTR(CompareReal)
-
- QML_BEGIN_INSTR(CompareString)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() == rhs.isUndefined());
- else output.setbool(*lhs.getstringptr() == *rhs.getstringptr());
- }
- QML_END_INSTR(CompareString)
-
- QML_BEGIN_INSTR(NotCompareReal)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() != rhs.isUndefined());
- else output.setbool(lhs.getqreal() != rhs.getqreal());
- }
- QML_END_INSTR(NotCompareReal)
-
- QML_BEGIN_INSTR(NotCompareString)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(lhs.isUndefined() != rhs.isUndefined());
- else output.setbool(*lhs.getstringptr() != *rhs.getstringptr());
- }
- QML_END_INSTR(NotCompareString)
-
- QML_BEGIN_INSTR(GreaterThanReal)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setbool(false);
- else output.setbool(lhs.getqreal() > rhs.getqreal());
- }
- QML_END_INSTR(GreaterThanReal)
-
- QML_BEGIN_INSTR(MaxReal)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
- else output.setqreal(qMax(lhs.getqreal(), rhs.getqreal()));
- }
- QML_END_INSTR(MaxReal)
-
- QML_BEGIN_INSTR(MinReal)
- {
- const Register &lhs = registers[instr->binaryop.src1];
- const Register &rhs = registers[instr->binaryop.src2];
- Register &output = registers[instr->binaryop.output];
- if (lhs.isUndefined() || rhs.isUndefined()) output.setNaN();
- else output.setqreal(qMin(lhs.getqreal(), rhs.getqreal()));
- }
- QML_END_INSTR(MinReal)
-
- QML_BEGIN_INSTR(NewString)
- {
- Register &output = registers[instr->construct.reg];
- new (output.getstringptr()) QString;
- output.settype(QMetaType::QString);
- }
- QML_END_INSTR(NewString)
-
- QML_BEGIN_INSTR(NewUrl)
- {
- Register &output = registers[instr->construct.reg];
- new (output.geturlptr()) QUrl;
- output.settype(QMetaType::QUrl);
- }
- QML_END_INSTR(NewUrl)
-
- QML_BEGIN_INSTR(CleanupString)
- registers[instr->cleanup.reg].getstringptr()->~QString();
-#ifdef REGISTER_CLEANUP_DEBUG
- registers[instr->cleanup.reg].setUndefined();
-#endif
- QML_END_INSTR(CleanupString)
-
- QML_BEGIN_INSTR(CleanupUrl)
- registers[instr->cleanup.reg].geturlptr()->~QUrl();
-#ifdef REGISTER_CLEANUP_DEBUG
- registers[instr->cleanup.reg].setUndefined();
-#endif
- QML_END_INSTR(CleanupUrl)
-
- QML_BEGIN_INSTR(Fetch)
- {
- const Register &input = registers[instr->fetch.objectReg];
- Register &output = registers[instr->fetch.output];
-
- if (input.isUndefined()) {
- throwException(instr->fetch.exceptionId, error, program, context);
- return;
- }
-
- QObject *object = input.getQObject();
- if (!object) {
- output.setUndefined();
- } else {
- void *argv[] = { output.typeDataPtr(), 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, instr->fetch.index, argv);
- }
- }
- QML_END_INSTR(Fetch)
-
- QML_BEGIN_INSTR(Store)
- {
- Register &data = registers[instr->store.reg];
- if (data.isUndefined()) {
- throwException(instr->store.exceptionId, error, program, context,
- QLatin1String("Unable to assign undefined value"));
- return;
- }
-
- int status = -1;
- void *argv[] = { data.typeDataPtr(), 0, &status, &storeFlags };
- QMetaObject::metacall(output, QMetaObject::WriteProperty,
- instr->store.index, argv);
- }
- QML_END_INSTR(Store)
-
- QML_BEGIN_INSTR(Copy)
- registers[instr->copy.reg] = registers[instr->copy.src];
- QML_END_INSTR(Copy)
-
- QML_BEGIN_INSTR(Skip)
- if (instr->skip.reg == -1 || !registers[instr->skip.reg].getbool())
- instr += instr->skip.count;
- QML_END_INSTR(Skip)
-
- QML_BEGIN_INSTR(Done)
- return;
- QML_END_INSTR(Done)
-
- QML_BEGIN_INSTR(InitString)
- if (!identifiers[instr->initstring.offset].identifier) {
- quint32 len = *(quint32 *)(data + instr->initstring.dataIdx);
- QChar *strdata = (QChar *)(data + instr->initstring.dataIdx + sizeof(quint32));
-
- QString str = QString::fromRawData(strdata, len);
-
- identifiers[instr->initstring.offset] = engine->objectClass->createPersistentIdentifier(str);
- }
- QML_END_INSTR(InitString)
-
- QML_BEGIN_INSTR(FindGenericTerminal)
- // We start the search in the parent context, as we know that the
- // name is not present in the current context or it would have been
- // found during the static compile
- findgeneric(registers + instr->find.reg, instr->find.subscribeIndex,
- context->parent,
- identifiers[instr->find.name].identifier,
- instr->common.type == Instr::FindGenericTerminal);
- QML_END_INSTR(FindGenericTerminal)
-
- QML_BEGIN_INSTR(FindGeneric)
- // We start the search in the parent context, as we know that the
- // name is not present in the current context or it would have been
- // found during the static compile
- findgeneric(registers + instr->find.reg, instr->find.subscribeIndex,
- context->parent,
- identifiers[instr->find.name].identifier,
- instr->common.type == Instr::FindGenericTerminal);
- QML_END_INSTR(FindGeneric)
-
- QML_BEGIN_INSTR(FindPropertyTerminal)
- {
- const Register &object = registers[instr->find.src];
- if (object.isUndefined()) {
- throwException(instr->find.exceptionId, error, program, context);
- return;
- }
-
- findproperty(object.getQObject(), registers + instr->find.reg,
- QDeclarativeEnginePrivate::get(context->engine),
- instr->find.subscribeIndex, identifiers[instr->find.name].identifier,
- instr->common.type == Instr::FindPropertyTerminal);
- }
- QML_END_INSTR(FindPropertyTerminal)
-
- QML_BEGIN_INSTR(FindProperty)
- {
- const Register &object = registers[instr->find.src];
- if (object.isUndefined()) {
- throwException(instr->find.exceptionId, error, program, context);
- return;
- }
-
- findproperty(object.getQObject(), registers + instr->find.reg,
- QDeclarativeEnginePrivate::get(context->engine),
- instr->find.subscribeIndex, identifiers[instr->find.name].identifier,
- instr->common.type == Instr::FindPropertyTerminal);
- }
- QML_END_INSTR(FindProperty)
-
- QML_BEGIN_INSTR(CleanupGeneric)
- {
- int type = registers[instr->cleanup.reg].gettype();
- if (type == qMetaTypeId<QVariant>()) {
- registers[instr->cleanup.reg].getvariantptr()->~QVariant();
-#ifdef REGISTER_CLEANUP_DEBUG
- registers[instr->cleanup.reg].setUndefined();
-#endif
- } else if (type == QMetaType::QString) {
- registers[instr->cleanup.reg].getstringptr()->~QString();
-#ifdef REGISTER_CLEANUP_DEBUG
- registers[instr->cleanup.reg].setUndefined();
-#endif
- } else if (type == QMetaType::QUrl) {
- registers[instr->cleanup.reg].geturlptr()->~QUrl();
-#ifdef REGISTER_CLEANUP_DEBUG
- registers[instr->cleanup.reg].setUndefined();
-#endif
- }
- }
- QML_END_INSTR(CleanupGeneric)
-
- QML_BEGIN_INSTR(ConvertGenericToReal)
- {
- Register &output = registers[instr->unaryop.output];
- Register &input = registers[instr->unaryop.src];
- bool ok = true;
- output.setqreal(toReal(&input, input.gettype(), &ok));
- if (!ok) output.setUndefined();
- }
- QML_END_INSTR(ConvertGenericToReal)
-
- QML_BEGIN_INSTR(ConvertGenericToBool)
- {
- Register &output = registers[instr->unaryop.output];
- Register &input = registers[instr->unaryop.src];
- bool ok = true;
- output.setbool(toBool(&input, input.gettype(), &ok));
- if (!ok) output.setUndefined();
- }
- QML_END_INSTR(ConvertGenericToBool)
-
- QML_BEGIN_INSTR(ConvertGenericToString)
- {
- Register &output = registers[instr->unaryop.output];
- Register &input = registers[instr->unaryop.src];
- bool ok = true;
- QString str = toString(&input, input.gettype(), &ok);
- if (ok) { new (output.getstringptr()) QString(str); output.settype(QMetaType::QString); }
- else { output.setUndefined(); }
- }
- QML_END_INSTR(ConvertGenericToString)
-
- QML_BEGIN_INSTR(ConvertGenericToUrl)
- {
- Register &output = registers[instr->unaryop.output];
- Register &input = registers[instr->unaryop.src];
- bool ok = true;
- QUrl url = toUrl(&input, input.gettype(), context, &ok);
- if (ok) { new (output.geturlptr()) QUrl(url); output.settype(QMetaType::QUrl); }
- else { output.setUndefined(); }
- }
- QML_END_INSTR(ConvertGenericToUrl)
-
-#ifdef QML_THREADED_INTERPRETER
- // nothing to do
-#else
- default:
- qFatal("EEK");
- break;
- } // switch
-
- ++instr;
- } // while
-#endif
-}
-
-void QDeclarativeBindingCompiler::dump(const QByteArray &programData)
-{
- const Program *program = (const Program *)programData.constData();
-
- qWarning() << "Program.bindings:" << program->bindings;
- qWarning() << "Program.dataLength:" << program->dataLength;
- qWarning() << "Program.subscriptions:" << program->subscriptions;
- qWarning() << "Program.indentifiers:" << program->identifiers;
-
- int count = program->instructionCount;
- const Instr *instr = program->instructions();
-
- while (count--) {
-
- dumpInstruction(instr);
- ++instr;
- }
-}
-
-/*!
-Clear the state associated with attempting to compile a specific binding.
-This does not clear the global "committed binding" states.
-*/
-void QDeclarativeBindingCompilerPrivate::resetInstanceState()
-{
- registers = 0;
- registerCleanups.clear();
- data = committed.data;
- exceptions = committed.exceptions;
- usedSubscriptionIds.clear();
- subscriptionSet.clear();
- subscriptionIds = committed.subscriptionIds;
- registeredStrings = committed.registeredStrings;
- bytecode.clear();
-}
-
-/*!
-Mark the last compile as successful, and add it to the "committed data"
-section.
-
-Returns the index for the committed binding.
-*/
-int QDeclarativeBindingCompilerPrivate::commitCompile()
-{
- int rv = committed.count();
- committed.offsets << committed.bytecode.count();
- committed.dependencies << usedSubscriptionIds;
- committed.bytecode << bytecode;
- committed.data = data;
- committed.exceptions = exceptions;
- committed.subscriptionIds = subscriptionIds;
- committed.registeredStrings = registeredStrings;
- return rv;
-}
-
-bool QDeclarativeBindingCompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
-{
- resetInstanceState();
-
- if (destination->type == -1)
- return false;
-
- if (bindingsDump()) {
- QDeclarativeJS::AST::ExpressionNode *n = node->expressionCast();
- if (n) {
- Instr id;
- id.common.type = Instr::BindingId;
- id.id.column = n->firstSourceLocation().startColumn;
- id.id.line = n->firstSourceLocation().startLine;
- bytecode << id;
- }
- }
-
- Result type;
-
- if (!parseExpression(node, type))
- return false;
-
- if (subscriptionSet.count() > 0xFFFF ||
- registeredStrings.count() > 0xFFFF)
- return false;
-
- if (type.unknownType) {
- if (!qmlExperimental())
- return false;
-
- if (destination->type != QMetaType::QReal &&
- destination->type != QVariant::String &&
- destination->type != QMetaType::Bool &&
- destination->type != QVariant::Url)
- return false;
-
- int convertReg = acquireReg();
- if (convertReg == -1)
- return false;
-
- if (destination->type == QMetaType::QReal) {
- Instr convert;
- convert.common.type = Instr::ConvertGenericToReal;
- convert.unaryop.output = convertReg;
- convert.unaryop.src = type.reg;
- bytecode << convert;
- } else if (destination->type == QVariant::String) {
- Instr convert;
- convert.common.type = Instr::ConvertGenericToString;
- convert.unaryop.output = convertReg;
- convert.unaryop.src = type.reg;
- bytecode << convert;
- } else if (destination->type == QMetaType::Bool) {
- Instr convert;
- convert.common.type = Instr::ConvertGenericToBool;
- convert.unaryop.output = convertReg;
- convert.unaryop.src = type.reg;
- bytecode << convert;
- } else if (destination->type == QVariant::Url) {
- Instr convert;
- convert.common.type = Instr::ConvertGenericToUrl;
- convert.unaryop.output = convertReg;
- convert.unaryop.src = type.reg;
- bytecode << convert;
- }
-
- Instr cleanup;
- cleanup.common.type = Instr::CleanupGeneric;
- cleanup.cleanup.reg = type.reg;
- bytecode << cleanup;
-
- Instr instr;
- instr.common.type = Instr::Store;
- instr.store.output = 0;
- instr.store.index = destination->index;
- instr.store.reg = convertReg;
- instr.store.exceptionId = exceptionId(node->expressionCast());
- bytecode << instr;
-
- if (destination->type == QVariant::String) {
- Instr cleanup;
- cleanup.common.type = Instr::CleanupString;
- cleanup.cleanup.reg = convertReg;
- bytecode << cleanup;
- } else if (destination->type == QVariant::Url) {
- Instr cleanup;
- cleanup.common.type = Instr::CleanupUrl;
- cleanup.cleanup.reg = convertReg;
- bytecode << cleanup;
- }
-
- releaseReg(convertReg);
-
- Instr done;
- done.common.type = Instr::Done;
- bytecode << done;
-
- } else {
- // Can we store the final value?
- if (type.type == QVariant::Int &&
- destination->type == QMetaType::QReal) {
- Instr instr;
- instr.common.type = Instr::ConvertIntToReal;
- instr.unaryop.output = type.reg;
- instr.unaryop.src = type.reg;
- bytecode << instr;
- type.type = QMetaType::QReal;
- } else if (type.type == QMetaType::QReal &&
- destination->type == QVariant::Int) {
- Instr instr;
- instr.common.type = Instr::ConvertRealToInt;
- instr.unaryop.output = type.reg;
- instr.unaryop.src = type.reg;
- bytecode << instr;
- type.type = QVariant::Int;
- } else if (type.type == destination->type) {
- } else {
- const QMetaObject *from = type.metaObject;
- const QMetaObject *to = engine->rawMetaObjectForType(destination->type);
-
- if (QDeclarativePropertyPrivate::canConvert(from, to))
- type.type = destination->type;
- }
-
- if (type.type == destination->type) {
- Instr instr;
- instr.common.type = Instr::Store;
- instr.store.output = 0;
- instr.store.index = destination->index;
- instr.store.reg = type.reg;
- instr.store.exceptionId = exceptionId(node->expressionCast());
- bytecode << instr;
-
- releaseReg(type.reg);
-
- Instr done;
- done.common.type = Instr::Done;
- bytecode << done;
- } else {
- return false;
- }
- }
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::parseExpression(QDeclarativeJS::AST::Node *node, Result &type)
-{
- while (node->kind == AST::Node::Kind_NestedExpression)
- node = static_cast<AST::NestedExpression *>(node)->expression;
-
- if (tryArith(node)) {
- if (!parseArith(node, type)) return false;
- } else if (tryLogic(node)) {
- if (!parseLogic(node, type)) return false;
- } else if (tryConditional(node)) {
- if (!parseConditional(node, type)) return false;
- } else if (tryName(node)) {
- if (!parseName(node, type)) return false;
- } else if (tryConstant(node)) {
- if (!parseConstant(node, type)) return false;
- } else if (tryMethod(node)) {
- if (!parseMethod(node, type)) return false;
- } else {
- return false;
- }
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::tryName(QDeclarativeJS::AST::Node *node)
-{
- return node->kind == AST::Node::Kind_IdentifierExpression ||
- node->kind == AST::Node::Kind_FieldMemberExpression;
-}
-
-bool QDeclarativeBindingCompilerPrivate::parseName(AST::Node *node, Result &type)
-{
- QStringList nameParts;
- QList<AST::ExpressionNode *> nameNodes;
- if (!buildName(nameParts, node, &nameNodes))
- return false;
-
- int reg = acquireReg();
- if (reg == -1)
- return false;
- type.reg = reg;
-
- QDeclarativeParser::Object *absType = 0;
-
- QStringList subscribeName;
-
- bool wasAttachedObject = false;
-
- for (int ii = 0; ii < nameParts.count(); ++ii) {
- const QString &name = nameParts.at(ii);
-
- // We don't handle signal properties or attached properties
- if (name.length() > 2 && name.startsWith(QLatin1String("on")) &&
- name.at(2).isUpper())
- return false;
-
- QDeclarativeType *attachType = 0;
- if (name.at(0).isUpper()) {
- // Could be an attached property
- if (ii == nameParts.count() - 1)
- return false;
- if (nameParts.at(ii + 1).at(0).isUpper())
- return false;
-
- QDeclarativeImportedNamespace *ns = 0;
- if (!imports.resolveType(name.toUtf8(), &attachType, 0, 0, 0, &ns))
- return false;
- if (ns || !attachType || !attachType->attachedPropertiesType())
- return false;
-
- wasAttachedObject = true;
- }
-
- if (ii == 0) {
-
- if (attachType) {
- Instr instr;
- instr.common.type = Instr::LoadScope;
- instr.load.index = 0;
- instr.load.reg = reg;
- bytecode << instr;
-
- Instr attach;
- attach.common.type = Instr::LoadAttached;
- attach.attached.output = reg;
- attach.attached.reg = reg;
- attach.attached.id = attachType->attachedPropertiesId();
- attach.attached.exceptionId = exceptionId(nameNodes.at(ii));
- bytecode << attach;
-
- subscribeName << contextName();
- subscribeName << QLatin1String("$$$ATTACH_") + name;
-
- absType = 0;
- type.metaObject = attachType->attachedPropertiesType();
-
- continue;
- } else if (ids.contains(name)) {
- QDeclarativeParser::Object *idObject = ids.value(name);
- absType = idObject;
- type.metaObject = absType->metaObject();
-
- // We check if the id object is the root or
- // scope object to avoid a subscription
- if (idObject == component) {
- Instr instr;
- instr.common.type = Instr::LoadRoot;
- instr.load.index = 0;
- instr.load.reg = reg;
- bytecode << instr;
- } else if (idObject == context) {
- Instr instr;
- instr.common.type = Instr::LoadScope;
- instr.load.index = 0;
- instr.load.reg = reg;
- bytecode << instr;
- } else {
- Instr instr;
- instr.common.type = Instr::LoadId;
- instr.load.index = idObject->idIndex;
- instr.load.reg = reg;
- bytecode << instr;
-
- subscribeName << QLatin1String("$$$ID_") + name;
-
- if (subscription(subscribeName, &type)) {
- Instr sub;
- sub.common.type = Instr::SubscribeId;
- sub.subscribe.offset = subscriptionIndex(subscribeName);
- sub.subscribe.reg = reg;
- sub.subscribe.index = instr.load.index;
- bytecode << sub;
- }
- }
-
- } else {
-
- QByteArray utf8Name = name.toUtf8();
- const char *cname = utf8Name.constData();
-
- int d0Idx = (context == component)?-1:context->metaObject()->indexOfProperty(cname);
- int d1Idx = -1;
- if (d0Idx == -1)
- d1Idx = component->metaObject()->indexOfProperty(cname);
-
- if (d0Idx != -1) {
- Instr instr;
- instr.common.type = Instr::LoadScope;
- instr.load.index = 0;
- instr.load.reg = reg;
- bytecode << instr;
-
- subscribeName << contextName();
- subscribeName << name;
-
- if (!fetch(type, context->metaObject(), reg, d0Idx, subscribeName, nameNodes.at(ii)))
- return false;
- } else if(d1Idx != -1) {
- Instr instr;
- instr.common.type = Instr::LoadRoot;
- instr.load.index = 0;
- instr.load.reg = reg;
- bytecode << instr;
-
- subscribeName << QLatin1String("$$$ROOT");
- subscribeName << name;
-
- if (!fetch(type, component->metaObject(), reg, d1Idx, subscribeName, nameNodes.at(ii)))
- return false;
- } else if (qmlExperimental()) {
- Instr find;
- if (nameParts.count() == 1)
- find.common.type = Instr::FindGenericTerminal;
- else
- find.common.type = Instr::FindGeneric;
-
- find.find.reg = reg;
- find.find.src = -1;
- find.find.name = registerString(name);
- find.find.exceptionId = exceptionId(nameNodes.at(ii));
-
- subscribeName << QString(QLatin1String("$$$Generic_") + name);
- if (subscription(subscribeName, &type))
- find.find.subscribeIndex = subscriptionIndex(subscribeName);
- else
- find.find.subscribeIndex = -1;
-
- bytecode << find;
- type.unknownType = true;
- }
-
- if (!type.unknownType && type.type == -1)
- return false; // Couldn't fetch that type
- }
-
- } else {
-
- if (attachType) {
- Instr attach;
- attach.common.type = Instr::LoadAttached;
- attach.attached.output = reg;
- attach.attached.reg = reg;
- attach.attached.id = attachType->attachedPropertiesId();
- bytecode << attach;
-
- absType = 0;
- type.metaObject = attachType->attachedPropertiesType();
-
- subscribeName << QLatin1String("$$$ATTACH_") + name;
- continue;
- }
-
- const QMetaObject *mo = 0;
- if (absType)
- mo = absType->metaObject();
- else if (type.metaObject)
- mo = type.metaObject;
-
- QByteArray utf8Name = name.toUtf8();
- const char *cname = utf8Name.constData();
- int idx = mo?mo->indexOfProperty(cname):-1;
- if (absType && idx == -1)
- return false;
-
- subscribeName << name;
-
- if (absType || (wasAttachedObject && idx != -1) || (mo && mo->property(idx).isFinal())) {
- absType = 0;
- if (!fetch(type, mo, reg, idx, subscribeName, nameNodes.at(ii)))
- return false;
- } else {
-
- Instr prop;
- if (ii == nameParts.count() -1 )
- prop.common.type = Instr::FindPropertyTerminal;
- else
- prop.common.type = Instr::FindProperty;
-
- prop.find.reg = reg;
- prop.find.src = reg;
- prop.find.name = registerString(name);
- prop.find.exceptionId = exceptionId(nameNodes.at(ii));
-
- if (subscription(subscribeName, &type))
- prop.find.subscribeIndex = subscriptionIndex(subscribeName);
- else
- prop.find.subscribeIndex = -1;
-
- type.unknownType = true;
- type.metaObject = 0;
- type.type = -1;
- type.reg = reg;
- bytecode << prop;
- }
- }
-
- wasAttachedObject = false;
- }
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::tryArith(QDeclarativeJS::AST::Node *node)
-{
- if (node->kind != AST::Node::Kind_BinaryExpression)
- return false;
-
- AST::BinaryExpression *expression = static_cast<AST::BinaryExpression *>(node);
- if (expression->op == QSOperator::Add ||
- expression->op == QSOperator::Sub)
- return true;
- else
- return false;
-}
-
-bool QDeclarativeBindingCompilerPrivate::parseArith(QDeclarativeJS::AST::Node *node, Result &type)
-{
- AST::BinaryExpression *expression = static_cast<AST::BinaryExpression *>(node);
-
- type.reg = acquireReg();
- if (type.reg == -1)
- return false;
-
- Result lhs;
- Result rhs;
-
- if (!parseExpression(expression->left, lhs)) return false;
- if (!parseExpression(expression->right, rhs)) return false;
-
- if ((lhs.type == QVariant::Int || lhs.type == QMetaType::QReal) &&
- (rhs.type == QVariant::Int || rhs.type == QMetaType::QReal))
- return numberArith(type, lhs, rhs, (QSOperator::Op)expression->op);
- else if(expression->op == QSOperator::Sub)
- return numberArith(type, lhs, rhs, (QSOperator::Op)expression->op);
- else if ((lhs.type == QMetaType::QString || lhs.unknownType) &&
- (rhs.type == QMetaType::QString || rhs.unknownType) &&
- (lhs.type == QMetaType::QString || rhs.type == QMetaType::QString))
- return stringArith(type, lhs, rhs, (QSOperator::Op)expression->op);
- else
- return false;
-}
-
-bool QDeclarativeBindingCompilerPrivate::numberArith(Result &type, const Result &lhs, const Result &rhs, QSOperator::Op op)
-{
- bool nativeReal = rhs.type == QMetaType::QReal ||
- lhs.type == QMetaType::QReal ||
- lhs.unknownType ||
- rhs.unknownType;
-
- if (nativeReal && lhs.type == QMetaType::Int) {
- Instr convert;
- convert.common.type = Instr::ConvertIntToReal;
- convert.unaryop.output = lhs.reg;
- convert.unaryop.src = lhs.reg;
- bytecode << convert;
- }
-
- if (nativeReal && rhs.type == QMetaType::Int) {
- Instr convert;
- convert.common.type = Instr::ConvertIntToReal;
- convert.unaryop.output = rhs.reg;
- convert.unaryop.src = rhs.reg;
- bytecode << convert;
- }
-
- int lhsTmp = -1;
- int rhsTmp = -1;
-
- if (lhs.unknownType) {
- if (!qmlExperimental())
- return false;
-
- lhsTmp = acquireReg();
- if (lhsTmp == -1)
- return false;
-
- Instr conv;
- conv.common.type = Instr::ConvertGenericToReal;
- conv.unaryop.output = lhsTmp;
- conv.unaryop.src = lhs.reg;
- bytecode << conv;
- }
-
- if (rhs.unknownType) {
- if (!qmlExperimental())
- return false;
-
- rhsTmp = acquireReg();
- if (rhsTmp == -1)
- return false;
-
- Instr conv;
- conv.common.type = Instr::ConvertGenericToReal;
- conv.unaryop.output = rhsTmp;
- conv.unaryop.src = rhs.reg;
- bytecode << conv;
- }
-
- Instr arith;
- if (op == QSOperator::Add) {
- arith.common.type = nativeReal?Instr::AddReal:Instr::AddInt;
- } else if (op == QSOperator::Sub) {
- arith.common.type = nativeReal?Instr::MinusReal:Instr::MinusInt;
- } else {
- qFatal("Unsupported arithmetic operator");
- }
-
- arith.binaryop.output = type.reg;
- arith.binaryop.src1 = (lhsTmp == -1)?lhs.reg:lhsTmp;
- arith.binaryop.src2 = (rhsTmp == -1)?rhs.reg:rhsTmp;
- bytecode << arith;
-
- type.metaObject = 0;
- type.type = nativeReal?QMetaType::QReal:QMetaType::Int;
- type.subscriptionSet.unite(lhs.subscriptionSet);
- type.subscriptionSet.unite(rhs.subscriptionSet);
-
- if (lhsTmp != -1) releaseReg(lhsTmp);
- if (rhsTmp != -1) releaseReg(rhsTmp);
- releaseReg(lhs.reg);
- releaseReg(rhs.reg);
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::stringArith(Result &type, const Result &lhs, const Result &rhs, QSOperator::Op op)
-{
- if (op != QSOperator::Add)
- return false;
-
- int lhsTmp = -1;
- int rhsTmp = -1;
-
- if (lhs.unknownType) {
- if (!qmlExperimental())
- return false;
-
- lhsTmp = acquireReg(Instr::CleanupString);
- if (lhsTmp == -1)
- return false;
-
- Instr convert;
- convert.common.type = Instr::ConvertGenericToString;
- convert.unaryop.output = lhsTmp;
- convert.unaryop.src = lhs.reg;
- bytecode << convert;
- }
-
- if (rhs.unknownType) {
- if (!qmlExperimental())
- return false;
-
- rhsTmp = acquireReg(Instr::CleanupString);
- if (rhsTmp == -1)
- return false;
-
- Instr convert;
- convert.common.type = Instr::ConvertGenericToString;
- convert.unaryop.output = rhsTmp;
- convert.unaryop.src = rhs.reg;
- bytecode << convert;
- }
-
- type.reg = acquireReg(Instr::CleanupString);
- if (type.reg == -1)
- return false;
-
- type.type = QMetaType::QString;
-
- Instr add;
- add.common.type = Instr::AddString;
- add.binaryop.output = type.reg;
- add.binaryop.src1 = (lhsTmp == -1)?lhs.reg:lhsTmp;
- add.binaryop.src2 = (rhsTmp == -1)?rhs.reg:rhsTmp;
- bytecode << add;
-
- if (lhsTmp != -1) releaseReg(lhsTmp);
- if (rhsTmp != -1) releaseReg(rhsTmp);
- releaseReg(lhs.reg);
- releaseReg(rhs.reg);
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::tryLogic(QDeclarativeJS::AST::Node *node)
-{
- if (node->kind != AST::Node::Kind_BinaryExpression)
- return false;
-
- AST::BinaryExpression *expression = static_cast<AST::BinaryExpression *>(node);
- if (expression->op == QSOperator::Gt ||
- expression->op == QSOperator::Equal ||
- expression->op == QSOperator::NotEqual)
- return true;
- else
- return false;
-}
-
-bool QDeclarativeBindingCompilerPrivate::parseLogic(QDeclarativeJS::AST::Node *node, Result &type)
-{
- AST::BinaryExpression *expression = static_cast<AST::BinaryExpression *>(node);
-
- Result lhs;
- Result rhs;
-
- if (!parseExpression(expression->left, lhs)) return false;
- if (!parseExpression(expression->right, rhs)) return false;
-
- type.reg = acquireReg();
- if (type.reg == -1)
- return false;
-
- type.metaObject = 0;
- type.type = QVariant::Bool;
-
- if (lhs.type == QMetaType::QReal && rhs.type == QMetaType::QReal) {
-
- Instr op;
- if (expression->op == QSOperator::Gt)
- op.common.type = Instr::GreaterThanReal;
- else if (expression->op == QSOperator::Equal)
- op.common.type = Instr::CompareReal;
- else if (expression->op == QSOperator::NotEqual)
- op.common.type = Instr::NotCompareReal;
- else
- return false;
- op.binaryop.output = type.reg;
- op.binaryop.src1 = lhs.reg;
- op.binaryop.src2 = rhs.reg;
- bytecode << op;
-
-
- } else if (lhs.type == QMetaType::QString && rhs.type == QMetaType::QString) {
-
- Instr op;
- if (expression->op == QSOperator::Equal)
- op.common.type = Instr::CompareString;
- else if (expression->op == QSOperator::NotEqual)
- op.common.type = Instr::NotCompareString;
- else
- return false;
- op.binaryop.output = type.reg;
- op.binaryop.src1 = lhs.reg;
- op.binaryop.src2 = rhs.reg;
- bytecode << op;
-
- } else {
- return false;
- }
-
- releaseReg(lhs.reg);
- releaseReg(rhs.reg);
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::tryConditional(QDeclarativeJS::AST::Node *node)
-{
- return (node->kind == AST::Node::Kind_ConditionalExpression);
-}
-
-bool QDeclarativeBindingCompilerPrivate::parseConditional(QDeclarativeJS::AST::Node *node, Result &type)
-{
- AST::ConditionalExpression *expression = static_cast<AST::ConditionalExpression *>(node);
-
- AST::Node *test = expression->expression;
- if (test->kind == AST::Node::Kind_NestedExpression)
- test = static_cast<AST::NestedExpression*>(test)->expression;
-
- Result etype;
- if (!parseExpression(test, etype)) return false;
-
- if (etype.type != QVariant::Bool)
- return false;
-
- Instr skip;
- skip.common.type = Instr::Skip;
- skip.skip.reg = etype.reg;
- skip.skip.count = 0;
- int skipIdx = bytecode.count();
- bytecode << skip;
-
- // Release to allow reuse of reg
- releaseReg(etype.reg);
-
- QSet<QString> preSubSet = subscriptionSet;
-
- // int preConditionalSubscriptions = subscriptionSet.count();
-
- Result ok;
- if (!parseExpression(expression->ok, ok)) return false;
- if (ok.unknownType) return false;
-
- int skipIdx2 = bytecode.count();
- skip.skip.reg = -1;
- bytecode << skip;
-
- // Release to allow reuse of reg
- releaseReg(ok.reg);
- bytecode[skipIdx].skip.count = bytecode.count() - skipIdx - 1;
-
- subscriptionSet = preSubSet;
-
- Result ko;
- if (!parseExpression(expression->ko, ko)) return false;
- if (ko.unknownType) return false;
-
- // Release to allow reuse of reg
- releaseReg(ko.reg);
- bytecode[skipIdx2].skip.count = bytecode.count() - skipIdx2 - 1;
-
- if (ok != ko)
- return false; // Must be same type and in same register
-
- subscriptionSet = preSubSet;
-
- if (!subscriptionNeutral(subscriptionSet, ok.subscriptionSet, ko.subscriptionSet))
- return false; // Conditionals cannot introduce new subscriptions
-
- type = ok;
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::tryConstant(QDeclarativeJS::AST::Node *node)
-{
- return node->kind == AST::Node::Kind_TrueLiteral ||
- node->kind == AST::Node::Kind_FalseLiteral ||
- node->kind == AST::Node::Kind_NumericLiteral ||
- node->kind == AST::Node::Kind_StringLiteral;
-}
-
-bool QDeclarativeBindingCompilerPrivate::parseConstant(QDeclarativeJS::AST::Node *node, Result &type)
-{
- type.metaObject = 0;
- type.type = -1;
- type.reg = acquireReg();
- if (type.reg == -1)
- return false;
-
- if (node->kind == AST::Node::Kind_TrueLiteral) {
- type.type = QVariant::Bool;
- Instr instr;
- instr.common.type = Instr::Bool;
- instr.bool_value.reg = type.reg;
- instr.bool_value.value = true;
- bytecode << instr;
- return true;
- } else if (node->kind == AST::Node::Kind_FalseLiteral) {
- type.type = QVariant::Bool;
- Instr instr;
- instr.common.type = Instr::Bool;
- instr.bool_value.reg = type.reg;
- instr.bool_value.value = false;
- bytecode << instr;
- return true;
- } else if (node->kind == AST::Node::Kind_NumericLiteral) {
- qreal value = qreal(static_cast<AST::NumericLiteral *>(node)->value);
-
- if (qreal(float(value)) != value)
- return false;
-
- type.type = QMetaType::QReal;
- Instr instr;
- instr.common.type = Instr::Real;
- instr.real_value.reg = type.reg;
- instr.real_value.value = float(value);
- bytecode << instr;
- return true;
- } else if (node->kind == AST::Node::Kind_StringLiteral) {
- QString str = static_cast<AST::StringLiteral *>(node)->value->asString();
- type.type = QMetaType::QString;
- type.reg = registerLiteralString(str);
- return true;
- } else {
- return false;
- }
-}
-
-bool QDeclarativeBindingCompilerPrivate::tryMethod(QDeclarativeJS::AST::Node *node)
-{
- return node->kind == AST::Node::Kind_CallExpression;
-}
-
-bool QDeclarativeBindingCompilerPrivate::parseMethod(QDeclarativeJS::AST::Node *node, Result &result)
-{
- AST::CallExpression *expr = static_cast<AST::CallExpression *>(node);
-
- QStringList name;
- if (!buildName(name, expr->base))
- return false;
-
- if (name.count() != 2 || name.at(0) != QLatin1String("Math"))
- return false;
-
- QString method = name.at(1);
-
- AST::ArgumentList *args = expr->arguments;
- if (!args) return false;
- AST::ExpressionNode *arg0 = args->expression;
- args = args->next;
- if (!args) return false;
- AST::ExpressionNode *arg1 = args->expression;
- if (args->next != 0) return false;
- if (!arg0 || !arg1) return false;
-
- Result r0;
- if (!parseExpression(arg0, r0)) return false;
- Result r1;
- if (!parseExpression(arg1, r1)) return false;
-
- if (r0.type != QMetaType::QReal || r1.type != QMetaType::QReal)
- return false;
-
- Instr op;
- if (method == QLatin1String("max")) {
- op.common.type = Instr::MaxReal;
- } else if (method == QLatin1String("min")) {
- op.common.type = Instr::MinReal;
- } else {
- return false;
- }
- // We release early to reuse registers
- releaseReg(r0.reg);
- releaseReg(r1.reg);
-
- op.binaryop.output = acquireReg();
- if (op.binaryop.output == -1)
- return false;
-
- op.binaryop.src1 = r0.reg;
- op.binaryop.src2 = r1.reg;
- bytecode << op;
-
- result.type = QMetaType::QReal;
- result.reg = op.binaryop.output;
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::buildName(QStringList &name,
- QDeclarativeJS::AST::Node *node,
- QList<QDeclarativeJS::AST::ExpressionNode *> *nodes)
-{
- if (node->kind == AST::Node::Kind_IdentifierExpression) {
- name << static_cast<AST::IdentifierExpression*>(node)->name->asString();
- if (nodes) *nodes << static_cast<AST::IdentifierExpression*>(node);
- } else if (node->kind == AST::Node::Kind_FieldMemberExpression) {
- AST::FieldMemberExpression *expr =
- static_cast<AST::FieldMemberExpression *>(node);
-
- if (!buildName(name, expr->base, nodes))
- return false;
-
- name << expr->name->asString();
- if (nodes) *nodes << expr;
- } else {
- return false;
- }
-
- return true;
-}
-
-bool QDeclarativeBindingCompilerPrivate::fetch(Result &rv, const QMetaObject *mo, int reg,
- int idx, const QStringList &subName,
- QDeclarativeJS::AST::ExpressionNode *node)
-{
- QMetaProperty prop = mo->property(idx);
- rv.metaObject = 0;
- rv.type = 0;
-
- //XXX binding optimizer doesn't handle properties with a revision
- if (prop.revision() > 0)
- return false;
-
- int fastFetchIndex = fastProperties()->accessorIndexForProperty(mo, idx);
-
- Instr fetch;
-
- if (!qmlDisableFastProperties() && fastFetchIndex != -1) {
- fetch.common.type = Instr::FetchAndSubscribe;
- fetch.fetchAndSubscribe.objectReg = reg;
- fetch.fetchAndSubscribe.output = reg;
- fetch.fetchAndSubscribe.function = fastFetchIndex;
- fetch.fetchAndSubscribe.subscription = subscriptionIndex(subName);
- fetch.fetchAndSubscribe.exceptionId = exceptionId(node);
- } else {
- if (subscription(subName, &rv) && prop.hasNotifySignal() && prop.notifySignalIndex() != -1) {
- Instr sub;
- sub.common.type = Instr::Subscribe;
- sub.subscribe.offset = subscriptionIndex(subName);
- sub.subscribe.reg = reg;
- sub.subscribe.index = prop.notifySignalIndex();
- bytecode << sub;
- }
-
- fetch.common.type = Instr::Fetch;
- fetch.fetch.objectReg = reg;
- fetch.fetch.index = idx;
- fetch.fetch.output = reg;
- fetch.fetch.exceptionId = exceptionId(node);
- }
-
- rv.type = prop.userType();
- rv.metaObject = engine->metaObjectForType(rv.type);
- rv.reg = reg;
-
- if (rv.type == QMetaType::QString) {
- int tmp = acquireReg();
- if (tmp == -1)
- return false;
- Instr copy;
- copy.common.type = Instr::Copy;
- copy.copy.reg = tmp;
- copy.copy.src = reg;
- bytecode << copy;
- releaseReg(tmp);
- fetch.fetch.objectReg = tmp;
-
- Instr setup;
- setup.common.type = Instr::NewString;
- setup.construct.reg = reg;
- bytecode << setup;
- registerCleanup(reg, Instr::CleanupString);
- }
-
- bytecode << fetch;
-
- if (!rv.metaObject &&
- rv.type != QMetaType::QReal &&
- rv.type != QMetaType::Int &&
- rv.type != QMetaType::Bool &&
- rv.type != qMetaTypeId<QDeclarativeAnchorLine>() &&
- rv.type != QMetaType::QString) {
- rv.metaObject = 0;
- rv.type = 0;
- return false; // Unsupported type (string not supported yet);
- }
-
- return true;
-}
-
-void QDeclarativeBindingCompilerPrivate::registerCleanup(int reg, int cleanup, int cleanupType)
-{
- registerCleanups.insert(reg, qMakePair(cleanup, cleanupType));
-}
-
-int QDeclarativeBindingCompilerPrivate::acquireReg(int cleanup, int cleanupType)
-{
- for (int ii = 0; ii < 32; ++ii) {
- if (!(registers & (1 << ii))) {
- registers |= (1 << ii);
-
- if (cleanup != Instr::Noop)
- registerCleanup(ii, cleanup, cleanupType);
-
- return ii;
- }
- }
- return -1;
-}
-
-void QDeclarativeBindingCompilerPrivate::releaseReg(int reg)
-{
- Q_ASSERT(reg >= 0 && reg <= 31);
-
- if (registerCleanups.contains(reg)) {
- QPair<int, int> c = registerCleanups[reg];
- registerCleanups.remove(reg);
- Instr cleanup;
- cleanup.common.type = (quint8)c.first;
- cleanup.cleanup.reg = reg;
- bytecode << cleanup;
- }
-
- quint32 mask = 1 << reg;
- registers &= ~mask;
-}
-
-// Returns a reg
-int QDeclarativeBindingCompilerPrivate::registerLiteralString(const QString &str)
-{
- QByteArray strdata((const char *)str.constData(), str.length() * sizeof(QChar));
- int offset = data.count();
- data += strdata;
-
- int reg = acquireReg(Instr::CleanupString);
- if (reg == -1)
- return false;
-
- Instr string;
- string.common.type = Instr::String;
- string.string_value.reg = reg;
- string.string_value.offset = offset;
- string.string_value.length = str.length();
- bytecode << string;
-
- return reg;
-}
-
-// Returns an identifier offset
-int QDeclarativeBindingCompilerPrivate::registerString(const QString &string)
-{
- Q_ASSERT(!string.isEmpty());
-
- QHash<QString, QPair<int, int> >::ConstIterator iter = registeredStrings.find(string);
-
- if (iter == registeredStrings.end()) {
- quint32 len = string.length();
- QByteArray lendata((const char *)&len, sizeof(quint32));
- QByteArray strdata((const char *)string.constData(), string.length() * sizeof(QChar));
- strdata.prepend(lendata);
- int rv = data.count();
- data += strdata;
-
- iter = registeredStrings.insert(string, qMakePair(registeredStrings.count(), rv));
- }
-
- Instr reg;
- reg.common.type = Instr::InitString;
- reg.initstring.offset = iter->first;
- reg.initstring.dataIdx = iter->second;
- bytecode << reg;
- return reg.initstring.offset;
-}
-
-bool QDeclarativeBindingCompilerPrivate::subscription(const QStringList &sub, Result *result)
-{
- QString str = sub.join(QLatin1String("."));
- result->subscriptionSet.insert(str);
-
- if (subscriptionSet.contains(str)) {
- return false;
- } else {
- subscriptionSet.insert(str);
- return true;
- }
-}
-
-int QDeclarativeBindingCompilerPrivate::subscriptionIndex(const QStringList &sub)
-{
- QString str = sub.join(QLatin1String("."));
- QHash<QString, int>::ConstIterator iter = subscriptionIds.find(str);
- if (iter == subscriptionIds.end())
- iter = subscriptionIds.insert(str, subscriptionIds.count());
- usedSubscriptionIds.insert(*iter);
- return *iter;
-}
-
-/*
- Returns true if lhs contains no subscriptions that aren't also in base or rhs AND
- rhs contains no subscriptions that aren't also in base or lhs.
-*/
-bool QDeclarativeBindingCompilerPrivate::subscriptionNeutral(const QSet<QString> &base,
- const QSet<QString> &lhs,
- const QSet<QString> &rhs)
-{
- QSet<QString> difflhs = lhs;
- difflhs.subtract(rhs);
- QSet<QString> diffrhs = rhs;
- diffrhs.subtract(lhs);
-
- difflhs.unite(diffrhs);
- difflhs.subtract(base);
-
- return difflhs.isEmpty();
-}
-
-quint8 QDeclarativeBindingCompilerPrivate::exceptionId(QDeclarativeJS::AST::ExpressionNode *n)
-{
- quint8 rv = 0xFF;
- if (n && exceptions.count() < 0xFF) {
- rv = (quint8)exceptions.count();
- QDeclarativeJS::AST::SourceLocation l = n->firstSourceLocation();
- quint64 e = l.startLine;
- e <<= 32;
- e |= l.startColumn;
- exceptions.append(e);
- }
- return rv;
-}
-
-QDeclarativeBindingCompiler::QDeclarativeBindingCompiler()
-: d(new QDeclarativeBindingCompilerPrivate)
-{
-}
-
-QDeclarativeBindingCompiler::~QDeclarativeBindingCompiler()
-{
- delete d; d = 0;
-}
-
-/*
-Returns true if any bindings were compiled.
-*/
-bool QDeclarativeBindingCompiler::isValid() const
-{
- return !d->committed.bytecode.isEmpty();
-}
-
-/*
--1 on failure, otherwise the binding index to use.
-*/
-int QDeclarativeBindingCompiler::compile(const Expression &expression, QDeclarativeEnginePrivate *engine)
-{
- if (!expression.expression.asAST()) return false;
-
- if (!qmlExperimental() && expression.property->isValueTypeSubProperty)
- return -1;
-
- if (qmlDisableOptimizer())
- return -1;
-
- d->context = expression.context;
- d->component = expression.component;
- d->destination = expression.property;
- d->ids = expression.ids;
- d->imports = expression.imports;
- d->engine = engine;
-
- if (d->compile(expression.expression.asAST())) {
- return d->commitCompile();
- } else {
- return -1;
- }
-}
-
-
-QByteArray QDeclarativeBindingCompilerPrivate::buildSignalTable() const
-{
- QHash<int, QList<int> > table;
-
- for (int ii = 0; ii < committed.count(); ++ii) {
- const QSet<int> &deps = committed.dependencies.at(ii);
- for (QSet<int>::ConstIterator iter = deps.begin(); iter != deps.end(); ++iter)
- table[*iter].append(ii);
- }
-
- QVector<quint32> header;
- QVector<quint32> data;
- for (int ii = 0; ii < committed.subscriptionIds.count(); ++ii) {
- header.append(committed.subscriptionIds.count() + data.count());
- const QList<int> &bindings = table[ii];
- data.append(bindings.count());
- for (int jj = 0; jj < bindings.count(); ++jj)
- data.append(bindings.at(jj));
- }
- header << data;
-
- return QByteArray((const char *)header.constData(), header.count() * sizeof(quint32));
-}
-
-QByteArray QDeclarativeBindingCompilerPrivate::buildExceptionData() const
-{
- QByteArray rv;
- rv.resize(committed.exceptions.count() * sizeof(quint64));
- ::memcpy(rv.data(), committed.exceptions.constData(), rv.size());
- return rv;
-}
-
-/*
-Returns the compiled program.
-*/
-QByteArray QDeclarativeBindingCompiler::program() const
-{
- QByteArray programData;
-
- if (isValid()) {
- Program prog;
- prog.bindings = d->committed.count();
-
- QVector<Instr> bytecode;
- Instr skip;
- skip.common.type = Instr::Skip;
- skip.skip.reg = -1;
- for (int ii = 0; ii < d->committed.count(); ++ii) {
- skip.skip.count = d->committed.count() - ii - 1;
- skip.skip.count+= d->committed.offsets.at(ii);
- bytecode << skip;
- }
- bytecode << d->committed.bytecode;
-
- QByteArray data = d->committed.data;
- while (data.count() % 4) data.append('\0');
- prog.signalTableOffset = data.count();
- data += d->buildSignalTable();
- while (data.count() % 4) data.append('\0');
- prog.exceptionDataOffset = data.count();
- data += d->buildExceptionData();
-
- prog.dataLength = 4 * ((data.size() + 3) / 4);
- prog.subscriptions = d->committed.subscriptionIds.count();
- prog.identifiers = d->committed.registeredStrings.count();
- prog.instructionCount = bytecode.count();
- prog.compiled = false;
- int size = sizeof(Program) + bytecode.count() * sizeof(Instr);
- size += prog.dataLength;
-
- programData.resize(size);
- memcpy(programData.data(), &prog, sizeof(Program));
- if (prog.dataLength)
- memcpy((char *)((Program *)programData.data())->data(), data.constData(),
- data.size());
- memcpy((char *)((Program *)programData.data())->instructions(), bytecode.constData(),
- bytecode.count() * sizeof(Instr));
- }
-
- return programData;
-}
-
-
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h
deleted file mode 100644
index e7b6937753..0000000000
--- a/src/declarative/qml/qdeclarativecompiledbindings_p.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEBINDINGOPTIMIZATIONS_P_H
-#define QDECLARATIVEBINDINGOPTIMIZATIONS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativebinding_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-struct QDeclarativeBindingCompilerPrivate;
-class QDeclarativeBindingCompiler
-{
-public:
- QDeclarativeBindingCompiler();
- ~QDeclarativeBindingCompiler();
-
- // Returns true if bindings were compiled
- bool isValid() const;
-
- struct Expression
- {
- QDeclarativeParser::Object *component;
- QDeclarativeParser::Object *context;
- QDeclarativeParser::Property *property;
- QDeclarativeParser::Variant expression;
- QHash<QString, QDeclarativeParser::Object *> ids;
- QDeclarativeImports imports;
- };
-
- // -1 on failure, otherwise the binding index to use
- int compile(const Expression &, QDeclarativeEnginePrivate *);
-
- // Returns the compiled program
- QByteArray program() const;
-
- static void dump(const QByteArray &);
-private:
- QDeclarativeBindingCompilerPrivate *d;
-};
-
-class QDeclarativeCompiledBindingsPrivate;
-class QDeclarativeCompiledBindings : public QObject, public QDeclarativeAbstractExpression, public QDeclarativeRefCount
-{
-public:
- QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context);
- virtual ~QDeclarativeCompiledBindings();
-
- QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property);
-
-protected:
- int qt_metacall(QMetaObject::Call, int, void **);
-
-private:
- Q_DISABLE_COPY(QDeclarativeCompiledBindings)
- Q_DECLARE_PRIVATE(QDeclarativeCompiledBindings)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECLARATIVEBINDINGOPTIMIZATIONS_P_H
-
diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp
index 913098c51d..2ea41d857f 100644
--- a/src/declarative/qml/qdeclarativecompileddata.cpp
+++ b/src/declarative/qml/qdeclarativecompileddata.cpp
@@ -97,70 +97,6 @@ int QDeclarativeCompiledData::indexForUrl(const QUrl &data)
return idx;
}
-int QDeclarativeCompiledData::indexForFloat(float *data, int count)
-{
- Q_ASSERT(count > 0);
-
- for (int ii = 0; ii <= floatData.count() - count; ++ii) {
- bool found = true;
- for (int jj = 0; jj < count; ++jj) {
- if (floatData.at(ii + jj) != data[jj]) {
- found = false;
- break;
- }
- }
-
- if (found)
- return ii;
- }
-
- int idx = floatData.count();
- for (int ii = 0; ii < count; ++ii)
- floatData << data[ii];
-
- return idx;
-}
-
-int QDeclarativeCompiledData::indexForInt(int *data, int count)
-{
- Q_ASSERT(count > 0);
-
- for (int ii = 0; ii <= intData.count() - count; ++ii) {
- bool found = true;
- for (int jj = 0; jj < count; ++jj) {
- if (intData.at(ii + jj) != data[jj]) {
- found = false;
- break;
- }
- }
-
- if (found)
- return ii;
- }
-
- int idx = intData.count();
- for (int ii = 0; ii < count; ++ii)
- intData << data[ii];
-
- return idx;
-}
-
-int QDeclarativeCompiledData::indexForLocation(const QDeclarativeParser::Location &l)
-{
- // ### FIXME
- int rv = locations.count();
- locations << l;
- return rv;
-}
-
-int QDeclarativeCompiledData::indexForLocation(const QDeclarativeParser::LocationSpan &l)
-{
- // ### FIXME
- int rv = locations.count();
- locations << l.start << l.end;
- return rv;
-}
-
QDeclarativeCompiledData::QDeclarativeCompiledData(QDeclarativeEngine *engine)
: QDeclarativeCleanup(engine), importCache(0), root(0), rootPropertyCache(0)
{
@@ -181,6 +117,9 @@ QDeclarativeCompiledData::~QDeclarativeCompiledData()
for (int ii = 0; ii < contextCaches.count(); ++ii)
contextCaches.at(ii)->release();
+ for (int ii = 0; ii < scripts.count(); ++ii)
+ scripts.at(ii)->release();
+
if (importCache)
importCache->release();
@@ -243,13 +182,42 @@ void QDeclarativeCompiledData::dumpInstructions()
{
if (!name.isEmpty())
qWarning() << name;
- qWarning().nospace() << "Index\tLine\tOperation\t\tData1\tData2\tData3\tComments";
+ qWarning().nospace() << "Index\tOperation\t\tData1\tData2\tData3\tComments";
qWarning().nospace() << "-------------------------------------------------------------------------------";
- for (int ii = 0; ii < bytecode.count(); ++ii) {
- dump(&bytecode[ii], ii);
+
+ const char *instructionStream = bytecode.constData();
+ const char *endInstructionStream = bytecode.constData() + bytecode.size();
+
+ int instructionCount = 0;
+ while (instructionStream < endInstructionStream) {
+ QDeclarativeInstruction *instr = (QDeclarativeInstruction *)instructionStream;
+ dump(instr, instructionCount);
+ instructionStream += instr->size();
+ instructionCount++;
}
+
qWarning().nospace() << "-------------------------------------------------------------------------------";
}
+int QDeclarativeCompiledData::addInstruction(const QDeclarativeInstruction &instr)
+{
+ int ptrOffset = bytecode.size();
+ int size = instr.size();
+ bytecode.resize(bytecode.size() + size);
+ char *data = bytecode.data() + ptrOffset;
+ qMemCopy(data, &instr, size);
+
+ return ptrOffset;
+}
+
+int QDeclarativeCompiledData::nextInstructionIndex()
+{
+ return bytecode.size();
+}
+
+QDeclarativeInstruction *QDeclarativeCompiledData::instruction(int index)
+{
+ return (QDeclarativeInstruction *)(bytecode.constData() + index);
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index e642a67102..e66a3fe792 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -63,7 +63,7 @@
#include "private/qdeclarativeglobal_p.h"
#include "private/qdeclarativescriptparser_p.h"
#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativecompiledbindings_p.h"
+#include "private/qdeclarativev4compiler_p.h"
#include "private/qdeclarativeglobalscriptclass_p.h"
#include <QColor>
@@ -79,7 +79,6 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATS);
-DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP);
using namespace QDeclarativeParser;
@@ -123,13 +122,26 @@ bool QDeclarativeCompiler::isAttachedPropertyName(const QByteArray &name)
/*!
Returns true if \a name refers to a signal property, false otherwise.
- Signal property names are those that start with "on", followed by a capital
- letter.
+ Signal property names are those that start with "on", followed by a first
+ character which is either a capital letter or one or more underscores followed
+ by a capital letter, which is then followed by other allowed characters.
+
+ Note that although ECMA-262r3 supports dollarsigns and escaped unicode
+ character codes in property names, for simplicity and performance reasons
+ QML only supports letters, numbers and underscores.
*/
bool QDeclarativeCompiler::isSignalPropertyName(const QByteArray &name)
{
- return name.length() >= 3 && name.startsWith("on") &&
- 'A' <= name.at(2) && 'Z' >= name.at(2);
+ if (name.length() < 3) return false;
+ if (!name.startsWith("on")) return false;
+ int ns = name.size();
+ for (int i = 2; i < ns; ++i) {
+ char curr = name.at(i);
+ if (curr == '_') continue;
+ if (curr >= 'A' && curr <= 'Z') return true;
+ return false;
+ }
+ return false; // consists solely of underscores - invalid.
}
/*!
@@ -201,6 +213,9 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
case QVariant::String:
if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected"));
break;
+ case QVariant::ByteArray:
+ if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: byte array expected"));
+ break;
case QVariant::Url:
if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: url expected"));
break;
@@ -320,24 +335,29 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop,
void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
QDeclarativeParser::Value *v)
{
- QString string = v->value.asString();
-
QDeclarativeInstruction instr;
- instr.line = v->location.start.line;
if (prop.isEnumType()) {
int value;
- if (prop.isFlagType()) {
- value = prop.enumerator().keysToValue(string.toUtf8().constData());
- } else
- value = prop.enumerator().keyToValue(string.toUtf8().constData());
+ if (v->value.isNumber()) {
+ // Preresolved enum
+ value = (int)v->value.asNumber();
+ } else {
+ // Must be a string
+ if (prop.isFlagType()) {
+ value = prop.enumerator().keysToValue(v->value.asString().toUtf8().constData());
+ } else
+ value = prop.enumerator().keyToValue(v->value.asString().toUtf8().constData());
+ }
- instr.type = QDeclarativeInstruction::StoreInteger;
+ instr.setType(QDeclarativeInstruction::StoreInteger);
instr.storeInteger.propertyIndex = prop.propertyIndex();
instr.storeInteger.value = value;
- output->bytecode << instr;
+ output->addInstruction(instr);
return;
}
+ QString string = v->value.asString();
+
int type = prop.userType();
switch(type) {
case -1:
@@ -345,20 +365,20 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
if (v->value.isNumber()) {
double n = v->value.asNumber();
if (double(int(n)) == n) {
- instr.type = QDeclarativeInstruction::StoreVariantInteger;
+ instr.setType(QDeclarativeInstruction::StoreVariantInteger);
instr.storeInteger.propertyIndex = prop.propertyIndex();
instr.storeInteger.value = int(n);
} else {
- instr.type = QDeclarativeInstruction::StoreVariantDouble;
+ instr.setType(QDeclarativeInstruction::StoreVariantDouble);
instr.storeDouble.propertyIndex = prop.propertyIndex();
instr.storeDouble.value = n;
}
} else if(v->value.isBoolean()) {
- instr.type = QDeclarativeInstruction::StoreVariantBool;
+ instr.setType(QDeclarativeInstruction::StoreVariantBool);
instr.storeBool.propertyIndex = prop.propertyIndex();
instr.storeBool.value = v->value.asBoolean();
} else {
- instr.type = QDeclarativeInstruction::StoreVariant;
+ instr.setType(QDeclarativeInstruction::StoreVariant);
instr.storeString.propertyIndex = prop.propertyIndex();
instr.storeString.value = output->indexForString(string);
}
@@ -366,14 +386,21 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
break;
case QVariant::String:
{
- instr.type = QDeclarativeInstruction::StoreString;
+ instr.setType(QDeclarativeInstruction::StoreString);
instr.storeString.propertyIndex = prop.propertyIndex();
instr.storeString.value = output->indexForString(string);
}
break;
+ case QVariant::ByteArray:
+ {
+ instr.setType(QDeclarativeInstruction::StoreByteArray);
+ instr.storeByteArray.propertyIndex = prop.propertyIndex();
+ instr.storeByteArray.value = output->indexForByteArray(string.toLatin1());
+ }
+ break;
case QVariant::Url:
{
- instr.type = QDeclarativeInstruction::StoreUrl;
+ instr.setType(QDeclarativeInstruction::StoreUrl);
QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string));
instr.storeUrl.propertyIndex = prop.propertyIndex();
instr.storeUrl.value = output->indexForUrl(u);
@@ -381,28 +408,28 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
break;
case QVariant::UInt:
{
- instr.type = QDeclarativeInstruction::StoreInteger;
+ instr.setType(QDeclarativeInstruction::StoreInteger);
instr.storeInteger.propertyIndex = prop.propertyIndex();
instr.storeInteger.value = uint(v->value.asNumber());
}
break;
case QVariant::Int:
{
- instr.type = QDeclarativeInstruction::StoreInteger;
+ instr.setType(QDeclarativeInstruction::StoreInteger);
instr.storeInteger.propertyIndex = prop.propertyIndex();
instr.storeInteger.value = int(v->value.asNumber());
}
break;
case QMetaType::Float:
{
- instr.type = QDeclarativeInstruction::StoreFloat;
+ instr.setType(QDeclarativeInstruction::StoreFloat);
instr.storeFloat.propertyIndex = prop.propertyIndex();
instr.storeFloat.value = float(v->value.asNumber());
}
break;
case QVariant::Double:
{
- instr.type = QDeclarativeInstruction::StoreDouble;
+ instr.setType(QDeclarativeInstruction::StoreDouble);
instr.storeDouble.propertyIndex = prop.propertyIndex();
instr.storeDouble.value = v->value.asNumber();
}
@@ -410,7 +437,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Color:
{
QColor c = QDeclarativeStringConverters::colorFromString(string);
- instr.type = QDeclarativeInstruction::StoreColor;
+ instr.setType(QDeclarativeInstruction::StoreColor);
instr.storeColor.propertyIndex = prop.propertyIndex();
instr.storeColor.value = c.rgba();
}
@@ -419,7 +446,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Date:
{
QDate d = QDeclarativeStringConverters::dateFromString(string);
- instr.type = QDeclarativeInstruction::StoreDate;
+ instr.setType(QDeclarativeInstruction::StoreDate);
instr.storeDate.propertyIndex = prop.propertyIndex();
instr.storeDate.value = d.toJulianDay();
}
@@ -427,80 +454,90 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Time:
{
QTime time = QDeclarativeStringConverters::timeFromString(string);
- int data[] = { time.hour(), time.minute(),
- time.second(), time.msec() };
- int index = output->indexForInt(data, 4);
- instr.type = QDeclarativeInstruction::StoreTime;
+ instr.setType(QDeclarativeInstruction::StoreTime);
instr.storeTime.propertyIndex = prop.propertyIndex();
- instr.storeTime.valueIndex = index;
+ instr.storeTime.time = *(QDeclarativeInstruction::instr_storeTime::QTime *)&time;
}
break;
case QVariant::DateTime:
{
QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(string);
- int data[] = { dateTime.date().toJulianDay(),
- dateTime.time().hour(),
- dateTime.time().minute(),
- dateTime.time().second(),
- dateTime.time().msec() };
- int index = output->indexForInt(data, 5);
- instr.type = QDeclarativeInstruction::StoreDateTime;
+ QTime time = dateTime.time();
+ instr.setType(QDeclarativeInstruction::StoreDateTime);
instr.storeDateTime.propertyIndex = prop.propertyIndex();
- instr.storeDateTime.valueIndex = index;
+ instr.storeDateTime.date = dateTime.date().toJulianDay();
+ instr.storeDateTime.time = *(QDeclarativeInstruction::instr_storeTime::QTime *)&time;
}
break;
#endif // QT_NO_DATESTRING
case QVariant::Point:
+ {
+ bool ok;
+ QPoint point = QDeclarativeStringConverters::pointFFromString(string, &ok).toPoint();
+ instr.setType(QDeclarativeInstruction::StorePoint);
+ instr.storePoint.propertyIndex = prop.propertyIndex();
+ instr.storePoint.point.xp = point.x();
+ instr.storePoint.point.yp = point.y();
+ }
+ break;
case QVariant::PointF:
{
bool ok;
- QPointF point =
- QDeclarativeStringConverters::pointFFromString(string, &ok);
- float data[] = { float(point.x()), float(point.y()) };
- int index = output->indexForFloat(data, 2);
- if (type == QVariant::PointF)
- instr.type = QDeclarativeInstruction::StorePointF;
- else
- instr.type = QDeclarativeInstruction::StorePoint;
- instr.storeRealPair.propertyIndex = prop.propertyIndex();
- instr.storeRealPair.valueIndex = index;
+ QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
+ instr.setType(QDeclarativeInstruction::StorePointF);
+ instr.storePointF.propertyIndex = prop.propertyIndex();
+ instr.storePointF.point.xp = point.x();
+ instr.storePointF.point.yp = point.y();
}
break;
case QVariant::Size:
+ {
+ bool ok;
+ QSize size = QDeclarativeStringConverters::sizeFFromString(string, &ok).toSize();
+ instr.setType(QDeclarativeInstruction::StoreSize);
+ instr.storeSize.propertyIndex = prop.propertyIndex();
+ instr.storeSize.size.wd = size.width();
+ instr.storeSize.size.ht = size.height();
+ }
+ break;
case QVariant::SizeF:
{
bool ok;
QSizeF size = QDeclarativeStringConverters::sizeFFromString(string, &ok);
- float data[] = { float(size.width()), float(size.height()) };
- int index = output->indexForFloat(data, 2);
- if (type == QVariant::SizeF)
- instr.type = QDeclarativeInstruction::StoreSizeF;
- else
- instr.type = QDeclarativeInstruction::StoreSize;
- instr.storeRealPair.propertyIndex = prop.propertyIndex();
- instr.storeRealPair.valueIndex = index;
+ instr.setType(QDeclarativeInstruction::StoreSizeF);
+ instr.storeSizeF.propertyIndex = prop.propertyIndex();
+ instr.storeSizeF.size.wd = size.width();
+ instr.storeSizeF.size.ht = size.height();
}
break;
case QVariant::Rect:
+ {
+ bool ok;
+ QRect rect = QDeclarativeStringConverters::rectFFromString(string, &ok).toRect();
+ instr.setType(QDeclarativeInstruction::StoreRect);
+ instr.storeRect.propertyIndex = prop.propertyIndex();
+ instr.storeRect.rect.x1 = rect.left();
+ instr.storeRect.rect.y1 = rect.top();
+ instr.storeRect.rect.x2 = rect.right();
+ instr.storeRect.rect.y2 = rect.bottom();
+ }
+ break;
case QVariant::RectF:
{
bool ok;
QRectF rect = QDeclarativeStringConverters::rectFFromString(string, &ok);
- float data[] = { float(rect.x()), float(rect.y()),
- float(rect.width()), float(rect.height()) };
- int index = output->indexForFloat(data, 4);
- if (type == QVariant::RectF)
- instr.type = QDeclarativeInstruction::StoreRectF;
- else
- instr.type = QDeclarativeInstruction::StoreRect;
- instr.storeRect.propertyIndex = prop.propertyIndex();
- instr.storeRect.valueIndex = index;
+ instr.setType(QDeclarativeInstruction::StoreRectF);
+ instr.storeRectF.propertyIndex = prop.propertyIndex();
+ instr.storeRectF.rect.xp = rect.left();
+ instr.storeRectF.rect.yp = rect.top();
+ instr.storeRectF.rect.w = rect.width();
+ instr.storeRectF.rect.h = rect.height();
}
break;
case QVariant::Bool:
{
bool b = v->value.asBoolean();
- instr.type = QDeclarativeInstruction::StoreBool;
+ instr.setType(QDeclarativeInstruction::StoreBool);
instr.storeBool.propertyIndex = prop.propertyIndex();
instr.storeBool.value = b;
}
@@ -508,31 +545,25 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop,
case QVariant::Vector3D:
{
bool ok;
- QVector3D vector =
- QDeclarativeStringConverters::vector3DFromString(string, &ok);
- float data[] = { float(vector.x()), float(vector.y()), float(vector.z()) };
- int index = output->indexForFloat(data, 3);
- instr.type = QDeclarativeInstruction::StoreVector3D;
- instr.storeRealPair.propertyIndex = prop.propertyIndex();
- instr.storeRealPair.valueIndex = index;
+ QVector3D vector = QDeclarativeStringConverters::vector3DFromString(string, &ok);
+ instr.setType(QDeclarativeInstruction::StoreVector3D);
+ instr.storeVector3D.propertyIndex = prop.propertyIndex();
+ instr.storeVector3D.vector.xp = vector.x();
+ instr.storeVector3D.vector.yp = vector.y();
+ instr.storeVector3D.vector.zp = vector.z();
}
break;
default:
{
int t = prop.userType();
- int index = output->customTypeData.count();
- instr.type = QDeclarativeInstruction::AssignCustomType;
+ instr.setType(QDeclarativeInstruction::AssignCustomType);
instr.assignCustomType.propertyIndex = prop.propertyIndex();
- instr.assignCustomType.valueIndex = index;
-
- QDeclarativeCompiledData::CustomTypeData data;
- data.index = output->indexForString(string);
- data.type = t;
- output->customTypeData << data;
+ instr.assignCustomType.primitive = output->indexForString(string);
+ instr.assignCustomType.type = t;
}
break;
}
- output->bytecode << instr;
+ output->addInstruction(instr);
}
/*!
@@ -542,9 +573,6 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data)
{
data->types.clear();
data->primitives.clear();
- data->floatData.clear();
- data->intData.clear();
- data->customTypeData.clear();
data->datas.clear();
data->bytecode.clear();
}
@@ -642,12 +670,35 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
compileState.root = tree;
componentStat.lineNumber = tree->location.start.line;
+ // Build global import scripts
+ QStringList importedScriptIndexes;
+
+ foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
+ importedScriptIndexes.append(script.qualifier);
+
+ QDeclarativeInstruction import;
+ import.setType(QDeclarativeInstruction::StoreImportedScript);
+ import.storeScript.value = output->scripts.count();
+
+ QDeclarativeScriptData *scriptData = script.script->scriptData();
+ scriptData->addref();
+ output->scripts << scriptData;
+ output->addInstruction(import);
+ }
+
+ // We generate the importCache before we build the tree so that
+ // it can be used in the binding compiler. Given we "expect" the
+ // QML compilation to succeed, this isn't a waste.
+ output->importCache = new QDeclarativeTypeNameCache(engine);
+ for (int ii = 0; ii < importedScriptIndexes.count(); ++ii)
+ output->importCache->add(importedScriptIndexes.at(ii), ii);
+ unit->imports().populateCache(output->importCache, engine);
+
if (!buildObject(tree, BindingContext()) || !completeComponentBuild())
return;
QDeclarativeInstruction init;
- init.type = QDeclarativeInstruction::Init;
- init.line = 0;
+ init.setType(QDeclarativeInstruction::Init);
init.init.bindingsSize = compileState.bindings.count();
init.init.parserStatusSize = compileState.parserStatusCount;
init.init.contextCache = genContextCache();
@@ -655,53 +706,17 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree)
init.init.compiledBinding = -1;
else
init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
- output->bytecode << init;
-
- // Build global import scripts
- QHash<QString, Object::ScriptBlock> importedScripts;
- QStringList importedScriptIndexes;
-
- foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
- QString scriptCode = script.script->scriptSource();
- Object::ScriptBlock::Pragmas pragmas = script.script->pragmas();
-
- Q_ASSERT(!importedScripts.contains(script.qualifier));
-
- if (!scriptCode.isEmpty()) {
- Object::ScriptBlock &scriptBlock = importedScripts[script.qualifier];
-
- scriptBlock.code = scriptCode;
- scriptBlock.file = script.script->finalUrl().toString();
- scriptBlock.pragmas = pragmas;
- }
- }
-
- for (QHash<QString, Object::ScriptBlock>::Iterator iter = importedScripts.begin();
- iter != importedScripts.end(); ++iter) {
-
- importedScriptIndexes.append(iter.key());
-
- QDeclarativeInstruction import;
- import.type = QDeclarativeInstruction::StoreImportedScript;
- import.line = 0;
- import.storeScript.value = output->scripts.count();
- output->scripts << *iter;
- output->bytecode << import;
- }
+ output->addInstruction(init);
genObject(tree);
QDeclarativeInstruction def;
- init.line = 0;
- def.type = QDeclarativeInstruction::SetDefault;
- output->bytecode << def;
-
- output->importCache = new QDeclarativeTypeNameCache(engine);
+ def.setType(QDeclarativeInstruction::SetDefault);
+ output->addInstruction(def);
- for (int ii = 0; ii < importedScriptIndexes.count(); ++ii)
- output->importCache->add(importedScriptIndexes.at(ii), ii);
-
- unit->imports().populateCache(output->importCache, engine);
+ QDeclarativeInstruction done;
+ done.setType(QDeclarativeInstruction::Done);
+ output->addInstruction(done);
Q_ASSERT(tree->metatype);
@@ -909,19 +924,19 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
!output->types.at(obj->type).type->isExtendedType() && obj != compileState.root) {
QDeclarativeInstruction create;
- create.type = QDeclarativeInstruction::CreateSimpleObject;
- create.line = obj->location.start.line;
+ create.setType(QDeclarativeInstruction::CreateSimpleObject);
create.createSimple.create = output->types.at(obj->type).type->createFunction();
create.createSimple.typeSize = output->types.at(obj->type).type->createSize();
create.createSimple.type = obj->type;
+ create.createSimple.line = obj->location.start.line;
create.createSimple.column = obj->location.start.column;
- output->bytecode << create;
+ output->addInstruction(create);
} else {
QDeclarativeInstruction create;
- create.type = QDeclarativeInstruction::CreateObject;
- create.line = obj->location.start.line;
+ create.setType(QDeclarativeInstruction::CreateObject);
+ create.create.line = obj->location.start.line;
create.create.column = obj->location.start.column;
create.create.data = -1;
if (!obj->custom.isEmpty())
@@ -935,15 +950,14 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
} else {
create.create.bindingBits = -1;
}
- output->bytecode << create;
+ output->addInstruction(create);
}
// Setup the synthesized meta object if necessary
if (!obj->metadata.isEmpty()) {
QDeclarativeInstruction meta;
- meta.type = QDeclarativeInstruction::StoreMetaObject;
- meta.line = 0;
+ meta.setType(QDeclarativeInstruction::StoreMetaObject);
meta.storeMeta.data = output->indexForByteArray(obj->metadata);
meta.storeMeta.aliasData = output->indexForByteArray(obj->synthdata);
meta.storeMeta.propertyCache = output->propertyCaches.count();
@@ -968,7 +982,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
}
output->propertyCaches << propertyCache;
- output->bytecode << meta;
+ output->addInstruction(meta);
} else if (obj == unitRoot) {
output->rootPropertyCache = tr.createPropertyCache(engine);
output->rootPropertyCache->addref();
@@ -977,20 +991,18 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
// Set the object id
if (!obj->id.isEmpty()) {
QDeclarativeInstruction id;
- id.type = QDeclarativeInstruction::SetId;
- id.line = 0;
+ id.setType(QDeclarativeInstruction::SetId);
id.setId.value = output->indexForString(obj->id);
id.setId.index = obj->idIndex;
- output->bytecode << id;
+ output->addInstruction(id);
}
// Begin the class
if (tr.type && obj->parserStatusCast != -1) {
QDeclarativeInstruction begin;
- begin.type = QDeclarativeInstruction::BeginObject;
+ begin.setType(QDeclarativeInstruction::BeginObject);
begin.begin.castValue = obj->parserStatusCast;
- begin.line = obj->location.start.line;
- output->bytecode << begin;
+ output->addInstruction(begin);
}
genObjectBody(obj);
@@ -1001,12 +1013,12 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
typedef QPair<Property *, int> PropPair;
foreach(const PropPair &prop, obj->scriptStringProperties) {
QDeclarativeInstruction ss;
- ss.type = QDeclarativeInstruction::StoreScriptString;
+ ss.setType(QDeclarativeInstruction::StoreScriptString);
ss.storeScriptString.propertyIndex = prop.first->index;
ss.storeScriptString.value =
output->indexForString(prop.first->values.at(0)->value.asScript());
ss.storeScriptString.scope = prop.second;
- output->bytecode << ss;
+ output->addInstruction(ss);
}
bool seenDefer = false;
@@ -1020,19 +1032,18 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
}
if (seenDefer) {
QDeclarativeInstruction defer;
- defer.type = QDeclarativeInstruction::Defer;
- defer.line = 0;
+ defer.setType(QDeclarativeInstruction::Defer);
defer.defer.deferCount = 0;
- int deferIdx = output->bytecode.count();
- output->bytecode << defer;
+ int deferIdx = output->addInstruction(defer);
+ int nextInstructionIndex = output->nextInstructionIndex();
QDeclarativeInstruction init;
- init.type = QDeclarativeInstruction::Init;
+ init.setType(QDeclarativeInstruction::Init);
init.init.bindingsSize = compileState.bindings.count(); // XXX - bigger than necessary
init.init.parserStatusSize = compileState.parserStatusCount; // XXX - bigger than necessary
init.init.contextCache = -1;
init.init.compiledBinding = -1;
- output->bytecode << init;
+ output->addInstruction(init);
foreach(Property *prop, obj->valueProperties) {
if (!prop->isDeferred)
@@ -1040,8 +1051,11 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
genValueProperty(prop, obj);
}
- output->bytecode[deferIdx].defer.deferCount =
- output->bytecode.count() - deferIdx - 1;
+ QDeclarativeInstruction done;
+ done.setType(QDeclarativeInstruction::Done);
+ output->addInstruction(done);
+
+ output->instruction(deferIdx)->defer.deferCount = output->nextInstructionIndex() - nextInstructionIndex;
}
foreach(Property *prop, obj->signalProperties) {
@@ -1053,25 +1067,25 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
genObject(v->object);
QDeclarativeInstruction assign;
- assign.type = QDeclarativeInstruction::AssignSignalObject;
- assign.line = v->location.start.line;
+ assign.setType(QDeclarativeInstruction::AssignSignalObject);
+ assign.assignSignalObject.line = v->location.start.line;
assign.assignSignalObject.signal =
output->indexForByteArray(prop->name);
- output->bytecode << assign;
+ output->addInstruction(assign);
} else if (v->type == Value::SignalExpression) {
BindingContext ctxt = compileState.signalExpressions.value(v);
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreSignal;
- store.line = v->location.start.line;
+ store.setType(QDeclarativeInstruction::StoreSignal);
store.storeSignal.signalIndex = prop->index;
store.storeSignal.value =
output->indexForString(v->value.asScript().trimmed());
store.storeSignal.context = ctxt.stack;
store.storeSignal.name = output->indexForByteArray(prop->name);
- output->bytecode << store;
+ store.storeSignal.line = v->location.start.line;
+ output->addInstruction(store);
}
@@ -1079,42 +1093,39 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
foreach(Property *prop, obj->attachedProperties) {
QDeclarativeInstruction fetch;
- fetch.type = QDeclarativeInstruction::FetchAttached;
- fetch.line = prop->location.start.line;
+ fetch.setType(QDeclarativeInstruction::FetchAttached);
fetch.fetchAttached.id = prop->index;
- output->bytecode << fetch;
+ fetch.fetchAttached.line = prop->location.start.line;
+ output->addInstruction(fetch);
genObjectBody(prop->value);
QDeclarativeInstruction pop;
- pop.type = QDeclarativeInstruction::PopFetchedObject;
- pop.line = prop->location.start.line;
- output->bytecode << pop;
+ pop.setType(QDeclarativeInstruction::PopFetchedObject);
+ output->addInstruction(pop);
}
foreach(Property *prop, obj->groupedProperties) {
QDeclarativeInstruction fetch;
- fetch.type = QDeclarativeInstruction::FetchObject;
+ fetch.setType(QDeclarativeInstruction::FetchObject);
fetch.fetch.property = prop->index;
- fetch.line = prop->location.start.line;
- output->bytecode << fetch;
+ fetch.fetch.line = prop->location.start.line;
+ output->addInstruction(fetch);
if (!prop->value->metadata.isEmpty()) {
QDeclarativeInstruction meta;
- meta.type = QDeclarativeInstruction::StoreMetaObject;
- meta.line = 0;
+ meta.setType(QDeclarativeInstruction::StoreMetaObject);
meta.storeMeta.data = output->indexForByteArray(prop->value->metadata);
meta.storeMeta.aliasData = output->indexForByteArray(prop->value->synthdata);
meta.storeMeta.propertyCache = -1;
- output->bytecode << meta;
+ output->addInstruction(meta);
}
genObjectBody(prop->value);
QDeclarativeInstruction pop;
- pop.type = QDeclarativeInstruction::PopFetchedObject;
- pop.line = prop->location.start.line;
- output->bytecode << pop;
+ pop.setType(QDeclarativeInstruction::PopFetchedObject);
+ output->addInstruction(pop);
}
foreach(Property *prop, obj->valueTypeProperties) {
@@ -1138,11 +1149,10 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj)
void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,QDeclarativeParser::Property *prop)
{
QDeclarativeInstruction fetch;
- fetch.type = QDeclarativeInstruction::FetchValueType;
+ fetch.setType(QDeclarativeInstruction::FetchValueType);
fetch.fetchValue.property = prop->index;
fetch.fetchValue.type = prop->type;
fetch.fetchValue.bindingSkipList = 0;
- fetch.line = prop->location.start.line;
if (obj->type == -1 || output->types.at(obj->type).component) {
// We only have to do this if this is a composite type. If it is a builtin
@@ -1155,19 +1165,18 @@ void QDeclarativeCompiler::genValueTypeProperty(QDeclarativeParser::Object *obj,
}
}
- output->bytecode << fetch;
+ output->addInstruction(fetch);
foreach(Property *vprop, prop->value->valueProperties) {
genPropertyAssignment(vprop, prop->value, prop);
}
QDeclarativeInstruction pop;
- pop.type = QDeclarativeInstruction::PopValueType;
+ pop.setType(QDeclarativeInstruction::PopValueType);
pop.fetchValue.property = prop->index;
pop.fetchValue.type = prop->type;
pop.fetchValue.bindingSkipList = 0;
- pop.line = prop->location.start.line;
- output->bytecode << pop;
+ output->addInstruction(pop);
}
void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
@@ -1176,18 +1185,18 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
Q_ASSERT(root);
QDeclarativeInstruction create;
- create.type = QDeclarativeInstruction::CreateComponent;
- create.line = root->location.start.line;
+ create.setType(QDeclarativeInstruction::CreateComponent);
+ create.createComponent.line = root->location.start.line;
create.createComponent.column = root->location.start.column;
create.createComponent.endLine = root->location.end.line;
- output->bytecode << create;
- int count = output->bytecode.count();
+ int createInstruction = output->addInstruction(create);
+ int nextInstructionIndex = output->nextInstructionIndex();
ComponentCompileState oldCompileState = compileState;
compileState = componentState(root);
QDeclarativeInstruction init;
- init.type = QDeclarativeInstruction::Init;
+ init.setType(QDeclarativeInstruction::Init);
init.init.bindingsSize = compileState.bindings.count();
init.init.parserStatusSize = compileState.parserStatusCount;
init.init.contextCache = genContextCache();
@@ -1195,28 +1204,29 @@ void QDeclarativeCompiler::genComponent(QDeclarativeParser::Object *obj)
init.init.compiledBinding = -1;
else
init.init.compiledBinding = output->indexForByteArray(compileState.compiledBindingData);
- init.line = obj->location.start.line;
- output->bytecode << init;
+ output->addInstruction(init);
genObject(root);
QDeclarativeInstruction def;
- init.line = 0;
- def.type = QDeclarativeInstruction::SetDefault;
- output->bytecode << def;
+ def.setType(QDeclarativeInstruction::SetDefault);
+ output->addInstruction(def);
+
+ QDeclarativeInstruction done;
+ done.setType(QDeclarativeInstruction::Done);
+ output->addInstruction(done);
- output->bytecode[count - 1].createComponent.count =
- output->bytecode.count() - count;
+ output->instruction(createInstruction)->createComponent.count =
+ output->nextInstructionIndex() - nextInstructionIndex;
compileState = oldCompileState;
if (!obj->id.isEmpty()) {
QDeclarativeInstruction id;
- id.type = QDeclarativeInstruction::SetId;
- id.line = 0;
+ id.setType(QDeclarativeInstruction::SetId);
id.setId.value = output->indexForString(obj->id);
id.setId.index = obj->idIndex;
- output->bytecode << id;
+ output->addInstruction(id);
}
}
@@ -1283,6 +1293,7 @@ bool QDeclarativeCompiler::buildComponentFromRoot(QDeclarativeParser::Object *ob
compileState = ComponentCompileState();
compileState.root = obj;
+ compileState.nested = true;
componentStat = ComponentStat();
componentStat.lineNumber = obj->location.start.line;
@@ -1342,8 +1353,15 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
QByteArray name = prop->name;
Q_ASSERT(name.startsWith("on"));
name = name.mid(2);
- if(name[0] >= 'A' && name[0] <= 'Z')
- name[0] = name[0] - 'A' + 'a';
+
+ // Note that the property name could start with any alpha or '_' or '$' character,
+ // so we need to do the lower-casing of the first alpha character.
+ for (int firstAlphaIndex = 0; firstAlphaIndex < name.size(); ++firstAlphaIndex) {
+ if (name[firstAlphaIndex] >= 'A' && name[firstAlphaIndex] <= 'Z') {
+ name[firstAlphaIndex] = name[firstAlphaIndex] - 'A' + 'a';
+ break;
+ }
+ }
bool notInRevision = false;
int sigIdx = indexOfSignal(obj, name, &notInRevision);
@@ -1442,8 +1460,6 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
if (typeNamespace) {
- // ### We might need to indicate that this property is a namespace
- // for the DOM API
COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
ctxt));
return true;
@@ -1607,12 +1623,11 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
int listType = enginePrivate->listType(prop->type);
QDeclarativeInstruction fetch;
- fetch.type = QDeclarativeInstruction::FetchQList;
- fetch.line = prop->location.start.line;
+ fetch.setType(QDeclarativeInstruction::FetchQList);
fetch.fetchQmlList.property = prop->index;
bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType);
fetch.fetchQmlList.type = listType;
- output->bytecode << fetch;
+ output->addInstruction(fetch);
for (int ii = 0; ii < prop->values.count(); ++ii) {
QDeclarativeParser::Value *v = prop->values.at(ii);
@@ -1622,14 +1637,13 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
genObject(v->object);
if (listTypeIsInterface) {
QDeclarativeInstruction assign;
- assign.type = QDeclarativeInstruction::AssignObjectList;
- assign.line = prop->location.start.line;
- output->bytecode << assign;
+ assign.setType(QDeclarativeInstruction::AssignObjectList);
+ assign.assignObjectList.line = prop->location.start.line;
+ output->addInstruction(assign);
} else {
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreObjectQList;
- store.line = prop->location.start.line;
- output->bytecode << store;
+ store.setType(QDeclarativeInstruction::StoreObjectQList);
+ output->addInstruction(store);
}
} else if (v->type == Value::PropertyBinding) {
@@ -1641,9 +1655,8 @@ void QDeclarativeCompiler::genListProperty(QDeclarativeParser::Property *prop,
}
QDeclarativeInstruction pop;
- pop.type = QDeclarativeInstruction::PopQList;
- pop.line = prop->location.start.line;
- output->bytecode << pop;
+ pop.setType(QDeclarativeInstruction::PopQList);
+ output->addInstruction(pop);
}
void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *prop,
@@ -1664,26 +1677,26 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
if (QDeclarativeMetaType::isInterface(prop->type)) {
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreInterface;
- store.line = v->object->location.start.line;
+ store.setType(QDeclarativeInstruction::StoreInterface);
+ store.storeObject.line = v->object->location.start.line;
store.storeObject.propertyIndex = prop->index;
- output->bytecode << store;
+ output->addInstruction(store);
} else if (prop->type == -1) {
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreVariantObject;
- store.line = v->object->location.start.line;
+ store.setType(QDeclarativeInstruction::StoreVariantObject);
+ store.storeObject.line = v->object->location.start.line;
store.storeObject.propertyIndex = prop->index;
- output->bytecode << store;
+ output->addInstruction(store);
} else {
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreObject;
- store.line = v->object->location.start.line;
+ store.setType(QDeclarativeInstruction::StoreObject);
+ store.storeObject.line = v->object->location.start.line;
store.storeObject.propertyIndex = prop->index;
- output->bytecode << store;
+ output->addInstruction(store);
}
} else if (v->type == Value::PropertyBinding) {
@@ -1710,8 +1723,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
genObject(v->object);
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreValueSource;
- store.line = v->object->location.start.line;
+ store.setType(QDeclarativeInstruction::StoreValueSource);
if (valueTypeProperty) {
store.assignValueSource.property = genValueTypeData(prop, valueTypeProperty);
store.assignValueSource.owner = 1;
@@ -1721,14 +1733,13 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
}
QDeclarativeType *valueType = toQmlType(v->object);
store.assignValueSource.castValue = valueType->propertyValueSourceCast();
- output->bytecode << store;
+ output->addInstruction(store);
} else if (v->type == Value::ValueInterceptor) {
genObject(v->object);
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreValueInterceptor;
- store.line = v->object->location.start.line;
+ store.setType(QDeclarativeInstruction::StoreValueInterceptor);
if (valueTypeProperty) {
store.assignValueInterceptor.property = genValueTypeData(prop, valueTypeProperty);
store.assignValueInterceptor.owner = 1;
@@ -1738,7 +1749,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p
}
QDeclarativeType *valueType = toQmlType(v->object);
store.assignValueInterceptor.castValue = valueType->propertyValueInterceptorCast();
- output->bytecode << store;
+ output->addInstruction(store);
}
}
@@ -2227,20 +2238,35 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
objTypeName = objType->qmlTypeName();
}
- if (!type || objTypeName != type->qmlTypeName())
+ if (!type)
return true;
QString enumValue = parts.at(1);
- int value;
- if (prop.isFlagType()) {
- value = prop.enumerator().keysToValue(enumValue.toUtf8().constData());
- } else
- value = prop.enumerator().keyToValue(enumValue.toUtf8().constData());
+ int value = -1;
+
+ if (objTypeName == type->qmlTypeName()) {
+ // When these two match, we can short cut the search
+ if (prop.isFlagType()) {
+ value = prop.enumerator().keysToValue(enumValue.toUtf8().constData());
+ } else {
+ value = prop.enumerator().keyToValue(enumValue.toUtf8().constData());
+ }
+ } else {
+ // Otherwise we have to search the whole type
+ // This matches the logic in QDeclarativeTypeNameScriptClass
+ QByteArray enumName = enumValue.toUtf8();
+ const QMetaObject *metaObject = type->baseMetaObject();
+ for (int ii = metaObject->enumeratorCount() - 1; value == -1 && ii >= 0; --ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ value = e.keyToValue(enumName.constData());
+ }
+ }
+
if (value == -1)
return true;
v->type = Value::Literal;
- v->value = QDeclarativeParser::Variant(enumValue);
+ v->value = QDeclarativeParser::Variant((double)value);
*isAssignment = true;
return true;
@@ -2412,7 +2438,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
newClassName.append("_QML_");
int idx = classIndexCounter()->fetchAndAddRelaxed(1);
newClassName.append(QByteArray::number(idx));
- if (compileState.root == obj) {
+ if (compileState.root == obj && !compileState.nested) {
QString path = output->url.path();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
if (lastSlash > -1) {
@@ -2810,7 +2836,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
const BindingReference &ref = compileState.bindings.value(binding);
if (ref.dataType == BindingReference::Experimental) {
QDeclarativeInstruction store;
- store.type = QDeclarativeInstruction::StoreCompiledBinding;
+ store.setType(QDeclarativeInstruction::StoreCompiledBinding);
store.assignBinding.value = ref.compiledIndex;
store.assignBinding.context = ref.bindingContext.stack;
store.assignBinding.owner = ref.bindingContext.owner;
@@ -2820,20 +2846,20 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
((prop->index & 0xFF) << 24);
else
store.assignBinding.property = prop->index;
- store.line = binding->location.start.line;
- output->bytecode << store;
+ store.assignBinding.line = binding->location.start.line;
+ output->addInstruction(store);
return;
}
QDeclarativeInstruction store;
if (!prop->isAlias)
- store.type = QDeclarativeInstruction::StoreBinding;
+ store.setType(QDeclarativeInstruction::StoreBinding);
else
- store.type = QDeclarativeInstruction::StoreBindingOnAlias;
+ store.setType(QDeclarativeInstruction::StoreBindingOnAlias);
store.assignBinding.value = output->indexForByteArray(ref.compiledData);
store.assignBinding.context = ref.bindingContext.stack;
store.assignBinding.owner = ref.bindingContext.owner;
- store.line = binding->location.start.line;
+ store.assignBinding.line = binding->location.start.line;
Q_ASSERT(ref.bindingContext.owner == 0 ||
(ref.bindingContext.owner != 0 && valueTypeProperty));
@@ -2843,7 +2869,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeParser::Value *bindi
store.assignBinding.property = genPropertyData(prop);
}
- output->bytecode << store;
+ output->addInstruction(store);
}
int QDeclarativeCompiler::genContextCache()
@@ -2888,25 +2914,26 @@ bool QDeclarativeCompiler::completeComponentBuild()
COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases));
}
- QDeclarativeBindingCompiler::Expression expr;
+ QDeclarativeV4Compiler::Expression expr;
expr.component = compileState.root;
expr.ids = compileState.ids;
+ expr.importCache = output->importCache;
+ expr.imports = unit->imports();
- QDeclarativeBindingCompiler bindingCompiler;
+ QDeclarativeV4Compiler bindingCompiler;
for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin();
iter != compileState.bindings.end(); ++iter) {
BindingReference &binding = *iter;
- expr.context = binding.bindingContext.object;
- expr.property = binding.property;
- expr.expression = binding.expression;
- expr.imports = unit->imports();
-
// ### We don't currently optimize for bindings on alias's - because
// of the solution to QTBUG-13719
if (!binding.property->isAlias) {
+ expr.context = binding.bindingContext.object;
+ expr.property = binding.property;
+ expr.expression = binding.expression;
+
int index = bindingCompiler.compile(expr, enginePrivate);
if (index != -1) {
binding.dataType = BindingReference::Experimental;
@@ -2947,11 +2974,8 @@ bool QDeclarativeCompiler::completeComponentBuild()
componentStat.scriptBindings.append(iter.key()->location);
}
- if (bindingCompiler.isValid()) {
+ if (bindingCompiler.isValid())
compileState.compiledBindingData = bindingCompiler.program();
- if (bindingsDump())
- QDeclarativeBindingCompiler::dump(compileState.compiledBindingData);
- }
saveComponentState();
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index bcc0b298a8..e4b9240a93 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -102,31 +102,26 @@ public:
QDeclarativePropertyCache *createPropertyCache(QDeclarativeEngine *);
};
QList<TypeReference> types;
- struct CustomTypeData
- {
- int index;
- int type;
- };
const QMetaObject *root;
QAbstractDynamicMetaObject rootData;
QDeclarativePropertyCache *rootPropertyCache;
QList<QString> primitives;
- QList<float> floatData;
- QList<int> intData;
- QList<CustomTypeData> customTypeData;
QList<QByteArray> datas;
- QList<QDeclarativeParser::Location> locations;
- QList<QDeclarativeInstruction> bytecode;
+ QByteArray bytecode;
QList<QScriptProgram *> cachedPrograms;
QList<QScriptValue *> cachedClosures;
QList<QDeclarativePropertyCache *> propertyCaches;
QList<QDeclarativeIntegerCache *> contextCaches;
- QList<QDeclarativeParser::Object::ScriptBlock> scripts;
+ QList<QDeclarativeScriptData *> scripts;
QList<QUrl> urls;
void dumpInstructions();
+ int addInstruction(const QDeclarativeInstruction &instr);
+ int nextInstructionIndex();
+ QDeclarativeInstruction *instruction(int index);
+
protected:
virtual void clear(); // From QDeclarativeCleanup
@@ -140,10 +135,6 @@ private:
int indexForString(const QString &);
int indexForByteArray(const QByteArray &);
- int indexForFloat(float *, int);
- int indexForInt(int *, int);
- int indexForLocation(const QDeclarativeParser::Location &);
- int indexForLocation(const QDeclarativeParser::LocationSpan &);
int indexForUrl(const QUrl &);
};
@@ -305,11 +296,12 @@ private:
struct ComponentCompileState
{
ComponentCompileState()
- : parserStatusCount(0), pushedProperties(0), root(0) {}
+ : parserStatusCount(0), pushedProperties(0), nested(false), root(0) {}
QHash<QString, QDeclarativeParser::Object *> ids;
QHash<int, QDeclarativeParser::Object *> idIndexes;
int parserStatusCount;
int pushedProperties;
+ bool nested;
QByteArray compiledBindingData;
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index d9f291ba64..01e2434f76 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -455,7 +455,7 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeEngine *engine, const Q
/*!
\internal
*/
-QDeclarativeComponent::QDeclarativeComponent(QDeclarativeEngine *engine, QDeclarativeCompiledData *cc, int start, int count, QObject *parent)
+QDeclarativeComponent::QDeclarativeComponent(QDeclarativeEngine *engine, QDeclarativeCompiledData *cc, int start, QObject *parent)
: QObject(*(new QDeclarativeComponentPrivate), parent)
{
Q_D(QDeclarativeComponent);
@@ -463,7 +463,6 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeEngine *engine, QDeclar
d->cc = cc;
cc->addref();
d->start = start;
- d->count = count;
d->url = cc->url;
d->progress = 1.0;
}
@@ -833,12 +832,40 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons
return 0;
}
- return begin(context, creationContext, cc, start, count, &state, 0, bindings);
+ return begin(context, creationContext, cc, start, &state, 0, bindings);
+}
+
+/*
+ Try to do what's necessary for a reasonable display of the type
+ name, but no more (just enough for the client to do more extensive cleanup).
+
+ Should only be called when debugging is enabled.
+*/
+static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
+{
+ static const QString qmlMarker(QLatin1String("_QML"));
+ static const QChar underscore(QLatin1Char('_'));
+ static const QChar asterisk(QLatin1Char('*'));
+ QDeclarativeType *type = QDeclarativeMetaType::qmlType(metaObject);
+ QString typeName = type ? QLatin1String(type->qmlTypeName()) : QLatin1String(metaObject->className());
+ if (!type) {
+ //### optimize further?
+ int marker = typeName.indexOf(qmlMarker);
+ if (marker != -1 && marker < typeName.count() - 1) {
+ if (typeName[marker + 1] == underscore) {
+ const QString className = typeName.left(marker) + asterisk;
+ type = QDeclarativeMetaType::qmlType(QMetaType::type(className.toLatin1()));
+ if (type)
+ typeName = QLatin1String(type->qmlTypeName());
+ }
+ }
+ }
+ return typeName;
}
QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentContext,
QDeclarativeContextData *componentCreationContext,
- QDeclarativeCompiledData *component, int start, int count,
+ QDeclarativeCompiledData *component, int start,
ConstructionState *state, QList<QDeclarativeError> *errors,
const QBitField &bindings)
{
@@ -848,10 +875,8 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
Q_ASSERT(!isRoot || state); // Either this isn't a root component, or a state data must be provided
Q_ASSERT((state != 0) ^ (errors != 0)); // One of state or errors (but not both) must be provided
- if (isRoot) {
+ if (isRoot)
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
- QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, component->url);
- }
QDeclarativeContextData *ctxt = new QDeclarativeContextData;
ctxt->isInternal = true;
@@ -868,7 +893,9 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
enginePriv->inBeginCreate = true;
QDeclarativeVME vme;
- QObject *rv = vme.run(ctxt, component, start, count, bindings);
+ enginePriv->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
+ QObject *rv = vme.run(ctxt, component, start, bindings);
+ enginePriv->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
if (vme.isError()) {
if(errors) *errors = vme.errors();
@@ -897,6 +924,11 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
if (!parentContext->isInternal)
parentContext->asQDeclarativeContextPrivate()->instances.append(rv);
QDeclarativeEngineDebugServer::instance()->objectCreated(parentContext->engine, rv);
+ if (isRoot) {
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, buildTypeNameForDebug(rv->metaObject()));
+ QDeclarativeData *data = QDeclarativeData::get(rv);
+ QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, component->url, data ? data->lineNumber : -1);
+ }
}
return rv;
diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h
index ab007e8bd8..15004a6cb1 100644
--- a/src/declarative/qml/qdeclarativecomponent.h
+++ b/src/declarative/qml/qdeclarativecomponent.h
@@ -96,13 +96,14 @@ public:
virtual QObject *beginCreate(QDeclarativeContext *);
virtual void completeCreate();
- void loadUrl(const QUrl &url);
- void setData(const QByteArray &, const QUrl &baseUrl);
-
QDeclarativeContext *creationContext() const;
static QDeclarativeComponentAttached *qmlAttachedProperties(QObject *);
+public Q_SLOTS:
+ void loadUrl(const QUrl &url);
+ void setData(const QByteArray &, const QUrl &baseUrl);
+
Q_SIGNALS:
void statusChanged(QDeclarativeComponent::Status);
void progressChanged(qreal);
@@ -113,11 +114,10 @@ protected:
Q_INVOKABLE Q_REVISION(1) QScriptValue createObject(QObject* parent, const QScriptValue& valuemap); //XXX Versioning
private:
- QDeclarativeComponent(QDeclarativeEngine *, QDeclarativeCompiledData *, int, int, QObject *parent);
+ QDeclarativeComponent(QDeclarativeEngine *, QDeclarativeCompiledData *, int, QObject *parent);
Q_DISABLE_COPY(QDeclarativeComponent)
friend class QDeclarativeVME;
- friend class QDeclarativeCompositeTypeData;
friend class QDeclarativeTypeData;
};
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index f30691b536..ef04a5e137 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -79,7 +79,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeComponentPrivate : public QObjectPrivate, pu
Q_DECLARE_PUBLIC(QDeclarativeComponent)
public:
- QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), engine(0), creationContext(0) {}
+ QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0) {}
QObject *beginCreate(QDeclarativeContextData *, const QBitField &);
void completeCreate();
@@ -94,7 +94,6 @@ public:
qreal progress;
int start;
- int count;
QDeclarativeCompiledData *cc;
struct ConstructionState {
@@ -109,7 +108,7 @@ public:
ConstructionState state;
static QObject *begin(QDeclarativeContextData *parentContext, QDeclarativeContextData *componentCreationContext,
- QDeclarativeCompiledData *component, int start, int count,
+ QDeclarativeCompiledData *component, int start,
ConstructionState *state, QList<QDeclarativeError> *errors,
const QBitField &bindings = QBitField());
static void beginDeferred(QDeclarativeEnginePrivate *enginePriv, QObject *object,
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index d57bc08d0f..c48f2ed3d4 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -46,9 +46,9 @@
#include "private/qdeclarativeexpression_p.h"
#include "private/qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
-#include "private/qdeclarativecompiledbindings_p.h"
#include "qdeclarativeinfo.h"
#include "private/qdeclarativeglobalscriptclass_p.h"
+#include "private/qdeclarativev4bindings_p.h"
#include <qscriptengine.h>
#include <QtCore/qvarlengtharray.h>
@@ -498,7 +498,7 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListProperty<QObject
QDeclarativeContextData::QDeclarativeContextData()
-: parent(0), engine(0), isInternal(false), publicContext(0), propertyNames(0), contextObject(0),
+: parent(0), engine(0), isInternal(false), ownedByParent(false), publicContext(0), propertyNames(0), contextObject(0),
imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0),
componentAttached(0)
@@ -506,7 +506,7 @@ QDeclarativeContextData::QDeclarativeContextData()
}
QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
-: parent(0), engine(0), isInternal(false), publicContext(ctxt), propertyNames(0), contextObject(0),
+: parent(0), engine(0), isInternal(false), ownedByParent(false), publicContext(ctxt), propertyNames(0), contextObject(0),
imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0),
componentAttached(0)
@@ -515,8 +515,13 @@ QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
void QDeclarativeContextData::invalidate()
{
- while (childContexts)
- childContexts->invalidate();
+ while (childContexts) {
+ if (childContexts->ownedByParent) {
+ childContexts->destroy();
+ } else {
+ childContexts->invalidate();
+ }
+ }
while (componentAttached) {
QDeclarativeComponentAttached *a = componentAttached;
@@ -614,7 +619,7 @@ void QDeclarativeContextData::destroy()
delete this;
}
-void QDeclarativeContextData::setParent(QDeclarativeContextData *p)
+void QDeclarativeContextData::setParent(QDeclarativeContextData *p, bool parentTakesOwnership)
{
if (p) {
parent = p;
@@ -623,6 +628,7 @@ void QDeclarativeContextData::setParent(QDeclarativeContextData *p)
if (nextChild) nextChild->prevChild = &nextChild;
prevChild = &p->childContexts;
p->childContexts = this;
+ ownedByParent = parentTakesOwnership;
}
}
@@ -662,72 +668,6 @@ void QDeclarativeContextData::addObject(QObject *o)
contextObjects = data;
}
-void QDeclarativeContextData::addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script)
-{
- if (!engine)
- return;
-
- QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
- QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
-
- const QString &code = script.code;
- const QString &url = script.file;
- const QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = script.pragmas;
-
- Q_ASSERT(!url.isEmpty());
-
- if (pragmas & QDeclarativeParser::Object::ScriptBlock::Shared) {
-
- QHash<QString, QScriptValue>::Iterator iter = enginePriv->m_sharedScriptImports.find(url);
- if (iter == enginePriv->m_sharedScriptImports.end()) {
- QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
-
- scriptContext->pushScope(enginePriv->contextClass->newUrlContext(url));
- scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject());
-
- QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine);
- scriptContext->pushScope(scope);
-
- scriptEngine->evaluate(code, url, 1);
-
- if (scriptEngine->hasUncaughtException()) {
- QDeclarativeError error;
- QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
- enginePriv->warning(error);
- }
-
- scriptEngine->popContext();
-
- iter = enginePriv->m_sharedScriptImports.insert(url, scope);
- }
-
- importedScripts.append(*iter);
-
- } else {
-
- QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
-
- scriptContext->pushScope(enginePriv->contextClass->newUrlContext(this, 0, url));
- scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject());
-
- QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine);
- scriptContext->pushScope(scope);
-
- scriptEngine->evaluate(code, url, 1);
-
- if (scriptEngine->hasUncaughtException()) {
- QDeclarativeError error;
- QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
- enginePriv->warning(error);
- }
-
- scriptEngine->popContext();
-
- importedScripts.append(scope);
-
- }
-}
-
void QDeclarativeContextData::setIdProperty(int idx, QObject *obj)
{
idValues[idx] = obj;
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index aa5f17c4f6..d7486b9653 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -77,7 +77,7 @@ class QDeclarativeEngine;
class QDeclarativeExpression;
class QDeclarativeExpressionPrivate;
class QDeclarativeAbstractExpression;
-class QDeclarativeCompiledBindings;
+class QDeclarativeV4Bindings;
class QDeclarativeContextData;
class QDeclarativeContextPrivate : public QObjectPrivate
@@ -124,7 +124,7 @@ public:
QDeclarativeContextData *parent;
QDeclarativeEngine *engine;
- void setParent(QDeclarativeContextData *);
+ void setParent(QDeclarativeContextData *, bool parentTakesOwnership = false);
void refreshExpressions();
void addObject(QObject *);
@@ -135,7 +135,9 @@ public:
// If internal is false publicContext owns this.
QDeclarativeContext *asQDeclarativeContext();
QDeclarativeContextPrivate *asQDeclarativeContextPrivate();
- bool isInternal;
+ quint32 isInternal:1;
+ quint32 ownedByParent:1; // unrelated to isInternal; parent context deletes children if true.
+ quint32 dummy:30;
QDeclarativeContext *publicContext;
// Property name cache
@@ -146,7 +148,6 @@ public:
// Any script blocks that exist on this context
QList<QScriptValue> importedScripts;
- void addImportedScript(const QDeclarativeParser::Object::ScriptBlock &script);
// Context base url
QUrl url;
@@ -188,7 +189,7 @@ public:
void setIdPropertyData(QDeclarativeIntegerCache *);
// Optimized binding pointer
- QDeclarativeCompiledBindings *optimizedBindings;
+ QDeclarativeV4Bindings *optimizedBindings;
// Linked contexts. this owns linkedContext.
QDeclarativeContextData *linkedContext;
diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp
index 0a7a749c43..ba7aca038d 100644
--- a/src/declarative/qml/qdeclarativedirparser.cpp
+++ b/src/declarative/qml/qdeclarativedirparser.cpp
@@ -142,7 +142,7 @@ bool QDeclarativeDirParser::parse()
} else if (sections[0] == QLatin1String("plugin")) {
if (sectionCount < 2) {
reportError(lineNumber, -1,
- QString::fromUtf8("plugin directive requires 2 arguments, but %1 were provided").arg(sectionCount + 1));
+ QString::fromUtf8("plugin directive requires one or two arguments, but %1 were provided").arg(sectionCount - 1));
continue;
}
@@ -154,12 +154,22 @@ bool QDeclarativeDirParser::parse()
} else if (sections[0] == QLatin1String("internal")) {
if (sectionCount != 3) {
reportError(lineNumber, -1,
- QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount + 1));
+ QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1));
continue;
}
Component entry(sections[1], sections[2], -1, -1);
entry.internal = true;
_components.append(entry);
+ } else if (sections[0] == QLatin1String("typeinfo")) {
+ if (sectionCount != 2) {
+ reportError(lineNumber, -1,
+ QString::fromUtf8("typeinfo requires 1 argument, but %1 were provided").arg(sectionCount - 1));
+ continue;
+ }
+#ifdef QT_CREATOR
+ TypeInfo typeInfo(sections[1]);
+ _typeInfos.append(typeInfo);
+#endif
} else if (sectionCount == 2) {
// No version specified (should only be used for relative qmldir files)
@@ -189,7 +199,7 @@ bool QDeclarativeDirParser::parse()
}
} else {
reportError(lineNumber, -1,
- QString::fromUtf8("a component declaration requires 3 arguments, but %1 were provided").arg(sectionCount + 1));
+ QString::fromUtf8("a component declaration requires two or three arguments, but %1 were provided").arg(sectionCount));
}
}
@@ -229,4 +239,11 @@ QList<QDeclarativeDirParser::Component> QDeclarativeDirParser::components() cons
return _components;
}
+#ifdef QT_CREATOR
+QList<QDeclarativeDirParser::TypeInfo> QDeclarativeDirParser::typeInfos() const
+{
+ return _typeInfos;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h
index 7db7d8cd46..d40833ac45 100644
--- a/src/declarative/qml/qdeclarativedirparser_p.h
+++ b/src/declarative/qml/qdeclarativedirparser_p.h
@@ -109,6 +109,19 @@ public:
QList<Component> components() const;
QList<Plugin> plugins() const;
+#ifdef QT_CREATOR
+ struct TypeInfo
+ {
+ TypeInfo() {}
+ TypeInfo(const QString &fileName)
+ : fileName(fileName) {}
+
+ QString fileName;
+ };
+
+ QList<TypeInfo> typeInfos() const;
+#endif
+
private:
void reportError(int line, int column, const QString &message);
@@ -118,6 +131,9 @@ private:
QString _source;
QList<Component> _components;
QList<Plugin> _plugins;
+#ifdef QT_CREATOR
+ QList<TypeInfo> _typeInfos;
+#endif
unsigned _isParsed: 1;
};
diff --git a/src/declarative/qml/qdeclarativedom.cpp b/src/declarative/qml/qdeclarativedom.cpp
deleted file mode 100644
index ac59123f67..0000000000
--- a/src/declarative/qml/qdeclarativedom.cpp
+++ /dev/null
@@ -1,1835 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qdeclarativedom_p.h"
-#include "private/qdeclarativedom_p_p.h"
-
-#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativescriptparser_p.h"
-#include "private/qdeclarativeglobal_p.h"
-
-#include <QtCore/QByteArray>
-#include <QtCore/QDebug>
-#include <QtCore/QString>
-
-QT_BEGIN_NAMESPACE
-
-QDeclarativeDomDocumentPrivate::QDeclarativeDomDocumentPrivate()
-: root(0)
-{
-}
-
-QDeclarativeDomDocumentPrivate::~QDeclarativeDomDocumentPrivate()
-{
- if (root) root->release();
-}
-
-/*!
- \class QDeclarativeDomDocument
- \internal
- \brief The QDeclarativeDomDocument class represents the root of a QML document
-
- A QML document is a self-contained snippet of QML, usually contained in a
- single file. Each document has a root object, accessible through
- QDeclarativeDomDocument::rootObject().
-
- The QDeclarativeDomDocument class allows the programmer to inspect a QML document by
- calling QDeclarativeDomDocument::load().
-
- The following example loads a QML file from disk, and prints out its root
- object type and the properties assigned in the root object.
- \code
- QFile file(inputFileName);
- file.open(QIODevice::ReadOnly);
- QByteArray xmlData = file.readAll();
-
- QDeclarativeDomDocument document;
- document.load(qmlengine, xmlData);
-
- QDeclarativeDomObject rootObject = document.rootObject();
- qDebug() << rootObject.objectType();
- foreach(QDeclarativeDomProperty property, rootObject.properties())
- qDebug() << property.propertyName();
- \endcode
-*/
-
-/*!
- Construct an empty QDeclarativeDomDocument.
-*/
-QDeclarativeDomDocument::QDeclarativeDomDocument()
-: d(new QDeclarativeDomDocumentPrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomDocument.
-*/
-QDeclarativeDomDocument::QDeclarativeDomDocument(const QDeclarativeDomDocument &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomDocument
-*/
-QDeclarativeDomDocument::~QDeclarativeDomDocument()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomDocument.
-*/
-QDeclarativeDomDocument &QDeclarativeDomDocument::operator=(const QDeclarativeDomDocument &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Returns all import statements in qml.
-*/
-QList<QDeclarativeDomImport> QDeclarativeDomDocument::imports() const
-{
- return d->imports;
-}
-
-/*!
- Loads a QDeclarativeDomDocument from \a data. \a data should be valid QML
- data. On success, true is returned. If the \a data is malformed, false
- is returned and QDeclarativeDomDocument::errors() contains an error description.
-
- \sa QDeclarativeDomDocument::loadError()
-*/
-bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray &data, const QUrl &url)
-{
- d->errors.clear();
- d->imports.clear();
-
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeTypeData *td = ep->typeLoader.get(data, url, QDeclarativeTypeLoader::PreserveParser);
-
- if(td->isError()) {
- d->errors = td->errors();
- td->release();
- return false;
- } else if(!td->isCompleteOrError()) {
- QDeclarativeError error;
- error.setDescription(QLatin1String("QDeclarativeDomDocument supports local types only"));
- d->errors << error;
- td->release();
- return false;
- }
-
- for (int i = 0; i < td->parser().imports().size(); ++i) {
- QDeclarativeScriptParser::Import parserImport = td->parser().imports().at(i);
- QDeclarativeDomImport domImport;
- domImport.d->type = static_cast<QDeclarativeDomImportPrivate::Type>(parserImport.type);
- domImport.d->uri = parserImport.uri;
- domImport.d->qualifier = parserImport.qualifier;
- domImport.d->version = parserImport.version;
- d->imports += domImport;
- }
-
- if (td->parser().tree()) {
- d->root = td->parser().tree();
- d->root->addref();
- }
-
- td->release();
- return true;
-}
-
-/*!
- Returns the last load errors. The load errors will be reset after a
- successful call to load().
-
- \sa load()
-*/
-QList<QDeclarativeError> QDeclarativeDomDocument::errors() const
-{
- return d->errors;
-}
-
-/*!
- Returns the document's root object, or an invalid QDeclarativeDomObject if the
- document has no root.
-
- In the sample QML below, the root object will be the QDeclarativeItem type.
- \qml
-Item {
- Text {
- text: "Hello World"
- }
-}
- \endqml
-*/
-QDeclarativeDomObject QDeclarativeDomDocument::rootObject() const
-{
- QDeclarativeDomObject rv;
- rv.d->object = d->root;
- if (rv.d->object) rv.d->object->addref();
- return rv;
-}
-
-QDeclarativeDomPropertyPrivate::QDeclarativeDomPropertyPrivate()
-: property(0)
-{
-}
-
-QDeclarativeDomPropertyPrivate::~QDeclarativeDomPropertyPrivate()
-{
- if (property) property->release();
-}
-
-QDeclarativeDomDynamicPropertyPrivate::QDeclarativeDomDynamicPropertyPrivate():
- valid(false)
-{
-}
-
-QDeclarativeDomDynamicPropertyPrivate::~QDeclarativeDomDynamicPropertyPrivate()
-{
- if (valid && property.defaultValue) property.defaultValue->release();
-}
-
-/*!
- \class QDeclarativeDomProperty
- \internal
- \brief The QDeclarativeDomProperty class represents one property assignment in the
- QML DOM tree
-
- Properties in QML can be assigned QML \l {QDeclarativeDomValue}{values}.
-
- \sa QDeclarativeDomObject
-*/
-
-/*!
- Construct an invalid QDeclarativeDomProperty.
-*/
-QDeclarativeDomProperty::QDeclarativeDomProperty()
-: d(new QDeclarativeDomPropertyPrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomProperty.
-*/
-QDeclarativeDomProperty::QDeclarativeDomProperty(const QDeclarativeDomProperty &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomProperty.
-*/
-QDeclarativeDomProperty::~QDeclarativeDomProperty()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomProperty.
-*/
-QDeclarativeDomProperty &QDeclarativeDomProperty::operator=(const QDeclarativeDomProperty &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Returns true if this is a valid QDeclarativeDomProperty, false otherwise.
-*/
-bool QDeclarativeDomProperty::isValid() const
-{
- return d->property != 0;
-}
-
-
-/*!
- Return the name of this property.
-
- \qml
-Text {
- x: 10
- y: 10
- font.bold: true
-}
- \endqml
-
- As illustrated above, a property name can be a simple string, such as "x" or
- "y", or a more complex "dot property", such as "font.bold". In both cases
- the full name is returned ("x", "y" and "font.bold") by this method.
-
- For dot properties, a split version of the name can be accessed by calling
- QDeclarativeDomProperty::propertyNameParts().
-
- \sa QDeclarativeDomProperty::propertyNameParts()
-*/
-QByteArray QDeclarativeDomProperty::propertyName() const
-{
- return d->propertyName;
-}
-
-/*!
- Return the name of this property, split into multiple parts in the case
- of dot properties.
-
- \qml
-Text {
- x: 10
- y: 10
- font.bold: true
-}
- \endqml
-
- For each of the properties shown above, this method would return ("x"),
- ("y") and ("font", "bold").
-
- \sa QDeclarativeDomProperty::propertyName()
-*/
-QList<QByteArray> QDeclarativeDomProperty::propertyNameParts() const
-{
- if (d->propertyName.isEmpty()) return QList<QByteArray>();
- else return d->propertyName.split('.');
-}
-
-/*!
- Return true if this property is used as a default property in the QML
- document.
-
- \code
-<Text text="hello"/>
-<Text>hello</Text>
- \endcode
-
- The above two examples return the same DOM tree, except that the second has
- the default property flag set on the text property. Observe that whether
- or not a property has isDefaultProperty set is determined by how the
- property is used, and not only by whether the property is the types default
- property.
-*/
-bool QDeclarativeDomProperty::isDefaultProperty() const
-{
- return d->property && d->property->isDefault;
-}
-
-/*!
- Returns the QDeclarativeDomValue that is assigned to this property, or an invalid
- QDeclarativeDomValue if no value is assigned.
-*/
-QDeclarativeDomValue QDeclarativeDomProperty::value() const
-{
- QDeclarativeDomValue rv;
- if (d->property) {
- rv.d->property = d->property;
- if (d->property->values.count())
- rv.d->value = d->property->values.at(0);
- else
- rv.d->value = d->property->onValues.at(0);
- rv.d->property->addref();
- rv.d->value->addref();
- }
- return rv;
-}
-
-/*!
- Returns the position in the input data where the property ID startd, or -1 if
- the property is invalid.
-*/
-int QDeclarativeDomProperty::position() const
-{
- if (d && d->property) {
- return d->property->location.range.offset;
- } else
- return -1;
-}
-
-/*!
- Returns the length in the input data from where the property ID started upto
- the end of it, or -1 if the property is invalid.
-*/
-int QDeclarativeDomProperty::length() const
-{
- if (d && d->property)
- return d->property->location.range.length;
- else
- return -1;
-}
-
-/*!
- Construct an invalid QDeclarativeDomDynamicProperty.
-*/
-QDeclarativeDomDynamicProperty::QDeclarativeDomDynamicProperty():
- d(new QDeclarativeDomDynamicPropertyPrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomDynamicProperty.
-*/
-QDeclarativeDomDynamicProperty::QDeclarativeDomDynamicProperty(const QDeclarativeDomDynamicProperty &other):
- d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomDynamicProperty.
-*/
-QDeclarativeDomDynamicProperty::~QDeclarativeDomDynamicProperty()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomDynamicProperty.
-*/
-QDeclarativeDomDynamicProperty &QDeclarativeDomDynamicProperty::operator=(const QDeclarativeDomDynamicProperty &other)
-{
- d = other.d;
- return *this;
-}
-
-bool QDeclarativeDomDynamicProperty::isValid() const
-{
- return d && d->valid;
-}
-
-/*!
- Return the name of this dynamic property.
-
- \qml
-Item {
- property int count: 10;
-}
- \endqml
-
- As illustrated above, a dynamic property name can have a name and a
- default value ("10").
-*/
-QByteArray QDeclarativeDomDynamicProperty::propertyName() const
-{
- if (isValid())
- return d->property.name;
- else
- return QByteArray();
-}
-
-/*!
- Returns the type of the dynamic property. Note that when the property is an
- alias property, this will return -1. Use QDeclarativeDomProperty::isAlias() to check
- if the property is an alias.
-*/
-int QDeclarativeDomDynamicProperty::propertyType() const
-{
- if (isValid()) {
- switch (d->property.type) {
- case QDeclarativeParser::Object::DynamicProperty::Bool:
- return QMetaType::type("bool");
-
- case QDeclarativeParser::Object::DynamicProperty::Color:
- return QMetaType::type("QColor");
-
- case QDeclarativeParser::Object::DynamicProperty::Time:
- return QMetaType::type("QTime");
-
- case QDeclarativeParser::Object::DynamicProperty::Date:
- return QMetaType::type("QDate");
-
- case QDeclarativeParser::Object::DynamicProperty::DateTime:
- return QMetaType::type("QDateTime");
-
- case QDeclarativeParser::Object::DynamicProperty::Int:
- return QMetaType::type("int");
-
- case QDeclarativeParser::Object::DynamicProperty::Real:
- return sizeof(qreal) == sizeof(double) ? QMetaType::type("double") : QMetaType::type("float");
-
- case QDeclarativeParser::Object::DynamicProperty::String:
- return QMetaType::type("QString");
-
- case QDeclarativeParser::Object::DynamicProperty::Url:
- return QMetaType::type("QUrl");
-
- case QDeclarativeParser::Object::DynamicProperty::Variant:
- return QMetaType::type("QVariant");
-
- default:
- break;
- }
- }
-
- return -1;
-}
-
-QByteArray QDeclarativeDomDynamicProperty::propertyTypeName() const
-{
- if (isValid())
- return d->property.customType;
-
- return QByteArray();
-}
-
-/*!
- Return true if this property is used as a default property in the QML
- document.
-
- \code
-<Text text="hello"/>
-<Text>hello</Text>
- \endcode
-
- The above two examples return the same DOM tree, except that the second has
- the default property flag set on the text property. Observe that whether
- or not a property has isDefaultProperty set is determined by how the
- property is used, and not only by whether the property is the types default
- property.
-*/
-bool QDeclarativeDomDynamicProperty::isDefaultProperty() const
-{
- if (isValid())
- return d->property.isDefaultProperty;
- else
- return false;
-}
-
-/*!
- Returns the default value as a QDeclarativeDomProperty.
-*/
-QDeclarativeDomProperty QDeclarativeDomDynamicProperty::defaultValue() const
-{
- QDeclarativeDomProperty rp;
-
- if (isValid() && d->property.defaultValue) {
- rp.d->property = d->property.defaultValue;
- rp.d->propertyName = propertyName();
- rp.d->property->addref();
- }
-
- return rp;
-}
-
-/*!
- Returns true if this dynamic property is an alias for another property,
- false otherwise.
-*/
-bool QDeclarativeDomDynamicProperty::isAlias() const
-{
- if (isValid())
- return d->property.type == QDeclarativeParser::Object::DynamicProperty::Alias;
- else
- return false;
-}
-
-/*!
- Returns the position in the input data where the property ID startd, or 0 if
- the property is invalid.
-*/
-int QDeclarativeDomDynamicProperty::position() const
-{
- if (isValid()) {
- return d->property.location.range.offset;
- } else
- return -1;
-}
-
-/*!
- Returns the length in the input data from where the property ID started upto
- the end of it, or 0 if the property is invalid.
-*/
-int QDeclarativeDomDynamicProperty::length() const
-{
- if (isValid())
- return d->property.location.range.length;
- else
- return -1;
-}
-
-QDeclarativeDomObjectPrivate::QDeclarativeDomObjectPrivate()
-: object(0)
-{
-}
-
-QDeclarativeDomObjectPrivate::~QDeclarativeDomObjectPrivate()
-{
- if (object) object->release();
-}
-
-QDeclarativeDomObjectPrivate::Properties
-QDeclarativeDomObjectPrivate::properties() const
-{
- Properties rv;
-
- for (QHash<QByteArray, QDeclarativeParser::Property *>::ConstIterator iter =
- object->properties.begin();
- iter != object->properties.end();
- ++iter) {
-
- rv << properties(*iter);
-
- }
- return rv;
-}
-
-QDeclarativeDomObjectPrivate::Properties
-QDeclarativeDomObjectPrivate::properties(QDeclarativeParser::Property *property) const
-{
- Properties rv;
-
- if (property->value) {
-
- for (QHash<QByteArray, QDeclarativeParser::Property *>::ConstIterator iter =
- property->value->properties.begin();
- iter != property->value->properties.end();
- ++iter) {
-
- rv << properties(*iter);
-
- }
-
- QByteArray name(property->name + '.');
- for (Properties::Iterator iter = rv.begin(); iter != rv.end(); ++iter)
- iter->second.prepend(name);
-
- } else {
- rv << qMakePair(property, property->name);
- }
-
- return rv;
-}
-
-/*!
- \class QDeclarativeDomObject
- \internal
- \brief The QDeclarativeDomObject class represents an object instantiation.
-
- Each object instantiated in a QML file has a corresponding QDeclarativeDomObject
- node in the QML DOM.
-
- In addition to the type information that determines the object to
- instantiate, QDeclarativeDomObject's also have a set of associated QDeclarativeDomProperty's.
- Each QDeclarativeDomProperty represents a QML property assignment on the instantiated
- object. For example,
-
- \qml
-QGraphicsWidget {
- opacity: 0.5
- size: "100x100"
-}
- \endqml
-
- describes a single QDeclarativeDomObject - "QGraphicsWidget" - with two properties,
- "opacity" and "size". Obviously QGraphicsWidget has many more properties than just
- these two, but the QML DOM representation only contains those assigned
- values (or bindings) in the QML file.
-*/
-
-/*!
- Construct an invalid QDeclarativeDomObject.
-*/
-QDeclarativeDomObject::QDeclarativeDomObject()
-: d(new QDeclarativeDomObjectPrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomObject.
-*/
-QDeclarativeDomObject::QDeclarativeDomObject(const QDeclarativeDomObject &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomObject.
-*/
-QDeclarativeDomObject::~QDeclarativeDomObject()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomObject.
-*/
-QDeclarativeDomObject &QDeclarativeDomObject::operator=(const QDeclarativeDomObject &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Returns true if this is a valid QDeclarativeDomObject, false otherwise.
-*/
-bool QDeclarativeDomObject::isValid() const
-{
- return d->object != 0;
-}
-
-/*!
- Returns the fully-qualified type name of this object.
-
- For example, the type of this object would be "Qt/4.6/Rectangle".
- \qml
-Rectangle { }
- \endqml
-*/
-QByteArray QDeclarativeDomObject::objectType() const
-{
- if (d->object) return d->object->typeName;
- else return QByteArray();
-}
-
-/*!
- Returns the type name as referenced in the qml file.
-
- For example, the type of this object would be "Rectangle".
- \qml
-Rectangle { }
- \endqml
-*/
-QByteArray QDeclarativeDomObject::objectClassName() const
-{
- if (d->object)
- return d->object->className;
- else
- return QByteArray();
-}
-
-int QDeclarativeDomObject::objectTypeMajorVersion() const
-{
- if (d->object)
- return d->object->majorVersion;
- else
- return -1;
-}
-
-int QDeclarativeDomObject::objectTypeMinorVersion() const
-{
- if (d->object)
- return d->object->minorVersion;
- else
- return -1;
-}
-
-/*!
- Returns the QML id assigned to this object, or an empty QByteArray if no id
- has been assigned.
-
- For example, the object id of this object would be "MyText".
- \qml
-Text { id: myText }
- \endqml
-*/
-QString QDeclarativeDomObject::objectId() const
-{
- if (d->object) {
- return d->object->id;
- } else {
- return QString();
- }
-}
-
-/*!
- Returns the list of assigned properties on this object.
-
- In the following example, "text" and "x" properties would be returned.
- \qml
-Text {
- text: "Hello world!"
- x: 100
-}
- \endqml
-*/
-QList<QDeclarativeDomProperty> QDeclarativeDomObject::properties() const
-{
- QList<QDeclarativeDomProperty> rv;
-
- if (!d->object || isComponent())
- return rv;
-
- QDeclarativeDomObjectPrivate::Properties properties = d->properties();
- for (int ii = 0; ii < properties.count(); ++ii) {
-
- QDeclarativeDomProperty domProperty;
- domProperty.d->property = properties.at(ii).first;
- domProperty.d->property->addref();
- domProperty.d->propertyName = properties.at(ii).second;
- rv << domProperty;
-
- }
-
- if (d->object->defaultProperty) {
- QDeclarativeDomProperty domProperty;
- domProperty.d->property = d->object->defaultProperty;
- domProperty.d->property->addref();
- domProperty.d->propertyName = d->object->defaultProperty->name;
- rv << domProperty;
- }
-
- return rv;
-}
-
-/*!
- Returns the object's \a name property if a value has been assigned to
- it, or an invalid QDeclarativeDomProperty otherwise.
-
- In the example below, \c {object.property("source")} would return a valid
- QDeclarativeDomProperty, and \c {object.property("tile")} an invalid QDeclarativeDomProperty.
-
- \qml
-Image { source: "sample.jpg" }
- \endqml
-*/
-QDeclarativeDomProperty QDeclarativeDomObject::property(const QByteArray &name) const
-{
- QList<QDeclarativeDomProperty> props = properties();
- for (int ii = 0; ii < props.count(); ++ii)
- if (props.at(ii).propertyName() == name)
- return props.at(ii);
- return QDeclarativeDomProperty();
-}
-
-QList<QDeclarativeDomDynamicProperty> QDeclarativeDomObject::dynamicProperties() const
-{
- QList<QDeclarativeDomDynamicProperty> properties;
-
- for (int i = 0; i < d->object->dynamicProperties.size(); ++i) {
- QDeclarativeDomDynamicProperty p;
- p.d = new QDeclarativeDomDynamicPropertyPrivate;
- p.d->property = d->object->dynamicProperties.at(i);
- p.d->valid = true;
-
- if (p.d->property.defaultValue)
- p.d->property.defaultValue->addref();
-
- properties.append(p);
- }
-
- return properties;
-}
-
-QDeclarativeDomDynamicProperty QDeclarativeDomObject::dynamicProperty(const QByteArray &name) const
-{
- QDeclarativeDomDynamicProperty p;
-
- if (!isValid())
- return p;
-
- for (int i = 0; i < d->object->dynamicProperties.size(); ++i) {
- if (d->object->dynamicProperties.at(i).name == name) {
- p.d = new QDeclarativeDomDynamicPropertyPrivate;
- p.d->property = d->object->dynamicProperties.at(i);
- if (p.d->property.defaultValue) p.d->property.defaultValue->addref();
- p.d->valid = true;
- }
- }
-
- return p;
-}
-
-/*!
- Returns true if this object is a custom type. Custom types are special
- types that allow embeddeding non-QML data, such as SVG or HTML data,
- directly into QML files.
-
- \note Currently this method will always return false, and is a placekeeper
- for future functionality.
-
- \sa QDeclarativeDomObject::customTypeData()
-*/
-bool QDeclarativeDomObject::isCustomType() const
-{
- return false;
-}
-
-/*!
- If this object represents a custom type, returns the data associated with
- the custom type, otherwise returns an empty QByteArray().
- QDeclarativeDomObject::isCustomType() can be used to check if this object represents
- a custom type.
-*/
-QByteArray QDeclarativeDomObject::customTypeData() const
-{
- return QByteArray();
-}
-
-/*!
- Returns true if this object is a sub-component object. Sub-component
- objects can be converted into QDeclarativeDomComponent instances by calling
- QDeclarativeDomObject::toComponent().
-
- \sa QDeclarativeDomObject::toComponent()
-*/
-bool QDeclarativeDomObject::isComponent() const
-{
- return (d->object && (d->object->typeName == "Qt/Component" || d->object->typeName == "QtQuick/Component"));
-}
-
-/*!
- Returns a QDeclarativeDomComponent for this object if it is a sub-component, or
- an invalid QDeclarativeDomComponent if not. QDeclarativeDomObject::isComponent() can be used
- to check if this object represents a sub-component.
-
- \sa QDeclarativeDomObject::isComponent()
-*/
-QDeclarativeDomComponent QDeclarativeDomObject::toComponent() const
-{
- QDeclarativeDomComponent rv;
- if (isComponent())
- rv.d = d;
- return rv;
-}
-
-/*!
- Returns the position in the input data where the property assignment started
-, or -1 if the property is invalid.
-*/
-int QDeclarativeDomObject::position() const
-{
- if (d && d->object)
- return d->object->location.range.offset;
- else
- return -1;
-}
-
-/*!
- Returns the length in the input data from where the property assignment star
-ted upto the end of it, or -1 if the property is invalid.
-*/
-int QDeclarativeDomObject::length() const
-{
- if (d && d->object)
- return d->object->location.range.length;
- else
- return -1;
-}
-
-// Returns the URL of the type, if it is an external type, or an empty URL if
-// not
-QUrl QDeclarativeDomObject::url() const
-{
- if (d && d->object)
- return d->object->url;
- else
- return QUrl();
-}
-
-QDeclarativeDomBasicValuePrivate::QDeclarativeDomBasicValuePrivate()
-: value(0)
-{
-}
-
-QDeclarativeDomBasicValuePrivate::~QDeclarativeDomBasicValuePrivate()
-{
- if (value) value->release();
-}
-
-/*!
- \class QDeclarativeDomValueLiteral
- \internal
- \brief The QDeclarativeDomValueLiteral class represents a literal value.
-
- A literal value is a simple value, written inline with the QML. In the
- example below, the "x", "y" and "color" properties are being assigned
- literal values.
-
- \qml
-Rectangle {
- x: 10
- y: 10
- color: "red"
-}
- \endqml
-*/
-
-/*!
- Construct an empty QDeclarativeDomValueLiteral.
-*/
-QDeclarativeDomValueLiteral::QDeclarativeDomValueLiteral():
- d(new QDeclarativeDomBasicValuePrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomValueLiteral.
-*/
-QDeclarativeDomValueLiteral::QDeclarativeDomValueLiteral(const QDeclarativeDomValueLiteral &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomValueLiteral.
-*/
-QDeclarativeDomValueLiteral::~QDeclarativeDomValueLiteral()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomValueLiteral.
-*/
-QDeclarativeDomValueLiteral &QDeclarativeDomValueLiteral::operator=(const QDeclarativeDomValueLiteral &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Return the literal value.
-
- In the example below, the literal value will be the string "10".
- \qml
-Rectangle { x: 10 }
- \endqml
-*/
-QString QDeclarativeDomValueLiteral::literal() const
-{
- if (d->value) return d->value->primitive();
- else return QString();
-}
-
-/*!
- \class QDeclarativeDomValueBinding
- \internal
- \brief The QDeclarativeDomValueBinding class represents a property binding.
-
- A property binding is an ECMAScript expression assigned to a property. In
- the example below, the "x" property is being assigned a property binding.
-
- \qml
-Rectangle { x: Other.x }
- \endqml
-*/
-
-/*!
- Construct an empty QDeclarativeDomValueBinding.
-*/
-QDeclarativeDomValueBinding::QDeclarativeDomValueBinding():
- d(new QDeclarativeDomBasicValuePrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomValueBinding.
-*/
-QDeclarativeDomValueBinding::QDeclarativeDomValueBinding(const QDeclarativeDomValueBinding &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomValueBinding.
-*/
-QDeclarativeDomValueBinding::~QDeclarativeDomValueBinding()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomValueBinding.
-*/
-QDeclarativeDomValueBinding &QDeclarativeDomValueBinding::operator=(const QDeclarativeDomValueBinding &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Return the binding expression.
-
- In the example below, the string "Other.x" will be returned.
- \qml
-Rectangle { x: Other.x }
- \endqml
-*/
-QString QDeclarativeDomValueBinding::binding() const
-{
- if (d->value)
- return d->value->value.asScript();
- else
- return QString();
-}
-
-/*!
- \class QDeclarativeDomValueValueSource
- \internal
- \brief The QDeclarativeDomValueValueSource class represents a value source assignment value.
-
- In QML, value sources are special value generating types that may be
- assigned to properties. Value sources inherit the QDeclarativePropertyValueSource
- class. In the example below, the "x" property is being assigned the
- NumberAnimation value source.
-
- \qml
-Rectangle {
- x: NumberAnimation {
- from: 0
- to: 100
- loops: Animation.Infinite
- }
-}
- \endqml
-*/
-
-/*!
- Construct an empty QDeclarativeDomValueValueSource.
-*/
-QDeclarativeDomValueValueSource::QDeclarativeDomValueValueSource():
- d(new QDeclarativeDomBasicValuePrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomValueValueSource.
-*/
-QDeclarativeDomValueValueSource::QDeclarativeDomValueValueSource(const QDeclarativeDomValueValueSource &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomValueValueSource.
-*/
-QDeclarativeDomValueValueSource::~QDeclarativeDomValueValueSource()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomValueValueSource.
-*/
-QDeclarativeDomValueValueSource &QDeclarativeDomValueValueSource::operator=(const QDeclarativeDomValueValueSource &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Return the value source object.
-
- In the example below, an object representing the NumberAnimation will be
- returned.
- \qml
-Rectangle {
- x: NumberAnimation {
- from: 0
- to: 100
- loops: Animation.Infinite
- }
-}
- \endqml
-*/
-QDeclarativeDomObject QDeclarativeDomValueValueSource::object() const
-{
- QDeclarativeDomObject rv;
- if (d->value) {
- rv.d->object = d->value->object;
- rv.d->object->addref();
- }
- return rv;
-}
-
-/*!
- \class QDeclarativeDomValueValueInterceptor
- \internal
- \brief The QDeclarativeDomValueValueInterceptor class represents a value interceptor assignment value.
-
- In QML, value interceptor are special write-intercepting types that may be
- assigned to properties. Value interceptor inherit the QDeclarativePropertyValueInterceptor
- class. In the example below, the "x" property is being assigned the
- Behavior value interceptor.
-
- \qml
-Rectangle {
- Behavior on x { NumberAnimation { duration: 500 } }
-}
- \endqml
-*/
-
-/*!
- Construct an empty QDeclarativeDomValueValueInterceptor.
-*/
-QDeclarativeDomValueValueInterceptor::QDeclarativeDomValueValueInterceptor():
- d(new QDeclarativeDomBasicValuePrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomValueValueInterceptor.
-*/
-QDeclarativeDomValueValueInterceptor::QDeclarativeDomValueValueInterceptor(const QDeclarativeDomValueValueInterceptor &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomValueValueInterceptor.
-*/
-QDeclarativeDomValueValueInterceptor::~QDeclarativeDomValueValueInterceptor()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomValueValueInterceptor.
-*/
-QDeclarativeDomValueValueInterceptor &QDeclarativeDomValueValueInterceptor::operator=(const QDeclarativeDomValueValueInterceptor &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Return the value interceptor object.
-
- In the example below, an object representing the Behavior will be
- returned.
- \qml
-Rectangle {
- Behavior on x { NumberAnimation { duration: 500 } }
-}
- \endqml
-*/
-QDeclarativeDomObject QDeclarativeDomValueValueInterceptor::object() const
-{
- QDeclarativeDomObject rv;
- if (d->value) {
- rv.d->object = d->value->object;
- rv.d->object->addref();
- }
- return rv;
-}
-
-QDeclarativeDomValuePrivate::QDeclarativeDomValuePrivate()
-: property(0), value(0)
-{
-}
-
-QDeclarativeDomValuePrivate::~QDeclarativeDomValuePrivate()
-{
- if (property) property->release();
- if (value) value->release();
-}
-
-/*!
- \class QDeclarativeDomValue
- \internal
- \brief The QDeclarativeDomValue class represents a generic Qml value.
-
- QDeclarativeDomValue's can be assigned to QML \l {QDeclarativeDomProperty}{properties}. In
- QML, properties can be assigned various different values, including basic
- literals, property bindings, property value sources, objects and lists of
- values. The QDeclarativeDomValue class allows a programmer to determine the specific
- value type being assigned and access more detailed information through a
- corresponding value type class.
-
- For example, in the following example,
-
- \qml
-Text {
- text: "Hello World!"
- y: Other.y
-}
- \endqml
-
- The text property is being assigned a literal, and the y property a property
- binding. To output the values assigned to the text and y properties in the
- above example from C++,
-
- \code
- QDeclarativeDomDocument document;
- QDeclarativeDomObject root = document.rootObject();
-
- QDeclarativeDomProperty text = root.property("text");
- if (text.value().isLiteral()) {
- QDeclarativeDomValueLiteral literal = text.value().toLiteral();
- qDebug() << literal.literal();
- }
-
- QDeclarativeDomProperty y = root.property("y");
- if (y.value().isBinding()) {
- QDeclarativeDomValueBinding binding = y.value().toBinding();
- qDebug() << binding.binding();
- }
- \endcode
-*/
-
-/*!
- Construct an invalid QDeclarativeDomValue.
-*/
-QDeclarativeDomValue::QDeclarativeDomValue()
-: d(new QDeclarativeDomValuePrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomValue.
-*/
-QDeclarativeDomValue::QDeclarativeDomValue(const QDeclarativeDomValue &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomValue
-*/
-QDeclarativeDomValue::~QDeclarativeDomValue()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomValue.
-*/
-QDeclarativeDomValue &QDeclarativeDomValue::operator=(const QDeclarativeDomValue &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- \enum QDeclarativeDomValue::Type
-
- The type of the QDeclarativeDomValue node.
-
- \value Invalid The QDeclarativeDomValue is invalid.
- \value Literal The QDeclarativeDomValue is a literal value assignment. Use QDeclarativeDomValue::toLiteral() to access the type instance.
- \value PropertyBinding The QDeclarativeDomValue is a property binding. Use QDeclarativeDomValue::toBinding() to access the type instance.
- \value ValueSource The QDeclarativeDomValue is a property value source. Use QDeclarativeDomValue::toValueSource() to access the type instance.
- \value ValueInterceptor The QDeclarativeDomValue is a property value interceptor. Use QDeclarativeDomValue::toValueInterceptor() to access the type instance.
- \value Object The QDeclarativeDomValue is an object assignment. Use QDeclarativeDomValue::toObject() to access the type instnace.
- \value List The QDeclarativeDomValue is a list of other values. Use QDeclarativeDomValue::toList() to access the type instance.
-*/
-
-/*!
- Returns the type of this QDeclarativeDomValue.
-*/
-QDeclarativeDomValue::Type QDeclarativeDomValue::type() const
-{
- if (d->property)
- if (QDeclarativeMetaType::isList(d->property->type) ||
- (d->property && (d->property->values.count() + d->property->onValues.count()) > 1))
- return List;
-
- QDeclarativeParser::Value *value = d->value;
- if (!value && !d->property)
- return Invalid;
-
- switch(value->type) {
- case QDeclarativeParser::Value::Unknown:
- return Invalid;
- case QDeclarativeParser::Value::Literal:
- return Literal;
- case QDeclarativeParser::Value::PropertyBinding:
- return PropertyBinding;
- case QDeclarativeParser::Value::ValueSource:
- return ValueSource;
- case QDeclarativeParser::Value::ValueInterceptor:
- return ValueInterceptor;
- case QDeclarativeParser::Value::CreatedObject:
- return Object;
- case QDeclarativeParser::Value::SignalObject:
- return Invalid;
- case QDeclarativeParser::Value::SignalExpression:
- return Literal;
- case QDeclarativeParser::Value::Id:
- return Literal;
- }
- return Invalid;
-}
-
-/*!
- Returns true if this is an invalid value, otherwise false.
-*/
-bool QDeclarativeDomValue::isInvalid() const
-{
- return type() == Invalid;
-}
-
-/*!
- Returns true if this is a literal value, otherwise false.
-*/
-bool QDeclarativeDomValue::isLiteral() const
-{
- return type() == Literal;
-}
-
-/*!
- Returns true if this is a property binding value, otherwise false.
-*/
-bool QDeclarativeDomValue::isBinding() const
-{
- return type() == PropertyBinding;
-}
-
-/*!
- Returns true if this is a value source value, otherwise false.
-*/
-bool QDeclarativeDomValue::isValueSource() const
-{
- return type() == ValueSource;
-}
-
-/*!
- Returns true if this is a value interceptor value, otherwise false.
-*/
-bool QDeclarativeDomValue::isValueInterceptor() const
-{
- return type() == ValueInterceptor;
-}
-
-/*!
- Returns true if this is an object value, otherwise false.
-*/
-bool QDeclarativeDomValue::isObject() const
-{
- return type() == Object;
-}
-
-/*!
- Returns true if this is a list value, otherwise false.
-*/
-bool QDeclarativeDomValue::isList() const
-{
- return type() == List;
-}
-
-/*!
- Returns a QDeclarativeDomValueLiteral if this value is a literal type, otherwise
- returns an invalid QDeclarativeDomValueLiteral.
-
- \sa QDeclarativeDomValue::type()
-*/
-QDeclarativeDomValueLiteral QDeclarativeDomValue::toLiteral() const
-{
- QDeclarativeDomValueLiteral rv;
- if (type() == Literal) {
- rv.d->value = d->value;
- rv.d->value->addref();
- }
- return rv;
-}
-
-/*!
- Returns a QDeclarativeDomValueBinding if this value is a property binding type,
- otherwise returns an invalid QDeclarativeDomValueBinding.
-
- \sa QDeclarativeDomValue::type()
-*/
-QDeclarativeDomValueBinding QDeclarativeDomValue::toBinding() const
-{
- QDeclarativeDomValueBinding rv;
- if (type() == PropertyBinding) {
- rv.d->value = d->value;
- rv.d->value->addref();
- }
- return rv;
-}
-
-/*!
- Returns a QDeclarativeDomValueValueSource if this value is a property value source
- type, otherwise returns an invalid QDeclarativeDomValueValueSource.
-
- \sa QDeclarativeDomValue::type()
-*/
-QDeclarativeDomValueValueSource QDeclarativeDomValue::toValueSource() const
-{
- QDeclarativeDomValueValueSource rv;
- if (type() == ValueSource) {
- rv.d->value = d->value;
- rv.d->value->addref();
- }
- return rv;
-}
-
-/*!
- Returns a QDeclarativeDomValueValueInterceptor if this value is a property value interceptor
- type, otherwise returns an invalid QDeclarativeDomValueValueInterceptor.
-
- \sa QDeclarativeDomValue::type()
-*/
-QDeclarativeDomValueValueInterceptor QDeclarativeDomValue::toValueInterceptor() const
-{
- QDeclarativeDomValueValueInterceptor rv;
- if (type() == ValueInterceptor) {
- rv.d->value = d->value;
- rv.d->value->addref();
- }
- return rv;
-}
-
-/*!
- Returns a QDeclarativeDomObject if this value is an object assignment type, otherwise
- returns an invalid QDeclarativeDomObject.
-
- \sa QDeclarativeDomValue::type()
-*/
-QDeclarativeDomObject QDeclarativeDomValue::toObject() const
-{
- QDeclarativeDomObject rv;
- if (type() == Object) {
- rv.d->object = d->value->object;
- rv.d->object->addref();
- }
- return rv;
-}
-
-/*!
- Returns a QDeclarativeDomList if this value is a list type, otherwise returns an
- invalid QDeclarativeDomList.
-
- \sa QDeclarativeDomValue::type()
-*/
-QDeclarativeDomList QDeclarativeDomValue::toList() const
-{
- QDeclarativeDomList rv;
- if (type() == List) {
- rv.d = d;
- }
- return rv;
-}
-
-/*!
- Returns the position in the input data where the property value startd, or -1
- if the value is invalid.
-*/
-int QDeclarativeDomValue::position() const
-{
- if (type() == Invalid)
- return -1;
- else
- return d->value->location.range.offset;
-}
-
-/*!
- Returns the length in the input data from where the property value started u
-pto the end of it, or -1 if the value is invalid.
-*/
-int QDeclarativeDomValue::length() const
-{
- if (type() == Invalid)
- return -1;
- else
- return d->value->location.range.length;
-}
-
-/*!
- \class QDeclarativeDomList
- \internal
- \brief The QDeclarativeDomList class represents a list of values assigned to a QML property.
-
- Lists of values can be assigned to properties. For example, the following
- example assigns multiple objects to Item's "children" property
- \qml
-Item {
- children: [
- Text { },
- Rectangle { }
- ]
-}
- \endqml
-
- Lists can also be implicitly created by assigning multiple
- \l {QDeclarativeDomValueValueSource}{value sources} or constants to a property.
- \qml
-Item {
- x: 10
- x: NumberAnimation {
- running: false
- from: 0
- to: 100
- }
-}
- \endqml
-*/
-
-/*!
- Construct an empty QDeclarativeDomList.
-*/
-QDeclarativeDomList::QDeclarativeDomList()
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomList.
-*/
-QDeclarativeDomList::QDeclarativeDomList(const QDeclarativeDomList &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomList.
-*/
-QDeclarativeDomList::~QDeclarativeDomList()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomList.
-*/
-QDeclarativeDomList &QDeclarativeDomList::operator=(const QDeclarativeDomList &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Returns the list of QDeclarativeDomValue's.
-*/
-QList<QDeclarativeDomValue> QDeclarativeDomList::values() const
-{
- QList<QDeclarativeDomValue> rv;
- if (!d->property)
- return rv;
-
- for (int ii = 0; ii < d->property->values.count(); ++ii) {
- QDeclarativeDomValue v;
- v.d->value = d->property->values.at(ii);
- v.d->value->addref();
- rv << v;
- }
-
- for (int ii = 0; ii < d->property->onValues.count(); ++ii) {
- QDeclarativeDomValue v;
- v.d->value = d->property->onValues.at(ii);
- v.d->value->addref();
- rv << v;
- }
-
- return rv;
-}
-
-/*!
- Returns the position in the input data where the list started, or -1 if
- the property is invalid.
-*/
-int QDeclarativeDomList::position() const
-{
- if (d && d->property) {
- return d->property->listValueRange.offset;
- } else
- return -1;
-}
-
-/*!
- Returns the length in the input data from where the list started upto
- the end of it, or 0 if the property is invalid.
-*/
-int QDeclarativeDomList::length() const
-{
- if (d && d->property)
- return d->property->listValueRange.length;
- else
- return -1;
-}
-
-/*!
- Returns a list of positions of the commas in the QML file.
-*/
-QList<int> QDeclarativeDomList:: commaPositions() const
-{
- if (d && d->property)
- return d->property->listCommaPositions;
- else
- return QList<int>();
-}
-
-/*!
- \class QDeclarativeDomComponent
- \internal
- \brief The QDeclarativeDomComponent class represents sub-component within a QML document.
-
- Sub-components are QDeclarativeComponents defined within a QML document. The
- following example shows the definition of a sub-component with the id
- "listDelegate".
-
- \qml
-Item {
- Component {
- id: listDelegate
- Text {
- text: modelData.text
- }
- }
-}
- \endqml
-
- Like QDeclarativeDomDocument's, components contain a single root object.
-*/
-
-/*!
- Construct an empty QDeclarativeDomComponent.
-*/
-QDeclarativeDomComponent::QDeclarativeDomComponent()
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomComponent.
-*/
-QDeclarativeDomComponent::QDeclarativeDomComponent(const QDeclarativeDomComponent &other)
-: QDeclarativeDomObject(other)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomComponent.
-*/
-QDeclarativeDomComponent::~QDeclarativeDomComponent()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomComponent.
-*/
-QDeclarativeDomComponent &QDeclarativeDomComponent::operator=(const QDeclarativeDomComponent &other)
-{
- static_cast<QDeclarativeDomObject &>(*this) = other;
- return *this;
-}
-
-/*!
- Returns the component's root object.
-
- In the example below, the root object is the "Text" object.
- \qml
-Item {
- Component {
- id: listDelegate
- Text {
- text: modelData.text
- }
- }
-}
- \endqml
-*/
-QDeclarativeDomObject QDeclarativeDomComponent::componentRoot() const
-{
- QDeclarativeDomObject rv;
- if (d->object) {
- QDeclarativeParser::Object *obj = 0;
- if (d->object->defaultProperty &&
- d->object->defaultProperty->values.count() == 1 &&
- d->object->defaultProperty->values.at(0)->object)
- obj = d->object->defaultProperty->values.at(0)->object;
-
- if (obj) {
- rv.d->object = obj;
- rv.d->object->addref();
- }
- }
-
- return rv;
-}
-
-QDeclarativeDomImportPrivate::QDeclarativeDomImportPrivate()
-: type(File)
-{
-}
-
-QDeclarativeDomImportPrivate::~QDeclarativeDomImportPrivate()
-{
-}
-
-/*!
- \class QDeclarativeDomImport
- \internal
- \brief The QDeclarativeDomImport class represents an import statement.
-*/
-
-/*!
- Construct an empty QDeclarativeDomImport.
-*/
-QDeclarativeDomImport::QDeclarativeDomImport()
-: d(new QDeclarativeDomImportPrivate)
-{
-}
-
-/*!
- Create a copy of \a other QDeclarativeDomImport.
-*/
-QDeclarativeDomImport::QDeclarativeDomImport(const QDeclarativeDomImport &other)
-: d(other.d)
-{
-}
-
-/*!
- Destroy the QDeclarativeDomImport.
-*/
-QDeclarativeDomImport::~QDeclarativeDomImport()
-{
-}
-
-/*!
- Assign \a other to this QDeclarativeDomImport.
-*/
-QDeclarativeDomImport &QDeclarativeDomImport::operator=(const QDeclarativeDomImport &other)
-{
- d = other.d;
- return *this;
-}
-
-/*!
- Returns the type of the import.
- */
-QDeclarativeDomImport::Type QDeclarativeDomImport::type() const
-{
- return static_cast<QDeclarativeDomImport::Type>(d->type);
-}
-
-/*!
- Returns the URI of the import (e.g. 'subdir' or 'com.nokia.Qt')
- */
-QString QDeclarativeDomImport::uri() const
-{
- return d->uri;
-}
-
-/*!
- Returns the version specified by the import. An empty string if no version was specified.
- */
-QString QDeclarativeDomImport::version() const
-{
- return d->version;
-}
-
-/*!
- Returns the (optional) qualifier string (the token following the 'as' keyword) of the import.
- */
-QString QDeclarativeDomImport::qualifier() const
-{
- return d->qualifier;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativedom_p.h b/src/declarative/qml/qdeclarativedom_p.h
deleted file mode 100644
index 9f255004e8..0000000000
--- a/src/declarative/qml/qdeclarativedom_p.h
+++ /dev/null
@@ -1,362 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEDOM_P_H
-#define QDECLARATIVEDOM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qdeclarativeerror.h"
-
-#include <QtCore/qlist.h>
-#include <QtCore/qshareddata.h>
-
-#include <private/qdeclarativeglobal_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QString;
-class QByteArray;
-class QDeclarativeDomObject;
-class QDeclarativeDomList;
-class QDeclarativeDomValue;
-class QDeclarativeEngine;
-class QDeclarativeDomComponent;
-class QDeclarativeDomImport;
-class QIODevice;
-
-class QDeclarativeDomDocumentPrivate;
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomDocument
-{
-public:
- QDeclarativeDomDocument();
- QDeclarativeDomDocument(const QDeclarativeDomDocument &);
- ~QDeclarativeDomDocument();
- QDeclarativeDomDocument &operator=(const QDeclarativeDomDocument &);
-
- QList<QDeclarativeDomImport> imports() const;
-
- QList<QDeclarativeError> errors() const;
- bool load(QDeclarativeEngine *, const QByteArray &, const QUrl & = QUrl());
-
- QDeclarativeDomObject rootObject() const;
-
-private:
- QSharedDataPointer<QDeclarativeDomDocumentPrivate> d;
-};
-
-class QDeclarativeDomPropertyPrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomProperty
-{
-public:
- QDeclarativeDomProperty();
- QDeclarativeDomProperty(const QDeclarativeDomProperty &);
- ~QDeclarativeDomProperty();
- QDeclarativeDomProperty &operator=(const QDeclarativeDomProperty &);
-
- bool isValid() const;
-
- QByteArray propertyName() const;
- QList<QByteArray> propertyNameParts() const;
-
- bool isDefaultProperty() const;
-
- QDeclarativeDomValue value() const;
-
- int position() const;
- int length() const;
-
-private:
- friend class QDeclarativeDomObject;
- friend class QDeclarativeDomDynamicProperty;
- QSharedDataPointer<QDeclarativeDomPropertyPrivate> d;
-};
-
-class QDeclarativeDomDynamicPropertyPrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomDynamicProperty
-{
-public:
- QDeclarativeDomDynamicProperty();
- QDeclarativeDomDynamicProperty(const QDeclarativeDomDynamicProperty &);
- ~QDeclarativeDomDynamicProperty();
- QDeclarativeDomDynamicProperty &operator=(const QDeclarativeDomDynamicProperty &);
-
- bool isValid() const;
-
- QByteArray propertyName() const;
- int propertyType() const;
- QByteArray propertyTypeName() const;
-
- bool isDefaultProperty() const;
- QDeclarativeDomProperty defaultValue() const;
-
- bool isAlias() const;
-
- int position() const;
- int length() const;
-
-private:
- friend class QDeclarativeDomObject;
- QSharedDataPointer<QDeclarativeDomDynamicPropertyPrivate> d;
-};
-
-class QDeclarativeDomObjectPrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomObject
-{
-public:
- QDeclarativeDomObject();
- QDeclarativeDomObject(const QDeclarativeDomObject &);
- ~QDeclarativeDomObject();
- QDeclarativeDomObject &operator=(const QDeclarativeDomObject &);
-
- bool isValid() const;
-
- QByteArray objectType() const;
- QByteArray objectClassName() const;
-
- int objectTypeMajorVersion() const;
- int objectTypeMinorVersion() const;
-
- QString objectId() const;
-
- QList<QDeclarativeDomProperty> properties() const;
- QDeclarativeDomProperty property(const QByteArray &) const;
-
- QList<QDeclarativeDomDynamicProperty> dynamicProperties() const;
- QDeclarativeDomDynamicProperty dynamicProperty(const QByteArray &) const;
-
- bool isCustomType() const;
- QByteArray customTypeData() const;
-
- bool isComponent() const;
- QDeclarativeDomComponent toComponent() const;
-
- int position() const;
- int length() const;
-
- QUrl url() const;
-private:
- friend class QDeclarativeDomDocument;
- friend class QDeclarativeDomComponent;
- friend class QDeclarativeDomValue;
- friend class QDeclarativeDomValueValueSource;
- friend class QDeclarativeDomValueValueInterceptor;
- QSharedDataPointer<QDeclarativeDomObjectPrivate> d;
-};
-
-class QDeclarativeDomValuePrivate;
-class QDeclarativeDomBasicValuePrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomValueLiteral
-{
-public:
- QDeclarativeDomValueLiteral();
- QDeclarativeDomValueLiteral(const QDeclarativeDomValueLiteral &);
- ~QDeclarativeDomValueLiteral();
- QDeclarativeDomValueLiteral &operator=(const QDeclarativeDomValueLiteral &);
-
- QString literal() const;
-
-private:
- friend class QDeclarativeDomValue;
- QSharedDataPointer<QDeclarativeDomBasicValuePrivate> d;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomValueBinding
-{
-public:
- QDeclarativeDomValueBinding();
- QDeclarativeDomValueBinding(const QDeclarativeDomValueBinding &);
- ~QDeclarativeDomValueBinding();
- QDeclarativeDomValueBinding &operator=(const QDeclarativeDomValueBinding &);
-
- QString binding() const;
-
-private:
- friend class QDeclarativeDomValue;
- QSharedDataPointer<QDeclarativeDomBasicValuePrivate> d;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomValueValueSource
-{
-public:
- QDeclarativeDomValueValueSource();
- QDeclarativeDomValueValueSource(const QDeclarativeDomValueValueSource &);
- ~QDeclarativeDomValueValueSource();
- QDeclarativeDomValueValueSource &operator=(const QDeclarativeDomValueValueSource &);
-
- QDeclarativeDomObject object() const;
-
-private:
- friend class QDeclarativeDomValue;
- QSharedDataPointer<QDeclarativeDomBasicValuePrivate> d;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomValueValueInterceptor
-{
-public:
- QDeclarativeDomValueValueInterceptor();
- QDeclarativeDomValueValueInterceptor(const QDeclarativeDomValueValueInterceptor &);
- ~QDeclarativeDomValueValueInterceptor();
- QDeclarativeDomValueValueInterceptor &operator=(const QDeclarativeDomValueValueInterceptor &);
-
- QDeclarativeDomObject object() const;
-
-private:
- friend class QDeclarativeDomValue;
- QSharedDataPointer<QDeclarativeDomBasicValuePrivate> d;
-};
-
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomComponent : public QDeclarativeDomObject
-{
-public:
- QDeclarativeDomComponent();
- QDeclarativeDomComponent(const QDeclarativeDomComponent &);
- ~QDeclarativeDomComponent();
- QDeclarativeDomComponent &operator=(const QDeclarativeDomComponent &);
-
- QDeclarativeDomObject componentRoot() const;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomValue
-{
-public:
- enum Type {
- Invalid,
- Literal,
- PropertyBinding,
- ValueSource,
- ValueInterceptor,
- Object,
- List
- };
-
- QDeclarativeDomValue();
- QDeclarativeDomValue(const QDeclarativeDomValue &);
- ~QDeclarativeDomValue();
- QDeclarativeDomValue &operator=(const QDeclarativeDomValue &);
-
- Type type() const;
-
- bool isInvalid() const;
- bool isLiteral() const;
- bool isBinding() const;
- bool isValueSource() const;
- bool isValueInterceptor() const;
- bool isObject() const;
- bool isList() const;
-
- QDeclarativeDomValueLiteral toLiteral() const;
- QDeclarativeDomValueBinding toBinding() const;
- QDeclarativeDomValueValueSource toValueSource() const;
- QDeclarativeDomValueValueInterceptor toValueInterceptor() const;
- QDeclarativeDomObject toObject() const;
- QDeclarativeDomList toList() const;
-
- int position() const;
- int length() const;
-
-private:
- friend class QDeclarativeDomProperty;
- friend class QDeclarativeDomList;
- QSharedDataPointer<QDeclarativeDomValuePrivate> d;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomList
-{
-public:
- QDeclarativeDomList();
- QDeclarativeDomList(const QDeclarativeDomList &);
- ~QDeclarativeDomList();
- QDeclarativeDomList &operator=(const QDeclarativeDomList &);
-
- QList<QDeclarativeDomValue> values() const;
-
- int position() const;
- int length() const;
-
- QList<int> commaPositions() const;
-
-private:
- friend class QDeclarativeDomValue;
- QSharedDataPointer<QDeclarativeDomValuePrivate> d;
-};
-
-class QDeclarativeDomImportPrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDomImport
-{
-public:
- enum Type { Library, File };
-
- QDeclarativeDomImport();
- QDeclarativeDomImport(const QDeclarativeDomImport &);
- ~QDeclarativeDomImport();
- QDeclarativeDomImport &operator=(const QDeclarativeDomImport &);
-
- Type type() const;
- QString uri() const;
- QString version() const;
- QString qualifier() const;
-
-private:
- friend class QDeclarativeDomDocument;
- QSharedDataPointer<QDeclarativeDomImportPrivate> d;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QDECLARATIVEDOM_P_H
diff --git a/src/declarative/qml/qdeclarativedom_p_p.h b/src/declarative/qml/qdeclarativedom_p_p.h
deleted file mode 100644
index bcff6236ec..0000000000
--- a/src/declarative/qml/qdeclarativedom_p_p.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDECLARATIVEDOM_P_P_H
-#define QDECLARATIVEDOM_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qdeclarativeparser_p.h"
-
-#include <QtCore/QtGlobal>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeDomDocumentPrivate : public QSharedData
-{
-public:
- QDeclarativeDomDocumentPrivate();
- QDeclarativeDomDocumentPrivate(const QDeclarativeDomDocumentPrivate &o)
- : QSharedData(o) { qFatal("Not impl"); }
- ~QDeclarativeDomDocumentPrivate();
-
- QList<QDeclarativeError> errors;
- QList<QDeclarativeDomImport> imports;
- QDeclarativeParser::Object *root;
- QList<int> automaticSemicolonOffsets;
-};
-
-class QDeclarativeDomObjectPrivate : public QSharedData
-{
-public:
- QDeclarativeDomObjectPrivate();
- QDeclarativeDomObjectPrivate(const QDeclarativeDomObjectPrivate &o)
- : QSharedData(o) { qFatal("Not impl"); }
- ~QDeclarativeDomObjectPrivate();
-
- typedef QList<QPair<QDeclarativeParser::Property *, QByteArray> > Properties;
- Properties properties() const;
- Properties properties(QDeclarativeParser::Property *) const;
-
- QDeclarativeParser::Object *object;
-};
-
-class QDeclarativeDomPropertyPrivate : public QSharedData
-{
-public:
- QDeclarativeDomPropertyPrivate();
- QDeclarativeDomPropertyPrivate(const QDeclarativeDomPropertyPrivate &o)
- : QSharedData(o) { qFatal("Not impl"); }
- ~QDeclarativeDomPropertyPrivate();
-
- QByteArray propertyName;
- QDeclarativeParser::Property *property;
-};
-
-class QDeclarativeDomDynamicPropertyPrivate : public QSharedData
-{
-public:
- QDeclarativeDomDynamicPropertyPrivate();
- QDeclarativeDomDynamicPropertyPrivate(const QDeclarativeDomDynamicPropertyPrivate &o)
- : QSharedData(o) { qFatal("Not impl"); }
- ~QDeclarativeDomDynamicPropertyPrivate();
-
- bool valid;
- QDeclarativeParser::Object::DynamicProperty property;
-};
-
-class QDeclarativeDomValuePrivate : public QSharedData
-{
-public:
- QDeclarativeDomValuePrivate();
- QDeclarativeDomValuePrivate(const QDeclarativeDomValuePrivate &o)
- : QSharedData(o) { qFatal("Not impl"); }
- ~QDeclarativeDomValuePrivate();
-
- QDeclarativeParser::Property *property;
- QDeclarativeParser::Value *value;
-};
-
-class QDeclarativeDomBasicValuePrivate : public QSharedData
-{
-public:
- QDeclarativeDomBasicValuePrivate();
- QDeclarativeDomBasicValuePrivate(const QDeclarativeDomBasicValuePrivate &o)
- : QSharedData(o) { qFatal("Not impl"); }
- ~QDeclarativeDomBasicValuePrivate();
-
- QDeclarativeParser::Value *value;
-};
-
-class QDeclarativeDomImportPrivate : public QSharedData
-{
-public:
- QDeclarativeDomImportPrivate();
- QDeclarativeDomImportPrivate(const QDeclarativeDomImportPrivate &o)
- : QSharedData(o) { qFatal("Not impl"); }
- ~QDeclarativeDomImportPrivate();
-
- enum Type { Library, File };
-
- Type type;
- QString uri;
- QString version;
- QString qualifier;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDECLARATIVEDOM_P_P_H
-
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 9e0e299c86..ecd6a2bd7a 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -55,6 +55,7 @@
#include "private/qdeclarativestringconverters_p.h"
#include "private/qdeclarativexmlhttprequest_p.h"
#include "private/qdeclarativesqldatabase_p.h"
+#include "private/qdeclarativescarceresourcescriptclass_p.h"
#include "private/qdeclarativetypenamescriptclass_p.h"
#include "private/qdeclarativelistscriptclass_p.h"
#include "qdeclarativescriptstring.h"
@@ -104,6 +105,8 @@
#include <private/qdeclarativeitemsmodule_p.h>
#include <private/qdeclarativeutilmodule_p.h>
+#include <private/qsgitemsmodule_p.h>
+#include <qsgtexture.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include <qt_windows.h>
@@ -350,13 +353,15 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
inBeginCreate(false), networkAccessManager(0), networkAccessManagerFactory(0),
- typeLoader(e), importDatabase(e), uniqueId(1)
+ scarceResources(0), scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
+ sgContext(0)
{
if (!qt_QmlQtModule_registered) {
qt_QmlQtModule_registered = true;
QDeclarativeItemModule::defineModule();
QDeclarativeUtilModule::defineModule();
QDeclarativeEnginePrivate::defineModule();
+ QSGItemsModule::defineModule();
QDeclarativeValueTypeFactory::registerValueTypes();
}
globalClass = new QDeclarativeGlobalScriptClass(&scriptEngine);
@@ -500,6 +505,8 @@ QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
contextClass = 0;
delete objectClass;
objectClass = 0;
+ delete scarceResourceClass;
+ scarceResourceClass = 0;
delete valueTypeClass;
valueTypeClass = 0;
delete typeNameClass;
@@ -515,7 +522,10 @@ QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
(*iter)->release();
for(QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
(*iter)->release();
-
+ for(QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
+ delete (*iter)->qobjectApi;
+ delete *iter;
+ }
}
void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
@@ -572,6 +582,7 @@ void QDeclarativeEnginePrivate::init()
contextClass = new QDeclarativeContextScriptClass(q);
objectClass = new QDeclarativeObjectScriptClass(q);
+ scarceResourceClass = new QDeclarativeScarceResourceScriptClass(q);
valueTypeClass = new QDeclarativeValueTypeScriptClass(q);
typeNameClass = new QDeclarativeTypeNameScriptClass(q);
listClass = new QDeclarativeListScriptClass(q);
@@ -647,9 +658,23 @@ QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
QDeclarativeEngine::~QDeclarativeEngine()
{
Q_D(QDeclarativeEngine);
- if (d->isDebugging) {
+ if (d->isDebugging)
QDeclarativeEngineDebugServer::instance()->remEngine(this);
- QJSDebugService::instance()->removeEngine(this);
+
+ // if we are the parent of any of the qobject module api instances,
+ // we need to remove them from our internal list, in order to prevent
+ // a segfault in engine private dtor.
+ QList<QDeclarativeMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
+ QObject *currQObjectApi = 0;
+ QDeclarativeMetaType::ModuleApiInstance *currInstance = 0;
+ foreach (const QDeclarativeMetaType::ModuleApi &key, keys) {
+ currInstance = d->moduleApiInstances.value(key);
+ currQObjectApi = currInstance->qobjectApi;
+ if (this->children().contains(currQObjectApi)) {
+ delete currQObjectApi;
+ delete currInstance;
+ d->moduleApiInstances.remove(key);
+ }
}
}
@@ -814,7 +839,19 @@ QDeclarativeImageProvider::ImageType QDeclarativeEnginePrivate::getImageProvider
locker.unlock();
if (provider)
return provider->imageType();
- return static_cast<QDeclarativeImageProvider::ImageType>(-1);
+ return QDeclarativeImageProvider::Invalid;
+}
+
+QSGTexture *QDeclarativeEnginePrivate::getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
+{
+ QMutexLocker locker(&mutex);
+ QSharedPointer<QDeclarativeImageProvider> provider = imageProviders.value(url.host());
+ locker.unlock();
+ if (provider) {
+ QString imageId = url.toString(QUrl::RemoveScheme | QUrl::RemoveAuthority).mid(1);
+ return provider->requestTexture(imageId, size, req_size);
+ }
+ return 0;
}
QImage QDeclarativeEnginePrivate::getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size)
@@ -1315,6 +1352,8 @@ Example (where \c parentItem is the id of an existing QML item):
In the case of an error, a QtScript Error object is thrown. This object has an additional property,
\c qmlErrors, which is an array of the errors encountered.
Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message.
+For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following:
+{ "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}.
Note that this function returns immediately, and therefore may not work if
the \a qml string loads new components (that is, external QML files that have not yet been loaded).
@@ -1361,7 +1400,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
QScriptValue arr = ctxt->engine()->newArray(errors.length());
int i = 0;
foreach (const QDeclarativeError &error, errors){
- errstr += QLatin1String(" ") + error.toString() + QLatin1String("\n");
+ errstr += QLatin1String("\n ") + error.toString();
QScriptValue qmlErrObject = ctxt->engine()->newObject();
qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
@@ -1388,7 +1427,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
QScriptValue arr = ctxt->engine()->newArray(errors.length());
int i = 0;
foreach (const QDeclarativeError &error, errors){
- errstr += QLatin1String(" ") + error.toString() + QLatin1String("\n");
+ errstr += QLatin1String("\n ") + error.toString();
QScriptValue qmlErrObject = ctxt->engine()->newObject();
qmlErrObject.setProperty(QLatin1String("lineNumber"), QScriptValue(error.line()));
qmlErrObject.setProperty(QLatin1String("columnNumber"), QScriptValue(error.column()));
@@ -1703,9 +1742,6 @@ QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine
qsreal w = ctxt->argument(2).toNumber();
qsreal h = ctxt->argument(3).toNumber();
- if (w < 0 || h < 0)
- return engine->nullValue();
-
return QDeclarativeEnginePrivate::get(engine)->scriptValueFromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
}
@@ -2060,7 +2096,9 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine
QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val)
{
- if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
+ if (variantIsScarceResource(val)) {
+ return scarceResourceClass->newScarceResource(val);
+ } else if (val.userType() == qMetaTypeId<QDeclarativeListReference>()) {
QDeclarativeListReferencePrivate *p =
QDeclarativeListReferencePrivate::get((QDeclarativeListReference*)val.constData());
if (p->object) {
@@ -2089,11 +2127,69 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v
}
}
+/*
+ If the variant is a scarce resource (consumes a large amount of memory, or
+ only a limited number of them can be held in memory at any given time without
+ exhausting supply for future use) we need to release the scarce resource
+ after evaluation of the javascript binding is complete.
+ */
+bool QDeclarativeEnginePrivate::variantIsScarceResource(const QVariant& val)
+{
+ if (val.type() == QVariant::Pixmap) {
+ return true;
+ } else if (val.type() == QVariant::Image) {
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ This function should be called prior to evaluation of any js expression,
+ so that scarce resources are not freed prematurely (eg, if there is a
+ nested javascript expression).
+ */
+void QDeclarativeEnginePrivate::referenceScarceResources()
+{
+ scarceResourcesRefCount += 1;
+}
+
+/*
+ This function should be called after evaluation of the js expression is
+ complete, and so the scarce resources may be freed safely.
+ */
+void QDeclarativeEnginePrivate::dereferenceScarceResources()
+{
+ Q_ASSERT(scarceResourcesRefCount > 0);
+ scarceResourcesRefCount -= 1;
+
+ // if the refcount is zero, then evaluation of the "top level"
+ // expression must have completed. We can safely release the
+ // scarce resources.
+ if (scarceResourcesRefCount == 0) {
+ // iterate through the list and release them all.
+ // note that the actual SRD is owned by the JS engine,
+ // so we cannot delete the SRD; but we can free the
+ // memory used by the variant in the SRD.
+ ScarceResourceData *srd = 0;
+ while (scarceResources) {
+ srd = scarceResources; // srd points to the "old" (current) head of the list
+ scarceResources = srd->next; // srd->next is the "new" head of the list
+ if (srd->next) srd->next->prev = &scarceResources; // newHead->prev = listptr.
+ srd->next = 0;
+ srd->prev = 0;
+ srd->releaseResource(); // release the old head node.
+ }
+ }
+}
+
QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint)
{
QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val);
if (dc == objectClass)
return QVariant::fromValue(objectClass->toQObject(val));
+ else if (dc == scarceResourceClass)
+ return scarceResourceClass->toVariant(val);
else if (dc == valueTypeClass)
return valueTypeClass->toVariant(val);
else if (dc == contextClass)
@@ -2222,6 +2318,20 @@ void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
Imports the plugin named \a filePath with the \a uri provided.
Returns true if the plugin was successfully imported; otherwise returns false.
+ On failure and if non-null, the \a errors list will have any errors which occurred prepended to it.
+
+ The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
+*/
+bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
+{
+ Q_D(QDeclarativeEngine);
+ return d->importDatabase.importPlugin(filePath, uri, errors);
+}
+
+/*!
+ Imports the plugin named \a filePath with the \a uri provided.
+ Returns true if the plugin was successfully imported; otherwise returns false.
+
On failure and if non-null, *\a errorString will be set to a message describing the failure.
The plugin has to be a Qt plugin which implements the QDeclarativeExtensionPlugin interface.
@@ -2229,7 +2339,18 @@ void QDeclarativeEngine::setPluginPathList(const QStringList &paths)
bool QDeclarativeEngine::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
{
Q_D(QDeclarativeEngine);
- return d->importDatabase.importPlugin(filePath, uri, errorString);
+ QList<QDeclarativeError> errors;
+ bool retn = d->importDatabase.importPlugin(filePath, uri, &errors);
+ if (!errors.isEmpty()) {
+ QString builtError;
+ for (int i = 0; i < errors.size(); ++i) {
+ builtError = QString(QLatin1String("%1\n %2"))
+ .arg(builtError)
+ .arg(errors.at(i).toString());
+ }
+ *errorString = builtError;
+ }
+ return retn;
}
/*!
diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h
index 61ab2b2c63..476ff60ec9 100644
--- a/src/declarative/qml/qdeclarativeengine.h
+++ b/src/declarative/qml/qdeclarativeengine.h
@@ -86,7 +86,8 @@ public:
void setPluginPathList(const QStringList &paths);
void addPluginPath(const QString& dir);
- bool importPlugin(const QString &filePath, const QString &uri, QString *errorString);
+ bool importPlugin(const QString &filePath, const QString &uri, QString *errorString); // XXX: Qt 5: Remove this function
+ bool importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors);
void setNetworkAccessManagerFactory(QDeclarativeNetworkAccessManagerFactory *);
QDeclarativeNetworkAccessManagerFactory *networkAccessManagerFactory() const;
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index 0a3fe5d130..c690ac7bff 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -67,6 +67,7 @@
#include "private/qdeclarativeproperty_p.h"
#include "private/qdeclarativepropertycache_p.h"
#include "private/qdeclarativeobjectscriptclass_p.h"
+#include "private/qdeclarativescarceresourcescriptclass_p.h"
#include "private/qdeclarativecontextscriptclass_p.h"
#include "private/qdeclarativevaluetypescriptclass_p.h"
#include "private/qdeclarativemetatype_p.h"
@@ -93,6 +94,8 @@ class QDeclarativeExpression;
class QDeclarativeContextScriptClass;
class QDeclarativeImportDatabase;
class QDeclarativeObjectScriptClass;
+class QDeclarativeScarceResourceScriptClass;
+class ScarceResourceData;
class QDeclarativeTypeNameScriptClass;
class QDeclarativeValueTypeScriptClass;
class QNetworkReply;
@@ -109,6 +112,8 @@ class QDeclarativeDelayedError;
class QDeclarativeWorkerScriptEngine;
class QDeclarativeGlobalScriptClass;
class QDir;
+class QSGTexture;
+class QSGContext;
class QDeclarativeScriptEngine : public QScriptEngine
{
@@ -168,6 +173,7 @@ public:
QDeclarativeContextData *sharedContext;
QObject *sharedScope;
QDeclarativeObjectScriptClass *objectClass;
+ QDeclarativeScarceResourceScriptClass *scarceResourceClass;
QDeclarativeValueTypeScriptClass *valueTypeClass;
QDeclarativeTypeNameScriptClass *typeNameClass;
QDeclarativeListScriptClass *listClass;
@@ -232,9 +238,22 @@ public:
QHash<QString,QSharedPointer<QDeclarativeImageProvider> > imageProviders;
QDeclarativeImageProvider::ImageType getImageProviderType(const QUrl &url);
+ QSGTexture *getTextureFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
QImage getImageFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
QPixmap getPixmapFromProvider(const QUrl &url, QSize *size, const QSize& req_size);
+ /*
+ A scarce resource (like a large pixmap or texture) will be cached in a
+ JavaScript wrapper object when accessed in a binding or other js expression.
+ We need some way to automatically release that scarce resource prior to normal
+ garbage collection (unless the user explicitly preserves the resource).
+ */
+ ScarceResourceData* scarceResources;
+ int scarceResourcesRefCount;
+ static bool variantIsScarceResource(const QVariant& val);
+ void referenceScarceResources();
+ void dereferenceScarceResources();
+
mutable QMutex mutex;
QDeclarativeTypeLoader typeLoader;
@@ -249,6 +268,8 @@ public:
QDeclarativeValueTypeFactory valueTypes;
+ QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *> moduleApiInstances;
+
QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache;
QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *> typePropertyCache;
inline QDeclarativePropertyCache *cache(QObject *obj);
@@ -269,8 +290,6 @@ public:
QHash<int, int> m_qmlLists;
QHash<int, QDeclarativeCompiledData *> m_compositeTypes;
- QHash<QString, QScriptValue> m_sharedScriptImports;
-
QScriptValue scriptValueFromVariant(const QVariant &);
QVariant scriptValueToVariant(const QScriptValue &, int hint = QVariant::Invalid);
@@ -326,6 +345,8 @@ public:
static void defineModule();
static bool qml_debugging_enabled;
+
+ QSGContext *sgContext;
};
/*!
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index e56f819faf..247bde9a6c 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -630,7 +630,6 @@ QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope,
if (!expressionFunctionValid) {
QDeclarativeEngine *engine = context()->engine;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
-
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
@@ -663,8 +662,10 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU
}
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine());
-
- return ep->scriptValueToVariant(scriptValue(secondaryScope, isUndefined), qMetaTypeId<QList<QObject*> >());
+ ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
+ QVariant retn(ep->scriptValueToVariant(scriptValue(secondaryScope, isUndefined), qMetaTypeId<QList<QObject*> >()));
+ ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
+ return retn;
}
/*!
diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp
index 559adf410e..50a3aad733 100644
--- a/src/declarative/qml/qdeclarativeimageprovider.cpp
+++ b/src/declarative/qml/qdeclarativeimageprovider.cpp
@@ -159,6 +159,8 @@ public:
requestImage() method will be called for all image requests.
\value Pixmap The Image Provider provides QPixmap images. The
requestPixmap() method will be called for all image requests.
+ \value Texture The Image Provider provides QSGTextureProvider based images.
+ The requestTexture() method will be called for all image requests. \omitvalue
*/
/*!
@@ -243,5 +245,36 @@ QPixmap QDeclarativeImageProvider::requestPixmap(const QString &id, QSize *size,
return QPixmap();
}
+
+/*!
+ Implement this method to return the texture with \a id. The default
+ implementation returns 0.
+
+ The \a id is the requested image source, with the "image:" scheme and
+ provider identifier removed. For example, if the image \l{Image::}{source}
+ was "image://myprovider/icons/home", the given \a id would be "icons/home".
+
+ The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
+ an Image element. If \a requestedSize is a valid size, the image
+ returned should be of that size.
+
+ In all cases, \a size must be set to the original size of the image. This
+ is used to set the \l {Item::}{width} and \l {Item::}{height} of the
+ relevant \l Image if these values have not been set explicitly.
+
+ \note this method may be called by multiple threads, so ensure the
+ implementation of this method is reentrant.
+*/
+
+QSGTexture *QDeclarativeImageProvider::requestTexture(const QString &id, QSize *size, const QSize &requestedSize)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(size);
+ Q_UNUSED(requestedSize);
+ if (d->type == Texture)
+ qWarning("ImageProvider supports Texture type but has not implemented requestTexture()");
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeimageprovider.h b/src/declarative/qml/qdeclarativeimageprovider.h
index ff11afb1e8..8d35d14ccf 100644
--- a/src/declarative/qml/qdeclarativeimageprovider.h
+++ b/src/declarative/qml/qdeclarativeimageprovider.h
@@ -52,13 +52,16 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QDeclarativeImageProviderPrivate;
+class QSGTexture;
class Q_DECLARATIVE_EXPORT QDeclarativeImageProvider
{
public:
enum ImageType {
Image,
- Pixmap
+ Pixmap,
+ Texture,
+ Invalid
};
QDeclarativeImageProvider(ImageType type);
@@ -68,6 +71,7 @@ public:
virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize);
virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize);
+ virtual QSGTexture *requestTexture(const QString &id, QSize *size, const QSize &requestedSize);
private:
QDeclarativeImageProviderPrivate *d;
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index bf261ef242..16b2fa2886 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -83,7 +83,7 @@ public:
QDeclarativeType** type_return, QUrl* url_return,
QUrl *base = 0, bool *typeRecursionDetected = 0);
bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QUrl *base = 0, QString *errorString = 0);
+ QUrl* url_return, QUrl *base = 0, QList<QDeclarativeError> *errors = 0);
};
class QDeclarativeImportsPrivate {
@@ -93,15 +93,15 @@ public:
bool importExtension(const QString &absoluteFilePath, const QString &uri,
QDeclarativeImportDatabase *database, QDeclarativeDirComponents* components,
- QString *errorString);
+ QList<QDeclarativeError> *errors);
QString resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database);
bool add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix,
int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType,
- QDeclarativeImportDatabase *database, QString *errorString);
+ QDeclarativeImportDatabase *database, QList<QDeclarativeError> *errors);
bool find(const QByteArray& type, int *vmajor, int *vminor,
- QDeclarativeType** type_return, QUrl* url_return, QString *errorString);
+ QDeclarativeType** type_return, QUrl* url_return, QList<QDeclarativeError> *errors);
QDeclarativeImportedNamespace *findNamespace(const QString& type);
@@ -163,7 +163,7 @@ QUrl QDeclarativeImports::baseUrl() const
static QDeclarativeTypeNameCache *
cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespace &set,
- QDeclarativeTypeNameCache *cache)
+ QDeclarativeTypeNameCache *cache, bool importWasQualified)
{
if (!cache)
cache = new QDeclarativeTypeNameCache(engine);
@@ -171,10 +171,27 @@ cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespac
QList<QDeclarativeType *> types = QDeclarativeMetaType::qmlTypes();
for (int ii = 0; ii < set.uris.count(); ++ii) {
- QByteArray base = set.uris.at(ii).toUtf8() + '/';
+ QByteArray uri = set.uris.at(ii).toUtf8();
int major = set.majversions.at(ii);
int minor = set.minversions.at(ii);
+ if (importWasQualified) {
+ QDeclarativeMetaType::ModuleApi moduleApi = QDeclarativeMetaType::moduleApi(uri, major, minor);
+ if (moduleApi.script || moduleApi.qobject) {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ QDeclarativeMetaType::ModuleApiInstance *a = ep->moduleApiInstances.value(moduleApi);
+ if (!a) {
+ a = new QDeclarativeMetaType::ModuleApiInstance;
+ a->scriptCallback = moduleApi.script;
+ a->qobjectCallback = moduleApi.qobject;
+ ep->moduleApiInstances.insert(moduleApi, a);
+ }
+ cache->setModuleApi(a);
+ }
+ }
+
+ QByteArray base = uri + '/';
+
foreach (QDeclarativeType *type, types) {
if (type->qmlTypeName().startsWith(base) &&
type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
@@ -200,15 +217,15 @@ void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDecla
QDeclarativeTypeNameCache::Data *d = cache->data(iter.key());
if (d) {
if (!d->typeNamespace)
- cacheForNamespace(engine, *(*iter), d->typeNamespace);
+ cacheForNamespace(engine, *(*iter), d->typeNamespace, true);
} else {
- QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0);
+ QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0, true);
cache->add(iter.key(), nc);
nc->release();
}
}
- cacheForNamespace(engine, set, cache);
+ cacheForNamespace(engine, set, cache, false);
}
/*!
@@ -227,7 +244,7 @@ void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDecla
*/
bool QDeclarativeImports::resolveType(const QByteArray& type,
QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
- QDeclarativeImportedNamespace** ns_return, QString *errorString) const
+ QDeclarativeImportedNamespace** ns_return, QList<QDeclarativeError> *errors) const
{
QDeclarativeImportedNamespace* ns = d->findNamespace(QString::fromUtf8(type));
if (ns) {
@@ -236,7 +253,7 @@ bool QDeclarativeImports::resolveType(const QByteArray& type,
return true;
}
if (type_return || url_return) {
- if (d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
+ if (d->find(type,vmaj,vmin,type_return,url_return, errors)) {
if (qmlImportTrace()) {
if (type_return && *type_return && url_return && !url_return->isEmpty())
qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
@@ -351,13 +368,16 @@ QDeclarativeImportsPrivate::~QDeclarativeImportsPrivate()
bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri,
QDeclarativeImportDatabase *database,
- QDeclarativeDirComponents* components, QString *errorString)
+ QDeclarativeDirComponents* components, QList<QDeclarativeError> *errors)
{
QFile file(absoluteFilePath);
QString filecontent;
if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath));
+ errors->prepend(error);
+ }
return false;
} else if (file.open(QFile::ReadOnly)) {
filecontent = QString::fromUtf8(file.readAll());
@@ -365,15 +385,29 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
<< "loaded " << absoluteFilePath;
} else {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath));
+ errors->prepend(error);
+ }
return false;
}
QDir dir = QFileInfo(file).dir();
+ QUrl url = QUrl::fromLocalFile(absoluteFilePath);
QDeclarativeDirParser qmldirParser;
qmldirParser.setSource(filecontent);
- qmldirParser.parse();
+ qmldirParser.setUrl(url);
+
+ // propagate any errors reported by the parser back up to the typeloader.
+ if (qmldirParser.parse()) {
+ if (errors) {
+ for (int i = 0; i < qmldirParser.errors().size(); ++i) {
+ errors->prepend(qmldirParser.errors().at(i));
+ }
+ }
+ return false;
+ }
if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);
@@ -390,14 +424,26 @@ bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath
}
#endif
if (!resolvedFilePath.isEmpty()) {
- if (!database->importPlugin(resolvedFilePath, uri, errorString)) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString);
+ if (!database->importPlugin(resolvedFilePath, uri, errors)) {
+ if (errors) {
+ // XXX TODO: should we leave the import plugin error alone?
+ // Here, we pop it off the top and coalesce it into this error's message.
+ // The reason is that the lower level may add url and line/column numbering information.
+ QDeclarativeError poppedError = errors->takeFirst();
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(poppedError.description()));
+ error.setUrl(url);
+ errors->prepend(error);
+ }
return false;
}
} else {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name));
+ error.setUrl(url);
+ errors->prepend(error);
+ }
return false;
}
}
@@ -443,7 +489,7 @@ QString QDeclarativeImportsPrivate::resolvedUri(const QString &dir_arg, QDeclara
bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix, int vmaj, int vmin,
QDeclarativeScriptParser::Import::Type importType,
- QDeclarativeImportDatabase *database, QString *errorString)
+ QDeclarativeImportDatabase *database, QList<QDeclarativeError> *errors)
{
QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork;
QString uri = uri_arg;
@@ -477,7 +523,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
uri = resolvedUri(dir, database);
- if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errors))
return false;
break;
}
@@ -496,7 +542,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
uri = resolvedUri(dir, database);
- if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errors))
return false;
break;
}
@@ -516,7 +562,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
uri = resolvedUri(dir, database);
- if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
+ if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errors))
return false;
break;
}
@@ -527,12 +573,14 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
versionFound = true;
if (!versionFound && qmldircomponents.isEmpty()) {
- if (errorString) {
+ if (errors) {
bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1);
+ QDeclarativeError error; // we don't set the url or line or column as these will be set by the loader.
if (anyversion)
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin));
else
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg);
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg));
+ errors->prepend(error);
}
return false;
}
@@ -545,15 +593,19 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
QString dir = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
QFileInfo dirinfo(dir);
if (dir.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg);
+ if (errors) {
+ QDeclarativeError error; // we don't set the line or column as these will be set by the loader.
+ error.setDescription(QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg));
+ error.setUrl(importUrl);
+ errors->prepend(error);
+ }
return false; // local import dirs must exist
}
uri = resolvedUri(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri))), database);
if (uri.endsWith(QLatin1Char('/')))
uri.chop(1);
if (QFile::exists(localFileOrQrc)) {
- if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errorString))
+ if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errors))
return false;
}
} else {
@@ -562,11 +614,14 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(base.resolved(QUrl(uri)));
QFileInfo dirinfo(localFileOrQrc);
if (localFileOrQrc.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
- if (errorString) {
+ if (errors) {
+ QDeclarativeError error; // we don't set the line or column as these will be set by the loader.
if (localFileOrQrc.isEmpty())
- *errorString = QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri);
+ error.setDescription(QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri));
else
- *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri);
+ error.setDescription(QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri));
+ error.setUrl(importUrl);
+ errors->prepend(error);
}
return false;
}
@@ -598,7 +653,11 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
if (lowest_maj > vmaj || (lowest_maj == vmaj && lowest_min > vmin)
|| highest_maj < vmaj || (highest_maj == vmaj && highest_min < vmin))
{
- *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
+ if (errors) {
+ QDeclarativeError error; // we don't set the url or line or column information, as these will be set by the loader.
+ error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin));
+ errors->prepend(error);
+ }
return false;
}
}
@@ -613,7 +672,7 @@ bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomp
}
bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QString *errorString)
+ QUrl* url_return, QList<QDeclarativeError> *errors)
{
QDeclarativeImportedNamespace *s = 0;
int slash = type.indexOf('/');
@@ -621,14 +680,20 @@ bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *
QString namespaceName = QString::fromUtf8(type.left(slash));
s = set.value(namespaceName);
if (!s) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("- %1 is not a namespace").arg(namespaceName);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("- %1 is not a namespace").arg(namespaceName));
+ errors->prepend(error);
+ }
return false;
}
int nslash = type.indexOf('/',slash+1);
if (nslash > 0) {
- if (errorString)
- *errorString = QDeclarativeImportDatabase::tr("- nested namespaces not allowed");
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(QDeclarativeImportDatabase::tr("- nested namespaces not allowed"));
+ errors->prepend(error);
+ }
return false;
}
} else {
@@ -636,7 +701,7 @@ bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *
}
QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
if (s) {
- if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString))
+ if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors))
return true;
if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) {
// qualified, and only 1 url
@@ -654,7 +719,7 @@ QDeclarativeImportedNamespace *QDeclarativeImportsPrivate::findNamespace(const Q
}
bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
- QUrl* url_return, QUrl *base, QString *errorString)
+ QUrl* url_return, QUrl *base, QList<QDeclarativeError> *errors)
{
bool typeRecursionDetected = false;
for (int i=0; i<urls.count(); ++i) {
@@ -663,7 +728,7 @@ bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, in
// check for type clashes
for (int j = i+1; j<urls.count(); ++j) {
if (find_helper(j, type, vmajor, vminor, 0, 0, base)) {
- if (errorString) {
+ if (errors) {
QString u1 = urls.at(i);
QString u2 = urls.at(j);
if (base) {
@@ -683,16 +748,16 @@ bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, in
}
}
- if (u1 != u2)
- *errorString
- = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 and in %2")
- .arg(u1).arg(u2);
- else
- *errorString
- = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
- .arg(u1)
- .arg(majversions.at(i)).arg(minversions.at(i))
- .arg(majversions.at(j)).arg(minversions.at(j));
+ QDeclarativeError error;
+ if (u1 != u2) {
+ error.setDescription(QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 and in %2").arg(u1).arg(u2));
+ } else {
+ error.setDescription(QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
+ .arg(u1)
+ .arg(majversions.at(i)).arg(minversions.at(i))
+ .arg(majversions.at(j)).arg(minversions.at(j)));
+ }
+ errors->prepend(error);
}
return false;
}
@@ -701,11 +766,13 @@ bool QDeclarativeImportedNamespace::find(const QByteArray& type, int *vmajor, in
return true;
}
}
- if (errorString) {
+ if (errors) {
+ QDeclarativeError error;
if (typeRecursionDetected)
- *errorString = QDeclarativeImportDatabase::tr("is instantiated recursively");
+ error.setDescription(QDeclarativeImportDatabase::tr("is instantiated recursively"));
else
- *errorString = QDeclarativeImportDatabase::tr("is not a type");
+ error.setDescription(QDeclarativeImportDatabase::tr("is not a type"));
+ errors->prepend(error);
}
return false;
}
@@ -790,7 +857,7 @@ bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb,
const QString& uri, const QString& prefix, int vmaj, int vmin,
QDeclarativeScriptParser::Import::Type importType,
const QDeclarativeDirComponents &qmldircomponentsnetwork,
- QString *errorString)
+ QList<QDeclarativeError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::addImport: "
@@ -798,7 +865,7 @@ bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb,
<< (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File")
<< " as " << prefix;
- return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errorString);
+ return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errors);
}
/*!
@@ -1013,7 +1080,7 @@ void QDeclarativeImportDatabase::setImportPathList(const QStringList &paths)
/*!
\internal
*/
-bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
+bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors)
{
if (qmlImportTrace())
qDebug().nospace() << "QDeclarativeImportDatabase::importPlugin: " << uri << " from " << filePath;
@@ -1033,15 +1100,21 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt
if (!engineInitialized || !typesRegistered) {
if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
- if (errorString)
- *errorString = tr("File name case mismatch for \"%2\"").arg(absoluteFilePath);
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(tr("File name case mismatch for \"%2\"").arg(absoluteFilePath));
+ errors->prepend(error);
+ }
return false;
}
QPluginLoader loader(absoluteFilePath);
if (!loader.load()) {
- if (errorString)
- *errorString = loader.errorString();
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(loader.errorString());
+ errors->prepend(error);
+ }
return false;
}
@@ -1063,8 +1136,11 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt
iface->initializeEngine(engine, moduleId);
}
} else {
- if (errorString)
- *errorString = loader.errorString();
+ if (errors) {
+ QDeclarativeError error;
+ error.setDescription(loader.errorString());
+ errors->prepend(error);
+ }
return false;
}
}
diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h
index 319e76ce98..fe9404d9b2 100644
--- a/src/declarative/qml/qdeclarativeimport_p.h
+++ b/src/declarative/qml/qdeclarativeimport_p.h
@@ -84,7 +84,7 @@ public:
QDeclarativeType** type_return, QUrl* url_return,
int *version_major, int *version_minor,
QDeclarativeImportedNamespace** ns_return,
- QString *errorString = 0) const;
+ QList<QDeclarativeError> *errors = 0) const;
bool resolveType(QDeclarativeImportedNamespace*,
const QByteArray& type,
QDeclarativeType** type_return, QUrl* url_return,
@@ -94,7 +94,7 @@ public:
const QString& uri, const QString& prefix, int vmaj, int vmin,
QDeclarativeScriptParser::Import::Type importType,
const QDeclarativeDirComponents &qmldircomponentsnetwork,
- QString *errorString);
+ QList<QDeclarativeError> *errors);
void populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const;
@@ -110,7 +110,7 @@ public:
QDeclarativeImportDatabase(QDeclarativeEngine *);
~QDeclarativeImportDatabase();
- bool importPlugin(const QString &filePath, const QString &uri, QString *errorString);
+ bool importPlugin(const QString &filePath, const QString &uri, QList<QDeclarativeError> *errors);
QStringList importPathList() const;
void setImportPathList(const QStringList &paths);
diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp
index 2fd5347782..e2f728ad69 100644
--- a/src/declarative/qml/qdeclarativeinfo.cpp
+++ b/src/declarative/qml/qdeclarativeinfo.cpp
@@ -129,6 +129,18 @@ QDeclarativeInfo::~QDeclarativeInfo()
int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
if (marker != -1)
typeName = typeName.left(marker);
+
+ marker = typeName.indexOf(QLatin1String("_QML_"));
+ if (marker != -1) {
+ typeName = typeName.left(marker) + "*";
+ type = QDeclarativeMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
+ if (type) {
+ typeName = QLatin1String(type->qmlTypeName());
+ int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
+ if (lastSlash != -1)
+ typeName = typeName.mid(lastSlash+1);
+ }
+ }
}
d->buffer.prepend(QLatin1String("QML ") + typeName + QLatin1String(": "));
diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp
index 446c9ab37c..fa0d8ea6f4 100644
--- a/src/declarative/qml/qdeclarativeinstruction.cpp
+++ b/src/declarative/qml/qdeclarativeinstruction.cpp
@@ -53,178 +53,184 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
Q_UNUSED(instr)
Q_UNUSED(idx)
#else
- QByteArray lineNumber = QByteArray::number(instr->line);
- if (instr->line == (unsigned short)-1)
- lineNumber = "NA";
- const char *line = lineNumber.constData();
-
- switch(instr->type) {
+ switch(instr->type()) {
case QDeclarativeInstruction::Init:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "INIT\t\t\t" << instr->init.bindingsSize << "\t" << instr->init.parserStatusSize << "\t" << instr->init.contextCache << "\t" << instr->init.compiledBinding;
+ qWarning().nospace() << idx << "\t\t" << "INIT\t\t\t" << instr->init.bindingsSize << "\t" << instr->init.parserStatusSize << "\t" << instr->init.contextCache << "\t" << instr->init.compiledBinding;
+ break;
+ case QDeclarativeInstruction::Done:
+ qWarning().nospace() << idx << "\t\t" << "DONE";
break;
case QDeclarativeInstruction::CreateObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t" << instr->create.bindingBits << "\t\t" << types.at(instr->create.type).className;
+ qWarning().nospace() << idx << "\t\t" << "CREATE\t\t\t" << instr->create.type << "\t" << instr->create.bindingBits << "\t\t" << types.at(instr->create.type).className;
break;
case QDeclarativeInstruction::CreateSimpleObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize;
+ qWarning().nospace() << idx << "\t\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize;
break;
case QDeclarativeInstruction::SetId:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "SETID\t\t\t" << instr->setId.value << "\t\t\t" << primitives.at(instr->setId.value);
+ qWarning().nospace() << idx << "\t\t" << "SETID\t\t\t" << instr->setId.value << "\t\t\t" << primitives.at(instr->setId.value);
break;
case QDeclarativeInstruction::SetDefault:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "SET_DEFAULT";
+ qWarning().nospace() << idx << "\t\t" << "SET_DEFAULT";
break;
case QDeclarativeInstruction::CreateComponent:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "CREATE_COMPONENT\t" << instr->createComponent.count;
+ qWarning().nospace() << idx << "\t\t" << "CREATE_COMPONENT\t" << instr->createComponent.count;
break;
case QDeclarativeInstruction::StoreMetaObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_META\t\t" << instr->storeMeta.data;
+ qWarning().nospace() << idx << "\t\t" << "STORE_META\t\t" << instr->storeMeta.data;
break;
-
case QDeclarativeInstruction::StoreFloat:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_FLOAT\t\t" << instr->storeFloat.propertyIndex << "\t" << instr->storeFloat.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_FLOAT\t\t" << instr->storeFloat.propertyIndex << "\t" << instr->storeFloat.value;
break;
case QDeclarativeInstruction::StoreDouble:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_DOUBLE\t\t" << instr->storeDouble.propertyIndex << "\t" << instr->storeDouble.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_DOUBLE\t\t" << instr->storeDouble.propertyIndex << "\t" << instr->storeDouble.value;
break;
case QDeclarativeInstruction::StoreInteger:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_INTEGER\t\t" << instr->storeInteger.propertyIndex << "\t" << instr->storeInteger.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_INTEGER\t\t" << instr->storeInteger.propertyIndex << "\t" << instr->storeInteger.value;
break;
case QDeclarativeInstruction::StoreBool:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_BOOL\t\t" << instr->storeBool.propertyIndex << "\t" << instr->storeBool.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_BOOL\t\t" << instr->storeBool.propertyIndex << "\t" << instr->storeBool.value;
break;
case QDeclarativeInstruction::StoreString:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_STRING\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value);
+ qWarning().nospace() << idx << "\t\t" << "STORE_STRING\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value);
+ break;
+ case QDeclarativeInstruction::StoreByteArray:
+ qWarning().nospace() << idx << "\t\t" << "STORE_BYTEARRAY" << instr->storeByteArray.propertyIndex << "\t" << instr->storeByteArray.value << "\t\t" << datas.at(instr->storeByteArray.value);
break;
case QDeclarativeInstruction::StoreUrl:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << urls.at(instr->storeUrl.value);
+ qWarning().nospace() << idx << "\t\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << urls.at(instr->storeUrl.value);
break;
case QDeclarativeInstruction::StoreColor:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_COLOR\t\t" << instr->storeColor.propertyIndex << "\t\t\t" << QString::number(instr->storeColor.value, 16);
+ qWarning().nospace() << idx << "\t\t" << "STORE_COLOR\t\t" << instr->storeColor.propertyIndex << "\t\t\t" << QString::number(instr->storeColor.value, 16);
break;
case QDeclarativeInstruction::StoreDate:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_DATE\t\t" << instr->storeDate.propertyIndex << "\t" << instr->storeDate.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_DATE\t\t" << instr->storeDate.propertyIndex << "\t" << instr->storeDate.value;
break;
case QDeclarativeInstruction::StoreTime:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_TIME\t\t" << instr->storeTime.propertyIndex << "\t" << instr->storeTime.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_TIME\t\t" << instr->storeTime.propertyIndex;
break;
case QDeclarativeInstruction::StoreDateTime:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_DATETIME\t\t" << instr->storeDateTime.propertyIndex << "\t" << instr->storeDateTime.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_DATETIME\t\t" << instr->storeDateTime.propertyIndex;
break;
case QDeclarativeInstruction::StorePoint:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_POINT\t\t" << instr->storeRealPair.propertyIndex << "\t" << instr->storeRealPair.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_POINT\t\t" << instr->storePoint.propertyIndex << "\t" << instr->storePoint.point.xp << "\t" << instr->storePoint.point.yp;
break;
case QDeclarativeInstruction::StorePointF:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_POINTF\t\t" << instr->storeRealPair.propertyIndex << "\t" << instr->storeRealPair.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_POINTF\t\t" << instr->storePointF.propertyIndex << "\t" << instr->storePointF.point.xp << "\t" << instr->storePointF.point.yp;
break;
case QDeclarativeInstruction::StoreSize:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SIZE\t\t" << instr->storeRealPair.propertyIndex << "\t" << instr->storeRealPair.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_SIZE\t\t" << instr->storeSize.propertyIndex << "\t" << instr->storeSize.size.wd << "\t" << instr->storeSize.size.ht;
break;
case QDeclarativeInstruction::StoreSizeF:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SIZEF\t\t" << instr->storeRealPair.propertyIndex << "\t" << instr->storeRealPair.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_SIZEF\t\t" << instr->storeSizeF.propertyIndex << "\t" << instr->storeSizeF.size.wd << "\t" << instr->storeSizeF.size.ht;
break;
case QDeclarativeInstruction::StoreRect:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_RECT\t\t" << instr->storeRect.propertyIndex << "\t" << instr->storeRect.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_RECT\t\t" << instr->storeRect.propertyIndex << "\t" << instr->storeRect.rect.x1 << "\t" << instr->storeRect.rect.y1 << "\t" << instr->storeRect.rect.x2 << "\t" << instr->storeRect.rect.y2;
break;
case QDeclarativeInstruction::StoreRectF:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_RECTF\t\t" << instr->storeRect.propertyIndex << "\t" << instr->storeRect.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_RECTF\t\t" << instr->storeRectF.propertyIndex << "\t" << instr->storeRectF.rect.xp << "\t" << instr->storeRectF.rect.yp << "\t" << instr->storeRectF.rect.w << "\t" << instr->storeRectF.rect.h;
break;
case QDeclarativeInstruction::StoreVector3D:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VECTOR3D\t\t" << instr->storeVector3D.propertyIndex << "\t" << instr->storeVector3D.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VECTOR3D\t\t" << instr->storeVector3D.propertyIndex << "\t" << instr->storeVector3D.vector.xp << "\t" << instr->storeVector3D.vector.yp << "\t" << instr->storeVector3D.vector.zp;
break;
case QDeclarativeInstruction::StoreVariant:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value);
+ qWarning().nospace() << idx << "\t\t" << "STORE_VARIANT\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value);
break;
case QDeclarativeInstruction::StoreVariantInteger:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT_INTEGER\t\t" << instr->storeInteger.propertyIndex << "\t" << instr->storeInteger.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VARIANT_INTEGER\t\t" << instr->storeInteger.propertyIndex << "\t" << instr->storeInteger.value;
break;
case QDeclarativeInstruction::StoreVariantDouble:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT_DOUBLE\t\t" << instr->storeDouble.propertyIndex << "\t" << instr->storeDouble.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VARIANT_DOUBLE\t\t" << instr->storeDouble.propertyIndex << "\t" << instr->storeDouble.value;
break;
case QDeclarativeInstruction::StoreVariantBool:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT_BOOL\t\t" << instr->storeBool.propertyIndex << "\t" << instr->storeBool.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VARIANT_BOOL\t\t" << instr->storeBool.propertyIndex << "\t" << instr->storeBool.value;
break;
case QDeclarativeInstruction::StoreObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_OBJECT\t\t" << instr->storeObject.propertyIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_OBJECT\t\t" << instr->storeObject.propertyIndex;
break;
case QDeclarativeInstruction::StoreVariantObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VARIANT_OBJECT\t" << instr->storeObject.propertyIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VARIANT_OBJECT\t" << instr->storeObject.propertyIndex;
break;
case QDeclarativeInstruction::StoreInterface:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_INTERFACE\t\t" << instr->storeObject.propertyIndex;
+ qWarning().nospace() << idx << "\t\t" << "STORE_INTERFACE\t\t" << instr->storeObject.propertyIndex;
break;
-
case QDeclarativeInstruction::StoreSignal:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SIGNAL\t\t" << instr->storeSignal.signalIndex << "\t" << instr->storeSignal.value << "\t\t" << primitives.at(instr->storeSignal.value);
+ qWarning().nospace() << idx << "\t\t" << "STORE_SIGNAL\t\t" << instr->storeSignal.signalIndex << "\t" << instr->storeSignal.value << "\t\t" << primitives.at(instr->storeSignal.value);
break;
case QDeclarativeInstruction::StoreImportedScript:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value;
+ qWarning().nospace() << idx << "\t\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value;
break;
case QDeclarativeInstruction::StoreScriptString:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope;
+ qWarning().nospace() << idx << "\t\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope;
break;
-
case QDeclarativeInstruction::AssignSignalObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << datas.at(instr->assignSignalObject.signal);
+ qWarning().nospace() << idx << "\t\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << datas.at(instr->assignSignalObject.signal);
break;
case QDeclarativeInstruction::AssignCustomType:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "ASSIGN_CUSTOMTYPE\t" << instr->assignCustomType.propertyIndex << "\t" << instr->assignCustomType.valueIndex;
+ qWarning().nospace() << idx << "\t\t" << "ASSIGN_CUSTOMTYPE\t" << instr->assignCustomType.propertyIndex << "\t" << instr->assignCustomType.primitive << "\t" << instr->assignCustomType.type;
break;
-
case QDeclarativeInstruction::StoreBinding:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+ qWarning().nospace() << idx << "\t\t" << "STORE_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
break;
case QDeclarativeInstruction::StoreBindingOnAlias:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_BINDING_ALIAS\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+ qWarning().nospace() << idx << "\t\t" << "STORE_BINDING_ALIAS\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
break;
case QDeclarativeInstruction::StoreCompiledBinding:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+ qWarning().nospace() << idx << "\t\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
break;
case QDeclarativeInstruction::StoreValueSource:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property << "\t" << instr->assignValueSource.castValue;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property << "\t" << instr->assignValueSource.castValue;
break;
case QDeclarativeInstruction::StoreValueInterceptor:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_VALUE_INTERCEPTOR\t" << instr->assignValueInterceptor.property << "\t" << instr->assignValueInterceptor.castValue;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VALUE_INTERCEPTOR\t" << instr->assignValueInterceptor.property << "\t" << instr->assignValueInterceptor.castValue;
break;
-
case QDeclarativeInstruction::BeginObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "BEGIN\t\t\t" << instr->begin.castValue;
+ qWarning().nospace() << idx << "\t\t" << "BEGIN\t\t\t" << instr->begin.castValue;
break;
case QDeclarativeInstruction::StoreObjectQList:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_OBJECT_QLIST";
+ qWarning().nospace() << idx << "\t\t" << "STORE_OBJECT_QLIST";
break;
case QDeclarativeInstruction::AssignObjectList:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "ASSIGN_OBJECT_LIST";
+ qWarning().nospace() << idx << "\t\t" << "ASSIGN_OBJECT_LIST";
break;
case QDeclarativeInstruction::FetchAttached:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.id;
+ qWarning().nospace() << idx << "\t\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.id;
break;
case QDeclarativeInstruction::FetchQList:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_QLIST\t\t" << instr->fetch.property;
+ qWarning().nospace() << idx << "\t\t" << "FETCH_QLIST\t\t" << instr->fetch.property;
break;
case QDeclarativeInstruction::FetchObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH\t\t\t" << instr->fetch.property;
+ qWarning().nospace() << idx << "\t\t" << "FETCH\t\t\t" << instr->fetch.property;
break;
case QDeclarativeInstruction::FetchValueType:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "FETCH_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type << "\t" << instr->fetchValue.bindingSkipList;
+ qWarning().nospace() << idx << "\t\t" << "FETCH_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type << "\t" << instr->fetchValue.bindingSkipList;
break;
case QDeclarativeInstruction::PopFetchedObject:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "POP";
+ qWarning().nospace() << idx << "\t\t" << "POP";
break;
case QDeclarativeInstruction::PopQList:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "POP_QLIST";
+ qWarning().nospace() << idx << "\t\t" << "POP_QLIST";
break;
case QDeclarativeInstruction::PopValueType:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "POP_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type;
+ qWarning().nospace() << idx << "\t\t" << "POP_VALUE\t\t" << instr->fetchValue.property << "\t" << instr->fetchValue.type;
break;
case QDeclarativeInstruction::Defer:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "DEFER" << "\t\t\t" << instr->defer.deferCount;
+ qWarning().nospace() << idx << "\t\t" << "DEFER" << "\t\t\t" << instr->defer.deferCount;
break;
default:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "XXX UNKNOWN INSTRUCTION" << "\t" << instr->type;
+ qWarning().nospace() << idx << "\t\t" << "XXX UNKNOWN INSTRUCTION" << "\t" << instr->type();
break;
}
#endif // QT_NO_DEBUG_STREAM
}
+int QDeclarativeInstruction::size() const
+{
+#define QML_RETURN_INSTR_SIZE(I, FMT) case I: return QDeclarativeInstructionMeta<(int)I>::Size;
+ switch (common.instructionType) {
+ FOR_EACH_QML_INSTR(QML_RETURN_INSTR_SIZE)
+ default: return 0;
+ }
+#undef QML_RETURN_INSTR_SIZE
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h
index 74f8ab4063..d040967882 100644
--- a/src/declarative/qml/qdeclarativeinstruction_p.h
+++ b/src/declarative/qml/qdeclarativeinstruction_p.h
@@ -57,303 +57,408 @@
QT_BEGIN_NAMESPACE
-class QDeclarativeCompiledData;
-class Q_AUTOTEST_EXPORT QDeclarativeInstruction
-{
-public:
- enum Type {
- //
- // Object Creation
- //
- // CreateObject - Create a new object instance and push it on the
- // object stack
- // SetId - Set the id of the object on the top of the object stack
- // SetDefault - Sets the instance on the top of the object stack to
- // be the context's default object.
- // StoreMetaObject - Assign the dynamic metaobject to object on the
- // top of the stack.
- Init, /* init */
- CreateObject, /* create */
- CreateSimpleObject, /* createSimple */
- SetId, /* setId */
- SetDefault,
- CreateComponent, /* createComponent */
- StoreMetaObject, /* storeMeta */
-
- //
- // Precomputed single assignment
- //
- // StoreFloat - Store a float in a core property
- // StoreDouble - Store a double in a core property
- // StoreInteger - Store a int or uint in a core property
- // StoreBool - Store a bool in a core property
- // StoreString - Store a QString in a core property
- // StoreUrl - Store a QUrl in a core property
- // StoreColor - Store a QColor in a core property
- // StoreDate - Store a QDate in a core property
- // StoreTime - Store a QTime in a core property
- // StoreDateTime - Store a QDateTime in a core property
- // StoreVariant - Store a QVariant in a core property
- // StoreObject - Pop the object on the top of the object stack and
- // store it in a core property
- StoreFloat, /* storeFloat */
- StoreDouble, /* storeDouble */
- StoreInteger, /* storeInteger */
- StoreBool, /* storeBool */
- StoreString, /* storeString */
- StoreUrl, /* storeUrl */
- StoreColor, /* storeColor */
- StoreDate, /* storeDate */
- StoreTime, /* storeTime */
- StoreDateTime, /* storeDateTime */
- StorePoint, /* storeRealPair */
- StorePointF, /* storeRealPair */
- StoreSize, /* storeRealPair */
- StoreSizeF, /* storeRealPair */
- StoreRect, /* storeRect */
- StoreRectF, /* storeRect */
- StoreVector3D, /* storeVector3D */
- StoreVariant, /* storeString */
- StoreVariantInteger, /* storeInteger */
- StoreVariantDouble, /* storeDouble */
- StoreVariantBool, /* storeBool */
- StoreObject, /* storeObject */
- StoreVariantObject, /* storeObject */
- StoreInterface, /* storeObject */
-
- StoreSignal, /* storeSignal */
- StoreImportedScript, /* storeScript */
- StoreScriptString, /* storeScriptString */
+#define FOR_EACH_QML_INSTR(F) \
+ F(Init, init) \
+ F(Done, common) \
+ F(CreateObject, create) \
+ F(CreateSimpleObject, createSimple) \
+ F(SetId, setId) \
+ F(SetDefault, common) \
+ F(CreateComponent, createComponent) \
+ F(StoreMetaObject, storeMeta) \
+ F(StoreVariant, storeString) \
+ F(StoreVariantInteger, storeInteger) \
+ F(StoreVariantDouble, storeDouble) \
+ F(StoreVariantBool, storeBool) \
+ F(StoreString, storeString) \
+ F(StoreByteArray, storeByteArray) \
+ F(StoreUrl, storeUrl) \
+ F(StoreFloat, storeFloat) \
+ F(StoreDouble, storeDouble) \
+ F(StoreBool, storeBool) \
+ F(StoreInteger, storeInteger) \
+ F(StoreColor, storeColor) \
+ F(StoreDate, storeDate) \
+ F(StoreTime, storeTime) \
+ F(StoreDateTime, storeDateTime) \
+ F(StorePoint, storePoint) \
+ F(StorePointF, storePointF) \
+ F(StoreSize, storeSize) \
+ F(StoreSizeF, storeSizeF) \
+ F(StoreRect, storeRect) \
+ F(StoreRectF, storeRectF) \
+ F(StoreVector3D, storeVector3D) \
+ F(StoreObject, storeObject) \
+ F(AssignCustomType, assignCustomType) \
+ F(AssignSignalObject, assignSignalObject) \
+ F(StoreSignal, storeSignal) \
+ F(StoreImportedScript, storeScript) \
+ F(StoreScriptString, storeScriptString) \
+ F(BeginObject, begin) \
+ F(StoreBinding, assignBinding) \
+ F(StoreBindingOnAlias, assignBinding) \
+ F(StoreCompiledBinding, assignBinding) \
+ F(StoreValueSource, assignValueSource) \
+ F(StoreValueInterceptor, assignValueInterceptor) \
+ F(StoreObjectQList, common) \
+ F(AssignObjectList, assignObjectList) \
+ F(StoreVariantObject, storeObject) \
+ F(StoreInterface, storeObject) \
+ F(FetchAttached, fetchAttached) \
+ F(FetchQList, fetchQmlList) \
+ F(FetchObject, fetch) \
+ F(PopQList, common) \
+ F(Defer, defer) \
+ F(PopFetchedObject, common) \
+ F(FetchValueType, fetchValue) \
+ F(PopValueType, fetchValue)
- //
- // Unresolved single assignment
- //
- AssignSignalObject, /* assignSignalObject */
- AssignCustomType, /* assignCustomType */
+#ifdef Q_ALIGNOF
+# define QML_INSTR_ALIGN_MASK (Q_ALIGNOF(QDeclarativeInstruction) - 1)
+#else
+# define QML_INSTR_ALIGN_MASK (sizeof(void *) - 1)
+#endif
- StoreBinding, /* assignBinding */
- StoreBindingOnAlias, /* assignBinding */
- StoreCompiledBinding, /* assignBinding */
- StoreValueSource, /* assignValueSource */
- StoreValueInterceptor, /* assignValueInterceptor */
+#define QML_INSTR_HEADER quint8 instructionType;
+#define QML_INSTR_ENUM(I, FMT) I,
+#define QML_INSTR_SIZE(I, FMT) ((sizeof(QDeclarativeInstruction::instr_##FMT) + QML_INSTR_ALIGN_MASK) & ~QML_INSTR_ALIGN_MASK)
- BeginObject, /* begin */
-
- StoreObjectQList, /* NA */
- AssignObjectList, /* NA */
-
- FetchAttached, /* fetchAttached */
- FetchQList, /* fetch */
- FetchObject, /* fetch */
- FetchValueType, /* fetchValue */
-
- //
- // Stack manipulation
- //
- // PopFetchedObject - Remove an object from the object stack
- // PopQList - Remove a list from the list stack
- PopFetchedObject,
- PopQList,
- PopValueType, /* fetchValue */
-
- //
- // Deferred creation
- //
- Defer /* defer */
+class QDeclarativeCompiledData;
+union QDeclarativeInstruction
+{
+ enum Type {
+ FOR_EACH_QML_INSTR(QML_INSTR_ENUM)
};
- QDeclarativeInstruction()
- : line(0) {}
- Type type;
- unsigned short line;
+ inline void setType(Type type) { common.instructionType = type; }
+ inline Type type() const { return (Type)common.instructionType; }
- struct InitInstruction {
+ struct instr_common {
+ QML_INSTR_HEADER
+ };
+ struct instr_init {
+ QML_INSTR_HEADER
int bindingsSize;
int parserStatusSize;
int contextCache;
int compiledBinding;
};
- struct CreateInstruction {
+ struct instr_create {
+ QML_INSTR_HEADER
int type;
int data;
int bindingBits;
ushort column;
+ ushort line;
};
- struct CreateSimpleInstruction {
+ struct instr_createSimple {
+ QML_INSTR_HEADER
void (*create)(void *);
int typeSize;
int type;
ushort column;
+ ushort line;
};
- struct StoreMetaInstruction {
+ struct instr_storeMeta {
+ QML_INSTR_HEADER
int data;
int aliasData;
int propertyCache;
};
- struct SetIdInstruction {
+ struct instr_setId {
+ QML_INSTR_HEADER
int value;
int index;
};
- struct AssignValueSourceInstruction {
+ struct instr_assignValueSource {
+ QML_INSTR_HEADER
int property;
int owner;
int castValue;
};
- struct AssignValueInterceptorInstruction {
+ struct instr_assignValueInterceptor {
+ QML_INSTR_HEADER
int property;
int owner;
int castValue;
};
- struct AssignBindingInstruction {
+ struct instr_assignBinding {
+ QML_INSTR_HEADER
unsigned int property;
int value;
short context;
short owner;
+ ushort line;
};
- struct FetchInstruction {
+ struct instr_fetch {
+ QML_INSTR_HEADER
int property;
+ ushort line;
};
- struct FetchValueInstruction {
+ struct instr_fetchValue {
+ QML_INSTR_HEADER
int property;
int type;
quint32 bindingSkipList;
};
- struct FetchQmlListInstruction {
+ struct instr_fetchQmlList {
+ QML_INSTR_HEADER
int property;
int type;
};
- struct BeginInstruction {
+ struct instr_begin {
+ QML_INSTR_HEADER
int castValue;
};
- struct StoreFloatInstruction {
+ struct instr_storeFloat {
+ QML_INSTR_HEADER
int propertyIndex;
float value;
};
- struct StoreDoubleInstruction {
+ struct instr_storeDouble {
+ QML_INSTR_HEADER
int propertyIndex;
double value;
};
- struct StoreIntegerInstruction {
+ struct instr_storeInteger {
+ QML_INSTR_HEADER
int propertyIndex;
int value;
};
- struct StoreBoolInstruction {
+ struct instr_storeBool {
+ QML_INSTR_HEADER
int propertyIndex;
bool value;
};
- struct StoreStringInstruction {
+ struct instr_storeString {
+ QML_INSTR_HEADER
+ int propertyIndex;
+ int value;
+ };
+ struct instr_storeByteArray {
+ QML_INSTR_HEADER
int propertyIndex;
int value;
};
- struct StoreScriptStringInstruction {
+ struct instr_storeScriptString {
+ QML_INSTR_HEADER
int propertyIndex;
int value;
int scope;
};
- struct StoreScriptInstruction {
+ struct instr_storeScript {
+ QML_INSTR_HEADER
int value;
};
- struct StoreUrlInstruction {
+ struct instr_storeUrl {
+ QML_INSTR_HEADER
int propertyIndex;
int value;
};
- struct StoreColorInstruction {
+ struct instr_storeColor {
+ QML_INSTR_HEADER
int propertyIndex;
unsigned int value;
};
- struct StoreDateInstruction {
+ struct instr_storeDate {
+ QML_INSTR_HEADER
int propertyIndex;
int value;
};
- struct StoreTimeInstruction {
+ struct instr_storeTime {
+ QML_INSTR_HEADER
int propertyIndex;
- int valueIndex;
- };
- struct StoreDateTimeInstruction {
+ struct QTime {
+ int mds;
+#if defined(Q_OS_WINCE)
+ int startTick;
+#endif
+ } time;
+ };
+ struct instr_storeDateTime {
+ QML_INSTR_HEADER
int propertyIndex;
- int valueIndex;
+ int date;
+ instr_storeTime::QTime time;
};
- struct StoreRealPairInstruction {
+ struct instr_storeRect {
+ QML_INSTR_HEADER
int propertyIndex;
- int valueIndex;
- };
- struct StoreRectInstruction {
+ struct QRect {
+#if defined(Q_OS_MAC)
+ int y1;
+ int x1;
+ int y2;
+ int x2;
+#else
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+#endif
+ } rect;
+ };
+ struct instr_storeRectF {
+ QML_INSTR_HEADER
int propertyIndex;
- int valueIndex;
- };
- struct StoreVector3DInstruction {
+ struct QRectF {
+ qreal xp;
+ qreal yp;
+ qreal w;
+ qreal h;
+ } rect;
+ };
+ struct instr_storeObject {
+ QML_INSTR_HEADER
int propertyIndex;
- int valueIndex;
+ ushort line;
};
- struct StoreObjectInstruction {
+ struct instr_assignCustomType {
+ QML_INSTR_HEADER
int propertyIndex;
+ int primitive;
+ int type;
+ ushort line;
};
- struct AssignCustomTypeInstruction {
- int propertyIndex;
- int valueIndex;
- };
- struct StoreSignalInstruction {
+ struct instr_storeSignal {
+ QML_INSTR_HEADER
int signalIndex;
int value;
short context;
int name;
+ ushort line;
};
- struct AssignSignalObjectInstruction {
+ struct instr_assignSignalObject {
+ QML_INSTR_HEADER
int signal;
+ ushort line;
};
- struct CreateComponentInstruction {
+ struct instr_createComponent {
+ QML_INSTR_HEADER
int count;
- ushort column;
int endLine;
int metaObject;
+ ushort column;
+ ushort line;
};
- struct FetchAttachedInstruction {
+ struct instr_fetchAttached {
+ QML_INSTR_HEADER
int id;
+ ushort line;
};
- struct DeferInstruction {
+ struct instr_defer {
+ QML_INSTR_HEADER
int deferCount;
};
-
- union {
- InitInstruction init;
- CreateInstruction create;
- CreateSimpleInstruction createSimple;
- StoreMetaInstruction storeMeta;
- SetIdInstruction setId;
- AssignValueSourceInstruction assignValueSource;
- AssignValueInterceptorInstruction assignValueInterceptor;
- AssignBindingInstruction assignBinding;
- FetchInstruction fetch;
- FetchValueInstruction fetchValue;
- FetchQmlListInstruction fetchQmlList;
- BeginInstruction begin;
- StoreFloatInstruction storeFloat;
- StoreDoubleInstruction storeDouble;
- StoreIntegerInstruction storeInteger;
- StoreBoolInstruction storeBool;
- StoreStringInstruction storeString;
- StoreScriptStringInstruction storeScriptString;
- StoreScriptInstruction storeScript;
- StoreUrlInstruction storeUrl;
- StoreColorInstruction storeColor;
- StoreDateInstruction storeDate;
- StoreTimeInstruction storeTime;
- StoreDateTimeInstruction storeDateTime;
- StoreRealPairInstruction storeRealPair;
- StoreRectInstruction storeRect;
- StoreVector3DInstruction storeVector3D;
- StoreObjectInstruction storeObject;
- AssignCustomTypeInstruction assignCustomType;
- StoreSignalInstruction storeSignal;
- AssignSignalObjectInstruction assignSignalObject;
- CreateComponentInstruction createComponent;
- FetchAttachedInstruction fetchAttached;
- DeferInstruction defer;
+ struct instr_assignObjectList {
+ QML_INSTR_HEADER
+ ushort line;
+ };
+ struct instr_storePoint {
+ QML_INSTR_HEADER
+ int propertyIndex;
+ struct QPoint {
+#if defined(Q_OS_MAC)
+ int yp;
+ int xp;
+#else
+ int xp;
+ int yp;
+#endif
+ } point;
+ };
+ struct instr_storePointF {
+ QML_INSTR_HEADER
+ int propertyIndex;
+ struct QPointF {
+ qreal xp;
+ qreal yp;
+ } point;
+ };
+ struct instr_storeSize {
+ QML_INSTR_HEADER
+ int propertyIndex;
+ struct QSize {
+ int wd;
+ int ht;
+ } size;
};
+ struct instr_storeSizeF {
+ QML_INSTR_HEADER
+ int propertyIndex;
+ struct QSizeF {
+ qreal wd;
+ qreal ht;
+ } size;
+ };
+ struct instr_storeVector3D {
+ QML_INSTR_HEADER
+ int propertyIndex;
+ struct QVector3D {
+ float xp;
+ float yp;
+ float zp;
+ } vector;
+ };
+
+ instr_common common;
+ instr_init init;
+ instr_create create;
+ instr_createSimple createSimple;
+ instr_storeMeta storeMeta;
+ instr_setId setId;
+ instr_assignValueSource assignValueSource;
+ instr_assignValueInterceptor assignValueInterceptor;
+ instr_assignBinding assignBinding;
+ instr_fetch fetch;
+ instr_fetchValue fetchValue;
+ instr_fetchQmlList fetchQmlList;
+ instr_begin begin;
+ instr_storeFloat storeFloat;
+ instr_storeDouble storeDouble;
+ instr_storeInteger storeInteger;
+ instr_storeBool storeBool;
+ instr_storeString storeString;
+ instr_storeByteArray storeByteArray;
+ instr_storeScriptString storeScriptString;
+ instr_storeScript storeScript;
+ instr_storeUrl storeUrl;
+ instr_storeColor storeColor;
+ instr_storeDate storeDate;
+ instr_storeTime storeTime;
+ instr_storeDateTime storeDateTime;
+ instr_storePoint storePoint;
+ instr_storePointF storePointF;
+ instr_storeSize storeSize;
+ instr_storeSizeF storeSizeF;
+ instr_storeRect storeRect;
+ instr_storeRectF storeRectF;
+ instr_storeVector3D storeVector3D;
+ instr_storeObject storeObject;
+ instr_assignCustomType assignCustomType;
+ instr_storeSignal storeSignal;
+ instr_assignSignalObject assignSignalObject;
+ instr_createComponent createComponent;
+ instr_fetchAttached fetchAttached;
+ instr_defer defer;
+ instr_assignObjectList assignObjectList;
- void dump(QDeclarativeCompiledData *);
+ int size() const;
};
+template<int N>
+struct QDeclarativeInstructionMeta {
+};
+
+#define QML_INSTR_META_TEMPLATE(I, FMT) \
+ template<> struct QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I> { \
+ enum { Size = QML_INSTR_SIZE(I, FMT) }; \
+ typedef QDeclarativeInstruction::instr_##FMT DataType; \
+ static const DataType &data(const QDeclarativeInstruction &instr) { return instr.FMT; } \
+ };
+FOR_EACH_QML_INSTR(QML_INSTR_META_TEMPLATE);
+#undef QML_INSTR_META_TEMPLATE
+
QT_END_NAMESPACE
#endif // QDECLARATIVEINSTRUCTION_P_H
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index 50c6907b70..73ed23ba9d 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -88,6 +88,7 @@ QT_BEGIN_NAMESPACE
struct QDeclarativeMetaTypeData
{
+ QDeclarativeMetaTypeData();
~QDeclarativeMetaTypeData();
QList<QDeclarativeType *> types;
typedef QHash<int, QDeclarativeType *> Ids;
@@ -98,6 +99,14 @@ struct QDeclarativeMetaTypeData
MetaObjects metaObjectToType;
typedef QHash<int, QDeclarativeMetaType::StringConverter> StringConverters;
StringConverters stringConverters;
+ struct ModuleApiList {
+ ModuleApiList() : sorted(true) {}
+ QList<QDeclarativeMetaType::ModuleApi> moduleApis;
+ bool sorted;
+ };
+ typedef QHash<QByteArray, ModuleApiList> ModuleApis;
+ ModuleApis moduleApis;
+ int moduleApiCount;
struct ModuleInfo {
ModuleInfo(int major, int minor)
@@ -119,6 +128,11 @@ struct QDeclarativeMetaTypeData
Q_GLOBAL_STATIC(QDeclarativeMetaTypeData, metaTypeData)
Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
+QDeclarativeMetaTypeData::QDeclarativeMetaTypeData()
+: moduleApiCount(0)
+{
+}
+
QDeclarativeMetaTypeData::~QDeclarativeMetaTypeData()
{
for (int i = 0; i < types.count(); ++i)
@@ -664,6 +678,34 @@ int registerType(const QDeclarativePrivate::RegisterType &type)
return index;
}
+int registerModuleApi(const QDeclarativePrivate::RegisterModuleApi &api)
+{
+ QWriteLocker lock(metaTypeDataLock());
+
+ QDeclarativeMetaTypeData *data = metaTypeData();
+ QByteArray uri(api.uri);
+ QDeclarativeMetaType::ModuleApi import;
+ import.major = api.versionMajor;
+ import.minor = api.versionMinor;
+ import.script = api.scriptApi;
+ import.qobject = api.qobjectApi;
+
+ int index = data->moduleApiCount++;
+
+ QDeclarativeMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
+ if (iter == data->moduleApis.end()) {
+ QDeclarativeMetaTypeData::ModuleApiList apis;
+ apis.moduleApis << import;
+ data->moduleApis.insert(uri, apis);
+ } else {
+ iter->moduleApis << import;
+ iter->sorted = false;
+ }
+
+ return index;
+}
+
+
/*
This method is "over generalized" to allow us to (potentially) register more types of things in
the future without adding exported symbols.
@@ -676,13 +718,16 @@ int QDeclarativePrivate::qmlregister(RegistrationType type, void *data)
return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
} else if (type == AutoParentRegistration) {
return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
+ } else if (type == ModuleApiRegistration) {
+ return registerModuleApi(*reinterpret_cast<RegisterModuleApi *>(data));
}
return -1;
}
/*
- Have any types been registered for \a module with at least versionMajor.versionMinor, and types
- for \a module with at most versionMajor.versionMinor.
+ Returns true if any type or API has been registered for the given \a module with at least
+ versionMajor.versionMinor, or if types have been registered for \a module with at most
+ versionMajor.versionMinor.
So if only 4.7 and 4.9 have been registered, 4.7,4.8, and 4.9 are valid, but not 4.6 nor 4.10.
@@ -691,13 +736,27 @@ int QDeclarativePrivate::qmlregister(RegistrationType type, void *data)
bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor)
{
QDeclarativeMetaTypeData *data = metaTypeData();
+
+ // first, check Types
QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(module);
- return it != data->modules.end()
+ if (it != data->modules.end()
&& ((versionMajor<0 && versionMinor<0) ||
(((*it).vmajor_max > versionMajor ||
((*it).vmajor_max == versionMajor && (*it).vminor_max >= versionMinor))
&& ((*it).vmajor_min < versionMajor ||
- ((*it).vmajor_min == versionMajor && (*it).vminor_min <= versionMinor))));
+ ((*it).vmajor_min == versionMajor && (*it).vminor_min <= versionMinor))))) {
+ return true;
+ }
+
+ // then, check ModuleApis
+ foreach (const QDeclarativeMetaType::ModuleApi &mApi, data->moduleApis.value(module).moduleApis) {
+ if ((versionMajor<0 && versionMinor<0)
+ || (mApi.major == versionMajor && mApi.minor == versionMinor)) {
+ return true;
+ }
+ }
+
+ return false;
}
QList<QDeclarativePrivate::AutoParentFunction> QDeclarativeMetaType::parentFunctions()
@@ -707,6 +766,35 @@ QList<QDeclarativePrivate::AutoParentFunction> QDeclarativeMetaType::parentFunct
return data->parentFunctions;
}
+static bool operator<(const QDeclarativeMetaType::ModuleApi &lhs, const QDeclarativeMetaType::ModuleApi &rhs)
+{
+ return lhs.major < rhs.major || (lhs.major == rhs.major && lhs.minor < rhs.minor);
+}
+
+QDeclarativeMetaType::ModuleApi
+QDeclarativeMetaType::moduleApi(const QByteArray &uri, int versionMajor, int versionMinor)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QDeclarativeMetaTypeData *data = metaTypeData();
+
+ QDeclarativeMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
+ if (iter == data->moduleApis.end())
+ return ModuleApi();
+
+ if (iter->sorted == false) {
+ qSort(iter->moduleApis.begin(), iter->moduleApis.end());
+ iter->sorted = true;
+ }
+
+ for (int ii = iter->moduleApis.count() - 1; ii >= 0; --ii) {
+ const ModuleApi &import = iter->moduleApis.at(ii);
+ if (import.major == versionMajor && import.minor <= versionMinor)
+ return import;
+ }
+
+ return ModuleApi();
+}
+
QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok)
{
if (!isQObject(v.userType())) {
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index a6a3e548c4..ba2d445826 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -59,6 +59,7 @@
#include <QtCore/qvariant.h>
#include <QtCore/qbitarray.h>
#include <private/qdeclarativeglobal_p.h>
+#include <QtScript/qscriptvalue.h>
QT_BEGIN_NAMESPACE
@@ -106,6 +107,25 @@ public:
static bool isModule(const QByteArray &module, int versionMajor, int versionMinor);
static QList<QDeclarativePrivate::AutoParentFunction> parentFunctions();
+
+ struct ModuleApiInstance {
+ ModuleApiInstance()
+ : scriptCallback(0), qobjectCallback(0), qobjectApi(0) {}
+
+ QScriptValue (*scriptCallback)(QDeclarativeEngine *, QScriptEngine *);
+ QObject *(*qobjectCallback)(QDeclarativeEngine *, QScriptEngine *);
+ QScriptValue scriptApi;
+ QObject *qobjectApi;
+ };
+ struct ModuleApi {
+ inline ModuleApi();
+ inline bool operator==(const ModuleApi &) const;
+ int major;
+ int minor;
+ QScriptValue (*script)(QDeclarativeEngine *, QScriptEngine *);
+ QObject *(*qobject)(QDeclarativeEngine *, QScriptEngine *);
+ };
+ static ModuleApi moduleApi(const QByteArray &, int, int);
};
class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeType
@@ -168,6 +188,25 @@ private:
QDeclarativeTypePrivate *d;
};
+QDeclarativeMetaType::ModuleApi::ModuleApi()
+// : major(0), minor(0), script(0), qobject(0)
+{
+ major = 0;
+ minor = 0;
+ script = 0;
+ qobject = 0;
+}
+
+bool QDeclarativeMetaType::ModuleApi::operator==(const ModuleApi &other) const
+{
+ return major == other.major && minor == other.minor && script == other.script && qobject == other.qobject;
+}
+
+inline uint qHash(const QDeclarativeMetaType::ModuleApi &import)
+{
+ return import.major ^ import.minor ^ quintptr(import.script) ^ quintptr(import.qobject);
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVEMETATYPE_P_H
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index 1ab97e70e7..53f702ce51 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -403,6 +403,33 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
} else if (value.isFunction() && !value.isRegExp()) {
// this is handled by the binding creation above
} else {
+ //### expand optimization for other known types
+ if (lastData->propType == QMetaType::Int && value.isNumber()) {
+ int rawValue = qRound(value.toNumber());
+ int status = -1;
+ int flags = 0;
+ void *a[] = { (void *)&rawValue, 0, &status, &flags };
+ QMetaObject::metacall(obj, QMetaObject::WriteProperty,
+ lastData->coreIndex, a);
+ return;
+ } else if (lastData->propType == QMetaType::QReal && value.isNumber()) {
+ qreal rawValue = qreal(value.toNumber());
+ int status = -1;
+ int flags = 0;
+ void *a[] = { (void *)&rawValue, 0, &status, &flags };
+ QMetaObject::metacall(obj, QMetaObject::WriteProperty,
+ lastData->coreIndex, a);
+ return;
+ } else if (lastData->propType == QMetaType::QString && value.isString()) {
+ const QString &rawValue = value.toString();
+ int status = -1;
+ int flags = 0;
+ void *a[] = { (void *)&rawValue, 0, &status, &flags };
+ QMetaObject::metacall(obj, QMetaObject::WriteProperty,
+ lastData->coreIndex, a);
+ return;
+ }
+
QVariant v;
if (lastData->flags & QDeclarativePropertyCache::Data::IsQList)
v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >());
diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h
index 2cf2317293..9eacc1d1cb 100644
--- a/src/declarative/qml/qdeclarativeprivate.h
+++ b/src/declarative/qml/qdeclarativeprivate.h
@@ -74,6 +74,9 @@ public:
};
+class QScriptValue;
+class QScriptEngine;
+class QDeclarativeEngine;
class QDeclarativeCustomParser;
namespace QDeclarativePrivate
{
@@ -233,10 +236,22 @@ namespace QDeclarativePrivate
AutoParentFunction function;
};
+ struct RegisterModuleApi {
+ int version;
+
+ const char *uri;
+ int versionMajor;
+ int versionMinor;
+
+ QScriptValue (*scriptApi)(QDeclarativeEngine *, QScriptEngine *);
+ QObject *(*qobjectApi)(QDeclarativeEngine *, QScriptEngine *);
+ };
+
enum RegistrationType {
TypeRegistration = 0,
InterfaceRegistration = 1,
- AutoParentRegistration = 2
+ AutoParentRegistration = 2,
+ ModuleApiRegistration = 3,
};
int Q_DECLARATIVE_EXPORT qmlregister(RegistrationType, void *);
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index e806dbf779..ae28049eed 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -183,6 +183,9 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name)
/*!
Creates a QDeclarativeProperty for the property \a name of \a obj
using the \l{QDeclarativeContext} {context} \a ctxt.
+
+ Creating a QDeclarativeProperty without a context will render some
+ properties - like attached properties - inaccessible.
*/
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeContext *ctxt)
: d(new QDeclarativePropertyPrivate)
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index 59e76afb3f..0fa4e24725 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -61,6 +61,8 @@ QDeclarativePropertyCache::Data::Flags QDeclarativePropertyCache::Data::flagsFor
flags |= Data::IsWritable;
if (p.isResettable())
flags |= Data::IsResettable;
+ if (p.isFinal())
+ flags |= Data::IsFinal;
if (propType == qMetaTypeId<QDeclarativeBinding *>()) {
flags |= Data::IsQmlBinding;
diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h
index 581f5197f4..7e34748c6c 100644
--- a/src/declarative/qml/qdeclarativepropertycache_p.h
+++ b/src/declarative/qml/qdeclarativepropertycache_p.h
@@ -84,20 +84,21 @@ public:
IsWritable = 0x00000002,
IsResettable = 0x00000004,
IsAlias = 0x00000008,
+ IsFinal = 0x00000010,
// These are mutualy exclusive
- IsFunction = 0x00000010,
- IsQObjectDerived = 0x00000020,
- IsEnumType = 0x00000040,
- IsQList = 0x00000080,
- IsQmlBinding = 0x00000100,
- IsQScriptValue = 0x00000200,
+ IsFunction = 0x00000020,
+ IsQObjectDerived = 0x00000040,
+ IsEnumType = 0x00000080,
+ IsQList = 0x00000100,
+ IsQmlBinding = 0x00000200,
+ IsQScriptValue = 0x00000400,
// Apply only to IsFunctions
- IsVMEFunction = 0x00000400,
- HasArguments = 0x00000800,
- IsSignal = 0x00001000,
- IsVMESignal = 0x00002000
+ IsVMEFunction = 0x00000800,
+ HasArguments = 0x00001000,
+ IsSignal = 0x00002000,
+ IsVMESignal = 0x00004000
};
Q_DECLARE_FLAGS(Flags, Flag)
diff --git a/src/declarative/qml/qdeclarativescarceresourcescriptclass.cpp b/src/declarative/qml/qdeclarativescarceresourcescriptclass.cpp
new file mode 100644
index 0000000000..d94e2d9332
--- /dev/null
+++ b/src/declarative/qml/qdeclarativescarceresourcescriptclass.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qdeclarativescarceresourcescriptclass_p.h"
+
+#include "private/qdeclarativeengine_p.h"
+#include "private/qdeclarativecontext_p.h"
+#include "private/qdeclarativedata_p.h"
+#include "private/qdeclarativetypenamescriptclass_p.h"
+#include "private/qdeclarativelistscriptclass_p.h"
+#include "private/qdeclarativebinding_p.h"
+#include "private/qdeclarativeguard_p.h"
+#include "private/qdeclarativevmemetaobject_p.h"
+
+#include <QtCore/qtimer.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtScript/qscriptcontextinfo.h>
+
+Q_DECLARE_METATYPE(QScriptValue);
+
+QT_BEGIN_NAMESPACE
+
+QDeclarativeScarceResourceScriptClass::QDeclarativeScarceResourceScriptClass(QDeclarativeEngine *bindEngine)
+ : QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine)
+{
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+
+ // Properties of this type can be explicitly preserved by clients,
+ // which prevents the scarce resource from being automatically
+ // released after the binding has been evaluated.
+ m_preserve = scriptEngine->newFunction(preserve);
+ m_preserveId = createPersistentIdentifier(QLatin1String("preserve"));
+
+ // Similarly, they can be explicitly destroyed by clients,
+ // which releases the scarce resource.
+ m_destroy = scriptEngine->newFunction(destroy);
+ m_destroyId = createPersistentIdentifier(QLatin1String("destroy"));
+}
+
+QDeclarativeScarceResourceScriptClass::~QDeclarativeScarceResourceScriptClass()
+{
+}
+
+/*
+ Returns a JavaScript object whose instance data is a new scarce resource data.
+ The scarce resource is added to the doubly-linked-list of scarce resources in the engine
+ so that the scarce resource can be released after evaluation completes.
+ */
+QScriptValue QDeclarativeScarceResourceScriptClass::newScarceResource(const QVariant &v)
+{
+ // create the scarce resource
+ ScarceResourceData *srd = new ScarceResourceData(v);
+
+ // insert into the linked list
+ QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine);
+ srd->insertInto(&enginePrivate->scarceResources);
+ Q_ASSERT(enginePrivate->scarceResourcesRefCount > 0);
+
+ // return the javascript object with the scarce resource instance data
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+ return QScriptDeclarativeClass::newObject(scriptEngine, this, srd); // JSC takes ownership of srd.
+}
+
+QVariant QDeclarativeScarceResourceScriptClass::toVariant(Object *object, bool *ok)
+{
+ ScarceResourceData *obj = static_cast<ScarceResourceData*>(object);
+ if (ok) *ok = true;
+ return obj->resource;
+}
+
+QVariant QDeclarativeScarceResourceScriptClass::toVariant(const QScriptValue &value)
+{
+ Q_ASSERT(scriptClass(value) == this);
+
+ return toVariant(object(value), 0);
+}
+
+// The destroy() and preserve() function properties are readable.
+QScriptClass::QueryFlags
+QDeclarativeScarceResourceScriptClass::queryProperty(Object *object, const Identifier &name,
+ QScriptClass::QueryFlags flags)
+{
+ Q_UNUSED(object)
+ Q_UNUSED(flags)
+
+ if (name == m_destroyId.identifier || name == m_preserveId.identifier)
+ return (QScriptClass::HandlesReadAccess);
+ return 0;
+}
+
+// Return the (function) values which may be evaluated by clients.
+QDeclarativeScarceResourceScriptClass::Value
+QDeclarativeScarceResourceScriptClass::property(Object *object, const Identifier &name)
+{
+ Q_UNUSED(object)
+
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+
+ // functions
+ if (name == m_preserveId.identifier)
+ return Value(scriptEngine, m_preserve);
+ else if (name == m_destroyId.identifier)
+ return Value(scriptEngine, m_destroy);
+
+ return Value();
+}
+
+/*
+ This method is called when the user explicitly calls the "preserve" method of a scarce resource in JavaScript
+ within the specified evaluation context \a context of the script engine \a engine.
+ Calling this function signifies that the user explicitly wants to preserve the resource rather than let it
+ be automatically released once evaluation of the expression is complete.
+ This function removes the internal scarce resource from the declarative engine's linked list of scarce resources
+ to release after evaluation of the expression completes. This means that the resource will only be truly
+ released when the JavaScript engine's garbage collector is run.
+
+ Example:
+ \qml
+ function getIcon(model) {
+ var icon = model.avatar; // a pixmap property
+ icon.preserve(); // explicitly preserves the resource
+ return icon; // a valid variant will be returned
+ }
+ \endqml
+ */
+QScriptValue QDeclarativeScarceResourceScriptClass::preserve(QScriptContext *context, QScriptEngine *engine)
+{
+ QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
+ QScriptValue that = context->thisObject();
+
+ if (scriptClass(that) != p->scarceResourceClass)
+ return engine->undefinedValue();
+
+ // The client wishes to preserve the resource in this SRD.
+ ScarceResourceData *data = static_cast<ScarceResourceData *>(p->scarceResourceClass->object(that));
+ if (!data)
+ return engine->undefinedValue();
+
+ // remove node from list, without releasing the resource.
+ data->removeNode();
+
+ return engine->undefinedValue();
+}
+
+/*
+ This method is called when the user explicitly calls the "destroy" method of a scarce resource in JavaScript
+ within the specified evaluation context \a context of the script engine \a engine.
+ Calling this function signifies that the user explicitly wants to release the resource.
+ This function sets the internal scarce resource variant to the invalid variant, in order to release the original resource,
+ and then removes the resource from the declarative engine's linked-list of scarce resources to
+ to release after evaluation of the expression completes, as it has already been released.
+
+ Example:
+ \qml
+ function getIcon(model) {
+ var icon = model.avatar; // a pixmap property
+ icon.destroy(); // explicitly releases the resource
+ return icon; // an invalid variant will be returned
+ }
+ \endqml
+ */
+QScriptValue QDeclarativeScarceResourceScriptClass::destroy(QScriptContext *context, QScriptEngine *engine)
+{
+ QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
+ QScriptValue that = context->thisObject();
+
+ if (scriptClass(that) != p->scarceResourceClass)
+ return engine->undefinedValue();
+
+ // the client wishes to release the resource in this SRD.
+ ScarceResourceData *data = static_cast<ScarceResourceData *>(p->scarceResourceClass->object(that));
+ if (!data)
+ return engine->undefinedValue();
+
+ // release the resource and remove the node from the list.
+ data->releaseResource();
+
+ return engine->undefinedValue();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativescarceresourcescriptclass_p.h b/src/declarative/qml/qdeclarativescarceresourcescriptclass_p.h
new file mode 100644
index 0000000000..2a1390a230
--- /dev/null
+++ b/src/declarative/qml/qdeclarativescarceresourcescriptclass_p.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVESCARCERESOURCESCRIPTCLASS_P_H
+#define QDECLARATIVESCARCERESOURCESCRIPTCLASS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qdeclarativepropertycache_p.h"
+#include "private/qdeclarativetypenamecache_p.h"
+
+#include <private/qscriptdeclarativeclass_p.h>
+#include <QtScript/qscriptengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeEngine;
+
+/*
+ Scarce resources (like pixmaps and textures) are managed manually
+ in that the variant will be set to the invalid variant once the
+ JavaScript engine has finished using the JavaScript object whose
+ instance data is the ScarceResourceData (but before the garbage
+ collector frees the JavaScript object itself).
+
+ The engine stores a doubly-linked-list of scarce resources which
+ will to be cleaned up after a binding is successfully evaluated
+ (unless the user explicitly preserves the scarce resource).
+
+ A ScarceResourceData pointer should not be deleted manually, as
+ all instances of a ScarceResourceData should be owned by the
+ JavaScript engine.
+ */
+struct ScarceResourceData : public QScriptDeclarativeClass::Object {
+ ScarceResourceData(const QVariant &v) : resource(v), prev(0), next(0)
+ {
+ }
+
+ virtual ~ScarceResourceData()
+ {
+ releaseResource();
+ }
+
+ // Insert this resource into the given list of resources.
+ void insertInto(ScarceResourceData **list)
+ {
+ // This node becomes the head of the list.
+ next = *list; // so our next = old list head
+ *list = this; // list now points to us (we're the head)
+ prev = list; // as we're the head, our prev ptr becomes the list ptr.
+
+ // and the next node's prev pointer must contain a ptr to our next ptr,
+ // since per definition, prev always contains a pointer to the previous node's "next" ptr,
+ // and the "this" node is the "this->next" node's "prev" node.
+ if (next) next->prev = &next;
+ }
+
+ // Remove this resource from the list of resources, without releasing the resource.
+ void removeNode()
+ {
+ // whatever previously pointed to this node (ie, as that node's "next" node)
+ // should now point to our next node (since we no longer exist in the list).
+ // and the next node's prev ptr should point to our prev node.
+ if (prev) *prev = next;
+ if (next) next->prev = prev;
+ prev = 0;
+ next = 0;
+ }
+
+ // Release this resource, and remove from the list.
+ void releaseResource()
+ {
+ resource = QVariant();
+ removeNode();
+ }
+
+ QVariant resource;
+
+ // prev always contains a pointer to the previous node's "next" ptr.
+ // :. for the head node, [*prev] will be engine->scarceResources
+ // :. for every other node, [*prev] will be the previous node's "next" ptr.
+ ScarceResourceData **prev;
+ ScarceResourceData *next;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeScarceResourceScriptClass : public QScriptDeclarativeClass
+{
+public:
+ QDeclarativeScarceResourceScriptClass(QDeclarativeEngine *);
+ ~QDeclarativeScarceResourceScriptClass();
+
+ // Creates a new JavaScript object whose instance data is the scarce resource v
+ QScriptValue newScarceResource(const QVariant &v);
+
+ // inherited from QScriptDeclarativeClass
+ virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
+ QScriptClass::QueryFlags flags);
+ virtual Value property(Object *, const Identifier &);
+ virtual QVariant toVariant(Object *, bool *ok = 0);
+ QVariant toVariant(const QScriptValue &value);
+
+private:
+ PersistentIdentifier m_preserveId;
+ PersistentIdentifier m_destroyId;
+ QScriptValue m_preserve;
+ QScriptValue m_destroy;
+
+ static QScriptValue preserve(QScriptContext *context, QScriptEngine *engine);
+ static QScriptValue destroy(QScriptContext *context, QScriptEngine *engine);
+
+ QDeclarativeEngine *engine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVESCARCERESOURCESCRIPTCLASS_P_H
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index d87f8da3dc..df1dec5efc 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -59,6 +59,22 @@ QT_BEGIN_NAMESPACE
using namespace QDeclarativeJS;
using namespace QDeclarativeParser;
+void QDeclarativeScriptParser::Import::extractVersion(int *maj, int *min) const
+{
+ *maj = -1; *min = -1;
+
+ if (!version.isEmpty()) {
+ int dot = version.indexOf(QLatin1Char('.'));
+ if (dot < 0) {
+ *maj = version.toInt();
+ *min = 0;
+ } else {
+ *maj = version.left(dot).toInt();
+ *min = version.mid(dot+1).toInt();
+ }
+ }
+}
+
namespace {
class ProcessAST: protected AST::Visitor
@@ -111,6 +127,7 @@ protected:
LocationSpan location,
AST::UiObjectInitializer *initializer = 0);
+ QDeclarativeParser::Variant getVariant(AST::Statement *stmt);
QDeclarativeParser::Variant getVariant(AST::ExpressionNode *expr);
LocationSpan location(AST::SourceLocation start, AST::SourceLocation end);
@@ -588,16 +605,16 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
property.location = location(node->firstSourceLocation(),
node->lastSourceLocation());
- if (node->expression) { // default value
+ if (node->statement) { // default value
property.defaultValue = new Property;
property.defaultValue->parent = _stateStack.top().object;
property.defaultValue->location =
- location(node->expression->firstSourceLocation(),
- node->expression->lastSourceLocation());
+ location(node->statement->firstSourceLocation(),
+ node->statement->lastSourceLocation());
QDeclarativeParser::Value *value = new QDeclarativeParser::Value;
- value->location = location(node->expression->firstSourceLocation(),
- node->expression->lastSourceLocation());
- value->value = getVariant(node->expression);
+ value->location = location(node->statement->firstSourceLocation(),
+ node->statement->lastSourceLocation());
+ value->value = getVariant(node->statement);
property.defaultValue->values << value;
}
@@ -642,6 +659,18 @@ bool ProcessAST::visit(AST::UiObjectBinding *node)
return false;
}
+QDeclarativeParser::Variant ProcessAST::getVariant(AST::Statement *stmt)
+{
+ if (stmt) {
+ if (AST::ExpressionStatement *exprStmt = AST::cast<AST::ExpressionStatement *>(stmt))
+ return getVariant(exprStmt->expression);
+
+ return QDeclarativeParser::Variant(asString(stmt), stmt);
+ }
+
+ return QDeclarativeParser::Variant();
+}
+
QDeclarativeParser::Variant ProcessAST::getVariant(AST::ExpressionNode *expr)
{
if (AST::StringLiteral *lit = AST::cast<AST::StringLiteral *>(expr)) {
@@ -708,7 +737,7 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
while (propertyCount--)
_stateStack.pop();
- return true;
+ return false;
}
static QList<int> collectCommas(AST::UiArrayMemberList *members)
@@ -743,7 +772,7 @@ bool ProcessAST::visit(AST::UiArrayBinding *node)
error.setLine(this->location(propertyName).start.line);
error.setColumn(this->location(propertyName).start.column);
_parser->_errors << error;
- return 0;
+ return false;
}
accept(node->members);
@@ -896,6 +925,19 @@ static void replaceWithSpace(QString &str, int idx, int n)
*data++ = space;
}
+static QDeclarativeParser::LocationSpan
+locationFromLexer(const QDeclarativeJS::Lexer &lex, int startLine, int startColumn, int startOffset)
+{
+ QDeclarativeParser::LocationSpan l;
+
+ l.start.line = startLine; l.start.column = startColumn;
+ l.end.line = lex.endLineNo(); l.end.column = lex.endColumnNo();
+ l.range.offset = startOffset;
+ l.range.length = lex.tokenOffset() + lex.tokenLength() - startOffset;
+
+ return l;
+}
+
/*
Searches for ".pragma <value>" declarations within \a script. Currently supported pragmas
are:
@@ -1024,7 +1066,8 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
return rv;
int startOffset = l.tokenOffset();
- int startLine = l.currentLineNo();
+ int startLine = l.startLineNo();
+ int startColumn = l.startColumnNo();
token = l.lex();
@@ -1062,8 +1105,11 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
if (!importId.at(0).isUpper())
return rv;
+ QDeclarativeParser::LocationSpan location =
+ locationFromLexer(l, startLine, startColumn, startOffset);
+
token = l.lex();
- if (l.currentLineNo() == startLine)
+ if (l.startLineNo() == startLine)
return rv;
replaceWithSpace(script, startOffset, endOffset - startOffset);
@@ -1072,9 +1118,9 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
import.type = Import::Script;
import.uri = file;
import.qualifier = importId;
+ import.location = location;
rv.imports << import;
-
} else {
// URI
QString uri;
@@ -1117,8 +1163,11 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
if (!importId.at(0).isUpper())
return rv;
+ QDeclarativeParser::LocationSpan location =
+ locationFromLexer(l, startLine, startColumn, startOffset);
+
token = l.lex();
- if (l.currentLineNo() == startLine)
+ if (l.startLineNo() == startLine)
return rv;
replaceWithSpace(script, startOffset, endOffset - startOffset);
@@ -1128,6 +1177,7 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
import.uri = uri;
import.version = version;
import.qualifier = importId;
+ import.location = location;
rv.imports << import;
}
@@ -1143,7 +1193,7 @@ QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMe
QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
int endOffset = l.tokenLength() + l.tokenOffset();
- if (pragmaValue == QLatin1String("library")) {
+ if (pragmaValue == library) {
pragmas |= QDeclarativeParser::Object::ScriptBlock::Shared;
replaceWithSpace(script, startOffset, endOffset - startOffset);
} else {
diff --git a/src/declarative/qml/qdeclarativescriptparser_p.h b/src/declarative/qml/qdeclarativescriptparser_p.h
index 5a64153370..73e797635a 100644
--- a/src/declarative/qml/qdeclarativescriptparser_p.h
+++ b/src/declarative/qml/qdeclarativescriptparser_p.h
@@ -67,7 +67,7 @@ QT_MODULE(Declarative)
class QByteArray;
class QDeclarativeScriptParserJsASTData;
-class QDeclarativeScriptParser
+class Q_AUTOTEST_EXPORT QDeclarativeScriptParser
{
public:
class Import
@@ -82,6 +82,8 @@ public:
QString qualifier;
QString version;
+ void extractVersion(int *maj, int *min) const;
+
QDeclarativeParser::LocationSpan location;
};
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index 168c1512e2..a413305e28 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -609,7 +609,7 @@ void QDeclarativeDataLoader::setData(QDeclarativeDataBlob *blob, const QByteArra
if (!blob->isError() && !blob->isWaiting())
blob->allDependenciesDone();
- if (blob->status() != QDeclarativeDataBlob::Error)
+ if (blob->status() != QDeclarativeDataBlob::Error)
blob->m_status = QDeclarativeDataBlob::WaitingForDependencies;
blob->m_inCallback = false;
@@ -680,24 +680,23 @@ QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QByteArray &data, const
}
/*!
-Returns a QDeclarativeScriptData for \a url. The QDeclarativeScriptData may be cached.
+Return a QDeclarativeScriptBlob for \a url. The QDeclarativeScriptData may be cached.
*/
-QDeclarativeScriptData *QDeclarativeTypeLoader::getScript(const QUrl &url)
+QDeclarativeScriptBlob *QDeclarativeTypeLoader::getScript(const QUrl &url)
{
Q_ASSERT(!url.isRelative() &&
(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
!QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
- QDeclarativeScriptData *scriptData = m_scriptCache.value(url);
+ QDeclarativeScriptBlob *scriptBlob = m_scriptCache.value(url);
- if (!scriptData) {
- scriptData = new QDeclarativeScriptData(url);
- m_scriptCache.insert(url, scriptData);
- QDeclarativeDataLoader::load(scriptData);
+ if (!scriptBlob) {
+ scriptBlob = new QDeclarativeScriptBlob(url, this);
+ m_scriptCache.insert(url, scriptBlob);
+ QDeclarativeDataLoader::load(scriptBlob);
}
- scriptData->addref();
- return scriptData;
+ return scriptBlob;
}
/*!
@@ -878,13 +877,14 @@ void QDeclarativeTypeData::dataReceived(const QByteArray &data)
}
} else if (import.type == QDeclarativeScriptParser::Import::Script) {
QUrl scriptUrl = finalUrl().resolved(QUrl(import.uri));
- QDeclarativeScriptData *data = typeLoader()->getScript(scriptUrl);
- addDependency(data);
+ QDeclarativeScriptBlob *blob = typeLoader()->getScript(scriptUrl);
+ addDependency(blob);
ScriptReference ref;
ref.location = import.location.start;
ref.qualifier = import.qualifier;
- ref.script = data;
+ ref.script = blob;
+ blob->addref();
m_scripts << ref;
}
@@ -943,14 +943,31 @@ void QDeclarativeTypeData::resolveTypes()
// For local urls, add an implicit import "." as first (most overridden) lookup.
// This will also trigger the loading of the qmldir and the import of any native
// types from available plugins.
+ QList<QDeclarativeError> errors;
if (QDeclarativeQmldirData *qmldir = qmldirForUrl(finalUrl().resolved(QUrl(QLatin1String("./qmldir"))))) {
m_imports.addImport(importDatabase, QLatin1String("."),
QString(), -1, -1, QDeclarativeScriptParser::Import::File,
- qmldir->dirComponents(), 0);
+ qmldir->dirComponents(), &errors);
} else {
m_imports.addImport(importDatabase, QLatin1String("."),
QString(), -1, -1, QDeclarativeScriptParser::Import::File,
- QDeclarativeDirComponents(), 0);
+ QDeclarativeDirComponents(), &errors);
+ }
+
+ // remove any errors which are due to the implicit import which aren't real errors.
+ // for example, if the implicitly included qmldir file doesn't exist, that is not an error.
+ QList<QDeclarativeError> realErrors;
+ for (int i = 0; i < errors.size(); ++i) {
+ if (errors.at(i).description() != QDeclarativeImportDatabase::tr("import \".\" has no qmldir and no namespace")
+ && errors.at(i).description() != QDeclarativeImportDatabase::tr("\".\": no such directory")) {
+ realErrors.prepend(errors.at(i)); // this is a real error.
+ }
+ }
+
+ // report any real errors which occurred during plugin loading or qmldir parsing.
+ if (!realErrors.isEmpty()) {
+ setError(realErrors);
+ return;
}
foreach (const QDeclarativeScriptParser::Import &import, scriptParser.imports()) {
@@ -960,34 +977,31 @@ void QDeclarativeTypeData::resolveTypes()
if (import.type == QDeclarativeScriptParser::Import::File && import.qualifier.isEmpty()) {
QUrl qmldirUrl = finalUrl().resolved(QUrl(import.uri + QLatin1String("/qmldir")));
- if (QDeclarativeQmldirData *qmldir = qmldirForUrl(qmldirUrl))
+ if (QDeclarativeQmldirData *qmldir = qmldirForUrl(qmldirUrl))
qmldircomponentsnetwork = qmldir->dirComponents();
}
int vmaj = -1;
int vmin = -1;
+ import.extractVersion(&vmaj, &vmin);
- if (!import.version.isEmpty()) {
- int dot = import.version.indexOf(QLatin1Char('.'));
- if (dot < 0) {
- vmaj = import.version.toInt();
- vmin = 0;
- } else {
- vmaj = import.version.left(dot).toInt();
- vmin = import.version.mid(dot+1).toInt();
- }
- }
-
- QString errorString;
+ QList<QDeclarativeError> errors;
if (!m_imports.addImport(importDatabase, import.uri, import.qualifier,
- vmaj, vmin, import.type, qmldircomponentsnetwork, &errorString)) {
+ vmaj, vmin, import.type, qmldircomponentsnetwork, &errors)) {
QDeclarativeError error;
+ if (errors.size()) {
+ error = errors.takeFirst();
+ } else {
+ // this should not be possible!
+ // Description should come from error provided by addImport() function.
+ error.setDescription(QDeclarativeTypeLoader::tr("Unreported error adding script import to import database"));
+ }
error.setUrl(m_imports.baseUrl());
- error.setDescription(errorString);
error.setLine(import.location.start.line);
error.setColumn(import.location.start.column);
+ errors.prepend(error); // put it back on the list after filling out information.
- setError(error);
+ setError(errors);
return;
}
}
@@ -1001,29 +1015,38 @@ void QDeclarativeTypeData::resolveTypes()
int majorVersion;
int minorVersion;
QDeclarativeImportedNamespace *typeNamespace = 0;
- QString errorString;
+ QList<QDeclarativeError> errors;
if (!m_imports.resolveType(typeName, &ref.type, &url, &majorVersion, &minorVersion,
- &typeNamespace, &errorString) || typeNamespace) {
+ &typeNamespace, &errors) || typeNamespace) {
// Known to not be a type:
// - known to be a namespace (Namespace {})
// - type with unknown namespace (UnknownNamespace.SomeType {})
QDeclarativeError error;
- error.setUrl(m_imports.baseUrl());
QString userTypeName = parserRef->name;
userTypeName.replace(QLatin1Char('/'),QLatin1Char('.'));
- if (typeNamespace)
+ if (typeNamespace) {
error.setDescription(QDeclarativeTypeLoader::tr("Namespace %1 cannot be used as a type").arg(userTypeName));
- else
- error.setDescription(QDeclarativeTypeLoader::tr("%1 %2").arg(userTypeName).arg(errorString));
+ } else {
+ if (errors.size()) {
+ error = errors.takeFirst();
+ } else {
+ // this should not be possible!
+ // Description should come from error provided by addImport() function.
+ error.setDescription(QDeclarativeTypeLoader::tr("Unreported error adding script import to import database"));
+ }
+ error.setUrl(m_imports.baseUrl());
+ error.setDescription(QDeclarativeTypeLoader::tr("%1 %2").arg(userTypeName).arg(error.description()));
+ }
if (!parserRef->refObjects.isEmpty()) {
QDeclarativeParser::Object *obj = parserRef->refObjects.first();
error.setLine(obj->location.start.line);
error.setColumn(obj->location.start.column);
}
-
- setError(error);
+
+ errors.prepend(error);
+ setError(errors);
return;
}
@@ -1056,25 +1079,156 @@ QDeclarativeQmldirData *QDeclarativeTypeData::qmldirForUrl(const QUrl &url)
return 0;
}
-QDeclarativeScriptData::QDeclarativeScriptData(const QUrl &url)
-: QDeclarativeDataBlob(url, JavaScriptFile), m_pragmas(QDeclarativeParser::Object::ScriptBlock::None)
+QDeclarativeScriptData::QDeclarativeScriptData(QDeclarativeEngine *engine)
+: QDeclarativeCleanup(engine), importCache(0), pragmas(QDeclarativeParser::Object::ScriptBlock::None),
+ m_loaded(false)
+{
+}
+
+QDeclarativeScriptData::~QDeclarativeScriptData()
{
+ clear();
}
-QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptData::pragmas() const
+void QDeclarativeScriptData::clear()
+{
+ if (importCache) {
+ importCache->release();
+ importCache = 0;
+ }
+
+ for (int ii = 0; ii < scripts.count(); ++ii)
+ scripts.at(ii)->release();
+ scripts.clear();
+}
+
+QDeclarativeScriptBlob::QDeclarativeScriptBlob(const QUrl &url, QDeclarativeTypeLoader *loader)
+: QDeclarativeDataBlob(url, JavaScriptFile), m_pragmas(QDeclarativeParser::Object::ScriptBlock::None),
+ m_scriptData(0), m_typeLoader(loader)
+{
+}
+
+QDeclarativeScriptBlob::~QDeclarativeScriptBlob()
+{
+ if (m_scriptData) {
+ m_scriptData->release();
+ m_scriptData = 0;
+ }
+}
+
+QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptBlob::pragmas() const
{
return m_pragmas;
}
-QString QDeclarativeScriptData::scriptSource() const
+QString QDeclarativeScriptBlob::scriptSource() const
{
return m_source;
}
-void QDeclarativeScriptData::dataReceived(const QByteArray &data)
+QDeclarativeTypeLoader *QDeclarativeScriptBlob::typeLoader() const
+{
+ return m_typeLoader;
+}
+
+const QDeclarativeImports &QDeclarativeScriptBlob::imports() const
+{
+ return m_imports;
+}
+
+QDeclarativeScriptData *QDeclarativeScriptBlob::scriptData() const
+{
+ return m_scriptData;
+}
+
+void QDeclarativeScriptBlob::dataReceived(const QByteArray &data)
{
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_typeLoader->engine());
+ QDeclarativeImportDatabase *importDatabase = &ep->importDatabase;
+
m_source = QString::fromUtf8(data);
- m_pragmas = QDeclarativeScriptParser::extractPragmas(m_source);
+
+ QDeclarativeScriptParser::JavaScriptMetaData metadata =
+ QDeclarativeScriptParser::extractMetaData(m_source);
+
+ m_imports.setBaseUrl(finalUrl());
+
+ m_pragmas = metadata.pragmas;
+
+ foreach (const QDeclarativeScriptParser::Import &import, metadata.imports) {
+ Q_ASSERT(import.type != QDeclarativeScriptParser::Import::File);
+
+ if (import.type == QDeclarativeScriptParser::Import::Script) {
+ QUrl scriptUrl = finalUrl().resolved(QUrl(import.uri));
+ QDeclarativeScriptBlob *blob = typeLoader()->getScript(scriptUrl);
+ addDependency(blob);
+
+ ScriptReference ref;
+ ref.location = import.location.start;
+ ref.qualifier = import.qualifier;
+ ref.script = blob;
+ blob->addref();
+ m_scripts << ref;
+ } else {
+ Q_ASSERT(import.type == QDeclarativeScriptParser::Import::Library);
+ int vmaj = -1;
+ int vmin = -1;
+ import.extractVersion(&vmaj, &vmin);
+
+ QList<QDeclarativeError> errors;
+ if (!m_imports.addImport(importDatabase, import.uri, import.qualifier, vmaj, vmin,
+ import.type, QDeclarativeDirComponents(), &errors)) {
+ QDeclarativeError error = errors.takeFirst();
+ // description should be set by addImport().
+ error.setUrl(m_imports.baseUrl());
+ error.setLine(import.location.start.line);
+ error.setColumn(import.location.start.column);
+ errors.prepend(error);
+
+ setError(errors);
+ return;
+ }
+ }
+ }
+}
+
+void QDeclarativeScriptBlob::done()
+{
+ // Check all script dependencies for errors
+ for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) {
+ const ScriptReference &script = m_scripts.at(ii);
+ Q_ASSERT(script.script->isCompleteOrError());
+ if (script.script->isError()) {
+ QList<QDeclarativeError> errors = script.script->errors();
+ QDeclarativeError error;
+ error.setUrl(finalUrl());
+ error.setLine(script.location.line);
+ error.setColumn(script.location.column);
+ error.setDescription(typeLoader()->tr("Script %1 unavailable").arg(script.script->url().toString()));
+ errors.prepend(error);
+ setError(errors);
+ }
+ }
+
+ if (isError())
+ return;
+
+ QDeclarativeEngine *engine = typeLoader()->engine();
+ m_scriptData = new QDeclarativeScriptData(engine);
+ m_scriptData->url = finalUrl();
+ m_scriptData->importCache = new QDeclarativeTypeNameCache(engine);
+
+ for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) {
+ const ScriptReference &script = m_scripts.at(ii);
+
+ m_scriptData->scripts.append(script.script);
+ m_scriptData->importCache->add(script.qualifier, ii);
+ }
+
+ m_imports.populateCache(m_scriptData->importCache, engine);
+
+ m_scriptData->pragmas = m_pragmas;
+ m_scriptData->m_program = QScriptProgram(m_source, finalUrl().toString());
}
QDeclarativeQmldirData::QDeclarativeQmldirData(const QUrl &url)
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
index 56b663689e..05873df4ca 100644
--- a/src/declarative/qml/qdeclarativetypeloader_p.h
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -55,8 +55,11 @@
#include <QtCore/qobject.h>
#include <QtNetwork/qnetworkreply.h>
+#include <QtScript/qscriptvalue.h>
+#include <QtScript/qscriptprogram.h>
#include <QtDeclarative/qdeclarativeerror.h>
#include <QtDeclarative/qdeclarativeengine.h>
+#include <private/qdeclarativecleanup_p.h>
#include <private/qdeclarativescriptparser_p.h>
#include <private/qdeclarativedirparser_p.h>
#include <private/qdeclarativeimport_p.h>
@@ -64,6 +67,7 @@
QT_BEGIN_NAMESPACE
class QDeclarativeScriptData;
+class QDeclarativeScriptBlob;
class QDeclarativeQmldirData;
class QDeclarativeTypeLoader;
class QDeclarativeCompiledData;
@@ -140,7 +144,7 @@ private:
QUrl m_finalUrl;
// List of QDeclarativeDataBlob's that are waiting for me to complete.
- QList<QDeclarativeDataBlob *> m_waitingOnMe;
+ QList<QDeclarativeDataBlob *> m_waitingOnMe;
// List of QDeclarativeDataBlob's that I am waiting for to complete.
QList<QDeclarativeDataBlob *> m_waitingFor;
@@ -178,7 +182,6 @@ private:
NetworkReplies m_networkReplies;
};
-
class Q_AUTOTEST_EXPORT QDeclarativeTypeLoader : public QDeclarativeDataLoader
{
Q_OBJECT
@@ -196,11 +199,11 @@ public:
QDeclarativeTypeData *get(const QByteArray &, const QUrl &url, Options = None);
void clearCache();
- QDeclarativeScriptData *getScript(const QUrl &);
+ QDeclarativeScriptBlob *getScript(const QUrl &);
QDeclarativeQmldirData *getQmldir(const QUrl &);
private:
typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
- typedef QHash<QUrl, QDeclarativeScriptData *> ScriptCache;
+ typedef QHash<QUrl, QDeclarativeScriptBlob *> ScriptCache;
typedef QHash<QUrl, QDeclarativeQmldirData *> QmldirCache;
TypeCache m_typeCache;
@@ -230,7 +233,7 @@ public:
QDeclarativeParser::Location location;
QString qualifier;
- QDeclarativeScriptData *script;
+ QDeclarativeScriptBlob *script;
};
QDeclarativeTypeData(const QUrl &, QDeclarativeTypeLoader::Options, QDeclarativeTypeLoader *);
@@ -285,20 +288,65 @@ private:
QDeclarativeTypeLoader *m_typeLoader;
};
-class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeDataBlob
+class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeRefCount, public QDeclarativeCleanup
{
public:
- QDeclarativeScriptData(const QUrl &);
+ QDeclarativeScriptData(QDeclarativeEngine *);
+ ~QDeclarativeScriptData();
+
+ QUrl url;
+ QDeclarativeTypeNameCache *importCache;
+ QList<QDeclarativeScriptBlob *> scripts;
+ QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas;
+
+protected:
+ virtual void clear(); // From QDeclarativeCleanup
+
+private:
+ friend class QDeclarativeVME;
+ friend class QDeclarativeScriptBlob;
+
+ bool m_loaded;
+ QScriptProgram m_program;
+ QScriptValue m_value;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativeScriptBlob : public QDeclarativeDataBlob
+{
+public:
+ QDeclarativeScriptBlob(const QUrl &, QDeclarativeTypeLoader *);
+ ~QDeclarativeScriptBlob();
+
+ struct ScriptReference
+ {
+ ScriptReference() : script(0) {}
+
+ QDeclarativeParser::Location location;
+ QString qualifier;
+ QDeclarativeScriptBlob *script;
+ };
QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas() const;
QString scriptSource() const;
+ QDeclarativeTypeLoader *typeLoader() const;
+ const QDeclarativeImports &imports() const;
+
+ QDeclarativeScriptData *scriptData() const;
+
protected:
virtual void dataReceived(const QByteArray &);
+ virtual void done();
private:
QDeclarativeParser::Object::ScriptBlock::Pragmas m_pragmas;
QString m_source;
+
+ QDeclarativeImports m_imports;
+ QList<ScriptReference> m_scripts;
+ QDeclarativeScriptData *m_scriptData;
+
+ QDeclarativeTypeLoader *m_typeLoader;
};
class Q_AUTOTEST_EXPORT QDeclarativeQmldirData : public QDeclarativeDataBlob
diff --git a/src/declarative/qml/qdeclarativetypenamecache.cpp b/src/declarative/qml/qdeclarativetypenamecache.cpp
index b171dbab6c..8a1b4bff43 100644
--- a/src/declarative/qml/qdeclarativetypenamecache.cpp
+++ b/src/declarative/qml/qdeclarativetypenamecache.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
QDeclarativeTypeNameCache::QDeclarativeTypeNameCache(QDeclarativeEngine *e)
-: QDeclarativeCleanup(e), engine(e)
+: QDeclarativeCleanup(e), engine(e), m_moduleApi(0)
{
}
@@ -60,6 +60,7 @@ void QDeclarativeTypeNameCache::clear()
qDeleteAll(stringCache);
stringCache.clear();
identifierCache.clear();
+ m_moduleApi = 0;
engine = 0;
}
@@ -114,5 +115,10 @@ QDeclarativeTypeNameCache::Data *QDeclarativeTypeNameCache::data(const QString &
return stringCache.value(id);
}
+void QDeclarativeTypeNameCache::setModuleApi(QDeclarativeMetaType::ModuleApiInstance *api)
+{
+ m_moduleApi = api;
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h
index e8a017428d..497633b993 100644
--- a/src/declarative/qml/qdeclarativetypenamecache_p.h
+++ b/src/declarative/qml/qdeclarativetypenamecache_p.h
@@ -55,6 +55,7 @@
#include "private/qdeclarativerefcount_p.h"
#include "private/qdeclarativecleanup_p.h"
+#include "private/qdeclarativemetatype_p.h"
#include <private/qscriptdeclarativeclass_p.h>
@@ -82,6 +83,10 @@ public:
Data *data(const QString &) const;
inline Data *data(const QScriptDeclarativeClass::Identifier &id) const;
+ inline bool isEmpty() const;
+
+ inline QDeclarativeMetaType::ModuleApiInstance *moduleApi() const;
+ void setModuleApi(QDeclarativeMetaType::ModuleApiInstance *);
protected:
virtual void clear();
@@ -96,6 +101,7 @@ private:
StringCache stringCache;
IdentifierCache identifierCache;
QDeclarativeEngine *engine;
+ QDeclarativeMetaType::ModuleApiInstance *m_moduleApi;
};
QDeclarativeTypeNameCache::Data::Data()
@@ -113,6 +119,16 @@ QDeclarativeTypeNameCache::Data *QDeclarativeTypeNameCache::data(const QScriptDe
return identifierCache.value(id);
}
+bool QDeclarativeTypeNameCache::isEmpty() const
+{
+ return identifierCache.isEmpty();
+}
+
+QDeclarativeMetaType::ModuleApiInstance *QDeclarativeTypeNameCache::moduleApi() const
+{
+ return m_moduleApi;
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVETYPENAMECACHE_P_H
diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
index 1cabff5a28..32fcdb4c08 100644
--- a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
@@ -63,7 +63,7 @@ struct TypeNameData : public QScriptDeclarativeClass::Object {
QDeclarativeTypeNameScriptClass::QDeclarativeTypeNameScriptClass(QDeclarativeEngine *bindEngine)
: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)),
- engine(bindEngine), object(0), type(0)
+ engine(bindEngine), object(0), type(0), api(0)
{
}
@@ -95,14 +95,35 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na
object = 0;
type = 0;
+ api = 0;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
if (data->typeNamespace) {
-
QDeclarativeTypeNameCache::Data *d = data->typeNamespace->data(name);
if (d && d->type) {
type = d->type;
return QScriptClass::HandlesReadAccess;
+ } else if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = data->typeNamespace->moduleApi()) {
+ if (moduleApi->scriptCallback) {
+ moduleApi->scriptApi = moduleApi->scriptCallback(engine, &ep->scriptEngine);
+ moduleApi->scriptCallback = 0;
+ moduleApi->qobjectCallback = 0;
+ } else if (moduleApi->qobjectCallback) {
+ moduleApi->qobjectApi = moduleApi->qobjectCallback(engine, &ep->scriptEngine);
+ moduleApi->scriptCallback = 0;
+ moduleApi->qobjectCallback = 0;
+ }
+
+ api = moduleApi;
+ if (api->qobjectApi) {
+ return ep->objectClass->queryProperty(api->qobjectApi, name, flags, 0,
+ QDeclarativeObjectScriptClass::SkipAttachedProperties);
+ } else {
+ return QScriptClass::HandlesReadAccess;
+ }
+
+ return 0;
+
} else {
return 0;
}
@@ -147,6 +168,10 @@ QDeclarativeTypeNameScriptClass::property(Object *obj, const Identifier &name)
return Value(scriptEngine, newObject(((TypeNameData *)obj)->object, type, ((TypeNameData *)obj)->mode));
} else if (object) {
return ep->objectClass->property(object, name);
+ } else if (api && api->qobjectApi) {
+ return ep->objectClass->property(api->qobjectApi, name);
+ } else if (api) {
+ return propertyValue(api->scriptApi, name);
} else {
return Value(scriptEngine, enumValue);
}
@@ -154,11 +179,16 @@ QDeclarativeTypeNameScriptClass::property(Object *obj, const Identifier &name)
void QDeclarativeTypeNameScriptClass::setProperty(Object *, const Identifier &n, const QScriptValue &v)
{
- Q_ASSERT(object);
Q_ASSERT(!type);
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- ep->objectClass->setProperty(object, n, v, context());
+ if (api) {
+ Q_ASSERT(api->qobjectApi);
+ ep->objectClass->setProperty(api->qobjectApi, n, v, context());
+ } else {
+ Q_ASSERT(object);
+ ep->objectClass->setProperty(object, n, v, context());
+ }
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass_p.h b/src/declarative/qml/qdeclarativetypenamescriptclass_p.h
index 8e8e19c427..9f386ba3a2 100644
--- a/src/declarative/qml/qdeclarativetypenamescriptclass_p.h
+++ b/src/declarative/qml/qdeclarativetypenamescriptclass_p.h
@@ -83,6 +83,7 @@ private:
QDeclarativeEngine *engine;
QObject *object;
QDeclarativeType *type;
+ QDeclarativeMetaType::ModuleApiInstance *api;
quint32 enumValue;
};
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 06aed98594..dd080a85e9 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -57,8 +57,9 @@
#include "private/qdeclarativevmemetaobject_p.h"
#include "private/qdeclarativebinding_p_p.h"
#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecompiledbindings_p.h"
+#include "private/qdeclarativev4bindings_p.h"
#include "private/qdeclarativeglobal_p.h"
+#include "private/qdeclarativeglobalscriptclass_p.h"
#include "qdeclarativescriptstring.h"
#include <QStack>
@@ -71,6 +72,7 @@
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdatetime.h>
+#include <QtScript/qscriptvalue.h>
QT_BEGIN_NAMESPACE
@@ -78,11 +80,11 @@ QDeclarativeVME::QDeclarativeVME()
{
}
-#define VME_EXCEPTION(desc) \
+#define VME_EXCEPTION(desc, line) \
{ \
QDeclarativeError error; \
error.setDescription(desc.trimmed()); \
- error.setLine(instr.line); \
+ error.setLine(line); \
error.setUrl(comp->url); \
vmeErrors << error; \
break; \
@@ -100,14 +102,13 @@ struct ListInstance
};
QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp,
- int start, int count, const QBitField &bindingSkipList)
+ int start, const QBitField &bindingSkipList)
{
QDeclarativeVMEStack<QObject *> stack;
if (start == -1) start = 0;
- if (count == -1) count = comp->bytecode.count();
- return run(stack, ctxt, comp, start, count, bindingSkipList);
+ return run(stack, ctxt, comp, start, bindingSkipList);
}
void QDeclarativeVME::runDeferred(QObject *object)
@@ -119,12 +120,11 @@ void QDeclarativeVME::runDeferred(QObject *object)
QDeclarativeContextData *ctxt = data->context;
QDeclarativeCompiledData *comp = data->deferredComponent;
- int start = data->deferredIdx + 1;
- int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount;
+ int start = data->deferredIdx;
QDeclarativeVMEStack<QObject *> stack;
stack.push(object);
- run(stack, ctxt, comp, start, count, QBitField());
+ run(stack, ctxt, comp, start, QBitField());
}
inline bool fastHasBinding(QObject *o, int index)
@@ -141,24 +141,28 @@ static void removeBindingOnProperty(QObject *o, int index)
if (binding) binding->destroy();
}
+#define QML_BEGIN_INSTR(I) \
+ case QDeclarativeInstruction::I: { \
+ const QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::DataType &instr = QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::data(genericInstr); \
+ instructionStream += QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::Size; \
+ Q_UNUSED(instr);
+
+#define QML_END_INSTR(I) } break;
+
#define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index)
QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
QDeclarativeContextData *ctxt,
QDeclarativeCompiledData *comp,
- int start, int count,
- const QBitField &bindingSkipList)
+ int start, const QBitField &bindingSkipList)
{
Q_ASSERT(comp);
Q_ASSERT(ctxt);
const QList<QDeclarativeCompiledData::TypeReference> &types = comp->types;
const QList<QString> &primitives = comp->primitives;
const QList<QByteArray> &datas = comp->datas;
- const QList<QDeclarativeCompiledData::CustomTypeData> &customTypeData = comp->customTypeData;
- const QList<int> &intData = comp->intData;
- const QList<float> &floatData = comp->floatData;
const QList<QDeclarativePropertyCache *> &propertyCaches = comp->propertyCaches;
- const QList<QDeclarativeParser::Object::ScriptBlock> &scripts = comp->scripts;
+ const QList<QDeclarativeScriptData *> &scripts = comp->scripts;
const QList<QUrl> &urls = comp->urls;
QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> bindValues;
@@ -173,821 +177,725 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor |
QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite;
- for (int ii = start; !isError() && ii < (start + count); ++ii) {
- const QDeclarativeInstruction &instr = comp->bytecode.at(ii);
-
- switch(instr.type) {
- case QDeclarativeInstruction::Init:
- {
- if (instr.init.bindingsSize)
- bindValues = QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding>(instr.init.bindingsSize);
- if (instr.init.parserStatusSize)
- parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.init.parserStatusSize);
- if (instr.init.contextCache != -1)
- ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache));
- if (instr.init.compiledBinding != -1)
- ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt);
+ const char *instructionStream = comp->bytecode.constData() + start;
+
+ bool done = false;
+ while (!isError() && !done) {
+ const QDeclarativeInstruction &genericInstr = *((QDeclarativeInstruction *)instructionStream);
+
+ switch(genericInstr.type()) {
+ QML_BEGIN_INSTR(Init)
+ if (instr.bindingsSize)
+ bindValues = QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding>(instr.bindingsSize);
+ if (instr.parserStatusSize)
+ parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.parserStatusSize);
+ if (instr.contextCache != -1)
+ ctxt->setIdPropertyData(comp->contextCaches.at(instr.contextCache));
+ if (instr.compiledBinding != -1)
+ ctxt->optimizedBindings = new QDeclarativeV4Bindings(datas.at(instr.compiledBinding).constData(), ctxt);
+ QML_END_INSTR(Init)
+
+ QML_BEGIN_INSTR(Done)
+ done = true;
+ QML_END_INSTR(Done)
+
+ QML_BEGIN_INSTR(CreateObject)
+ QBitField bindings;
+ if (instr.bindingBits != -1) {
+ const QByteArray &bits = datas.at(instr.bindingBits);
+ bindings = QBitField((const quint32*)bits.constData(),
+ bits.size() * 8);
}
- break;
-
- case QDeclarativeInstruction::CreateObject:
- {
- QBitField bindings;
- if (instr.create.bindingBits != -1) {
- const QByteArray &bits = datas.at(instr.create.bindingBits);
- bindings = QBitField((const quint32*)bits.constData(),
- bits.size() * 8);
- }
- if (stack.isEmpty())
- bindings = bindings.united(bindingSkipList);
+ if (stack.isEmpty())
+ bindings = bindings.united(bindingSkipList);
- QObject *o =
- types.at(instr.create.type).createInstance(ctxt, bindings, &vmeErrors);
-
- if (!o) {
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(QString::fromLatin1(types.at(instr.create.type).className)));
- }
-
- QDeclarativeData *ddata = QDeclarativeData::get(o);
- Q_ASSERT(ddata);
-
- if (stack.isEmpty()) {
- if (ddata->context) {
- Q_ASSERT(ddata->context != ctxt);
- Q_ASSERT(ddata->outerContext);
- Q_ASSERT(ddata->outerContext != ctxt);
- QDeclarativeContextData *c = ddata->context;
- while (c->linkedContext) c = c->linkedContext;
- c->linkedContext = ctxt;
- } else {
- ctxt->addObject(o);
- }
+ QObject *o =
+ types.at(instr.type).createInstance(ctxt, bindings, &vmeErrors);
- ddata->ownContext = true;
- } else if (!ddata->context) {
- ctxt->addObject(o);
- }
-
- ddata->setImplicitDestructible();
- ddata->outerContext = ctxt;
- ddata->lineNumber = instr.line;
- ddata->columnNumber = instr.create.column;
-
- if (instr.create.data != -1) {
- QDeclarativeCustomParser *customParser =
- types.at(instr.create.type).type->customParser();
- customParser->setCustomData(o, datas.at(instr.create.data));
- }
- if (!stack.isEmpty()) {
- QObject *parent = stack.top();
- if (o->isWidgetType()) {
- QWidget *widget = static_cast<QWidget*>(o);
- if (parent->isWidgetType()) {
- QWidget *parentWidget = static_cast<QWidget*>(parent);
- widget->setParent(parentWidget);
- } else {
- // TODO: parent might be a layout
- }
- } else {
- QDeclarative_setParent_noEvent(o, parent);
- }
- }
- stack.push(o);
+ if (!o) {
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(QString::fromLatin1(types.at(instr.type).className)), instr.line);
}
- break;
-
- case QDeclarativeInstruction::CreateSimpleObject:
- {
- QObject *o = (QObject *)operator new(instr.createSimple.typeSize +
- sizeof(QDeclarativeData));
- ::memset(o, 0, instr.createSimple.typeSize + sizeof(QDeclarativeData));
- instr.createSimple.create(o);
-
- QDeclarativeData *ddata = (QDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize);
- const QDeclarativeCompiledData::TypeReference &ref = types.at(instr.createSimple.type);
- if (!ddata->propertyCache && ref.typePropertyCache) {
- ddata->propertyCache = ref.typePropertyCache;
- ddata->propertyCache->addref();
- }
- ddata->lineNumber = instr.line;
- ddata->columnNumber = instr.createSimple.column;
-
- QObjectPrivate::get(o)->declarativeData = ddata;
- ddata->context = ddata->outerContext = ctxt;
- ddata->nextContextObject = ctxt->contextObjects;
- if (ddata->nextContextObject)
- ddata->nextContextObject->prevContextObject = &ddata->nextContextObject;
- ddata->prevContextObject = &ctxt->contextObjects;
- ctxt->contextObjects = ddata;
-
- QObject *parent = stack.top();
- QDeclarative_setParent_noEvent(o, parent);
-
- stack.push(o);
- }
- break;
-
- case QDeclarativeInstruction::SetId:
- {
- QObject *target = stack.top();
- ctxt->setIdProperty(instr.setId.index, target);
- }
- break;
-
-
- case QDeclarativeInstruction::SetDefault:
- {
- ctxt->contextObject = stack.top();
- }
- break;
- case QDeclarativeInstruction::CreateComponent:
- {
- QDeclarativeComponent *qcomp =
- new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count,
- stack.isEmpty() ? 0 : stack.top());
-
- QDeclarativeData *ddata = QDeclarativeData::get(qcomp, true);
- Q_ASSERT(ddata);
-
- ctxt->addObject(qcomp);
-
- if (stack.isEmpty())
- ddata->ownContext = true;
-
- ddata->setImplicitDestructible();
- ddata->outerContext = ctxt;
- ddata->lineNumber = instr.line;
- ddata->columnNumber = instr.create.column;
-
- QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt;
-
- stack.push(qcomp);
- ii += instr.createComponent.count;
- }
- break;
-
- case QDeclarativeInstruction::StoreMetaObject:
- {
- QObject *target = stack.top();
-
- QMetaObject mo;
- const QByteArray &metadata = datas.at(instr.storeMeta.data);
- QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
-
- const QDeclarativeVMEMetaData *data =
- (const QDeclarativeVMEMetaData *)datas.at(instr.storeMeta.aliasData).constData();
-
- (void)new QDeclarativeVMEMetaObject(target, &mo, data, comp);
-
- if (instr.storeMeta.propertyCache != -1) {
- QDeclarativeData *ddata = QDeclarativeData::get(target, true);
- if (ddata->propertyCache) ddata->propertyCache->release();
- ddata->propertyCache = propertyCaches.at(instr.storeMeta.propertyCache);
- ddata->propertyCache->addref();
+ QDeclarativeData *ddata = QDeclarativeData::get(o);
+ Q_ASSERT(ddata);
+
+ if (stack.isEmpty()) {
+ if (ddata->context) {
+ Q_ASSERT(ddata->context != ctxt);
+ Q_ASSERT(ddata->outerContext);
+ Q_ASSERT(ddata->outerContext != ctxt);
+ QDeclarativeContextData *c = ddata->context;
+ while (c->linkedContext) c = c->linkedContext;
+ c->linkedContext = ctxt;
+ } else {
+ ctxt->addObject(o);
}
- }
- break;
-
- case QDeclarativeInstruction::StoreVariant:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeString.propertyIndex);
-
- // XXX - can be more efficient
- QVariant v = QDeclarativeStringConverters::variantFromString(primitives.at(instr.storeString.value));
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeString.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreVariantInteger:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeString.propertyIndex);
-
- QVariant v(instr.storeInteger.value);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeString.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreVariantDouble:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeString.propertyIndex);
-
- QVariant v(instr.storeDouble.value);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeString.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreVariantBool:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeString.propertyIndex);
-
- QVariant v(instr.storeBool.value);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeString.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreString:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeString.propertyIndex);
-
- void *a[] = { (void *)&primitives.at(instr.storeString.value), 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeString.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreUrl:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeUrl.propertyIndex);
-
- void *a[] = { (void *)&urls.at(instr.storeUrl.value), 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeUrl.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreFloat:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeFloat.propertyIndex);
-
- float f = instr.storeFloat.value;
- void *a[] = { &f, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeFloat.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreDouble:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeDouble.propertyIndex);
-
- double d = instr.storeDouble.value;
- void *a[] = { &d, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeDouble.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreBool:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeBool.propertyIndex);
-
- void *a[] = { (void *)&instr.storeBool.value, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeBool.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreInteger:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeInteger.propertyIndex);
-
- void *a[] = { (void *)&instr.storeInteger.value, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeInteger.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreColor:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeColor.propertyIndex);
-
- QColor c = QColor::fromRgba(instr.storeColor.value);
- void *a[] = { &c, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeColor.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreDate:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeDate.propertyIndex);
-
- QDate d = QDate::fromJulianDay(instr.storeDate.value);
- void *a[] = { &d, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeDate.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreTime:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeTime.propertyIndex);
-
- QTime t;
- t.setHMS(intData.at(instr.storeTime.valueIndex),
- intData.at(instr.storeTime.valueIndex+1),
- intData.at(instr.storeTime.valueIndex+2),
- intData.at(instr.storeTime.valueIndex+3));
- void *a[] = { &t, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeTime.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StoreDateTime:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeDateTime.propertyIndex);
-
- QTime t;
- t.setHMS(intData.at(instr.storeDateTime.valueIndex+1),
- intData.at(instr.storeDateTime.valueIndex+2),
- intData.at(instr.storeDateTime.valueIndex+3),
- intData.at(instr.storeDateTime.valueIndex+4));
- QDateTime dt(QDate::fromJulianDay(intData.at(instr.storeDateTime.valueIndex)), t);
- void *a[] = { &dt, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeDateTime.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StorePoint:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex);
-
- QPoint p = QPointF(floatData.at(instr.storeRealPair.valueIndex),
- floatData.at(instr.storeRealPair.valueIndex+1)).toPoint();
- void *a[] = { &p, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeRealPair.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::StorePointF:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex);
-
- QPointF p(floatData.at(instr.storeRealPair.valueIndex),
- floatData.at(instr.storeRealPair.valueIndex+1));
- void *a[] = { &p, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeRealPair.propertyIndex, a);
- }
- break;
- case QDeclarativeInstruction::StoreSize:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex);
-
- QSize p = QSizeF(floatData.at(instr.storeRealPair.valueIndex),
- floatData.at(instr.storeRealPair.valueIndex+1)).toSize();
- void *a[] = { &p, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeRealPair.propertyIndex, a);
+ ddata->ownContext = true;
+ } else if (!ddata->context) {
+ ctxt->addObject(o);
}
- break;
- case QDeclarativeInstruction::StoreSizeF:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeRealPair.propertyIndex);
+ ddata->setImplicitDestructible();
+ ddata->outerContext = ctxt;
+ ddata->lineNumber = instr.line;
+ ddata->columnNumber = instr.column;
- QSizeF s(floatData.at(instr.storeRealPair.valueIndex),
- floatData.at(instr.storeRealPair.valueIndex+1));
- void *a[] = { &s, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeRealPair.propertyIndex, a);
+ if (instr.data != -1) {
+ QDeclarativeCustomParser *customParser =
+ types.at(instr.type).type->customParser();
+ customParser->setCustomData(o, datas.at(instr.data));
}
- break;
-
- case QDeclarativeInstruction::StoreRect:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeRect.propertyIndex);
-
- QRect r = QRectF(floatData.at(instr.storeRect.valueIndex),
- floatData.at(instr.storeRect.valueIndex+1),
- floatData.at(instr.storeRect.valueIndex+2),
- floatData.at(instr.storeRect.valueIndex+3)).toRect();
- void *a[] = { &r, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeRect.propertyIndex, a);
+ if (!stack.isEmpty()) {
+ QObject *parent = stack.top();
+ if (o->isWidgetType()) {
+ QWidget *widget = static_cast<QWidget*>(o);
+ if (parent->isWidgetType()) {
+ QWidget *parentWidget = static_cast<QWidget*>(parent);
+ widget->setParent(parentWidget);
+ } else {
+ // TODO: parent might be a layout
+ }
+ } else {
+ QDeclarative_setParent_noEvent(o, parent);
+ }
}
- break;
-
- case QDeclarativeInstruction::StoreRectF:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeRect.propertyIndex);
-
- QRectF r(floatData.at(instr.storeRect.valueIndex),
- floatData.at(instr.storeRect.valueIndex+1),
- floatData.at(instr.storeRect.valueIndex+2),
- floatData.at(instr.storeRect.valueIndex+3));
- void *a[] = { &r, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeRect.propertyIndex, a);
+ stack.push(o);
+ QML_END_INSTR(CreateObject)
+
+ QML_BEGIN_INSTR(CreateSimpleObject)
+ QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QDeclarativeData));
+ ::memset(o, 0, instr.typeSize + sizeof(QDeclarativeData));
+ instr.create(o);
+
+ QDeclarativeData *ddata = (QDeclarativeData *)(((const char *)o) + instr.typeSize);
+ const QDeclarativeCompiledData::TypeReference &ref = types.at(instr.type);
+ if (!ddata->propertyCache && ref.typePropertyCache) {
+ ddata->propertyCache = ref.typePropertyCache;
+ ddata->propertyCache->addref();
}
- break;
+ ddata->lineNumber = instr.line;
+ ddata->columnNumber = instr.column;
- case QDeclarativeInstruction::StoreVector3D:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeVector3D.propertyIndex);
-
- QVector3D p(floatData.at(instr.storeVector3D.valueIndex),
- floatData.at(instr.storeVector3D.valueIndex+1),
- floatData.at(instr.storeVector3D.valueIndex+2));
- void *a[] = { &p, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeVector3D.propertyIndex, a);
- }
- break;
+ QObjectPrivate::get(o)->declarativeData = ddata;
+ ddata->context = ddata->outerContext = ctxt;
+ ddata->nextContextObject = ctxt->contextObjects;
+ if (ddata->nextContextObject)
+ ddata->nextContextObject->prevContextObject = &ddata->nextContextObject;
+ ddata->prevContextObject = &ctxt->contextObjects;
+ ctxt->contextObjects = ddata;
- case QDeclarativeInstruction::StoreObject:
- {
- QObject *assignObj = stack.pop();
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeObject.propertyIndex);
+ QObject *parent = stack.top();
+ QDeclarative_setParent_noEvent(o, parent);
- void *a[] = { (void *)&assignObj, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeObject.propertyIndex, a);
- }
- break;
+ stack.push(o);
+ QML_END_INSTR(CreateSimpleObject)
+ QML_BEGIN_INSTR(SetId)
+ QObject *target = stack.top();
+ ctxt->setIdProperty(instr.index, target);
+ QML_END_INSTR(SetId)
- case QDeclarativeInstruction::AssignCustomType:
- {
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.assignCustomType.propertyIndex);
-
- QDeclarativeCompiledData::CustomTypeData data = customTypeData.at(instr.assignCustomType.valueIndex);
- const QString &primitive = primitives.at(data.index);
- QDeclarativeMetaType::StringConverter converter =
- QDeclarativeMetaType::customStringConverter(data.type);
- QVariant v = (*converter)(primitive);
-
- QMetaProperty prop =
- target->metaObject()->property(instr.assignCustomType.propertyIndex);
- if (v.isNull() || ((int)prop.type() != data.type && prop.userType() != data.type))
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())));
-
- void *a[] = { (void *)v.data(), 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.assignCustomType.propertyIndex, a);
- }
- break;
+ QML_BEGIN_INSTR(SetDefault)
+ ctxt->contextObject = stack.top();
+ QML_END_INSTR(SetDefault)
- case QDeclarativeInstruction::AssignSignalObject:
- {
- // XXX optimize
+ QML_BEGIN_INSTR(CreateComponent)
+ QDeclarativeComponent *qcomp =
+ new QDeclarativeComponent(ctxt->engine, comp, instructionStream - comp->bytecode.constData(),
+ stack.isEmpty() ? 0 : stack.top());
- QObject *assign = stack.pop();
- QObject *target = stack.top();
- int sigIdx = instr.assignSignalObject.signal;
- const QByteArray &pr = datas.at(sigIdx);
+ QDeclarativeData *ddata = QDeclarativeData::get(qcomp, true);
+ Q_ASSERT(ddata);
- QDeclarativeProperty prop(target, QString::fromUtf8(pr));
- if (prop.type() & QDeclarativeProperty::SignalProperty) {
+ ctxt->addObject(qcomp);
- QMetaMethod method = QDeclarativeMetaType::defaultMethod(assign);
- if (method.signature() == 0)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())));
+ if (stack.isEmpty())
+ ddata->ownContext = true;
- if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature()))
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())));
+ ddata->setImplicitDestructible();
+ ddata->outerContext = ctxt;
+ ddata->lineNumber = instr.line;
+ ddata->columnNumber = instr.column;
- QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex());
+ QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt;
- } else {
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(QString::fromUtf8(pr)));
- }
+ stack.push(qcomp);
+ instructionStream += instr.count;
+ QML_END_INSTR(CreateComponent)
+ QML_BEGIN_INSTR(StoreMetaObject)
+ QObject *target = stack.top();
- }
- break;
+ QMetaObject mo;
+ const QByteArray &metadata = datas.at(instr.data);
+ QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
- case QDeclarativeInstruction::StoreSignal:
- {
- QObject *target = stack.top();
- QObject *context = stack.at(stack.count() - 1 - instr.storeSignal.context);
+ const QDeclarativeVMEMetaData *data =
+ (const QDeclarativeVMEMetaData *)datas.at(instr.aliasData).constData();
- QMetaMethod signal = target->metaObject()->method(instr.storeSignal.signalIndex);
+ (void)new QDeclarativeVMEMetaObject(target, &mo, data, comp);
- QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target);
- QDeclarativeExpression *expr =
- new QDeclarativeExpression(ctxt, context, primitives.at(instr.storeSignal.value));
- expr->setSourceLocation(comp->name, instr.line);
- static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = datas.at(instr.storeSignal.name);
- bs->setExpression(expr);
+ if (instr.propertyCache != -1) {
+ QDeclarativeData *ddata = QDeclarativeData::get(target, true);
+ if (ddata->propertyCache) ddata->propertyCache->release();
+ ddata->propertyCache = propertyCaches.at(instr.propertyCache);
+ ddata->propertyCache->addref();
}
- break;
-
- case QDeclarativeInstruction::StoreImportedScript:
- {
- ctxt->addImportedScript(scripts.at(instr.storeScript.value));
+ QML_END_INSTR(StoreMetaObject)
+
+ QML_BEGIN_INSTR(StoreVariant)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ // XXX - can be more efficient
+ QVariant v = QDeclarativeStringConverters::variantFromString(primitives.at(instr.value));
+ void *a[] = { &v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreVariant)
+
+ QML_BEGIN_INSTR(StoreVariantInteger)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QVariant v(instr.value);
+ void *a[] = { &v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreVariantInteger)
+
+ QML_BEGIN_INSTR(StoreVariantDouble)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QVariant v(instr.value);
+ void *a[] = { &v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreVariantDouble)
+
+ QML_BEGIN_INSTR(StoreVariantBool)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QVariant v(instr.value);
+ void *a[] = { &v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreVariantBool)
+
+ QML_BEGIN_INSTR(StoreString)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ void *a[] = { (void *)&primitives.at(instr.value), 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreString)
+
+ QML_BEGIN_INSTR(StoreByteArray)
+ QObject *target = stack.top();
+ void *a[] = { (void *)&datas.at(instr.value), 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreByteArray)
+
+ QML_BEGIN_INSTR(StoreUrl)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ void *a[] = { (void *)&urls.at(instr.value), 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreUrl)
+
+ QML_BEGIN_INSTR(StoreFloat)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ float f = instr.value;
+ void *a[] = { &f, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreFloat)
+
+ QML_BEGIN_INSTR(StoreDouble)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ double d = instr.value;
+ void *a[] = { &d, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreDouble)
+
+ QML_BEGIN_INSTR(StoreBool)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ void *a[] = { (void *)&instr.value, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreBool)
+
+ QML_BEGIN_INSTR(StoreInteger)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ void *a[] = { (void *)&instr.value, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreInteger)
+
+ QML_BEGIN_INSTR(StoreColor)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QColor c = QColor::fromRgba(instr.value);
+ void *a[] = { &c, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreColor)
+
+ QML_BEGIN_INSTR(StoreDate)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QDate d = QDate::fromJulianDay(instr.value);
+ void *a[] = { &d, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreDate)
+
+ QML_BEGIN_INSTR(StoreTime)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QTime *t = (QTime *)&instr.time;
+ void *a[] = { t, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreTime)
+
+ QML_BEGIN_INSTR(StoreDateTime)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QTime *t = (QTime *)&instr.time;
+ QDateTime dt(QDate::fromJulianDay(instr.date), *t);
+ void *a[] = { &dt, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreDateTime)
+
+ QML_BEGIN_INSTR(StorePoint)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QPoint *p = (QPoint *)&instr.point;
+ void *a[] = { p, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StorePoint)
+
+ QML_BEGIN_INSTR(StorePointF)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QPointF *p = (QPointF *)&instr.point;
+ void *a[] = { p, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StorePointF)
+
+ QML_BEGIN_INSTR(StoreSize)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QSize *s = (QSize *)&instr.size;
+ void *a[] = { s, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreSize)
+
+ QML_BEGIN_INSTR(StoreSizeF)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QSizeF *s = (QSizeF *)&instr.size;
+ void *a[] = { s, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreSizeF)
+
+ QML_BEGIN_INSTR(StoreRect)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QRect *r = (QRect *)&instr.rect;
+ void *a[] = { r, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreRect)
+
+ QML_BEGIN_INSTR(StoreRectF)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QRectF *r = (QRectF *)&instr.rect;
+ void *a[] = { r, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreRectF)
+
+ QML_BEGIN_INSTR(StoreVector3D)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QVector3D *v = (QVector3D *)&instr.vector;
+ void *a[] = { v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreVector3D)
+
+ QML_BEGIN_INSTR(StoreObject)
+ QObject *assignObj = stack.pop();
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ void *a[] = { (void *)&assignObj, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreObject)
+
+ QML_BEGIN_INSTR(AssignCustomType)
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ const QString &primitive = primitives.at(instr.primitive);
+ int type = instr.type;
+ QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
+ QVariant v = (*converter)(primitive);
+
+ QMetaProperty prop =
+ target->metaObject()->property(instr.propertyIndex);
+ if (v.isNull() || ((int)prop.type() != type && prop.userType() != type))
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())), instr.line);
+
+ void *a[] = { (void *)v.data(), 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(AssignCustomType)
+
+ QML_BEGIN_INSTR(AssignSignalObject)
+ // XXX optimize
+
+ QObject *assign = stack.pop();
+ QObject *target = stack.top();
+ int sigIdx = instr.signal;
+ const QByteArray &pr = datas.at(sigIdx);
+
+ QDeclarativeProperty prop(target, QString::fromUtf8(pr));
+ if (prop.type() & QDeclarativeProperty::SignalProperty) {
+
+ QMetaMethod method = QDeclarativeMetaType::defaultMethod(assign);
+ if (method.signature() == 0)
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())), instr.line);
+
+ if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature()))
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())), instr.line);
+
+ QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex());
+
+ } else {
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(QString::fromUtf8(pr)), instr.line);
}
- break;
- case QDeclarativeInstruction::StoreScriptString:
- {
- QObject *target = stack.top();
- QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope);
- QDeclarativeScriptString ss;
- ss.setContext(ctxt->asQDeclarativeContext());
- ss.setScopeObject(scope);
- ss.setScript(primitives.at(instr.storeScriptString.value));
-
- void *a[] = { &ss, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeScriptString.propertyIndex, a);
- }
- break;
-
- case QDeclarativeInstruction::BeginObject:
- {
- QObject *target = stack.top();
- QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.begin.castValue);
- parserStatus.append(status);
- status->d = &parserStatus.values[parserStatus.count - 1];
-
- status->classBegin();
- }
- break;
-
- case QDeclarativeInstruction::StoreBinding:
- case QDeclarativeInstruction::StoreBindingOnAlias:
- {
- QObject *target =
- stack.at(stack.count() - 1 - instr.assignBinding.owner);
- QObject *context =
- stack.at(stack.count() - 1 - instr.assignBinding.context);
- QDeclarativeProperty mp =
- QDeclarativePropertyPrivate::restore(datas.at(instr.assignBinding.property), target, ctxt);
-
- int coreIndex = mp.index();
-
- if ((stack.count() - instr.assignBinding.owner) == 1 && bindingSkipList.testBit(coreIndex))
- break;
-
- QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.assignBinding.value).constData(), comp, context, ctxt, comp->name, instr.line, 0);
- bindValues.append(bind);
- bind->m_mePtr = &bindValues.values[bindValues.count - 1];
- bind->setTarget(mp);
-
- if (instr.type == QDeclarativeInstruction::StoreBindingOnAlias) {
- QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind);
- if (old) { old->destroy(); }
- } else {
- bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
+ QML_END_INSTR(AssignSignalObject)
+
+ QML_BEGIN_INSTR(StoreSignal)
+ QObject *target = stack.top();
+ QObject *context = stack.at(stack.count() - 1 - instr.context);
+
+ QMetaMethod signal = target->metaObject()->method(instr.signalIndex);
+
+ QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target);
+ QDeclarativeExpression *expr =
+ new QDeclarativeExpression(ctxt, context, primitives.at(instr.value));
+ expr->setSourceLocation(comp->name, instr.line);
+ static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = datas.at(instr.name);
+ bs->setExpression(expr);
+ QML_END_INSTR(StoreSignal)
+
+ QML_BEGIN_INSTR(StoreImportedScript)
+ ctxt->importedScripts << run(ctxt, scripts.at(instr.value));
+ QML_END_INSTR(StoreImportedScript)
+
+ QML_BEGIN_INSTR(StoreScriptString)
+ QObject *target = stack.top();
+ QObject *scope = stack.at(stack.count() - 1 - instr.scope);
+ QDeclarativeScriptString ss;
+ ss.setContext(ctxt->asQDeclarativeContext());
+ ss.setScopeObject(scope);
+ ss.setScript(primitives.at(instr.value));
+
+ void *a[] = { &ss, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreScriptString)
+
+ QML_BEGIN_INSTR(BeginObject)
+ QObject *target = stack.top();
+ QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.castValue);
+ parserStatus.append(status);
+ status->d = &parserStatus.values[parserStatus.count - 1];
+
+ status->classBegin();
+ QML_END_INSTR(BeginObject)
+
+ QML_BEGIN_INSTR(StoreBinding)
+ QObject *target =
+ stack.at(stack.count() - 1 - instr.owner);
+ QObject *context =
+ stack.at(stack.count() - 1 - instr.context);
+
+ QDeclarativeProperty mp =
+ QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+
+ int coreIndex = mp.index();
+
+ if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex))
+ break;
+
+ QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.value).constData(), comp, context, ctxt, comp->name, instr.line, 0);
+ bindValues.append(bind);
+ bind->m_mePtr = &bindValues.values[bindValues.count - 1];
+ bind->setTarget(mp);
+
+ bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
+ QML_END_INSTR(StoreBinding)
+
+ QML_BEGIN_INSTR(StoreBindingOnAlias)
+ QObject *target =
+ stack.at(stack.count() - 1 - instr.owner);
+ QObject *context =
+ stack.at(stack.count() - 1 - instr.context);
+
+ QDeclarativeProperty mp =
+ QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+
+ int coreIndex = mp.index();
+
+ if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex))
+ break;
+
+ QDeclarativeBinding *bind = new QDeclarativeBinding((void *)datas.at(instr.value).constData(), comp, context, ctxt, comp->name, instr.line, 0);
+ bindValues.append(bind);
+ bind->m_mePtr = &bindValues.values[bindValues.count - 1];
+ bind->setTarget(mp);
+
+ QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind);
+ if (old) { old->destroy(); }
+ QML_END_INSTR(StoreBindingOnAlias)
+
+ QML_BEGIN_INSTR(StoreCompiledBinding)
+ QObject *target =
+ stack.at(stack.count() - 1 - instr.owner);
+ QObject *scope =
+ stack.at(stack.count() - 1 - instr.context);
+
+ int property = instr.property;
+ if (stack.count() == 1 && bindingSkipList.testBit(property & 0xFFFF))
+ break;
+
+ QDeclarativeAbstractBinding *binding =
+ ctxt->optimizedBindings->configBinding(instr.value, target, scope, property);
+ bindValues.append(binding);
+ binding->m_mePtr = &bindValues.values[bindValues.count - 1];
+ binding->addToObject(target, property);
+ QML_END_INSTR(StoreCompiledBinding)
+
+ QML_BEGIN_INSTR(StoreValueSource)
+ QObject *obj = stack.pop();
+ QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.castValue);
+ QObject *target = stack.at(stack.count() - 1 - instr.owner);
+
+ QDeclarativeProperty prop =
+ QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+ obj->setParent(target);
+ vs->setTarget(prop);
+ QML_END_INSTR(StoreValueSource)
+
+ QML_BEGIN_INSTR(StoreValueInterceptor)
+ QObject *obj = stack.pop();
+ QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.castValue);
+ QObject *target = stack.at(stack.count() - 1 - instr.owner);
+ QDeclarativeProperty prop =
+ QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+ obj->setParent(target);
+ vi->setTarget(prop);
+ QDeclarativeVMEMetaObject *mo = static_cast<QDeclarativeVMEMetaObject *>((QMetaObject*)target->metaObject());
+ mo->registerInterceptor(prop.index(), QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), vi);
+ QML_END_INSTR(StoreValueInterceptor)
+
+ QML_BEGIN_INSTR(StoreObjectQList)
+ QObject *assign = stack.pop();
+
+ const ListInstance &list = qliststack.top();
+ list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, assign);
+ QML_END_INSTR(StoreObjectQList)
+
+ QML_BEGIN_INSTR(AssignObjectList)
+ // This is only used for assigning interfaces
+ QObject *assign = stack.pop();
+ const ListInstance &list = qliststack.top();
+
+ int type = list.type;
+
+ void *ptr = 0;
+
+ const char *iid = QDeclarativeMetaType::interfaceIId(type);
+ if (iid)
+ ptr = assign->qt_metacast(iid);
+ if (!ptr)
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to list"), instr.line);
+
+
+ list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, ptr);
+ QML_END_INSTR(AssignObjectList)
+
+ QML_BEGIN_INSTR(StoreVariantObject)
+ QObject *assign = stack.pop();
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ QVariant v = QVariant::fromValue(assign);
+ void *a[] = { &v, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.propertyIndex, a);
+ QML_END_INSTR(StoreVariantObject)
+
+ QML_BEGIN_INSTR(StoreInterface)
+ QObject *assign = stack.pop();
+ QObject *target = stack.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ int coreIdx = instr.propertyIndex;
+ QMetaProperty prop = target->metaObject()->property(coreIdx);
+ int t = prop.userType();
+ const char *iid = QDeclarativeMetaType::interfaceIId(t);
+ bool ok = false;
+ if (iid) {
+ void *ptr = assign->qt_metacast(iid);
+ if (ptr) {
+ void *a[] = { &ptr, 0, &status, &flags };
+ QMetaObject::metacall(target,
+ QMetaObject::WriteProperty,
+ coreIdx, a);
+ ok = true;
}
- }
- break;
+ }
- case QDeclarativeInstruction::StoreCompiledBinding:
- {
- QObject *target =
- stack.at(stack.count() - 1 - instr.assignBinding.owner);
- QObject *scope =
- stack.at(stack.count() - 1 - instr.assignBinding.context);
-
- int property = instr.assignBinding.property;
- if (stack.count() == 1 && bindingSkipList.testBit(property & 0xFFFF))
- break;
-
- QDeclarativeAbstractBinding *binding =
- ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property);
- bindValues.append(binding);
- binding->m_mePtr = &bindValues.values[bindValues.count - 1];
- binding->addToObject(target, property);
- }
- break;
+ if (!ok)
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to interface property"), instr.line);
+ QML_END_INSTR(StoreInterface)
+
+ QML_BEGIN_INSTR(FetchAttached)
+ QObject *target = stack.top();
- case QDeclarativeInstruction::StoreValueSource:
- {
- QObject *obj = stack.pop();
- QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.assignValueSource.castValue);
- QObject *target = stack.at(stack.count() - 1 - instr.assignValueSource.owner);
+ QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.id, target);
- QDeclarativeProperty prop =
- QDeclarativePropertyPrivate::restore(datas.at(instr.assignValueSource.property), target, ctxt);
- obj->setParent(target);
- vs->setTarget(prop);
- }
- break;
+ if (!qmlObject)
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create attached object"), instr.line);
- case QDeclarativeInstruction::StoreValueInterceptor:
- {
- QObject *obj = stack.pop();
- QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.assignValueInterceptor.castValue);
- QObject *target = stack.at(stack.count() - 1 - instr.assignValueInterceptor.owner);
- QDeclarativeProperty prop =
- QDeclarativePropertyPrivate::restore(datas.at(instr.assignValueInterceptor.property), target, ctxt);
- obj->setParent(target);
- vi->setTarget(prop);
- QDeclarativeVMEMetaObject *mo = static_cast<QDeclarativeVMEMetaObject *>((QMetaObject*)target->metaObject());
- mo->registerInterceptor(prop.index(), QDeclarativePropertyPrivate::valueTypeCoreIndex(prop), vi);
- }
- break;
+ stack.push(qmlObject);
+ QML_END_INSTR(FetchAttached)
- case QDeclarativeInstruction::StoreObjectQList:
- {
- QObject *assign = stack.pop();
+ QML_BEGIN_INSTR(FetchQList)
+ QObject *target = stack.top();
- const ListInstance &list = qliststack.top();
- list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, assign);
- }
- break;
+ qliststack.push(ListInstance(instr.type));
- case QDeclarativeInstruction::AssignObjectList:
- {
- // This is only used for assigning interfaces
- QObject *assign = stack.pop();
- const ListInstance &list = qliststack.top();
+ void *a[1];
+ a[0] = (void *)&(qliststack.top().qListProperty);
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ instr.property, a);
+ QML_END_INSTR(FetchQList)
- int type = list.type;
+ QML_BEGIN_INSTR(FetchObject)
+ QObject *target = stack.top();
- void *ptr = 0;
+ QObject *obj = 0;
+ // NOTE: This assumes a cast to QObject does not alter the
+ // object pointer
+ void *a[1];
+ a[0] = &obj;
+ QMetaObject::metacall(target, QMetaObject::ReadProperty,
+ instr.property, a);
- const char *iid = QDeclarativeMetaType::interfaceIId(type);
- if (iid)
- ptr = assign->qt_metacast(iid);
- if (!ptr)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to list"));
+ if (!obj)
+ VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.property).name())), instr.line);
+ stack.push(obj);
+ QML_END_INSTR(FetchObject)
- list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, ptr);
- }
- break;
+ QML_BEGIN_INSTR(PopQList)
+ qliststack.pop();
+ QML_END_INSTR(PopQList)
- case QDeclarativeInstruction::StoreVariantObject:
- {
- QObject *assign = stack.pop();
+ QML_BEGIN_INSTR(Defer)
+ if (instr.deferCount) {
QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeObject.propertyIndex);
-
- QVariant v = QVariant::fromValue(assign);
- void *a[] = { &v, 0, &status, &flags };
- QMetaObject::metacall(target, QMetaObject::WriteProperty,
- instr.storeObject.propertyIndex, a);
+ QDeclarativeData *data =
+ QDeclarativeData::get(target, true);
+ comp->addref();
+ data->deferredComponent = comp;
+ data->deferredIdx = instructionStream - comp->bytecode.constData();
+ instructionStream += instr.deferCount;
}
- break;
-
- case QDeclarativeInstruction::StoreInterface:
- {
- QObject *assign = stack.pop();
- QObject *target = stack.top();
- CLEAN_PROPERTY(target, instr.storeObject.propertyIndex);
-
- int coreIdx = instr.storeObject.propertyIndex;
- QMetaProperty prop = target->metaObject()->property(coreIdx);
- int t = prop.userType();
- const char *iid = QDeclarativeMetaType::interfaceIId(t);
- bool ok = false;
- if (iid) {
- void *ptr = assign->qt_metacast(iid);
- if (ptr) {
- void *a[] = { &ptr, 0, &status, &flags };
- QMetaObject::metacall(target,
- QMetaObject::WriteProperty,
- coreIdx, a);
- ok = true;
+ QML_END_INSTR(Defer)
+
+ QML_BEGIN_INSTR(PopFetchedObject)
+ stack.pop();
+ QML_END_INSTR(PopFetchedObject)
+
+ QML_BEGIN_INSTR(FetchValueType)
+ QObject *target = stack.top();
+
+ if (instr.bindingSkipList != 0) {
+ // Possibly need to clear bindings
+ QDeclarativeData *targetData = QDeclarativeData::get(target);
+ if (targetData) {
+ QDeclarativeAbstractBinding *binding =
+ QDeclarativePropertyPrivate::binding(target, instr.property, -1);
+
+ if (binding && binding->bindingType() != QDeclarativeAbstractBinding::ValueTypeProxy) {
+ QDeclarativePropertyPrivate::setBinding(target, instr.property, -1, 0);
+ binding->destroy();
+ } else if (binding) {
+ QDeclarativeValueTypeProxyBinding *proxy =
+ static_cast<QDeclarativeValueTypeProxyBinding *>(binding);
+ proxy->removeBindings(instr.bindingSkipList);
}
- }
-
- if (!ok)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to interface property"));
- }
- break;
-
- case QDeclarativeInstruction::FetchAttached:
- {
- QObject *target = stack.top();
-
- QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target);
-
- if (!qmlObject)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create attached object"));
-
- stack.push(qmlObject);
- }
- break;
-
- case QDeclarativeInstruction::FetchQList:
- {
- QObject *target = stack.top();
-
- qliststack.push(ListInstance(instr.fetchQmlList.type));
-
- void *a[1];
- a[0] = (void *)&(qliststack.top().qListProperty);
- QMetaObject::metacall(target, QMetaObject::ReadProperty,
- instr.fetchQmlList.property, a);
- }
- break;
-
- case QDeclarativeInstruction::FetchObject:
- {
- QObject *target = stack.top();
-
- QObject *obj = 0;
- // NOTE: This assumes a cast to QObject does not alter the
- // object pointer
- void *a[1];
- a[0] = &obj;
- QMetaObject::metacall(target, QMetaObject::ReadProperty,
- instr.fetch.property, a);
-
- if (!obj)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.fetch.property).name())));
-
- stack.push(obj);
- }
- break;
-
- case QDeclarativeInstruction::PopQList:
- {
- qliststack.pop();
- }
- break;
-
- case QDeclarativeInstruction::Defer:
- {
- if (instr.defer.deferCount) {
- QObject *target = stack.top();
- QDeclarativeData *data =
- QDeclarativeData::get(target, true);
- comp->addref();
- data->deferredComponent = comp;
- data->deferredIdx = ii;
- ii += instr.defer.deferCount;
}
}
- break;
-
- case QDeclarativeInstruction::PopFetchedObject:
- {
- stack.pop();
- }
- break;
-
- case QDeclarativeInstruction::FetchValueType:
- {
- QObject *target = stack.top();
- if (instr.fetchValue.bindingSkipList != 0) {
- // Possibly need to clear bindings
- QDeclarativeData *targetData = QDeclarativeData::get(target);
- if (targetData) {
- QDeclarativeAbstractBinding *binding =
- QDeclarativePropertyPrivate::binding(target, instr.fetchValue.property, -1);
-
- if (binding && binding->bindingType() != QDeclarativeAbstractBinding::ValueTypeProxy) {
- QDeclarativePropertyPrivate::setBinding(target, instr.fetchValue.property, -1, 0);
- binding->destroy();
- } else if (binding) {
- QDeclarativeValueTypeProxyBinding *proxy =
- static_cast<QDeclarativeValueTypeProxyBinding *>(binding);
- proxy->removeBindings(instr.fetchValue.bindingSkipList);
- }
- }
- }
-
- QDeclarativeValueType *valueHandler = ep->valueTypes[instr.fetchValue.type];
- valueHandler->read(target, instr.fetchValue.property);
- stack.push(valueHandler);
- }
- break;
+ QDeclarativeValueType *valueHandler = ep->valueTypes[instr.type];
+ valueHandler->read(target, instr.property);
+ stack.push(valueHandler);
+ QML_END_INSTR(FetchValueType)
- case QDeclarativeInstruction::PopValueType:
- {
- QDeclarativeValueType *valueHandler =
- static_cast<QDeclarativeValueType *>(stack.pop());
- QObject *target = stack.top();
- valueHandler->write(target, instr.fetchValue.property,
- QDeclarativePropertyPrivate::BypassInterceptor);
- }
- break;
+ QML_BEGIN_INSTR(PopValueType)
+ QDeclarativeValueType *valueHandler =
+ static_cast<QDeclarativeValueType *>(stack.pop());
+ QObject *target = stack.top();
+ valueHandler->write(target, instr.property, QDeclarativePropertyPrivate::BypassInterceptor);
+ QML_END_INSTR(PopValueType)
default:
- qFatal("QDeclarativeCompiledData: Internal error - unknown instruction %d", instr.type);
+ qFatal("QDeclarativeCompiledData: Internal error - unknown instruction %d", genericInstr.type());
break;
}
}
@@ -1050,9 +958,72 @@ QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData
return rv;
} else {
Q_ASSERT(component);
- return QDeclarativeComponentPrivate::begin(ctxt, 0, component, -1, -1, 0, errors, bindings);
+ return QDeclarativeComponentPrivate::begin(ctxt, 0, component, -1, 0, errors, bindings);
}
}
+QScriptValue QDeclarativeVME::run(QDeclarativeContextData *parentCtxt, QDeclarativeScriptData *script)
+{
+ if (script->m_loaded)
+ return script->m_value;
+
+ QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(parentCtxt->engine);
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(parentCtxt->engine);
+
+ bool shared = script->pragmas & QDeclarativeParser::Object::ScriptBlock::Shared;
+
+ // Create the script context if required
+ QDeclarativeContextData *ctxt = 0;
+ if (!shared) {
+ ctxt = new QDeclarativeContextData;
+ ctxt->isInternal = true;
+ ctxt->url = script->url;
+
+ // For backward compatibility, if there are no imports, we need to use the
+ // imports from the parent context. See QTBUG-17518.
+ if (!script->importCache->isEmpty()) {
+ ctxt->imports = script->importCache;
+ } else {
+ ctxt->imports = parentCtxt->imports;
+ }
+
+ if (ctxt->imports) {
+ ctxt->imports->addref();
+ }
+
+ ctxt->setParent(parentCtxt, true);
+
+ for (int ii = 0; ii < script->scripts.count(); ++ii)
+ ctxt->importedScripts << run(ctxt, script->scripts.at(ii)->scriptData());
+ }
+
+ QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
+ if (shared) {
+ scriptContext->pushScope(enginePriv->contextClass->newUrlContext(script->url.toString())); // XXX toString()?
+ } else {
+ scriptContext->pushScope(enginePriv->contextClass->newUrlContext(ctxt, 0, script->url.toString()));
+ }
+
+ scriptContext->pushScope(enginePriv->globalClass->staticGlobalObject());
+ QScriptValue scope = QScriptDeclarativeClass::newStaticScopeObject(scriptEngine);
+ scriptContext->pushScope(scope);
+
+ scriptEngine->evaluate(script->m_program);
+
+ if (scriptEngine->hasUncaughtException()) {
+ QDeclarativeError error;
+ QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
+ enginePriv->warning(error);
+ }
+
+ scriptEngine->popContext();
+
+ if (shared) {
+ script->m_loaded = true;
+ script->m_value = scope;
+ }
+
+ return scope;
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h
index 6b7b93f09e..b255e7fa55 100644
--- a/src/declarative/qml/qdeclarativevme_p.h
+++ b/src/declarative/qml/qdeclarativevme_p.h
@@ -62,7 +62,8 @@
QT_BEGIN_NAMESPACE
class QObject;
-class QDeclarativeInstruction;
+class QScriptValue;
+class QDeclarativeScriptData;
class QDeclarativeCompiledData;
class QDeclarativeCompiledData;
class QDeclarativeContextData;
@@ -101,8 +102,9 @@ public:
QDeclarativeVME();
QObject *run(QDeclarativeContextData *, QDeclarativeCompiledData *,
- int start = -1, int count = -1,
- const QBitField & = QBitField());
+ int start = -1, const QBitField & = QBitField());
+ QScriptValue run(QDeclarativeContextData *, QDeclarativeScriptData *);
+
void runDeferred(QObject *);
bool isError() const;
@@ -111,8 +113,7 @@ public:
private:
QObject *run(QDeclarativeVMEStack<QObject *> &,
QDeclarativeContextData *, QDeclarativeCompiledData *,
- int start, int count,
- const QBitField &);
+ int start, const QBitField &);
QList<QDeclarativeError> vmeErrors;
};
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index f63f264831..78519b2601 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -647,6 +647,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
return -1; // We can't run the method
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
+ ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
QScriptValue function = method(id);
@@ -657,10 +658,19 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
args << ep->scriptValueFromVariant(*(QVariant *)a[ii + 1]);
}
}
+
QScriptValue rv = function.call(ep->objectClass->newQObject(object), args);
+ if (ep->scriptEngine.hasUncaughtException()) {
+ QDeclarativeError error;
+ QDeclarativeExpressionPrivate::exceptionToError(&ep->scriptEngine, error);
+ if (error.isValid()) {
+ ep->warning(error);
+ }
+ }
if (a[0]) *reinterpret_cast<QVariant *>(a[0]) = ep->scriptValueToVariant(rv);
+ ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
return -1;
}
return -1;
diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
index 3bc9100a0e..83b7d170a4 100644
--- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp
+++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
@@ -101,6 +101,8 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(xhrDump, QML_XHR_DUMP);
+namespace {
+
class DocumentImpl;
class NodeImpl
{
@@ -323,6 +325,8 @@ public:
static QScriptValue load(QScriptEngine *engine, const QByteArray &data);
};
+}
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(Node)
@@ -1231,6 +1235,18 @@ void QDeclarativeXMLHttpRequest::downloadProgress(qint64 bytes)
}
}
+static const char *errorToString(QNetworkReply::NetworkError error)
+{
+ int idx = QNetworkReply::staticMetaObject.indexOfEnumerator("NetworkError");
+ if (idx == -1) return "EnumLookupFailed";
+
+ QMetaEnum e = QNetworkReply::staticMetaObject.enumerator(idx);
+
+ const char *name = e.valueToKey(error);
+ if (!name) return "EnumLookupFailed";
+ else return name;
+}
+
void QDeclarativeXMLHttpRequest::error(QNetworkReply::NetworkError error)
{
Q_UNUSED(error)
@@ -1245,6 +1261,11 @@ void QDeclarativeXMLHttpRequest::error(QNetworkReply::NetworkError error)
m_data.clear();
destroyNetwork();
+ if (xhrDump()) {
+ qWarning().nospace() << "XMLHttpRequest: ERROR " << qPrintable(m_url.toString());
+ qWarning().nospace() << " " << error << " " << errorToString(error) << " " << m_statusText;
+ }
+
if (error == QNetworkReply::ContentAccessDenied ||
error == QNetworkReply::ContentOperationNotPermittedError ||
error == QNetworkReply::ContentNotFoundError ||
diff --git a/src/declarative/qml/qintrusivelist.cpp b/src/declarative/qml/qintrusivelist.cpp
new file mode 100644
index 0000000000..6c27af0777
--- /dev/null
+++ b/src/declarative/qml/qintrusivelist.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qintrusivelist_p.h"
+
+/*!
+\class QIntrusiveList
+\brief The QIntrusiveList class is a template class that provides a list of objects using static storage.
+\internal
+
+QIntrusiveList creates a linked list of objects. Adding and removing objects from the
+QIntrusiveList is a constant time operation and is very quick. The list performs no memory
+allocations, but does require the objects being added to the list to contain a QIntrusiveListNode
+instance for the list's use. Even so, for small lists QIntrusiveList uses less memory than Qt's
+other list classes.
+
+As QIntrusiveList uses storage inside the objects in the list, each object can only be in one
+list at a time. Objects are inserted by the insert() method. If the object is already
+in a list (including the one it is being inserted into) it is first removed, and then inserted
+at the head of the list. QIntrusiveList is a last-in-first-out list. That is, following an
+insert() the inserted object becomes the list's first() object.
+
+\code
+struct MyObject {
+ MyObject(int value) : value(value) {}
+
+ int value;
+ QIntrusiveListNode node;
+};
+typedef QIntrusiveList<MyObject, &MyObject::node> MyObjectList;
+
+void foo() {
+ MyObjectList list;
+
+ MyObject m0(0);
+ MyObject m1(1);
+ MyObject m2(2);
+
+ list.insert(&m0);
+ list.insert(&m1);
+ list.insert(&m2);
+
+ // QIntrusiveList is LIFO, so will print: 2... 1... 0...
+ for (MyObjectList::iterator iter = list.begin(); iter != list.end(); ++iter) {
+ qWarning() << iter->value;
+ }
+}
+\endcode
+*/
+
+
+/*!
+\fn QIntrusiveList::QIntrusiveList();
+
+Construct an empty list.
+*/
+
+/*!
+\fn QIntrusiveList::~QIntrusiveList();
+
+Destroy the list. All entries are removed.
+*/
+
+/*!
+\fn void QIntrusiveList::insert(N *object);
+
+Insert \a object into the list. If \a object is a member of this, or another list, it will be
+removed and inserted at the head of this list.
+*/
+
+/*!
+\fn void QIntrusiveList::remove(N *object);
+
+Remove \a object from the list. \a object must not be null.
+*/
+
+/*!
+\fn N *QIntrusiveList::first() const
+
+Returns the first entry in this list, or null if the list is empty.
+*/
+
+/*!
+\fn N *QIntrusiveList::next(N *current)
+
+Returns the next object after \a current, or null if \a current is the last object. \a current cannot be null.
+*/
+
+/*!
+\fn iterator QIntrusiveList::begin()
+
+Returns an STL-style interator pointing to the first item in the list.
+
+\sa end()
+*/
+
+/*!
+\fn iterator QIntrusiveList::end()
+
+Returns an STL-style iterator pointing to the imaginary item after the last item in the list.
+
+\sa begin()
+*/
+
+/*!
+iterator &QInplacelist::iterator::erase()
+
+Remove the current object from the list, and return an iterator to the next element.
+*/
+
+
+/*!
+\fn QIntrusiveListNode::QIntrusiveListNode()
+
+Create a QIntrusiveListNode.
+*/
+
+/*!
+\fn QIntrusiveListNode::~QIntrusiveListNode()
+
+Destroy the QIntrusiveListNode. If the node is in a list, it is removed.
+*/
+
+/*!
+\fn void QIntrusiveListNode::remove()
+
+If in a list, remove this node otherwise do nothing.
+*/
+
+/*!
+\fn bool QIntrusiveListNode::isInList() const
+
+Returns true if this node is in a list, false otherwise.
+*/
+
diff --git a/src/declarative/qml/qintrusivelist_p.h b/src/declarative/qml/qintrusivelist_p.h
new file mode 100644
index 0000000000..459d051d07
--- /dev/null
+++ b/src/declarative/qml/qintrusivelist_p.h
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QINTRUSIVELIST_P_H
+#define QINTRUSIVELIST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIntrusiveListNode;
+template<class N, QIntrusiveListNode N::*member>
+class QIntrusiveList
+{
+public:
+ inline QIntrusiveList();
+ inline ~QIntrusiveList();
+
+ inline void insert(N *n);
+ inline void remove(N *n);
+
+ class iterator {
+ public:
+ inline iterator();
+ inline iterator(N *value);
+
+ inline N *operator*() const;
+ inline N *operator->() const;
+ inline bool operator==(const iterator &other) const;
+ inline bool operator!=(const iterator &other) const;
+ inline iterator &operator++();
+
+ inline iterator &erase();
+
+ private:
+ N *_value;
+ };
+ typedef iterator Iterator;
+
+ inline N *first() const;
+ static inline N *next(N *current);
+
+ inline iterator begin();
+ inline iterator end();
+
+private:
+ static inline N *nodeToN(QIntrusiveListNode *node);
+
+ QIntrusiveListNode *__first;
+};
+
+class QIntrusiveListNode
+{
+public:
+ inline QIntrusiveListNode();
+ inline ~QIntrusiveListNode();
+
+ inline void remove();
+ inline bool isInList() const;
+
+ QIntrusiveListNode *_next;
+ QIntrusiveListNode**_prev;
+};
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::iterator::iterator()
+: _value(0)
+{
+}
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::iterator::iterator(N *value)
+: _value(value)
+{
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::iterator::operator*() const
+{
+ return _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::iterator::operator->() const
+{
+ return _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+bool QIntrusiveList<N, member>::iterator::operator==(const iterator &other) const
+{
+ return other._value == _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+bool QIntrusiveList<N, member>::iterator::operator!=(const iterator &other) const
+{
+ return other._value != _value;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::operator++()
+{
+ _value = QIntrusiveList<N, member>::next(_value);
+ return *this;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::erase()
+{
+ N *old = _value;
+ _value = QIntrusiveList<N, member>::next(_value);
+ (old->*member).remove();
+ return *this;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::QIntrusiveList()
+: __first(0)
+{
+}
+
+template<class N, QIntrusiveListNode N::*member>
+QIntrusiveList<N, member>::~QIntrusiveList()
+{
+ while (__first) __first->remove();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+void QIntrusiveList<N, member>::insert(N *n)
+{
+ QIntrusiveListNode *nnode = &(n->*member);
+ nnode->remove();
+
+ nnode->_next = __first;
+ if (nnode->_next) nnode->_next->_prev = &nnode->_next;
+ __first = nnode;
+ nnode->_prev = &__first;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+void QIntrusiveList<N, member>::remove(N *n)
+{
+ QIntrusiveListNode *nnode = &(n->*member);
+ nnode->remove();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::first() const
+{
+ return __first?nodeToN(__first):0;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::next(N *current)
+{
+ QIntrusiveListNode *nextnode = (current->*member)._next;
+ N *nextstruct = nextnode?nodeToN(nextnode):0;
+ return nextstruct;
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::begin()
+{
+ return __first?iterator(nodeToN(__first)):iterator();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::end()
+{
+ return iterator();
+}
+
+template<class N, QIntrusiveListNode N::*member>
+N *QIntrusiveList<N, member>::nodeToN(QIntrusiveListNode *node)
+{
+ return (N *)((char *)node - ((char *)&(((N *)0)->*member) - (char *)0));
+}
+
+QIntrusiveListNode::QIntrusiveListNode()
+: _next(0), _prev(0)
+{
+}
+
+QIntrusiveListNode::~QIntrusiveListNode()
+{
+ remove();
+}
+
+void QIntrusiveListNode::remove()
+{
+ if (_prev) *_prev = _next;
+ if (_next) _next->_prev = _prev;
+ _prev = 0;
+ _next = 0;
+}
+
+bool QIntrusiveListNode::isInList() const
+{
+ return _prev != 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QINTRUSIVELIST_P_H
diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp
index 4fe49ab559..f5e8369ebc 100644
--- a/src/declarative/qml/qmetaobjectbuilder.cpp
+++ b/src/declarative/qml/qmetaobjectbuilder.cpp
@@ -101,7 +101,7 @@ bool isVariantType(const char* type)
return qvariant_nameToType(type) != 0;
}
-// copied from qmetaobject.cpp
+// copied from qmetaobject_p.h
// do not touch without touching the moc as well
enum PropertyFlags {
Invalid = 0x00000000,
@@ -111,6 +111,8 @@ enum PropertyFlags {
EnumOrFlag = 0x00000008,
StdCppSet = 0x00000100,
// Override = 0x00000200,
+ Constant = 0x00000400,
+ Final = 0x00000800,
Designable = 0x00001000,
ResolveDesignable = 0x00002000,
Scriptable = 0x00004000,
@@ -618,6 +620,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
property.setUser(prototype.isUser());
property.setStdCppSet(prototype.hasStdCppSet());
property.setEnumOrFlag(prototype.isEnumType());
+ property.setConstant(prototype.isConstant());
+ property.setFinal(prototype.isFinal());
if (prototype.hasNotifySignal()) {
// Find an existing method for the notify signal, or add a new one.
QMetaMethod method = prototype.notifySignal();
@@ -2280,6 +2284,32 @@ bool QMetaPropertyBuilder::isEnumOrFlag() const
}
/*!
+ Returns true if the property is constant; otherwise returns false.
+ The default value is false.
+*/
+bool QMetaPropertyBuilder::isConstant() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Constant);
+ else
+ return false;
+}
+
+/*!
+ Returns true if the property is final; otherwise returns false.
+ The default value is false.
+*/
+bool QMetaPropertyBuilder::isFinal() const
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ return d->flag(Final);
+ else
+ return false;
+}
+
+/*!
Sets this property to readable if \a value is true.
\sa isReadable(), setWritable()
@@ -2403,6 +2433,31 @@ void QMetaPropertyBuilder::setEnumOrFlag(bool value)
}
/*!
+ Sets the \c CONSTANT flag on this property to \a value.
+
+ \sa isConstant()
+*/
+void QMetaPropertyBuilder::setConstant(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Constant, value);
+}
+
+/*!
+ Sets the \c FINAL flag on this property to \a value.
+
+ \sa isFinal()
+*/
+void QMetaPropertyBuilder::setFinal(bool value)
+{
+ QMetaPropertyBuilderPrivate *d = d_func();
+ if (d)
+ d->setFlag(Final, value);
+}
+
+
+/*!
\class QMetaEnumBuilder
\internal
\brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
diff --git a/src/declarative/qml/qmetaobjectbuilder_p.h b/src/declarative/qml/qmetaobjectbuilder_p.h
index f06a6633c9..a80ba904b6 100644
--- a/src/declarative/qml/qmetaobjectbuilder_p.h
+++ b/src/declarative/qml/qmetaobjectbuilder_p.h
@@ -258,6 +258,8 @@ public:
bool isUser() const;
bool hasStdCppSet() const;
bool isEnumOrFlag() const;
+ bool isConstant() const;
+ bool isFinal() const;
void setReadable(bool value);
void setWritable(bool value);
@@ -269,6 +271,8 @@ public:
void setUser(bool value);
void setStdCppSet(bool value);
void setEnumOrFlag(bool value);
+ void setConstant(bool value);
+ void setFinal(bool value);
private:
const QMetaObjectBuilder *_mobj;
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index bf9e54a986..62c1f97d60 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -18,7 +18,6 @@ SOURCES += \
$$PWD/qdeclarativecompiler.cpp \
$$PWD/qdeclarativecompileddata.cpp \
$$PWD/qdeclarativeboundsignal.cpp \
- $$PWD/qdeclarativedom.cpp \
$$PWD/qdeclarativerefcount.cpp \
$$PWD/qdeclarativemetatype.cpp \
$$PWD/qdeclarativestringconverters.cpp \
@@ -30,7 +29,6 @@ SOURCES += \
$$PWD/qdeclarativeenginedebug.cpp \
$$PWD/qdeclarativerewrite.cpp \
$$PWD/qdeclarativevaluetype.cpp \
- $$PWD/qdeclarativecompiledbindings.cpp \
$$PWD/qdeclarativefastproperties.cpp \
$$PWD/qdeclarativexmlhttprequest.cpp \
$$PWD/qdeclarativesqldatabase.cpp \
@@ -44,6 +42,7 @@ SOURCES += \
$$PWD/qdeclarativetypenamecache.cpp \
$$PWD/qdeclarativescriptstring.cpp \
$$PWD/qdeclarativeobjectscriptclass.cpp \
+ $$PWD/qdeclarativescarceresourcescriptclass.cpp \
$$PWD/qdeclarativecontextscriptclass.cpp \
$$PWD/qdeclarativeglobalscriptclass.cpp \
$$PWD/qdeclarativevaluetypescriptclass.cpp \
@@ -56,7 +55,8 @@ SOURCES += \
$$PWD/qdeclarativeextensionplugin.cpp \
$$PWD/qdeclarativeimport.cpp \
$$PWD/qdeclarativelist.cpp \
- $$PWD/qperformancetimer.cpp
+ $$PWD/qperformancetimer.cpp \
+ $$PWD/qintrusivelist.cpp \
HEADERS += \
$$PWD/qdeclarativeparser_p.h \
@@ -81,8 +81,6 @@ HEADERS += \
$$PWD/qdeclarativeengine_p.h \
$$PWD/qdeclarativeexpression_p.h \
$$PWD/qdeclarativeprivate.h \
- $$PWD/qdeclarativedom_p.h \
- $$PWD/qdeclarativedom_p_p.h \
$$PWD/qdeclarativerefcount_p.h \
$$PWD/qdeclarativemetatype_p.h \
$$PWD/qdeclarativeengine.h \
@@ -104,7 +102,6 @@ HEADERS += \
$$PWD/qpodvector_p.h \
$$PWD/qbitfield_p.h \
$$PWD/qdeclarativevaluetype_p.h \
- $$PWD/qdeclarativecompiledbindings_p.h \
$$PWD/qdeclarativefastproperties_p.h \
$$PWD/qdeclarativexmlhttprequest_p.h \
$$PWD/qdeclarativesqldatabase_p.h \
@@ -118,6 +115,7 @@ HEADERS += \
$$PWD/qdeclarativetypenamecache_p.h \
$$PWD/qdeclarativescriptstring.h \
$$PWD/qdeclarativeobjectscriptclass_p.h \
+ $$PWD/qdeclarativescarceresourcescriptclass_p.h \
$$PWD/qdeclarativecontextscriptclass_p.h \
$$PWD/qdeclarativeglobalscriptclass_p.h \
$$PWD/qdeclarativevaluetypescriptclass_p.h \
@@ -131,11 +129,13 @@ HEADERS += \
$$PWD/qdeclarativeextensioninterface.h \
$$PWD/qdeclarativeimport_p.h \
$$PWD/qdeclarativeextensionplugin.h \
- $$PWD/qperformancetimer_p.h
+ $$PWD/qperformancetimer_p.h \
+ $$PWD/qintrusivelist_p.h \
QT += sql
include(parser/parser.pri)
include(rewriter/rewriter.pri)
+include(v4/v4.pri)
# mirrors logic in corelib/kernel/kernel.pri
unix:!symbian: contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri)
diff --git a/src/declarative/qml/v4/qdeclarativev4bindings.cpp b/src/declarative/qml/v4/qdeclarativev4bindings.cpp
new file mode 100644
index 0000000000..5ef293de89
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4bindings.cpp
@@ -0,0 +1,1530 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// #define REGISTER_CLEANUP_DEBUG
+
+#include "private/qdeclarativev4bindings_p.h"
+#include "private/qdeclarativev4program_p.h"
+#include "private/qdeclarativev4compiler_p.h"
+
+#include <private/qdeclarativefastproperties_p.h>
+#include <private/qdeclarativedebugtrace_p.h>
+#include <private/qdeclarativeanchors_p_p.h> // For AnchorLine
+#include <private/qsganchors_p_p.h> // For AnchorLine
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qmath.h>
+#include <math.h> // ::fmod
+
+QT_BEGIN_NAMESPACE
+
+using namespace QDeclarativeJS;
+
+namespace {
+struct Register {
+ typedef QDeclarativeRegisterType Type;
+
+ void setUndefined() { dataType = UndefinedType; }
+ void setNaN() { setqreal(qSNaN()); }
+ bool isUndefined() const { return dataType == UndefinedType; }
+
+ void setQObject(QObject *o) { *((QObject **)data) = o; dataType = QObjectStarType; }
+ QObject *getQObject() const { return *((QObject **)data); }
+
+ void setqreal(qreal v) { *((qreal *)data) = v; dataType = QRealType; }
+ qreal getqreal() const { return *((qreal *)data); }
+ qreal &getqrealref() const { return *((qreal *)data); }
+
+ void setint(int v) { *((int *)data) = v; dataType = IntType; }
+ int getint() const { return *((int *)data); }
+ int &getintref() const { return *((int *)data); }
+
+ void setbool(bool v) { *((bool *)data) = v; dataType = BoolType; }
+ bool getbool() const { return *((bool *)data); }
+ bool &getboolref() const { return *((bool *)data); }
+
+ QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
+ QString *getstringptr() { return (QString *)typeDataPtr(); }
+ QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
+ const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
+ const QString *getstringptr() const { return (QString *)typeDataPtr(); }
+ const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
+
+ void *typeDataPtr() { return (void *)&data; }
+ void *typeMemory() { return (void *)data; }
+ const void *typeDataPtr() const { return (void *)&data; }
+ const void *typeMemory() const { return (void *)data; }
+
+ Type gettype() const { return dataType; }
+ void settype(Type t) { dataType = t; }
+
+ // int type; // Optional type
+
+ Type dataType; // Type of data
+ void *data[2]; // Object stored here
+
+ inline void cleanup();
+ inline void cleanupString();
+ inline void cleanupUrl();
+ inline void cleanupVariant();
+
+ inline void copy(const Register &other);
+ inline void init(Type type);
+#ifdef REGISTER_CLEANUP_DEBUG
+ Register() {
+ type = 0;
+ }
+
+ ~Register() {
+ if (dataType >= FirstCleanupType)
+ qWarning("Register leaked of type %d", dataType);
+ }
+#endif
+};
+
+void Register::cleanup()
+{
+ if (dataType >= FirstCleanupType) {
+ if (dataType == QStringType) {
+ getstringptr()->~QString();
+ } else if (dataType == QUrlType) {
+ geturlptr()->~QUrl();
+ } else if (dataType == QVariantType) {
+ getvariantptr()->~QVariant();
+ }
+ }
+ setUndefined();
+}
+
+void Register::cleanupString()
+{
+ getstringptr()->~QString();
+ setUndefined();
+}
+
+void Register::cleanupUrl()
+{
+ geturlptr()->~QUrl();
+ setUndefined();
+}
+
+void Register::cleanupVariant()
+{
+ getvariantptr()->~QVariant();
+ setUndefined();
+}
+
+void Register::copy(const Register &other)
+{
+ *this = other;
+ if (other.dataType >= FirstCleanupType) {
+ if (other.dataType == QStringType)
+ new (getstringptr()) QString(*other.getstringptr());
+ else if (other.dataType == QUrlType)
+ new (geturlptr()) QUrl(*other.geturlptr());
+ else if (other.dataType == QVariantType)
+ new (getvariantptr()) QVariant(*other.getvariantptr());
+ }
+}
+
+void Register::init(Type type)
+{
+ dataType = type;
+ if (dataType >= FirstCleanupType) {
+ if (dataType == QStringType)
+ new (getstringptr()) QString();
+ else if (dataType == QUrlType)
+ new (geturlptr()) QUrl();
+ else if (dataType == QVariantType)
+ new (getvariantptr()) QVariant();
+ }
+}
+
+} // end of anonymous namespace
+
+class QDeclarativeV4BindingsPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeV4Bindings)
+
+public:
+ QDeclarativeV4BindingsPrivate();
+ virtual ~QDeclarativeV4BindingsPrivate();
+
+ struct Binding : public QDeclarativeAbstractBinding, public QDeclarativeDelayedError {
+ Binding() : enabled(false), updating(0), property(0),
+ scope(0), target(0), executedBlocks(0), parent(0) {}
+
+ // Inherited from QDeclarativeAbstractBinding
+ virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void destroy();
+
+ int index:30;
+ bool enabled:1;
+ bool updating:1;
+ int property;
+ QObject *scope;
+ QObject *target;
+ quint32 executedBlocks;
+
+ QDeclarativeV4BindingsPrivate *parent;
+ };
+
+ typedef QDeclarativeNotifierEndpoint Subscription;
+ Subscription *subscriptions;
+ QScriptDeclarativeClass::PersistentIdentifier *identifiers;
+
+ void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
+
+ QDeclarativeV4Program *program;
+ Binding *bindings;
+
+ static int methodCount;
+
+ void init();
+ void run(int instr, quint32 &executedBlocks, QDeclarativeContextData *context,
+ QDeclarativeDelayedError *error, QObject *scope, QObject *output,
+ QDeclarativePropertyPrivate::WriteFlags storeFlags
+#ifdef QML_THREADED_INTERPRETER
+ , void ***decode_instr = 0
+#endif
+ );
+
+
+ inline void unsubscribe(int subIndex);
+ inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex);
+ inline void subscribe(QObject *o, int notifyIndex, int subIndex);
+
+ inline static qint32 toInt32(qsreal n);
+ static const qsreal D32;
+ static quint32 toUint32(qsreal n);
+};
+
+QDeclarativeV4BindingsPrivate::QDeclarativeV4BindingsPrivate()
+: subscriptions(0), identifiers(0), program(0), bindings(0)
+{
+}
+
+QDeclarativeV4BindingsPrivate::~QDeclarativeV4BindingsPrivate()
+{
+ delete [] subscriptions; subscriptions = 0;
+ delete [] identifiers; identifiers = 0;
+}
+
+int QDeclarativeV4BindingsPrivate::methodCount = -1;
+
+QDeclarativeV4Bindings::QDeclarativeV4Bindings(const char *program, QDeclarativeContextData *context)
+: QObject(*(new QDeclarativeV4BindingsPrivate))
+{
+ Q_D(QDeclarativeV4Bindings);
+
+ if (d->methodCount == -1)
+ d->methodCount = QDeclarativeV4Bindings::staticMetaObject.methodCount();
+
+ d->program = (QDeclarativeV4Program *)program;
+
+ if (program) {
+ d->init();
+
+ QDeclarativeAbstractExpression::setContext(context);
+ }
+}
+
+QDeclarativeV4Bindings::~QDeclarativeV4Bindings()
+{
+ Q_D(QDeclarativeV4Bindings);
+
+ delete [] d->bindings;
+}
+
+QDeclarativeAbstractBinding *QDeclarativeV4Bindings::configBinding(int index, QObject *target,
+ QObject *scope, int property)
+{
+ Q_D(QDeclarativeV4Bindings);
+
+ QDeclarativeV4BindingsPrivate::Binding *rv = d->bindings + index;
+
+ rv->index = index;
+ rv->property = property;
+ rv->target = target;
+ rv->scope = scope;
+ rv->parent = d;
+
+ addref(); // This is decremented in Binding::destroy()
+
+ return rv;
+}
+
+void QDeclarativeV4BindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ if (enabled != e) {
+ enabled = e;
+
+ if (e) update(flags);
+ }
+}
+
+void QDeclarativeV4BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
+ parent->run(this, flags);
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
+}
+
+void QDeclarativeV4BindingsPrivate::Binding::destroy()
+{
+ enabled = false;
+ removeFromObject();
+ clear();
+ parent->q_func()->release();
+}
+
+int QDeclarativeV4Bindings::qt_metacall(QMetaObject::Call c, int id, void **)
+{
+ Q_D(QDeclarativeV4Bindings);
+
+ if (c == QMetaObject::InvokeMetaMethod && id >= d->methodCount) {
+ id -= d->methodCount;
+
+ QDeclarativeV4Program::BindingReferenceList *list = d->program->signalTable(id);
+
+ for (quint32 ii = 0; ii < list->count; ++ii) {
+ QDeclarativeV4Program::BindingReference *bindingRef = list->bindings + ii;
+
+ QDeclarativeV4BindingsPrivate::Binding *binding = d->bindings + bindingRef->binding;
+ if (binding->executedBlocks & bindingRef->blockMask)
+ d->run(binding, QDeclarativePropertyPrivate::DontRemoveBinding);
+ }
+ }
+ return -1;
+}
+
+void QDeclarativeV4BindingsPrivate::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ Q_Q(QDeclarativeV4Bindings);
+
+ if (!binding->enabled)
+ return;
+
+ QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context();
+ if (!context || !context->isValid())
+ return;
+
+ if (binding->updating) {
+ QString name;
+ if (binding->property & 0xFFFF0000) {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
+
+ QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
+ Q_ASSERT(vt);
+
+ name = QLatin1String(binding->target->metaObject()->property(binding->property & 0xFFFF).name());
+ name.append(QLatin1String("."));
+ name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name()));
+ } else {
+ name = QLatin1String(binding->target->metaObject()->property(binding->property).name());
+ }
+ qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeV4Bindings", "Binding loop detected for property \"%1\"").arg(name);
+ return;
+ }
+
+ binding->updating = true;
+ if (binding->property & 0xFFFF0000) {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
+
+ QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
+ Q_ASSERT(vt);
+ vt->read(binding->target, binding->property & 0xFFFF);
+
+ QObject *target = vt;
+ run(binding->index, binding->executedBlocks, context, binding, binding->scope, target, flags);
+
+ vt->write(binding->target, binding->property & 0xFFFF, flags);
+ } else {
+ run(binding->index, binding->executedBlocks, context, binding, binding->scope, binding->target, flags);
+ }
+ binding->updating = false;
+}
+
+
+void QDeclarativeV4BindingsPrivate::unsubscribe(int subIndex)
+{
+ QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
+ sub->disconnect();
+}
+
+void QDeclarativeV4BindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
+{
+ Q_Q(QDeclarativeV4Bindings);
+
+ unsubscribe(subIndex);
+
+ if (p->idValues[idIndex]) {
+ QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
+ sub->target = q;
+ sub->targetMethod = methodCount + subIndex;
+ sub->connect(&p->idValues[idIndex].bindings);
+ }
+}
+
+void QDeclarativeV4BindingsPrivate::subscribe(QObject *o, int notifyIndex, int subIndex)
+{
+ Q_Q(QDeclarativeV4Bindings);
+
+ QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
+ sub->target = q;
+ sub->targetMethod = methodCount + subIndex;
+ if (o)
+ sub->connect(o, notifyIndex);
+ else
+ sub->disconnect();
+}
+
+// Conversion functions - these MUST match the QtScript expression path
+inline static qreal toReal(Register *reg, int type, bool *ok = 0)
+{
+ if (ok) *ok = true;
+
+ if (type == QMetaType::QReal) {
+ return reg->getqreal();
+ } else if (type == qMetaTypeId<QVariant>()) {
+ return reg->getvariantptr()->toReal();
+ } else {
+ if (ok) *ok = false;
+ return 0;
+ }
+}
+
+inline static QString toString(Register *reg, int type, bool *ok = 0)
+{
+ if (ok) *ok = true;
+
+ if (type == QMetaType::QReal) {
+ return QString::number(reg->getqreal());
+ } else if (type == QMetaType::Int) {
+ return QString::number(reg->getint());
+ } else if (type == qMetaTypeId<QVariant>()) {
+ return reg->getvariantptr()->toString();
+ } else if (type == QMetaType::QString) {
+ return *reg->getstringptr();
+ } else {
+ if (ok) *ok = false;
+ return QString();
+ }
+}
+
+inline static bool toBool(Register *reg, int type, bool *ok = 0)
+{
+ if (ok) *ok = true;
+
+ if (type == QMetaType::Bool) {
+ return reg->getbool();
+ } else if (type == qMetaTypeId<QVariant>()) {
+ return reg->getvariantptr()->toBool();
+ } else {
+ if (ok) *ok = false;
+ return false;
+ }
+}
+
+inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok = 0)
+{
+ if (ok) *ok = true;
+
+ QUrl base;
+ if (type == qMetaTypeId<QVariant>()) {
+ QVariant *var = reg->getvariantptr();
+ int vt = var->type();
+ if (vt == QVariant::Url) {
+ base = var->toUrl();
+ } else if (vt == QVariant::ByteArray) {
+ base = QUrl(QString::fromUtf8(var->toByteArray()));
+ } else if (vt == QVariant::String) {
+ base = QUrl(var->toString());
+ } else {
+ if (ok) *ok = false;
+ return QUrl();
+ }
+ } else if (type == QMetaType::QString) {
+ base = QUrl(*reg->getstringptr());
+ } else {
+ if (ok) *ok = false;
+ return QUrl();
+ }
+
+ if (!base.isEmpty() && base.isRelative())
+ return context->url.resolved(base);
+ else
+ return base;
+}
+
+static QObject *variantToQObject(const QVariant &value, bool *ok)
+{
+ if (ok) *ok = true;
+
+ if (value.userType() == QMetaType::QObjectStar) {
+ return qvariant_cast<QObject*>(value);
+ } else {
+ if (ok) *ok = false;
+ return 0;
+ }
+}
+
+void QDeclarativeV4BindingsPrivate::init()
+{
+ if (program->subscriptions)
+ subscriptions = new QDeclarativeV4BindingsPrivate::Subscription[program->subscriptions];
+ if (program->identifiers)
+ identifiers = new QScriptDeclarativeClass::PersistentIdentifier[program->identifiers];
+
+ bindings = new QDeclarativeV4BindingsPrivate::Binding[program->bindings];
+}
+
+static bool testCompareVariants(const QVariant &qtscriptRaw, const QVariant &v4)
+{
+ QVariant qtscript = qtscriptRaw;
+
+ if (qtscript.userType() == v4.userType()) {
+ } else if (qtscript.canConvert((QVariant::Type)v4.userType())) {
+ qtscript.convert((QVariant::Type)v4.userType());
+ } else if (qtscript.userType() == QVariant::Invalid && v4.userType() == QMetaType::QObjectStar) {
+ qtscript = qVariantFromValue<QObject *>(0);
+ } else {
+ return false;
+ }
+
+ int type = qtscript.userType();
+
+ if (type == qMetaTypeId<QDeclarativeAnchorLine>()) {
+ QDeclarativeAnchorLine la = qvariant_cast<QDeclarativeAnchorLine>(qtscript);
+ QDeclarativeAnchorLine ra = qvariant_cast<QDeclarativeAnchorLine>(v4);
+
+ return la == ra;
+ } else if (type == qMetaTypeId<QSGAnchorLine>()) {
+ QSGAnchorLine la = qvariant_cast<QSGAnchorLine>(qtscript);
+ QSGAnchorLine ra = qvariant_cast<QSGAnchorLine>(v4);
+
+ return la == ra;
+ } else if (type == QMetaType::Double) {
+
+ double la = qvariant_cast<double>(qtscript);
+ double lr = qvariant_cast<double>(v4);
+
+ return la == lr || (qIsNaN(la) && qIsNaN(lr));
+
+ } else if (type == QMetaType::Float) {
+
+ float la = qvariant_cast<float>(qtscript);
+ float lr = qvariant_cast<float>(v4);
+
+ return la == lr || (qIsNaN(la) && qIsNaN(lr));
+
+ } else {
+ return qtscript == v4;
+ }
+}
+
+QByteArray testResultToString(const QVariant &result, bool undefined)
+{
+ if (undefined) {
+ return "undefined";
+ } else {
+ QString rv;
+ QDebug d(&rv);
+ d << result;
+ return rv.toUtf8();
+ }
+}
+
+static void testBindingResult(const QString &binding, int line, int column,
+ QDeclarativeContextData *context, QObject *scope,
+ const Register &result, int resultType)
+{
+ QDeclarativeExpression expression(context->asQDeclarativeContext(), scope, binding);
+ bool isUndefined = false;
+ QVariant value = expression.evaluate(&isUndefined);
+
+ bool iserror = false;
+ QByteArray qtscriptResult;
+ QByteArray v4Result;
+
+ if (expression.hasError()) {
+ iserror = true;
+ qtscriptResult = "exception";
+ } else {
+ qtscriptResult = testResultToString(value, isUndefined);
+ }
+
+ if (isUndefined && result.isUndefined()) {
+ return;
+ } else if(isUndefined != result.isUndefined()) {
+ iserror = true;
+ }
+
+ QVariant v4value;
+ if (!result.isUndefined()) {
+ switch (resultType) {
+ case QMetaType::QString:
+ v4value = *result.getstringptr();
+ break;
+ case QMetaType::QUrl:
+ v4value = *result.geturlptr();
+ break;
+ case QMetaType::QObjectStar:
+ v4value = qVariantFromValue<QObject *>(result.getQObject());
+ break;
+ case QMetaType::Bool:
+ v4value = result.getbool();
+ break;
+ case QMetaType::Int:
+ v4value = result.getint();
+ break;
+ case QMetaType::QReal:
+ v4value = result.getqreal();
+ break;
+ default:
+ if (resultType == qMetaTypeId<QDeclarativeAnchorLine>()) {
+ v4value = qVariantFromValue<QDeclarativeAnchorLine>(*(QDeclarativeAnchorLine *)result.typeDataPtr());
+ } else if (resultType == qMetaTypeId<QSGAnchorLine>()) {
+ v4value = qVariantFromValue<QSGAnchorLine>(*(QSGAnchorLine *)result.typeDataPtr());
+ } else {
+ iserror = true;
+ v4Result = "Unknown V4 type";
+ }
+ }
+ }
+ if (v4Result.isEmpty())
+ v4Result = testResultToString(v4value, result.isUndefined());
+
+ if (!testCompareVariants(value, v4value))
+ iserror = true;
+
+ if (iserror) {
+ qWarning().nospace() << "QDeclarativeV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column;
+
+ qWarning().nospace() << " Binding: " << binding;
+ qWarning().nospace() << " QtScript: " << qtscriptResult.constData();
+ qWarning().nospace() << " V4: " << v4Result.constData();
+ }
+}
+
+static void testBindingException(const QString &binding, int line, int column,
+ QDeclarativeContextData *context, QObject *scope)
+{
+ QDeclarativeExpression expression(context->asQDeclarativeContext(), scope, binding);
+ bool isUndefined = false;
+ QVariant value = expression.evaluate(&isUndefined);
+
+ if (!expression.hasError()) {
+ QByteArray qtscriptResult = testResultToString(value, isUndefined);
+ qWarning().nospace() << "QDeclarativeV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column;
+ qWarning().nospace() << " Binding: " << binding;
+ qWarning().nospace() << " QtScript: " << qtscriptResult.constData();
+ qWarning().nospace() << " V4: exception";
+ }
+}
+
+static void throwException(int id, QDeclarativeDelayedError *error,
+ QDeclarativeV4Program *program, QDeclarativeContextData *context,
+ const QString &description = QString())
+{
+ error->error.setUrl(context->url);
+ if (description.isEmpty())
+ error->error.setDescription(QLatin1String("TypeError: Result of expression is not an object"));
+ else
+ error->error.setDescription(description);
+ if (id != 0xFF) {
+ quint64 e = *((quint64 *)(program->data() + program->exceptionDataOffset) + id);
+ error->error.setLine((e >> 32) & 0xFFFFFFFF);
+ error->error.setColumn(e & 0xFFFFFFFF);
+ } else {
+ error->error.setLine(-1);
+ error->error.setColumn(-1);
+ }
+ if (!context->engine || !error->addError(QDeclarativeEnginePrivate::get(context->engine)))
+ QDeclarativeEnginePrivate::warning(context->engine, error->error);
+}
+
+const qsreal QDeclarativeV4BindingsPrivate::D32 = 4294967296.0;
+
+qint32 QDeclarativeV4BindingsPrivate::toInt32(qsreal n)
+{
+ if (qIsNaN(n) || qIsInf(n) || (n == 0))
+ return 0;
+
+ double sign = (n < 0) ? -1.0 : 1.0;
+ qsreal abs_n = fabs(n);
+
+ n = ::fmod(sign * ::floor(abs_n), D32);
+ const double D31 = D32 / 2.0;
+
+ if (sign == -1 && n < -D31)
+ n += D32;
+
+ else if (sign != -1 && n >= D31)
+ n -= D32;
+
+ return qint32 (n);
+}
+
+inline quint32 QDeclarativeV4BindingsPrivate::toUint32(qsreal n)
+{
+ if (qIsNaN(n) || qIsInf(n) || (n == 0))
+ return 0;
+
+ double sign = (n < 0) ? -1.0 : 1.0;
+ qsreal abs_n = fabs(n);
+
+ n = ::fmod(sign * ::floor(abs_n), D32);
+
+ if (n < 0)
+ n += D32;
+
+ return quint32 (n);
+}
+
+#define THROW_EXCEPTION_STR(id, str) { \
+ if (testBinding) testBindingException(*testBindingSource, bindingLine, bindingColumn, context, scope); \
+ throwException((id), error, program, context, (str)); \
+ goto exceptionExit; \
+}
+
+#define THROW_EXCEPTION(id) THROW_EXCEPTION_STR(id, QString())
+
+#define MARK_REGISTER(reg) cleanupRegisterMask |= (1 << (reg))
+#define MARK_CLEAN_REGISTER(reg) cleanupRegisterMask &= ~(1 << (reg))
+
+#define STRING_REGISTER(reg) { \
+ registers[(reg)].settype(QStringType); \
+ MARK_REGISTER(reg); \
+}
+
+#define URL_REGISTER(reg) { \
+ registers[(reg)].settype(QUrlType); \
+ MARK_REGISTER(reg); \
+}
+
+#define VARIANT_REGISTER(reg) { \
+ registers[(reg)].settype(QVariantType); \
+ MARK_REGISTER(reg); \
+}
+
+#ifdef QML_THREADED_INTERPRETER
+void **QDeclarativeV4Bindings::getDecodeInstrTable()
+{
+ static void **decode_instr;
+ if (!decode_instr) {
+ QDeclarativeV4Bindings dummy(0, 0);
+ quint32 executedBlocks = 0;
+ dummy.d_func()->run(0, executedBlocks, 0, 0, 0, 0, QDeclarativePropertyPrivate::BypassInterceptor, &decode_instr);
+ }
+ return decode_instr;
+}
+#endif
+
+void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
+ QDeclarativeContextData *context, QDeclarativeDelayedError *error,
+ QObject *scope, QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags
+#ifdef QML_THREADED_INTERPRETER
+ ,void ***table
+#endif
+ )
+{
+ Q_Q(QDeclarativeV4Bindings);
+
+#ifdef QML_THREADED_INTERPRETER
+ if (table) {
+ static void *decode_instr[] = {
+ FOR_EACH_V4_INSTR(QML_V4_INSTR_ADDR)
+ };
+
+ *table = decode_instr;
+ return;
+ }
+#endif
+
+
+ error->removeError();
+
+ Register registers[32];
+ quint32 cleanupRegisterMask = 0;
+
+ executedBlocks = 0;
+
+ QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(context->engine);
+ const char *code = program->instructions();
+ code += instrIndex * QML_V4_INSTR_SIZE(Jump, jump);
+ const Instr *instr = (const Instr *) code;
+
+ const char *data = program->data();
+
+ QString *testBindingSource = 0;
+ bool testBinding = false;
+ int bindingLine = 0;
+ int bindingColumn = 0;
+
+#ifdef QML_THREADED_INTERPRETER
+ goto *instr->common.code;
+#else
+ for (;;) {
+ switch (instr->common.type) {
+#endif
+
+ QML_V4_BEGIN_INSTR(Noop, common)
+ QML_V4_END_INSTR(Noop, common)
+
+ QML_V4_BEGIN_INSTR(BindingId, id)
+ bindingLine = instr->id.line;
+ bindingColumn = instr->id.column;
+ QML_V4_END_INSTR(BindingId, id)
+
+ QML_V4_BEGIN_INSTR(SubscribeId, subscribeop)
+ subscribeId(context, instr->subscribeop.index, instr->subscribeop.offset);
+ QML_V4_END_INSTR(SubscribeId, subscribeop)
+
+ QML_V4_BEGIN_INSTR(Subscribe, subscribeop)
+ {
+ QObject *o = 0;
+ const Register &object = registers[instr->subscribeop.reg];
+ if (!object.isUndefined()) o = object.getQObject();
+ subscribe(o, instr->subscribeop.index, instr->subscribeop.offset);
+ }
+ QML_V4_END_INSTR(Subscribe, subscribeop)
+
+ QML_V4_BEGIN_INSTR(FetchAndSubscribe, fetchAndSubscribe)
+ {
+ Register &reg = registers[instr->fetchAndSubscribe.reg];
+
+ if (reg.isUndefined())
+ THROW_EXCEPTION(instr->fetchAndSubscribe.exceptionId);
+
+ QObject *object = reg.getQObject();
+ if (!object) {
+ reg.setUndefined();
+ } else {
+ int subIdx = instr->fetchAndSubscribe.subscription;
+ QDeclarativeV4BindingsPrivate::Subscription *sub = 0;
+ if (subIdx != -1) {
+ sub = (subscriptions + subIdx);
+ sub->target = q;
+ sub->targetMethod = methodCount + subIdx;
+ }
+ reg.init((Register::Type)instr->fetchAndSubscribe.valueType);
+ if (instr->fetchAndSubscribe.valueType >= FirstCleanupType)
+ MARK_REGISTER(instr->fetchAndSubscribe.reg);
+ QDeclarativeV4Compiler::fastPropertyAccessor()->accessor(instr->fetchAndSubscribe.function)(object, reg.typeDataPtr(), sub);
+ }
+ }
+ QML_V4_END_INSTR(FetchAndSubscribe, fetchAndSubscribe)
+
+ QML_V4_BEGIN_INSTR(LoadId, load)
+ registers[instr->load.reg].setQObject(context->idValues[instr->load.index].data());
+ QML_V4_END_INSTR(LoadId, load)
+
+ QML_V4_BEGIN_INSTR(LoadScope, load)
+ registers[instr->load.reg].setQObject(scope);
+ QML_V4_END_INSTR(LoadScope, load)
+
+ QML_V4_BEGIN_INSTR(LoadRoot, load)
+ registers[instr->load.reg].setQObject(context->contextObject);
+ QML_V4_END_INSTR(LoadRoot, load)
+
+ QML_V4_BEGIN_INSTR(LoadAttached, attached)
+ {
+ const Register &input = registers[instr->attached.reg];
+ Register &output = registers[instr->attached.output];
+ if (input.isUndefined())
+ THROW_EXCEPTION(instr->attached.exceptionId);
+
+ QObject *object = registers[instr->attached.reg].getQObject();
+ if (!object) {
+ output.setUndefined();
+ } else {
+ QObject *attached = qmlAttachedPropertiesObjectById(instr->attached.id, input.getQObject(), true);
+ Q_ASSERT(attached);
+ output.setQObject(attached);
+ }
+ }
+ QML_V4_END_INSTR(LoadAttached, attached)
+
+ QML_V4_BEGIN_INSTR(UnaryNot, unaryop)
+ {
+ registers[instr->unaryop.output].setbool(!registers[instr->unaryop.src].getbool());
+ }
+ QML_V4_END_INSTR(UnaryNot, unaryop)
+
+ QML_V4_BEGIN_INSTR(UnaryMinusReal, unaryop)
+ {
+ registers[instr->unaryop.output].setqreal(-registers[instr->unaryop.src].getqreal());
+ }
+ QML_V4_END_INSTR(UnaryMinusReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(UnaryMinusInt, unaryop)
+ {
+ registers[instr->unaryop.output].setint(-registers[instr->unaryop.src].getint());
+ }
+ QML_V4_END_INSTR(UnaryMinusInt, unaryop)
+
+ QML_V4_BEGIN_INSTR(UnaryPlusReal, unaryop)
+ {
+ registers[instr->unaryop.output].setqreal(+registers[instr->unaryop.src].getqreal());
+ }
+ QML_V4_END_INSTR(UnaryPlusReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(UnaryPlusInt, unaryop)
+ {
+ registers[instr->unaryop.output].setint(+registers[instr->unaryop.src].getint());
+ }
+ QML_V4_END_INSTR(UnaryPlusInt, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertBoolToInt, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setint(src.getbool());
+ }
+ QML_V4_END_INSTR(ConvertBoolToInt, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertBoolToReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setqreal(src.getbool());
+ }
+ QML_V4_END_INSTR(ConvertBoolToReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertBoolToString, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getstringptr()) QString(QLatin1String(src.getbool() ? "true" : "false"));
+ STRING_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertBoolToString, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertIntToBool, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setbool(src.getint());
+ }
+ QML_V4_END_INSTR(ConvertIntToBool, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertIntToReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setqreal(qreal(src.getint()));
+ }
+ QML_V4_END_INSTR(ConvertIntToReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertIntToString, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getstringptr()) QString(QString::number(src.getint()));
+ STRING_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertIntToString, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertRealToBool, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setbool(src.getqreal() != 0);
+ }
+ QML_V4_END_INSTR(ConvertRealToBool, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertRealToInt, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setint(toInt32(src.getqreal()));
+ }
+ QML_V4_END_INSTR(ConvertRealToInt, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertRealToString, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getstringptr()) QString(QString::number(src.getqreal()));
+ STRING_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertRealToString, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertStringToBool, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ // Delegate the conversion. This is pretty fast and it doesn't require a QScriptEngine.
+ // Ideally we should just call the methods in the QScript namespace directly.
+ QScriptValue tmp(*src.getstringptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupString();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ output.setbool(tmp.toBool());
+ }
+ }
+ QML_V4_END_INSTR(ConvertStringToBool, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertStringToInt, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ // Delegate the conversion. This is pretty fast and it doesn't require a QScriptEngine.
+ // Ideally we should just call the methods in the QScript namespace directly.
+ QScriptValue tmp(*src.getstringptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupString();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ output.setint(tmp.toInt32());
+ }
+ }
+ QML_V4_END_INSTR(ConvertStringToInt, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertStringToReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ // Delegate the conversion. This is pretty fast and it doesn't require a QScriptEngine.
+ // Ideally we should just call the methods in the QScript namespace directly.
+ QScriptValue tmp(*src.getstringptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupString();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ output.setqreal(tmp.toNumber());
+ }
+ }
+ QML_V4_END_INSTR(ConvertStringToReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(MathSinReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setqreal(qSin(src.getqreal()));
+ }
+ QML_V4_END_INSTR(MathSinReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(MathCosReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setqreal(qCos(src.getqreal()));
+ }
+ QML_V4_END_INSTR(MathCosReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(MathRoundReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setint(qRound(src.getqreal()));
+ }
+ QML_V4_END_INSTR(MathRoundReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(MathFloorReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setint(qFloor(src.getqreal()));
+ }
+ QML_V4_END_INSTR(MathFloorReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(MathPIReal, unaryop)
+ {
+ static const qsreal qmlPI = 2.0 * qAsin(1.0);
+ Register &output = registers[instr->unaryop.output];
+ output.setqreal(qmlPI);
+ }
+ QML_V4_END_INSTR(MathPIReal, unaryop)
+
+ QML_V4_BEGIN_INSTR(Real, real_value)
+ registers[instr->real_value.reg].setqreal(instr->real_value.value);
+ QML_V4_END_INSTR(Real, real_value)
+
+ QML_V4_BEGIN_INSTR(Int, int_value)
+ registers[instr->int_value.reg].setint(instr->int_value.value);
+ QML_V4_END_INSTR(Int, int_value)
+
+ QML_V4_BEGIN_INSTR(Bool, bool_value)
+ registers[instr->bool_value.reg].setbool(instr->bool_value.value);
+ QML_V4_END_INSTR(Bool, bool_value)
+
+ QML_V4_BEGIN_INSTR(String, string_value)
+ {
+ Register &output = registers[instr->string_value.reg];
+ QChar *string = (QChar *)(data + instr->string_value.offset);
+ new (output.getstringptr()) QString(string, instr->string_value.length);
+ STRING_REGISTER(instr->string_value.reg);
+ }
+ QML_V4_END_INSTR(String, string_value)
+
+ QML_V4_BEGIN_INSTR(EnableV4Test, string_value)
+ {
+ testBindingSource = new QString((QChar *)(data + instr->string_value.offset), instr->string_value.length);
+ testBinding = true;
+ }
+ QML_V4_END_INSTR(String, string_value)
+
+ QML_V4_BEGIN_INSTR(BitAndInt, binaryop)
+ {
+ registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() &
+ registers[instr->binaryop.right].getint());
+ }
+ QML_V4_END_INSTR(BitAndInt, binaryop)
+
+ QML_V4_BEGIN_INSTR(BitOrInt, binaryop)
+ {
+ registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() |
+ registers[instr->binaryop.right].getint());
+ }
+ QML_V4_END_INSTR(BitAndInt, binaryop)
+
+ QML_V4_BEGIN_INSTR(BitXorInt, binaryop)
+ {
+ registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() ^
+ registers[instr->binaryop.right].getint());
+ }
+ QML_V4_END_INSTR(BitXorInt, binaryop)
+
+ QML_V4_BEGIN_INSTR(AddReal, binaryop)
+ {
+ registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() +
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(AddReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(AddString, binaryop)
+ {
+ QString &string = *registers[instr->binaryop.output].getstringptr();
+ if (instr->binaryop.output == instr->binaryop.left) {
+ string += registers[instr->binaryop.right].getstringptr();
+ } else {
+ string = *registers[instr->binaryop.left].getstringptr() +
+ *registers[instr->binaryop.right].getstringptr();
+ }
+ }
+ QML_V4_END_INSTR(AddString, binaryop)
+
+ QML_V4_BEGIN_INSTR(SubReal, binaryop)
+ {
+ registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() -
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(SubReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(MulReal, binaryop)
+ {
+ registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() *
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(MulReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(DivReal, binaryop)
+ {
+ registers[instr->binaryop.output].setqreal(registers[instr->binaryop.left].getqreal() /
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(DivReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(ModReal, binaryop)
+ {
+ Register &target = registers[instr->binaryop.output];
+ const Register &left = registers[instr->binaryop.left];
+ const Register &right = registers[instr->binaryop.right];
+ if (QMetaType::QReal == QMetaType::Float)
+ target.setqreal(::fmodf(left.getqreal(), right.getqreal()));
+ else
+ target.setqreal(::fmod(left.getqreal(), right.getqreal()));
+ }
+ QML_V4_END_INSTR(ModInt, binaryop)
+
+ QML_V4_BEGIN_INSTR(LShiftInt, binaryop)
+ {
+ registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() <<
+ registers[instr->binaryop.right].getint());
+ }
+ QML_V4_END_INSTR(LShiftInt, binaryop)
+
+ QML_V4_BEGIN_INSTR(RShiftInt, binaryop)
+ {
+ registers[instr->binaryop.output].setint(registers[instr->binaryop.left].getint() >>
+ registers[instr->binaryop.right].getint());
+ }
+ QML_V4_END_INSTR(RShiftInt, binaryop)
+
+ QML_V4_BEGIN_INSTR(URShiftInt, binaryop)
+ {
+ registers[instr->binaryop.output].setint((unsigned)registers[instr->binaryop.left].getint() >>
+ registers[instr->binaryop.right].getint());
+ }
+ QML_V4_END_INSTR(URShiftInt, binaryop)
+
+ QML_V4_BEGIN_INSTR(GtReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() >
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(GtReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(LtReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() <
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(LtReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(GeReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() >=
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(GeReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(LeReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() <=
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(LeReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(EqualReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() ==
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(EqualReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(NotEqualReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() !=
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(NotEqualReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(StrictEqualReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() ==
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(StrictEqualReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(StrictNotEqualReal, binaryop)
+ {
+ registers[instr->binaryop.output].setbool(registers[instr->binaryop.left].getqreal() !=
+ registers[instr->binaryop.right].getqreal());
+ }
+ QML_V4_END_INSTR(StrictNotEqualReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(GtString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a > b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(GtString, binaryop)
+
+ QML_V4_BEGIN_INSTR(LtString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a < b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(LtString, binaryop)
+
+ QML_V4_BEGIN_INSTR(GeString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a >= b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(GeString, binaryop)
+
+ QML_V4_BEGIN_INSTR(LeString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a <= b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(LeString, binaryop)
+
+ QML_V4_BEGIN_INSTR(EqualString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a == b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(EqualString, binaryop)
+
+ QML_V4_BEGIN_INSTR(NotEqualString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a != b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(NotEqualString, binaryop)
+
+ QML_V4_BEGIN_INSTR(StrictEqualString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a == b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(StrictEqualString, binaryop)
+
+ QML_V4_BEGIN_INSTR(StrictNotEqualString, binaryop)
+ {
+ const QString &a = *registers[instr->binaryop.left].getstringptr();
+ const QString &b = *registers[instr->binaryop.right].getstringptr();
+ bool result = a != b;
+ if (instr->binaryop.left == instr->binaryop.output) {
+ registers[instr->binaryop.output].cleanupString();
+ MARK_CLEAN_REGISTER(instr->binaryop.output);
+ }
+ registers[instr->binaryop.output].setbool(result);
+ }
+ QML_V4_END_INSTR(StrictNotEqualString, binaryop)
+
+ QML_V4_BEGIN_INSTR(NewString, construct)
+ {
+ Register &output = registers[instr->construct.reg];
+ new (output.getstringptr()) QString;
+ STRING_REGISTER(instr->construct.reg);
+ }
+ QML_V4_END_INSTR(NewString, construct)
+
+ QML_V4_BEGIN_INSTR(NewUrl, construct)
+ {
+ Register &output = registers[instr->construct.reg];
+ new (output.geturlptr()) QUrl;
+ URL_REGISTER(instr->construct.reg);
+ }
+ QML_V4_END_INSTR(NewUrl, construct)
+
+ QML_V4_BEGIN_INSTR(Fetch, fetch)
+ {
+ Register &reg = registers[instr->fetch.reg];
+
+ if (reg.isUndefined())
+ THROW_EXCEPTION(instr->fetch.exceptionId);
+
+ QObject *object = reg.getQObject();
+ if (!object) {
+ THROW_EXCEPTION(instr->fetch.exceptionId);
+ } else {
+ reg.init((Register::Type)instr->fetch.valueType);
+ if (instr->fetch.valueType >= FirstCleanupType)
+ MARK_REGISTER(instr->fetch.reg);
+ void *argv[] = { reg.typeDataPtr(), 0 };
+ QMetaObject::metacall(object, QMetaObject::ReadProperty, instr->fetch.index, argv);
+ }
+ }
+ QML_V4_END_INSTR(Fetch, fetch)
+
+ QML_V4_BEGIN_INSTR(TestV4Store, storetest)
+ {
+ Register &data = registers[instr->storetest.reg];
+ testBindingResult(*testBindingSource, bindingLine, bindingColumn, context,
+ scope, data, instr->storetest.regType);
+ }
+ QML_V4_END_INSTR(TestV4Store, storetest)
+
+ QML_V4_BEGIN_INSTR(Store, store)
+ {
+ Register &data = registers[instr->store.reg];
+
+ if (data.isUndefined())
+ THROW_EXCEPTION_STR(instr->store.exceptionId, QLatin1String("Unable to assign undefined value"));
+
+ int status = -1;
+ void *argv[] = { data.typeDataPtr(), 0, &status, &storeFlags };
+ QMetaObject::metacall(output, QMetaObject::WriteProperty,
+ instr->store.index, argv);
+
+ goto programExit;
+ }
+ QML_V4_END_INSTR(Store, store)
+
+ QML_V4_BEGIN_INSTR(Copy, copy)
+ registers[instr->copy.reg].copy(registers[instr->copy.src]);
+ if (registers[instr->copy.reg].gettype() >= FirstCleanupType)
+ MARK_REGISTER(instr->copy.reg);
+ QML_V4_END_INSTR(Copy, copy)
+
+ QML_V4_BEGIN_INSTR(Jump, jump)
+ if (instr->jump.reg == -1 || !registers[instr->jump.reg].getbool())
+ code += instr->jump.count;
+ QML_V4_END_INSTR(Jump, jump)
+
+ QML_V4_BEGIN_INSTR(BranchTrue, branchop)
+ if (registers[instr->branchop.reg].getbool())
+ code += instr->branchop.offset;
+ QML_V4_END_INSTR(BranchTrue, branchop)
+
+ QML_V4_BEGIN_INSTR(BranchFalse, branchop)
+ if (! registers[instr->branchop.reg].getbool())
+ code += instr->branchop.offset;
+ QML_V4_END_INSTR(BranchFalse, branchop)
+
+ QML_V4_BEGIN_INSTR(Branch, branchop)
+ code += instr->branchop.offset;
+ QML_V4_END_INSTR(Branch, branchop)
+
+ QML_V4_BEGIN_INSTR(Block, blockop)
+ executedBlocks |= instr->blockop.block;
+ QML_V4_END_INSTR(Block, blockop)
+
+ QML_V4_BEGIN_INSTR(InitString, initstring)
+ if (!identifiers[instr->initstring.offset].identifier) {
+ quint32 len = *(quint32 *)(data + instr->initstring.dataIdx);
+ QChar *strdata = (QChar *)(data + instr->initstring.dataIdx + sizeof(quint32));
+
+ QString str = QString::fromRawData(strdata, len);
+
+ identifiers[instr->initstring.offset] = engine->objectClass->createPersistentIdentifier(str);
+ }
+ QML_V4_END_INSTR(InitString, initstring)
+
+ QML_V4_BEGIN_INSTR(CleanupRegister, cleanup)
+ registers[instr->cleanup.reg].cleanup();
+ QML_V4_END_INSTR(CleanupRegister, cleanup)
+
+#ifdef QML_THREADED_INTERPRETER
+ // nothing to do
+#else
+ default:
+ qFatal("QDeclarativeV4: Unknown instruction %d encountered.", instr->common.type);
+ break;
+ } // switch
+
+ } // while
+#endif
+
+ Q_ASSERT(!"Unreachable code reached");
+
+programExit:
+exceptionExit:
+ delete testBindingSource;
+
+ int reg = 0;
+ while (cleanupRegisterMask) {
+ if (cleanupRegisterMask & 0x1)
+ registers[reg].cleanup();
+
+ reg++;
+ cleanupRegisterMask >>= 1;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4bindings_p.h b/src/declarative/qml/v4/qdeclarativev4bindings_p.h
new file mode 100644
index 0000000000..9f225b65b6
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4bindings_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEV4BINDINGS_P_H
+#define QDECLARATIVEV4BINDINGS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qdeclarativeexpression_p.h"
+#include "private/qdeclarativebinding_p.h"
+#include "private/qdeclarativev4instruction_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeV4BindingsPrivate;
+class QDeclarativeV4Bindings : public QObject,
+ public QDeclarativeAbstractExpression,
+ public QDeclarativeRefCount
+{
+public:
+ QDeclarativeV4Bindings(const char *program, QDeclarativeContextData *context);
+ virtual ~QDeclarativeV4Bindings();
+
+ QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property);
+
+#ifdef QML_THREADED_INTERPRETER
+ static void **getDecodeInstrTable();
+#endif
+
+protected:
+ int qt_metacall(QMetaObject::Call, int, void **);
+
+private:
+ Q_DISABLE_COPY(QDeclarativeV4Bindings)
+ Q_DECLARE_PRIVATE(QDeclarativeV4Bindings)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEV4BINDINGS_P_H
+
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler.cpp b/src/declarative/qml/v4/qdeclarativev4compiler.cpp
new file mode 100644
index 0000000000..e67a3821d7
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4compiler.cpp
@@ -0,0 +1,1340 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativev4compiler_p.h"
+#include "qdeclarativev4compiler_p_p.h"
+#include "qdeclarativev4program_p.h"
+#include "qdeclarativev4ir_p.h"
+#include "qdeclarativev4irbuilder_p.h"
+
+#include <private/qdeclarativejsast_p.h>
+#include <private/qdeclarativefastproperties_p.h>
+#include <private/qdeclarativejsengine_p.h>
+#include <private/qdeclarativeanchors_p_p.h> // For AnchorLine
+#include <private/qsganchors_p_p.h> // For AnchorLine
+
+QT_BEGIN_NAMESPACE
+
+DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP)
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER)
+DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL)
+DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
+DEFINE_BOOL_CONFIG_OPTION(qmlBindingsTestEnv, QML_BINDINGS_TEST)
+
+Q_GLOBAL_STATIC(QDeclarativeFastProperties, fastProperties)
+
+static bool qmlBindingsTest = false;
+
+using namespace QDeclarativeJS;
+QDeclarativeV4CompilerPrivate::QDeclarativeV4CompilerPrivate()
+: _function(0) , _block(0) , _discarded(false)
+{
+}
+
+//
+// tracing
+//
+void QDeclarativeV4CompilerPrivate::trace(int line, int column)
+{
+ bytecode.clear();
+
+ this->currentReg = _function->tempCount;
+
+ foreach (IR::BasicBlock *bb, _function->basicBlocks) {
+ if (! bb->isTerminated() && (bb->index + 1) < _function->basicBlocks.size())
+ bb->JUMP(_function->basicBlocks.at(bb->index + 1));
+ }
+
+ QVector<IR::BasicBlock *> blocks;
+ trace(&blocks);
+ currentBlockMask = 0x00000001;
+
+
+ for (int i = 0; i < blocks.size(); ++i) {
+ IR::BasicBlock *block = blocks.at(i);
+ IR::BasicBlock *next = i + 1 < blocks.size() ? blocks.at(i + 1) : 0;
+ if (IR::Stmt *terminator = block->terminator()) {
+ if (IR::CJump *cj = terminator->asCJump()) {
+ if (cj->iffalse != next) {
+ block->i(new IR::Jump(cj->iffalse));
+ }
+ } else if (IR::Jump *j = terminator->asJump()) {
+ if (j->target == next) {
+ delete block->statements.back();
+ block->statements.resize(block->statements.size() - 1);
+ }
+ }
+ }
+
+ block->offset = bytecode.size();
+
+ if (bytecode.isEmpty()) {
+ if (qmlBindingsTest || bindingsDump()) {
+ Instr id;
+ id.common.type = Instr::BindingId;
+ id.id.column = column;
+ id.id.line = line;
+ gen(id);
+ }
+
+ if (qmlBindingsTest) {
+ QString str = expression->expression.asScript();
+ QByteArray strdata((const char *)str.constData(), str.length() * sizeof(QChar));
+ int offset = data.count();
+ data += strdata;
+
+ Instr test;
+ test.common.type = Instr::EnableV4Test;
+ test.string_value.reg = 0;
+ test.string_value.offset = offset;
+ test.string_value.length = str.length();
+ gen(test);
+ }
+ }
+
+ bool usic = false;
+ int patchesCount = patches.count();
+ qSwap(usedSubscriptionIdsChanged, usic);
+
+ int blockopIndex = bytecode.size();
+ Instr blockop;
+ blockop.block(currentBlockMask);
+ gen(blockop);
+
+ foreach (IR::Stmt *s, block->statements)
+ s->accept(this);
+
+ qSwap(usedSubscriptionIdsChanged, usic);
+
+ if (usic) {
+ if (currentBlockMask == 0x80000000) {
+ discard();
+ return;
+ }
+ currentBlockMask <<= 1;
+ } else {
+ const int adjust = bytecode.remove(blockopIndex);
+ // Correct patches
+ for (int ii = patchesCount; ii < patches.count(); ++ii)
+ patches[ii].offset -= adjust;
+ }
+ }
+
+#ifdef DEBUG_IR_STRUCTURE
+ IR::IRDump dump;
+ for (int i = 0; i < blocks.size(); ++i) {
+ dump.basicblock(blocks.at(i));
+ }
+#endif
+
+
+ // back patching
+ foreach (const Patch &patch, patches) {
+ Instr &instr = bytecode[patch.offset];
+ instr.branchop.offset = patch.block->offset - patch.offset - instr.size();
+ }
+
+ patches.clear();
+}
+
+void QDeclarativeV4CompilerPrivate::trace(QVector<IR::BasicBlock *> *blocks)
+{
+ QList<IR::BasicBlock *> todo = QList<IR::BasicBlock *>::fromVector(_function->basicBlocks);
+ while (! todo.isEmpty()) {
+ IR::BasicBlock *block = todo.takeFirst();
+
+ while (! blocks->contains(block)) {
+ blocks->append(block);
+
+ if (IR::Stmt *terminator = block->terminator()) {
+ if (IR::CJump *cj = terminator->asCJump())
+ block = cj->iffalse;
+ else if (IR::Jump *j = terminator->asJump())
+ block = j->target;
+ }
+ }
+ }
+}
+
+void QDeclarativeV4CompilerPrivate::traceExpression(IR::Expr *e, quint8 r)
+{
+ if (!e) {
+ discard();
+ } else {
+ qSwap(currentReg, r);
+ e->accept(this);
+ qSwap(currentReg, r);
+ }
+}
+
+//
+// expressions
+//
+void QDeclarativeV4CompilerPrivate::visitConst(IR::Const *e)
+{
+ Instr i;
+ switch (e->type) {
+ case IR::BoolType:
+ i.move_reg_bool(currentReg, e->value);
+ gen(i);
+ break;
+
+ case IR::IntType:
+ i.move_reg_int(currentReg, e->value);
+ gen(i);
+ break;
+
+ case IR::RealType:
+ i.move_reg_qreal(currentReg, e->value);
+ gen(i);
+ break;
+
+ default:
+ if (qmlVerboseCompiler())
+ qWarning() << Q_FUNC_INFO << "unexpected type";
+ discard();
+ }
+}
+
+void QDeclarativeV4CompilerPrivate::visitString(IR::String *e)
+{
+ registerLiteralString(currentReg, e->value);
+}
+
+void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
+{
+ if (e->base) {
+ // fetch the object and store it in reg.
+ traceExpression(e->base, currentReg);
+ } else {
+ _subscribeName.clear();
+ }
+
+ if (e->storage == IR::Name::RootStorage) {
+
+ Instr instr;
+ instr.load_root(currentReg);
+ gen(instr);
+
+ if (e->symbol == IR::Name::IdObject) {
+ // The ID is a reference to the root object
+ return;
+ }
+
+ } else if (e->storage == IR::Name::ScopeStorage) {
+
+ Instr instr;
+ instr.load_scope(currentReg);
+ gen(instr);
+
+ _subscribeName << contextName();
+
+ } else if (e->storage == IR::Name::IdStorage) {
+
+ Instr instr;
+ instr.load_id(currentReg, e->index);
+ gen(instr);
+
+ _subscribeName << QLatin1String("$$$ID_") + e->id;
+
+ if (blockNeedsSubscription(_subscribeName)) {
+ Instr sub;
+ sub.subscribeId(currentReg, subscriptionIndex(_subscribeName), instr.load.index);
+ gen(sub);
+ }
+
+ return;
+ } else {
+ // No action needed
+ }
+
+ switch (e->symbol) {
+ case IR::Name::Unbound:
+ case IR::Name::IdObject:
+ case IR::Name::Slot:
+ case IR::Name::Object: {
+ Q_ASSERT(!"Unreachable");
+ discard();
+ } break;
+
+ case IR::Name::AttachType: {
+ _subscribeName << e->id;
+
+ Instr attached;
+ attached.common.type = Instr::LoadAttached;
+ attached.attached.output = currentReg;
+ attached.attached.reg = currentReg;
+ attached.attached.exceptionId = exceptionId(e->line, e->column);
+ Q_ASSERT(e->declarativeType->attachedPropertiesId() != -1);
+ attached.attached.id = e->declarativeType->attachedPropertiesId();
+ gen(attached);
+ } break;
+
+ case IR::Name::Property: {
+ _subscribeName << e->id;
+
+ QMetaProperty prop = e->meta->property(e->index);
+ int fastFetchIndex = fastProperties()->accessorIndexForProperty(e->meta, e->index);
+
+ const int propTy = prop.userType();
+ QDeclarativeRegisterType regType;
+
+ switch (propTy) {
+ case QMetaType::QReal:
+ regType = QRealType;
+ break;
+ case QMetaType::Bool:
+ regType = BoolType;
+ break;
+ case QMetaType::Int:
+ regType = IntType;
+ break;
+ case QMetaType::QString:
+ regType = QStringType;
+ break;
+
+ default:
+ if (propTy == qMetaTypeId<QDeclarativeAnchorLine>()) {
+ regType = PODValueType;
+ } else if (propTy == qMetaTypeId<QSGAnchorLine>()) {
+ regType = PODValueType;
+ } else if (QDeclarativeMetaType::isQObject(propTy)) {
+ regType = QObjectStarType;
+ } else {
+ if (qmlVerboseCompiler())
+ qWarning() << "Discard unsupported property type:" << QMetaType::typeName(propTy);
+ discard(); // Unsupported type
+ return;
+ }
+
+ break;
+ } // switch
+
+ Instr fetch;
+
+ if (fastFetchIndex != -1) {
+ fetch.common.type = Instr::FetchAndSubscribe;
+ fetch.fetchAndSubscribe.reg = currentReg;
+ fetch.fetchAndSubscribe.function = fastFetchIndex;
+ fetch.fetchAndSubscribe.subscription = subscriptionIndex(_subscribeName);
+ fetch.fetchAndSubscribe.exceptionId = exceptionId(e->line, e->column);
+ fetch.fetchAndSubscribe.valueType = regType;
+ } else {
+ if (blockNeedsSubscription(_subscribeName) && prop.hasNotifySignal() && prop.notifySignalIndex() != -1) {
+ Instr sub;
+ sub.subscribe(currentReg, subscriptionIndex(_subscribeName), prop.notifySignalIndex());
+ gen(sub);
+ }
+
+ fetch.common.type = Instr::Fetch;
+ fetch.fetch.reg = currentReg;
+ fetch.fetch.index = e->index;
+ fetch.fetch.exceptionId = exceptionId(e->line, e->column);
+ fetch.fetch.valueType = regType;
+ }
+
+ gen(fetch);
+
+ } break;
+ } // switch
+}
+
+void QDeclarativeV4CompilerPrivate::visitTemp(IR::Temp *e)
+{
+ if (currentReg != e->index) {
+ Instr i;
+ i.move_reg_reg(currentReg, e->index);
+ gen(i);
+ }
+}
+
+void QDeclarativeV4CompilerPrivate::visitUnop(IR::Unop *e)
+{
+ Instr i;
+
+ quint8 src = currentReg;
+
+ if (IR::Temp *temp = e->expr->asTemp()) {
+ src = temp->index;
+ } else {
+ traceExpression(e->expr, src);
+ }
+
+ switch (e->op) {
+ case IR::OpInvalid:
+ Q_ASSERT(!"unreachable");
+ break;
+
+ case IR::OpIfTrue:
+ convertToBool(e->expr, src);
+ if (src != currentReg) {
+ i.move_reg_reg(currentReg, src);
+ gen(i);
+ }
+ break;
+
+ case IR::OpNot:
+ convertToBool(e->expr, src);
+ i.unary_not(currentReg, src);
+ gen(i);
+ break;
+
+ case IR::OpUMinus:
+ if (e->expr->type == IR::RealType) {
+ i.uminus_real(currentReg, src);
+ gen(i);
+ } else if (e->expr->type == IR::IntType) {
+ convertToReal(e->expr, currentReg);
+ i.uminus_real(currentReg, src);
+ gen(i);
+ } else {
+ discard();
+ }
+ break;
+
+ case IR::OpUPlus:
+ if (e->expr->type == IR::RealType) {
+ i.uplus_real(currentReg, src);
+ gen(i);
+ } else if (e->expr->type == IR::IntType) {
+ convertToReal(e->expr, currentReg);
+ i.uplus_real(currentReg, src);
+ gen(i);
+ } else {
+ discard();
+ }
+ break;
+
+ case IR::OpCompl:
+ i.ucompl_real(currentReg, src);
+ gen(i);
+ discard(); // ???
+ break;
+
+ case IR::OpBitAnd:
+ case IR::OpBitOr:
+ case IR::OpBitXor:
+ case IR::OpAdd:
+ case IR::OpSub:
+ case IR::OpMul:
+ case IR::OpDiv:
+ case IR::OpMod:
+ case IR::OpLShift:
+ case IR::OpRShift:
+ case IR::OpURShift:
+ case IR::OpGt:
+ case IR::OpLt:
+ case IR::OpGe:
+ case IR::OpLe:
+ case IR::OpEqual:
+ case IR::OpNotEqual:
+ case IR::OpStrictEqual:
+ case IR::OpStrictNotEqual:
+ case IR::OpAnd:
+ case IR::OpOr:
+ Q_ASSERT(!"unreachable");
+ break;
+ } // switch
+}
+
+void QDeclarativeV4CompilerPrivate::convertToReal(IR::Expr *expr, int reg)
+{
+ if (expr->type == IR::RealType)
+ return;
+
+ Instr conv;
+ conv.unaryop.output = reg;
+ conv.unaryop.src = reg;
+
+ switch (expr->type) {
+ case IR::BoolType:
+ conv.common.type = Instr::ConvertBoolToReal;
+ gen(conv);
+ break;
+
+ case IR::IntType:
+ conv.common.type = Instr::ConvertIntToReal;
+ gen(conv);
+ break;
+
+ case IR::RealType:
+ // nothing to do
+ return;
+
+ default:
+ discard();
+ break;
+ } // switch
+}
+
+void QDeclarativeV4CompilerPrivate::convertToInt(IR::Expr *expr, int reg)
+{
+ if (expr->type == IR::IntType)
+ return;
+
+ Instr conv;
+ conv.unaryop.output = reg;
+ conv.unaryop.src = reg;
+
+ switch (expr->type) {
+ case IR::BoolType:
+ conv.common.type = Instr::ConvertBoolToInt;
+ gen(conv);
+ break;
+
+ case IR::IntType:
+ // nothing to do
+ return;
+
+ case IR::RealType:
+ conv.common.type = Instr::ConvertRealToInt;
+ gen(conv);
+ break;
+
+ default:
+ discard();
+ break;
+ } // switch
+}
+
+void QDeclarativeV4CompilerPrivate::convertToBool(IR::Expr *expr, int reg)
+{
+ if (expr->type == IR::BoolType)
+ return;
+
+ Instr conv;
+ conv.unaryop.output = reg;
+ conv.unaryop.src = reg;
+
+ switch (expr->type) {
+ case IR::BoolType:
+ // nothing to do
+ break;
+
+ case IR::IntType:
+ conv.common.type = Instr::ConvertIntToBool;
+ gen(conv);
+ break;
+
+ case IR::RealType:
+ conv.common.type = Instr::ConvertRealToBool;
+ gen(conv);
+ return;
+
+ case IR::StringType:
+ conv.common.type = Instr::ConvertStringToBool;
+ gen(conv);
+ return;
+
+ default:
+ discard();
+ break;
+ } // switch
+}
+
+quint8 QDeclarativeV4CompilerPrivate::instructionOpcode(IR::Binop *e)
+{
+ switch (e->op) {
+ case IR::OpInvalid:
+ return Instr::Noop;
+
+ case IR::OpIfTrue:
+ case IR::OpNot:
+ case IR::OpUMinus:
+ case IR::OpUPlus:
+ case IR::OpCompl:
+ return Instr::Noop;
+
+ case IR::OpBitAnd:
+ return Instr::BitAndInt;
+
+ case IR::OpBitOr:
+ return Instr::BitOrInt;
+
+ case IR::OpBitXor:
+ return Instr::BitXorInt;
+
+ case IR::OpAdd:
+ if (e->type == IR::StringType)
+ return Instr::AddString;
+ return Instr::AddReal;
+
+ case IR::OpSub:
+ return Instr::SubReal;
+
+ case IR::OpMul:
+ return Instr::MulReal;
+
+ case IR::OpDiv:
+ return Instr::DivReal;
+
+ case IR::OpMod:
+ return Instr::ModReal;
+
+ case IR::OpLShift:
+ return Instr::LShiftInt;
+
+ case IR::OpRShift:
+ return Instr::RShiftInt;
+
+ case IR::OpURShift:
+ return Instr::URShiftInt;
+
+ case IR::OpGt:
+ if (e->left->type == IR::StringType)
+ return Instr::GtString;
+ return Instr::GtReal;
+
+ case IR::OpLt:
+ if (e->left->type == IR::StringType)
+ return Instr::LtString;
+ return Instr::LtReal;
+
+ case IR::OpGe:
+ if (e->left->type == IR::StringType)
+ return Instr::GeString;
+ return Instr::GeReal;
+
+ case IR::OpLe:
+ if (e->left->type == IR::StringType)
+ return Instr::LeString;
+ return Instr::LeReal;
+
+ case IR::OpEqual:
+ if (e->left->type == IR::StringType)
+ return Instr::EqualString;
+ return Instr::EqualReal;
+
+ case IR::OpNotEqual:
+ if (e->left->type == IR::StringType)
+ return Instr::NotEqualString;
+ return Instr::NotEqualReal;
+
+ case IR::OpStrictEqual:
+ if (e->left->type == IR::StringType)
+ return Instr::StrictEqualString;
+ return Instr::StrictEqualReal;
+
+ case IR::OpStrictNotEqual:
+ if (e->left->type == IR::StringType)
+ return Instr::StrictNotEqualString;
+ return Instr::StrictNotEqualReal;
+
+ case IR::OpAnd:
+ case IR::OpOr:
+ return Instr::Noop;
+
+ } // switch
+
+ return Instr::Noop;
+}
+
+void QDeclarativeV4CompilerPrivate::visitBinop(IR::Binop *e)
+{
+ int left = currentReg;
+ int right = currentReg + 1;
+
+ if (e->left->asTemp() && e->type != IR::StringType) // Not sure if the e->type != String test is needed
+ left = e->left->asTemp()->index;
+ else
+ traceExpression(e->left, left);
+
+ if (IR::Temp *t = e->right->asTemp())
+ right = t->index;
+ else
+ traceExpression(e->right, right);
+
+ if (e->left->type != e->right->type) {
+ if (qmlVerboseCompiler())
+ qWarning().nospace() << "invalid operands to binary operator " << IR::binaryOperator(e->op)
+ << "(`" << IR::binaryOperator(e->left->type)
+ << "' and `"
+ << IR::binaryOperator(e->right->type)
+ << "'";
+ discard();
+ return;
+ }
+
+ switch (e->op) {
+ case IR::OpInvalid:
+ discard();
+ break;
+
+ // unary
+ case IR::OpIfTrue:
+ case IR::OpNot:
+ case IR::OpUMinus:
+ case IR::OpUPlus:
+ case IR::OpCompl:
+ discard();
+ break;
+
+ case IR::OpBitAnd:
+ case IR::OpBitOr:
+ case IR::OpBitXor:
+ case IR::OpLShift:
+ case IR::OpRShift:
+ case IR::OpURShift:
+ convertToInt(e->left, left);
+ convertToInt(e->right, right);
+ break;
+
+ case IR::OpAdd:
+ if (e->type != IR::StringType) {
+ convertToReal(e->left, left);
+ convertToReal(e->right, right);
+ }
+ break;
+
+ case IR::OpSub:
+ case IR::OpMul:
+ case IR::OpDiv:
+ case IR::OpMod:
+ convertToReal(e->left, left);
+ convertToReal(e->right, right);
+ break;
+
+ case IR::OpGt:
+ case IR::OpLt:
+ case IR::OpGe:
+ case IR::OpLe:
+ case IR::OpEqual:
+ case IR::OpNotEqual:
+ case IR::OpStrictEqual:
+ case IR::OpStrictNotEqual:
+ if (e->left->type != IR::StringType) {
+ convertToReal(e->left, left);
+ convertToReal(e->right, right);
+ }
+ break;
+
+ case IR::OpAnd:
+ case IR::OpOr:
+ discard(); // ### unreachable
+ break;
+ } // switch
+
+ const quint8 opcode = instructionOpcode(e);
+ if (opcode != Instr::Noop) {
+ Instr instr;
+ instr.common.type = opcode;
+ instr.binaryop.output = currentReg;
+ instr.binaryop.left = left;
+ instr.binaryop.right = right;
+ gen(instr);
+ }
+}
+
+void QDeclarativeV4CompilerPrivate::visitCall(IR::Call *call)
+{
+ if (IR::Name *name = call->base->asName()) {
+ if (call->args.size() == 1 && call->args.at(0)->type == IR::RealType) {
+ traceExpression(call->args.at(0), currentReg);
+
+ Instr instr;
+ instr.common.type = Instr::Noop;
+
+ switch (name->builtin) {
+ case IR::NoBuiltinSymbol:
+ break;
+
+ case IR::MathSinBultinFunction:
+ instr.math_sin_real(currentReg);
+ break;
+
+ case IR::MathCosBultinFunction:
+ instr.math_cos_real(currentReg);
+ break;
+
+ case IR::MathRoundBultinFunction:
+ instr.math_round_real(currentReg);
+ break;
+
+ case IR::MathFloorBultinFunction:
+ instr.math_floor_real(currentReg);
+ break;
+
+ case IR::MathPIBuiltinConstant:
+ break;
+ } // switch
+
+ if (instr.common.type != Instr::Noop) {
+ gen(instr);
+ return;
+ }
+ }
+ }
+
+ if (qmlVerboseCompiler())
+ qWarning() << "TODO:" << Q_FUNC_INFO << __LINE__;
+ discard();
+}
+
+
+//
+// statements
+//
+void QDeclarativeV4CompilerPrivate::visitExp(IR::Exp *s)
+{
+ traceExpression(s->expr, currentReg);
+}
+
+void QDeclarativeV4CompilerPrivate::visitMove(IR::Move *s)
+{
+ IR::Temp *target = s->target->asTemp();
+ Q_ASSERT(target != 0);
+
+ quint8 dest = target->index;
+
+ if (target->type != s->source->type) {
+ quint8 src = dest;
+
+ if (IR::Temp *t = s->source->asTemp())
+ src = t->index;
+ else
+ traceExpression(s->source, dest);
+
+ Instr conv;
+ conv.common.type = Instr::Noop;
+ if (target->type == IR::BoolType) {
+ switch (s->source->type) {
+ case IR::IntType: conv.common.type = Instr::ConvertIntToBool; break;
+ case IR::RealType: conv.common.type = Instr::ConvertRealToBool; break;
+ case IR::StringType: conv.common.type = Instr::ConvertStringToBool; break;
+ default: break;
+ } // switch
+ } else if (target->type == IR::IntType) {
+ switch (s->source->type) {
+ case IR::BoolType: conv.common.type = Instr::ConvertBoolToInt; break;
+ case IR::RealType: {
+ if (s->isMoveForReturn)
+ conv.common.type = Instr::MathRoundReal;
+ else
+ conv.common.type = Instr::ConvertRealToInt;
+ break;
+ }
+ case IR::StringType: conv.common.type = Instr::ConvertStringToInt; break;
+ default: break;
+ } // switch
+ } else if (target->type == IR::RealType) {
+ switch (s->source->type) {
+ case IR::BoolType: conv.common.type = Instr::ConvertBoolToReal; break;
+ case IR::IntType: conv.common.type = Instr::ConvertIntToReal; break;
+ case IR::StringType: conv.common.type = Instr::ConvertStringToReal; break;
+ default: break;
+ } // switch
+ } else if (target->type == IR::StringType) {
+ switch (s->source->type) {
+ case IR::BoolType: conv.common.type = Instr::ConvertBoolToString; break;
+ case IR::IntType: conv.common.type = Instr::ConvertIntToString; break;
+ case IR::RealType: conv.common.type = Instr::ConvertRealToString; break;
+ default: break;
+ } // switch
+ }
+ if (conv.common.type != Instr::Noop) {
+ conv.unaryop.output = dest;
+ conv.unaryop.src = src;
+ gen(conv);
+ } else {
+ discard();
+ }
+ } else {
+ traceExpression(s->source, dest);
+ }
+}
+
+void QDeclarativeV4CompilerPrivate::visitJump(IR::Jump *s)
+{
+ patches.append(Patch(s->target, bytecode.size()));
+
+ Instr i;
+ i.branch(0); // ### backpatch
+ gen(i);
+}
+
+void QDeclarativeV4CompilerPrivate::visitCJump(IR::CJump *s)
+{
+ traceExpression(s->cond, currentReg);
+
+ patches.append(Patch(s->iftrue, bytecode.size()));
+
+ Instr i;
+ i.branch_true(currentReg, 0); // ### backpatch
+ gen(i);
+}
+
+void QDeclarativeV4CompilerPrivate::visitRet(IR::Ret *s)
+{
+ Q_ASSERT(s->expr != 0);
+
+ int storeReg = currentReg;
+
+ if (IR::Temp *temp = s->expr->asTemp()) {
+ storeReg = temp->index;
+ } else {
+ traceExpression(s->expr, storeReg);
+ }
+
+ if (qmlBindingsTest) {
+ Instr test;
+ test.common.type = Instr::TestV4Store;
+ test.storetest.reg = storeReg;
+ switch (s->type) {
+ case IR::StringType:
+ test.storetest.regType = QMetaType::QString;
+ break;
+ case IR::UrlType:
+ test.storetest.regType = QMetaType::QUrl;
+ break;
+ case IR::AnchorLineType:
+ test.storetest.regType = qMetaTypeId<QDeclarativeAnchorLine>();
+ break;
+ case IR::SGAnchorLineType:
+ test.storetest.regType = qMetaTypeId<QSGAnchorLine>();
+ break;
+ case IR::ObjectType:
+ test.storetest.regType = QMetaType::QObjectStar;
+ break;
+ case IR::BoolType:
+ test.storetest.regType = QMetaType::Bool;
+ break;
+ case IR::IntType:
+ test.storetest.regType = QMetaType::Int;
+ break;
+ case IR::RealType:
+ test.storetest.regType = QMetaType::QReal;
+ break;
+ default:
+ discard();
+ return;
+ }
+ gen(test);
+ }
+
+ Instr store;
+ store.common.type = Instr::Store;
+ store.store.output = 0;
+ store.store.index = expression->property->index;
+ store.store.reg = storeReg;
+ store.store.exceptionId = exceptionId(s->line, s->column);
+ gen(store);
+}
+
+void QDeclarativeV4Compiler::dump(const QByteArray &programData)
+{
+ const QDeclarativeV4Program *program = (const QDeclarativeV4Program *)programData.constData();
+
+ qWarning() << "Program.bindings:" << program->bindings;
+ qWarning() << "Program.dataLength:" << program->dataLength;
+ qWarning() << "Program.subscriptions:" << program->subscriptions;
+ qWarning() << "Program.indentifiers:" << program->identifiers;
+
+ const int programSize = program->instructionCount;
+ const char *start = program->instructions();
+ const char *code = start;
+ const char *end = code + programSize;
+ while (code < end) {
+ Instr *instr = (Instr *) code;
+ instr->dump(code - start);
+ code += instr->size();
+ }
+}
+
+QDeclarativeFastProperties *QDeclarativeV4Compiler::fastPropertyAccessor()
+{
+ return fastProperties();
+}
+
+/*!
+Clear the state associated with attempting to compile a specific binding.
+This does not clear the global "committed binding" states.
+*/
+void QDeclarativeV4CompilerPrivate::resetInstanceState()
+{
+ registerCleanups.clear();
+ data = committed.data;
+ exceptions = committed.exceptions;
+ usedSubscriptionIds.clear();
+ subscriptionIds = committed.subscriptionIds;
+ registeredStrings = committed.registeredStrings;
+ bytecode.clear();
+ patches.clear();
+ currentReg = 0;
+}
+
+/*!
+Mark the last compile as successful, and add it to the "committed data"
+section.
+
+Returns the index for the committed binding.
+*/
+int QDeclarativeV4CompilerPrivate::commitCompile()
+{
+ int rv = committed.count();
+ committed.offsets << committed.bytecode.count();
+ committed.dependencies << usedSubscriptionIds;
+ committed.bytecode += bytecode.code();
+ committed.data = data;
+ committed.exceptions = exceptions;
+ committed.subscriptionIds = subscriptionIds;
+ committed.registeredStrings = registeredStrings;
+ return rv;
+}
+
+bool QDeclarativeV4CompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
+{
+ resetInstanceState();
+
+ if (expression->property->type == -1)
+ return false;
+
+ AST::SourceLocation location;
+ if (AST::ExpressionNode *astExpression = node->expressionCast()) {
+ location = astExpression->firstSourceLocation();
+ } else if (AST::Statement *astStatement = node->statementCast()) {
+ if (AST::Block *block = AST::cast<AST::Block *>(astStatement))
+ location = block->lbraceToken;
+ else if (AST::IfStatement *ifStmt = AST::cast<AST::IfStatement *>(astStatement))
+ location = ifStmt->ifToken;
+ else
+ return false;
+ } else {
+ return false;
+ }
+
+ IR::Module module;
+ IR::Function *function = 0;
+
+ QDeclarativeV4IRBuilder irBuilder(expression, engine);
+ if (!(function = irBuilder(&module, node)))
+ return false;
+
+ bool discarded = false;
+ qSwap(_discarded, discarded);
+ qSwap(_function, function);
+ trace(location.startLine, location.startColumn);
+ qSwap(_function, function);
+ qSwap(_discarded, discarded);
+
+ if (qmlVerboseCompiler()) {
+ QTextStream qerr(stderr, QIODevice::WriteOnly);
+ if (discarded)
+ qerr << "======== TODO ====== " << endl;
+ else
+ qerr << "==================== " << endl;
+ qerr << "\tline: " << location.startLine
+ << "\tcolumn: " << location.startColumn
+ << endl;
+ foreach (IR::BasicBlock *bb, function->basicBlocks)
+ bb->dump(qerr);
+ qerr << endl;
+ }
+
+ if (discarded || subscriptionIds.count() > 0xFFFF || registeredStrings.count() > 0xFFFF)
+ return false;
+
+ return true;
+}
+
+// Returns a reg
+int QDeclarativeV4CompilerPrivate::registerLiteralString(quint8 reg, const QString &str)
+{
+ // ### string cleanup
+
+ QByteArray strdata((const char *)str.constData(), str.length() * sizeof(QChar));
+ int offset = data.count();
+ data += strdata;
+
+ Instr string;
+ string.common.type = Instr::String;
+ string.string_value.reg = reg;
+ string.string_value.offset = offset;
+ string.string_value.length = str.length();
+ gen(string);
+
+ return reg;
+}
+
+// Returns an identifier offset
+int QDeclarativeV4CompilerPrivate::registerString(const QString &string)
+{
+ Q_ASSERT(!string.isEmpty());
+
+ QHash<QString, QPair<int, int> >::ConstIterator iter = registeredStrings.find(string);
+
+ if (iter == registeredStrings.end()) {
+ quint32 len = string.length();
+ QByteArray lendata((const char *)&len, sizeof(quint32));
+ QByteArray strdata((const char *)string.constData(), string.length() * sizeof(QChar));
+ strdata.prepend(lendata);
+ int rv = data.count();
+ data += strdata;
+
+ iter = registeredStrings.insert(string, qMakePair(registeredStrings.count(), rv));
+ }
+
+ Instr reg;
+ reg.common.type = Instr::InitString;
+ reg.initstring.offset = iter->first;
+ reg.initstring.dataIdx = iter->second;
+ gen(reg);
+ return reg.initstring.offset;
+}
+
+/*!
+Returns true if the current expression has not already subscribed to \a sub in currentBlockMask.
+*/
+bool QDeclarativeV4CompilerPrivate::blockNeedsSubscription(const QStringList &sub)
+{
+ QString str = sub.join(QLatin1String("."));
+
+ QHash<QString, int>::ConstIterator iter = subscriptionIds.find(str);
+ if (iter == subscriptionIds.end())
+ return true;
+
+ QHash<int, quint32>::ConstIterator uiter = usedSubscriptionIds.find(*iter);
+ if (uiter == usedSubscriptionIds.end())
+ return true;
+ else
+ return !(*uiter & currentBlockMask);
+}
+
+int QDeclarativeV4CompilerPrivate::subscriptionIndex(const QStringList &sub)
+{
+ QString str = sub.join(QLatin1String("."));
+ QHash<QString, int>::ConstIterator iter = subscriptionIds.find(str);
+ if (iter == subscriptionIds.end())
+ iter = subscriptionIds.insert(str, subscriptionIds.count());
+ if (!(usedSubscriptionIds[*iter] & currentBlockMask)) {
+ usedSubscriptionIds[*iter] |= currentBlockMask;
+ usedSubscriptionIdsChanged = true;
+ }
+ return *iter;
+}
+
+quint32 QDeclarativeV4CompilerPrivate::subscriptionBlockMask(const QStringList &sub)
+{
+ QString str = sub.join(QLatin1String("."));
+
+ QHash<QString, int>::ConstIterator iter = subscriptionIds.find(str);
+ Q_ASSERT(iter != subscriptionIds.end());
+
+ QHash<int, quint32>::ConstIterator uiter = usedSubscriptionIds.find(*iter);
+ Q_ASSERT(uiter != usedSubscriptionIds.end());
+
+ return *uiter;
+}
+
+quint8 QDeclarativeV4CompilerPrivate::exceptionId(quint32 line, quint32 column)
+{
+ quint8 rv = 0xFF;
+ if (exceptions.count() < 0xFF) {
+ rv = (quint8)exceptions.count();
+ quint64 e = line;
+ e <<= 32;
+ e |= column;
+ exceptions.append(e);
+ }
+ return rv;
+}
+
+quint8 QDeclarativeV4CompilerPrivate::exceptionId(QDeclarativeJS::AST::ExpressionNode *n)
+{
+ quint8 rv = 0xFF;
+ if (n && exceptions.count() < 0xFF) {
+ QDeclarativeJS::AST::SourceLocation l = n->firstSourceLocation();
+ rv = exceptionId(l.startLine, l.startColumn);
+ }
+ return rv;
+}
+
+QDeclarativeV4Compiler::QDeclarativeV4Compiler()
+: d(new QDeclarativeV4CompilerPrivate)
+{
+ qmlBindingsTest |= qmlBindingsTestEnv();
+}
+
+QDeclarativeV4Compiler::~QDeclarativeV4Compiler()
+{
+ delete d; d = 0;
+}
+
+/*
+Returns true if any bindings were compiled.
+*/
+bool QDeclarativeV4Compiler::isValid() const
+{
+ return !d->committed.bytecode.isEmpty();
+}
+
+/*
+-1 on failure, otherwise the binding index to use.
+*/
+int QDeclarativeV4Compiler::compile(const Expression &expression, QDeclarativeEnginePrivate *engine)
+{
+ if (!expression.expression.asAST()) return false;
+
+ if (!qmlExperimental() && expression.property->isValueTypeSubProperty)
+ return -1;
+
+ if (qmlDisableOptimizer())
+ return -1;
+
+ d->expression = &expression;
+ d->engine = engine;
+
+ if (d->compile(expression.expression.asAST())) {
+ return d->commitCompile();
+ } else {
+ return -1;
+ }
+}
+
+QByteArray QDeclarativeV4CompilerPrivate::buildSignalTable() const
+{
+ QHash<int, QList<QPair<int, quint32> > > table;
+
+ for (int ii = 0; ii < committed.count(); ++ii) {
+ const QHash<int, quint32> &deps = committed.dependencies.at(ii);
+ for (QHash<int, quint32>::ConstIterator iter = deps.begin(); iter != deps.end(); ++iter)
+ table[iter.key()].append(qMakePair(ii, iter.value()));
+ }
+
+ QVector<quint32> header;
+ QVector<quint32> data;
+ for (int ii = 0; ii < committed.subscriptionIds.count(); ++ii) {
+ header.append(committed.subscriptionIds.count() + data.count());
+ const QList<QPair<int, quint32> > &bindings = table[ii];
+ data.append(bindings.count());
+ for (int jj = 0; jj < bindings.count(); ++jj) {
+ data.append(bindings.at(jj).first);
+ data.append(bindings.at(jj).second);
+ }
+ }
+ header << data;
+
+ return QByteArray((const char *)header.constData(), header.count() * sizeof(quint32));
+}
+
+QByteArray QDeclarativeV4CompilerPrivate::buildExceptionData() const
+{
+ QByteArray rv;
+ rv.resize(committed.exceptions.count() * sizeof(quint64));
+ ::memcpy(rv.data(), committed.exceptions.constData(), rv.size());
+ return rv;
+}
+
+/*
+Returns the compiled program.
+*/
+QByteArray QDeclarativeV4Compiler::program() const
+{
+ QByteArray programData;
+
+ if (isValid()) {
+ QDeclarativeV4Program prog;
+ prog.bindings = d->committed.count();
+
+ Bytecode bc;
+ Instr jump;
+ jump.common.type = Instr::Jump;
+ jump.jump.reg = -1;
+
+ for (int ii = 0; ii < d->committed.count(); ++ii) {
+ jump.jump.count = d->committed.count() - ii - 1;
+ jump.jump.count*= jump.size();
+ jump.jump.count+= d->committed.offsets.at(ii);
+ bc.append(jump);
+ }
+
+
+ QByteArray bytecode = bc.code();
+ bytecode += d->committed.bytecode;
+
+ QByteArray data = d->committed.data;
+ while (data.count() % 4) data.append('\0');
+ prog.signalTableOffset = data.count();
+ data += d->buildSignalTable();
+ while (data.count() % 4) data.append('\0');
+ prog.exceptionDataOffset = data.count();
+ data += d->buildExceptionData();
+
+ prog.dataLength = 4 * ((data.size() + 3) / 4);
+ prog.subscriptions = d->committed.subscriptionIds.count();
+ prog.identifiers = d->committed.registeredStrings.count();
+ prog.instructionCount = bytecode.count();
+ int size = sizeof(QDeclarativeV4Program) + bytecode.count();
+ size += prog.dataLength;
+
+ programData.resize(size);
+ memcpy(programData.data(), &prog, sizeof(QDeclarativeV4Program));
+ if (prog.dataLength)
+ memcpy((char *)((QDeclarativeV4Program *)programData.data())->data(), data.constData(),
+ data.size());
+ memcpy((char *)((QDeclarativeV4Program *)programData.data())->instructions(), bytecode.constData(),
+ bytecode.count());
+ }
+
+ if (bindingsDump()) {
+ qWarning().nospace() << "Subscription slots:";
+
+ for (QHash<QString, int>::ConstIterator iter = d->committed.subscriptionIds.begin();
+ iter != d->committed.subscriptionIds.end();
+ ++iter) {
+ qWarning().nospace() << " " << iter.value() << "\t-> " << iter.key();
+ }
+
+
+ QDeclarativeV4Compiler::dump(programData);
+ }
+
+ return programData;
+}
+
+void QDeclarativeV4Compiler::enableBindingsTest(bool e)
+{
+ if (e)
+ qmlBindingsTest = true;
+ else
+ qmlBindingsTest = qmlBindingsTestEnv();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler_p.h b/src/declarative/qml/v4/qdeclarativev4compiler_p.h
new file mode 100644
index 0000000000..c10691dc87
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4compiler_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEV4COMPILER_P_H
+#define QDECLARATIVEV4COMPILER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qdeclarativeexpression_p.h"
+#include "private/qdeclarativebinding_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeFastProperties;
+class QDeclarativeTypeNameCache;
+class QDeclarativeV4CompilerPrivate;
+class Q_AUTOTEST_EXPORT QDeclarativeV4Compiler
+{
+public:
+ QDeclarativeV4Compiler();
+ ~QDeclarativeV4Compiler();
+
+ // Returns true if bindings were compiled
+ bool isValid() const;
+
+ struct Expression
+ {
+ QDeclarativeParser::Object *component;
+ QDeclarativeParser::Object *context;
+ QDeclarativeParser::Property *property;
+ QDeclarativeParser::Variant expression;
+ QHash<QString, QDeclarativeParser::Object *> ids;
+ QDeclarativeTypeNameCache *importCache;
+ QDeclarativeImports imports;
+ };
+
+ // -1 on failure, otherwise the binding index to use
+ int compile(const Expression &, QDeclarativeEnginePrivate *);
+
+ // Returns the compiled program
+ QByteArray program() const;
+
+ static void dump(const QByteArray &);
+ static QDeclarativeFastProperties *fastPropertyAccessor();
+ static void enableBindingsTest(bool);
+private:
+ QDeclarativeV4CompilerPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEV4COMPILER_P_H
+
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h b/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h
new file mode 100644
index 0000000000..1b2a998422
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEV4COMPILER_P_P_H
+#define QDECLARATIVEV4COMPILER_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qdeclarativev4instruction_p.h"
+#include "qdeclarativev4ir_p.h"
+#include <private/qdeclarativeparser_p.h>
+#include <private/qdeclarativeimport_p.h>
+#include <private/qdeclarativeengine_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeV4CompilerPrivate: protected QDeclarativeJS::IR::ExprVisitor,
+ protected QDeclarativeJS::IR::StmtVisitor
+{
+public:
+ QDeclarativeV4CompilerPrivate();
+
+ void resetInstanceState();
+ int commitCompile();
+
+ const QDeclarativeV4Compiler::Expression *expression;
+ QDeclarativeEnginePrivate *engine;
+
+ QString contextName() const { return QLatin1String("$$$SCOPE_") + QString::number((quintptr)expression->context, 16); }
+
+ bool compile(QDeclarativeJS::AST::Node *);
+
+ QHash<int, QPair<int, int> > registerCleanups;
+
+ int registerLiteralString(quint8 reg, const QString &);
+ int registerString(const QString &);
+ QHash<QString, QPair<int, int> > registeredStrings;
+ QByteArray data;
+
+ bool blockNeedsSubscription(const QStringList &);
+ int subscriptionIndex(const QStringList &);
+ quint32 subscriptionBlockMask(const QStringList &);
+
+ quint8 exceptionId(quint32 line, quint32 column);
+ quint8 exceptionId(QDeclarativeJS::AST::ExpressionNode *);
+ QVector<quint64> exceptions;
+
+ QHash<int, quint32> usedSubscriptionIds;
+
+ QHash<QString, int> subscriptionIds;
+ QDeclarativeJS::Bytecode bytecode;
+
+ // back patching
+ struct Patch {
+ QDeclarativeJS::IR::BasicBlock *block; // the basic block
+ int offset; // the index of the instruction to patch
+ Patch(QDeclarativeJS::IR::BasicBlock *block = 0, int index = -1)
+ : block(block), offset(index) {}
+ };
+ QVector<Patch> patches;
+
+ // Committed binding data
+ struct {
+ QList<int> offsets;
+ QList<QHash<int, quint32> > dependencies;
+
+ //QDeclarativeJS::Bytecode bytecode;
+ QByteArray bytecode;
+ QByteArray data;
+ QHash<QString, int> subscriptionIds;
+ QVector<quint64> exceptions;
+
+ QHash<QString, QPair<int, int> > registeredStrings;
+
+ int count() const { return offsets.count(); }
+ } committed;
+
+ QByteArray buildSignalTable() const;
+ QByteArray buildExceptionData() const;
+
+ void convertToReal(QDeclarativeJS::IR::Expr *expr, int reg);
+ void convertToInt(QDeclarativeJS::IR::Expr *expr, int reg);
+ void convertToBool(QDeclarativeJS::IR::Expr *expr, int reg);
+ quint8 instructionOpcode(QDeclarativeJS::IR::Binop *e);
+
+protected:
+
+ //
+ // tracing
+ //
+ void trace(int line, int column);
+ void trace(QVector<QDeclarativeJS::IR::BasicBlock *> *blocks);
+ void traceExpression(QDeclarativeJS::IR::Expr *e, quint8 r);
+
+ inline void gen(const QDeclarativeJS::Instr &i) { bytecode.append(i); }
+
+ //
+ // expressions
+ //
+ virtual void visitConst(QDeclarativeJS::IR::Const *e);
+ virtual void visitString(QDeclarativeJS::IR::String *e);
+ virtual void visitName(QDeclarativeJS::IR::Name *e);
+ virtual void visitTemp(QDeclarativeJS::IR::Temp *e);
+ virtual void visitUnop(QDeclarativeJS::IR::Unop *e);
+ virtual void visitBinop(QDeclarativeJS::IR::Binop *e);
+ virtual void visitCall(QDeclarativeJS::IR::Call *e);
+
+ //
+ // statements
+ //
+ virtual void visitExp(QDeclarativeJS::IR::Exp *s);
+ virtual void visitMove(QDeclarativeJS::IR::Move *s);
+ virtual void visitJump(QDeclarativeJS::IR::Jump *s);
+ virtual void visitCJump(QDeclarativeJS::IR::CJump *s);
+ virtual void visitRet(QDeclarativeJS::IR::Ret *s);
+
+private:
+ QStringList _subscribeName;
+ QDeclarativeJS::IR::Function *_function;
+ QDeclarativeJS::IR::BasicBlock *_block;
+ void discard() { _discarded = true; }
+ bool _discarded;
+ quint8 currentReg;
+
+ bool usedSubscriptionIdsChanged;
+ quint32 currentBlockMask;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEV4COMPILER_P_P_H
+
diff --git a/src/declarative/qml/v4/qdeclarativev4instruction.cpp b/src/declarative/qml/v4/qdeclarativev4instruction.cpp
new file mode 100644
index 0000000000..9c3bf914e0
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4instruction.cpp
@@ -0,0 +1,559 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativev4instruction_p.h"
+#include "qdeclarativev4bindings_p.h"
+
+#include <QtCore/qdebug.h>
+#include <private/qdeclarativeglobal_p.h>
+
+// Define this to do a test dump of all the instructions at startup. This is
+// helpful to test that each instruction's Instr::dump() case uses the correct
+// number of tabs etc and otherwise looks correct.
+// #define DEBUG_INSTR_DUMP
+
+QT_BEGIN_NAMESPACE
+
+DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
+
+namespace QDeclarativeJS {
+
+#ifdef DEBUG_INSTR_DUMP
+static struct DumpInstrAtStartup {
+ DumpInstrAtStartup() {
+#define DUMP_INSTR_AT_STARTUP(Type, FMT) { Instr i; i.common.type = Instr::Type; i.dump(0); }
+ FOR_EACH_V4_INSTR(DUMP_INSTR_AT_STARTUP);
+ }
+} dump_instr_at_startup;
+#endif
+
+int Instr::size() const
+{
+#define V4_RETURN_INSTR_SIZE(I, FMT) case I: return QML_V4_INSTR_SIZE(I, FMT);
+ switch (common.type) {
+ FOR_EACH_V4_INSTR(V4_RETURN_INSTR_SIZE)
+ }
+#undef V4_RETURN_INSTR_SIZE
+ return 0;
+}
+
+void Instr::dump(int address) const
+{
+ QByteArray leading;
+ if (address != -1) {
+ leading = QByteArray::number(address);
+ leading.prepend(QByteArray(8 - leading.count(), ' '));
+ leading.append("\t");
+ }
+
+#define INSTR_DUMP qWarning().nospace() << leading.constData()
+
+ switch (common.type) {
+ case Instr::Noop:
+ INSTR_DUMP << "\t" << "Noop";
+ break;
+ case Instr::BindingId:
+ INSTR_DUMP << id.line << ":" << id.column << ":";
+ break;
+ case Instr::Subscribe:
+ INSTR_DUMP << "\t" << "Subscribe" << "\t\t" << "Object_Reg(" << subscribeop.reg << ") Notify_Signal(" << subscribeop.index << ") -> Subscribe_Slot(" << subscribeop.offset << ")";
+ break;
+ case Instr::SubscribeId:
+ INSTR_DUMP << "\t" << "SubscribeId" << "\t\t" << "Id_Offset(" << subscribeop.index << ") -> Subscribe_Slot(" << subscribeop.offset << ")";
+ break;
+ case Instr::FetchAndSubscribe:
+ INSTR_DUMP << "\t" << "FetchAndSubscribe" << "\t" << "Object_Reg(" << fetchAndSubscribe.reg << ") Fast_Accessor(" << fetchAndSubscribe.function << ") -> Output_Reg(" << fetchAndSubscribe.reg << ") Subscription_Slot(" << fetchAndSubscribe.subscription << ")";
+ break;
+ case Instr::LoadId:
+ INSTR_DUMP << "\t" << "LoadId" << "\t\t\t" << "Id_Offset(" << load.index << ") -> Output_Reg(" << load.reg << ")";
+ break;
+ case Instr::LoadScope:
+ INSTR_DUMP << "\t" << "LoadScope" << "\t\t" << "-> Output_Reg(" << load.reg << ")";
+ break;
+ case Instr::LoadRoot:
+ INSTR_DUMP << "\t" << "LoadRoot" << "\t\t" << "-> Output_Reg(" << load.reg << ")";
+ break;
+ case Instr::LoadAttached:
+ INSTR_DUMP << "\t" << "LoadAttached" << "\t\t" << "Object_Reg(" << attached.reg << ") Attached_Index(" << attached.id << ") -> Output_Reg(" << attached.output << ")";
+ break;
+ case Instr::UnaryNot:
+ INSTR_DUMP << "\t" << "UnaryNot" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::UnaryMinusReal:
+ INSTR_DUMP << "\t" << "UnaryMinusReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::UnaryMinusInt:
+ INSTR_DUMP << "\t" << "UnaryMinusInt" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::UnaryPlusReal:
+ INSTR_DUMP << "\t" << "UnaryPlusReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::UnaryPlusInt:
+ INSTR_DUMP << "\t" << "UnaryPlusInt" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertBoolToInt:
+ INSTR_DUMP << "\t" << "ConvertBoolToInt" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertBoolToReal:
+ INSTR_DUMP << "\t" << "ConvertBoolToReal" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertBoolToString:
+ INSTR_DUMP << "\t" << "ConvertBoolToString" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertIntToBool:
+ INSTR_DUMP << "\t" << "ConvertIntToBool" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertIntToReal:
+ INSTR_DUMP << "\t" << "ConvertIntToReal" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertIntToString:
+ INSTR_DUMP << "\t" << "ConvertIntToString" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertRealToBool:
+ INSTR_DUMP << "\t" << "ConvertRealToBool" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertRealToInt:
+ INSTR_DUMP << "\t" << "ConvertRealToInt" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertRealToString:
+ INSTR_DUMP << "\t" << "ConvertRealToString" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertStringToBool:
+ INSTR_DUMP << "\t" << "ConvertStringToBool" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertStringToInt:
+ INSTR_DUMP << "\t" << "ConvertStringToInt" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::ConvertStringToReal:
+ INSTR_DUMP << "\t" << "ConvertStringToReal" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::MathSinReal:
+ INSTR_DUMP << "\t" << "MathSinReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::MathCosReal:
+ INSTR_DUMP << "\t" << "MathCosReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::MathRoundReal:
+ INSTR_DUMP << "\t" << "MathRoundReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::MathFloorReal:
+ INSTR_DUMP << "\t" << "MathFloorReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::MathPIReal:
+ INSTR_DUMP << "\t" << "MathPIReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
+ break;
+ case Instr::Real:
+ INSTR_DUMP << "\t" << "Real" << "\t\t\t" << "Constant(" << real_value.value << ") -> Output_Reg(" << real_value.reg << ")";
+ break;
+ case Instr::Int:
+ INSTR_DUMP << "\t" << "Int" << "\t\t\t" << "Constant(" << int_value.value << ") -> Output_Reg(" << int_value.reg << ")";
+ break;
+ case Instr::Bool:
+ INSTR_DUMP << "\t" << "Bool" << "\t\t\t" << "Constant(" << bool_value.value << ") -> Output_Reg(" << bool_value.reg << ")";
+ break;
+ case Instr::String:
+ INSTR_DUMP << "\t" << "String" << "\t\t\t" << "String_DataIndex(" << string_value.offset << ") String_Length(" << string_value.length << ") -> Output_Register(" << string_value.reg << ")";
+ break;
+ case Instr::EnableV4Test:
+ INSTR_DUMP << "\t" << "EnableV4Test" << "\t\t" << "String_DataIndex(" << string_value.offset << ") String_Length(" << string_value.length << ")";
+ break;
+ case Instr::TestV4Store:
+ INSTR_DUMP << "\t" << "TestV4Store" << "\t\t" << "Input_Reg(" << storetest.reg << ") Reg_Type(" << storetest.regType << ")";
+ break;
+ case Instr::BitAndInt:
+ INSTR_DUMP << "\t" << "BitAndInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::BitOrInt:
+ INSTR_DUMP << "\t" << "BitOrInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::BitXorInt:
+ INSTR_DUMP << "\t" << "BitXorInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::AddReal:
+ INSTR_DUMP << "\t" << "AddReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::AddString:
+ INSTR_DUMP << "\t" << "AddString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::SubReal:
+ INSTR_DUMP << "\t" << "SubReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::MulReal:
+ INSTR_DUMP << "\t" << "MulReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::DivReal:
+ INSTR_DUMP << "\t" << "DivReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::ModReal:
+ INSTR_DUMP << "\t" << "ModReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::LShiftInt:
+ INSTR_DUMP << "\t" << "LShiftInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::RShiftInt:
+ INSTR_DUMP << "\t" << "RShiftInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::URShiftInt:
+ INSTR_DUMP << "\t" << "URShiftInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::GtReal:
+ INSTR_DUMP << "\t" << "GtReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::LtReal:
+ INSTR_DUMP << "\t" << "LtReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::GeReal:
+ INSTR_DUMP << "\t" << "GeReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::LeReal:
+ INSTR_DUMP << "\t" << "LeReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::EqualReal:
+ INSTR_DUMP << "\t" << "EqualReal" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::NotEqualReal:
+ INSTR_DUMP << "\t" << "NotEqualReal" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::StrictEqualReal:
+ INSTR_DUMP << "\t" << "StrictEqualReal" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::StrictNotEqualReal:
+ INSTR_DUMP << "\t" << "StrictNotEqualReal" << "\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::GtString:
+ INSTR_DUMP << "\t" << "GtString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::LtString:
+ INSTR_DUMP << "\t" << "LtString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::GeString:
+ INSTR_DUMP << "\t" << "GeString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::LeString:
+ INSTR_DUMP << "\t" << "LeString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::EqualString:
+ INSTR_DUMP << "\t" << "EqualString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::NotEqualString:
+ INSTR_DUMP << "\t" << "NotEqualString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::StrictEqualString:
+ INSTR_DUMP << "\t" << "StrictEqualString" << "\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::StrictNotEqualString:
+ INSTR_DUMP << "\t" << "StrictNotEqualString" << "\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
+ break;
+ case Instr::NewString:
+ INSTR_DUMP << "\t" << "NewString" << "\t\t" << "Register(" << construct.reg << ")";
+ break;
+ case Instr::NewUrl:
+ INSTR_DUMP << "\t" << "NewUrl" << "\t\t\t" << "Register(" << construct.reg << ")";
+ break;
+ case Instr::CleanupRegister:
+ INSTR_DUMP << "\t" << "CleanupRegister" << "\t\t" << "Register(" << cleanup.reg << ")";
+ break;
+ case Instr::Fetch:
+ INSTR_DUMP << "\t" << "Fetch" << "\t\t\t" << "Object_Reg(" << fetch.reg << ") Property_Index(" << fetch.index << ") -> Output_Reg(" << fetch.reg << ")";
+ break;
+ case Instr::Store:
+ INSTR_DUMP << "\t" << "Store" << "\t\t\t" << "Input_Reg(" << store.reg << ") -> Object_Reg(" << store.output << ") Property_Index(" << store.index << ")";
+ break;
+ case Instr::Copy:
+ INSTR_DUMP << "\t" << "Copy" << "\t\t\t" << "Input_Reg(" << copy.src << ") -> Output_Reg(" << copy.reg << ")";
+ break;
+ case Instr::Jump:
+ if (jump.reg != -1) {
+ INSTR_DUMP << "\t" << "Jump" << "\t\t\t" << "Address(" << (address + size() + jump.count) << ") [if false == Input_Reg(" << jump.reg << ")]";
+ } else {
+ INSTR_DUMP << "\t" << "Jump" << "\t\t\t" << "Address(" << (address + size() + jump.count) << ")";
+ }
+ break;
+ case Instr::BranchFalse:
+ INSTR_DUMP << "\t" << "BranchFalse" << "\t\t" << "Address(" << (address + size() + branchop.offset) << ") [if false == Input_Reg(" << branchop.reg << ")]";
+ break;
+ case Instr::BranchTrue:
+ INSTR_DUMP << "\t" << "BranchTrue" << "\t\t" << "Address(" << (address + size() + branchop.offset) << ") [if true == Input_Reg(" << branchop.reg << ")]";
+ break;
+ case Instr::Branch:
+ INSTR_DUMP << "\t" << "Branch" << "\t\t\t" << "Address(" << (address + size() + branchop.offset) << ")";
+ break;
+ case Instr::InitString:
+ INSTR_DUMP << "\t" << "InitString" << "\t\t" << "String_DataIndex(" << initstring.dataIdx << ") -> String_Slot(" << initstring.offset << ")";
+ break;
+ case Instr::Block:
+ INSTR_DUMP << "\t" << "Block" << "\t\t\t" << "Mask(" << QByteArray::number(blockop.block, 16).constData() << ")";
+ break;
+ default:
+ INSTR_DUMP << "\t" << "Unknown";
+ break;
+ }
+}
+
+void Instr::noop()
+{
+ common.type = Noop;
+}
+
+void Instr::load_root(quint8 reg)
+{
+ common.type = LoadRoot;
+ load.reg = reg;
+ load.index = 0;
+}
+
+void Instr::load_scope(quint8 reg)
+{
+ common.type = LoadScope;
+ load.reg = reg;
+ load.index = 0;
+}
+
+void Instr::load_id(quint8 reg, quint32 idIndex)
+{
+ common.type = LoadId;
+ load.reg = reg;
+ load.index = idIndex;
+}
+
+void Instr::subscribe(qint8 reg, quint16 subscribeSlot, quint32 notifyIndex)
+{
+ common.type = Instr::Subscribe;
+ subscribeop.reg = reg;
+ subscribeop.offset = subscribeSlot;
+ subscribeop.index = notifyIndex;
+}
+
+void Instr::subscribeId(qint8 reg, quint16 subscribeSlot, quint32 idIndex)
+{
+ common.type = Instr::SubscribeId;
+ subscribeop.reg = reg;
+ subscribeop.offset = subscribeSlot;
+ subscribeop.index = idIndex;
+}
+
+void Instr::move_reg_bool(quint8 reg, bool value)
+{
+ common.type = Bool;
+ bool_value.reg = reg;
+ bool_value.value = value;
+}
+
+void Instr::move_reg_int(quint8 reg, int value)
+{
+ common.type = Int;
+ int_value.reg = reg;
+ int_value.value = value;
+}
+
+void Instr::move_reg_qreal(quint8 reg, qreal value)
+{
+ common.type = Real;
+ real_value.reg = reg;
+ real_value.value = value;
+}
+
+void Instr::move_reg_reg(quint8 reg, quint8 src)
+{
+ common.type = Copy;
+ copy.reg = reg;
+ copy.src = src;
+}
+
+void Instr::unary_not(quint8 dest, quint8 src)
+{
+ common.type = UnaryNot;
+ unaryop.src = src;
+ unaryop.output = dest;
+}
+
+void Instr::uminus_real(quint8 dest, quint8 src)
+{
+ common.type = UnaryMinusReal;
+ unaryop.src = src;
+ unaryop.output = dest;
+}
+
+void Instr::uminus_int(quint8 dest, quint8 src)
+{
+ common.type = UnaryMinusInt;
+ unaryop.src = src;
+ unaryop.output = dest;
+}
+
+void Instr::uplus_real(quint8 dest, quint8 src)
+{
+ common.type = UnaryPlusReal;
+ unaryop.src = src;
+ unaryop.output = dest;
+}
+
+void Instr::uplus_int(quint8 dest, quint8 src)
+{
+ common.type = UnaryPlusInt;
+ unaryop.src = src;
+ unaryop.output = dest;
+}
+
+void Instr::ucompl_real(quint8 dest, quint8 src)
+{
+ Q_UNUSED(dest);
+ Q_UNUSED(src);
+ if (qmlVerboseCompiler())
+ qWarning() << "TODO" << Q_FUNC_INFO;
+}
+
+void Instr::ucompl_int(quint8 dest, quint8 src)
+{
+ Q_UNUSED(dest);
+ Q_UNUSED(src);
+ if (qmlVerboseCompiler())
+ qWarning() << "TODO" << Q_FUNC_INFO;
+}
+
+void Instr::math_sin_real(quint8 reg)
+{
+ common.type = MathSinReal;
+ unaryop.src = reg;
+ unaryop.output = reg;
+}
+
+void Instr::math_cos_real(quint8 reg)
+{
+ common.type = MathCosReal;
+ unaryop.src = reg;
+ unaryop.output = reg;
+}
+
+void Instr::math_round_real(quint8 reg)
+{
+ common.type = MathRoundReal;
+ unaryop.src = reg;
+ unaryop.output = reg;
+}
+
+void Instr::math_floor_real(quint8 reg)
+{
+ common.type = MathFloorReal;
+ unaryop.src = reg;
+ unaryop.output = reg;
+}
+
+void Instr::math_pi_real(quint8 reg)
+{
+ common.type = MathPIReal;
+ unaryop.src = reg;
+ unaryop.output = reg;
+}
+
+void Instr::branch_true(quint8 reg, qint16 offset)
+{
+ common.type = BranchTrue;
+ branchop.reg = reg;
+ branchop.offset = offset;
+}
+
+void Instr::branch_false(quint8 reg, qint16 offset)
+{
+ common.type = BranchFalse;
+ branchop.reg = reg;
+ branchop.offset = offset;
+}
+
+void Instr::branch(qint16 offset)
+{
+ common.type = Branch;
+ branchop.offset = offset;
+}
+
+void Instr::block(quint32 mask)
+{
+ common.type = Block;
+ blockop.block = mask;
+}
+
+Bytecode::Bytecode()
+{
+#ifdef QML_THREADED_INTERPRETER
+ decodeInstr = QDeclarativeV4Bindings::getDecodeInstrTable();
+#endif
+}
+
+void Bytecode::append(const Instr &instr)
+{
+ const char *it;
+#ifdef QML_THREADED_INTERPRETER
+ Instr i = instr;
+ i.common.code = decodeInstr[i.common.type];
+ it = (const char *) &i;
+#else
+ it = (const char *) &instr;
+#endif
+ d.append(it, instr.size());
+}
+
+void Bytecode::append(const QVector<Instr> &instrs)
+{
+ foreach (const Instr &i, instrs)
+ append(i);
+}
+
+int Bytecode::remove(int offset)
+{
+ const Instr *instr = (const Instr *) (d.begin() + offset);
+ const int instrSize = instr->size();
+ d.remove(offset, instrSize);
+ return instrSize;
+}
+
+const Instr &Bytecode::operator[](int offset) const
+{
+ return *((const Instr *) (d.begin() + offset));
+}
+
+Instr &Bytecode::operator[](int offset)
+{
+ return *((Instr *) (d.begin() + offset));
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4instruction_p.h b/src/declarative/qml/v4/qdeclarativev4instruction_p.h
new file mode 100644
index 0000000000..67b152adea
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4instruction_p.h
@@ -0,0 +1,444 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEV4INSTRUCTION_P_H
+#define QDECLARATIVEV4INSTRUCTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qvector.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define FOR_EACH_V4_INSTR(F) \
+ F(Noop, common) \
+ F(BindingId, id) \
+ F(Subscribe, subscribeop) \
+ F(SubscribeId, subscribeop) \
+ F(FetchAndSubscribe, fetchAndSubscribe) \
+ F(LoadId, load) \
+ F(LoadScope, load) \
+ F(LoadRoot, load) \
+ F(LoadAttached, attached) \
+ F(UnaryNot, unaryop) \
+ F(UnaryMinusReal, unaryop) \
+ F(UnaryMinusInt, unaryop) \
+ F(UnaryPlusReal, unaryop) \
+ F(UnaryPlusInt, unaryop) \
+ F(ConvertBoolToInt, unaryop) \
+ F(ConvertBoolToReal, unaryop) \
+ F(ConvertBoolToString, unaryop) \
+ F(ConvertIntToBool, unaryop) \
+ F(ConvertIntToReal, unaryop) \
+ F(ConvertIntToString, unaryop) \
+ F(ConvertRealToBool, unaryop) \
+ F(ConvertRealToInt, unaryop) \
+ F(ConvertRealToString, unaryop) \
+ F(ConvertStringToBool, unaryop) \
+ F(ConvertStringToInt, unaryop) \
+ F(ConvertStringToReal, unaryop) \
+ F(MathSinReal, unaryop) \
+ F(MathCosReal, unaryop) \
+ F(MathRoundReal, unaryop) \
+ F(MathFloorReal, unaryop) \
+ F(MathPIReal, unaryop) \
+ F(Real, real_value) \
+ F(Int, int_value) \
+ F(Bool, bool_value) \
+ F(String, string_value) \
+ F(EnableV4Test, string_value) \
+ F(TestV4Store, storetest) \
+ F(BitAndInt, binaryop) \
+ F(BitOrInt, binaryop) \
+ F(BitXorInt, binaryop) \
+ F(AddReal, binaryop) \
+ F(AddString, binaryop) \
+ F(SubReal, binaryop) \
+ F(MulReal, binaryop) \
+ F(DivReal, binaryop) \
+ F(ModReal, binaryop) \
+ F(LShiftInt, binaryop) \
+ F(RShiftInt, binaryop) \
+ F(URShiftInt, binaryop) \
+ F(GtReal, binaryop) \
+ F(LtReal, binaryop) \
+ F(GeReal, binaryop) \
+ F(LeReal, binaryop) \
+ F(EqualReal, binaryop) \
+ F(NotEqualReal, binaryop) \
+ F(StrictEqualReal, binaryop) \
+ F(StrictNotEqualReal, binaryop) \
+ F(GtString, binaryop) \
+ F(LtString, binaryop) \
+ F(GeString, binaryop) \
+ F(LeString, binaryop) \
+ F(EqualString, binaryop) \
+ F(NotEqualString, binaryop) \
+ F(StrictEqualString, binaryop) \
+ F(StrictNotEqualString, binaryop) \
+ F(NewString, construct) \
+ F(NewUrl, construct) \
+ F(CleanupRegister, cleanup) \
+ F(Copy, copy) \
+ F(Fetch, fetch) \
+ F(Store, store) \
+ F(Jump, jump) \
+ F(BranchTrue, branchop) \
+ F(BranchFalse, branchop) \
+ F(Branch, branchop) \
+ F(Block, blockop) \
+ /* Speculative property resolution */ \
+ F(InitString, initstring)
+
+#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
+# define QML_THREADED_INTERPRETER
+#endif
+
+#ifdef Q_ALIGNOF
+# define QML_V4_INSTR_ALIGN_MASK (Q_ALIGNOF(Instr) - 1)
+#else
+# define QML_V4_INSTR_ALIGN_MASK (sizeof(void *) - 1)
+#endif
+
+#define QML_V4_INSTR_ENUM(I, FMT) I,
+#define QML_V4_INSTR_ADDR(I, FMT) &&op_##I,
+#define QML_V4_INSTR_SIZE(I, FMT) ((sizeof(Instr::instr_##FMT) + QML_V4_INSTR_ALIGN_MASK) & ~QML_V4_INSTR_ALIGN_MASK)
+
+#ifdef QML_THREADED_INTERPRETER
+# define QML_V4_BEGIN_INSTR(I,FMT) op_##I:
+# define QML_V4_END_INSTR(I,FMT) code += QML_V4_INSTR_SIZE(I, FMT); instr = (const Instr *) code; goto *instr->common.code;
+# define QML_V4_INSTR_HEADER void *code;
+#else
+# define QML_V4_BEGIN_INSTR(I,FMT) case Instr::I:
+# define QML_V4_END_INSTR(I,FMT) code += QML_V4_INSTR_SIZE(I, FMT); instr = (const Instr *) code; break;
+# define QML_V4_INSTR_HEADER
+#endif
+
+namespace QDeclarativeJS {
+
+union Instr {
+ int size() const;
+ void dump(int = -1) const;
+ void noop();
+ void load_root(quint8 reg);
+ void load_scope(quint8 reg);
+ void load_id(quint8 reg, quint32 idIndex);
+ void subscribe(qint8 reg, quint16 offset, quint32 index);
+ void subscribeId(qint8 reg, quint16 offset, quint32 index);
+ void move_reg_bool(quint8 reg, bool value);
+ void move_reg_int(quint8 reg, int value);
+ void move_reg_qreal(quint8 reg, qreal value);
+ void move_reg_reg(quint8 reg, quint8 src);
+
+ void unary_not(quint8 dest, quint8 src);
+ void uminus_real(quint8 dest, quint8 src);
+ void uminus_int(quint8 dest, quint8 src);
+ void uplus_real(quint8 dest, quint8 src);
+ void uplus_int(quint8 dest, quint8 src);
+ void ucompl_real(quint8 dest, quint8 src);
+ void ucompl_int(quint8 dest, quint8 src);
+
+ void math_sin_real(quint8 reg);
+ void math_cos_real(quint8 reg);
+ void math_round_real(quint8 reg);
+ void math_floor_real(quint8 reg);
+ void math_pi_real(quint8 reg);
+ void branch_true(quint8 reg, qint16 offset);
+ void branch_false(quint8 reg, qint16 offset);
+ void branch(qint16 offset);
+ void block(quint32 mask);
+
+ enum {
+ FOR_EACH_V4_INSTR(QML_V4_INSTR_ENUM)
+ };
+
+ struct instr_common {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ };
+
+ struct instr_id {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ quint16 column;
+ quint32 line;
+ };
+
+ struct instr_init {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ quint16 subscriptions;
+ quint16 identifiers;
+ };
+
+ struct instr_subscribeop {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ quint16 offset;
+ quint32 index;
+ };
+
+ struct instr_load {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ quint32 index;
+ };
+
+ struct instr_attached {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 output;
+ qint8 reg;
+ quint8 exceptionId;
+ quint32 id;
+ };
+
+ struct instr_store {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 output;
+ qint8 reg;
+ quint8 exceptionId;
+ quint32 index;
+ };
+
+ struct instr_storetest {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ qint32 regType;
+ };
+
+ struct instr_fetchAndSubscribe {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ quint8 exceptionId;
+ quint8 valueType;
+ quint16 subscription;
+ quint16 function;
+ };
+
+ struct instr_fetch{
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ quint8 exceptionId;
+ quint8 valueType;
+ quint32 index;
+ };
+
+ struct instr_copy {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ qint8 src;
+ };
+
+ struct instr_construct {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ };
+
+ struct instr_real_value {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ qreal value; // XXX Makes the instruction 12 bytes
+ };
+
+ struct instr_int_value {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ int value;
+ };
+
+ struct instr_bool_value {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ bool value;
+ };
+
+ struct instr_string_value {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ quint16 length;
+ quint32 offset;
+ };
+
+ struct instr_binaryop {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 output;
+ qint8 left;
+ qint8 right;
+ };
+
+ struct instr_unaryop {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 output;
+ qint8 src;
+ };
+
+ struct instr_jump {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ quint32 count;
+ };
+
+ struct instr_find {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ qint8 src;
+ quint8 exceptionId;
+ quint16 name;
+ quint16 subscribeIndex;
+ };
+
+ struct instr_cleanup {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ qint8 reg;
+ };
+
+ struct instr_initstring {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ quint16 offset;
+ quint32 dataIdx;
+ };
+
+ struct instr_branchop {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ quint8 reg;
+ qint16 offset;
+ };
+
+ struct instr_blockop {
+ QML_V4_INSTR_HEADER
+ quint8 type;
+ quint32 block;
+ };
+
+ instr_common common;
+ instr_id id;
+ instr_init init;
+ instr_subscribeop subscribeop;
+ instr_load load;
+ instr_attached attached;
+ instr_store store;
+ instr_storetest storetest;
+ instr_fetchAndSubscribe fetchAndSubscribe;
+ instr_fetch fetch;
+ instr_copy copy;
+ instr_construct construct;
+ instr_real_value real_value;
+ instr_int_value int_value;
+ instr_bool_value bool_value;
+ instr_string_value string_value;
+ instr_binaryop binaryop;
+ instr_unaryop unaryop;
+ instr_jump jump;
+ instr_find find;
+ instr_cleanup cleanup;
+ instr_initstring initstring;
+ instr_branchop branchop;
+ instr_blockop blockop;
+};
+
+class Bytecode
+{
+ Q_DISABLE_COPY(Bytecode)
+
+public:
+ Bytecode();
+
+ QByteArray code() const { return d; }
+ const char *constData() const { return d.constData(); }
+ int size() const { return d.size(); }
+ int count() const { return d.count(); }
+ void clear() { d.clear(); }
+ bool isEmpty() const { return d.isEmpty(); }
+ void append(const Instr &instr);
+ void append(const QVector<Instr> &instrs);
+ int remove(int index);
+
+ const Instr &operator[](int offset) const;
+ Instr &operator[](int offset);
+
+private:
+ QByteArray d;
+#ifdef QML_THREADED_INTERPRETER
+ void **decodeInstr;
+#endif
+};
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEV4INSTRUCTION_P_H
+
diff --git a/src/declarative/qml/v4/qdeclarativev4ir.cpp b/src/declarative/qml/v4/qdeclarativev4ir.cpp
new file mode 100644
index 0000000000..7876e6ccea
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4ir.cpp
@@ -0,0 +1,832 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativev4ir_p.h"
+
+#include <QtCore/qtextstream.h>
+#include <QtCore/qdebug.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QDeclarativeJS {
+namespace IR {
+
+inline const char *typeName(Type t)
+{
+ switch (t) {
+ case InvalidType: return "invalid";
+ case UndefinedType: return "undefined";
+ case NullType: return "null";
+ case VoidType: return "void";
+ case StringType: return "string";
+ case UrlType: return "url";
+ case AnchorLineType: return "AnchorLine";
+ case SGAnchorLineType: return "SGAnchorLine";
+ case AttachType: return "AttachType";
+ case ObjectType: return "object";
+ case BoolType: return "bool";
+ case IntType: return "int";
+ case RealType: return "qreal";
+ case RealNaNType: return "NaN";
+ default: return "invalid";
+ }
+}
+
+IR::Type maxType(IR::Type left, IR::Type right)
+{
+ if (left == right)
+ return left;
+ else if (left >= IR::FirstNumberType && right >= IR::FirstNumberType)
+ return qMax(left, right);
+ else if ((left >= IR::FirstNumberType && right == IR::StringType) ||
+ (right >= IR::FirstNumberType && left == IR::StringType))
+ return IR::StringType;
+ else
+ return IR::InvalidType;
+}
+
+
+const char *opname(AluOp op)
+{
+ switch (op) {
+ case OpInvalid: return "?";
+
+ case OpIfTrue: return "(bool)";
+ case OpNot: return "!";
+ case OpUMinus: return "-";
+ case OpUPlus: return "+";
+ case OpCompl: return "~";
+
+ case OpBitAnd: return "&";
+ case OpBitOr: return "|";
+ case OpBitXor: return "^";
+
+ case OpAdd: return "+";
+ case OpSub: return "-";
+ case OpMul: return "*";
+ case OpDiv: return "/";
+ case OpMod: return "%";
+
+ case OpLShift: return "<<";
+ case OpRShift: return ">>";
+ case OpURShift: return ">>>";
+
+ case OpGt: return ">";
+ case OpLt: return "<";
+ case OpGe: return ">=";
+ case OpLe: return "<=";
+ case OpEqual: return "==";
+ case OpNotEqual: return "!=";
+ case OpStrictEqual: return "===";
+ case OpStrictNotEqual: return "!==";
+
+ case OpAnd: return "&&";
+ case OpOr: return "||";
+
+ default: return "?";
+
+ } // switch
+}
+
+AluOp binaryOperator(int op)
+{
+ switch (static_cast<QSOperator::Op>(op)) {
+ case QSOperator::Add: return OpAdd;
+ case QSOperator::And: return OpAnd;
+ case QSOperator::BitAnd: return OpBitAnd;
+ case QSOperator::BitOr: return OpBitOr;
+ case QSOperator::BitXor: return OpBitXor;
+ case QSOperator::Div: return OpDiv;
+ case QSOperator::Equal: return OpEqual;
+ case QSOperator::Ge: return OpGe;
+ case QSOperator::Gt: return OpGt;
+ case QSOperator::Le: return OpLe;
+ case QSOperator::LShift: return OpLShift;
+ case QSOperator::Lt: return OpLt;
+ case QSOperator::Mod: return OpMod;
+ case QSOperator::Mul: return OpMul;
+ case QSOperator::NotEqual: return OpNotEqual;
+ case QSOperator::Or: return OpOr;
+ case QSOperator::RShift: return OpRShift;
+ case QSOperator::StrictEqual: return OpStrictEqual;
+ case QSOperator::StrictNotEqual: return OpStrictNotEqual;
+ case QSOperator::Sub: return OpSub;
+ case QSOperator::URShift: return OpURShift;
+ default: return OpInvalid;
+ }
+}
+
+void Const::dump(QTextStream &out)
+{
+ out << value;
+}
+
+void String::dump(QTextStream &out)
+{
+ out << '"' << escape(value) << '"';
+}
+
+QString String::escape(const QString &s)
+{
+ QString r;
+ foreach (const QChar &ch, s) {
+ if (ch == QLatin1Char('\n'))
+ r += QLatin1String("\\n");
+ else if (ch == QLatin1Char('\r'))
+ r += QLatin1String("\\r");
+ else if (ch == QLatin1Char('\\'))
+ r += QLatin1String("\\\\");
+ else if (ch == QLatin1Char('"'))
+ r += QLatin1String("\\\"");
+ else if (ch == QLatin1Char('\''))
+ r += QLatin1String("\\'");
+ else
+ r += ch;
+ }
+ return r;
+}
+
+Name::Name(Name *base, Type type, const QString &id, Symbol symbol, quint32 line, quint32 column)
+: Expr(type)
+ , base(base)
+ , id(id)
+ , symbol(symbol)
+ , ptr(0)
+ , index(-1)
+ , storage(MemberStorage)
+ , builtin(NoBuiltinSymbol)
+ , line(line)
+ , column(column)
+{
+ if (id.length() == 8 && id == QLatin1String("Math.sin")) {
+ builtin = MathSinBultinFunction;
+ } else if (id.length() == 8 && id == QLatin1String("Math.cos")) {
+ builtin = MathCosBultinFunction;
+ } else if (id.length() == 10 && id == QLatin1String("Math.round")) {
+ builtin = MathRoundBultinFunction;
+ } else if (id.length() == 10 && id == QLatin1String("Math.floor)")) {
+ builtin = MathFloorBultinFunction;
+ } else if (id.length() == 7 && id == QLatin1String("Math.PI")) {
+ builtin = MathPIBuiltinConstant;
+ type = RealType;
+ }
+}
+
+void Name::dump(QTextStream &out)
+{
+ if (base) {
+ base->dump(out);
+ out << '.';
+ }
+
+ out << id;
+}
+
+void Temp::dump(QTextStream &out)
+{
+ out << 't' << index;
+}
+
+void Unop::dump(QTextStream &out)
+{
+ out << opname(op);
+ expr->dump(out);
+}
+
+Type Unop::typeForOp(AluOp op, Expr *expr)
+{
+ switch (op) {
+ case OpIfTrue: return BoolType;
+ case OpNot: return BoolType;
+
+ case OpUMinus:
+ case OpUPlus:
+ case OpCompl:
+ return maxType(expr->type, RealType);
+
+ default:
+ break;
+ }
+
+ return InvalidType;
+}
+
+void Binop::dump(QTextStream &out)
+{
+ left->dump(out);
+ out << ' ' << opname(op) << ' ';
+ right->dump(out);
+}
+
+Type Binop::typeForOp(AluOp op, Expr *left, Expr *right)
+{
+ if (! (left && right))
+ return InvalidType;
+
+ switch (op) {
+ case OpInvalid:
+ return InvalidType;
+
+ // unary operators
+ case OpIfTrue:
+ case OpNot:
+ case OpUMinus:
+ case OpUPlus:
+ case OpCompl:
+ return InvalidType;
+
+ // bit fields
+ case OpBitAnd:
+ case OpBitOr:
+ case OpBitXor:
+ return IntType;
+
+ case OpAdd:
+ if (left->type == StringType)
+ return StringType;
+ return RealType;
+
+ case OpSub:
+ case OpMul:
+ case OpDiv:
+ case OpMod:
+ return RealType;
+
+ case OpLShift:
+ case OpRShift:
+ case OpURShift:
+ return IntType;
+
+ case OpAnd:
+ case OpOr:
+ return BoolType;
+
+ case OpGt:
+ case OpLt:
+ case OpGe:
+ case OpLe:
+ case OpEqual:
+ case OpNotEqual:
+ case OpStrictEqual:
+ case OpStrictNotEqual:
+ return BoolType;
+ } // switch
+
+ return InvalidType;
+}
+
+void Call::dump(QTextStream &out)
+{
+ base->dump(out);
+ out << '(';
+ for (int i = 0; i < args.size(); ++i) {
+ if (i)
+ out << ", ";
+ args.at(i)->dump(out);
+ }
+ out << ')';
+}
+
+Type Call::typeForFunction(Expr *base)
+{
+ if (! base)
+ return InvalidType;
+
+ if (Name *name = base->asName()) {
+ switch (name->builtin) {
+ case MathSinBultinFunction:
+ case MathCosBultinFunction:
+ return RealType;
+
+ case MathRoundBultinFunction:
+ case MathFloorBultinFunction:
+ return IntType;
+
+ case NoBuiltinSymbol:
+ case MathPIBuiltinConstant:
+ break;
+ }
+ } // switch
+
+ return InvalidType;
+}
+
+void Exp::dump(QTextStream &out, Mode)
+{
+ out << "(void) ";
+ expr->dump(out);
+ out << ';';
+}
+
+void Move::dump(QTextStream &out, Mode)
+{
+ target->dump(out);
+ out << " = ";
+ if (source->type != target->type)
+ out << typeName(source->type) << "_to_" << typeName(target->type) << '(';
+ source->dump(out);
+ if (source->type != target->type)
+ out << ')';
+ out << ';';
+}
+
+void Jump::dump(QTextStream &out, Mode mode)
+{
+ Q_UNUSED(mode);
+ out << "goto " << 'L' << target << ';';
+}
+
+void CJump::dump(QTextStream &out, Mode mode)
+{
+ Q_UNUSED(mode);
+ out << "if (";
+ cond->dump(out);
+ out << ") goto " << 'L' << iftrue << "; else goto " << 'L' << iffalse << ';';
+}
+
+void Ret::dump(QTextStream &out, Mode)
+{
+ out << "return";
+ if (expr) {
+ out << ' ';
+ expr->dump(out);
+ }
+ out << ';';
+}
+
+Function::~Function()
+{
+ qDeleteAll(basicBlocks);
+ qDeleteAll(temps);
+}
+
+BasicBlock *Function::newBasicBlock()
+{
+ const int index = basicBlocks.size();
+ return i(new BasicBlock(this, index));
+}
+
+void Function::dump(QTextStream &out)
+{
+ QString fname;
+ if (name)
+ fname = name->asString();
+ else
+ fname = QLatin1String("$anonymous");
+ out << "function " << fname << "() {" << endl;
+ foreach (BasicBlock *bb, basicBlocks) {
+ bb->dump(out);
+ }
+ out << '}' << endl;
+}
+
+Temp *BasicBlock::TEMP(Type type, int index)
+{
+ return function->e(new Temp(type, index));
+}
+
+Temp *BasicBlock::TEMP(Type type)
+{
+ return TEMP(type, function->tempCount++);
+}
+
+Expr *BasicBlock::CONST(double value)
+{
+ return CONST(IR::RealType, value);
+}
+
+Expr *BasicBlock::CONST(Type type, double value)
+{
+ return function->e(new Const(type, value));
+}
+
+Expr *BasicBlock::STRING(const QString &value)
+{
+ return function->e(new String(value));
+}
+
+Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
+{
+ return NAME(0, id, line, column);
+}
+
+Name *BasicBlock::NAME(Name *base, const QString &id, quint32 line, quint32 column)
+{
+ return function->e(new Name(base, InvalidType, id, Name::Unbound, line, column));
+}
+
+Name *BasicBlock::SYMBOL(Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage,
+ quint32 line, quint32 column)
+{
+ Name *name = SYMBOL(/*base = */ 0, type, id, meta, index, line, column);
+ name->storage = storage;
+ return name;
+}
+
+Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage,
+ quint32 line, quint32 column)
+{
+ Name *name = new Name(base, type, id, Name::Property, line, column);
+ name->meta = meta;
+ name->index = index;
+ name->storage = storage;
+ return function->e(name);
+}
+
+Name *BasicBlock::SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index,
+ quint32 line, quint32 column)
+{
+ Name *name = new Name(base, type, id, Name::Property, line, column);
+ name->meta = meta;
+ name->index = index;
+ return function->e(name);
+}
+
+Name *BasicBlock::ID_OBJECT(const QString &id, const QDeclarativeParser::Object *object, quint32 line, quint32 column)
+{
+ Name *name = new Name(/*base = */ 0, IR::ObjectType, id, Name::IdObject, line, column);
+ name->idObject = object;
+ name->index = object->idIndex;
+ name->storage = Name::IdStorage;
+ return function->e(name);
+}
+
+Name *BasicBlock::ATTACH_TYPE(const QString &id, const QDeclarativeType *attachType, Name::Storage storage,
+ quint32 line, quint32 column)
+{
+ Name *name = new Name(/*base = */ 0, IR::AttachType, id, Name::AttachType, line, column);
+ name->declarativeType = attachType;
+ name->storage = storage;
+ return function->e(name);
+}
+
+
+Expr *BasicBlock::UNOP(AluOp op, Expr *expr)
+{
+ return function->e(new Unop(op, expr));
+}
+
+Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
+{
+ if (left && right) {
+ if (Const *c1 = left->asConst()) {
+ if (Const *c2 = right->asConst()) {
+ switch (op) {
+ case OpAdd: return CONST(c1->value + c2->value);
+ case OpAnd: return CONST(c1->value ? c2->value : 0);
+ case OpBitAnd: return CONST(int(c1->value) & int(c2->value));
+ case OpBitOr: return CONST(int(c1->value) | int(c2->value));
+ case OpBitXor: return CONST(int(c1->value) ^ int(c2->value));
+ case OpDiv: return CONST(c1->value / c2->value);
+ case OpEqual: return CONST(c1->value == c2->value);
+ case OpGe: return CONST(c1->value >= c2->value);
+ case OpGt: return CONST(c1->value > c2->value);
+ case OpLe: return CONST(c1->value <= c2->value);
+ case OpLShift: return CONST(int(c1->value) << int(c2->value));
+ case OpLt: return CONST(c1->value < c2->value);
+ case OpMod: return CONST(::fmod(c1->value, c2->value));
+ case OpMul: return CONST(c1->value * c2->value);
+ case OpNotEqual: return CONST(c1->value != c2->value);
+ case OpOr: return CONST(c1->value ? c1->value : c2->value);
+ case OpRShift: return CONST(int(c1->value) >> int(c2->value));
+ case OpStrictEqual: return CONST(c1->value == c2->value);
+ case OpStrictNotEqual: return CONST(c1->value != c2->value);
+ case OpSub: return CONST(c1->value - c2->value);
+ case OpURShift: return CONST(unsigned(c1->value) >> int(c2->value));
+
+ case OpIfTrue: // unary ops
+ case OpNot:
+ case OpUMinus:
+ case OpUPlus:
+ case OpCompl:
+ case OpInvalid:
+ break;
+ }
+ }
+ }
+ }
+
+ return function->e(new Binop(op, left, right));
+}
+
+Expr *BasicBlock::CALL(Expr *base, const QVector<Expr *> &args)
+{
+ return function->e(new Call(base, args));
+}
+
+Stmt *BasicBlock::EXP(Expr *expr)
+{
+ return i(new Exp(expr));
+}
+
+Stmt *BasicBlock::MOVE(Expr *target, Expr *source, bool isMoveForReturn)
+{
+ return i(new Move(target, source, isMoveForReturn));
+}
+
+Stmt *BasicBlock::JUMP(BasicBlock *target)
+{
+ if (isTerminated())
+ return 0;
+ else
+ return i(new Jump(target));
+}
+
+Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
+{
+ if (isTerminated())
+ return 0;
+ return i(new CJump(cond, iftrue, iffalse));
+}
+
+Stmt *BasicBlock::RET(Expr *expr, Type type, quint32 line, quint32 column)
+{
+ if (isTerminated())
+ return 0;
+ else
+ return i(new Ret(expr, type, line, column));
+}
+
+void BasicBlock::dump(QTextStream &out)
+{
+ out << 'L' << this << ':' << endl;
+ foreach (Stmt *s, statements) {
+ out << '\t';
+ s->dump(out);
+ out << endl;
+ }
+}
+
+void Module::dump(QTextStream &out)
+{
+ foreach (Function *fun, functions) {
+ fun->dump(out);
+ out << endl;
+ }
+}
+
+#ifdef DEBUG_IR_STRUCTURE
+
+static const char *symbolname(Name::Symbol s)
+{
+ switch (s) {
+ case Name::Unbound:
+ return "Unbound";
+ case Name::IdObject:
+ return "IdObject";
+ case Name::AttachType:
+ return "AttachType";
+ case Name::Object:
+ return "Object";
+ case Name::Property:
+ return "Property";
+ case Name::Slot:
+ return "Slot";
+ default:
+ Q_ASSERT(!"Unreachable");
+ return "Unknown";
+ }
+}
+
+static const char *storagename(Name::Storage s)
+{
+ switch (s) {
+ case Name::MemberStorage:
+ return "MemberStorage";
+ case Name::IdStorage:
+ return "IdStorage";
+ case Name::RootStorage:
+ return "RootStorage";
+ case Name::ScopeStorage:
+ return "ScopeStorage";
+ default:
+ Q_ASSERT(!"Unreachable");
+ return "UnknownStorage";
+ }
+}
+
+IRDump::IRDump()
+: indentSize(0)
+{
+}
+
+void IRDump::inc()
+{
+ indentSize++;
+ indentData = QByteArray(indentSize * 4, ' ');
+}
+
+void IRDump::dec()
+{
+ indentSize--;
+ indentData = QByteArray(indentSize * 4, ' ');
+}
+
+void IRDump::dec();
+
+void IRDump::expression(QDeclarativeJS::IR::Expr *e)
+{
+ inc();
+
+ e->accept(this);
+
+ dec();
+}
+
+void IRDump::basicblock(QDeclarativeJS::IR::BasicBlock *b)
+{
+ inc();
+
+ qWarning().nospace() << indent() << "BasicBlock " << b << " {";
+ for (int ii = 0; ii < b->statements.count(); ++ii) {
+ statement(b->statements.at(ii));
+ if (ii != (b->statements.count() - 1))
+ qWarning();
+ }
+ qWarning().nospace() << indent() << "}";
+
+ dec();
+}
+
+void IRDump::statement(QDeclarativeJS::IR::Stmt *s)
+{
+ inc();
+
+ s->accept(this);
+
+ dec();
+}
+
+void IRDump::function(QDeclarativeJS::IR::Function *f)
+{
+ inc();
+
+ qWarning().nospace() << indent() << "Function {";
+ for (int ii = 0; ii < f->basicBlocks.count(); ++ii) {
+ basicblock(f->basicBlocks.at(ii));
+ }
+ qWarning().nospace() << indent() << "}";
+
+ dec();
+}
+
+const char *IRDump::indent()
+{
+ return indentData.constData();
+}
+
+void IRDump::visitConst(QDeclarativeJS::IR::Const *e)
+{
+ qWarning().nospace() << indent() << "Const:Expr { type: " << typeName(e->type) << ", value: " << e->value << "}";
+}
+
+void IRDump::visitString(QDeclarativeJS::IR::String *e)
+{
+ qWarning().nospace() << indent() << "String:Expr { type: " << typeName(e->type) << ", value: " << e->value << "}";
+}
+
+static void namedumprecur(QDeclarativeJS::IR::Name *e, const char *indent)
+{
+ if (e->base) namedumprecur(e->base, indent);
+ qWarning().nospace() << indent << " { type: " << typeName(e->type) << ", symbol: " << symbolname(e->symbol) << ", storage: " << storagename(e->storage) << ", id: " << e->id << "}";
+}
+
+void IRDump::visitName(QDeclarativeJS::IR::Name *e)
+{
+ qWarning().nospace() << indent() << "Name:Expr {";
+ namedumprecur(e, indent());
+ qWarning().nospace() << indent() << "}";
+}
+
+void IRDump::visitTemp(QDeclarativeJS::IR::Temp *e)
+{
+ qWarning().nospace() << indent() << "Temp:Expr { type: " << typeName(e->type) << ", index: " << e->index << " }";
+}
+
+void IRDump::visitUnop(QDeclarativeJS::IR::Unop *e)
+{
+ qWarning().nospace() << indent() << "Unop:Expr { ";
+ qWarning().nospace() << indent() << " type: " << typeName(e->type) << ", op: " << opname(e->op);
+ qWarning().nospace() << indent() << " expr: {";
+ expression(e->expr);
+ qWarning().nospace() << indent() << " }";
+ qWarning().nospace() << indent() << "}";
+}
+
+void IRDump::visitBinop(QDeclarativeJS::IR::Binop *e)
+{
+ qWarning().nospace() << indent() << "Binop:Expr { ";
+ qWarning().nospace() << indent() << " type: " << typeName(e->type) << ", op: " << opname(e->op);
+ qWarning().nospace() << indent() << " left: {";
+ inc();
+ expression(e->left);
+ dec();
+ qWarning().nospace() << indent() << " },";
+ qWarning().nospace() << indent() << " right: {";
+ inc();
+ expression(e->right);
+ dec();
+ qWarning().nospace() << indent() << " }";
+ qWarning().nospace() << indent() << "}";
+}
+
+void IRDump::visitCall(QDeclarativeJS::IR::Call *e)
+{
+ Q_UNUSED(e);
+ qWarning().nospace() << indent() << "Exp::Call { }";
+}
+
+void IRDump::visitExp(QDeclarativeJS::IR::Exp *s)
+{
+ qWarning().nospace() << indent() << "Exp:Stmt {";
+ expression(s->expr);
+ qWarning().nospace() << indent() << "}";
+}
+
+void IRDump::visitMove(QDeclarativeJS::IR::Move *s)
+{
+ qWarning().nospace() << indent() << "Move:Stmt {";
+ qWarning().nospace() << indent() << " isMoveForReturn: " << s->isMoveForReturn;
+ qWarning().nospace() << indent() << " target: {";
+ inc();
+ expression(s->target);
+ dec();
+ qWarning().nospace() << indent() << " },";
+ qWarning().nospace() << indent() << " source: {";
+ inc();
+ expression(s->source);
+ dec();
+ qWarning().nospace() << indent() << " }";
+ qWarning().nospace() << indent() << "}";
+}
+
+void IRDump::visitJump(QDeclarativeJS::IR::Jump *s)
+{
+ qWarning().nospace() << indent() << "Jump:Stmt { BasicBlock(" << s->target << ") }";
+}
+
+void IRDump::visitCJump(QDeclarativeJS::IR::CJump *s)
+{
+ qWarning().nospace() << indent() << "CJump:Stmt {";
+ qWarning().nospace() << indent() << " cond: {";
+ inc();
+ expression(s->cond);
+ dec();
+ qWarning().nospace() << indent() << " }";
+ qWarning().nospace() << indent() << " iftrue: BasicBlock(" << s->iftrue << ")";
+ qWarning().nospace() << indent() << " iffalse: BasicBlock(" << s->iffalse << ")";
+ qWarning().nospace() << indent() << "}";
+}
+
+void IRDump::visitRet(QDeclarativeJS::IR::Ret *s)
+{
+ qWarning().nospace() << indent() << "Ret:Stmt {";
+ qWarning().nospace() << indent() << " type: " << typeName(s->type);
+ expression(s->expr);
+ qWarning().nospace() << indent() << "}";
+}
+#endif
+
+} // end of namespace IR
+} // end of namespace QDeclarativeJS
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4ir_p.h b/src/declarative/qml/v4/qdeclarativev4ir_p.h
new file mode 100644
index 0000000000..93815e9154
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4ir_p.h
@@ -0,0 +1,546 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEV4IR_P_H
+#define QDECLARATIVEV4IR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qdeclarativejsast_p.h>
+#include <private/qdeclarativejsengine_p.h>
+#include <private/qdeclarativeparser_p.h>
+#include <private/qdeclarativeimport_p.h>
+#include <private/qdeclarativeengine_p.h>
+#include <private/qdeclarativev4compiler_p.h>
+
+#include <QtCore/qvector.h>
+
+// #define DEBUG_IR_STRUCTURE
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QTextStream;
+class QDeclarativeType;
+
+namespace QDeclarativeJS {
+
+namespace IR {
+
+struct BasicBlock;
+struct Function;
+struct Module;
+
+struct Stmt;
+struct Expr;
+
+// expressions
+struct Const;
+struct String;
+struct Name;
+struct Temp;
+struct Unop;
+struct Binop;
+struct Call;
+
+// statements
+struct Exp;
+struct Move;
+struct Jump;
+struct CJump;
+struct Ret;
+
+enum AluOp {
+ OpInvalid = 0,
+
+ OpIfTrue,
+ OpNot,
+ OpUMinus,
+ OpUPlus,
+ OpCompl,
+
+ OpBitAnd,
+ OpBitOr,
+ OpBitXor,
+
+ OpAdd,
+ OpSub,
+ OpMul,
+ OpDiv,
+ OpMod,
+
+ OpLShift,
+ OpRShift,
+ OpURShift,
+
+ OpGt,
+ OpLt,
+ OpGe,
+ OpLe,
+ OpEqual,
+ OpNotEqual,
+ OpStrictEqual,
+ OpStrictNotEqual,
+
+ OpAnd,
+ OpOr
+};
+AluOp binaryOperator(int op);
+
+enum Type {
+ InvalidType,
+ UndefinedType,
+ NullType,
+ VoidType,
+ StringType,
+ UrlType,
+ AnchorLineType,
+ SGAnchorLineType,
+ AttachType,
+ ObjectType,
+
+ FirstNumberType,
+ BoolType = FirstNumberType,
+ IntType,
+ RealType,
+ RealNaNType
+};
+Type maxType(IR::Type left, IR::Type right);
+
+struct ExprVisitor {
+ virtual ~ExprVisitor() {}
+ virtual void visitConst(Const *) {}
+ virtual void visitString(String *) {}
+ virtual void visitName(Name *) {}
+ virtual void visitTemp(Temp *) {}
+ virtual void visitUnop(Unop *) {}
+ virtual void visitBinop(Binop *) {}
+ virtual void visitCall(Call *) {}
+};
+
+struct StmtVisitor {
+ virtual ~StmtVisitor() {}
+ virtual void visitExp(Exp *) {}
+ virtual void visitMove(Move *) {}
+ virtual void visitJump(Jump *) {}
+ virtual void visitCJump(CJump *) {}
+ virtual void visitRet(Ret *) {}
+};
+
+struct Expr {
+ Type type;
+
+ Expr(Type type): type(type) {}
+ virtual ~Expr() {}
+ virtual void accept(ExprVisitor *) = 0;
+ virtual Const *asConst() { return 0; }
+ virtual String *asString() { return 0; }
+ virtual Name *asName() { return 0; }
+ virtual Temp *asTemp() { return 0; }
+ virtual Unop *asUnop() { return 0; }
+ virtual Binop *asBinop() { return 0; }
+ virtual Call *asCall() { return 0; }
+ virtual void dump(QTextStream &out) = 0;
+};
+
+struct Const: Expr {
+ double value;
+ Const(Type type, double value): Expr(type), value(value) {}
+
+ virtual void accept(ExprVisitor *v) { v->visitConst(this); }
+ virtual Const *asConst() { return this; }
+
+ virtual void dump(QTextStream &out);
+};
+
+struct String: Expr {
+ QString value;
+ String(const QString &value): Expr(StringType), value(value) {}
+
+ virtual void accept(ExprVisitor *v) { v->visitString(this); }
+ virtual String *asString() { return this; }
+
+ virtual void dump(QTextStream &out);
+ static QString escape(const QString &s);
+};
+
+enum BuiltinSymbol {
+ NoBuiltinSymbol,
+ MathSinBultinFunction,
+ MathCosBultinFunction,
+ MathRoundBultinFunction,
+ MathFloorBultinFunction,
+
+ MathPIBuiltinConstant
+};
+
+struct Name: Expr {
+ enum Symbol {
+ Unbound,
+ IdObject, // This is a load of a id object. Storage will always be IdStorage
+ AttachType, // This is a load of an attached object
+ Object, // XXX what is this for?
+ Property, // This is a load of a regular property
+ Slot // XXX what is this for?
+ };
+
+ enum Storage {
+ MemberStorage, // This is a property of a previously fetched object
+ IdStorage, // This is a load of a id object. Symbol will always be IdObject
+ RootStorage, // This is a property of the root object
+ ScopeStorage // This is a property of the scope object
+ };
+
+ Name *base;
+ QString id;
+ Symbol symbol;
+ union {
+ void *ptr;
+ const QMetaObject *meta;
+ const QDeclarativeType *declarativeType;
+ const QDeclarativeParser::Object *idObject;
+ };
+ int index;
+ Storage storage;
+ BuiltinSymbol builtin;
+ quint32 line;
+ quint32 column;
+
+ Name(Name *base, Type type, const QString &id, Symbol symbol, quint32 line, quint32 column);
+
+ inline bool is(Symbol s) const { return s == symbol; }
+ inline bool isNot(Symbol s) const { return s != symbol; }
+
+ virtual void accept(ExprVisitor *v) { v->visitName(this); }
+ virtual Name *asName() { return this; }
+
+ virtual void dump(QTextStream &out);
+};
+
+struct Temp: Expr {
+ int index;
+ Temp(Type type, int index): Expr(type), index(index) {}
+
+ virtual void accept(ExprVisitor *v) { v->visitTemp(this); }
+ virtual Temp *asTemp() { return this; }
+
+ virtual void dump(QTextStream &out);
+};
+
+struct Unop: Expr {
+ AluOp op;
+ Expr *expr;
+
+ Unop(AluOp op, Expr *expr)
+ : Expr(typeForOp(op, expr)), op(op), expr(expr) {}
+
+ virtual void accept(ExprVisitor *v) { v->visitUnop(this); }
+ virtual Unop *asUnop() { return this; }
+
+ virtual void dump(QTextStream &out);
+
+private:
+ static Type typeForOp(AluOp op, Expr *expr);
+};
+
+struct Binop: Expr {
+ AluOp op;
+ Expr *left;
+ Expr *right;
+ Binop(AluOp op, Expr *left, Expr *right)
+ : Expr(typeForOp(op, left, right)), op(op), left(left), right(right) {}
+
+ virtual void accept(ExprVisitor *v) { v->visitBinop(this); }
+ virtual Binop *asBinop() { return this; }
+
+ virtual void dump(QTextStream &out);
+
+private:
+ static Type typeForOp(AluOp op, Expr *left, Expr *right);
+};
+
+struct Call: Expr {
+ Expr *base;
+ QVector<Expr *> args;
+
+ Call(Expr *base, const QVector<Expr *> &args)
+ : Expr(typeForFunction(base)), base(base), args(args) {}
+
+ virtual void accept(ExprVisitor *v) { v->visitCall(this); }
+ virtual Call *asCall() { return this; }
+
+ virtual void dump(QTextStream &out);
+
+private:
+ static Type typeForFunction(Expr *base);
+};
+
+struct Stmt {
+ enum Mode {
+ HIR,
+ MIR
+ };
+
+ virtual ~Stmt() {}
+ virtual Stmt *asTerminator() { return 0; }
+
+ virtual void accept(StmtVisitor *) = 0;
+ virtual Exp *asExp() { return 0; }
+ virtual Move *asMove() { return 0; }
+ virtual Jump *asJump() { return 0; }
+ virtual CJump *asCJump() { return 0; }
+ virtual Ret *asRet() { return 0; }
+ virtual void dump(QTextStream &out, Mode mode = HIR) = 0;
+};
+
+struct Exp: Stmt {
+ Expr *expr;
+ Exp(Expr *expr): expr(expr) {}
+
+ virtual void accept(StmtVisitor *v) { v->visitExp(this); }
+ virtual Exp *asExp() { return this; }
+
+ virtual void dump(QTextStream &out, Mode);
+};
+
+struct Move: Stmt {
+ Expr *target;
+ Expr *source;
+ bool isMoveForReturn;
+ Move(Expr *target, Expr *source, bool isMoveForReturn): target(target), source(source), isMoveForReturn(isMoveForReturn) {}
+
+ virtual void accept(StmtVisitor *v) { v->visitMove(this); }
+ virtual Move *asMove() { return this; }
+
+ virtual void dump(QTextStream &out, Mode);
+};
+
+struct Jump: Stmt {
+ BasicBlock *target;
+ Jump(BasicBlock *target): target(target) {}
+
+ virtual Stmt *asTerminator() { return this; }
+
+ virtual void accept(StmtVisitor *v) { v->visitJump(this); }
+ virtual Jump *asJump() { return this; }
+
+ virtual void dump(QTextStream &out, Mode mode);
+};
+
+struct CJump: Stmt {
+ Expr *cond;
+ BasicBlock *iftrue;
+ BasicBlock *iffalse;
+ CJump(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
+ : cond(cond), iftrue(iftrue), iffalse(iffalse) {}
+
+ virtual Stmt *asTerminator() { return this; }
+
+ virtual void accept(StmtVisitor *v) { v->visitCJump(this); }
+ virtual CJump *asCJump() { return this; }
+
+ virtual void dump(QTextStream &out, Mode mode);
+};
+
+struct Ret: Stmt {
+ Expr *expr;
+ Type type;
+ quint32 line;
+ quint32 column;
+ Ret(Expr *expr, Type type, quint32 line, quint32 column): expr(expr), type(type), line(line), column(column) {}
+
+ virtual Stmt *asTerminator() { return this; }
+
+ virtual void accept(StmtVisitor *v) { v->visitRet(this); }
+ virtual Ret *asRet() { return this; }
+
+ virtual void dump(QTextStream &out, Mode);
+};
+
+struct Function {
+ Module *module;
+ const NameId *name;
+ int tempCount;
+ QVector<BasicBlock *> basicBlocks;
+ QVector<Expr *> temps;
+
+ template <typename BB> inline BB i(BB i) { basicBlocks.append(i); return i; }
+ template <typename E> inline E e(E e) { temps.append(e); return e; }
+
+ Function(Module *module, const NameId *name = 0): module(module), name(name), tempCount(0) {}
+ ~Function();
+
+ BasicBlock *newBasicBlock();
+
+ virtual void dump(QTextStream &out);
+};
+
+struct BasicBlock {
+ Function *function;
+ int index;
+ QVector<Stmt *> statements;
+ int offset;
+
+ BasicBlock(Function *function, int index): function(function), index(index), offset(-1) {}
+ ~BasicBlock() { qDeleteAll(statements); }
+
+ template <typename Instr> inline Instr i(Instr i) { statements.append(i); return i; }
+
+ inline bool isEmpty() const {
+ return statements.isEmpty();
+ }
+
+ inline Stmt *terminator() const {
+ if (! statements.isEmpty() && statements.last()->asTerminator() != 0)
+ return statements.last();
+ return 0;
+ }
+
+ inline bool isTerminated() const {
+ if (terminator() != 0)
+ return true;
+ return false;
+ }
+
+ Temp *TEMP(Type type, int index);
+ Temp *TEMP(Type type);
+
+ Expr *CONST(double value);
+ Expr *CONST(Type type, double value);
+ Expr *STRING(const QString &value);
+
+ Name *NAME(const QString &id, quint32 line, quint32 column);
+ Name *NAME(Name *base, const QString &id, quint32 line, quint32 column);
+ Name *SYMBOL(Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage, quint32 line, quint32 column);
+ Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index, quint32 line, quint32 column);
+ Name *SYMBOL(Name *base, Type type, const QString &id, const QMetaObject *meta, int index, Name::Storage storage, quint32 line, quint32 column);
+ Name *ID_OBJECT(const QString &id, const QDeclarativeParser::Object *object, quint32 line, quint32 column);
+ Name *ATTACH_TYPE(const QString &id, const QDeclarativeType *attachType, Name::Storage storage, quint32 line, quint32 column);
+
+ Expr *UNOP(AluOp op, Expr *expr);
+ Expr *BINOP(AluOp op, Expr *left, Expr *right);
+ Expr *CALL(Expr *base, const QVector<Expr *> &args);
+
+ Stmt *EXP(Expr *expr);
+ Stmt *MOVE(Expr *target, Expr *source, bool = false);
+
+ Stmt *JUMP(BasicBlock *target);
+ Stmt *CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse);
+ Stmt *RET(Expr *expr, Type type, quint32 line, quint32 column);
+
+ virtual void dump(QTextStream &out);
+};
+
+struct Module {
+ QVector<Function *> functions;
+
+ Module() {}
+ ~Module() { qDeleteAll(functions); }
+
+ template <typename BB> inline BB i(BB i) { functions.append(i); return i; }
+
+ Function *newFunction(const NameId *name = 0) { return i(new Function(this, name)); }
+
+ virtual void dump(QTextStream &out);
+};
+
+#ifdef DEBUG_IR_STRUCTURE
+struct IRDump : public ExprVisitor,
+ public StmtVisitor
+{
+public:
+ IRDump();
+
+ void expression(QDeclarativeJS::IR::Expr *);
+ void basicblock(QDeclarativeJS::IR::BasicBlock *);
+ void statement(QDeclarativeJS::IR::Stmt *);
+ void function(QDeclarativeJS::IR::Function *);
+protected:
+
+ const char *indent();
+
+ //
+ // expressions
+ //
+ virtual void visitConst(QDeclarativeJS::IR::Const *e);
+ virtual void visitString(QDeclarativeJS::IR::String *e);
+ virtual void visitName(QDeclarativeJS::IR::Name *e);
+ virtual void visitTemp(QDeclarativeJS::IR::Temp *e);
+ virtual void visitUnop(QDeclarativeJS::IR::Unop *e);
+ virtual void visitBinop(QDeclarativeJS::IR::Binop *e);
+ virtual void visitCall(QDeclarativeJS::IR::Call *e);
+
+ //
+ // statements
+ //
+ virtual void visitExp(QDeclarativeJS::IR::Exp *s);
+ virtual void visitMove(QDeclarativeJS::IR::Move *s);
+ virtual void visitJump(QDeclarativeJS::IR::Jump *s);
+ virtual void visitCJump(QDeclarativeJS::IR::CJump *s);
+ virtual void visitRet(QDeclarativeJS::IR::Ret *s);
+
+private:
+ int indentSize;
+ QByteArray indentData;
+ void inc();
+ void dec();
+};
+#endif
+
+} // end of namespace IR
+
+} // end of namespace QDeclarativeJS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEV4IR_P_H
diff --git a/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp b/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp
new file mode 100644
index 0000000000..103d5ba0df
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp
@@ -0,0 +1,1315 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativev4irbuilder_p.h"
+
+#include <private/qdeclarativeglobalscriptclass_p.h> // For illegalNames
+#include <private/qdeclarativeanchors_p_p.h> // For AnchorLine
+#include <private/qsganchors_p_p.h> // For AnchorLine
+#include <private/qdeclarativetypenamecache_p.h>
+
+DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
+
+QT_BEGIN_NAMESPACE
+
+using namespace QDeclarativeJS;
+
+static IR::Type irTypeFromVariantType(int t, QDeclarativeEnginePrivate *engine, const QMetaObject *meta)
+{
+ switch (t) {
+ case QMetaType::Bool:
+ return IR::BoolType;
+
+ case QMetaType::Int:
+ return IR::IntType;
+
+ case QMetaType::QReal:
+ return IR::RealType;
+
+ case QMetaType::QString:
+ return IR::StringType;
+
+ case QMetaType::QUrl:
+ return IR::UrlType;
+
+ default:
+ if (t == qMetaTypeId<QDeclarativeAnchorLine>())
+ return IR::AnchorLineType;
+ else if (t == qMetaTypeId<QSGAnchorLine>())
+ return IR::SGAnchorLineType;
+ else if (const QMetaObject *m = engine->metaObjectForType(t)) {
+ meta = m;
+ return IR::ObjectType;
+ }
+
+ return IR::InvalidType;
+ }
+}
+
+QDeclarativeV4IRBuilder::QDeclarativeV4IRBuilder(const QDeclarativeV4Compiler::Expression *expr,
+ QDeclarativeEnginePrivate *engine)
+: m_expression(expr), m_engine(engine), _module(0), _function(0), _block(0), _discard(false)
+{
+}
+
+QDeclarativeJS::IR::Function *
+QDeclarativeV4IRBuilder::operator()(QDeclarativeJS::IR::Module *module,
+ QDeclarativeJS::AST::Node *ast)
+{
+ bool discarded = false;
+
+ qSwap(_module, module);
+
+ IR::Function *function = _module->newFunction();
+ IR::BasicBlock *block = function->newBasicBlock();
+
+ qSwap(_discard, discarded);
+ qSwap(_function, function);
+ qSwap(_block, block);
+
+ ExprResult r;
+ AST::SourceLocation location;
+ if (AST::ExpressionNode *asExpr = ast->expressionCast()) {
+ r = expression(asExpr);
+ location = asExpr->firstSourceLocation();
+ } else if (AST::Statement *asStmt = ast->statementCast()) {
+ r = statement(asStmt);
+ location = asStmt->firstSourceLocation();
+ }
+
+ //_block->MOVE(_block->TEMP(IR::InvalidType), r.code);
+ if (r.code) {
+ const QMetaObject *m = 0;
+ const IR::Type targetType = irTypeFromVariantType(m_expression->property->type, m_engine, m);
+ if (targetType != r.type()) {
+ IR::Expr *x = _block->TEMP(targetType);
+ _block->MOVE(x, r, true);
+ r.code = x;
+ }
+ _block->RET(r.code, targetType, location.startLine, location.startColumn);
+ }
+
+ qSwap(_block, block);
+ qSwap(_function, function);
+ qSwap(_discard, discarded);
+
+ qSwap(_module, module);
+
+ return discarded?0:function;
+}
+
+bool QDeclarativeV4IRBuilder::buildName(QStringList &name,
+ AST::Node *node,
+ QList<AST::ExpressionNode *> *nodes)
+{
+ if (node->kind == AST::Node::Kind_IdentifierExpression) {
+ name << static_cast<AST::IdentifierExpression*>(node)->name->asString();
+ if (nodes) *nodes << static_cast<AST::IdentifierExpression*>(node);
+ } else if (node->kind == AST::Node::Kind_FieldMemberExpression) {
+ AST::FieldMemberExpression *expr =
+ static_cast<AST::FieldMemberExpression *>(node);
+
+ if (!buildName(name, expr->base, nodes))
+ return false;
+
+ name << expr->name->asString();
+ if (nodes) *nodes << expr;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+void QDeclarativeV4IRBuilder::discard()
+{
+ _discard = true;
+}
+
+QDeclarativeV4IRBuilder::ExprResult
+QDeclarativeV4IRBuilder::expression(AST::ExpressionNode *ast)
+{
+ ExprResult r;
+ if (ast) {
+ qSwap(_expr, r);
+ accept(ast);
+ qSwap(_expr, r);
+
+ if (r.is(IR::InvalidType))
+ discard();
+ else {
+ Q_ASSERT(r.hint == r.format);
+ }
+ }
+
+ return r;
+}
+
+void QDeclarativeV4IRBuilder::condition(AST::ExpressionNode *ast, IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
+{
+ if (! ast)
+ return;
+ ExprResult r(iftrue, iffalse);
+ qSwap(_expr, r);
+ accept(ast);
+ qSwap(_expr, r);
+
+ if (r.format != ExprResult::cx) {
+ if (! r.code)
+ discard();
+
+ Q_ASSERT(r.hint == ExprResult::cx);
+ Q_ASSERT(r.format == ExprResult::ex);
+
+ if (r.type() != IR::BoolType) {
+ IR::Temp *t = _block->TEMP(IR::BoolType);
+ _block->MOVE(t, r);
+ r = t;
+ }
+
+ _block->CJUMP(_block->UNOP(IR::OpIfTrue, r), iftrue, iffalse);
+ }
+}
+
+QDeclarativeV4IRBuilder::ExprResult
+QDeclarativeV4IRBuilder::statement(AST::Statement *ast)
+{
+ ExprResult r;
+ if (ast) {
+ qSwap(_expr, r);
+ accept(ast);
+ qSwap(_expr, r);
+
+ if (r.is(IR::InvalidType))
+ discard();
+ else {
+ Q_ASSERT(r.hint == r.format);
+ }
+ }
+
+ return r;
+}
+
+void QDeclarativeV4IRBuilder::sourceElement(AST::SourceElement *ast)
+{
+ accept(ast);
+}
+
+void QDeclarativeV4IRBuilder::implicitCvt(ExprResult &expr, IR::Type type)
+{
+ if (expr.type() == type)
+ return; // nothing to do
+
+ IR::Expr *x = _block->TEMP(type);
+ _block->MOVE(x, expr.code);
+ expr.code = x;
+}
+
+// QML
+bool QDeclarativeV4IRBuilder::visit(AST::UiProgram *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiImportList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiImport *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiPublicMember *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiSourceElement *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiObjectDefinition *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiObjectInitializer *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiObjectBinding *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiScriptBinding *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiArrayBinding *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiObjectMemberList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiArrayMemberList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiQualifiedId *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiSignature *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiFormalList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UiFormal *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+
+// JS
+bool QDeclarativeV4IRBuilder::visit(AST::Program *ast)
+{
+ _function = _module->newFunction();
+ _block = _function->newBasicBlock();
+ accept(ast->elements);
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::SourceElements *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::FunctionSourceElement *)
+{
+ return true; // look inside
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::StatementSourceElement *)
+{
+ return true; // look inside
+}
+
+// object literals
+bool QDeclarativeV4IRBuilder::visit(AST::PropertyNameAndValueList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::IdentifierPropertyName *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::StringLiteralPropertyName *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::NumericLiteralPropertyName *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+
+// array literals
+bool QDeclarativeV4IRBuilder::visit(AST::ElementList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::Elision *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+
+// function calls
+bool QDeclarativeV4IRBuilder::visit(AST::ArgumentList *)
+{
+ Q_ASSERT(!"unreachable");
+ return false;
+}
+
+// expressions
+bool QDeclarativeV4IRBuilder::visit(AST::ObjectLiteral *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ArrayLiteral *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ThisExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::IdentifierExpression *ast)
+{
+ const quint32 line = ast->identifierToken.startLine;
+ const quint32 column = ast->identifierToken.startColumn;
+
+ const QString name = ast->name->asString();
+
+ if (name.at(0) == QLatin1Char('u') && name.length() == 9 && name == QLatin1String("undefined")) {
+ _expr.code = _block->CONST(IR::UndefinedType, 0); // ### undefined value
+ } else if(m_engine->globalClass->illegalNames().contains(name) ) {
+ if (qmlVerboseCompiler()) qWarning() << "*** illegal symbol:" << name;
+ return false;
+ } else if (const QDeclarativeParser::Object *obj = m_expression->ids.value(name)) {
+ IR::Name *code = _block->ID_OBJECT(name, obj, line, column);
+ if (obj == m_expression->component)
+ code->storage = IR::Name::RootStorage;
+ _expr.code = code;
+ } else if (QDeclarativeTypeNameCache::Data *typeNameData = m_expression->importCache->data(name)) {
+ if (typeNameData->importedScriptIndex != -1) {
+ // We don't support invoking imported scripts
+ } else if (typeNameData->type) {
+ _expr.code = _block->ATTACH_TYPE(name, typeNameData->type, IR::Name::ScopeStorage, line, column);
+ } else if (typeNameData->typeNamespace) {
+ // We don't support namespaces
+ } else {
+ Q_ASSERT(!"Unreachable");
+ }
+ } else {
+ bool found = false;
+
+ if (m_expression->context != m_expression->component) {
+ // RootStorage is more efficient than ScopeStorage, so prefer that if they are the same
+ QDeclarativePropertyCache *cache = m_expression->context->synthCache;
+ const QMetaObject *metaObject = m_expression->context->metaObject();
+ if (!cache) cache = m_engine->cache(metaObject);
+
+ QDeclarativePropertyCache::Data *data = cache->property(name);
+
+ if (data && data->revision != 0) {
+ if (qmlVerboseCompiler())
+ qWarning() << "*** versioned symbol:" << name;
+ discard();
+ return false;
+ }
+
+ if (data && !(data->flags & QDeclarativePropertyCache::Data::IsFunction)) {
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
+ _expr.code = _block->SYMBOL(irType, name, metaObject, data->coreIndex, IR::Name::ScopeStorage, line, column);
+ found = true;
+ }
+ }
+
+ if (!found) {
+ QDeclarativePropertyCache *cache = m_expression->component->synthCache;
+ const QMetaObject *metaObject = m_expression->component->metaObject();
+ if (!cache) cache = m_engine->cache(metaObject);
+
+ QDeclarativePropertyCache::Data *data = cache->property(name);
+
+ if (data && data->revision != 0) {
+ if (qmlVerboseCompiler())
+ qWarning() << "*** versioned symbol:" << name;
+ discard();
+ return false;
+ }
+
+ if (data && !(data->flags & QDeclarativePropertyCache::Data::IsFunction)) {
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, metaObject);
+ _expr.code = _block->SYMBOL(irType, name, metaObject, data->coreIndex, IR::Name::RootStorage, line, column);
+ found = true;
+ }
+ }
+
+ if (!found && qmlVerboseCompiler())
+ qWarning() << "*** unknown symbol:" << name;
+ }
+
+ if (_expr.code && _expr.hint == ExprResult::cx) {
+ _expr.format = ExprResult::cx;
+
+ if (_expr.type() != IR::BoolType) {
+ IR::Temp *t = _block->TEMP(IR::BoolType);
+ _block->MOVE(t, _expr);
+ _expr.code = t;
+ }
+
+ _block->CJUMP(_expr.code, _expr.iftrue, _expr.iffalse);
+ _expr.code = 0;
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::NullExpression *)
+{
+ // ### TODO: cx format
+ _expr.code = _block->CONST(IR::NullType, 0);
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::TrueLiteral *)
+{
+ // ### TODO: cx format
+ _expr.code = _block->CONST(IR::BoolType, 1);
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::FalseLiteral *)
+{
+ // ### TODO: cx format
+ _expr.code = _block->CONST(IR::BoolType, 0);
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::StringLiteral *ast)
+{
+ // ### TODO: cx format
+ _expr.code = _block->STRING(ast->value->asString());
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::NumericLiteral *ast)
+{
+ if (_expr.hint == ExprResult::cx) {
+ _expr.format = ExprResult::cx;
+ _block->JUMP(ast->value ? _expr.iftrue : _expr.iffalse);
+ } else {
+ _expr.code = _block->CONST(ast->value);
+ }
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::RegExpLiteral *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::NestedExpression *)
+{
+ return true; // the value of the nested expression
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ArrayMemberExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
+{
+ if (IR::Expr *left = expression(ast->base)) {
+ if (IR::Name *baseName = left->asName()) {
+ const quint32 line = ast->identifierToken.startLine;
+ const quint32 column = ast->identifierToken.startColumn;
+
+ QString name = ast->name->asString();
+
+ switch(baseName->symbol) {
+ case IR::Name::Unbound:
+ break;
+
+ case IR::Name::AttachType:
+ if (name.at(0).isUpper()) {
+ QByteArray utf8Name = name.toUtf8();
+ const char *enumName = utf8Name.constData();
+
+ const QMetaObject *meta = baseName->declarativeType->metaObject();
+ bool found = false;
+ for (int ii = 0; !found && ii < meta->enumeratorCount(); ++ii) {
+ QMetaEnum e = meta->enumerator(ii);
+ for (int jj = 0; !found && jj < e.keyCount(); ++jj) {
+ if (0 == strcmp(e.key(jj), enumName)) {
+ found = true;
+ _expr.code = _block->CONST(IR::IntType, e.value(jj));
+ }
+ }
+ }
+
+ if (!found && qmlVerboseCompiler())
+ qWarning() << "*** unresolved enum:"
+ << (baseName->id + QLatin1String(".") + ast->name->asString());
+ } else if(const QMetaObject *attachedMeta = baseName->declarativeType->attachedPropertiesType()) {
+ QDeclarativePropertyCache *cache = m_engine->cache(attachedMeta);
+ QDeclarativePropertyCache::Data *data = cache->property(name);
+
+ if (!data || data->flags & QDeclarativePropertyCache::Data::IsFunction)
+ return false; // Don't support methods (or non-existing properties ;)
+
+ if(!(data->flags & QDeclarativePropertyCache::Data::IsFinal)) {
+ if (qmlVerboseCompiler())
+ qWarning() << "*** non-final attached property:"
+ << (baseName->id + QLatin1String(".") + ast->name->asString());
+ return false; // We don't know enough about this property
+ }
+
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, attachedMeta);
+ _expr.code = _block->SYMBOL(baseName, irType, name, attachedMeta, data->coreIndex, line, column);
+ }
+ break;
+
+ case IR::Name::IdObject: {
+ const QDeclarativeParser::Object *idObject = baseName->idObject;
+ QDeclarativePropertyCache *cache =
+ idObject->synthCache?idObject->synthCache:m_engine->cache(idObject->metaObject());
+
+ QDeclarativePropertyCache::Data *data = cache->property(name);
+
+ if (!data || data->flags & QDeclarativePropertyCache::Data::IsFunction)
+ return false; // Don't support methods (or non-existing properties ;)
+
+ if (data->revision != 0) {
+ if (qmlVerboseCompiler())
+ qWarning() << "*** versioned symbol:" << name;
+ discard();
+ return false;
+ }
+
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, idObject->metaObject());
+ _expr.code = _block->SYMBOL(baseName, irType, name,
+ idObject->metaObject(), data->coreIndex, line, column);
+ }
+ break;
+
+ case IR::Name::Property:
+ if (baseName->type == IR::ObjectType) {
+ const QMetaObject *m =
+ m_engine->metaObjectForType(baseName->meta->property(baseName->index).userType());
+ QDeclarativePropertyCache *cache = m_engine->cache(m);
+
+ QDeclarativePropertyCache::Data *data = cache->property(name);
+
+ if (!data || data->flags & QDeclarativePropertyCache::Data::IsFunction)
+ return false; // Don't support methods (or non-existing properties ;)
+
+ if(!(data->flags & QDeclarativePropertyCache::Data::IsFinal)) {
+ if (qmlVerboseCompiler())
+ qWarning() << "*** non-final property access:"
+ << (baseName->id + QLatin1String(".") + ast->name->asString());
+ return false; // We don't know enough about this property
+ }
+
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, baseName->meta);
+ _expr.code = _block->SYMBOL(baseName, irType, name,
+ baseName->meta, data->coreIndex, line, column);
+ }
+ break;
+
+ case IR::Name::Object:
+ case IR::Name::Slot:
+ break;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::NewMemberExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::NewExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::CallExpression *ast)
+{
+ QStringList names;
+ QList<AST::ExpressionNode *> nameNodes;
+ if (buildName(names, ast->base, &nameNodes)) {
+ //ExprResult base = expression(ast->base);
+ const QString id = names.join(QLatin1String("."));
+ const quint32 line = nameNodes.last()->firstSourceLocation().startLine;
+ const quint32 column = nameNodes.last()->firstSourceLocation().startColumn;
+ IR::Expr *base = _block->NAME(id, line, column);
+
+ QVector<IR::Expr *> args;
+ for (AST::ArgumentList *it = ast->arguments; it; it = it->next)
+ args.append(expression(it->expression));
+
+ IR::Temp *r = _block->TEMP(IR::InvalidType);
+ IR::Expr *call = _block->CALL(base, args);
+ _block->MOVE(r, call);
+ r->type = call->type;
+ _expr.code = r;
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::PostIncrementExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::PostDecrementExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::DeleteExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::VoidExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::TypeOfExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::PreIncrementExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::PreDecrementExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UnaryPlusExpression *ast)
+{
+ ExprResult expr = expression(ast->expression);
+ if (expr.isNot(IR::InvalidType)) {
+ if (expr.code->asConst() != 0) {
+ _expr = expr;
+ return false;
+ }
+
+ IR::Expr *code = _block->UNOP(IR::OpUPlus, expr);
+ _expr.code = _block->TEMP(code->type);
+ _block->MOVE(_expr, code);
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::UnaryMinusExpression *ast)
+{
+ ExprResult expr = expression(ast->expression);
+ if (expr.isNot(IR::InvalidType)) {
+ if (IR::Const *c = expr.code->asConst()) {
+ _expr = expr;
+ _expr.code = _block->CONST(-c->value);
+ return false;
+ }
+
+ IR::Expr *code = _block->UNOP(IR::OpUMinus, expr);
+ _expr.code = _block->TEMP(code->type);
+ _block->MOVE(_expr, code);
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::TildeExpression *ast)
+{
+ ExprResult expr = expression(ast->expression);
+ if (expr.isNot(IR::InvalidType)) {
+ if (IR::Const *c = expr.code->asConst()) {
+ _expr = expr;
+ _expr.code = _block->CONST(~int(c->value));
+ return false;
+ }
+ IR::Expr *code = _block->UNOP(IR::OpCompl, expr);
+ _expr.code = _block->TEMP(code->type);
+ _block->MOVE(_expr, code);
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::NotExpression *ast)
+{
+ ExprResult expr = expression(ast->expression);
+
+ if (expr.isNot(IR::InvalidType)) {
+ if (IR::Const *c = expr.code->asConst()) {
+ _expr = expr;
+ _expr.code = _block->CONST(!c->value);
+ return false;
+ }
+
+ IR::Expr *code = _block->UNOP(IR::OpNot, expr);
+ _expr.code = _block->TEMP(code->type);
+ _block->MOVE(_expr, code);
+
+ } else if (expr.hint == ExprResult::cx) {
+ expr.format = ExprResult::cx;
+ _block->CJUMP(_block->UNOP(IR::OpNot, expr), _expr.iftrue, _expr.iffalse);
+ return false;
+ }
+
+ return false;
+}
+
+void QDeclarativeV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left, ExprResult right)
+{
+ if (IR::Type t = maxType(left.type(), right.type())) {
+ implicitCvt(left, t);
+ implicitCvt(right, t);
+
+ if (_expr.hint == ExprResult::cx) {
+ _expr.format = ExprResult::cx;
+ _block->CJUMP(_block->BINOP(IR::binaryOperator(ast->op), left, right), _expr.iftrue, _expr.iffalse);
+ } else {
+ IR::Expr *code = _block->BINOP(IR::binaryOperator(ast->op), left, right);
+ _expr.code = _block->TEMP(code->type);
+ _block->MOVE(_expr.code, code);
+ }
+ }
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::BinaryExpression *ast)
+{
+ switch (ast->op) {
+ case QSOperator::And: {
+ if (_expr.hint == ExprResult::cx) {
+ _expr.format = ExprResult::cx;
+
+ Q_ASSERT(_expr.iffalse != 0);
+ Q_ASSERT(_expr.iftrue != 0);
+
+ IR::BasicBlock *iftrue = _function->newBasicBlock();
+ condition(ast->left, iftrue, _expr.iffalse);
+
+ _block = iftrue;
+ condition(ast->right, _expr.iftrue, _expr.iffalse);
+ } else {
+ IR::BasicBlock *iftrue = _function->newBasicBlock();
+ IR::BasicBlock *iffalse = _function->newBasicBlock();
+ IR::BasicBlock *endif = _function->newBasicBlock();
+
+ condition(ast->left, iftrue, iffalse);
+
+ IR::Temp *r = _block->TEMP(IR::InvalidType);
+
+ _block = iffalse;
+ _block->MOVE(r, _block->CONST(0)); // ### use the right null value
+ _block->JUMP(endif);
+
+ _block = iftrue;
+ ExprResult right = expression(ast->right);
+ _block->MOVE(r, right);
+ _block->JUMP(endif);
+
+ _block = endif;
+
+ r->type = right.type(); // ### not exactly, it can be IR::BoolType.
+ _expr.code = r;
+ }
+ } break;
+
+ case QSOperator::Or: {
+ IR::BasicBlock *iftrue = _function->newBasicBlock();
+ IR::BasicBlock *endif = _function->newBasicBlock();
+
+ ExprResult left = expression(ast->left);
+ IR::Temp *r = _block->TEMP(left.type());
+ _block->MOVE(r, left);
+
+ IR::Expr *cond = r;
+ if (r->type != IR::BoolType) {
+ cond = _block->TEMP(IR::BoolType);
+ _block->MOVE(cond, r);
+ }
+
+ _block->CJUMP(_block->UNOP(IR::OpNot, cond), iftrue, endif);
+
+ _block = iftrue;
+ ExprResult right = expression(ast->right);
+ _block->MOVE(r, right);
+
+ if (left.type() != right.type())
+ discard();
+
+ _expr.code = r;
+
+ _block = endif;
+ } break;
+
+ case QSOperator::Lt:
+ case QSOperator::Gt:
+ case QSOperator::Le:
+ case QSOperator::Ge: {
+ ExprResult left = expression(ast->left);
+ ExprResult right = expression(ast->right);
+ if (left.type() == IR::StringType && right.type() == IR::StringType) {
+ binop(ast, left, right);
+ } else if (left.isValid() && right.isValid()) {
+ implicitCvt(left, IR::RealType);
+ implicitCvt(right, IR::RealType);
+ binop(ast, left, right);
+ }
+ } break;
+
+ case QSOperator::NotEqual:
+ case QSOperator::Equal: {
+ ExprResult left = expression(ast->left);
+ ExprResult right = expression(ast->right);
+ if ((left.type() == IR::NullType || left.type() == IR::UndefinedType) &&
+ (right.type() == IR::NullType || right.type() == IR::UndefinedType)) {
+ const bool isEq = ast->op == QSOperator::Equal;
+ if (_expr.hint == ExprResult::cx) {
+ _expr.format = ExprResult::cx;
+ _block->JUMP(isEq ? _expr.iftrue : _expr.iffalse);
+ } else {
+ _expr.code = _block->CONST(IR::BoolType, isEq ? 1 : 0);
+ }
+ } else if ((left.type() == IR::StringType && right.type() >= IR::FirstNumberType) ||
+ (left.type() >= IR::FirstNumberType && right.type() == IR::StringType)) {
+ implicitCvt(left, IR::RealType);
+ implicitCvt(right, IR::RealType);
+ binop(ast, left, right);
+ } else if (left.type() == IR::BoolType || right.type() == IR::BoolType) {
+ implicitCvt(left, IR::BoolType);
+ implicitCvt(right, IR::BoolType);
+ } else if (left.isValid() && right.isValid()) {
+ binop(ast, left, right);
+ }
+ } break;
+
+ case QSOperator::StrictEqual:
+ case QSOperator::StrictNotEqual: {
+ ExprResult left = expression(ast->left);
+ ExprResult right = expression(ast->right);
+ if (left.type() == right.type()) {
+ binop(ast, left, right);
+ } else if (left.type() >= IR::BoolType && right.type() >= IR::BoolType) {
+ // left and right have numeric type (int or real)
+ binop(ast, left, right);
+ } else if (left.isValid() && right.isValid()) {
+ const bool isEq = ast->op == QSOperator::StrictEqual;
+ if (_expr.hint == ExprResult::cx) {
+ _expr.format = ExprResult::cx;
+ _block->JUMP(isEq ? _expr.iftrue : _expr.iffalse);
+ } else {
+ _expr.code = _block->CONST(IR::BoolType, isEq ? 1 : 0);
+ }
+ }
+ } break;
+
+ case QSOperator::BitAnd:
+ case QSOperator::BitOr:
+ case QSOperator::BitXor:
+ case QSOperator::LShift:
+ case QSOperator::RShift:
+ case QSOperator::URShift: {
+ ExprResult left = expression(ast->left);
+ if (left.is(IR::InvalidType))
+ return false;
+
+ ExprResult right = expression(ast->right);
+ if (right.is(IR::InvalidType))
+ return false;
+
+ implicitCvt(left, IR::IntType);
+ implicitCvt(right, IR::IntType);
+
+ IR::Expr *code = _block->BINOP(IR::binaryOperator(ast->op), left, right);
+ _expr.code = _block->TEMP(code->type);
+ _block->MOVE(_expr.code, code);
+
+ } break;
+
+ case QSOperator::Add: {
+ ExprResult left = expression(ast->left);
+ if (left.is(IR::InvalidType))
+ return false;
+
+ ExprResult right = expression(ast->right);
+ if (right.is(IR::InvalidType))
+ return false;
+
+ if (left.isPrimitive() && right.isPrimitive()) {
+ if (left.type() == IR::StringType || right.type() == IR::StringType) {
+ implicitCvt(left, IR::StringType);
+ implicitCvt(right, IR::StringType);
+ }
+ binop(ast, left, right);
+ }
+ } break;
+
+ case QSOperator::Div:
+ case QSOperator::Mod:
+ case QSOperator::Mul:
+ case QSOperator::Sub: {
+ ExprResult left = expression(ast->left);
+ if (left.is(IR::InvalidType))
+ return false;
+
+ ExprResult right = expression(ast->right);
+ if (right.is(IR::InvalidType))
+ return false;
+
+ IR::Type t = maxType(left.type(), right.type());
+ if (t >= IR::FirstNumberType) {
+ implicitCvt(left, IR::RealType);
+ implicitCvt(right, IR::RealType);
+
+ IR::Expr *code = _block->BINOP(IR::binaryOperator(ast->op), left, right);
+ _expr.code = _block->TEMP(code->type);
+ _block->MOVE(_expr.code, code);
+ }
+ } break;
+
+ case QSOperator::In:
+ case QSOperator::InstanceOf:
+ case QSOperator::Assign:
+ case QSOperator::InplaceAnd:
+ case QSOperator::InplaceSub:
+ case QSOperator::InplaceDiv:
+ case QSOperator::InplaceAdd:
+ case QSOperator::InplaceLeftShift:
+ case QSOperator::InplaceMod:
+ case QSOperator::InplaceMul:
+ case QSOperator::InplaceOr:
+ case QSOperator::InplaceRightShift:
+ case QSOperator::InplaceURightShift:
+ case QSOperator::InplaceXor:
+ // yup, we don't do those.
+ break;
+ } // switch
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ConditionalExpression *ast)
+{
+ IR::BasicBlock *iftrue = _function->newBasicBlock();
+ IR::BasicBlock *iffalse = _function->newBasicBlock();
+ IR::BasicBlock *endif = _function->newBasicBlock();
+
+ condition(ast->expression, iftrue, iffalse);
+
+ IR::Temp *r = _block->TEMP(IR::InvalidType);
+
+ qSwap(_block, iftrue);
+ ExprResult ok = expression(ast->ok);
+ _block->MOVE(r, ok);
+ _block->JUMP(endif);
+ qSwap(_block, iftrue);
+
+ qSwap(_block, iffalse);
+ ExprResult ko = expression(ast->ko);
+ _block->MOVE(r, ko);
+ _block->JUMP(endif);
+ qSwap(_block, iffalse);
+
+ r->type = maxType(ok.type(), ko.type());
+ _expr.code = r;
+
+ _block = endif;
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::Expression *ast)
+{
+ _block->EXP(expression(ast->left));
+ _expr = expression(ast->right);
+
+ return false;
+}
+
+
+// statements
+bool QDeclarativeV4IRBuilder::visit(AST::Block *ast)
+{
+ if (ast->statements && ! ast->statements->next) {
+ // we have one and only one statement
+ accept(ast->statements->statement);
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::StatementList *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::VariableStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::VariableDeclarationList *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::VariableDeclaration *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::EmptyStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ExpressionStatement *ast)
+{
+ if (ast->expression) {
+ // return the value of this expression
+ return true;
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::IfStatement *ast)
+{
+ if (! ast->ko) {
+ // This is an if statement without an else branch.
+ discard();
+ } else {
+ IR::BasicBlock *iftrue = _function->newBasicBlock();
+ IR::BasicBlock *iffalse = _function->newBasicBlock();
+ IR::BasicBlock *endif = _function->newBasicBlock();
+
+ condition(ast->expression, iftrue, iffalse);
+
+ IR::Temp *r = _block->TEMP(IR::InvalidType);
+
+ qSwap(_block, iftrue);
+ ExprResult ok = statement(ast->ok);
+ _block->MOVE(r, ok);
+ _block->JUMP(endif);
+ qSwap(_block, iftrue);
+
+ qSwap(_block, iffalse);
+ ExprResult ko = statement(ast->ko);
+ _block->MOVE(r, ko);
+ _block->JUMP(endif);
+ qSwap(_block, iffalse);
+
+ r->type = maxType(ok.type(), ko.type());
+ _expr.code = r;
+
+ _block = endif;
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::DoWhileStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::WhileStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ForStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::LocalForStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ForEachStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::LocalForEachStatement *)
+{
+ discard();
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ContinueStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::BreakStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ReturnStatement *ast)
+{
+ if (ast->expression) {
+ // return the value of the expression
+ return true;
+ }
+
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::WithStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::SwitchStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::CaseBlock *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::CaseClauses *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::CaseClause *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::DefaultClause *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::LabelledStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::ThrowStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::TryStatement *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::Catch *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::Finally *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::FunctionDeclaration *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::FunctionExpression *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::FormalParameterList *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::FunctionBody *)
+{
+ return false;
+}
+
+bool QDeclarativeV4IRBuilder::visit(AST::DebuggerStatement *)
+{
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h b/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h
new file mode 100644
index 0000000000..f0bfd6624c
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEV4IRBUILDER_P_H
+#define QDECLARATIVEV4IRBUILDER_P_H
+
+#include <QtCore/qglobal.h>
+
+#include "qdeclarativev4ir_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeV4IRBuilder : public QDeclarativeJS::AST::Visitor
+{
+public:
+ QDeclarativeV4IRBuilder(const QDeclarativeV4Compiler::Expression *, QDeclarativeEnginePrivate *);
+
+ QDeclarativeJS::IR::Function *operator()(QDeclarativeJS::IR::Module *, QDeclarativeJS::AST::Node *);
+
+protected:
+ struct ExprResult {
+ enum Format {
+ ex, // expression
+ cx // condition
+ };
+
+ QDeclarativeJS::IR::Expr *code;
+ QDeclarativeJS::IR::BasicBlock *iftrue;
+ QDeclarativeJS::IR::BasicBlock *iffalse;
+ Format hint; // requested format
+ Format format; // instruction format
+
+ ExprResult(QDeclarativeJS::IR::Expr *expr = 0)
+ : code(expr), iftrue(0), iffalse(0), hint(ex), format(ex) {}
+
+ ExprResult(QDeclarativeJS::IR::BasicBlock *iftrue, QDeclarativeJS::IR::BasicBlock *iffalse)
+ : code(0), iftrue(iftrue), iffalse(iffalse), hint(cx), format(ex) {}
+
+ inline QDeclarativeJS::IR::Type type() const { return code ? code->type : QDeclarativeJS::IR::InvalidType; }
+
+ inline QDeclarativeJS::IR::Expr *get() const { return code; }
+ inline operator QDeclarativeJS::IR::Expr *() const { return get(); }
+ inline QDeclarativeJS::IR::Expr *operator->() const { return get(); }
+ inline bool isValid() const { return code ? code->type != QDeclarativeJS::IR::InvalidType : false; }
+ inline bool is(QDeclarativeJS::IR::Type t) const { return type() == t; }
+ inline bool isNot(QDeclarativeJS::IR::Type t) const { return type() != t; }
+
+ bool isPrimitive() const {
+ switch (type()) {
+ case QDeclarativeJS::IR::UndefinedType: // ### TODO
+ case QDeclarativeJS::IR::NullType: // ### TODO
+ case QDeclarativeJS::IR::UrlType: // ### TODO
+ return false;
+
+ case QDeclarativeJS::IR::StringType:
+ case QDeclarativeJS::IR::BoolType:
+ case QDeclarativeJS::IR::IntType:
+ case QDeclarativeJS::IR::RealType:
+ case QDeclarativeJS::IR::RealNaNType:
+ return true;
+
+ default:
+ return false;
+ } // switch
+ }
+ };
+
+ inline void accept(QDeclarativeJS::AST::Node *ast) { QDeclarativeJS::AST::Node::accept(ast, this); }
+
+ ExprResult expression(QDeclarativeJS::AST::ExpressionNode *ast);
+ ExprResult statement(QDeclarativeJS::AST::Statement *ast);
+ void sourceElement(QDeclarativeJS::AST::SourceElement *ast);
+ void condition(QDeclarativeJS::AST::ExpressionNode *ast, QDeclarativeJS::IR::BasicBlock *iftrue, QDeclarativeJS::IR::BasicBlock *iffalse);
+ void binop(QDeclarativeJS::AST::BinaryExpression *ast, ExprResult left, ExprResult right);
+
+ void implicitCvt(ExprResult &expr, QDeclarativeJS::IR::Type type);
+
+ // QML
+ virtual bool visit(QDeclarativeJS::AST::UiProgram *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiImportList *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiImport *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiPublicMember *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiSourceElement *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiObjectDefinition *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiObjectInitializer *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiObjectBinding *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiScriptBinding *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiArrayBinding *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiObjectMemberList *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiArrayMemberList *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiQualifiedId *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiSignature *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiFormalList *ast);
+ virtual bool visit(QDeclarativeJS::AST::UiFormal *ast);
+
+ // JS
+ virtual bool visit(QDeclarativeJS::AST::Program *ast);
+ virtual bool visit(QDeclarativeJS::AST::SourceElements *ast);
+ virtual bool visit(QDeclarativeJS::AST::FunctionSourceElement *ast);
+ virtual bool visit(QDeclarativeJS::AST::StatementSourceElement *ast);
+
+ // object literals
+ virtual bool visit(QDeclarativeJS::AST::PropertyNameAndValueList *ast);
+ virtual bool visit(QDeclarativeJS::AST::IdentifierPropertyName *ast);
+ virtual bool visit(QDeclarativeJS::AST::StringLiteralPropertyName *ast);
+ virtual bool visit(QDeclarativeJS::AST::NumericLiteralPropertyName *ast);
+
+ // array literals
+ virtual bool visit(QDeclarativeJS::AST::ElementList *ast);
+ virtual bool visit(QDeclarativeJS::AST::Elision *ast);
+
+ // function calls
+ virtual bool visit(QDeclarativeJS::AST::ArgumentList *ast);
+
+ // expressions
+ virtual bool visit(QDeclarativeJS::AST::ObjectLiteral *ast);
+ virtual bool visit(QDeclarativeJS::AST::ArrayLiteral *ast);
+ virtual bool visit(QDeclarativeJS::AST::ThisExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::IdentifierExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::NullExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::TrueLiteral *ast);
+ virtual bool visit(QDeclarativeJS::AST::FalseLiteral *ast);
+ virtual bool visit(QDeclarativeJS::AST::StringLiteral *ast);
+ virtual bool visit(QDeclarativeJS::AST::NumericLiteral *ast);
+ virtual bool visit(QDeclarativeJS::AST::RegExpLiteral *ast);
+ virtual bool visit(QDeclarativeJS::AST::NestedExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::ArrayMemberExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::FieldMemberExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::NewMemberExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::NewExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::CallExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::PostIncrementExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::PostDecrementExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::DeleteExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::VoidExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::TypeOfExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::PreIncrementExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::PreDecrementExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::UnaryPlusExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::UnaryMinusExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::TildeExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::NotExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::BinaryExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::ConditionalExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::Expression *ast);
+
+ // statements
+ virtual bool visit(QDeclarativeJS::AST::Block *ast);
+ virtual bool visit(QDeclarativeJS::AST::StatementList *ast);
+ virtual bool visit(QDeclarativeJS::AST::VariableStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::VariableDeclarationList *ast);
+ virtual bool visit(QDeclarativeJS::AST::VariableDeclaration *ast);
+ virtual bool visit(QDeclarativeJS::AST::EmptyStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::ExpressionStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::IfStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::DoWhileStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::WhileStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::ForStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::LocalForStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::ForEachStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::LocalForEachStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::ContinueStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::BreakStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::ReturnStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::WithStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::SwitchStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::CaseBlock *ast);
+ virtual bool visit(QDeclarativeJS::AST::CaseClauses *ast);
+ virtual bool visit(QDeclarativeJS::AST::CaseClause *ast);
+ virtual bool visit(QDeclarativeJS::AST::DefaultClause *ast);
+ virtual bool visit(QDeclarativeJS::AST::LabelledStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::ThrowStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::TryStatement *ast);
+ virtual bool visit(QDeclarativeJS::AST::Catch *ast);
+ virtual bool visit(QDeclarativeJS::AST::Finally *ast);
+ virtual bool visit(QDeclarativeJS::AST::FunctionDeclaration *ast);
+ virtual bool visit(QDeclarativeJS::AST::FunctionExpression *ast);
+ virtual bool visit(QDeclarativeJS::AST::FormalParameterList *ast);
+ virtual bool visit(QDeclarativeJS::AST::FunctionBody *ast);
+ virtual bool visit(QDeclarativeJS::AST::DebuggerStatement *ast);
+
+private:
+ bool buildName(QStringList &name, QDeclarativeJS::AST::Node *node,
+ QList<QDeclarativeJS::AST::ExpressionNode *> *nodes);
+ void discard();
+
+ const QDeclarativeV4Compiler::Expression *m_expression;
+ QDeclarativeEnginePrivate *m_engine;
+
+ QDeclarativeJS::IR::Module *_module;
+ QDeclarativeJS::IR::Function *_function;
+ QDeclarativeJS::IR::BasicBlock *_block;
+ bool _discard;
+
+ ExprResult _expr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEV4IRBUILDER_P_H
diff --git a/src/declarative/qml/v4/qdeclarativev4program_p.h b/src/declarative/qml/v4/qdeclarativev4program_p.h
new file mode 100644
index 0000000000..d036bd6f73
--- /dev/null
+++ b/src/declarative/qml/v4/qdeclarativev4program_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEV4PROGRAM_P_H
+#define QDECLARATIVEV4PROGRAM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qdeclarativev4instruction_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+struct QDeclarativeV4Program {
+ quint32 bindings;
+ quint32 dataLength;
+ quint32 signalTableOffset;
+ quint32 exceptionDataOffset;
+ quint16 subscriptions;
+ quint16 identifiers;
+ quint16 instructionCount;
+
+ struct BindingReference {
+ quint32 binding;
+ quint32 blockMask;
+ };
+
+ struct BindingReferenceList {
+ quint32 count;
+ BindingReference bindings[];
+ };
+
+ inline const char *data() const;
+ inline const char *instructions() const;
+ inline BindingReferenceList *signalTable(int signalIndex) const;
+};
+
+enum QDeclarativeRegisterType {
+ UndefinedType,
+ QObjectStarType,
+ QRealType,
+ IntType,
+ BoolType,
+
+ PODValueType,
+
+ FirstCleanupType,
+ QStringType = FirstCleanupType,
+ QUrlType,
+ QVariantType,
+};
+
+const char *QDeclarativeV4Program::data() const
+{
+ return ((const char *)this) + sizeof(QDeclarativeV4Program);
+}
+
+const char *QDeclarativeV4Program::instructions() const
+{
+ return (const char *)(data() + dataLength);
+}
+
+QDeclarativeV4Program::BindingReferenceList *QDeclarativeV4Program::signalTable(int signalIndex) const
+{
+ quint32 *signalTable = (quint32 *)(data() + signalTableOffset);
+ return (BindingReferenceList *)(signalTable + signalTable[signalIndex]);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEV4PROGRAM_P_H
+
diff --git a/src/declarative/qml/v4/v4.pri b/src/declarative/qml/v4/v4.pri
new file mode 100644
index 0000000000..085f0ae443
--- /dev/null
+++ b/src/declarative/qml/v4/v4.pri
@@ -0,0 +1,17 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qdeclarativev4compiler_p.h \
+ $$PWD/qdeclarativev4compiler_p_p.h \
+ $$PWD/qdeclarativev4ir_p.h \
+ $$PWD/qdeclarativev4irbuilder_p.h \
+ $$PWD/qdeclarativev4instruction_p.h \
+ $$PWD/qdeclarativev4bindings_p.h \
+ $$PWD/qdeclarativev4program_p.h \
+
+SOURCES += \
+ $$PWD/qdeclarativev4compiler.cpp \
+ $$PWD/qdeclarativev4ir.cpp \
+ $$PWD/qdeclarativev4irbuilder.cpp \
+ $$PWD/qdeclarativev4instruction.cpp \
+ $$PWD/qdeclarativev4bindings.cpp \