parallelize `await` expressions in instance

parallelize-async-work
ComputerGuy 4 days ago
parent b138c6055b
commit 82cb5156c7

@ -90,10 +90,10 @@ export interface ComponentClientTransformState extends ClientTransformState {
export interface ParallelizedChunk {
declarators: Array<{
id: Pattern;
id: Pattern | null;
init: Expression;
}>;
kind: VariableDeclaration['kind'];
kind: VariableDeclaration['kind'] | null;
/** index in instance body */
position: number;
bindings: Binding[];

@ -1,13 +1,16 @@
/** @import { Expression, ExpressionStatement } from 'estree' */
/** @import { ComponentContext } from '../types' */
/** @import { Expression, ExpressionStatement, Node, Program } from 'estree' */
/** @import { ComponentContext, ParallelizedChunk } from '../types' */
import * as b from '#compiler/builders';
import { get_rune } from '../../../scope.js';
import { can_be_parallelized } from '../utils.js';
/**
* @param {ExpressionStatement} node
* @param {ComponentContext} context
*/
export function ExpressionStatement(node, context) {
const parent = /** @type {Node} */ (context.path.at(-1));
const position = /** @type {Program} */ (parent).body?.indexOf?.(node);
if (node.expression.type === 'CallExpression') {
const rune = get_rune(node.expression, context.state.scope);
@ -25,6 +28,39 @@ export function ExpressionStatement(node, context) {
return b.empty;
}
}
if (
node.expression.type === 'AwaitExpression' &&
context.state.analysis.instance?.scope === context.state.scope
) {
const current_chunk = context.state.current_parallelized_chunk;
const parallelize = can_be_parallelized(
node.expression.argument,
context.state.scope,
context.state.analysis,
current_chunk?.bindings ?? []
);
if (parallelize) {
const declarator = {
id: null,
init: /** @type {Expression} */ (context.visit(node.expression))
};
if (current_chunk) {
current_chunk.declarators.push(declarator);
current_chunk.position = position;
} else {
/** @type {ParallelizedChunk} */
const chunk = {
kind: null,
declarators: [declarator],
position,
bindings: []
};
context.state.current_parallelized_chunk = chunk;
context.state.parallelized_chunks.push(chunk);
}
return;
}
}
context.next();
}

@ -148,20 +148,28 @@ export function Program(node, context) {
for (const chunk of context.state.parallelized_chunks) {
if (chunk.declarators.length === 1) {
const declarator = chunk.declarators[0];
body.splice(
chunk.position + offset,
0,
b.declaration(chunk.kind, [
b.declarator(declarator.id, b.call(b.await(b.call('$.save', declarator.init))))
])
);
if (declarator.id === null || chunk.kind === null) {
body.splice(
chunk.position + offset,
0,
b.stmt(b.call(b.await(b.call('$.save', declarator.init))))
);
} else {
body.splice(
chunk.position + offset,
0,
b.declaration(chunk.kind, [
b.declarator(declarator.id, b.call(b.await(b.call('$.save', declarator.init))))
])
);
}
} else {
const pattern = b.array_pattern(chunk.declarators.map(({ id }) => id));
const init = b.call(`$.all`, ...chunk.declarators.map(({ init }) => init));
const init = b.call('$.all', ...chunk.declarators.map(({ init }) => init));
body.splice(
chunk.position + offset,
0,
b.declaration(chunk.kind, [b.declarator(pattern, b.await(init))])
b.declaration(chunk.kind ?? 'const', [b.declarator(pattern, b.await(init))])
);
}
offset++;

@ -69,10 +69,14 @@ export function VariableDeclaration(node, context) {
id,
init: /** @type {Expression} */ (visited_init)
};
if (current_chunk && current_chunk.kind === node.kind) {
if (
current_chunk &&
(current_chunk.kind === node.kind || current_chunk.kind === null)
) {
current_chunk.declarators.push(_declarator);
current_chunk.bindings.push(...bindings);
current_chunk.position = /** @type {Program} */ (parent).body.indexOf(node);
current_chunk.kind = node.kind;
} else {
/** @type {ParallelizedChunk} */
const chunk = {
@ -370,10 +374,11 @@ export function VariableDeclaration(node, context) {
id,
init: /** @type {Expression} */ (init)
}));
if (current_chunk && current_chunk.kind === node.kind) {
if (current_chunk && (current_chunk.kind === node.kind || current_chunk.kind === null)) {
current_chunk.declarators.push(...declarators);
current_chunk.bindings.push(...bindings);
current_chunk.position = position;
current_chunk.kind = node.kind;
} else {
/** @type {ParallelizedChunk} */
const chunk = {

Loading…
Cancel
Save