-
Notifications
You must be signed in to change notification settings - Fork 1.4k
(READY FOR REVIEW)Garbage collect: A stop-the-world cycle collector #4180
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| use proc_macro2::TokenStream; | ||
| use quote::quote; | ||
| use syn::{AttributeArgs, DeriveInput, Result}; | ||
|
|
||
| /// also remove `#[notrace]` attr, and not trace corresponding field | ||
| fn gen_trace_code(item: &mut DeriveInput) -> Result<TokenStream> { | ||
| match &mut item.data { | ||
| syn::Data::Struct(s) => { | ||
| let fields = &mut s.fields; | ||
| if let syn::Fields::Named(ref mut fields) = fields { | ||
| let res: TokenStream = fields | ||
| .named | ||
| .iter_mut() | ||
| .map(|f| { | ||
| let name = f | ||
| .ident | ||
| .as_ref() | ||
| .expect("Field should have a name in non-tuple struct"); | ||
| let mut do_trace = true; | ||
| f.attrs.retain(|attr| { | ||
| // remove #[notrace] and not trace this specifed field | ||
| if attr.path.segments.last().unwrap().ident == "notrace" { | ||
| do_trace = false; | ||
| false | ||
| } else { | ||
| true | ||
| } | ||
| }); | ||
| if do_trace { | ||
| quote!( | ||
| ::rustpython_vm::object::gc::Trace::trace(&self.#name, tracer_fn); | ||
| ) | ||
| } else { | ||
| quote!() | ||
| } | ||
| }) | ||
| .collect(); | ||
| Ok(res) | ||
| } else { | ||
| panic!("Expect only Named fields") | ||
| } | ||
| } | ||
| syn::Data::Enum(_) => todo!(), | ||
| syn::Data::Union(_) => todo!(), | ||
| } | ||
| } | ||
|
|
||
| pub(crate) fn impl_pytrace(attr: AttributeArgs, mut item: DeriveInput) -> Result<TokenStream> { | ||
| if !attr.is_empty() { | ||
| panic!( | ||
| "pytrace macro expect no attr(s), found {} attr(s)", | ||
| attr.len() | ||
| ); | ||
| } | ||
|
|
||
| let trace_code = gen_trace_code(&mut item)?; | ||
|
|
||
| let ty = &item.ident; | ||
|
|
||
| let ret = quote! { | ||
| #item | ||
| #[cfg(feature = "gc_bacon")] | ||
| unsafe impl ::rustpython_vm::object::gc::Trace for #ty { | ||
| fn trace(&self, tracer_fn: &mut ::rustpython_vm::object::gc::TracerFn) { | ||
| #trace_code | ||
| } | ||
| } | ||
| }; | ||
| Ok(ret) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -91,3 +91,20 @@ pub fn pypayload(input: TokenStream) -> TokenStream { | |
| let input = parse_macro_input!(input); | ||
| derive_impl::pypayload(input).into() | ||
| } | ||
|
|
||
| /// use on struct with named fields like `struct A{x:i32, y:i32}` to impl `Trace` for datatype | ||
| /// | ||
| /// use `#[notrace]` on fields you wish not to trace | ||
| /// | ||
| /// add `trace` attr to `#[pyclass]` to make it | ||
| /// traceable(Even from type-erased PyObject)(i.e. write `#[pyclass(trace)]`) | ||
| /// better to place after `#[pyclass]` so pyclass know `pytrace`'s existance and impl a MaybeTrace calling Trace | ||
| #[proc_macro_attribute] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could probably be a normal derive() macro, and then you wouldn't have to deal with removing the notrace attr
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, |
||
| pub fn pytrace( | ||
| attr: proc_macro::TokenStream, | ||
| item: proc_macro::TokenStream, | ||
| ) -> proc_macro::TokenStream { | ||
| let attr = parse_macro_input!(attr); | ||
| let item = parse_macro_input!(item); | ||
| derive_impl::pytrace(attr, item).into() | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.