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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/js/messages.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-callsite.cc
diff --git a/src/builtins/builtins-callsite.cc b/src/builtins/builtins-callsite.cc
index c7b273e8438c05c0b5fc8bb0400517eafc397d4f..2038f28f680aa215f15d220e44dcc1f6849f2a7a 100644
--- a/src/builtins/builtins-callsite.cc
+++ b/src/builtins/builtins-callsite.cc
@@ -199,32 +199,39 @@ MaybeHandle<String> FormatEvalOrigin(Isolate* isolate, Handle<Script> script) {
return result;
}
-} // namespace
-
-BUILTIN(CallSitePrototypeGetEvalOrigin) {
- HandleScope scope(isolate);
- CHECK_CALLSITE(recv, "getEvalOrigin");
-
- CallSite call_site(isolate, recv);
- if (call_site.IsWasm()) return *isolate->factory()->undefined_value();
+MaybeHandle<Object> GetEvalOrigin(Isolate* isolate, Handle<JSObject> object) {
+ CallSite call_site(isolate, object);
+ if (call_site.IsWasm()) return isolate->factory()->undefined_value();
// Retrieve the function's script object.
Handle<Object> function_obj;
Handle<Symbol> symbol = isolate->factory()->call_site_function_symbol();
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, function_obj,
- JSObject::GetProperty(recv, symbol));
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, function_obj,
+ JSObject::GetProperty(object, symbol), Object);
DCHECK(function_obj->IsJSFunction());
Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj);
Handle<Object> script = handle(function->shared()->script(), isolate);
if (!script->IsScript()) {
- return *isolate->factory()->undefined_value();
+ return isolate->factory()->undefined_value();
}
- RETURN_RESULT_OR_FAILURE(
- isolate, FormatEvalOrigin(isolate, Handle<Script>::cast(script)));
+ Handle<String> str;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, str, FormatEvalOrigin(isolate, Handle<Script>::cast(script)),
+ String);
+
+ return str;
+}
+
+} // namespace
+
+BUILTIN(CallSitePrototypeGetEvalOrigin) {
+ HandleScope scope(isolate);
+ CHECK_CALLSITE(recv, "getEvalOrigin");
+ RETURN_RESULT_OR_FAILURE(isolate, GetEvalOrigin(isolate, recv));
}
BUILTIN(CallSitePrototypeGetFileName) {
@@ -324,25 +331,32 @@ BUILTIN(CallSitePrototypeGetThis) {
return *receiver;
}
-BUILTIN(CallSitePrototypeGetTypeName) {
- HandleScope scope(isolate);
- CHECK_CALLSITE(recv, "getTypeName");
+namespace {
+MaybeHandle<Object> GetTypeName(Isolate* isolate, Handle<JSObject> object) {
Handle<Object> receiver;
Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol();
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver,
- JSObject::GetProperty(recv, symbol));
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
+ JSObject::GetProperty(object, symbol), Object);
// TODO(jgruber): Check for strict/constructor here as above.
if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate))
- return *isolate->factory()->null_value();
+ return isolate->factory()->null_value();
- if (receiver->IsJSProxy()) return *isolate->factory()->Proxy_string();
+ if (receiver->IsJSProxy()) return isolate->factory()->Proxy_string();
Handle<JSReceiver> receiver_object =
Object::ToObject(isolate, receiver).ToHandleChecked();
- return *JSReceiver::GetConstructorName(receiver_object);
+ return JSReceiver::GetConstructorName(receiver_object);
+}
+
+} // namespace
+
+BUILTIN(CallSitePrototypeGetTypeName) {
+ HandleScope scope(isolate);
+ CHECK_CALLSITE(recv, "getTypeName");
+ RETURN_RESULT_OR_FAILURE(isolate, GetTypeName(isolate, recv));
}
BUILTIN(CallSitePrototypeIsConstructor) {
@@ -381,10 +395,217 @@ BUILTIN(CallSitePrototypeIsToplevel) {
return isolate->heap()->ToBoolean(call_site.IsToplevel());
}
+namespace {
+
+bool IsNonEmptyString(Handle<Object> object) {
+ return (object->IsString() && String::cast(*object)->length() > 0);
+}
+
+MaybeHandle<JSObject> AppendWasmToString(Isolate* isolate,
+ Handle<JSObject> recv,
+ CallSite* call_site,
+ IncrementalStringBuilder* builder) {
+ Handle<Object> name = call_site->GetFunctionName();
+ if (name->IsNull(isolate)) {
+ builder->AppendCString("<WASM UNNAMED>");
+ } else {
+ DCHECK(name->IsString());
+ builder->AppendString(Handle<String>::cast(name));
+ }
+
+ builder->AppendCString(" (<WASM>[");
+
+ Handle<String> ix = isolate->factory()->NumberToString(
+ handle(Smi::FromInt(call_site->wasm_func_index()), isolate));
+ builder->AppendString(ix);
+
+ builder->AppendCString("]+");
+
+ Handle<Object> pos;
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, pos, JSObject::GetProperty(
+ recv, isolate->factory()->call_site_position_symbol()),
+ JSObject);
+ DCHECK(pos->IsNumber());
+ builder->AppendString(isolate->factory()->NumberToString(pos));
+ builder->AppendCString(")");
+
+ return recv;
+}
+
+MaybeHandle<JSObject> AppendFileLocation(Isolate* isolate,
+ Handle<JSObject> recv,
+ CallSite* call_site,
+ IncrementalStringBuilder* builder) {
+ if (call_site->IsNative()) {
+ builder->AppendCString("native");
+ return recv;
+ }
+
+ Handle<Object> file_name = call_site->GetScriptNameOrSourceUrl();
+ if (!file_name->IsString() && call_site->IsEval()) {
+ Handle<Object> eval_origin;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_origin,
+ GetEvalOrigin(isolate, recv), JSObject);
+ DCHECK(eval_origin->IsString());
+ builder->AppendString(Handle<String>::cast(eval_origin));
+ builder->AppendCString(", "); // Expecting source position to follow.
+ }
+
+ if (IsNonEmptyString(file_name)) {
+ builder->AppendString(Handle<String>::cast(file_name));
+ } else {
+ // Source code does not originate from a file and is not native, but we
+ // can still get the source position inside the source string, e.g. in
+ // an eval string.
+ builder->AppendCString("<anonymous>");
+ }
+
+ int line_number = call_site->GetLineNumber();
+ if (line_number != -1) {
+ builder->AppendCharacter(':');
+ Handle<String> line_string = isolate->factory()->NumberToString(
+ handle(Smi::FromInt(line_number), isolate), isolate);
+ builder->AppendString(line_string);
+
+ int column_number = call_site->GetColumnNumber();
+ if (column_number != -1) {
+ builder->AppendCharacter(':');
+ Handle<String> column_string = isolate->factory()->NumberToString(
+ handle(Smi::FromInt(column_number), isolate), isolate);
+ builder->AppendString(column_string);
+ }
+ }
+
+ return recv;
+}
+
+int StringIndexOf(Isolate* isolate, Handle<String> subject,
+ Handle<String> pattern) {
+ if (pattern->length() > subject->length()) return -1;
+ return String::IndexOf(isolate, subject, pattern, 0);
+}
+
+// Returns true iff
+// 1. the subject ends with '.' + pattern, or
+// 2. subject == pattern.
+bool StringEndsWithMethodName(Isolate* isolate, Handle<String> subject,
+ Handle<String> pattern) {
+ if (String::Equals(subject, pattern)) return true;
+
+ FlatStringReader subject_reader(isolate, String::Flatten(subject));
+ FlatStringReader pattern_reader(isolate, String::Flatten(pattern));
+
+ int pattern_index = pattern_reader.length() - 1;
+ int subject_index = subject_reader.length() - 1;
+ for (int i = 0; i <= pattern_reader.length(); i++) { // Iterate over len + 1.
+ if (subject_index < 0) {
+ return false;
+ }
+
+ const uc32 subject_char = subject_reader.Get(subject_index);
+ if (i == pattern_reader.length()) {
+ if (subject_char != '.') return false;
+ } else if (subject_char != pattern_reader.Get(pattern_index)) {
+ return false;
+ }
+
+ pattern_index--;
+ subject_index--;
+ }
+
+ return true;
+}
+
+MaybeHandle<JSObject> AppendMethodCall(Isolate* isolate, Handle<JSObject> recv,
+ CallSite* call_site,
+ IncrementalStringBuilder* builder) {
+ Handle<Object> type_name;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, type_name, GetTypeName(isolate, recv),
+ JSObject);
+ Handle<Object> method_name = call_site->GetMethodName();
+ Handle<Object> function_name = call_site->GetFunctionName();
+
+ if (IsNonEmptyString(function_name)) {
+ Handle<String> function_string = Handle<String>::cast(function_name);
+ if (type_name->IsString()) {
+ Handle<String> type_string = Handle<String>::cast(type_name);
+ bool starts_with_type_name =
+ (StringIndexOf(isolate, function_string, type_string) == 0);
+ if (!starts_with_type_name) {
+ builder->AppendString(type_string);
+ builder->AppendCharacter('.');
+ }
+ }
+ builder->AppendString(function_string);
+
+ if (IsNonEmptyString(method_name)) {
+ Handle<String> method_string = Handle<String>::cast(method_name);
+ if (!StringEndsWithMethodName(isolate, function_string, method_string)) {
+ builder->AppendCString(" [as ");
+ builder->AppendString(method_string);
+ builder->AppendCharacter(']');
+ }
+ }
+ } else {
+ builder->AppendString(Handle<String>::cast(type_name));
+ builder->AppendCharacter('.');
+ if (IsNonEmptyString(method_name)) {
+ builder->AppendString(Handle<String>::cast(method_name));
+ } else {
+ builder->AppendCString("<anonymous>");
+ }
+ }
+
+ return recv;
+}
+
+} // namespace
+
BUILTIN(CallSitePrototypeToString) {
HandleScope scope(isolate);
- // TODO(jgruber)
- return *isolate->factory()->undefined_value();
+ CHECK_CALLSITE(recv, "toString");
+
+ IncrementalStringBuilder builder(isolate);
+
+ CallSite call_site(isolate, recv);
+ if (call_site.IsWasm()) {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, AppendWasmToString(isolate, recv, &call_site, &builder));
+ RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
+ }
+
+ DCHECK(!call_site.IsWasm());
+ Handle<Object> function_name = call_site.GetFunctionName();
+
+ const bool is_toplevel = call_site.IsToplevel();
+ const bool is_constructor = call_site.IsConstructor();
+ const bool is_method_call = !(is_toplevel || is_constructor);
+
+ if (is_method_call) {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, AppendMethodCall(isolate, recv, &call_site, &builder));
+ } else if (is_constructor) {
+ builder.AppendCString("new ");
+ if (IsNonEmptyString(function_name)) {
+ builder.AppendString(Handle<String>::cast(function_name));
+ } else {
+ builder.AppendCString("<anonymous>");
+ }
+ } else if (IsNonEmptyString(function_name)) {
+ builder.AppendString(Handle<String>::cast(function_name));
+ } else {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, AppendFileLocation(isolate, recv, &call_site, &builder));
+ RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
+ }
+
+ builder.AppendCString(" (");
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, AppendFileLocation(isolate, recv, &call_site, &builder));
+ builder.AppendCString(")");
+
+ RETURN_RESULT_OR_FAILURE(isolate, builder.Finish());
}
#undef CHECK_CALLSITE
« 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