turbo_tasks/task/
local_task.rs1use std::{fmt, sync::Arc};
2
3use anyhow::{Result, anyhow};
4
5use crate::{
6 MagicAny, OutputContent, RawVc, TaskPersistence, TraitMethod, TurboTasksBackendApi,
7 ValueTypeId,
8 backend::{Backend, TypedCellContent},
9 event::Event,
10 macro_helpers::NativeFunction,
11 registry,
12};
13
14pub enum LocalTask {
16 Scheduled { done_event: Event },
17 Done { output: OutputContent },
18}
19
20pub struct LocalTaskSpec {
21 pub(crate) this: Option<RawVc>,
23 pub(crate) arg: Box<dyn MagicAny>,
25 pub(crate) task_type: LocalTaskType,
26}
27
28#[derive(Copy, Clone)]
29pub enum LocalTaskType {
30 ResolveNative { native_fn: &'static NativeFunction },
33
34 ResolveTrait { trait_method: &'static TraitMethod },
38}
39
40impl fmt::Display for LocalTaskType {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 match self {
43 LocalTaskType::ResolveNative { native_fn } => write!(f, "*{}", native_fn.name),
44 LocalTaskType::ResolveTrait { trait_method } => write!(
45 f,
46 "*{}::{}",
47 trait_method.trait_name, trait_method.method_name
48 ),
49 }
50 }
51}
52
53impl LocalTaskType {
54 pub(crate) async fn run_resolve_native<B: Backend + 'static>(
57 native_fn: &'static NativeFunction,
58 mut this: Option<RawVc>,
59 arg: &dyn MagicAny,
60 persistence: TaskPersistence,
61 turbo_tasks: Arc<dyn TurboTasksBackendApi<B>>,
62 ) -> Result<RawVc> {
63 if let Some(this) = this.as_mut() {
64 *this = this.resolve().await?;
65 }
66 let arg = native_fn.arg_meta.resolve(arg).await?;
67 Ok(turbo_tasks.native_call(native_fn, this, arg, persistence))
68 }
69 pub(crate) async fn run_resolve_trait<B: Backend + 'static>(
71 trait_method: &'static TraitMethod,
72 this: RawVc,
73 arg: &dyn MagicAny,
74 persistence: TaskPersistence,
75 turbo_tasks: Arc<dyn TurboTasksBackendApi<B>>,
76 ) -> Result<RawVc> {
77 let this = this.resolve().await?;
78 let TypedCellContent(this_ty, _) = this.into_read().await?;
79
80 let native_fn = Self::resolve_trait_method_from_value(trait_method, this_ty)?;
81 let arg = native_fn.arg_meta.filter_and_resolve(arg).await?;
82 Ok(turbo_tasks.native_call(native_fn, Some(this), arg, persistence))
83 }
84
85 fn resolve_trait_method_from_value(
86 trait_method: &'static TraitMethod,
87 value_type: ValueTypeId,
88 ) -> Result<&'static NativeFunction> {
89 match registry::get_value_type(value_type).get_trait_method(trait_method) {
90 Some(native_fn) => Ok(native_fn),
91 None => Err(anyhow!(
92 "{} doesn't implement the trait for {:?}, the compiler should have flagged this",
93 registry::get_value_type(value_type),
94 trait_method
95 )),
96 }
97 }
98}
99
100#[cfg(test)]
101pub(crate) mod tests {
102 use super::*;
103 use crate::{self as turbo_tasks, Vc};
104
105 #[turbo_tasks::function]
106 fn mock_func_task() -> Vc<()> {
107 Vc::cell(())
108 }
109
110 #[turbo_tasks::value_trait]
111 trait MockTrait {
112 #[turbo_tasks::function]
113 fn mock_method_task() -> Vc<()>;
114 }
115
116 #[test]
117 fn test_fmt() {
118 assert_eq!(
119 LocalTaskType::ResolveNative {
120 native_fn: &MOCK_FUNC_TASK_FUNCTION,
121 }
122 .to_string(),
123 "*mock_func_task",
124 );
125 assert_eq!(
126 LocalTaskType::ResolveTrait {
127 trait_method: MOCKTRAIT_TRAIT_TYPE.get("mock_method_task"),
128 }
129 .to_string(),
130 "*MockTrait::mock_method_task",
131 );
132 }
133}