diff --git a/src/ScriptEngine.HostedScript/HostedScriptEngine.cs b/src/ScriptEngine.HostedScript/HostedScriptEngine.cs index 23aaa81da..f41496ce5 100644 --- a/src/ScriptEngine.HostedScript/HostedScriptEngine.cs +++ b/src/ScriptEngine.HostedScript/HostedScriptEngine.cs @@ -27,8 +27,6 @@ public class HostedScriptEngine : IDisposable private bool _isInitialized; private readonly OneScriptLibraryOptions _workingConfig; - - private CodeStatProcessor _codeStat; public HostedScriptEngine(ScriptingEngine engine) { @@ -143,22 +141,10 @@ private Process InitProcess(IHostApplication host, IExecutableModule module) var process = new Process(host, module, _engine); return process; } - - public void EnableCodeStatistics() - { - _codeStat = new CodeStatProcessor(); - _engine.SetCodeStatisticsCollector(_codeStat); - } - - public CodeStatDataCollection GetCodeStatData() - { - return _codeStat.GetStatData(); - } public void Dispose() { _engine?.Dispose(); - _codeStat?.EndCodeStat(); } } } diff --git a/src/ScriptEngine/Machine/CodeStat/CodeStatProcessor.cs b/src/ScriptEngine/Machine/CodeStat/CodeStatProcessor.cs index cee7b1f86..15be6508f 100644 --- a/src/ScriptEngine/Machine/CodeStat/CodeStatProcessor.cs +++ b/src/ScriptEngine/Machine/CodeStat/CodeStatProcessor.cs @@ -1,94 +1,90 @@ -/*---------------------------------------------------------- -This Source Code Form is subject to the terms of the -Mozilla Public License, v.2.0. If a copy of the MPL -was not distributed with this file, You can obtain one -at http://mozilla.org/MPL/2.0/. -----------------------------------------------------------*/ - -using System.Diagnostics; -using System.Collections.Generic; - -namespace ScriptEngine.Machine -{ - public class CodeStatProcessor : ICodeStatCollector - { - private Dictionary _codeStat = new Dictionary(); - private Dictionary _watchers = new Dictionary(); - private Stopwatch _activeStopwatch = null; - private HashSet _preparedScripts = new HashSet(); - - public CodeStatProcessor() - { - } - - public bool IsPrepared(string ScriptFileName) - { - return _preparedScripts.Contains(ScriptFileName); - } - - public void MarkEntryReached(CodeStatEntry entry, int count = 1) - { - int oldValue = 0; - _codeStat.TryGetValue(entry, out oldValue); - _codeStat[entry] = oldValue + count; - - if (count == 0) - { - if (!_watchers.ContainsKey(entry)) - { - _watchers.Add(entry, new Stopwatch()); - } - } - else - { - _activeStopwatch?.Stop(); - _activeStopwatch = _watchers[entry]; - _activeStopwatch.Start(); - } - } - - public void MarkPrepared(string scriptFileName) - { - _preparedScripts.Add(scriptFileName); - } - - public CodeStatDataCollection GetStatData() - { - CodeStatDataCollection data = new CodeStatDataCollection(); - foreach (var item in _codeStat) - { - if (!IsPrepared(item.Key.ScriptFileName)) - { - continue; - } - data.Add(new CodeStatData(item.Key, _watchers[item.Key].ElapsedMilliseconds, item.Value)); - } - - return data; - } - - public void EndCodeStat() - { - _activeStopwatch?.Stop(); - } - - public void StopWatch(CodeStatEntry entry) - { - if (_watchers.ContainsKey(entry)) - { - _watchers[entry].Stop(); - } - } - - public void ResumeWatch(CodeStatEntry entry) - { - _activeStopwatch?.Stop(); - - if (_watchers.ContainsKey(entry)) - { - _activeStopwatch = _watchers[entry]; - _activeStopwatch.Start(); - } - } - } -} +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ + +using System.Diagnostics; +using System.Collections.Generic; + +namespace ScriptEngine.Machine +{ + public class CodeStatProcessor : ICodeStatCollector + { + private Dictionary _codeStat = new Dictionary(); + private Dictionary _watchers = new Dictionary(); + private Stopwatch _activeStopwatch = null; + private HashSet _preparedScripts = new HashSet(); + + public bool IsPrepared(string ScriptFileName) + { + return _preparedScripts.Contains(ScriptFileName); + } + + public void MarkEntryReached(CodeStatEntry entry, int count = 1) + { + int oldValue = 0; + _codeStat.TryGetValue(entry, out oldValue); + _codeStat[entry] = oldValue + count; + + if (count == 0) + { + if (!_watchers.ContainsKey(entry)) + { + _watchers.Add(entry, new Stopwatch()); + } + } + else + { + _activeStopwatch?.Stop(); + _activeStopwatch = _watchers[entry]; + _activeStopwatch.Start(); + } + } + + public void MarkPrepared(string scriptFileName) + { + _preparedScripts.Add(scriptFileName); + } + + public CodeStatDataCollection GetStatData() + { + CodeStatDataCollection data = new CodeStatDataCollection(); + foreach (var item in _codeStat) + { + if (!IsPrepared(item.Key.ScriptFileName)) + { + continue; + } + data.Add(new CodeStatData(item.Key, _watchers[item.Key].ElapsedMilliseconds, item.Value)); + } + + return data; + } + + public void EndCodeStat() + { + _activeStopwatch?.Stop(); + } + + public void StopWatch(CodeStatEntry entry) + { + if (_watchers.ContainsKey(entry)) + { + _watchers[entry].Stop(); + } + } + + public void ResumeWatch(CodeStatEntry entry) + { + _activeStopwatch?.Stop(); + + if (_watchers.ContainsKey(entry)) + { + _activeStopwatch = _watchers[entry]; + _activeStopwatch.Start(); + } + } + } +} diff --git a/src/ScriptEngine/Machine/MachineInstance.cs b/src/ScriptEngine/Machine/MachineInstance.cs index 4759269da..966b8d9be 100644 --- a/src/ScriptEngine/Machine/MachineInstance.cs +++ b/src/ScriptEngine/Machine/MachineInstance.cs @@ -96,6 +96,7 @@ public void SetMemory(ExecutionContext memory) ContextsAttached(); _mem = memory; + _codeStatCollector = _mem.Services.TryResolve(); } internal MachineStoredState SaveState() @@ -107,7 +108,6 @@ internal MachineStoredState SaveState() CallStack = _callStack, OperationStack = _operationStack, StopManager = _stopManager, - CodeStatCollector = _codeStatCollector, Memory = _mem }; } @@ -120,7 +120,6 @@ internal void RestoreState(MachineStoredState state) _callStack = state.CallStack; _exceptionsStack = state.ExceptionsStack; _stopManager = state.StopManager; - _codeStatCollector = state.CodeStatCollector; _mem = state.Memory; SetFrame(_callStack.Peek()); @@ -571,11 +570,6 @@ private bool ShouldRethrowException(ScriptException exc) return false; } - public void SetCodeStatisticsCollector(ICodeStatCollector collector) - { - _codeStatCollector = collector; - } - private CodeStatEntry CurrentCodeEntry() { return new CodeStatEntry(CurrentScript?.Source, _currentFrame.MethodName, _currentFrame.LineNumber); diff --git a/src/ScriptEngine/ScriptingEngine.cs b/src/ScriptEngine/ScriptingEngine.cs index 8a5bc73bb..3388bdf0a 100644 --- a/src/ScriptEngine/ScriptingEngine.cs +++ b/src/ScriptEngine/ScriptingEngine.cs @@ -83,7 +83,7 @@ public void AttachExternalAssembly(System.Reflection.Assembly asm) public void Initialize() { SetDefaultEnvironmentIfNeeded(); - + EnableCodeStatistics(); UpdateContexts(); _attachedScriptsFactory = new AttachedScriptsFactory(this); @@ -186,10 +186,13 @@ private set } } - public void SetCodeStatisticsCollector(ICodeStatCollector collector) + private void EnableCodeStatistics() { + var collector = Services.TryResolve(); + if (collector == default) + return; + ProduceExtraCode |= CodeGenerationFlags.CodeStatistics; - MachineInstance.Current.SetCodeStatisticsCollector(collector); } #region IDisposable Members diff --git a/src/oscript/ExecuteScriptBehavior.cs b/src/oscript/ExecuteScriptBehavior.cs index 12ee05a04..9e6069be2 100644 --- a/src/oscript/ExecuteScriptBehavior.cs +++ b/src/oscript/ExecuteScriptBehavior.cs @@ -1,105 +1,111 @@ -/*---------------------------------------------------------- -This Source Code Form is subject to the terms of the -Mozilla Public License, v.2.0. If a copy of the MPL -was not distributed with this file, You can obtain one -at http://mozilla.org/MPL/2.0/. -----------------------------------------------------------*/ -using System; -using OneScript.StandardLibrary; -using ScriptEngine; -using ScriptEngine.HostedScript; -using ScriptEngine.Hosting; -using ScriptEngine.Machine; - -namespace oscript -{ - class ExecuteScriptBehavior : AppBehavior, IHostApplication, ISystemLogWriter - { - protected string[] _scriptArgs; - protected string _path; - - public ExecuteScriptBehavior(string path, string[] args) - { - _scriptArgs = args; - _path = path; - } - - public IDebugController DebugController { get; set; } - - public string CodeStatFile { get; set; } - - public bool CodeStatisticsEnabled => CodeStatFile != null; - - public override int Execute() - { - if (!System.IO.File.Exists(_path)) - { - Echo($"Script file is not found '{_path}'"); - return 2; - } - - SystemLogger.SetWriter(this); - - var builder = ConsoleHostBuilder.Create(_path); - builder.WithDebugger(DebugController); - - var hostedScript = ConsoleHostBuilder.Build(builder); - - if (CodeStatisticsEnabled) - hostedScript.EnableCodeStatistics(); - - var source = hostedScript.Loader.FromFile(_path); - Process process; - try - { - process = hostedScript.CreateProcess(this, source); - } - catch (Exception e) - { - ShowExceptionInfo(e); - return 1; - } - - var result = process.Start(); - hostedScript.Dispose(); - - if (CodeStatisticsEnabled) - { - var codeStat = hostedScript.GetCodeStatData(); - var statsWriter = new CodeStatWriter(CodeStatFile, CodeStatWriterType.JSON); - statsWriter.Write(codeStat); - } - - return result; - } - - #region IHostApplication Members - - public void Echo(string text, MessageStatusEnum status = MessageStatusEnum.Ordinary) - { - ConsoleHostImpl.Echo(text, status); - } - - public void ShowExceptionInfo(Exception exc) - { - ConsoleHostImpl.ShowExceptionInfo(exc); - } - - public bool InputString(out string result, string prompt, int maxLen, bool multiline) - { - return ConsoleHostImpl.InputString(out result, prompt, maxLen, multiline); - } - - public string[] GetCommandLineArguments() - { - return _scriptArgs; - } - - #endregion - - public void Write(string text) - { - Console.Error.WriteLine(text); - } - } -} +/*---------------------------------------------------------- +This Source Code Form is subject to the terms of the +Mozilla Public License, v.2.0. If a copy of the MPL +was not distributed with this file, You can obtain one +at http://mozilla.org/MPL/2.0/. +----------------------------------------------------------*/ +using System; +using OneScript.StandardLibrary; +using ScriptEngine; +using ScriptEngine.HostedScript; +using ScriptEngine.Hosting; +using ScriptEngine.Machine; + +namespace oscript +{ + class ExecuteScriptBehavior : AppBehavior, IHostApplication, ISystemLogWriter + { + protected string[] _scriptArgs; + protected string _path; + + public ExecuteScriptBehavior(string path, string[] args) + { + _scriptArgs = args; + _path = path; + } + + public IDebugController DebugController { get; set; } + + public string CodeStatFile { get; set; } + + public bool CodeStatisticsEnabled => CodeStatFile != null; + + public override int Execute() + { + if (!System.IO.File.Exists(_path)) + { + Echo($"Script file is not found '{_path}'"); + return 2; + } + + SystemLogger.SetWriter(this); + + var builder = ConsoleHostBuilder.Create(_path); + builder.WithDebugger(DebugController); + CodeStatProcessor codeStatProcessor = null; + if (CodeStatisticsEnabled) + { + codeStatProcessor = new CodeStatProcessor(); + builder.Services.RegisterSingleton(codeStatProcessor); + } + + var hostedScript = ConsoleHostBuilder.Build(builder); + + + + var source = hostedScript.Loader.FromFile(_path); + Process process; + try + { + process = hostedScript.CreateProcess(this, source); + } + catch (Exception e) + { + ShowExceptionInfo(e); + return 1; + } + + var result = process.Start(); + hostedScript.Dispose(); + + if (codeStatProcessor != null) + { + codeStatProcessor.EndCodeStat(); + var codeStat = codeStatProcessor.GetStatData(); + var statsWriter = new CodeStatWriter(CodeStatFile, CodeStatWriterType.JSON); + statsWriter.Write(codeStat); + } + + return result; + } + + #region IHostApplication Members + + public void Echo(string text, MessageStatusEnum status = MessageStatusEnum.Ordinary) + { + ConsoleHostImpl.Echo(text, status); + } + + public void ShowExceptionInfo(Exception exc) + { + ConsoleHostImpl.ShowExceptionInfo(exc); + } + + public bool InputString(out string result, string prompt, int maxLen, bool multiline) + { + return ConsoleHostImpl.InputString(out result, prompt, maxLen, multiline); + } + + public string[] GetCommandLineArguments() + { + return _scriptArgs; + } + + #endregion + + public void Write(string text) + { + Console.Error.WriteLine(text); + } + } +}