From a190b92bb4eb40ecf8c30d6f368c0d15ec317580 Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Wed, 27 May 2009 15:15:54 +1000
Subject: Small cleanups

---
 src/declarative/qml/qmlcompiler.cpp | 16 +++++++---------
 src/declarative/qml/qmlcompiler_p.h |  4 +---
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index cce8109..09f4e0b 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -728,12 +728,12 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
     ids.clear();
     if (obj) 
         COMPILE_CHECK(compileObject(obj, ctxt));
-    ids = oldIds;
 
     create.createComponent.count = output->bytecode.count() - count;
 
     int inc = optimizeExpressions(count, count - 1 + create.createComponent.count, count);
     create.createComponent.count += inc;
+    ids = oldIds;
     return true;
 }
 
@@ -914,7 +914,7 @@ bool QmlCompiler::compileProperty(Property *prop, Object *obj, int ctxt)
 
     } else if (isAttachedPropertyName(prop->name)) {
 
-        COMPILE_CHECK(compileAttachedProperty(prop, obj, ctxt));
+        COMPILE_CHECK(compileAttachedProperty(prop, ctxt));
 
     } else if (prop->index == -1) {
 
@@ -995,7 +995,6 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop,
 // }
 // GridView is an attached property object.
 bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop, 
-                                          QmlParser::Object *obj,
                                           int ctxt)
 {
     Q_ASSERT(prop->value);
@@ -1158,7 +1157,7 @@ bool QmlCompiler::compilePropertyAssignment(QmlParser::Property *prop,
         Value *v = prop->values.at(ii);
         if (v->object) {
 
-            COMPILE_CHECK(compilePropertyObjectAssignment(prop, obj, v, ctxt));
+            COMPILE_CHECK(compilePropertyObjectAssignment(prop, v, ctxt));
 
         } else {
 
@@ -1172,7 +1171,6 @@ bool QmlCompiler::compilePropertyAssignment(QmlParser::Property *prop,
 
 // Compile assigning a single object instance to a regular property 
 bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
-                                                  QmlParser::Object *obj,
                                                   QmlParser::Value *v,
                                                   int ctxt)
 {
@@ -1402,6 +1400,10 @@ bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
     Q_ASSERT(mo);
     Q_ASSERT(prop->index);
 
+    QMetaProperty mp = mo->property(prop->index);
+    if (!mp.isWritable() && !QmlMetaType::isList(prop->type))
+        COMPILE_EXCEPTION2(prop, "Cannot assign binding to read-only property");
+
     QmlBasicScript bs;
     bs.compile(bind.toLatin1());
 
@@ -1423,11 +1425,7 @@ bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
 
     assign.assignBinding.property = prop->index;
     assign.assignBinding.value = bref;
-    QMetaProperty mp = mo->property(assign.assignBinding.property);
-    if (!mp.isWritable() && !QmlMetaType::isList(prop->type))
-        COMPILE_EXCEPTION2(prop, "Cannot assign binding to read-only property");
     assign.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
-
     savedTypes.insert(output->bytecode.count(), prop->type);
     output->bytecode << assign;
 
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index bc9e06c..6e9bafb 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -137,7 +137,6 @@ private:
     bool compileIdProperty(QmlParser::Property *prop, 
                            QmlParser::Object *obj);
     bool compileAttachedProperty(QmlParser::Property *prop, 
-                                 QmlParser::Object *obj,
                                  int ctxt);
     bool compileNestedProperty(QmlParser::Property *prop,
                                int ctxt);
@@ -148,7 +147,6 @@ private:
                                    QmlParser::Object *obj,
                                    int ctxt);
     bool compilePropertyObjectAssignment(QmlParser::Property *prop,
-                                         QmlParser::Object *obj,
                                          QmlParser::Value *value,
                                          int ctxt);
     bool compilePropertyLiteralAssignment(QmlParser::Property *prop,
@@ -166,11 +164,11 @@ private:
     int optimizeExpressions(int start, int end, int patch = -1);
 
     QSet<QString> ids;
+    QHash<int, int> savedTypes;
 
     QList<QmlError> exceptions;
     QmlCompiledData *output;
 
-    QHash<int, int> savedTypes;
 };
 
 QT_END_NAMESPACE
-- 
cgit v0.12


From 0a6df63c7150f0010b08ce2ba08a492cd129a96f Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Wed, 27 May 2009 16:03:25 +1000
Subject: Save the JavaScript AST in the QmlParser::Variant for use by others

---
 src/declarative/qml/qmlparser.cpp       | 18 +++++++++++++++---
 src/declarative/qml/qmlparser_p.h       |  7 ++++++-
 src/declarative/qml/qmlscriptparser.cpp |  8 ++++----
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index c5d7092..5c2a69f 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -281,10 +281,14 @@ QmlParser::Variant::Variant(double v, const QString &asWritten)
 {
 }
 
-QmlParser::Variant::Variant(const QString &v, Type type)
-: t(type), s(v)
+QmlParser::Variant::Variant(const QString &v)
+: t(String), s(v)
+{
+}
+
+QmlParser::Variant::Variant(const QString &v, JavaScript::AST::Node *n)
+: t(Script), n(n), s(v)
 {
-    Q_ASSERT(type == String || type == Script);
 }
 
 QmlParser::Variant &QmlParser::Variant::operator=(const Variant &o)
@@ -334,4 +338,12 @@ QString QmlParser::Variant::asScript() const
     }
 }
 
+JavaScript::AST::Node *QmlParser::Variant::asAST() const
+{
+    if (type() == Script)
+        return n;
+    else
+        return 0;
+}
+
 QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 721f1a8..cb9b540 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -55,6 +55,8 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
+namespace JavaScript { namespace AST { class Node; } }
+
 /*
     XXX
 
@@ -175,7 +177,8 @@ namespace QmlParser
         Variant(const Variant &);
         Variant(bool);
         Variant(double, const QString &asWritten=QString());
-        Variant(const QString &, Type = String);
+        Variant(const QString &);
+        Variant(const QString &, JavaScript::AST::Node *);
         Variant &operator=(const Variant &);
 
         Type type() const;
@@ -189,12 +192,14 @@ namespace QmlParser
         QString asString() const;
         double asNumber() const;
         QString asScript() const;
+        JavaScript::AST::Node *asAST() const;
 
     private:
         Type t;
         union {
             bool b;
             double d;
+            JavaScript::AST::Node *n;
         };
         QString s;
     };
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index 5c5b25e..b862953 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -587,7 +587,7 @@ QmlParser::Variant ProcessAST::getVariant(AST::ExpressionNode *expr)
         if (lit->suffix == AST::NumericLiteral::noSuffix)
             return QmlParser::Variant(lit->value, asString(expr));
         else
-            return QmlParser::Variant(asString(expr), QmlParser::Variant::Script);
+            return QmlParser::Variant(asString(expr), expr);
 
     } else {
 
@@ -597,7 +597,7 @@ QmlParser::Variant ProcessAST::getVariant(AST::ExpressionNode *expr)
            }
         }
 
-        return QmlParser::Variant(asString(expr), QmlParser::Variant::Script);
+        return QmlParser::Variant(asString(expr), expr);
     }
 }
 
@@ -620,8 +620,8 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
     if (AST::ExpressionStatement *stmt = AST::cast<AST::ExpressionStatement *>(node->statement)) {
         primitive = getVariant(stmt->expression);
     } else { // do binding
-        primitive = QmlParser::Variant(asString(node->statement),
-                                       QmlParser::Variant::Script);
+        primitive = QmlParser::Variant(asString(node->statement), 
+                                       node->statement);
     }
 
     Value *v = new Value;
-- 
cgit v0.12


From c8f180e7023308b8a051b53943b9a088a7f0c427 Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Wed, 27 May 2009 20:40:28 +1000
Subject: Small cleanups

---
 src/declarative/qml/qmlcompiler.cpp     | 175 +++++++++++++++-----------------
 src/declarative/qml/qmlcompiler_p.h     |  26 ++++-
 src/declarative/qml/qmlscriptparser.cpp |  34 +++++--
 src/declarative/qml/qmlscriptparser_p.h |   2 +
 4 files changed, 132 insertions(+), 105 deletions(-)

diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 09f4e0b..b9a848a 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -62,6 +62,7 @@
 #include "private/qmlcustomparser_p_p.h"
 #include <private/qmlcontext_p.h>
 #include <private/qmlcomponent_p.h>
+#include "parser/javascriptast_p.h"
 
 #include "qmlscriptparser_p.h"
 
@@ -516,6 +517,7 @@ bool QmlCompiler::compile(QmlEngine *engine,
     }
 
     output = 0;
+
     return !isError();
 }
 
@@ -542,7 +544,7 @@ void QmlCompiler::compileTree(Object *tree)
     def.type = QmlInstruction::SetDefault;
     output->bytecode << def;
 
-    optimizeExpressions(0, output->bytecode.count() - 1, 0);
+    finalizeComponent(0);
 }
 
 bool QmlCompiler::compileObject(Object *obj, int ctxt)
@@ -588,6 +590,8 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
         begin.begin.castValue = parserStatusCast;
         begin.line = obj->location.start.line;
         output->bytecode << begin;
+
+        compileState.parserStatusCount++;
     }
 
     // Check if this is a custom parser type.  Custom parser types allow 
@@ -688,9 +692,14 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt)
         if (!isValidId(val))
             COMPILE_EXCEPTION("Invalid id property value");
 
-        if (ids.contains(val))
+        if (compileState.ids.contains(val))
             COMPILE_EXCEPTION("id is not unique");
-        ids.insert(val);
+
+        IdReference reference;
+        reference.id = val;
+        reference.object = obj;
+        reference.instructionIdx = output->bytecode.count();
+        compileState.ids.insert(val, reference);
 
         int pref = output->indexForString(val);
         QmlInstruction id;
@@ -699,8 +708,6 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt)
         id.setId.value = pref;
         id.setId.save = -1;
 
-        savedTypes.insert(output->bytecode.count(), -1);
-
         output->bytecode << id;
     }
 
@@ -724,16 +731,16 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
     init.line = obj->location.start.line;
     output->bytecode << init;
 
-    QSet<QString> oldIds = ids;
-    ids.clear();
+    ComponentCompileState oldComponentCompileState = compileState;
+    compileState = ComponentCompileState();
     if (obj) 
         COMPILE_CHECK(compileObject(obj, ctxt));
 
     create.createComponent.count = output->bytecode.count() - count;
 
-    int inc = optimizeExpressions(count, count - 1 + create.createComponent.count, count);
+    int inc = finalizeComponent(count);
     create.createComponent.count += inc;
-    ids = oldIds;
+    compileState = oldComponentCompileState;
     return true;
 }
 
@@ -950,41 +957,43 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop,
     if (prop->values.count() > 1)
         COMPILE_EXCEPTION2(prop, "The object id may only be set once");
 
-    if (prop->values.count() == 1) {
-        if (prop->values.at(0)->object)
-            COMPILE_EXCEPTION("Cannot assign an object as an id");
-        QString val = prop->values.at(0)->primitive();
-        if (!isValidId(val))
-            COMPILE_EXCEPTION(val << "is not a valid id");
-        if (ids.contains(val))
-            COMPILE_EXCEPTION("id is not unique");
-        ids.insert(val);
+    if (prop->values.at(0)->object)
+        COMPILE_EXCEPTION("Cannot assign an object as an id");
+    QString val = prop->values.at(0)->primitive();
+    if (!isValidId(val))
+        COMPILE_EXCEPTION(val << "is not a valid id");
+    if (compileState.ids.contains(val))
+        COMPILE_EXCEPTION("id is not unique");
 
-        int pref = output->indexForString(val);
+    int pref = output->indexForString(val);
 
-        if (prop->type == QVariant::String) {
-            QmlInstruction assign;
-            assign.type = QmlInstruction::StoreString;
-            assign.storeString.propertyIndex = prop->index;
-            assign.storeString.value = pref;
-            assign.line = prop->values.at(0)->location.start.line;
-            output->bytecode << assign;
+    if (prop->type == QVariant::String) {
+        QmlInstruction assign;
+        assign.type = QmlInstruction::StoreString;
+        assign.storeString.propertyIndex = prop->index;
+        assign.storeString.value = pref;
+        assign.line = prop->values.at(0)->location.start.line;
+        output->bytecode << assign;
 
-            prop->values.at(0)->type = Value::Id;
-        } else {
-            prop->values.at(0)->type = Value::Literal;
-        }
+        prop->values.at(0)->type = Value::Id;
+    } else {
+        prop->values.at(0)->type = Value::Literal;
+    }
 
-        QmlInstruction id;
-        id.type = QmlInstruction::SetId;
-        id.line = prop->values.at(0)->location.start.line;
-        id.setId.value = pref;
-        id.setId.save = -1;
-        savedTypes.insert(output->bytecode.count(), obj->type);
-        output->bytecode << id;
+    IdReference reference;
+    reference.id = val;
+    reference.object = obj;
+    reference.instructionIdx = output->bytecode.count();
+    compileState.ids.insert(val, reference);
 
-        obj->id = val.toLatin1();
-    }
+    QmlInstruction id;
+    id.type = QmlInstruction::SetId;
+    id.line = prop->values.at(0)->location.start.line;
+    id.setId.value = pref;
+    id.setId.save = -1;
+    output->bytecode << id;
+
+    obj->id = val.toLatin1();
 
     return true;
 }
@@ -1116,7 +1125,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
                     COMPILE_EXCEPTION("Can only assign one binding to lists");
 
                 assignedBinding = true;
-                COMPILE_CHECK(compileBinding(v->value.asScript(), prop, ctxt, 
+                COMPILE_CHECK(compileBinding(v->value, prop, ctxt, 
                                              obj->metaObject(), 
                                              v->location.start.line));
                 v->type = Value::PropertyBinding;
@@ -1287,7 +1296,7 @@ bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
 
     if (v->value.isScript()) {
 
-        COMPILE_CHECK(compileBinding(v->value.asScript(), prop, ctxt, 
+        COMPILE_CHECK(compileBinding(v->value, prop, ctxt, 
                                      obj->metaObject(), 
                                      v->location.start.line));
 
@@ -1394,7 +1403,8 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj)
     return true;
 }
 
-bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
+bool QmlCompiler::compileBinding(const QmlParser::Variant &bind, 
+                                 QmlParser::Property *prop,
                                  int ctxt, const QMetaObject *mo, qint64 line)
 {
     Q_ASSERT(mo);
@@ -1405,13 +1415,13 @@ bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
         COMPILE_EXCEPTION2(prop, "Cannot assign binding to read-only property");
 
     QmlBasicScript bs;
-    bs.compile(bind.toLatin1());
+    bs.compile(bind.asScript().toLatin1());
 
     int bref;
     if (bs.isValid()) {
         bref = output->indexForByteArray(QByteArray(bs.compileData(), bs.compileDataSize()));
     } else {
-        bref = output->indexForString(bind);
+        bref = output->indexForString(bind.asScript());
     }
 
     QmlInstruction assign;
@@ -1426,49 +1436,28 @@ bool QmlCompiler::compileBinding(const QString &bind, QmlParser::Property *prop,
     assign.assignBinding.property = prop->index;
     assign.assignBinding.value = bref;
     assign.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
-    savedTypes.insert(output->bytecode.count(), prop->type);
+    BindingReference reference;
+    reference.expression = bind;
+    reference.property = prop;
+    reference.instructionIdx = output->bytecode.count();
+    compileState.bindings << reference;
+
     output->bytecode << assign;
 
     return true;
 }
 
-int QmlCompiler::optimizeExpressions(int start, int end, int patch)
+// Update the init instruction with final data, and optimize some simple 
+// bindings
+int QmlCompiler::finalizeComponent(int patch)
 {
-    QHash<QString, int> ids;
     int saveCount = 0;
     int newInstrs = 0;
-    int bindingsCount = 0;
-    int parserStatusCount = 0;
 
-    for (int ii = start; ii <= end; ++ii) {
-        const QmlInstruction &instr = output->bytecode.at(ii);
-
-        if (instr.type == QmlInstruction::CreateComponent) {
-            ii += instr.createComponent.count - 1;
-            continue;
-        }
-
-        if (instr.type == QmlInstruction::SetId) {
-            QString id = output->primitives.at(instr.setId.value);
-            ids.insert(id, ii);
-        }
-    }
-
-    for (int ii = start; ii <= end; ++ii) {
-        const QmlInstruction &instr = output->bytecode.at(ii);
-
-        if (instr.type == QmlInstruction::CreateComponent) {
-            ii += instr.createComponent.count - 1;
-            continue;
-        }
-        
-        if (instr.type == QmlInstruction::StoreBinding ||
-            instr.type == QmlInstruction::StoreCompiledBinding) {
-            ++bindingsCount;
-        } else if (instr.type == QmlInstruction::BeginObject) {
-            ++parserStatusCount;
-        }
+    for (int ii = 0; ii < compileState.bindings.count(); ++ii) {
+        const BindingReference &binding = compileState.bindings.at(ii);
 
+        QmlInstruction &instr = output->bytecode[binding.instructionIdx];
 
         if (instr.type == QmlInstruction::StoreCompiledBinding) {
             QmlBasicScript s(output->datas.at(instr.assignBinding.value).constData());
@@ -1478,16 +1467,17 @@ int QmlCompiler::optimizeExpressions(int start, int end, int patch)
                 if (!slt.at(0).isUpper())
                     continue;
 
-                if (ids.contains(slt) && 
+                if (compileState.ids.contains(slt) && 
                    instr.assignBinding.category == QmlMetaProperty::Object) {
-                    int id = ids[slt];
 
-                    int idType = savedTypes.value(id);
-                    int storeType = savedTypes.value(ii);
+                    IdReference reference = 
+                        compileState.ids[slt];
+
+                    const QMetaObject *idMo = reference.object->metaObject();
+                    const QMetaObject *storeMo = QmlMetaType::rawMetaObjectForType(binding.property->type);
 
-                    const QMetaObject *idMo = (idType == -1)?&QmlComponent::staticMetaObject:output->types.at(idType).metaObject();
-                    const QMetaObject *storeMo = 
-                        QmlMetaType::rawMetaObjectForType(storeType);
+                    Q_ASSERT(idMo);
+                    Q_ASSERT(storeMo);
 
                     bool canAssign = false;
                     while (!canAssign && idMo) {
@@ -1502,19 +1492,19 @@ int QmlCompiler::optimizeExpressions(int start, int end, int patch)
 
                     int saveId = -1;
 
-                    if (output->bytecode.at(id).setId.save != -1) {
-                        saveId = output->bytecode.at(id).setId.save;
+                    int instructionIdx = reference.instructionIdx;
+                    if (output->bytecode.at(instructionIdx).setId.save != -1) {
+                        saveId = output->bytecode.at(instructionIdx).setId.save;
                     } else {
-                        output->bytecode[id].setId.save = saveCount;
+                        output->bytecode[instructionIdx].setId.save = saveCount;
                         saveId = saveCount;
                         ++saveCount;
                     }
 
                     int prop = instr.assignBinding.property;
 
-                    QmlInstruction &rwinstr = output->bytecode[ii];
-                    rwinstr.type = QmlInstruction::PushProperty;
-                    rwinstr.pushProperty.property = prop;
+                    instr.type = QmlInstruction::PushProperty;
+                    instr.pushProperty.property = prop;
 
                     QmlInstruction instr;
                     instr.type = QmlInstruction::StoreStackObject;
@@ -1529,8 +1519,9 @@ int QmlCompiler::optimizeExpressions(int start, int end, int patch)
     }
 
     output->bytecode[patch].init.dataSize = saveCount;
-    output->bytecode[patch].init.bindingsSize = bindingsCount;
-    output->bytecode[patch].init.parserStatusSize = parserStatusCount;;
+    output->bytecode[patch].init.bindingsSize = compileState.bindings.count();
+    output->bytecode[patch].init.parserStatusSize = 
+        compileState.parserStatusCount;
 
     return newInstrs;
 }
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 6e9bafb..b1963da 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -158,13 +158,31 @@ private:
                                  QmlParser::Value *value);
 
     bool compileDynamicMeta(QmlParser::Object *obj);
-    bool compileBinding(const QString &, QmlParser::Property *prop,
+    bool compileBinding(const QmlParser::Variant &, QmlParser::Property *prop,
                         int ctxt, const QMetaObject *, qint64);
 
-    int optimizeExpressions(int start, int end, int patch = -1);
+    int finalizeComponent(int patch);
 
-    QSet<QString> ids;
-    QHash<int, int> savedTypes;
+    struct IdReference {
+        QString id;
+        QmlParser::Object *object;
+        int instructionIdx;
+    };
+
+    struct BindingReference {
+        QmlParser::Variant expression;
+        QmlParser::Property *property;
+        int instructionIdx;
+    };
+
+    struct ComponentCompileState
+    {
+        ComponentCompileState() : parserStatusCount(0) {}
+        QHash<QString, IdReference> ids;
+        int parserStatusCount;
+        QList<BindingReference> bindings;
+    };
+    ComponentCompileState compileState;
 
     QList<QmlError> exceptions;
     QmlCompiledData *output;
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index b862953..b1ffc98 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -597,7 +597,7 @@ QmlParser::Variant ProcessAST::getVariant(AST::ExpressionNode *expr)
            }
         }
 
-        return QmlParser::Variant(asString(expr), expr);
+        return  QmlParser::Variant(asString(expr), expr);
     }
 }
 
@@ -716,33 +716,44 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
 
 
 QmlScriptParser::QmlScriptParser()
-: root(0)
+: root(0), data(0)
 {
 
 }
 
 QmlScriptParser::~QmlScriptParser()
 {
+    clear();
 }
 
-bool QmlScriptParser::parse(const QByteArray &data, const QUrl &url)
+class QmlScriptParserJsASTData
+{
+public:
+    QmlScriptParserJsASTData(const QString &filename)
+        : nodePool(filename, &engine) {}
+
+    Engine engine;
+    NodePool nodePool;
+};
+
+bool QmlScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
 {
 #ifdef Q_ENABLE_PERFORMANCE_LOG
     QFxPerfTimer<QFxPerf::QmlParsing> pt;
 #endif
+    clear();
+
     const QString fileName = url.toString();
 
-    QTextStream stream(data, QIODevice::ReadOnly);
+    QTextStream stream(qmldata, QIODevice::ReadOnly);
     const QString code = stream.readAll();
 
-    Engine engine;
-
-    NodePool nodePool(fileName, &engine);
+    data = new QmlScriptParserJsASTData(fileName);
 
-    Lexer lexer(&engine);
+    Lexer lexer(&data->engine);
     lexer.setCode(code, /*line = */ 1);
 
