[hir] Introduce AbstractState.read to lookup value
Split AbstractState.alias into two separate operations for better readability.
Sathya Gunasekaran committed
Dec 5, 2022 at 22:26 UTC
1c6e39a1d6e04a7fc167fc2c57f5ff115e4d63ab
1 file changed
+36
-34
compiler/forget/src/HIR/BuildAliasSets.ts
+36
-34
@@ -17,58 +17,47 @@ class AbstractState {
17
aliases = new DisjointSet<Identifier>();
18
#values = new Map<Identifier, AbstractValue>();
19
20
- // Simple lvalue:
21
- // lvalue = alias;
22
- // lvalue = alias.memberPath;
23
- alias(lvalue: LValue, alias: Place) {
20
+ read(alias: Place): AbstractValue {
21
// Simple alias:
25
- // lvalue = alias;
22
+ // read(alias);
23
if (alias.memberPath === null) {
24
let value = this.#values.get(alias.identifier);
25
29
- // Don't know what this, let's default to an Object conservatively.
26
+ // Don't know what this is, let's default to an Object conservatively.
27
if (value === undefined) {
28
value = { kind: "Object", values: new Map() };
29
}
30
34
- this.#values.set(lvalue.place.identifier, value);
35
-
36
- // No need to alias Primitives
37
- if (value.kind !== "Primitive") {
38
- this.aliases.union([lvalue.place.identifier, alias.identifier]);
39
- }
40
- return;
31
+ this.#values.set(alias.identifier, value);
32
+ return value;
33
}
34
35
// Complex alias:
44
- // lvalue = alias.memberPath;
45
- if (alias.memberPath.length > 1) {
46
- // TODO(gsn): Handle nested member paths
47
- return;
48
- }
49
-
36
+ // read(alias.memberPath);
37
let object = this.#values.get(alias.identifier);
38
52
- // Don't know what this, let's default to an Object conservatively.
39
+ // Don't know what this is, let's default to an Object conservatively.
40
if (object === undefined) {
41
object = { kind: "Object", values: new Map() };
42
+ this.#values.set(alias.identifier, object);
43
}
44
45
// We're doing a member lookup on a non object.
46
//
47
// alias = 1;
60
- // lvalue = alias.memberPath;
48
+ // read(alias.memberPath);
49
if (object.kind !== "Object") {
50
+ // Update alias to be an object
51
+ object = { kind: "Object", values: new Map() };
52
+ this.#values.set(alias.identifier, object);
53
+
54
// Conservatively type the value as object.
55
//
56
// NOTE(gsn): Should this be an AbstractUnknown rather than an
57
// AbstractObject?
66
- this.#values.set(lvalue.place.identifier, {
67
- kind: "Object",
68
- values: new Map(),
69
- });
70
- this.aliases.union([lvalue.place.identifier, alias.identifier]);
71
- return;
58
+ let value: AbstractObject = { kind: "Object", values: new Map() };
59
+ object.values.set(alias.memberPath[0], value);
60
+ return value;
61
}
62
63
let value = object.values.get(alias.memberPath[0]);
@@ -76,21 +65,34 @@ class AbstractState {
65
// We don't have a value for this member path.
66
//
67
// alias = {};
79
- // lvalue = alias.memberPath;
68
+ // read(alias.memberPath);
69
if (value === undefined) {
70
// Conservatively type the value as object.
82
- this.#values.set(lvalue.place.identifier, {
71
+ value = {
72
kind: "Object",
73
values: new Map(),
85
- });
86
- this.aliases.union([lvalue.place.identifier, alias.identifier]);
87
- return;
74
+ };
75
+ object.values.set(alias.memberPath[0], value);
76
+ return value;
77
}
78
79
// We have a value for this memberPath!
80
//
92
- // alias.memberPath = value;
93
- // lvalue = alias.memberPath;
81
+ // alias.memberPath = value;
82
+ // read(alias.memberPath);
83
+ return value;
84
+ }
85
+
86
+ // Simple lvalue:
87
+ // lvalue = alias;
88
+ // lvalue = alias.memberPath;
89
+ alias(lvalue: LValue, alias: Place) {
90
+ if (alias.memberPath !== null && alias.memberPath.length > 1) {
91
+ // TODO(gsn): Handle nested member paths
92
+ return;
93
+ }
94
+
95
+ const value = this.read(alias);
96
this.#values.set(lvalue.place.identifier, value);
97
98
// No need to alias Primitives.