mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Foundation for IndexStore/IndexLoad (no lowering)
Adds new types for IndexLoad/IndexStore (renamed later in the stack to ComputedLoad/ComputedStore) which will be used to represent computed property access/update. The actual lowering to use these is later in the stack.
This commit is contained in:
@@ -473,6 +473,26 @@ export function codegenInstructionValue(
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "IndexStore": {
|
||||
value = t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(
|
||||
codegenPlace(temp, instrValue.object),
|
||||
codegenPlace(temp, instrValue.property),
|
||||
true
|
||||
),
|
||||
codegenPlace(temp, instrValue.value)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "IndexLoad": {
|
||||
value = t.memberExpression(
|
||||
codegenPlace(temp, instrValue.object),
|
||||
codegenPlace(temp, instrValue.property),
|
||||
true
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "Identifier": {
|
||||
value = codegenPlace(temp, instrValue);
|
||||
break;
|
||||
|
||||
@@ -298,6 +298,11 @@ export type InstructionData =
|
||||
// load `object.property`
|
||||
| { kind: "PropertyLoad"; object: Place; property: string }
|
||||
|
||||
// store `object[index] = value` - like PropertyStore but with a dynamic property
|
||||
| { kind: "IndexStore"; object: Place; property: Place; value: Place }
|
||||
// load `object[index]` - like PropertyLoad but with a dynamic property
|
||||
| { kind: "IndexLoad"; object: Place; property: Place }
|
||||
|
||||
/**
|
||||
* Catch-all for statements such as type imports, nested class declarations, etc
|
||||
* which are not directly represented, but included for completeness and to allow
|
||||
|
||||
@@ -607,6 +607,42 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case "IndexStore": {
|
||||
const effect = isObjectType(instrValue.object.identifier)
|
||||
? Effect.Store
|
||||
: Effect.Mutate;
|
||||
env.reference(instrValue.value, Effect.Read);
|
||||
env.reference(instrValue.property, Effect.Read);
|
||||
env.reference(instrValue.object, effect);
|
||||
|
||||
const lvalue = instr.lvalue;
|
||||
if (lvalue !== null) {
|
||||
env.alias(lvalue.place, instrValue.value);
|
||||
lvalue.place.effect = Effect.Store;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case "IndexLoad": {
|
||||
if (!env.isDefined(instrValue.object)) {
|
||||
// TODO @josephsavona: improve handling of globals
|
||||
const value: InstructionValue = {
|
||||
kind: "Primitive",
|
||||
loc: instrValue.loc,
|
||||
value: undefined,
|
||||
};
|
||||
env.initialize(value, ValueKind.Frozen);
|
||||
env.define(instrValue.object, value);
|
||||
}
|
||||
|
||||
env.reference(instrValue.object, Effect.Read);
|
||||
env.reference(instrValue.property, Effect.Read);
|
||||
const lvalue = instr.lvalue;
|
||||
if (lvalue !== null) {
|
||||
env.initialize(instrValue, env.kind(instrValue.object));
|
||||
env.define(lvalue.place, instrValue);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case "Identifier": {
|
||||
env.reference(instrValue, Effect.Read);
|
||||
const lvalue = instr.lvalue;
|
||||
|
||||
@@ -277,6 +277,18 @@ export function printInstructionValue(instrValue: InstructionValue): string {
|
||||
} = ${printPlace(instrValue.value)}`;
|
||||
break;
|
||||
}
|
||||
case "IndexLoad": {
|
||||
value = `IndexLoad ${printPlace(instrValue.object)}[${printPlace(
|
||||
instrValue.property
|
||||
)}]`;
|
||||
break;
|
||||
}
|
||||
case "IndexStore": {
|
||||
value = `IndexStore ${printPlace(instrValue.object)}[${printPlace(
|
||||
instrValue.property
|
||||
)}] = ${printPlace(instrValue.value)}`;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assertExhaustive(
|
||||
instrValue,
|
||||
|
||||
@@ -50,6 +50,17 @@ export function* eachInstructionValueOperand(
|
||||
yield instrValue.value;
|
||||
break;
|
||||
}
|
||||
case "IndexLoad": {
|
||||
yield instrValue.object;
|
||||
yield instrValue.property;
|
||||
break;
|
||||
}
|
||||
case "IndexStore": {
|
||||
yield instrValue.object;
|
||||
yield instrValue.property;
|
||||
yield instrValue.value;
|
||||
break;
|
||||
}
|
||||
case "UnaryExpression": {
|
||||
yield instrValue.value;
|
||||
break;
|
||||
@@ -110,6 +121,17 @@ export function mapInstructionOperands(
|
||||
instrValue.value = fn(instrValue.value);
|
||||
break;
|
||||
}
|
||||
case "IndexLoad": {
|
||||
instrValue.object = fn(instrValue.object);
|
||||
instrValue.property = fn(instrValue.property);
|
||||
break;
|
||||
}
|
||||
case "IndexStore": {
|
||||
instrValue.object = fn(instrValue.object);
|
||||
instrValue.property = fn(instrValue.property);
|
||||
instrValue.value = fn(instrValue.value);
|
||||
break;
|
||||
}
|
||||
case "Identifier": {
|
||||
instr.value = fn(instrValue);
|
||||
break;
|
||||
|
||||
@@ -161,11 +161,13 @@ function mayAllocate(value: InstructionValue): boolean {
|
||||
case "BinaryExpression":
|
||||
case "Identifier":
|
||||
case "PropertyLoad":
|
||||
case "IndexLoad":
|
||||
case "JSXText":
|
||||
case "Primitive": {
|
||||
return false;
|
||||
}
|
||||
case "PropertyStore":
|
||||
case "IndexStore":
|
||||
case "ArrayExpression":
|
||||
case "CallExpression":
|
||||
case "JsxExpression":
|
||||
|
||||
@@ -302,6 +302,8 @@ function valueKind(value: InstructionValue): DeclKind {
|
||||
case "Primitive": {
|
||||
return DeclKind.Const;
|
||||
}
|
||||
case "IndexLoad":
|
||||
case "IndexStore":
|
||||
case "PropertyStore":
|
||||
case "PropertyLoad":
|
||||
case "Identifier":
|
||||
|
||||
Reference in New Issue
Block a user