public ScriptEngine(bool debugOutput = false) { _debugOutput = debugOutput; _runtime = new Microsoft.ClearScript.V8.V8Runtime(); _engine = _runtime.CreateScriptEngine(); _engine.AddHostObject("setTimeout", new Func <dynamic, int, int>(setTimeout)); _engine.AddHostObject("clearTimeout", new Action <int>(clearTimeout)); Func <OutputKind, Action <object> > debugWrite = k => o => log(Convert.ToString(o), k); _engine.AddHostObject("console", new { log = debugWrite(OutputKind.Log), error = debugWrite(OutputKind.Error), warn = debugWrite(OutputKind.Warning), debug = _debugOutput ? debugWrite(OutputKind.Debug) : null }); var queueTransition = new Subject <bool>(); var runQueue = _queue .Do(_ => queueTransition.OnNext(true)) .ObserveOn(System.Reactive.Concurrency.ThreadPoolScheduler.Instance) .Do(a => a()) .Do(_ => queueTransition.OnNext(false), queueTransition.OnError, queueTransition.OnCompleted) .Publish(); var queueSize = queueTransition .Scan(0, (size, queued) => size + (queued ? 1 : -1)) .Do(s => log("ScriptEngine: Queue size = " + s, OutputKind.Debug), (Exception ex) => log(ex.ToString(), OutputKind.Error)) .Replay(1); _runningQueue = new CompositeDisposable(runQueue.Connect(), queueSize.Connect()); _queueSize = queueSize; _doneActions = runQueue; }
public ReactRunner(string file, bool enableFileWatcher, bool enableCompilation, bool disableGlobalMembers, JsonSerializerSettings serializationSettings) { //setup assembly resolver so it can find the v8 dlls AssemblyResolver.Initialize(); JsFile = file; EnableFileWatcher = enableFileWatcher; EnableCompilation = enableCompilation; DisableGlobalMembers = disableGlobalMembers; SerializationSettings = serializationSettings; //Initialize the v8 runtime Runtime = new V8Runtime(); //Read the scripts text content ScriptRaw = File.ReadAllText(JsFile); if (EnableCompilation) { //If compilation is enabled, we compile the scripts Compiled = Runtime.Compile(ScriptRaw); CompiledShimms = Runtime.Compile(JavascriptShimms.ConsoleShim); } if (EnableFileWatcher) { fileWatcher = new FileSystemWatcher(); fileWatcher.Path = Path.GetDirectoryName(JsFile); fileWatcher.Filter = Path.GetFileName(JsFile); fileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Attributes | NotifyFilters.Size; fileWatcher.Changed += fileWatcher_Changed; fileWatcher.EnableRaisingEvents = true; } }
internal V8ScriptEngine(V8Runtime runtime, string name, V8RuntimeConstraints constraints, V8ScriptEngineFlags flags, int debugPort) : base((runtime != null) ? runtime.Name + ":" + name : name) { using (var localRuntime = (runtime != null) ? null : new V8Runtime(name, constraints)) { var activeRuntime = runtime ?? localRuntime; hostItemCollateral = activeRuntime.HostItemCollateral; engineFlags = flags; proxy = V8ContextProxy.Create(activeRuntime.IsolateProxy, Name, flags, debugPort); script = GetRootItem(); var engineInternal = Evaluate( MiscHelpers.FormatInvariant("{0} [internal]", GetType().Name), false, @" EngineInternal = (function () { function convertArgs(args) { var result = []; var count = args.Length; for (var i = 0; i < count; i++) { result.push(args[i]); } return result; } function construct(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) { return new this(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); } var isHostObjectKey = this.isHostObjectKey; delete this.isHostObjectKey; return { getCommandResult: function (value) { if (value == null) { return value; } if (typeof(value.hasOwnProperty) != 'function') { return '[external]'; } if (value[isHostObjectKey] === true) { return value; } if (typeof(value.toString) != 'function') { return '[' + typeof(value) + ']'; } return value.toString(); }, invokeConstructor: function (constructor, args) { if (typeof(constructor) != 'function') { throw new Error('Function expected'); } return construct.apply(constructor, convertArgs(args)); }, invokeMethod: function (target, method, args) { if (typeof(method) != 'function') { throw new Error('Function expected'); } return method.apply(target, convertArgs(args)); }, getStackTrace: function () { try { throw new Error('[stack trace]'); } catch (exception) { return exception.stack; } return ''; } }; })(); " ); ((IDisposable)engineInternal).Dispose(); if (flags.HasFlag(V8ScriptEngineFlags.EnableDebugging | V8ScriptEngineFlags.AwaitDebuggerAndPauseOnStart)) { awaitDebuggerAndPause = true; } } }
/// <summary> /// Creates a new Runtime Manager. /// </summary> /// <param name="settings">Settings to apply to the Runtime Manager and the scripts it runs.</param> public RuntimeManager(IManagerSettings settings) { _settings = settings; _v8Runtime = new V8Runtime(new V8RuntimeConstraints { MaxExecutableSize = settings.MaxExecutableBytes, MaxOldSpaceSize = settings.MaxOldSpaceBytes, MaxNewSpaceSize = settings.MaxNewSpaceBytes }); _scriptCompiler = new ScriptCompiler(_v8Runtime, settings); }
internal V8ScriptEngine(V8Runtime runtime, string name, V8RuntimeConstraints constraints, V8ScriptEngineFlags flags, int debugPort) : base((runtime != null) ? runtime.Name + ":" + name : name) { using (var localRuntime = (runtime != null) ? null : new V8Runtime(name, constraints)) { var activeRuntime = runtime ?? localRuntime; engineFlags = flags; proxy = V8ContextProxy.Create(activeRuntime.IsolateProxy, Name, flags.HasFlag(V8ScriptEngineFlags.EnableDebugging), flags.HasFlag(V8ScriptEngineFlags.DisableGlobalMembers), debugPort); script = GetRootItem(); var engineInternal = Evaluate( MiscHelpers.FormatInvariant("{0} [internal]", GetType().Name), false, @" EngineInternal = (function () { function convertArgs(args) { var result = []; var count = args.Length; for (var i = 0; i < count; i++) { result.push(args[i]); } return result; } function construct(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) { return new this(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); } return { getCommandResult: function (value) { if (value != null) { if (((typeof(value) == 'object') && !value.hasOwnProperty('{c2cf47d3-916b-4a3f-be2a-6ff567425808}')) || (typeof(value) == 'function')) { if (typeof(value.toString) == 'function') { return value.toString(); } } } return value; }, invokeConstructor: function (constructor, args) { if (typeof(constructor) != 'function') { throw new Error('Function expected'); } return construct.apply(constructor, convertArgs(args)); }, invokeMethod: function (target, method, args) { if (typeof(method) != 'function') { throw new Error('Function expected'); } return method.apply(target, convertArgs(args)); }, getStackTrace: function () { try { throw new Error('[stack trace]'); } catch (exception) { return exception.stack; } return ''; } }; })(); " ); ((IDisposable)engineInternal).Dispose(); } }
public void V8ScriptEngine_General_Precompiled_Dual() { engine.Dispose(); using (var runtime = new V8Runtime()) { using (var script = runtime.Compile(generalScript)) { engine = runtime.CreateScriptEngine(); using (var console = new StringWriter()) { var clr = new HostTypeCollection(type => type != typeof(Console), "mscorlib", "System", "System.Core"); clr.GetNamespaceNode("System").SetPropertyNoCheck("Console", console); engine.AddHostObject("host", new ExtendedHostFunctions()); engine.AddHostObject("clr", clr); engine.Evaluate(script); Assert.AreEqual(MiscHelpers.FormatCode(generalScriptOutput), console.ToString().Replace("\r\n", "\n")); console.GetStringBuilder().Clear(); Assert.AreEqual(string.Empty, console.ToString()); engine.Evaluate(script); Assert.AreEqual(MiscHelpers.FormatCode(generalScriptOutput), console.ToString().Replace("\r\n", "\n")); } engine.Dispose(); engine = runtime.CreateScriptEngine(); using (var console = new StringWriter()) { var clr = new HostTypeCollection(type => type != typeof(Console), "mscorlib", "System", "System.Core"); clr.GetNamespaceNode("System").SetPropertyNoCheck("Console", console); engine.AddHostObject("host", new ExtendedHostFunctions()); engine.AddHostObject("clr", clr); engine.Evaluate(script); Assert.AreEqual(MiscHelpers.FormatCode(generalScriptOutput), console.ToString().Replace("\r\n", "\n")); console.GetStringBuilder().Clear(); Assert.AreEqual(string.Empty, console.ToString()); engine.Evaluate(script); Assert.AreEqual(MiscHelpers.FormatCode(generalScriptOutput), console.ToString().Replace("\r\n", "\n")); } } } }
public void V8ScriptEngine_MaxRuntimeStackUsage() { using (var runtime = new V8Runtime()) { using (var engine1 = runtime.CreateScriptEngine()) { using (var engine2 = runtime.CreateScriptEngine()) { var value = (UIntPtr)123456; engine1.MaxRuntimeStackUsage = value; Assert.AreEqual(value, engine1.MaxRuntimeStackUsage); Assert.AreEqual(value, engine2.MaxRuntimeStackUsage); Assert.AreEqual(value, runtime.MaxStackUsage); value = (UIntPtr)654321; runtime.MaxStackUsage = value; Assert.AreEqual(value, engine1.MaxRuntimeStackUsage); Assert.AreEqual(value, engine2.MaxRuntimeStackUsage); Assert.AreEqual(value, runtime.MaxStackUsage); } } } }
public ScriptCompiler(V8Runtime v8Runtime, IManagerSettings settings) { _settings = settings; _v8Runtime = v8Runtime; _scriptCache = new LruCache<string, CachedV8Script>(LurchTableOrder.Access, settings.ScriptCacheMaxCount); }
public void BugFix_FinalizerHang_V8ScriptEngine() { engine.Dispose(); using (var runtime = new V8Runtime(V8RuntimeFlags.EnableDebugging)) { engine = runtime.CreateScriptEngine(); engine.Script.bar = new Action(() => { GC.Collect(); GC.WaitForPendingFinalizers(); }); for (var index = 0; index < 100; index++) { runtime.CreateScriptEngine(); } engine.Execute("bar()"); } }