Browse Source

Don't use BlockStatement to model function body (#771)

Marko Lahma 5 years ago
parent
commit
62656a0ab6

+ 32 - 0
Jint.Tests/Runtime/ConstTests.cs

@@ -0,0 +1,32 @@
+using System;
+using Xunit;
+
+namespace Jint.Tests.Runtime
+{
+    public class ConstTests
+    {
+        private readonly Engine _engine;
+
+        public ConstTests()
+        {
+            _engine = new Engine()
+                .SetValue("log", new Action<object>(Console.WriteLine))
+                .SetValue("assert", new Action<bool>(Assert.True))
+                .SetValue("equal", new Action<object, object>(Assert.Equal));
+        }
+
+        [Fact]
+        public void ConstInsideIife()
+        {
+            _engine.Execute(@"
+                (function(){
+                    const testVariable = 'test';
+                    function render() {
+                        log(testVariable);
+                    }
+                    render();
+                })();
+            ");
+        }
+    }
+}

+ 1 - 1
Jint.Tests/Runtime/InteropTests.cs

@@ -2146,7 +2146,7 @@ namespace Jint.Tests.Runtime
 
 
             engine.Execute("var jsObj = { 'key1' :'value1', 'key2' : 'value2' }");
             engine.Execute("var jsObj = { 'key1' :'value1', 'key2' : 'value2' }");
 
 
-            engine.SetValue("netObj", new Dictionary<string, object>()
+            engine.SetValue("netObj", new Dictionary<string, object>
             {
             {
                 {"key1", "value1"},
                 {"key1", "value1"},
                 {"key2", "value2"},
                 {"key2", "value2"},

+ 1 - 1
Jint/Native/Function/ArrowFunctionInstance.cs

@@ -59,7 +59,7 @@ namespace Jint.Native.Function
                         arguments,
                         arguments,
                         localEnv);
                         localEnv);
 
 
-                    var result = _function.Body.Execute();
+                    var result = _function.Execute();
 
 
                     var value = result.GetValueOrDefault().Clone();
                     var value = result.GetValueOrDefault().Clone();
 
 

+ 1 - 1
Jint/Native/Function/ScriptFunctionInstance.cs

@@ -109,7 +109,7 @@ namespace Jint.Native.Function
                         arguments,
                         arguments,
                         localEnv);
                         localEnv);
 
 
-                    var result = _function.Body.Execute();
+                    var result = _function.Execute();
                     var value = result.GetValueOrDefault().Clone();
                     var value = result.GetValueOrDefault().Clone();
                     argumentsInstance?.FunctionWasCalled();
                     argumentsInstance?.FunctionWasCalled();
 
 

+ 13 - 15
Jint/Runtime/Interpreter/JintFunctionDefinition.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using Esprima.Ast;
 using Esprima.Ast;
 using Jint.Native;
 using Jint.Native;
 using Jint.Native.Function;
 using Jint.Native.Function;
-using Jint.Runtime.Interpreter.Statements;
+using Jint.Runtime.Interpreter.Expressions;
 
 
 namespace Jint.Runtime.Interpreter
 namespace Jint.Runtime.Interpreter
 {
 {
@@ -14,8 +14,9 @@ namespace Jint.Runtime.Interpreter
     {
     {
         private readonly Engine _engine;
         private readonly Engine _engine;
         
         
-        private JintStatement _body;
-        
+        private JintExpression _bodyExpression;
+        private JintStatementList _bodyStatementList;
+
         public readonly string Name;
         public readonly string Name;
         public readonly bool Strict;
         public readonly bool Strict;
         public readonly IFunction Function;
         public readonly IFunction Function;
@@ -47,21 +48,18 @@ namespace Jint.Runtime.Interpreter
             }
             }
         }
         }
 
 
-        public JintStatement Body
+        internal Completion Execute()
         {
         {
-            get
+            if (Function.Expression)
             {
             {
-                if (_body != null)
-                {
-                    return _body;
-                }
-
-                _body = Function.Expression
-                    ? (JintStatement) new JintReturnStatement(_engine, new ReturnStatement((Expression) Function.Body))
-                    : new JintBlockStatement(_engine, (BlockStatement) Function.Body);
-
-                return _body;
+                _bodyExpression ??= JintExpression.Build(_engine, (Expression) Function.Body);
+                var jsValue = _bodyExpression?.GetValue() ?? Undefined.Instance;
+                return new Completion(CompletionType.Return, jsValue, null, Function.Body.Location);
             }
             }
+
+            var blockStatement = (BlockStatement) Function.Body;
+            _bodyStatementList ??= new JintStatementList(_engine, blockStatement, blockStatement.Body);
+            return _bodyStatementList.Execute();
         }
         }
 
 
         internal State Initialize(Engine engine, FunctionInstance functionInstance)
         internal State Initialize(Engine engine, FunctionInstance functionInstance)