From 791384f34d18ed794e9702337ce8a7d442a5176e Mon Sep 17 00:00:00 2001 From: Marko Lahma Date: Fri, 10 Nov 2023 19:40:18 +0200 Subject: [PATCH] Move expression initialize to expression implementation (#1677) --- .../BindingPatternAssignmentExpression.cs | 13 +++--- .../Expressions/JintArrayExpression.cs | 10 ++++- .../Expressions/JintAssignmentExpression.cs | 10 ++++- .../Expressions/JintAwaitExpression.cs | 12 +++--- .../Expressions/JintBinaryExpression.cs | 41 ++++++++++++++++++- .../Expressions/JintCallExpression.cs | 10 ++++- .../Interpreter/Expressions/JintExpression.cs | 23 ----------- .../Expressions/JintIdentifierExpression.cs | 10 ++++- .../Expressions/JintImportExpression.cs | 10 ++++- .../Expressions/JintLogicalAndExpression.cs | 10 ++++- .../Expressions/JintMemberExpression.cs | 10 ++++- .../Expressions/JintNewExpression.cs | 10 ++++- .../Expressions/JintObjectExpression.cs | 10 ++++- .../Expressions/JintSequenceExpression.cs | 10 ++++- .../JintTaggedTemplateExpression.cs | 10 ++++- .../JintTemplateLiteralExpression.cs | 17 ++++---- .../Expressions/JintUpdateExpression.cs | 10 ++++- 17 files changed, 158 insertions(+), 68 deletions(-) diff --git a/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs b/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs index b6e2964f3d..9a808961bf 100644 --- a/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs @@ -12,20 +12,21 @@ internal sealed class BindingPatternAssignmentExpression : JintExpression { private readonly BindingPattern _pattern; private JintExpression _right = null!; + private bool _initialized; public BindingPatternAssignmentExpression(AssignmentExpression expression) : base(expression) { _pattern = (BindingPattern) expression.Left; - _initialized = false; - } - - protected override void Initialize(EvaluationContext context) - { - _right = Build(((AssignmentExpression) _expression).Right); } protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + _right = Build(((AssignmentExpression) _expression).Right); + _initialized = true; + } + var rightValue = _right.GetValue(context); if (context.IsAbrupt()) { diff --git a/Jint/Runtime/Interpreter/Expressions/JintArrayExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintArrayExpression.cs index 0a67535406..230b9ff4b8 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintArrayExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintArrayExpression.cs @@ -8,10 +8,10 @@ internal sealed class JintArrayExpression : JintExpression { private JintExpression?[] _expressions = Array.Empty(); private bool _hasSpreads; + private bool _initialized; private JintArrayExpression(ArrayExpression expression) : base(expression) { - _initialized = false; } public static JintExpression Build(ArrayExpression expression) @@ -21,7 +21,7 @@ public static JintExpression Build(ArrayExpression expression) : new JintArrayExpression(expression); } - protected override void Initialize(EvaluationContext context) + private void Initialize() { ref readonly var elements = ref ((ArrayExpression) _expression).Elements; var expressions = _expressions = new JintExpression[((ArrayExpression) _expression).Elements.Count]; @@ -42,6 +42,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + var engine = context.Engine; var a = engine.Realm.Intrinsics.Array.ArrayCreate(_hasSpreads ? 0 : (uint) _expressions.Length); diff --git a/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs index 74ca100e36..1bac40f5af 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintAssignmentExpression.cs @@ -343,13 +343,13 @@ internal sealed class SimpleAssignmentExpression : JintExpression private JintIdentifierExpression? _leftIdentifier; private bool _evalOrArguments; + private bool _initialized; public SimpleAssignmentExpression(AssignmentExpression expression) : base(expression) { - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { var assignmentExpression = (AssignmentExpression) _expression; _left = Build((Expression) assignmentExpression.Left); @@ -361,6 +361,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + object? completion = null; if (_leftIdentifier != null) { diff --git a/Jint/Runtime/Interpreter/Expressions/JintAwaitExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintAwaitExpression.cs index baaaa6b6e7..600b7cbb55 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintAwaitExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintAwaitExpression.cs @@ -6,19 +6,21 @@ namespace Jint.Runtime.Interpreter.Expressions; internal sealed class JintAwaitExpression : JintExpression { private JintExpression _awaitExpression = null!; + private bool _initialized; public JintAwaitExpression(AwaitExpression expression) : base(expression) { _initialized = false; } - protected override void Initialize(EvaluationContext context) - { - _awaitExpression = Build(((AwaitExpression) _expression).Argument); - } - protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + _awaitExpression = Build(((AwaitExpression) _expression).Argument); + _initialized = true; + } + var engine = context.Engine; var asyncContext = engine.ExecutionContext; diff --git a/Jint/Runtime/Interpreter/Expressions/JintBinaryExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintBinaryExpression.cs index 9828dd6446..b17a6dd703 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintBinaryExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintBinaryExpression.cs @@ -20,18 +20,25 @@ internal abstract class JintBinaryExpression : JintExpression private JintExpression _left = null!; private JintExpression _right = null!; + private bool _initialized; private JintBinaryExpression(BinaryExpression expression) : base(expression) { // TODO check https://tc39.es/ecma262/#sec-applystringornumericbinaryoperator - _initialized = false; } - protected override void Initialize(EvaluationContext context) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureInitialized() { + if (_initialized) + { + return; + } + var expression = (BinaryExpression) _expression; _left = Build(expression.Left); _right = Build(expression.Right); + _initialized = true; } internal static bool TryOperatorOverloading( @@ -196,6 +203,8 @@ public StrictlyEqualBinaryExpression(BinaryExpression expression) : base(express protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); var equal = left == right; @@ -211,6 +220,8 @@ public StrictlyNotEqualBinaryExpression(BinaryExpression expression) : base(expr protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); return left == right ? JsBoolean.False : JsBoolean.True; @@ -225,6 +236,8 @@ public LessBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -248,6 +261,8 @@ public GreaterBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -271,6 +286,8 @@ public PlusBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -314,6 +331,8 @@ public MinusBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -352,6 +371,8 @@ public TimesBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -393,6 +414,8 @@ public DivideBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -419,6 +442,8 @@ public EqualBinaryExpression(BinaryExpression expression, bool invert = false) : protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -448,6 +473,8 @@ public CompareBinaryExpression(BinaryExpression expression, bool leftFirst) : ba protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var leftValue = _left.GetValue(context); var rightValue = _right.GetValue(context); @@ -473,6 +500,8 @@ public InstanceOfBinaryExpression(BinaryExpression expression) : base(expression protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var leftValue = _left.GetValue(context); var rightValue = _right.GetValue(context); return leftValue.InstanceofOperator(rightValue) ? JsBoolean.True : JsBoolean.False; @@ -487,6 +516,8 @@ public ExponentiationBinaryExpression(BinaryExpression expression) : base(expres protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var leftReference = _left.GetValue(context); var rightReference = _right.GetValue(context); @@ -612,6 +643,8 @@ public InBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -640,6 +673,8 @@ public ModuloBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var left = _left.GetValue(context); var right = _right.GetValue(context); @@ -754,6 +789,8 @@ public BitwiseBinaryExpression(BinaryExpression expression) : base(expression) protected override object EvaluateInternal(EvaluationContext context) { + EnsureInitialized(); + var lval = _left.GetValue(context); var rval = _right.GetValue(context); diff --git a/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs index c1f1e0abfc..a44bf7163c 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintCallExpression.cs @@ -16,13 +16,13 @@ internal sealed class JintCallExpression : JintExpression private JintExpression _calleeExpression = null!; private bool _hasSpreads; + private bool _initialized; public JintCallExpression(CallExpression expression) : base(expression) { - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize(EvaluationContext context) { var expression = (CallExpression) _expression; ref readonly var expressionArguments = ref expression.Arguments; @@ -78,6 +78,12 @@ static bool CanSpread(Node? e) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(context); + _initialized = true; + } + if (!context.Engine._stackGuard.TryEnterOnCurrentStack()) { return context.Engine._stackGuard.RunOnEmptyStack(EvaluateInternal, context); diff --git a/Jint/Runtime/Interpreter/Expressions/JintExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintExpression.cs index 51e42f766a..fe78d83ef8 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintExpression.cs @@ -10,9 +10,6 @@ namespace Jint.Runtime.Interpreter.Expressions { internal abstract class JintExpression { - // require sub-classes to set to false explicitly to skip virtual call - protected bool _initialized = true; - protected internal readonly Expression _expression; protected JintExpression(Expression expression) @@ -43,12 +40,6 @@ public object Evaluate(EvaluationContext context) var oldSyntaxElement = context.LastSyntaxElement; context.PrepareFor(_expression); - if (!_initialized) - { - Initialize(context); - _initialized = true; - } - var result = EvaluateInternal(context); context.LastSyntaxElement = oldSyntaxElement; @@ -59,23 +50,9 @@ public object Evaluate(EvaluationContext context) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal object EvaluateWithoutNodeTracking(EvaluationContext context) { - if (!_initialized) - { - Initialize(context); - _initialized = true; - } - return EvaluateInternal(context); } - /// - /// Opportunity to build one-time structures and caching based on lexical context. - /// - /// - protected virtual void Initialize(EvaluationContext context) - { - } - protected abstract object EvaluateInternal(EvaluationContext context); /// diff --git a/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs index d86d7e9784..5120b40378 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintIdentifierExpression.cs @@ -10,10 +10,10 @@ namespace Jint.Runtime.Interpreter.Expressions; internal sealed class JintIdentifierExpression : JintExpression { private EnvironmentRecord.BindingName _identifier = null!; + private bool _initialized; public JintIdentifierExpression(Identifier expression) : base(expression) { - _initialized = false; } public EnvironmentRecord.BindingName Identifier @@ -25,7 +25,7 @@ public EnvironmentRecord.BindingName Identifier } } - protected override void Initialize(EvaluationContext context) + private void Initialize() { EnsureIdentifier(); } @@ -47,6 +47,12 @@ public bool HasEvalOrArguments protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + var engine = context.Engine; var env = engine.ExecutionContext.LexicalEnvironment; var strict = StrictModeScope.IsStrictModeCode; diff --git a/Jint/Runtime/Interpreter/Expressions/JintImportExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintImportExpression.cs index 5f03d8667e..c90affcf9b 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintImportExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintImportExpression.cs @@ -7,14 +7,14 @@ namespace Jint.Runtime.Interpreter.Expressions; internal sealed class JintImportExpression : JintExpression { private JintExpression _importExpression; + private bool _initialized; public JintImportExpression(ImportExpression expression) : base(expression) { - _initialized = false; _importExpression = null!; } - protected override void Initialize(EvaluationContext context) + private void Initialize(EvaluationContext context) { var expression = ((ImportExpression) _expression).Source; _importExpression = Build(expression); @@ -25,6 +25,12 @@ protected override void Initialize(EvaluationContext context) /// protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(context); + _initialized = true; + } + var referencingScriptOrModule = context.Engine.GetActiveScriptOrModule(); var argRef = _importExpression.Evaluate(context); var specifier = context.Engine.GetValue(argRef); //.UnwrapIfPromise(); diff --git a/Jint/Runtime/Interpreter/Expressions/JintLogicalAndExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintLogicalAndExpression.cs index a7531617b4..8a091bdb40 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintLogicalAndExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintLogicalAndExpression.cs @@ -7,13 +7,13 @@ internal sealed class JintLogicalAndExpression : JintExpression { private JintExpression _left = null!; private JintExpression _right = null!; + private bool _initialized; public JintLogicalAndExpression(BinaryExpression expression) : base(expression) { - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { var expression = (BinaryExpression) _expression; _left = Build(expression.Left); @@ -22,6 +22,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + var left = _left.GetValue(context); if (left is JsBoolean b && !b._value) diff --git a/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs index f2480d2774..7ba1557516 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintMemberExpression.cs @@ -14,14 +14,14 @@ internal sealed class JintMemberExpression : JintExpression private JintExpression _objectExpression = null!; private JintExpression? _propertyExpression; private JsValue? _determinedProperty; + private bool _initialized; public JintMemberExpression(MemberExpression expression) : base(expression) { - _initialized = false; _memberExpression = (MemberExpression) _expression; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { _objectExpression = Build(_memberExpression.Object); @@ -45,6 +45,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + JsValue? actualThis = null; string? baseReferenceName = null; JsValue? baseValue = null; diff --git a/Jint/Runtime/Interpreter/Expressions/JintNewExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintNewExpression.cs index 3b9a91e571..20d6c51aa8 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintNewExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintNewExpression.cs @@ -8,13 +8,13 @@ internal sealed class JintNewExpression : JintExpression private JintExpression _calleeExpression = null!; private JintExpression[] _jintArguments = Array.Empty(); private bool _hasSpreads; + private bool _initialized; public JintNewExpression(NewExpression expression) : base(expression) { - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { var expression = (NewExpression) _expression; _calleeExpression = Build(expression.Callee); @@ -35,6 +35,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + var engine = context.Engine; // todo: optimize by defining a common abstract class or interface diff --git a/Jint/Runtime/Interpreter/Expressions/JintObjectExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintObjectExpression.cs index b02d0af123..437c7899a1 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintObjectExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintObjectExpression.cs @@ -18,6 +18,7 @@ internal sealed class JintObjectExpression : JintExpression // check if we can do a shortcut when all are object properties // and don't require duplicate checking private bool _canBuildFast; + private bool _initialized; private sealed class ObjectProperty { @@ -54,7 +55,6 @@ public JintFunctionDefinition GetFunctionDefinition(Engine engine) private JintObjectExpression(ObjectExpression expression) : base(expression) { - _initialized = false; } public static JintExpression Build(ObjectExpression expression) @@ -64,7 +64,7 @@ public static JintExpression Build(ObjectExpression expression) : new JintObjectExpression(expression); } - protected override void Initialize(EvaluationContext context) + private void Initialize() { _canBuildFast = true; var expression = (ObjectExpression) _expression; @@ -120,6 +120,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + return _canBuildFast ? BuildObjectFast(context) : BuildObjectNormal(context); diff --git a/Jint/Runtime/Interpreter/Expressions/JintSequenceExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintSequenceExpression.cs index 415960764a..b4a2148d59 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintSequenceExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintSequenceExpression.cs @@ -6,13 +6,13 @@ namespace Jint.Runtime.Interpreter.Expressions internal sealed class JintSequenceExpression : JintExpression { private JintExpression[] _expressions = Array.Empty(); + private bool _initialized; public JintSequenceExpression(SequenceExpression expression) : base(expression) { - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { var expression = (SequenceExpression) _expression; ref readonly var expressions = ref expression.Expressions; @@ -27,6 +27,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + var result = JsValue.Undefined; foreach (var expression in _expressions) { diff --git a/Jint/Runtime/Interpreter/Expressions/JintTaggedTemplateExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintTaggedTemplateExpression.cs index 88ee87c6e4..95e34407b4 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintTaggedTemplateExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintTaggedTemplateExpression.cs @@ -12,13 +12,13 @@ internal sealed class JintTaggedTemplateExpression : JintExpression private JintExpression _tagIdentifier = null!; private JintTemplateLiteralExpression _quasi = null!; + private bool _initialized; public JintTaggedTemplateExpression(TaggedTemplateExpression expression) : base(expression) { - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { var taggedTemplateExpression = (TaggedTemplateExpression) _expression; _tagIdentifier = Build(taggedTemplateExpression.Tag); @@ -28,6 +28,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + var engine = context.Engine; var identifier = _tagIdentifier.Evaluate(context); diff --git a/Jint/Runtime/Interpreter/Expressions/JintTemplateLiteralExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintTemplateLiteralExpression.cs index 105f9d81af..e3b7688ac4 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintTemplateLiteralExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintTemplateLiteralExpression.cs @@ -8,14 +8,14 @@ internal sealed class JintTemplateLiteralExpression : JintExpression { internal readonly TemplateLiteral _templateLiteralExpression; internal JintExpression[] _expressions = Array.Empty(); + private bool _initialized; public JintTemplateLiteralExpression(TemplateLiteral expression) : base(expression) { _templateLiteralExpression = expression; - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { DoInitialize(); } @@ -32,8 +32,14 @@ internal void DoInitialize() _initialized = true; } - private JsString BuildString(EvaluationContext context) + protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + using var sb = StringBuilderPool.Rent(); ref readonly var elements = ref _templateLiteralExpression.Quasis; for (var i = 0; i < elements.Count; i++) @@ -49,9 +55,4 @@ private JsString BuildString(EvaluationContext context) return JsString.Create(sb.ToString()); } - - protected override object EvaluateInternal(EvaluationContext context) - { - return BuildString(context); - } } diff --git a/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs b/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs index b71da841a1..ddcec5bcb3 100644 --- a/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs +++ b/Jint/Runtime/Interpreter/Expressions/JintUpdateExpression.cs @@ -13,13 +13,13 @@ internal sealed class JintUpdateExpression : JintExpression private JintIdentifierExpression? _leftIdentifier; private bool _evalOrArguments; + private bool _initialized; public JintUpdateExpression(UpdateExpression expression) : base(expression) { - _initialized = false; } - protected override void Initialize(EvaluationContext context) + private void Initialize() { var expression = (UpdateExpression) _expression; _prefix = expression.Prefix; @@ -43,6 +43,12 @@ protected override void Initialize(EvaluationContext context) protected override object EvaluateInternal(EvaluationContext context) { + if (!_initialized) + { + Initialize(); + _initialized = true; + } + var fastResult = _leftIdentifier != null ? UpdateIdentifier(context) : null;