18ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 28ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 38ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org// found in the LICENSE file. 48ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 58ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org#include "src/v8.h" 68ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 78ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org#include "src/bootstrapper.h" 87dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org#include "src/deoptimizer.h" 98ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org#include "src/lookup.h" 103e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/lookup-inl.h" 118ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 128ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgnamespace v8 { 138ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgnamespace internal { 148ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 158ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 168ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgvoid LookupIterator::Next() { 171af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK_NE(JSPROXY, state_); 181af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK_NE(TRANSITION, state_); 193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org DisallowHeapAllocation no_gc; 208ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org has_property_ = false; 213e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 22d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org JSReceiver* holder = *holder_; 233e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org Map* map = *holder_map_; 243e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 253e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // Perform lookup on current holder. 261af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org state_ = LookupInHolder(map, holder); 271af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (IsFound()) return; 283e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 293e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // Continue lookup if lookup on current holder failed. 301af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org do { 313e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org JSReceiver* maybe_holder = NextHolder(map); 323e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (maybe_holder == NULL) break; 333e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org holder = maybe_holder; 343e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org map = holder->map(); 351af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org state_ = LookupInHolder(map, holder); 361af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } while (!IsFound()); 373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org 38d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (holder != *holder_) { 39d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org holder_ = handle(holder, isolate_); 40d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org holder_map_ = handle(map, isolate_); 41d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org } 428ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 438ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 448ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 458ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgHandle<JSReceiver> LookupIterator::GetRoot() const { 46d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (receiver_->IsJSReceiver()) return Handle<JSReceiver>::cast(receiver_); 479bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Handle<Object> root = 48d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org handle(receiver_->GetRootMap(isolate_)->prototype(), isolate_); 499bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org CHECK(!root->IsNull()); 509bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return Handle<JSReceiver>::cast(root); 518ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 528ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 538ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 548ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgHandle<Map> LookupIterator::GetReceiverMap() const { 55d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (receiver_->IsNumber()) return isolate_->factory()->heap_number_map(); 56d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org return handle(Handle<HeapObject>::cast(receiver_)->map(), isolate_); 578ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 588ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 598ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 60a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<JSObject> LookupIterator::GetStoreTarget() const { 61d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (receiver_->IsJSGlobalProxy()) { 62d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org PrototypeIterator iter(isolate(), receiver_); 63d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (iter.IsAtEnd()) return Handle<JSGlobalProxy>::cast(receiver_); 64a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); 65a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 66d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org return Handle<JSObject>::cast(receiver_); 67a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 68a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 69a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 708ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgbool LookupIterator::IsBootstrapping() const { 718ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org return isolate_->bootstrapper()->IsActive(); 728ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 738ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 748ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 758ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgbool LookupIterator::HasAccess(v8::AccessType access_type) const { 76e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(ACCESS_CHECK, state_); 77f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type); 788ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 798ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 808ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 817dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.orgvoid LookupIterator::ReloadPropertyInformation() { 827dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org state_ = BEFORE_PROPERTY; 83d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org state_ = LookupInHolder(*holder_map_, *holder_); 841af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(IsFound() || holder_map_->is_dictionary_map()); 857dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org} 867dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 877dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 88474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgvoid LookupIterator::PrepareForDataProperty(Handle<Object> value) { 891af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(state_ == DATA || state_ == ACCESSOR); 90e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(HolderIsReceiverOrHiddenPrototype()); 911af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (holder_map_->is_dictionary_map()) return; 92e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org holder_map_ = 93e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); 94f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); 957dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org ReloadPropertyInformation(); 96474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org} 97474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 98474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid LookupIterator::ReconfigureDataProperty(Handle<Object> value, 1005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org PropertyAttributes attributes) { 1011af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(state_ == DATA || state_ == ACCESSOR); 1025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org DCHECK(HolderIsReceiverOrHiddenPrototype()); 1035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org Handle<JSObject> holder = GetHolder<JSObject>(); 1045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (holder_map_->is_dictionary_map()) { 1055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org PropertyDetails details(attributes, NORMAL, 0); 1065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org JSObject::SetNormalizedProperty(holder, name(), value, details); 1071af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } else { 1081af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(), 1091af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org attributes); 1101af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org JSObject::MigrateToMap(holder, holder_map_); 1115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org } 1125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 1137dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org ReloadPropertyInformation(); 1145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org} 1155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 1165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org 117a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid LookupIterator::PrepareTransitionToDataProperty( 118474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<Object> value, PropertyAttributes attributes, 119474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Object::StoreFromKeyed store_mode) { 120a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (state_ == TRANSITION) return; 1211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(state_ != LookupIterator::ACCESSOR || 1221af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org GetAccessors()->IsDeclaredAccessorInfo()); 1231af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype()); 124474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 125474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // Can only be called when the receiver is a JSObject. JSProxy has to be 126474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // handled via a trap. Adding properties to primitive values is not 127474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // observable. 128a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = GetStoreTarget(); 129474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 130a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (!name().is_identical_to(isolate()->factory()->hidden_string()) && 131a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org !receiver->map()->is_extensible()) { 132a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return; 133474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 134474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 135a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org transition_map_ = Map::TransitionToDataProperty( 1366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org handle(receiver->map(), isolate_), name_, value, attributes, store_mode); 137a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org state_ = TRANSITION; 138a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 139a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 140a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 141a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid LookupIterator::ApplyTransitionToDataProperty() { 142a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK_EQ(TRANSITION, state_); 143a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 144a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = GetStoreTarget(); 145d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org holder_ = receiver; 146a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org holder_map_ = transition_map_; 147474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org JSObject::MigrateToMap(receiver, holder_map_); 1487dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org ReloadPropertyInformation(); 1497dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org} 1507dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1517dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1527dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.orgvoid LookupIterator::TransitionToAccessorProperty( 1537dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org AccessorComponent component, Handle<Object> accessor, 1547dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org PropertyAttributes attributes) { 1557dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org DCHECK(!accessor->IsNull()); 1567dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org // Can only be called when the receiver is a JSObject. JSProxy has to be 1577dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org // handled via a trap. Adding properties to primitive values is not 1587dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org // observable. 159a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = GetStoreTarget(); 160d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org holder_ = receiver; 1616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org holder_map_ = 1626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Map::TransitionToAccessorProperty(handle(receiver->map(), isolate_), 1636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org name_, component, accessor, attributes); 1647dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org JSObject::MigrateToMap(receiver, holder_map_); 1657dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1667dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org ReloadPropertyInformation(); 1677dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1687dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org if (!holder_map_->is_dictionary_map()) return; 1697dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1707dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org // We have to deoptimize since accesses to data properties may have been 1717dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org // inlined without a corresponding map-check. 1727dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org if (holder_map_->IsGlobalObjectMap()) { 1737dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org Deoptimizer::DeoptimizeGlobalObject(*receiver); 1747dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org } 1757dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1767dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org // Install the accessor into the dictionary-mode object. 1777dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org PropertyDetails details(attributes, CALLBACKS, 0); 1787dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org Handle<AccessorPair> pair; 1791af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { 1807dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org pair = Handle<AccessorPair>::cast(GetAccessors()); 1817dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org // If the component and attributes are identical, nothing has to be done. 1827dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org if (pair->get(component) == *accessor) { 1837dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org if (property_details().attributes() == attributes) return; 1847dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org } else { 1857dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org pair = AccessorPair::Copy(pair); 1867dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org pair->set(component, *accessor); 1877dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org } 1887dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org } else { 1897dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org pair = isolate()->factory()->NewAccessorPair(); 1907dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org pair->set(component, *accessor); 1917dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org } 1927dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org JSObject::SetNormalizedProperty(receiver, name_, pair, details); 1937dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org 1947dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org JSObject::ReoptimizeIfPrototype(receiver); 1956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org holder_map_ = handle(receiver->map(), isolate_); 1967dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org ReloadPropertyInformation(); 197474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org} 198474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 199474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 200e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgbool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { 201e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); 2025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org // Optimization that only works if configuration_ is not mutable. 2036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (!check_prototype_chain()) return true; 204474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org DisallowHeapAllocation no_gc; 205d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (!receiver_->IsJSReceiver()) return false; 206d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org Object* current = *receiver_; 207d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org JSReceiver* holder = *holder_; 208474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // JSProxy do not occur as hidden prototypes. 209474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (current->IsJSProxy()) { 210474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org return JSReceiver::cast(current) == holder; 211474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 212474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org PrototypeIterator iter(isolate(), current, 213474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org PrototypeIterator::START_AT_RECEIVER); 214474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org do { 215474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (JSReceiver::cast(iter.GetCurrent()) == holder) return true; 216e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!current->IsJSProxy()); 217474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org iter.Advance(); 218474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); 219474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org return false; 220474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org} 221474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 222474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 2238ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgHandle<Object> LookupIterator::FetchValue() const { 2248ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org Object* result = NULL; 225f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org Handle<JSObject> holder = GetHolder<JSObject>(); 2261af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (holder_map_->is_dictionary_map()) { 2271af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org result = holder->property_dictionary()->ValueAt(number_); 2281af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (holder_map_->IsGlobalObjectMap()) { 2291af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org result = PropertyCell::cast(result)->value(); 2301af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 2311af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } else if (property_details_.type() == v8::internal::FIELD) { 2321af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); 2331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return JSObject::FastPropertyAt(holder, property_details_.representation(), 2341af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org field_index); 2351af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } else { 2361af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org result = holder_map_->instance_descriptors()->GetValue(number_); 2378ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org } 2388ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org return handle(result, isolate_); 2398ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 2408ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 2418ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 2429d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgint LookupIterator::GetConstantIndex() const { 2439d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK(has_property_); 2441af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(!holder_map_->is_dictionary_map()); 2459d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); 2469d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org return descriptor_number(); 2479d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org} 2489d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 2499d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgFieldIndex LookupIterator::GetFieldIndex() const { 2519d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK(has_property_); 2521af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(!holder_map_->is_dictionary_map()); 2539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK_EQ(v8::internal::FIELD, property_details_.type()); 254e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org int index = 2551af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org holder_map_->instance_descriptors()->GetFieldIndex(descriptor_number()); 256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org bool is_double = representation().IsDouble(); 2571af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return FieldIndex::ForPropertyIndex(*holder_map_, index, is_double); 258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org} 259e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 260e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 261a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<HeapType> LookupIterator::GetFieldType() const { 262a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(has_property_); 2631af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(!holder_map_->is_dictionary_map()); 264a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK_EQ(v8::internal::FIELD, property_details_.type()); 265a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return handle( 2661af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org holder_map_->instance_descriptors()->GetFieldType(descriptor_number()), 267a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate_); 268a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 269a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 270a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 271e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgHandle<PropertyCell> LookupIterator::GetPropertyCell() const { 272e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Handle<JSObject> holder = GetHolder<JSObject>(); 273e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 274e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Object* value = global->property_dictionary()->ValueAt(dictionary_entry()); 275e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return Handle<PropertyCell>(PropertyCell::cast(value)); 276e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org} 277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 2798ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgHandle<Object> LookupIterator::GetAccessors() const { 2801af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK_EQ(ACCESSOR, state_); 2818ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org return FetchValue(); 2828ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 2838ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 2848ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 2858ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.orgHandle<Object> LookupIterator::GetDataValue() const { 2861af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK_EQ(DATA, state_); 2878ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org Handle<Object> value = FetchValue(); 2888ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org return value; 2898ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} 2908ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 2918ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org 292474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgvoid LookupIterator::WriteDataValue(Handle<Object> value) { 2931af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK_EQ(DATA, state_); 294f2af15a6b44ea6276bdd609ee122babe52842a42machenbach@chromium.org Handle<JSObject> holder = GetHolder<JSObject>(); 2951af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (holder_map_->is_dictionary_map()) { 296474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org NameDictionary* property_dictionary = holder->property_dictionary(); 297474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (holder->IsGlobalObject()) { 298474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<PropertyCell> cell( 299e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry()))); 300474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org PropertyCell::SetValueInferType(cell, value); 301474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } else { 302e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org property_dictionary->ValueAtPut(dictionary_entry(), *value); 303474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 304474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } else if (property_details_.type() == v8::internal::FIELD) { 305e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org holder->WriteToField(descriptor_number(), *value); 306474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } else { 307e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); 308474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 309474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org} 310474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 311474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 312474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgvoid LookupIterator::InternalizeName() { 313474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (name_->IsUniqueName()) return; 314474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org name_ = factory()->InternalizeString(Handle<String>::cast(name_)); 315474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org} 3168ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org} } // namespace v8::internal 317