Revision: 3901
Author: [email protected]
Date: Thu Feb 18 07:10:35 2010
Log: Remove the LookupResult IsValid method because it is confusing.

Replaced IsValid by IsPropertyOrTransition and used IsProperty in most
of the places where IsValid was used before.  Most of the time when
inspecting a lookup result we really want to know if there is a real
property present.  Only for stores are we interested in transitions.

BUG=http://crbug.com/20104
TEST=cctest/test-api/NamedInterceptorMapTransitionRead
Review URL: http://codereview.chromium.org/647015
http://code.google.com/p/v8/source/detail?r=3901

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/arm/stub-cache-arm.cc
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/fast-codegen.cc
 /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/property.cc
 /branches/bleeding_edge/src/property.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/stub-cache.cc
 /branches/bleeding_edge/src/x64/stub-cache-x64.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/src/api.cc  Wed Feb 17 05:23:46 2010
+++ /branches/bleeding_edge/src/api.cc  Thu Feb 18 07:10:35 2010
@@ -2207,7 +2207,7 @@
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::LookupResult lookup;
   self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
-  if (lookup.IsValid()) {
+  if (lookup.IsProperty()) {
     PropertyAttributes attributes;
     i::Handle<i::Object> result(self_obj->GetProperty(*self_obj,
                                                       &lookup,
@@ -2226,7 +2226,7 @@
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::LookupResult lookup;
   self_obj->LookupRealNamedProperty(*key_obj, &lookup);
-  if (lookup.IsValid()) {
+  if (lookup.IsProperty()) {
     PropertyAttributes attributes;
     i::Handle<i::Object> result(self_obj->GetProperty(*self_obj,
                                                       &lookup,
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Mon Feb 15 05:20:49 2010 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu Feb 18 07:10:35 2010
@@ -579,7 +579,7 @@
       stub_compiler->CheckPrototypes(object, receiver, holder,
                                      scratch1, scratch2, name, miss);

-  if (lookup->IsValid() && lookup->IsCacheable()) {
+  if (lookup->IsProperty() && lookup->IsCacheable()) {
     compiler->CompileCacheable(masm,
                                stub_compiler,
                                receiver,
@@ -985,7 +985,7 @@

   // If we call a constant function when the interceptor returns
   // the no-result sentinel, generate code that optimizes this case.
-  if (lookup.IsValid() &&
+  if (lookup.IsProperty() &&
       lookup.IsCacheable() &&
       lookup.type() == CONSTANT_FUNCTION &&
       lookup.GetConstantFunction()->is_compiled() &&
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Wed Feb 17 02:54:49 2010
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Feb 18 07:10:35 2010
@@ -723,11 +723,11 @@
 #ifdef DEBUG
     LookupResult lookup;
     result->LocalLookup(Heap::callee_symbol(), &lookup);
-    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
+    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::arguments_callee_index);

     result->LocalLookup(Heap::length_symbol(), &lookup);
-    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
+    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::arguments_length_index);

ASSERT(result->map()->inobject_properties() > Heap::arguments_callee_index);
@@ -1352,7 +1352,7 @@
           LookupResult result;
           to->LocalLookup(descs->GetKey(i), &result);
           // If the property is already there we skip it
-          if (result.IsValid()) continue;
+          if (result.IsProperty()) continue;
           HandleScope inner;
           Handle<DescriptorArray> inst_descs =
               Handle<DescriptorArray>(to->map()->instance_descriptors());
@@ -1389,7 +1389,7 @@
         // If the property is already there we skip it.
         LookupResult result;
         to->LocalLookup(String::cast(raw_key), &result);
-        if (result.IsValid()) continue;
+        if (result.IsProperty()) continue;
         // Set the property.
         Handle<String> key = Handle<String>(String::cast(raw_key));
         Handle<Object> value = Handle<Object>(properties->ValueAt(i));
=======================================
--- /branches/bleeding_edge/src/fast-codegen.cc Fri Feb 12 02:16:30 2010
+++ /branches/bleeding_edge/src/fast-codegen.cc Thu Feb 18 07:10:35 2010
@@ -220,7 +220,7 @@
   if (info()->has_global_object()) {
     LookupResult lookup;
     info()->global_object()->Lookup(*expr->name(), &lookup);
-    if (!lookup.IsValid()) {
+    if (!lookup.IsProperty()) {
       BAILOUT("Non-existing global variable");
     }
     // We do not handle global variables with accessors or interceptors.
@@ -284,7 +284,7 @@
     Handle<String> name = Handle<String>::cast(key->handle());
     LookupResult lookup;
     receiver->Lookup(*name, &lookup);
-    if (!lookup.IsValid()) {
+    if (!lookup.IsProperty()) {
       BAILOUT("Assigned property not found at compile time");
     }
if (lookup.holder() != *receiver) BAILOUT("Non-own property assignment");
@@ -322,7 +322,7 @@
     Handle<String> name = Handle<String>::cast(key->handle());
     LookupResult lookup;
     receiver->Lookup(*name, &lookup);
-    if (!lookup.IsValid()) {
+    if (!lookup.IsProperty()) {
       BAILOUT("Referenced property not found at compile time");
     }
if (lookup.holder() != *receiver) BAILOUT("Non-own property reference");
@@ -586,7 +586,7 @@
   info()->global_object()->Lookup(*expr->name(), &lookup);
// We only support normal (non-accessor/interceptor) DontDelete properties
   // for now.
-  ASSERT(lookup.IsValid());
+  ASSERT(lookup.IsProperty());
   ASSERT_EQ(NORMAL, lookup.type());
   ASSERT(lookup.IsDontDelete());
   Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup));
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Feb 18 02:09:54 2010 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Feb 18 07:10:35 2010
@@ -323,7 +323,7 @@
       stub_compiler->CheckPrototypes(object, receiver, holder,
                                      scratch1, scratch2, name, miss);

-  if (lookup->IsValid() && lookup->IsCacheable()) {
+  if (lookup->IsProperty() && lookup->IsCacheable()) {
     compiler->CompileCacheable(masm,
                                stub_compiler,
                                receiver,
@@ -484,7 +484,7 @@
       is_simple_api_call_(false),
       expected_receiver_type_(NULL),
       api_call_info_(NULL) {
-    if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+    if (!lookup->IsProperty() || !lookup->IsCacheable()) return;

     // We only optimize constant function calls.
     if (lookup->type() != CONSTANT_FUNCTION) return;
=======================================
--- /branches/bleeding_edge/src/ic.cc   Tue Feb 16 04:14:23 2010
+++ /branches/bleeding_edge/src/ic.cc   Thu Feb 18 07:10:35 2010
@@ -330,10 +330,11 @@
   while (true) {
     object->Lookup(name, lookup);
     // Besides normal conditions (property not found or it's not
-    // an interceptor), bail out of lookup is not cacheable: we won't
+    // an interceptor), bail out if lookup is not cacheable: we won't
     // be able to IC it anyway and regular lookup should work fine.
-    if (lookup->IsNotFound() || lookup->type() != INTERCEPTOR ||
-        !lookup->IsCacheable()) {
+    if (!lookup->IsFound()
+        || (lookup->type() != INTERCEPTOR)
+        || !lookup->IsCacheable()) {
       return;
     }

@@ -343,7 +344,7 @@
     }

     holder->LocalLookupRealNamedProperty(name, lookup);
-    if (lookup->IsValid()) {
+    if (lookup->IsProperty()) {
       ASSERT(lookup->type() != INTERCEPTOR);
       return;
     }
@@ -422,7 +423,7 @@
   LookupResult lookup;
   LookupForRead(*object, *name, &lookup);

-  if (!lookup.IsValid()) {
+  if (!lookup.IsProperty()) {
     // If the object does not have the requested property, check which
     // exception we need to throw.
     if (IsContextual(object)) {
@@ -493,7 +494,7 @@
                           Handle<String> name) {
   ASSERT(lookup->IsLoaded());
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;

   // Compute the number of arguments.
   int argc = target()->arguments_count();
@@ -642,8 +643,8 @@
   LookupResult lookup;
   LookupForRead(*object, *name, &lookup);

-  // If lookup is invalid, check if we need to throw an exception.
-  if (!lookup.IsValid()) {
+  // If we did not find a property, check if we need to throw an exception.
+  if (!lookup.IsProperty()) {
     if (FLAG_strict || IsContextual(object)) {
       return ReferenceError("not_defined", name);
     }
@@ -653,7 +654,7 @@
   bool can_be_inlined =
       FLAG_use_ic &&
       state == PREMONOMORPHIC &&
-      lookup.IsValid() &&
+      lookup.IsProperty() &&
       lookup.IsLoaded() &&
       lookup.IsCacheable() &&
       lookup.holder() == *object &&
@@ -681,7 +682,7 @@
   }

   PropertyAttributes attr;
-  if (lookup.IsValid() && lookup.type() == INTERCEPTOR) {
+  if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
     // Get the property.
     Object* result = object->GetProperty(*object, &lookup, *name, &attr);
     if (result->IsFailure()) return result;
@@ -704,7 +705,7 @@
                           Handle<String> name) {
   ASSERT(lookup->IsLoaded());
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;

   // Loading properties from values is not common, so don't try to
   // deal with non-JS objects here.
@@ -857,8 +858,8 @@
     LookupResult lookup;
     LookupForRead(*object, *name, &lookup);

-    // If lookup is invalid, check if we need to throw an exception.
-    if (!lookup.IsValid()) {
+ // If we did not find a property, check if we need to throw an exception.
+    if (!lookup.IsProperty()) {
       if (FLAG_strict || IsContextual(object)) {
         return ReferenceError("not_defined", name);
       }
@@ -869,7 +870,7 @@
     }

     PropertyAttributes attr;
-    if (lookup.IsValid() && lookup.type() == INTERCEPTOR) {
+    if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
       // Get the property.
       Object* result = object->GetProperty(*object, &lookup, *name, &attr);
       if (result->IsFailure()) return result;
@@ -921,7 +922,7 @@
Handle<Object> object, Handle<String> name) {
   ASSERT(lookup->IsLoaded());
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;

   if (!object->IsJSObject()) return;
   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
@@ -994,7 +995,7 @@

 static bool StoreICableLookup(LookupResult* lookup) {
   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return false;
+ if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;

   // If the property is read-only, we leave the IC in its current
   // state.
@@ -1214,7 +1215,7 @@
   if (receiver->IsJSGlobalProxy()) return;

   // Bail out if we didn't find a result.
-  if (!lookup->IsValid() || !lookup->IsCacheable()) return;
+  if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;

   // If the property is read-only, we leave the IC in its current
   // state.
=======================================
--- /branches/bleeding_edge/src/objects.cc      Thu Feb 18 05:13:21 2010
+++ /branches/bleeding_edge/src/objects.cc      Thu Feb 18 07:10:35 2010
@@ -219,7 +219,7 @@
     LookupResult* result,
     String* name,
     PropertyAttributes* attributes) {
-  if (result->IsValid()) {
+  if (result->IsProperty()) {
     switch (result->type()) {
       case CALLBACKS: {
         // Only allow API accessors.
@@ -242,7 +242,7 @@
         // Search ALL_CAN_READ accessors in prototype chain.
         LookupResult r;
         result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyWithFailedAccessCheck(receiver,
                                                   &r,
                                                   name,
@@ -255,16 +255,15 @@
         // No access check in GetPropertyAttributeWithInterceptor.
         LookupResult r;
         result->holder()->LookupRealNamedProperty(name, &r);
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyWithFailedAccessCheck(receiver,
                                                   &r,
                                                   name,
                                                   attributes);
         }
       }
-      default: {
-        break;
-      }
+      default:
+        UNREACHABLE();
     }
   }

@@ -280,7 +279,7 @@
     LookupResult* result,
     String* name,
     bool continue_search) {
-  if (result->IsValid()) {
+  if (result->IsProperty()) {
     switch (result->type()) {
       case CALLBACKS: {
         // Only allow API accessors.
@@ -301,7 +300,7 @@
         // Search ALL_CAN_READ accessors in prototype chain.
         LookupResult r;
         result->holder()->LookupRealNamedPropertyInPrototypes(name, &r);
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyAttributeWithFailedAccessCheck(receiver,
                                                            &r,
                                                            name,
@@ -319,7 +318,7 @@
         } else {
           result->holder()->LocalLookupRealNamedProperty(name, &r);
         }
-        if (r.IsValid()) {
+        if (r.IsProperty()) {
           return GetPropertyAttributeWithFailedAccessCheck(receiver,
                                                            &r,
                                                            name,
@@ -328,9 +327,8 @@
         break;
       }

-      default: {
-        break;
-      }
+      default:
+        UNREACHABLE();
     }
   }

@@ -505,7 +503,7 @@
   // holder will always be the interceptor holder and the search may
   // only continue with a current object just after the interceptor
   // holder in the prototype chain.
-  Object* last = result->IsValid() ? result->holder() : Heap::null_value();
+ Object* last = result->IsProperty() ? result->holder() : Heap::null_value();
   for (Object* current = this; true; current = current->GetPrototype()) {
     if (current->IsAccessCheckNeeded()) {
       // Check if we're allowed to read from the current object. Note
@@ -1463,8 +1461,12 @@
   // Check local property, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
- if (result.IsValid()) return SetProperty(&result, name, value, attributes);
-  // Add real property.
+  if (result.IsFound()) {
+    // An existing property, a map transition or a null descriptor was
+    // found.  Use set property to handle all these cases.
+    return SetProperty(&result, name, value, attributes);
+  }
+  // Add a new real property.
   return AddProperty(name, value, attributes);
 }

@@ -1696,8 +1698,8 @@
        pt != Heap::null_value();
        pt = pt->GetPrototype()) {
     JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
-    if (result->IsValid()) {
-      if (!result->IsTransitionType() && result->IsReadOnly()) {
+    if (result->IsProperty()) {
+      if (result->IsReadOnly()) {
         result->NotFound();
         return;
       }
@@ -1758,7 +1760,11 @@

   if (HasFastProperties()) {
     LookupInDescriptor(name, result);
-    if (result->IsValid()) {
+    if (result->IsFound()) {
+      // A property, a map transition or a null descriptor was found.
+      // We return all of these result types because
+      // LocalLookupRealNamedProperty is used when setting properties
+      // where map transitions and null descriptors are handled.
       ASSERT(result->holder() == this && result->type() != NORMAL);
       // Disallow caching for uninitialized constants. These can only
       // occur as fields.
@@ -1808,16 +1814,7 @@
        pt != Heap::null_value();
        pt = JSObject::cast(pt)->GetPrototype()) {
     JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
-    if (result->IsValid()) {
-      switch (result->type()) {
-        case NORMAL:
-        case FIELD:
-        case CONSTANT_FUNCTION:
-        case CALLBACKS:
-          return;
-        default: break;
-      }
-    }
+    if (result->IsProperty() && (result->type() != INTERCEPTOR)) return;
   }
   result->NotFound();
 }
@@ -1903,14 +1900,15 @@
     // accessor that wants to handle the property.
     LookupResult accessor_result;
     LookupCallbackSetterInPrototypes(name, &accessor_result);
-    if (accessor_result.IsValid()) {
+    if (accessor_result.IsProperty()) {
       return SetPropertyWithCallback(accessor_result.GetCallbackObject(),
                                      name,
                                      value,
                                      accessor_result.holder());
     }
   }
-  if (result->IsNotFound()) {
+  if (!result->IsFound()) {
+    // Neither properties nor transitions found.
     return AddProperty(name, value, attributes);
   }
   if (!result->IsLoaded()) {
@@ -1972,15 +1970,12 @@
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
   AssertNoContextChange ncc;
-  // ADDED TO CLONE
-  LookupResult result_struct;
-  LocalLookup(name, &result_struct);
-  LookupResult* result = &result_struct;
-  // END ADDED TO CLONE
+  LookupResult result;
+  LocalLookup(name, &result);
   // Check access rights if needed.
   if (IsAccessCheckNeeded()
-    && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
-    return SetPropertyWithFailedAccessCheck(result, name, value);
+      && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
+    return SetPropertyWithFailedAccessCheck(&result, name, value);
   }

   if (IsJSGlobalProxy()) {
@@ -1994,33 +1989,34 @@
   }

   // Check for accessor in prototype chain removed here in clone.
-  if (result->IsNotFound()) {
+  if (!result.IsFound()) {
+    // Neither properties nor transitions found.
     return AddProperty(name, value, attributes);
   }
-  if (!result->IsLoaded()) {
-    return SetLazyProperty(result, name, value, attributes);
+  if (!result.IsLoaded()) {
+    return SetLazyProperty(&result, name, value, attributes);
   }
   PropertyDetails details = PropertyDetails(attributes, NORMAL);

   // Check of IsReadOnly removed from here in clone.
-  switch (result->type()) {
+  switch (result.type()) {
     case NORMAL:
       return SetNormalizedProperty(name, value, details);
     case FIELD:
-      return FastPropertyAtPut(result->GetFieldIndex(), value);
+      return FastPropertyAtPut(result.GetFieldIndex(), value);
     case MAP_TRANSITION:
-      if (attributes == result->GetAttributes()) {
+      if (attributes == result.GetAttributes()) {
         // Only use map transition if the attributes match.
-        return AddFastPropertyUsingMap(result->GetTransitionMap(),
+        return AddFastPropertyUsingMap(result.GetTransitionMap(),
                                        name,
                                        value);
       }
       return ConvertDescriptorToField(name, value, attributes);
     case CONSTANT_FUNCTION:
       // Only replace the function if necessary.
-      if (value == result->GetConstantFunction()) return value;
+      if (value == result.GetConstantFunction()) return value;
       // Preserve the attributes of this existing property.
-      attributes = result->GetAttributes();
+      attributes = result.GetAttributes();
       return ConvertDescriptorToField(name, value, attributes);
     case CALLBACKS:
     case INTERCEPTOR:
@@ -2136,7 +2132,7 @@
                                                      name,
                                                      continue_search);
   }
-  if (result->IsValid()) {
+  if (result->IsProperty()) {
     switch (result->type()) {
       case NORMAL:  // fall through
       case FIELD:
@@ -2146,13 +2142,8 @@
       case INTERCEPTOR:
         return result->holder()->
GetPropertyAttributeWithInterceptor(receiver, name, continue_search);
-      case MAP_TRANSITION:
-      case CONSTANT_TRANSITION:
-      case NULL_DESCRIPTOR:
-        return ABSENT;
       default:
         UNREACHABLE();
-        break;
     }
   }
   return ABSENT;
@@ -2325,7 +2316,7 @@
   // Check local property, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
-  if (!result.IsValid()) return Heap::true_value();
+  if (!result.IsProperty()) return Heap::true_value();

   // Normalize object if needed.
   Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
@@ -2509,7 +2500,7 @@
   } else {
     LookupResult result;
     LocalLookup(name, &result);
-    if (!result.IsValid()) return Heap::true_value();
+    if (!result.IsProperty()) return Heap::true_value();
     // Ignore attributes if forcing a deletion.
     if (result.IsDontDelete() && mode != FORCE_DELETION) {
       return Heap::false_value();
@@ -2744,7 +2735,7 @@
        current != Heap::null_value();
        current = JSObject::cast(current)->GetPrototype()) {
     JSObject::cast(current)->LocalLookup(name, result);
-    if (result->IsValid() && !result->IsTransitionType()) return;
+    if (result->IsProperty()) return;
   }
   result->NotFound();
 }
@@ -2756,7 +2747,7 @@
        current != Heap::null_value();
        current = JSObject::cast(current)->GetPrototype()) {
     JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
-    if (result->IsValid() && result->type() == CALLBACKS) return;
+    if (result->IsProperty() && result->type() == CALLBACKS) return;
   }
   result->NotFound();
 }
@@ -2786,7 +2777,7 @@
   // cause security problems.
   LookupResult callback_result;
   LookupCallback(name, &callback_result);
-  if (callback_result.IsValid()) {
+  if (callback_result.IsFound()) {
     Object* obj = callback_result.GetCallbackObject();
     if (obj->IsAccessorInfo() &&
         AccessorInfo::cast(obj)->prohibits_overwriting()) {
@@ -2837,7 +2828,7 @@
     // Lookup the name.
     LookupResult result;
     LocalLookup(name, &result);
-    if (result.IsValid()) {
+    if (result.IsProperty()) {
       if (result.IsReadOnly()) return Heap::undefined_value();
       if (result.type() == CALLBACKS) {
         Object* obj = result.GetCallbackObject();
@@ -2959,7 +2950,7 @@
          obj = JSObject::cast(obj)->GetPrototype()) {
       LookupResult result;
       JSObject::cast(obj)->LocalLookup(name, &result);
-      if (result.IsValid()) {
+      if (result.IsProperty()) {
         if (result.IsReadOnly()) return Heap::undefined_value();
         if (result.type() == CALLBACKS) {
           Object* obj = result.GetCallbackObject();
@@ -4851,7 +4842,7 @@
       LookupResult result;
       String* name = GetThisPropertyAssignmentName(i);
       js_object->LocalLookupRealNamedProperty(name, &result);
-      if (result.IsValid() && result.type() == CALLBACKS) {
+      if (result.IsProperty() && result.type() == CALLBACKS) {
         return false;
       }
     }
@@ -6252,7 +6243,9 @@
   // Check local property in holder, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
- if (result.IsValid()) return GetProperty(receiver, &result, name, attributes);
+  if (result.IsProperty()) {
+    return GetProperty(receiver, &result, name, attributes);
+  }
   // Continue searching via the prototype chain.
   Object* pt = GetPrototype();
   *attributes = ABSENT;
@@ -6268,8 +6261,10 @@
   // Check local property in holder, ignore interceptor.
   LookupResult result;
   LocalLookupRealNamedProperty(name, &result);
-  if (!result.IsValid()) return Heap::undefined_value();
-  return GetProperty(receiver, &result, name, attributes);
+  if (result.IsProperty()) {
+    return GetProperty(receiver, &result, name, attributes);
+  }
+  return Heap::undefined_value();
 }


@@ -6321,24 +6316,7 @@

   LookupResult result;
   LocalLookupRealNamedProperty(key, &result);
-  if (result.IsValid()) {
-    switch (result.type()) {
-      case NORMAL:    // fall through.
-      case FIELD:     // fall through.
-      case CALLBACKS:  // fall through.
-      case CONSTANT_FUNCTION:
-        return true;
-      case INTERCEPTOR:
-      case MAP_TRANSITION:
-      case CONSTANT_TRANSITION:
-      case NULL_DESCRIPTOR:
-        return false;
-      default:
-        UNREACHABLE();
-    }
-  }
-
-  return false;
+  return result.IsProperty() && (result.type() != INTERCEPTOR);
 }


@@ -6400,7 +6378,7 @@

   LookupResult result;
   LocalLookupRealNamedProperty(key, &result);
-  return result.IsValid() && (result.type() == CALLBACKS);
+  return result.IsProperty() && (result.type() == CALLBACKS);
 }


=======================================
--- /branches/bleeding_edge/src/property.cc     Fri Jul 10 12:25:18 2009
+++ /branches/bleeding_edge/src/property.cc     Thu Feb 18 07:10:35 2010
@@ -33,7 +33,7 @@

 #ifdef DEBUG
 void LookupResult::Print() {
-  if (!IsValid()) {
+  if (!IsFound()) {
     PrintF("Not Found\n");
     return;
   }
=======================================
--- /branches/bleeding_edge/src/property.h      Fri Jul 10 12:25:18 2009
+++ /branches/bleeding_edge/src/property.h      Thu Feb 18 07:10:35 2010
@@ -201,23 +201,17 @@
   }

   JSObject* holder() {
-    ASSERT(IsValid());
+    ASSERT(IsFound());
     return holder_;
   }

   PropertyType type() {
-    ASSERT(IsValid());
+    ASSERT(IsFound());
     return details_.type();
   }
-
-  bool IsTransitionType() {
-    PropertyType t = type();
-    if (t == MAP_TRANSITION || t == CONSTANT_TRANSITION) return true;
-    return false;
-  }

   PropertyAttributes GetAttributes() {
-    ASSERT(IsValid());
+    ASSERT(IsFound());
     return details_.attributes();
   }

@@ -229,14 +223,17 @@
   bool IsDontDelete() { return details_.IsDontDelete(); }
   bool IsDontEnum() { return details_.IsDontEnum(); }
   bool IsDeleted() { return details_.IsDeleted(); }
-
-  bool IsValid() { return  lookup_type_ != NOT_FOUND; }
-  bool IsNotFound() { return lookup_type_ == NOT_FOUND; }
-
-  // Tells whether the result is a property.
-  // Excluding transitions and the null descriptor.
+  bool IsFound() { return lookup_type_ != NOT_FOUND; }
+
+  // Is the result is a property excluding transitions and the null
+  // descriptor?
   bool IsProperty() {
-    return IsValid() && type() < FIRST_PHANTOM_PROPERTY_TYPE;
+    return IsFound() && (type() < FIRST_PHANTOM_PROPERTY_TYPE);
+  }
+
+  // Is the result a property or a transition?
+  bool IsPropertyOrTransition() {
+    return IsFound() && (type() != NULL_DESCRIPTOR);
   }

   bool IsCacheable() { return cacheable_; }
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Thu Feb 18 05:13:21 2010
+++ /branches/bleeding_edge/src/runtime.cc      Thu Feb 18 07:10:35 2010
@@ -2895,7 +2895,7 @@
   // If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
   // delete it to avoid running into trouble in DefineAccessor, which
   // handles this incorrectly if the property is readonly (does nothing)
-  if (result.IsValid() &&
+  if (result.IsProperty() &&
       (result.type() == FIELD || result.type() == NORMAL
        || result.type() == CONSTANT_FUNCTION)) {
     obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc   Mon Feb 15 05:20:49 2010
+++ /branches/bleeding_edge/src/stub-cache.cc   Thu Feb 18 07:10:35 2010
@@ -1069,12 +1069,14 @@
   }
   return GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
 }
+

 void StubCompiler::LookupPostInterceptor(JSObject* holder,
                                          String* name,
                                          LookupResult* lookup) {
   holder->LocalLookupRealNamedProperty(name, lookup);
-  if (lookup->IsNotFound()) {
+  if (!lookup->IsProperty()) {
+    lookup->NotFound();
     Object* proto = holder->GetPrototype();
     if (proto != Heap::null_value()) {
       proto->Lookup(name, lookup);
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Mon Feb 15 05:20:49 2010 +++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Thu Feb 18 07:10:35 2010
@@ -399,7 +399,7 @@
       stub_compiler->CheckPrototypes(object, receiver, holder,
                                      scratch1, scratch2, name, miss);

-  if (lookup->IsValid() && lookup->IsCacheable()) {
+  if (lookup->IsProperty() && lookup->IsCacheable()) {
     compiler->CompileCacheable(masm,
                                stub_compiler,
                                receiver,
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Thu Feb 18 01:41:47 2010
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Thu Feb 18 07:10:35 2010
@@ -2526,6 +2526,33 @@
     CHECK_EQ(result, v8_str("x"));
   }
 }
+
+
+static v8::Handle<Value> SetXOnPrototypeGetter(Local<String> property,
+                                               const AccessorInfo& info) {
+  // Set x on the prototype object and do not handle the get request.
+  v8::Handle<v8::Value> proto = info.Holder()->GetPrototype();
+ v8::Handle<v8::Object>::Cast(proto)->Set(v8_str("x"), v8::Integer::New(23));
+  return v8::Handle<Value>();
+}
+
+
+// This is a regression test for http://crbug.com/20104. Map
+// transitions should not interfere with post interceptor lookup.
+THREADED_TEST(NamedInterceptorMapTransitionRead) {
+  v8::HandleScope scope;
+ Local<v8::FunctionTemplate> function_template = v8::FunctionTemplate::New();
+  Local<v8::ObjectTemplate> instance_template
+      = function_template->InstanceTemplate();
+  instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter);
+  LocalContext context;
+  context->Global()->Set(v8_str("F"), function_template->GetFunction());
+  // Create an instance of F and introduce a map transition for x.
+  CompileRun("var o = new F(); o.x = 23;");
+ // Create an instance of F and invoke the getter. The result should be 23.
+  Local<Value> result = CompileRun("o = new F(); o.x");
+  CHECK_EQ(result->Int32Value(), 23);
+}


 static v8::Handle<Value> IndexedPropertyGetter(uint32_t index,

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to