| Index: src/objects.cc | 
| =================================================================== | 
| --- src/objects.cc	(revision 410) | 
| +++ src/objects.cc	(working copy) | 
| @@ -1569,51 +1569,94 @@ | 
|  | 
|  | 
| // Set a real local property, even if it is READ_ONLY.  If the property is not | 
| -// present, add it with attributes NONE.  This code is the same as in | 
| -// SetProperty, except for the check for IsReadOnly and the check for a | 
| -// callback setter. | 
| -Object* JSObject::IgnoreAttributesAndSetLocalProperty(String* name, | 
| -                                                      Object* value) { | 
| +// present, add it with attributes NONE.  This code is an exact clone of | 
| +// SetProperty, with the check for IsReadOnly and the check for a | 
| +// callback setter removed.  The two lines looking up the LookupResult | 
| +// result are also added.  If one of the functions is changed, the other | 
| +// should be. | 
| +Object* JSObject::IgnoreAttributesAndSetLocalProperty( | 
| +    String* name, | 
| +    Object* value, | 
| +    PropertyAttributes attributes) { | 
| // Make sure that the top context does not change when doing callbacks or | 
| // interceptor calls. | 
| AssertNoContextChange ncc; | 
| - | 
| -  LookupResult result; | 
| -  LocalLookup(name, &result); | 
| - | 
| +  // ADDED TO CLONE | 
| +  LookupResult result_struct; | 
| +  LocalLookup(name, &result_struct); | 
| +  LookupResult* result = &result_struct; | 
| +  // END ADDED TO CLONE | 
| // Check access rights if needed. | 
| -  if (IsAccessCheckNeeded() && | 
| -      !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 
| -    Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 
| -    return value; | 
| +  if (IsAccessCheckNeeded() | 
| +    && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 
| +    return SetPropertyWithFailedAccessCheck(result, name, value); | 
| } | 
| - | 
| -  if (result.IsValid()) { | 
| -    switch (result.type()) { | 
| -      case NORMAL: | 
| -        property_dictionary()->ValueAtPut(result.GetDictionaryEntry(), value); | 
| -        return value; | 
| -      case FIELD: | 
| -        properties()->set(result.GetFieldIndex(), value); | 
| -        return value; | 
| -      case MAP_TRANSITION: | 
| -        return AddFastPropertyUsingMap(result.GetTransitionMap(), name, value); | 
| -      case CONSTANT_FUNCTION: | 
| -        return ReplaceConstantFunctionProperty(name, value); | 
| -      case CALLBACKS: | 
| -        return SetPropertyWithCallback(result.GetCallbackObject(), name, value, | 
| -                                       result.holder()); | 
| -      case INTERCEPTOR: | 
| -        return SetPropertyWithInterceptor(name, value, NONE); | 
| -      case CONSTANT_TRANSITION: | 
| -      case NULL_DESCRIPTOR: | 
| -        UNREACHABLE(); | 
| -        break; | 
| +  /* | 
| +    REMOVED FROM CLONE | 
| +    if (result->IsNotFound() || !result->IsProperty()) { | 
| +    // We could not find a local property so let's check whether there is an | 
| +    // accessor that wants to handle the property. | 
| +    LookupResult accessor_result; | 
| +    LookupCallbackSetterInPrototypes(name, &accessor_result); | 
| +    if (accessor_result.IsValid()) { | 
| +      return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 
| +                                     name, | 
| +                                     value, | 
| +                                     accessor_result.holder()); | 
| } | 
| +    } | 
| +  */ | 
| +  if (result->IsNotFound()) { | 
| +    return AddProperty(name, value, attributes); | 
| } | 
| - | 
| -  // The property was not found | 
| -  return AddProperty(name, value, NONE); | 
| +  if (!result->IsLoaded()) { | 
| +    return SetLazyProperty(result, name, value, attributes); | 
| +  } | 
| +  /* | 
| +    REMOVED FROM CLONE | 
| +    if (result->IsReadOnly() && result->IsProperty()) return value; | 
| +  */ | 
| +  // This is a real property that is not read-only, or it is a | 
| +  // transition or null descriptor and there are no setters in the prototypes. | 
| +  switch (result->type()) { | 
| +    case NORMAL: | 
| +      property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 
| +      return value; | 
| +    case FIELD: | 
| +      properties()->set(result->GetFieldIndex(), value); | 
| +      return value; | 
| +    case MAP_TRANSITION: | 
| +      if (attributes == result->GetAttributes()) { | 
| +        // Only use map transition if the attributes match. | 
| +        return AddFastPropertyUsingMap(result->GetTransitionMap(), | 
| +                                       name, | 
| +                                       value); | 
| +      } else { | 
| +        return AddFastProperty(name, value, attributes); | 
| +      } | 
| +    case CONSTANT_FUNCTION: | 
| +      if (value == result->GetConstantFunction()) return value; | 
| +      // Only replace the function if necessary. | 
| +      return ReplaceConstantFunctionProperty(name, value); | 
| +    case CALLBACKS: | 
| +      return SetPropertyWithCallback(result->GetCallbackObject(), | 
| +                                     name, | 
| +                                     value, | 
| +                                     result->holder()); | 
| +    case INTERCEPTOR: | 
| +      return SetPropertyWithInterceptor(name, value, attributes); | 
| +    case CONSTANT_TRANSITION: | 
| +      // Replace with a MAP_TRANSITION to a new map with a FIELD, even | 
| +      // if the value is a function. | 
| +      // AddProperty has been extended to do this, in this case. | 
| +      return AddFastProperty(name, value, attributes); | 
| +    case NULL_DESCRIPTOR: | 
| +      UNREACHABLE(); | 
| +    default: | 
| +      UNREACHABLE(); | 
| +  } | 
| +  UNREACHABLE(); | 
| +  return value; | 
| } | 
|  | 
|  | 
|  |