-    Parser parser(&engine);
+    Parser parser(&data->engine);
 
     if (! parser.parse() || !_errors.isEmpty()) {
 
@@ -808,6 +819,11 @@ void QmlScriptParser::clear()
     _nameSpacePaths.clear();
     _typeNames.clear();
     _errors.clear();
+
+    if (data) {
+        delete data;
+        data = 0;
+    }
 }
 
 int QmlScriptParser::findOrCreateTypeId(const QString &name)
diff --git a/src/declarative/qml/qmlscriptparser_p.h b/src/declarative/qml/qmlscriptparser_p.h
index a9ffa47..3993194 100644
--- a/src/declarative/qml/qmlscriptparser_p.h
+++ b/src/declarative/qml/qmlscriptparser_p.h
@@ -54,6 +54,7 @@ QT_MODULE(Declarative)
 
 class QByteArray;
 
+class QmlScriptParserJsASTData;
 class QmlScriptParser
 {
 public:
@@ -98,6 +99,7 @@ public:
     QList<Import> _imports;
     QStringList _typeNames;
     QString _scriptFile;
+    QmlScriptParserJsASTData *data;
 };
 
 QT_END_NAMESPACE
-- 
cgit v0.12


From b865ab6508963cbad0a12319b40db17f9925bbde Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Thu, 28 May 2009 10:48:50 +1000
Subject: QmlBasicScript should work on the actual JS AST tree

---
 src/declarative/fx/qfxkeyactions.cpp               |   2 +-
 src/declarative/qml/parser/javascriptast_p.h       |   6 +-
 src/declarative/qml/qml.pri                        |   6 +-
 src/declarative/qml/qmlbasicscript.cpp             | 853 +++++++++++++++++++
 src/declarative/qml/qmlbasicscript_p.h             | 104 +++
 src/declarative/qml/qmlbindablevalue.cpp           |   4 +-
 src/declarative/qml/qmlbindablevalue.h             |   2 +-
 src/declarative/qml/qmlcompiler.cpp                |  45 +-
 src/declarative/qml/qmlengine.cpp                  |  36 +-
 src/declarative/qml/qmlengine_p.h                  |   4 +-
 src/declarative/qml/qmlexpression.h                |   2 -
 src/declarative/qml/qmlparser.cpp                  |   1 -
 src/declarative/qml/script/generator/generator.pro |  11 -
 src/declarative/qml/script/generator/main.cpp      | 135 ---
 src/declarative/qml/script/instructions.h          |  32 -
 src/declarative/qml/script/keywords.cpp            |  89 --
 src/declarative/qml/script/lexer.cpp               | 139 ----
 src/declarative/qml/script/lexer.h                 |  54 --
 src/declarative/qml/script/qmlbasicscript.cpp      | 921 ---------------------
 src/declarative/qml/script/qmlbasicscript.h        |  76 --
 src/declarative/qml/script/qmlbasicscript_p.h      |  53 --
 src/declarative/qml/script/script.pri              |  11 -
 src/declarative/qml/script/tokens.cpp              |  43 -
 src/declarative/qml/script/tokens.h                |  36 -
 24 files changed, 1017 insertions(+), 1648 deletions(-)
 create mode 100644 src/declarative/qml/qmlbasicscript.cpp
 create mode 100644 src/declarative/qml/qmlbasicscript_p.h
 delete mode 100644 src/declarative/qml/script/generator/generator.pro
 delete mode 100644 src/declarative/qml/script/generator/main.cpp
 delete mode 100644 src/declarative/qml/script/instructions.h
 delete mode 100644 src/declarative/qml/script/keywords.cpp
 delete mode 100644 src/declarative/qml/script/lexer.cpp
 delete mode 100644 src/declarative/qml/script/lexer.h
 delete mode 100644 src/declarative/qml/script/qmlbasicscript.cpp
 delete mode 100644 src/declarative/qml/script/qmlbasicscript.h
 delete mode 100644 src/declarative/qml/script/qmlbasicscript_p.h
 delete mode 100644 src/declarative/qml/script/script.pri
 delete mode 100644 src/declarative/qml/script/tokens.cpp
 delete mode 100644 src/declarative/qml/script/tokens.h

