Skip to content

Commit

Permalink
Derive the import namespace from the provider module (#786)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffcharles authored Oct 21, 2024
1 parent 1ffa0a7 commit 4a7f0ad
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
4 changes: 2 additions & 2 deletions crates/cli/src/codegen/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl DynamicGenerator {

/// Generate function imports.
pub fn generate_imports(&self, module: &mut Module) -> Result<Imports> {
let import_namespace = self.provider.import_namespace();
let import_namespace = self.provider.import_namespace()?;
let canonical_abi_realloc_type = module.types.add(
&[ValType::I32, ValType::I32, ValType::I32, ValType::I32],
&[ValType::I32],
Expand Down Expand Up @@ -146,7 +146,7 @@ impl DynamicGenerator {
&[],
);
let (invoke_fn, _) =
module.add_import_func(&self.provider.import_namespace(), "invoke", invoke_type);
module.add_import_func(&self.provider.import_namespace()?, "invoke", invoke_type);

let fn_name_ptr_local = module.locals.add(ValType::I32);
for export in &self.function_exports {
Expand Down
30 changes: 22 additions & 8 deletions crates/cli/src/providers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::bytecode;
use anyhow::Result;
use anyhow::{anyhow, Result};
use std::str;

const QUICKJS_PROVIDER_MODULE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/provider.wasm"));

Expand Down Expand Up @@ -30,12 +31,25 @@ impl Provider {
}

/// The import namespace to use for this provider.
pub fn import_namespace(&self) -> String {
let prefix = "javy_quickjs_provider_v";
let version = match self {
Self::Default => 3,
Self::V2 => 2,
};
format!("{prefix}{version}")
pub fn import_namespace(&self) -> Result<String> {
match self {
Self::V2 => Ok("javy_quickjs_provider_v2".to_string()),
Self::Default => {
let module = walrus::Module::from_buffer(self.as_bytes())?;
let import_namespace = module
.customs
.iter()
.find_map(|(_, section)| {
if section.name() == "import_namespace" {
Some(section)
} else {
None
}
})
.ok_or_else(|| anyhow!("Provider is missing import_namespace custom section"))?
.data(&Default::default()); // Argument is required but not actually used for anything.
Ok(str::from_utf8(&import_namespace)?.to_string())
}
}
}
}
4 changes: 4 additions & 0 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use anyhow::anyhow;
use javy::Runtime;
use javy_config::Config;
use namespace::import_namespace;
use once_cell::sync::OnceCell;
use std::slice;
use std::str;

mod execution;
mod namespace;
mod runtime;

const FUNCTION_MODULE_NAME: &str = "function.mjs";
Expand All @@ -14,6 +16,8 @@ static mut COMPILE_SRC_RET_AREA: [u32; 2] = [0; 2];

static mut RUNTIME: OnceCell<Runtime> = OnceCell::new();

import_namespace!("javy_quickjs_provider_v3");

/// Used by Wizer to preinitialize the module.
#[export_name = "initialize_runtime"]
pub extern "C" fn initialize_runtime() {
Expand Down
20 changes: 20 additions & 0 deletions crates/core/src/namespace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Create a custom section named `import_namespace` with the contents of the
// string argument.
macro_rules! import_namespace {
($str:literal) => {
const IMPORT_NAMESPACE_BYTES: &[u8] = $str.as_bytes();

#[link_section = "import_namespace"]
pub static IMPORT_NAMESPACE: [u8; IMPORT_NAMESPACE_BYTES.len()] = {
let mut arr = [0u8; IMPORT_NAMESPACE_BYTES.len()];
let mut i = 0;
while i < IMPORT_NAMESPACE_BYTES.len() {
arr[i] = IMPORT_NAMESPACE_BYTES[i];
i += 1;
}
arr
};
};
}

pub(crate) use import_namespace;

0 comments on commit 4a7f0ad

Please sign in to comment.