| 1 | /** |
| 2 | * Copyright (c) Meta Platforms, Inc. and 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 | |
| 8 | import {HIRFunction, IdentifierId} from '../HIR'; |
| 9 | |
| 10 | export function outlineFunctions( |
| 11 | fn: HIRFunction, |
| 12 | fbtOperands: Set<IdentifierId>, |
| 13 | ): void { |
| 14 | for (const [, block] of fn.body.blocks) { |
| 15 | for (const instr of block.instructions) { |
| 16 | const {value, lvalue} = instr; |
| 17 | |
| 18 | if ( |
| 19 | value.kind === 'FunctionExpression' || |
| 20 | value.kind === 'ObjectMethod' |
| 21 | ) { |
| 22 | // Recurse in case there are inner functions which can be outlined |
| 23 | outlineFunctions(value.loweredFunc.func, fbtOperands); |
| 24 | } |
| 25 | if ( |
| 26 | value.kind === 'FunctionExpression' && |
| 27 | value.loweredFunc.func.context.length === 0 && |
| 28 | // TODO: handle outlining named functions |
| 29 | value.loweredFunc.func.id === null && |
| 30 | !fbtOperands.has(lvalue.identifier.id) |
| 31 | ) { |
| 32 | const loweredFunc = value.loweredFunc.func; |
| 33 | |
| 34 | const id = fn.env.generateGloballyUniqueIdentifierName( |
| 35 | loweredFunc.id ?? loweredFunc.nameHint, |
| 36 | ); |
| 37 | loweredFunc.id = id.value; |
| 38 | |
| 39 | fn.env.outlineFunction(loweredFunc, null); |
| 40 | instr.value = { |
| 41 | kind: 'LoadGlobal', |
| 42 | binding: { |
| 43 | kind: 'Global', |
| 44 | name: id.value, |
| 45 | }, |
| 46 | loc: value.loc, |
| 47 | }; |
| 48 | } |
| 49 | } |
| 50 | } |
| 51 | } |