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 2535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2546 JSReceiver::SetProperty(global, name, value, attributes, SLOPPY)); | 2546 JSReceiver::SetProperty(global, name, value, attributes, SLOPPY)); |
2547 return *value; | 2547 return *value; |
2548 } | 2548 } |
2549 | 2549 |
2550 // Set the value, but only if we're assigning the initial value to a | 2550 // Set the value, but only if we're assigning the initial value to a |
2551 // constant. For now, we determine this by checking if the | 2551 // constant. For now, we determine this by checking if the |
2552 // current value is the hole. | 2552 // current value is the hole. |
2553 // Strict mode handling not needed (const is disallowed in strict mode). | 2553 // Strict mode handling not needed (const is disallowed in strict mode). |
2554 if (lookup.IsField()) { | 2554 if (lookup.IsField()) { |
2555 FixedArray* properties = global->properties(); | 2555 FixedArray* properties = global->properties(); |
2556 int index = lookup.GetFieldIndex().field_index(); | 2556 int index = lookup.GetFieldIndex().property_index(); |
2557 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) { | 2557 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) { |
2558 properties->set(index, *value); | 2558 properties->set(index, *value); |
2559 } | 2559 } |
2560 } else if (lookup.IsNormal()) { | 2560 } else if (lookup.IsNormal()) { |
2561 if (global->GetNormalizedProperty(&lookup)->IsTheHole() || | 2561 if (global->GetNormalizedProperty(&lookup)->IsTheHole() || |
2562 !lookup.IsReadOnly()) { | 2562 !lookup.IsReadOnly()) { |
2563 HandleScope scope(isolate); | 2563 HandleScope scope(isolate); |
2564 JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value); | 2564 JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value); |
2565 } | 2565 } |
2566 } else { | 2566 } else { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2635 // This is the property that was introduced by the const declaration. | 2635 // This is the property that was introduced by the const declaration. |
2636 // Set it if it hasn't been set before. NOTE: We cannot use | 2636 // Set it if it hasn't been set before. NOTE: We cannot use |
2637 // GetProperty() to get the current value as it 'unholes' the value. | 2637 // GetProperty() to get the current value as it 'unholes' the value. |
2638 LookupResult lookup(isolate); | 2638 LookupResult lookup(isolate); |
2639 object->LookupOwnRealNamedProperty(name, &lookup); | 2639 object->LookupOwnRealNamedProperty(name, &lookup); |
2640 ASSERT(lookup.IsFound()); // the property was declared | 2640 ASSERT(lookup.IsFound()); // the property was declared |
2641 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only | 2641 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only |
2642 | 2642 |
2643 if (lookup.IsField()) { | 2643 if (lookup.IsField()) { |
2644 FixedArray* properties = object->properties(); | 2644 FixedArray* properties = object->properties(); |
2645 int index = lookup.GetFieldIndex().field_index(); | 2645 FieldIndex index = lookup.GetFieldIndex(); |
2646 if (properties->get(index)->IsTheHole()) { | 2646 ASSERT(!index.is_inobject()); |
2647 properties->set(index, *value); | 2647 if (properties->get(index.property_index())->IsTheHole()) { |
| 2648 properties->set(index.property_index(), *value); |
2648 } | 2649 } |
2649 } else if (lookup.IsNormal()) { | 2650 } else if (lookup.IsNormal()) { |
2650 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { | 2651 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { |
2651 JSObject::SetNormalizedProperty(object, &lookup, value); | 2652 JSObject::SetNormalizedProperty(object, &lookup, value); |
2652 } | 2653 } |
2653 } else { | 2654 } else { |
2654 // We should not reach here. Any real, named property should be | 2655 // We should not reach here. Any real, named property should be |
2655 // either a field or a dictionary slot. | 2656 // either a field or a dictionary slot. |
2656 UNREACHABLE(); | 2657 UNREACHABLE(); |
2657 } | 2658 } |
(...skipping 2386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5044 if (!receiver_obj->IsJSGlobalProxy() && | 5045 if (!receiver_obj->IsJSGlobalProxy() && |
5045 !receiver_obj->IsAccessCheckNeeded() && | 5046 !receiver_obj->IsAccessCheckNeeded() && |
5046 key_obj->IsName()) { | 5047 key_obj->IsName()) { |
5047 DisallowHeapAllocation no_allocation; | 5048 DisallowHeapAllocation no_allocation; |
5048 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); | 5049 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); |
5049 Handle<Name> key = Handle<Name>::cast(key_obj); | 5050 Handle<Name> key = Handle<Name>::cast(key_obj); |
5050 if (receiver->HasFastProperties()) { | 5051 if (receiver->HasFastProperties()) { |
5051 // Attempt to use lookup cache. | 5052 // Attempt to use lookup cache. |
5052 Handle<Map> receiver_map(receiver->map(), isolate); | 5053 Handle<Map> receiver_map(receiver->map(), isolate); |
5053 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); | 5054 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
5054 int offset = keyed_lookup_cache->Lookup(receiver_map, key); | 5055 int index = keyed_lookup_cache->Lookup(receiver_map, key); |
5055 if (offset != -1) { | 5056 if (index != -1) { |
5056 // Doubles are not cached, so raw read the value. | 5057 // Doubles are not cached, so raw read the value. |
5057 Object* value = receiver->RawFastPropertyAt(offset); | 5058 Object* value = receiver->RawFastPropertyAt( |
| 5059 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); |
5058 return value->IsTheHole() | 5060 return value->IsTheHole() |
5059 ? isolate->heap()->undefined_value() | 5061 ? isolate->heap()->undefined_value() |
5060 : value; | 5062 : value; |
5061 } | 5063 } |
5062 // Lookup cache miss. Perform lookup and update the cache if | 5064 // Lookup cache miss. Perform lookup and update the cache if |
5063 // appropriate. | 5065 // appropriate. |
5064 LookupResult result(isolate); | 5066 LookupResult result(isolate); |
5065 receiver->LookupOwn(key, &result); | 5067 receiver->LookupOwn(key, &result); |
5066 if (result.IsField()) { | 5068 if (result.IsField()) { |
5067 int offset = result.GetFieldIndex().field_index(); | 5069 FieldIndex field_index = result.GetFieldIndex(); |
5068 // Do not track double fields in the keyed lookup cache. Reading | 5070 // Do not track double fields in the keyed lookup cache. Reading |
5069 // double values requires boxing. | 5071 // double values requires boxing. |
5070 if (!result.representation().IsDouble()) { | 5072 if (!result.representation().IsDouble()) { |
5071 keyed_lookup_cache->Update(receiver_map, key, offset); | 5073 keyed_lookup_cache->Update(receiver_map, key, |
| 5074 field_index.GetKeyedLookupCacheIndex()); |
5072 } | 5075 } |
5073 AllowHeapAllocation allow_allocation; | 5076 AllowHeapAllocation allow_allocation; |
5074 return *JSObject::FastPropertyAt( | 5077 return *JSObject::FastPropertyAt(receiver, result.representation(), |
5075 receiver, result.representation(), offset); | 5078 field_index); |
5076 } | 5079 } |
5077 } else { | 5080 } else { |
5078 // Attempt dictionary lookup. | 5081 // Attempt dictionary lookup. |
5079 NameDictionary* dictionary = receiver->property_dictionary(); | 5082 NameDictionary* dictionary = receiver->property_dictionary(); |
5080 int entry = dictionary->FindEntry(key); | 5083 int entry = dictionary->FindEntry(key); |
5081 if ((entry != NameDictionary::kNotFound) && | 5084 if ((entry != NameDictionary::kNotFound) && |
5082 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 5085 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
5083 Object* value = dictionary->ValueAt(entry); | 5086 Object* value = dictionary->ValueAt(entry); |
5084 if (!receiver->IsGlobalObject()) return value; | 5087 if (!receiver->IsGlobalObject()) return value; |
5085 value = PropertyCell::cast(value)->value(); | 5088 value = PropertyCell::cast(value)->value(); |
(...skipping 5681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10767 Handle<Object> value = isolate->factory()->undefined_value(); | 10770 Handle<Object> value = isolate->factory()->undefined_value(); |
10768 if (!result->IsFound()) return value; | 10771 if (!result->IsFound()) return value; |
10769 switch (result->type()) { | 10772 switch (result->type()) { |
10770 case NORMAL: | 10773 case NORMAL: |
10771 value = JSObject::GetNormalizedProperty( | 10774 value = JSObject::GetNormalizedProperty( |
10772 handle(result->holder(), isolate), result); | 10775 handle(result->holder(), isolate), result); |
10773 break; | 10776 break; |
10774 case FIELD: | 10777 case FIELD: |
10775 value = JSObject::FastPropertyAt(handle(result->holder(), isolate), | 10778 value = JSObject::FastPropertyAt(handle(result->holder(), isolate), |
10776 result->representation(), | 10779 result->representation(), |
10777 result->GetFieldIndex().field_index()); | 10780 result->GetFieldIndex()); |
10778 break; | 10781 break; |
10779 case CONSTANT: | 10782 case CONSTANT: |
10780 return handle(result->GetConstant(), isolate); | 10783 return handle(result->GetConstant(), isolate); |
10781 case CALLBACKS: { | 10784 case CALLBACKS: { |
10782 Handle<Object> structure(result->GetCallbackObject(), isolate); | 10785 Handle<Object> structure(result->GetCallbackObject(), isolate); |
10783 ASSERT(!structure->IsForeign()); | 10786 ASSERT(!structure->IsForeign()); |
10784 if (structure->IsAccessorInfo()) { | 10787 if (structure->IsAccessorInfo()) { |
10785 MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback( | 10788 MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback( |
10786 receiver, name, handle(result->holder(), isolate), structure); | 10789 receiver, name, handle(result->holder(), isolate), structure); |
10787 if (!obj.ToHandle(&value)) { | 10790 if (!obj.ToHandle(&value)) { |
(...skipping 3748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14536 isolate->heap()->NotifyContextDisposed(); | 14539 isolate->heap()->NotifyContextDisposed(); |
14537 return isolate->heap()->undefined_value(); | 14540 return isolate->heap()->undefined_value(); |
14538 } | 14541 } |
14539 | 14542 |
14540 | 14543 |
14541 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { | 14544 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { |
14542 HandleScope scope(isolate); | 14545 HandleScope scope(isolate); |
14543 ASSERT(args.length() == 2); | 14546 ASSERT(args.length() == 2); |
14544 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 14547 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
14545 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1); | 14548 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1); |
14546 int idx = index->value() >> 1; | 14549 RUNTIME_ASSERT((index->value() & 1) == 1); |
14547 int inobject_properties = object->map()->inobject_properties(); | 14550 FieldIndex field_index = |
14548 if (idx < 0) { | 14551 FieldIndex::ForLoadByFieldIndex(object->map(), index->value() >> 1); |
14549 idx = -idx + inobject_properties - 1; | 14552 int max_idx = field_index.is_inobject() |
14550 } | 14553 ? object->map()->inobject_properties() |
14551 int max_idx = object->properties()->length() + inobject_properties; | 14554 : object->properties()->length(); |
14552 RUNTIME_ASSERT(idx < max_idx); | 14555 RUNTIME_ASSERT(field_index.property_index() < max_idx); |
14553 Handle<Object> raw_value(object->RawFastPropertyAt(idx), isolate); | 14556 Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate); |
14554 RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized()); | 14557 RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized()); |
14555 return *Object::NewStorageFor(isolate, raw_value, Representation::Double()); | 14558 return *Object::NewStorageFor(isolate, raw_value, Representation::Double()); |
14556 } | 14559 } |
14557 | 14560 |
14558 | 14561 |
14559 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { | 14562 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { |
14560 HandleScope scope(isolate); | 14563 HandleScope scope(isolate); |
14561 ASSERT(args.length() == 1); | 14564 ASSERT(args.length() == 1); |
14562 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 14565 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
14563 if (!object->IsJSObject()) return Smi::FromInt(0); | 14566 if (!object->IsJSObject()) return Smi::FromInt(0); |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15136 } | 15139 } |
15137 return NULL; | 15140 return NULL; |
15138 } | 15141 } |
15139 | 15142 |
15140 | 15143 |
15141 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15144 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15142 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15145 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15143 } | 15146 } |
15144 | 15147 |
15145 } } // namespace v8::internal | 15148 } } // namespace v8::internal |
OLD | NEW |