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 Deno {
|
||||||
namespace core {
|
namespace core {
|
||||||
namespace ops {
|
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_scoped_import(path: string, scopeKeys: string[]): string;
|
||||||
|
|
||||||
function op_resolve_path(currentDir: string, path: 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> {
|
pub(crate) struct Runtime<Ctx: RuntimeContext> {
|
||||||
js_runtime: JsRuntime,
|
js_runtime: JsRuntime,
|
||||||
|
#[cfg(feature = "inspector")]
|
||||||
rt: tokio::runtime::Runtime,
|
rt: tokio::runtime::Runtime,
|
||||||
#[cfg(feature = "inspector")]
|
#[cfg(feature = "inspector")]
|
||||||
wait_for_inspector: bool,
|
wait_for_inspector: bool,
|
||||||
@@ -178,6 +179,7 @@ impl<Ctx: RuntimeContext> Runtime<Ctx> {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
js_runtime,
|
js_runtime,
|
||||||
|
#[cfg(feature = "inspector")]
|
||||||
rt: tokio::runtime::Builder::new_current_thread()
|
rt: tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
.build()
|
.build()
|
||||||
@@ -230,22 +232,6 @@ impl<Ctx: RuntimeContext> Runtime<Ctx> {
|
|||||||
|
|
||||||
crate::error::parse_js_error(error, 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
|
// Retrieve scope from JsRuntime
|
||||||
deno_core::scope!(scope, self.js_runtime);
|
deno_core::scope!(scope, self.js_runtime);
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ use std::convert::Infallible;
|
|||||||
use std::path::{Component, Path, PathBuf};
|
use std::path::{Component, Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use hashbrown::{HashMap, HashSet, hash_map::Entry};
|
use deno_core::error::JsError;
|
||||||
|
|
||||||
use deno_core::{FromV8, OpState, ToV8, v8};
|
use deno_core::{FromV8, OpState, ToV8, v8};
|
||||||
|
use hashbrown::{HashMap, HashSet, hash_map::Entry};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rust_embed::Embed;
|
use rust_embed::Embed;
|
||||||
|
|
||||||
@@ -62,12 +62,60 @@ where
|
|||||||
#[folder = "src/runtime/corepkgs"]
|
#[folder = "src/runtime/corepkgs"]
|
||||||
pub(crate) struct CorePkgs;
|
pub(crate) struct CorePkgs;
|
||||||
|
|
||||||
#[deno_core::op2]
|
fn new_simple_jserror(msg: String) -> Box<JsError> {
|
||||||
#[string]
|
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>(
|
pub(super) fn op_import<Ctx: RuntimeContext>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
) -> Result<String> {
|
) -> Result<Compiled> {
|
||||||
let _span = tracing::info_span!("op_import", path = %path).entered();
|
let _span = tracing::info_span!("op_import", path = %path).entered();
|
||||||
let ctx: &mut Ctx = state.get_ctx_mut();
|
let ctx: &mut Ctx = state.get_ctx_mut();
|
||||||
|
|
||||||
@@ -83,7 +131,8 @@ pub(super) fn op_import<Ctx: RuntimeContext>(
|
|||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
ctx.add_source(source.clone());
|
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 {
|
} else {
|
||||||
return Err(format!("Corepkg not found: {}", corepkg_name).into());
|
return Err(format!("Corepkg not found: {}", corepkg_name).into());
|
||||||
}
|
}
|
||||||
@@ -107,7 +156,8 @@ pub(super) fn op_import<Ctx: RuntimeContext>(
|
|||||||
tracing::debug!("Compiling file");
|
tracing::debug!("Compiling file");
|
||||||
ctx.add_source(source.clone());
|
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]
|
#[deno_core::op2]
|
||||||
|
|||||||
Reference in New Issue
Block a user