diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/node/lib.rs | 2 | ||||
-rw-r--r-- | ext/node/ops/v8.rs | 48 | ||||
-rw-r--r-- | ext/node/polyfills/vm.ts | 21 |
3 files changed, 65 insertions, 6 deletions
diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 547f1d60a..56f4b0ee0 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -30,6 +30,7 @@ mod path; mod polyfill; mod resolution; +pub use ops::v8::VM_CONTEXT_INDEX; pub use package_json::PackageJson; pub use path::PathClean; pub use polyfill::is_builtin_node_module; @@ -243,6 +244,7 @@ deno_core::extension!(deno_node, ops::winerror::op_node_sys_to_uv_error, ops::v8::op_v8_cached_data_version_tag, ops::v8::op_v8_get_heap_statistics, + ops::v8::op_vm_run_in_new_context, ops::idna::op_node_idna_domain_to_ascii, ops::idna::op_node_idna_domain_to_unicode, ops::idna::op_node_idna_punycode_decode, diff --git a/ext/node/ops/v8.rs b/ext/node/ops/v8.rs index dbb84e932..17af49358 100644 --- a/ext/node/ops/v8.rs +++ b/ext/node/ops/v8.rs @@ -1,4 +1,5 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +use deno_core::error::AnyError; use deno_core::op2; use deno_core::v8; @@ -30,3 +31,50 @@ pub fn op_v8_get_heap_statistics( buffer[12] = stats.used_global_handles_size() as f64; buffer[13] = stats.external_memory() as f64; } + +pub const VM_CONTEXT_INDEX: usize = 0; + +fn make_context<'a>( + scope: &mut v8::HandleScope<'a>, +) -> v8::Local<'a, v8::Context> { + let scope = &mut v8::EscapableHandleScope::new(scope); + let context = v8::Context::from_snapshot(scope, VM_CONTEXT_INDEX).unwrap(); + scope.escape(context) +} + +#[op2] +pub fn op_vm_run_in_new_context<'a>( + scope: &mut v8::HandleScope<'a>, + script: v8::Local<v8::String>, + ctx_val: v8::Local<v8::Value>, +) -> Result<v8::Local<'a, v8::Value>, AnyError> { + let _ctx_obj = if ctx_val.is_undefined() || ctx_val.is_null() { + v8::Object::new(scope) + } else { + ctx_val.try_into()? + }; + + let ctx = make_context(scope); + + let scope = &mut v8::ContextScope::new(scope, ctx); + + let tc_scope = &mut v8::TryCatch::new(scope); + let script = match v8::Script::compile(tc_scope, script, None) { + Some(s) => s, + None => { + assert!(tc_scope.has_caught()); + tc_scope.rethrow(); + return Ok(v8::undefined(tc_scope).into()); + } + }; + + Ok(match script.run(tc_scope) { + Some(result) => result, + None => { + assert!(tc_scope.has_caught()); + tc_scope.rethrow(); + + v8::undefined(tc_scope).into() + } + }) +} diff --git a/ext/node/polyfills/vm.ts b/ext/node/polyfills/vm.ts index 39cd1ce36..45c67526e 100644 --- a/ext/node/polyfills/vm.ts +++ b/ext/node/polyfills/vm.ts @@ -6,6 +6,7 @@ import { notImplemented } from "ext:deno_node/_utils.ts"; const { core } = globalThis.__bootstrap; +const ops = core.ops; export class Script { code: string; @@ -25,8 +26,13 @@ export class Script { notImplemented("Script.prototype.runInContext"); } - runInNewContext(_contextObject: any, _options: any) { - notImplemented("Script.prototype.runInNewContext"); + runInNewContext(contextObject: any, options: any) { + if (options) { + console.warn( + "Script.runInNewContext options are currently not supported", + ); + } + return ops.op_vm_run_in_new_context(this.code, contextObject); } createCachedData() { @@ -51,11 +57,14 @@ export function runInContext( } export function runInNewContext( - _code: string, - _contextObject: any, - _options: any, + code: string, + contextObject: any, + options: any, ) { - notImplemented("runInNewContext"); + if (options) { + console.warn("vm.runInNewContext options are currently not supported"); + } + return ops.op_vm_run_in_new_context(code, contextObject); } export function runInThisContext( |