mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: minor optimizations; make initializer functions Wasm start function; fix compilation; remove debugging output
This commit is contained in:
parent
f95250ddf7
commit
73dda91d35
|
@ -17,17 +17,6 @@ package org.teavm.backend.wasm;
|
||||||
|
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCDeclarationsGenerator;
|
import org.teavm.backend.wasm.generate.gc.WasmGCDeclarationsGenerator;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmGlobal;
|
|
||||||
import org.teavm.backend.wasm.model.WasmLocal;
|
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmDrop;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmFunctionReference;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmGetGlobal;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmGetLocal;
|
|
||||||
import org.teavm.backend.wasm.model.expression.WasmSetGlobal;
|
|
||||||
import org.teavm.backend.wasm.runtime.StringInternPool;
|
import org.teavm.backend.wasm.runtime.StringInternPool;
|
||||||
import org.teavm.backend.wasm.runtime.gc.WasmGCSupport;
|
import org.teavm.backend.wasm.runtime.gc.WasmGCSupport;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
@ -35,8 +24,6 @@ import org.teavm.model.ValueType;
|
||||||
|
|
||||||
public class WasmGCModuleGenerator {
|
public class WasmGCModuleGenerator {
|
||||||
private WasmGCDeclarationsGenerator declarationsGenerator;
|
private WasmGCDeclarationsGenerator declarationsGenerator;
|
||||||
private WasmFunction initializer;
|
|
||||||
private WasmGlobal initializerRef;
|
|
||||||
|
|
||||||
public WasmGCModuleGenerator(WasmGCDeclarationsGenerator declarationsGenerator) {
|
public WasmGCModuleGenerator(WasmGCDeclarationsGenerator declarationsGenerator) {
|
||||||
this.declarationsGenerator = declarationsGenerator;
|
this.declarationsGenerator = declarationsGenerator;
|
||||||
|
@ -44,166 +31,66 @@ public class WasmGCModuleGenerator {
|
||||||
|
|
||||||
public void generate() {
|
public void generate() {
|
||||||
declarationsGenerator.generate();
|
declarationsGenerator.generate();
|
||||||
if (initializer != null) {
|
createInitializer();
|
||||||
fillInitializer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillInitializer() {
|
|
||||||
declarationsGenerator.contributeToInitializer(initializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WasmFunction generateMainFunction(String entryPoint) {
|
public WasmFunction generateMainFunction(String entryPoint) {
|
||||||
var mainFunction = declarationsGenerator.functions().forStaticMethod(new MethodReference(entryPoint,
|
return declarationsGenerator.functions().forStaticMethod(new MethodReference(entryPoint,
|
||||||
"main", ValueType.parse(String[].class), ValueType.VOID));
|
"main", ValueType.parse(String[].class), ValueType.VOID));
|
||||||
var stringArrayType = declarationsGenerator.typeMapper()
|
|
||||||
.mapType(ValueType.parse(String[].class));
|
|
||||||
var mainFunctionCaller = new WasmFunction(declarationsGenerator.functionTypes.of(null, stringArrayType));
|
|
||||||
var argsLocal = new WasmLocal(stringArrayType, "args");
|
|
||||||
declarationsGenerator.module.functions.add(mainFunctionCaller);
|
|
||||||
mainFunctionCaller.getBody().add(callInitializer());
|
|
||||||
|
|
||||||
var callToMainFunction = new WasmCall(mainFunction, new WasmGetLocal(argsLocal));
|
|
||||||
mainFunctionCaller.getBody().add(callToMainFunction);
|
|
||||||
|
|
||||||
return mainFunctionCaller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateCreateStringBuilderFunction() {
|
public WasmFunction generateCreateStringBuilderFunction() {
|
||||||
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
return declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
WasmGCSupport.class, "createStringBuilder", StringBuilder.class));
|
WasmGCSupport.class, "createStringBuilder", StringBuilder.class));
|
||||||
var caller = new WasmFunction(function.getType());
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmCall(function));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateCreateStringArrayFunction() {
|
public WasmFunction generateCreateStringArrayFunction() {
|
||||||
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
return declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
WasmGCSupport.class, "createStringArray", int.class, String[].class));
|
WasmGCSupport.class, "createStringArray", int.class, String[].class));
|
||||||
var caller = new WasmFunction(function.getType());
|
|
||||||
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
|
||||||
caller.add(sizeLocal);
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmCall(function, new WasmGetLocal(sizeLocal)));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateAppendCharFunction() {
|
public WasmFunction generateAppendCharFunction() {
|
||||||
var function = declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
return declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
||||||
StringBuilder.class, "append", char.class, StringBuilder.class));
|
StringBuilder.class, "append", char.class, StringBuilder.class));
|
||||||
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
|
||||||
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(null, stringBuilderType, WasmType.INT32));
|
|
||||||
var stringBuilderLocal = new WasmLocal(stringBuilderType, "stringBuilder");
|
|
||||||
var codeLocal = new WasmLocal(WasmType.INT32, "charCode");
|
|
||||||
caller.add(stringBuilderLocal);
|
|
||||||
caller.add(codeLocal);
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmDrop(new WasmCall(function, new WasmGetLocal(stringBuilderLocal),
|
|
||||||
new WasmGetLocal(codeLocal))));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateBuildStringFunction() {
|
public WasmFunction generateBuildStringFunction() {
|
||||||
var function = declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
return declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
||||||
StringBuilder.class, "toString", String.class));
|
StringBuilder.class, "toString", String.class));
|
||||||
var stringBuilderType = declarationsGenerator.typeMapper().mapType(ValueType.parse(StringBuilder.class));
|
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
|
||||||
var caller = new WasmFunction(declarationsGenerator.functionTypes.of(stringType, stringBuilderType));
|
|
||||||
var stringBuilderLocal = new WasmLocal(stringBuilderType, "stringBuilder");
|
|
||||||
caller.add(stringBuilderLocal);
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmCall(function, new WasmGetLocal(stringBuilderLocal)));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateSetToStringArrayFunction() {
|
public WasmFunction generateSetToStringArrayFunction() {
|
||||||
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
return declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
WasmGCSupport.class, "setToStringArray", String[].class, int.class, String.class, void.class));
|
WasmGCSupport.class, "setToStringArray", String[].class, int.class, String.class, void.class));
|
||||||
var stringArrayType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String[].class));
|
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
|
||||||
var caller = new WasmFunction(function.getType());
|
|
||||||
var arrayLocal = new WasmLocal(stringArrayType, "array");
|
|
||||||
var indexLocal = new WasmLocal(WasmType.INT32, "index");
|
|
||||||
var valueLocal = new WasmLocal(stringType, "string");
|
|
||||||
caller.add(arrayLocal);
|
|
||||||
caller.add(indexLocal);
|
|
||||||
caller.add(valueLocal);
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmCall(function, new WasmGetLocal(arrayLocal),
|
|
||||||
new WasmGetLocal(indexLocal), new WasmGetLocal(valueLocal)));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateStringLengthFunction() {
|
public WasmFunction generateStringLengthFunction() {
|
||||||
var function = declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
return declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
||||||
String.class, "length", int.class));
|
String.class, "length", int.class));
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
|
||||||
var caller = new WasmFunction(function.getType());
|
|
||||||
var stringLocal = new WasmLocal(stringType, "string");
|
|
||||||
caller.add(stringLocal);
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmCall(function, new WasmGetLocal(stringLocal)));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateCharAtFunction() {
|
public WasmFunction generateCharAtFunction() {
|
||||||
var function = declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
return declarationsGenerator.functions().forInstanceMethod(new MethodReference(
|
||||||
String.class, "charAt", int.class, char.class));
|
String.class, "charAt", int.class, char.class));
|
||||||
var stringType = declarationsGenerator.typeMapper().mapType(ValueType.parse(String.class));
|
|
||||||
var caller = new WasmFunction(function.getType());
|
|
||||||
var stringLocal = new WasmLocal(stringType, "string");
|
|
||||||
var indexLocal = new WasmLocal(WasmType.INT32, "index");
|
|
||||||
caller.add(stringLocal);
|
|
||||||
caller.add(indexLocal);
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmCall(function, new WasmGetLocal(stringLocal),
|
|
||||||
new WasmGetLocal(indexLocal)));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WasmFunction generateReportGarbageCollectedStringFunction() {
|
public WasmFunction generateReportGarbageCollectedStringFunction() {
|
||||||
var entryType = ValueType.object(StringInternPool.class.getName() + "$Entry");
|
var entryType = ValueType.object(StringInternPool.class.getName() + "$Entry");
|
||||||
var function = declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
return declarationsGenerator.functions().forStaticMethod(new MethodReference(
|
||||||
StringInternPool.class.getName(),
|
StringInternPool.class.getName(),
|
||||||
"remove",
|
"remove",
|
||||||
entryType,
|
entryType,
|
||||||
ValueType.VOID
|
ValueType.VOID
|
||||||
));
|
));
|
||||||
var caller = new WasmFunction(function.getType());
|
|
||||||
var entryLocal = new WasmLocal(declarationsGenerator.typeMapper().mapType(entryType));
|
|
||||||
caller.add(entryLocal);
|
|
||||||
caller.getBody().add(callInitializer());
|
|
||||||
caller.getBody().add(new WasmCall(function, new WasmGetLocal(entryLocal)));
|
|
||||||
declarationsGenerator.module.functions.add(caller);
|
|
||||||
return caller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createInitializer() {
|
private void createInitializer() {
|
||||||
if (initializer != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var functionType = declarationsGenerator.functionTypes.of(null);
|
var functionType = declarationsGenerator.functionTypes.of(null);
|
||||||
initializer = new WasmFunction(functionType);
|
var initializer = new WasmFunction(functionType);
|
||||||
initializer.setReferenced(true);
|
|
||||||
initializer.setName("teavm@initializer");
|
initializer.setName("teavm@initializer");
|
||||||
declarationsGenerator.module.functions.add(initializer);
|
declarationsGenerator.module.functions.add(initializer);
|
||||||
initializerRef = new WasmGlobal("teavm@initializerRef", functionType.getNonNullReference(),
|
declarationsGenerator.module.setStartFunction(initializer);
|
||||||
new WasmFunctionReference(initializer));
|
declarationsGenerator.contributeToInitializer(initializer);
|
||||||
declarationsGenerator.module.globals.add(initializerRef);
|
|
||||||
initializer.getBody().add(new WasmSetGlobal(initializerRef,
|
|
||||||
new WasmFunctionReference(declarationsGenerator.dummyInitializer())));
|
|
||||||
}
|
|
||||||
|
|
||||||
private WasmExpression callInitializer() {
|
|
||||||
createInitializer();
|
|
||||||
return new WasmCallReference(new WasmGetGlobal(initializerRef), declarationsGenerator.functionTypes.of(null));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ public class DebugLinesBuilder extends DebugSectionBuilder implements DebugLines
|
||||||
public void location(String file, int line) {
|
public void location(String file, int line) {
|
||||||
if (Objects.equals(file, this.file) && this.ptr != lastWrittenPtr && this.line != line) {
|
if (Objects.equals(file, this.file) && this.ptr != lastWrittenPtr && this.line != line) {
|
||||||
if (this.ptr - lastWrittenPtr < 32 && Math.abs(line - this.line) <= 3) {
|
if (this.ptr - lastWrittenPtr < 32 && Math.abs(line - this.line) <= 3) {
|
||||||
System.out.println(blob.ptr() + indent.toString() + "[user] ptr: " + this.ptr + ", line: " + line);
|
|
||||||
blob.writeByte(DebugConstants.LOC_USER + (this.ptr - lastWrittenPtr) + 32 * (line - this.line + 3));
|
blob.writeByte(DebugConstants.LOC_USER + (this.ptr - lastWrittenPtr) + 32 * (line - this.line + 3));
|
||||||
this.line = line;
|
this.line = line;
|
||||||
lastWrittenPtr = ptr;
|
lastWrittenPtr = ptr;
|
||||||
|
@ -59,12 +58,10 @@ public class DebugLinesBuilder extends DebugSectionBuilder implements DebugLines
|
||||||
flushPtr();
|
flushPtr();
|
||||||
this.line = 1;
|
this.line = 1;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
System.out.println(blob.ptr() + indent.toString() + "[file] " + file);
|
|
||||||
blob.writeByte(DebugConstants.LOC_FILE).writeLEB(file != null ? files.filePtr(file) : 0);
|
blob.writeByte(DebugConstants.LOC_FILE).writeLEB(file != null ? files.filePtr(file) : 0);
|
||||||
}
|
}
|
||||||
if (this.line != line) {
|
if (this.line != line) {
|
||||||
flushPtr();
|
flushPtr();
|
||||||
System.out.println(blob.ptr() + indent.toString() + "[line] " + line);
|
|
||||||
blob.writeByte(DebugConstants.LOC_LINE).writeSLEB(line - this.line);
|
blob.writeByte(DebugConstants.LOC_LINE).writeSLEB(line - this.line);
|
||||||
this.line = line;
|
this.line = line;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +74,6 @@ public class DebugLinesBuilder extends DebugSectionBuilder implements DebugLines
|
||||||
|
|
||||||
private void flushPtr() {
|
private void flushPtr() {
|
||||||
if (ptr != lastWrittenPtr) {
|
if (ptr != lastWrittenPtr) {
|
||||||
System.out.println(blob.ptr() + indent.toString() + "[ptr] " + ptr);
|
|
||||||
blob.writeLEB(DebugConstants.LOC_PTR);
|
blob.writeLEB(DebugConstants.LOC_PTR);
|
||||||
blob.writeLEB(ptr - lastWrittenPtr);
|
blob.writeLEB(ptr - lastWrittenPtr);
|
||||||
lastWrittenPtr = ptr;
|
lastWrittenPtr = ptr;
|
||||||
|
@ -87,7 +83,6 @@ public class DebugLinesBuilder extends DebugSectionBuilder implements DebugLines
|
||||||
@Override
|
@Override
|
||||||
public void start(MethodReference methodReference) {
|
public void start(MethodReference methodReference) {
|
||||||
flushPtr();
|
flushPtr();
|
||||||
System.out.println(blob.ptr() + indent.toString() + "[start] method: " + methodReference);
|
|
||||||
indent.append(".");
|
indent.append(".");
|
||||||
blob.writeLEB(DebugConstants.LOC_START);
|
blob.writeLEB(DebugConstants.LOC_START);
|
||||||
blob.writeLEB(methods.methodPtr(methodReference));
|
blob.writeLEB(methods.methodPtr(methodReference));
|
||||||
|
@ -100,7 +95,6 @@ public class DebugLinesBuilder extends DebugSectionBuilder implements DebugLines
|
||||||
public void end() {
|
public void end() {
|
||||||
flushPtr();
|
flushPtr();
|
||||||
indent.setLength(indent.length() - 1);
|
indent.setLength(indent.length() - 1);
|
||||||
System.out.println(blob.ptr() + indent.toString() + "[end]");
|
|
||||||
blob.writeLEB(DebugConstants.LOC_END);
|
blob.writeLEB(DebugConstants.LOC_END);
|
||||||
if (!states.isEmpty()) {
|
if (!states.isEmpty()) {
|
||||||
var state = states.pop();
|
var state = states.pop();
|
||||||
|
|
|
@ -132,6 +132,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
private boolean async;
|
private boolean async;
|
||||||
protected WasmExpression result;
|
protected WasmExpression result;
|
||||||
protected List<WasmExpression> resultConsumer;
|
protected List<WasmExpression> resultConsumer;
|
||||||
|
protected int blockLevel;
|
||||||
|
|
||||||
public BaseWasmGenerationVisitor(BaseWasmGenerationContext context, MethodReference currentMethod,
|
public BaseWasmGenerationVisitor(BaseWasmGenerationContext context, MethodReference currentMethod,
|
||||||
WasmFunction function, int firstVariable, boolean async) {
|
WasmFunction function, int firstVariable, boolean async) {
|
||||||
|
@ -591,9 +592,11 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
@Override
|
@Override
|
||||||
public void visit(ConditionalStatement statement) {
|
public void visit(ConditionalStatement statement) {
|
||||||
accept(statement.getCondition());
|
accept(statement.getCondition());
|
||||||
|
++blockLevel;
|
||||||
var conditional = new WasmConditional(forCondition(result));
|
var conditional = new WasmConditional(forCondition(result));
|
||||||
visitMany(statement.getConsequent(), conditional.getThenBlock().getBody());
|
visitMany(statement.getConsequent(), conditional.getThenBlock().getBody());
|
||||||
visitMany(statement.getAlternative(), conditional.getElseBlock().getBody());
|
visitMany(statement.getAlternative(), conditional.getElseBlock().getBody());
|
||||||
|
--blockLevel;
|
||||||
resultConsumer.add(conditional);
|
resultConsumer.add(conditional);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,6 +619,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
.max().orElse(0);
|
.max().orElse(0);
|
||||||
|
|
||||||
var defaultBlock = new WasmBlock(false);
|
var defaultBlock = new WasmBlock(false);
|
||||||
|
++blockLevel;
|
||||||
breakTargets.put(statement, defaultBlock);
|
breakTargets.put(statement, defaultBlock);
|
||||||
var oldBreakTarget = currentBreakTarget;
|
var oldBreakTarget = currentBreakTarget;
|
||||||
currentBreakTarget = statement;
|
currentBreakTarget = statement;
|
||||||
|
@ -651,6 +655,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
breakTargets.remove(statement);
|
breakTargets.remove(statement);
|
||||||
currentBreakTarget = oldBreakTarget;
|
currentBreakTarget = oldBreakTarget;
|
||||||
|
|
||||||
|
--blockLevel;
|
||||||
resultConsumer.add(wrapper);
|
resultConsumer.add(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,6 +743,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
var wrapper = new WasmBlock(false);
|
var wrapper = new WasmBlock(false);
|
||||||
var loop = new WasmBlock(true);
|
var loop = new WasmBlock(true);
|
||||||
|
|
||||||
|
++blockLevel;
|
||||||
continueTargets.put(statement, loop);
|
continueTargets.put(statement, loop);
|
||||||
breakTargets.put(statement, wrapper);
|
breakTargets.put(statement, wrapper);
|
||||||
var oldBreakTarget = currentBreakTarget;
|
var oldBreakTarget = currentBreakTarget;
|
||||||
|
@ -765,6 +771,8 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
} else {
|
} else {
|
||||||
resultConsumer.add(loop);
|
resultConsumer.add(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--blockLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WasmExpression invocation(InvocationExpr expr, List<WasmExpression> resultConsumer, boolean willDrop) {
|
protected WasmExpression invocation(InvocationExpr expr, List<WasmExpression> resultConsumer, boolean willDrop) {
|
||||||
|
@ -957,6 +965,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
@Override
|
@Override
|
||||||
public void visit(BlockStatement statement) {
|
public void visit(BlockStatement statement) {
|
||||||
var block = new WasmBlock(false);
|
var block = new WasmBlock(false);
|
||||||
|
++blockLevel;
|
||||||
|
|
||||||
if (statement.getId() != null) {
|
if (statement.getId() != null) {
|
||||||
breakTargets.put(statement, block);
|
breakTargets.put(statement, block);
|
||||||
|
@ -969,6 +978,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
}
|
}
|
||||||
|
|
||||||
resultConsumer.add(block);
|
resultConsumer.add(block);
|
||||||
|
--blockLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1053,9 +1063,15 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
} else {
|
} else {
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
var wasmStatement = new WasmReturn(result);
|
if (blockLevel == 0) {
|
||||||
wasmStatement.setLocation(statement.getLocation());
|
if (result != null) {
|
||||||
resultConsumer.add(wasmStatement);
|
resultConsumer.add(result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var wasmStatement = new WasmReturn(result);
|
||||||
|
wasmStatement.setLocation(statement.getLocation());
|
||||||
|
resultConsumer.add(wasmStatement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WasmExpression forceType(WasmExpression expression, ValueType type) {
|
protected WasmExpression forceType(WasmExpression expression, ValueType type) {
|
||||||
|
@ -1181,6 +1197,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
protected void generateTry(List<TryCatchStatement> tryCatchStatements, List<Statement> protectedBody) {
|
protected void generateTry(List<TryCatchStatement> tryCatchStatements, List<Statement> protectedBody) {
|
||||||
var throwableType = mapType(ValueType.object("java.lang.Throwable"));
|
var throwableType = mapType(ValueType.object("java.lang.Throwable"));
|
||||||
var innerCatchBlock = new WasmBlock(false);
|
var innerCatchBlock = new WasmBlock(false);
|
||||||
|
++blockLevel;
|
||||||
|
|
||||||
var catchBlocks = new ArrayList<WasmBlock>();
|
var catchBlocks = new ArrayList<WasmBlock>();
|
||||||
for (int i = 0; i < tryCatchStatements.size(); ++i) {
|
for (int i = 0; i < tryCatchStatements.size(); ++i) {
|
||||||
|
@ -1247,6 +1264,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
|
|
||||||
resultConsumer.add(outerCatchBlock);
|
resultConsumer.add(outerCatchBlock);
|
||||||
tempVars.release(exceptionVar);
|
tempVars.release(exceptionVar);
|
||||||
|
--blockLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkExceptionType(TryCatchStatement tryCatch, WasmLocal exceptionVar, List<WasmExpression> target,
|
protected void checkExceptionType(TryCatchStatement tryCatch, WasmLocal exceptionVar, List<WasmExpression> target,
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.teavm.ast.ArrayType;
|
||||||
import org.teavm.ast.BinaryExpr;
|
import org.teavm.ast.BinaryExpr;
|
||||||
import org.teavm.ast.CastExpr;
|
import org.teavm.ast.CastExpr;
|
||||||
import org.teavm.ast.ConditionalExpr;
|
import org.teavm.ast.ConditionalExpr;
|
||||||
|
import org.teavm.ast.ConstantExpr;
|
||||||
import org.teavm.ast.Expr;
|
import org.teavm.ast.Expr;
|
||||||
import org.teavm.ast.InstanceOfExpr;
|
import org.teavm.ast.InstanceOfExpr;
|
||||||
import org.teavm.ast.InvocationExpr;
|
import org.teavm.ast.InvocationExpr;
|
||||||
|
@ -281,20 +282,12 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
if (expr.getType() == null) {
|
if (expr.getType() == null) {
|
||||||
switch (expr.getOperation()) {
|
switch (expr.getOperation()) {
|
||||||
case EQUALS: {
|
case EQUALS: {
|
||||||
accept(expr.getFirstOperand());
|
isReferenceEq(expr);
|
||||||
var first = result;
|
|
||||||
accept(expr.getSecondOperand());
|
|
||||||
var second = result;
|
|
||||||
result = new WasmReferencesEqual(first, second);
|
|
||||||
result.setLocation(expr.getLocation());
|
result.setLocation(expr.getLocation());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case NOT_EQUALS:
|
case NOT_EQUALS:
|
||||||
accept(expr.getFirstOperand());
|
isReferenceEq(expr);
|
||||||
var first = result;
|
|
||||||
accept(expr.getSecondOperand());
|
|
||||||
var second = result;
|
|
||||||
result = new WasmReferencesEqual(first, second);
|
|
||||||
result = new WasmIntUnary(WasmIntType.INT32, WasmIntUnaryOperation.EQZ, result);
|
result = new WasmIntUnary(WasmIntType.INT32, WasmIntUnaryOperation.EQZ, result);
|
||||||
result.setLocation(expr.getLocation());
|
result.setLocation(expr.getLocation());
|
||||||
return;
|
return;
|
||||||
|
@ -305,6 +298,29 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
super.visit(expr);
|
super.visit(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void isReferenceEq(BinaryExpr expr) {
|
||||||
|
if (isNull(expr.getFirstOperand())) {
|
||||||
|
accept(expr.getSecondOperand());
|
||||||
|
result = new WasmIsNull(result);
|
||||||
|
} else if (isNull(expr.getSecondOperand())) {
|
||||||
|
accept(expr.getFirstOperand());
|
||||||
|
result = new WasmIsNull(result);
|
||||||
|
} else {
|
||||||
|
accept(expr.getFirstOperand());
|
||||||
|
var first = result;
|
||||||
|
accept(expr.getSecondOperand());
|
||||||
|
var second = result;
|
||||||
|
result = new WasmReferencesEqual(first, second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNull(Expr expr) {
|
||||||
|
if (!(expr instanceof ConstantExpr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ((ConstantExpr) expr).getValue() == null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WasmExpression generateVirtualCall(WasmLocal instance, MethodReference method,
|
protected WasmExpression generateVirtualCall(WasmLocal instance, MethodReference method,
|
||||||
List<WasmExpression> arguments) {
|
List<WasmExpression> arguments) {
|
||||||
|
|
|
@ -1406,7 +1406,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
||||||
if (debugLines != null) {
|
if (debugLines != null) {
|
||||||
debugLines.advance(writer.getPosition() + addressOffset);
|
debugLines.advance(writer.getPosition() + addressOffset);
|
||||||
while (!methodStack.isEmpty()) {
|
while (!methodStack.isEmpty()) {
|
||||||
methodStack.removeLast();
|
methodStack.remove(methodStack.size() - 1);
|
||||||
debugLines.end();
|
debugLines.end();
|
||||||
}
|
}
|
||||||
debugLines.end();
|
debugLines.end();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user