Avoid bool to Oddball conversions by being lazy.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Mar 2013 16:22:19 +0000 (16:22 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Mar 2013 16:22:19 +0000 (16:22 +0000)
R=svenpanne@chromium.org
BUG=v8:2491

Review URL: https://chromiumcodereview.appspot.com/12459011

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

src/api.cc
src/ast.h
src/execution.cc
src/execution.h
src/isolate.cc
src/objects.cc
src/objects.h
src/parser.cc
src/runtime.cc

index 4d91e8f..4ec3936 100644 (file)
@@ -2583,7 +2583,8 @@ Local<Boolean> Value::ToBoolean() const {
     }
     LOG_API(isolate, "ToBoolean");
     ENTER_V8(isolate);
-    i::Handle<i::Object> val = i::Execution::ToBoolean(isolate, obj);
+    i::Handle<i::Object> val =
+        isolate->factory()->ToBoolean(obj->BooleanValue());
     return Local<Boolean>(ToApi<Boolean>(val));
   }
 }
@@ -2739,17 +2740,7 @@ void v8::RegExp::CheckCast(v8::Value* that) {
 
 
 bool Value::BooleanValue() const {
-  i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  if (obj->IsBoolean()) {
-    return obj->IsTrue();
-  } else {
-    i::Isolate* isolate = i::Isolate::Current();
-    if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
-    LOG_API(isolate, "BooleanValue");
-    ENTER_V8(isolate);
-    i::Handle<i::Object> value = i::Execution::ToBoolean(isolate, obj);
-    return value->IsTrue();
-  }
+  return Utils::OpenHandle(this)->BooleanValue();
 }
 
 
index 66b4dd4..05f0653 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1183,8 +1183,8 @@ class Literal: public Expression {
     return Handle<String>::cast(handle_);
   }
 
-  virtual bool ToBooleanIsTrue() { return handle_->ToBoolean()->IsTrue(); }
-  virtual bool ToBooleanIsFalse() { return handle_->ToBoolean()->IsFalse(); }
+  virtual bool ToBooleanIsTrue() { return handle_->BooleanValue(); }
+  virtual bool ToBooleanIsFalse() { return !handle_->BooleanValue(); }
 
   // Identity testers.
   bool IsNull() const {
index 705faa5..1012911 100644 (file)
@@ -601,22 +601,6 @@ void StackGuard::InitThread(const ExecutionAccess& lock) {
   } while (false)
 
 
-Handle<Object> Execution::ToBoolean(Isolate* isolate, Handle<Object> obj) {
-  // See the similar code in runtime.js:ToBoolean.
-  if (obj->IsBoolean()) return obj;
-  bool result = true;
-  if (obj->IsString()) {
-    result = Handle<String>::cast(obj)->length() != 0;
-  } else if (obj->IsNull() || obj->IsUndefined()) {
-    result = false;
-  } else if (obj->IsNumber()) {
-    double value = obj->Number();
-    result = !((value == 0) || isnan(value));
-  }
-  return Handle<Object>(isolate->heap()->ToBoolean(result), isolate);
-}
-
-
 Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) {
   RETURN_NATIVE_CALL(to_number, { obj }, exc);
 }
index 9e70fc1..7ce5b8c 100644 (file)
@@ -91,9 +91,6 @@ class Execution : public AllStatic {
                                 Handle<Object> argv[],
                                 bool* caught_exception);
 
-  // ECMA-262 9.2
-  static Handle<Object> ToBoolean(Isolate* isolate, Handle<Object> obj);
-
   // ECMA-262 9.3
   static Handle<Object> ToNumber(Handle<Object> obj, bool* exc);
 
index 5e61761..f56f99b 100644 (file)
@@ -754,7 +754,7 @@ Handle<JSArray> Isolate::CaptureCurrentStackTrace(
 
       if (options & StackTrace::kFunctionName) {
         Handle<Object> fun_name(fun->shared()->name(), this);
-        if (fun_name->ToBoolean()->IsFalse()) {
+        if (!fun_name->BooleanValue()) {
           fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
         }
         CHECK_NOT_EMPTY_HANDLE(this,
index a33f6e5..fe36002 100644 (file)
@@ -105,28 +105,14 @@ MaybeObject* Object::ToObject() {
 }
 
 
-Object* Object::ToBoolean() {
-  if (IsTrue()) return this;
-  if (IsFalse()) return this;
-  if (IsSmi()) {
-    return Isolate::Current()->heap()->ToBoolean(Smi::cast(this)->value() != 0);
-  }
-  HeapObject* heap_object = HeapObject::cast(this);
-  if (heap_object->IsUndefined() || heap_object->IsNull()) {
-    return heap_object->GetHeap()->false_value();
-  }
-  // Undetectable object is false
-  if (heap_object->IsUndetectableObject()) {
-    return heap_object->GetHeap()->false_value();
-  }
-  if (heap_object->IsString()) {
-    return heap_object->GetHeap()->ToBoolean(
-        String::cast(this)->length() != 0);
-  }
-  if (heap_object->IsHeapNumber()) {
-    return HeapNumber::cast(this)->HeapNumberToBoolean();
-  }
-  return heap_object->GetHeap()->true_value();
+bool Object::BooleanValue() {
+  if (IsBoolean()) return IsTrue();
+  if (IsSmi()) return Smi::cast(this)->value() != 0;
+  if (IsUndefined() || IsNull()) return false;
+  if (IsUndetectableObject()) return false;   // Undetectable object is false.
+  if (IsString()) return String::cast(this)->length() != 0;
+  if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue();
+  return true;
 }
 
 
@@ -1627,7 +1613,7 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
 }
 
 
-Object* HeapNumber::HeapNumberToBoolean() {
+bool HeapNumber::HeapNumberBooleanValue() {
   // NaN, +0, and -0 should return the false object
 #if __BYTE_ORDER == __LITTLE_ENDIAN
   union IeeeDoubleLittleEndianArchType u;
@@ -1637,15 +1623,13 @@ Object* HeapNumber::HeapNumberToBoolean() {
   u.d = value();
   if (u.bits.exp == 2047) {
     // Detect NaN for IEEE double precision floating point.
-    if ((u.bits.man_low | u.bits.man_high) != 0)
-      return GetHeap()->false_value();
+    if ((u.bits.man_low | u.bits.man_high) != 0) return false;
   }
   if (u.bits.exp == 0) {
     // Detect +0, and -0 for IEEE double precision floating point.
-    if ((u.bits.man_low | u.bits.man_high) == 0)
-      return GetHeap()->false_value();
+    if ((u.bits.man_low | u.bits.man_high) == 0) return false;
   }
-  return GetHeap()->true_value();
+  return true;
 }
 
 
@@ -2778,7 +2762,7 @@ bool JSProxy::HasPropertyWithHandler(Name* name_raw) {
     "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
   if (isolate->has_pending_exception()) return false;
 
-  return result->ToBoolean()->IsTrue();
+  return result->BooleanValue();
 }
 
 
@@ -2910,8 +2894,8 @@ MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
     "delete", Handle<Object>(), ARRAY_SIZE(args), args);
   if (isolate->has_pending_exception()) return Failure::Exception();
 
-  Object* bool_result = result->ToBoolean();
-  if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) {
+  bool result_bool = result->BooleanValue();
+  if (mode == STRICT_DELETION && !result_bool) {
     Handle<Object> handler(receiver->handler(), isolate);
     Handle<String> trap_name = isolate->factory()->InternalizeOneByteString(
         STATIC_ASCII_VECTOR("delete"));
@@ -2921,7 +2905,7 @@ MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
     isolate->Throw(*error);
     return Failure::Exception();
   }
-  return bool_result;
+  return isolate->heap()->ToBoolean(result_bool);
 }
 
 
@@ -2984,9 +2968,9 @@ MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
   }
 
   int attributes = NONE;
-  if (enumerable->ToBoolean()->IsFalse()) attributes |= DONT_ENUM;
-  if (configurable->ToBoolean()->IsFalse()) attributes |= DONT_DELETE;
-  if (writable->ToBoolean()->IsFalse()) attributes |= READ_ONLY;
+  if (!enumerable->BooleanValue()) attributes |= DONT_ENUM;
+  if (!configurable->BooleanValue()) attributes |= DONT_DELETE;
+  if (!writable->BooleanValue()) attributes |= READ_ONLY;
   return static_cast<PropertyAttributes>(attributes);
 }
 
index 59cddc2..a1b07f0 100644 (file)
@@ -1055,7 +1055,7 @@ class Object : public MaybeObject {
   inline bool HasSpecificClassOf(String* name);
 
   MUST_USE_RESULT MaybeObject* ToObject();             // ECMA-262 9.9.
-  Object* ToBoolean();                                 // ECMA-262 9.2.
+  bool BooleanValue();                                 // ECMA-262 9.2.
 
   // Convert to a JSObject if needed.
   // native_context is used when creating wrapper object.
@@ -1465,7 +1465,8 @@ class HeapNumber: public HeapObject {
   static inline HeapNumber* cast(Object* obj);
 
   // Dispatched behavior.
-  Object* HeapNumberToBoolean();
+  bool HeapNumberBooleanValue();
+
   inline void HeapNumberPrint() {
     HeapNumberPrint(stdout);
   }
index 2b2cf65..17d5a46 100644 (file)
@@ -3222,7 +3222,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
       Handle<Object> literal = expression->AsLiteral()->handle();
       if (op == Token::NOT) {
         // Convert the literal to a boolean condition and negate it.
-        bool condition = literal->ToBoolean()->IsTrue();
+        bool condition = literal->BooleanValue();
         Handle<Object> result(isolate()->heap()->ToBoolean(!condition),
                               isolate());
         return factory()->NewLiteral(result);
index f88651a..59a25db 100644 (file)
@@ -4977,7 +4977,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ToBool) {
   NoHandleAllocation ha(isolate);
   ASSERT(args.length() == 1);
 
-  return args[0]->ToBoolean();
+  return isolate->heap()->ToBoolean(args[0]->BooleanValue());
 }