Beispiel #1
0
        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);
 }
Beispiel #9
0
        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()");
            }
        }