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 {
RuntimeArray array = (RuntimeArray) self;
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);
size = itemSize * array.size + headerSize.toInt();
}

View File

@ -772,7 +772,7 @@ public class ClassGenerator {
for (int i = 1; i < ranges.size(); ++i) {
lower = ranges.get(i - 1).upper;
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);");

View File

@ -66,6 +66,7 @@ import org.teavm.model.ClassReader;
import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
import org.teavm.model.classes.VirtualTable;
import org.teavm.runtime.Allocator;
import org.teavm.runtime.ExceptionHandling;
import org.teavm.runtime.RuntimeClass;
@ -140,6 +141,28 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
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:
break;
}
@ -372,28 +395,47 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
break;
}
case DYNAMIC: {
String receiver = "recv_" + temporaryReceiverLevel++;
maxTemporaryReceiverLevel = Math.max(maxTemporaryReceiverLevel, temporaryReceiverLevel);
writer.print("((").print(receiver).print(" = ");
expr.getArguments().get(0).acceptVisitor(this);
VirtualTable vtable = context.getVirtualTableProvider().lookup(expr.getMethod().getClassName());
if (vtable == null || !vtable.getEntries().containsKey(expr.getMethod().getDescriptor())) {
writer.print("(");
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(")
.print(receiver).print(", ")
.print(names.forClassClass(expr.getMethod().getClassName())).print(", ")
.print(names.forVirtualMethod(expr.getMethod()))
.print(")(").print(receiver);
for (int i = 1; i < expr.getArguments().size(); ++i) {
writer.print(", ");
expr.getArguments().get(i).acceptVisitor(this);
writer.print("), METHOD(")
.print(receiver).print(", ")
.print(names.forClassClass(expr.getMethod().getClassName())).print(", ")
.print(names.forVirtualMethod(expr.getMethod()))
.print(")(").print(receiver);
for (int i = 1; i < expr.getArguments().size(); ++i) {
writer.print(", ");
expr.getArguments().get(i).acceptVisitor(this);
}
writer.print("))");
temporaryReceiverLevel--;
}
writer.print("))");
temporaryReceiverLevel--;
break;
}
}
}
private void printDefaultValue(ValueType type) {
if (type instanceof ValueType.Primitive) {
writer.print("0");
} else {
writer.print("NULL");
}
}
private void processInclude(AnnotationContainerReader container) {
AnnotationReader annot = container.get(Include.class.getName());
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.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Arrays;
@ -326,9 +327,11 @@ public class VectorTest {
Enumeration<Object> orgNum = tVector.elements();
Enumeration<Object> cnum = v.elements();
int index = 0;
while (orgNum.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());
}