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 29 matching lines...) Expand all Loading... |
40 HandleScope scope(isolate); | 40 HandleScope scope(isolate); |
41 Handle<Object> data(loc->script()->name(), isolate); | 41 Handle<Object> data(loc->script()->name(), isolate); |
42 std::unique_ptr<char[]> data_str; | 42 std::unique_ptr<char[]> data_str; |
43 if (data->IsString()) | 43 if (data->IsString()) |
44 data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS); | 44 data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS); |
45 PrintF("%s:%i: %s\n", data_str.get() ? data_str.get() : "<unknown>", | 45 PrintF("%s:%i: %s\n", data_str.get() ? data_str.get() : "<unknown>", |
46 loc->start_pos(), str.get()); | 46 loc->start_pos(), str.get()); |
47 } | 47 } |
48 } | 48 } |
49 | 49 |
50 | |
51 Handle<JSMessageObject> MessageHandler::MakeMessageObject( | 50 Handle<JSMessageObject> MessageHandler::MakeMessageObject( |
52 Isolate* isolate, MessageTemplate::Template message, | 51 Isolate* isolate, MessageTemplate::Template message, |
53 MessageLocation* location, Handle<Object> argument, | 52 const MessageLocation* location, Handle<Object> argument, |
54 Handle<JSArray> stack_frames) { | 53 Handle<JSArray> stack_frames) { |
55 Factory* factory = isolate->factory(); | 54 Factory* factory = isolate->factory(); |
56 | 55 |
57 int start = -1; | 56 int start = -1; |
58 int end = -1; | 57 int end = -1; |
59 Handle<Object> script_handle = factory->undefined_value(); | 58 Handle<Object> script_handle = factory->undefined_value(); |
60 if (location != NULL) { | 59 if (location != NULL) { |
61 start = location->start_pos(); | 60 start = location->start_pos(); |
62 end = location->end_pos(); | 61 end = location->end_pos(); |
63 script_handle = Script::GetWrapper(location->script()); | 62 script_handle = Script::GetWrapper(location->script()); |
64 } else { | 63 } else { |
65 script_handle = Script::GetWrapper(isolate->factory()->empty_script()); | 64 script_handle = Script::GetWrapper(isolate->factory()->empty_script()); |
66 } | 65 } |
67 | 66 |
68 Handle<Object> stack_frames_handle = stack_frames.is_null() | 67 Handle<Object> stack_frames_handle = stack_frames.is_null() |
69 ? Handle<Object>::cast(factory->undefined_value()) | 68 ? Handle<Object>::cast(factory->undefined_value()) |
70 : Handle<Object>::cast(stack_frames); | 69 : Handle<Object>::cast(stack_frames); |
71 | 70 |
72 Handle<JSMessageObject> message_obj = factory->NewJSMessageObject( | 71 Handle<JSMessageObject> message_obj = factory->NewJSMessageObject( |
73 message, argument, start, end, script_handle, stack_frames_handle); | 72 message, argument, start, end, script_handle, stack_frames_handle); |
74 | 73 |
75 return message_obj; | 74 return message_obj; |
76 } | 75 } |
77 | 76 |
| 77 void MessageHandler::ReportMessage(Isolate* isolate, const MessageLocation* loc, |
| 78 Handle<JSMessageObject> message) { |
| 79 v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message); |
78 | 80 |
79 void MessageHandler::ReportMessage(Isolate* isolate, MessageLocation* loc, | 81 if (api_message_obj->ErrorLevel() == v8::Isolate::kMessageError) { |
80 Handle<JSMessageObject> message) { | 82 // We are calling into embedder's code which can throw exceptions. |
81 // We are calling into embedder's code which can throw exceptions. | 83 // Thus we need to save current exception state, reset it to the clean one |
82 // Thus we need to save current exception state, reset it to the clean one | 84 // and ignore scheduled exceptions callbacks can throw. |
83 // and ignore scheduled exceptions callbacks can throw. | |
84 | 85 |
85 // We pass the exception object into the message handler callback though. | 86 // We pass the exception object into the message handler callback though. |
86 Object* exception_object = isolate->heap()->undefined_value(); | 87 Object* exception_object = isolate->heap()->undefined_value(); |
87 if (isolate->has_pending_exception()) { | 88 if (isolate->has_pending_exception()) { |
88 exception_object = isolate->pending_exception(); | 89 exception_object = isolate->pending_exception(); |
89 } | 90 } |
90 Handle<Object> exception(exception_object, isolate); | 91 Handle<Object> exception(exception_object, isolate); |
91 | 92 |
92 Isolate::ExceptionScope exception_scope(isolate); | 93 Isolate::ExceptionScope exception_scope(isolate); |
93 isolate->clear_pending_exception(); | 94 isolate->clear_pending_exception(); |
94 isolate->set_external_caught_exception(false); | 95 isolate->set_external_caught_exception(false); |
95 | 96 |
96 // Turn the exception on the message into a string if it is an object. | 97 // Turn the exception on the message into a string if it is an object. |
97 if (message->argument()->IsJSObject()) { | 98 if (message->argument()->IsJSObject()) { |
98 HandleScope scope(isolate); | 99 HandleScope scope(isolate); |
99 Handle<Object> argument(message->argument(), isolate); | 100 Handle<Object> argument(message->argument(), isolate); |
100 | 101 |
101 MaybeHandle<Object> maybe_stringified; | 102 MaybeHandle<Object> maybe_stringified; |
102 Handle<Object> stringified; | 103 Handle<Object> stringified; |
103 // Make sure we don't leak uncaught internally generated Error objects. | 104 // Make sure we don't leak uncaught internally generated Error objects. |
104 if (argument->IsJSError()) { | 105 if (argument->IsJSError()) { |
105 maybe_stringified = Object::NoSideEffectsToString(isolate, argument); | 106 maybe_stringified = Object::NoSideEffectsToString(isolate, argument); |
106 } else { | 107 } else { |
107 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); | 108 v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); |
108 catcher.SetVerbose(false); | 109 catcher.SetVerbose(false); |
109 catcher.SetCaptureMessage(false); | 110 catcher.SetCaptureMessage(false); |
110 | 111 |
111 maybe_stringified = Object::ToString(isolate, argument); | 112 maybe_stringified = Object::ToString(isolate, argument); |
| 113 } |
| 114 |
| 115 if (!maybe_stringified.ToHandle(&stringified)) { |
| 116 stringified = |
| 117 isolate->factory()->NewStringFromAsciiChecked("exception"); |
| 118 } |
| 119 message->set_argument(*stringified); |
112 } | 120 } |
113 | 121 |
114 if (!maybe_stringified.ToHandle(&stringified)) { | 122 v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception); |
115 stringified = isolate->factory()->NewStringFromAsciiChecked("exception"); | 123 ReportMessageNoExceptions(isolate, loc, message, api_exception_obj); |
116 } | 124 } else { |
117 message->set_argument(*stringified); | 125 ReportMessageNoExceptions(isolate, loc, message, v8::Local<v8::Value>()); |
118 } | 126 } |
| 127 } |
119 | 128 |
| 129 void MessageHandler::ReportMessageNoExceptions( |
| 130 Isolate* isolate, const MessageLocation* loc, Handle<Object> message, |
| 131 v8::Local<v8::Value> api_exception_obj) { |
120 v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message); | 132 v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message); |
121 v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception); | 133 int error_level = api_message_obj->ErrorLevel(); |
122 | 134 |
123 Handle<TemplateList> global_listeners = | 135 Handle<TemplateList> global_listeners = |
124 isolate->factory()->message_listeners(); | 136 isolate->factory()->message_listeners(); |
125 int global_length = global_listeners->length(); | 137 int global_length = global_listeners->length(); |
126 if (global_length == 0) { | 138 if (global_length == 0) { |
127 DefaultMessageReport(isolate, loc, message); | 139 DefaultMessageReport(isolate, loc, message); |
128 if (isolate->has_scheduled_exception()) { | 140 if (isolate->has_scheduled_exception()) { |
129 isolate->clear_scheduled_exception(); | 141 isolate->clear_scheduled_exception(); |
130 } | 142 } |
131 } else { | 143 } else { |
132 for (int i = 0; i < global_length; i++) { | 144 for (int i = 0; i < global_length; i++) { |
133 HandleScope scope(isolate); | 145 HandleScope scope(isolate); |
134 if (global_listeners->get(i)->IsUndefined(isolate)) continue; | 146 if (global_listeners->get(i)->IsUndefined(isolate)) continue; |
135 FixedArray* listener = FixedArray::cast(global_listeners->get(i)); | 147 FixedArray* listener = FixedArray::cast(global_listeners->get(i)); |
136 Foreign* callback_obj = Foreign::cast(listener->get(0)); | 148 Foreign* callback_obj = Foreign::cast(listener->get(0)); |
| 149 int32_t message_levels = |
| 150 static_cast<int32_t>(Smi::cast(listener->get(2))->value()); |
| 151 if (!(message_levels & error_level)) { |
| 152 continue; |
| 153 } |
137 v8::MessageCallback callback = | 154 v8::MessageCallback callback = |
138 FUNCTION_CAST<v8::MessageCallback>(callback_obj->foreign_address()); | 155 FUNCTION_CAST<v8::MessageCallback>(callback_obj->foreign_address()); |
139 Handle<Object> callback_data(listener->get(1), isolate); | 156 Handle<Object> callback_data(listener->get(1), isolate); |
140 { | 157 { |
141 // Do not allow exceptions to propagate. | 158 // Do not allow exceptions to propagate. |
142 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); | 159 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); |
143 callback(api_message_obj, callback_data->IsUndefined(isolate) | 160 callback(api_message_obj, callback_data->IsUndefined(isolate) |
144 ? api_exception_obj | 161 ? api_exception_obj |
145 : v8::Utils::ToLocal(callback_data)); | 162 : v8::Utils::ToLocal(callback_data)); |
146 } | 163 } |
(...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 DCHECK(mode != SKIP_UNTIL_SEEN); | 1231 DCHECK(mode != SKIP_UNTIL_SEEN); |
1215 | 1232 |
1216 Handle<Object> no_caller; | 1233 Handle<Object> no_caller; |
1217 Handle<String> msg = FormatMessage(isolate, template_index, arg0, arg1, arg2); | 1234 Handle<String> msg = FormatMessage(isolate, template_index, arg0, arg1, arg2); |
1218 return ErrorUtils::Construct(isolate, constructor, constructor, msg, mode, | 1235 return ErrorUtils::Construct(isolate, constructor, constructor, msg, mode, |
1219 no_caller, false); | 1236 no_caller, false); |
1220 } | 1237 } |
1221 | 1238 |
1222 } // namespace internal | 1239 } // namespace internal |
1223 } // namespace v8 | 1240 } // namespace v8 |
OLD | NEW |