Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / v4 / qv4compiler.cpp
index 857bceb..0d29872 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
 **
 ** This file is part of the QtDeclarative module of the Qt Toolkit.
 **
@@ -35,6 +34,7 @@
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
@@ -46,9 +46,8 @@
 #include "qv4irbuilder_p.h"
 
 #include <private/qdeclarativejsast_p.h>
-#include <private/qdeclarativefastproperties_p.h>
+#include <private/qdeclarativeaccessors_p.h>
 #include <private/qdeclarativejsengine_p.h>
-#include <private/qquickanchors_p_p.h> // For AnchorLine
 
 QT_BEGIN_NAMESPACE
 
@@ -277,7 +276,7 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
 
         Instr::LoadId instr;
         instr.reg = currentReg;
-        instr.index = e->index;
+        instr.index = e->idObject->idIndex;
         gen(instr);
 
         _subscribeName << QLatin1String("$$$ID_") + *e->id;
@@ -311,7 +310,8 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
         attached.output = currentReg;
         attached.reg = currentReg;
         attached.exceptionId = exceptionId(e->line, e->column);
-        Q_ASSERT(e->declarativeType->attachedPropertiesId() != -1);
+        if (e->declarativeType->attachedPropertiesId() == -1)
+            discard();
         attached.id = e->declarativeType->attachedPropertiesId();
         gen(attached);
     } break;
