C backend: more bugfixes

* Fix cloning Object[] in 64-bit systems
* Fix generation of x instanceof Interface
* Fix a % b when a and b are float or double
* Fix generation of unreachable virtual calls
This commit is contained in:
Alexey Andreev 2018-05-05 23:35:17 +03:00
parent c11b868c0b
commit 37efbd742b
4 changed files with 63 additions and 18 deletions

View File

@ -247,7 +247,7 @@ public class TObject {
} else { } else {
RuntimeArray array = (RuntimeArray) self; RuntimeArray array = (RuntimeArray) self;
copy = Allocator.allocateArray(cls, array.size).toStructure(); copy = Allocator.allocateArray(cls, array.size).toStructure();
int itemSize = (cls.itemType.flags & RuntimeClass.PRIMITIVE) == 0 ? 4 : cls.itemType.size; int itemSize = (cls.itemType.flags & RuntimeClass.PRIMITIVE) == 0 ? Address.sizeOf() : cls.itemType.size;
Address headerSize = Address.align(Address.fromInt(Structure.sizeOf(RuntimeArray.class)), itemSize); Address headerSize = Address.align(Address.fromInt(Structure.sizeOf(RuntimeArray.class)), itemSize);
size = itemSize * array.size + headerSize.toInt(); size = itemSize * array.size + headerSize.toInt();
} }

View File

@ -772,7 +772,7 @@ public class ClassGenerator {
for (int i = 1; i < ranges.size(); ++i) { for (int i = 1; i < ranges.size(); ++i) {
lower = ranges.get(i - 1).upper; lower = ranges.get(i - 1).upper;
upper = ranges.get(i).lower; upper = ranges.get(i).lower;
isSupertypeWriter.println("if (tag >= " + lower + " || tag < " + upper + ") return INT32_C(0);"); isSupertypeWriter.println("if (tag >= " + lower + " && tag < " + upper + ") return INT32_C(0);");
} }
isSupertypeWriter.println("return INT32_C(1);"); isSupertypeWriter.println("return INT32_C(1);");

View File

@ -66,6 +66,7 @@ import org.teavm.model.ClassReader;
import org.teavm.model.MethodReader; import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
import org.teavm.model.classes.VirtualTable;
import org.teavm.runtime.Allocator; import org.teavm.runtime.Allocator;
import org.teavm.runtime.ExceptionHandling; import org.teavm.runtime.ExceptionHandling;
import org.teavm.runtime.RuntimeClass; import org.teavm.runtime.RuntimeClass;
@ -140,6 +141,28 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
return; return;
} }
case MODULO: {
switch (expr.getType()) {
case FLOAT:
writer.print("fmodf(");
expr.getFirstOperand().acceptVisitor(this);
writer.print(", ");
expr.getSecondOperand().acceptVisitor(this);
writer.print(")");
return;
case DOUBLE:
writer.print("fmod(");
expr.getFirstOperand().acceptVisitor(this);
writer.print(", ");
expr.getSecondOperand().acceptVisitor(this);
writer.print(")");
return;
default:
break;
}
break;
}
default: default:
break; break;
} }
@ -372,28 +395,47 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
break; break;
} }
case DYNAMIC: { case DYNAMIC: {
String receiver = "recv_" + temporaryReceiverLevel++; VirtualTable vtable = context.getVirtualTableProvider().lookup(expr.getMethod().getClassName());
maxTemporaryReceiverLevel = Math.max(maxTemporaryReceiverLevel, temporaryReceiverLevel); if (vtable == null || !vtable.getEntries().containsKey(expr.getMethod().getDescriptor())) {
writer.print("((").print(receiver).print(" = "); writer.print("(");
expr.getArguments().get(0).acceptVisitor(this); for (Expr arg : expr.getArguments()) {
arg.acceptVisitor(this);
writer.print(", ");
}
printDefaultValue(expr.getMethod().getReturnType());
writer.print(")");
} else {
String receiver = "recv_" + temporaryReceiverLevel++;
maxTemporaryReceiverLevel = Math.max(maxTemporaryReceiverLevel, temporaryReceiverLevel);
writer.print("((").print(receiver).print(" = ");
expr.getArguments().get(0).acceptVisitor(this);
writer.print("), METHOD(") writer.print("), METHOD(")
.print(receiver).print(", ") .print(receiver).print(", ")
.print(names.forClassClass(expr.getMethod().getClassName())).print(", ") .print(names.forClassClass(expr.getMethod().getClassName())).print(", ")
.print(names.forVirtualMethod(expr.getMethod())) .print(names.forVirtualMethod(expr.getMethod()))
.print(")(").print(receiver); .print(")(").print(receiver);
for (int i = 1; i < expr.getArguments().size(); ++i) { for (int i = 1; i < expr.getArguments().size(); ++i) {
writer.print(", "); writer.print(", ");
expr.getArguments().get(i).acceptVisitor(this); expr.getArguments().get(i).acceptVisitor(this);
}
writer.print("))");
temporaryReceiverLevel--;
} }
writer.print("))");
temporaryReceiverLevel--;
break; break;
} }
} }
} }
private void printDefaultValue(ValueType type) {
if (type instanceof ValueType.Primitive) {
writer.print("0");
} else {
writer.print("NULL");
}
}
private void processInclude(AnnotationContainerReader container) { private void processInclude(AnnotationContainerReader container) {
AnnotationReader annot = container.get(Include.class.getName()); AnnotationReader annot = container.get(Include.class.getName());
if (annot == null) { if (annot == null) {

View File

@ -52,6 +52,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.util.Arrays; import java.util.Arrays;
@ -326,9 +327,11 @@ public class VectorTest {
Enumeration<Object> orgNum = tVector.elements(); Enumeration<Object> orgNum = tVector.elements();
Enumeration<Object> cnum = v.elements(); Enumeration<Object> cnum = v.elements();
int index = 0;
while (orgNum.hasMoreElements()) { while (orgNum.hasMoreElements()) {
assertTrue("Not enough elements copied", cnum.hasMoreElements()); assertTrue("Not enough elements copied", cnum.hasMoreElements());
assertTrue("Vector cloned improperly, elements do not match", orgNum.nextElement() == cnum.nextElement()); assertSame("Vector cloned improperly, element " + index++ + " does not match",
orgNum.nextElement(), cnum.nextElement());
} }
assertTrue("Not enough elements copied", !cnum.hasMoreElements()); assertTrue("Not enough elements copied", !cnum.hasMoreElements());
} }