mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
WASM: fix bugs
This commit is contained in:
parent
055f39c1c8
commit
2610fe5428
|
@ -670,9 +670,10 @@ public class WasmTarget implements TeaVMTarget {
|
|||
gcIntrinsic.setRegionsAddress(address);
|
||||
gcIntrinsic.setRegionMaxCount(regionCount);
|
||||
|
||||
gcMemory -= regionCount * 2;
|
||||
address += regionCount * 2;
|
||||
address = (address + 4) >> 2 << 2;
|
||||
|
||||
gcMemory = module.getMemorySize() * 65536 - address;
|
||||
gcIntrinsic.setHeapAddress(address);
|
||||
gcIntrinsic.setAvailableBytes(gcMemory);
|
||||
}
|
||||
|
|
|
@ -22,11 +22,6 @@ import org.teavm.backend.wasm.binary.BinaryWriter;
|
|||
import org.teavm.backend.wasm.model.WasmFunction;
|
||||
import org.teavm.backend.wasm.model.WasmLocal;
|
||||
import org.teavm.backend.wasm.model.WasmType;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmFloat32Constant;
|
||||
import org.teavm.backend.wasm.model.expression.WasmFloat64Constant;
|
||||
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
||||
import org.teavm.backend.wasm.model.expression.WasmInt64Constant;
|
||||
import org.teavm.interop.Export;
|
||||
import org.teavm.model.AnnotationReader;
|
||||
import org.teavm.model.ClassHolder;
|
||||
|
@ -90,27 +85,6 @@ public class WasmGenerator {
|
|||
methodAst.getBody().acceptVisitor(visitor);
|
||||
function.getBody().add(visitor.result);
|
||||
|
||||
if (function.getResult() != null) {
|
||||
WasmExpression finalExpr;
|
||||
switch (function.getResult()) {
|
||||
case INT32:
|
||||
finalExpr = new WasmInt32Constant(0);
|
||||
break;
|
||||
case INT64:
|
||||
finalExpr = new WasmInt64Constant(0);
|
||||
break;
|
||||
case FLOAT32:
|
||||
finalExpr = new WasmFloat32Constant(0);
|
||||
break;
|
||||
case FLOAT64:
|
||||
finalExpr = new WasmFloat64Constant(0);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
function.getBody().add(finalExpr);
|
||||
}
|
||||
|
||||
AnnotationReader exportAnnot = method.getAnnotations().get(Export.class.getName());
|
||||
if (exportAnnot != null) {
|
||||
function.setExportName(exportAnnot.getValue("name").getString());
|
||||
|
|
|
@ -55,28 +55,24 @@ public class WasmRenderer {
|
|||
|
||||
public void render(WasmModule module) {
|
||||
visitor.open().append("module");
|
||||
renderMemory(module);
|
||||
renderTypes(module);
|
||||
|
||||
for (WasmFunction function : module.getFunctions().values()) {
|
||||
if (function.getImportName() == null) {
|
||||
continue;
|
||||
}
|
||||
lf().renderImport(function);
|
||||
}
|
||||
for (WasmFunction function : module.getFunctions().values()) {
|
||||
if (function.getImportName() != null) {
|
||||
continue;
|
||||
lf().render(function);
|
||||
}
|
||||
lf().render(function);
|
||||
}
|
||||
for (WasmFunction function : module.getFunctions().values()) {
|
||||
if (function.getExportName() == null) {
|
||||
continue;
|
||||
if (function.getImportName() == null) {
|
||||
lf().render(function);
|
||||
}
|
||||
lf().renderExport(function);
|
||||
}
|
||||
|
||||
renderTable(module);
|
||||
renderMemory(module);
|
||||
renderElement(module);
|
||||
renderData(module);
|
||||
|
||||
if (module.getStartFunction() != null) {
|
||||
visitor.lf().open().append("start $" + module.getStartFunction().getName()).close().lf();
|
||||
}
|
||||
|
@ -85,9 +81,12 @@ public class WasmRenderer {
|
|||
|
||||
public void renderMemory(WasmModule module) {
|
||||
visitor.lf();
|
||||
visitor.open().append("memory " + module.getMemorySize());
|
||||
visitor.open().append("memory " + module.getMemorySize()).close().lf();
|
||||
}
|
||||
|
||||
public void renderData(WasmModule module) {
|
||||
for (WasmMemorySegment segment : module.getSegments()) {
|
||||
visitor.lf().open().append("segment " + segment.getOffset());
|
||||
visitor.lf().open().append("data (i32.const " + segment.getOffset() + ")");
|
||||
visitor.indent();
|
||||
for (int i = 0; i < segment.getLength(); i += 256) {
|
||||
visitor.lf().append("\"");
|
||||
|
@ -110,26 +109,21 @@ public class WasmRenderer {
|
|||
visitor.outdent();
|
||||
visitor.close();
|
||||
}
|
||||
visitor.close().lf();
|
||||
}
|
||||
|
||||
public void renderImport(WasmFunction function) {
|
||||
String importModule = function.getImportModule();
|
||||
if (importModule == null) {
|
||||
importModule = "";
|
||||
}
|
||||
visitor.open().append("import $" + function.getName() + " \"" + importModule + "\" "
|
||||
+ "\"" + function.getImportName() + "\"");
|
||||
renderSignature(function);
|
||||
visitor.close();
|
||||
}
|
||||
|
||||
public void renderExport(WasmFunction function) {
|
||||
visitor.open().append("export \"" + function.getExportName() + "\" $" + function.getName()).close();
|
||||
}
|
||||
|
||||
public void render(WasmFunction function) {
|
||||
visitor.open().append("func $" + function.getName());
|
||||
|
||||
if (function.getImportName() != null) {
|
||||
String importModule = function.getImportModule();
|
||||
if (importModule == null) {
|
||||
importModule = "";
|
||||
}
|
||||
visitor.append(" (import \"" + importModule + "\" \"" + function.getImportName() + "\")");
|
||||
} else if (function.getExportName() != null) {
|
||||
visitor.append(" (export \"" + function.getExportName() + "\")");
|
||||
}
|
||||
|
||||
renderSignature(function);
|
||||
|
||||
int firstLocalVariable = function.getParameters().size();
|
||||
|
@ -142,6 +136,9 @@ public class WasmRenderer {
|
|||
}
|
||||
visitor.close();
|
||||
}
|
||||
for (WasmExpression part : function.getBody()) {
|
||||
visitor.preprocess(part);
|
||||
}
|
||||
for (WasmExpression part : function.getBody()) {
|
||||
visitor.line(part);
|
||||
}
|
||||
|
@ -195,7 +192,15 @@ public class WasmRenderer {
|
|||
return;
|
||||
}
|
||||
|
||||
visitor.lf().open().append("table");
|
||||
visitor.lf().open().append("table " + module.getFunctionTable().size() + " anyfunc").close().lf();
|
||||
}
|
||||
|
||||
private void renderElement(WasmModule module) {
|
||||
if (module.getFunctionTable().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
visitor.lf().open().append("elem (i32.const 0)");
|
||||
for (WasmFunction function : module.getFunctionTable()) {
|
||||
visitor.lf().append("$" + function.getName());
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.teavm.backend.wasm.model.expression.WasmBreak;
|
|||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||
import org.teavm.backend.wasm.model.expression.WasmConditional;
|
||||
import org.teavm.backend.wasm.model.expression.WasmConversion;
|
||||
import org.teavm.backend.wasm.model.expression.WasmDefaultExpressionVisitor;
|
||||
import org.teavm.backend.wasm.model.expression.WasmDrop;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpressionVisitor;
|
||||
|
@ -71,6 +72,35 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
|||
List<WasmSignature> signatureList = new ArrayList<>();
|
||||
Map<WasmSignature, Integer> signatureMap = new HashMap<>();
|
||||
|
||||
void preprocess(WasmExpression expression) {
|
||||
expression.acceptVisitor(new WasmDefaultExpressionVisitor() {
|
||||
@Override
|
||||
public void visit(WasmBranch expression) {
|
||||
super.visit(expression);
|
||||
register(expression.getTarget());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmBreak expression) {
|
||||
super.visit(expression);
|
||||
register(expression.getTarget());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmSwitch expression) {
|
||||
super.visit(expression);
|
||||
for (WasmBlock target : expression.getTargets()) {
|
||||
register(target);
|
||||
}
|
||||
register(expression.getDefaultTarget());
|
||||
}
|
||||
|
||||
private void register(WasmBlock block) {
|
||||
blockIdentifiers.computeIfAbsent(block, key -> "block_" + blockIdentifiers.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void clear() {
|
||||
blockIdentifiers.clear();
|
||||
usedIdentifiers.clear();
|
||||
|
@ -135,13 +165,18 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmBlock expression) {
|
||||
renderBlock(expression, expression.isLoop() ? "loop" : "block");
|
||||
renderBlock(expression, expression.isLoop() ? "loop" : "block", true);
|
||||
}
|
||||
|
||||
private void renderBlock(WasmBlock block, String name) {
|
||||
String id = getIdentifier("@block");
|
||||
blockIdentifiers.put(block, id);
|
||||
open().append(name + " $" + id);
|
||||
private void renderBlock(WasmBlock block, String name, boolean signature) {
|
||||
open().append(name);
|
||||
String id = blockIdentifiers.get(block);
|
||||
if (id != null) {
|
||||
append(" $" + id);
|
||||
}
|
||||
if (signature && block.getType() != null) {
|
||||
append(" " + type(block.getType()));
|
||||
}
|
||||
for (WasmExpression part : block.getBody()) {
|
||||
line(part);
|
||||
}
|
||||
|
@ -183,14 +218,19 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmConditional expression) {
|
||||
open().append("if");
|
||||
|
||||
if (expression.getType() != null) {
|
||||
append(" " + type(expression.getType()));
|
||||
}
|
||||
|
||||
line(expression.getCondition());
|
||||
|
||||
lf();
|
||||
renderBlock(expression.getThenBlock(), "then");
|
||||
renderBlock(expression.getThenBlock(), "then", false);
|
||||
|
||||
if (!expression.getElseBlock().getBody().isEmpty()) {
|
||||
lf();
|
||||
renderBlock(expression.getElseBlock(), "else");
|
||||
renderBlock(expression.getElseBlock(), "else", false);
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -343,7 +383,7 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmCall expression) {
|
||||
open().append(expression.isImported() ? "call_import" : "call").append(" $" + expression.getFunctionName());
|
||||
open().append("call").append(" $" + expression.getFunctionName());
|
||||
for (WasmExpression argument : expression.getArguments()) {
|
||||
line(argument);
|
||||
}
|
||||
|
|
|
@ -70,12 +70,15 @@ public final class GC {
|
|||
next = currentChunk.toAddress().add(size);
|
||||
}
|
||||
int freeSize = current.size;
|
||||
currentChunk = next.toStructure();
|
||||
freeSize -= size;
|
||||
if (freeSize > 0) {
|
||||
currentChunk.classReference = 0;
|
||||
currentChunk = next.toStructure();
|
||||
currentChunk.size = freeSize;
|
||||
} else {
|
||||
freeMemory -= size;
|
||||
getAvailableChunkIfPossible(currentChunk.size + 1);
|
||||
}
|
||||
currentChunk.classReference = 0;
|
||||
freeMemory -= size;
|
||||
return current;
|
||||
}
|
||||
|
@ -89,6 +92,9 @@ public final class GC {
|
|||
}
|
||||
|
||||
private static boolean getAvailableChunkIfPossible(int size) {
|
||||
if (freeChunks == 0) {
|
||||
return false;
|
||||
}
|
||||
while (true) {
|
||||
if (currentChunk.toAddress().add(size) == currentChunkLimit) {
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue
Block a user