| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <limits> | 6 #include <limits> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 4787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4798 DisallowHeapAllocation no_allocation; | 4798 DisallowHeapAllocation no_allocation; |
| 4799 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); | 4799 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); |
| 4800 Handle<Name> key = Handle<Name>::cast(key_obj); | 4800 Handle<Name> key = Handle<Name>::cast(key_obj); |
| 4801 if (receiver->HasFastProperties()) { | 4801 if (receiver->HasFastProperties()) { |
| 4802 // Attempt to use lookup cache. | 4802 // Attempt to use lookup cache. |
| 4803 Handle<Map> receiver_map(receiver->map(), isolate); | 4803 Handle<Map> receiver_map(receiver->map(), isolate); |
| 4804 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); | 4804 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
| 4805 int index = keyed_lookup_cache->Lookup(receiver_map, key); | 4805 int index = keyed_lookup_cache->Lookup(receiver_map, key); |
| 4806 if (index != -1) { | 4806 if (index != -1) { |
| 4807 // Doubles are not cached, so raw read the value. | 4807 // Doubles are not cached, so raw read the value. |
| 4808 Object* value = receiver->RawFastPropertyAt( | 4808 return receiver->RawFastPropertyAt( |
| 4809 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); | 4809 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); |
| 4810 return value->IsTheHole() | |
| 4811 ? isolate->heap()->undefined_value() | |
| 4812 : value; | |
| 4813 } | 4810 } |
| 4814 // Lookup cache miss. Perform lookup and update the cache if | 4811 // Lookup cache miss. Perform lookup and update the cache if |
| 4815 // appropriate. | 4812 // appropriate. |
| 4816 LookupResult result(isolate); | 4813 LookupResult result(isolate); |
| 4817 receiver->LookupOwn(key, &result); | 4814 receiver->LookupOwn(key, &result); |
| 4818 if (result.IsField()) { | 4815 if (result.IsField()) { |
| 4819 FieldIndex field_index = result.GetFieldIndex(); | 4816 FieldIndex field_index = result.GetFieldIndex(); |
| 4820 // Do not track double fields in the keyed lookup cache. Reading | 4817 // Do not track double fields in the keyed lookup cache. Reading |
| 4821 // double values requires boxing. | 4818 // double values requires boxing. |
| 4822 if (!result.representation().IsDouble()) { | 4819 if (!result.representation().IsDouble()) { |
| 4823 keyed_lookup_cache->Update(receiver_map, key, | 4820 keyed_lookup_cache->Update(receiver_map, key, |
| 4824 field_index.GetKeyedLookupCacheIndex()); | 4821 field_index.GetKeyedLookupCacheIndex()); |
| 4825 } | 4822 } |
| 4826 AllowHeapAllocation allow_allocation; | 4823 AllowHeapAllocation allow_allocation; |
| 4827 return *JSObject::FastPropertyAt(receiver, result.representation(), | 4824 return *JSObject::FastPropertyAt(receiver, result.representation(), |
| 4828 field_index); | 4825 field_index); |
| 4829 } | 4826 } |
| 4830 } else { | 4827 } else { |
| 4831 // Attempt dictionary lookup. | 4828 // Attempt dictionary lookup. |
| 4832 NameDictionary* dictionary = receiver->property_dictionary(); | 4829 NameDictionary* dictionary = receiver->property_dictionary(); |
| 4833 int entry = dictionary->FindEntry(key); | 4830 int entry = dictionary->FindEntry(key); |
| 4834 if ((entry != NameDictionary::kNotFound) && | 4831 if ((entry != NameDictionary::kNotFound) && |
| 4835 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 4832 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
| 4836 Object* value = dictionary->ValueAt(entry); | 4833 Object* value = dictionary->ValueAt(entry); |
| 4837 if (!receiver->IsGlobalObject()) return value; | 4834 if (!receiver->IsGlobalObject()) return value; |
| 4838 value = PropertyCell::cast(value)->value(); | 4835 value = PropertyCell::cast(value)->value(); |
| 4839 if (!value->IsTheHole()) return value; | 4836 if (!value->IsTheHole()) return value; |
| 4840 // If value is the hole do the general lookup. | 4837 // If value is the hole (meaning, absent) do the general lookup. |
| 4841 } | 4838 } |
| 4842 } | 4839 } |
| 4843 } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) { | 4840 } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) { |
| 4844 // JSObject without a name key. If the key is a Smi, check for a | 4841 // JSObject without a name key. If the key is a Smi, check for a |
| 4845 // definite out-of-bounds access to elements, which is a strong indicator | 4842 // definite out-of-bounds access to elements, which is a strong indicator |
| 4846 // that subsequent accesses will also call the runtime. Proactively | 4843 // that subsequent accesses will also call the runtime. Proactively |
| 4847 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of | 4844 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of |
| 4848 // doubles for those future calls in the case that the elements would | 4845 // doubles for those future calls in the case that the elements would |
| 4849 // become FAST_DOUBLE_ELEMENTS. | 4846 // become FAST_DOUBLE_ELEMENTS. |
| 4850 Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj); | 4847 Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj); |
| (...skipping 5783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10634 | 10631 |
| 10635 static Handle<Object> DebugLookupResultValue(Isolate* isolate, | 10632 static Handle<Object> DebugLookupResultValue(Isolate* isolate, |
| 10636 Handle<Object> receiver, | 10633 Handle<Object> receiver, |
| 10637 Handle<Name> name, | 10634 Handle<Name> name, |
| 10638 LookupResult* result, | 10635 LookupResult* result, |
| 10639 bool* has_caught = NULL) { | 10636 bool* has_caught = NULL) { |
| 10640 Handle<Object> value = isolate->factory()->undefined_value(); | 10637 Handle<Object> value = isolate->factory()->undefined_value(); |
| 10641 if (!result->IsFound()) return value; | 10638 if (!result->IsFound()) return value; |
| 10642 switch (result->type()) { | 10639 switch (result->type()) { |
| 10643 case NORMAL: | 10640 case NORMAL: |
| 10644 value = JSObject::GetNormalizedProperty( | 10641 return JSObject::GetNormalizedProperty(handle(result->holder(), isolate), |
| 10645 handle(result->holder(), isolate), result); | 10642 result); |
| 10646 break; | |
| 10647 case FIELD: | 10643 case FIELD: |
| 10648 value = JSObject::FastPropertyAt(handle(result->holder(), isolate), | 10644 return JSObject::FastPropertyAt(handle(result->holder(), isolate), |
| 10649 result->representation(), | 10645 result->representation(), |
| 10650 result->GetFieldIndex()); | 10646 result->GetFieldIndex()); |
| 10651 break; | |
| 10652 case CONSTANT: | 10647 case CONSTANT: |
| 10653 return handle(result->GetConstant(), isolate); | 10648 return handle(result->GetConstant(), isolate); |
| 10654 case CALLBACKS: { | 10649 case CALLBACKS: { |
| 10655 Handle<Object> structure(result->GetCallbackObject(), isolate); | 10650 Handle<Object> structure(result->GetCallbackObject(), isolate); |
| 10656 ASSERT(!structure->IsForeign()); | 10651 ASSERT(!structure->IsForeign()); |
| 10657 if (structure->IsAccessorInfo()) { | 10652 if (structure->IsAccessorInfo()) { |
| 10658 MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor( | 10653 MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor( |
| 10659 receiver, name, handle(result->holder(), isolate), structure); | 10654 receiver, name, handle(result->holder(), isolate), structure); |
| 10660 if (!obj.ToHandle(&value)) { | 10655 if (!obj.ToHandle(&value)) { |
| 10661 value = handle(isolate->pending_exception(), isolate); | 10656 value = handle(isolate->pending_exception(), isolate); |
| 10662 isolate->clear_pending_exception(); | 10657 isolate->clear_pending_exception(); |
| 10663 if (has_caught != NULL) *has_caught = true; | 10658 if (has_caught != NULL) *has_caught = true; |
| 10664 return value; | 10659 return value; |
| 10665 } | 10660 } |
| 10666 } | 10661 } |
| 10667 break; | 10662 break; |
| 10668 } | 10663 } |
| 10669 case INTERCEPTOR: | 10664 case INTERCEPTOR: |
| 10670 case HANDLER: | 10665 case HANDLER: |
| 10671 break; | 10666 break; |
| 10672 case NONEXISTENT: | 10667 case NONEXISTENT: |
| 10673 UNREACHABLE(); | 10668 UNREACHABLE(); |
| 10674 break; | 10669 break; |
| 10675 } | 10670 } |
| 10676 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 10671 return value; |
| 10677 return value->IsTheHole() | |
| 10678 ? Handle<Object>::cast(isolate->factory()->undefined_value()) : value; | |
| 10679 } | 10672 } |
| 10680 | 10673 |
| 10681 | 10674 |
| 10682 // Get debugger related details for an object property. | 10675 // Get debugger related details for an object property. |
| 10683 // args[0]: object holding property | 10676 // args[0]: object holding property |
| 10684 // args[1]: name of the property | 10677 // args[1]: name of the property |
| 10685 // | 10678 // |
| 10686 // The array returned contains the following information: | 10679 // The array returned contains the following information: |
| 10687 // 0: Property value | 10680 // 0: Property value |
| 10688 // 1: Property details | 10681 // 1: Property details |
| (...skipping 4267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14956 } | 14949 } |
| 14957 return NULL; | 14950 return NULL; |
| 14958 } | 14951 } |
| 14959 | 14952 |
| 14960 | 14953 |
| 14961 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 14954 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
| 14962 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 14955 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
| 14963 } | 14956 } |
| 14964 | 14957 |
| 14965 } } // namespace v8::internal | 14958 } } // namespace v8::internal |
| OLD | NEW |