@@ -2185,10 +2185,14 @@ impl AsyncTaskIntrinsic {
21852185 let debug_log_fn = Intrinsic :: DebugLog . name ( ) ;
21862186 let lower_import_backwards_compat_fn = Self :: LowerImportBackwardsCompat . name ( ) ;
21872187 let current_task_get_fn = Self :: GetCurrentTask . name ( ) ;
2188+ let create_new_current_task_fn = Self :: CreateNewCurrentTask . name ( ) ;
21882189 let get_or_create_async_state_fn =
21892190 Intrinsic :: Component ( ComponentIntrinsic :: GetOrCreateAsyncState ) . name ( ) ;
21902191 let async_event_code_enum = Intrinsic :: AsyncEventCodeEnum . name ( ) ;
21912192 let get_global_current_task_meta_fn = Intrinsic :: GetGlobalCurrentTaskMetaFn . name ( ) ;
2193+ let set_global_current_task_meta_fn = Intrinsic :: SetGlobalCurrentTaskMetaFn . name ( ) ;
2194+ let clear_global_current_task_meta_fn =
2195+ Intrinsic :: ClearGlobalCurrentTaskMetaFn . name ( ) ;
21922196 let promise_with_resolvers_fn = Intrinsic :: PromiseWithResolversPonyfill . name ( ) ;
21932197
21942198 output. push_str ( & format ! (
@@ -2211,10 +2215,52 @@ impl AsyncTaskIntrinsic {
22112215 importFn,
22122216 }} = args;
22132217
2214- const {{ taskID }} = {get_global_current_task_meta_fn}(componentIdx);
2218+ let meta = {get_global_current_task_meta_fn}(componentIdx);
2219+ let createdTask;
2220+
2221+ // Some components depend on initialization logic (i.e. `_initialize` or some such
2222+ // core wasm export) that is embedded in the component, but is not executed or wizer'd
2223+ // away before the transpiled component is attempted to be used.
2224+ //
2225+ // These components execut their initialization logic *when they are imported* in the
2226+ // transpiled context -- so we may get a call to an export that is lowered without going
2227+ // through `CallWasm` or `CallInterface`.
2228+ //
2229+ if (!meta) {{
2230+ if (funcTypeIsAsync || (isAsync && !isManualAsync)) {{
2231+ throw new Error('p3 async wasm exports cannot use backwards compat auto-task init');
2232+ }}
2233+
2234+ const [newTask, newTaskID] = {create_new_current_task_fn}({{
2235+ componentIdx,
2236+ isAsync,
2237+ isManualAsync,
2238+ callingWasmExport: false,
2239+ }});
2240+ createdTask = newTask;
2241+
2242+ // Since we're managing the task creation ourselves we must clear ourselves
2243+ createdTask.registerOnResolveHandler(() => {{
2244+ {clear_global_current_task_meta_fn}({{
2245+ taskID: task.id(),
2246+ componentIdx: task.componentIdx(),
2247+ }});
2248+ }});
2249+
2250+ {set_global_current_task_meta_fn}({{
2251+ componentIdx,
2252+ taskID: newTaskID,
2253+ }});
2254+
2255+ meta = {get_global_current_task_meta_fn}(componentIdx);
2256+ }}
2257+
2258+ const {{ taskID }} = meta;
22152259
22162260 const taskMeta = {current_task_get_fn}(componentIdx, taskID);
2217- if (!taskMeta) {{ throw new Error('invalid/missing async task meta'); }}
2261+ if (!taskMeta) {{
2262+ throw new Error('invalid/missing async task meta');
2263+ }}
22182264
22192265 const task = taskMeta.task;
22202266 if (!task) {{ throw new Error('invalid/missing async task'); }}
@@ -2258,13 +2304,20 @@ impl AsyncTaskIntrinsic {
22582304 // TODO(breaking): remove once we get rid of manual async import specification,
22592305 // as func types cannot be detected in that case only (and we don't need that w/ p3)
22602306 if (!isManualAsync && !isAsync && !funcTypeIsAsync) {{
2307+ if (createdTask) {{ createdTask.enterSync(); }}
2308+
22612309 const res = importFn(...params);
2310+
22622311 // TODO(breaking): remove once we get rid of manual async import specification,
22632312 // as func types cannot be detected in that case only (and we don't need that w/ p3)
22642313 if (!funcTypeIsAsync && !subtask.isReturned()) {{
22652314 throw new Error('post-execution subtasks must either be async or returned');
22662315 }}
2267- return subtask.getResult();
2316+
2317+ const syncRes = subtask.getResult();
2318+ if (createdTask) {{ createdTask.resolve([syncRes]); }}
2319+
2320+ return syncRes;
22682321 }}
22692322
22702323 // Sync-lowered async functions requires async behavior because the callee *can* block,
@@ -2333,10 +2386,16 @@ impl AsyncTaskIntrinsic {
23332386 queueMicrotask(async () => {{
23342387 try {{
23352388 {debug_log_fn}('[{lower_import_backwards_compat_fn}()] calling lowered import', {{ importFn, params }});
2336- const res = await importFn(...params);
2389+ if (createdTask) {{ await createdTask.enter(); }}
2390+
2391+ const asyncRes = await importFn(...params);
23372392 if (requiresManualAsyncResult) {{
23382393 manualAsyncResult.resolve(subtask.getResult());
23392394 }}
2395+
2396+ if (createdTask) {{ createdTask.resolve([asyncRes]); }}
2397+
2398+
23402399 }} catch (err) {{
23412400 {debug_log_fn}("[{lower_import_backwards_compat_fn}()] import fn error:", err);
23422401 if (requiresManualAsyncResult) {{
0 commit comments