[wip][typer] Infer Array instance properties
--- TODO: add inference for TypedFunction to `InferReferenceEffects`
Mofei Zhang committed
Mar 21, 2023 at 14:57 UTC
ec345ca538704b25c66879025528e3b0dd1f96a2
13 files changed
+252
-90
compiler/forget/src/HIR/ObjectShape.ts
new
+134
@@ -0,0 +1,134 @@
1
+/**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+import invariant from "invariant";
8
+import { Effect } from "./HIR";
9
+import { BuiltInType, FunctionType, PrimitiveType } from "./Types";
10
+
11
+const PRIMITIVE_TYPE: PrimitiveType = {
12
+ kind: "Primitive",
13
+};
14
+
15
+let nextAnonId = 0;
16
+// use strings since they are easily debuggable, even though `Symbol()`
17
+// might be more performant
18
+function createAnonId(): string {
19
+ return `<generated_${nextAnonId++}>`;
20
+}
21
+
22
+function addFunction(
23
+ registry: ShapeRegistry,
24
+ properties: Iterable<[string, BuiltInType | null]>,
25
+ fn: FunctionSignature
26
+): FunctionType {
27
+ const shapeId = createAnonId();
28
+ addShape(registry, shapeId, properties, fn);
29
+ return {
30
+ kind: "Function",
31
+ shapeId,
32
+ };
33
+}
34
+
35
+function addShape(
36
+ registry: ShapeRegistry,
37
+ id: string,
38
+ properties: Iterable<[string, BuiltInType | null]>,
39
+ functionType?: FunctionSignature
40
+): ObjectShape {
41
+ const shape: ObjectShape = {
42
+ properties: new Map(properties),
43
+ functionType: functionType ?? null,
44
+ };
45
+
46
+ invariant(
47
+ !registry.has(id),
48
+ `[ObjectShape] Could not add shape to registry: name ${id} already exists.`
49
+ );
50
+ registry.set(id, shape);
51
+ return shape;
52
+}
53
+
54
+// Param type not recorded since it currently does not affect inference.
55
+// Specifically, we currently do not:
56
+// - infer types based on their usage in argument position
57
+// - handle inference for overloaded / generic functions
58
+export type FunctionSignature = {
59
+ positionalParams: Array<Effect>;
60
+ restParam: Effect | null;
61
+ returnType: BuiltInType | null;
62
+ calleeEffect: Effect;
63
+};
64
+
65
+export type ObjectShape = {
66
+ properties: Map<string, BuiltInType | null>;
67
+ functionType: FunctionSignature | null;
68
+};
69
+
70
+export type ShapeRegistry = Map<string, ObjectShape>;
71
+
72
+/**
73
+ * Shapes of built-in types
74
+ */
75
+
76
+// The only "entrypoints" should be Globals and recursive lookups from properties / functions
77
+export const BUILTIN_SHAPES: ShapeRegistry = new Map();
78
+export const ArrayShapeId = "Array";
79
+export const ObjectShapeId = "Object";
80
+
81
+/* Built-in array shape */
82
+addShape(BUILTIN_SHAPES, ArrayShapeId, [
83
+ [
84
+ "at",
85
+ addFunction(BUILTIN_SHAPES, [], {
86
+ positionalParams: [Effect.Read],
87
+ restParam: null,
88
+ returnType: null,
89
+ calleeEffect: Effect.Capture,
90
+ }),
91
+ ],
92
+ [
93
+ "concat",
94
+ addFunction(BUILTIN_SHAPES, [], {
95
+ positionalParams: [],
96
+ restParam: Effect.Capture,
97
+ returnType: {
98
+ kind: "Object",
99
+ shapeId: ArrayShapeId,
100
+ },
101
+ calleeEffect: Effect.Capture,
102
+ }),
103
+ ],
104
+ ["length", PRIMITIVE_TYPE],
105
+ [
106
+ "push",
107
+ addFunction(BUILTIN_SHAPES, [], {
108
+ positionalParams: [],
109
+ restParam: Effect.Capture,
110
+ returnType: {
111
+ kind: "Primitive",
112
+ },
113
+ calleeEffect: Effect.Store,
114
+ }),
115
+ ],
116
+ // TODO: rest of Array properties
117
+]);
118
+
119
+/* Built-in Object shape */
120
+addShape(BUILTIN_SHAPES, ObjectShapeId, [
121
+ [
122
+ "toString",
123
+ addFunction(BUILTIN_SHAPES, [], {
124
+ positionalParams: [],
125
+ restParam: null,
126
+ returnType: {
127
+ kind: "Primitive",
128
+ },
129
+ calleeEffect: Effect.Read,
130
+ }),
131
+ ],
132
+ // TODO:
133
+ // hasOwnProperty, isPrototypeOf, propertyIsEnumerable, toLocaleString, valueOf
134
+]);
compiler/forget/src/HIR/PrintHIR.ts
+8
-1
@@ -566,7 +566,14 @@ function printScope(scope: ReactiveScope | null): string {
566
567
function printType(type: Type): string {
568
if (type.kind === "Type") return "";
569
- return `:T${type.kind}`;
569
+ // TODO(mofeiZ): add debugName for generated ids
570
+ if (type.kind === "Object" && type.shapeId != null) {
571
+ return `:T${type.kind}<${type.shapeId}>`;
572
+ } else if (type.kind === "Function" && type.shapeId != null) {
573
+ return `:T${type.kind}<${type.shapeId}>`;
574
+ } else {
575
+ return `:T${type.kind}`;
576
+ }
577
}
578
579
export function printSourceLocation(loc: SourceLocation): string {
compiler/forget/src/HIR/Types.ts
+25
-12
@@ -7,23 +7,36 @@
7
import invariant from "invariant";
8
import { Hook } from "./Hooks";
9
10
-export type Type =
11
- | PrimitiveType
12
- | HookType
13
- | FunctionType
14
- | ObjectType
15
- | PhiType
16
- | PolyType
17
- | TypeVar;
10
+export type BuiltInType = PrimitiveType | FunctionType | ObjectType;
11
+
12
+export type Type = BuiltInType | HookType | PhiType | PolyType | TypeVar;
13
export type PrimitiveType = { kind: "Primitive" };
19
-export type FunctionType = {
20
- kind: "Function";
21
-};
14
export type HookType = {
15
kind: "Hook";
16
definition: Hook;
17
};
26
-export type ObjectType = { kind: "Object" };
18
+
19
+/**
20
+ * An {@link FunctionType} or {@link ObjectType} (also a JS object) may be associated with an
21
+ * inferred "object shape", i.e. a known property (key -> Type) map. This is
22
+ * subtly different from JS language semantics - `shape` represents both
23
+ * OwnPropertyDescriptors and properties present in the prototype chain.
24
+ *
25
+ * In addition, a {@link FunctionType} may be associated with an inferred signature,
26
+ *
27
+ * If `shapeId` is present, it is a key into the global ShapeRegistry.
28
+ */
29
+
30
+export type FunctionType = {
31
+ kind: "Function";
32
+ shapeId: string | null;
33
+};
34
+
35
+export type ObjectType = {
36
+ kind: "Object";
37
+ shapeId: string | null;
38
+};
39
+
40
export type TypeVar = {
41
kind: "Type";
42
id: TypeId;
compiler/forget/src/TypeInference/InferTypes.ts
+10
-2
@@ -9,6 +9,7 @@ import {
9
TypeId,
10
TypeVar,
11
} from "../HIR/HIR";
12
+import { ArrayShapeId, ObjectShapeId } from "../HIR/ObjectShape";
13
import { eachInstructionLValue, eachInstructionOperand } from "../HIR/visitors";
14
15
function isPrimitiveBinaryOp(op: t.BinaryExpression["operator"]): boolean {
@@ -150,7 +151,7 @@ function* generateInstructionTypes(
151
if (hook !== null) {
152
type = { kind: "Hook", definition: hook };
153
} else {
153
- type = { kind: "Function" };
154
+ type = { kind: "Function", shapeId: null };
155
}
156
yield equation(value.callee.identifier.type, type);
157
break;
@@ -158,7 +159,14 @@ function* generateInstructionTypes(
159
160
case "ObjectExpression": {
161
invariant(left !== null, "invald object expression");
161
- yield equation(left, { kind: "Object" });
162
+ yield equation(left, { kind: "Object", shapeId: ObjectShapeId });
163
+ break;
164
+ }
165
+
166
+ case "ArrayExpression": {
167
+ if (left) {
168
+ yield equation(left, { kind: "Object", shapeId: ArrayShapeId });
169
+ }
170
break;
171
}
172
}
compiler/forget/src/__tests__/fixtures/hir/simple-array.expect.md
+2
-2
@@ -25,7 +25,7 @@ bb0 (block):
25
[9] store $27 = StoreLocal Const mutate y$26 = capture $25
26
[10] mutate $28:TPrimitive = LoadLocal read x$21:TPrimitive
27
[11] mutate $29 = LoadLocal capture y$26
28
- [12] store $30 = Array [read $28:TPrimitive, capture $29]
29
- [13] Return freeze $30
28
+ [12] store $30:TObject<Array> = Array [read $28:TPrimitive, capture $29]
29
+ [13] Return freeze $30:TObject<Array>
30
```
31
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/simple-object.expect.md
+2
-2
@@ -25,7 +25,7 @@ bb0 (block):
25
[9] store $27 = StoreLocal Const mutate y$26 = capture $25
26
[10] mutate $28:TPrimitive = LoadLocal read x$21:TPrimitive
27
[11] mutate $29 = LoadLocal capture y$26
28
- [12] store $30:TObject = Object { x: read $28:TPrimitive, y: capture $29 }
29
- [13] Return freeze $30:TObject
28
+ [12] store $30:TObject<Object> = Object { x: read $28:TPrimitive, y: capture $29 }
29
+ [13] Return freeze $30:TObject<Object>
30
```
31
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction-with-mutation.expect.md
+7
-7
@@ -19,12 +19,12 @@ function foo(props) {
19
20
```javascript
21
bb0 (block):
22
- [1] store $35[1:33] = Array []
23
- [2] store $37[2:33] = StoreLocal Let mutate x$36[2:33] = capture $35[1:33]
24
- [3] mutate $38[3:33] = LoadLocal capture x$36[2:33]
22
+ [1] store $35[1:33]:TObject<Array> = Array []
23
+ [2] store $37[2:33]:TObject<Array> = StoreLocal Let store x$36[2:33]:TObject<Array> = capture $35[1:33]:TObject<Array>
24
+ [3] mutate $38[3:33]:TObject<Array> = LoadLocal capture x$36[2:33]:TObject<Array>
25
[4] mutate $39 = LoadLocal read props$34
26
[5] mutate $40 = PropertyLoad read $39.bar
27
- [6] mutate $41 = PropertyCall mutate $38[3:33].push(read $40)
27
+ [6] mutate $41 = PropertyCall mutate $38[3:33]:TObject<Array>.push(read $40)
28
[7] Ternary test:bb2 fallthrough=bb1
29
bb2 (value):
30
predecessor blocks: bb0
@@ -33,9 +33,9 @@ bb2 (value):
33
[10] Branch (read $43) then:bb3 else:bb4
34
bb3 (value):
35
predecessor blocks: bb2
36
- [14] store $48[14:33] = Array []
37
- [15] store $49[15:33] = Array [capture $48[14:33]]
38
- [16] store $51[16:33] = Destructure Reassign [ mutate x$36[16:33] ] = capture $49[15:33]
36
+ [14] store $48[14:33]:TObject<Array> = Array []
37
+ [15] store $49[15:33]:TObject<Array> = Array [capture $48[14:33]:TObject<Array>]
38
+ [16] store $51[16:33] = Destructure Reassign [ mutate x$36[16:33] ] = capture $49[15:33]:TObject<Array>
39
[17] mutate $52[17:33] = LoadLocal capture x$36[16:33]
40
[18] mutate $53 = LoadLocal read props$34
41
[19] mutate $54 = PropertyLoad read $53.foo
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction.expect.md
+7
-7
@@ -18,12 +18,12 @@ function foo(props) {
18
19
```javascript
20
bb0 (block):
21
- [1] store $32[1:7] = Array []
22
- [2] store $34[2:7] = StoreLocal Let mutate x$33[2:7] = capture $32[1:7]
23
- [3] mutate $35[3:7] = LoadLocal capture x$33[2:7]
21
+ [1] store $32[1:7]:TObject<Array> = Array []
22
+ [2] store $34[2:7]:TObject<Array> = StoreLocal Let store x$33[2:7]:TObject<Array> = capture $32[1:7]:TObject<Array>
23
+ [3] mutate $35[3:7]:TObject<Array> = LoadLocal capture x$33[2:7]:TObject<Array>
24
[4] mutate $36 = LoadLocal read props$31
25
[5] mutate $37 = PropertyLoad read $36.bar
26
- [6] mutate $38 = PropertyCall mutate $35[3:7].push(read $37)
26
+ [6] mutate $38 = PropertyCall mutate $35[3:7]:TObject<Array>.push(read $37)
27
[7] Ternary test:bb2 fallthrough=bb1
28
bb2 (value):
29
predecessor blocks: bb0
@@ -32,9 +32,9 @@ bb2 (value):
32
[10] Branch (read $40) then:bb3 else:bb4
33
bb3 (value):
34
predecessor blocks: bb2
35
- [14] store $45[14:21] = Array []
36
- [15] store $46[15:21] = Array [capture $45[14:21]]
37
- [16] store $48[16:21] = Destructure Reassign [ mutate x$33[16:21] ] = capture $46[15:21]
35
+ [14] store $45[14:21]:TObject<Array> = Array []
36
+ [15] store $46[15:21]:TObject<Array> = Array [capture $45[14:21]:TObject<Array>]
37
+ [16] store $48[16:21] = Destructure Reassign [ mutate x$33[16:21] ] = capture $46[15:21]:TObject<Array>
38
[17] mutate $49[17:21] = LoadLocal capture x$33[16:21]
39
[18] mutate $50 = LoadLocal read props$31
40
[19] mutate $51 = PropertyLoad read $50.foo
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-with-mutation.expect.md
+9
-9
@@ -17,12 +17,12 @@ function foo(props) {
17
18
```javascript
19
bb0 (block):
20
- [1] store $33[1:31] = Array []
21
- [2] store $35[2:31] = StoreLocal Let mutate x$34[2:31] = capture $33[1:31]
22
- [3] mutate $36[3:31] = LoadLocal capture x$34[2:31]
20
+ [1] store $33[1:31]:TObject<Array> = Array []
21
+ [2] store $35[2:31]:TObject<Array> = StoreLocal Let store x$34[2:31]:TObject<Array> = capture $33[1:31]:TObject<Array>
22
+ [3] mutate $36[3:31]:TObject<Array> = LoadLocal capture x$34[2:31]:TObject<Array>
23
[4] mutate $37 = LoadLocal read props$32
24
[5] mutate $38 = PropertyLoad read $37.bar
25
- [6] mutate $39 = PropertyCall mutate $36[3:31].push(read $38)
25
+ [6] mutate $39 = PropertyCall mutate $36[3:31]:TObject<Array>.push(read $38)
26
[7] Ternary test:bb2 fallthrough=bb1
27
bb2 (value):
28
predecessor blocks: bb0
@@ -31,12 +31,12 @@ bb2 (value):
31
[10] Branch (read $41) then:bb3 else:bb4
32
bb3 (value):
33
predecessor blocks: bb2
34
- [13] store $45[13:31] = Array []
35
- [14] store $47[14:31] = StoreLocal Reassign mutate x$34[14:31] = capture $45[13:31]
36
- [15] mutate $48[15:31] = LoadLocal capture x$34[14:31]
34
+ [13] store $45[13:31]:TObject<Array> = Array []
35
+ [14] store $47[14:31]:TObject<Array> = StoreLocal Reassign store x$34[14:31]:TObject<Array> = capture $45[13:31]:TObject<Array>
36
+ [15] mutate $48[15:31]:TObject<Array> = LoadLocal capture x$34[14:31]:TObject<Array>
37
[16] mutate $49 = LoadLocal read props$32
38
[17] mutate $50 = PropertyLoad read $49.foo
39
- [18] mutate $51[18:28] = PropertyCall mutate $48[15:31].push(read $50)
39
+ [18] mutate $51[18:28] = PropertyCall mutate $48[15:31]:TObject<Array>.push(read $50)
40
[19] store $53[19:28] = StoreLocal Const mutate $52[7:28] = capture $51[18:28]
41
[20] Goto bb1
42
bb4 (value):
@@ -47,7 +47,7 @@ bb4 (value):
47
bb1 (block):
48
predecessor blocks: bb3 bb4
49
$59[7:28]:TPhi: phi(bb3: $52, bb4: $55)
50
- x$34[2:31]:TPhi: phi(bb3: x$34, bb4: x$34)
50
+ x$34[2:31]:TObject<Array>: phi(bb3: x$34, bb4: x$34)
51
[24] store $58[24:28] = StoreLocal Const mutate _$57[24:28] = capture $52[7:28]
52
[25] mutate $60 = Global console
53
[26] mutate $61[26:28] = LoadLocal capture _$57[24:28]
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary.expect.md
+9
-9
@@ -16,12 +16,12 @@ function foo(props) {
16
17
```javascript
18
bb0 (block):
19
- [1] store $30[1:7] = Array []
20
- [2] store $32[2:7] = StoreLocal Let mutate x$31[2:7] = capture $30[1:7]
21
- [3] mutate $33[3:7] = LoadLocal capture x$31[2:7]
19
+ [1] store $30[1:7]:TObject<Array> = Array []
20
+ [2] store $32[2:7]:TObject<Array> = StoreLocal Let store x$31[2:7]:TObject<Array> = capture $30[1:7]:TObject<Array>
21
+ [3] mutate $33[3:7]:TObject<Array> = LoadLocal capture x$31[2:7]:TObject<Array>
22
[4] mutate $34 = LoadLocal read props$29
23
[5] mutate $35 = PropertyLoad read $34.bar
24
- [6] mutate $36 = PropertyCall mutate $33[3:7].push(read $35)
24
+ [6] mutate $36 = PropertyCall mutate $33[3:7]:TObject<Array>.push(read $35)
25
[7] Ternary test:bb2 fallthrough=bb1
26
bb2 (value):
27
predecessor blocks: bb0
@@ -30,12 +30,12 @@ bb2 (value):
30
[10] Branch (read $38) then:bb3 else:bb4
31
bb3 (value):
32
predecessor blocks: bb2
33
- [13] store $42[13:19] = Array []
34
- [14] store $44[14:19] = StoreLocal Reassign mutate x$31[14:19] = capture $42[13:19]
35
- [15] mutate $45[15:19] = LoadLocal capture x$31[14:19]
33
+ [13] store $42[13:19]:TObject<Array> = Array []
34
+ [14] store $44[14:19]:TObject<Array> = StoreLocal Reassign store x$31[14:19]:TObject<Array> = capture $42[13:19]:TObject<Array>
35
+ [15] mutate $45[15:19]:TObject<Array> = LoadLocal capture x$31[14:19]:TObject<Array>
36
[16] mutate $46 = LoadLocal read props$29
37
[17] mutate $47 = PropertyLoad read $46.foo
38
- [18] mutate $48[18:28] = PropertyCall mutate $45[15:19].push(read $47)
38
+ [18] mutate $48[18:28] = PropertyCall mutate $45[15:19]:TObject<Array>.push(read $47)
39
[19] store $50[19:28] = StoreLocal Const mutate $49[7:28] = capture $48[18:28]
40
[20] Goto bb1
41
bb4 (value):
@@ -46,7 +46,7 @@ bb4 (value):
46
bb1 (block):
47
predecessor blocks: bb3 bb4
48
$56[7:28]:TPhi: phi(bb3: $49, bb4: $52)
49
- x$31:TPhi: phi(bb3: x$31, bb4: x$31)
49
+ x$31:TObject<Array>: phi(bb3: x$31, bb4: x$31)
50
[24] store $55[24:28] = StoreLocal Const mutate _$54[24:28] = capture $49[7:28]
51
[25] mutate $57 = Global console
52
[26] mutate $58[26:28] = LoadLocal capture _$54[24:28]
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary-with-mutation.expect.md
+13
-13
@@ -19,12 +19,12 @@ function foo(props) {
19
20
```javascript
21
bb0 (block):
22
- [1] store $40[1:7] = Array []
23
- [2] store $42[2:7] = StoreLocal Let mutate x$41[2:38] = capture $40[1:7]
24
- [3] mutate $43[3:7] = LoadLocal capture x$41[2:38]
22
+ [1] store $40[1:7]:TObject<Array> = Array []
23
+ [2] store $42[2:7]:TObject<Array> = StoreLocal Let store x$41[2:38]:TObject<Array> = capture $40[1:7]:TObject<Array>
24
+ [3] mutate $43[3:7]:TObject<Array> = LoadLocal capture x$41[2:38]:TObject<Array>
25
[4] mutate $44 = LoadLocal read props$39
26
[5] mutate $45 = PropertyLoad read $44.bar
27
- [6] mutate $46 = PropertyCall mutate $43[3:7].push(read $45)
27
+ [6] mutate $46 = PropertyCall mutate $43[3:7]:TObject<Array>.push(read $45)
28
[7] Ternary test:bb2 fallthrough=bb1
29
bb2 (value):
30
predecessor blocks: bb0
@@ -33,28 +33,28 @@ bb2 (value):
33
[10] Branch (read $48) then:bb3 else:bb4
34
bb3 (value):
35
predecessor blocks: bb2
36
- [13] store $52[13:38] = Array []
37
- [14] store $54[14:38] = StoreLocal Reassign mutate x$41[14:38] = capture $52[13:38]
38
- [15] mutate $55[15:38] = LoadLocal capture x$41[14:38]
36
+ [13] store $52[13:38]:TObject<Array> = Array []
37
+ [14] store $54[14:38]:TObject<Array> = StoreLocal Reassign store x$41[14:38]:TObject<Array> = capture $52[13:38]:TObject<Array>
38
+ [15] mutate $55[15:38]:TObject<Array> = LoadLocal capture x$41[14:38]:TObject<Array>
39
[16] mutate $56 = LoadLocal read props$39
40
[17] mutate $57 = PropertyLoad read $56.foo
41
- [18] mutate $58[18:35] = PropertyCall mutate $55[15:38].push(read $57)
41
+ [18] mutate $58[18:35] = PropertyCall mutate $55[15:38]:TObject<Array>.push(read $57)
42
[19] store $60[19:35] = StoreLocal Const mutate $59[7:35] = capture $58[18:35]
43
[20] Goto bb1
44
bb4 (value):
45
predecessor blocks: bb2
46
- [23] store $64[23:38] = Array []
47
- [24] store $66[24:38] = StoreLocal Reassign mutate x$41[24:38] = capture $64[23:38]
48
- [25] mutate $67[25:38] = LoadLocal capture x$41[24:38]
46
+ [23] store $64[23:38]:TObject<Array> = Array []
47
+ [24] store $66[24:38]:TObject<Array> = StoreLocal Reassign store x$41[24:38]:TObject<Array> = capture $64[23:38]:TObject<Array>
48
+ [25] mutate $67[25:38]:TObject<Array> = LoadLocal capture x$41[24:38]:TObject<Array>
49
[26] mutate $68 = LoadLocal read props$39
50
[27] mutate $69 = PropertyLoad read $68.bar
51
- [28] mutate $70[28:35] = PropertyCall mutate $67[25:38].push(read $69)
51
+ [28] mutate $70[28:35] = PropertyCall mutate $67[25:38]:TObject<Array>.push(read $69)
52
[29] store $72[29:35] = StoreLocal Const mutate $59[7:35] = capture $70[28:35]
53
[30] Goto bb1
54
bb1 (block):
55
predecessor blocks: bb3 bb4
56
$75[7:35]:TPhi: phi(bb3: $59, bb4: $71)
57
- x$41[14:38]:TPhi: phi(bb3: x$41, bb4: x$41)
57
+ x$41[14:38]:TObject<Array>: phi(bb3: x$41, bb4: x$41)
58
[31] store $74[31:35] = StoreLocal Const mutate _$73[31:35] = capture $59[7:35]
59
[32] mutate $76 = Global console
60
[33] mutate $77[33:35] = LoadLocal capture _$73[31:35]
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary.expect.md
+13
-13
@@ -18,12 +18,12 @@ function foo(props) {
18
19
```javascript
20
bb0 (block):
21
- [1] store $37[1:7] = Array []
22
- [2] store $39[2:7] = StoreLocal Let mutate x$38[2:7] = capture $37[1:7]
23
- [3] mutate $40[3:7] = LoadLocal capture x$38[2:7]
21
+ [1] store $37[1:7]:TObject<Array> = Array []
22
+ [2] store $39[2:7]:TObject<Array> = StoreLocal Let store x$38[2:7]:TObject<Array> = capture $37[1:7]:TObject<Array>
23
+ [3] mutate $40[3:7]:TObject<Array> = LoadLocal capture x$38[2:7]:TObject<Array>
24
[4] mutate $41 = LoadLocal read props$36
25
[5] mutate $42 = PropertyLoad read $41.bar
26
- [6] mutate $43 = PropertyCall mutate $40[3:7].push(read $42)
26
+ [6] mutate $43 = PropertyCall mutate $40[3:7]:TObject<Array>.push(read $42)
27
[7] Ternary test:bb2 fallthrough=bb1
28
bb2 (value):
29
predecessor blocks: bb0
@@ -32,28 +32,28 @@ bb2 (value):
32
[10] Branch (read $45) then:bb3 else:bb4
33
bb3 (value):
34
predecessor blocks: bb2
35
- [13] store $49[13:19] = Array []
36
- [14] store $51[14:19] = StoreLocal Reassign mutate x$38[14:19] = capture $49[13:19]
37
- [15] mutate $52[15:19] = LoadLocal capture x$38[14:19]
35
+ [13] store $49[13:19]:TObject<Array> = Array []
36
+ [14] store $51[14:19]:TObject<Array> = StoreLocal Reassign store x$38[14:19]:TObject<Array> = capture $49[13:19]:TObject<Array>
37
+ [15] mutate $52[15:19]:TObject<Array> = LoadLocal capture x$38[14:19]:TObject<Array>
38
[16] mutate $53 = LoadLocal read props$36
39
[17] mutate $54 = PropertyLoad read $53.foo
40
- [18] mutate $55[18:35] = PropertyCall mutate $52[15:19].push(read $54)
40
+ [18] mutate $55[18:35] = PropertyCall mutate $52[15:19]:TObject<Array>.push(read $54)
41
[19] store $57[19:35] = StoreLocal Const mutate $56[7:35] = capture $55[18:35]
42
[20] Goto bb1
43
bb4 (value):
44
predecessor blocks: bb2
45
- [23] store $61[23:29] = Array []
46
- [24] store $63[24:29] = StoreLocal Reassign mutate x$38[24:29] = capture $61[23:29]
47
- [25] mutate $64[25:29] = LoadLocal capture x$38[24:29]
45
+ [23] store $61[23:29]:TObject<Array> = Array []
46
+ [24] store $63[24:29]:TObject<Array> = StoreLocal Reassign store x$38[24:29]:TObject<Array> = capture $61[23:29]:TObject<Array>
47
+ [25] mutate $64[25:29]:TObject<Array> = LoadLocal capture x$38[24:29]:TObject<Array>
48
[26] mutate $65 = LoadLocal read props$36
49
[27] mutate $66 = PropertyLoad read $65.bar
50
- [28] mutate $67[28:35] = PropertyCall mutate $64[25:29].push(read $66)
50
+ [28] mutate $67[28:35] = PropertyCall mutate $64[25:29]:TObject<Array>.push(read $66)
51
[29] store $69[29:35] = StoreLocal Const mutate $56[7:35] = capture $67[28:35]
52
[30] Goto bb1
53
bb1 (block):
54
predecessor blocks: bb3 bb4
55
$72[7:35]:TPhi: phi(bb3: $56, bb4: $68)
56
- x$38:TPhi: phi(bb3: x$38, bb4: x$38)
56
+ x$38:TObject<Array>: phi(bb3: x$38, bb4: x$38)
57
[31] store $71[31:35] = StoreLocal Const mutate _$70[31:35] = capture $56[7:35]
58
[32] mutate $73 = Global console
59
[33] mutate $74[33:35] = LoadLocal capture _$70[31:35]
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-with-mutation.expect.md
+13
-13
@@ -24,36 +24,36 @@ function foo(props) {
24
25
```javascript
26
bb0 (block):
27
- [1] store $32[1:7] = Array []
28
- [2] store $34[2:7] = StoreLocal Let mutate x$33[2:31] = capture $32[1:7]
29
- [3] mutate $35[3:7] = LoadLocal capture x$33[2:31]
27
+ [1] store $32[1:7]:TObject<Array> = Array []
28
+ [2] store $34[2:7]:TObject<Array> = StoreLocal Let store x$33[2:31]:TObject<Array> = capture $32[1:7]:TObject<Array>
29
+ [3] mutate $35[3:7]:TObject<Array> = LoadLocal capture x$33[2:31]:TObject<Array>
30
[4] mutate $36 = LoadLocal read props$31
31
[5] mutate $37 = PropertyLoad read $36.bar
32
- [6] mutate $38 = PropertyCall mutate $35[3:7].push(read $37)
32
+ [6] mutate $38 = PropertyCall mutate $35[3:7]:TObject<Array>.push(read $37)
33
[7] mutate $39 = LoadLocal read props$31
34
[8] mutate $40 = PropertyLoad read $39.cond
35
[9] If (read $40) then:bb2 else:bb3 fallthrough=bb1
36
bb2 (block):
37
predecessor blocks: bb0
38
- [12] store $44[12:31] = Array []
39
- [13] store $46[13:31] = StoreLocal Reassign mutate x$33[13:31] = capture $44[12:31]
40
- [14] mutate $47[14:31] = LoadLocal capture x$33[13:31]
38
+ [12] store $44[12:31]:TObject<Array> = Array []
39
+ [13] store $46[13:31]:TObject<Array> = StoreLocal Reassign store x$33[13:31]:TObject<Array> = capture $44[12:31]:TObject<Array>
40
+ [14] mutate $47[14:31]:TObject<Array> = LoadLocal capture x$33[13:31]:TObject<Array>
41
[15] mutate $48 = LoadLocal read props$31
42
[16] mutate $49 = PropertyLoad read $48.foo
43
- [17] mutate $50 = PropertyCall mutate $47[14:31].push(read $49)
43
+ [17] mutate $50 = PropertyCall mutate $47[14:31]:TObject<Array>.push(read $49)
44
[18] Goto bb1
45
bb3 (block):
46
predecessor blocks: bb0
47
- [21] store $54[21:31] = Array []
48
- [22] store $56[22:31] = StoreLocal Reassign mutate x$33[22:31] = capture $54[21:31]
49
- [23] mutate $57[23:31] = LoadLocal capture x$33[22:31]
47
+ [21] store $54[21:31]:TObject<Array> = Array []
48
+ [22] store $56[22:31]:TObject<Array> = StoreLocal Reassign store x$33[22:31]:TObject<Array> = capture $54[21:31]:TObject<Array>
49
+ [23] mutate $57[23:31]:TObject<Array> = LoadLocal capture x$33[22:31]:TObject<Array>
50
[24] mutate $58 = LoadLocal read props$31
51
[25] mutate $59 = PropertyLoad read $58.bar
52
- [26] mutate $60 = PropertyCall mutate $57[23:31].push(read $59)
52
+ [26] mutate $60 = PropertyCall mutate $57[23:31]:TObject<Array>.push(read $59)
53
[27] Goto bb1
54
bb1 (block):
55
predecessor blocks: bb2 bb3
56
- x$33[13:31]:TPhi: phi(bb2: x$33, bb3: x$33)
56
+ x$33[13:31]:TObject<Array>: phi(bb2: x$33, bb3: x$33)
57
[28] mutate $61:TFunction = Global mut
58
[29] mutate $62[29:31] = LoadLocal capture x$33[13:31]
59
[30] mutate $64 = Call read $61:TFunction(mutate $62[29:31])