mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Creating Wasm -> C translator
This commit is contained in:
parent
199d91d28c
commit
0ac61919d5
|
@ -60,7 +60,7 @@ import org.teavm.backend.wasm.model.expression.WasmReturn;
|
|||
import org.teavm.backend.wasm.model.expression.WasmStoreInt32;
|
||||
import org.teavm.backend.wasm.patches.ClassPatch;
|
||||
import org.teavm.backend.wasm.patches.ObjectPatch;
|
||||
import org.teavm.backend.wasm.render.WasmRenderer;
|
||||
import org.teavm.backend.wasm.render.WasmCRenderer;
|
||||
import org.teavm.dependency.ClassDependency;
|
||||
import org.teavm.dependency.DependencyChecker;
|
||||
import org.teavm.dependency.DependencyListener;
|
||||
|
@ -103,6 +103,7 @@ import org.teavm.vm.spi.TeaVMHostExtension;
|
|||
|
||||
public class WasmTarget implements TeaVMTarget {
|
||||
private TeaVMTargetController controller;
|
||||
private boolean debugging;
|
||||
|
||||
@Override
|
||||
public void setController(TeaVMTargetController controller) {
|
||||
|
@ -134,6 +135,14 @@ public class WasmTarget implements TeaVMTarget {
|
|||
return listeners;
|
||||
}
|
||||
|
||||
public boolean isDebugging() {
|
||||
return debugging;
|
||||
}
|
||||
|
||||
public void setDebugging(boolean debugging) {
|
||||
this.debugging = debugging;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeDependencies(DependencyChecker dependencyChecker) {
|
||||
for (Class type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
||||
|
@ -301,7 +310,8 @@ public class WasmTarget implements TeaVMTarget {
|
|||
module.getFunctionTable().add(module.getFunctions().get(function));
|
||||
}
|
||||
|
||||
WasmRenderer renderer = new WasmRenderer();
|
||||
WasmCRenderer renderer = new WasmCRenderer();
|
||||
renderer.setOutputLineNumbers(debugging);
|
||||
renderer.render(module);
|
||||
|
||||
try {
|
||||
|
|
|
@ -31,4 +31,13 @@ class CBlock extends CLine {
|
|||
public List<CLine> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
void render(WasmCRenderer target) {
|
||||
target.indent();
|
||||
for (CLine line : lines) {
|
||||
line.render(target);
|
||||
}
|
||||
target.outdent();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.backend.wasm.render;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.teavm.model.TextLocation;
|
||||
|
||||
class CExpression {
|
||||
private String text;
|
||||
|
@ -50,6 +51,14 @@ class CExpression {
|
|||
return lines;
|
||||
}
|
||||
|
||||
public void addLine(String text, TextLocation location) {
|
||||
lines.add(new CSingleLine(text, location));
|
||||
}
|
||||
|
||||
public void addLine(String text) {
|
||||
addLine(text, null);
|
||||
}
|
||||
|
||||
public static CExpression relocatable(String text) {
|
||||
CExpression expression = new CExpression(text);
|
||||
expression.setRelocatable(true);
|
||||
|
|
|
@ -16,4 +16,5 @@
|
|||
package org.teavm.backend.wasm.render;
|
||||
|
||||
abstract class CLine {
|
||||
abstract void render(WasmCRenderer target);
|
||||
}
|
||||
|
|
|
@ -15,14 +15,52 @@
|
|||
*/
|
||||
package org.teavm.backend.wasm.render;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.teavm.model.TextLocation;
|
||||
|
||||
class CSingleLine extends CLine {
|
||||
private String text;
|
||||
private TextLocation location;
|
||||
|
||||
public CSingleLine(String text) {
|
||||
this(text, null);
|
||||
}
|
||||
|
||||
public CSingleLine(String text, TextLocation location) {
|
||||
this.text = text;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public TextLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(TextLocation location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
void render(WasmCRenderer target) {
|
||||
if (target.outputLineNumbers) {
|
||||
TextLocation location = this.location;
|
||||
if (location == null) {
|
||||
location = target.lastReportedLocation;
|
||||
}
|
||||
if (location != null) {
|
||||
if (!Objects.equals(target.currentFile, location.getFileName())) {
|
||||
target.line("#line " + (location.getLine() - 1) + " \"" + location.getFileName() + "\"");
|
||||
} else if (location.getLine() != target.currentLine) {
|
||||
target.line("#line " + (location.getLine() - 1));
|
||||
}
|
||||
target.currentFile = location.getFileName();
|
||||
target.currentLine = location.getLine() + 1;
|
||||
target.lastReportedLocation = location;
|
||||
}
|
||||
}
|
||||
target.line(text);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,5 +15,187 @@
|
|||
*/
|
||||
package org.teavm.backend.wasm.render;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.teavm.backend.wasm.model.WasmFunction;
|
||||
import org.teavm.backend.wasm.model.WasmLocal;
|
||||
import org.teavm.backend.wasm.model.WasmMemorySegment;
|
||||
import org.teavm.backend.wasm.model.WasmModule;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.model.TextLocation;
|
||||
|
||||
public class WasmCRenderer {
|
||||
private StringBuilder out = new StringBuilder();
|
||||
private int indentLevel;
|
||||
String currentFile = "";
|
||||
int currentLine = -1;
|
||||
boolean outputLineNumbers;
|
||||
TextLocation lastReportedLocation;
|
||||
|
||||
public boolean isOutputLineNumbers() {
|
||||
return outputLineNumbers;
|
||||
}
|
||||
|
||||
public void setOutputLineNumbers(boolean outputLineNumbers) {
|
||||
this.outputLineNumbers = outputLineNumbers;
|
||||
}
|
||||
|
||||
void indent() {
|
||||
++indentLevel;
|
||||
}
|
||||
|
||||
void outdent() {
|
||||
--indentLevel;
|
||||
}
|
||||
|
||||
void line(String line) {
|
||||
for (int i = 0; i < indentLevel; ++i) {
|
||||
out.append(" ");
|
||||
}
|
||||
out.append(line).append("\n");
|
||||
}
|
||||
|
||||
public void render(WasmModule module) {
|
||||
line("#include <inttypes.h>");
|
||||
line("#include <string.h>");
|
||||
line("#include <stdlib.h>");
|
||||
line("#include <assert.h>");
|
||||
line("");
|
||||
|
||||
renderFunctionDeclarations(module);
|
||||
line("static int8_t *wasm_heap;");
|
||||
renderFunctionTable(module);
|
||||
|
||||
for (WasmFunction function : module.getFunctions().values()) {
|
||||
if (function.getImportName() == null) {
|
||||
renderFunction(function);
|
||||
}
|
||||
}
|
||||
|
||||
line("void main() {");
|
||||
indent();
|
||||
|
||||
renderHeap(module);
|
||||
if (module.getStartFunction() != null) {
|
||||
line(module.getStartFunction().getName() + "();");
|
||||
}
|
||||
|
||||
for (WasmFunction function : module.getFunctions().values()) {
|
||||
if (function.getExportName() != null && function.getExportName().equals("main")) {
|
||||
line(function.getName() + "(0);");
|
||||
}
|
||||
}
|
||||
|
||||
outdent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void renderHeap(WasmModule module) {
|
||||
line("wasm_heap = malloc(" + 65535 * module.getMemorySize() + ");");
|
||||
for (WasmMemorySegment segment : module.getSegments()) {
|
||||
line("memcpy(wasm_heap + " + segment.getOffset() + ",");
|
||||
indent();
|
||||
for (int i = 0; i < segment.getLength(); i += 48) {
|
||||
byte[] data = segment.getData(i, Math.min(i + 48, segment.getLength()) - i);
|
||||
boolean last = i + data.length >= segment.getLength();
|
||||
StringBuilder sb = new StringBuilder("\"");
|
||||
for (int j = 0; j < data.length; ++j) {
|
||||
byte b = data[j];
|
||||
sb.append("\\x")
|
||||
.append(Character.forDigit((b >>> 4) & 0xF, 16))
|
||||
.append(Character.forDigit(b & 0xF, 16));
|
||||
}
|
||||
sb.append("\"");
|
||||
if (last) {
|
||||
sb.append(", " + segment.getLength() + ");");
|
||||
}
|
||||
line(sb.toString());
|
||||
}
|
||||
outdent();
|
||||
}
|
||||
}
|
||||
|
||||
private void renderFunctionTable(WasmModule module) {
|
||||
line("static void *wasm_table[] = {");
|
||||
if (!module.getFunctionTable().isEmpty()) {
|
||||
indent();
|
||||
for (int i = 0; i < module.getFunctionTable().size() - 1; ++i) {
|
||||
WasmFunction function = module.getFunctionTable().get(i);
|
||||
line(function.getName() + ",");
|
||||
}
|
||||
line(module.getFunctionTable().get(module.getFunctionTable().size() - 1).getName());
|
||||
outdent();
|
||||
}
|
||||
line("};");
|
||||
line("");
|
||||
}
|
||||
|
||||
private void renderFunctionDeclarations(WasmModule module) {
|
||||
for (WasmFunction function : module.getFunctions().values()) {
|
||||
line(functionDeclaration(function) + ";");
|
||||
}
|
||||
}
|
||||
|
||||
private void renderFunction(WasmFunction function) {
|
||||
line(functionDeclaration(function) + " {");
|
||||
indent();
|
||||
|
||||
List<WasmLocal> variables = function.getLocalVariables().subList(function.getParameters().size(),
|
||||
function.getLocalVariables().size());
|
||||
for (WasmLocal variable : variables) {
|
||||
line(WasmCRenderingVisitor.mapType(variable.getType()) + " var_" + variable.getIndex() + ";");
|
||||
}
|
||||
|
||||
WasmCRenderingVisitor visitor = new WasmCRenderingVisitor(function.getResult(), function.getModule());
|
||||
List<WasmExpression> body = function.getBody();
|
||||
List<CLine> lines = new ArrayList<>();
|
||||
if (!body.isEmpty()) {
|
||||
for (int i = 0; i < body.size() - 1; ++i) {
|
||||
visitor.setRequiredType(null);
|
||||
body.get(i).acceptVisitor(visitor);
|
||||
lines.addAll(visitor.getValue().getLines());
|
||||
}
|
||||
|
||||
visitor.setRequiredType(function.getResult());
|
||||
body.get(body.size() - 1).acceptVisitor(visitor);
|
||||
lines.addAll(visitor.getValue().getLines());
|
||||
if (visitor.getValue().getText() != null) {
|
||||
lines.add(new CSingleLine(visitor.getValue().getText()));
|
||||
}
|
||||
}
|
||||
|
||||
for (CLine line : lines) {
|
||||
line.render(this);
|
||||
}
|
||||
|
||||
outdent();
|
||||
line("}");
|
||||
line("");
|
||||
}
|
||||
|
||||
private String functionDeclaration(WasmFunction function) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (function.getImportName() != null) {
|
||||
sb.append("extern ");
|
||||
} else if (function.getExportName() == null) {
|
||||
sb.append("static ");
|
||||
}
|
||||
sb.append(WasmCRenderingVisitor.mapType(function.getResult())).append(' ');
|
||||
sb.append(function.getName()).append("(");
|
||||
for (int i = 0; i < function.getParameters().size(); ++i) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(WasmCRenderingVisitor.mapType(function.getParameters().get(i)));
|
||||
sb.append(" var_" + i);
|
||||
}
|
||||
sb.append(")");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
private WasmType functionType;
|
||||
private WasmModule module;
|
||||
|
||||
public WasmCRenderingVisitor(WasmType functionType, WasmModule module) {
|
||||
WasmCRenderingVisitor(WasmType functionType, WasmModule module) {
|
||||
this.functionType = functionType;
|
||||
this.module = module;
|
||||
}
|
||||
|
@ -76,6 +76,10 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
return value;
|
||||
}
|
||||
|
||||
void setRequiredType(WasmType requiredType) {
|
||||
this.requiredType = requiredType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmBlock expression) {
|
||||
BlockInfo info = new BlockInfo();
|
||||
|
@ -99,7 +103,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
result.getLines().addAll(value.getLines());
|
||||
if (info.type != null) {
|
||||
if (info.temporaryVariable != null) {
|
||||
result.getLines().add(new CSingleLine(info.temporaryVariable + " = " + result.getText()));
|
||||
result.getLines().add(new CSingleLine(info.temporaryVariable + " = " + value.getText() + ";"));
|
||||
result.setText(info.temporaryVariable);
|
||||
} else {
|
||||
result.setText(value.getText());
|
||||
|
@ -110,14 +114,15 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
result.getLines().add(0, declareVariable(info.temporaryVariable, info.type));
|
||||
}
|
||||
|
||||
if (info.label != null || expression.isLoop()) {
|
||||
if (expression.isLoop()) {
|
||||
List<CLine> lines = new ArrayList<>();
|
||||
String header = expression.isLoop() ? "for(;;) " : "";
|
||||
lines.add(new CSingleLine(info.label + ": " + header + "{"));
|
||||
lines.add(new CSingleLine(getLabel(info) + ": do {"));
|
||||
lines.add(new CBlock(result.getLines()));
|
||||
lines.add(new CSingleLine("}"));
|
||||
lines.add(new CSingleLine("} while(0);"));
|
||||
result.getLines().clear();
|
||||
result.getLines().addAll(lines);
|
||||
} else if (info.label != null) {
|
||||
result.getLines().add(new CSingleLine(info.label + ": ;"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,9 +137,9 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
requiredType = WasmType.INT32;
|
||||
expression.getCondition().acceptVisitor(this);
|
||||
result.getLines().addAll(value.getLines());
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.getLines().add(new CSingleLine("if (" + value.getText() + ") {"));
|
||||
CBlock breakBlock = new CBlock(generateBreak(expression.getResult(), expression.getTarget()));
|
||||
result.addLine("if (" + value.getText() + ") {", expression.getLocation());
|
||||
CBlock breakBlock = new CBlock(generateBreak(expression.getResult(), expression.getTarget(),
|
||||
expression.getLocation()));
|
||||
result.getLines().add(breakBlock);
|
||||
result.getLines().add(new CSingleLine("}"));
|
||||
|
||||
|
@ -144,11 +149,12 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmBreak expression) {
|
||||
CExpression result = new CExpression();
|
||||
result.getLines().addAll(generateBreak(expression.getResult(), expression.getTarget()));
|
||||
result.getLines().addAll(generateBreak(expression.getResult(), expression.getTarget(),
|
||||
expression.getLocation()));
|
||||
value = result;
|
||||
}
|
||||
|
||||
private List<CLine> generateBreak(WasmExpression result, WasmBlock target) {
|
||||
private List<CLine> generateBreak(WasmExpression result, WasmBlock target, TextLocation location) {
|
||||
List<CLine> lines = new ArrayList<>();
|
||||
BlockInfo targetInfo = blockInfoMap.get(target);
|
||||
|
||||
|
@ -156,25 +162,24 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
if (targetInfo.temporaryVariable == null) {
|
||||
targetInfo.temporaryVariable = "tmp_" + temporaryIndex++;
|
||||
}
|
||||
if (targetInfo.label == null) {
|
||||
targetInfo.label = "block_" + blockIndex++;
|
||||
}
|
||||
requiredType = targetInfo.type;
|
||||
result.acceptVisitor(this);
|
||||
lines.addAll(value.getLines());
|
||||
reportLocation(result.getLocation(), lines);
|
||||
lines.add(new CSingleLine(targetInfo.temporaryVariable + " = " + value.getText() + ";"));
|
||||
}
|
||||
reportLocation(result.getLocation(), lines);
|
||||
if (target.isLoop()) {
|
||||
lines.add(new CSingleLine("break " + targetInfo.label + ";"));
|
||||
} else {
|
||||
lines.add(new CSingleLine("continue " + targetInfo.label + ";"));
|
||||
lines.add(new CSingleLine(targetInfo.temporaryVariable + " = " + value.getText() + ";",
|
||||
result.getLocation()));
|
||||
}
|
||||
lines.add(new CSingleLine("goto " + getLabel(targetInfo) + ";", location));
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
private String getLabel(BlockInfo blockInfo) {
|
||||
if (blockInfo.label == null) {
|
||||
blockInfo.label = "block_" + blockIndex++;
|
||||
}
|
||||
return blockInfo.label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmSwitch expression) {
|
||||
CExpression result = new CExpression();
|
||||
|
@ -182,24 +187,17 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
requiredType = WasmType.INT32;
|
||||
expression.getSelector().acceptVisitor(this);
|
||||
result.getLines().addAll(value.getLines());
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.getLines().add(new CSingleLine("switch (" + value.getLines() + ") {"));
|
||||
result.addLine("switch (" + value.getText() + ") {", expression.getLocation());
|
||||
|
||||
CBlock switchBlock = new CBlock();
|
||||
result.getLines().add(switchBlock);
|
||||
for (int i = 0; i < expression.getTargets().size(); ++i) {
|
||||
BlockInfo targetInfo = blockInfoMap.get(expression.getTargets().get(i));
|
||||
if (targetInfo.label == null) {
|
||||
targetInfo.label = "block_" + blockIndex++;
|
||||
}
|
||||
switchBlock.getLines().add(new CSingleLine("case " + i + ": break " + targetInfo.label + ";"));
|
||||
switchBlock.getLines().add(new CSingleLine("case " + i + ": goto " + getLabel(targetInfo) + ";"));
|
||||
}
|
||||
|
||||
BlockInfo defaultTargetInfo = blockInfoMap.get(expression.getDefaultTarget());
|
||||
if (defaultTargetInfo.label == null) {
|
||||
defaultTargetInfo.label = "block_" + blockIndex++;
|
||||
}
|
||||
switchBlock.getLines().add(new CSingleLine("default: break " + defaultTargetInfo.label + ";"));
|
||||
switchBlock.getLines().add(new CSingleLine("default: goto " + getLabel(defaultTargetInfo) + ";"));
|
||||
|
||||
result.getLines().add(new CSingleLine("}"));
|
||||
|
||||
|
@ -241,17 +239,18 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
CBlock thenBlock = new CBlock();
|
||||
thenBlock.getLines().addAll(thenExpression.getLines());
|
||||
if (temporary != null) {
|
||||
thenBlock.getLines().add(new CSingleLine(temporary + " = " + thenExpression.getText()));
|
||||
thenBlock.getLines().add(new CSingleLine(temporary + " = " + thenExpression.getText() + ";"));
|
||||
}
|
||||
result.getLines().add(thenBlock);
|
||||
|
||||
if (!elseExpression.getText().isEmpty() || elseExpression.getText() != null) {
|
||||
if (elseExpression.getText() != null || !elseExpression.getLines().isEmpty()) {
|
||||
result.getLines().add(new CSingleLine("} else {"));
|
||||
CBlock elseBlock = new CBlock();
|
||||
elseBlock.getLines().addAll(elseBlock.getLines());
|
||||
elseBlock.getLines().addAll(elseExpression.getLines());
|
||||
if (temporary != null) {
|
||||
elseBlock.getLines().add(new CSingleLine(temporary + " = " + elseExpression.getText()));
|
||||
elseBlock.getLines().add(new CSingleLine(temporary + " = " + elseExpression.getText() + ";"));
|
||||
}
|
||||
result.getLines().add(elseBlock);
|
||||
}
|
||||
|
||||
result.getLines().add(new CSingleLine("}"));
|
||||
|
@ -267,11 +266,9 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
requiredType = functionType;
|
||||
expression.getValue().acceptVisitor(this);
|
||||
result.getLines().addAll(value.getLines());
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.getLines().add(new CSingleLine("return " + value.getText() + ";"));
|
||||
result.addLine("return " + value.getText() + ";", expression.getLocation());
|
||||
} else {
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.getLines().add(new CSingleLine("return;"));
|
||||
result.addLine("return;", expression.getLocation());
|
||||
}
|
||||
|
||||
value = result;
|
||||
|
@ -280,8 +277,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmUnreachable expression) {
|
||||
CExpression result = new CExpression();
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.getLines().add(new CSingleLine("assert(false);"));
|
||||
result.addLine("assert(0);", expression.getLocation());
|
||||
value = result;
|
||||
}
|
||||
|
||||
|
@ -317,7 +313,8 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
expression.getValue().acceptVisitor(this);
|
||||
result.getLines().addAll(value.getLines());
|
||||
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.addLine("var_" + expression.getLocal().getIndex() + " = " + value.getText() + ";",
|
||||
expression.getLocation());
|
||||
|
||||
value = result;
|
||||
}
|
||||
|
@ -514,7 +511,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
if (expression.isRelocatable()) {
|
||||
return expression;
|
||||
}
|
||||
String var = "tmp_" + temporaryIndex;
|
||||
String var = "tmp_" + temporaryIndex++;
|
||||
target.getLines().add(new CSingleLine(mapType(type) + " " + var + " = " + expression.getText() + ";"));
|
||||
return CExpression.relocatable(var);
|
||||
}
|
||||
|
@ -615,7 +612,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
CExpression operand = value;
|
||||
|
||||
result.getLines().addAll(operand.getLines());
|
||||
if (type != null && expression.getSourceType() != expression.getSourceType()) {
|
||||
if (type != null && expression.getSourceType() != expression.getTargetType()) {
|
||||
switch (expression.getTargetType()) {
|
||||
case INT32:
|
||||
if (expression.isSigned()) {
|
||||
|
@ -652,7 +649,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
value = operand;
|
||||
value = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -668,8 +665,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
result.setText(sb.toString());
|
||||
|
||||
if (type == null) {
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.getLines().add(new CSingleLine(result.getText()));
|
||||
result.addLine(result.getText() + ";", expression.getLocation());
|
||||
result.setText(null);
|
||||
}
|
||||
value = result;
|
||||
|
@ -688,19 +684,19 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
sb.append(mapType(expression.getParameterTypes().get(i)));
|
||||
}
|
||||
sb.append(") ");
|
||||
sb.append(")) ");
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getSelector().acceptVisitor(this);
|
||||
value = cacheIfNeeded(WasmType.INT32, value, result);
|
||||
result.getLines().addAll(value.getLines());
|
||||
sb.append("wasm_table[" + result.getText() + "])(");
|
||||
sb.append("wasm_table[" + value.getText() + "])(");
|
||||
translateArguments(expression.getArguments(), expression.getParameterTypes(), result, sb);
|
||||
sb.append(")");
|
||||
result.setText(sb.toString());
|
||||
|
||||
if (type == null) {
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
result.getLines().add(new CSingleLine(result.getText()));
|
||||
result.addLine(result.getText() + ";", expression.getLocation());
|
||||
result.setText(null);
|
||||
}
|
||||
value = result;
|
||||
|
@ -742,7 +738,6 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmDrop expression) {
|
||||
CExpression result = new CExpression();
|
||||
requiredType = null;
|
||||
reportLocation(expression.getLocation(), result.getLines());
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
result.getLines().addAll(value.getLines());
|
||||
value = result;
|
||||
|
@ -754,7 +749,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
WasmType type = requiredType;
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex();
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
if (type == null) {
|
||||
value = index;
|
||||
|
@ -764,19 +759,19 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
result.getLines().addAll(index.getLines());
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
result.setText("(int32_t) (int8_t) wasm_heap[" + index + "]");
|
||||
result.setText("(int32_t) (int8_t) wasm_heap[" + index.getText() + "]");
|
||||
break;
|
||||
case UINT8:
|
||||
result.setText("(int32_t) (uint8_t) wasm_heap[" + index + "]");
|
||||
result.setText("(int32_t) (uint8_t) wasm_heap[" + index.getText() + "]");
|
||||
break;
|
||||
case INT16:
|
||||
result.setText("(int32_t) *((int16_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("(int32_t) *((int16_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
case UINT16:
|
||||
result.setText("(int32_t) *((uint16_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("(int32_t) *((uint16_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
case INT32:
|
||||
result.setText("*((int32_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("*((int32_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -789,7 +784,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
WasmType type = requiredType;
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex();
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
if (type == null) {
|
||||
value = index;
|
||||
|
@ -799,25 +794,25 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
result.getLines().addAll(index.getLines());
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
result.setText("(int64_t) (int8_t) wasm_heap[" + index + "]");
|
||||
result.setText("(int64_t) (int8_t) wasm_heap[" + index.getText() + "]");
|
||||
break;
|
||||
case UINT8:
|
||||
result.setText("(int64_t) (uint8_t) wasm_heap[" + index + "]");
|
||||
result.setText("(int64_t) (uint8_t) wasm_heap[" + index.getText() + "]");
|
||||
break;
|
||||
case INT16:
|
||||
result.setText("(int64_t) *((int16_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("(int64_t) *((int16_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
case UINT16:
|
||||
result.setText("(int64_t) *((uint16_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("(int64_t) *((uint16_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
case INT32:
|
||||
result.setText("(int64_t) *((int32_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("(int64_t) *((int32_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
case UINT32:
|
||||
result.setText("(int64_t) *((uint32_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("(int64_t) *((uint32_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
case INT64:
|
||||
result.setText("*((int64_t *) &wasm_heap[" + index + "])");
|
||||
result.setText("*((int64_t *) &wasm_heap[" + index.getText() + "])");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -830,7 +825,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
WasmType type = requiredType;
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex();
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
if (type == null) {
|
||||
value = index;
|
||||
|
@ -838,7 +833,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
|
||||
result.getLines().addAll(index.getLines());
|
||||
result.setText("*((float *) &wasm_heap[" + index + "])");
|
||||
result.setText("*((float *) &wasm_heap[" + index.getText() + "])");
|
||||
|
||||
value = result;
|
||||
}
|
||||
|
@ -849,7 +844,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
WasmType type = requiredType;
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex();
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
if (type == null) {
|
||||
value = index;
|
||||
|
@ -857,42 +852,145 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
|
||||
result.getLines().addAll(index.getLines());
|
||||
result.setText("*((double *) &wasm_heap[" + index + "])");
|
||||
result.setText("*((double *) &wasm_heap[" + index.getText() + "])");
|
||||
|
||||
value = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreInt32 expression) {
|
||||
CExpression result = new CExpression();
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getValue().acceptVisitor(this);
|
||||
CExpression valueToStore = value;
|
||||
|
||||
result.getLines().addAll(index.getLines());
|
||||
result.getLines().addAll(valueToStore.getLines());
|
||||
|
||||
String line;
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
line = "wasm_heap[" + index.getText() + "] = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case UINT8:
|
||||
line = "*((uint8_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case INT16:
|
||||
line = "*((int16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case UINT16:
|
||||
line = "*((uint16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case INT32:
|
||||
line = "*((int32_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError(expression.getConvertTo().toString());
|
||||
}
|
||||
result.addLine(line, expression.getLocation());
|
||||
|
||||
value = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreInt64 expression) {
|
||||
CExpression result = new CExpression();
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
|
||||
requiredType = WasmType.INT64;
|
||||
expression.getValue().acceptVisitor(this);
|
||||
CExpression valueToStore = value;
|
||||
|
||||
result.getLines().addAll(index.getLines());
|
||||
result.getLines().addAll(valueToStore.getLines());
|
||||
|
||||
String line;
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
line = "wasm_heap[" + index.getText() + "] = " + valueToStore.getText();
|
||||
break;
|
||||
case UINT8:
|
||||
line = "*((uint8_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case INT16:
|
||||
line = "*((int16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case UINT16:
|
||||
line = "*((uint16_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case INT32:
|
||||
line = "*((int32_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case UINT32:
|
||||
line = "*((uint32_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
case INT64:
|
||||
line = "*((int64_t *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";";
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
result.addLine(line, expression.getLocation());
|
||||
|
||||
value = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreFloat32 expression) {
|
||||
CExpression result = new CExpression();
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
|
||||
requiredType = WasmType.FLOAT32;
|
||||
expression.getValue().acceptVisitor(this);
|
||||
CExpression valueToStore = value;
|
||||
|
||||
result.getLines().addAll(index.getLines());
|
||||
result.getLines().addAll(valueToStore.getLines());
|
||||
|
||||
result.addLine("*((float *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";",
|
||||
expression.getLocation());
|
||||
|
||||
value = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreFloat64 expression) {
|
||||
CExpression result = new CExpression();
|
||||
|
||||
requiredType = WasmType.INT32;
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
CExpression index = value;
|
||||
|
||||
requiredType = WasmType.FLOAT64;
|
||||
expression.getValue().acceptVisitor(this);
|
||||
CExpression valueToStore = value;
|
||||
|
||||
result.getLines().addAll(index.getLines());
|
||||
result.getLines().addAll(valueToStore.getLines());
|
||||
|
||||
result.addLine("*((double *) &wasm_heap[" + index.getText() + "]) = " + valueToStore.getText() + ";",
|
||||
expression.getLocation());
|
||||
|
||||
value = result;
|
||||
}
|
||||
|
||||
private CLine declareVariable(String name, WasmType type) {
|
||||
return new CSingleLine(mapType(type) + " " + name + ";");
|
||||
}
|
||||
|
||||
private void reportLocation(TextLocation location, List<CLine> lines) {
|
||||
if (location != null) {
|
||||
lines.add(new CSingleLine("#line " + location.getFileName() + " " + location.getLine()));
|
||||
}
|
||||
}
|
||||
|
||||
private static String mapType(WasmType type) {
|
||||
static String mapType(WasmType type) {
|
||||
if (type == null) {
|
||||
return "void";
|
||||
}
|
||||
|
@ -929,7 +1027,7 @@ class WasmCRenderingVisitor implements WasmExpressionVisitor {
|
|||
throw new AssertionError(type.toString());
|
||||
}
|
||||
|
||||
static class BlockInfo {
|
||||
private static class BlockInfo {
|
||||
int index;
|
||||
String label;
|
||||
String temporaryVariable;
|
||||
|
|
|
@ -320,6 +320,7 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
|
||||
private WasmTarget prepareWebAssemblyTarget() {
|
||||
webAssemblyTarget = new WasmTarget();
|
||||
webAssemblyTarget.setDebugging(debugInformationGenerated);
|
||||
return webAssemblyTarget;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user