optimize: use v8::Script::compile to run script directly in op_import

This commit is contained in:
2026-02-19 18:22:40 +08:00
parent b424f60f9f
commit 7eb3acf26f
3 changed files with 60 additions and 24 deletions

View File

@@ -48,7 +48,7 @@ declare global {
namespace Deno {
namespace core {
namespace ops {
function op_import(path: string): string;
function op_import(path: string): NixValue;
function op_scoped_import(path: string, scopeKeys: string[]): string;
function op_resolve_path(currentDir: string, path: string): string;

View File

@@ -116,6 +116,7 @@ pub(crate) use private::NixRuntimeError;
pub(crate) struct Runtime<Ctx: RuntimeContext> {
js_runtime: JsRuntime,
#[cfg(feature = "inspector")]
rt: tokio::runtime::Runtime,
#[cfg(feature = "inspector")]
wait_for_inspector: bool,
@@ -178,6 +179,7 @@ impl<Ctx: RuntimeContext> Runtime<Ctx> {
Ok(Self {
js_runtime,
#[cfg(feature = "inspector")]
rt: tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
@@ -230,22 +232,6 @@ impl<Ctx: RuntimeContext> Runtime<Ctx> {
crate::error::parse_js_error(error, ctx)
})?;
let global_value = self
.rt
.block_on(self.js_runtime.resolve(global_value))
.map_err(|error| {
let op_state = self.js_runtime.op_state();
let op_state_borrow = op_state.borrow();
let ctx: &Ctx = op_state_borrow.get_ctx();
crate::error::parse_js_error(error, ctx)
})?;
#[cfg(feature = "inspector")]
{
let _ = self
.rt
.block_on(self.js_runtime.run_event_loop(Default::default()));
}
// Retrieve scope from JsRuntime
deno_core::scope!(scope, self.js_runtime);

View File

@@ -3,9 +3,9 @@ use std::convert::Infallible;
use std::path::{Component, Path, PathBuf};
use std::str::FromStr;
use hashbrown::{HashMap, HashSet, hash_map::Entry};
use deno_core::error::JsError;
use deno_core::{FromV8, OpState, ToV8, v8};
use hashbrown::{HashMap, HashSet, hash_map::Entry};
use regex::Regex;
use rust_embed::Embed;
@@ -62,12 +62,60 @@ where
#[folder = "src/runtime/corepkgs"]
pub(crate) struct CorePkgs;
#[deno_core::op2]
#[string]
fn new_simple_jserror(msg: String) -> Box<JsError> {
JsError {
message: Some(msg.clone()),
name: None,
stack: None,
cause: None,
exception_message: msg,
frames: Vec::new(),
source_line: None,
source_line_frame_index: None,
aggregated: None,
additional_properties: Vec::new(),
}
.into()
}
struct Compiled(String);
impl<'a> ToV8<'a> for Compiled {
type Error = Box<JsError>;
fn to_v8<'i>(
self,
scope: &mut v8::PinScope<'a, 'i>,
) -> std::result::Result<v8::Local<'a, v8::Value>, Self::Error> {
let Ok(script) = self.0.to_v8(scope);
let Some(source) = script.to_string(scope) else {
unsafe { std::hint::unreachable_unchecked() }
};
let tc = std::pin::pin!(v8::TryCatch::new(scope));
let mut scope = tc.init();
let Some(compiled) = v8::Script::compile(&scope, source, None) else {
let msg = scope
.exception()
.map(|e| e.to_rust_string_lossy(&scope))
.unwrap_or_else(|| "failed to compile code".into());
return Err(new_simple_jserror(msg));
};
match compiled.run(&scope) {
Some(val) => Ok(val),
None => Err(scope
.exception()
.map(|e| JsError::from_v8_exception(&mut scope, e))
.unwrap_or_else(|| {
new_simple_jserror("script execution failed unexpectedly".into())
})),
}
}
}
#[deno_core::op2(reentrant)]
pub(super) fn op_import<Ctx: RuntimeContext>(
state: &mut OpState,
#[string] path: String,
) -> Result<String> {
) -> Result<Compiled> {
let _span = tracing::info_span!("op_import", path = %path).entered();
let ctx: &mut Ctx = state.get_ctx_mut();
@@ -83,7 +131,8 @@ pub(super) fn op_import<Ctx: RuntimeContext>(
.into(),
);
ctx.add_source(source.clone());
return Ok(ctx.compile(source).map_err(|err| err.to_string())?);
let code = ctx.compile(source).map_err(|err| err.to_string())?;
return Ok(Compiled(code));
} else {
return Err(format!("Corepkg not found: {}", corepkg_name).into());
}
@@ -107,7 +156,8 @@ pub(super) fn op_import<Ctx: RuntimeContext>(
tracing::debug!("Compiling file");
ctx.add_source(source.clone());
Ok(ctx.compile(source).map_err(|err| err.to_string())?)
let code = ctx.compile(source).map_err(|err| err.to_string())?;
Ok(Compiled(code))
}
#[deno_core::op2]