Browse Source

Add ScriptOrModule to FunctionInstance (#1156)

Marko Lahma 3 years ago
parent
commit
59a9cd262f
3 changed files with 40 additions and 14 deletions
  1. 32 13
      Jint/Engine.cs
  2. 3 1
      Jint/Native/Function/FunctionInstance.cs
  3. 5 0
      Jint/Runtime/ScriptRecord.cs

+ 32 - 13
Jint/Engine.cs

@@ -261,11 +261,31 @@ namespace Jint
 
 
         public Engine Execute(Script script)
         public Engine Execute(Script script)
         {
         {
-            Engine DoInvoke()
+            var strict = _isStrict || script.Strict;
+            ExecuteWithConstraints(strict, () => ScriptEvaluation(new ScriptRecord(Realm, script, string.Empty)));
+
+            return this;
+        }
+        
+        /// <summary>
+        /// https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation
+        /// </summary>
+        private Engine ScriptEvaluation(ScriptRecord scriptRecord)
+        {
+            var globalEnv = Realm.GlobalEnv;
+
+            var scriptContext = new ExecutionContext(
+                scriptRecord,
+                lexicalEnvironment: globalEnv,
+                variableEnvironment: globalEnv,
+                privateEnvironment: null,
+                Realm);
+
+            EnterExecutionContext(scriptContext);
+            try
             {
             {
-                GlobalDeclarationInstantiation(
-                    script,
-                    Realm.GlobalEnv);
+                var script = scriptRecord.EcmaScriptCode;
+                GlobalDeclarationInstantiation(script, globalEnv);
 
 
                 var list = new JintStatementList(null, script.Body);
                 var list = new JintStatementList(null, script.Body);
 
 
@@ -295,11 +315,10 @@ namespace Jint
 
 
                 return this;
                 return this;
             }
             }
-
-            var strict = _isStrict || script.Strict;
-            ExecuteWithConstraints(strict, DoInvoke);
-
-            return this;
+            finally
+            {
+                LeaveExecutionContext();
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -397,7 +416,7 @@ namespace Jint
 
 
             if (baseValue.IsUndefined())
             if (baseValue.IsUndefined())
             {
             {
-                if (_referenceResolver.TryUnresolvableReference(this, reference, out JsValue val))
+                if (_referenceResolver.TryUnresolvableReference(this, reference, out var val))
                 {
                 {
                     return val;
                     return val;
                 }
                 }
@@ -782,7 +801,7 @@ namespace Jint
                         var fnDefinable = env.CanDeclareGlobalFunction(fn);
                         var fnDefinable = env.CanDeclareGlobalFunction(fn);
                         if (!fnDefinable)
                         if (!fnDefinable)
                         {
                         {
-                            ExceptionHelper.ThrowTypeError(realm);
+                            ExceptionHelper.ThrowTypeError(realm, "Cannot declare global function " + fn);
                         }
                         }
 
 
                         declaredFunctionNames.Add(fn);
                         declaredFunctionNames.Add(fn);
@@ -891,8 +910,8 @@ namespace Jint
             var hasParameterExpressions = configuration.HasParameterExpressions;
             var hasParameterExpressions = configuration.HasParameterExpressions;
 
 
             var canInitializeParametersOnDeclaration = simpleParameterList && !configuration.HasDuplicates;
             var canInitializeParametersOnDeclaration = simpleParameterList && !configuration.HasDuplicates;
-            env.InitializeParameters(parameterNames, hasDuplicates,
-                canInitializeParametersOnDeclaration ? argumentsList : null);
+            var arguments = canInitializeParametersOnDeclaration ? argumentsList : null;
+            env.InitializeParameters(parameterNames, hasDuplicates, arguments);
 
 
             ArgumentsInstance ao = null;
             ArgumentsInstance ao = null;
             if (configuration.ArgumentsObjectNeeded)
             if (configuration.ArgumentsObjectNeeded)

+ 3 - 1
Jint/Native/Function/FunctionInstance.cs

@@ -26,6 +26,7 @@ namespace Jint.Native.Function
 
 
         internal Realm _realm;
         internal Realm _realm;
         private PrivateEnvironmentRecord _privateEnvironment;
         private PrivateEnvironmentRecord _privateEnvironment;
+        private readonly IScriptOrModule _scriptOrModule;
 
 
         protected FunctionInstance(
         protected FunctionInstance(
             Engine engine,
             Engine engine,
@@ -65,6 +66,7 @@ namespace Jint.Native.Function
             }
             }
             _realm = realm;
             _realm = realm;
             _thisMode = thisMode;
             _thisMode = thisMode;
+            _scriptOrModule = _engine.GetActiveScriptOrModule();
         }
         }
 
 
         // for example RavenDB wants to inspect this
         // for example RavenDB wants to inspect this
@@ -349,7 +351,7 @@ namespace Jint.Native.Function
             var calleeRealm = _realm;
             var calleeRealm = _realm;
 
 
             var calleeContext = new ExecutionContext(
             var calleeContext = new ExecutionContext(
-                null,
+                _scriptOrModule,
                 localEnv,
                 localEnv,
                 localEnv,
                 localEnv,
                 _privateEnvironment,
                 _privateEnvironment,

+ 5 - 0
Jint/Runtime/ScriptRecord.cs

@@ -0,0 +1,5 @@
+using Esprima.Ast;
+
+namespace Jint.Runtime;
+
+internal sealed record ScriptRecord(Realm Realm, Script EcmaScriptCode, string Location) : IScriptOrModule;