Browse Source

Fix double evaluation of typeof operator (#987)

Gökhan Kurt 3 years ago
parent
commit
6b22d92172

+ 15 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -2761,6 +2761,21 @@ x.test = {
             Assert.Equal("White", result.white);
         }
 
+        [Fact]
+        public void TypeofShouldEvaluateOnce()
+        {
+            var engine = new Engine();
+            var result = engine.Evaluate(@"
+                let res = 0;
+                const fn = () => res++;
+                typeof fn();
+                res;
+                ")
+                .AsNumber();
+
+            Assert.Equal(1, result);
+        }
+
         private class Wrapper
         {
             public Testificate Test { get; set; }

+ 12 - 7
Jint/Runtime/Interpreter/Expressions/JintUnaryExpression.cs

@@ -161,19 +161,24 @@ namespace Jint.Runtime.Interpreter.Expressions
 
                 case UnaryOperator.TypeOf:
                 {
-                    var value = _argument.Evaluate(context).Value;
-                    r = value as Reference;
-                    if (r != null)
+                    var result = _argument.Evaluate(context);
+                    JsValue v;
+
+                    if (result.Value is Reference rf)
                     {
-                        if (r.IsUnresolvableReference())
+                        if (rf.IsUnresolvableReference())
                         {
-                            engine._referencePool.Return(r);
+                            engine._referencePool.Return(rf);
                             return JsString.UndefinedString;
                         }
+
+                        v = engine.GetValue(rf, true);
+                    }
+                    else
+                    { 
+                        v = (JsValue) result.Value;
                     }
 
-                    // TODO: double evaluation problem
-                    var v = _argument.GetValue(context).Value;
                     if (v.IsUndefined())
                     {
                         return JsString.UndefinedString;