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 { export interface ParallelizedChunk {
declarators: Array<{ declarators: Array<{
id: Pattern; id: Pattern | null;
init: Expression; init: Expression;
}>; }>;
kind: VariableDeclaration['kind']; kind: VariableDeclaration['kind'] | null;
/** index in instance body */ /** index in instance body */
position: number; position: number;
bindings: Binding[]; bindings: Binding[];

@ -1,13 +1,16 @@
/** @import { Expression, ExpressionStatement } from 'estree' */ /** @import { Expression, ExpressionStatement, Node, Program } from 'estree' */
/** @import { ComponentContext } from '../types' */ /** @import { ComponentContext, ParallelizedChunk } from '../types' */
import * as b from '#compiler/builders'; import * as b from '#compiler/builders';
import { get_rune } from '../../../scope.js'; import { get_rune } from '../../../scope.js';
import { can_be_parallelized } from '../utils.js';
/** /**
* @param {ExpressionStatement} node * @param {ExpressionStatement} node
* @param {ComponentContext} context * @param {ComponentContext} context
*/ */
export function ExpressionStatement(node, 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') { if (node.expression.type === 'CallExpression') {
const rune = get_rune(node.expression, context.state.scope); const rune = get_rune(node.expression, context.state.scope);
@ -25,6 +28,39 @@ export function ExpressionStatement(node, context) {
return b.empty; 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(); context.next();
} }

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

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

Loading…
Cancel
Save