aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4value.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4value.cpp')
-rw-r--r--src/qml/jsruntime/qv4value.cpp168
1 files changed, 88 insertions, 80 deletions
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 718b87d2c9..f97aa66669 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -48,44 +48,9 @@
using namespace QV4;
-int Value::toInt32() const
-{
- if (isConvertibleToInt())
- return int_32;
- double d;
- if (isDouble())
- d = dbl;
- else
- d = toNumber();
-
- const double D32 = 4294967296.0;
- const double D31 = D32 / 2.0;
-
- if ((d >= -D31 && d < D31))
- return static_cast<int>(d);
-
- return Value::toInt32(d);
-}
-
-unsigned int Value::toUInt32() const
-{
- if (isConvertibleToInt())
- return (unsigned) int_32;
- double d;
- if (isDouble())
- d = dbl;
- else
- d = toNumber();
-
- const double D32 = 4294967296.0;
- if (d >= 0 && d < D32)
- return static_cast<uint>(d);
- return toUInt32(d);
-}
-
int Value::toUInt16() const
{
- if (isConvertibleToInt())
+ if (integerCompatible())
return (ushort)(uint)integerValue();
double number = toNumber();
@@ -111,41 +76,39 @@ int Value::toUInt16() const
double Value::toInteger() const
{
- if (isConvertibleToInt())
+ if (integerCompatible())
return int_32;
return Value::toInteger(toNumber());
}
-double Value::toNumber() const
+double Value::toNumberImpl() const
{
- QV4::Value v = *this;
-
- redo:
- switch (v.type()) {
+ switch (type()) {
case QV4::Value::Undefined_Type:
return std::numeric_limits<double>::quiet_NaN();
+ case QV4::Value::Managed_Type:
+ if (isString())
+ return __qmljs_string_to_number(stringValue()->toQString());
+ {
+ ExecutionContext *ctx = objectValue()->internalClass->engine->current;
+ Scope scope(ctx);
+ ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), NUMBER_HINT));
+ return prim->toNumber();
+ }
case QV4::Value::Null_Type:
- return 0;
case QV4::Value::Boolean_Type:
- return (v.booleanValue() ? 1. : 0.);
case QV4::Value::Integer_Type:
- return v.int_32;
- case QV4::Value::String_Type:
- return __qmljs_string_to_number(v.toQString());
- case QV4::Value::Object_Type: {
- v = __qmljs_to_primitive(ValueRef::fromRawValue(this), QV4::NUMBER_HINT);
- goto redo;
- }
default: // double
- return v.doubleValue();
+ Q_UNREACHABLE();
}
}
-QString Value::toQString() const
+QString Value::toQStringNoThrow() const
{
switch (type()) {
case Value::Undefined_Type:
+ case Value::Empty_Type:
return QStringLiteral("undefined");
case Value::Null_Type:
return QStringLiteral("null");
@@ -154,28 +117,64 @@ QString Value::toQString() const
return QStringLiteral("true");
else
return QStringLiteral("false");
- case Value::String_Type:
- return stringValue()->toQString();
- case Value::Object_Type: {
- ExecutionContext *ctx = objectValue()->internalClass->engine->current;
- ValueScope scope(ctx);
- try {
- ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), STRING_HINT));
- if (prim->isPrimitive())
- return prim->toQString();
- } catch (Exception &e) {
- e.accept(ctx);
+ case Value::Managed_Type:
+ if (isString())
+ return stringValue()->toQString();
+ {
+ ExecutionContext *ctx = objectValue()->internalClass->engine->current;
+ Scope scope(ctx);
try {
- ScopedValue ex(scope, e.value());
- ScopedValue prim(scope, __qmljs_to_primitive(ex, STRING_HINT));
+ ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), STRING_HINT));
if (prim->isPrimitive())
- return prim->toQString();
- } catch(Exception &e) {
+ return prim->toQStringNoThrow();
+ } catch (Exception &e) {
e.accept(ctx);
+ try {
+ ScopedValue ex(scope, e.value());
+ ScopedValue prim(scope, __qmljs_to_primitive(ex, STRING_HINT));
+ if (prim->isPrimitive())
+ return prim->toQStringNoThrow();
+ } catch(Exception &e) {
+ e.accept(ctx);
+ }
}
+ return QString();
}
- return QString();
+ case Value::Integer_Type: {
+ QString str;
+ __qmljs_numberToString(&str, (double)int_32, 10);
+ return str;
+ }
+ default: { // double
+ QString str;
+ __qmljs_numberToString(&str, doubleValue(), 10);
+ return str;
}
+ } // switch
+}
+
+QString Value::toQString() const
+{
+ switch (type()) {
+ case Value::Undefined_Type:
+ case Value::Empty_Type:
+ return QStringLiteral("undefined");
+ case Value::Null_Type:
+ return QStringLiteral("null");
+ case Value::Boolean_Type:
+ if (booleanValue())
+ return QStringLiteral("true");
+ else
+ return QStringLiteral("false");
+ case Value::Managed_Type:
+ if (isString())
+ return stringValue()->toQString();
+ {
+ ExecutionContext *ctx = objectValue()->internalClass->engine->current;
+ Scope scope(ctx);
+ ScopedValue prim(scope, __qmljs_to_primitive(ValueRef::fromRawValue(this), STRING_HINT));
+ return prim->toQString();
+ }
case Value::Integer_Type: {
QString str;
__qmljs_numberToString(&str, (double)int_32, 10);
@@ -194,10 +193,10 @@ bool Value::sameValue(Value other) const {
return true;
if (isString() && other.isString())
return stringValue()->isEqualTo(other.stringValue());
- if (isInteger())
- return int_32 ? (double(int_32) == other.dbl) : (other.val == 0);
- if (other.isInteger())
- return other.int_32 ? (dbl == double(other.int_32)) : (val == 0);
+ if (isInteger() && other.isDouble())
+ return int_32 ? (double(int_32) == other.doubleValue()) : (other.val == 0);
+ if (isDouble() && other.isInteger())
+ return other.int_32 ? (doubleValue() == double(other.int_32)) : (val == 0);
return false;
}
@@ -273,25 +272,24 @@ String *Value::toString(ExecutionContext *ctx) const
{
if (isString())
return stringValue();
- return __qmljs_convert_to_string(ctx, ValueRef::fromRawValue(this));
+ return __qmljs_convert_to_string(ctx, ValueRef::fromRawValue(this))->getPointer();
}
Object *Value::toObject(ExecutionContext *ctx) const
{
if (isObject())
return objectValue();
- return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this));
+ return __qmljs_convert_to_object(ctx, ValueRef::fromRawValue(this))->getPointer();
}
-Value Value::property(ExecutionContext *ctx, String *name) const
+PersistentValue::PersistentValue(const Value &val)
+ : d(new PersistentValuePrivate(val))
{
- return isObject() ? objectValue()->get(name) : undefinedValue();
}
-
-PersistentValue::PersistentValue(const Value &val)
- : d(new PersistentValuePrivate(val))
+PersistentValue::PersistentValue(ReturnedValue val)
+ : d(new PersistentValuePrivate(Value::fromReturnedValue(val)))
{
}
@@ -328,6 +326,16 @@ PersistentValue &PersistentValue::operator =(const Value &other)
return *this;
}
+PersistentValue &PersistentValue::operator =(const ReturnedValue &other)
+{
+ if (!d) {
+ d = new PersistentValuePrivate(Value::fromReturnedValue(other));
+ return *this;
+ }
+ d = d->detach(Value::fromReturnedValue(other));
+ return *this;
+}
+
PersistentValue::~PersistentValue()
{
if (d)