mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
Save the receiver and key locals of a literal-union keyed write
This commit is contained in:
@@ -2610,14 +2610,14 @@ export function lowerElementWrite(lowerer: Lowerer, expr: ts.BinaryExpression):
|
||||
// A key whose literal type names only declared fields of one type
|
||||
// writes the field it names. JavaScript evaluates the receiver, then
|
||||
// the key, then the value; the dispatch reads the saved receiver and
|
||||
// key once per named field.
|
||||
// key once per named field. Locals are saved too, because the key or
|
||||
// the value can reassign them.
|
||||
const named =
|
||||
litKey === null ? sameTypedFieldKeys(lowerer, shape, target.argumentExpression) : null;
|
||||
if (named && !shape.fields.every((f) => typeEquals(f.type, named.fieldType))) {
|
||||
const loc = locOf(expr);
|
||||
const body: IrStmt[] = [];
|
||||
const save = (value: IrExpr, name: string): IrExpr => {
|
||||
if (value.kind === "varRef") return value;
|
||||
const temp = lowerer.declareHiddenLocal(name, value.type);
|
||||
body.push({ kind: "varDecl", localId: temp.id, init: value, loc });
|
||||
return varRef(temp.id, temp.type, loc);
|
||||
|
||||
@@ -76,3 +76,23 @@ function only(s: Stats, key: "bytes"): number {
|
||||
return s[key];
|
||||
}
|
||||
console.log(only(stats[3]!, "bytes"));
|
||||
|
||||
// A key or value that reassigns the receiver or key local: the write goes
|
||||
// to the receiver and key evaluated before them.
|
||||
let target = stats[0]!;
|
||||
let slot: Counter = "hits";
|
||||
target[slot] = ((slot = "misses"), 500);
|
||||
console.log(stats[0]!.hits, stats[0]!.misses, slot);
|
||||
target[slot] = ((target = stats[2]!), 600);
|
||||
console.log(stats[0]!.misses, stats[2]!.misses, target === stats[2]);
|
||||
function retarget(): Counter {
|
||||
target = stats[3]!;
|
||||
return "bytes";
|
||||
}
|
||||
target = stats[1]!;
|
||||
target[retarget()] = 700;
|
||||
console.log(stats[1]!.bytes, stats[3]!.bytes === 700);
|
||||
target = stats[0]!;
|
||||
slot = "hits";
|
||||
target[slot] += ((slot = "bytes"), (target = stats[1]!), 1);
|
||||
console.log(stats[0]!.hits, stats[0]!.bytes, stats[1]!.hits);
|
||||
|
||||
Reference in New Issue
Block a user