Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement quote macro. #1743

Draft
wants to merge 26 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3c8625d
Rework internal TokenStream representation (#1699)
maciektr Nov 13, 2024
1ca0332
Avoid unnecessary allocations when freeing stable structs (#1700)
maciektr Nov 13, 2024
ab58da4
Implement first version of the quote macro.
wawel37 Nov 14, 2024
c4e114d
Make quote similar api to rust quote. Need cleanup and tests
wawel37 Nov 19, 2024
48c99e8
Add initial tests
wawel37 Nov 19, 2024
d9c3ac5
Rework internal TokenStream representation (#1699)
maciektr Nov 13, 2024
1731b26
Avoid unnecessary allocations when freeing stable structs (#1700)
maciektr Nov 13, 2024
23b6bfd
Add cairo edition to TokenStreamMetadata (#1704)
maciektr Nov 13, 2024
8b8b19d
Allocate token's content into an arena (#1722)
maciektr Nov 15, 2024
33cba3e
Add initial tests
wawel37 Nov 19, 2024
50e45cb
Add cairo-ls as code owners of proc-macro-server (#1730)
maciektr Nov 12, 2024
13be28b
Update Cairo (#1739)
maciektr Nov 13, 2024
c358412
Prepare `cairo-lang-macro` release `0.1.1` (#1740)
maciektr Nov 13, 2024
8eda7d8
Prepare `scarb-proc-macro-server-types` release `0.1.0`. (#1741)
maciektr Nov 13, 2024
f129ead
Website: Suggest asdf as the default installation method (#1744)
maciektr Nov 15, 2024
8d934b7
Bump the non-critical group with 7 updates (#1752)
dependabot[bot] Nov 18, 2024
5e1080b
Rework internal TokenStream representation (#1699)
wawel37 Nov 20, 2024
bac3377
Avoid unnecessary allocations when freeing stable structs (#1700)
maciektr Nov 13, 2024
7058f59
Add cairo edition to TokenStreamMetadata (#1704)
maciektr Nov 13, 2024
75b0526
Allocate token's content into an arena (#1722)
maciektr Nov 15, 2024
6cbaf39
Merge branch 'dev' into quote-macro
wawel37 Nov 20, 2024
0b1a8c9
Minor conversion fix
wawel37 Nov 20, 2024
6cb1d27
Implement Debug for InternedStr (#1760)
maciektr Nov 21, 2024
17e15c2
Refactor: split proc macro host into submodules (#1747)
maciektr Nov 21, 2024
fb56089
Adjustment to token changes and interendStr
wawel37 Nov 25, 2024
dbbba27
Merge branch 'dev' into quote-macro
wawel37 Nov 25, 2024
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
214 changes: 59 additions & 155 deletions Cargo.lock

Large diffs are not rendered by default.

51 changes: 27 additions & 24 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ members = [
"plugins/cairo-lang-macro",
"plugins/cairo-lang-macro-attributes",
"plugins/cairo-lang-macro-stable",
"plugins/cairo-lang-quote",
"utils/create-output-dir",
"utils/scarb-proc-macro-server-types",
"utils/scarb-build-metadata",
Expand All @@ -35,30 +36,32 @@ anyhow = "1"
assert_fs = "1"
async-trait = "0.1"
axum = { version = "0.6", features = ["http2"] }
cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-debug = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-defs = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-diagnostics = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-doc = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-filesystem = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-formatter = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-language-server = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-lowering = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-parser = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-project = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-runner = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-semantic = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-sierra-generator = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-sierra-to-casm = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-sierra-type-size = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-starknet-classes = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-syntax = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-test-plugin = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-test-runner = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0" }
cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo", rev = "3874879adcc2f36d7e1235fc9aec8420ff7013b0", features = ["env_logger"] }
bumpalo = "3"
cairo-lang-casm = { path = "../cairo/crates/cairo-lang-casm" }
cairo-lang-compiler = { path = "../cairo/crates/cairo-lang-compiler" }
cairo-lang-debug = { path = "../cairo/crates/cairo-lang-debug" }
cairo-lang-defs = { path = "../cairo/crates/cairo-lang-defs" }
cairo-lang-diagnostics = { path = "../cairo/crates/cairo-lang-diagnostics" }
cairo-lang-doc = { path = "../cairo/crates/cairo-lang-doc" }
cairo-lang-filesystem = { path = "../cairo/crates/cairo-lang-filesystem" }
cairo-lang-formatter = { path = "../cairo/crates/cairo-lang-formatter" }
cairo-lang-language-server = { path = "../cairo/crates/cairo-lang-language-server" }
cairo-lang-lowering = { path = "../cairo/crates/cairo-lang-lowering" }
cairo-lang-parser = { path = "../cairo/crates/cairo-lang-parser" }
cairo-lang-project = { path = "../cairo/crates/cairo-lang-project" }
cairo-lang-runner = { path = "../cairo/crates/cairo-lang-runner" }
cairo-lang-semantic = { path = "../cairo/crates/cairo-lang-semantic" }
cairo-lang-sierra = { path = "../cairo/crates/cairo-lang-sierra" }
cairo-lang-sierra-generator = { path = "../cairo/crates/cairo-lang-sierra-generator" }
cairo-lang-sierra-to-casm = { path = "../cairo/crates/cairo-lang-sierra-to-casm" }
cairo-lang-sierra-type-size = { path = "../cairo/crates/cairo-lang-sierra-type-size" }
cairo-lang-starknet = { path = "../cairo/crates/cairo-lang-starknet" }
cairo-lang-starknet-classes = { path = "../cairo/crates/cairo-lang-starknet-classes" }
cairo-lang-syntax = { path = "../cairo/crates/cairo-lang-syntax" }
cairo-lang-test-plugin = { path = "../cairo/crates/cairo-lang-test-plugin" }
cairo-lang-test-runner = { path = "../cairo/crates/cairo-lang-test-runner" }
cairo-lang-utils = { path = "../cairo/crates/cairo-lang-utils" }
cairo-lang-stable-token = { path = "../cairo/crates/cairo-lang-stable-token", version = "1.0" }
camino = { version = "1", features = ["serde1"] }
cargo_metadata = ">=0.18"
clap = { version = "4", features = ["derive", "env", "string"] }
Expand Down
37 changes: 24 additions & 13 deletions plugins/cairo-lang-macro-stable/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
use crate::ffi::{StableOption, StableSlice};
use std::ffi::CStr;
use std::num::NonZeroU8;
use std::os::raw::c_char;
use std::ptr::NonNull;

pub mod ffi;

#[repr(C)]
#[derive(Debug)]
pub struct StableToken {
pub span: Option<StableTextSpan>,
pub ptr: *const u8,
pub len: usize,
}

#[repr(C)]
#[derive(Debug)]
pub struct StableTextSpan {
pub start: usize,
pub end: usize,
}

#[repr(C)]
#[derive(Debug)]
pub enum StableTokenTree {
Ident(StableToken),
}

#[repr(C)]
#[derive(Debug)]
pub struct StableExpansion {
Expand All @@ -23,8 +43,9 @@ pub type StableExpansionsList = StableSlice<StableExpansion>;
#[repr(C)]
#[derive(Debug)]
pub struct StableTokenStream {
pub value: *mut c_char,
pub tokens: StableSlice<StableTokenTree>,
pub metadata: StableTokenStreamMetadata,
pub size_hint: usize,
}

/// Token stream metadata.
Expand All @@ -35,6 +56,7 @@ pub struct StableTokenStream {
pub struct StableTokenStreamMetadata {
pub original_file_path: Option<NonNull<c_char>>,
pub file_id: Option<NonNull<c_char>>,
pub edition: Option<NonNull<c_char>>,
}

/// Auxiliary data returned by the procedural macro.
Expand Down Expand Up @@ -76,17 +98,6 @@ pub struct StableResultWrapper {
pub output: StableProcMacroResult,
}

impl StableTokenStream {
/// Convert to String.
///
/// # Safety
pub unsafe fn to_string(&self) -> String {
// Note that this does not deallocate the c-string.
// The memory must still be freed with `CString::from_raw`.
CStr::from_ptr(self.value).to_string_lossy().to_string()
}
}

#[repr(C)]
pub struct StablePostProcessContext {
pub aux_data: StableSlice<StableAuxData>,
Expand Down
7 changes: 5 additions & 2 deletions plugins/cairo-lang-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ readme = "README.md"
repository.workspace = true

[dependencies]
cairo-lang-macro-attributes = "0.1"
cairo-lang-macro-stable = "1"
bumpalo.workspace = true
cairo-lang-macro-attributes = { path = "../cairo-lang-macro-attributes" }
cairo-lang-macro-stable = { path = "../cairo-lang-macro-stable" }
cairo-lang-stable-token.workspace = true
linkme.workspace = true
serde = { workspace = true, optional = true }

[dev-dependencies]
indoc.workspace = true
serde.workspace = true
serde_json.workspace = true

Expand Down
66 changes: 42 additions & 24 deletions plugins/cairo-lang-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@
pub use cairo_lang_macro_attributes::*;
#[doc(hidden)]
pub use linkme;
use std::cell::RefCell;

use cairo_lang_macro_stable::ffi::StableSlice;
use cairo_lang_macro_stable::{
StableExpansionsList, StablePostProcessContext, StableProcMacroResult,
};
use std::ffi::{c_char, CStr, CString};
use std::ops::Deref;

mod types;

pub use types::*;

// A thread-local allocation context for allocating tokens on proc macro side.
thread_local!(static CONTEXT: RefCell<AllocationContext> = RefCell::default() );

#[doc(hidden)]
#[derive(Clone)]
pub struct ExpansionDefinition {
Expand Down Expand Up @@ -97,29 +102,42 @@ pub unsafe extern "C" fn expand(
stable_attr: cairo_lang_macro_stable::StableTokenStream,
stable_token_stream: cairo_lang_macro_stable::StableTokenStream,
) -> cairo_lang_macro_stable::StableResultWrapper {
let token_stream = TokenStream::from_stable(&stable_token_stream);
let attr_token_stream = TokenStream::from_stable(&stable_attr);
let item_name = CStr::from_ptr(item_name).to_string_lossy().to_string();
let fun = MACRO_DEFINITIONS_SLICE
.iter()
.find_map(|m| {
if m.name == item_name.as_str() {
Some(m.fun.clone())
} else {
None
}
})
.expect("procedural macro not found");
let result = match fun {
ExpansionFunc::Attr(fun) => fun(attr_token_stream, token_stream),
ExpansionFunc::Other(fun) => fun(token_stream),
};
let result: StableProcMacroResult = result.into_stable();
cairo_lang_macro_stable::StableResultWrapper {
input: stable_token_stream,
input_attr: stable_attr,
output: result,
}
CONTEXT.with(|ctx_cell| {
// Read size hint from stable token stream. This will be used to create a sufficiently
// large bump allocation buffer.
let size_hint: usize = stable_token_stream.size_hint + stable_attr.size_hint;
// Replace the allocation context with a new one.
// If there is no interned string guards, the old context will be de-allocated.
ctx_cell.replace(AllocationContext::with_capacity(size_hint));
let ctx_borrow = ctx_cell.borrow();
let ctx: &AllocationContext = ctx_borrow.deref();
// Copy the stable token stream into current context.
let token_stream = TokenStream::from_stable_in(&stable_token_stream, ctx);
let attr_token_stream = TokenStream::from_stable_in(&stable_attr, ctx);
let item_name = CStr::from_ptr(item_name)
.to_str()
.expect("item name must be a valid string");
let fun = MACRO_DEFINITIONS_SLICE
.iter()
.find_map(|m| {
if m.name == item_name {
Some(m.fun.clone())
} else {
None
}
})
.expect("procedural macro not found");
let result = match fun {
ExpansionFunc::Attr(fun) => fun(attr_token_stream, token_stream),
ExpansionFunc::Other(fun) => fun(token_stream),
};
let result: StableProcMacroResult = result.into_stable();
cairo_lang_macro_stable::StableResultWrapper {
input: stable_token_stream,
input_attr: stable_attr,
output: result,
}
})
}

/// Free the memory allocated for the [`StableProcMacroResult`].
Expand All @@ -134,7 +152,7 @@ pub unsafe extern "C" fn expand(
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn free_result(result: StableProcMacroResult) {
ProcMacroResult::from_owned_stable(result);
ProcMacroResult::free_owned_stable(result);
}

/// Distributed slice for storing auxiliary data collection callback pointers.
Expand Down
Loading
Loading