@samitouri / QOS-React-2 / commits / 1c6e39a1d6

[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.