Bytecode für Post-/Preincrement und Post-/Predecrement
This commit is contained in:
parent
3233ccd845
commit
e1c6369bcb
@ -175,10 +175,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
isAssignStmt =false;
|
isAssignStmt =false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Die folgeneden Fälle müssen noch betrachtet werden: - Long OPARATION Integer
|
|
||||||
* usw.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
|
|
||||||
@ -194,7 +191,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V",
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V",
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
// tmp!!
|
|
||||||
Label endLabel = new Label();
|
Label endLabel = new Label();
|
||||||
// this case for while loops
|
// this case for while loops
|
||||||
if(!isAssignStmt)
|
if(!isAssignStmt)
|
||||||
@ -687,35 +684,76 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
String typeOfUnary = getResolvedType(unaryExpr.getType());
|
String typeOfUnary = getResolvedType(unaryExpr.getType());
|
||||||
|
|
||||||
|
boolean isIncOrDec = false;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case POSTDECREMENT:
|
case POSTDECREMENT:
|
||||||
case POSTINCREMENT:
|
case POSTINCREMENT:
|
||||||
genBCForPostUnary(op, typeOfUnary);
|
if(isAssignStmt)
|
||||||
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
genBCForIncAndDec(op, typeOfUnary);
|
||||||
|
getValueOfIns(typeOfUnary);
|
||||||
|
isIncOrDec = true;
|
||||||
|
break;
|
||||||
|
case PREDECREMENT:
|
||||||
|
case PREINCREMENT:
|
||||||
|
genBCForIncAndDec(op, typeOfUnary);
|
||||||
|
getValueOfIns(typeOfUnary);
|
||||||
|
if(isAssignStmt)
|
||||||
|
mv.visitInsn(Opcodes.DUP);
|
||||||
|
isIncOrDec = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MINUS:
|
||||||
|
doVisitNegIns(typeOfUnary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
getValueOfIns(typeOfUnary);
|
|
||||||
if(unaryExpr.expr instanceof LocalVar) {
|
// Für Byte und Short muss noch einen Cast geben i2b, i2s
|
||||||
|
// das wird später gemacht, da bytecode für cast noch nicht erzeugt wird
|
||||||
|
|
||||||
|
if(isIncOrDec && (unaryExpr.expr instanceof LocalVar)) {
|
||||||
LocalVar local = (LocalVar) unaryExpr.expr;
|
LocalVar local = (LocalVar) unaryExpr.expr;
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name));
|
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void genBCForPostUnary(Operation op, String typeOfUnary) {
|
private void doVisitNegIns(String typeOfUnary) {
|
||||||
if(isAssignStmt)
|
switch (typeOfUnary) {
|
||||||
mv.visitInsn(Opcodes.DUP);
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.LNEG);
|
||||||
|
break;
|
||||||
|
case "java/lang/Double":
|
||||||
|
mv.visitInsn(Opcodes.DNEG);
|
||||||
|
break;
|
||||||
|
case "java/lang/Float":
|
||||||
|
mv.visitInsn(Opcodes.FNEG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mv.visitInsn(Opcodes.INEG);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void genBCForIncAndDec(Operation op, String typeOfUnary) {
|
||||||
|
|
||||||
getVlaueIns(typeOfUnary);
|
getVlaueIns(typeOfUnary);
|
||||||
doAssign(typeOfUnary, 1.0, true);
|
doAssign(typeOfUnary, 1.0, true);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case POSTDECREMENT:
|
case POSTDECREMENT:
|
||||||
throw new NotImplementedException();
|
case PREDECREMENT:
|
||||||
|
doVisitSubOpInsn(typeOfUnary);
|
||||||
|
break;
|
||||||
|
|
||||||
case POSTINCREMENT:
|
case POSTINCREMENT:
|
||||||
|
case PREINCREMENT:
|
||||||
doVisitAddOpInsn(typeOfUnary);
|
doVisitAddOpInsn(typeOfUnary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,13 @@ public class PostIncTest {
|
|||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpBeforeClass() throws Exception {
|
public static void setUpBeforeClass() throws Exception {
|
||||||
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/PostInc.jav";
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/PostIncDec.jav";
|
||||||
fileToTest = new File(path);
|
fileToTest = new File(path);
|
||||||
compiler = new JavaTXCompiler(fileToTest);
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
compiler.generateBytecode();
|
compiler.generateBytecode();
|
||||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
classToTest = loader.loadClass("PostInc");
|
classToTest = loader.loadClass("PostIncDec");
|
||||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,5 +47,19 @@ public class PostIncTest {
|
|||||||
Integer res = (Integer) m.invoke(instanceOfClass);
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
assertEquals(0, res);
|
assertEquals(0, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD1() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(-1, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d2");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(0, res);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
65
test/bytecode/PreIncTest.java
Normal file
65
test/bytecode/PreIncTest.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class PreIncTest {
|
||||||
|
private static String path;
|
||||||
|
private static File fileToTest;
|
||||||
|
private static JavaTXCompiler compiler;
|
||||||
|
private static ClassLoader loader;
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static String pathToClassFile;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/PreInc.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode();
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://" + pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("PreInc");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(1, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m2");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(1, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(-1, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d2");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(-1, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
|
|
||||||
public class PostInc {
|
|
||||||
m() {
|
|
||||||
var i = 0;
|
|
||||||
i++;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
m2() {
|
|
||||||
var i = 0;
|
|
||||||
var j = i++;
|
|
||||||
return j;
|
|
||||||
}
|
|
||||||
}
|
|
27
test/bytecode/javFiles/PostIncDec.jav
Normal file
27
test/bytecode/javFiles/PostIncDec.jav
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public class PostIncDec {
|
||||||
|
m() {
|
||||||
|
var i = 0;
|
||||||
|
i++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
m2() {
|
||||||
|
var i = 0;
|
||||||
|
var j = i++;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
d() {
|
||||||
|
var i = 0;
|
||||||
|
i--;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
d2() {
|
||||||
|
var i = 0;
|
||||||
|
var j = i--;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
28
test/bytecode/javFiles/PreInc.jav
Normal file
28
test/bytecode/javFiles/PreInc.jav
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public class PreInc {
|
||||||
|
m() {
|
||||||
|
var i = 0;
|
||||||
|
++i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
m2() {
|
||||||
|
var i = 0;
|
||||||
|
var j = ++i;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
d() {
|
||||||
|
var i = 0;
|
||||||
|
--i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
d2() {
|
||||||
|
var i = 0;
|
||||||
|
var j = --i;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user