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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Die folgeneden Fälle müssen noch betrachtet werden: - Long OPARATION Integer
|
||||
* usw.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void visit(BinaryExpr binary) {
|
||||
|
||||
@ -194,7 +191,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V",
|
||||
false);
|
||||
}
|
||||
// tmp!!
|
||||
|
||||
Label endLabel = new Label();
|
||||
// this case for while loops
|
||||
if(!isAssignStmt)
|
||||
@ -687,35 +684,76 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
String typeOfUnary = getResolvedType(unaryExpr.getType());
|
||||
|
||||
boolean isIncOrDec = false;
|
||||
|
||||
switch (op) {
|
||||
case POSTDECREMENT:
|
||||
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;
|
||||
|
||||
default:
|
||||
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;
|
||||
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name));
|
||||
}
|
||||
}
|
||||
|
||||
private void genBCForPostUnary(Operation op, String typeOfUnary) {
|
||||
if(isAssignStmt)
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
private void doVisitNegIns(String typeOfUnary) {
|
||||
switch (typeOfUnary) {
|
||||
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);
|
||||
doAssign(typeOfUnary, 1.0, true);
|
||||
|
||||
switch (op) {
|
||||
case POSTDECREMENT:
|
||||
throw new NotImplementedException();
|
||||
case PREDECREMENT:
|
||||
doVisitSubOpInsn(typeOfUnary);
|
||||
break;
|
||||
|
||||
case POSTINCREMENT:
|
||||
case PREINCREMENT:
|
||||
doVisitAddOpInsn(typeOfUnary);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -24,13 +24,13 @@ public class PostIncTest {
|
||||
|
||||
@BeforeClass
|
||||
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);
|
||||
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("PostInc");
|
||||
classToTest = loader.loadClass("PostIncDec");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@ -47,5 +47,19 @@ public class PostIncTest {
|
||||
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||
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