Skip to content

Commit

Permalink
Implement loading shared libraries for proc macro plugins
Browse files Browse the repository at this point in the history
commit-id:a3155bbf
  • Loading branch information
maciektr committed Feb 6, 2024
1 parent 727a0d9 commit 7b136e7
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 17 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ xshell = "0.2"
xxhash-rust = { version = "0.8", features = ["xxh3"] }
zip = { version = "0.6", default-features = false, features = ["deflate"] }
zstd = "0.13"
libloading = "0.8.1"

[profile.release]
lto = true
Expand Down
1 change: 1 addition & 0 deletions scarb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ include_dir.workspace = true
indoc.workspace = true
itertools.workspace = true
libc.workspace = true
libloading.workspace = true
once_cell.workspace = true
pathdiff.workspace = true
petgraph.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion scarb/src/compiler/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn load_plugins(
let instance = plugin.instantiate()?;
builder.with_plugin_suite(instance.plugin_suite());
} else {
proc_macros.register(plugin_info.package.clone());
proc_macros.register(plugin_info.package.clone())?;
}
}
builder.with_plugin_suite(proc_macros.instantiate()?.plugin_suite());
Expand Down
97 changes: 87 additions & 10 deletions scarb/src/compiler/plugin/proc_macro/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
use crate::core::Package;
use anyhow::Result;
use cairo_lang_defs::patcher::PatchBuilder;
use cairo_lang_syntax::node::db::SyntaxGroup;
use cairo_lang_syntax::node::{ast, TypedSyntaxNode};
use camino::Utf8PathBuf;
use libloading::{Library, Symbol};
use scarb_macro_interface::plugin::{ProcMacroResult, TokenStream};
use scarb_macro_interface::stable::{StableProcMacroResult, StableTokenStream};
use std::fmt::Debug;

#[cfg(not(windows))]
use libloading::os::unix::Symbol as RawSymbol;
#[cfg(windows)]
use libloading::os::windows::Symbol as RawSymbol;

pub trait FromItemAst {
fn from_item_ast(db: &dyn SyntaxGroup, item_ast: ast::ModuleItem) -> Self;
}
Expand All @@ -18,19 +27,87 @@ impl FromItemAst for TokenStream {
}
}

#[derive(Debug, Clone)]
pub struct ProcMacroInstance {}
#[non_exhaustive]
pub struct ProcMacroInstance {
plugin: Plugin,
}

impl Debug for ProcMacroInstance {
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}

fn shared_lib_path(package: &Package) -> Utf8PathBuf {
let lib_name = format!(
"{}{}.{}",
shared_lib_prefix(),
package.id.name,
shared_lib_ext()
);
package.root().join("target").join("release").join(lib_name)
}

fn shared_lib_prefix() -> &'static str {
#[cfg(windows)]
return "";
#[cfg(not(windows))]
return "lib";
}

fn shared_lib_ext() -> &'static str {
#[cfg(target_os = "windows")]
return "dll";
#[cfg(target_os = "macos")]
return "dylib";
#[cfg(not(target_os = "windows"))]
#[cfg(not(target_os = "macos"))]
return "so";
}

impl ProcMacroInstance {
pub fn new(_package: Package) -> Self {
// Load shared library
// TODO(maciektr): Implement
Self {}
/// Load shared library
pub fn try_new(package: Package) -> Result<Self> {
let plugin = unsafe { Plugin::try_new(shared_lib_path(&package))? };
Ok(Self { plugin })
}

/// Apply expansion to token stream.
pub(crate) fn generate_code(&self, token_stream: TokenStream) -> ProcMacroResult {
let ffi_token_stream = unsafe { StableTokenStream::from_token_stream(token_stream) };
let result = (self.plugin.vtable.expand)(ffi_token_stream);
unsafe { result.to_proc_macro_result() }
}
}

type ExpandCode = extern "C" fn(StableTokenStream) -> StableProcMacroResult;

struct VTableV0 {
expand: RawSymbol<ExpandCode>,
}

impl VTableV0 {
unsafe fn try_new(library: &Library) -> Result<VTableV0> {
println!("Loading plugin API version 0...");

let expand: Symbol<'_, ExpandCode> = library.get(b"expand\0")?;
let expand = expand.into_raw();

Ok(VTableV0 { expand })
}
}

struct Plugin {
#[allow(dead_code)]
library: Library,
vtable: VTableV0,
}

impl Plugin {
unsafe fn try_new(library_name: Utf8PathBuf) -> Result<Plugin> {
let library = Library::new(library_name)?;
let vtable = VTableV0::try_new(&library)?;

pub(crate) fn generate_code(&self, _token_stream: TokenStream) -> ProcMacroResult {
// Apply expansion to token stream.
// TODO(maciektr): Implement
ProcMacroResult::Leave
Ok(Plugin { library, vtable })
}
}
13 changes: 7 additions & 6 deletions scarb/src/compiler/plugin/proc_macro/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use typed_builder::TypedBuilder;

#[derive(Debug, TypedBuilder)]
pub struct ProcMacroHost {
macros: HashMap<SmolStr, Box<ProcMacroInstance>>,
macros: HashMap<SmolStr, Arc<ProcMacroInstance>>,
}

pub type ProcMacroId = SmolStr;
Expand Down Expand Up @@ -148,7 +148,7 @@ impl MacroPlugin for ProcMacroHost {

#[derive(Default)]
pub struct ProcMacroHostPlugin {
macros: HashMap<SmolStr, Box<ProcMacroInstance>>,
macros: HashMap<SmolStr, Arc<ProcMacroInstance>>,
}

impl ProcMacroHostPlugin {
Expand All @@ -160,12 +160,13 @@ impl ProcMacroHostPlugin {
)
}

pub fn register(&mut self, package: Package) {
pub fn register(&mut self, package: Package) -> Result<()> {
// Create instance
// Register instance in hash map
let name = package.id.name.to_smol_str();
let instance = ProcMacroInstance::new(package);
self.macros.insert(name, Box::new(instance));
let instance = ProcMacroInstance::try_new(package)?;
self.macros.insert(name, Arc::new(instance));
Ok(())
}
}

Expand All @@ -184,7 +185,7 @@ impl CairoPlugin for ProcMacroHostPlugin {

#[derive(TypedBuilder)]
pub struct ProcMacroHostPluginInstance {
macros: HashMap<SmolStr, Box<ProcMacroInstance>>,
macros: HashMap<SmolStr, Arc<ProcMacroInstance>>,
}

impl ProcMacroHostPluginInstance {
Expand Down

0 comments on commit 7b136e7

Please sign in to comment.