| Index: src/lookup.cc
|
| diff --git a/src/lookup.cc b/src/lookup.cc
|
| index 19ae1f021db110b1beb2fea4e368d902020cc8be..e98e111e3ea9db77883822ad6d2ca258eb21cd56 100644
|
| --- a/src/lookup.cc
|
| +++ b/src/lookup.cc
|
| @@ -144,6 +144,78 @@ bool LookupIterator::HasProperty() {
|
| }
|
|
|
|
|
| +void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
|
| + ASSERT(has_property_);
|
| + ASSERT(HolderIsReceiver());
|
| + if (property_encoding_ == DICTIONARY) return;
|
| + holder_map_ = Map::PrepareForDataProperty(holder_map_, number_, value);
|
| + JSObject::MigrateToMap(GetHolder(), holder_map_);
|
| + // Reload property information.
|
| + if (holder_map_->is_dictionary_map()) {
|
| + property_encoding_ = DICTIONARY;
|
| + } else {
|
| + property_encoding_ = DESCRIPTOR;
|
| + }
|
| + CHECK(HasProperty());
|
| +}
|
| +
|
| +
|
| +void LookupIterator::TransitionToDataProperty(
|
| + Handle<Object> value, PropertyAttributes attributes,
|
| + Object::StoreFromKeyed store_mode) {
|
| + ASSERT(!has_property_ || !HolderIsReceiver());
|
| +
|
| + // Can only be called when the receiver is a JSObject. JSProxy has to be
|
| + // handled via a trap. Adding properties to primitive values is not
|
| + // observable.
|
| + Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
|
| +
|
| + // Properties have to be added to context extension objects through
|
| + // SetOwnPropertyIgnoreAttributes.
|
| + ASSERT(!receiver->IsJSContextExtensionObject());
|
| +
|
| + if (receiver->IsJSGlobalProxy()) {
|
| + PrototypeIterator iter(isolate(), receiver);
|
| + receiver =
|
| + Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
|
| + }
|
| +
|
| + maybe_holder_ = receiver;
|
| + holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_,
|
| + value, attributes, store_mode);
|
| + JSObject::MigrateToMap(receiver, holder_map_);
|
| +
|
| + // Reload the information.
|
| + state_ = NOT_FOUND;
|
| + configuration_ = CHECK_OWN_REAL;
|
| + state_ = LookupInHolder();
|
| + ASSERT(IsFound());
|
| + HasProperty();
|
| +}
|
| +
|
| +
|
| +bool LookupIterator::HolderIsReceiver() const {
|
| + ASSERT(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
|
| + DisallowHeapAllocation no_gc;
|
| + Handle<Object> receiver = GetReceiver();
|
| + if (!receiver->IsJSReceiver()) return false;
|
| + Object* current = *receiver;
|
| + JSReceiver* holder = *maybe_holder_.ToHandleChecked();
|
| + // JSProxy do not occur as hidden prototypes.
|
| + if (current->IsJSProxy()) {
|
| + return JSReceiver::cast(current) == holder;
|
| + }
|
| + PrototypeIterator iter(isolate(), current,
|
| + PrototypeIterator::START_AT_RECEIVER);
|
| + do {
|
| + if (JSReceiver::cast(iter.GetCurrent()) == holder) return true;
|
| + ASSERT(!current->IsJSProxy());
|
| + iter.Advance();
|
| + } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
|
| + return false;
|
| +}
|
| +
|
| +
|
| Handle<Object> LookupIterator::FetchValue() const {
|
| Object* result = NULL;
|
| switch (property_encoding_) {
|
| @@ -181,4 +253,29 @@ Handle<Object> LookupIterator::GetDataValue() const {
|
| }
|
|
|
|
|
| +void LookupIterator::WriteDataValue(Handle<Object> value) {
|
| + ASSERT(is_guaranteed_to_have_holder());
|
| + ASSERT(has_property_);
|
| + if (property_encoding_ == DICTIONARY) {
|
| + Handle<JSObject> holder = GetHolder();
|
| + NameDictionary* property_dictionary = holder->property_dictionary();
|
| + if (holder->IsGlobalObject()) {
|
| + Handle<PropertyCell> cell(
|
| + PropertyCell::cast(property_dictionary->ValueAt(number_)));
|
| + PropertyCell::SetValueInferType(cell, value);
|
| + } else {
|
| + property_dictionary->ValueAtPut(number_, *value);
|
| + }
|
| + } else if (property_details_.type() == v8::internal::FIELD) {
|
| + GetHolder()->WriteToField(number_, *value);
|
| + } else {
|
| + ASSERT_EQ(v8::internal::CONSTANT, property_details_.type());
|
| + }
|
| +}
|
| +
|
| +
|
| +void LookupIterator::InternalizeName() {
|
| + if (name_->IsUniqueName()) return;
|
| + name_ = factory()->InternalizeString(Handle<String>::cast(name_));
|
| +}
|
| } } // namespace v8::internal
|
|
|