Skip to content

Commit

Permalink
Add Options.InteropOptions.BuildCallStackHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
scgm0 committed Feb 26, 2024
1 parent 2c56043 commit a7416d9
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Jint/Engine.Advanced.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public string StackTrace
return string.Empty;
}

return _engine.CallStack.BuildCallStackString(lastSyntaxElement.Location);
return _engine.CallStack.BuildCallStackString(_engine, lastSyntaxElement.Location);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Jint/Native/Error/ErrorConstructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public override ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)

// If the current function is the ErrorConstructor itself (i.e. "throw new Error(...)" was called
// from script), exclude it from the stack trace, because the trace should begin at the throw point.
return callStack.BuildCallStackString(lastSyntaxNode.Location, currentFunction == this ? 1 : 0);
return callStack.BuildCallStackString(_engine, lastSyntaxNode.Location, currentFunction == this ? 1 : 0);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions Jint/Options.Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ public static Options SetWrapObjectHandler(this Options options, Options.WrapObj
return options;
}

/// <summary>
///
/// </summary>
public static Options SetBuildCallStackHandler(this Options options, Options.BuildCallStackDelegate buildCallStackHandler)
{
options.Interop.BuildCallStackHandler = buildCallStackHandler;
return options;
}

/// <summary>
/// Sets the type converter to use.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions Jint/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using Esprima;
using Jint.Native;
using Jint.Native.Object;
using Jint.Runtime;
Expand All @@ -27,6 +29,8 @@ public class Options

public delegate bool ExceptionHandlerDelegate(Exception exception);

public delegate string? BuildCallStackDelegate(string shortDescription, Location location, List<string>? arguments);

/// <summary>
/// Execution constraints for the engine.
/// </summary>
Expand Down Expand Up @@ -293,6 +297,11 @@ public class InteropOptions
/// </summary>
public WrapObjectDelegate WrapObjectHandler { get; set; } = static (engine, target, type) => new ObjectWrapper(engine, target, type);

/// <summary>
///
/// </summary>
public BuildCallStackDelegate BuildCallStackHandler { get; set; } = static (string description, Location location, List<string>? arguments) => null;

/// <summary>
///
/// </summary>
Expand Down
32 changes: 22 additions & 10 deletions Jint/Runtime/CallStack/JintCallStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,29 @@ public override string ToString()
return string.Join("->", _stack.Select(static cse => cse.ToString()).Reverse());
}

internal string BuildCallStackString(Location location, int excludeTop = 0)
internal string BuildCallStackString(Engine engine, Location location, int excludeTop = 0)
{
static void AppendLocation(
ref ValueStringBuilder sb,
string shortDescription,
in Location loc,
in CallStackElement? element)
in CallStackElement? element,
Engine engine)
{
List<string>? arguments = null;

if (element?.Arguments is not null)
{
arguments = element.Value.Arguments.Value.Select(GetPropertyKey).ToList();
}

var str = engine.Options.Interop.BuildCallStackHandler.Invoke(shortDescription, loc, arguments);
if (!string.IsNullOrEmpty(str))
{
sb.Append(str);
return;
}

sb.Append(" at");

if (!string.IsNullOrWhiteSpace(shortDescription))
Expand All @@ -133,19 +148,16 @@ static void AppendLocation(
sb.Append(shortDescription);
}

if (element?.Arguments is not null)
if (arguments is not null)
{
// it's a function
sb.Append(" (");
for (var index = 0; index < element.Value.Arguments.Value.Count; index++)
for (var index = 0; index < arguments.Count; index++)
{
if (index != 0)
{
sb.Append(", ");
}

var arg = element.Value.Arguments.Value[index];
sb.Append(GetPropertyKey(arg));
sb.Append(arguments[index]);
}
sb.Append(')');
}
Expand All @@ -166,7 +178,7 @@ static void AppendLocation(
var element = index >= 0 ? _stack[index] : (CallStackElement?) null;
var shortDescription = element?.ToString() ?? "";

AppendLocation(ref builder, shortDescription, location, element);
AppendLocation(ref builder, shortDescription, location, element, engine);

location = element?.Location ?? default;
index--;
Expand All @@ -176,7 +188,7 @@ static void AppendLocation(
element = index >= 0 ? _stack[index] : null;
shortDescription = element?.ToString() ?? "";

AppendLocation(ref builder, shortDescription, location, element);
AppendLocation(ref builder, shortDescription, location, element, engine);

location = element?.Location ?? default;
index--;
Expand Down
4 changes: 2 additions & 2 deletions Jint/Runtime/JavaScriptException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ internal void SetCallstack(Engine engine, Location location, bool overwriteExist
var errObj = Error.IsObject() ? Error.AsObject() : null;
if (errObj is null)
{
_callStack = engine.CallStack.BuildCallStackString(location);
_callStack = engine.CallStack.BuildCallStackString(engine, location);
return;
}

Expand All @@ -100,7 +100,7 @@ internal void SetCallstack(Engine engine, Location location, bool overwriteExist
}
else
{
_callStack = engine.CallStack.BuildCallStackString(location);
_callStack = engine.CallStack.BuildCallStackString(engine, location);
errObj.FastSetProperty(CommonProperties.Stack._value, new PropertyDescriptor(_callStack, false, false, false));
}
}
Expand Down

0 comments on commit a7416d9

Please sign in to comment.