Correctly handle negative 0
authorLars Knoll <lars.knoll@digia.com>
Wed, 12 Dec 2012 19:34:31 +0000 (20:34 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Wed, 12 Dec 2012 10:49:14 +0000 (11:49 +0100)
-0 and +0 are two distinct numbers. Since integers only
have one 0 value, we need to convert the number to double
when negating a 0

Change-Id: I915c4bd7168eece947fa91c6b65137a873d4f75a
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qmljs_runtime.h
qv4isel_masm.cpp
qv4isel_util_p.h

index 1021d4e..2de6f19 100644 (file)
@@ -457,7 +457,8 @@ inline Value __qmljs_uminus(Value value, ExecutionContext *ctx)
 {
     TRACE1(value);
 
-    if (value.isInteger())
+    // +0 != -0, so we need to convert to double when negating 0
+    if (value.isInteger() && value.integerValue())
         return Value::fromInt32(-value.integerValue());
     double n = __qmljs_to_number(value, ctx);
     return Value::fromDouble(-n);
index d107a6b..b3d7b78 100644 (file)
@@ -634,30 +634,7 @@ void InstructionSelection::visitMove(IR::Move *s)
                 return;
             } else if (IR::Const *c = s->source->asConst()) {
                 Address dest = _asm->loadTempAddress(Assembler::ScratchRegister, t);
-                Value v;
-                switch (c->type) {
-                case IR::NullType:
-                    v = Value::nullValue();
-                    break;
-                case IR::UndefinedType:
-                    v = Value::undefinedValue();
-                    break;
-                case IR::BoolType:
-                    v = Value::fromBoolean(c->value != 0);
-                    break;
-                case IR::NumberType: {
-                    int ival = (int)c->value;
-                    if (ival == c->value) {
-                        v = Value::fromInt32(ival);
-                    } else {
-                        v = Value::fromDouble(c->value);
-                    }
-                }
-                    break;
-                default:
-                    Q_UNIMPLEMENTED();
-                    assert(!"TODO");
-                }
+                Value v = convertToValue(c);
                 _asm->storeValue(v, dest);
                 return;
             } else if (IR::Temp *t2 = s->source->asTemp()) {
index ff6cc21..693af03 100644 (file)
@@ -46,7 +46,8 @@ inline VM::Value convertToValue(IR::Const *c)
         return VM::Value::fromBoolean(c->value != 0);
     case IR::NumberType: {
         int ival = (int)c->value;
-        if (ival == c->value) {
+        // +0 != -0, so we need to convert to double when negating 0
+        if (ival == c->value && c->value != -0) {
             return VM::Value::fromInt32(ival);
         } else {
             return VM::Value::fromDouble(c->value);