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 25, 2024
1 parent 2c56043 commit 501229c
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 36 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
11 changes: 11 additions & 0 deletions Jint/Options.Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ public static Options SetWrapObjectHandler(this Options options, Options.WrapObj
return options;
}

/// <summary>
///
/// </summary>
/// <param name="options"></param>
/// <param name="buildCallStackHandler"></param>
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
40 changes: 40 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 void BuildCallStackDelegate(ref ValueStringBuilder valueStringBuilder, string shortDescription, Location location, List<string>? arguments);

/// <summary>
/// Execution constraints for the engine.
/// </summary>
Expand Down Expand Up @@ -293,6 +297,42 @@ 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 (ref ValueStringBuilder sb, string shortDescription, Location loc, List<string>? arguments) =>
{
sb.Append(" at");
if (!string.IsNullOrWhiteSpace(shortDescription))
{
sb.Append(' ');
sb.Append(shortDescription);
}
if (arguments is not null)
{
sb.Append(" (");
for (var index = 0; index < arguments.Count; index++)
{
if (index != 0)
{
sb.Append(", ");
}
sb.Append(arguments[index]);
}
sb.Append(')');
}
sb.Append(' ');
sb.Append(loc.Source);
sb.Append(':');
sb.Append(loc.End.Line.ToString(CultureInfo.InvariantCulture));
sb.Append(':');
sb.Append((loc.Start.Column + 1).ToString(CultureInfo.InvariantCulture)); // report column number instead of index
sb.Append(Environment.NewLine);
};

/// <summary>
///
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion Jint/Pooling/ValueStringBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// ReSharper disable once CheckNamespace
namespace System.Text;

internal ref struct ValueStringBuilder
public ref struct ValueStringBuilder
{
private char[]? _arrayToReturnToPool;
private Span<char> _chars;
Expand Down
39 changes: 8 additions & 31 deletions Jint/Runtime/CallStack/JintCallStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,46 +117,23 @@ 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)
{
sb.Append(" at");

if (!string.IsNullOrWhiteSpace(shortDescription))
{
sb.Append(' ');
sb.Append(shortDescription);
}
List<string>? arguments = null;

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

var arg = element.Value.Arguments.Value[index];
sb.Append(GetPropertyKey(arg));
}
sb.Append(')');
arguments = element.Value.Arguments.Value.Select(GetPropertyKey).ToList();
}

sb.Append(' ');
sb.Append(loc.Source);
sb.Append(':');
sb.Append(loc.End.Line.ToString(CultureInfo.InvariantCulture));
sb.Append(':');
sb.Append((loc.Start.Column + 1).ToString(CultureInfo.InvariantCulture)); // report column number instead of index
sb.Append(System.Environment.NewLine);
engine.Options.Interop.BuildCallStackHandler.Invoke(ref sb, shortDescription, loc, arguments);
}

var builder = new ValueStringBuilder();
Expand All @@ -166,7 +143,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 +153,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 501229c

Please sign in to comment.