@@ -319,10 +319,12 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
     case IR::Name::Property: {
         _subscribeName << *e->id;
 
-        QMetaProperty prop = e->meta->property(e->index);
-        int fastFetchIndex = QDeclarativeFastProperties::instance()->accessorIndexForProperty(e->meta, e->index);
+        if (e->property->coreIndex == -1) {
+            QMetaProperty prop;
+            e->property->load(prop, QDeclarativeEnginePrivate::get(engine));
+        }
 
-        const int propTy = prop.userType();
+        const int propTy = e->property->propType;
         QDeclarativeRegisterType regType;
 
         switch (propTy) {
@@ -338,11 +340,14 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
         case QMetaType::QString:
             regType = QStringType;
             break;
+        case QMetaType::QUrl:
+            regType = QUrlType;
+            break;
 
         default:
             if (propTy == qMetaTypeId<QDeclarative1AnchorLine>()) {
                 regType = PODValueType;
-            } else if (propTy == qMetaTypeId<QQuickAnchorLine>()) {
+            } else if (propTy == QDeclarativeMetaType::QQuickAnchorLineMetaTypeId()) {
                 regType = PODValueType;
             } else if (QDeclarativeMetaType::isQObject(propTy)) {
                 regType = QObjectStarType;
@@ -356,26 +361,26 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
             break;
         } // switch
 
-        if (fastFetchIndex != -1) {
+        if (e->property->hasAccessors()) {
             Instr::FetchAndSubscribe fetch;
             fetch.reg = currentReg;
-            fetch.function = fastFetchIndex;
             fetch.subscription = subscriptionIndex(_subscribeName);
             fetch.exceptionId = exceptionId(e->line, e->column);
             fetch.valueType = regType;
+            fetch.property = *e->property;
             gen(fetch);
         } else {
-            if (blockNeedsSubscription(_subscribeName) && prop.hasNotifySignal() && prop.notifySignalIndex() != -1) {
+            if (blockNeedsSubscription(_subscribeName) && e->property->notifyIndex != -1) {
                 Instr::Subscribe sub;
                 sub.reg = currentReg;
                 sub.offset = subscriptionIndex(_subscribeName);
-                sub.index = prop.notifySignalIndex();
+                sub.index = e->property->notifyIndex;
                 gen(sub);
             }
 
             Instr::Fetch fetch;
             fetch.reg = currentReg;
-            fetch.index = e->index;
+            fetch.index = e->property->coreIndex;
             fetch.exceptionId = exceptionId(e->line, e->column);
             fetch.valueType = regType;
             gen(fetch);
@@ -846,15 +851,40 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
             traceExpression(s->source, dest);
 
         V4Instr::Type opcode = V4Instr::Noop;
-        if (target->type == IR::BoolType) {
-            switch (s->source->type) {
+        IR::Type targetTy = s->target->type;
+        IR::Type sourceTy = s->source->type;
+
+        if (sourceTy == IR::UrlType) {
+            switch (targetTy) {
+            case IR::BoolType:
+            case IR::StringType:
+                // nothing to do. V4 will generate optimized
+                // url-to-xxx conversions.
+                break;
+            default: {
+                // generate a UrlToString conversion and fix
+                // the type of the source expression.
+                V4Instr conv;
+                conv.unaryop.output = V4Instr::ConvertUrlToString;
+                conv.unaryop.src = src;
+                gen(opcode, conv);
+
+                sourceTy = IR::StringType;
+                break;
+            }
+            } // switch
+        }
+
+        if (targetTy == IR::BoolType) {
+            switch (sourceTy) {
             case IR::IntType: opcode = V4Instr::ConvertIntToBool; break;
             case IR::RealType: opcode = V4Instr::ConvertRealToBool; break;
             case IR::StringType: opcode = V4Instr::ConvertStringToBool; break;
+            case IR::UrlType: opcode = V4Instr::ConvertUrlToBool; break;
             default: break;
             } // switch
-        } else if (target->type == IR::IntType) {
-            switch (s->source->type) {
+        } else if (targetTy == IR::IntType) {
+            switch (sourceTy) {
             case IR::BoolType: opcode = V4Instr::ConvertBoolToInt; break;
             case IR::RealType: {
                 if (s->isMoveForReturn)
@@ -866,26 +896,49 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
             case IR::StringType: opcode = V4Instr::ConvertStringToInt; break;
             default: break;
             } // switch
-        } else if (target->type == IR::RealType) {
-            switch (s->source->type) {
+        } else if (targetTy == IR::RealType) {
+            switch (sourceTy) {
             case IR::BoolType: opcode = V4Instr::ConvertBoolToReal; break;
             case IR::IntType: opcode = V4Instr::ConvertIntToReal; break;
             case IR::StringType: opcode = V4Instr::ConvertStringToReal; break;
             default: break;
             } // switch
-        } else if (target->type == IR::StringType) {
-            switch (s->source->type) {
+        } else if (targetTy == IR::StringType) {
+            switch (sourceTy) {
             case IR::BoolType: opcode = V4Instr::ConvertBoolToString; break;
             case IR::IntType:  opcode = V4Instr::ConvertIntToString; break;
             case IR::RealType: opcode = V4Instr::ConvertRealToString; break;
+            case IR::UrlType: opcode = V4Instr::ConvertUrlToString; break;
+            default: break;
+            } // switch
+        } else if (targetTy == IR::UrlType) {
+            V4Instr convToString;
+            convToString.unaryop.output = dest;
+            convToString.unaryop.src = src;
+
+            // try to convert the source expression to a string.
+            switch (sourceTy) {
+            case IR::BoolType: gen(V4Instr::ConvertBoolToString, convToString); sourceTy = IR::StringType; break;
+            case IR::IntType:  gen(V4Instr::ConvertIntToString,  convToString); sourceTy = IR::StringType; break;
+            case IR::RealType: gen(V4Instr::ConvertRealToString, convToString); sourceTy = IR::StringType; break;
             default: break;
             } // switch
+
+            if (sourceTy == IR::StringType)
+                opcode = V4Instr::ConvertStringToUrl;
         }
         if (opcode != V4Instr::Noop) {
             V4Instr conv;
             conv.unaryop.output = dest;
             conv.unaryop.src = src;
             gen(opcode, conv);
+
+            if (s->isMoveForReturn && opcode == V4Instr::ConvertStringToUrl) {
+                V4Instr resolveUrl;
+                resolveUrl.unaryop.output = dest;
+                resolveUrl.unaryop.src = dest;
+                gen(V4Instr::ResolveUrl, resolveUrl);
+            }
         } else {
             discard();
         }
@@ -941,7 +994,7 @@ void QV4CompilerPrivate::visitRet(IR::Ret *s)
             test.regType = qMetaTypeId<QDeclarative1AnchorLine>();
             break;
         case IR::SGAnchorLineType:
-            test.regType = qMetaTypeId<QQuickAnchorLine>();
+            test.regType = QDeclarativeMetaType::QQuickAnchorLineMetaTypeId();
             break;
         case IR::ObjectType:
             test.regType = QMetaType::QObjectStar;