Skip to content

Commit 178bd8c

Browse files
committed
Register values and traits
This was pretty tricky but follows the existing patterns. This also allowed us to replace a dashmap with a hashmap Also move more of the implementation into the runtime level.
1 parent ddd8cf4 commit 178bd8c

File tree

9 files changed

+256
-255
lines changed

9 files changed

+256
-255
lines changed

turbopack/crates/turbo-tasks-build/src/lib.rs

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::{
22
env::{self, current_dir},
3-
fmt::Write,
43
fs::read_dir,
54
path::{MAIN_SEPARATOR as PATH_SEP, PathBuf},
65
sync::Arc,
@@ -14,10 +13,7 @@ use syn::{
1413
Attribute, Expr, Ident, Item, ItemEnum, ItemImpl, ItemMacro, ItemMod, ItemStruct, Lit, Meta,
1514
parse_quote,
1615
};
17-
use turbo_tasks_macros_shared::{
18-
GenericTypeInput, PrimitiveInput, get_path_ident, get_register_trait_impls_ident,
19-
get_register_trait_methods_ident, get_register_value_type_ident, get_type_ident,
20-
};
16+
use turbo_tasks_macros_shared::{GenericTypeInput, PrimitiveInput, get_path_ident, get_type_ident};
2117

2218
pub fn generate_register() {
2319
println!("cargo:rerun-if-changed=build.rs");
@@ -165,42 +161,42 @@ pub fn generate_register() {
165161
}
166162

167163
let mut values_code = String::new();
168-
for ((mod_path, ident), entry) in values {
169-
for attribute in &entry.attributes {
170-
values_code.push_str(attribute);
171-
}
172-
writeln!(
173-
values_code,
174-
"crate{}::{}({}, #[allow(unused_variables)] |value| {{",
175-
mod_path,
176-
get_register_value_type_ident(&ident),
177-
entry.global_name,
178-
)
179-
.unwrap();
180-
// Register all the trait items for each impl so we can dispatch to them as turbotasks
181-
for trait_ident in &entry.trait_idents {
182-
writeln!(
183-
values_code,
184-
" crate{}::{}(value);",
185-
mod_path,
186-
get_register_trait_methods_ident(trait_ident, &ident),
187-
)
188-
.unwrap();
189-
}
190-
writeln!(values_code, "}}, #[allow(unused_variables)] |value_id| {{").unwrap();
191-
// Register all the vtables for the impls so we can dispatch to them as normal indirect
192-
// trait calls.
193-
for trait_ident in &entry.trait_idents {
194-
writeln!(
195-
values_code,
196-
" crate{}::{}(value_id);",
197-
mod_path,
198-
get_register_trait_impls_ident(trait_ident, &ident),
199-
)
200-
.unwrap();
201-
}
202-
writeln!(values_code, "}});").unwrap();
203-
}
164+
// for ((mod_path, ident), entry) in values {
165+
// for attribute in &entry.attributes {
166+
// values_code.push_str(attribute);
167+
// }
168+
// writeln!(
169+
// values_code,
170+
// "crate{}::{}({}, #[allow(unused_variables)] |value| {{",
171+
// mod_path,
172+
// get_register_value_type_ident(&ident),
173+
// entry.global_name,
174+
// )
175+
// .unwrap();
176+
// // Register all the trait items for each impl so we can dispatch to them as
177+
// turbotasks for trait_ident in &entry.trait_idents {
178+
// writeln!(
179+
// values_code,
180+
// " crate{}::{}(value);",
181+
// mod_path,
182+
// get_register_trait_methods_ident(trait_ident, &ident),
183+
// )
184+
// .unwrap();
185+
// }
186+
// writeln!(values_code, "}}, #[allow(unused_variables)] |value_id| {{").unwrap();
187+
// // Register all the vtables for the impls so we can dispatch to them as normal
188+
// indirect // trait calls.
189+
// for trait_ident in &entry.trait_idents {
190+
// writeln!(
191+
// values_code,
192+
// " crate{}::{}(value_id);",
193+
// mod_path,
194+
// get_register_trait_impls_ident(trait_ident, &ident),
195+
// )
196+
// .unwrap();
197+
// }
198+
// writeln!(values_code, "}});").unwrap();
199+
// }
204200

205201
let code = format!(
206202
"{{\nstatic ONCE: std::sync::Once = std::sync::Once::new();\nONCE.call_once(|| \

turbopack/crates/turbo-tasks-macros-shared/src/ident.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ pub fn get_register_trait_methods_ident(trait_ident: &Ident, struct_ident: &Iden
1515
)
1616
}
1717

18-
pub fn get_register_trait_impls_ident(trait_ident: &Ident, struct_ident: &Ident) -> Ident {
18+
pub fn get_cast_to_fat_pointer_ident(trait_ident: &Ident, struct_ident: &Ident) -> Ident {
1919
Ident::new(
20-
&format!("__register_{struct_ident}_{trait_ident}_trait_impls"),
20+
&format!("_cast_to_fat_pointer_{struct_ident}_{trait_ident}"),
2121
trait_ident.span(),
2222
)
2323
}

turbopack/crates/turbo-tasks-macros/src/value_impl_macro.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use syn::{
99
spanned::Spanned,
1010
};
1111
use turbo_tasks_macros_shared::{
12-
get_inherent_impl_function_ident, get_path_ident, get_register_trait_impls_ident,
12+
get_cast_to_fat_pointer_ident, get_inherent_impl_function_ident, get_path_ident,
1313
get_register_trait_methods_ident, get_trait_impl_function_ident, get_type_ident, is_self_used,
1414
};
1515

@@ -175,11 +175,10 @@ pub fn value_impl(args: TokenStream, input: TokenStream) -> TokenStream {
175175

176176
let (impl_generics, _, where_clause) = generics.split_for_impl();
177177

178-
let register_trait_methods: Ident =
179-
get_register_trait_methods_ident(&trait_ident, ty_ident);
180-
let register_trait_impls: Ident = get_register_trait_impls_ident(&trait_ident, ty_ident);
178+
let cast_to_fat_pointer_ident: Ident =
179+
get_cast_to_fat_pointer_ident(&trait_ident, ty_ident);
181180

182-
let mut trait_registers = Vec::new();
181+
let mut trait_methods = Vec::new();
183182
let mut trait_functions = Vec::with_capacity(items.len());
184183
let mut trait_items = Vec::new();
185184
let mut all_definitions = Vec::with_capacity(items.len());
@@ -283,31 +282,41 @@ pub fn value_impl(args: TokenStream, input: TokenStream) -> TokenStream {
283282
}
284283
});
285284

286-
trait_registers.push(quote! {
287-
value.register_trait_method(
288-
<::std::boxed::Box<dyn #trait_path> as turbo_tasks::VcValueTrait>::get_trait_type_id(),
289-
stringify!(#ident),
290-
&#native_function_ident);
285+
trait_methods.push(quote! {
286+
(stringify!(#ident), &#native_function_ident),
291287
});
292288
}
293289
}
294290

295291
quote! {
296-
#[doc(hidden)]
297-
#[allow(non_snake_case)]
298-
pub(crate) fn #register_trait_methods(value: &mut turbo_tasks::ValueType) {
299-
value.register_trait(<::std::boxed::Box<dyn #trait_path> as turbo_tasks::VcValueTrait>::get_trait_type_id());
300-
#(#trait_registers)*
292+
// Register all the function impls so the ValueType can find them
293+
// This means objects resolve as
294+
// 1 NativeFunctions
295+
// 2 TraitTypes (requires functions)
296+
// 3 ValueTypes (requires functions and TraitTypeIds)
297+
// 4.VTableRegistries (requires ValueTypeIds)
298+
turbo_tasks::macro_helpers::inventory_submit!{
299+
turbo_tasks::macro_helpers::CollectableTraitMethods(
300+
concat!(module_path!(), "::", stringify!(#ty_ident)),
301+
|| (<::std::boxed::Box<dyn #trait_path> as turbo_tasks::VcValueTrait>::get_trait_type_id(),
302+
vec![#(#trait_methods)*])
303+
)
301304
}
302-
#[doc(hidden)]
305+
306+
// These can execute later so they can reference value_types during registration
307+
308+
turbo_tasks::macro_helpers::inventory_submit!{
309+
turbo_tasks::macro_helpers::CollectableTraitCastFunctions(
310+
<::std::boxed::Box<dyn #trait_path> as turbo_tasks::VcValueTrait>::get_trait_type_id,
311+
<#ty as turbo_tasks::VcValueType>::get_value_type_id,
312+
#cast_to_fat_pointer_ident as *const ()
313+
)
314+
}
315+
303316
#[allow(non_snake_case)]
304-
pub(crate) fn #register_trait_impls(value_id: turbo_tasks::ValueTypeId) {
305-
// NOTE(lukesandberg): This relies on the nightly ptr_metadata feature. Alternatively
306-
// we could generate a function that does the downcasting and pass that up to register_trait.
307-
// This would avoid the nightly feature.
308-
let fat_pointer: *const dyn #trait_path = ::std::ptr::null::<#ty>() as *const dyn #trait_path;
309-
let metadata = turbo_tasks::macro_helpers::metadata(fat_pointer);
310-
turbo_tasks::macro_helpers::register_trait_impl::<dyn #trait_path, ::std::boxed::Box<dyn #trait_path>>(value_id, metadata);
317+
fn #cast_to_fat_pointer_ident(raw: * const ()) -> *const dyn #trait_path {
318+
let typed = raw as *const #ty;
319+
typed as *const dyn #trait_path
311320
}
312321

313322
// NOTE(alexkirsz) We can't have a general `turbo_tasks::Upcast<Box<dyn Trait>> for T where T: Trait` because

turbopack/crates/turbo-tasks-macros/src/value_macro.rs

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -455,9 +455,7 @@ pub fn value_type_and_register(
455455
cell_mode: proc_macro2::TokenStream,
456456
new_value_type: proc_macro2::TokenStream,
457457
) -> proc_macro2::TokenStream {
458-
let value_type_init_ident = get_value_type_init_ident(ident);
459458
let value_type_ident = get_value_type_ident(ident);
460-
let register_value_type_ident = get_register_value_type_ident(ident);
461459

462460
let (impl_generics, where_clause) = if let Some(generics) = generics {
463461
let (impl_generics, _, where_clause) = generics.split_for_impl();
@@ -467,37 +465,15 @@ pub fn value_type_and_register(
467465
};
468466

469467
quote! {
470-
#[doc(hidden)]
471-
static #value_type_init_ident: turbo_tasks::macro_helpers::OnceCell<
472-
turbo_tasks::ValueType,
473-
> = turbo_tasks::macro_helpers::OnceCell::new();
474-
#[doc(hidden)]
475-
pub(crate) static #value_type_ident: turbo_tasks::macro_helpers::Lazy<&turbo_tasks::ValueType> =
476-
turbo_tasks::macro_helpers::Lazy::new(|| {
477-
#value_type_init_ident.get_or_init(|| {
478-
panic!(
479-
concat!(
480-
stringify!(#value_type_ident),
481-
" has not been initialized (this should happen via the generated register function)"
482-
)
483-
)
484-
})
485-
});
486-
487468

488-
#[doc(hidden)]
489-
#[allow(non_snake_case)]
490-
pub(crate) fn #register_value_type_ident(
491-
global_name: &'static str,
492-
init: impl FnOnce(&mut turbo_tasks::ValueType),
493-
register_traits: impl FnOnce(turbo_tasks::ValueTypeId),
494-
) {
495-
#value_type_init_ident.get_or_init(|| {
469+
static #value_type_ident: turbo_tasks::macro_helpers::Lazy<turbo_tasks::ValueType> =
470+
turbo_tasks::macro_helpers::Lazy::new(|| {
496471
let mut value = #new_value_type;
497-
init(&mut value);
472+
turbo_tasks::macro_helpers::register_trait_methods(&mut value);
498473
value
499-
}).register(global_name, register_traits);
500-
}
474+
});
475+
476+
turbo_tasks::macro_helpers::inventory_submit!{turbo_tasks::macro_helpers::CollectableValueType(&#value_type_ident)}
501477

502478
unsafe impl #impl_generics turbo_tasks::VcValueType for #ty #where_clause {
503479
type Read = #read;
@@ -506,7 +482,7 @@ pub fn value_type_and_register(
506482
fn get_value_type_id() -> turbo_tasks::ValueTypeId {
507483
static ident: turbo_tasks::macro_helpers::Lazy<turbo_tasks::ValueTypeId> =
508484
turbo_tasks::macro_helpers::Lazy::new(|| {
509-
turbo_tasks::registry::get_value_type_id(*#value_type_ident)
485+
turbo_tasks::registry::get_value_type_id(&#value_type_ident)
510486
});
511487

512488
*ident

turbopack/crates/turbo-tasks-macros/src/value_trait_macro.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream {
303303

304304
fn get_impl_vtables() -> &'static turbo_tasks::macro_helpers::VTableRegistry<Self::ValueTrait> {
305305
static registry: turbo_tasks::macro_helpers::Lazy<turbo_tasks::macro_helpers::VTableRegistry<dyn # trait_ident>> =
306-
turbo_tasks::macro_helpers::Lazy::new(turbo_tasks::macro_helpers::VTableRegistry::new);
306+
turbo_tasks::macro_helpers::Lazy::new(|| turbo_tasks::macro_helpers::VTableRegistry::new(turbo_tasks::registry::get_trait_type_id(&#trait_type_ident)));
307307

308308
&*registry
309309
}

0 commit comments

Comments
 (0)