optimize: use v8::Script::compile to run script directly in op_import
This commit is contained in:
2
nix-js/runtime-ts/src/types/global.d.ts
vendored
2
nix-js/runtime-ts/src/types/global.d.ts
vendored
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user