Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: src/builtins/builtins-callsite.cc

Issue 2174723002: Move CallSite.toString to C++ (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@callsite-port
Patch Set: Rebase Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/js/messages.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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) {
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 if (!script->IsScript()) {
218 return isolate->factory()->undefined_value();
219 }
220
221 Handle<String> str;
222 ASSIGN_RETURN_ON_EXCEPTION(
223 isolate, str, FormatEvalOrigin(isolate, Handle<Script>::cast(script)),
224 String);
225
226 return str;
227 }
228
202 } // namespace 229 } // namespace
203 230
204 BUILTIN(CallSitePrototypeGetEvalOrigin) { 231 BUILTIN(CallSitePrototypeGetEvalOrigin) {
205 HandleScope scope(isolate); 232 HandleScope scope(isolate);
206 CHECK_CALLSITE(recv, "getEvalOrigin"); 233 CHECK_CALLSITE(recv, "getEvalOrigin");
207 234 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 if (!script->IsScript()) {
223 return *isolate->factory()->undefined_value();
224 }
225
226 RETURN_RESULT_OR_FAILURE(
227 isolate, FormatEvalOrigin(isolate, Handle<Script>::cast(script)));
228 } 235 }
229 236
230 BUILTIN(CallSitePrototypeGetFileName) { 237 BUILTIN(CallSitePrototypeGetFileName) {
231 HandleScope scope(isolate); 238 HandleScope scope(isolate);
232 CHECK_CALLSITE(recv, "getFileName"); 239 CHECK_CALLSITE(recv, "getFileName");
233 240
234 CallSite call_site(isolate, recv); 241 CallSite call_site(isolate, recv);
235 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); 242 CHECK(call_site.IsJavaScript() || call_site.IsWasm());
236 return *call_site.GetFileName(); 243 return *call_site.GetFileName();
237 } 244 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol(); 324 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol();
318 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, 325 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
319 JSObject::GetProperty(recv, symbol)); 326 JSObject::GetProperty(recv, symbol));
320 327
321 if (*receiver == isolate->heap()->call_site_constructor_symbol()) 328 if (*receiver == isolate->heap()->call_site_constructor_symbol())
322 return *isolate->factory()->undefined_value(); 329 return *isolate->factory()->undefined_value();
323 330
324 return *receiver; 331 return *receiver;
325 } 332 }
326 333
334 namespace {
335
336 MaybeHandle<Object> GetTypeName(Isolate* isolate, Handle<JSObject> object) {
337 Handle<Object> receiver;
338 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol();
339 ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
340 JSObject::GetProperty(object, symbol), Object);
341
342 // TODO(jgruber): Check for strict/constructor here as above.
343
344 if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate))
345 return isolate->factory()->null_value();
346
347 if (receiver->IsJSProxy()) return isolate->factory()->Proxy_string();
348
349 Handle<JSReceiver> receiver_object =
350 Object::ToObject(isolate, receiver).ToHandleChecked();
351 return JSReceiver::GetConstructorName(receiver_object);
352 }
353
354 } // namespace
355
327 BUILTIN(CallSitePrototypeGetTypeName) { 356 BUILTIN(CallSitePrototypeGetTypeName) {
328 HandleScope scope(isolate); 357 HandleScope scope(isolate);
329 CHECK_CALLSITE(recv, "getTypeName"); 358 CHECK_CALLSITE(recv, "getTypeName");
330 359 RETURN_RESULT_OR_FAILURE(isolate, GetTypeName(isolate, recv));
331 Handle<Object> receiver;
332 Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol();
333 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
334 JSObject::GetProperty(recv, symbol));
335
336 // TODO(jgruber): Check for strict/constructor here as above.
337
338 if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate))
339 return *isolate->factory()->null_value();
340
341 if (receiver->IsJSProxy()) return *isolate->factory()->Proxy_string();
342
343 Handle<JSReceiver> receiver_object =
344 Object::ToObject(isolate, receiver).ToHandleChecked();
345 return *JSReceiver::GetConstructorName(receiver_object);
346 } 360 }
347 361
348 BUILTIN(CallSitePrototypeIsConstructor) { 362 BUILTIN(CallSitePrototypeIsConstructor) {
349 HandleScope scope(isolate); 363 HandleScope scope(isolate);
350 CHECK_CALLSITE(recv, "isConstructor"); 364 CHECK_CALLSITE(recv, "isConstructor");
351 365
352 CallSite call_site(isolate, recv); 366 CallSite call_site(isolate, recv);
353 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); 367 CHECK(call_site.IsJavaScript() || call_site.IsWasm());
354 return isolate->heap()->ToBoolean(call_site.IsConstructor()); 368 return isolate->heap()->ToBoolean(call_site.IsConstructor());
355 } 369 }
(...skipping 18 matching lines...) Expand all
374 388
375 BUILTIN(CallSitePrototypeIsToplevel) { 389 BUILTIN(CallSitePrototypeIsToplevel) {
376 HandleScope scope(isolate); 390 HandleScope scope(isolate);
377 CHECK_CALLSITE(recv, "isToplevel"); 391 CHECK_CALLSITE(recv, "isToplevel");
378 392
379 CallSite call_site(isolate, recv); 393 CallSite call_site(isolate, recv);
380 CHECK(call_site.IsJavaScript() || call_site.IsWasm()); 394 CHECK(call_site.IsJavaScript() || call_site.IsWasm());
381 return isolate->heap()->ToBoolean(call_site.IsToplevel()); 395 return isolate->heap()->ToBoolean(call_site.IsToplevel());
382 } 396 }
383 397
398 namespace {
399
400 bool IsNonEmptyString(Handle<Object> object) {
401 return (object->IsString() && String::cast(*object)->length() > 0);
402 }
403
404 MaybeHandle<JSObject> AppendWasmToString(Isolate* isolate,
405 Handle<JSObject> recv,
406 CallSite* call_site,
407 IncrementalStringBuilder* builder) {
408 Handle<Object> name = call_site->GetFunctionName();
409 if (name->IsNull(isolate)) {
410 builder->AppendCString("<WASM UNNAMED>");
411 } else {
412 DCHECK(name->IsString());
413 builder->AppendString(Handle<String>::cast(name));
414 }
415
416 builder->AppendCString(" (<WASM>[");
417
418 Handle<String> ix = isolate->factory()->NumberToString(
419 handle(Smi::FromInt(call_site->wasm_func_index()), isolate));
420 builder->AppendString(ix);
421
422 builder->AppendCString("]+");
423
424 Handle<Object> pos;
425 ASSIGN_RETURN_ON_EXCEPTION(
426 isolate, pos, JSObject::GetProperty(
427 recv, isolate->factory()->call_site_position_symbol()),
428 JSObject);
429 DCHECK(pos->IsNumber());
430 builder->AppendString(isolate->factory()->NumberToString(pos));
431 builder->AppendCString(")");
432
433 return recv;
434 }
435
436 MaybeHandle<JSObject> AppendFileLocation(Isolate* isolate,
437 Handle<JSObject> recv,
438 CallSite* call_site,
439 IncrementalStringBuilder* builder) {
440 if (call_site->IsNative()) {
441 builder->AppendCString("native");
442 return recv;
443 }
444
445 Handle<Object> file_name = call_site->GetScriptNameOrSourceUrl();
446 if (!file_name->IsString() && call_site->IsEval()) {
447 Handle<Object> eval_origin;
448 ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_origin,
449 GetEvalOrigin(isolate, recv), JSObject);
450 DCHECK(eval_origin->IsString());
451 builder->AppendString(Handle<String>::cast(eval_origin));
452 builder->AppendCString(", "); // Expecting source position to follow.
453 }
454
455 if (IsNonEmptyString(file_name)) {
456 builder->AppendString(Handle<String>::cast(file_name));
457 } else {
458 // Source code does not originate from a file and is not native, but we
459 // can still get the source position inside the source string, e.g. in
460 // an eval string.
461 builder->AppendCString("<anonymous>");
462 }
463
464 int line_number = call_site->GetLineNumber();
465 if (line_number != -1) {
466 builder->AppendCharacter(':');
467 Handle<String> line_string = isolate->factory()->NumberToString(
468 handle(Smi::FromInt(line_number), isolate), isolate);
469 builder->AppendString(line_string);
470
471 int column_number = call_site->GetColumnNumber();
472 if (column_number != -1) {
473 builder->AppendCharacter(':');
474 Handle<String> column_string = isolate->factory()->NumberToString(
475 handle(Smi::FromInt(column_number), isolate), isolate);
476 builder->AppendString(column_string);
477 }
478 }
479
480 return recv;
481 }
482
483 int StringIndexOf(Isolate* isolate, Handle<String> subject,
484 Handle<String> pattern) {
485 if (pattern->length() > subject->length()) return -1;
486 return String::IndexOf(isolate, subject, pattern, 0);
487 }
488
489 // Returns true iff
490 // 1. the subject ends with '.' + pattern, or
491 // 2. subject == pattern.
492 bool StringEndsWithMethodName(Isolate* isolate, Handle<String> subject,
493 Handle<String> pattern) {
494 if (String::Equals(subject, pattern)) return true;
495
496 FlatStringReader subject_reader(isolate, String::Flatten(subject));
497 FlatStringReader pattern_reader(isolate, String::Flatten(pattern));
498
499 int pattern_index = pattern_reader.length() - 1;
500 int subject_index = subject_reader.length() - 1;
501 for (int i = 0; i <= pattern_reader.length(); i++) { // Iterate over len + 1.
502 if (subject_index < 0) {
503 return false;
504 }
505
506 const uc32 subject_char = subject_reader.Get(subject_index);
507 if (i == pattern_reader.length()) {
508 if (subject_char != '.') return false;
509 } else if (subject_char != pattern_reader.Get(pattern_index)) {
510 return false;
511 }
512
513 pattern_index--;
514 subject_index--;
515 }
516
517 return true;
518 }
519
520 MaybeHandle<JSObject> AppendMethodCall(Isolate* isolate, Handle<JSObject> recv,
521 CallSite* call_site,
522 IncrementalStringBuilder* builder) {
523 Handle<Object> type_name;
524 ASSIGN_RETURN_ON_EXCEPTION(isolate, type_name, GetTypeName(isolate, recv),
525 JSObject);
526 Handle<Object> method_name = call_site->GetMethodName();
527 Handle<Object> function_name = call_site->GetFunctionName();
528
529 if (IsNonEmptyString(function_name)) {
530 Handle<String> function_string = Handle<String>::cast(function_name);
531 if (type_name->IsString()) {
532 Handle<String> type_string = Handle<String>::cast(type_name);
533 bool starts_with_type_name =
534 (StringIndexOf(isolate, function_string, type_string) == 0);
535 if (!starts_with_type_name) {
536 builder->AppendString(type_string);
537 builder->AppendCharacter('.');
538 }
539 }
540 builder->AppendString(function_string);
541
542 if (IsNonEmptyString(method_name)) {
543 Handle<String> method_string = Handle<String>::cast(method_name);
544 if (!StringEndsWithMethodName(isolate, function_string, method_string)) {
545 builder->AppendCString(" [as ");
546 builder->AppendString(method_string);
547 builder->AppendCharacter(']');
548 }
549 }
550 } else {
551 builder->AppendString(Handle<String>::cast(type_name));
552 builder->AppendCharacter('.');
553 if (IsNonEmptyString(method_name)) {
554 builder->AppendString(Handle<String>::cast(method_name));
555 } else {
556 builder->AppendCString("<anonymous>");
557 }
558 }
559
560 return recv;
561 }
562
563 } // namespace
564
384 BUILTIN(CallSitePrototypeToString) { 565 BUILTIN(CallSitePrototypeToString) {
385 HandleScope scope(isolate); 566 HandleScope scope(isolate);
386 // TODO(jgruber) 567 CHECK_CALLSITE(recv, "toString");
387 return *isolate->factory()->undefined_value(); 568
569 IncrementalStringBuilder builder(isolate);
570
571 CallSite call_site(isolate, recv);
572 if (call_site.IsWasm()) {
573 RETURN_FAILURE_ON_EXCEPTION(
574 isolate, AppendWasmToString(isolate, recv, &call_site, &builder));
575 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
576 }
577
578 DCHECK(!call_site.IsWasm());
579 Handle<Object> function_name = call_site.GetFunctionName();
580
581 const bool is_toplevel = call_site.IsToplevel();
582 const bool is_constructor = call_site.IsConstructor();
583 const bool is_method_call = !(is_toplevel || is_constructor);
584
585 if (is_method_call) {
586 RETURN_FAILURE_ON_EXCEPTION(
587 isolate, AppendMethodCall(isolate, recv, &call_site, &builder));
588 } else if (is_constructor) {
589 builder.AppendCString("new ");
590 if (IsNonEmptyString(function_name)) {
591 builder.AppendString(Handle<String>::cast(function_name));
592 } else {
593 builder.AppendCString("<anonymous>");
594 }
595 } else if (IsNonEmptyString(function_name)) {
596 builder.AppendString(Handle<String>::cast(function_name));
597 } else {
598 RETURN_FAILURE_ON_EXCEPTION(
599 isolate, AppendFileLocation(isolate, recv, &call_site, &builder));
600 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
601 }
602
603 builder.AppendCString(" (");
604 RETURN_FAILURE_ON_EXCEPTION(
605 isolate, AppendFileLocation(isolate, recv, &call_site, &builder));
606 builder.AppendCString(")");
607
608 RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
388 } 609 }
389 610
390 #undef CHECK_CALLSITE 611 #undef CHECK_CALLSITE
391 612
392 } // namespace internal 613 } // namespace internal
393 } // namespace v8 614 } // namespace v8
OLDNEW
« no previous file with comments | « src/bootstrapper.cc ('k') | src/js/messages.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698