parallelize-async-work
ComputerGuy 6 days ago
parent 7788c30087
commit c17a1e3ed2

@ -1,4 +1,4 @@
/** @import { CallExpression, Expression, Identifier, Literal, Program, VariableDeclaration, VariableDeclarator } from 'estree' */ /** @import { CallExpression, Expression, Identifier, Literal, Node, Program, VariableDeclaration, VariableDeclarator } from 'estree' */
/** @import { Binding } from '#compiler' */ /** @import { Binding } from '#compiler' */
/** @import { ComponentContext, ParallelizedChunk } from '../types' */ /** @import { ComponentContext, ParallelizedChunk } from '../types' */
import { dev, is_ignored, locate_node } from '../../../../state.js'; import { dev, is_ignored, locate_node } from '../../../../state.js';
@ -23,12 +23,14 @@ import { get_value } from './shared/declarations.js';
export function VariableDeclaration(node, context) { export function VariableDeclaration(node, context) {
/** @type {VariableDeclarator[]} */ /** @type {VariableDeclarator[]} */
const declarations = []; const declarations = [];
const parent = /** @type {Node} */ (context.path.at(-1));
const position = /** @type {Program} */ (parent).body?.indexOf?.(node);
if (context.state.analysis.runes) { if (context.state.analysis.runes) {
for (const declarator of node.declarations) { for (const declarator of node.declarations) {
const init = /** @type {Expression} */ (declarator.init); const init = /** @type {Expression} */ (declarator.init);
const rune = get_rune(init, context.state.scope); const rune = get_rune(init, context.state.scope);
const bindings = context.state.scope.get_bindings(declarator);
if ( if (
!rune || !rune ||
rune === '$effect.tracking' || rune === '$effect.tracking' ||
@ -53,40 +55,34 @@ export function VariableDeclaration(node, context) {
init.argument, init.argument,
context.state.scope, context.state.scope,
context.state.analysis, context.state.analysis,
[ [...(context.state.current_parallelized_chunk?.bindings ?? []), ...bindings]
...(context.state.current_parallelized_chunk?.bindings ?? []),
...context.state.scope.get_bindings(declarator)
]
); );
if (parallelize) { if (parallelize) {
const bindings = context.state.scope.get_bindings(declarator); const { id, init: visited_init } = /** @type {VariableDeclarator} */ (
const visited = /** @type {VariableDeclarator} */ (
context.visit({ context.visit({
...declarator, ...declarator,
init: init.argument init: init.argument
}) })
); );
const declarators = [ const _declarator = {
{ id,
id: visited.id, init: /** @type {Expression} */ (visited_init)
init: /** @type {Expression} */ (visited.init) };
}
];
if ( if (
context.state.current_parallelized_chunk && context.state.current_parallelized_chunk &&
context.state.current_parallelized_chunk.kind === node.kind context.state.current_parallelized_chunk.kind === node.kind
) { ) {
context.state.current_parallelized_chunk.declarators.push(...declarators); context.state.current_parallelized_chunk.declarators.push(_declarator);
context.state.current_parallelized_chunk.bindings.push(...bindings); context.state.current_parallelized_chunk.bindings.push(...bindings);
context.state.current_parallelized_chunk.position = /** @type {Program} */ ( context.state.current_parallelized_chunk.position = /** @type {Program} */ (
context.path.at(-1) parent
).body.indexOf(node); ).body.indexOf(node);
} else { } else {
/** @type {ParallelizedChunk} */ /** @type {ParallelizedChunk} */
const chunk = { const chunk = {
kind: node.kind, kind: node.kind,
declarators, declarators: [_declarator],
position: /** @type {Program} */ (context.path.at(-1)).body.indexOf(node), position,
bindings bindings
}; };
context.state.current_parallelized_chunk = chunk; context.state.current_parallelized_chunk = chunk;
@ -185,9 +181,7 @@ export function VariableDeclaration(node, context) {
* @param {Expression} value * @param {Expression} value
*/ */
const create_state_declarator = (id, value) => { const create_state_declarator = (id, value) => {
const binding = /** @type {import('#compiler').Binding} */ ( const binding = /** @type {Binding} */ (context.state.scope.get(id.name));
context.state.scope.get(id.name)
);
const is_state = is_state_source(binding, context.state.analysis); const is_state = is_state_source(binding, context.state.analysis);
const is_proxy = should_proxy(value, context.state.scope); const is_proxy = should_proxy(value, context.state.scope);
@ -386,15 +380,13 @@ export function VariableDeclaration(node, context) {
) { ) {
context.state.current_parallelized_chunk.declarators.push(...declarators); context.state.current_parallelized_chunk.declarators.push(...declarators);
context.state.current_parallelized_chunk.bindings.push(...bindings); context.state.current_parallelized_chunk.bindings.push(...bindings);
context.state.current_parallelized_chunk.position = /** @type {Program} */ ( context.state.current_parallelized_chunk.position = position;
context.path.at(-1)
).body.indexOf(node);
} else { } else {
/** @type {ParallelizedChunk} */ /** @type {ParallelizedChunk} */
const chunk = { const chunk = {
kind: node.kind, kind: node.kind,
declarators, declarators,
position: /** @type {Program} */ (context.path.at(-1)).body.indexOf(node), position,
bindings bindings
}; };
context.state.current_parallelized_chunk = chunk; context.state.current_parallelized_chunk = chunk;
@ -407,7 +399,7 @@ export function VariableDeclaration(node, context) {
} }
} else { } else {
for (const declarator of node.declarations) { for (const declarator of node.declarations) {
const bindings = /** @type {Binding[]} */ (context.state.scope.get_bindings(declarator)); const bindings = context.state.scope.get_bindings(declarator);
const has_state = bindings.some((binding) => binding.kind === 'state'); const has_state = bindings.some((binding) => binding.kind === 'state');
const has_props = bindings.some((binding) => binding.kind === 'bindable_prop'); const has_props = bindings.some((binding) => binding.kind === 'bindable_prop');
@ -510,13 +502,9 @@ export function VariableDeclaration(node, context) {
* @param {Expression} value * @param {Expression} value
*/ */
function create_state_declarators(declarator, context, value) { function create_state_declarators(declarator, context, value) {
const immutable = context.state.analysis.immutable ? b.true : undefined;
if (declarator.id.type === 'Identifier') { if (declarator.id.type === 'Identifier') {
return [ return [b.declarator(declarator.id, b.call('$.mutable_source', value, immutable))];
b.declarator(
declarator.id,
b.call('$.mutable_source', value, context.state.analysis.immutable ? b.true : undefined)
)
];
} }
const tmp = b.id(context.state.scope.generate('tmp')); const tmp = b.id(context.state.scope.generate('tmp'));
@ -531,15 +519,13 @@ function create_state_declarators(declarator, context, value) {
const expression = /** @type {Expression} */ (context.visit(b.thunk(value))); const expression = /** @type {Expression} */ (context.visit(b.thunk(value)));
return b.declarator(id, b.call('$.derived', expression)); return b.declarator(id, b.call('$.derived', expression));
}), }),
...paths.map((path) => { ...paths.map(({ expression, node }) => {
const value = /** @type {Expression} */ (context.visit(path.expression)); const value = /** @type {Expression} */ (context.visit(expression));
const binding = context.state.scope.get(/** @type {Identifier} */ (path.node).name); const binding = context.state.scope.get(/** @type {Identifier} */ (node).name);
return b.declarator( return b.declarator(
path.node, node,
binding?.kind === 'state' binding?.kind === 'state' ? b.call('$.mutable_source', value, immutable) : value
? b.call('$.mutable_source', value, context.state.analysis.immutable ? b.true : undefined)
: value
); );
}) })
]; ];

Loading…
Cancel
Save