Skip to content

Commit f1c0772

Browse files
wip: debug
1 parent 88e8326 commit f1c0772

File tree

4 files changed

+65
-65
lines changed

4 files changed

+65
-65
lines changed

crates/js-component-bindgen/src/function_bindgen.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,8 @@ impl Bindgen for FunctionBindgen<'_> {
12431243
has_post_return = self.post_return.is_some(),
12441244
);
12451245

1246+
uwriteln!(self.src, "console.log('[CALL_WASM] {name}')");
1247+
12461248
// Inject machinery for starting a 'current' task
12471249
self.start_current_task(
12481250
inst,
@@ -1326,6 +1328,8 @@ impl Bindgen for FunctionBindgen<'_> {
13261328
async_ = async_.then_some("async").unwrap_or("sync"),
13271329
);
13281330

1331+
uwriteln!(self.src, "console.log('[CALL_INTERFACE] {}')", func.name);
1332+
13291333
// // Inject machinery for starting a 'current' task
13301334
// self.start_current_task(
13311335
// inst,

crates/js-component-bindgen/src/intrinsics/p3/async_future.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,9 @@ impl AsyncFutureIntrinsic {
398398
}});
399399
400400
if (!isAsync && !e.hasPendingEvent()) {{
401-
await task.blockOn({{ promise: e.waitForPendingEvent(), isAsync: false }});
401+
// TODO: replace with what block on used to be? wait for?
402+
// await task.blockOn({{ promise: e.waitForPendingEvent(), isAsync: false }});
403+
throw new Error('not implemented');
402404
}}
403405
404406
if (futureEnd.hasPendingEvent()) {{
@@ -458,7 +460,9 @@ impl AsyncFutureIntrinsic {
458460
// TODO: cancel the shared thing (waitable?)
459461
if (!futureEnd.hasPendingEvent()) {{
460462
if (!isAsync) {{
461-
await task.blockOn({{ promise: futureEnd.waitable, isAsync: false }});
463+
// TODO: repalce with what task.blockOn used to do
464+
// await task.blockOn({{ promise: futureEnd.waitable, isAsync: false }});
465+
throw new Error('not implemented');
462466
}} else {{
463467
return {async_blocked_const};
464468
}}

crates/js-component-bindgen/src/intrinsics/p3/async_task.rs

Lines changed: 28 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -519,11 +519,12 @@ impl AsyncTaskIntrinsic {
519519
}}
520520
const tasks = {global_task_map}.get(componentIdx);
521521
522+
const callbackFn = getCallbackFn ? getCallbackFn() : null;
522523
const newTask = new {task_class}({{
523524
componentIdx,
524525
isAsync,
525526
entryFnName,
526-
callbackFn: getCallbackFn ? getCallbackFn() : null,
527+
callbackFn,
527528
callbackFnName,
528529
stringEncoding,
529530
getCalleeParamsFn,
@@ -648,10 +649,12 @@ impl AsyncTaskIntrinsic {
648649
#componentIdx;
649650
#state;
650651
#isAsync;
651-
#onResolve = null;
652652
#entryFnName = null;
653653
#subtasks = [];
654+
655+
#onResolve = null;
654656
#completionPromise = null;
657+
655658
#memoryIdx = null;
656659
657660
#callbackFn = null;
@@ -665,6 +668,8 @@ impl AsyncTaskIntrinsic {
665668
666669
#parentSubtask = null;
667670
671+
#needsExclusiveLock = false;
672+
668673
cancelled = false;
669674
requested = false;
670675
alwaysTaskReturn = false;
@@ -676,7 +681,6 @@ impl AsyncTaskIntrinsic {
676681
awaitableResume = null;
677682
awaitableCancel = null;
678683
679-
680684
constructor(opts) {{
681685
this.#id = ++{task_class}._ID;
682686
@@ -709,6 +713,17 @@ impl AsyncTaskIntrinsic {
709713
if (opts.stringEncoding) {{ this.#stringEncoding = opts.stringEncoding; }}
710714
711715
if (opts.parentSubtask) {{ this.#parentSubtask = opts.parentSubtask; }}
716+
717+
this.#needsExclusiveLock = this.isSync() || !this.hasCallback();
718+
console.log('CREATED TASK', {{
719+
componentIdx: this.#componentIdx,
720+
entryFnName: this.#entryFnName,
721+
id: this.#id,
722+
sync: this.isSync(),
723+
hasCallback: this.hasCallback(),
724+
needsExclusiveLock: this.#needsExclusiveLock,
725+
}});
726+
console.log();
712727
}}
713728
714729
taskState() {{ return this.#state.slice(); }}
@@ -718,6 +733,11 @@ impl AsyncTaskIntrinsic {
718733
entryFnName() {{ return this.#entryFnName; }}
719734
completionPromise() {{ return this.#completionPromise; }}
720735
736+
isAsync() {{ return this.#isAsync; }}
737+
isSync() {{ return !this.isAsync(); }}
738+
739+
hasCallback() {{ return this.#callbackFn !== null; }}
740+
721741
setMemoryIdx(idx) {{ this.#memoryIdx = idx; }}
722742
getMemoryIdx(idx) {{ return this.#memoryIdx; }}
723743
@@ -857,52 +877,6 @@ impl AsyncTaskIntrinsic {
857877
throw new Error('{task_class}#pollForEvent() not implemented');
858878
}}
859879
860-
async blockOn(opts) {{
861-
const {{ awaitable, isCancellable, forCallback }} = opts;
862-
{debug_log_fn}('[{task_class}#blockOn()] args', {{ taskID: this.#id, awaitable, isCancellable, forCallback }});
863-
864-
if (awaitable.resolved() && !{global_async_determinism} && {coin_flip_fn}()) {{
865-
return {task_class}.BlockResult.NOT_CANCELLED;
866-
}}
867-
868-
const cstate = {get_or_create_async_state_fn}(this.#componentIdx);
869-
if (forCallback) {{ cstate.exclusiveRelease(); }}
870-
871-
let cancelled = await this.onBlock(awaitable);
872-
if (cancelled === {task_class}.BlockResult.CANCELLED && !isCancellable) {{
873-
const secondCancel = await this.onBlock(awaitable);
874-
if (secondCancel !== {task_class}.BlockResult.NOT_CANCELLED) {{
875-
throw new Error('uncancellable task was canceled despite second onBlock()');
876-
}}
877-
}}
878-
879-
if (forCallback) {{
880-
const acquired = new {awaitable_class}(cstate.exclusiveLock());
881-
cancelled = await this.onBlock(acquired);
882-
if (cancelled === {task_class}.BlockResult.CANCELLED) {{
883-
const secondCancel = await this.onBlock(acquired);
884-
if (secondCancel !== {task_class}.BlockResult.NOT_CANCELLED) {{
885-
throw new Error('uncancellable callback task was canceled despite second onBlock()');
886-
}}
887-
}}
888-
}}
889-
890-
if (cancelled === {task_class}.BlockResult.CANCELLED) {{
891-
if (this.#state !== {task_class}.State.INITIAL) {{
892-
throw new Error('cancelled task is not at initial state');
893-
}}
894-
if (isCancellable) {{
895-
this.#state = {task_class}.State.CANCELLED;
896-
return {task_class}.BlockResult.CANCELLED;
897-
}} else {{
898-
this.#state = {task_class}.State.CANCEL_PENDING;
899-
return {task_class}.BlockResult.NOT_CANCELLED;
900-
}}
901-
}}
902-
903-
return {task_class}.BlockResult.NOT_CANCELLED;
904-
}}
905-
906880
async onBlock(awaitable) {{
907881
{debug_log_fn}('[{task_class}#onBlock()] args', {{ taskID: this.#id, awaitable }});
908882
if (!(awaitable instanceof {awaitable_class})) {{
@@ -1078,12 +1052,15 @@ impl AsyncTaskIntrinsic {
10781052
}}
10791053
state.inSyncExportCall = false;
10801054
1081-
if (!state.isExclusivelyLocked()) {{
1082-
throw new Error('task should have been exclusively locked at end of execution');
1055+
if (this.needsExclusiveLock() && !state.isExclusivelyLocked()) {{
1056+
throw new Error('task [' + this.#id + '] exit: component [' + this.#componentIdx + '] should have been exclusively locked');
10831057
}}
1058+
10841059
state.exclusiveRelease();
10851060
}}
10861061
1062+
needsExclusiveLock(v) {{ return this.#needsExclusiveLock; }}
1063+
10871064
createSubtask(args) {{
10881065
{debug_log_fn}('[{task_class}#createSubtask()] args', args);
10891066
const {{ componentIdx, memoryIdx, childTask }} = args;

crates/js-component-bindgen/src/intrinsics/p3/host.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,10 @@ impl HostIntrinsic {
134134
AsyncTaskIntrinsic::GlobalAsyncCurrentComponentIdxs.name();
135135
let current_task_get_fn =
136136
Intrinsic::AsyncTask(AsyncTaskIntrinsic::GetCurrentTask).name();
137-
let start_current_task =
137+
let start_current_task_fn =
138138
Intrinsic::AsyncTask(AsyncTaskIntrinsic::StartCurrentTask).name();
139+
let end_current_task_fn =
140+
Intrinsic::AsyncTask(AsyncTaskIntrinsic::EndCurrentTask).name();
139141

140142
// See:
141143
// https://github.com/bytecodealliance/wasmtime/blob/e2f9ca6be1b06b5c5c9e78834d10b8132cea0c80/crates/wasmtime/src/runtime/component/concurrent.rs#L2033
@@ -172,16 +174,22 @@ impl HostIntrinsic {
172174
{debug_log_fn}('[{prepare_call_fn}()] args', {{ memoryIdx }});
173175
const argArray = [...arguments];
174176
175-
const taskMeta = {current_task_get_fn}({current_component_idx_globals}.at(-1), {current_async_task_id_globals}.at(-1));
176-
if (!taskMeta) {{ throw new Error('invalid/missing current async task meta during prepare call'); }}
177+
const currentCallerTaskMeta = {current_task_get_fn}(callerInstanceIdx);
178+
if (!currentCallerTaskMeta) {{ throw new Error('invalid/missing current task for caller during prepare call'); }}
177179
178-
const task = taskMeta.task;
179-
if (!task) {{ throw new Error('unexpectedly missing task in task meta during prepare call'); }}
180+
const currentCallerTask = currentCallerTaskMeta.task;
181+
if (!currentCallerTask) {{ throw new Error('unexpectedly missing task in meta for caller during prepare call'); }}
180182
181-
// TODO: callee instance is coming up becasue the subtask's Task was removed already?
183+
console.log('DURING PREPARE', {{
184+
currentCallerTask,
185+
currentCallerTaskID: currentCallerTask.id(),
186+
taskComponentIdx: currentCallerTask.componentIdx(),
187+
callerIdx: callerInstanceIdx,
188+
calleeIdx: calleeInstanceIdx,
189+
}});
182190
183-
if (task.componentIdx() !== callerInstanceIdx) {{
184-
throw new Error(`task component idx [${{ task.componentIdx() }}] differs from caller [${{ callerInstanceIdx }}] (callee ${{ calleeInstanceIdx }})`);
191+
if (currentCallerTask.componentIdx() !== callerInstanceIdx) {{
192+
throw new Error(`task component idx [${{ currentCallerTask.componentIdx() }}] differs from caller [${{ callerInstanceIdx }}] (callee ${{ calleeInstanceIdx }})`);
185193
}}
186194
187195
const directParams = storagePtr === -1;
@@ -214,22 +222,29 @@ impl HostIntrinsic {
214222
throw new Error(`unrecognized string encoding enum [${{stringEncoding}}]`);
215223
}}
216224
217-
const [newTask, newTaskID] = {start_current_task}({{
225+
const [newTask, newTaskID] = {start_current_task_fn}({{
218226
componentIdx: calleeInstanceIdx,
219-
isAsync: true, // TODO: we don't know if this task corresponds to an async function or not?
227+
isAsync: true,
220228
getCalleeParamsFn,
229+
// TODO: find a way to pass the import name through here
230+
entryFnName: 'task/' + currentCallerTask.id() + '/new-prepare-task',
221231
stringEncoding,
222232
}});
223233
234+
console.log('====');
235+
console.log('CREATING NEW SUBTASK', {{ callerInstanceIdx, calleeInstanceIdx, newTaskID }});
236+
console.log('====');
237+
224238
const subtask = task.createSubtask({{
225-
componentIdx: task.componentIdx(),
226-
parentTask: task,
239+
componentIdx: callerInstanceIdx,
240+
parentTask: currentCallerTask,
227241
childTask: newTask,
228242
}});
229243
230244
newTask.setParentSubtask(subtask);
231245
232246
newTask.completionPromise().then(() => {{
247+
{end_current_task_fn}(calleeInstanceIdx, newTaskID);
233248
// TODO: run return function when the task finishes and the return is ready to be saved
234249
}});
235250

0 commit comments

Comments
 (0)