diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2014-08-22 15:09:24 +0200 |
---|---|---|
committer | Trevor Norris <trev.norris@gmail.com> | 2014-09-16 12:28:47 -0700 |
commit | 21e60643b0795fe7b6a46ff29d73df60e6a7c9f5 (patch) | |
tree | 9eabb3502881497dcb7766179a5d2ee4647a03bd | |
parent | 174f7d2820dcb12f1b4b511840416a03cd65b9cf (diff) | |
download | nodejs-21e60643b0795fe7b6a46ff29d73df60e6a7c9f5.tar.gz nodejs-21e60643b0795fe7b6a46ff29d73df60e6a7c9f5.tar.bz2 nodejs-21e60643b0795fe7b6a46ff29d73df60e6a7c9f5.zip |
lib, src: add vm.runInDebugContext()
Compiles and executes source code in V8's debugger context. Provides
a programmatic way to get access to the debug object by executing:
var Debug = vm.runInDebugContext('Debug');
Fixes #7886.
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
-rw-r--r-- | doc/api/vm.markdown | 14 | ||||
-rw-r--r-- | lib/vm.js | 4 | ||||
-rw-r--r-- | src/node_contextify.cc | 16 | ||||
-rw-r--r-- | test/simple/test-vm-debug-context.js | 48 |
4 files changed, 82 insertions, 0 deletions
diff --git a/doc/api/vm.markdown b/doc/api/vm.markdown index 8ad7e72d4..0f963ca43 100644 --- a/doc/api/vm.markdown +++ b/doc/api/vm.markdown @@ -134,6 +134,20 @@ Note that running untrusted code is a tricky business requiring great care. a separate process. +## vm.runInDebugContext(code) + +`vm.runInDebugContext` compiles and executes `code` inside the V8 debug context. +The primary use case is to get access to the V8 debug object: + + var Debug = vm.runInDebugContext('Debug'); + Debug.scripts().forEach(function(script) { console.log(script.name); }); + +Note that the debug context and object are intrinsically tied to V8's debugger +implementation and may change (or even get removed) without prior warning. + +The debug object can also be exposed with the `--expose_debug_as=` switch. + + ## Class: Script A class for holding precompiled scripts, and running them in specific sandboxes. @@ -55,6 +55,10 @@ exports.createContext = function(sandbox) { return sandbox; }; +exports.runInDebugContext = function(code) { + return binding.runInDebugContext(code); +}; + exports.runInContext = function(code, contextifiedSandbox, options) { var script = new Script(code, options); return script.runInContext(contextifiedSandbox, options); diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 9525e7db6..bb43536d8 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -28,6 +28,7 @@ #include "env-inl.h" #include "util.h" #include "util-inl.h" +#include "v8-debug.h" namespace node { @@ -35,6 +36,7 @@ using v8::AccessType; using v8::Array; using v8::Boolean; using v8::Context; +using v8::Debug; using v8::EscapableHandleScope; using v8::External; using v8::Function; @@ -244,11 +246,25 @@ class ContextifyContext { function_template->InstanceTemplate()->SetInternalFieldCount(1); env->set_script_data_constructor_function(function_template->GetFunction()); + NODE_SET_METHOD(target, "runInDebugContext", RunInDebugContext); NODE_SET_METHOD(target, "makeContext", MakeContext); NODE_SET_METHOD(target, "isContext", IsContext); } + static void RunInDebugContext(const FunctionCallbackInfo<Value>& args) { + HandleScope scope(args.GetIsolate()); + Local<String> script_source(args[0]->ToString()); + if (script_source.IsEmpty()) + return; // Exception pending. + Context::Scope context_scope(Debug::GetDebugContext()); + Local<Script> script = Script::Compile(script_source); + if (script.IsEmpty()) + return; // Exception pending. + args.GetReturnValue().Set(script->Run()); + } + + static void MakeContext(const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args.GetIsolate()); HandleScope scope(env->isolate()); diff --git a/test/simple/test-vm-debug-context.js b/test/simple/test-vm-debug-context.js new file mode 100644 index 000000000..5569b3853 --- /dev/null +++ b/test/simple/test-vm-debug-context.js @@ -0,0 +1,48 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var vm = require('vm'); + +assert.throws(function() { + vm.runInDebugContext('*'); +}, /SyntaxError/); + +assert.throws(function() { + vm.runInDebugContext({ toString: assert.fail }); +}, /AssertionError/); + +assert.throws(function() { + vm.runInDebugContext('throw URIError("BAM")'); +}, /URIError/); + +assert.throws(function() { + vm.runInDebugContext('(function(f) { f(f) })(function(f) { f(f) })'); +}, /RangeError/); + +assert.equal(typeof(vm.runInDebugContext('this')), 'object'); +assert.equal(typeof(vm.runInDebugContext('Debug')), 'object'); + +assert.strictEqual(vm.runInDebugContext(), undefined); +assert.strictEqual(vm.runInDebugContext(0), 0); +assert.strictEqual(vm.runInDebugContext(null), null); +assert.strictEqual(vm.runInDebugContext(undefined), undefined); |