diff options
Diffstat (limited to 'src/qml/jsruntime/qv4value.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4value.cpp | 119 |
1 files changed, 25 insertions, 94 deletions
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index f41442df7a..0d4711df3c 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -75,39 +75,29 @@ int Value::toUInt16() const return (unsigned short)number; } -bool Value::toBoolean() const +bool Value::toBooleanImpl(Value val) { - if (isInteger() || isBoolean()) - return static_cast<bool>(int_32()); - - if (isUndefined() || isNull()) - return false; - - if (isManaged()) { + if (val.isManagedOrUndefined()) { + Heap::Base *b = val.m(); + if (!b) + return false; #ifdef V4_BOOTSTRAP Q_UNIMPLEMENTED(); #else - if (String *s = stringValue()) - return s->toQString().length() > 0; + if (b->vtable()->isString) + return static_cast<Heap::String *>(b)->length() > 0; #endif return true; } // double - return doubleValue() && !std::isnan(doubleValue()); + double d = val.doubleValue(); + return d && !std::isnan(d); } -double Value::toInteger() const +double Value::toNumberImpl(Value val) { - if (integerCompatible()) - return int_32(); - - return Primitive::toInteger(toNumber()); -} - -double Value::toNumberImpl() const -{ - switch (type()) { + switch (val.type()) { case QV4::Value::Undefined_Type: return std::numeric_limits<double>::quiet_NaN(); case QV4::Value::Managed_Type: @@ -115,12 +105,13 @@ double Value::toNumberImpl() const Q_UNIMPLEMENTED(); Q_FALLTHROUGH(); #else - if (String *s = stringValue()) + if (String *s = val.stringValue()) return RuntimeHelpers::stringToNumber(s->toQString()); { - Q_ASSERT(isObject()); - Scope scope(objectValue()->engine()); - ScopedValue prim(scope, RuntimeHelpers::toPrimitive(*this, NUMBER_HINT)); + Q_ASSERT(val.isObject()); + Scope scope(val.objectValue()->engine()); + ScopedValue protectThis(scope, val); + ScopedValue prim(scope, RuntimeHelpers::toPrimitive(val, NUMBER_HINT)); if (scope.engine->hasException) return 0; return prim->toNumber(); @@ -129,7 +120,7 @@ double Value::toNumberImpl() const case QV4::Value::Null_Type: case QV4::Value::Boolean_Type: case QV4::Value::Integer_Type: - return int_32(); + return val.int_32(); default: // double Q_UNREACHABLE(); } @@ -236,83 +227,23 @@ bool Value::sameValue(Value other) const { if (s && os) return s->isEqualTo(os); if (isInteger() && other.isDouble()) - return int_32() ? (double(int_32()) == other.doubleValue()) : (other._val == 0); + return int_32() ? (double(int_32()) == other.doubleValue()) + : (other.doubleValue() == 0 && !std::signbit(other.doubleValue())); if (isDouble() && other.isInteger()) - return other.int_32() ? (doubleValue() == double(other.int_32())) : (_val == 0); + return other.int_32() ? (doubleValue() == double(other.int_32())) + : (doubleValue() == 0 && !std::signbit(doubleValue())); return false; } - -int Primitive::toInt32(double number) -{ - const double D32 = 4294967296.0; - const double D31 = D32 / 2.0; - - if ((number >= -D31 && number < D31)) - return static_cast<int>(number); - - - if (!std::isfinite(number)) - return 0; - - double d = ::floor(::fabs(number)); - if (std::signbit(number)) - d = -d; - - number = ::fmod(d , D32); - - if (number < -D31) - number += D32; - else if (number >= D31) - number -= D32; - - return int(number); -} - -unsigned int Primitive::toUInt32(double number) -{ - const double D32 = 4294967296.0; - if ((number >= 0 && number < D32)) - return static_cast<uint>(number); - - if (!std::isfinite(number)) - return +0; - - double d = ::floor(::fabs(number)); - if (std::signbit(number)) - d = -d; - - number = ::fmod(d , D32); - - if (number < 0) - number += D32; - - return unsigned(number); -} - -double Primitive::toInteger(double number) -{ - if (std::isnan(number)) - return +0; - else if (! number || std::isinf(number)) - return number; - const double v = floor(fabs(number)); - return std::signbit(number) ? -v : v; -} - #ifndef V4_BOOTSTRAP -Heap::String *Value::toString(ExecutionEngine *e) const +Heap::String *Value::toString(ExecutionEngine *e, Value val) { - if (String *s = stringValue()) - return s->d(); - return RuntimeHelpers::convertToString(e, *this); + return RuntimeHelpers::convertToString(e, val); } -Heap::Object *Value::toObject(ExecutionEngine *e) const +Heap::Object *Value::toObject(ExecutionEngine *e, Value val) { - if (Object *o = objectValue()) - return o->d(); - return RuntimeHelpers::convertToObject(e, *this); + return RuntimeHelpers::convertToObject(e, val); } uint Value::asArrayLength(bool *ok) const |