OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 5594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5605 MaybeObject* maybe_copy = map()->Copy(); | 5605 MaybeObject* maybe_copy = map()->Copy(); |
5606 if (!maybe_copy->To(&new_map)) return maybe_copy; | 5606 if (!maybe_copy->To(&new_map)) return maybe_copy; |
5607 new_map->set_is_observed(true); | 5607 new_map->set_is_observed(true); |
5608 } | 5608 } |
5609 set_map(new_map); | 5609 set_map(new_map); |
5610 | 5610 |
5611 return heap->undefined_value(); | 5611 return heap->undefined_value(); |
5612 } | 5612 } |
5613 | 5613 |
5614 | 5614 |
5615 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { | 5615 // TODO(mstarzinger): Temporary wrapper until handlified. |
| 5616 static Handle<Object> NewStorageFor(Isolate* isolate, |
| 5617 Handle<Object> object, |
| 5618 Representation representation) { |
| 5619 Heap* heap = isolate->heap(); |
| 5620 CALL_HEAP_FUNCTION(isolate, |
| 5621 object->AllocateNewStorageFor(heap, representation), |
| 5622 Object); |
| 5623 } |
| 5624 |
| 5625 |
| 5626 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { |
| 5627 Isolate* isolate = object->GetIsolate(); |
| 5628 CALL_HEAP_FUNCTION(isolate, |
| 5629 isolate->heap()->CopyJSObject(*object), JSObject); |
| 5630 } |
| 5631 |
| 5632 |
| 5633 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { |
| 5634 Isolate* isolate = object->GetIsolate(); |
5616 StackLimitCheck check(isolate); | 5635 StackLimitCheck check(isolate); |
5617 if (check.HasOverflowed()) return isolate->StackOverflow(); | 5636 if (check.HasOverflowed()) { |
5618 | 5637 isolate->StackOverflow(); |
5619 if (map()->is_deprecated()) { | 5638 return Handle<JSObject>::null(); |
5620 MaybeObject* maybe_failure = MigrateInstance(); | |
5621 if (maybe_failure->IsFailure()) return maybe_failure; | |
5622 } | 5639 } |
5623 | 5640 |
5624 Heap* heap = isolate->heap(); | 5641 if (object->map()->is_deprecated()) { |
5625 Object* result; | 5642 MigrateInstance(object); |
5626 { MaybeObject* maybe_result = heap->CopyJSObject(this); | |
5627 if (!maybe_result->ToObject(&result)) return maybe_result; | |
5628 } | 5643 } |
5629 JSObject* copy = JSObject::cast(result); | 5644 |
| 5645 Handle<JSObject> copy = Copy(object); |
5630 | 5646 |
5631 // Deep copy local properties. | 5647 // Deep copy local properties. |
5632 if (copy->HasFastProperties()) { | 5648 if (copy->HasFastProperties()) { |
5633 DescriptorArray* descriptors = copy->map()->instance_descriptors(); | 5649 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
5634 int limit = copy->map()->NumberOfOwnDescriptors(); | 5650 int limit = copy->map()->NumberOfOwnDescriptors(); |
5635 for (int i = 0; i < limit; i++) { | 5651 for (int i = 0; i < limit; i++) { |
5636 PropertyDetails details = descriptors->GetDetails(i); | 5652 PropertyDetails details = descriptors->GetDetails(i); |
5637 if (details.type() != FIELD) continue; | 5653 if (details.type() != FIELD) continue; |
5638 int index = descriptors->GetFieldIndex(i); | 5654 int index = descriptors->GetFieldIndex(i); |
5639 Object* value = RawFastPropertyAt(index); | 5655 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
5640 if (value->IsJSObject()) { | 5656 if (value->IsJSObject()) { |
5641 JSObject* js_object = JSObject::cast(value); | 5657 value = DeepCopy(Handle<JSObject>::cast(value)); |
5642 MaybeObject* maybe_copy = js_object->DeepCopy(isolate); | 5658 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); |
5643 if (!maybe_copy->To(&value)) return maybe_copy; | |
5644 } else { | 5659 } else { |
5645 Representation representation = details.representation(); | 5660 Representation representation = details.representation(); |
5646 MaybeObject* maybe_storage = | 5661 value = NewStorageFor(isolate, value, representation); |
5647 value->AllocateNewStorageFor(heap, representation); | |
5648 if (!maybe_storage->To(&value)) return maybe_storage; | |
5649 } | 5662 } |
5650 copy->FastPropertyAtPut(index, value); | 5663 copy->FastPropertyAtPut(index, *value); |
5651 } | 5664 } |
5652 } else { | 5665 } else { |
5653 { MaybeObject* maybe_result = | 5666 Handle<FixedArray> names = |
5654 heap->AllocateFixedArray(copy->NumberOfLocalProperties()); | 5667 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); |
5655 if (!maybe_result->ToObject(&result)) return maybe_result; | 5668 copy->GetLocalPropertyNames(*names, 0); |
5656 } | |
5657 FixedArray* names = FixedArray::cast(result); | |
5658 copy->GetLocalPropertyNames(names, 0); | |
5659 for (int i = 0; i < names->length(); i++) { | 5669 for (int i = 0; i < names->length(); i++) { |
5660 ASSERT(names->get(i)->IsString()); | 5670 ASSERT(names->get(i)->IsString()); |
5661 String* key_string = String::cast(names->get(i)); | 5671 Handle<String> key_string(String::cast(names->get(i))); |
5662 PropertyAttributes attributes = | 5672 PropertyAttributes attributes = |
5663 copy->GetLocalPropertyAttribute(key_string); | 5673 copy->GetLocalPropertyAttribute(*key_string); |
5664 // Only deep copy fields from the object literal expression. | 5674 // Only deep copy fields from the object literal expression. |
5665 // In particular, don't try to copy the length attribute of | 5675 // In particular, don't try to copy the length attribute of |
5666 // an array. | 5676 // an array. |
5667 if (attributes != NONE) continue; | 5677 if (attributes != NONE) continue; |
5668 Object* value = | 5678 Handle<Object> value( |
5669 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked(); | 5679 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), |
| 5680 isolate); |
5670 if (value->IsJSObject()) { | 5681 if (value->IsJSObject()) { |
5671 JSObject* js_object = JSObject::cast(value); | 5682 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); |
5672 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); | 5683 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
5673 if (!maybe_result->ToObject(&result)) return maybe_result; | 5684 // Creating object copy for literals. No strict mode needed. |
5674 } | 5685 CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty( |
5675 { MaybeObject* maybe_result = | 5686 copy, key_string, result, NONE, kNonStrictMode)); |
5676 // Creating object copy for literals. No strict mode needed. | |
5677 copy->SetProperty(key_string, result, NONE, kNonStrictMode); | |
5678 if (!maybe_result->ToObject(&result)) return maybe_result; | |
5679 } | |
5680 } | 5687 } |
5681 } | 5688 } |
5682 } | 5689 } |
5683 | 5690 |
5684 // Deep copy local elements. | 5691 // Deep copy local elements. |
5685 // Pixel elements cannot be created using an object literal. | 5692 // Pixel elements cannot be created using an object literal. |
5686 ASSERT(!copy->HasExternalArrayElements()); | 5693 ASSERT(!copy->HasExternalArrayElements()); |
5687 switch (copy->GetElementsKind()) { | 5694 switch (copy->GetElementsKind()) { |
5688 case FAST_SMI_ELEMENTS: | 5695 case FAST_SMI_ELEMENTS: |
5689 case FAST_ELEMENTS: | 5696 case FAST_ELEMENTS: |
5690 case FAST_HOLEY_SMI_ELEMENTS: | 5697 case FAST_HOLEY_SMI_ELEMENTS: |
5691 case FAST_HOLEY_ELEMENTS: { | 5698 case FAST_HOLEY_ELEMENTS: { |
5692 FixedArray* elements = FixedArray::cast(copy->elements()); | 5699 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
5693 if (elements->map() == heap->fixed_cow_array_map()) { | 5700 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
5694 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 5701 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
5695 #ifdef DEBUG | 5702 #ifdef DEBUG |
5696 for (int i = 0; i < elements->length(); i++) { | 5703 for (int i = 0; i < elements->length(); i++) { |
5697 ASSERT(!elements->get(i)->IsJSObject()); | 5704 ASSERT(!elements->get(i)->IsJSObject()); |
5698 } | 5705 } |
5699 #endif | 5706 #endif |
5700 } else { | 5707 } else { |
5701 for (int i = 0; i < elements->length(); i++) { | 5708 for (int i = 0; i < elements->length(); i++) { |
5702 Object* value = elements->get(i); | 5709 Handle<Object> value(elements->get(i), isolate); |
5703 ASSERT(value->IsSmi() || | 5710 ASSERT(value->IsSmi() || |
5704 value->IsTheHole() || | 5711 value->IsTheHole() || |
5705 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 5712 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
5706 if (value->IsJSObject()) { | 5713 if (value->IsJSObject()) { |
5707 JSObject* js_object = JSObject::cast(value); | 5714 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); |
5708 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); | 5715 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
5709 if (!maybe_result->ToObject(&result)) return maybe_result; | 5716 elements->set(i, *result); |
5710 } | |
5711 elements->set(i, result); | |
5712 } | 5717 } |
5713 } | 5718 } |
5714 } | 5719 } |
5715 break; | 5720 break; |
5716 } | 5721 } |
5717 case DICTIONARY_ELEMENTS: { | 5722 case DICTIONARY_ELEMENTS: { |
5718 SeededNumberDictionary* element_dictionary = copy->element_dictionary(); | 5723 Handle<SeededNumberDictionary> element_dictionary( |
| 5724 copy->element_dictionary()); |
5719 int capacity = element_dictionary->Capacity(); | 5725 int capacity = element_dictionary->Capacity(); |
5720 for (int i = 0; i < capacity; i++) { | 5726 for (int i = 0; i < capacity; i++) { |
5721 Object* k = element_dictionary->KeyAt(i); | 5727 Object* k = element_dictionary->KeyAt(i); |
5722 if (element_dictionary->IsKey(k)) { | 5728 if (element_dictionary->IsKey(k)) { |
5723 Object* value = element_dictionary->ValueAt(i); | 5729 Handle<Object> value(element_dictionary->ValueAt(i), isolate); |
5724 if (value->IsJSObject()) { | 5730 if (value->IsJSObject()) { |
5725 JSObject* js_object = JSObject::cast(value); | 5731 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); |
5726 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); | 5732 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
5727 if (!maybe_result->ToObject(&result)) return maybe_result; | 5733 element_dictionary->ValueAtPut(i, *result); |
5728 } | |
5729 element_dictionary->ValueAtPut(i, result); | |
5730 } | 5734 } |
5731 } | 5735 } |
5732 } | 5736 } |
5733 break; | 5737 break; |
5734 } | 5738 } |
5735 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5739 case NON_STRICT_ARGUMENTS_ELEMENTS: |
5736 UNIMPLEMENTED(); | 5740 UNIMPLEMENTED(); |
5737 break; | 5741 break; |
5738 case EXTERNAL_PIXEL_ELEMENTS: | 5742 case EXTERNAL_PIXEL_ELEMENTS: |
5739 case EXTERNAL_BYTE_ELEMENTS: | 5743 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 10237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15977 #define ERROR_MESSAGES_TEXTS(C, T) T, | 15981 #define ERROR_MESSAGES_TEXTS(C, T) T, |
15978 static const char* error_messages_[] = { | 15982 static const char* error_messages_[] = { |
15979 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 15983 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
15980 }; | 15984 }; |
15981 #undef ERROR_MESSAGES_TEXTS | 15985 #undef ERROR_MESSAGES_TEXTS |
15982 return error_messages_[reason]; | 15986 return error_messages_[reason]; |
15983 } | 15987 } |
15984 | 15988 |
15985 | 15989 |
15986 } } // namespace v8::internal | 15990 } } // namespace v8::internal |
OLD | NEW |