| 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;
|
| }
|
|
|
|
|
|
|