Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jimple to JavaObjects to change minimaltestsuite #1162

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions sootup.core/src/main/java/sootup/core/model/Body.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,17 @@ public boolean isStmtBranchTarget(@Nonnull Stmt targetStmt) {
return getStmtGraph().isStmtBranchTarget(targetStmt);
}

/** Returns the last stmt in this body. */
@Nonnull
public Stmt getLastStmt() {
Iterator<Stmt> it = getStmts().iterator();
Stmt o = it.next();
while (it.hasNext()) {
o = it.next();
}
return o;
}

/** Returns the first non-identity stmt in this body. */
@Nonnull
public Stmt getFirstNonIdentityStmt() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package sootup.jimple.frontend.buildjavacode;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import sootup.core.jimple.basic.Local;
import sootup.core.jimple.common.constant.IntConstant;
import sootup.core.jimple.common.stmt.*;
import sootup.core.jimple.javabytecode.stmt.JEnterMonitorStmt;
import sootup.core.jimple.javabytecode.stmt.JExitMonitorStmt;
import sootup.core.jimple.javabytecode.stmt.JRetStmt;
import sootup.core.jimple.javabytecode.stmt.JSwitchStmt;
import sootup.core.model.Body;
import sootup.core.types.Type;

public class JavaCodeBuilder {

private final List<String> javaCodeObjects = new LinkedList<>();
Map<String, String> varAndType = new HashMap<>();
JavaCodeValueVisitor javaCodeValueVisitor = new JavaCodeValueVisitor();

public JavaCodeBuilder(Body body) {
this.initJavaCode();
this.createStmtGraph(body);
this.createMethod();
this.createClass();
}

public List<String> getJavaCodeObjects() {
return javaCodeObjects;
}

public void createClass() {
JavaCodeClassSpec javaCodeClassSpec = new JavaCodeClassSpec();
javaCodeClassSpec.addModifier("public");
String classString = javaCodeClassSpec.build();
javaCodeObjects.add(classString);
}

public void createMethod() {
JavaCodeMethodSpec javaCodeMethodSpec = new JavaCodeMethodSpec();
javaCodeMethodSpec.addMethodSignature("dummyMain", "main", "void", "Collections.empty()");
javaCodeMethodSpec.addModifier("public").addModifier("static");
String methodStr = javaCodeMethodSpec.build();
javaCodeObjects.add(methodStr);
}

public void createStmtGraph(Body body) {
javaCodeObjects.add("MutableStmtGraph stmtGraph = bodyBuilder.getStmtGraph();");
javaCodeObjects.add(String.format("stmtGraph.setStartingStmt(%s);", body.getFirstNonIdentityStmt()));
// TODO: loop over statements and put edges
javaCodeObjects.add(String.format("stmtGraph.putEdge(%s, %s)", body.getFirstNonIdentityStmt(), body.getLastStmt()));
}

public void initJavaCode() {
javaCodeObjects.add("Body.BodyBuilder bodyBuilder = Body.builder()");
javaCodeObjects.add(
String.format(
"JavaIdentifierFactory %s = JavaIdentifierFactory.getInstance();", "factory"));
javaCodeObjects.add(
String.format(
"StmtPositionInfo %s = StmtPositionInfo.getNoStmtPositionInfo();",
"noStmtPositionInfo"));
}

public void addThisRef(Local leftOp, Type classType) {
javaCodeObjects.add(
String.format(
"IdentityRef %s = JavaJimple.newThisRef(factory.getClassType(\"%s\"));",
leftOp.getName(), classType));
}

public void addLocal(Local value) {
javaCodeObjects.add(
String.format(
"Local %s = JavaJimple.newLocal(\"%s\", factory.getClassType(\"%s\"));",
value, value.getName(), value.getType()));
}

public void addAssignment(JAssignStmt stmt) {
String typeString = "";
if (stmt.getRightOp() instanceof IntConstant) {
typeString =
String.format(
"IntConstant.getInstance(%s)", ((IntConstant) stmt.getRightOp()).getValue());
} else if (stmt.getRightOp() instanceof Local) {
typeString =
String.format(
"JavaJimple.newLocal(\"%s\", factory.getClassType(\"%s\"))",
((Local) stmt.getRightOp()).getName(), stmt.getRightOp().getType());
}
javaCodeObjects.add(
String.format(
"Stmt %s = JavaJimple.newAssignment(JavaJimple.newLocal(\"%s\", factory.classType(\"%s\")), %s , noStmtPositionInfo)",
stmt.getLeftOp(),
stmt.getLeftOp(),
stmt.getType(),
typeString));
}

public void addNop(JNopStmt stmt) {
javaCodeObjects.add(
String.format("Stmt nop = new JNopStmt(StmtPositionInfo.getNoStmtPositionInfo())"));
}

public void addGoto(JGotoStmt stmt) {
javaCodeObjects.add(
String.format("Stmt stmt1 = new JGotoStmt(StmtPositionInfo.getNoStmtPositionInfo());"));
}

public void addJRet(JRetStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt stmt = new JRetStmt(%s, StmtPositionInfo.getNoStmtPositionInfo());",
stmt.getStmtAddress()));
}

