mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -08:00
Fix error. Apply frequency-based alias generation for some $rt functions
This commit is contained in:
parent
62118e2cfe
commit
93c7fb52b4
|
@ -31,4 +31,6 @@ public interface AliasProvider {
|
|||
String getAlias(MethodDescriptor method);
|
||||
|
||||
String getAlias(String className);
|
||||
|
||||
String getFunctionAlias(String name);
|
||||
}
|
||||
|
|
|
@ -76,4 +76,9 @@ public class DefaultAliasProvider implements AliasProvider {
|
|||
public String getAlias(FieldReference field) {
|
||||
return field.getFieldName() + (lastSuffix++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFunctionAlias(String name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
|
|||
private Map<String, String> privateAliases = new HashMap<>();
|
||||
private Map<String, String> classAliases = new HashMap<>();
|
||||
private Map<String, String> fieldAliases = new HashMap<>();
|
||||
private Map<String, String> functionAliases = new HashMap<>();
|
||||
private boolean minifying;
|
||||
|
||||
public DefaultNamingStrategy(AliasProvider aliasProvider, ClassReaderSource classSource) {
|
||||
|
@ -126,6 +127,19 @@ public class DefaultNamingStrategy implements NamingStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameForFunction(String name) throws NamingException {
|
||||
if (!minifying) {
|
||||
return name;
|
||||
}
|
||||
String alias = functionAliases.get(name);
|
||||
if (alias == null) {
|
||||
alias = aliasProvider.getFunctionAlias(name);
|
||||
functionAliases.put(name, alias);
|
||||
}
|
||||
return alias;
|
||||
}
|
||||
|
||||
private MethodReference getRealMethod(MethodReference methodRef) {
|
||||
String className = methodRef.getClassName();
|
||||
while (className != null) {
|
||||
|
|
|
@ -50,6 +50,11 @@ public class MinifyingAliasProvider implements AliasProvider {
|
|||
return getNewAlias(lastSuffix++, startLetters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFunctionAlias(String className) {
|
||||
return getNewAlias(lastSuffix++, startLetters);
|
||||
}
|
||||
|
||||
private String getNewAlias(int index, String startLetters) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(startLetters.charAt(index % startLetters.length()));
|
||||
|
|
|
@ -37,4 +37,6 @@ public interface NameFrequencyConsumer {
|
|||
void consume(String className);
|
||||
|
||||
void consume(FieldReference field);
|
||||
|
||||
void consumeFunction(String name);
|
||||
}
|
||||
|
|
|
@ -139,6 +139,22 @@ public class NamingOrderer implements NameFrequencyConsumer {
|
|||
entry.frequency++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consumeFunction(final String name) {
|
||||
String key = "n:" + name;
|
||||
Entry entry = entries.get(key);
|
||||
if (entry == null) {
|
||||
entry = new Entry();
|
||||
entry.operation = new NamingOperation() {
|
||||
@Override public void perform(NamingStrategy naming) {
|
||||
naming.getNameForFunction(name);
|
||||
}
|
||||
};
|
||||
entries.put(key, entry);
|
||||
}
|
||||
entry.frequency++;
|
||||
}
|
||||
|
||||
public void apply(NamingStrategy naming) {
|
||||
List<Entry> entryList = new ArrayList<>(entries.values());
|
||||
Collections.sort(entryList, new Comparator<Entry>() {
|
||||
|
|
|
@ -37,4 +37,6 @@ public interface NamingStrategy {
|
|||
String getFullNameForAsync(MethodReference method) throws NamingException;
|
||||
|
||||
String getNameFor(FieldReference field) throws NamingException;
|
||||
|
||||
String getNameForFunction(String name) throws NamingException;
|
||||
}
|
||||
|
|
|
@ -137,6 +137,10 @@ public class SourceWriter implements Appendable, LocationProvider {
|
|||
return append(naming.getFullNameFor(new MethodReference(cls, name, params)));
|
||||
}
|
||||
|
||||
public SourceWriter appendFunction(String name) throws NamingException, IOException {
|
||||
return append(naming.getNameForFunction(name));
|
||||
}
|
||||
|
||||
private void appendIndent() throws IOException {
|
||||
if (minified) {
|
||||
return;
|
||||
|
|
|
@ -70,6 +70,8 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
if (asyncFamilyMethods.contains(method.getReference())) {
|
||||
consumer.consume(method.getReference());
|
||||
consumer.consumeAsync(method.getReference());
|
||||
consumer.consumeFunction("$rt_asyncError");
|
||||
consumer.consumeFunction("$rt_asyncResult");
|
||||
}
|
||||
}
|
||||
if (clinit != null && (method.getModifiers().contains(NodeModifier.STATIC) ||
|
||||
|
@ -118,6 +120,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
async = true;
|
||||
for (AsyncMethodPart part : methodNode.getBody()) {
|
||||
part.getStatement().acceptVisitor(this);
|
||||
consumer.consumeFunction("$rt_guardAsync");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,11 +183,15 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
if (statement.getResult() != null) {
|
||||
statement.getResult().acceptVisitor(this);
|
||||
}
|
||||
if (async) {
|
||||
consumer.consumeFunction("$rt_asyncResult");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ThrowStatement statement) {
|
||||
statement.getException().acceptVisitor(this);
|
||||
consumer.consumeFunction("$rt_throw");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -235,11 +242,25 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
public void visit(BinaryExpr expr) {
|
||||
expr.getFirstOperand().acceptVisitor(this);
|
||||
expr.getSecondOperand().acceptVisitor(this);
|
||||
switch (expr.getOperation()) {
|
||||
case COMPARE:
|
||||
consumer.consumeFunction("$rt_compare");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UnaryExpr expr) {
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
switch (expr.getOperation()) {
|
||||
case NULL_CHECK:
|
||||
consumer.consumeFunction("$rt_nullCheck");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -263,6 +284,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
if (type instanceof ValueType.Object) {
|
||||
String clsName = ((ValueType.Object)type).getClassName();
|
||||
consumer.consume(clsName);
|
||||
consumer.consumeFunction("$rt_cls");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,6 +329,9 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (asyncCall) {
|
||||
consumer.consumeFunction("$rt_continue");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -324,6 +349,9 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
public void visit(NewArrayExpr expr) {
|
||||
visitType(expr.getType());
|
||||
expr.getLength().acceptVisitor(this);
|
||||
if (!(expr.getType() instanceof ValueType.Primitive)) {
|
||||
consumer.consumeFunction("$rt_createArray");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -338,6 +366,15 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
|
|||
public void visit(InstanceOfExpr expr) {
|
||||
expr.getExpr().acceptVisitor(this);
|
||||
visitType(expr.getType());
|
||||
if (expr.getType() instanceof ValueType.Object) {
|
||||
String clsName = ((ValueType.Object)expr.getType()).getClassName();
|
||||
ClassReader cls = classSource.get(clsName);
|
||||
if (cls == null || cls.hasModifier(ElementModifier.INTERFACE)) {
|
||||
consumer.consumeFunction("$rt_isInstance");
|
||||
}
|
||||
} else {
|
||||
consumer.consumeFunction("$rt_isInstance");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -259,6 +259,20 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
writer.outdent().append("}").newLine();
|
||||
}
|
||||
|
||||
private void renderRuntimeAliases() throws IOException {
|
||||
String[] names = { "$rt_asyncResult", "$rt_asyncError", "$rt_continue", "$rt_guardAsync", "$rt_throw",
|
||||
"$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray", "$rt_isInstance" };
|
||||
boolean first = true;
|
||||
for (String name : names) {
|
||||
if (!first) {
|
||||
writer.softNewLine();
|
||||
}
|
||||
first = false;
|
||||
writer.append("var ").appendFunction(name).ws().append('=').ws().append(name).append(";").softNewLine();
|
||||
}
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
public void render(List<ClassNode> classes) throws RenderingException {
|
||||
if (minifying) {
|
||||
NamingOrderer orderer = new NamingOrderer();
|
||||
|
@ -269,6 +283,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
orderer.apply(naming);
|
||||
}
|
||||
|
||||
if (minifying) {
|
||||
try {
|
||||
renderRuntimeAliases();
|
||||
} catch (IOException e) {
|
||||
throw new RenderingException(e);
|
||||
}
|
||||
}
|
||||
for (ClassNode cls : classes) {
|
||||
renderDeclaration(cls);
|
||||
}
|
||||
|
@ -638,9 +660,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
writer.append(");").softNewLine();
|
||||
writer.outdent().append("}").ws().append("catch").ws().append("($e)").ws()
|
||||
.append("{").indent().softNewLine();
|
||||
writer.append("return ").append(getReturnVariable()).append("($rt_asyncError($e));").softNewLine();
|
||||
writer.append("return ").append(getReturnVariable()).append("(").appendFunction("$rt_asyncError")
|
||||
.append("($e));").softNewLine();
|
||||
writer.outdent().append("}");
|
||||
writer.append(getReturnVariable()).append("($rt_asyncResult($x));").softNewLine();
|
||||
writer.append(getReturnVariable()).append("(").appendFunction("$rt_asyncResult").append("($x));")
|
||||
.softNewLine();
|
||||
writer.outdent().append("}");
|
||||
if (inner) {
|
||||
writer.append(';');
|
||||
|
@ -744,7 +768,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
for (int i = 0; i < methodNode.getBody().size(); ++i) {
|
||||
writer.append("var ").append(getPartVariable(i)).ws().append("=").ws()
|
||||
.append("$rt_guardAsync(function(");
|
||||
.appendFunction("$rt_guardAsync").append("(function(");
|
||||
if (i > 0) {
|
||||
writer.append("$restore");
|
||||
}
|
||||
|
@ -1074,7 +1098,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
writer.append("return");
|
||||
if (async) {
|
||||
writer.append(' ').append(getReturnVariable()).append("($rt_asyncResult(");
|
||||
writer.append(' ').append(getReturnVariable()).append("(").appendFunction("$rt_asyncResult")
|
||||
.append("(");
|
||||
}
|
||||
if (statement.getResult() != null) {
|
||||
if (!async) {
|
||||
|
@ -1105,7 +1130,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
if (statement.getLocation() != null) {
|
||||
pushLocation(statement.getLocation());
|
||||
}
|
||||
writer.append("$rt_throw(");
|
||||
writer.appendFunction("$rt_throw").append("(");
|
||||
prevCallSite = debugEmitter.emitCallSite();
|
||||
priority = Priority.COMMA;
|
||||
associativity = Associativity.NONE;
|
||||
|
@ -1282,7 +1307,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
visitBinary(expr, "!==", Priority.COMPARISON, Associativity.LEFT);
|
||||
break;
|
||||
case COMPARE:
|
||||
visitBinaryFunction(expr, "$rt_compare");
|
||||
visitBinaryFunction(expr, naming.getNameForFunction("$rt_compare"));
|
||||
break;
|
||||
case COMPARE_LONG:
|
||||
visitBinaryFunction(expr, "Long_compare");
|
||||
|
@ -1420,7 +1445,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
break;
|
||||
case NULL_CHECK:
|
||||
enterPriority(Priority.COMMA, Associativity.NONE, false);
|
||||
writer.append("$rt_nullCheck(");
|
||||
writer.appendFunction("$rt_nullCheck").append("(");
|
||||
expr.getOperand().acceptVisitor(this);
|
||||
writer.append(')');
|
||||
exitPriority();
|
||||
|
@ -1483,7 +1508,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
if (cst instanceof ValueType) {
|
||||
ValueType type = (ValueType)cst;
|
||||
return "$rt_cls(" + typeToClsString(naming, type) + ")";
|
||||
return naming.getNameForFunction("$rt_cls") + "(" + typeToClsString(naming, type) + ")";
|
||||
} else if (cst instanceof String) {
|
||||
String string = (String)cst;
|
||||
Integer index = stringPoolMap.get(string);
|
||||
|
@ -1738,7 +1763,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
if (hasParams) {
|
||||
writer.append(',').ws();
|
||||
}
|
||||
writer.append("$rt_continue(").append(getPartVariable(expr.getAsyncTarget())).append(')');
|
||||
writer.appendFunction("$rt_continue").append("(").append(getPartVariable(expr.getAsyncTarget()))
|
||||
.append(')');
|
||||
}
|
||||
writer.append(')');
|
||||
exitPriority();
|
||||
|
@ -1849,7 +1875,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
writer.append("$rt_createArray(").append(typeToClsString(naming, expr.getType())).append(",").ws();
|
||||
writer.appendFunction("$rt_createArray").append("(").append(typeToClsString(naming, expr.getType()))
|
||||
.append(",").ws();
|
||||
expr.getLength().acceptVisitor(this);
|
||||
writer.append(")");
|
||||
}
|
||||
|
@ -1946,7 +1973,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
}
|
||||
enterPriority(Priority.COMMA, Associativity.NONE, false);
|
||||
writer.append("$rt_isInstance(");
|
||||
writer.appendFunction("$rt_isInstance").append("(");
|
||||
expr.getExpr().acceptVisitor(this);
|
||||
writer.append(",").ws().append(typeToClsString(naming, expr.getType())).append(")");
|
||||
exitPriority();
|
||||
|
@ -2037,7 +2064,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
writer.append("return ").append(naming.getFullNameForAsync(monitorEnterRef)).append("(");
|
||||
statement.getObjectRef().acceptVisitor(this);
|
||||
writer.append(",").ws();
|
||||
writer.append("$rt_continue(").append(getPartVariable(statement.getAsyncTarget())).append(')');
|
||||
writer.appendFunction("$rt_continue").append("(").append(getPartVariable(statement.getAsyncTarget()))
|
||||
.append(')');
|
||||
writer.append(");").softNewLine();
|
||||
} else {
|
||||
MethodReference monitorEnterRef = new MethodReference(
|
||||
|
|
|
@ -549,11 +549,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
for (MethodReference injectedMethod : methodInjectors.keySet()) {
|
||||
decompiler.addMethodToPass(injectedMethod);
|
||||
}
|
||||
List<String> classOrder = decompiler.getClassOrdering(classes.getClassNames());
|
||||
List<ClassNode> classNodes = new ArrayList<>();
|
||||
int index = 0;
|
||||
try (PrintWriter bytecodeLogger = bytecodeLogging ?
|
||||
new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")) : null) {
|
||||
for (String className : classes.getClassNames()) {
|
||||
for (String className : classOrder) {
|
||||
ClassHolder cls = classes.get(className);
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
processMethod(method);
|
||||
|
|
Loading…
Reference in New Issue
Block a user