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 17 matching lines...) Expand all Loading... |
28 SmartArrayPointer<char> data_str; | 28 SmartArrayPointer<char> data_str; |
29 if (data->IsString()) | 29 if (data->IsString()) |
30 data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS); | 30 data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS); |
31 PrintF("%s:%i: %s\n", data_str.get() ? data_str.get() : "<unknown>", | 31 PrintF("%s:%i: %s\n", data_str.get() ? data_str.get() : "<unknown>", |
32 loc->start_pos(), str.get()); | 32 loc->start_pos(), str.get()); |
33 } | 33 } |
34 } | 34 } |
35 | 35 |
36 | 36 |
37 Handle<JSMessageObject> MessageHandler::MakeMessageObject( | 37 Handle<JSMessageObject> MessageHandler::MakeMessageObject( |
38 Isolate* isolate, | 38 Isolate* isolate, MessageTemplate::Template message, MessageLocation* loc, |
39 const char* type, | 39 Handle<Object> argument, Handle<JSArray> stack_frames) { |
40 MessageLocation* loc, | |
41 Vector< Handle<Object> > args, | |
42 Handle<JSArray> stack_frames) { | |
43 Factory* factory = isolate->factory(); | 40 Factory* factory = isolate->factory(); |
44 Handle<String> type_handle = factory->InternalizeUtf8String(type); | |
45 Handle<FixedArray> arguments_elements = | |
46 factory->NewFixedArray(args.length()); | |
47 for (int i = 0; i < args.length(); i++) { | |
48 arguments_elements->set(i, *args[i]); | |
49 } | |
50 Handle<JSArray> arguments_handle = | |
51 factory->NewJSArrayWithElements(arguments_elements); | |
52 | 41 |
53 int start = 0; | 42 int start = 0; |
54 int end = 0; | 43 int end = 0; |
55 Handle<Object> script_handle = factory->undefined_value(); | 44 Handle<Object> script_handle = factory->undefined_value(); |
56 if (loc) { | 45 if (loc) { |
57 start = loc->start_pos(); | 46 start = loc->start_pos(); |
58 end = loc->end_pos(); | 47 end = loc->end_pos(); |
59 script_handle = Script::GetWrapper(loc->script()); | 48 script_handle = Script::GetWrapper(loc->script()); |
60 } | 49 } |
61 | 50 |
62 Handle<Object> stack_frames_handle = stack_frames.is_null() | 51 Handle<Object> stack_frames_handle = stack_frames.is_null() |
63 ? Handle<Object>::cast(factory->undefined_value()) | 52 ? Handle<Object>::cast(factory->undefined_value()) |
64 : Handle<Object>::cast(stack_frames); | 53 : Handle<Object>::cast(stack_frames); |
65 | 54 |
66 Handle<JSMessageObject> message = | 55 Handle<JSMessageObject> message_obj = factory->NewJSMessageObject( |
67 factory->NewJSMessageObject(type_handle, | 56 message, argument, start, end, script_handle, stack_frames_handle); |
68 arguments_handle, | |
69 start, | |
70 end, | |
71 script_handle, | |
72 stack_frames_handle); | |
73 | 57 |
74 return message; | 58 return message_obj; |
75 } | 59 } |
76 | 60 |
77 | 61 |
78 void MessageHandler::ReportMessage(Isolate* isolate, | 62 void MessageHandler::ReportMessage(Isolate* isolate, |
79 MessageLocation* loc, | 63 MessageLocation* loc, |
80 Handle<Object> message) { | 64 Handle<Object> message) { |
81 // We are calling into embedder's code which can throw exceptions. | 65 // We are calling into embedder's code which can throw exceptions. |
82 // Thus we need to save current exception state, reset it to the clean one | 66 // Thus we need to save current exception state, reset it to the clean one |
83 // and ignore scheduled exceptions callbacks can throw. | 67 // and ignore scheduled exceptions callbacks can throw. |
84 | 68 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 if (isolate->has_scheduled_exception()) { | 106 if (isolate->has_scheduled_exception()) { |
123 isolate->clear_scheduled_exception(); | 107 isolate->clear_scheduled_exception(); |
124 } | 108 } |
125 } | 109 } |
126 } | 110 } |
127 } | 111 } |
128 | 112 |
129 | 113 |
130 Handle<String> MessageHandler::GetMessage(Isolate* isolate, | 114 Handle<String> MessageHandler::GetMessage(Isolate* isolate, |
131 Handle<Object> data) { | 115 Handle<Object> data) { |
132 Factory* factory = isolate->factory(); | |
133 Handle<String> fmt_str = | |
134 factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("$formatMessage")); | |
135 Handle<JSFunction> fun = Handle<JSFunction>::cast(Object::GetProperty( | |
136 isolate->js_builtins_object(), fmt_str).ToHandleChecked()); | |
137 Handle<JSMessageObject> message = Handle<JSMessageObject>::cast(data); | 116 Handle<JSMessageObject> message = Handle<JSMessageObject>::cast(data); |
138 Handle<Object> argv[] = { Handle<Object>(message->type(), isolate), | 117 Handle<Object> arg = Handle<Object>(message->argument(), isolate); |
139 Handle<Object>(message->arguments(), isolate) }; | 118 return MessageTemplate::FormatMessage(isolate, message->type(), arg); |
140 | |
141 MaybeHandle<Object> maybe_result = Execution::TryCall( | |
142 fun, isolate->js_builtins_object(), arraysize(argv), argv); | |
143 Handle<Object> result; | |
144 if (!maybe_result.ToHandle(&result) || !result->IsString()) { | |
145 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); | |
146 } | |
147 Handle<String> result_string = Handle<String>::cast(result); | |
148 // A string that has been obtained from JS code in this way is | |
149 // likely to be a complicated ConsString of some sort. We flatten it | |
150 // here to improve the efficiency of converting it to a C string and | |
151 // other operations that are likely to take place (see GetLocalizedMessage | |
152 // for example). | |
153 result_string = String::Flatten(result_string); | |
154 return result_string; | |
155 } | 119 } |
156 | 120 |
157 | 121 |
158 SmartArrayPointer<char> MessageHandler::GetLocalizedMessage( | 122 SmartArrayPointer<char> MessageHandler::GetLocalizedMessage( |
159 Isolate* isolate, | 123 Isolate* isolate, |
160 Handle<Object> data) { | 124 Handle<Object> data) { |
161 HandleScope scope(isolate); | 125 HandleScope scope(isolate); |
162 return GetMessage(isolate, data)->ToCString(DISALLOW_NULLS); | 126 return GetMessage(isolate, data)->ToCString(DISALLOW_NULLS); |
163 } | 127 } |
164 | 128 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 | 269 |
306 bool CallSite::IsConstructor(Isolate* isolate) { | 270 bool CallSite::IsConstructor(Isolate* isolate) { |
307 if (!receiver_->IsJSObject()) return false; | 271 if (!receiver_->IsJSObject()) return false; |
308 Handle<Object> constructor = | 272 Handle<Object> constructor = |
309 JSReceiver::GetDataProperty(Handle<JSObject>::cast(receiver_), | 273 JSReceiver::GetDataProperty(Handle<JSObject>::cast(receiver_), |
310 isolate->factory()->constructor_string()); | 274 isolate->factory()->constructor_string()); |
311 return constructor.is_identical_to(fun_); | 275 return constructor.is_identical_to(fun_); |
312 } | 276 } |
313 | 277 |
314 | 278 |
| 279 Handle<String> MessageTemplate::FormatMessage(Isolate* isolate, |
| 280 int template_index, |
| 281 Handle<Object> arg) { |
| 282 Factory* factory = isolate->factory(); |
| 283 Handle<String> fmt_str = factory->InternalizeOneByteString( |
| 284 STATIC_CHAR_VECTOR("$noSideEffectToString")); |
| 285 Handle<JSFunction> fun = Handle<JSFunction>::cast( |
| 286 Object::GetProperty(isolate->js_builtins_object(), fmt_str) |
| 287 .ToHandleChecked()); |
| 288 |
| 289 MaybeHandle<Object> maybe_result = |
| 290 Execution::TryCall(fun, isolate->js_builtins_object(), 1, &arg); |
| 291 Handle<Object> result; |
| 292 if (!maybe_result.ToHandle(&result) || !result->IsString()) { |
| 293 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); |
| 294 } |
| 295 MaybeHandle<String> maybe_result_string = MessageTemplate::FormatMessage( |
| 296 template_index, Handle<String>::cast(result), factory->empty_string(), |
| 297 factory->empty_string()); |
| 298 Handle<String> result_string; |
| 299 if (!maybe_result_string.ToHandle(&result_string)) { |
| 300 return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>")); |
| 301 } |
| 302 // 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 |
| 304 // here to improve the efficiency of converting it to a C string and |
| 305 // other operations that are likely to take place (see GetLocalizedMessage |
| 306 // for example). |
| 307 return String::Flatten(result_string); |
| 308 } |
| 309 |
| 310 |
315 MaybeHandle<String> MessageTemplate::FormatMessage(int template_index, | 311 MaybeHandle<String> MessageTemplate::FormatMessage(int template_index, |
316 Handle<String> arg0, | 312 Handle<String> arg0, |
317 Handle<String> arg1, | 313 Handle<String> arg1, |
318 Handle<String> arg2) { | 314 Handle<String> arg2) { |
319 const char* template_string; | 315 const char* template_string; |
320 switch (template_index) { | 316 switch (template_index) { |
321 #define CASE(NAME, STRING) \ | 317 #define CASE(NAME, STRING) \ |
322 case k##NAME: \ | 318 case k##NAME: \ |
323 template_string = STRING; \ | 319 template_string = STRING; \ |
324 break; | 320 break; |
325 MESSAGE_TEMPLATES(CASE) | 321 MESSAGE_TEMPLATES(CASE) |
326 #undef CASE | 322 #undef CASE |
327 case kLastMessage: | 323 case kLastMessage: |
328 default: | 324 default: |
329 UNREACHABLE(); | 325 UNREACHABLE(); |
330 template_string = ""; | 326 template_string = ""; |
331 break; | 327 break; |
332 } | 328 } |
333 | 329 |
334 Isolate* isolate = arg0->GetIsolate(); | 330 Isolate* isolate = arg0->GetIsolate(); |
335 IncrementalStringBuilder builder(isolate); | 331 IncrementalStringBuilder builder(isolate); |
336 | 332 |
337 unsigned int i = 0; | 333 unsigned int i = 0; |
338 Handle<String> args[] = {arg0, arg1, arg2}; | 334 Handle<String> args[] = {arg0, arg1, arg2}; |
339 for (const char* c = template_string; *c != '\0'; c++) { | 335 for (const char* c = template_string; *c != '\0'; c++) { |
340 if (*c == '%') { | 336 if (*c == '%') { |
341 DCHECK(i < arraysize(args)); | 337 // %% results in verbatim %. |
342 builder.AppendString(args[i++]); | 338 if (*(c + 1) == '%') { |
| 339 c++; |
| 340 builder.AppendCharacter('%'); |
| 341 } else { |
| 342 DCHECK(i < arraysize(args)); |
| 343 builder.AppendString(args[i++]); |
| 344 } |
343 } else { | 345 } else { |
344 builder.AppendCharacter(*c); | 346 builder.AppendCharacter(*c); |
345 } | 347 } |
346 } | 348 } |
347 | 349 |
348 return builder.Finish(); | 350 return builder.Finish(); |
349 } | 351 } |
350 } } // namespace v8::internal | 352 } } // namespace v8::internal |
OLD | NEW |