OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 117 matching lines...) Loading... | |
128 } | 128 } |
129 return heap_object->GetHeap()->true_value(); | 129 return heap_object->GetHeap()->true_value(); |
130 } | 130 } |
131 | 131 |
132 | 132 |
133 void Object::Lookup(String* name, LookupResult* result) { | 133 void Object::Lookup(String* name, LookupResult* result) { |
134 Object* holder = NULL; | 134 Object* holder = NULL; |
135 if (IsJSReceiver()) { | 135 if (IsJSReceiver()) { |
136 holder = this; | 136 holder = this; |
137 } else { | 137 } else { |
138 Context* native_context = Isolate::Current()->context()->native_context(); | 138 Context* native_context = result->isolate()->context()->native_context(); |
139 if (IsNumber()) { | 139 if (IsNumber()) { |
140 holder = native_context->number_function()->instance_prototype(); | 140 holder = native_context->number_function()->instance_prototype(); |
141 } else if (IsString()) { | 141 } else if (IsString()) { |
142 holder = native_context->string_function()->instance_prototype(); | 142 holder = native_context->string_function()->instance_prototype(); |
143 } else if (IsBoolean()) { | 143 } else if (IsBoolean()) { |
144 holder = native_context->boolean_function()->instance_prototype(); | 144 holder = native_context->boolean_function()->instance_prototype(); |
145 } else { | 145 } else { |
146 Isolate::Current()->PushStackTraceAndDie( | 146 Isolate::Current()->PushStackTraceAndDie( |
147 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001); | 147 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001); |
148 } | 148 } |
(...skipping 457 matching lines...) Loading... | |
606 } | 606 } |
607 | 607 |
608 | 608 |
609 MaybeObject* Object::GetProperty(Object* receiver, | 609 MaybeObject* Object::GetProperty(Object* receiver, |
610 LookupResult* result, | 610 LookupResult* result, |
611 String* name, | 611 String* name, |
612 PropertyAttributes* attributes) { | 612 PropertyAttributes* attributes) { |
613 // Make sure that the top context does not change when doing | 613 // Make sure that the top context does not change when doing |
614 // callbacks or interceptor calls. | 614 // callbacks or interceptor calls. |
615 AssertNoContextChange ncc; | 615 AssertNoContextChange ncc; |
616 Heap* heap = name->GetHeap(); | 616 Isolate* isolate = name->GetIsolate(); |
617 Heap* heap = isolate->heap(); | |
617 | 618 |
618 // Traverse the prototype chain from the current object (this) to | 619 // Traverse the prototype chain from the current object (this) to |
619 // the holder and check for access rights. This avoids traversing the | 620 // the holder and check for access rights. This avoids traversing the |
620 // objects more than once in case of interceptors, because the | 621 // objects more than once in case of interceptors, because the |
621 // holder will always be the interceptor holder and the search may | 622 // holder will always be the interceptor holder and the search may |
622 // only continue with a current object just after the interceptor | 623 // only continue with a current object just after the interceptor |
623 // holder in the prototype chain. | 624 // holder in the prototype chain. |
624 // Proxy handlers do not use the proxy's prototype, so we can skip this. | 625 // Proxy handlers do not use the proxy's prototype, so we can skip this. |
625 if (!result->IsHandler()) { | 626 if (!result->IsHandler()) { |
626 Object* last = result->IsProperty() | 627 Object* last = result->IsProperty() |
627 ? result->holder() | 628 ? result->holder() |
628 : Object::cast(heap->null_value()); | 629 : Object::cast(heap->null_value()); |
629 ASSERT(this != this->GetPrototype()); | 630 ASSERT(this != this->GetPrototype(isolate)); |
630 for (Object* current = this; true; current = current->GetPrototype()) { | 631 for (Object* current = this; |
632 true; | |
633 current = current->GetPrototype(isolate)) { | |
631 if (current->IsAccessCheckNeeded()) { | 634 if (current->IsAccessCheckNeeded()) { |
632 // Check if we're allowed to read from the current object. Note | 635 // Check if we're allowed to read from the current object. Note |
633 // that even though we may not actually end up loading the named | 636 // that even though we may not actually end up loading the named |
634 // property from the current object, we still check that we have | 637 // property from the current object, we still check that we have |
635 // access to it. | 638 // access to it. |
636 // TODO(dcarney): revert. | 639 // TODO(dcarney): revert. |
637 CHECK(current->IsJSObject()); | 640 CHECK(current->IsJSObject()); |
638 JSObject* checked = JSObject::cast(current); | 641 JSObject* checked = JSObject::cast(current); |
639 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 642 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { |
640 return checked->GetPropertyWithFailedAccessCheck(receiver, | 643 return checked->GetPropertyWithFailedAccessCheck(receiver, |
(...skipping 39 matching lines...) Loading... | |
680 case NONEXISTENT: | 683 case NONEXISTENT: |
681 UNREACHABLE(); | 684 UNREACHABLE(); |
682 break; | 685 break; |
683 } | 686 } |
684 UNREACHABLE(); | 687 UNREACHABLE(); |
685 return NULL; | 688 return NULL; |
686 } | 689 } |
687 | 690 |
688 | 691 |
689 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 692 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
690 Heap* heap = IsSmi() | 693 Isolate* isolate = IsSmi() |
691 ? Isolate::Current()->heap() | 694 ? Isolate::Current() |
692 : HeapObject::cast(this)->GetHeap(); | 695 : HeapObject::cast(this)->GetIsolate(); |
696 Heap* heap = isolate->heap(); | |
693 Object* holder = this; | 697 Object* holder = this; |
694 | 698 |
695 // Iterate up the prototype chain until an element is found or the null | 699 // Iterate up the prototype chain until an element is found or the null |
696 // prototype is encountered. | 700 // prototype is encountered. |
697 for (holder = this; | 701 for (holder = this; |
698 holder != heap->null_value(); | 702 holder != heap->null_value(); |
699 holder = holder->GetPrototype()) { | 703 holder = holder->GetPrototype(isolate)) { |
700 if (!holder->IsJSObject()) { | 704 if (!holder->IsJSObject()) { |
701 Isolate* isolate = heap->isolate(); | |
702 Context* native_context = isolate->context()->native_context(); | 705 Context* native_context = isolate->context()->native_context(); |
703 if (holder->IsNumber()) { | 706 if (holder->IsNumber()) { |
704 holder = native_context->number_function()->instance_prototype(); | 707 holder = native_context->number_function()->instance_prototype(); |
705 } else if (holder->IsString()) { | 708 } else if (holder->IsString()) { |
706 holder = native_context->string_function()->instance_prototype(); | 709 holder = native_context->string_function()->instance_prototype(); |
707 } else if (holder->IsBoolean()) { | 710 } else if (holder->IsBoolean()) { |
708 holder = native_context->boolean_function()->instance_prototype(); | 711 holder = native_context->boolean_function()->instance_prototype(); |
709 } else if (holder->IsJSProxy()) { | 712 } else if (holder->IsJSProxy()) { |
710 return JSProxy::cast(holder)->GetElementWithHandler(receiver, index); | 713 return JSProxy::cast(holder)->GetElementWithHandler(receiver, index); |
711 } else { | 714 } else { |
(...skipping 25 matching lines...) Loading... | |
737 MaybeObject* result = js_object->GetElementsAccessor()->Get( | 740 MaybeObject* result = js_object->GetElementsAccessor()->Get( |
738 receiver, js_object, index); | 741 receiver, js_object, index); |
739 if (result != heap->the_hole_value()) return result; | 742 if (result != heap->the_hole_value()) return result; |
740 } | 743 } |
741 } | 744 } |
742 | 745 |
743 return heap->undefined_value(); | 746 return heap->undefined_value(); |
744 } | 747 } |
745 | 748 |
746 | 749 |
747 Object* Object::GetPrototype() { | 750 Object* Object::GetPrototype(Isolate* isolate) { |
748 if (IsSmi()) { | 751 if (IsSmi()) { |
749 Heap* heap = Isolate::Current()->heap(); | 752 Heap* heap = Isolate::Current()->heap(); |
ulan
2013/02/27 13:19:14
Shouldn't this be isolate->heap()?
| |
750 Context* context = heap->isolate()->context()->native_context(); | 753 Context* context = heap->isolate()->context()->native_context(); |
751 return context->number_function()->instance_prototype(); | 754 return context->number_function()->instance_prototype(); |
752 } | 755 } |
753 | 756 |
754 HeapObject* heap_object = HeapObject::cast(this); | 757 HeapObject* heap_object = HeapObject::cast(this); |
755 | 758 |
756 // The object is either a number, a string, a boolean, | 759 // The object is either a number, a string, a boolean, |
757 // a real JS object, or a Harmony proxy. | 760 // a real JS object, or a Harmony proxy. |
758 if (heap_object->IsJSReceiver()) { | 761 if (heap_object->IsJSReceiver()) { |
759 return heap_object->map()->prototype(); | 762 return heap_object->map()->prototype(); |
(...skipping 1333 matching lines...) Loading... | |
2093 | 2096 |
2094 | 2097 |
2095 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2098 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
2096 uint32_t index, | 2099 uint32_t index, |
2097 Object* value, | 2100 Object* value, |
2098 bool* found, | 2101 bool* found, |
2099 StrictModeFlag strict_mode) { | 2102 StrictModeFlag strict_mode) { |
2100 Heap* heap = GetHeap(); | 2103 Heap* heap = GetHeap(); |
2101 for (Object* pt = GetPrototype(); | 2104 for (Object* pt = GetPrototype(); |
2102 pt != heap->null_value(); | 2105 pt != heap->null_value(); |
2103 pt = pt->GetPrototype()) { | 2106 pt = pt->GetPrototype(GetIsolate())) { |
2104 if (pt->IsJSProxy()) { | 2107 if (pt->IsJSProxy()) { |
2105 String* name; | 2108 String* name; |
2106 MaybeObject* maybe = GetHeap()->Uint32ToString(index); | 2109 MaybeObject* maybe = heap->Uint32ToString(index); |
2107 if (!maybe->To<String>(&name)) { | 2110 if (!maybe->To<String>(&name)) { |
2108 *found = true; // Force abort | 2111 *found = true; // Force abort |
2109 return maybe; | 2112 return maybe; |
2110 } | 2113 } |
2111 return JSProxy::cast(pt)->SetPropertyViaPrototypesWithHandler( | 2114 return JSProxy::cast(pt)->SetPropertyViaPrototypesWithHandler( |
2112 this, name, value, NONE, strict_mode, found); | 2115 this, name, value, NONE, strict_mode, found); |
2113 } | 2116 } |
2114 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 2117 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
2115 continue; | 2118 continue; |
2116 } | 2119 } |
(...skipping 379 matching lines...) Loading... | |
2496 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { | 2499 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { |
2497 LocalLookupRealNamedProperty(name, result); | 2500 LocalLookupRealNamedProperty(name, result); |
2498 if (result->IsFound()) return; | 2501 if (result->IsFound()) return; |
2499 | 2502 |
2500 LookupRealNamedPropertyInPrototypes(name, result); | 2503 LookupRealNamedPropertyInPrototypes(name, result); |
2501 } | 2504 } |
2502 | 2505 |
2503 | 2506 |
2504 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, | 2507 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, |
2505 LookupResult* result) { | 2508 LookupResult* result) { |
2506 Heap* heap = GetHeap(); | 2509 Isolate* isolate = GetIsolate(); |
2510 Heap* heap = isolate->heap(); | |
2507 for (Object* pt = GetPrototype(); | 2511 for (Object* pt = GetPrototype(); |
2508 pt != heap->null_value(); | 2512 pt != heap->null_value(); |
2509 pt = pt->GetPrototype()) { | 2513 pt = pt->GetPrototype(isolate)) { |
2510 if (pt->IsJSProxy()) { | 2514 if (pt->IsJSProxy()) { |
2511 return result->HandlerResult(JSProxy::cast(pt)); | 2515 return result->HandlerResult(JSProxy::cast(pt)); |
2512 } | 2516 } |
2513 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 2517 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
2514 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); | 2518 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); |
2515 if (result->IsFound()) return; | 2519 if (result->IsFound()) return; |
2516 } | 2520 } |
2517 result->NotFound(); | 2521 result->NotFound(); |
2518 } | 2522 } |
2519 | 2523 |
(...skipping 5622 matching lines...) Loading... | |
8142 | 8146 |
8143 | 8147 |
8144 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { | 8148 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { |
8145 // Check the basic conditions for generating inline constructor code. | 8149 // Check the basic conditions for generating inline constructor code. |
8146 if (!FLAG_inline_new | 8150 if (!FLAG_inline_new |
8147 || !has_only_simple_this_property_assignments() | 8151 || !has_only_simple_this_property_assignments() |
8148 || this_property_assignments_count() == 0) { | 8152 || this_property_assignments_count() == 0) { |
8149 return false; | 8153 return false; |
8150 } | 8154 } |
8151 | 8155 |
8152 Heap* heap = GetHeap(); | 8156 Isolate* isolate = GetIsolate(); |
8157 Heap* heap = isolate->heap(); | |
8153 | 8158 |
8154 // Traverse the proposed prototype chain looking for properties of the | 8159 // Traverse the proposed prototype chain looking for properties of the |
8155 // same names as are set by the inline constructor. | 8160 // same names as are set by the inline constructor. |
8156 for (Object* obj = prototype; | 8161 for (Object* obj = prototype; |
8157 obj != heap->null_value(); | 8162 obj != heap->null_value(); |
8158 obj = obj->GetPrototype()) { | 8163 obj = obj->GetPrototype(isolate)) { |
8159 JSReceiver* receiver = JSReceiver::cast(obj); | 8164 JSReceiver* receiver = JSReceiver::cast(obj); |
8160 for (int i = 0; i < this_property_assignments_count(); i++) { | 8165 for (int i = 0; i < this_property_assignments_count(); i++) { |
8161 LookupResult result(heap->isolate()); | 8166 LookupResult result(heap->isolate()); |
8162 String* name = GetThisPropertyAssignmentName(i); | 8167 String* name = GetThisPropertyAssignmentName(i); |
8163 receiver->LocalLookup(name, &result); | 8168 receiver->LocalLookup(name, &result); |
8164 if (result.IsFound()) { | 8169 if (result.IsFound()) { |
8165 switch (result.type()) { | 8170 switch (result.type()) { |
8166 case NORMAL: | 8171 case NORMAL: |
8167 case FIELD: | 8172 case FIELD: |
8168 case CONSTANT_FUNCTION: | 8173 case CONSTANT_FUNCTION: |
(...skipping 1435 matching lines...) Loading... | |
9604 Deoptimizer::DeoptimizeAllFunctionsWith(&filter); | 9609 Deoptimizer::DeoptimizeAllFunctionsWith(&filter); |
9605 } | 9610 } |
9606 | 9611 |
9607 | 9612 |
9608 MaybeObject* JSReceiver::SetPrototype(Object* value, | 9613 MaybeObject* JSReceiver::SetPrototype(Object* value, |
9609 bool skip_hidden_prototypes) { | 9614 bool skip_hidden_prototypes) { |
9610 #ifdef DEBUG | 9615 #ifdef DEBUG |
9611 int size = Size(); | 9616 int size = Size(); |
9612 #endif | 9617 #endif |
9613 | 9618 |
9614 Heap* heap = GetHeap(); | 9619 Isolate* isolate = GetIsolate(); |
9620 Heap* heap = isolate->heap(); | |
9615 // Silently ignore the change if value is not a JSObject or null. | 9621 // Silently ignore the change if value is not a JSObject or null. |
9616 // SpiderMonkey behaves this way. | 9622 // SpiderMonkey behaves this way. |
9617 if (!value->IsJSReceiver() && !value->IsNull()) return value; | 9623 if (!value->IsJSReceiver() && !value->IsNull()) return value; |
9618 | 9624 |
9619 // From 8.6.2 Object Internal Methods | 9625 // From 8.6.2 Object Internal Methods |
9620 // ... | 9626 // ... |
9621 // In addition, if [[Extensible]] is false the value of the [[Class]] and | 9627 // In addition, if [[Extensible]] is false the value of the [[Class]] and |
9622 // [[Prototype]] internal properties of the object may not be modified. | 9628 // [[Prototype]] internal properties of the object may not be modified. |
9623 // ... | 9629 // ... |
9624 // Implementation specific extensions that modify [[Class]], [[Prototype]] | 9630 // Implementation specific extensions that modify [[Class]], [[Prototype]] |
9625 // or [[Extensible]] must not violate the invariants defined in the preceding | 9631 // or [[Extensible]] must not violate the invariants defined in the preceding |
9626 // paragraph. | 9632 // paragraph. |
9627 if (!this->map()->is_extensible()) { | 9633 if (!this->map()->is_extensible()) { |
9628 HandleScope scope(heap->isolate()); | 9634 HandleScope scope(isolate); |
9629 Handle<Object> handle(this, heap->isolate()); | 9635 Handle<Object> handle(this, isolate); |
9630 return heap->isolate()->Throw( | 9636 return isolate->Throw( |
9631 *FACTORY->NewTypeError("non_extensible_proto", | 9637 *isolate->factory()->NewTypeError("non_extensible_proto", |
9632 HandleVector<Object>(&handle, 1))); | 9638 HandleVector<Object>(&handle, 1))); |
9633 } | 9639 } |
9634 | 9640 |
9635 // Before we can set the prototype we need to be sure | 9641 // Before we can set the prototype we need to be sure |
9636 // prototype cycles are prevented. | 9642 // prototype cycles are prevented. |
9637 // It is sufficient to validate that the receiver is not in the new prototype | 9643 // It is sufficient to validate that the receiver is not in the new prototype |
9638 // chain. | 9644 // chain. |
9639 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { | 9645 for (Object* pt = value; |
9646 pt != heap->null_value(); | |
9647 pt = pt->GetPrototype(isolate)) { | |
9640 if (JSReceiver::cast(pt) == this) { | 9648 if (JSReceiver::cast(pt) == this) { |
9641 // Cycle detected. | 9649 // Cycle detected. |
9642 HandleScope scope(heap->isolate()); | 9650 HandleScope scope(isolate); |
9643 return heap->isolate()->Throw( | 9651 return isolate->Throw( |
9644 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); | 9652 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); |
9645 } | 9653 } |
9646 } | 9654 } |
9647 | 9655 |
9648 JSReceiver* real_receiver = this; | 9656 JSReceiver* real_receiver = this; |
9649 | 9657 |
9650 if (skip_hidden_prototypes) { | 9658 if (skip_hidden_prototypes) { |
9651 // Find the first object in the chain whose prototype object is not | 9659 // Find the first object in the chain whose prototype object is not |
9652 // hidden and set the new prototype on that object. | 9660 // hidden and set the new prototype on that object. |
9653 Object* current_proto = real_receiver->GetPrototype(); | 9661 Object* current_proto = real_receiver->GetPrototype(); |
9654 while (current_proto->IsJSObject() && | 9662 while (current_proto->IsJSObject() && |
9655 JSReceiver::cast(current_proto)->map()->is_hidden_prototype()) { | 9663 JSReceiver::cast(current_proto)->map()->is_hidden_prototype()) { |
9656 real_receiver = JSReceiver::cast(current_proto); | 9664 real_receiver = JSReceiver::cast(current_proto); |
9657 current_proto = current_proto->GetPrototype(); | 9665 current_proto = current_proto->GetPrototype(isolate); |
9658 } | 9666 } |
9659 } | 9667 } |
9660 | 9668 |
9661 // Set the new prototype of the object. | 9669 // Set the new prototype of the object. |
9662 Map* map = real_receiver->map(); | 9670 Map* map = real_receiver->map(); |
9663 | 9671 |
9664 // Nothing to do if prototype is already set. | 9672 // Nothing to do if prototype is already set. |
9665 if (map->prototype() == value) return value; | 9673 if (map->prototype() == value) return value; |
9666 | 9674 |
9667 if (value->IsJSObject()) { | 9675 if (value->IsJSObject()) { |
(...skipping 4313 matching lines...) Loading... | |
13981 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13989 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13982 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13990 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13983 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13991 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13984 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13992 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13985 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13993 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13986 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13994 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13987 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13995 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13988 } | 13996 } |
13989 | 13997 |
13990 } } // namespace v8::internal | 13998 } } // namespace v8::internal |
OLD | NEW |