Commit 97146803 authored by jgruber's avatar jgruber Committed by Commit bot

Use toString tag to format receiver in stack traces

This concerns formatting of calls to, e.g., Math.acos in stack traces,
in which the receiver is an object with an attached toString tag. If
such a tag exists, use it to format the receiver typename to ensure that
the stack trace includes 'Math.acos' instead of 'Object.acos'.

R=yangguo@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/2110683007
Cr-Commit-Position: refs/heads/master@{#37513}
parent 293bd788
......@@ -599,12 +599,7 @@ function FormatStackTrace(obj, raw_stack) {
function GetTypeName(receiver, requireConstructor) {
if (IS_NULL_OR_UNDEFINED(receiver)) return null;
if (IS_PROXY(receiver)) return "Proxy";
var constructor = %GetDataProperty(TO_OBJECT(receiver), "constructor");
if (!IS_FUNCTION(constructor)) {
return requireConstructor ? null : %_Call(NoSideEffectsToString, receiver);
}
return %FunctionGetName(constructor);
return %GetConstructorName(receiver);
}
......
......@@ -758,6 +758,15 @@ RUNTIME_FUNCTION(Runtime_GetDataProperty) {
return *JSReceiver::GetDataProperty(object, name);
}
RUNTIME_FUNCTION(Runtime_GetConstructorName) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
CHECK(!object->IsUndefined(isolate) && !object->IsNull(isolate));
Handle<JSReceiver> recv = Object::ToObject(isolate, object).ToHandleChecked();
return *JSReceiver::GetConstructorName(recv);
}
RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
SealHandleScope shs(isolate);
......
......@@ -401,6 +401,7 @@ namespace internal {
F(DefineAccessorPropertyUnchecked, 5, 1) \
F(DefineDataPropertyInLiteral, 5, 1) \
F(GetDataProperty, 2, 1) \
F(GetConstructorName, 1, 1) \
F(HasFastPackedElements, 1, 1) \
F(ValueOf, 1, 1) \
F(IsJSReceiver, 1, 1) \
......
......@@ -47,4 +47,22 @@ testBuiltinInStackTrace("Date.prototype.getTime.call('')", "at String.getTime");
// C++ builtins.
testBuiltinInStackTrace("Boolean.prototype.toString.call(thrower);",
"at Object.toString");
// Constructor builtins.
testBuiltinInStackTrace("new Date(thrower);", "at new Date");
// Ensure we correctly pick up the receiver's string tag.
testBuiltinInStackTrace("Math.max(thrower);", "at Math.max");
testBuiltinInStackTrace("Math.min(thrower);", "at Math.min");
testBuiltinInStackTrace("Math.acos(thrower);", "at Math.acos");
testBuiltinInStackTrace("Math.asin(thrower);", "at Math.asin");
testBuiltinInStackTrace("Math.fround(thrower);", "at Math.fround");
testBuiltinInStackTrace("Math.imul(thrower);", "at Math.imul");
// As above, but function passed as an argument and then called.
testBuiltinInStackTrace("((f, x) => f(x))(Math.max, thrower);", "at max");
testBuiltinInStackTrace("((f, x) => f(x))(Math.min, thrower);", "at min");
testBuiltinInStackTrace("((f, x) => f(x))(Math.acos, thrower);", "at acos");
testBuiltinInStackTrace("((f, x) => f(x))(Math.asin, thrower);", "at asin");
testBuiltinInStackTrace("((f, x) => f(x))(Math.fround, thrower);", "at fround");
testBuiltinInStackTrace("((f, x) => f(x))(Math.imul, thrower);", "at imul");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment