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); | |
5643 if (!maybe_copy->To(&value)) return maybe_copy; | |
5644 } else { | 5658 } else { |
5645 Representation representation = details.representation(); | 5659 Representation representation = details.representation(); |
5646 MaybeObject* maybe_storage = | 5660 value = NewStorageFor(isolate, value, representation); |
5647 value->AllocateNewStorageFor(heap, representation); | |
5648 if (!maybe_storage->To(&value)) return maybe_storage; | |
5649 } | 5661 } |
5650 copy->FastPropertyAtPut(index, value); | 5662 copy->FastPropertyAtPut(index, *value); |
5651 } | 5663 } |
5652 } else { | 5664 } else { |
5653 { MaybeObject* maybe_result = | 5665 Handle<FixedArray> names = |
5654 heap->AllocateFixedArray(copy->NumberOfLocalProperties()); | 5666 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); |
5655 if (!maybe_result->ToObject(&result)) return maybe_result; | 5667 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++) { | 5668 for (int i = 0; i < names->length(); i++) { |
5660 ASSERT(names->get(i)->IsString()); | 5669 ASSERT(names->get(i)->IsString()); |
5661 String* key_string = String::cast(names->get(i)); | 5670 Handle<String> key_string(String::cast(names->get(i))); |
5662 PropertyAttributes attributes = | 5671 PropertyAttributes attributes = |
5663 copy->GetLocalPropertyAttribute(key_string); | 5672 copy->GetLocalPropertyAttribute(*key_string); |
5664 // Only deep copy fields from the object literal expression. | 5673 // Only deep copy fields from the object literal expression. |
5665 // In particular, don't try to copy the length attribute of | 5674 // In particular, don't try to copy the length attribute of |
5666 // an array. | 5675 // an array. |
5667 if (attributes != NONE) continue; | 5676 if (attributes != NONE) continue; |
5668 Object* value = | 5677 Handle<Object> value( |
5669 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked(); | 5678 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), |
5679 isolate); | |
5670 if (value->IsJSObject()) { | 5680 if (value->IsJSObject()) { |
5671 JSObject* js_object = JSObject::cast(value); | 5681 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); |
5672 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); | 5682 // Creating object copy for literals. No strict mode needed. |
5673 if (!maybe_result->ToObject(&result)) return maybe_result; | 5683 CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty( |
5674 } | 5684 copy, key_string, result, NONE, kNonStrictMode)); |
5675 { MaybeObject* maybe_result = | |
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 } | 5685 } |
5681 } | 5686 } |
5682 } | 5687 } |
5683 | 5688 |
5684 // Deep copy local elements. | 5689 // Deep copy local elements. |
5685 // Pixel elements cannot be created using an object literal. | 5690 // Pixel elements cannot be created using an object literal. |
5686 ASSERT(!copy->HasExternalArrayElements()); | 5691 ASSERT(!copy->HasExternalArrayElements()); |
5687 switch (copy->GetElementsKind()) { | 5692 switch (copy->GetElementsKind()) { |
5688 case FAST_SMI_ELEMENTS: | 5693 case FAST_SMI_ELEMENTS: |
5689 case FAST_ELEMENTS: | 5694 case FAST_ELEMENTS: |
5690 case FAST_HOLEY_SMI_ELEMENTS: | 5695 case FAST_HOLEY_SMI_ELEMENTS: |
5691 case FAST_HOLEY_ELEMENTS: { | 5696 case FAST_HOLEY_ELEMENTS: { |
5692 FixedArray* elements = FixedArray::cast(copy->elements()); | 5697 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
5693 if (elements->map() == heap->fixed_cow_array_map()) { | 5698 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
5694 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 5699 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
5695 #ifdef DEBUG | 5700 #ifdef DEBUG |
5696 for (int i = 0; i < elements->length(); i++) { | 5701 for (int i = 0; i < elements->length(); i++) { |
5697 ASSERT(!elements->get(i)->IsJSObject()); | 5702 ASSERT(!elements->get(i)->IsJSObject()); |
5698 } | 5703 } |
5699 #endif | 5704 #endif |
5700 } else { | 5705 } else { |
5701 for (int i = 0; i < elements->length(); i++) { | 5706 for (int i = 0; i < elements->length(); i++) { |
5702 Object* value = elements->get(i); | 5707 Handle<Object> value(elements->get(i), isolate); |
5703 ASSERT(value->IsSmi() || | 5708 ASSERT(value->IsSmi() || |
5704 value->IsTheHole() || | 5709 value->IsTheHole() || |
5705 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 5710 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
Toon Verwaest
2013/08/20 09:37:13
We can only have JSObject values if we are in the
Michael Starzinger
2013/08/29 19:18:27
I see your point. I can add special treatment for
| |
5706 if (value->IsJSObject()) { | 5711 if (value->IsJSObject()) { |
5707 JSObject* js_object = JSObject::cast(value); | 5712 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); |
5708 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); | 5713 elements->set(i, *result); |
5709 if (!maybe_result->ToObject(&result)) return maybe_result; | |
5710 } | |
5711 elements->set(i, result); | |
5712 } | 5714 } |
5713 } | 5715 } |
5714 } | 5716 } |
5715 break; | 5717 break; |
5716 } | 5718 } |
5717 case DICTIONARY_ELEMENTS: { | 5719 case DICTIONARY_ELEMENTS: { |
5718 SeededNumberDictionary* element_dictionary = copy->element_dictionary(); | 5720 Handle<SeededNumberDictionary> element_dictionary( |
5721 copy->element_dictionary()); | |
5719 int capacity = element_dictionary->Capacity(); | 5722 int capacity = element_dictionary->Capacity(); |
5720 for (int i = 0; i < capacity; i++) { | 5723 for (int i = 0; i < capacity; i++) { |
5721 Object* k = element_dictionary->KeyAt(i); | 5724 Object* k = element_dictionary->KeyAt(i); |
5722 if (element_dictionary->IsKey(k)) { | 5725 if (element_dictionary->IsKey(k)) { |
5723 Object* value = element_dictionary->ValueAt(i); | 5726 Handle<Object> value(element_dictionary->ValueAt(i), isolate); |
5724 if (value->IsJSObject()) { | 5727 if (value->IsJSObject()) { |
5725 JSObject* js_object = JSObject::cast(value); | 5728 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); |
5726 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); | 5729 element_dictionary->ValueAtPut(i, *result); |
5727 if (!maybe_result->ToObject(&result)) return maybe_result; | |
5728 } | |
5729 element_dictionary->ValueAtPut(i, result); | |
5730 } | 5730 } |
5731 } | 5731 } |
5732 } | 5732 } |
5733 break; | 5733 break; |
5734 } | 5734 } |
5735 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5735 case NON_STRICT_ARGUMENTS_ELEMENTS: |
5736 UNIMPLEMENTED(); | 5736 UNIMPLEMENTED(); |
5737 break; | 5737 break; |
5738 case EXTERNAL_PIXEL_ELEMENTS: | 5738 case EXTERNAL_PIXEL_ELEMENTS: |
5739 case EXTERNAL_BYTE_ELEMENTS: | 5739 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, | 15977 #define ERROR_MESSAGES_TEXTS(C, T) T, |
15978 static const char* error_messages_[] = { | 15978 static const char* error_messages_[] = { |
15979 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 15979 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
15980 }; | 15980 }; |
15981 #undef ERROR_MESSAGES_TEXTS | 15981 #undef ERROR_MESSAGES_TEXTS |
15982 return error_messages_[reason]; | 15982 return error_messages_[reason]; |
15983 } | 15983 } |
15984 | 15984 |
15985 | 15985 |
15986 } } // namespace v8::internal | 15986 } } // namespace v8::internal |
OLD | NEW |