Beispiel #1
0
        /// <summary>
        /// Change the state of the interpreter.
        /// </summary>
        /// <param name="source">The source from where we changed the state (an interpreter usually).</param>
        /// <param name="e">The new state.</param>
        internal void ChangeState(object source, BaZicInterpreterStateChangeEventArgs e)
        {
            if (e.State == BaZicInterpreterState.StoppedWithError || e.State == BaZicInterpreterState.Stopped)
            {
                ProgramInterpreter?.CloseUserInterface();
            }

            lock (_stateChangedHistory)
            {
                var oldState = State;

                switch (e.State)
                {
                case BaZicInterpreterState.StoppedWithError:
                    if (State != BaZicInterpreterState.StoppedWithError)
                    {
                        Error = e.Error;
                        State = e.State;
                    }
                    break;

                case BaZicInterpreterState.Pause:
                case BaZicInterpreterState.Preparing:
                case BaZicInterpreterState.Ready:
                case BaZicInterpreterState.Running:
                case BaZicInterpreterState.Idle:
                case BaZicInterpreterState.Stopped:
                    State = e.State;
                    break;

                case BaZicInterpreterState.Log:
                    Logger.Instance.Debug($"BaZic Interpreter : {e.LogMessage}");
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(e.State));
                }

                if (e.State == BaZicInterpreterState.Log || e.State == BaZicInterpreterState.Ready || State != oldState)
                {
                    _stateChangedHistory.Add(e);
                    StateChanged?.Invoke(this, e);
                    _middleware.SendLog(this, e);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Starts the interpreter in debug mode. The program will be interpreted and support the beakpoint and step by step debugging.
        /// </summary>
        /// <param name="callback">The cross-AppDomain task proxy.</param>
        /// <param name="verbose">Defines if the verbose mode must be enabled or not.</param>
        /// <param name="args">The arguments to pass to the entry point.</param>
        /// <returns>Returns an awaitable task that can wait the end of the program execution</returns>
        internal void StartDebug(MarshaledResultSetter callback, bool verbose, params object[] args)
        {
            Requires.NotNull(_middleware, nameof(_middleware));
            if (_releaseModeForced)
            {
                throw new UnexpectedException(new Exception(L.BaZic.Runtime.BaZicInterpreter.CannotStartDebugAfterBuild));
            }

            _forceStop = false;
            DebugMode  = true;

            var action = new Action(() =>
            {
                LoadAssemblies();

                if (State == BaZicInterpreterState.Preparing)
                {
                    if (ProgramInterpreter == null)
                    {
                        var executionFlowId = RunningStateManager.AddCallStackForUnwaitedMethodInvocation();
                        RunningStateManager.SetIsRunningMainFunction(true);

                        ProgramInterpreter = new ProgramInterpreter(this, Program, executionFlowId);
                    }

                    ProgramInterpreter.Start(_programArguments);

                    RunningStateManager.WaitUnwaitedMethodInvocation(ProgramInterpreter.ExecutionFlowId);

                    if (State == BaZicInterpreterState.Running || State == BaZicInterpreterState.Idle)
                    {
                        ProgramResult = ProgramInterpreter.ProgramResult;
                        FreePauseModeWaiter();
                    }
                }
            });

            callback.ContinueWith(() =>
            {
                RunningStateManager.SetIsRunningMainFunction(false);
                RunningStateManager.UpdateState();
            }, null);

            Start(callback, action, verbose, args);
        }
 /// <summary>
 /// Dispose the resources
 /// </summary>
 public void Dispose()
 {
     Stop();
     if (ProgramInterpreter != null)
     {
         ProgramInterpreter.Dispose();
     }
     if (_stateChangedHistory != null)
     {
         _stateChangedHistory.Clear();
     }
     if (DebugInfo != null)
     {
         DebugInfo.CallStackService.StackTraceCallCount.Clear();
         DebugInfo.CallStackService.CallStacks.Clear();
         DebugInfo.CallStackService.CallCount = 0;
         DebugInfo = null;
     }
     Error = null;
     Program = null;
     ProgramInterpreter = null;
 }
        /// <summary>
        /// Start the interpreter
        /// </summary>
        /// <param name="debugMode">Defines if the debug mode must be enabled or not</param>
        /// <returns>Returns an awaitable task that can wait the end of the program execution</returns>
        private Task RunAsync(bool debugMode)
        {
            InDebugMode = debugMode;
            return Task.Run(() =>
            {
                RuntimeHelpers.EnsureSufficientExecutionStack();
                GCSettings.LatencyMode = GCLatencyMode.LowLatency;

                ProgramInterpreter = new ProgramInterpreter(Program, debugMode);

                ProgramInterpreter.StateChanged += ChangeState;
                ProgramInterpreter.Start();

                Stop(false);

                ProgramInterpreter.StateChanged -= ChangeState;
                ProgramInterpreter.Dispose();

                GCSettings.LatencyMode = GCLatencyMode.Interactive;
                GC.Collect();
                GC.WaitForPendingFinalizers();
            });
        }
Beispiel #5
0
        /// <summary>
        /// Invoke a public method accessible from outside of the interpreter (EXTERN FUNCTION) in Debug mode.
        /// </summary>
        /// <param name="callback">The cross-AppDomain task proxy.</param>
        /// <param name="verbose">Defines if the verbose mode must be enabled or not.</param>
        /// <param name="methodName">The name of the method.</param>
        /// <param name="awaitIfAsync">Await if the method is maked as asynchronous.</param>
        /// <param name="args">The arguments to pass to the method.</param>
        /// <returns>Returns the result of the invocation (a <see cref="Task"/> in the case of a not awaited asynchronous method, or the value returned by the method).</returns>
        private async void InvokeMethodDebug(MarshaledResultSetter <object> callback, bool verbose, string methodName, bool awaitIfAsync, object[] args)
        {
            DebugMode = true;

            if (State == BaZicInterpreterState.Ready || State == BaZicInterpreterState.Stopped || State == BaZicInterpreterState.StoppedWithError)
            {
                // Creates a new ProgramInterpreter.

                var privateCallback = new MarshaledResultSetter();
                var action          = new Action(() =>
                {
                    LoadAssemblies();

                    if (State == BaZicInterpreterState.Preparing)
                    {
                        var executionFlowIdProgram = RunningStateManager.AddCallStackForUnwaitedMethodInvocation();

                        ProgramInterpreter = new ProgramInterpreter(this, Program, executionFlowIdProgram);
                        ProgramInterpreter.InitializeGlobalState();
                        ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Idle));
                    }
                });

                Start(privateCallback, action, verbose);
                await privateCallback.Task;
            }

            var currentCulture = LocalizationHelper.GetCurrentCulture();

            var thread = Task.Run(() =>
            {
                object result = null;
                try
                {
                    LocalizationHelper.SetCurrentCulture(currentCulture, false, false);

                    Task.Delay(500).ConfigureAwait(false).GetAwaiter().GetResult();

                    if (State == BaZicInterpreterState.Preparing)
                    {
                        // Wait for running.
                        WaitForState(BaZicInterpreterState.Running, BaZicInterpreterState.Idle);
                    }

                    if (State == BaZicInterpreterState.Running)
                    {
                        // Wait for having being idle.
                        WaitForState(BaZicInterpreterState.Idle, BaZicInterpreterState.Stopped, BaZicInterpreterState.StoppedWithError);

                        if (_forceStop)
                        {
                            // The state is Stopped and it has been requested by the user (command await Stop()) or the interpreter is disposing.
                            return(null);
                        }
                    }

                    CheckState(BaZicInterpreterState.Idle, BaZicInterpreterState.Stopped, BaZicInterpreterState.StoppedWithError);

                    var arguments = new List <PrimitiveExpression>();
                    if (args != null)
                    {
                        foreach (var argument in args)
                        {
                            arguments.Add(new PrimitiveExpression(argument));
                        }
                    }

                    RunningStateManager.StartsExternMethod();
                    var executionFlowId = RunningStateManager.AddCallStackForUnwaitedMethodInvocation();

                    result = ProgramInterpreter.InvokeMethod(executionFlowId, methodName, awaitIfAsync, arguments.ToArray());
                }
                catch (Exception exception)
                {
                    CoreHelper.ReportException(exception);
                    if (!_ignoreException)
                    {
                        ChangeState(this, new UnexpectedException(exception));
                    }

                    _ignoreException = false;
                }
                finally
                {
                    RunningStateManager.StopsExternMethod();
                    RunningStateManager.UpdateState();
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }

                return(result);
            });

            var t = thread.ContinueWith((task) =>
            {
                callback.SetResult(task.Result);
            });
        }