- Clamp double values as doubles to get a free NaN check and
authoriposva@chromium.org <iposva@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 28 Jul 2009 18:11:12 +0000 (18:11 +0000)
committeriposva@chromium.org <iposva@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 28 Jul 2009 18:11:12 +0000 (18:11 +0000)
  to handle infinity properly.

Review URL: http://codereview.chromium.org/159518

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2564 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects.cc
test/cctest/test-api.cc

index 7467475..e4db9bd 100644 (file)
@@ -6985,28 +6985,32 @@ Object* JSObject::PrepareElementsForSort(uint32_t limit) {
 Object* PixelArray::SetValue(uint32_t index, Object* value) {
   uint8_t clamped_value = 0;
   if (index < static_cast<uint32_t>(length())) {
-    int int_value = 0;
     if (value->IsSmi()) {
-      int_value = Smi::cast(value)->value();
+      int int_value = Smi::cast(value)->value();
+      if (int_value < 0) {
+        clamped_value = 0;
+      } else if (int_value > 255) {
+        clamped_value = 255;
+      } else {
+        clamped_value = static_cast<uint8_t>(int_value);
+      }
     } else if (value->IsHeapNumber()) {
       double double_value = HeapNumber::cast(value)->value();
-      if (!isnan(double_value)) {
-        // NaN clamps to zero (default). Other doubles are rounded to
-        // the nearest integer.
-        int_value = static_cast<int>(double_value + 0.5);
+      if (!(double_value > 0)) {
+        // NaN and less than zero clamp to zero.
+        clamped_value = 0;
+      } else if (double_value > 255) {
+        // Greater than 255 clamp to 255.
+        clamped_value = 255;
+      } else {
+        // Other doubles are rounded to the nearest integer.
+        clamped_value = static_cast<uint8_t>(double_value + 0.5);
       }
     } else {
       // Clamp undefined to zero (default). All other types have been
       // converted to a number type further up in the call chain.
       ASSERT(value->IsUndefined());
     }
-    if (int_value < 0) {
-      clamped_value = 0;
-    } else if (int_value > 255) {
-      clamped_value = 255;
-    } else {
-      clamped_value = static_cast<uint8_t>(int_value);
-    }
     set(index, clamped_value);
   }
   return Smi::FromInt(clamped_value);
index b0d92f6..e3f52b4 100644 (file)
@@ -7651,6 +7651,20 @@ THREADED_TEST(PixelArray) {
   CHECK_EQ(0, result->Int32Value());
   CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(5))->value());
 
+  result = CompileRun("for (var i = 0; i < 8; i++) {"
+                      "  pixels[8] = Infinity;"
+                      "}"
+                      "pixels[8];");
+  CHECK_EQ(255, result->Int32Value());
+  CHECK_EQ(255, i::Smi::cast(jsobj->GetElement(8))->value());
+
+  result = CompileRun("for (var i = 0; i < 8; i++) {"
+                      "  pixels[9] = -Infinity;"
+                      "}"
+                      "pixels[9];");
+  CHECK_EQ(0, result->Int32Value());
+  CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(9))->value());
+
   result = CompileRun("pixels[3] = 33;"
                       "delete pixels[3];"
                       "pixels[3];");