diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2023-12-11 12:38:45 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-11 07:08:45 +0000 |
commit | 02e138dca9c9fd79f47d352114b45b21dbb2b2ba (patch) | |
tree | 396fce46b544635ecec93a0c7592d570e48474cb /ext/node/ops/v8.rs | |
parent | 0bee37a5e24048cbf92c1b56efd0c65deaea1418 (diff) |
fix(ext/node): basic vm.runInNewContext implementation (#21527)
Simple implementation to support webpack (& Next.js):
https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/javascript/JavascriptParser.js#L4329
Diffstat (limited to 'ext/node/ops/v8.rs')
-rw-r--r-- | ext/node/ops/v8.rs | 48 |
1 files changed, 48 insertions, 0 deletions
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() + } + }) +} |