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