Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repository = "https://github.com/Icemic/quickjs-rusty"
version = "0.7.0"

[package.metadata.docs.rs]
features = ["chrono", "bigint", "log"]
features = ["chrono", "bigint"]

[features]
bigint = ["num-bigint", "num-traits"]
Expand All @@ -22,7 +22,7 @@ serde = ["thiserror", "dep:serde"]
anyhow = {version = "1"}
chrono = {version = "0.4.7", optional = true}
libquickjs-ng-sys = {version = "^0.7.1", path = "./libquickjs-sys"}
log = {version = "0.4.8", optional = true}
log = "0.4"
num-bigint = {version = "0.4.4", optional = true}
num-traits = {version = "0.2.0", optional = true}
serde = {version = "1", features = ["derive"], optional = true}
Expand Down
9 changes: 5 additions & 4 deletions examples/eval_module.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Result;
use quickjs_rusty::Context;

struct Custom {
Expand Down Expand Up @@ -31,20 +32,20 @@ pub fn main() {
println!("js: 1 + 2 = {:?}", value);
}

fn module_loader(module_name: &str, opaque: *mut std::ffi::c_void) -> String {
fn module_loader(module_name: &str, opaque: *mut std::ffi::c_void) -> Result<String> {
println!("module_loader: {:?}", module_name);
let custom = unsafe { &*(opaque as *mut Custom) };
assert!(custom.foo == 123);
"export function add(a, b) { return a + b; }; console.log('module loaded.')".to_string()
Ok("export function add(a, b) { return a + b; }; console.log('module loaded.')".to_string())
}

fn module_normalize(
module_base_name: &str,
module_name: &str,
opaque: *mut std::ffi::c_void,
) -> String {
) -> Result<String> {
println!("module_normalize: {:?} {:?}", module_base_name, module_name);
let custom = unsafe { &*(opaque as *mut Custom) };
assert!(custom.foo == 123);
module_name.to_string()
Ok(module_name.to_string())
}
2 changes: 1 addition & 1 deletion src/errors/execution_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl fmt::Display for ExecutionError {
Internal(e) => write!(f, "Internal error: {}", e),
Exception(e) => {
if e.is_string() {
write!(f, "{:?}", e.to_string().unwrap())
write!(f, "{}", e.to_string().unwrap())
} else {
write!(f, "JS Exception: {:?}", e)
}
Expand Down
44 changes: 34 additions & 10 deletions src/module_loader.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use std::ffi::{c_char, c_void, CStr};
use std::ffi::{c_char, c_void, CStr, CString};
use std::ptr::null_mut;

use anyhow::Result;
use libquickjs_ng_sys as q;

use super::compile::compile_module;

pub type JSModuleLoaderFunc = Box<dyn Fn(&str, *mut c_void) -> String>;
pub type JSModuleNormalizeFunc = Box<dyn Fn(&str, &str, *mut c_void) -> String>;
/// Custom module loader function, passes (module_name, opaque) and returns module code
/// If the module code is not found, return None
pub type JSModuleLoaderFunc = Box<dyn Fn(&str, *mut c_void) -> Result<String>>;
/// Custom module normalize function, passes (module_base_name, module_name, opaque)
/// and returns normalized module name (or None if not found)
pub type JSModuleNormalizeFunc = Box<dyn Fn(&str, &str, *mut c_void) -> Result<String>>;

pub struct ModuleLoader {
pub loader: JSModuleLoaderFunc,
Expand All @@ -23,17 +28,22 @@ pub unsafe extern "C" fn js_module_loader(
let opaque = wrapper.opaque;
let loader = &wrapper.loader;

let module_name = CStr::from_ptr(module_name).to_str().unwrap();
let module_code = loader(module_name, opaque);
let module_name = CStr::from_ptr(module_name).to_string_lossy().to_string();
let module_code = match loader(&module_name, opaque) {
Ok(v) => v,
Err(err) => {
throw_internal_error(ctx, &err.to_string());
return null_mut() as *mut q::JSModuleDef;
}
};

match compile_module(ctx, &module_code, module_name) {
match compile_module(ctx, &module_code, &module_name) {
Ok(v) => {
let module_def = q::JS_Ext_GetPtr(v.value);
// q::JS_DupValue(wrapper.context, v.value);
module_def as *mut q::JSModuleDef
}
Err(e) => {
eprintln!("compile module error: {:?}", e);
throw_internal_error(ctx, &e.to_string());
null_mut() as *mut q::JSModuleDef
}
}
Expand All @@ -54,7 +64,13 @@ pub unsafe extern "C" fn js_module_normalize(

if let Some(module_normalize_func) = normalize {
let mut normalized_module_name =
module_normalize_func(module_base_name, module_name, opaque);
match module_normalize_func(module_base_name, module_name, opaque) {
Ok(v) => v,
Err(err) => {
throw_internal_error(ctx, &err.to_string());
return null_mut() as *mut c_char;
}
};
normalized_module_name.push('\0');
let m = q::js_malloc(ctx, normalized_module_name.len());
std::ptr::copy(
Expand All @@ -64,7 +80,15 @@ pub unsafe extern "C" fn js_module_normalize(
);
m as *mut c_char
} else {
eprintln!("module normalize func not set");
log::warn!("module normalize func not set");
null_mut() as *mut c_char
}
}

#[inline]
fn throw_internal_error(ctx: *mut q::JSContext, err: &str) {
let err = CString::new(err).unwrap();
unsafe {
q::JS_ThrowInternalError(ctx, err.as_ptr() as *const i8);
}
}
Loading