1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14import { BaseEdge, BaseExplicitGraph, BaseNode, NodeID } from '../core/graph/BaseExplicitGraph'; 15import { CallGraph } from '../callgraph/model/CallGraph'; 16import { ArkAssignStmt, Stmt } from '../core/base/Stmt'; 17import { GraphPrinter } from '../save/GraphPrinter'; 18import { PrinterBuilder } from '../save/PrinterBuilder'; 19 20/** 21 * Direct value flow graph 22 * Consist of stmt(node) and direct Def-Use edge 23 * Is basic of VFG. And VFG is building on DVFG 24 */ 25export class DVFG extends BaseExplicitGraph { 26 private cg: CallGraph; 27 private stmtToVFGMap: Map<Stmt, NodeID>; 28 constructor(cg: CallGraph) { 29 super(); 30 this.cg = cg; 31 this.stmtToVFGMap = new Map(); 32 } 33 34 public getCG(): CallGraph { 35 return this.cg; 36 } 37 38 public getGraphName(): string { 39 return 'Direct-VFG'; 40 } 41 42 public getOrNewDVFGNode(stmt: Stmt): DVFGNode { 43 let node = this.stmtToVFGMap.get(stmt); 44 if (node) { 45 return this.getNode(node)! as DVFGNode; 46 } 47 48 let kind: DVFGNodeKind = DVFGNodeKind.normal; 49 if (stmt instanceof ArkAssignStmt) { 50 //TODO: split assign to copy, write, load 51 kind = DVFGNodeKind.assign; 52 } else { 53 // TODO: handle other type of stmt 54 } 55 56 return this.addDVFGNode(stmt, kind); 57 } 58 59 public addDVFGNode(stmt: Stmt, kind: DVFGNodeKind): DVFGNode { 60 let id: NodeID = this.nodeNum; 61 let dvfgNode = new DVFGNode(id, kind, stmt); 62 63 this.addNode(dvfgNode); 64 this.stmtToVFGMap.set(stmt, dvfgNode.getID()); 65 return dvfgNode; 66 } 67 68 public addDVFGEdge(src: DVFGNode, dst: DVFGNode): boolean { 69 let kind = 0; //common kind 70 let edge = new DVFGEdge(src, dst, kind); 71 if (this.ifEdgeExisting(edge)) { 72 return false; 73 } 74 75 src.addOutgoingEdge(edge); 76 dst.addIncomingEdge(edge); 77 78 return true; 79 } 80 81 public dump(name: string): void { 82 let printer = new GraphPrinter<this>(this); 83 PrinterBuilder.dump(printer, name); 84 } 85} 86 87export enum DVFGNodeKind { 88 assign, 89 copy, 90 write, 91 load, 92 addr, 93 if, 94 actualParm, 95 formalParm, 96 actualRet, 97 formalRet, 98 unary, 99 binary, 100 normal, 101} 102 103export class DVFGNode extends BaseNode { 104 private stmt: Stmt; 105 106 constructor(i: NodeID, k: DVFGNodeKind, s: Stmt) { 107 super(i, k); 108 this.stmt = s; 109 } 110 111 public getDotLabel(): string { 112 let label: string = 'ID: ' + this.getID() + '\n'; 113 label = label + this.stmt.toString(); 114 return label; 115 } 116 117 public getStmt(): Stmt { 118 return this.stmt; 119 } 120} 121 122export class DVFGEdge extends BaseEdge {} 123