@samitouri / QOS-React-2 / commits / 0bbb36e1a4

[codegen] more locations: binary, return, call (#820)

Jan Kassens committed Nov 28, 2022 at 16:54 UTC 0bbb36e1a4d4db04a52c27fe07d9eb0de06c4889
6 files changed +24 -6
compiler/forget/src/HIR/BuildHIR.ts
+1
@@ -136,6 +136,7 @@ function lowerStatement(
136 const fallthrough = builder.reserve();
137 const terminal: ReturnTerminal = {
138 kind: "return",
139 + loc: stmt.node.loc ?? GeneratedSource,
140 value,
141 id: makeInstructionId(0),
142 };
compiler/forget/src/HIR/Codegen.ts
+12 -4
@@ -43,6 +43,8 @@ function withLoc<TNode extends t.Node, T extends (...args: any[]) => TNode>(
43 };
44 }
45
46 +const createBinaryExpression = withLoc(t.binaryExpression);
47 +const createCallExpression = withLoc(t.callExpression);
48 const createExpressionStatement = withLoc(t.expressionStatement);
49 const createFunctionDeclaration = withLoc(t.functionDeclaration);
50 const createLabelledStatement = withLoc(t.labeledStatement);
@@ -192,15 +194,16 @@ class CodegenVisitor
194 return createWhileStatement(terminal.loc, terminal.test, terminal.loop);
195 }
196 case "return": {
197 + const createReturnStatement = withLoc(t.returnStatement);
198 if (terminal.value !== null) {
196 - return t.returnStatement(terminal.value);
199 + return createReturnStatement(terminal.loc, terminal.value);
200 } else if (this.depth === 1) {
201 // A return at the top-level of a function must be the last instruction,
202 // and functions implicitly return after the last instruction of the top-level.
203 // Elide the return.
204 return t.emptyStatement();
205 } else {
203 - return t.returnStatement();
206 + return createReturnStatement(terminal.loc);
207 }
208 }
209 case "throw": {
@@ -253,7 +256,12 @@ function codegenInstructionValue(
256 case "BinaryExpression": {
257 const left = codegenPlace(temp, instrValue.left);
258 const right = codegenPlace(temp, instrValue.right);
256 - value = t.binaryExpression(instrValue.operator, left, right);
259 + value = createBinaryExpression(
260 + instrValue.loc,
261 + instrValue.operator,
262 + left,
263 + right
264 + );
265 break;
266 }
267 case "UnaryExpression": {
@@ -270,7 +278,7 @@ function codegenInstructionValue(
278 case "CallExpression": {
279 const callee = codegenPlace(temp, instrValue.callee);
280 const args = instrValue.args.map((arg) => codegenPlace(temp, arg));
273 - value = t.callExpression(callee, args);
281 + value = createCallExpression(instrValue.loc, callee, args);
282 break;
283 }
284 case "NewExpression": {
compiler/forget/src/HIR/HIR.ts
+1
@@ -114,6 +114,7 @@ export type ThrowTerminal = { kind: "throw"; value: Place; id: InstructionId };
114
115 export type ReturnTerminal = {
116 kind: "return";
117 + loc: SourceLocation;
118 value: Place | null;
119 id: InstructionId;
120 };
compiler/forget/src/HIR/HIRBuilder.ts
+7 -1
@@ -11,6 +11,7 @@ import { invariant } from "../CompilerError";
11 import {
12 BasicBlock,
13 BlockId,
14 + GeneratedSource,
15 GotoVariant,
16 HIR,
17 Identifier,
@@ -145,7 +146,12 @@ export default class HIRBuilder {
146 this.#completed.set(blockId, {
147 id: blockId,
148 instructions,
148 - terminal: { kind: "return", value: null, id: makeInstructionId(0) },
149 + terminal: {
150 + kind: "return",
151 + loc: GeneratedSource,
152 + value: null,
153 + id: makeInstructionId(0),
154 + },
155 preds: new Set(),
156 phis: new Set(),
157 });
compiler/forget/src/HIR/HIRTreeVisitor.ts
+2 -1
@@ -74,6 +74,7 @@ class Driver<TBlock, TValue, TItem, TCase> {
74 blockValue,
75 this.visitor.visitTerminal({
76 kind: "return",
77 + loc: terminal.loc,
78 value,
79 })
80 );
@@ -697,7 +698,7 @@ export interface Visitor<TBlock, TValue, TItem, TCase> {
698 }
699
700 export type BlockTerminal<TBlock, TValue, TItem, TCase> =
700 - | { kind: "return"; value: TValue | null }
701 + | { kind: "return"; loc: SourceLocation; value: TValue | null }
702 | { kind: "throw"; value: TValue }
703 | {
704 kind: "if";
compiler/forget/src/HIR/visitors.ts
+1
@@ -193,6 +193,7 @@ export function mapTerminalSuccessors(
193 case "return": {
194 return {
195 kind: "return",
196 + loc: terminal.loc,
197 value: terminal.value,
198 id: makeInstructionId(0),
199 };