首页 > 编程知识 正文

相亲对象,vo对象指的是什么

时间:2023-05-03 10:48:50 阅读:151297 作者:2544

原文链接: https://github.com/s able/soot/wiki/fundamental-soot-objects

Soot有巨大而复杂的类继承关系。 本文档介绍了最重要的类,以便于Soot的扩展开发。

对以下概念进行说明。BodyUnit,3358www.Sina.com/,Local,http://www.Sina.com

一切关于http://www.Sina.com/(s )

在Creating a class from scratch (链接: https://github.com/s able/soot/wiki/creating-a-class-from-scratch )文档中

Soot使用Value存储方法的代码。 Soot有UnitBoxValueBoxBody和3358www.Sina.com/四种Body,分别是

请记住,“链”(chain )就像一个列表的数据结构,提供对链中元素的一定时间内的访问,例如插入和删除。

3358www.Sina.com/中的三个主要链是Body的链、Body链和Body链本例说明了这三个链中每一个链的作用。

考虑以下Java方法:

publicstaticvoidmain (string [ ] argv ) Throwsexception(intx=2,y=6; system.out.println('hi!' ); system.out.println(x*y ); try{int z=y*x; }catch(exceptione ) {throw e; }

将其转换为Jimple代码后,有以下简短的Jimple代码:

publicstaticvoidmain (Java.lang.string [ ] ) throws Java.lang.exception { Java.lang.string [ ] r0; int i0,i1,i2,$i3,$i4; java.io.PrintStream $r1,$r2; java.lang.Exception $r3,r4; r0 :=@parameter0; i0=2; i1=6; $r1=java.lang.System.out; $R1.println('hi!' '; $r2=java.lang.System.out; $i3=i0*i1; $i4=$i3 i1; $R2.println($I4 ); label0:i2=i1*i0; 标签1:谷歌标签3; label 2: $ r 3:=@ caught exception; r4=$r3; throw r4; 标签3:返回; catch Java.lang.exceptionfromlabel0to label1with label 2; } Local变量

此方法的locals位于此方法的开头:

java.lang.String[]r0;

BafBodyi0、i1、i2、$i3、$i4;

java.io.PrintStream$r1,$r2;

java.lang.Exception$r3,r4;

3358www.Sina.com/(s )收集于JimpleBody并可从ShimpleBody访问。 各个中间显示有针对GrimpBody的独自实现; 这些实现必须确保对于每个定义3358www.Sina.com/可以调用BodyUnits请注意,local变量必须具有类型。

Locals

为了支持Java异常处理,请访问Soot的3358www.Sina.com/或Traps

trong>这一概念。其观点是在Java字节码中,异常处理程序是由一个多元组(异常、开始点、结束点、处理程序)表示;在开始和结束单元之间(包括开始处,但不包括结束处),如果异常被抛出,则执行处理程序。

在上面这个例子中,有一个trap:

catch java.lang.Exception from label0 to label1 with label2;

 

Units

Body中最有意思的部分即Unit(s)链(chain),这是Body中的实际代码。Jimple用Stmt实现了Unit,Grimp则用Inst来实现。这表明每个中间表示(IR)有它自己的对语句(statement)的概念。

Jimple Stmt中的一个例子便是AssignStmt,这代表一条Jimple的分配语句。AssignStmt可能是下面这种形式:

x = y + z;

 

Value

代码通常会对数据进行操作。为了表示数据,Soot提供了Value接口。下面是一些不同类型的Value(s):

Local(s)

Constant(s)

n  表达式(Expr

ParameterRef(s), CaughtExceptionRef(s)和 ThisRef(s)

Expr接口,反过来,有一整套实现;其中有NewExprAddExpr。通常,一个Expr会对一个或多个Value(s)执行一些动作并返回另一个Value

下面是使用Value(s)的一个例子:

x = y + 2;

这是一个AssignStmt,左操作数是x,右操作数是y+2,右操作数是一个AddExpr。这个AddExpr反过来包含Value(s) y2作为它的操作数;前一个操作数是一个Local,后一个操作数是一个Constant

在Jimple中,我们强制要求所有的Value(s)最多包含一个表达式(contain at most 1 expression)。Grimp则没有这个限制,这使得其产生的代码很容易阅读但很难分析。

 

Boxes

Boxes在Soot中无处不在。主要要记住就是一个Box是一个指针,它提供对Soot对象的间接访问。

对于Box,更具描述性的名称可能是Ref。但不幸的是,在Soot中Ref代表其它的意思。

在Soot中有两类Box(es),分别为ValueBoxUnitBox。一个UnitBox包含Unit(s),一个ValueBox包含Value(s),在C++中,分别表示为(Unit*)和(Value*)。

下面将描述每一种Box

 

UnitBox

某些Unit(s)可能需要包含对其它Unit(s)的引用。比如,一个GotoStmt需要知道它的目标是什么。因此,Soot提供了UnitBoxUnitBox是一个包含了一个Unit的Box。

考虑下面的Jimple代码:

    x = 5;     goto l2;     y = 3; l2: z = 9;

每个Unit都必须提供getUnitBoxes()方法,对于大多数UnitBox(es)而言,这个方法会返回一个空列表,对于GotoStmt而言,getUnitBoxes()方法将会返回包含一个元素的列表。包含一个指向l2的Box

注意到对于SwitchStmt而言,通常getUnitBoxes()方法将会返回包含许多boxes的列表。

Box的概念对于修改代码而言最为有用。比如我们有下面一条语句s:

s: goto l2;

在l2处有一个Stmt:

l2: goto l3; 很明显,不管s的实际类型是什么,s可以指向l3而不指向l2。因此对于各种类型的Unit(s),我们可以统一做下面的事情:

public void readjustJumps(Unit s, Unit oldU, Unit newU){ Iterator ubIt = s.getUnitBoxes.iterator(); while (ubIt.hasNext()) { StmtBox tb = (StmtBox)ubIt.next(); Stmt targ = (Stmt)tb.getUnit(); if (targ == oldU) tb.setUnit(newU); }} Unit自身使用了一些与上面类似的代码,这样便能够创建PatchingChainPatchingChain是对Chain的一种实现,它能够调整那些指向将要从Chain中删除的Unit(s)的指针。


ValueBox

类似于Unit(s),我们经常需要指向Value的指针。这由ValueBox 类表示。对于一个Unit,我们可以获得ValueBox的列表,包括在这个Unit中已使用和被定义的值(values)。

我们可以利用这些boxes来进行常数合并(constant folding):对于一个AssignStmt,其计算一个AddExpr,将两个常数值相加,我们则可以静态的将它们相加然后把结果放置到UseBox

下面是一个合并 AddExpr 的例子:

public void foldAdds(Unit u){ Iterator ubIt = u.getUseBoxes().iterator(); while (ubIt.hasNext()) { ValueBox vb = (ValueBox) ubIt.next(); Value v = vb.getValue(); if (v instanceof AddExpr) { AddExpr ae = (AddExpr) v; Value lo = ae.getOp1(), ro = ae.getOp2(); if (lo instanceof IntConstant && ro instanceof IntConstant) { IntConstant l = (IntConstant) lo, r = (IntConstant) ro; int sum = l.value + r.value; vb.setValue(IntConstant.v(sum)); } } }} 注意到不管Unit 的类型是什么,这都适用。


Unit 重新访问

我们现在讨论任何Unit 都必须提供的几种不同的方法。

public List getUseBoxes();public List getDefBoxes();public List getUseAndDefBoxes(); 上面三个方法返回在该Unit被使用、被定义或二者兼有的ValueBox(s)的一个List(s),对于getUseBoxes(),它返回所有被使用的值(values),包括表达式以及这些表达式的组成部分。

public List getUnitBoxes(); 这个方法返回由该方法指向的的unit 的UnitBox(es)的一个List

public List getBoxesPointingToThis(); 这个方法返回UnitBox(es)的列表,这些UnitBox都指向此Unit(即调用这个方法的Unit)。

public boolean fallsThrough();public boolean branches(); 这些方法处理该Unit之后的的执行流,前面一个方法返回真如果可以接着执行接下来的Unit,后面一个方法返回真如果执行流可能流入其他的Unit,这个Unit不是紧跟当前Unit之后的Unit。

public void redirectJumpsToThisTo(Unit newLocation); 这个方法使用getBoxesPointingToThis()来改变所有跳转至该Unit的跳转语句,将它们指向newLocation



版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。