Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: src/objects.cc

Issue 376233002: Introduce a PrototypeIterator class and use it for prototype access (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: updates Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/prototype.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h" 8 #include "src/allocation-site-scopes.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 10 matching lines...) Expand all
21 #include "src/field-index.h" 21 #include "src/field-index.h"
22 #include "src/full-codegen.h" 22 #include "src/full-codegen.h"
23 #include "src/hydrogen.h" 23 #include "src/hydrogen.h"
24 #include "src/isolate-inl.h" 24 #include "src/isolate-inl.h"
25 #include "src/log.h" 25 #include "src/log.h"
26 #include "src/lookup.h" 26 #include "src/lookup.h"
27 #include "src/macro-assembler.h" 27 #include "src/macro-assembler.h"
28 #include "src/mark-compact.h" 28 #include "src/mark-compact.h"
29 #include "src/objects-inl.h" 29 #include "src/objects-inl.h"
30 #include "src/objects-visiting-inl.h" 30 #include "src/objects-visiting-inl.h"
31 #include "src/prototype.h"
31 #include "src/safepoint-table.h" 32 #include "src/safepoint-table.h"
32 #include "src/string-search.h" 33 #include "src/string-search.h"
33 #include "src/string-stream.h" 34 #include "src/string-stream.h"
34 #include "src/utils.h" 35 #include "src/utils.h"
35 36
36 #ifdef ENABLE_DISASSEMBLER 37 #ifdef ENABLE_DISASSEMBLER
37 #include "src/disasm.h" 38 #include "src/disasm.h"
38 #include "src/disassembler.h" 39 #include "src/disassembler.h"
39 #endif 40 #endif
40 41
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return map() != fun->initial_map() 795 return map() != fun->initial_map()
795 || !HasFastObjectElements() 796 || !HasFastObjectElements()
796 || !HasFastProperties(); 797 || !HasFastProperties();
797 } 798 }
798 799
799 800
800 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, 801 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
801 Handle<Object> object, 802 Handle<Object> object,
802 Handle<Object> receiver, 803 Handle<Object> receiver,
803 uint32_t index) { 804 uint32_t index) {
804 Handle<Object> holder; 805 if (object->IsUndefined()) {
806 // TODO(verwaest): Why is this check here?
807 UNREACHABLE();
808 return isolate->factory()->undefined_value();
809 }
805 810
806 // Iterate up the prototype chain until an element is found or the null 811 // Iterate up the prototype chain until an element is found or the null
807 // prototype is encountered. 812 // prototype is encountered.
808 for (holder = object; 813 for (PrototypeIterator iter(isolate, object,
809 !holder->IsNull(); 814 object->IsJSProxy() || object->IsJSObject()
810 holder = Handle<Object>(holder->GetPrototype(isolate), isolate)) { 815 ? PrototypeIterator::START_AT_RECEIVER
811 if (!holder->IsJSObject()) { 816 : PrototypeIterator::START_AT_PROTOTYPE);
812 if (holder->IsJSProxy()) { 817 !iter.IsAtEnd(); iter.Advance()) {
813 return JSProxy::GetElementWithHandler( 818 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
814 Handle<JSProxy>::cast(holder), receiver, index); 819 return JSProxy::GetElementWithHandler(
815 } else if (holder->IsUndefined()) { 820 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
816 // Undefined has no indexed properties. 821 index);
817 return isolate->factory()->undefined_value();
818 } else {
819 holder = Handle<Object>(holder->GetPrototype(isolate), isolate);
820 ASSERT(holder->IsJSObject());
821 }
822 } 822 }
823 823
824 // Inline the case for JSObjects. Doing so significantly improves the 824 // Inline the case for JSObjects. Doing so significantly improves the
825 // performance of fetching elements where checking the prototype chain is 825 // performance of fetching elements where checking the prototype chain is
826 // necessary. 826 // necessary.
827 Handle<JSObject> js_object = Handle<JSObject>::cast(holder); 827 Handle<JSObject> js_object =
828 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
828 829
829 // Check access rights if needed. 830 // Check access rights if needed.
830 if (js_object->IsAccessCheckNeeded()) { 831 if (js_object->IsAccessCheckNeeded()) {
831 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) { 832 if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
832 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET); 833 isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
833 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 834 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
834 return isolate->factory()->undefined_value(); 835 return isolate->factory()->undefined_value();
835 } 836 }
836 } 837 }
837 838
838 if (js_object->HasIndexedInterceptor()) { 839 if (js_object->HasIndexedInterceptor()) {
839 return JSObject::GetElementWithInterceptor(js_object, receiver, index); 840 return JSObject::GetElementWithInterceptor(js_object, receiver, index);
840 } 841 }
841 842
842 if (js_object->elements() != isolate->heap()->empty_fixed_array()) { 843 if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
843 Handle<Object> result; 844 Handle<Object> result;
844 ASSIGN_RETURN_ON_EXCEPTION( 845 ASSIGN_RETURN_ON_EXCEPTION(
845 isolate, result, 846 isolate, result,
846 js_object->GetElementsAccessor()->Get(receiver, js_object, index), 847 js_object->GetElementsAccessor()->Get(receiver, js_object, index),
847 Object); 848 Object);
848 if (!result->IsTheHole()) return result; 849 if (!result->IsTheHole()) return result;
849 } 850 }
850 } 851 }
851 852
852 return isolate->factory()->undefined_value(); 853 return isolate->factory()->undefined_value();
853 } 854 }
854 855
855 856
856 Object* Object::GetPrototype(Isolate* isolate) { 857 Map* Object::GetRootMap(Isolate* isolate) {
857 DisallowHeapAllocation no_alloc; 858 DisallowHeapAllocation no_alloc;
858 if (IsSmi()) { 859 if (IsSmi()) {
859 Context* context = isolate->context()->native_context(); 860 Context* context = isolate->context()->native_context();
860 return context->number_function()->instance_prototype(); 861 return context->number_function()->initial_map();
861 } 862 }
862 863
863 HeapObject* heap_object = HeapObject::cast(this); 864 HeapObject* heap_object = HeapObject::cast(this);
864 865
865 // The object is either a number, a string, a boolean, 866 // The object is either a number, a string, a boolean,
866 // a real JS object, or a Harmony proxy. 867 // a real JS object, or a Harmony proxy.
867 if (heap_object->IsJSReceiver()) { 868 if (heap_object->IsJSReceiver()) {
868 return heap_object->map()->prototype(); 869 return heap_object->map();
869 } 870 }
870 Context* context = isolate->context()->native_context(); 871 Context* context = isolate->context()->native_context();
871 872
872 if (heap_object->IsHeapNumber()) { 873 if (heap_object->IsHeapNumber()) {
873 return context->number_function()->instance_prototype(); 874 return context->number_function()->initial_map();
874 } 875 }
875 if (heap_object->IsString()) { 876 if (heap_object->IsString()) {
876 return context->string_function()->instance_prototype(); 877 return context->string_function()->initial_map();
877 } 878 }
878 if (heap_object->IsSymbol()) { 879 if (heap_object->IsSymbol()) {
879 return context->symbol_function()->instance_prototype(); 880 return context->symbol_function()->initial_map();
880 } 881 }
881 if (heap_object->IsBoolean()) { 882 if (heap_object->IsBoolean()) {
882 return context->boolean_function()->instance_prototype(); 883 return context->boolean_function()->initial_map();
883 } else {
884 return isolate->heap()->null_value();
885 } 884 }
885 return isolate->heap()->null_value()->map();
886 } 886 }
887 887
888 888
889 Handle<Object> Object::GetPrototype(Isolate* isolate,
890 Handle<Object> object) {
891 return handle(object->GetPrototype(isolate), isolate);
892 }
893
894
895 Object* Object::GetHash() { 889 Object* Object::GetHash() {
896 // The object is either a number, a name, an odd-ball, 890 // The object is either a number, a name, an odd-ball,
897 // a real JS object, or a Harmony proxy. 891 // a real JS object, or a Harmony proxy.
898 if (IsNumber()) { 892 if (IsNumber()) {
899 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); 893 uint32_t hash = ComputeLongHash(double_to_uint64(Number()));
900 return Smi::FromInt(hash & Smi::kMaxValue); 894 return Smi::FromInt(hash & Smi::kMaxValue);
901 } 895 }
902 if (IsName()) { 896 if (IsName()) {
903 uint32_t hash = Name::cast(this)->Hash(); 897 uint32_t hash = Name::cast(this)->Hash();
904 return Smi::FromInt(hash); 898 return Smi::FromInt(hash);
(...skipping 2116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3021 } 3015 }
3022 3016
3023 3017
3024 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( 3018 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
3025 Handle<JSObject> object, 3019 Handle<JSObject> object,
3026 uint32_t index, 3020 uint32_t index,
3027 Handle<Object> value, 3021 Handle<Object> value,
3028 bool* found, 3022 bool* found,
3029 StrictMode strict_mode) { 3023 StrictMode strict_mode) {
3030 Isolate *isolate = object->GetIsolate(); 3024 Isolate *isolate = object->GetIsolate();
3031 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); 3025 for (PrototypeIterator iter(isolate, object); !iter.IsAtEnd();
3032 !proto->IsNull(); 3026 iter.Advance()) {
3033 proto = handle(proto->GetPrototype(isolate), isolate)) { 3027 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
3034 if (proto->IsJSProxy()) {
3035 return JSProxy::SetPropertyViaPrototypesWithHandler( 3028 return JSProxy::SetPropertyViaPrototypesWithHandler(
3036 Handle<JSProxy>::cast(proto), 3029 Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), object,
3037 object,
3038 isolate->factory()->Uint32ToString(index), // name 3030 isolate->factory()->Uint32ToString(index), // name
3039 value, 3031 value, NONE, strict_mode, found);
3040 NONE,
3041 strict_mode,
3042 found);
3043 } 3032 }
3044 Handle<JSObject> js_proto = Handle<JSObject>::cast(proto); 3033 Handle<JSObject> js_proto =
3034 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
3045 if (!js_proto->HasDictionaryElements()) { 3035 if (!js_proto->HasDictionaryElements()) {
3046 continue; 3036 continue;
3047 } 3037 }
3048 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); 3038 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary());
3049 int entry = dictionary->FindEntry(index); 3039 int entry = dictionary->FindEntry(index);
3050 if (entry != SeededNumberDictionary::kNotFound) { 3040 if (entry != SeededNumberDictionary::kNotFound) {
3051 PropertyDetails details = dictionary->DetailsAt(entry); 3041 PropertyDetails details = dictionary->DetailsAt(entry);
3052 if (details.type() == CALLBACKS) { 3042 if (details.type() == CALLBACKS) {
3053 *found = true; 3043 *found = true;
3054 Handle<Object> structure(dictionary->ValueAt(entry), isolate); 3044 Handle<Object> structure(dictionary->ValueAt(entry), isolate);
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
3512 if (result->IsFound()) return; 3502 if (result->IsFound()) return;
3513 3503
3514 LookupRealNamedPropertyInPrototypes(name, result); 3504 LookupRealNamedPropertyInPrototypes(name, result);
3515 } 3505 }
3516 3506
3517 3507
3518 void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name, 3508 void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name,
3519 LookupResult* result) { 3509 LookupResult* result) {
3520 DisallowHeapAllocation no_gc; 3510 DisallowHeapAllocation no_gc;
3521 Isolate* isolate = GetIsolate(); 3511 Isolate* isolate = GetIsolate();
3522 Heap* heap = isolate->heap(); 3512 for (PrototypeIterator iter(isolate, this); !iter.IsAtEnd(); iter.Advance()) {
3523 for (Object* pt = GetPrototype(); 3513 if (iter.GetCurrent()->IsJSProxy()) {
3524 pt != heap->null_value(); 3514 return result->HandlerResult(JSProxy::cast(iter.GetCurrent()));
3525 pt = pt->GetPrototype(isolate)) {
3526 if (pt->IsJSProxy()) {
3527 return result->HandlerResult(JSProxy::cast(pt));
3528 } 3515 }
3529 JSObject::cast(pt)->LookupOwnRealNamedProperty(name, result); 3516 JSObject::cast(iter.GetCurrent())->LookupOwnRealNamedProperty(name, result);
3530 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); 3517 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR));
3531 if (result->IsFound()) return; 3518 if (result->IsFound()) return;
3532 } 3519 }
3533 result->NotFound(); 3520 result->NotFound();
3534 } 3521 }
3535 3522
3536 3523
3537 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, 3524 MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
3538 LookupResult* result, 3525 LookupResult* result,
3539 Handle<Name> key, 3526 Handle<Name> key,
(...skipping 2822 matching lines...) Expand 10 before | Expand all | Expand 10 after
6362 6349
6363 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, 6350 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
6364 KeyCollectionType type) { 6351 KeyCollectionType type) {
6365 USE(ContainsOnlyValidKeys); 6352 USE(ContainsOnlyValidKeys);
6366 Isolate* isolate = object->GetIsolate(); 6353 Isolate* isolate = object->GetIsolate();
6367 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); 6354 Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
6368 Handle<JSFunction> arguments_function( 6355 Handle<JSFunction> arguments_function(
6369 JSFunction::cast(isolate->sloppy_arguments_map()->constructor())); 6356 JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
6370 6357
6371 // Only collect keys if access is permitted. 6358 // Only collect keys if access is permitted.
6372 for (Handle<Object> p = object; 6359 for (PrototypeIterator iter(isolate, object,
6373 *p != isolate->heap()->null_value(); 6360 PrototypeIterator::START_AT_RECEIVER);
6374 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { 6361 !iter.IsAtEnd(); iter.Advance()) {
6375 if (p->IsJSProxy()) { 6362 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
6376 Handle<JSProxy> proxy(JSProxy::cast(*p), isolate); 6363 Handle<JSProxy> proxy(JSProxy::cast(*PrototypeIterator::GetCurrent(iter)),
6364 isolate);
6377 Handle<Object> args[] = { proxy }; 6365 Handle<Object> args[] = { proxy };
6378 Handle<Object> names; 6366 Handle<Object> names;
6379 ASSIGN_RETURN_ON_EXCEPTION( 6367 ASSIGN_RETURN_ON_EXCEPTION(
6380 isolate, names, 6368 isolate, names,
6381 Execution::Call(isolate, 6369 Execution::Call(isolate,
6382 isolate->proxy_enumerate(), 6370 isolate->proxy_enumerate(),
6383 object, 6371 object,
6384 ARRAY_SIZE(args), 6372 ARRAY_SIZE(args),
6385 args), 6373 args),
6386 FixedArray); 6374 FixedArray);
6387 ASSIGN_RETURN_ON_EXCEPTION( 6375 ASSIGN_RETURN_ON_EXCEPTION(
6388 isolate, content, 6376 isolate, content,
6389 FixedArray::AddKeysFromArrayLike( 6377 FixedArray::AddKeysFromArrayLike(
6390 content, Handle<JSObject>::cast(names)), 6378 content, Handle<JSObject>::cast(names)),
6391 FixedArray); 6379 FixedArray);
6392 break; 6380 break;
6393 } 6381 }
6394 6382
6395 Handle<JSObject> current(JSObject::cast(*p), isolate); 6383 Handle<JSObject> current =
6384 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
6396 6385
6397 // Check access rights if required. 6386 // Check access rights if required.
6398 if (current->IsAccessCheckNeeded() && 6387 if (current->IsAccessCheckNeeded() &&
6399 !isolate->MayNamedAccess( 6388 !isolate->MayNamedAccess(
6400 current, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { 6389 current, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
6401 isolate->ReportFailedAccessCheck(current, v8::ACCESS_KEYS); 6390 isolate->ReportFailedAccessCheck(current, v8::ACCESS_KEYS);
6402 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray); 6391 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, FixedArray);
6403 break; 6392 break;
6404 } 6393 }
6405 6394
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
6603 } 6592 }
6604 6593
6605 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); 6594 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name);
6606 accessors->SetComponents(*getter, *setter); 6595 accessors->SetComponents(*getter, *setter);
6607 6596
6608 SetPropertyCallback(object, name, accessors, attributes); 6597 SetPropertyCallback(object, name, accessors, attributes);
6609 } 6598 }
6610 6599
6611 6600
6612 bool Map::DictionaryElementsInPrototypeChainOnly() { 6601 bool Map::DictionaryElementsInPrototypeChainOnly() {
6613 Heap* heap = GetHeap();
6614
6615 if (IsDictionaryElementsKind(elements_kind())) { 6602 if (IsDictionaryElementsKind(elements_kind())) {
6616 return false; 6603 return false;
6617 } 6604 }
6618 6605
6619 for (Object* prototype = this->prototype(); 6606 for (PrototypeIterator iter(this); !iter.IsAtEnd(); iter.Advance()) {
6620 prototype != heap->null_value(); 6607 if (iter.GetCurrent()->IsJSProxy()) {
6621 prototype = prototype->GetPrototype(GetIsolate())) {
6622 if (prototype->IsJSProxy()) {
6623 // Be conservative, don't walk into proxies. 6608 // Be conservative, don't walk into proxies.
6624 return true; 6609 return true;
6625 } 6610 }
6626 6611
6627 if (IsDictionaryElementsKind( 6612 if (IsDictionaryElementsKind(
6628 JSObject::cast(prototype)->map()->elements_kind())) { 6613 JSObject::cast(iter.GetCurrent())->map()->elements_kind())) {
6629 return true; 6614 return true;
6630 } 6615 }
6631 } 6616 }
6632 6617
6633 return false; 6618 return false;
6634 } 6619 }
6635 6620
6636 6621
6637 void JSObject::SetElementCallback(Handle<JSObject> object, 6622 void JSObject::SetElementCallback(Handle<JSObject> object,
6638 uint32_t index, 6623 uint32_t index,
(...skipping 3480 matching lines...) Expand 10 before | Expand all | Expand 10 after
10119 instance_type = JS_OBJECT_TYPE; 10104 instance_type = JS_OBJECT_TYPE;
10120 instance_size = function->shared()->CalculateInstanceSize(); 10105 instance_size = function->shared()->CalculateInstanceSize();
10121 in_object_properties = function->shared()->CalculateInObjectProperties(); 10106 in_object_properties = function->shared()->CalculateInObjectProperties();
10122 } 10107 }
10123 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); 10108 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size);
10124 10109
10125 // Fetch or allocate prototype. 10110 // Fetch or allocate prototype.
10126 Handle<Object> prototype; 10111 Handle<Object> prototype;
10127 if (function->has_instance_prototype()) { 10112 if (function->has_instance_prototype()) {
10128 prototype = handle(function->instance_prototype(), isolate); 10113 prototype = handle(function->instance_prototype(), isolate);
10129 for (Handle<Object> p = prototype; !p->IsNull() && !p->IsJSProxy(); 10114 for (PrototypeIterator iter(isolate, prototype,
10130 p = Object::GetPrototype(isolate, p)) { 10115 PrototypeIterator::START_AT_RECEIVER);
10131 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(p)); 10116 !iter.IsAtEnd(); iter.Advance()) {
10117 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
10118 break;
10119 }
10120 JSObject::OptimizeAsPrototype(
10121 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
10132 } 10122 }
10133 } else { 10123 } else {
10134 prototype = isolate->factory()->NewFunctionPrototype(function); 10124 prototype = isolate->factory()->NewFunctionPrototype(function);
10135 } 10125 }
10136 map->set_inobject_properties(in_object_properties); 10126 map->set_inobject_properties(in_object_properties);
10137 map->set_unused_property_fields(in_object_properties); 10127 map->set_unused_property_fields(in_object_properties);
10138 map->set_prototype(*prototype); 10128 map->set_prototype(*prototype);
10139 ASSERT(map->has_fast_object_elements()); 10129 ASSERT(map->has_fast_object_elements());
10140 10130
10141 // Finally link initial map and constructor function. 10131 // Finally link initial map and constructor function.
(...skipping 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after
12191 Handle<Object> args[] = { object }; 12181 Handle<Object> args[] = { object };
12192 Handle<Object> error = isolate->factory()->NewTypeError( 12182 Handle<Object> error = isolate->factory()->NewTypeError(
12193 "non_extensible_proto", HandleVector(args, ARRAY_SIZE(args))); 12183 "non_extensible_proto", HandleVector(args, ARRAY_SIZE(args)));
12194 return isolate->Throw<Object>(error); 12184 return isolate->Throw<Object>(error);
12195 } 12185 }
12196 12186
12197 // Before we can set the prototype we need to be sure 12187 // Before we can set the prototype we need to be sure
12198 // prototype cycles are prevented. 12188 // prototype cycles are prevented.
12199 // It is sufficient to validate that the receiver is not in the new prototype 12189 // It is sufficient to validate that the receiver is not in the new prototype
12200 // chain. 12190 // chain.
12201 for (Object* pt = *value; 12191 for (PrototypeIterator iter(isolate, *value,
12202 pt != heap->null_value(); 12192 PrototypeIterator::START_AT_RECEIVER);
12203 pt = pt->GetPrototype(isolate)) { 12193 !iter.IsAtEnd(); iter.Advance()) {
12204 if (JSReceiver::cast(pt) == *object) { 12194 if (JSReceiver::cast(iter.GetCurrent()) == *object) {
12205 // Cycle detected. 12195 // Cycle detected.
12206 Handle<Object> error = isolate->factory()->NewError( 12196 Handle<Object> error = isolate->factory()->NewError(
12207 "cyclic_proto", HandleVector<Object>(NULL, 0)); 12197 "cyclic_proto", HandleVector<Object>(NULL, 0));
12208 return isolate->Throw<Object>(error); 12198 return isolate->Throw<Object>(error);
12209 } 12199 }
12210 } 12200 }
12211 12201
12212 bool dictionary_elements_in_chain = 12202 bool dictionary_elements_in_chain =
12213 object->map()->DictionaryElementsInPrototypeChainOnly(); 12203 object->map()->DictionaryElementsInPrototypeChainOnly();
12214 Handle<JSObject> real_receiver = object; 12204 Handle<JSObject> real_receiver = object;
12215 12205
12216 if (skip_hidden_prototypes) { 12206 if (skip_hidden_prototypes) {
12217 // Find the first object in the chain whose prototype object is not 12207 // Find the first object in the chain whose prototype object is not
12218 // hidden and set the new prototype on that object. 12208 // hidden and set the new prototype on that object.
12219 Object* current_proto = real_receiver->GetPrototype(); 12209 PrototypeIterator iter(isolate, real_receiver);
12220 while (current_proto->IsJSObject() && 12210 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
12221 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { 12211 real_receiver =
12222 real_receiver = handle(JSObject::cast(current_proto), isolate); 12212 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
12223 current_proto = current_proto->GetPrototype(isolate); 12213 iter.Advance();
12224 } 12214 }
12225 } 12215 }
12226 12216
12227 // Set the new prototype of the object. 12217 // Set the new prototype of the object.
12228 Handle<Map> map(real_receiver->map()); 12218 Handle<Map> map(real_receiver->map());
12229 12219
12230 // Nothing to do if prototype is already set. 12220 // Nothing to do if prototype is already set.
12231 if (map->prototype() == *value) return value; 12221 if (map->prototype() == *value) return value;
12232 12222
12233 if (value->IsJSObject()) { 12223 if (value->IsJSObject()) {
(...skipping 4761 matching lines...) Expand 10 before | Expand all | Expand 10 after
16995 #define ERROR_MESSAGES_TEXTS(C, T) T, 16985 #define ERROR_MESSAGES_TEXTS(C, T) T,
16996 static const char* error_messages_[] = { 16986 static const char* error_messages_[] = {
16997 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16987 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16998 }; 16988 };
16999 #undef ERROR_MESSAGES_TEXTS 16989 #undef ERROR_MESSAGES_TEXTS
17000 return error_messages_[reason]; 16990 return error_messages_[reason];
17001 } 16991 }
17002 16992
17003 16993
17004 } } // namespace v8::internal 16994 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/prototype.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698