diff options
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/v4/qv4bindings.cpp | 30 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8engine_p.h | 12 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8valuetypewrapper.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/v8/qv8valuetypewrapper_p.h | 2 |
5 files changed, 48 insertions, 4 deletions
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index 0088741170..169e60ec41 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -649,6 +649,7 @@ static void testBindingResult(const QString &binding, quint16 line, quint16 colu qtscriptResult = "exception"; } else if ((value.userType() != resultType) && (resultType != QMetaType::QVariant) && + (resultType != qMetaTypeId<QJSValue>()) && (resultType != handleType)) { // Override the QMetaType conversions to make them more JS friendly. if (value.userType() == QMetaType::Double && (resultType == QMetaType::QString || @@ -708,6 +709,8 @@ static void testBindingResult(const QString &binding, quint16 line, quint16 colu default: if (resultType == QQmlMetaType::QQuickAnchorLineMetaTypeId()) { v4value = QVariant(QQmlMetaType::QQuickAnchorLineMetaTypeId(), result.typeDataPtr()); + } else if (resultType == qMetaTypeId<QJSValue>()) { + v4value = result.getjsvalueptr()->toVariant(); } else if (resultType == handleType) { QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine); v4value = ep->v8engine()->toVariant(*result.gethandleptr(), resultType); @@ -1834,8 +1837,19 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, { const Register &src = registers[instr->unaryop.src]; Register &output = registers[instr->unaryop.output]; - if (src.isUndefined()) output.setUndefined(); - else output.setint(qFloor(src.getnumber())); + if (src.isUndefined()) + output.setUndefined(); + else if (src.isNaN()) + // output should be an int, but still NaN + output.setNaNType(); + else if (src.isInf()) + // output should be an int, but still Inf + output.setInfType(signBitSet(src.getnumber())); + else if (src.isNegativeZero()) + // output should be an int, but still -0 + output.setNegativeZeroType(); + else + output.setint(qFloor(src.getnumber())); } QML_V4_END_INSTR(MathFloorNumber, unaryop) @@ -1854,8 +1868,16 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, else if (src.isNegativeZero()) // output should be an int, but still -0 output.setNegativeZeroType(); - else - output.setint(qCeil(src.getnumber())); + else { + // Ensure that we preserve the sign bit (Math.ceil(-0) -> -0) + const double input = src.getnumber(); + const int ceiled = qCeil(input); + if (ceiled == 0 && signBitSet(input)) { + output.setNegativeZeroType(); + } else { + output.setint(ceiled); + } + } } QML_V4_END_INSTR(MathCeilNumber, unaryop) diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 9f37c2dcaa..cbb9053de7 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -1289,6 +1289,8 @@ QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value, return variantValue(value); if (isQObject(value)) return qVariantFromValue(qtObjectFromJS(value)); + if (isValueType(value)) + return toValueType(value); return variantMapFromJS(value->ToObject(), visitedObjects); } diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 28acd15ff8..09ff7f4b2f 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -332,6 +332,8 @@ public: // Create a new value type object inline v8::Handle<v8::Value> newValueType(QObject *, int coreIndex, QQmlValueType *); inline v8::Handle<v8::Value> newValueType(const QVariant &, QQmlValueType *); + inline bool isValueType(v8::Handle<v8::Value>) const; + inline QVariant toValueType(v8::Handle<v8::Value> obj); // Create a new sequence type object inline v8::Handle<v8::Value> newSequence(int sequenceType, QObject *, int coreIndex, bool *succeeded); @@ -599,6 +601,16 @@ v8::Handle<v8::Value> QV8Engine::newValueType(const QVariant &value, QQmlValueTy return m_valueTypeWrapper.newValueType(value, type); } +bool QV8Engine::isValueType(v8::Handle<v8::Value> obj) const +{ + return obj->IsObject()?m_valueTypeWrapper.isValueType(v8::Handle<v8::Object>::Cast(obj)):false; +} + +QVariant QV8Engine::toValueType(v8::Handle<v8::Value> obj) +{ + return obj->IsObject()?m_valueTypeWrapper.toVariant(v8::Handle<v8::Object>::Cast(obj)):QVariant(); +} + v8::Handle<v8::Value> QV8Engine::newSequence(int sequenceType, QObject *object, int property, bool *succeeded) { return m_sequenceWrapper.newSequence(sequenceType, object, property, succeeded); diff --git a/src/qml/qml/v8/qv8valuetypewrapper.cpp b/src/qml/qml/v8/qv8valuetypewrapper.cpp index 6a0521b8be..0408df4b00 100644 --- a/src/qml/qml/v8/qv8valuetypewrapper.cpp +++ b/src/qml/qml/v8/qv8valuetypewrapper.cpp @@ -181,6 +181,12 @@ static bool readReferenceValue(QV8ValueTypeReferenceResource *reference) return true; } +bool QV8ValueTypeWrapper::isValueType(v8::Handle<v8::Object> obj) const +{ + QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(obj); + return (r != 0); +} + QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj, int typeHint, bool *succeeded) { // NOTE: obj must not be an external resource object (ie, wrapper object) diff --git a/src/qml/qml/v8/qv8valuetypewrapper_p.h b/src/qml/qml/v8/qv8valuetypewrapper_p.h index f3dd246116..849ca4112e 100644 --- a/src/qml/qml/v8/qv8valuetypewrapper_p.h +++ b/src/qml/qml/v8/qv8valuetypewrapper_p.h @@ -76,6 +76,8 @@ public: v8::Local<v8::Object> newValueType(QObject *, int, QQmlValueType *); v8::Local<v8::Object> newValueType(const QVariant &, QQmlValueType *); + bool isValueType(v8::Handle<v8::Object>) const; + QVariant toVariant(v8::Handle<v8::Object>, int typeHint, bool *succeeded); QVariant toVariant(v8::Handle<v8::Object>); QVariant toVariant(QV8ObjectResource *); |