| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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/messages.h" | 5 #include "src/messages.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/execution.h" | 10 #include "src/execution.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 94 |
| 95 // Turn the exception on the message into a string if it is an object. | 95 // Turn the exception on the message into a string if it is an object. |
| 96 if (message->argument()->IsJSObject()) { | 96 if (message->argument()->IsJSObject()) { |
| 97 HandleScope scope(isolate); | 97 HandleScope scope(isolate); |
| 98 Handle<Object> argument(message->argument(), isolate); | 98 Handle<Object> argument(message->argument(), isolate); |
| 99 | 99 |
| 100 MaybeHandle<Object> maybe_stringified; | 100 MaybeHandle<Object> maybe_stringified; |
| 101 Handle<Object> stringified; | 101 Handle<Object> stringified; |
| 102 // Make sure we don't leak uncaught internally generated Error objects. | 102 // Make sure we don't leak uncaught internally generated Error objects. |
| 103 if (argument->IsJSError()) { | 103 if (argument->IsJSError()) { |
| 104 Handle<Object> args[] = {argument}; | 104 maybe_stringified = Object::NoSideEffectsToString(isolate, argument); |
| 105 maybe_stringified = Execution::TryCall( | |
| 106 isolate, isolate->no_side_effects_to_string_fun(), | |
| 107 isolate->factory()->undefined_value(), arraysize(args), args); | |
| 108 } else { | 105 } else { |
| 109 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); | 106 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); |
| 110 catcher.SetVerbose(false); | 107 catcher.SetVerbose(false); |
| 111 catcher.SetCaptureMessage(false); | 108 catcher.SetCaptureMessage(false); |
| 112 | 109 |
| 113 maybe_stringified = Object::ToString(isolate, argument); | 110 maybe_stringified = Object::ToString(isolate, argument); |
| 114 } | 111 } |
| 115 | 112 |
| 116 if (!maybe_stringified.ToHandle(&stringified)) { | 113 if (!maybe_stringified.ToHandle(&stringified)) { |
| 117 stringified = isolate->factory()->NewStringFromAsciiChecked("exception"); | 114 stringified = isolate->factory()->NewStringFromAsciiChecked("exception"); |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 } | 660 } |
| 664 } | 661 } |
| 665 | 662 |
| 666 RETURN_RESULT(isolate, builder.Finish(), Object); | 663 RETURN_RESULT(isolate, builder.Finish(), Object); |
| 667 } | 664 } |
| 668 | 665 |
| 669 Handle<String> MessageTemplate::FormatMessage(Isolate* isolate, | 666 Handle<String> MessageTemplate::FormatMessage(Isolate* isolate, |
| 670 int template_index, | 667 int template_index, |
| 671 Handle<Object> arg) { | 668 Handle<Object> arg) { |
| 672 Factory* factory = isolate->factory(); | 669 Factory* factory = isolate->factory(); |
| 673 Handle<String> result_string; | 670 Handle<String> result_string = Object::NoSideEffectsToString(isolate, arg); |
| 674 if (arg->IsString()) { | |
| 675 result_string = Handle<String>::cast(arg); | |
| 676 } else { | |
| 677 Handle<JSFunction> fun = isolate->no_side_effects_to_string_fun(); | |
| 678 | |
| 679 MaybeHandle<Object> maybe_result = | |
| 680 Execution::TryCall(isolate, fun, factory->undefined_value(), 1, &arg); | |
| 681 Handle<Object> result; | |
| 682 if (!maybe_result.ToHandle(&result) || !result->IsString()) { | |
| 683 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); | |
| 684 } | |
| 685 result_string = Handle<String>::cast(result); | |
| 686 } | |
| 687 MaybeHandle<String> maybe_result_string = MessageTemplate::FormatMessage( | 671 MaybeHandle<String> maybe_result_string = MessageTemplate::FormatMessage( |
| 688 template_index, result_string, factory->empty_string(), | 672 template_index, result_string, factory->empty_string(), |
| 689 factory->empty_string()); | 673 factory->empty_string()); |
| 690 if (!maybe_result_string.ToHandle(&result_string)) { | 674 if (!maybe_result_string.ToHandle(&result_string)) { |
| 691 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); | 675 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); |
| 692 } | 676 } |
| 693 // A string that has been obtained from JS code in this way is | 677 // A string that has been obtained from JS code in this way is |
| 694 // likely to be a complicated ConsString of some sort. We flatten it | 678 // likely to be a complicated ConsString of some sort. We flatten it |
| 695 // here to improve the efficiency of converting it to a C string and | 679 // here to improve the efficiency of converting it to a C string and |
| 696 // other operations that are likely to take place (see GetLocalizedMessage | 680 // other operations that are likely to take place (see GetLocalizedMessage |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 } else { | 726 } else { |
| 743 builder.AppendCharacter(*c); | 727 builder.AppendCharacter(*c); |
| 744 } | 728 } |
| 745 } | 729 } |
| 746 | 730 |
| 747 return builder.Finish(); | 731 return builder.Finish(); |
| 748 } | 732 } |
| 749 | 733 |
| 750 MaybeHandle<Object> ErrorUtils::Construct( | 734 MaybeHandle<Object> ErrorUtils::Construct( |
| 751 Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target, | 735 Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target, |
| 752 Handle<Object> message, FrameSkipMode mode, bool suppress_detailed_trace) { | 736 Handle<Object> message, FrameSkipMode mode, Handle<Object> caller, |
| 737 bool suppress_detailed_trace) { |
| 753 // 1. If NewTarget is undefined, let newTarget be the active function object, | 738 // 1. If NewTarget is undefined, let newTarget be the active function object, |
| 754 // else let newTarget be NewTarget. | 739 // else let newTarget be NewTarget. |
| 755 | 740 |
| 756 Handle<JSReceiver> new_target_recv = | 741 Handle<JSReceiver> new_target_recv = |
| 757 new_target->IsJSReceiver() ? Handle<JSReceiver>::cast(new_target) | 742 new_target->IsJSReceiver() ? Handle<JSReceiver>::cast(new_target) |
| 758 : Handle<JSReceiver>::cast(target); | 743 : Handle<JSReceiver>::cast(target); |
| 759 | 744 |
| 760 // 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%ErrorPrototype%", | 745 // 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%ErrorPrototype%", |
| 761 // « [[ErrorData]] »). | 746 // « [[ErrorData]] »). |
| 762 Handle<JSObject> err; | 747 Handle<JSObject> err; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 779 msg_string, DONT_ENUM), | 764 msg_string, DONT_ENUM), |
| 780 Object); | 765 Object); |
| 781 } | 766 } |
| 782 | 767 |
| 783 // Optionally capture a more detailed stack trace for the message. | 768 // Optionally capture a more detailed stack trace for the message. |
| 784 if (!suppress_detailed_trace) { | 769 if (!suppress_detailed_trace) { |
| 785 RETURN_ON_EXCEPTION(isolate, isolate->CaptureAndSetDetailedStackTrace(err), | 770 RETURN_ON_EXCEPTION(isolate, isolate->CaptureAndSetDetailedStackTrace(err), |
| 786 Object); | 771 Object); |
| 787 } | 772 } |
| 788 | 773 |
| 789 // When we're passed a JSFunction as new target, we can skip frames until that | |
| 790 // specific function is seen instead of unconditionally skipping the first | |
| 791 // frame. | |
| 792 Handle<Object> caller; | |
| 793 if (mode == SKIP_FIRST && new_target->IsJSFunction()) { | |
| 794 mode = SKIP_UNTIL_SEEN; | |
| 795 caller = new_target; | |
| 796 } | |
| 797 | |
| 798 // Capture a simple stack trace for the stack property. | 774 // Capture a simple stack trace for the stack property. |
| 799 RETURN_ON_EXCEPTION(isolate, | 775 RETURN_ON_EXCEPTION(isolate, |
| 800 isolate->CaptureAndSetSimpleStackTrace(err, mode, caller), | 776 isolate->CaptureAndSetSimpleStackTrace(err, mode, caller), |
| 801 Object); | 777 Object); |
| 802 | 778 |
| 803 return err; | 779 return err; |
| 804 } | 780 } |
| 805 | 781 |
| 806 namespace { | 782 namespace { |
| 807 | 783 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 IncrementalStringBuilder builder(isolate); | 847 IncrementalStringBuilder builder(isolate); |
| 872 builder.AppendString(name); | 848 builder.AppendString(name); |
| 873 builder.AppendCString(": "); | 849 builder.AppendCString(": "); |
| 874 builder.AppendString(msg); | 850 builder.AppendString(msg); |
| 875 | 851 |
| 876 Handle<String> result; | 852 Handle<String> result; |
| 877 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String); | 853 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String); |
| 878 return result; | 854 return result; |
| 879 } | 855 } |
| 880 | 856 |
| 857 namespace { |
| 858 |
| 859 Handle<String> FormatMessage(Isolate* isolate, int template_index, |
| 860 Handle<Object> arg0, Handle<Object> arg1, |
| 861 Handle<Object> arg2) { |
| 862 Handle<String> arg0_str = Object::NoSideEffectsToString(isolate, arg0); |
| 863 Handle<String> arg1_str = Object::NoSideEffectsToString(isolate, arg1); |
| 864 Handle<String> arg2_str = Object::NoSideEffectsToString(isolate, arg2); |
| 865 |
| 866 isolate->native_context()->IncrementErrorsThrown(); |
| 867 |
| 868 Handle<String> msg; |
| 869 if (!MessageTemplate::FormatMessage(template_index, arg0_str, arg1_str, |
| 870 arg2_str) |
| 871 .ToHandle(&msg)) { |
| 872 DCHECK(isolate->has_pending_exception()); |
| 873 isolate->clear_pending_exception(); |
| 874 return isolate->factory()->NewStringFromAsciiChecked("<error>"); |
| 875 } |
| 876 |
| 877 return msg; |
| 878 } |
| 879 |
| 880 } // namespace |
| 881 |
| 882 // static |
| 883 MaybeHandle<Object> ErrorUtils::MakeGenericError( |
| 884 Isolate* isolate, Handle<JSFunction> constructor, int template_index, |
| 885 Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg2, |
| 886 FrameSkipMode mode) { |
| 887 // This function used to be implemented in JavaScript, and JSEntryStub clears |
| 888 // any pending exceptions - so whenever we'd call this from C++, pending |
| 889 // exceptions would be cleared. Preserve this behavior. |
| 890 isolate->clear_pending_exception(); |
| 891 |
| 892 DCHECK(mode != SKIP_UNTIL_SEEN); |
| 893 |
| 894 Handle<Object> no_caller; |
| 895 Handle<String> msg = FormatMessage(isolate, template_index, arg0, arg1, arg2); |
| 896 return ErrorUtils::Construct(isolate, constructor, constructor, msg, mode, |
| 897 no_caller, false); |
| 898 } |
| 899 |
| 881 #define SET_CALLSITE_PROPERTY(target, key, value) \ | 900 #define SET_CALLSITE_PROPERTY(target, key, value) \ |
| 882 RETURN_ON_EXCEPTION( \ | 901 RETURN_ON_EXCEPTION( \ |
| 883 isolate, JSObject::SetOwnPropertyIgnoreAttributes( \ | 902 isolate, JSObject::SetOwnPropertyIgnoreAttributes( \ |
| 884 target, isolate->factory()->key(), value, DONT_ENUM), \ | 903 target, isolate->factory()->key(), value, DONT_ENUM), \ |
| 885 Object) | 904 Object) |
| 886 | 905 |
| 887 MaybeHandle<Object> CallSiteUtils::Construct(Isolate* isolate, | 906 MaybeHandle<Object> CallSiteUtils::Construct(Isolate* isolate, |
| 888 Handle<Object> receiver, | 907 Handle<Object> receiver, |
| 889 Handle<Object> fun, | 908 Handle<Object> fun, |
| 890 Handle<Object> pos, | 909 Handle<Object> pos, |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 builder.AppendCString(" ("); | 1177 builder.AppendCString(" ("); |
| 1159 RETURN_ON_EXCEPTION( | 1178 RETURN_ON_EXCEPTION( |
| 1160 isolate, AppendFileLocation(isolate, recv, &call_site, &builder), String); | 1179 isolate, AppendFileLocation(isolate, recv, &call_site, &builder), String); |
| 1161 builder.AppendCString(")"); | 1180 builder.AppendCString(")"); |
| 1162 | 1181 |
| 1163 RETURN_RESULT(isolate, builder.Finish(), String); | 1182 RETURN_RESULT(isolate, builder.Finish(), String); |
| 1164 } | 1183 } |
| 1165 | 1184 |
| 1166 } // namespace internal | 1185 } // namespace internal |
| 1167 } // namespace v8 | 1186 } // namespace v8 |
| OLD | NEW |