[hir] Introduce AbstractState.read to lookup value

Split AbstractState.alias into two separate operations for better readability.
This commit is contained in:
Sathya Gunasekaran
2022-12-05 22:26:59 +00:00
parent 7bdd0f03cb
commit 1c6e39a1d6
+36 -34
View File
@@ -17,58 +17,47 @@ class AbstractState {
aliases = new DisjointSet<Identifier>();
#values = new Map<Identifier, AbstractValue>();
// Simple lvalue:
// lvalue = alias;
// lvalue = alias.memberPath;
alias(lvalue: LValue, alias: Place) {
read(alias: Place): AbstractValue {
// Simple alias:
// lvalue = alias;
// read(alias);
if (alias.memberPath === null) {
let value = this.#values.get(alias.identifier);
// Don't know what this, let's default to an Object conservatively.
// Don't know what this is, let's default to an Object conservatively.
if (value === undefined) {
value = { kind: "Object", values: new Map() };
}
this.#values.set(lvalue.place.identifier, value);
// No need to alias Primitives
if (value.kind !== "Primitive") {
this.aliases.union([lvalue.place.identifier, alias.identifier]);
}
return;
this.#values.set(alias.identifier, value);
return value;
}
// Complex alias:
// lvalue = alias.memberPath;
if (alias.memberPath.length > 1) {
// TODO(gsn): Handle nested member paths
return;
}
// read(alias.memberPath);
let object = this.#values.get(alias.identifier);
// Don't know what this, let's default to an Object conservatively.
// Don't know what this is, let's default to an Object conservatively.
if (object === undefined) {
object = { kind: "Object", values: new Map() };
this.#values.set(alias.identifier, object);
}
// We're doing a member lookup on a non object.
//
// alias = 1;
// lvalue = alias.memberPath;
// read(alias.memberPath);
if (object.kind !== "Object") {
// Update alias to be an object
object = { kind: "Object", values: new Map() };
this.#values.set(alias.identifier, object);
// Conservatively type the value as object.
//
// NOTE(gsn): Should this be an AbstractUnknown rather than an
// AbstractObject?
this.#values.set(lvalue.place.identifier, {
kind: "Object",
values: new Map(),
});
this.aliases.union([lvalue.place.identifier, alias.identifier]);
return;
let value: AbstractObject = { kind: "Object", values: new Map() };
object.values.set(alias.memberPath[0], value);
return value;
}
let value = object.values.get(alias.memberPath[0]);
@@ -76,21 +65,34 @@ class AbstractState {
// We don't have a value for this member path.
//
// alias = {};
// lvalue = alias.memberPath;
// read(alias.memberPath);
if (value === undefined) {
// Conservatively type the value as object.
this.#values.set(lvalue.place.identifier, {
value = {
kind: "Object",
values: new Map(),
});
this.aliases.union([lvalue.place.identifier, alias.identifier]);
return;
};
object.values.set(alias.memberPath[0], value);
return value;
}
// We have a value for this memberPath!
//
// alias.memberPath = value;
// lvalue = alias.memberPath;
// alias.memberPath = value;
// read(alias.memberPath);
return value;
}
// Simple lvalue:
// lvalue = alias;
// lvalue = alias.memberPath;
alias(lvalue: LValue, alias: Place) {
if (alias.memberPath !== null && alias.memberPath.length > 1) {
// TODO(gsn): Handle nested member paths
return;
}
const value = this.read(alias);
this.#values.set(lvalue.place.identifier, value);
// No need to alias Primitives.