v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
call-site-info.cc
Go to the documentation of this file.
1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <optional>
8
9#include "src/base/strings.h"
13
14#if V8_ENABLE_WEBASSEMBLY
16#endif // V8_ENABLE_WEBASSEMBLY
17
18namespace v8::internal {
19
21 if (!IsAsync()) return false;
22 Tagged<JSFunction> fun = Cast<JSFunction>(function());
23 return fun == fun->native_context()->promise_all();
24}
25
27 if (!IsAsync()) return false;
28 Tagged<JSFunction> fun = Cast<JSFunction>(function());
29 return fun == fun->native_context()->promise_all_settled();
30}
31
33 if (!IsAsync()) return false;
34 Tagged<JSFunction> fun = Cast<JSFunction>(function());
35 return fun == fun->native_context()->promise_any();
36}
37
39#if V8_ENABLE_WEBASSEMBLY
40 if (IsBuiltin()) return true;
41#endif
42 if (auto script = GetScript()) {
43 return script.value()->type() == Script::Type::kNative;
44 }
45 return false;
46}
47
49 if (auto script = GetScript()) {
50 return script.value()->compilation_type() == Script::CompilationType::kEval;
51 }
52 return false;
53}
54
56#if V8_ENABLE_WEBASSEMBLY
57 if (IsWasm()) return false;
58 if (IsBuiltin()) return false;
59#endif // V8_ENABLE_WEBASSEMBLY
60 return GetSharedFunctionInfo()->IsUserJavaScript();
61}
62
64#if V8_ENABLE_WEBASSEMBLY
65 if (IsWasm()) return false;
66 if (IsBuiltin()) return false;
67#endif // V8_ENABLE_WEBASSEMBLY
68 return !IsToplevel() && !IsConstructor();
69}
70
72 return IsJSGlobalProxy(receiver_or_instance()) ||
73 IsNullOrUndefined(receiver_or_instance());
74}
75
76// static
78 Isolate* isolate = info->GetIsolate();
79#if V8_ENABLE_WEBASSEMBLY
80 if (info->IsWasm() && !info->IsAsmJsWasm()) {
81 return 1;
82 }
83#endif // V8_ENABLE_WEBASSEMBLY
85 if (GetScript(isolate, info).ToHandle(&script)) {
86 int position = GetSourcePosition(info);
87 int line_number = Script::GetLineNumber(script, position) + 1;
88 if (script->HasSourceURLComment()) {
89 line_number -= script->line_offset();
90 }
91 return line_number;
92 }
94}
95
96// static
98 Isolate* isolate = callsite_info->GetIsolate();
99 int position = GetSourcePosition(callsite_info);
100#if V8_ENABLE_WEBASSEMBLY
101 if (callsite_info->IsWasm() && !callsite_info->IsAsmJsWasm()) {
102 return position + 1;
103 }
104#endif // V8_ENABLE_WEBASSEMBLY
106 if (GetScript(isolate, callsite_info).ToHandle(&script)) {
107 Script::PositionInfo position_info;
108 Script::GetPositionInfo(script, position, &position_info);
109 int column_number = position_info.column + 1;
110 if (script->HasSourceURLComment() &&
111 position_info.line == script->line_offset()) {
112 column_number -= script->column_offset();
113 }
114 return column_number;
115 }
117}
118
119// static
121 Isolate* isolate = info->GetIsolate();
122#if V8_ENABLE_WEBASSEMBLY
123 if (info->IsWasm() && !info->IsAsmJsWasm()) {
124 return 1;
125 }
126#endif // V8_ENABLE_WEBASSEMBLY
128 if (!GetScript(isolate, info).ToHandle(&script)) {
130 }
131#if V8_ENABLE_WEBASSEMBLY
132 if (info->IsAsmJsWasm()) {
133 auto* module = info->GetWasmInstance()->module();
134 auto func_index = info->GetWasmFunctionIndex();
135 int position = wasm::GetSourcePosition(module, func_index, 0,
136 info->IsAsmJsAtNumberConversion());
137 return Script::GetLineNumber(script, position) + 1;
138 }
139#endif // V8_ENABLE_WEBASSEMBLY
140 int position = info->GetSharedFunctionInfo()->function_token_position();
141 return Script::GetLineNumber(script, position) + 1;
142}
143
144// static
146 Isolate* isolate = info->GetIsolate();
147#if V8_ENABLE_WEBASSEMBLY
148 if (info->IsWasm() && !info->IsAsmJsWasm()) {
149 auto* module = info->GetWasmInstance()->module();
150 auto func_index = info->GetWasmFunctionIndex();
151 return GetWasmFunctionOffset(module, func_index);
152 }
153#endif // V8_ENABLE_WEBASSEMBLY
155 if (!GetScript(isolate, info).ToHandle(&script)) {
157 }
158#if V8_ENABLE_WEBASSEMBLY
159 if (info->IsAsmJsWasm()) {
160 auto* module = info->GetWasmInstance()->module();
161 auto func_index = info->GetWasmFunctionIndex();
162 int position = wasm::GetSourcePosition(module, func_index, 0,
163 info->IsAsmJsAtNumberConversion());
164 return Script::GetColumnNumber(script, position) + 1;
165 }
166#endif // V8_ENABLE_WEBASSEMBLY
167 int position = info->GetSharedFunctionInfo()->function_token_position();
168 return Script::GetColumnNumber(script, position) + 1;
169}
170
172 if (auto script = GetScript()) {
173 return script.value()->id();
174 }
176}
177
179 if (auto script = GetScript()) {
180 return script.value()->name();
181 }
182 return ReadOnlyRoots(GetIsolate()).null_value();
183}
184
186 if (auto script = GetScript()) {
187 return script.value()->GetNameOrSourceURL();
188 }
189 return ReadOnlyRoots(GetIsolate()).null_value();
190}
191
193 if (auto script = GetScript()) {
194 if (script.value()->HasValidSource()) {
195 return script.value()->source();
196 }
197 }
198 return ReadOnlyRoots(GetIsolate()).null_value();
199}
200
202 if (auto script = GetScript()) {
203 return script.value()->source_mapping_url();
204 }
205 return ReadOnlyRoots(GetIsolate()).null_value();
206}
207
208// static
212 Isolate* isolate = info->GetIsolate();
213 if (!GetScript(isolate, info).ToHandle(&script)) {
214 return isolate->factory()->empty_string();
215 }
216 if (script->HasValidSource()) {
217 return Script::GetScriptHash(isolate, script, /*forceForInspector:*/ false);
218 }
219 return isolate->factory()->empty_string();
220}
221
222namespace {
223
224MaybeHandle<String> FormatEvalOrigin(Isolate* isolate,
225 DirectHandle<Script> script) {
226 Handle<Object> sourceURL(script->GetNameOrSourceURL(), isolate);
227 if (IsString(*sourceURL)) return Cast<String>(sourceURL);
228
229 IncrementalStringBuilder builder(isolate);
230 builder.AppendCStringLiteral("eval at ");
231 if (script->has_eval_from_shared()) {
232 DirectHandle<SharedFunctionInfo> eval_shared(script->eval_from_shared(),
233 isolate);
234 auto eval_name = SharedFunctionInfo::DebugName(isolate, eval_shared);
235 if (eval_name->length() != 0) {
236 builder.AppendString(eval_name);
237 } else {
238 builder.AppendCStringLiteral("<anonymous>");
239 }
240 if (IsScript(eval_shared->script())) {
241 DirectHandle<Script> eval_script(Cast<Script>(eval_shared->script()),
242 isolate);
243 builder.AppendCStringLiteral(" (");
244 if (eval_script->compilation_type() == Script::CompilationType::kEval) {
245 // Eval script originated from another eval.
246 DirectHandle<String> str;
247 ASSIGN_RETURN_ON_EXCEPTION(isolate, str,
248 FormatEvalOrigin(isolate, eval_script));
249 builder.AppendString(str);
250 } else {
251 // eval script originated from "real" source.
252 DirectHandle<Object> eval_script_name(eval_script->name(), isolate);
253 if (IsString(*eval_script_name)) {
254 builder.AppendString(Cast<String>(eval_script_name));
255 Script::PositionInfo info;
256 if (Script::GetPositionInfo(eval_script,
257 Script::GetEvalPosition(isolate, script),
259 builder.AppendCharacter(':');
260 builder.AppendInt(info.line + 1);
261 builder.AppendCharacter(':');
262 builder.AppendInt(info.column + 1);
263 }
264 } else {
265 builder.AppendCStringLiteral("unknown source");
266 }
267 }
268 builder.AppendCharacter(')');
269 }
270 } else {
271 builder.AppendCStringLiteral("<anonymous>");
272 }
273 return indirect_handle(builder.Finish().ToHandleChecked(), isolate);
274}
275
276} // namespace
277
278// static
281 auto isolate = info->GetIsolate();
283 if (!GetScript(isolate, info).ToHandle(&script) ||
284 script->compilation_type() != Script::CompilationType::kEval) {
285 return isolate->factory()->undefined_value();
286 }
287 return FormatEvalOrigin(isolate, script).ToHandleChecked();
288}
289
290// static
293 Isolate* isolate = info->GetIsolate();
294#if V8_ENABLE_WEBASSEMBLY
295 if (info->IsWasm()) {
296 DirectHandle<WasmModuleObject> module_object(
297 info->GetWasmInstance()->module_object(), isolate);
298 uint32_t func_index = info->GetWasmFunctionIndex();
300 if (WasmModuleObject::GetFunctionNameOrNull(isolate, module_object,
301 func_index)
302 .ToHandle(&name)) {
303 return name;
304 }
305 return isolate->factory()->null_value();
306 }
307 if (info->IsBuiltin()) {
308 Builtin builtin = Builtins::FromInt(Cast<Smi>(info->function()).value());
309 return isolate->factory()->NewStringFromAsciiChecked(
310 Builtins::NameForStackTrace(isolate, builtin));
311 }
312#endif // V8_ENABLE_WEBASSEMBLY
313 DirectHandle<JSFunction> function(Cast<JSFunction>(info->function()),
314 isolate);
315 if (function->shared()->HasBuiltinId()) {
316 Builtin builtin = function->shared()->builtin_id();
317 const char* maybe_known_name =
318 Builtins::NameForStackTrace(isolate, builtin);
319 if (maybe_known_name) {
320 // This is for cases where using the builtin's name allows us to print
321 // e.g. "String.indexOf", instead of just "indexOf" which is what we
322 // would infer below.
323 return isolate->factory()->NewStringFromAsciiChecked(maybe_known_name);
324 }
325 }
327 if (name->length() != 0) return name;
328 if (info->IsEval()) return isolate->factory()->eval_string();
329 return isolate->factory()->null_value();
330}
331
332// static
335 Isolate* isolate = info->GetIsolate();
336#if V8_ENABLE_WEBASSEMBLY
337 if (info->IsWasm()) {
339 isolate,
340 direct_handle(info->GetWasmInstance()->trusted_data(isolate), isolate),
341 info->GetWasmFunctionIndex());
342 }
343 if (info->IsBuiltin()) {
344 return Cast<String>(GetFunctionName(info));
345 }
346#endif // V8_ENABLE_WEBASSEMBLY
347 DirectHandle<JSFunction> function(Cast<JSFunction>(info->function()),
348 isolate);
350 if (name->length() == 0 && info->IsEval()) {
351 name = isolate->factory()->eval_string();
352 }
353 return name;
354}
355
356namespace {
357
358Tagged<PrimitiveHeapObject> InferMethodNameFromFastObject(
361 ReadOnlyRoots roots(isolate);
362 Tagged<Map> map = receiver->map();
363 Tagged<DescriptorArray> descriptors = map->instance_descriptors(isolate);
364 for (auto i : map->IterateOwnDescriptors()) {
365 Tagged<PrimitiveHeapObject> key = descriptors->GetKey(i);
366 if (IsSymbol(key)) continue;
367 auto details = descriptors->GetDetails(i);
368 if (details.IsDontEnum()) continue;
370 if (details.location() == PropertyLocation::kField) {
371 auto field_index = FieldIndex::ForPropertyIndex(
372 map, details.field_index(), details.representation());
373 if (field_index.is_double()) continue;
374 value = receiver->RawFastPropertyAt(isolate, field_index);
375 } else {
376 value = descriptors->GetStrongValue(i);
377 }
378 if (value != fun) {
379 if (!IsAccessorPair(value)) continue;
380 auto pair = Cast<AccessorPair>(value);
381 if (pair->getter() != fun && pair->setter() != fun) continue;
382 }
383 if (name != key) {
384 name = IsUndefined(name, isolate)
385 ? key
386 : Tagged<PrimitiveHeapObject>(roots.null_value());
387 }
388 }
389 return name;
390}
391
392template <typename Dictionary>
393Tagged<PrimitiveHeapObject> InferMethodNameFromDictionary(
394 Isolate* isolate, Tagged<Dictionary> dictionary, Tagged<JSFunction> fun,
396 ReadOnlyRoots roots(isolate);
397 for (auto i : dictionary->IterateEntries()) {
399 if (!dictionary->ToKey(roots, i, &key)) continue;
400 if (IsSymbol(key)) continue;
401 auto details = dictionary->DetailsAt(i);
402 if (details.IsDontEnum()) continue;
403 auto value = dictionary->ValueAt(i);
404 if (value != fun) {
405 if (!IsAccessorPair(value)) continue;
406 auto pair = Cast<AccessorPair>(value);
407 if (pair->getter() != fun && pair->setter() != fun) continue;
408 }
409 if (name != key) {
410 name = IsUndefined(name, isolate)
412 : Tagged<PrimitiveHeapObject>(roots.null_value());
413 }
414 }
415 return name;
416}
417
418Tagged<PrimitiveHeapObject> InferMethodName(Isolate* isolate,
420 Tagged<JSFunction> fun) {
422 ReadOnlyRoots roots(isolate);
423 Tagged<PrimitiveHeapObject> name = roots.undefined_value();
424 for (PrototypeIterator it(isolate, receiver, kStartAtReceiver); !it.IsAtEnd();
425 it.Advance()) {
426 auto current = it.GetCurrent();
427 if (!IsJSObject(current)) break;
428 auto object = Cast<JSObject>(current);
429 if (IsAccessCheckNeeded(object)) break;
430 if (object->HasFastProperties()) {
431 name = InferMethodNameFromFastObject(isolate, object, fun, name);
432 } else if (IsJSGlobalObject(object)) {
433 name = InferMethodNameFromDictionary(
434 isolate,
435 Cast<JSGlobalObject>(object)->global_dictionary(kAcquireLoad), fun,
436 name);
438 name = InferMethodNameFromDictionary(
439 isolate, object->property_dictionary_swiss(), fun, name);
440 } else {
441 name = InferMethodNameFromDictionary(
442 isolate, object->property_dictionary(), fun, name);
443 }
444 }
445 if (IsUndefined(name, isolate)) return roots.null_value();
446 return name;
447}
448
449} // namespace
450
451// static
454 Isolate* isolate = info->GetIsolate();
455 DirectHandle<Object> receiver_or_instance(info->receiver_or_instance(),
456 isolate);
457#if V8_ENABLE_WEBASSEMBLY
458 if (info->IsWasm()) return isolate->factory()->null_value();
459#endif // V8_ENABLE_WEBASSEMBLY
460 if (IsNullOrUndefined(*receiver_or_instance, isolate)) {
461 return isolate->factory()->null_value();
462 }
463
464 DirectHandle<JSFunction> function(Cast<JSFunction>(info->function()),
465 isolate);
466 // Class members initializer function is not a method.
467 if (IsClassMembersInitializerFunction(function->shared()->kind())) {
468 return isolate->factory()->null_value();
469 }
470
472 Object::ToObject(isolate, receiver_or_instance).ToHandleChecked();
473 Handle<String> name(function->shared()->Name(), isolate);
474 name = String::Flatten(isolate, name);
475
476 // ES2015 gives getters and setters name prefixes which must
477 // be stripped to find the property name.
478 if (name->HasOneBytePrefix(base::CStrVector("get ")) ||
479 name->HasOneBytePrefix(base::CStrVector("set "))) {
480 name = isolate->factory()->NewProperSubString(name, 4, name->length());
481 } else if (name->length() == 0) {
482 // The function doesn't have a meaningful "name" property, however
483 // the parser does store an inferred name "o.foo" for the common
484 // case of `o.foo = function() {...}`, so see if we can derive a
485 // property name to guess from that.
486 name = handle(function->shared()->inferred_name(), isolate);
487 for (int index = name->length(); --index >= 0;) {
488 if (name->Get(index, isolate) == '.') {
489 name = isolate->factory()->NewProperSubString(name, index + 1,
490 name->length());
491 break;
492 }
493 }
494 }
495
496 if (name->length() != 0) {
497 PropertyKey key(isolate, Cast<Name>(name));
498 LookupIterator it(isolate, receiver, key,
500 if (it.state() == LookupIterator::DATA) {
501 if (it.GetDataValue().is_identical_to(function)) {
502 return name;
503 }
504 } else if (it.state() == LookupIterator::ACCESSOR) {
505 DirectHandle<Object> accessors = it.GetAccessors();
506 if (IsAccessorPair(*accessors)) {
507 auto pair = Cast<AccessorPair>(accessors);
508 if (pair->getter() == *function || pair->setter() == *function) {
509 return name;
510 }
511 }
512 }
513 }
514
515 return direct_handle(InferMethodName(isolate, *receiver, *function), isolate);
516}
517
518// static
521 Isolate* isolate = info->GetIsolate();
522 if (!info->IsMethodCall()) {
523 return isolate->factory()->null_value();
524 }
526 Object::ToObject(isolate,
527 direct_handle(info->receiver_or_instance(), isolate))
528 .ToHandleChecked();
529 if (IsJSProxy(*receiver)) {
530 return isolate->factory()->Proxy_string();
531 }
532 if (IsJSFunction(*receiver)) {
534 DirectHandle<String> class_name = JSFunction::GetDebugName(function);
535 if (class_name->length() != 0) {
536 return class_name;
537 }
538 }
540}
541
542#if V8_ENABLE_WEBASSEMBLY
543uint32_t CallSiteInfo::GetWasmFunctionIndex() const {
544 DCHECK(IsWasm());
545 return Smi::ToInt(Cast<Smi>(function()));
546}
547
548Tagged<WasmInstanceObject> CallSiteInfo::GetWasmInstance() const {
549 DCHECK(IsWasm());
550 return Cast<WasmInstanceObject>(receiver_or_instance());
551}
552
553// static
554DirectHandle<Object> CallSiteInfo::GetWasmModuleName(
555 DirectHandle<CallSiteInfo> info) {
556 Isolate* isolate = info->GetIsolate();
557 if (info->IsWasm()) {
558 DirectHandle<String> name;
559 auto module_object =
560 direct_handle(info->GetWasmInstance()->module_object(), isolate);
561 if (WasmModuleObject::GetModuleNameOrNull(isolate, module_object)
562 .ToHandle(&name)) {
563 return name;
564 }
565 }
566 return isolate->factory()->null_value();
567}
568#endif // V8_ENABLE_WEBASSEMBLY
569
570// static
572 if (info->flags() & kIsSourcePositionComputed) {
573 return info->code_offset_or_source_position();
574 }
575 DCHECK(!info->IsPromiseAll());
576 DCHECK(!info->IsPromiseAllSettled());
577 DCHECK(!info->IsPromiseAny());
578 int source_position =
579 ComputeSourcePosition(info, info->code_offset_or_source_position());
580 info->set_code_offset_or_source_position(source_position);
581 info->set_flags(info->flags() | kIsSourcePositionComputed);
582 return source_position;
583}
584
585// static
587 MessageLocation* location) {
588 Isolate* isolate = info->GetIsolate();
589#if V8_ENABLE_WEBASSEMBLY
590 if (info->IsWasm()) {
591 int pos = GetSourcePosition(info);
592 Handle<Script> script(info->GetWasmInstance()->module_object()->script(),
593 isolate);
594 *location = MessageLocation(script, pos, pos + 1);
595 return true;
596 }
597 if (info->IsBuiltin()) {
598 return false;
599 }
600#endif // V8_ENABLE_WEBASSEMBLY
601
602 Handle<SharedFunctionInfo> shared(info->GetSharedFunctionInfo(), isolate);
603 if (!shared->IsSubjectToDebugging()) return false;
604 Handle<Script> script(Cast<Script>(shared->script()), isolate);
605 if (IsUndefined(script->source())) return false;
606 if (info->flags() & kIsSourcePositionComputed ||
607 (shared->HasBytecodeArray() &&
608 shared->GetBytecodeArray(isolate)->HasSourcePositionTable())) {
609 int pos = GetSourcePosition(info);
610 *location = MessageLocation(script, pos, pos + 1, shared);
611 } else {
612 int code_offset = info->code_offset_or_source_position();
613 *location = MessageLocation(script, shared, code_offset);
614 }
615 return true;
616}
617
618// static
620 int offset) {
621 Isolate* isolate = info->GetIsolate();
622#if V8_ENABLE_WEBASSEMBLY
623#if V8_ENABLE_DRUMBRAKE
624 if (info->IsWasmInterpretedFrame()) {
625 auto module = info->GetWasmInstance()->module();
626 uint32_t func_index = info->GetWasmFunctionIndex();
627 return wasm::GetSourcePosition(module, func_index, offset,
628 info->IsAsmJsAtNumberConversion());
629 } else {
630#endif // V8_ENABLE_DRUMBRAKE
631 if (info->IsWasm()) {
632 auto module = info->GetWasmInstance()->trusted_data(isolate)->module();
633 uint32_t func_index = info->GetWasmFunctionIndex();
634 return wasm::GetSourcePosition(module, func_index, offset,
635 info->IsAsmJsAtNumberConversion());
636 }
637#if V8_ENABLE_DRUMBRAKE
638 }
639#endif // V8_ENABLE_DRUMBRAKE
640 if (info->IsBuiltin()) {
641 return 0;
642 }
643#endif // V8_ENABLE_WEBASSEMBLY
644 DirectHandle<SharedFunctionInfo> shared(info->GetSharedFunctionInfo(),
645 isolate);
647 Tagged<HeapObject> code = info->code_object(isolate);
648 DCHECK(IsCode(code) || IsBytecodeArray(code));
649 return Cast<AbstractCode>(code)->SourcePosition(isolate, offset);
650}
651
652std::optional<Tagged<Script>> CallSiteInfo::GetScript() const {
653#if V8_ENABLE_WEBASSEMBLY
654 if (IsWasm()) {
655 return GetWasmInstance()
656 ->trusted_data(GetIsolate())
657 ->module_object()
658 ->script();
659 }
660 if (IsBuiltin()) {
661 return std::nullopt;
662 }
663#endif // V8_ENABLE_WEBASSEMBLY
664 Tagged<Object> script = GetSharedFunctionInfo()->script();
665 if (IsScript(script)) return Cast<Script>(script);
666 return std::nullopt;
667}
668
670#if V8_ENABLE_WEBASSEMBLY
671 DCHECK(!IsWasm());
672 DCHECK(!IsBuiltin());
673#endif // V8_ENABLE_WEBASSEMBLY
674 return Cast<JSFunction>(function())->shared();
675}
676
677// static
679 Isolate* isolate, DirectHandle<CallSiteInfo> info) {
680 if (auto script = info->GetScript()) {
681 return direct_handle(*script, isolate);
682 }
683 return kNullMaybeHandle;
684}
685
686namespace {
687
688bool IsNonEmptyString(DirectHandle<Object> object) {
689 return (IsString(*object) && Cast<String>(*object)->length() > 0);
690}
691
692void AppendFileLocation(Isolate* isolate, DirectHandle<CallSiteInfo> frame,
693 IncrementalStringBuilder* builder) {
694 DirectHandle<Object> script_name_or_source_url(
695 frame->GetScriptNameOrSourceURL(), isolate);
696 if (!IsString(*script_name_or_source_url) && frame->IsEval()) {
697 builder->AppendString(Cast<String>(CallSiteInfo::GetEvalOrigin(frame)));
698 // Expecting source position to follow.
699 builder->AppendCStringLiteral(", ");
700 }
701
702 if (IsNonEmptyString(script_name_or_source_url)) {
703 builder->AppendString(Cast<String>(script_name_or_source_url));
704 } else {
705 // Source code does not originate from a file and is not native, but we
706 // can still get the source position inside the source string, e.g. in
707 // an eval string.
708 builder->AppendCStringLiteral("<anonymous>");
709 }
710
711 int line_number = CallSiteInfo::GetLineNumber(frame);
712 if (line_number != Message::kNoLineNumberInfo) {
713 builder->AppendCharacter(':');
714 builder->AppendInt(line_number);
715
716 int column_number = CallSiteInfo::GetColumnNumber(frame);
717 if (column_number != Message::kNoColumnInfo) {
718 builder->AppendCharacter(':');
719 builder->AppendInt(column_number);
720 }
721 }
722}
723
724// Returns true iff
725// 1. the subject ends with '.' + pattern or ' ' + pattern, or
726// 2. subject == pattern.
727bool StringEndsWithMethodName(Isolate* isolate, DirectHandle<String> subject,
728 DirectHandle<String> pattern) {
729 if (String::Equals(isolate, subject, pattern)) return true;
730
731 FlatStringReader subject_reader(isolate, String::Flatten(isolate, subject));
732 FlatStringReader pattern_reader(isolate, String::Flatten(isolate, pattern));
733
734 int pattern_index = pattern_reader.length() - 1;
735 int subject_index = subject_reader.length() - 1;
736 // Iterate over len + 1.
737 for (uint32_t i = 0; i <= pattern_reader.length(); i++) {
738 if (subject_index < 0) {
739 return false;
740 }
741
742 const base::uc32 subject_char = subject_reader.Get(subject_index);
743 if (i == pattern_reader.length()) {
744 if (subject_char != '.' && subject_char != ' ') return false;
745 } else if (subject_char != pattern_reader.Get(pattern_index)) {
746 return false;
747 }
748
749 pattern_index--;
750 subject_index--;
751 }
752
753 return true;
754}
755
756void AppendMethodCall(Isolate* isolate, DirectHandle<CallSiteInfo> frame,
757 IncrementalStringBuilder* builder) {
758 DirectHandle<Object> type_name = CallSiteInfo::GetTypeName(frame);
759 DirectHandle<Object> method_name = CallSiteInfo::GetMethodName(frame);
760 DirectHandle<Object> function_name = CallSiteInfo::GetFunctionName(frame);
761
762 if (IsNonEmptyString(function_name)) {
763 DirectHandle<String> function_string = Cast<String>(function_name);
764 if (IsNonEmptyString(type_name)) {
765 DirectHandle<String> type_string = Cast<String>(type_name);
766 if (String::IsIdentifier(isolate, function_string) &&
767 !String::Equals(isolate, function_string, type_string)) {
768 builder->AppendString(type_string);
769 builder->AppendCharacter('.');
770 }
771 }
772 builder->AppendString(function_string);
773
774 if (IsNonEmptyString(method_name)) {
775 DirectHandle<String> method_string = Cast<String>(method_name);
776 if (!StringEndsWithMethodName(isolate, function_string, method_string)) {
777 builder->AppendCStringLiteral(" [as ");
778 builder->AppendString(method_string);
779 builder->AppendCharacter(']');
780 }
781 }
782 } else {
783 if (IsNonEmptyString(type_name)) {
784 builder->AppendString(Cast<String>(type_name));
785 builder->AppendCharacter('.');
786 }
787 if (IsNonEmptyString(method_name)) {
788 builder->AppendString(Cast<String>(method_name));
789 } else {
790 builder->AppendCStringLiteral("<anonymous>");
791 }
792 }
793}
794
795void SerializeJSStackFrame(Isolate* isolate, DirectHandle<CallSiteInfo> frame,
796 IncrementalStringBuilder* builder) {
797 DirectHandle<Object> function_name = CallSiteInfo::GetFunctionName(frame);
798 if (frame->IsAsync()) {
799 builder->AppendCStringLiteral("async ");
800 if (frame->IsPromiseAll() || frame->IsPromiseAny() ||
801 frame->IsPromiseAllSettled()) {
802 builder->AppendCStringLiteral("Promise.");
803 builder->AppendString(Cast<String>(function_name));
804 builder->AppendCStringLiteral(" (index ");
805 builder->AppendInt(CallSiteInfo::GetSourcePosition(frame));
806 builder->AppendCharacter(')');
807 return;
808 }
809 }
810 if (frame->IsMethodCall()) {
811 AppendMethodCall(isolate, frame, builder);
812 } else if (frame->IsConstructor()) {
813 builder->AppendCStringLiteral("new ");
814 if (IsNonEmptyString(function_name)) {
815 builder->AppendString(Cast<String>(function_name));
816 } else {
817 builder->AppendCStringLiteral("<anonymous>");
818 }
819 } else if (IsNonEmptyString(function_name)) {
820 builder->AppendString(Cast<String>(function_name));
821 } else {
822 AppendFileLocation(isolate, frame, builder);
823 return;
824 }
825 builder->AppendCStringLiteral(" (");
826 AppendFileLocation(isolate, frame, builder);
827 builder->AppendCharacter(')');
828}
829
830#if V8_ENABLE_WEBASSEMBLY
831void SerializeWasmStackFrame(Isolate* isolate, DirectHandle<CallSiteInfo> frame,
832 IncrementalStringBuilder* builder) {
833 DirectHandle<Object> module_name = CallSiteInfo::GetWasmModuleName(frame);
834 DirectHandle<Object> function_name = CallSiteInfo::GetFunctionName(frame);
835 const bool has_name = !IsNull(*module_name) || !IsNull(*function_name);
836 if (has_name) {
837 if (IsNull(*module_name)) {
838 builder->AppendString(Cast<String>(function_name));
839 } else {
840 builder->AppendString(Cast<String>(module_name));
841 if (!IsNull(*function_name)) {
842 builder->AppendCharacter('.');
843 builder->AppendString(Cast<String>(function_name));
844 }
845 }
846 builder->AppendCStringLiteral(" (");
847 }
848
849 DirectHandle<Object> url(frame->GetScriptNameOrSourceURL(), isolate);
850 if (IsNonEmptyString(url)) {
851 builder->AppendString(Cast<String>(url));
852 } else {
853 builder->AppendCStringLiteral("<anonymous>");
854 }
855 builder->AppendCharacter(':');
856
857 const int wasm_func_index = frame->GetWasmFunctionIndex();
858 builder->AppendCStringLiteral("wasm-function[");
859 builder->AppendInt(wasm_func_index);
860 builder->AppendCStringLiteral("]:");
861
862 char buffer[16];
863 SNPrintF(base::ArrayVector(buffer), "0x%x",
865 builder->AppendCString(buffer);
866
867 if (has_name) builder->AppendCharacter(')');
868}
869
870void SerializeBuiltinStackFrame(Isolate* isolate,
871 DirectHandle<CallSiteInfo> frame,
872 IncrementalStringBuilder* builder) {
873 builder->AppendString(Cast<String>(CallSiteInfo::GetFunctionName(frame)));
874 builder->AppendCStringLiteral(" (<anonymous>)");
875}
876#endif // V8_ENABLE_WEBASSEMBLY
877
878} // namespace
879
881 IncrementalStringBuilder* builder) {
882#if V8_ENABLE_WEBASSEMBLY
883 if (frame->IsWasm() && !frame->IsAsmJsWasm()) {
884 SerializeWasmStackFrame(isolate, frame, builder);
885 return;
886 }
887 if (frame->IsBuiltin()) {
888 SerializeBuiltinStackFrame(isolate, frame, builder);
889 return;
890 }
891#endif // V8_ENABLE_WEBASSEMBLY
892 SerializeJSStackFrame(isolate, frame, builder);
893}
894
896 Isolate* isolate, DirectHandle<CallSiteInfo> frame) {
897 IncrementalStringBuilder builder(isolate);
898 SerializeCallSiteInfo(isolate, frame, &builder);
899 return builder.Finish();
900}
901
902} // namespace v8::internal
SourcePosition pos
static const int kNoLineNumberInfo
Definition v8-message.h:198
static const int kNoScriptIdInfo
Definition v8-message.h:200
static const int kNoColumnInfo
Definition v8-message.h:199
static V8_EXPORT_PRIVATE const char * NameForStackTrace(Isolate *isolate, Builtin builtin)
Definition builtins.cc:233
static constexpr Builtin FromInt(int id)
Definition builtins.h:140
static DirectHandle< String > GetScriptHash(DirectHandle< CallSiteInfo > info)
static int GetEnclosingColumnNumber(DirectHandle< CallSiteInfo > info)
static V8_EXPORT_PRIVATE int GetLineNumber(DirectHandle< CallSiteInfo > info)
Tagged< Object > GetScriptName() const
Tagged< SharedFunctionInfo > GetSharedFunctionInfo() const
static Handle< PrimitiveHeapObject > GetEvalOrigin(DirectHandle< CallSiteInfo > info)
static DirectHandle< String > GetFunctionDebugName(DirectHandle< CallSiteInfo > info)
static int ComputeSourcePosition(DirectHandle< CallSiteInfo > info, int offset)
std::optional< Tagged< Script > > GetScript() const
static V8_EXPORT_PRIVATE int GetColumnNumber(DirectHandle< CallSiteInfo > info)
Tagged< Object > GetScriptSource() const
static int GetEnclosingLineNumber(DirectHandle< CallSiteInfo > info)
static bool ComputeLocation(DirectHandle< CallSiteInfo > info, MessageLocation *location)
Tagged< Object > GetScriptSourceMappingURL() const
static DirectHandle< Object > GetTypeName(DirectHandle< CallSiteInfo > info)
static int GetSourcePosition(DirectHandle< CallSiteInfo > info)
static V8_EXPORT_PRIVATE DirectHandle< PrimitiveHeapObject > GetFunctionName(DirectHandle< CallSiteInfo > info)
static DirectHandle< Object > GetMethodName(DirectHandle< CallSiteInfo > info)
Tagged< Object > GetScriptNameOrSourceURL() const
static FieldIndex ForPropertyIndex(Tagged< Map > map, int index, Representation representation=Representation::Tagged())
MaybeDirectHandle< String > Finish()
v8::internal::Factory * factory()
Definition isolate.h:1527
static DirectHandle< String > GetDebugName(DirectHandle< JSFunction > function)
static DirectHandle< String > GetConstructorName(Isolate *isolate, DirectHandle< JSReceiver > receiver)
static V8_WARN_UNUSED_RESULT HandleType< JSReceiver >::MaybeType ToObject(Isolate *isolate, HandleType< T > object, const char *method_name=nullptr)
static DirectHandle< String > GetScriptHash(Isolate *isolate, DirectHandle< Script > script, bool forceForInspector)
Definition objects.cc:4717
static V8_EXPORT_PRIVATE int GetLineNumber(DirectHandle< Script > script, int code_offset)
Definition objects.cc:4698
static bool GetPositionInfo(DirectHandle< Script > script, int position, PositionInfo *info, OffsetFlag offset_flag=OffsetFlag::kWithOffset)
Definition objects.cc:4367
static int GetColumnNumber(DirectHandle< Script > script, int code_offset)
Definition objects.cc:4686
static int GetEvalPosition(Isolate *isolate, DirectHandle< Script > script)
Definition objects.cc:4294
static void EnsureSourcePositionsAvailable(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared_info)
static Handle< String > DebugName(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared)
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
static bool IsIdentifier(Isolate *isolate, DirectHandle< String > str)
Definition string.cc:1789
bool Equals(Tagged< String > other) const
Definition string-inl.h:535
static MaybeDirectHandle< String > GetFunctionNameOrNull(Isolate *, DirectHandle< WasmModuleObject >, uint32_t func_index)
static MaybeDirectHandle< String > GetModuleNameOrNull(Isolate *, DirectHandle< WasmModuleObject >)
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
Definition globals.h:242
Handle< SharedFunctionInfo > info
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:291
int32_t offset
TNode< Object > receiver
SharedFunctionInfoRef shared
std::string pattern
int position
Definition liveedit.cc:290
int SNPrintF(Vector< char > str, const char *format,...)
Definition strings.cc:20
constexpr Vector< T > ArrayVector(T(&arr)[N])
Definition vector.h:354
uint32_t uc32
Definition strings.h:19
Vector< const char > CStrVector(const char *data)
Definition vector.h:331
int GetSourcePosition(const WasmModule *module, uint32_t func_index, uint32_t byte_offset, bool is_at_number_conversion)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
constexpr NullMaybeHandleType kNullMaybeHandle
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
Tagged(T object) -> Tagged< T >
V8_INLINE IndirectHandle< T > indirect_handle(DirectHandle< T > handle)
Definition handles.h:757
void SerializeCallSiteInfo(Isolate *isolate, DirectHandle< CallSiteInfo > frame, IncrementalStringBuilder *builder)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
kMemory0SizeOffset Address kNewAllocationLimitAddressOffset Address kOldAllocationLimitAddressOffset uint8_t kGlobalsStartOffset kJumpTableStartOffset std::atomic< uint32_t > kTieringBudgetArrayOffset kDataSegmentStartsOffset kElementSegmentsOffset Tagged< WasmInstanceObject >
bool IsNullOrUndefined(Tagged< Object > obj, Isolate *isolate)
bool IsClassMembersInitializerFunction(FunctionKind kind)
return value
Definition map-inl.h:893
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
Definition map-inl.h:70
DirectHandle< String > GetWasmFunctionDebugName(Isolate *isolate, DirectHandle< WasmTrustedInstanceData > instance_data, uint32_t func_index)
kInterpreterTrampolineOffset script
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
static constexpr AcquireLoadTag kAcquireLoad
Definition globals.h:2908
#define DCHECK(condition)
Definition logging.h:482