OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 #include "src/string-builder.h" | 8 #include "src/string-builder.h" |
9 #include "src/wasm/wasm-module.h" | 9 #include "src/wasm/wasm-module.h" |
10 | 10 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 } | 192 } |
193 } | 193 } |
194 builder.AppendCString(")"); | 194 builder.AppendCString(")"); |
195 } | 195 } |
196 | 196 |
197 Handle<String> result; | 197 Handle<String> result; |
198 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String); | 198 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String); |
199 return result; | 199 return result; |
200 } | 200 } |
201 | 201 |
202 MaybeHandle<Object> GetEvalOrigin(Isolate* isolate, Handle<JSObject> object) { | |
Yang
2016/07/28 06:04:10
I'm inclined to move these helper functions to the
jgruber
2016/07/28 09:21:50
Yes that's a good point. I ran into the same thing
Yang
2016/07/28 09:55:00
I'm fine with having that in a separate CL.
| |
203 CallSite call_site(isolate, object); | |
204 if (call_site.IsWasm()) return isolate->factory()->undefined_value(); | |
205 | |
206 // Retrieve the function's script object. | |
207 | |
208 Handle<Object> function_obj; | |
209 Handle<Symbol> symbol = isolate->factory()->call_site_function_symbol(); | |
210 ASSIGN_RETURN_ON_EXCEPTION(isolate, function_obj, | |
211 JSObject::GetProperty(object, symbol), Object); | |
212 | |
213 DCHECK(function_obj->IsJSFunction()); | |
214 Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj); | |
215 Handle<Object> script = handle(function->shared()->script(), isolate); | |
216 | |
217 Handle<String> str; | |
218 ASSIGN_RETURN_ON_EXCEPTION( | |
219 isolate, str, FormatEvalOrigin(isolate, Handle<Script>::cast(script)), | |
220 String); | |
221 | |
222 return str; | |
223 } | |
224 | |
202 } // namespace | 225 } // namespace |
203 | 226 |
204 BUILTIN(CallSitePrototypeGetEvalOrigin) { | 227 BUILTIN(CallSitePrototypeGetEvalOrigin) { |
205 HandleScope scope(isolate); | 228 HandleScope scope(isolate); |
206 CHECK_CALLSITE(recv, "getEvalOrigin"); | 229 CHECK_CALLSITE(recv, "getEvalOrigin"); |
207 | 230 RETURN_RESULT_OR_FAILURE(isolate, GetEvalOrigin(isolate, recv)); |
208 CallSite call_site(isolate, recv); | |
209 if (call_site.IsWasm()) return *isolate->factory()->undefined_value(); | |
210 | |
211 // Retrieve the function's script object. | |
212 | |
213 Handle<Object> function_obj; | |
214 Handle<Symbol> symbol = isolate->factory()->call_site_function_symbol(); | |
215 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, function_obj, | |
216 JSObject::GetProperty(recv, symbol)); | |
217 | |
218 DCHECK(function_obj->IsJSFunction()); | |
219 Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj); | |
220 Handle<Object> script = handle(function->shared()->script(), isolate); | |
221 | |
222 RETURN_RESULT_OR_FAILURE( | |
223 isolate, FormatEvalOrigin(isolate, Handle<Script>::cast(script))); | |
224 } | 231 } |
225 | 232 |
226 BUILTIN(CallSitePrototypeGetFileName) { | 233 BUILTIN(CallSitePrototypeGetFileName) { |
227 HandleScope scope(isolate); | 234 HandleScope scope(isolate); |
228 CHECK_CALLSITE(recv, "getFileName"); | 235 CHECK_CALLSITE(recv, "getFileName"); |
229 | 236 |
230 CallSite call_site(isolate, recv); | 237 CallSite call_site(isolate, recv); |
231 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 238 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); |
232 return *call_site.GetFileName(); | 239 return *call_site.GetFileName(); |
233 } | 240 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol(); | 320 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol(); |
314 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 321 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, |
315 JSObject::GetProperty(recv, symbol)); | 322 JSObject::GetProperty(recv, symbol)); |
316 | 323 |
317 if (*receiver == isolate->heap()->call_site_constructor_symbol()) | 324 if (*receiver == isolate->heap()->call_site_constructor_symbol()) |
318 return *isolate->factory()->undefined_value(); | 325 return *isolate->factory()->undefined_value(); |
319 | 326 |
320 return *receiver; | 327 return *receiver; |
321 } | 328 } |
322 | 329 |
330 namespace { | |
331 | |
332 MaybeHandle<Object> GetTypeName(Isolate* isolate, Handle<JSObject> object) { | |
Yang
2016/07/28 06:04:10
Same here.
jgruber
2016/07/28 09:21:49
Acknowledged.
| |
333 Handle<Object> receiver; | |
334 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol(); | |
335 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver, | |
336 JSObject::GetProperty(object, symbol), Object); | |
337 | |
338 // TODO(jgruber): Check for strict/constructor here as above. | |
339 | |
340 if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) | |
341 return isolate->factory()->null_value(); | |
342 | |
343 if (receiver->IsJSProxy()) return isolate->factory()->Proxy_string(); | |
344 | |
345 Handle<JSReceiver> receiver_object = | |
346 Object::ToObject(isolate, receiver).ToHandleChecked(); | |
347 return JSReceiver::GetConstructorName(receiver_object); | |
348 } | |
349 | |
350 } // namespace | |
351 | |
323 BUILTIN(CallSitePrototypeGetTypeName) { | 352 BUILTIN(CallSitePrototypeGetTypeName) { |
324 HandleScope scope(isolate); | 353 HandleScope scope(isolate); |
325 CHECK_CALLSITE(recv, "getTypeName"); | 354 CHECK_CALLSITE(recv, "getTypeName"); |
326 | 355 RETURN_RESULT_OR_FAILURE(isolate, GetTypeName(isolate, recv)); |
327 Handle<Object> receiver; | |
328 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol(); | |
329 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | |
330 JSObject::GetProperty(recv, symbol)); | |
331 | |
332 // TODO(jgruber): Check for strict/constructor here as above. | |
333 | |
334 if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) | |
335 return *isolate->factory()->null_value(); | |
336 | |
337 if (receiver->IsJSProxy()) return *isolate->factory()->Proxy_string(); | |
338 | |
339 Handle<JSReceiver> receiver_object = | |
340 Object::ToObject(isolate, receiver).ToHandleChecked(); | |
341 return *JSReceiver::GetConstructorName(receiver_object); | |
342 } | 356 } |
343 | 357 |
344 BUILTIN(CallSitePrototypeIsConstructor) { | 358 BUILTIN(CallSitePrototypeIsConstructor) { |
345 HandleScope scope(isolate); | 359 HandleScope scope(isolate); |
346 CHECK_CALLSITE(recv, "isConstructor"); | 360 CHECK_CALLSITE(recv, "isConstructor"); |
347 | 361 |
348 CallSite call_site(isolate, recv); | 362 CallSite call_site(isolate, recv); |
349 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 363 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); |
350 return isolate->heap()->ToBoolean(call_site.IsConstructor()); | 364 return isolate->heap()->ToBoolean(call_site.IsConstructor()); |
351 } | 365 } |
(...skipping 18 matching lines...) Expand all Loading... | |
370 | 384 |
371 BUILTIN(CallSitePrototypeIsToplevel) { | 385 BUILTIN(CallSitePrototypeIsToplevel) { |
372 HandleScope scope(isolate); | 386 HandleScope scope(isolate); |
373 CHECK_CALLSITE(recv, "isToplevel"); | 387 CHECK_CALLSITE(recv, "isToplevel"); |
374 | 388 |
375 CallSite call_site(isolate, recv); | 389 CallSite call_site(isolate, recv); |
376 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 390 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); |
377 return isolate->heap()->ToBoolean(call_site.IsToplevel()); | 391 return isolate->heap()->ToBoolean(call_site.IsToplevel()); |
378 } | 392 } |
379 | 393 |
394 namespace { | |
395 | |
396 MaybeHandle<JSObject> AppendWasmToString(Isolate* isolate, | |
397 Handle<JSObject> recv, | |
398 CallSite* call_site, | |
399 IncrementalStringBuilder* builder) { | |
400 Handle<Object> name = call_site->GetFunctionName(); | |
401 if (name->IsNull(isolate)) { | |
402 builder->AppendCString("<WASM UNNAMED>"); | |
403 } else { | |
404 DCHECK(name->IsString()); | |
405 builder->AppendString(Handle<String>::cast(name)); | |
406 } | |
407 | |
408 builder->AppendCString(" (<WASM>["); | |
409 | |
410 Handle<String> ix = isolate->factory()->NumberToString( | |
411 handle(Smi::FromInt(call_site->wasm_func_index()), isolate)); | |
412 builder->AppendString(ix); | |
413 | |
414 builder->AppendCString("]+"); | |
415 | |
416 Handle<Object> pos; | |
417 ASSIGN_RETURN_ON_EXCEPTION( | |
418 isolate, pos, JSObject::GetProperty( | |
419 recv, isolate->factory()->call_site_position_symbol()), | |
420 JSObject); | |
421 DCHECK(pos->IsNumber()); | |
422 builder->AppendString(isolate->factory()->NumberToString(pos)); | |
423 builder->AppendCString(")"); | |
424 | |
425 return recv; | |
426 } | |
427 | |
428 MaybeHandle<JSObject> AppendFileLocation(Isolate* isolate, | |
429 Handle<JSObject> recv, | |
430 CallSite* call_site, | |
431 IncrementalStringBuilder* builder) { | |
432 if (call_site->IsNative()) { | |
433 builder->AppendCString("native"); | |
434 return recv; | |
435 } | |
436 | |
437 Handle<Object> file_name = call_site->GetScriptNameOrSourceUrl(); | |
438 if (!file_name->IsString() && call_site->IsEval()) { | |
439 Handle<Object> eval_origin; | |
440 ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_origin, | |
441 GetEvalOrigin(isolate, recv), JSObject); | |
442 DCHECK(eval_origin->IsString()); | |
443 builder->AppendString(Handle<String>::cast(eval_origin)); | |
444 builder->AppendCString(", "); // Expecting source position to follow. | |
445 } | |
446 | |
447 if (file_name->IsString()) { | |
448 builder->AppendString(Handle<String>::cast(file_name)); | |
449 } else { | |
450 // Source code does not originate from a file and is not native, but we | |
451 // can still get the source position inside the source string, e.g. in | |
452 // an eval string. | |
453 builder->AppendCString("<anonymous>"); | |
454 } | |
455 | |
456 int line_number = call_site->GetLineNumber(); | |
457 if (line_number != -1) { | |
458 builder->AppendCharacter(':'); | |
459 Handle<String> line_string = isolate->factory()->NumberToString( | |
460 handle(Smi::FromInt(line_number), isolate), isolate); | |
461 builder->AppendString(line_string); | |
462 | |
463 int column_number = call_site->GetColumnNumber(); | |
464 if (column_number != -1) { | |
465 builder->AppendCharacter(':'); | |
466 Handle<String> column_string = isolate->factory()->NumberToString( | |
467 handle(Smi::FromInt(column_number), isolate), isolate); | |
468 builder->AppendString(column_string); | |
469 } | |
470 } | |
471 | |
472 return recv; | |
473 } | |
474 | |
475 int StringIndexOf(Isolate* isolate, Handle<String> subject, | |
476 Handle<String> pattern) { | |
477 if (pattern->length() > subject->length()) return -1; | |
478 return String::IndexOf(isolate, subject, pattern, 0); | |
479 } | |
480 | |
481 MaybeHandle<JSObject> AppendMethodCall(Isolate* isolate, Handle<JSObject> recv, | |
482 CallSite* call_site, | |
483 IncrementalStringBuilder* builder) { | |
484 Handle<Object> type_name; | |
485 ASSIGN_RETURN_ON_EXCEPTION(isolate, type_name, GetTypeName(isolate, recv), | |
486 JSObject); | |
487 Handle<Object> method_name = call_site->GetMethodName(); | |
488 Handle<Object> function_name = call_site->GetFunctionName(); | |
489 | |
490 if (function_name->IsString()) { | |
491 Handle<String> function_string = Handle<String>::cast(function_name); | |
492 if (type_name->IsString()) { | |
493 Handle<String> type_string = Handle<String>::cast(type_name); | |
494 bool starts_with_type_name = | |
495 (StringIndexOf(isolate, function_string, type_string) == 0); | |
496 if (!starts_with_type_name) { | |
497 builder->AppendString(type_string); | |
498 builder->AppendCharacter('.'); | |
499 } | |
500 } | |
501 builder->AppendString(function_string); | |
502 | |
503 if (method_name->IsString()) { | |
504 Handle<String> method_string = Handle<String>::cast(method_name); | |
505 Handle<String> dot_method_string; | |
506 ASSIGN_RETURN_ON_EXCEPTION( | |
507 isolate, dot_method_string, | |
508 isolate->factory()->NewConsString(isolate->factory()->dot_string(), | |
Yang
2016/07/28 06:04:10
This looks really inefficient to me. We want to kn
jgruber
2016/07/28 09:21:49
Done. This also fixes a bug (already present in th
| |
509 method_string), | |
510 JSObject); | |
511 | |
512 bool ends_with_method_name = | |
513 (StringIndexOf(isolate, function_string, dot_method_string) == | |
514 function_string->length() - dot_method_string->length()); | |
515 if (!ends_with_method_name) { | |
516 builder->AppendCString(" [as "); | |
517 builder->AppendString(method_string); | |
518 builder->AppendCharacter(']'); | |
519 } | |
520 } | |
521 } else { | |
522 builder->AppendString(Handle<String>::cast(type_name)); | |
523 builder->AppendCharacter('.'); | |
524 if (method_name->IsString()) { | |
525 builder->AppendString(Handle<String>::cast(method_name)); | |
526 } else { | |
527 builder->AppendCString("<anonymous>"); | |
528 } | |
529 } | |
530 | |
531 return recv; | |
532 } | |
533 | |
534 } // namespace | |
535 | |
380 BUILTIN(CallSitePrototypeToString) { | 536 BUILTIN(CallSitePrototypeToString) { |
381 HandleScope scope(isolate); | 537 HandleScope scope(isolate); |
382 // TODO(jgruber) | 538 CHECK_CALLSITE(recv, "toString"); |
383 return *isolate->factory()->undefined_value(); | 539 |
540 IncrementalStringBuilder builder(isolate); | |
541 | |
542 CallSite call_site(isolate, recv); | |
543 if (call_site.IsWasm()) { | |
544 RETURN_FAILURE_ON_EXCEPTION( | |
545 isolate, AppendWasmToString(isolate, recv, &call_site, &builder)); | |
546 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish()); | |
547 } | |
548 | |
549 DCHECK(!call_site.IsWasm()); | |
550 Handle<Object> function_name = call_site.GetFunctionName(); | |
551 | |
552 const bool is_toplevel = call_site.IsToplevel(); | |
553 const bool is_constructor = call_site.IsConstructor(); | |
554 const bool is_method_call = !(is_toplevel || is_constructor); | |
555 | |
556 if (is_method_call) { | |
557 RETURN_FAILURE_ON_EXCEPTION( | |
558 isolate, AppendMethodCall(isolate, recv, &call_site, &builder)); | |
559 } else if (is_constructor) { | |
560 builder.AppendCString("new "); | |
561 if (function_name->IsString()) { | |
562 builder.AppendString(Handle<String>::cast(function_name)); | |
563 } else { | |
564 builder.AppendCString("<anonymous>"); | |
565 } | |
566 } else if (function_name->IsString()) { | |
567 builder.AppendString(Handle<String>::cast(function_name)); | |
568 } else { | |
569 RETURN_FAILURE_ON_EXCEPTION( | |
570 isolate, AppendFileLocation(isolate, recv, &call_site, &builder)); | |
571 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish()); | |
572 } | |
573 | |
574 builder.AppendCString(" ("); | |
575 RETURN_FAILURE_ON_EXCEPTION( | |
576 isolate, AppendFileLocation(isolate, recv, &call_site, &builder)); | |
577 builder.AppendCString(")"); | |
578 | |
579 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish()); | |
384 } | 580 } |
385 | 581 |
386 #undef CHECK_CALLSITE | 582 #undef CHECK_CALLSITE |
387 | 583 |
388 } // namespace internal | 584 } // namespace internal |
389 } // namespace v8 | 585 } // namespace v8 |
OLD | NEW |