public void addJReturn(JReturnStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt jreturn = new JReturnStmt(%s, StmtPositionInfo.getNoStmtPositionInfo());",
stmt.getOp()));
}

public void addJThrow(JThrowStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt jthrow = new JThrowStmt(%s, StmtPositionInfo.getNoStmtPositionInfo());",
stmt.getOp()));
}

public void addJSwitch(JSwitchStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt jswitch = new JSwitchStmt(%s, %s, StmtPositionInfo.getNoStmtPositionInfo());",
stmt.getKey(), stmt.getValues()));
}

public void addJReturnVoid(JReturnVoidStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt jreturnvoid = new JReturnVoidStmt(StmtPositionInfo.getNoStmtPositionInfo());"));
}

public void addIf(JIfStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt jif = Jimple.newIfStmt(%s, StmtPositionInfo.getNoStmtPositionInfo());",
stmt.getCondition()));
}

public void addJExitMonitor(JExitMonitorStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt jexitmonitor = new JExitMonitorStmt(%s, StmtPositionInfo.getNoStmtPositionInfo());",
stmt.getOp()));
}

public void addJEnterMonitor(JEnterMonitorStmt stmt) {
javaCodeObjects.add(
String.format(
"Stmt jentermonitor = new JEnterMonitorStmt(%s, StmtPositionInfo.getNoStmtPositionInfo());",
stmt.getOp()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package sootup.jimple.frontend.buildjavacode;

import java.util.ArrayList;
import java.util.List;

public class JavaCodeClassSpec {
private final List<String> modifiers = new ArrayList<>();
private final List<JavaCodeMethodSpec> methods = new ArrayList<>();

public JavaCodeClassSpec addModifier(String modifier) {
if (modifier != null && !modifier.isEmpty()) {
modifiers.add("MethodModifier." + modifier.toUpperCase());
}
return this;
}

public JavaCodeClassSpec addMethod(JavaCodeMethodSpec javaCodeMethodSpec) {
methods.add(javaCodeMethodSpec);
return this;
}

public String build() {
StringBuilder builder = new StringBuilder();
String modifiersString = String.join(", ", modifiers);
builder.append("JavaSootClass mainClass = new JavaSootClass(new OverridingJavaClassSource(")
.append("new EagerInputLocation(),")
.append("null,")
.append("view.getIdentifierFactory().getClassType(\"dummyMain\"),")
.append("null,")
.append("Collections.emptySet(),")
.append("null,")
.append("Collections.emptySet(),")
.append("Collections.singleton(dummyMainMethod),")
.append("NoPositionInformation.getInstance(),")
.append("EnumSet.of(").append(modifiersString).append("),")
.append("Collections.emptyList(),")
.append("Collections.emptyList(),")
.append("Collections.emptyList()),")
.append("SourceType.Application);");

return builder.toString();
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sootup.jimple.frontend.buildjavacode;

import java.util.ArrayList;
import java.util.List;

public class JavaCodeMethodSpec {
private static StringBuilder javaCodeMethodSignature = new StringBuilder();
private final List<JavaCodeStmtSpec> statements = new ArrayList<>();
private final List<String> modifiers = new ArrayList<>();

public JavaCodeMethodSpec addMethodSignature(String clsSig, String methodName, String returnType, String parameters) {
javaCodeMethodSignature.append("MethodSignature methodSignature = view.getIdentifierFactory().getMethodSignature(")
.append("\"").append(clsSig).append("\"")
.append("\"").append(methodName).append("\"")
.append("\"").append(returnType).append("\"")
.append("\"").append(parameters).append("\"")
.append(");");
return this;
}

public JavaCodeMethodSpec addModifier(String modifier) {
if (modifier != null && !modifier.isEmpty()) {
modifiers.add("MethodModifier." + modifier.toUpperCase());
}
return this;
}

public JavaCodeMethodSpec addStatement(JavaCodeStmtSpec statement) {
statements.add(statement);
return this;
}

public String build() {
StringBuilder builder = new StringBuilder();
String modifiersString = String.join(", ", modifiers);

builder.append("JavaSootMethod dummyMainMethod = new JavaSootMethod(")
.append("new OverridingBodySource(methodSignature, body),")
.append("methodSignature,")
.append("EnumSet.of(").append(modifiersString).append("),")
.append("Collections.emptyList(),")
.append("Collections.emptyList(),")
.append("NoPositionInformation.getInstance());");

return builder.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package sootup.jimple.frontend.buildjavacode;

public class JavaCodeStmtSpec {
private final String stmt;

private JavaCodeStmtSpec(String stmt) {
this.stmt = stmt;
}

public static JavaCodeStmtSpec identity(String variable, String type) {
return new JavaCodeStmtSpec(variable + " := @" + type);
}

public static JavaCodeStmtSpec assign(String variable, String value) {
return new JavaCodeStmtSpec(variable + " = " + value + ";");
}

public static JavaCodeStmtSpec ifStmt(String condition) {
return new JavaCodeStmtSpec("if (" + condition + ") {");
}

public static JavaCodeStmtSpec endBlock() {
return new JavaCodeStmtSpec("}");
}

public String build() {
return stmt;
}
}
Loading
Loading