diff --git a/src/ScriptEngine.HostedScript/HostedScriptEngine.cs b/src/ScriptEngine.HostedScript/HostedScriptEngine.cs
index 6ed02ed64..d2c6dfc5d 100644
--- a/src/ScriptEngine.HostedScript/HostedScriptEngine.cs
+++ b/src/ScriptEngine.HostedScript/HostedScriptEngine.cs
@@ -12,7 +12,6 @@ This Source Code Form is subject to the terms of the
using OneScript.Compilation;
using OneScript.Contexts;
using OneScript.DependencyInjection;
-using OneScript.Execution;
using OneScript.StandardLibrary;
using OneScript.StandardLibrary.Tasks;
using ScriptEngine.Machine.Contexts;
@@ -85,35 +84,64 @@ public ICompilerFrontend GetCompilerService()
{
var compilerSvc = _engine.GetCompilerService();
compilerSvc.FillSymbols(typeof(UserScriptContextInstance));
-
+ DefineConstants(compilerSvc);
return compilerSvc;
}
+ ///
+ /// Создаёт процесс выполнения скрипта: инициализация, компиляция исходника, подготовка к запуску.
+ ///
+ /// Хост-приложение для взаимодействия со скриптом.
+ /// Исходный код скрипта.
+ /// Процесс, готовый к вызову .
+ ///
+ /// При ошибке компиляции или подготовки исключение пробрасывается вызывающему коду.
+ ///
public Process CreateProcess(IHostApplication host, SourceCode src)
{
Initialize();
SetGlobalEnvironment(host, src);
-
- if (_engine.Debugger.IsEnabled)
- {
- _engine.Debugger.Start();
- _engine.Debugger.GetSession().WaitReadyToRun();
- }
var compilerSvc = GetCompilerService();
- DefineConstants(compilerSvc);
- IExecutableModule module;
- var bslProcess = _engine.NewProcess();
+ return Process.Create(_engine, compilerSvc, src);
+ }
+
+ ///
+ /// Создаёт и запускает процесс скрипта, возвращает код завершения.
+ ///
+ /// Хост-приложение для взаимодействия со скриптом.
+ /// Исходный код скрипта.
+ ///
+ /// Код завершения скрипта; при ошибке создания/выполнения — 1
+ /// после вывода информации об исключении через .
+ ///
+ ///
+ /// Управляет сессией отладчика: старт и ожидание готовности перед созданием процесса,
+ /// уведомление о завершении при любом исходе.
+ /// Прерывание скрипта () обрабатывается в
+ /// и возвращается как штатный код выхода.
+ ///
+ public int RunProcess(IHostApplication host, SourceCode source)
+ {
try
{
- module = compilerSvc.Compile(src, bslProcess);
+ if (_engine.Debugger.IsEnabled)
+ {
+ _engine.Debugger.Start();
+ _engine.Debugger.GetSession().WaitReadyToRun();
+ }
+
+ var process = CreateProcess(host, source);
+ var exitCode = process.Start();
+ _engine.Debugger.NotifyProcessExit(exitCode);
+ return exitCode;
}
- catch (CompilerException)
+ catch (Exception e)
{
_engine.Debugger.NotifyProcessExit(1);
- throw;
+ host.ShowExceptionInfo(e);
+ return 1;
}
- return InitProcess(bslProcess, host, module);
}
private void DefineConstants(ICompilerFrontend compilerSvc)
@@ -139,14 +167,6 @@ public void SetGlobalEnvironment(IHostApplication host, SourceCode src)
_globalCtx.InitInstance();
}
- private Process InitProcess(IBslProcess bslProcess, IHostApplication host, IExecutableModule module)
- {
- Initialize();
-
- var process = new Process(bslProcess, host, module, _engine);
- return process;
- }
-
public void Dispose()
{
_engine?.Dispose();
diff --git a/src/ScriptEngine.HostedScript/Process.cs b/src/ScriptEngine.HostedScript/Process.cs
index 39a36d266..5159a8c51 100644
--- a/src/ScriptEngine.HostedScript/Process.cs
+++ b/src/ScriptEngine.HostedScript/Process.cs
@@ -4,59 +4,66 @@ This Source Code Form is subject to the terms of the
was not distributed with this file, You can obtain one
at http://mozilla.org/MPL/2.0/.
----------------------------------------------------------*/
-using System;
+
+using OneScript.Compilation;
using OneScript.Execution;
+using OneScript.Sources;
using ScriptEngine.Machine;
namespace ScriptEngine.HostedScript
{
+ ///
+ /// Скомпилированный процесс выполнения скрипта.
+ ///
public class Process
{
- ScriptingEngine _engine;
-
- readonly IHostApplication _host;
- readonly IExecutableModule _module;
- private IBslProcess _bslProcess;
+ private readonly ScriptingEngine _engine;
+ private readonly IExecutableModule _module;
+ private readonly IBslProcess _bslProcess;
- internal Process(
+ private Process(
IBslProcess process,
- IHostApplication host,
IExecutableModule src,
ScriptingEngine runtime)
{
- _host = host;
_engine = runtime;
_module = src;
_bslProcess = process;
}
- public int Start()
+ ///
+ /// Создаёт процесс: выделяет runtime-процесс, компилирует исходник, готовит к запуску.
+ ///
+ internal static Process Create(
+ ScriptingEngine engine,
+ ICompilerFrontend compiler,
+ SourceCode source)
{
- int exitCode = 0;
+ var bslProcess = engine.NewProcess();
+ var module = compiler.Compile(source, bslProcess);
+ return new Process(bslProcess, module, engine);
+ }
+ ///
+ /// Запускает выполнение скрипта.
+ ///
+ ///
+ /// 0 при успешном завершении; код выхода при прерывании скрипта.
+ ///
+ ///
+ /// Прочие исключения пробрасываются вызывающему коду.
+ ///
+ public int Start()
+ {
try
{
_engine.NewObject(_module, _bslProcess);
- exitCode = 0;
+ return 0;
}
catch (ScriptInterruptionException e)
{
- exitCode = e.ExitCode;
+ return e.ExitCode;
}
- catch (Exception e)
- {
- _host.ShowExceptionInfo(e);
- exitCode = 1;
- }
- finally
- {
- _engine.Debugger.NotifyProcessExit(exitCode);
- _engine.Dispose();
- _engine = null;
- }
-
- return exitCode;
}
-
}
}
diff --git a/src/TestApp/MainWindow.xaml.cs b/src/TestApp/MainWindow.xaml.cs
index 320401b17..d60cec9e5 100644
--- a/src/TestApp/MainWindow.xaml.cs
+++ b/src/TestApp/MainWindow.xaml.cs
@@ -159,7 +159,7 @@ private HostedScriptEngine CreateEngine()
private void Button_Click(object sender, RoutedEventArgs e)
{
- var hostedScript = CreateEngine();
+ using var hostedScript = CreateEngine();
hostedScript.Initialize();
var src = hostedScript.Loader.FromString(txtCode.Text);
@@ -205,27 +205,16 @@ private void Button_Click_1(object sender, RoutedEventArgs e)
var host = new Host(result, l_args.ToArray());
SystemLogger.SetWriter(host);
- var hostedScript = CreateEngine();
+ using var hostedScript = CreateEngine();
var src = SourceCodeBuilder.Create()
.FromSource(new EditedFileSource(txtCode.Text, _currentDocPath))
.WithName(_currentDocPath)
.Build();
- Process process = null;
- try
- {
- process = hostedScript.CreateProcess(host, src);
- }
- catch (Exception exc)
- {
- host.Echo(exc.Message);
- return;
- }
-
result.AppendText("Script started: " + DateTime.Now.ToString() + "\n");
sw.Start();
- var returnCode = process.Start();
+ var returnCode = hostedScript.RunProcess(host, src);
sw.Stop();
if (returnCode != 0)
{
@@ -233,7 +222,6 @@ private void Button_Click_1(object sender, RoutedEventArgs e)
}
result.AppendText("\nScript completed: " + DateTime.Now.ToString());
result.AppendText("\nDuration: " + sw.Elapsed.ToString() + "\n");
-
}
private static string GetFileDialogFilter()
@@ -422,11 +410,18 @@ public Host(TextBox output, string [] arguments = null)
public void Echo(string str, MessageStatusEnum status = MessageStatusEnum.Ordinary)
{
- _output.Dispatcher.BeginInvoke(new Action(() =>
+ void Append()
{
_output.AppendText(str + '\n');
_output.ScrollToEnd();
- }));
+ }
+
+ // RunProcess вызывается с UI-потока: без синхронной записи
+ // ShowExceptionInfo оказывается после "Error detected" / "Script completed".
+ if (_output.Dispatcher.CheckAccess())
+ Append();
+ else
+ _output.Dispatcher.BeginInvoke(new Action(Append));
}
public void ShowExceptionInfo(Exception exc)
diff --git a/src/oscript/CgiBehavior.cs b/src/oscript/CgiBehavior.cs
index 3354a0597..f0781bf9e 100644
--- a/src/oscript/CgiBehavior.cs
+++ b/src/oscript/CgiBehavior.cs
@@ -68,33 +68,17 @@ private int RunCGIMode(string scriptFile)
e.AddAssembly(GetType().Assembly);
});
- var engine = ConsoleHostBuilder.Build(builder);
-
- var request = new WebRequestContext(engine.Services.Resolve().MaxBytesInMemory);
+ using var engine = ConsoleHostBuilder.Build(builder);
+ using var request = new WebRequestContext(engine.Services.Resolve().MaxBytesInMemory);
engine.InjectGlobalProperty("ВебЗапрос", "WebRequest", request, true);
engine.InjectObject(this);
var source = engine.Loader.FromFile(scriptFile);
-
- Process process;
-
- try
- {
- process = engine.CreateProcess(this, source);
- }
- catch (Exception e)
- {
- ShowExceptionInfo(e);
- return 1;
- }
-
- var exitCode = process.Start();
+ var exitCode = engine.RunProcess(this, source);
if (!_isContentEchoed)
Echo("");
- request.Dispose();
-
return exitCode;
}
diff --git a/src/oscript/CheckSyntaxBehavior.cs b/src/oscript/CheckSyntaxBehavior.cs
index aa285ec6e..3148fd1e4 100644
--- a/src/oscript/CheckSyntaxBehavior.cs
+++ b/src/oscript/CheckSyntaxBehavior.cs
@@ -28,7 +28,7 @@ public CheckSyntaxBehavior(string path, string envFile, bool isCgi = false)
public override int Execute()
{
var builder = ConsoleHostBuilder.Create(_path);
- var hostedScript = ConsoleHostBuilder.Build(builder);
+ using var hostedScript = ConsoleHostBuilder.Build(builder);
hostedScript.Initialize();
if (_isCgi)
diff --git a/src/oscript/ConsoleApplicationHost.cs b/src/oscript/ConsoleApplicationHost.cs
index 45b2bc11c..412ee0384 100644
--- a/src/oscript/ConsoleApplicationHost.cs
+++ b/src/oscript/ConsoleApplicationHost.cs
@@ -33,19 +33,7 @@ public void Write(string text)
public int RunProcess(HostedScriptEngine engine, SourceCode source)
{
SystemLogger.SetWriter(this);
-
- Process process;
- try
- {
- process = engine.CreateProcess(this, source);
- }
- catch (Exception e)
- {
- ShowExceptionInfo(e);
- return 1;
- }
-
- return process.Start();
+ return engine.RunProcess(this, source);
}
}
}
diff --git a/src/oscript/ShowCompiledBehavior.cs b/src/oscript/ShowCompiledBehavior.cs
index 5be120562..cf257d264 100644
--- a/src/oscript/ShowCompiledBehavior.cs
+++ b/src/oscript/ShowCompiledBehavior.cs
@@ -23,7 +23,7 @@ public ShowCompiledBehavior(string path)
public override int Execute()
{
var builder = ConsoleHostBuilder.Create(_path);
- var hostedScript = ConsoleHostBuilder.Build(builder);
+ using var hostedScript = ConsoleHostBuilder.Build(builder);
hostedScript.Initialize();
var source = hostedScript.Loader.FromFile(_path);