| 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 |