Skip to content

Commit a34bed4

Browse files
committed
refactor(code-mode): consume QuickJS handles
1 parent 7b16b35 commit a34bed4

1 file changed

Lines changed: 22 additions & 59 deletions

File tree

src/agents/code-mode.worker.ts

Lines changed: 22 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,7 @@ class CodeModeGuestError extends Error {
120120
}
121121

122122
function isQuickJsInterruptedError(error: unknown): boolean {
123-
if (error instanceof CodeModeGuestError) {
124-
return false;
125-
}
126-
// Match on the raw QuickJS message, not the formatted errorMessage() string,
127-
// which now leads with the error name and appends backtrace frames.
128-
if (error instanceof JSException) {
129-
return error.message === "interrupted";
130-
}
131-
return errorMessage(error) === "interrupted";
123+
return error instanceof JSException && error.message === "interrupted";
132124
}
133125

134126
type VmRun = {
@@ -437,37 +429,23 @@ async function createVm(params: {
437429
return timedOut;
438430
},
439431
});
440-
const catalogHandle = vm.hostToHandle(params.catalog);
441-
try {
442-
vm.setProp(vm.global, "__openclawCatalog", catalogHandle);
443-
} finally {
444-
catalogHandle.dispose();
445-
}
446-
const namespacesHandle = vm.hostToHandle(params.namespaces);
447-
try {
448-
vm.setProp(vm.global, "__openclawNamespaces", namespacesHandle);
449-
} finally {
450-
namespacesHandle.dispose();
451-
}
452-
const apiFilesHandle = vm.hostToHandle(params.apiFiles);
453-
try {
454-
vm.setProp(vm.global, "__openclawApiFiles", apiFilesHandle);
455-
} finally {
456-
apiFilesHandle.dispose();
457-
}
458-
const hostRequest = vm.newFunction(
432+
vm.hostToHandle(params.catalog).consume((handle) =>
433+
vm.global.setProp("__openclawCatalog", handle),
434+
);
435+
vm.hostToHandle(params.namespaces).consume((handle) =>
436+
vm.global.setProp("__openclawNamespaces", handle),
437+
);
438+
vm.hostToHandle(params.apiFiles).consume((handle) =>
439+
vm.global.setProp("__openclawApiFiles", handle),
440+
);
441+
vm.newFunction(
459442
"__openclawHostRequest",
460443
createHostRequestHandler({
461444
vm,
462445
pendingRequests: params.pendingRequests,
463446
config: params.config,
464447
}),
465-
);
466-
try {
467-
vm.setProp(vm.global, "__openclawHostRequest", hostRequest);
468-
} finally {
469-
hostRequest.dispose();
470-
}
448+
).consume((hostRequest) => vm.global.setProp("__openclawHostRequest", hostRequest));
471449
vm.evalCode(CONTROLLER_SOURCE, "openclaw-code-mode:controller.js").dispose();
472450
return { vm, didTimeout: () => timedOut || deadlineReached() };
473451
}
@@ -502,18 +480,12 @@ async function restoreVm(params: {
502480
}
503481

504482
function takeOutput(vm: QuickJS): unknown[] {
505-
const take = vm.global.getProp("__openclawTakeOutput");
506-
try {
507-
const output = vm.callFunction(take, vm.undefined);
508-
try {
483+
return vm.global.getProp("__openclawTakeOutput").consume((take) =>
484+
vm.callFunction(take, vm.undefined).consume((output) => {
509485
const dumped = vm.dump(output);
510486
return Array.isArray(dumped) ? (dumped as unknown[]) : [];
511-
} finally {
512-
output.dispose();
513-
}
514-
} finally {
515-
take.dispose();
516-
}
487+
}),
488+
);
517489
}
518490

519491
function takeOutputSafely(vm: QuickJS): unknown[] {
@@ -565,25 +537,19 @@ async function readCompletedResult(vm: QuickJS, resultHandle: JSValueHandle): Pr
565537
}
566538
const settled = await vm.resolvePromise(resultHandle);
567539
if ("error" in settled) {
568-
try {
540+
return settled.error.consume((error) => {
569541
// vm.dump rebuilds a host Error carrying the QuickJS name/message/stack;
570542
// format it like the synchronous path so async rejections keep their cause
571543
// and location instead of collapsing to the bare message.
572-
const dumped = vm.dump(settled.error);
544+
const dumped = vm.dump(error);
573545
const text =
574546
dumped instanceof Error
575547
? formatQuickJsError(dumped.name, dumped.message, dumped.stack)
576548
: errorMessage(dumped);
577549
throw new CodeModeGuestError(text);
578-
} finally {
579-
settled.error.dispose();
580-
}
581-
}
582-
try {
583-
return toJsonSafe(vm.dump(settled.value));
584-
} finally {
585-
settled.value.dispose();
550+
});
586551
}
552+
return settled.value.consume((value) => toJsonSafe(vm.dump(value)));
587553
}
588554

589555
function waitingResult(params: {
@@ -688,8 +654,7 @@ async function runResume(input: Extract<CodeModeWorkerInput, { kind: "resume" }>
688654
pendingRequests,
689655
config: input.config,
690656
prepare: () => {
691-
const settle = vm.global.getProp("__openclawSettleBridge");
692-
try {
657+
vm.global.getProp("__openclawSettleBridge").consume((settle) => {
693658
for (const request of input.settledRequests) {
694659
const id = vm.newString(request.id);
695660
const payload = vm.newString(JSON.stringify(request.ok ? request.value : request.error));
@@ -706,9 +671,7 @@ async function runResume(input: Extract<CodeModeWorkerInput, { kind: "resume" }>
706671
payload.dispose();
707672
}
708673
}
709-
} finally {
710-
settle.dispose();
711-
}
674+
});
712675
},
713676
});
714677
}

0 commit comments

Comments
 (0)