diff --git a/src/declarative/fx/qfxkeyactions.cpp b/src/declarative/fx/qfxkeyactions.cpp
index 5a1fd7d..4aae74f 100644
--- a/src/declarative/fx/qfxkeyactions.cpp
+++ b/src/declarative/fx/qfxkeyactions.cpp
@@ -899,7 +899,7 @@ void QFxKeyActions::keyPressEvent(QKeyEvent *event)
 {
     Qt::Key key = (Qt::Key)event->key();
     if (d->enabled && d->key(key)) {
-        QmlExpression b(qmlContext(this), d->action(key), this, false);
+        QmlExpression b(qmlContext(this), d->action(key), this);
         b.value();
         event->accept();
     } else {
diff --git a/src/declarative/qml/parser/javascriptast_p.h b/src/declarative/qml/parser/javascriptast_p.h
index b5fd922..23d59e5 100644
--- a/src/declarative/qml/parser/javascriptast_p.h
+++ b/src/declarative/qml/parser/javascriptast_p.h
@@ -61,8 +61,6 @@ QT_BEGIN_NAMESPACE
 #define JAVASCRIPT_DECLARE_AST_NODE(name) \
   enum { K = Kind_##name };
 
-class NameId;
-
 namespace QSOperator // ### rename
 {
 
@@ -106,7 +104,9 @@ enum Op {
 
 } // namespace QSOperator
 
-namespace JavaScript { namespace AST {
+namespace JavaScript { 
+class NameId;
+namespace AST {
 
 template <typename _T1, typename _T2>
 _T1 cast(_T2 *ast)
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index b6ac30e..c61200e 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -23,7 +23,8 @@ SOURCES += qml/qmlparser.cpp \
     qml/qmlcompositetypemanager.cpp \
     qml/qmlinfo.cpp \
     qml/qmlerror.cpp \
-    qml/qmlscriptparser.cpp
+    qml/qmlscriptparser.cpp \
+    qml/qmlbasicscript.cpp 
 
 HEADERS += qml/qmlparser_p.h \
     qml/qmlinstruction_p.h \
@@ -61,7 +62,8 @@ HEADERS += qml/qmlparser_p.h \
     qml/qmllist.h \
     qml/qmldeclarativedata_p.h \
     qml/qmlerror.h \
-    qml/qmlscriptparser_p.h
+    qml/qmlscriptparser_p.h \
+    qml/qmlbasicscript_p.h  
 
 # for qtscript debugger
 QT += scripttools
diff --git a/src/declarative/qml/qmlbasicscript.cpp b/src/declarative/qml/qmlbasicscript.cpp
new file mode 100644
index 0000000..3d74b37
--- /dev/null
+++ b/src/declarative/qml/qmlbasicscript.cpp
@@ -0,0 +1,853 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlbasicscript_p.h"
+#include <QColor>
+#include <QDebug>
+#include <private/qmlengine_p.h>
+#include <private/qmlcontext_p.h>
+#include <QStack>
+#include <qfxperf.h>
+#include <private/qmlrefcount_p.h>
+#include <private/javascriptast_p.h>
+#include <private/javascriptengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+struct ScriptInstruction {
+    enum {
+        Load,       // fetch
+        Fetch,       // fetch
+
+        Add,         // NA
+        Subtract,    // NA
+        Multiply,    // NA
+        Equals,      // NA
+        And,         // NA
+
+        Int,         // integer
+        Bool,        // boolean
+    } type;
+
+    union {
+        struct {
+            int idx;
+        } fetch;
+        struct {
+            int value;
+        } integer;
+        struct {
+            bool value;
+        } boolean;
+    };
+};
+
+DEFINE_BOOL_CONFIG_OPTION(scriptWarnings, QML_SCRIPT_WARNINGS);
+
+class QmlBasicScriptPrivate
+{
+public:
+    enum Flags { OwnData = 0x00000001 };
+    
+    int size;
+    int stateSize;
+    int instructionCount;
+    int exprLen;
+
+    ScriptInstruction *instructions() const { return (ScriptInstruction *)((char *)this + sizeof(QmlBasicScriptPrivate)); }
+
+    const char *expr() const
+    {
+        return (const char *)(instructions() + instructionCount);
+    }
+
+    const char *data() const 
+    {
+        return (const char *)(instructions() + instructionCount) + exprLen + 1;
+    }
+
+    static unsigned int alignRound(int s)
+    {
+        if (s % 4) 
+            s += 4 - (s % 4);
+        return s;
+    }
+};
+
+QDebug operator<<(QDebug lhs, const QmlBasicScriptNodeCache &rhs)
+{
+    switch(rhs.type) {
+    case QmlBasicScriptNodeCache::Invalid:
+        lhs << "Invalid";
+        break;
+    case QmlBasicScriptNodeCache::Core:
+        lhs << "Core" << rhs.object << rhs.core;
+        break;
+    case QmlBasicScriptNodeCache::Attached: 
+        lhs << "Attached" << rhs.object << rhs.attached;
+        break;
+    case QmlBasicScriptNodeCache::Signal: 
+        lhs << "Signal" << rhs.object << rhs.core;
+        break;
+    case QmlBasicScriptNodeCache::SignalProperty: 
+        lhs << "SignalProperty" << rhs.object << rhs.core;
+        break;
+    case QmlBasicScriptNodeCache::Variant: 
+        lhs << "Variant" << rhs.context;
+        break;
+    }
+
+    return lhs;
+}
+
+void QmlBasicScriptNodeCache::clear()
+{
+    object = 0;
+    metaObject = 0;
+    type = Invalid;
+}
+
+static QVariant toObjectOrVariant(const QVariant &v)
+{
+    switch(v.type()) {
+        case QVariant::String:
+        case QVariant::UInt:
+        case QVariant::Int:
+        case 135:
+        case QVariant::Double:
+        case QVariant::Color:
+        case QVariant::Bool:
+        default:
+            return v;
+        case QVariant::UserType:
+            {
+                QObject *o = QmlMetaType::toQObject(v);
+                if (o)
+                    return qVariantFromValue(o);
+                else
+                    return v;
+            }
+            break;
+    }
+}
+
+static QVariant fetch_value(QObject *o, int idx, int type)
+{
+    switch(type) {
+        case QVariant::String:
+            {
+                QString val;
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                return QVariant(val);
+            }
+            break;
+        case QVariant::UInt:
+            {
+                uint val;
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                return QVariant(val);
+            }
+            break;
+        case QVariant::Int:
+            {
+                int val;
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                return QVariant(val);
+            }
+            break;
+        case 135:
+            {
+                float val;
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                return QVariant(val);
+            }
+            break;
+        case QVariant::Double:
+            {
+                double val;
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                return QVariant(val);
+            }
+            break;
+        case QVariant::Color:
+            {
+                QColor val;
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                return QVariant(val);
+            }
+            break;
+        case QVariant::Bool:
+            {
+                bool val;
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                return QVariant(val);
+            }
+            break;
+        default:  
+            {
+                if (QmlMetaType::isObject(type)) {
+                    // NOTE: This assumes a cast to QObject does not alter the 
+                    // object pointer
+                    QObject *val = 0;
+                    void *args[] = { &val, 0 };
+                    QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
+                    return QVariant::fromValue(val);
+                } else {
+                    QVariant var = o->metaObject()->property(idx).read(o);
+                    if (QmlMetaType::isObject(var.userType())) {
+                        QObject *obj = 0;
+                        obj = *(QObject **)var.data();
+                        var = QVariant::fromValue(obj);
+                    }
+                    return var;
+                }
+            }
+            break;
+    };
+}
+
+QVariant QmlBasicScriptNodeCache::value(const char *) const
+{
+    //QFxPerfTimer<QFxPerf::BasicScriptValue> pt;
+    switch(type) {
+    case Invalid:
+        break;
+    case Core:
+        return fetch_value(object, core, coreType);
+        break;
+    case Attached:
+        return qVariantFromValue(static_cast<QObject *>(attached));
+        break;
+    case Signal:
+        // XXX
+        Q_ASSERT(!"Not implemented");
+        break;
+    case SignalProperty:
+        break;
+    case Variant:
+        return context->propertyValues[contextIndex];
+    };
+    return QVariant();
+}
+
+struct QmlBasicScriptCompiler
+{
+    QmlBasicScriptCompiler()
+    : script(0), stateSize(0) {}
+    QmlBasicScript *script;
+    int stateSize;
+
+    bool compile(JavaScript::AST::Node *);
+
+    bool compileExpression(JavaScript::AST::Node *);
+
+    bool tryConstant(JavaScript::AST::Node *);
+    bool parseConstant(JavaScript::AST::Node *);
+    bool tryName(JavaScript::AST::Node *);
+    bool parseName(JavaScript::AST::Node *);
+    bool tryBinaryExpression(JavaScript::AST::Node *);
+    bool compileBinaryExpression(JavaScript::AST::Node *);
+
+    QByteArray data;
+    QList<ScriptInstruction> bytecode;
+};
+
+/*!
+    \internal
+    \class QmlBasicScript
+    \brief The QmlBasicScript class provides a fast implementation of a limited subset of JavaScript bindings.
+
+    QmlBasicScript instances are used to accelerate binding.  Instead of using
+    the slower, fully fledged JavaScript engine, many simple bindings can be
+    evaluated using the QmlBasicScript engine.
+
+    To see if the QmlBasicScript engine can handle a binding, call compile()
+    and check the return value, or isValid() afterwards.  
+
+    To evaluate the binding, the QmlBasicScript instance needs some memory in
+    which to cache state.  This may be allocated by calling newScriptState()
+    and destroyed by calling deleteScriptState().  The state data is then passed
+    to the run() method when evaluating the binding.
+
+    To further accelerate binding, QmlBasicScript can return a precompiled 
+    version of itself that can be saved for future use.  Call compileData() to
+    get an opaque pointer to the compiled state, and compileDataSize() for the
+    size of this data in bytes.  This data can be saved and passed to future
+    instances of the QmlBasicScript constructor.  The initial copy of compile
+    data is owned by the QmlBindScript instance on which compile() was called.
+*/
+
+/*!
+    Create a new QmlBasicScript instance.
+*/
+QmlBasicScript::QmlBasicScript()
+: flags(0), d(0), rc(0)
+{
+}
+
+/*!
+    Create a new QmlBasicScript instance from saved \a data.
+
+    \a data \b must be data previously acquired from calling compileData() on a
+    previously created QmlBasicScript instance.  Any other data will almost
+    certainly cause the QmlBasicScript engine to crash.
+
+    \a data must continue to be valid throughout the QmlBasicScript instance 
+    life.  It does not assume ownership of the memory.
+
+    If \a owner is set, it is referenced on creation and dereferenced on 
+    destruction of this instance.
+*/
+QmlBasicScript::QmlBasicScript(const char *data, QmlRefCount *owner)
+: flags(0), d((QmlBasicScriptPrivate *)data), rc(owner)
+{
+    if (rc) rc->addref();
+}
+
+/*!
+    Return the text of the script expression.
+ */
+QByteArray QmlBasicScript::expression() const
+{
+    if (!d)
+        return QByteArray();
+    else
+        return QByteArray(d->expr());
+}
+
+/*!
+    Destroy the script instance.
+*/
+QmlBasicScript::~QmlBasicScript()
+{
+    if (flags & QmlBasicScriptPrivate::OwnData)
+        free(d);
+    if (rc) rc->release();
+    d = 0;
+    rc = 0;
+}
+
+/*!
+    Clear this script.  The object will then be in its initial state, as though
+    it were freshly constructed with default constructor.
+*/
+void QmlBasicScript::clear()
+{
+    if (flags & QmlBasicScriptPrivate::OwnData)
+        free(d);
+    if (rc) rc->release();
+    d = 0;
+    rc = 0;
+    flags = 0;
+}
+
+/*!
+    Return the script state memory for this script instance.  This memory should
+    only be destroyed by calling deleteScriptState().
+ */
+void *QmlBasicScript::newScriptState()
+{
+    if (!d) {
+        return 0;
+    } else  {
+        void *rv = ::malloc(d->stateSize * sizeof(QmlBasicScriptNodeCache));
+        ::memset(rv, 0, d->stateSize * sizeof(QmlBasicScriptNodeCache));
+        return rv;
+    }
+}
+
+/*!
+    Delete the \a data previously allocated by newScriptState().
+ */
+void QmlBasicScript::deleteScriptState(void *data)
+{
+    if (!data) return;
+    Q_ASSERT(d);
+    clearCache(data);
+    free(data);
+}
+
+/*!
+    Dump the script instructions to stderr for debugging.
+ */
+void QmlBasicScript::dump()
+{
+    if (!d)
+        return;
+
+    qWarning() << d->instructionCount << "instructions:";
+    const char *data = d->data();
+    for (int ii = 0; ii < d->instructionCount; ++ii) {
+        const ScriptInstruction &instr = d->instructions()[ii];
+
+        switch(instr.type) {
+        case ScriptInstruction::Load:
+            qWarning().nospace() << "LOAD\t\t" << instr.fetch.idx << "\t\t" 
+                                 << QByteArray(data + instr.fetch.idx);
+            break;
+        case ScriptInstruction::Fetch:
+            qWarning().nospace() << "FETCH\t\t" << instr.fetch.idx << "\t\t" 
+                                 << QByteArray(data + instr.fetch.idx);
+            break;
+        case ScriptInstruction::Add:
+            qWarning().nospace() << "ADD";
+            break;
+        case ScriptInstruction::Subtract:
+            qWarning().nospace() << "SUBTRACT";
+            break;
+        case ScriptInstruction::Multiply:
+            qWarning().nospace() << "MULTIPLY";
+            break;
+        case ScriptInstruction::Equals:
+            qWarning().nospace() << "EQUALS";
+            break;
+        case ScriptInstruction::Int:
+            qWarning().nospace() << "INT\t\t" << instr.integer.value;
+            break;
+        case ScriptInstruction::Bool:
+            qWarning().nospace() << "BOOL\t\t" << instr.boolean.value;
+            break;
+        default:
+            qWarning().nospace() << "UNKNOWN";
+            break;
+        }
+    }
+}
+
+/*!
+    Return true if this is a valid script binding, otherwise returns false.
+ */
+bool QmlBasicScript::isValid() const
+{
+    return d != 0;
+}
+
+/*!
+    Compile \a v and return true if the compilation is successful, otherwise
+    returns false.
+ */
+bool QmlBasicScript::compile(const QmlParser::Variant &v)
+{
+    if (!v.asAST()) return false;
+
+    QByteArray expr = v.asScript().toLatin1();
+    const char *src = expr.constData();
+
+    QmlBasicScriptCompiler bsc;
+    bsc.script = this;
+
+    if (d) {
+        if (flags & QmlBasicScriptPrivate::OwnData)
+            free(d);
+        d = 0;
+        flags = 0;
+    }
+
+    if (bsc.compile(v.asAST())) {
+        int len = ::strlen(src);
+        flags = QmlBasicScriptPrivate::OwnData;
+        int size = sizeof(QmlBasicScriptPrivate) + 
+                   bsc.bytecode.count() * sizeof(ScriptInstruction) + 
+                   QmlBasicScriptPrivate::alignRound(bsc.data.count() + len + 1);
+        d = (QmlBasicScriptPrivate *) malloc(size);
+        d->size = size;
+        d->stateSize = bsc.stateSize;
+        d->instructionCount = bsc.bytecode.count();
+        d->exprLen = len;
+        ::memcpy((char *)d->expr(), src, len + 1);
+        for (int ii = 0; ii < d->instructionCount; ++ii) 
+            d->instructions()[ii] = bsc.bytecode.at(ii);
+        ::memcpy((char *)d->data(), bsc.data.constData(), bsc.data.count());
+    } 
+
+    return d != 0;
+}
+
+bool QmlBasicScriptCompiler::compile(JavaScript::AST::Node *node)
+{
+    return compileExpression(node);
+}
+
+using namespace JavaScript;
+bool QmlBasicScriptCompiler::tryConstant(JavaScript::AST::Node *node)
+{
+    if (node->kind == AST::Node::Kind_TrueLiteral || 
+        node->kind == AST::Node::Kind_FalseLiteral)
+        return true;
+
+    if (node->kind == AST::Node::Kind_NumericLiteral) {
+        AST::NumericLiteral *lit = static_cast<AST::NumericLiteral *>(node);
+
+        return lit->suffix == AST::NumericLiteral::noSuffix &&
+               double(int(lit->value)) == lit->value;
+    }
+
+    return false;
+}
+
+bool QmlBasicScriptCompiler::parseConstant(JavaScript::AST::Node *node)
+{
+    ScriptInstruction instr;
+
+    if (node->kind == AST::Node::Kind_NumericLiteral) {
+        AST::NumericLiteral *lit = static_cast<AST::NumericLiteral *>(node);
+        instr.type = ScriptInstruction::Int;
+        instr.integer.value = int(lit->value);
+    } else {
+        instr.type = ScriptInstruction::Bool;
+        instr.boolean.value = node->kind == AST::Node::Kind_TrueLiteral;
+    }
+
+    bytecode.append(instr);
+
+    return true;
+}
+
+bool QmlBasicScriptCompiler::tryName(JavaScript::AST::Node *node)
+{
+    return node->kind == AST::Node::Kind_IdentifierExpression ||
+           node->kind == AST::Node::Kind_FieldMemberExpression;
+}
+
+bool QmlBasicScriptCompiler::parseName(AST::Node *node)
+{
+    bool load = false;
+
+    QString name;
+    if (node->kind == AST::Node::Kind_IdentifierExpression) {
+        name = static_cast<AST::IdentifierExpression *>(node)->name->asString();
+        load = true;
+    } else if (node->kind == AST::Node::Kind_FieldMemberExpression) {
+        AST::FieldMemberExpression *expr = static_cast<AST::FieldMemberExpression *>(node);
+
+        if (!parseName(expr->base))
+            return false;
+
+        name = expr->name->asString();
+    } else {
+        return false;
+    }
+
+    int nref = data.count();
+    data.append(name.toUtf8());
+    data.append('\0');
+    ScriptInstruction instr;
+    if (load)
+        instr.type = ScriptInstruction::Load;
+    else
+        instr.type = ScriptInstruction::Fetch;
+    instr.fetch.idx = nref;
+    bytecode.append(instr);
+    ++stateSize;
+
+    return true;
+}
+
+bool QmlBasicScriptCompiler::compileExpression(JavaScript::AST::Node *node)
+{
+    if (tryBinaryExpression(node))
+        return compileBinaryExpression(node);
+    else if (tryConstant(node))
+        return parseConstant(node);
+    else if (tryName(node))
+        return parseName(node);
+    else
+        return false;
+}
+
+bool QmlBasicScriptCompiler::tryBinaryExpression(AST::Node *node)
+{
+    if (node->kind == AST::Node::Kind_BinaryExpression) {
+        AST::BinaryExpression *expr = 
+            static_cast<AST::BinaryExpression *>(node);
+
+        if (expr->op == QSOperator::Add ||
+            expr->op == QSOperator::Sub ||
+            expr->op == QSOperator::Equal ||
+            expr->op == QSOperator::And ||
+            expr->op == QSOperator::Mul)
+            return true;
+    }
+    return false;
+}
+
+bool QmlBasicScriptCompiler::compileBinaryExpression(AST::Node *node)
+{
+    if (node->kind == AST::Node::Kind_BinaryExpression) {
+        AST::BinaryExpression *expr = 
+            static_cast<AST::BinaryExpression *>(node);
+
+        if (!compileExpression(expr->left)) return false;
+        if (!compileExpression(expr->right)) return false;
+
+        ScriptInstruction instr;
+        switch (expr->op) {
+        case QSOperator::Add:
+            instr.type = ScriptInstruction::Add;
+            break;
+        case QSOperator::Sub:
+            instr.type = ScriptInstruction::Subtract;
+            break;
+        case QSOperator::Equal:
+            instr.type = ScriptInstruction::Equals;
+            break;
+        case QSOperator::And:
+            instr.type = ScriptInstruction::And;
+            break;
+        case QSOperator::Mul:
+            instr.type = ScriptInstruction::Multiply;
+            break;
+        default:
+            return false;
+        }
+
+        bytecode.append(instr);
+        return true;
+    } 
+    return false;
+}
+
+/*!
+    \internal
+*/
+void QmlBasicScript::clearCache(void *voidCache)
+{
+    QmlBasicScriptNodeCache *dataCache =
+        reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache);
+
+    for (int ii = 0; ii < d->stateSize; ++ii) {
+        if (!dataCache[ii].isCore() && !dataCache[ii].isVariant() && 
+            dataCache[ii].object) {
+            QMetaObject::removeGuard(&dataCache[ii].object);
+            dataCache[ii].object = 0;
+        }
+        dataCache[ii].clear();
+    }
+}
+
+void QmlBasicScript::guard(QmlBasicScriptNodeCache &n)
+{
+    if (n.object) {
+        if (n.isVariant()) {
+        } else if (n.isCore()) {
+            n.metaObject = 
+                n.object->metaObject();
+        } else {
+            QMetaObject::addGuard(&n.object);
+        }
+    }
+}
+
+bool QmlBasicScript::valid(QmlBasicScriptNodeCache &n, QObject *obj)
+{
+    return n.object == obj && 
+                       (!n.isCore() || obj->metaObject() == n.metaObject); 
+}
+
+
+/*!
+    \enum QmlBasicScript::CacheState
+    \value NoChange The query has not change.  Any previous monitoring is still
+    valid.
+    \value Incremental The query has been incrementally changed.  Any previous 
+    monitoring is still valid, but needs to have the fresh properties added to
+    it.
+    \value Reset The entire query has been reset from the beginning.  Any previous
+    monitoring is now invalid.
+*/
+
+/*!
+    Run the script in \a context and return the result.  \a voidCache should 
+    contain state memory previously acquired from newScript. 
+ */
+QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *cached)
+{
+    if (!isValid())
+        return QVariant();
+
+    QmlBasicScriptNodeCache *dataCache =
+        reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache);
+    int dataCacheItem; 
+    QStack<QVariant> stack;
+
+    bool resetting = false;
+    bool hasReset = false;
+
+    const char *data = d->data();
+
+    if (dataCache[0].type == QmlBasicScriptNodeCache::Invalid) {
+        resetting = true;
+        hasReset = true;
+    }
+
+    CacheState state = NoChange;
+
+    dataCacheItem = 0;
+    for (int idx = 0; idx < d->instructionCount; ++idx) {
+        const ScriptInstruction &instr = d->instructions()[idx];
+
+        switch(instr.type) {
+            case ScriptInstruction::Load: // either an object or a property
+            case ScriptInstruction::Fetch: // can only be a property
+            {
+                const char *id = data + instr.fetch.idx;
+                QmlBasicScriptNodeCache &n = dataCache[dataCacheItem];
+
+                if (instr.type == ScriptInstruction::Load) {
+
+                    if (n.type == QmlBasicScriptNodeCache::Invalid) {
+                        context->engine()->d_func()->loadCache(n, QLatin1String(id), static_cast<QmlContextPrivate*>(context->d_ptr));
+                        state = Incremental;
+                    }
+
+                    if(!n.isValid())
+                        qWarning("ReferenceError: %s is not defined", id);
+
+                } else { // instr.type == ScriptInstruction::Fetch
+
+                    QVariant o = stack.pop();
+                    QObject *obj = qvariant_cast<QObject *>(o);
+                    if (!obj) {
+                        if (n.type == QmlBasicScriptNodeCache::Invalid) {
+                            if (scriptWarnings())
+                                qWarning() << "QmlBasicScript: Unable to convert" << o;
+                            *cached = state;
+                            return QVariant();
+                        } else {
+                            clearCache(dataCache);
+                            *cached = Reset;
+                            CacheState dummy;
+                            return run(context, voidCache, &dummy);
+                        }
+                    } else if (n.type == QmlBasicScriptNodeCache::Invalid) {
+                        context->engine()->d_func()->fetchCache(n, QLatin1String(id), obj);
+                        guard(n);
+                        state = Incremental;
+                    } else if (!valid(n, obj)) {
+                        clearCache(dataCache);
+                        *cached = Reset;
+                        CacheState dummy;
+                        return run(context, voidCache, &dummy);
+                    }
+
+                }
+
+                QVariant var = n.value(id);
+                stack.push(var);
+                ++dataCacheItem;
+            }
+                break;
+            case ScriptInstruction::Int:
+                stack.push(QVariant(instr.integer.value));
+                break;
+            case ScriptInstruction::Bool:
+                stack.push(QVariant(instr.boolean.value));
+                break;
+            case ScriptInstruction::Add:
+                {
+                    QVariant rhs = stack.pop();
+                    QVariant lhs = stack.pop();
+
+                    stack.push(rhs.toDouble() + lhs.toDouble());
+                }
+                break;
+            case ScriptInstruction::Subtract:
+                {
+                    QVariant rhs = stack.pop();
+                    QVariant lhs = stack.pop();
+
+                    stack.push(lhs.toDouble() - rhs.toDouble());
+                }
+                break;
+            case ScriptInstruction::Multiply:
+                {
+                    QVariant rhs = stack.pop();
+                    QVariant lhs = stack.pop();
+
+                    stack.push(rhs.toDouble() * lhs.toDouble());
+                }
+                break;
+            case ScriptInstruction::Equals:
+                {
+                    QVariant rhs = stack.pop();
+                    QVariant lhs = stack.pop();
+
+                    stack.push(rhs == lhs);
+                }
+                break;
+            case ScriptInstruction::And:
+                {
+                    QVariant rhs = stack.pop();
+                    QVariant lhs = stack.pop();
+
+                    stack.push(rhs.toBool() && lhs.toBool());
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    *cached = state;
+
+    if (stack.isEmpty())
+        return QVariant();
+    else
+        return stack.top();
+}
+
+/*!
+    Return a pointer to the script's compile data, or null if there is no data.
+ */
+const char *QmlBasicScript::compileData() const
+{
+    return (const char *)d;
+}
+
+/*!
+    Return the size of the script's compile data, or zero if there is no data.
+    The size will always be a multiple of 4.
+ */
+unsigned int QmlBasicScript::compileDataSize() const
+{
+    if (d)
+        return d->size;
+    else
+        return 0;
+}
+
+bool QmlBasicScript::isSingleLoad() const
+{
+    if (!d)
+        return false;
+
+    return d->instructionCount == 1 &&
+           d->instructions()[0].type == ScriptInstruction::Load;
+}
+
+QByteArray QmlBasicScript::singleLoadTarget() const
+{
+    if (!isSingleLoad())
+        return QByteArray();
+
+    // We know there is one instruction and it is a load
+    return QByteArray(d->data() + d->instructions()[0].fetch.idx);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlbasicscript_p.h b/src/declarative/qml/qmlbasicscript_p.h
new file mode 100644
index 0000000..1117e11
--- /dev/null
+++ b/src/declarative/qml/qmlbasicscript_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $TROLLTECH_DUAL_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLBASICSCRIPT_P_H
+#define QMLBASICSCRIPT_P_H
+
+#include <QtCore/QList>
+#include <QtCore/QByteArray>
+#include <QtCore/QVariant>
+#include <private/qmlparser_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QmlRefCount;
+class QmlContext;
+class QmlBasicScriptPrivate;
+class QmlBasicScriptNodeCache;
+class QmlBasicScript
+{
+public:
+    QmlBasicScript();
+    QmlBasicScript(const char *, QmlRefCount * = 0);
+    ~QmlBasicScript();
+
+    // Always 4-byte aligned
+    const char *compileData() const;
+    unsigned int compileDataSize() const;
+
+    QByteArray expression() const;
+
+    bool compile(const QmlParser::Variant &);
+    bool isValid() const;
+
+    void clear();
+
+    void dump();
+    void *newScriptState();
+    void deleteScriptState(void *);
+
+    enum CacheState { NoChange, Incremental, Reset };
+    QVariant run(QmlContext *, void *, CacheState *);
+
+    // Optimization opportunities
+    bool isSingleLoad() const;
+    QByteArray singleLoadTarget() const;
+
+private:
+    int flags;
+    QmlBasicScriptPrivate *d;
+    QmlRefCount *rc;
+
+    void clearCache(void *);
+    void guard(QmlBasicScriptNodeCache &);
+    bool valid(QmlBasicScriptNodeCache &, QObject *);
+};
+
+class QmlContextPrivate;
+class QDebug;
+class QmlBasicScriptNodeCache
+{
+public:
+    QObject *object;
+    const QMetaObject *metaObject;
+    enum { Invalid,
+           Core, 
+           Attached, 
+           Signal,
+           SignalProperty, 
+           Variant
+    } type;
+    union {
+        int core;
+        QObject *attached;
+        QmlContextPrivate *context;
+    };
+    int coreType;
+    int contextIndex;
+
+    bool isValid() const { return type != Invalid; }
+    bool isCore() const { return type == Core; }
+    bool isVariant() const { return type == Variant; }
+    void clear();
+    QVariant value(const char *) const;
+};
+
+QDebug operator<<(QDebug, const QmlBasicScriptNodeCache &);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLBASICSCRIPT_P_H
+
+
diff --git a/src/declarative/qml/qmlbindablevalue.cpp b/src/declarative/qml/qmlbindablevalue.cpp
index d5157b6..351e0bd 100644
--- a/src/declarative/qml/qmlbindablevalue.cpp
+++ b/src/declarative/qml/qmlbindablevalue.cpp
@@ -69,8 +69,8 @@ QmlBindableValue::QmlBindableValue(void *data, QmlRefCount *rc, QObject *obj, QO
 {
 }
 
-QmlBindableValue::QmlBindableValue(const QString &str, QObject *obj, bool sse, QObject *parent)
-: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent), QmlExpression(QmlContext::activeContext(), str, obj, sse)
+QmlBindableValue::QmlBindableValue(const QString &str, QObject *obj, QObject *parent)
+: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent), QmlExpression(QmlContext::activeContext(), str, obj)
 {
 }
 
diff --git a/src/declarative/qml/qmlbindablevalue.h b/src/declarative/qml/qmlbindablevalue.h
index c5bb97b..71a7051 100644
--- a/src/declarative/qml/qmlbindablevalue.h
+++ b/src/declarative/qml/qmlbindablevalue.h
@@ -63,7 +63,7 @@ class Q_DECLARATIVE_EXPORT QmlBindableValue : public QmlPropertyValueSource,
 Q_OBJECT
 public:
     QmlBindableValue(QObject *parent);
-    QmlBindableValue(const QString &, QObject *, bool = true, QObject *parent=0);
+    QmlBindableValue(const QString &, QObject *, QObject *parent=0);
     QmlBindableValue(void *, QmlRefCount *, QObject *, QObject *parent);
     ~QmlBindableValue();
 
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index b9a848a..75d01c2 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -46,7 +46,7 @@
 #include <qmlpropertyvaluesource.h>
 #include <qmlcomponent.h>
 #include "private/qmetaobjectbuilder_p.h"
-#include <qmlbasicscript.h>
+#include "qmlbasicscript_p.h"
 #include <QColor>
 #include <QDebug>
 #include <QPointF>
@@ -1415,7 +1415,7 @@ bool QmlCompiler::compileBinding(const QmlParser::Variant &bind,
         COMPILE_EXCEPTION2(prop, "Cannot assign binding to read-only property");
 
     QmlBasicScript bs;
-    bs.compile(bind.asScript().toLatin1());
+    bs.compile(bind);
 
     int bref;
     if (bs.isValid()) {
@@ -1447,6 +1447,47 @@ bool QmlCompiler::compileBinding(const QmlParser::Variant &bind,
     return true;
 }
 
+#if 0
+
+#include <iostream> 
+#ifdef Q_CC_GNU 
+#include <cxxabi.h> 
+#endif 
+ 
+//////////////////////////////////////////////////////////////////////////////// 
+// AST Dump 
+//////////////////////////////////////////////////////////////////////////////// 
+class Dump: protected JavaScript::AST::Visitor 
+{ 
+    std::ostream &out; 
+    int depth; 
+ 
+public: 
+    Dump(std::ostream &out) 
+        : out(out), depth(-1) 
+     { } 
+ 
+    void operator()(JavaScript::AST::Node *node) 
+    { JavaScript::AST::Node::acceptChild(node, this); } 
+ 
+protected: 
+    virtual bool preVisit(JavaScript::AST::Node *node) 
+    { 
+        const char *name = typeid(*node).name(); 
+#ifdef Q_CC_GNU 
+        name = abi::__cxa_demangle(name, 0, 0, 0) + 17; 
+#endif 
+        std::cout << std::string(++depth, ' ') << name << std::endl; 
+        return true; 
+    } 
+ 
+    virtual void postVisit(JavaScript::AST::Node *) 
+    { 
+        --depth; 
+    } 
+}; 
+#endif
+
 // Update the init instruction with final data, and optimize some simple 
 // bindings
 int QmlCompiler::finalizeComponent(int patch)
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 3db8d92..c67c220 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -820,15 +820,9 @@ QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, void *expr, QmlRefC
 {
 }
 
-QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, const QString &expr, bool ssecompile)
+QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, const QString &expr)
 : q(b), ctxt(0), expression(expr), sseData(0), proxy(0), me(0), trackChange(true), line(-1), id(0), log(0)
 {
-    if (ssecompile) {
-#ifdef Q_ENABLE_PERFORMANCE_LOG
-        QFxPerfTimer<QFxPerf::BindCompile> pt;
-#endif
-        sse.compile(expr.toLatin1());
-    }
 }
 
 QmlExpressionPrivate::~QmlExpressionPrivate()
@@ -863,19 +857,6 @@ QmlExpression::QmlExpression(QmlContext *ctxt, void *expr,
     d->me = me;
 }
 
-/*! \internal */
-QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expr, 
-                             QObject *me, bool ssecompile)
-: d(new QmlExpressionPrivate(this, expr, ssecompile))
-{
-    d->ctxt = ctxt;
-    if(ctxt && ctxt->engine())
-        d->id = ctxt->engine()->d_func()->getUniqueId();
-    if(ctxt)
-        ctxt->d_func()->childExpressions.insert(this);
-    d->me = me;
-}
-
 /*!
     Create a QmlExpression object.
 
@@ -885,7 +866,7 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expr,
 */
 QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression, 
                              QObject *scope)
-: d(new QmlExpressionPrivate(this, expression, true))
+: d(new QmlExpressionPrivate(this, expression))
 {
     d->ctxt = ctxt;
     if(ctxt && ctxt->engine())
@@ -956,10 +937,7 @@ void QmlExpression::setExpression(const QString &expression)
 
     d->expression = expression;
 
-    if (d->expression.isEmpty())
-        d->sse.clear();
-    else
-        d->sse.compile(expression.toLatin1());
+    d->sse.clear();
 }
 
 /*!
@@ -1245,13 +1223,7 @@ QmlExpressionObject::QmlExpressionObject(QObject *parent)
     the expression's execution.
 */
 QmlExpressionObject::QmlExpressionObject(QmlContext *ctxt, const QString &expression, QObject *scope, QObject *parent)
-: QObject(parent), QmlExpression(ctxt, expression, scope, true)
-{
-}
-
-/*!  \internal */
-QmlExpressionObject::QmlExpressionObject(QmlContext *ctxt, const QString &expr, QObject *scope, bool sse)
-: QmlExpression(ctxt, expr, scope, sse)
+: QObject(parent), QmlExpression(ctxt, expression, scope)
 {
 }
 
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 0dc4736..89b0a4a 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -53,7 +53,7 @@
 #include <private/qmlclassfactory_p.h>
 #include <private/qmlcompositetypemanager_p.h>
 #include <QtDeclarative/qml.h>
-#include <QtDeclarative/qmlbasicscript.h>
+#include <private/qmlbasicscript_p.h>
 #include <QtDeclarative/qmlcontext.h>
 #include <QtDeclarative/qmlengine.h>
 #include <QtDeclarative/qmlexpression.h>
@@ -265,7 +265,7 @@ class QmlExpressionPrivate
 {
 public:
     QmlExpressionPrivate(QmlExpression *);
-    QmlExpressionPrivate(QmlExpression *, const QString &expr, bool);
+    QmlExpressionPrivate(QmlExpression *, const QString &expr);
     QmlExpressionPrivate(QmlExpression *, void *expr, QmlRefCount *rc);
     ~QmlExpressionPrivate();
 
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index ea3b093..651fd9c 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -62,7 +62,6 @@ class Q_DECLARATIVE_EXPORT QmlExpression
 public:
     QmlExpression();
     QmlExpression(QmlContext *, const QString &, QObject *);
-    QmlExpression(QmlContext *, const QString &, QObject *, bool);
     QmlExpression(QmlContext *, void *, QmlRefCount *rc, QObject *me);
     virtual ~QmlExpression();
 
@@ -101,7 +100,6 @@ class Q_DECLARATIVE_EXPORT QmlExpressionObject : public QObject,
 public:
     QmlExpressionObject(QObject *parent = 0);
     QmlExpressionObject(QmlContext *, const QString &, QObject *scope, QObject *parent = 0);
-    QmlExpressionObject(QmlContext *, const QString &, QObject *scope, bool);
     QmlExpressionObject(QmlContext *, void *, QmlRefCount *, QObject *);
 
 public Q_SLOTS:
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index 5c2a69f..f262b5d 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -52,7 +52,6 @@
 #include <qml.h>
 #include "private/qmlcomponent_p.h"
 #include <qmlcomponent.h>
-#include <qmlbasicscript.h>
 #include "private/qmetaobjectbuilder_p.h"
 #include <private/qmlvmemetaobject_p.h>
 #include <private/qmlcompiler_p.h>
diff --git a/src/declarative/qml/script/generator/generator.pro b/src/declarative/qml/script/generator/generator.pro
deleted file mode 100644
index 1b2a4c7..0000000
--- a/src/declarative/qml/script/generator/generator.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-######################################################################
-# Automatically generated by qmake (2.01a) Mon Apr 2 20:15:52 2007
-######################################################################
-
-TEMPLATE = app
-TARGET = 
-DEPENDPATH += .
-INCLUDEPATH += .
-
-# Input
-SOURCES += main.cpp
diff --git a/src/declarative/qml/script/generator/main.cpp b/src/declarative/qml/script/generator/main.cpp
deleted file mode 100644
index a841cbc..0000000
--- a/src/declarative/qml/script/generator/main.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** This file is part of the $PACKAGE_NAME$.
-**
-** Copyright (C) $THISYEAR$ $COMPANY_NAME$.
-**
-** $QT_EXTENDED_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#include <QList>
-#include <QByteArray>
-
-
-QT_BEGIN_NAMESPACE
-struct Keyword {
-    const char *lexem;
-    const char *token;
-};
-
-struct State
-{
-    State(const char* token) : token(token)
-    {
-        ::memset(next, 0, sizeof(next));
-    }
-    State(const State &other) : token(other.token)
-    {
-        ::memcpy(next, other.next, sizeof(next));
-    }
-    State &operator=(const State &other)
-    {
-        token = other.token;
-        ::memcpy(next, other.next, sizeof(next));
-        return *this;
-    }
-
-    QByteArray token;
-    int next[128];
-};
-
-Keyword keywords[] =
-{
-    {"<", "LANGLE" },
-    {">", "RANGLE" },
-    {"+", "PLUS" },
-    {"-", "MINUS" },
-    {"*", "STAR" },
-    {"==", "EQUALS" },
-    {"&&", "AND" },
-    {".", "DOT"},
-    {"true", "TOKEN_TRUE"},
-    {"false", "TOKEN_FALSE"},
-    {" ", "WHITESPACE"},
-    {"\t", "WHITESPACE"},
-    {0, 0}
-};
-
-bool is_character(char s)
-{
-    return (s >= 'a' && s <= 'z') ||
-           (s >= 'A' && s <= 'Z') ||
-           (s >= '0' && s <= '9') ||
-           s == '_';
-}
-
-void newState(QList<State> &states, const char *token, const char *lexem)
-{
-    int state = 0;
-    bool character = is_character(*lexem);
-
-    while(*lexem) {
-        int next = states[state].next[(int)*lexem];
-
-        if (!next) {
-            next = states.size();
-            states += State(character?"CHARACTER":"INCOMPLETE");
-            states[state].next[(int)*lexem] = next;
-        }
-
-        state = next;
-        ++lexem;
-        character = character && is_character(*lexem);
-    }
-
-    states[state].token = token;
-}
-
-void newState(QList<State> &states, const char *token, char lexem)
-{
-    int next = states[0].next[(int)lexem];
-    if (!next) {
-        next = states.size();
-        states += State(token);
-        states[0].next[(int)lexem] = next;
-    } else {
-        states[next].token = token;
-    }
-}
-
-int main()
-{
-    QList<State> states;
-    states += State("NOTOKEN");
-
-    // identifiers
-    for (int cc = 'a'; cc <= 'z'; ++cc)
-        newState(states, "CHARACTER", cc);
-    for (int cc = 'A'; cc <= 'Z'; ++cc)
-        newState(states, "CHARACTER", cc);
-    newState(states, "CHARACTER", '_');
-
-    // add digits
-    for (int cc = '0'; cc <= '9'; ++cc)
-        newState(states, "DIGIT", cc);
-
-    // keywords
-    for (int ii = 0; keywords[ii].lexem; ++ii)
-        newState(states, keywords[ii].token, keywords[ii].lexem);
-
-    ::printf("static const struct\n{\n"
-             "    Token token;\n"
-             "    char next[128];\n"
-             "} keywords[] = {\n");
-
-    for (int ii = 0; ii < states.size(); ++ii) {
-        printf("%s    { %s, { ", ii?",\n":"", states[ii].token.data());
-        for (int jj = 0; jj < 128; jj++) 
-            printf("%s%d", jj?",":"", states[ii].next[jj]);
-        printf(" } }");
-    }
-
-    printf("\n};\n");
-}
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/script/instructions.h b/src/declarative/qml/script/instructions.h
deleted file mode 100644
index a21cbce..0000000
--- a/src/declarative/qml/script/instructions.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _INSTRUCTIONS_H_
-#define _INSTRUCTIONS_H_
-
-struct ScriptInstruction {
-    enum {
-        Load,       // fetch
-        Fetch,       // fetch
-
-        Add,         // NA
-        Subtract,    // NA
-        Multiply,    // NA
-        Equals,      // NA
-        And,         // NA
-
-        Int,         // integer
-        Bool,        // boolean
-    } type;
-
-    union {
-        struct {
-            int idx;
-        } fetch;
-        struct {
-            int value;
-        } integer;
-        struct {
-            bool value;
-        } boolean;
-    };
-};
-
-#endif // _INSTRUCTIONS_H_
diff --git a/src/declarative/qml/script/keywords.cpp b/src/declarative/qml/script/keywords.cpp
deleted file mode 100644
index 4cde65b..0000000
--- a/src/declarative/qml/script/keywords.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-static const struct
-{
-    Token token;
-    char next[128];
-} keywords[] = {
-    { NOTOKEN, { 0,0,0,0,0,0,0,0,0,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,71,0,0,0,68,66,0,67,73,0,54,55,56,57,58,59,60,61,62,63,0,0,64,69,65,0,0,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,0,0,0,0,53,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,0,0,0,0,0 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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,74,0,0,0,0,0,0,0,0,0,0,0,0,0 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { CHARACTER, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { DIGIT, { 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,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 } },
-    { LANGLE, { 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,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 } },
-    { RANGLE, { 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,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 } },
-    { PLUS, { 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,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 } },
-    { MINUS, { 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,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 } },
-    { STAR, { 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,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 } },
-    { INCOMPLETE, { 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,70,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 } },
-    { EQUALS, { 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,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 } },
-    { INCOMPLETE, { 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,72,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,0,0,0,0,0,0 } },
-    { AND, { 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,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 } },
-    { DOT, { 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,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 } },
-    { CHARACTER, { 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,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,75,0,0,0,0,0,0,0,0,0,0 } },
-    { CHARACTER, { 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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,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 } },
-    { TOKEN_TRUE, { 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,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 } },
-    { CHARACTER, { 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,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,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } },
-    { CHARACTER, { 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,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,79,0,0,0,0,0,0,0,0,0,0,0,0 } },
-    { CHARACTER, { 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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,80,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 } },
-    { TOKEN_FALSE, { 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,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 } },
-    { WHITESPACE, { 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,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 } },
-    { WHITESPACE, { 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,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 } }
-};
diff --git a/src/declarative/qml/script/lexer.cpp b/src/declarative/qml/script/lexer.cpp
deleted file mode 100644
index d3ef935..0000000
--- a/src/declarative/qml/script/lexer.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** This file is part of the $PACKAGE_NAME$.
-**
-** Copyright (C) $THISYEAR$ $COMPANY_NAME$.
-**
-** $QT_EXTENDED_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#include <QByteArray>
-#include "lexer.h"
-#include "keywords.cpp"
-#include <QDebug>
-
-
-QT_BEGIN_NAMESPACE
-QList<LexerToken> tokenize(const char *text)
-{
-    QList<LexerToken> rv;
-
-    int lineNo = 0;
-    int charNo = 0;
-    int state = 0;
-    int tokenStart = 0;
-    bool other = false;
-
-    const char *textprog = text;
-
-    bool done = false;
-    while (!done) {
-        char textchar = *textprog;
-        done = !textchar;
-
-        if (other) {
-            if (keywords[state].next[(int)textchar]) {
-
-                // Do other token
-                LexerToken token;
-                token.token = OTHER;
-                token.start = tokenStart;
-                token.end = textprog - text - 1;
-                token.line = lineNo + 1;
-                token.offset = charNo - (token.end - token.start);
-                tokenStart = token.end + 1;
-                rv.append(token);
-                other = false;
-
-            } else {
-                goto continue_loop;
-            }
-        }
-
-        if (keywords[state].next[(int)textchar]) {
-
-            state = keywords[state].next[(int)textchar];
-
-        } else if (0 == state ||
-                  keywords[state].token == INCOMPLETE) {
-
-            other = true;
-            if (keywords[state].token == INCOMPLETE) {
-                state = 0;
-                continue;
-            }
-
-        } else {
-
-            // Token completed
-            Token tokenType = keywords[state].token;
-            bool tokenCollapsed = false;
-            if (tokenType == CHARACTER ||
-               tokenType == DIGIT ||
-               tokenType == WHITESPACE) {
-
-                Token lastTokenType =
-                    rv.isEmpty()?NOTOKEN:rv.last().token;
-                if (tokenType == lastTokenType) {
-
-                    rv.last().end = textprog - text - 1;
-                    tokenStart = rv.last().end + 1;
-
-                    tokenCollapsed = true;
-                }
-            }
-
-            if (!tokenCollapsed) {
-                LexerToken token;
-                token.token = keywords[state].token;
-                token.start = tokenStart;
-                token.end = textprog - text - 1;
-                token.line = lineNo + 1;
-                token.offset = charNo - (token.end - token.start);
-                tokenStart = token.end + 1;
-                rv.append(token);
-            }
-
-            state = keywords[0].next[(int)textchar];
-            if (0 == state)
-                other = true;
-        }
-
-continue_loop:
-        // Reset error reporting variables
-        if (textchar == '\n') {
-            ++lineNo;
-            charNo = 0;
-        } else {
-            charNo++;
-        }
-
-        // Increment ptrs
-        ++textprog;
-    }
-
-    if (other && ((textprog - text - 1) != tokenStart)) {
-        // Do other token
-        LexerToken token;
-        token.token = OTHER;
-        token.start = tokenStart;
-        token.end = textprog - text - 1;
-        token.line = lineNo + 1;
-        token.offset = charNo - (token.end - token.start);
-        tokenStart = token.end + 1;
-        rv.append(token);
-        other = false;
-    }
-    return rv;
-}
-
-void dumpTokens(const char *text, const QList<LexerToken> &tokens)
-{
-    for (int ii = 0; ii < tokens.count(); ++ii) {
-        QByteArray ba(text + tokens.at(ii).start, tokens.at(ii).end - tokens.at(ii).start + 1);
-        qWarning() << tokens.at(ii).line << ":" << tokens.at(ii).offset << tokenToString(tokens.at(ii).token) << "(" << tokens.at(ii).start << "-" << tokens.at(ii).end << ")" << ba;
-    }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/script/lexer.h b/src/declarative/qml/script/lexer.h
deleted file mode 100644
index 9de4afd..0000000
--- a/src/declarative/qml/script/lexer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** This file is part of the $PACKAGE_NAME$.
-**
-** Copyright (C) $THISYEAR$ $COMPANY_NAME$.
-**
-** $QT_EXTENDED_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#ifndef LEXER_H
-#define LEXER_H
-
-#include <QtCore/QList>
-#include "tokens.h"
-
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-struct LexerToken
-{
-    LexerToken() : token(NOTOKEN), start(-1), end(-1), line(-1), offset(-1) {}
-    LexerToken(const LexerToken &other) : token(other.token),
-                                          start(other.start),
-                                          end(other.end),
-                                          line(other.line),
-                                          offset(other.offset) {}
-    LexerToken &operator=(const LexerToken &other) {
-        token = other.token;
-        start = other.start;
-        end = other.end;
-        line = other.line;
-        offset = other.offset;
-        return *this;
-    }
-
-    Token token;
-    int start;
-    int end;
-    int line;
-    int offset;
-};
-
-QList<LexerToken> tokenize(const char *text);
-void dumpTokens(const char *text, const QList<LexerToken> &tokens);
-
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-#endif
diff --git a/src/declarative/qml/script/qmlbasicscript.cpp b/src/declarative/qml/script/qmlbasicscript.cpp
deleted file mode 100644
index 37a6678..0000000
--- a/src/declarative/qml/script/qmlbasicscript.cpp
+++ /dev/null
@@ -1,921 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the $MODULE$ of the Qt Toolkit.
-**
-** $TROLLTECH_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#include "qmlbasicscript.h"
-#include "qmlbasicscript_p.h"
-#include "lexer.h"
-#include <QColor>
-#include <QDebug>
-#include <private/qmlengine_p.h>
-#include <private/qmlcontext_p.h>
-#include <QStack>
-#include <qfxperf.h>
-#include <private/qmlrefcount_p.h>
-
-
-QT_BEGIN_NAMESPACE
-DEFINE_BOOL_CONFIG_OPTION(scriptWarnings, QML_SCRIPT_WARNINGS);
-
-class QmlBasicScriptPrivate
-{
-public:
-    enum Flags { OwnData = 0x00000001 };
-    
-    int size;
-    int stateSize;
-    int instructionCount;
-    int exprLen;
-
-    ScriptInstruction *instructions() const { return (ScriptInstruction *)((char *)this + sizeof(QmlBasicScriptPrivate)); }
-
-    const char *expr() const
-    {
-        return (const char *)(instructions() + instructionCount);
-    }
-
-    const char *data() const 
-    {
-        return (const char *)(instructions() + instructionCount) + exprLen + 1;
-    }
-
-    static unsigned int alignRound(int s)
-    {
-        if (s % 4) 
-            s += 4 - (s % 4);
-        return s;
-    }
-};
-
-QDebug operator<<(QDebug lhs, const QmlBasicScriptNodeCache &rhs)
-{
-    switch(rhs.type) {
-    case QmlBasicScriptNodeCache::Invalid:
-        lhs << "Invalid";
-        break;
-    case QmlBasicScriptNodeCache::Core:
-        lhs << "Core" << rhs.object << rhs.core;
-        break;
-    case QmlBasicScriptNodeCache::Attached: 
-        lhs << "Attached" << rhs.object << rhs.attached;
-        break;
-    case QmlBasicScriptNodeCache::Signal: 
-        lhs << "Signal" << rhs.object << rhs.core;
-        break;
-    case QmlBasicScriptNodeCache::SignalProperty: 
-        lhs << "SignalProperty" << rhs.object << rhs.core;
-        break;
-    case QmlBasicScriptNodeCache::Variant: 
-        lhs << "Variant" << rhs.context;
-        break;
-    }
-
-    return lhs;
-}
-
-void QmlBasicScriptNodeCache::clear()
-{
-    object = 0;
-    metaObject = 0;
-    type = Invalid;
-}
-
-static QVariant toObjectOrVariant(const QVariant &v)
-{
-    switch(v.type()) {
-        case QVariant::String:
-        case QVariant::UInt:
-        case QVariant::Int:
-        case 135:
-        case QVariant::Double:
-        case QVariant::Color:
-        case QVariant::Bool:
-        default:
-            return v;
-        case QVariant::UserType:
-            {
-                QObject *o = QmlMetaType::toQObject(v);
-                if (o)
-                    return qVariantFromValue(o);
-                else
-                    return v;
-            }
-            break;
-    }
-}
-
-static QVariant fetch_value(QObject *o, int idx, int type)
-{
-    switch(type) {
-        case QVariant::String:
-            {
-                QString val;
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                return QVariant(val);
-            }
-            break;
-        case QVariant::UInt:
-            {
-                uint val;
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                return QVariant(val);
-            }
-            break;
-        case QVariant::Int:
-            {
-                int val;
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                return QVariant(val);
-            }
-            break;
-        case 135:
-            {
-                float val;
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                return QVariant(val);
-            }
-            break;
-        case QVariant::Double:
-            {
-                double val;
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                return QVariant(val);
-            }
-            break;
-        case QVariant::Color:
-            {
-                QColor val;
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                return QVariant(val);
-            }
-            break;
-        case QVariant::Bool:
-            {
-                bool val;
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                return QVariant(val);
-            }
-            break;
-        default:  
-            {
-                if (QmlMetaType::isObject(type)) {
-                    // NOTE: This assumes a cast to QObject does not alter the 
-                    // object pointer
-                    QObject *val = 0;
-                    void *args[] = { &val, 0 };
-                    QMetaObject::metacall(o, QMetaObject::ReadProperty, idx, args);
-                    return QVariant::fromValue(val);
-                } else {
-                    QVariant var = o->metaObject()->property(idx).read(o);
-                    if (QmlMetaType::isObject(var.userType())) {
-                        QObject *obj = 0;
-                        obj = *(QObject **)var.data();
-                        var = QVariant::fromValue(obj);
-                    }
-                    return var;
-                }
-            }
-            break;
-    };
-}
-
-QVariant QmlBasicScriptNodeCache::value(const char *name) const
-{
-    //QFxPerfTimer<QFxPerf::BasicScriptValue> pt;
-    switch(type) {
-    case Invalid:
-        break;
-    case Core:
-        return fetch_value(object, core, coreType);
-        break;
-    case Attached:
-        return qVariantFromValue(static_cast<QObject *>(attached));
-        break;
-    case Signal:
-        // XXX
-        Q_ASSERT(!"Not implemented");
-        break;
-    case SignalProperty:
-        break;
-    case Variant:
-        return context->propertyValues[contextIndex];
-    };
-    return QVariant();
-}
-
-struct QmlBasicScriptCompiler
-{
-    QmlBasicScriptCompiler()
-    : script(0), stateSize(0), src(0), idx(0) {}
-    QmlBasicScript *script;
-    QList<LexerToken> tokens;
-    int stateSize;
-    const char *src;
-    int idx;
-
-    bool compile();
-    bool compileExpr();
-
-    bool parseFetch();
-    bool parseName();
-    bool parseConstant();
-    void skipWhitespace();
-
-    QByteArray data;
-    QList<ScriptInstruction> bytecode;
-
-    QByteArray string(int, int);
-    Token token() const;
-    bool atEnd() const;
-    void adv();
-    int index() const;
-};
-
-/*!
-    \internal
-    \class QmlBasicScript
-    \brief The QmlBasicScript class provides a fast implementation of a limited subset of JavaScript bindings.
-
-    QmlBasicScript instances are used to accelerate binding.  Instead of using
-    the slower, fully fledged JavaScript engine, many simple bindings can be
-    evaluated using the QmlBasicScript engine.
-
-    To see if the QmlBasicScript engine can handle a binding, call compile()
-    and check the return value, or isValid() afterwards.  
-
-    To evaluate the binding, the QmlBasicScript instance needs some memory in
-    which to cache state.  This may be allocated by calling newScriptState()
-    and destroyed by calling deleteScriptState().  The state data is then passed
-    to the run() method when evaluating the binding.
-
-    To further accelerate binding, QmlBasicScript can return a precompiled 
-    version of itself that can be saved for future use.  Call compileData() to
-    get an opaque pointer to the compiled state, and compileDataSize() for the
-    size of this data in bytes.  This data can be saved and passed to future
-    instances of the QmlBasicScript constructor.  The initial copy of compile
-    data is owned by the QmlBindScript instance on which compile() was called.
-*/
-
-/*!
-    Create a new QmlBasicScript instance.
-*/
-QmlBasicScript::QmlBasicScript()
-: flags(0), d(0), rc(0)
-{
-}
-
-/*!
-    Create a new QmlBasicScript instance from saved \a data.
-
-    \a data \b must be data previously acquired from calling compileData() on a
-    previously created QmlBasicScript instance.  Any other data will almost
-    certainly cause the QmlBasicScript engine to crash.
-
-    \a data must continue to be valid throughout the QmlBasicScript instance 
-    life.  It does not assume ownership of the memory.
-
-    If \a owner is set, it is referenced on creation and dereferenced on 
-    destruction of this instance.
-*/
-QmlBasicScript::QmlBasicScript(const char *data, QmlRefCount *owner)
-: flags(0), d((QmlBasicScriptPrivate *)data), rc(owner)
-{
-    if (rc) rc->addref();
-}
-
-/*!
-    Return the text of the script expression.
- */
-QByteArray QmlBasicScript::expression() const
-{
-    if (!d)
-        return QByteArray();
-    else
-        return QByteArray(d->expr());
-}
-
-/*!
-    Destroy the script instance.
-*/
-QmlBasicScript::~QmlBasicScript()
-{
-    if (flags & QmlBasicScriptPrivate::OwnData)
-        free(d);
-    if (rc) rc->release();
-    d = 0;
-    rc = 0;
-}
-
-/*!
-    Clear this script.  The object will then be in its initial state, as though
-    it were freshly constructed with default constructor.
-*/
-void QmlBasicScript::clear()
-{
-    if (flags & QmlBasicScriptPrivate::OwnData)
-        free(d);
-    if (rc) rc->release();
-    d = 0;
-    rc = 0;
-    flags = 0;
-}
-
-/*!
-    Return the script state memory for this script instance.  This memory should
-    only be destroyed by calling deleteScriptState().
- */
-void *QmlBasicScript::newScriptState()
-{
-    if (!d) {
-        return 0;
-    } else  {
-        void *rv = ::malloc(d->stateSize * sizeof(QmlBasicScriptNodeCache));
-        ::memset(rv, 0, d->stateSize * sizeof(QmlBasicScriptNodeCache));
-        return rv;
-    }
-}
-
-/*!
-    Delete the \a data previously allocated by newScriptState().
- */
-void QmlBasicScript::deleteScriptState(void *data)
-{
-    if (!data) return;
-    Q_ASSERT(d);
-    clearCache(data);
-    free(data);
-}
-
-/*!
-    Dump the script instructions to stderr for debugging.
- */
-void QmlBasicScript::dump()
-{
-    if (!d)
-        return;
-
-    qWarning() << d->instructionCount << "instructions:";
-    const char *data = d->data();
-    for (int ii = 0; ii < d->instructionCount; ++ii) {
-        const ScriptInstruction &instr = d->instructions()[ii];
-
-        switch(instr.type) {
-        case ScriptInstruction::Load:
-            qWarning().nospace() << "LOAD\t\t" << instr.fetch.idx << "\t\t" 
-                                 << QByteArray(data + instr.fetch.idx);
-            break;
-        case ScriptInstruction::Fetch:
-            qWarning().nospace() << "FETCH\t\t" << instr.fetch.idx << "\t\t" 
-                                 << QByteArray(data + instr.fetch.idx);
-            break;
-        case ScriptInstruction::Add:
-            qWarning().nospace() << "ADD";
-            break;
-        case ScriptInstruction::Subtract:
-            qWarning().nospace() << "SUBTRACT";
-            break;
-        case ScriptInstruction::Multiply:
-            qWarning().nospace() << "MULTIPLY";
-            break;
-        case ScriptInstruction::Equals:
-            qWarning().nospace() << "EQUALS";
-            break;
-        case ScriptInstruction::Int:
-            qWarning().nospace() << "INT\t\t" << instr.integer.value;
-            break;
-        case ScriptInstruction::Bool:
-            qWarning().nospace() << "BOOL\t\t" << instr.boolean.value;
-            break;
-        default:
-            qWarning().nospace() << "UNKNOWN";
-            break;
-        }
-    }
-}
-
-/*!
-    Return true if this is a valid script binding, otherwise returns false.
- */
-bool QmlBasicScript::isValid() const
-{
-    return d != 0;
-}
-
-/*!
-    Compile \a src and return true if the compilation is successful, otherwise
-    returns false.
- */
-bool QmlBasicScript::compile(const QByteArray &src)
-{
-    bool rv = compile(src.constData());
-    return rv;
-}
-
-/*!
-    \overload
-
-    Compile \a src and return true if the compilation is successful, otherwise
-    returns false.
- */
-bool QmlBasicScript::compile(const char *src)
-{
-    if (!src) return false;
-
-    QmlBasicScriptCompiler bsc;
-    bsc.script = this;
-    bsc.tokens = tokenize(src);
-    bsc.src = src;
-    // dumpTokens(src, bsc.tokens);
-
-    if (d) {
-        if (flags & QmlBasicScriptPrivate::OwnData)
-            free(d);
-        d = 0;
-        flags = 0;
-    }
-
-    if (bsc.compile()) {
-        int len = ::strlen(src);
-        flags = QmlBasicScriptPrivate::OwnData;
-        int size = sizeof(QmlBasicScriptPrivate) + 
-                   bsc.bytecode.count() * sizeof(ScriptInstruction) + 
-                   QmlBasicScriptPrivate::alignRound(bsc.data.count() + len + 1);
-        d = (QmlBasicScriptPrivate *) malloc(size);
-        d->size = size;
-        d->stateSize = bsc.stateSize;
-        d->instructionCount = bsc.bytecode.count();
-        d->exprLen = len;
-        ::memcpy((char *)d->expr(), src, len + 1);
-        for (int ii = 0; ii < d->instructionCount; ++ii) 
-            d->instructions()[ii] = bsc.bytecode.at(ii);
-        ::memcpy((char *)d->data(), bsc.data.constData(), bsc.data.count());
-    } 
-
-    return d != 0;
-}
-
-void QmlBasicScriptCompiler::skipWhitespace()
-{
-    while(idx < tokens.count() && tokens.at(idx).token == WHITESPACE)
-        ++idx;
-}
-
-bool QmlBasicScriptCompiler::compile()
-{
-    if (!compileExpr())
-        return false;
-
-    skipWhitespace();
-
-    if (atEnd())
-        return true;
-
-    int t = token();
-    if (t != AND) 
-        return false;
-
-    adv();
-    skipWhitespace();
-    if (!compileExpr())
-        return false;
-
-    ScriptInstruction instr;
-    instr.type = ScriptInstruction::And;
-    bytecode.append(instr);
-
-    skipWhitespace();
-
-    return atEnd();
-}
-
-bool QmlBasicScriptCompiler::compileExpr()
-{
-    /*
-        EXPRESSION := <NAME><OPERATOR>[<CONSTANT>|<NAME>]
-     */
-
-    if (!parseName())
-        return false;
-
-    skipWhitespace();
-
-    if (atEnd())
-        return true;
-
-    int t = token();
-    switch(t) {
-    case PLUS:
-    case MINUS:
-        /*
-    case LANGLE:
-    case RANGLE:
-    */
-    case STAR:
-    case EQUALS:
-        break;
-    default:
-        return true;
-    }
-    adv();
-
-    skipWhitespace();
-
-    if (!parseConstant() &&
-       !parseName())
-        return false;
-
-    ScriptInstruction instr;
-    switch(t) {
-    case PLUS:
-        instr.type = ScriptInstruction::Add;
-        break;
-    case MINUS:
-        instr.type = ScriptInstruction::Subtract;
-        break;
-    case STAR:
-        instr.type = ScriptInstruction::Multiply;
-        break;
-    case EQUALS:
-        instr.type = ScriptInstruction::Equals;
-        break;
-    default:
-        break;
-    }
-    bytecode.append(instr);
-
-    skipWhitespace();
-
-    return true;
-}
-
-bool QmlBasicScriptCompiler::parseName()
-{
-    skipWhitespace();
-    
-    bool named = false;
-    bool seenchar = false;
-    bool seendot = false;
-    int namestart = -1;
-    bool pushed = false;
-    while(!atEnd()) {
-        int t = token();
-        if (t == CHARACTER) {
-            named = true;
-            seendot = false;
-            seenchar = true;
-            namestart = index();
-            adv();
-        } else if (t == DIGIT) {
-            if (!seenchar) break;
-            adv();
-        } else if (t == DOT) {
-            seendot = true;
-            if (namestart == -1)
-                break;
-
-            seenchar = false;
-            QByteArray name = string(namestart, index() - 1);
-            int nref = data.count();
-            data.append(name);
-            data.append('\0');
-            ScriptInstruction instr;
-            if (pushed)
-                instr.type = ScriptInstruction::Fetch;
-            else
-                instr.type = ScriptInstruction::Load;
-            pushed = true;
-            instr.fetch.idx = nref;
-            bytecode.append(instr);
-            ++stateSize;
-            namestart = -1;
-            adv();
-        } else {
-            break;
-        }
-    }
-
-    if (namestart != -1) {
-        QByteArray name = string(namestart, index() - 1);
-        int nref = data.count();
-        data.append(name);
-        data.append('\0');
-        ScriptInstruction instr;
-        if (pushed)
-            instr.type = ScriptInstruction::Fetch;
-        else
-            instr.type = ScriptInstruction::Load;
-        pushed = true;
-        instr.fetch.idx = nref;
-        bytecode.append(instr);
-        ++stateSize;
-    }
-
-    if (seendot)
-        return false;
-    else
-        return named;
-}
-
-bool QmlBasicScriptCompiler::parseConstant()
-{
-    switch(token()) {
-    case DIGIT:
-        {
-            ScriptInstruction instr;
-            instr.type = ScriptInstruction::Int;
-            instr.integer.value = string(index(), index()).toUInt();
-            bytecode.append(instr);
-            adv();
-        }
-        break;
-    case TOKEN_TRUE:
-    case TOKEN_FALSE:
-        {
-            ScriptInstruction instr;
-            instr.type = ScriptInstruction::Bool;
-            instr.boolean.value = (token() == TOKEN_TRUE);
-            bytecode.append(instr);
-            adv();
-        }
-        break;
-
-    default:
-        return false;
-    }
-
-    return true;
-}
-
-bool QmlBasicScriptCompiler::atEnd() const
-{
-    return idx >= tokens.count();
-}
-
-Token QmlBasicScriptCompiler::token() const
-{
-    return tokens.at(idx).token;
-}
-
-void QmlBasicScriptCompiler::adv()
-{
-    ++idx;
-}
-
-int QmlBasicScriptCompiler::index() const
-{
-    return idx;
-}
-
-QByteArray QmlBasicScriptCompiler::string(int from, int to)
-{
-    QByteArray rv;
-    for (int ii = from; ii <= to; ++ii) {
-        const LexerToken &token = tokens.at(ii);
-        rv.append(QByteArray(src + token.start, token.end - token.start + 1));
-    }
-    return rv;
-}
-
-/*!
-    \internal
-*/
-void QmlBasicScript::clearCache(void *voidCache)
-{
-    QmlBasicScriptNodeCache *dataCache =
-        reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache);
-
-    for (int ii = 0; ii < d->stateSize; ++ii) {
-        if (!dataCache[ii].isCore() && !dataCache[ii].isVariant() && 
-            dataCache[ii].object) {
-            QMetaObject::removeGuard(&dataCache[ii].object);
-            dataCache[ii].object = 0;
-        }
-        dataCache[ii].clear();
-    }
-}
-
-void QmlBasicScript::guard(QmlBasicScriptNodeCache &n)
-{
-    if (n.object) {
-        if (n.isVariant()) {
-        } else if (n.isCore()) {
-            n.metaObject = 
-                n.object->metaObject();
-        } else {
-            QMetaObject::addGuard(&n.object);
-        }
-    }
-}
-
-bool QmlBasicScript::valid(QmlBasicScriptNodeCache &n, QObject *obj)
-{
-    return n.object == obj && 
-                       (!n.isCore() || obj->metaObject() == n.metaObject); 
-}
-
-
-/*!
-    \enum QmlBasicScript::CacheState
-    \value NoChange The query has not change.  Any previous monitoring is still
-    valid.
-    \value Incremental The query has been incrementally changed.  Any previous 
-    monitoring is still valid, but needs to have the fresh properties added to
-    it.
-    \value Reset The entire query has been reset from the beginning.  Any previous
-    monitoring is now invalid.
-*/
-
-/*!
-    Run the script in \a context and return the result.  \a voidCache should 
-    contain state memory previously acquired from newScript. 
- */
-QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *cached)
-{
-    if (!isValid())
-        return QVariant();
-
-    QmlBasicScriptNodeCache *dataCache =
-        reinterpret_cast<QmlBasicScriptNodeCache *>(voidCache);
-    int dataCacheItem; 
-    QStack<QVariant> stack;
-
-    bool resetting = false;
-    bool hasReset = false;
-
-    const char *data = d->data();
-
-    if (dataCache[0].type == QmlBasicScriptNodeCache::Invalid) {
-        resetting = true;
-        hasReset = true;
-    }
-
-    CacheState state = NoChange;
-
-    dataCacheItem = 0;
-    for (int idx = 0; idx < d->instructionCount; ++idx) {
-        const ScriptInstruction &instr = d->instructions()[idx];
-
-        switch(instr.type) {
-            case ScriptInstruction::Load: // either an object or a property
-            case ScriptInstruction::Fetch: // can only be a property
-            {
-                const char *id = data + instr.fetch.idx;
-                QmlBasicScriptNodeCache &n = dataCache[dataCacheItem];
-
-                if (instr.type == ScriptInstruction::Load) {
-
-                    if (n.type == QmlBasicScriptNodeCache::Invalid) {
-                        context->engine()->d_func()->loadCache(n, QLatin1String(id), static_cast<QmlContextPrivate*>(context->d_ptr));
-                        state = Incremental;
-                    }
-
-                    if(!n.isValid())
-                        qWarning("ReferenceError: %s is not defined", id);
-
-                } else { // instr.type == ScriptInstruction::Fetch
-
-                    QVariant o = stack.pop();
-                    QObject *obj = qvariant_cast<QObject *>(o);
-                    if (!obj) {
-                        if (n.type == QmlBasicScriptNodeCache::Invalid) {
-                            if (scriptWarnings())
-                                qWarning() << "QmlBasicScript: Unable to convert" << o;
-                            *cached = state;
-                            return QVariant();
-                        } else {
-                            clearCache(dataCache);
-                            *cached = Reset;
-                            CacheState dummy;
-                            return run(context, voidCache, &dummy);
-                        }
-                    } else if (n.type == QmlBasicScriptNodeCache::Invalid) {
-                        context->engine()->d_func()->fetchCache(n, QLatin1String(id), obj);
-                        guard(n);
-                        state = Incremental;
-                    } else if (!valid(n, obj)) {
-                        clearCache(dataCache);
-                        *cached = Reset;
-                        CacheState dummy;
-                        return run(context, voidCache, &dummy);
-                    }
-
-                }
-
-                QVariant var = n.value(id);
-                stack.push(var);
-                ++dataCacheItem;
-            }
-                break;
-            case ScriptInstruction::Int:
-                stack.push(QVariant(instr.integer.value));
-                break;
-            case ScriptInstruction::Bool:
-                stack.push(QVariant(instr.boolean.value));
-                break;
-            case ScriptInstruction::Add:
-                {
-                    QVariant rhs = stack.pop();
-                    QVariant lhs = stack.pop();
-
-                    stack.push(rhs.toDouble() + lhs.toDouble());
-                }
-                break;
-            case ScriptInstruction::Subtract:
-                {
-                    QVariant rhs = stack.pop();
-                    QVariant lhs = stack.pop();
-
-                    stack.push(lhs.toDouble() - rhs.toDouble());
-                }
-                break;
-            case ScriptInstruction::Multiply:
-                {
-                    QVariant rhs = stack.pop();
-                    QVariant lhs = stack.pop();
-
-                    stack.push(rhs.toDouble() * lhs.toDouble());
-                }
-                break;
-            case ScriptInstruction::Equals:
-                {
-                    QVariant rhs = stack.pop();
-                    QVariant lhs = stack.pop();
-
-                    stack.push(rhs == lhs);
-                }
-                break;
-            case ScriptInstruction::And:
-                {
-                    QVariant rhs = stack.pop();
-                    QVariant lhs = stack.pop();
-
-                    stack.push(rhs.toBool() && lhs.toBool());
-                }
-                break;
-            default:
-                break;
-        }
-    }
-
-    *cached = state;
-
-    if (stack.isEmpty())
-        return QVariant();
-    else
-        return stack.top();
-}
-
-/*!
-    Return a pointer to the script's compile data, or null if there is no data.
- */
-const char *QmlBasicScript::compileData() const
-{
-    return (const char *)d;
-}
-
-/*!
-    Return the size of the script's compile data, or zero if there is no data.
-    The size will always be a multiple of 4.
- */
-unsigned int QmlBasicScript::compileDataSize() const
-{
-    if (d)
-        return d->size;
-    else
-        return 0;
-}
-
-bool QmlBasicScript::isSingleLoad() const
-{
-    if (!d)
-        return false;
-
-    return d->instructionCount == 1 &&
-           d->instructions()[0].type == ScriptInstruction::Load;
-}
-
-QByteArray QmlBasicScript::singleLoadTarget() const
-{
-    if (!isSingleLoad())
-        return QByteArray();
-
-    // We know there is one instruction and it is a load
-    return QByteArray(d->data() + d->instructions()[0].fetch.idx);
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/script/qmlbasicscript.h b/src/declarative/qml/script/qmlbasicscript.h
deleted file mode 100644
index 5ef2148..0000000
--- a/src/declarative/qml/script/qmlbasicscript.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the $MODULE$ of the Qt Toolkit.
-**
-** $TROLLTECH_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMLBASICSCRIPT_H
-#define QMLBASICSCRIPT_H
-
-#include "instructions.h"
-#include <QtCore/QList>
-#include <QtCore/QByteArray>
-#include "lexer.h"
-#include <QtCore/QVariant>
-
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-class QmlRefCount;
-class QmlContext;
-class QmlBasicScriptPrivate;
-class QmlBasicScriptNodeCache;
-class QmlBasicScript
-{
-public:
-    QmlBasicScript();
-    QmlBasicScript(const char *, QmlRefCount * = 0);
-    ~QmlBasicScript();
-
-    // Always 4-byte aligned
-    const char *compileData() const;
-    unsigned int compileDataSize() const;
-
-    QByteArray expression() const;
-
-    bool compile(const QByteArray &);
-    bool compile(const char *);
-    bool isValid() const;
-
-    void clear();
-
-    void dump();
-    void *newScriptState();
-    void deleteScriptState(void *);
-
-    enum CacheState { NoChange, Incremental, Reset };
-    QVariant run(QmlContext *, void *, CacheState *);
-
-    // Optimization opportunities
-    bool isSingleLoad() const;
-    QByteArray singleLoadTarget() const;
-
-private:
-    int flags;
-    QmlBasicScriptPrivate *d;
-    QmlRefCount *rc;
-
-    void clearCache(void *);
-    void guard(QmlBasicScriptNodeCache &);
-    bool valid(QmlBasicScriptNodeCache &, QObject *);
-};
-
-#endif // QMLBASICSCRIPT_H
-
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
diff --git a/src/declarative/qml/script/qmlbasicscript_p.h b/src/declarative/qml/script/qmlbasicscript_p.h
deleted file mode 100644
index 3b7e966..0000000
--- a/src/declarative/qml/script/qmlbasicscript_p.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the $MODULE$ of the Qt Toolkit.
-**
-** $TROLLTECH_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMLBASICSCRIPT_P_H
-#define QMLBASICSCRIPT_P_H
-
-QT_BEGIN_NAMESPACE
-
-class QObject;
-class QmlContextPrivate;
-class QDebug;
-class QByteArray;
-
-class QmlBasicScriptNodeCache
-{
-public:
-    QObject *object;
-    const QMetaObject *metaObject;
-    enum { Invalid,
-           Core, 
-           Attached, 
-           Signal,
-           SignalProperty, 
-           Variant
-    } type;
-    union {
-        int core;
-        QObject *attached;
-        QmlContextPrivate *context;
-    };
-    int coreType;
-    int contextIndex;
-
-    bool isValid() const { return type != Invalid; }
-    bool isCore() const { return type == Core; }
-    bool isVariant() const { return type == Variant; }
-    void clear();
-    QVariant value(const char *) const;
-};
-
-QDebug operator<<(QDebug, const QmlBasicScriptNodeCache &);
-
-#endif // QMLBASICSCRIPT_P_H
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/script/script.pri b/src/declarative/qml/script/script.pri
deleted file mode 100644
index 6c43efe..0000000
--- a/src/declarative/qml/script/script.pri
+++ /dev/null
@@ -1,11 +0,0 @@
-SOURCES += \
-           qml/script/tokens.cpp \
-           qml/script/lexer.cpp \
-           qml/script/qmlbasicscript.cpp
-
-HEADERS += \
-           qml/script/tokens.h \
-           qml/script/lexer.h \
-           qml/script/instructions.h \
-           qml/script/qmlbasicscript.h \
-           qml/script/qmlbasicscript_p.h
diff --git a/src/declarative/qml/script/tokens.cpp b/src/declarative/qml/script/tokens.cpp
deleted file mode 100644
index a2fb100..0000000
--- a/src/declarative/qml/script/tokens.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/****************************************************************************
-**
-** This file is part of the $PACKAGE_NAME$.
-**
-** Copyright (C) $THISYEAR$ $COMPANY_NAME$.
-**
-** $QT_EXTENDED_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#include "tokens.h"
-
-
-/*!
-  Returns a string representation of token \a tok.
-*/
-const char *tokenToString(Token tok)
-{
-    switch(tok) {
-#define CASE(X) case X: return #X;
-        CASE(NOTOKEN)
-        CASE(INCOMPLETE)
-        CASE(WHITESPACE)
-        CASE(LANGLE)
-        CASE(RANGLE)
-        CASE(PLUS)
-        CASE(MINUS)
-        CASE(STAR)
-        CASE(EQUALS)
-        CASE(DOT)
-        CASE(CHARACTER)
-        CASE(DIGIT)
-        CASE(OTHER)
-        CASE(AND)
-    case TOKEN_TRUE:
-        return "TRUE";
-    case TOKEN_FALSE:
-        return "FALSE";
-#undef CASE
-    }
-    return 0;
-}
-
diff --git a/src/declarative/qml/script/tokens.h b/src/declarative/qml/script/tokens.h
deleted file mode 100644
index 753e40c..0000000
--- a/src/declarative/qml/script/tokens.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/****************************************************************************
-**
-** This file is part of the $PACKAGE_NAME$.
-**
-** Copyright (C) $THISYEAR$ $COMPANY_NAME$.
-**
-** $QT_EXTENDED_DUAL_LICENSE$
-**
-****************************************************************************/
-
-#ifndef TOKENS_H
-#define TOKENS_H
-
-enum Token {
-    // Lexer tokens
-    NOTOKEN, 
-    INCOMPLETE,
-    WHITESPACE,
-    LANGLE,
-    RANGLE,
-    PLUS,
-    MINUS,
-    STAR,
-    EQUALS, 
-    AND,
-    DOT,
-    CHARACTER,
-    DIGIT,
-    TOKEN_TRUE,
-    TOKEN_FALSE,
-    OTHER
-};
-
-const char *tokenToString(Token);
-
-#endif
-- 
cgit v0.12


From 1090d5d1fad890d9f43e87e19277e1f624921d6d Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Thu, 28 May 2009 13:25:31 +1000
Subject: Delay the compilation of bindings until the end

This way we have a better understanding of the complete context in which the binding will be executed.
---
 src/declarative/qml/qmlcompiler.cpp     | 175 +++++++++++++++-----------------
 src/declarative/qml/qmlcompiler_p.h     |  14 ++-
 src/declarative/qml/qmlparser.cpp       |  17 ++--
 src/declarative/qml/qmlparser_p.h       |   3 +
 src/declarative/qml/qmlscriptparser.cpp |   1 +
 5 files changed, 107 insertions(+), 103 deletions(-)

diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 75d01c2..3029934 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -736,10 +736,8 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
     if (obj) 
         COMPILE_CHECK(compileObject(obj, ctxt));
 
+    finalizeComponent(count);
     create.createComponent.count = output->bytecode.count() - count;
-
-    int inc = finalizeComponent(count);
-    create.createComponent.count += inc;
     compileState = oldComponentCompileState;
     return true;
 }
@@ -1125,9 +1123,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
                     COMPILE_EXCEPTION("Can only assign one binding to lists");
 
                 assignedBinding = true;
-                COMPILE_CHECK(compileBinding(v->value, prop, ctxt, 
-                                             obj->metaObject(), 
-                                             v->location.start.line));
+                COMPILE_CHECK(compileBinding(v, prop, ctxt));
                 v->type = Value::PropertyBinding;
             } else {
                 COMPILE_EXCEPTION("Cannot assign primitives to lists");
@@ -1296,9 +1292,7 @@ bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
 
     if (v->value.isScript()) {
 
-        COMPILE_CHECK(compileBinding(v->value, prop, ctxt, 
-                                     obj->metaObject(), 
-                                     v->location.start.line));
+        COMPILE_CHECK(compileBinding(v, prop, ctxt));
 
         v->type = Value::PropertyBinding;
 
@@ -1403,46 +1397,27 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj)
     return true;
 }
 
-bool QmlCompiler::compileBinding(const QmlParser::Variant &bind, 
+bool QmlCompiler::compileBinding(QmlParser::Value *value, 
                                  QmlParser::Property *prop,
-                                 int ctxt, const QMetaObject *mo, qint64 line)
+                                 int ctxt)
 {
-    Q_ASSERT(mo);
     Q_ASSERT(prop->index);
+    Q_ASSERT(prop->parent);
+    Q_ASSERT(prop->parent->metaObject());
 
-    QMetaProperty mp = mo->property(prop->index);
+    QMetaProperty mp = prop->parent->metaObject()->property(prop->index);
     if (!mp.isWritable() && !QmlMetaType::isList(prop->type))
         COMPILE_EXCEPTION2(prop, "Cannot assign binding to read-only property");
 
-    QmlBasicScript bs;
-    bs.compile(bind);
-
-    int bref;
-    if (bs.isValid()) {
-        bref = output->indexForByteArray(QByteArray(bs.compileData(), bs.compileDataSize()));
-    } else {
-        bref = output->indexForString(bind.asScript());
-    }
-
-    QmlInstruction assign;
-    assign.assignBinding.context = ctxt;
-    assign.line = line;
-
-    if (bs.isValid()) 
-        assign.type = QmlInstruction::StoreCompiledBinding;
-    else
-        assign.type = QmlInstruction::StoreBinding;
-
-    assign.assignBinding.property = prop->index;
-    assign.assignBinding.value = bref;
-    assign.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
     BindingReference reference;
-    reference.expression = bind;
+    reference.expression = value->value;
     reference.property = prop;
+    reference.value = value;
     reference.instructionIdx = output->bytecode.count();
+    reference.bindingContext = ctxt;
     compileState.bindings << reference;
 
-    output->bytecode << assign;
+    output->bytecode << QmlInstruction();;
 
     return true;
 }
@@ -1490,81 +1465,95 @@ protected:
 
 // Update the init instruction with final data, and optimize some simple 
 // bindings
-int QmlCompiler::finalizeComponent(int patch)
+void QmlCompiler::finalizeComponent(int patch)
 {
-    int saveCount = 0;
-    int newInstrs = 0;
-
     for (int ii = 0; ii < compileState.bindings.count(); ++ii) {
         const BindingReference &binding = compileState.bindings.at(ii);
+        finalizeBinding(binding);
+    }
 
-        QmlInstruction &instr = output->bytecode[binding.instructionIdx];
-
-        if (instr.type == QmlInstruction::StoreCompiledBinding) {
-            QmlBasicScript s(output->datas.at(instr.assignBinding.value).constData());
-
-            if (s.isSingleLoad()) {
-                QString slt = QLatin1String(s.singleLoadTarget());
-                if (!slt.at(0).isUpper())
-                    continue;
-
-                if (compileState.ids.contains(slt) && 
-                   instr.assignBinding.category == QmlMetaProperty::Object) {
+    output->bytecode[patch].init.dataSize = compileState.savedObjects;;
+    output->bytecode[patch].init.bindingsSize = compileState.bindings.count();
+    output->bytecode[patch].init.parserStatusSize = 
+        compileState.parserStatusCount;
+}
 
-                    IdReference reference = 
-                        compileState.ids[slt];
+void QmlCompiler::finalizeBinding(const BindingReference &binding)
+{
+    QmlBasicScript bs;
+    bs.compile(binding.expression);
 
-                    const QMetaObject *idMo = reference.object->metaObject();
-                    const QMetaObject *storeMo = QmlMetaType::rawMetaObjectForType(binding.property->type);
+    QmlInstruction &instr = output->bytecode[binding.instructionIdx];
+    instr.line = binding.value->location.start.line;
 
-                    Q_ASSERT(idMo);
-                    Q_ASSERT(storeMo);
+    // Single load optimization 
+    if (bs.isValid() && bs.isSingleLoad()) {
 
-                    bool canAssign = false;
-                    while (!canAssign && idMo) {
-                        if (idMo == storeMo)
-                            canAssign = true;
-                        else
-                            idMo = idMo->superClass();
-                    }
+        QString singleLoadTarget = QLatin1String(bs.singleLoadTarget());
 
-                    if (!canAssign)
-                        continue;
+        if (singleLoadTarget.at(0).isUpper() && 
+            compileState.ids.contains(singleLoadTarget) &&
+            QmlMetaType::isObject(binding.property->type)) {
 
-                    int saveId = -1;
+            IdReference reference = compileState.ids[singleLoadTarget];
 
-                    int instructionIdx = reference.instructionIdx;
-                    if (output->bytecode.at(instructionIdx).setId.save != -1) {
-                        saveId = output->bytecode.at(instructionIdx).setId.save;
-                    } else {
-                        output->bytecode[instructionIdx].setId.save = saveCount;
-                        saveId = saveCount;
-                        ++saveCount;
-                    }
+            const QMetaObject *idMo = reference.object->metaObject();
+            const QMetaObject *storeMo = 
+                QmlMetaType::rawMetaObjectForType(binding.property->type);
 
-                    int prop = instr.assignBinding.property;
+            Q_ASSERT(idMo);
+            Q_ASSERT(storeMo);
 
-                    instr.type = QmlInstruction::PushProperty;
-                    instr.pushProperty.property = prop;
+            bool canAssign = false;
+            while (!canAssign && idMo) {
+                if (idMo == storeMo)
+                    canAssign = true;
+                else
+                    idMo = idMo->superClass();
+            }
 
-                    QmlInstruction instr;
-                    instr.type = QmlInstruction::StoreStackObject;
-                    instr.line = 0;
-                    instr.assignStackObject.property = newInstrs;
-                    instr.assignStackObject.object = saveId;
-                    output->bytecode << instr;
-                    ++newInstrs;
+            if (canAssign) {
+                int instructionIdx = reference.instructionIdx;
+                if (output->bytecode.at(instructionIdx).setId.save == -1) {
+                    output->bytecode[instructionIdx].setId.save = 
+                        compileState.savedObjects++;
                 }
+                int saveId = output->bytecode.at(instructionIdx).setId.save;
+
+                instr.type = QmlInstruction::PushProperty;
+                instr.pushProperty.property = binding.property->index;
+
+                QmlInstruction store;
+                store.type = QmlInstruction::StoreStackObject;
+                store.line = 0;
+                store.assignStackObject.property = 
+                    compileState.pushedProperties++;
+                store.assignStackObject.object = saveId;
+                output->bytecode << store;
+                return;
             }
-        } 
+        }
     }
 
-    output->bytecode[patch].init.dataSize = saveCount;
-    output->bytecode[patch].init.bindingsSize = compileState.bindings.count();
-    output->bytecode[patch].init.parserStatusSize = 
-        compileState.parserStatusCount;
+    // General binding fallback
+    int bref;
+    if (bs.isValid()) {
+        bref = output->indexForByteArray(QByteArray(bs.compileData(), bs.compileDataSize()));
+    } else {
+        bref = output->indexForString(binding.expression.asScript());
+    }
+
+    instr.assignBinding.context = binding.bindingContext;
+
+    if (bs.isValid()) 
+        instr.type = QmlInstruction::StoreCompiledBinding;
+    else
+        instr.type = QmlInstruction::StoreBinding;
 
-    return newInstrs;
+    instr.assignBinding.property = binding.property->index;
+    instr.assignBinding.value = bref;
+    QMetaProperty mp = binding.property->parent->metaObject()->property(binding.property->index);
+    instr.assignBinding.category = QmlMetaProperty::propertyCategory(mp);
 }
 
 QmlCompiledData::QmlCompiledData()
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index b1963da..eb24b91 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -158,10 +158,12 @@ private:
                                  QmlParser::Value *value);
 
     bool compileDynamicMeta(QmlParser::Object *obj);
-    bool compileBinding(const QmlParser::Variant &, QmlParser::Property *prop,
-                        int ctxt, const QMetaObject *, qint64);
+    bool compileBinding(QmlParser::Value *, QmlParser::Property *prop,
+                        int ctxt);
 
-    int finalizeComponent(int patch);
+    void finalizeComponent(int patch);
+    class BindingReference;
+    void finalizeBinding(const BindingReference &); 
 
     struct IdReference {
         QString id;
@@ -172,14 +174,18 @@ private:
     struct BindingReference {
         QmlParser::Variant expression;
         QmlParser::Property *property;
+        QmlParser::Value *value;
         int instructionIdx;
+        int bindingContext;
     };
 
     struct ComponentCompileState
     {
-        ComponentCompileState() : parserStatusCount(0) {}
+        ComponentCompileState() : parserStatusCount(0), savedObjects(0), pushedProperties(0) {}
         QHash<QString, IdReference> ids;
         int parserStatusCount;
+        int savedObjects;
+        int pushedProperties;
         QList<BindingReference> bindings;
     };
     ComponentCompileState compileState;
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index f262b5d..fadfbb1 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -83,18 +83,23 @@ const QMetaObject *Object::metaObject() const
 
 QmlParser::Property *Object::getDefaultProperty()
 {
-    if (!defaultProperty)
+    if (!defaultProperty) {
         defaultProperty = new Property;
+        defaultProperty->parent = this;
+    }
     return defaultProperty;
 }
 
 Property *QmlParser::Object::getProperty(const QByteArray &name, bool create)
 {
     if (!properties.contains(name)) {
-        if (create)
-            properties.insert(name, new Property(name));
-        else
+        if (create) {
+            Property *property = new Property(name);
+            property->parent = this;
+            properties.insert(name, property);
+        } else {
             return 0;
+        }
     }
     return properties[name];
 }
@@ -153,12 +158,12 @@ void QmlParser::Object::dump(int indent) const
 }
 
 QmlParser::Property::Property()
-: type(0), index(-1), value(0), isDefault(true)
+: parent(0), type(0), index(-1), value(0), isDefault(true)
 {
 }
 
 QmlParser::Property::Property(const QByteArray &n)
-: type(0), index(-1), value(0), name(n), isDefault(false)
+: parent(0), type(0), index(-1), value(0), name(n), isDefault(false)
 {
 }
 
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index cb9b540..020cae5 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -252,6 +252,9 @@ namespace QmlParser
         Property(const QByteArray &n);
         virtual ~Property();
 
+        // The Object to which this property is attached
+        Object *parent;
+
         Object *getValue();
         void addValue(Value *v);
 
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index b1ffc98..75c81a7 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -532,6 +532,7 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
 
         if (node->expression) { // default value
             property.defaultValue = new Property;
+            property.defaultValue->parent = _stateStack.top().object;
             Value *value = new Value;
             value->location = location(node->expression->firstSourceLocation(),
                                        node->expression->lastSourceLocation());
-- 
cgit v0.12