• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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