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 |