|
@@ -114,14 +114,20 @@ internal sealed class JintCallStack
|
|
return string.Join("->", _stack.Select(static cse => cse.ToString()).Reverse());
|
|
return string.Join("->", _stack.Select(static cse => cse.ToString()).Reverse());
|
|
}
|
|
}
|
|
|
|
|
|
- internal string BuildCallStackString(SourceLocation location, int excludeTop = 0)
|
|
|
|
|
|
+ internal string BuildCallStackString(Engine engine, SourceLocation location, int excludeTop = 0)
|
|
{
|
|
{
|
|
static void AppendLocation(
|
|
static void AppendLocation(
|
|
ref ValueStringBuilder sb,
|
|
ref ValueStringBuilder sb,
|
|
string shortDescription,
|
|
string shortDescription,
|
|
in SourceLocation loc,
|
|
in SourceLocation loc,
|
|
- in CallStackElement? element)
|
|
|
|
|
|
+ in CallStackElement? element,
|
|
|
|
+ Options.BuildCallStackDelegate? callStackBuilder)
|
|
{
|
|
{
|
|
|
|
+ if (callStackBuilder != null && TryInvokeCustomCallStackHandler(callStackBuilder, element, shortDescription, loc, ref sb))
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
sb.Append(" at");
|
|
sb.Append(" at");
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(shortDescription))
|
|
if (!string.IsNullOrWhiteSpace(shortDescription))
|
|
@@ -134,15 +140,15 @@ internal sealed class JintCallStack
|
|
{
|
|
{
|
|
// it's a function
|
|
// it's a function
|
|
sb.Append(" (");
|
|
sb.Append(" (");
|
|
- for (var index = 0; index < element.Value.Arguments.Value.Count; index++)
|
|
|
|
|
|
+ var arguments = element.Value.Arguments.Value;
|
|
|
|
+ for (var i = 0; i < arguments.Count; i++)
|
|
{
|
|
{
|
|
- if (index != 0)
|
|
|
|
|
|
+ if (i != 0)
|
|
{
|
|
{
|
|
sb.Append(", ");
|
|
sb.Append(", ");
|
|
}
|
|
}
|
|
|
|
|
|
- var arg = element.Value.Arguments.Value[index];
|
|
|
|
- sb.Append(GetPropertyKey(arg));
|
|
|
|
|
|
+ sb.Append(GetPropertyKey(arguments[i]));
|
|
}
|
|
}
|
|
sb.Append(')');
|
|
sb.Append(')');
|
|
}
|
|
}
|
|
@@ -156,6 +162,7 @@ internal sealed class JintCallStack
|
|
sb.Append(System.Environment.NewLine);
|
|
sb.Append(System.Environment.NewLine);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ var customCallStackBuilder = engine.Options.Interop.BuildCallStackHandler;
|
|
var builder = new ValueStringBuilder();
|
|
var builder = new ValueStringBuilder();
|
|
|
|
|
|
// stack is one frame behind function-wise when we start to process it from expression level
|
|
// stack is one frame behind function-wise when we start to process it from expression level
|
|
@@ -163,7 +170,7 @@ internal sealed class JintCallStack
|
|
var element = index >= 0 ? _stack[index] : (CallStackElement?) null;
|
|
var element = index >= 0 ? _stack[index] : (CallStackElement?) null;
|
|
var shortDescription = element?.ToString() ?? "";
|
|
var shortDescription = element?.ToString() ?? "";
|
|
|
|
|
|
- AppendLocation(ref builder, shortDescription, location, element);
|
|
|
|
|
|
+ AppendLocation(ref builder, shortDescription, location, element, customCallStackBuilder);
|
|
|
|
|
|
location = element?.Location ?? default;
|
|
location = element?.Location ?? default;
|
|
index--;
|
|
index--;
|
|
@@ -173,7 +180,7 @@ internal sealed class JintCallStack
|
|
element = index >= 0 ? _stack[index] : null;
|
|
element = index >= 0 ? _stack[index] : null;
|
|
shortDescription = element?.ToString() ?? "";
|
|
shortDescription = element?.ToString() ?? "";
|
|
|
|
|
|
- AppendLocation(ref builder, shortDescription, location, element);
|
|
|
|
|
|
+ AppendLocation(ref builder, shortDescription, location, element, customCallStackBuilder);
|
|
|
|
|
|
location = element?.Location ?? default;
|
|
location = element?.Location ?? default;
|
|
index--;
|
|
index--;
|
|
@@ -186,6 +193,34 @@ internal sealed class JintCallStack
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private static bool TryInvokeCustomCallStackHandler(
|
|
|
|
+ Options.BuildCallStackDelegate handler,
|
|
|
|
+ CallStackElement? element,
|
|
|
|
+ string shortDescription,
|
|
|
|
+ SourceLocation loc,
|
|
|
|
+ ref ValueStringBuilder sb)
|
|
|
|
+ {
|
|
|
|
+ string[]? arguments = null;
|
|
|
|
+ if (element?.Arguments is not null)
|
|
|
|
+ {
|
|
|
|
+ var args = element.Value.Arguments.Value;
|
|
|
|
+ arguments = args.Count > 0 ? new string[args.Count] : [];
|
|
|
|
+ for (var i = 0; i < arguments.Length; i++)
|
|
|
|
+ {
|
|
|
|
+ arguments[i] = GetPropertyKey(args[i]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var str = handler(shortDescription, loc, arguments);
|
|
|
|
+ if (!string.IsNullOrEmpty(str))
|
|
|
|
+ {
|
|
|
|
+ sb.Append(str);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
/// <summary>
|
|
/// <summary>
|
|
/// A version of <see cref="AstExtensions.GetKey"/> that cannot get into loop as we are already building a stack.
|
|
/// A version of <see cref="AstExtensions.GetKey"/> that cannot get into loop as we are already building a stack.
|
|
/// </summary>
|
|
/// </summary>
|
|
@@ -203,8 +238,7 @@ internal sealed class JintCallStack
|
|
|
|
|
|
if (expression is MemberExpression { Computed: false } staticMemberExpression)
|
|
if (expression is MemberExpression { Computed: false } staticMemberExpression)
|
|
{
|
|
{
|
|
- return GetPropertyKey(staticMemberExpression.Object) + "." +
|
|
|
|
- GetPropertyKey(staticMemberExpression.Property);
|
|
|
|
|
|
+ return $"{GetPropertyKey(staticMemberExpression.Object)}.{GetPropertyKey(staticMemberExpression.Property)}";
|
|
}
|
|
}
|
|
|
|
|
|
return "?";
|
|
return "?";
|