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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/execution.h" | 8 #include "src/execution.h" |
9 #include "src/heap/spaces-inl.h" | 9 #include "src/heap/spaces-inl.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 ? Handle<Object>::cast(factory->undefined_value()) | 52 ? Handle<Object>::cast(factory->undefined_value()) |
53 : Handle<Object>::cast(stack_frames); | 53 : Handle<Object>::cast(stack_frames); |
54 | 54 |
55 Handle<JSMessageObject> message_obj = factory->NewJSMessageObject( | 55 Handle<JSMessageObject> message_obj = factory->NewJSMessageObject( |
56 message, argument, start, end, script_handle, stack_frames_handle); | 56 message, argument, start, end, script_handle, stack_frames_handle); |
57 | 57 |
58 return message_obj; | 58 return message_obj; |
59 } | 59 } |
60 | 60 |
61 | 61 |
62 void MessageHandler::ReportMessage(Isolate* isolate, | 62 void MessageHandler::ReportMessage(Isolate* isolate, MessageLocation* loc, |
63 MessageLocation* loc, | 63 Handle<JSMessageObject> message) { |
64 Handle<Object> message) { | |
65 // We are calling into embedder's code which can throw exceptions. | 64 // We are calling into embedder's code which can throw exceptions. |
66 // Thus we need to save current exception state, reset it to the clean one | 65 // Thus we need to save current exception state, reset it to the clean one |
67 // and ignore scheduled exceptions callbacks can throw. | 66 // and ignore scheduled exceptions callbacks can throw. |
68 | 67 |
69 // We pass the exception object into the message handler callback though. | 68 // We pass the exception object into the message handler callback though. |
70 Object* exception_object = isolate->heap()->undefined_value(); | 69 Object* exception_object = isolate->heap()->undefined_value(); |
71 if (isolate->has_pending_exception()) { | 70 if (isolate->has_pending_exception()) { |
72 exception_object = isolate->pending_exception(); | 71 exception_object = isolate->pending_exception(); |
73 } | 72 } |
74 Handle<Object> exception_handle(exception_object, isolate); | 73 Handle<Object> exception(exception_object, isolate); |
75 | 74 |
76 Isolate::ExceptionScope exception_scope(isolate); | 75 Isolate::ExceptionScope exception_scope(isolate); |
77 isolate->clear_pending_exception(); | 76 isolate->clear_pending_exception(); |
78 isolate->set_external_caught_exception(false); | 77 isolate->set_external_caught_exception(false); |
79 | 78 |
| 79 // Turn the exception on the message into a string if it is an object. |
| 80 if (message->argument()->IsJSObject()) { |
| 81 HandleScope scope(isolate); |
| 82 Handle<Object> argument(message->argument(), isolate); |
| 83 Handle<Object> args[] = {argument}; |
| 84 MaybeHandle<Object> maybe_stringified = Execution::TryCall( |
| 85 isolate->to_detail_string_fun(), isolate->js_builtins_object(), |
| 86 arraysize(args), args); |
| 87 Handle<Object> stringified; |
| 88 if (!maybe_stringified.ToHandle(&stringified)) { |
| 89 stringified = isolate->factory()->NewStringFromAsciiChecked("exception"); |
| 90 } |
| 91 message->set_argument(*stringified); |
| 92 } |
| 93 |
80 v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message); | 94 v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message); |
81 v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception_handle); | 95 v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception); |
82 | 96 |
83 v8::NeanderArray global_listeners(isolate->factory()->message_listeners()); | 97 v8::NeanderArray global_listeners(isolate->factory()->message_listeners()); |
84 int global_length = global_listeners.length(); | 98 int global_length = global_listeners.length(); |
85 if (global_length == 0) { | 99 if (global_length == 0) { |
86 DefaultMessageReport(isolate, loc, message); | 100 DefaultMessageReport(isolate, loc, message); |
87 if (isolate->has_scheduled_exception()) { | 101 if (isolate->has_scheduled_exception()) { |
88 isolate->clear_scheduled_exception(); | 102 isolate->clear_scheduled_exception(); |
89 } | 103 } |
90 } else { | 104 } else { |
91 for (int i = 0; i < global_length; i++) { | 105 for (int i = 0; i < global_length; i++) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 JSReceiver::GetDataProperty(Handle<JSObject>::cast(receiver_), | 287 JSReceiver::GetDataProperty(Handle<JSObject>::cast(receiver_), |
274 isolate->factory()->constructor_string()); | 288 isolate->factory()->constructor_string()); |
275 return constructor.is_identical_to(fun_); | 289 return constructor.is_identical_to(fun_); |
276 } | 290 } |
277 | 291 |
278 | 292 |
279 Handle<String> MessageTemplate::FormatMessage(Isolate* isolate, | 293 Handle<String> MessageTemplate::FormatMessage(Isolate* isolate, |
280 int template_index, | 294 int template_index, |
281 Handle<Object> arg) { | 295 Handle<Object> arg) { |
282 Factory* factory = isolate->factory(); | 296 Factory* factory = isolate->factory(); |
283 Handle<String> fmt_str = factory->InternalizeOneByteString( | 297 Handle<String> result_string; |
284 STATIC_CHAR_VECTOR("$noSideEffectToString")); | 298 if (arg->IsString()) { |
285 Handle<JSFunction> fun = Handle<JSFunction>::cast( | 299 result_string = Handle<String>::cast(arg); |
286 Object::GetProperty(isolate->js_builtins_object(), fmt_str) | 300 } else { |
287 .ToHandleChecked()); | 301 Handle<String> fmt_str = factory->InternalizeOneByteString( |
| 302 STATIC_CHAR_VECTOR("$noSideEffectToString")); |
| 303 Handle<JSFunction> fun = Handle<JSFunction>::cast( |
| 304 Object::GetProperty(isolate->js_builtins_object(), fmt_str) |
| 305 .ToHandleChecked()); |
288 | 306 |
289 MaybeHandle<Object> maybe_result = | 307 MaybeHandle<Object> maybe_result = |
290 Execution::TryCall(fun, isolate->js_builtins_object(), 1, &arg); | 308 Execution::TryCall(fun, isolate->js_builtins_object(), 1, &arg); |
291 Handle<Object> result; | 309 Handle<Object> result; |
292 if (!maybe_result.ToHandle(&result) || !result->IsString()) { | 310 if (!maybe_result.ToHandle(&result) || !result->IsString()) { |
293 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); | 311 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); |
| 312 } |
| 313 result_string = Handle<String>::cast(result); |
294 } | 314 } |
295 MaybeHandle<String> maybe_result_string = MessageTemplate::FormatMessage( | 315 MaybeHandle<String> maybe_result_string = MessageTemplate::FormatMessage( |
296 template_index, Handle<String>::cast(result), factory->empty_string(), | 316 template_index, result_string, factory->empty_string(), |
297 factory->empty_string()); | 317 factory->empty_string()); |
298 Handle<String> result_string; | |
299 if (!maybe_result_string.ToHandle(&result_string)) { | 318 if (!maybe_result_string.ToHandle(&result_string)) { |
300 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); | 319 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); |
301 } | 320 } |
302 // A string that has been obtained from JS code in this way is | 321 // A string that has been obtained from JS code in this way is |
303 // likely to be a complicated ConsString of some sort. We flatten it | 322 // likely to be a complicated ConsString of some sort. We flatten it |
304 // here to improve the efficiency of converting it to a C string and | 323 // here to improve the efficiency of converting it to a C string and |
305 // other operations that are likely to take place (see GetLocalizedMessage | 324 // other operations that are likely to take place (see GetLocalizedMessage |
306 // for example). | 325 // for example). |
307 return String::Flatten(result_string); | 326 return String::Flatten(result_string); |
308 } | 327 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 builder.AppendString(args[i++]); | 362 builder.AppendString(args[i++]); |
344 } | 363 } |
345 } else { | 364 } else { |
346 builder.AppendCharacter(*c); | 365 builder.AppendCharacter(*c); |
347 } | 366 } |
348 } | 367 } |
349 | 368 |
350 return builder.Finish(); | 369 return builder.Finish(); |
351 } | 370 } |
352 } } // namespace v8::internal | 371 } } // namespace v8::internal |
OLD | NEW |