feat: switch to using queuePriority based on referenceGroup order

This commit is contained in:
Michael Rawlings 2022-02-17 13:21:37 -08:00
parent c5f3262fb1
commit a6647c73cb
No known key found for this signature in database
GPG Key ID: B9088328804D407C
15 changed files with 79 additions and 94 deletions

View File

@ -7,7 +7,7 @@ function _hydrate_clickCount(clickCount = _read(2)) {
const _onclick = function () {
const clickCount = _read(2);
_queue(_apply_clickCount, 2, clickCount + 1);
_queue(_apply_clickCount, 0, clickCount + 1);
};
function _apply_clickCount(clickCount) {

View File

@ -15,7 +15,7 @@ function _applyWith_selected_num(selected = _readInOwner(4), num = _read(2)) {
const _onclick = function () {
const num = _read(2);
_queueInOwner(_apply_selected, 4, num);
_queueInOwner(_apply_selected, 0, num);
};
function _apply_num(num) {
@ -31,11 +31,11 @@ function _apply_num(num) {
}
function _apply_selected2(selected = _readInOwner(4)) {
_queue(_applyWith_selected_num, 4);
_queue(_applyWith_selected_num, 2);
}
function _apply_selected(selected) {
if (_write(4, selected)) _queueForEach(0, _apply_selected2, 4);
if (_write(4, selected)) _queueForEach(0, _apply_selected2, 0);
}
function _apply() {

View File

@ -9,7 +9,7 @@ function _hydrate_clickCount(clickCount = _readInOwner(4)) {
const _onclick = function () {
const clickCount = _readInOwner(4);
_queueInOwner(_apply_clickCount, 4, clickCount + 1);
_queueInOwner(_apply_clickCount, 0, clickCount + 1);
};
function _apply_clickCount2(clickCount = _readInOwner(4)) {
@ -24,7 +24,7 @@ function _apply_clickCount(clickCount) {
if (_write(4, clickCount)) {
_setConditionalRenderer(0, clickCount < 3 ? _if : null);
_queueInBranch(0, _if, _apply_clickCount2, 4);
_queueInBranch(0, _if, _apply_clickCount2, 0);
}
}

View File

@ -21,9 +21,9 @@ const _onclick = function () {
// TODO: nested writes ([...items, id++]) don't work
const nextId = id + 1;
_queue(_apply_id, 6, nextId);
_queue(_apply_id, 0, nextId);
_queue(_apply_items, 7, [...items, nextId]);
_queue(_apply_items, 1, [...items, nextId]);
};
function _applyWith_id_items(id = _read(6), items = _read(7)) {
@ -35,7 +35,7 @@ function _applyWith_id_items(id = _read(6), items = _read(7)) {
const _onclick2 = function () {
const items = _read(7);
_queue(_apply_items, 7, items.slice(0, -1));
_queue(_apply_items, 1, items.slice(0, -1));
};
function _apply_items(items) {
@ -46,12 +46,12 @@ function _apply_items(items) {
_hydrate_items();
_queue(_applyWith_id_items, 7);
_queue(_applyWith_id_items, 2);
}
}
function _apply_id(id) {
if (_write(6, id)) _queue(_applyWith_id_items, 6);
if (_write(6, id)) _queue(_applyWith_id_items, 2);
}
function _apply() {

View File

@ -9,7 +9,7 @@ function _hydrate_show(show = _read(5)) {
const _onclick = function () {
const show = _read(5);
_queue(_apply_show, 5, !show);
_queue(_apply_show, 0, !show);
};
function _apply_show(show) {

View File

@ -19,19 +19,19 @@ function _applyWith_a_b(a = _read(12), b = _read(13)) {
}
function _apply_y(y) {
if (_write(15, y)) _queue(_applyWith_x_y, 15);
if (_write(15, y)) _queue(_applyWith_x_y, 5);
}
function _apply_x(x) {
if (_write(14, x)) _queue(_applyWith_x_y, 14);
if (_write(14, x)) _queue(_applyWith_x_y, 5);
}
function _apply_b(b) {
if (_write(13, b)) _queue(_applyWith_a_b, 13);
if (_write(13, b)) _queue(_applyWith_a_b, 4);
}
function _apply_a(a) {
if (_write(12, a)) _queue(_applyWith_a_b, 12);
if (_write(12, a)) _queue(_applyWith_a_b, 4);
}
export const template = "<!><!><div><!></div>";

View File

@ -5,7 +5,7 @@ function _hydrateWith_x_y(x = _read(3), y = _read(4)) {
}
function _applyWith_x_y(x = _read(3), y = _read(4)) {
_write(5, _queue(_apply_x, 3, y = x + y));
_write(5, _queue(_apply_x, 0, y = x + y));
_hydrateWith_x_y();
}
@ -14,7 +14,7 @@ function _apply_y(y) {
if (_write(4, y)) {
_data(2, y);
_queue(_applyWith_x_y, 4);
_queue(_applyWith_x_y, 2);
}
}
@ -22,7 +22,7 @@ function _apply_x(x) {
if (_write(3, x)) {
_data(1, x);
_queue(_applyWith_x_y, 3);
_queue(_applyWith_x_y, 2);
}
}

View File

@ -1,7 +1,6 @@
import { types as t } from "@marko/compiler";
import { Tag, assertNoParams, assertNoVar } from "@marko/babel-utils";
import { exitBranch, queueBranchBuilder } from "./if";
import { setQueueBuilder } from "../../util/apply-hydrate";
import { exitBranch } from "./if";
export default {
translate: {
@ -35,8 +34,6 @@ export default {
);
}
}
setQueueBuilder(tag, queueBranchBuilder);
},
exit(tag) {
exitBranch(tag);

View File

@ -1,7 +1,6 @@
import type { types as t } from "@marko/compiler";
import { Tag, assertNoParams, assertNoVar } from "@marko/babel-utils";
import { setQueueBuilder } from "../../util/apply-hydrate";
import { exitBranch, queueBranchBuilder } from "./if";
import { exitBranch } from "./if";
export default {
translate: {
@ -30,8 +29,6 @@ export default {
);
}
}
setQueueBuilder(tag, queueBranchBuilder);
},
exit(tag) {
exitBranch(tag);

View File

@ -3,11 +3,7 @@ import { Tag, assertNoParams, assertNoVar } from "@marko/babel-utils";
import * as writer from "../../util/writer";
import * as walks from "../../util/walks";
import * as sorted from "../../util/sorted-arr";
import {
addStatement,
queueBuilder,
setQueueBuilder,
} from "../../util/apply-hydrate";
import { addStatement, setQueueBuilder } from "../../util/apply-hydrate";
import { callRuntime } from "../../util/runtime";
import { isCoreTagName } from "../../util/is-core-tag";
import toFirstStatementOrBlock from "../../util/to-first-statement-or-block";
@ -72,7 +68,6 @@ export default {
walks.visit(tag, walks.WalkCodes.Replace);
walks.enterShallow(tag);
setQueueBuilder(tag, queueBranchBuilder);
if (isOutputHTML()) {
writer.flushBefore(tag);
}
@ -99,21 +94,6 @@ const BRANCHES_LOOKUP = new WeakMap<
}[]
>();
export const queueBranchBuilder: queueBuilder = (
binding,
functionIdentifier,
targetSectionId
) => {
const renderer = writer.getRenderer(targetSectionId);
return callRuntime(
"queueInBranch",
t.numericLiteral(0),
renderer,
functionIdentifier,
t.numericLiteral(binding.id)
);
};
export function exitBranch(tag: t.NodePath<t.MarkoTag>) {
const bodySectionId = getSectionId(tag.get("body"));
const nextTag = tag.getNextSibling();
@ -121,12 +101,23 @@ export function exitBranch(tag: t.NodePath<t.MarkoTag>) {
isCoreTagName(nextTag, "else") || isCoreTagName(nextTag, "else-if")
);
const branches = BRANCHES_LOOKUP.get(tag) || [];
const reserve = tag.node.extra.reserve!;
branches.push({
tag,
sectionId: bodySectionId,
});
setQueueBuilder(tag, ({ identifier, queuePriority }) =>
callRuntime(
"queueInBranch",
t.numericLiteral(reserve.id),
writer.getRenderer(bodySectionId),
identifier,
queuePriority
)
);
if (isOutputHTML()) {
writer.flushInto(tag);
}

View File

@ -4,7 +4,7 @@ import { assertNoBodyContent } from "../util/assert";
import translateVar from "../util/translate-var";
import { isOutputDOM } from "../util/marko-config";
import { getSectionId } from "../util/sections";
import { addStatement, bindingToApplyId } from "../util/apply-hydrate";
import { addStatement, bindingToApplyGroup } from "../util/apply-hydrate";
export default {
translate(tag) {
@ -50,7 +50,8 @@ export default {
identifiers.length === 1
? t.expressionStatement(
t.callExpression(
bindingToApplyId(identifiers[0].extra.reserve!, sectionId),
bindingToApplyGroup(identifiers[0].extra.reserve!, sectionId)
.identifier,
[defaultAttr.value]
)
)
@ -61,7 +62,8 @@ export default {
...identifiers.map((identifier) =>
t.expressionStatement(
t.callExpression(
bindingToApplyId(identifier.extra.reserve!, sectionId),
bindingToApplyGroup(identifier.extra.reserve!, sectionId)
.identifier,
[t.identifier(identifier.name)]
)
)

View File

@ -5,8 +5,7 @@ import * as writer from "../util/writer";
import * as walks from "../util/walks";
import {
addStatement,
bindingToApplyId,
queueBuilder,
bindingToApplyGroup,
setQueueBuilder,
} from "../util/apply-hydrate";
import { getOrCreateSectionId, getSectionId } from "../util/sections";
@ -45,7 +44,6 @@ export default {
walks.visit(tag, walks.WalkCodes.Replace);
walks.enterShallow(tag);
setQueueBuilder(tag, queueEachBuilder);
if (isOutputHTML()) {
writer.flushBefore(tag);
}
@ -131,10 +129,20 @@ const translateDOM = {
const {
attributes,
body: { params },
extra: { reserve },
} = node;
const ofAttr = findName(attributes, "of");
const byAttr = findName(attributes, "by");
setQueueBuilder(tag, ({ identifier, queuePriority }) => {
return callRuntime(
"queueForEach",
t.numericLiteral(reserve!.id),
identifier,
queuePriority
);
});
if (ofAttr) {
const ofAttrValue = ofAttr.value!;
const [valParam] = params;
@ -163,11 +171,12 @@ const translateDOM = {
t.expressionStatement(
callRuntime(
"setLoopOf",
t.numericLiteral(node.extra.reserve!.id),
t.numericLiteral(reserve!.id),
ofAttrValue,
rendererId,
byAttr ? byAttr.value! : t.nullLiteral(),
bindingToApplyId(valParam.extra.reserve!, bodySectionId)
bindingToApplyGroup(valParam.extra.reserve!, bodySectionId)
.identifier
)
)
);
@ -175,15 +184,6 @@ const translateDOM = {
},
};
const queueEachBuilder: queueBuilder = (binding, functionIdentifier) => {
return callRuntime(
"queueForEach",
t.numericLiteral(0),
functionIdentifier,
t.numericLiteral(binding.id)
);
};
const translateHTML = {
exit(tag: t.NodePath<t.MarkoTag>) {
const { node } = tag;

View File

@ -3,7 +3,7 @@ import { Tag, assertNoParams } from "@marko/babel-utils";
import { assertNoBodyContent } from "../util/assert";
import translateVar from "../util/translate-var";
import { isOutputDOM } from "../util/marko-config";
import { addStatement, bindingToApplyId } from "../util/apply-hydrate";
import { addStatement, bindingToApplyGroup } from "../util/apply-hydrate";
import { callQueue } from "../util/runtime";
import replaceAssignments from "../util/replace-assignments";
import { getSectionId } from "../util/sections";
@ -50,7 +50,8 @@ export default {
if (isOutputDOM()) {
const sectionId = getSectionId(tag);
const binding = tagVar.extra.reserve!;
const applyId = bindingToApplyId(binding, sectionId);
const applyGroup = bindingToApplyGroup(binding, sectionId);
const applyId = applyGroup.identifier;
// TODO: add defined guard if bindings exist.
addStatement(
"apply",
@ -62,7 +63,7 @@ export default {
replaceAssignments(
tag.scope.getBinding(binding.name)!,
(assignment, value) =>
callQueue(applyId, binding, value, getSectionId(assignment))
callQueue(applyGroup, binding, value, getSectionId(assignment))
);
} else {
translateVar(tag, defaultAttr.value);

View File

@ -10,17 +10,14 @@ import * as sorted from "../util/sorted-arr";
import { currentProgramPath } from "../visitors/program";
import { callRuntime, callRead } from "./runtime";
interface ReferenceGroup {
export interface ReferenceGroup {
identifier: t.Identifier;
references: References;
statements: t.Statement[];
queuePriority: t.NumericLiteral;
}
export type queueBuilder = (
binding: Reserve,
functionIdentifier: t.Identifier,
targetSectionId: number
) => t.Expression;
export type queueBuilder = (group: ReferenceGroup) => t.Expression;
const [getApply] = createSectionState<ReferenceGroup[]>("apply", () => []);
const [getHydrate] = createSectionState<ReferenceGroup[]>("hydrate", () => []);
@ -56,12 +53,12 @@ export function addStatement(
return isNew ? 1 : 0;
}
export function bindingToApplyId(binding: Reserve, sectionId: number) {
export function bindingToApplyGroup(binding: Reserve, sectionId: number) {
const applyGroups = getApply(sectionId);
const group =
getGroupByReferences(applyGroups, binding) ??
createAndInsertGroup("apply", applyGroups, binding);
return group.identifier;
return group;
}
function createAndInsertGroup(
@ -74,6 +71,7 @@ function createAndInsertGroup(
identifier,
references,
statements: [],
queuePriority: t.numericLiteral(NaN),
};
sorted.insert(compareReferenceGroups, groups, group);
return group;
@ -98,8 +96,11 @@ export function writeAllStatementGroups() {
export function writeApplyGroups(sectionId: number) {
const groups = getApply(sectionId);
if (!groups.length) return;
for (let i = groups.length; i--; ) {
const { identifier, references, statements } = groups[i];
const group = groups[i];
const { identifier, references, statements, queuePriority } = group;
let params: (t.Identifier | t.RestElement | t.Pattern)[];
let body: t.BlockStatement;
@ -120,7 +121,7 @@ export function writeApplyGroups(sectionId: number) {
binding,
t.expressionStatement(
// TODO: might need to queue in a child scope
callRuntime("queue", identifier, t.numericLiteral(binding.id))
callRuntime("queue", identifier, queuePriority)
)
);
}
@ -139,7 +140,7 @@ export function writeApplyGroups(sectionId: number) {
"apply",
references.sectionId,
references,
t.expressionStatement(factory(references, identifier, sectionId))
t.expressionStatement(factory(group))
);
}
} else {
@ -169,6 +170,11 @@ export function writeApplyGroups(sectionId: number) {
result.traverse(bindFunctionsVisitor, { root: result, sectionId });
}
}
const offset = groups[0].references ? 0 : 1;
for (let i = offset; i < groups.length; i++) {
groups[i].queuePriority.value = i - offset;
}
}
export function writeHydrateGroups(sectionId: number) {

View File

@ -3,6 +3,7 @@ import { importNamed } from "@marko/babel-utils";
import { getMarkoOpts } from "./marko-config";
import type { Reserve } from "./reserve";
import { currentProgramPath } from "../visitors/program";
import type { ReferenceGroup } from "./apply-hydrate";
export function importRuntime(name: string) {
const { output } = getMarkoOpts();
@ -55,7 +56,7 @@ export function callRead(reference: Reserve, targetSectionId: number) {
}
export function callQueue(
fnIdentifier: t.Identifier,
{ identifier, queuePriority }: ReferenceGroup,
reference: Reserve,
value: t.Expression,
targetSectionId: number
@ -63,24 +64,14 @@ export function callQueue(
const diff = getScopeDepthDifference(reference, targetSectionId);
switch (diff) {
case 0:
return callRuntime(
"queue",
fnIdentifier,
t.numericLiteral(reference.id),
value
);
return callRuntime("queue", identifier, queuePriority, value);
case 1:
return callRuntime(
"queueInOwner",
fnIdentifier,
t.numericLiteral(reference.id),
value
);
return callRuntime("queueInOwner", identifier, queuePriority, value);
default:
return callRuntime(
"queueInOwner",
fnIdentifier,
t.numericLiteral(reference.id),
identifier,
queuePriority,
value,
t.numericLiteral(diff)
);