1/* 2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { 17 AbstractBinopExpr, 18 AbstractExpr, 19 AbstractInvokeExpr, 20 ArkAwaitExpr, 21 ArkCastExpr, 22 ArkDeleteExpr, 23 ArkInstanceInvokeExpr, 24 ArkInstanceOfExpr, 25 ArkNewArrayExpr, 26 ArkPtrInvokeExpr, 27 ArkTypeOfExpr, 28 ArkUnopExpr, 29 ArkYieldExpr, 30} from '../base/Expr'; 31import { Local } from '../base/Local'; 32import { Value } from '../base/Value'; 33import { AbstractFieldRef } from '../base/Ref'; 34 35/** 36 * Replace old use of a Expr inplace 37 */ 38export class ExprUseReplacer { 39 private oldUse: Value; 40 private newUse: Value; 41 42 constructor(oldUse: Value, newUse: Value) { 43 this.oldUse = oldUse; 44 this.newUse = newUse; 45 } 46 47 public caseExpr(expr: AbstractExpr): void { 48 if (expr instanceof AbstractBinopExpr) { 49 this.caseBinopExpr(expr); 50 } else if (expr instanceof AbstractInvokeExpr) { 51 this.caseInvokeExpr(expr); 52 } else if (expr instanceof ArkNewArrayExpr) { 53 this.caseNewArrayExpr(expr); 54 } else if (expr instanceof ArkTypeOfExpr) { 55 this.caseTypeOfExpr(expr); 56 } else if (expr instanceof ArkInstanceOfExpr) { 57 this.caseInstanceOfExpr(expr); 58 } else if (expr instanceof ArkCastExpr) { 59 this.caseCastExpr(expr); 60 } else if (expr instanceof ArkAwaitExpr) { 61 this.caseAwaitExpr(expr); 62 } else if (expr instanceof ArkYieldExpr) { 63 this.caseYieldExpr(expr); 64 } else if (expr instanceof ArkDeleteExpr) { 65 this.caseDeleteExpr(expr); 66 } else if (expr instanceof ArkUnopExpr) { 67 this.caseUnopExpr(expr); 68 } 69 } 70 71 private caseBinopExpr(expr: AbstractBinopExpr): void { 72 if (expr.getOp1() === this.oldUse) { 73 expr.setOp1(this.newUse); 74 } 75 if (expr.getOp2() === this.oldUse) { 76 expr.setOp2(this.newUse); 77 } 78 } 79 80 private caseInvokeExpr(expr: AbstractInvokeExpr): void { 81 let args = expr.getArgs(); 82 for (let i = 0; i < args.length; i++) { 83 if (args[i] === this.oldUse) { 84 args[i] = this.newUse; 85 } 86 } 87 88 if (expr instanceof ArkInstanceInvokeExpr && expr.getBase() === this.oldUse) { 89 expr.setBase(<Local> this.newUse); 90 } else if (expr instanceof ArkPtrInvokeExpr && expr.getFuncPtrLocal() === this.oldUse && this.newUse instanceof Local) { 91 expr.setFunPtrLocal(this.newUse); 92 } 93 } 94 95 private caseNewArrayExpr(expr: ArkNewArrayExpr): void { 96 if (expr.getSize() === this.oldUse) { 97 expr.setSize(this.newUse); 98 } 99 } 100 101 private caseTypeOfExpr(expr: ArkTypeOfExpr): void { 102 if (expr.getOp() === this.oldUse) { 103 expr.setOp(this.newUse); 104 } 105 } 106 107 private caseInstanceOfExpr(expr: ArkInstanceOfExpr): void { 108 if (expr.getOp() === this.oldUse) { 109 expr.setOp(this.newUse); 110 } 111 } 112 113 private caseCastExpr(expr: ArkCastExpr): void { 114 if (expr.getOp() === this.oldUse) { 115 expr.setOp(this.newUse); 116 } 117 } 118 119 private caseAwaitExpr(expr: ArkAwaitExpr): void { 120 if (expr.getPromise() === this.oldUse) { 121 expr.setPromise(this.newUse); 122 } 123 } 124 125 private caseDeleteExpr(expr: ArkDeleteExpr): void { 126 if (expr.getField() === this.oldUse && this.newUse instanceof AbstractFieldRef) { 127 expr.setField(this.newUse); 128 } 129 } 130 131 private caseYieldExpr(expr: ArkYieldExpr): void { 132 if (expr.getYieldValue() === this.oldUse) { 133 expr.setYieldValue(this.newUse); 134 } 135 } 136 137 private caseUnopExpr(expr: ArkUnopExpr): void { 138 if (expr.getOp() === this.oldUse) { 139 expr.setOp(this.newUse); 140 } 141 } 142} 143