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