From dfed0aa93b4b1d2188e89f004908584920a2b4eb Mon Sep 17 00:00:00 2001 From: Adam Simon Date: Sat, 11 Apr 2026 15:41:23 +0200 Subject: [PATCH 1/5] Improve Function.prototype.toString() to return source text for non-native functions --- Directory.Packages.props | 4 +- Jint/AstExtensions.cs | 35 +++++++++++++++- Jint/Engine.Ast.cs | 28 +++++-------- Jint/Engine.Defaults.cs | 14 +++++++ Jint/Extensions/AcornimaExtensions.cs | 16 +++++--- Jint/Native/Function/ClassDefinition.cs | 25 +++++------ Jint/Native/Function/Function.cs | 14 ++++++- .../Function/FunctionInstance.Dynamic.cs | 18 ++++---- Jint/Native/Function/SourceText.cs | 41 +++++++++++++++++++ Jint/ParsingOptions.cs | 2 + .../Expressions/JintClassExpression.cs | 2 +- .../Expressions/JintObjectExpression.cs | 6 +-- .../Interpreter/JintFunctionDefinition.cs | 26 ++++++++++-- .../JintClassDeclarationStatement.cs | 2 +- .../JintExportDefaultDeclaration.cs | 2 +- 15 files changed, 176 insertions(+), 59 deletions(-) create mode 100644 Jint/Native/Function/SourceText.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index db46280bc1..c71f08cad6 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,8 +4,8 @@ true - - + + diff --git a/Jint/AstExtensions.cs b/Jint/AstExtensions.cs index 0dbfa72940..edfdd9ac5a 100644 --- a/Jint/AstExtensions.cs +++ b/Jint/AstExtensions.cs @@ -1,4 +1,5 @@ using System.Runtime.CompilerServices; +using System.Threading; using Jint.Native; using Jint.Native.Function; using Jint.Native.Object; @@ -17,6 +18,8 @@ public static class AstExtensions internal static readonly SourceLocation DefaultLocation; #pragma warning restore CS0649 // Field is never assigned to, and will always have its default value + private static Tokenizer? s_cachedTokenizer; + public static JsValue GetKey(this T property, Engine engine) where T : IProperty => GetKey(property.Key, engine, property.Computed); public static JsValue GetKey(this Expression expression, Engine engine, bool resolveComputed = false) @@ -325,7 +328,7 @@ internal static void BindingInitialization( /// /// https://tc39.es/ecma262/#sec-runtime-semantics-definemethod /// - internal static Record DefineMethod(this T m, ObjectInstance obj, ObjectInstance? functionPrototype = null) where T : IProperty + internal static Record DefineMethod(this T m, ObjectInstance obj, ObjectInstance? functionPrototype = null, INode? sourceTextNode = null) where T : IProperty { var engine = obj.Engine; var propKey = TypeConverter.ToPropertyKey(m.GetKey(engine)); @@ -342,7 +345,18 @@ internal static Record DefineMethod(this T m, ObjectInstance obj, ObjectInsta Throw.SyntaxError(engine.Realm); } - var definition = new JintFunctionDefinition(function); + int sourceTextStart, sourceTextEnd; + if (sourceTextNode is not null) + { + (sourceTextStart, sourceTextEnd) = sourceTextNode.Range; + } + else + { + sourceTextStart = m is MethodDefinition { Static: true } ? ~m.RangeRef.Start : m.RangeRef.Start; + sourceTextEnd = m.RangeRef.End; + } + + var definition = new JintFunctionDefinition(function, sourceTextStart, sourceTextEnd); var closure = intrinsics.Function.OrdinaryFunctionCreate(prototype, definition, definition.ThisMode, env, privateEnv); closure.MakeMethod(obj); @@ -523,6 +537,23 @@ internal static DisposeHint GetDisposeHint(this VariableDeclarationKind statemen }; } + internal static int GetSecondTokenStartIndex(string sourceText, int start, int end) + { + var tokenizer = Interlocked.Exchange(ref s_cachedTokenizer, value: null) ?? new Tokenizer(string.Empty); + try + { + tokenizer.Reset(sourceText, start, end - start, SourceType.Script); + tokenizer.Next(); + tokenizer.Next(); // skip first token + potential whitespace and/or comments + return tokenizer.Current.Start; + } + finally + { + tokenizer.Reset(string.Empty); + Volatile.Write(ref s_cachedTokenizer, tokenizer); + } + } + private sealed class MinimalSyntaxElement : Node { public MinimalSyntaxElement(in SourceLocation location) : base(NodeType.Unknown) diff --git a/Jint/Engine.Ast.cs b/Jint/Engine.Ast.cs index 3e843dad4e..00c46fddd6 100644 --- a/Jint/Engine.Ast.cs +++ b/Jint/Engine.Ast.cs @@ -20,25 +20,17 @@ public static Prepared