mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Fix generation of integer multiplication in minified mode. Fix String.intern() (see #370)
This commit is contained in:
parent
5db4c11e10
commit
d968b20e4c
|
@ -34,6 +34,7 @@ import org.teavm.ast.NativeMethodNode;
|
||||||
import org.teavm.ast.NewArrayExpr;
|
import org.teavm.ast.NewArrayExpr;
|
||||||
import org.teavm.ast.NewExpr;
|
import org.teavm.ast.NewExpr;
|
||||||
import org.teavm.ast.NewMultiArrayExpr;
|
import org.teavm.ast.NewMultiArrayExpr;
|
||||||
|
import org.teavm.ast.OperationType;
|
||||||
import org.teavm.ast.QualificationExpr;
|
import org.teavm.ast.QualificationExpr;
|
||||||
import org.teavm.ast.RecursiveVisitor;
|
import org.teavm.ast.RecursiveVisitor;
|
||||||
import org.teavm.ast.RegularMethodNode;
|
import org.teavm.ast.RegularMethodNode;
|
||||||
|
@ -200,6 +201,12 @@ class NameFrequencyEstimator extends RecursiveVisitor implements MethodNodeVisit
|
||||||
case COMPARE:
|
case COMPARE:
|
||||||
consumer.consumeFunction("$rt_compare");
|
consumer.consumeFunction("$rt_compare");
|
||||||
break;
|
break;
|
||||||
|
case MULTIPLY:
|
||||||
|
if (expr.getType() == OperationType.INT && !RenderingUtil.isSmallInteger(expr.getFirstOperand())
|
||||||
|
&& !RenderingUtil.isSmallInteger(expr.getSecondOperand())) {
|
||||||
|
consumer.consumeFunction("$rt_imul");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,7 @@ public class Renderer implements RenderingManager {
|
||||||
private void renderRuntimeAliases() throws IOException {
|
private void renderRuntimeAliases() throws IOException {
|
||||||
String[] names = { "$rt_throw", "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray",
|
String[] names = { "$rt_throw", "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray",
|
||||||
"$rt_isInstance", "$rt_nativeThread", "$rt_suspending", "$rt_resuming", "$rt_invalidPointer",
|
"$rt_isInstance", "$rt_nativeThread", "$rt_suspending", "$rt_resuming", "$rt_invalidPointer",
|
||||||
"$rt_s", "$rt_eraseClinit" };
|
"$rt_s", "$rt_eraseClinit", "$rt_imul" };
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String name : names) {
|
for (String name : names) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
|
|
|
@ -19,6 +19,8 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.teavm.ast.ConstantExpr;
|
||||||
|
import org.teavm.ast.Expr;
|
||||||
|
|
||||||
public final class RenderingUtil {
|
public final class RenderingUtil {
|
||||||
public static final Set<String> KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("break", "case",
|
public static final Set<String> KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("break", "case",
|
||||||
|
@ -98,4 +100,18 @@ public final class RenderingUtil {
|
||||||
public static String indexToId(int index) {
|
public static String indexToId(int index) {
|
||||||
return indexToId(index, VARIABLE_START_CHARS);
|
return indexToId(index, VARIABLE_START_CHARS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isSmallInteger(Expr expr) {
|
||||||
|
if (!(expr instanceof ConstantExpr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object constant = ((ConstantExpr) expr).getValue();
|
||||||
|
if (!(constant instanceof Integer)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value = (Integer) constant;
|
||||||
|
return Math.abs(value) < (1 << 18);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,7 @@ public class RuntimeRenderer {
|
||||||
|
|
||||||
private static final MethodReference NPE_INIT_METHOD = new MethodReference(NullPointerException.class,
|
private static final MethodReference NPE_INIT_METHOD = new MethodReference(NullPointerException.class,
|
||||||
"<init>", void.class);
|
"<init>", void.class);
|
||||||
private static final MethodDescriptor STRING_INTERN_METHOD = new MethodDescriptor("intern",
|
private static final MethodDescriptor STRING_INTERN_METHOD = new MethodDescriptor("intern", String.class);
|
||||||
String.class, String.class);
|
|
||||||
private static final MethodDescriptor CURRENT_THREAD_METHOD = new MethodDescriptor("currentThread",
|
private static final MethodDescriptor CURRENT_THREAD_METHOD = new MethodDescriptor("currentThread",
|
||||||
Thread.class);
|
Thread.class);
|
||||||
private static final MethodReference STACK_TRACE_ELEM_INIT = new MethodReference(StackTraceElement.class,
|
private static final MethodReference STACK_TRACE_ELEM_INIT = new MethodReference(StackTraceElement.class,
|
||||||
|
@ -154,7 +153,7 @@ public class RuntimeRenderer {
|
||||||
writer.append("function $rt_intern(str) {").indent().softNewLine();
|
writer.append("function $rt_intern(str) {").indent().softNewLine();
|
||||||
ClassReader stringCls = classSource.get(STRING_CLASS);
|
ClassReader stringCls = classSource.get(STRING_CLASS);
|
||||||
if (stringCls != null && stringCls.getMethod(STRING_INTERN_METHOD) != null) {
|
if (stringCls != null && stringCls.getMethod(STRING_INTERN_METHOD) != null) {
|
||||||
writer.append("return ").appendMethodBody(new MethodReference(String.class, "intern", String.class))
|
writer.append("return ").appendMethodBody(new MethodReference(STRING_CLASS, STRING_INTERN_METHOD))
|
||||||
.append("(str);").softNewLine();
|
.append("(str);").softNewLine();
|
||||||
} else {
|
} else {
|
||||||
writer.append("return str;").softNewLine();
|
writer.append("return str;").softNewLine();
|
||||||
|
|
|
@ -694,8 +694,8 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
|
||||||
visitBinary(expr, "-", expr.getType() == OperationType.INT);
|
visitBinary(expr, "-", expr.getType() == OperationType.INT);
|
||||||
break;
|
break;
|
||||||
case MULTIPLY:
|
case MULTIPLY:
|
||||||
if (expr.getType() != OperationType.INT || isSmallInteger(expr.getFirstOperand())
|
if (expr.getType() != OperationType.INT || RenderingUtil.isSmallInteger(expr.getFirstOperand())
|
||||||
|| isSmallInteger(expr.getSecondOperand())) {
|
|| RenderingUtil.isSmallInteger(expr.getSecondOperand())) {
|
||||||
visitBinary(expr, "*", expr.getType() == OperationType.INT);
|
visitBinary(expr, "*", expr.getType() == OperationType.INT);
|
||||||
} else {
|
} else {
|
||||||
visitBinaryFunction(expr, naming.getNameForFunction("$rt_imul"));
|
visitBinaryFunction(expr, naming.getNameForFunction("$rt_imul"));
|
||||||
|
@ -764,20 +764,6 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSmallInteger(Expr expr) {
|
|
||||||
if (!(expr instanceof ConstantExpr)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object constant = ((ConstantExpr) expr).getValue();
|
|
||||||
if (!(constant instanceof Integer)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int value = (Integer) constant;
|
|
||||||
return Math.abs(value) < (1 << 18);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(UnaryExpr expr) {
|
public void visit(UnaryExpr expr) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -282,7 +282,8 @@ public class StringTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void interns() {
|
public void interns() {
|
||||||
assertSame(("ab" + "c").intern(), ("a" + "bc").intern());
|
assertSame("xabc".substring(1).intern(), "abcx".substring(0, 3).intern());
|
||||||
|
assertSame("xabc".substring(1).intern(), "abc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class ThreadTest {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
long duration = System.currentTimeMillis() - start;
|
long duration = System.currentTimeMillis() - start;
|
||||||
assertTrue("Thread.sleed did not wait enogh", duration >= 100);
|
assertTrue("Thread.sleep did not wait enough", duration >= 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -62,7 +62,7 @@ function launchTest(callback) {
|
||||||
if (result instanceof Error) {
|
if (result instanceof Error) {
|
||||||
callback({
|
callback({
|
||||||
status: "failed",
|
status: "failed",
|
||||||
errorMessage: buildErrorMessage(e)
|
errorMessage: buildErrorMessage(result)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
callback({ status: "OK" });
|
callback({ status: "OK" });
|
||||||
|
|
Loading…
Reference in New Issue
Block a user