summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2014-08-22 15:09:24 +0200
committerTrevor Norris <trev.norris@gmail.com>2014-09-16 12:28:47 -0700
commit21e60643b0795fe7b6a46ff29d73df60e6a7c9f5 (patch)
tree9eabb3502881497dcb7766179a5d2ee4647a03bd
parent174f7d2820dcb12f1b4b511840416a03cd65b9cf (diff)
downloadnodejs-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.markdown14
-rw-r--r--lib/vm.js4
-rw-r--r--src/node_contextify.cc16
-rw-r--r--test/simple/test-vm-debug-context.js48
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.
diff --git a/lib/vm.js b/lib/vm.js
index 83b78b874..7c6c59c0a 100644
--- a/lib/vm.js
+++ b/lib/vm.js
@@ -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);