From ec345ca538704b25c66879025528e3b0dd1f96a2 Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Tue, 21 Mar 2023 14:57:11 -0400 Subject: [PATCH] [wip][typer] Infer Array instance properties --- TODO: add inference for TypedFunction to `InferReferenceEffects` --- compiler/forget/src/HIR/ObjectShape.ts | 134 ++++++++++++++++++ compiler/forget/src/HIR/PrintHIR.ts | 9 +- compiler/forget/src/HIR/Types.ts | 37 +++-- .../forget/src/TypeInference/InferTypes.ts | 12 +- .../fixtures/hir/simple-array.expect.md | 4 +- .../fixtures/hir/simple-object.expect.md | 4 +- ...ernary-destruction-with-mutation.expect.md | 14 +- ...ssa-renaming-ternary-destruction.expect.md | 14 +- ...a-renaming-ternary-with-mutation.expect.md | 18 +-- .../hir/ssa-renaming-ternary.expect.md | 18 +-- ...onditional-ternary-with-mutation.expect.md | 26 ++-- ...a-renaming-unconditional-ternary.expect.md | 26 ++-- ...ming-unconditional-with-mutation.expect.md | 26 ++-- 13 files changed, 252 insertions(+), 90 deletions(-) create mode 100644 compiler/forget/src/HIR/ObjectShape.ts diff --git a/compiler/forget/src/HIR/ObjectShape.ts b/compiler/forget/src/HIR/ObjectShape.ts new file mode 100644 index 0000000000..b0014d964a --- /dev/null +++ b/compiler/forget/src/HIR/ObjectShape.ts @@ -0,0 +1,134 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import invariant from "invariant"; +import { Effect } from "./HIR"; +import { BuiltInType, FunctionType, PrimitiveType } from "./Types"; + +const PRIMITIVE_TYPE: PrimitiveType = { + kind: "Primitive", +}; + +let nextAnonId = 0; +// use strings since they are easily debuggable, even though `Symbol()` +// might be more performant +function createAnonId(): string { + return ``; +} + +function addFunction( + registry: ShapeRegistry, + properties: Iterable<[string, BuiltInType | null]>, + fn: FunctionSignature +): FunctionType { + const shapeId = createAnonId(); + addShape(registry, shapeId, properties, fn); + return { + kind: "Function", + shapeId, + }; +} + +function addShape( + registry: ShapeRegistry, + id: string, + properties: Iterable<[string, BuiltInType | null]>, + functionType?: FunctionSignature +): ObjectShape { + const shape: ObjectShape = { + properties: new Map(properties), + functionType: functionType ?? null, + }; + + invariant( + !registry.has(id), + `[ObjectShape] Could not add shape to registry: name ${id} already exists.` + ); + registry.set(id, shape); + return shape; +} + +// Param type not recorded since it currently does not affect inference. +// Specifically, we currently do not: +// - infer types based on their usage in argument position +// - handle inference for overloaded / generic functions +export type FunctionSignature = { + positionalParams: Array; + restParam: Effect | null; + returnType: BuiltInType | null; + calleeEffect: Effect; +}; + +export type ObjectShape = { + properties: Map; + functionType: FunctionSignature | null; +}; + +export type ShapeRegistry = Map; + +/** + * Shapes of built-in types + */ + +// The only "entrypoints" should be Globals and recursive lookups from properties / functions +export const BUILTIN_SHAPES: ShapeRegistry = new Map(); +export const ArrayShapeId = "Array"; +export const ObjectShapeId = "Object"; + +/* Built-in array shape */ +addShape(BUILTIN_SHAPES, ArrayShapeId, [ + [ + "at", + addFunction(BUILTIN_SHAPES, [], { + positionalParams: [Effect.Read], + restParam: null, + returnType: null, + calleeEffect: Effect.Capture, + }), + ], + [ + "concat", + addFunction(BUILTIN_SHAPES, [], { + positionalParams: [], + restParam: Effect.Capture, + returnType: { + kind: "Object", + shapeId: ArrayShapeId, + }, + calleeEffect: Effect.Capture, + }), + ], + ["length", PRIMITIVE_TYPE], + [ + "push", + addFunction(BUILTIN_SHAPES, [], { + positionalParams: [], + restParam: Effect.Capture, + returnType: { + kind: "Primitive", + }, + calleeEffect: Effect.Store, + }), + ], + // TODO: rest of Array properties +]); + +/* Built-in Object shape */ +addShape(BUILTIN_SHAPES, ObjectShapeId, [ + [ + "toString", + addFunction(BUILTIN_SHAPES, [], { + positionalParams: [], + restParam: null, + returnType: { + kind: "Primitive", + }, + calleeEffect: Effect.Read, + }), + ], + // TODO: + // hasOwnProperty, isPrototypeOf, propertyIsEnumerable, toLocaleString, valueOf +]); diff --git a/compiler/forget/src/HIR/PrintHIR.ts b/compiler/forget/src/HIR/PrintHIR.ts index a8991a47c4..65821ed1ab 100644 --- a/compiler/forget/src/HIR/PrintHIR.ts +++ b/compiler/forget/src/HIR/PrintHIR.ts @@ -566,7 +566,14 @@ function printScope(scope: ReactiveScope | null): string { function printType(type: Type): string { if (type.kind === "Type") return ""; - return `:T${type.kind}`; + // TODO(mofeiZ): add debugName for generated ids + if (type.kind === "Object" && type.shapeId != null) { + return `:T${type.kind}<${type.shapeId}>`; + } else if (type.kind === "Function" && type.shapeId != null) { + return `:T${type.kind}<${type.shapeId}>`; + } else { + return `:T${type.kind}`; + } } export function printSourceLocation(loc: SourceLocation): string { diff --git a/compiler/forget/src/HIR/Types.ts b/compiler/forget/src/HIR/Types.ts index 959bb52751..933ef3aa20 100644 --- a/compiler/forget/src/HIR/Types.ts +++ b/compiler/forget/src/HIR/Types.ts @@ -7,23 +7,36 @@ import invariant from "invariant"; import { Hook } from "./Hooks"; -export type Type = - | PrimitiveType - | HookType - | FunctionType - | ObjectType - | PhiType - | PolyType - | TypeVar; +export type BuiltInType = PrimitiveType | FunctionType | ObjectType; + +export type Type = BuiltInType | HookType | PhiType | PolyType | TypeVar; export type PrimitiveType = { kind: "Primitive" }; -export type FunctionType = { - kind: "Function"; -}; export type HookType = { kind: "Hook"; definition: Hook; }; -export type ObjectType = { kind: "Object" }; + +/** + * An {@link FunctionType} or {@link ObjectType} (also a JS object) may be associated with an + * inferred "object shape", i.e. a known property (key -> Type) map. This is + * subtly different from JS language semantics - `shape` represents both + * OwnPropertyDescriptors and properties present in the prototype chain. + * + * In addition, a {@link FunctionType} may be associated with an inferred signature, + * + * If `shapeId` is present, it is a key into the global ShapeRegistry. + */ + +export type FunctionType = { + kind: "Function"; + shapeId: string | null; +}; + +export type ObjectType = { + kind: "Object"; + shapeId: string | null; +}; + export type TypeVar = { kind: "Type"; id: TypeId; diff --git a/compiler/forget/src/TypeInference/InferTypes.ts b/compiler/forget/src/TypeInference/InferTypes.ts index 9fad30415c..72b977a4e9 100644 --- a/compiler/forget/src/TypeInference/InferTypes.ts +++ b/compiler/forget/src/TypeInference/InferTypes.ts @@ -9,6 +9,7 @@ import { TypeId, TypeVar, } from "../HIR/HIR"; +import { ArrayShapeId, ObjectShapeId } from "../HIR/ObjectShape"; import { eachInstructionLValue, eachInstructionOperand } from "../HIR/visitors"; function isPrimitiveBinaryOp(op: t.BinaryExpression["operator"]): boolean { @@ -150,7 +151,7 @@ function* generateInstructionTypes( if (hook !== null) { type = { kind: "Hook", definition: hook }; } else { - type = { kind: "Function" }; + type = { kind: "Function", shapeId: null }; } yield equation(value.callee.identifier.type, type); break; @@ -158,7 +159,14 @@ function* generateInstructionTypes( case "ObjectExpression": { invariant(left !== null, "invald object expression"); - yield equation(left, { kind: "Object" }); + yield equation(left, { kind: "Object", shapeId: ObjectShapeId }); + break; + } + + case "ArrayExpression": { + if (left) { + yield equation(left, { kind: "Object", shapeId: ArrayShapeId }); + } break; } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple-array.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple-array.expect.md index cfcdf7c01b..d1224dddbc 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple-array.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple-array.expect.md @@ -25,7 +25,7 @@ bb0 (block): [9] store $27 = StoreLocal Const mutate y$26 = capture $25 [10] mutate $28:TPrimitive = LoadLocal read x$21:TPrimitive [11] mutate $29 = LoadLocal capture y$26 - [12] store $30 = Array [read $28:TPrimitive, capture $29] - [13] Return freeze $30 + [12] store $30:TObject = Array [read $28:TPrimitive, capture $29] + [13] Return freeze $30:TObject ``` \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple-object.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple-object.expect.md index a8bf278561..73d2ab6693 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple-object.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple-object.expect.md @@ -25,7 +25,7 @@ bb0 (block): [9] store $27 = StoreLocal Const mutate y$26 = capture $25 [10] mutate $28:TPrimitive = LoadLocal read x$21:TPrimitive [11] mutate $29 = LoadLocal capture y$26 - [12] store $30:TObject = Object { x: read $28:TPrimitive, y: capture $29 } - [13] Return freeze $30:TObject + [12] store $30:TObject = Object { x: read $28:TPrimitive, y: capture $29 } + [13] Return freeze $30:TObject ``` \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction-with-mutation.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction-with-mutation.expect.md index 59a9cc8df1..0f9a9bcbdb 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction-with-mutation.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction-with-mutation.expect.md @@ -19,12 +19,12 @@ function foo(props) { ```javascript bb0 (block): - [1] store $35[1:33] = Array [] - [2] store $37[2:33] = StoreLocal Let mutate x$36[2:33] = capture $35[1:33] - [3] mutate $38[3:33] = LoadLocal capture x$36[2:33] + [1] store $35[1:33]:TObject = Array [] + [2] store $37[2:33]:TObject = StoreLocal Let store x$36[2:33]:TObject = capture $35[1:33]:TObject + [3] mutate $38[3:33]:TObject = LoadLocal capture x$36[2:33]:TObject [4] mutate $39 = LoadLocal read props$34 [5] mutate $40 = PropertyLoad read $39.bar - [6] mutate $41 = PropertyCall mutate $38[3:33].push(read $40) + [6] mutate $41 = PropertyCall mutate $38[3:33]:TObject.push(read $40) [7] Ternary test:bb2 fallthrough=bb1 bb2 (value): predecessor blocks: bb0 @@ -33,9 +33,9 @@ bb2 (value): [10] Branch (read $43) then:bb3 else:bb4 bb3 (value): predecessor blocks: bb2 - [14] store $48[14:33] = Array [] - [15] store $49[15:33] = Array [capture $48[14:33]] - [16] store $51[16:33] = Destructure Reassign [ mutate x$36[16:33] ] = capture $49[15:33] + [14] store $48[14:33]:TObject = Array [] + [15] store $49[15:33]:TObject = Array [capture $48[14:33]:TObject] + [16] store $51[16:33] = Destructure Reassign [ mutate x$36[16:33] ] = capture $49[15:33]:TObject [17] mutate $52[17:33] = LoadLocal capture x$36[16:33] [18] mutate $53 = LoadLocal read props$34 [19] mutate $54 = PropertyLoad read $53.foo diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction.expect.md index a0055dba41..c3817bde9a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-destruction.expect.md @@ -18,12 +18,12 @@ function foo(props) { ```javascript bb0 (block): - [1] store $32[1:7] = Array [] - [2] store $34[2:7] = StoreLocal Let mutate x$33[2:7] = capture $32[1:7] - [3] mutate $35[3:7] = LoadLocal capture x$33[2:7] + [1] store $32[1:7]:TObject = Array [] + [2] store $34[2:7]:TObject = StoreLocal Let store x$33[2:7]:TObject = capture $32[1:7]:TObject + [3] mutate $35[3:7]:TObject = LoadLocal capture x$33[2:7]:TObject [4] mutate $36 = LoadLocal read props$31 [5] mutate $37 = PropertyLoad read $36.bar - [6] mutate $38 = PropertyCall mutate $35[3:7].push(read $37) + [6] mutate $38 = PropertyCall mutate $35[3:7]:TObject.push(read $37) [7] Ternary test:bb2 fallthrough=bb1 bb2 (value): predecessor blocks: bb0 @@ -32,9 +32,9 @@ bb2 (value): [10] Branch (read $40) then:bb3 else:bb4 bb3 (value): predecessor blocks: bb2 - [14] store $45[14:21] = Array [] - [15] store $46[15:21] = Array [capture $45[14:21]] - [16] store $48[16:21] = Destructure Reassign [ mutate x$33[16:21] ] = capture $46[15:21] + [14] store $45[14:21]:TObject = Array [] + [15] store $46[15:21]:TObject = Array [capture $45[14:21]:TObject] + [16] store $48[16:21] = Destructure Reassign [ mutate x$33[16:21] ] = capture $46[15:21]:TObject [17] mutate $49[17:21] = LoadLocal capture x$33[16:21] [18] mutate $50 = LoadLocal read props$31 [19] mutate $51 = PropertyLoad read $50.foo diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-with-mutation.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-with-mutation.expect.md index 5520eeabd0..2f583e3fc8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-with-mutation.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary-with-mutation.expect.md @@ -17,12 +17,12 @@ function foo(props) { ```javascript bb0 (block): - [1] store $33[1:31] = Array [] - [2] store $35[2:31] = StoreLocal Let mutate x$34[2:31] = capture $33[1:31] - [3] mutate $36[3:31] = LoadLocal capture x$34[2:31] + [1] store $33[1:31]:TObject = Array [] + [2] store $35[2:31]:TObject = StoreLocal Let store x$34[2:31]:TObject = capture $33[1:31]:TObject + [3] mutate $36[3:31]:TObject = LoadLocal capture x$34[2:31]:TObject [4] mutate $37 = LoadLocal read props$32 [5] mutate $38 = PropertyLoad read $37.bar - [6] mutate $39 = PropertyCall mutate $36[3:31].push(read $38) + [6] mutate $39 = PropertyCall mutate $36[3:31]:TObject.push(read $38) [7] Ternary test:bb2 fallthrough=bb1 bb2 (value): predecessor blocks: bb0 @@ -31,12 +31,12 @@ bb2 (value): [10] Branch (read $41) then:bb3 else:bb4 bb3 (value): predecessor blocks: bb2 - [13] store $45[13:31] = Array [] - [14] store $47[14:31] = StoreLocal Reassign mutate x$34[14:31] = capture $45[13:31] - [15] mutate $48[15:31] = LoadLocal capture x$34[14:31] + [13] store $45[13:31]:TObject = Array [] + [14] store $47[14:31]:TObject = StoreLocal Reassign store x$34[14:31]:TObject = capture $45[13:31]:TObject + [15] mutate $48[15:31]:TObject = LoadLocal capture x$34[14:31]:TObject [16] mutate $49 = LoadLocal read props$32 [17] mutate $50 = PropertyLoad read $49.foo - [18] mutate $51[18:28] = PropertyCall mutate $48[15:31].push(read $50) + [18] mutate $51[18:28] = PropertyCall mutate $48[15:31]:TObject.push(read $50) [19] store $53[19:28] = StoreLocal Const mutate $52[7:28] = capture $51[18:28] [20] Goto bb1 bb4 (value): @@ -47,7 +47,7 @@ bb4 (value): bb1 (block): predecessor blocks: bb3 bb4 $59[7:28]:TPhi: phi(bb3: $52, bb4: $55) - x$34[2:31]:TPhi: phi(bb3: x$34, bb4: x$34) + x$34[2:31]:TObject: phi(bb3: x$34, bb4: x$34) [24] store $58[24:28] = StoreLocal Const mutate _$57[24:28] = capture $52[7:28] [25] mutate $60 = Global console [26] mutate $61[26:28] = LoadLocal capture _$57[24:28] diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary.expect.md index b37f245b56..cbf455e326 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-ternary.expect.md @@ -16,12 +16,12 @@ function foo(props) { ```javascript bb0 (block): - [1] store $30[1:7] = Array [] - [2] store $32[2:7] = StoreLocal Let mutate x$31[2:7] = capture $30[1:7] - [3] mutate $33[3:7] = LoadLocal capture x$31[2:7] + [1] store $30[1:7]:TObject = Array [] + [2] store $32[2:7]:TObject = StoreLocal Let store x$31[2:7]:TObject = capture $30[1:7]:TObject + [3] mutate $33[3:7]:TObject = LoadLocal capture x$31[2:7]:TObject [4] mutate $34 = LoadLocal read props$29 [5] mutate $35 = PropertyLoad read $34.bar - [6] mutate $36 = PropertyCall mutate $33[3:7].push(read $35) + [6] mutate $36 = PropertyCall mutate $33[3:7]:TObject.push(read $35) [7] Ternary test:bb2 fallthrough=bb1 bb2 (value): predecessor blocks: bb0 @@ -30,12 +30,12 @@ bb2 (value): [10] Branch (read $38) then:bb3 else:bb4 bb3 (value): predecessor blocks: bb2 - [13] store $42[13:19] = Array [] - [14] store $44[14:19] = StoreLocal Reassign mutate x$31[14:19] = capture $42[13:19] - [15] mutate $45[15:19] = LoadLocal capture x$31[14:19] + [13] store $42[13:19]:TObject = Array [] + [14] store $44[14:19]:TObject = StoreLocal Reassign store x$31[14:19]:TObject = capture $42[13:19]:TObject + [15] mutate $45[15:19]:TObject = LoadLocal capture x$31[14:19]:TObject [16] mutate $46 = LoadLocal read props$29 [17] mutate $47 = PropertyLoad read $46.foo - [18] mutate $48[18:28] = PropertyCall mutate $45[15:19].push(read $47) + [18] mutate $48[18:28] = PropertyCall mutate $45[15:19]:TObject.push(read $47) [19] store $50[19:28] = StoreLocal Const mutate $49[7:28] = capture $48[18:28] [20] Goto bb1 bb4 (value): @@ -46,7 +46,7 @@ bb4 (value): bb1 (block): predecessor blocks: bb3 bb4 $56[7:28]:TPhi: phi(bb3: $49, bb4: $52) - x$31:TPhi: phi(bb3: x$31, bb4: x$31) + x$31:TObject: phi(bb3: x$31, bb4: x$31) [24] store $55[24:28] = StoreLocal Const mutate _$54[24:28] = capture $49[7:28] [25] mutate $57 = Global console [26] mutate $58[26:28] = LoadLocal capture _$54[24:28] diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary-with-mutation.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary-with-mutation.expect.md index 9a5110b738..4b9d529734 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary-with-mutation.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary-with-mutation.expect.md @@ -19,12 +19,12 @@ function foo(props) { ```javascript bb0 (block): - [1] store $40[1:7] = Array [] - [2] store $42[2:7] = StoreLocal Let mutate x$41[2:38] = capture $40[1:7] - [3] mutate $43[3:7] = LoadLocal capture x$41[2:38] + [1] store $40[1:7]:TObject = Array [] + [2] store $42[2:7]:TObject = StoreLocal Let store x$41[2:38]:TObject = capture $40[1:7]:TObject + [3] mutate $43[3:7]:TObject = LoadLocal capture x$41[2:38]:TObject [4] mutate $44 = LoadLocal read props$39 [5] mutate $45 = PropertyLoad read $44.bar - [6] mutate $46 = PropertyCall mutate $43[3:7].push(read $45) + [6] mutate $46 = PropertyCall mutate $43[3:7]:TObject.push(read $45) [7] Ternary test:bb2 fallthrough=bb1 bb2 (value): predecessor blocks: bb0 @@ -33,28 +33,28 @@ bb2 (value): [10] Branch (read $48) then:bb3 else:bb4 bb3 (value): predecessor blocks: bb2 - [13] store $52[13:38] = Array [] - [14] store $54[14:38] = StoreLocal Reassign mutate x$41[14:38] = capture $52[13:38] - [15] mutate $55[15:38] = LoadLocal capture x$41[14:38] + [13] store $52[13:38]:TObject = Array [] + [14] store $54[14:38]:TObject = StoreLocal Reassign store x$41[14:38]:TObject = capture $52[13:38]:TObject + [15] mutate $55[15:38]:TObject = LoadLocal capture x$41[14:38]:TObject [16] mutate $56 = LoadLocal read props$39 [17] mutate $57 = PropertyLoad read $56.foo - [18] mutate $58[18:35] = PropertyCall mutate $55[15:38].push(read $57) + [18] mutate $58[18:35] = PropertyCall mutate $55[15:38]:TObject.push(read $57) [19] store $60[19:35] = StoreLocal Const mutate $59[7:35] = capture $58[18:35] [20] Goto bb1 bb4 (value): predecessor blocks: bb2 - [23] store $64[23:38] = Array [] - [24] store $66[24:38] = StoreLocal Reassign mutate x$41[24:38] = capture $64[23:38] - [25] mutate $67[25:38] = LoadLocal capture x$41[24:38] + [23] store $64[23:38]:TObject = Array [] + [24] store $66[24:38]:TObject = StoreLocal Reassign store x$41[24:38]:TObject = capture $64[23:38]:TObject + [25] mutate $67[25:38]:TObject = LoadLocal capture x$41[24:38]:TObject [26] mutate $68 = LoadLocal read props$39 [27] mutate $69 = PropertyLoad read $68.bar - [28] mutate $70[28:35] = PropertyCall mutate $67[25:38].push(read $69) + [28] mutate $70[28:35] = PropertyCall mutate $67[25:38]:TObject.push(read $69) [29] store $72[29:35] = StoreLocal Const mutate $59[7:35] = capture $70[28:35] [30] Goto bb1 bb1 (block): predecessor blocks: bb3 bb4 $75[7:35]:TPhi: phi(bb3: $59, bb4: $71) - x$41[14:38]:TPhi: phi(bb3: x$41, bb4: x$41) + x$41[14:38]:TObject: phi(bb3: x$41, bb4: x$41) [31] store $74[31:35] = StoreLocal Const mutate _$73[31:35] = capture $59[7:35] [32] mutate $76 = Global console [33] mutate $77[33:35] = LoadLocal capture _$73[31:35] diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary.expect.md index 5d2e8adb25..01ad770f5a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-ternary.expect.md @@ -18,12 +18,12 @@ function foo(props) { ```javascript bb0 (block): - [1] store $37[1:7] = Array [] - [2] store $39[2:7] = StoreLocal Let mutate x$38[2:7] = capture $37[1:7] - [3] mutate $40[3:7] = LoadLocal capture x$38[2:7] + [1] store $37[1:7]:TObject = Array [] + [2] store $39[2:7]:TObject = StoreLocal Let store x$38[2:7]:TObject = capture $37[1:7]:TObject + [3] mutate $40[3:7]:TObject = LoadLocal capture x$38[2:7]:TObject [4] mutate $41 = LoadLocal read props$36 [5] mutate $42 = PropertyLoad read $41.bar - [6] mutate $43 = PropertyCall mutate $40[3:7].push(read $42) + [6] mutate $43 = PropertyCall mutate $40[3:7]:TObject.push(read $42) [7] Ternary test:bb2 fallthrough=bb1 bb2 (value): predecessor blocks: bb0 @@ -32,28 +32,28 @@ bb2 (value): [10] Branch (read $45) then:bb3 else:bb4 bb3 (value): predecessor blocks: bb2 - [13] store $49[13:19] = Array [] - [14] store $51[14:19] = StoreLocal Reassign mutate x$38[14:19] = capture $49[13:19] - [15] mutate $52[15:19] = LoadLocal capture x$38[14:19] + [13] store $49[13:19]:TObject = Array [] + [14] store $51[14:19]:TObject = StoreLocal Reassign store x$38[14:19]:TObject = capture $49[13:19]:TObject + [15] mutate $52[15:19]:TObject = LoadLocal capture x$38[14:19]:TObject [16] mutate $53 = LoadLocal read props$36 [17] mutate $54 = PropertyLoad read $53.foo - [18] mutate $55[18:35] = PropertyCall mutate $52[15:19].push(read $54) + [18] mutate $55[18:35] = PropertyCall mutate $52[15:19]:TObject.push(read $54) [19] store $57[19:35] = StoreLocal Const mutate $56[7:35] = capture $55[18:35] [20] Goto bb1 bb4 (value): predecessor blocks: bb2 - [23] store $61[23:29] = Array [] - [24] store $63[24:29] = StoreLocal Reassign mutate x$38[24:29] = capture $61[23:29] - [25] mutate $64[25:29] = LoadLocal capture x$38[24:29] + [23] store $61[23:29]:TObject = Array [] + [24] store $63[24:29]:TObject = StoreLocal Reassign store x$38[24:29]:TObject = capture $61[23:29]:TObject + [25] mutate $64[25:29]:TObject = LoadLocal capture x$38[24:29]:TObject [26] mutate $65 = LoadLocal read props$36 [27] mutate $66 = PropertyLoad read $65.bar - [28] mutate $67[28:35] = PropertyCall mutate $64[25:29].push(read $66) + [28] mutate $67[28:35] = PropertyCall mutate $64[25:29]:TObject.push(read $66) [29] store $69[29:35] = StoreLocal Const mutate $56[7:35] = capture $67[28:35] [30] Goto bb1 bb1 (block): predecessor blocks: bb3 bb4 $72[7:35]:TPhi: phi(bb3: $56, bb4: $68) - x$38:TPhi: phi(bb3: x$38, bb4: x$38) + x$38:TObject: phi(bb3: x$38, bb4: x$38) [31] store $71[31:35] = StoreLocal Const mutate _$70[31:35] = capture $56[7:35] [32] mutate $73 = Global console [33] mutate $74[33:35] = LoadLocal capture _$70[31:35] diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-with-mutation.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-with-mutation.expect.md index 1f044a7774..9f5abc1d6a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-with-mutation.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-renaming-unconditional-with-mutation.expect.md @@ -24,36 +24,36 @@ function foo(props) { ```javascript bb0 (block): - [1] store $32[1:7] = Array [] - [2] store $34[2:7] = StoreLocal Let mutate x$33[2:31] = capture $32[1:7] - [3] mutate $35[3:7] = LoadLocal capture x$33[2:31] + [1] store $32[1:7]:TObject = Array [] + [2] store $34[2:7]:TObject = StoreLocal Let store x$33[2:31]:TObject = capture $32[1:7]:TObject + [3] mutate $35[3:7]:TObject = LoadLocal capture x$33[2:31]:TObject [4] mutate $36 = LoadLocal read props$31 [5] mutate $37 = PropertyLoad read $36.bar - [6] mutate $38 = PropertyCall mutate $35[3:7].push(read $37) + [6] mutate $38 = PropertyCall mutate $35[3:7]:TObject.push(read $37) [7] mutate $39 = LoadLocal read props$31 [8] mutate $40 = PropertyLoad read $39.cond [9] If (read $40) then:bb2 else:bb3 fallthrough=bb1 bb2 (block): predecessor blocks: bb0 - [12] store $44[12:31] = Array [] - [13] store $46[13:31] = StoreLocal Reassign mutate x$33[13:31] = capture $44[12:31] - [14] mutate $47[14:31] = LoadLocal capture x$33[13:31] + [12] store $44[12:31]:TObject = Array [] + [13] store $46[13:31]:TObject = StoreLocal Reassign store x$33[13:31]:TObject = capture $44[12:31]:TObject + [14] mutate $47[14:31]:TObject = LoadLocal capture x$33[13:31]:TObject [15] mutate $48 = LoadLocal read props$31 [16] mutate $49 = PropertyLoad read $48.foo - [17] mutate $50 = PropertyCall mutate $47[14:31].push(read $49) + [17] mutate $50 = PropertyCall mutate $47[14:31]:TObject.push(read $49) [18] Goto bb1 bb3 (block): predecessor blocks: bb0 - [21] store $54[21:31] = Array [] - [22] store $56[22:31] = StoreLocal Reassign mutate x$33[22:31] = capture $54[21:31] - [23] mutate $57[23:31] = LoadLocal capture x$33[22:31] + [21] store $54[21:31]:TObject = Array [] + [22] store $56[22:31]:TObject = StoreLocal Reassign store x$33[22:31]:TObject = capture $54[21:31]:TObject + [23] mutate $57[23:31]:TObject = LoadLocal capture x$33[22:31]:TObject [24] mutate $58 = LoadLocal read props$31 [25] mutate $59 = PropertyLoad read $58.bar - [26] mutate $60 = PropertyCall mutate $57[23:31].push(read $59) + [26] mutate $60 = PropertyCall mutate $57[23:31]:TObject.push(read $59) [27] Goto bb1 bb1 (block): predecessor blocks: bb2 bb3 - x$33[13:31]:TPhi: phi(bb2: x$33, bb3: x$33) + x$33[13:31]:TObject: phi(bb2: x$33, bb3: x$33) [28] mutate $61:TFunction = Global mut [29] mutate $62[29:31] = LoadLocal capture x$33[13:31] [30] mutate $64 = Call read $61:TFunction(mutate $62[29:31])