mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 00: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.setRegionsAddress(address);
|
||||||
gcIntrinsic.setRegionMaxCount(regionCount);
|
gcIntrinsic.setRegionMaxCount(regionCount);
|
||||||
|
|
||||||
gcMemory -= regionCount * 2;
|
|
||||||
address += regionCount * 2;
|
address += regionCount * 2;
|
||||||
address = (address + 4) >> 2 << 2;
|
address = (address + 4) >> 2 << 2;
|
||||||
|
|
||||||
|
gcMemory = module.getMemorySize() * 65536 - address;
|
||||||
gcIntrinsic.setHeapAddress(address);
|
gcIntrinsic.setHeapAddress(address);
|
||||||
gcIntrinsic.setAvailableBytes(gcMemory);
|
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.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmLocal;
|
import org.teavm.backend.wasm.model.WasmLocal;
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
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.interop.Export;
|
||||||
import org.teavm.model.AnnotationReader;
|
import org.teavm.model.AnnotationReader;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
|
@ -90,27 +85,6 @@ public class WasmGenerator {
|
||||||
methodAst.getBody().acceptVisitor(visitor);
|
methodAst.getBody().acceptVisitor(visitor);
|
||||||
function.getBody().add(visitor.result);
|
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());
|
AnnotationReader exportAnnot = method.getAnnotations().get(Export.class.getName());
|
||||||
if (exportAnnot != null) {
|
if (exportAnnot != null) {
|
||||||
function.setExportName(exportAnnot.getValue("name").getString());
|
function.setExportName(exportAnnot.getValue("name").getString());
|
||||||
|
|
|
@ -55,28 +55,24 @@ public class WasmRenderer {
|
||||||
|
|
||||||
public void render(WasmModule module) {
|
public void render(WasmModule module) {
|
||||||
visitor.open().append("module");
|
visitor.open().append("module");
|
||||||
renderMemory(module);
|
|
||||||
renderTypes(module);
|
renderTypes(module);
|
||||||
|
|
||||||
for (WasmFunction function : module.getFunctions().values()) {
|
|
||||||
if (function.getImportName() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
lf().renderImport(function);
|
|
||||||
}
|
|
||||||
for (WasmFunction function : module.getFunctions().values()) {
|
for (WasmFunction function : module.getFunctions().values()) {
|
||||||
if (function.getImportName() != null) {
|
if (function.getImportName() != null) {
|
||||||
continue;
|
lf().render(function);
|
||||||
}
|
}
|
||||||
lf().render(function);
|
|
||||||
}
|
}
|
||||||
for (WasmFunction function : module.getFunctions().values()) {
|
for (WasmFunction function : module.getFunctions().values()) {
|
||||||
if (function.getExportName() == null) {
|
if (function.getImportName() == null) {
|
||||||
continue;
|
lf().render(function);
|
||||||
}
|
}
|
||||||
lf().renderExport(function);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTable(module);
|
renderTable(module);
|
||||||
|
renderMemory(module);
|
||||||
|
renderElement(module);
|
||||||
|
renderData(module);
|
||||||
|
|
||||||
if (module.getStartFunction() != null) {
|
if (module.getStartFunction() != null) {
|
||||||
visitor.lf().open().append("start $" + module.getStartFunction().getName()).close().lf();
|
visitor.lf().open().append("start $" + module.getStartFunction().getName()).close().lf();
|
||||||
}
|
}
|
||||||
|
@ -85,9 +81,12 @@ public class WasmRenderer {
|
||||||
|
|
||||||
public void renderMemory(WasmModule module) {
|
public void renderMemory(WasmModule module) {
|
||||||
visitor.lf();
|
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()) {
|
for (WasmMemorySegment segment : module.getSegments()) {
|
||||||
visitor.lf().open().append("segment " + segment.getOffset());
|
visitor.lf().open().append("data (i32.const " + segment.getOffset() + ")");
|
||||||
visitor.indent();
|
visitor.indent();
|
||||||
for (int i = 0; i < segment.getLength(); i += 256) {
|
for (int i = 0; i < segment.getLength(); i += 256) {
|
||||||
visitor.lf().append("\"");
|
visitor.lf().append("\"");
|
||||||
|
@ -110,26 +109,21 @@ public class WasmRenderer {
|
||||||
visitor.outdent();
|
visitor.outdent();
|
||||||
visitor.close();
|
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) {
|
public void render(WasmFunction function) {
|
||||||
visitor.open().append("func $" + function.getName());
|
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);
|
renderSignature(function);
|
||||||
|
|
||||||
int firstLocalVariable = function.getParameters().size();
|
int firstLocalVariable = function.getParameters().size();
|
||||||
|
@ -142,6 +136,9 @@ public class WasmRenderer {
|
||||||
}
|
}
|
||||||
visitor.close();
|
visitor.close();
|
||||||
}
|
}
|
||||||
|
for (WasmExpression part : function.getBody()) {
|
||||||
|
visitor.preprocess(part);
|
||||||
|
}
|
||||||
for (WasmExpression part : function.getBody()) {
|
for (WasmExpression part : function.getBody()) {
|
||||||
visitor.line(part);
|
visitor.line(part);
|
||||||
}
|
}
|
||||||
|
@ -195,7 +192,15 @@ public class WasmRenderer {
|
||||||
return;
|
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()) {
|
for (WasmFunction function : module.getFunctionTable()) {
|
||||||
visitor.lf().append("$" + function.getName());
|
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.WasmCall;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmConditional;
|
import org.teavm.backend.wasm.model.expression.WasmConditional;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmConversion;
|
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.WasmDrop;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpressionVisitor;
|
import org.teavm.backend.wasm.model.expression.WasmExpressionVisitor;
|
||||||
|
@ -71,6 +72,35 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
||||||
List<WasmSignature> signatureList = new ArrayList<>();
|
List<WasmSignature> signatureList = new ArrayList<>();
|
||||||
Map<WasmSignature, Integer> signatureMap = new HashMap<>();
|
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() {
|
void clear() {
|
||||||
blockIdentifiers.clear();
|
blockIdentifiers.clear();
|
||||||
usedIdentifiers.clear();
|
usedIdentifiers.clear();
|
||||||
|
@ -135,13 +165,18 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WasmBlock expression) {
|
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) {
|
private void renderBlock(WasmBlock block, String name, boolean signature) {
|
||||||
String id = getIdentifier("@block");
|
open().append(name);
|
||||||
blockIdentifiers.put(block, id);
|
String id = blockIdentifiers.get(block);
|
||||||
open().append(name + " $" + id);
|
if (id != null) {
|
||||||
|
append(" $" + id);
|
||||||
|
}
|
||||||
|
if (signature && block.getType() != null) {
|
||||||
|
append(" " + type(block.getType()));
|
||||||
|
}
|
||||||
for (WasmExpression part : block.getBody()) {
|
for (WasmExpression part : block.getBody()) {
|
||||||
line(part);
|
line(part);
|
||||||
}
|
}
|
||||||
|
@ -183,14 +218,19 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
||||||
@Override
|
@Override
|
||||||
public void visit(WasmConditional expression) {
|
public void visit(WasmConditional expression) {
|
||||||
open().append("if");
|
open().append("if");
|
||||||
|
|
||||||
|
if (expression.getType() != null) {
|
||||||
|
append(" " + type(expression.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
line(expression.getCondition());
|
line(expression.getCondition());
|
||||||
|
|
||||||
lf();
|
lf();
|
||||||
renderBlock(expression.getThenBlock(), "then");
|
renderBlock(expression.getThenBlock(), "then", false);
|
||||||
|
|
||||||
if (!expression.getElseBlock().getBody().isEmpty()) {
|
if (!expression.getElseBlock().getBody().isEmpty()) {
|
||||||
lf();
|
lf();
|
||||||
renderBlock(expression.getElseBlock(), "else");
|
renderBlock(expression.getElseBlock(), "else", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
@ -343,7 +383,7 @@ class WasmRenderingVisitor implements WasmExpressionVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WasmCall expression) {
|
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()) {
|
for (WasmExpression argument : expression.getArguments()) {
|
||||||
line(argument);
|
line(argument);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,12 +70,15 @@ public final class GC {
|
||||||
next = currentChunk.toAddress().add(size);
|
next = currentChunk.toAddress().add(size);
|
||||||
}
|
}
|
||||||
int freeSize = current.size;
|
int freeSize = current.size;
|
||||||
currentChunk = next.toStructure();
|
|
||||||
freeSize -= size;
|
freeSize -= size;
|
||||||
if (freeSize > 0) {
|
if (freeSize > 0) {
|
||||||
currentChunk.classReference = 0;
|
currentChunk = next.toStructure();
|
||||||
currentChunk.size = freeSize;
|
currentChunk.size = freeSize;
|
||||||
|
} else {
|
||||||
|
freeMemory -= size;
|
||||||
|
getAvailableChunkIfPossible(currentChunk.size + 1);
|
||||||
}
|
}
|
||||||
|
currentChunk.classReference = 0;
|
||||||
freeMemory -= size;
|
freeMemory -= size;
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +92,9 @@ public final class GC {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean getAvailableChunkIfPossible(int size) {
|
private static boolean getAvailableChunkIfPossible(int size) {
|
||||||
|
if (freeChunks == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
if (currentChunk.toAddress().add(size) == currentChunkLimit) {
|
if (currentChunk.toAddress().add(size) == currentChunkLimit) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user