mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
WASM: add support of 0x0D binary version
This commit is contained in:
parent
24efd1f49c
commit
9364ad943a
|
@ -63,6 +63,9 @@ public class WasmBinaryRenderer {
|
|||
case V_0xC:
|
||||
output.writeInt32(0xC);
|
||||
break;
|
||||
case V_0xD:
|
||||
output.writeInt32(0xD);
|
||||
break;
|
||||
}
|
||||
|
||||
renderSignatures(module);
|
||||
|
@ -91,14 +94,14 @@ public class WasmBinaryRenderer {
|
|||
|
||||
section.writeLEB(signatures.size());
|
||||
for (WasmSignature signature : signatures) {
|
||||
section.writeByte(0x40);
|
||||
section.writeByte(version == WasmBinaryVersion.V_0xD ? 0x60 : 0x40);
|
||||
section.writeLEB(signature.types.length - 1);
|
||||
for (int i = 1; i < signature.types.length; ++i) {
|
||||
section.writeType(signature.types[i]);
|
||||
section.writeType(signature.types[i], version);
|
||||
}
|
||||
if (signature.types[0] != null) {
|
||||
section.writeByte(1);
|
||||
section.writeType(signature.types[0]);
|
||||
section.writeType(signature.types[0], version);
|
||||
} else {
|
||||
section.writeByte(0);
|
||||
}
|
||||
|
@ -143,7 +146,7 @@ public class WasmBinaryRenderer {
|
|||
|
||||
section.writeAsciiString(function.getImportName());
|
||||
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
section.writeByte(EXTERNAL_KIND_FUNCTION);
|
||||
section.writeLEB(signatureIndex);
|
||||
}
|
||||
|
@ -185,7 +188,11 @@ public class WasmBinaryRenderer {
|
|||
}
|
||||
} else {
|
||||
section.writeByte(1);
|
||||
section.writeByte(0x20);
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
section.writeByte(0x70);
|
||||
} else {
|
||||
section.writeByte(0x20);
|
||||
}
|
||||
section.writeByte(0);
|
||||
section.writeLEB(functionIndexes.size());
|
||||
}
|
||||
|
@ -195,7 +202,7 @@ public class WasmBinaryRenderer {
|
|||
private void renderMemory(WasmModule module) {
|
||||
WasmBinaryWriter section = new WasmBinaryWriter();
|
||||
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
section.writeByte(1);
|
||||
section.writeByte(1);
|
||||
}
|
||||
|
@ -227,7 +234,7 @@ public class WasmBinaryRenderer {
|
|||
|
||||
section.writeAsciiString(function.getExportName());
|
||||
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
section.writeByte(EXTERNAL_KIND_FUNCTION);
|
||||
section.writeLEB(functionIndex);
|
||||
}
|
||||
|
@ -248,7 +255,7 @@ public class WasmBinaryRenderer {
|
|||
}
|
||||
|
||||
private void renderElement(WasmModule module) {
|
||||
if (module.getFunctionTable().isEmpty() || version != WasmBinaryVersion.V_0xC) {
|
||||
if (module.getFunctionTable().isEmpty() || version == WasmBinaryVersion.V_0xB) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -256,9 +263,7 @@ public class WasmBinaryRenderer {
|
|||
section.writeLEB(1);
|
||||
section.writeLEB(0);
|
||||
|
||||
section.writeByte(0x10);
|
||||
section.writeLEB(0);
|
||||
section.writeByte(0x0F);
|
||||
renderInitializer(section, 0);
|
||||
|
||||
section.writeLEB(module.getFunctionTable().size());
|
||||
for (WasmFunction function : module.getFunctionTable()) {
|
||||
|
@ -309,12 +314,12 @@ public class WasmBinaryRenderer {
|
|||
code.writeLEB(localEntries.size());
|
||||
for (LocalEntry entry : localEntries) {
|
||||
code.writeLEB(entry.count);
|
||||
code.writeType(entry.type);
|
||||
code.writeType(entry.type, version);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Integer> importIndexes = this.importIndexes;
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
importIndexes = this.functionIndexes;
|
||||
}
|
||||
WasmBinaryRenderingVisitor visitor = new WasmBinaryRenderingVisitor(code, version, functionIndexes,
|
||||
|
@ -324,11 +329,25 @@ public class WasmBinaryRenderer {
|
|||
}
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
code.writeByte(0x0F);
|
||||
} else if (version == WasmBinaryVersion.V_0xD) {
|
||||
code.writeByte(0x0B);
|
||||
}
|
||||
|
||||
return code.getData();
|
||||
}
|
||||
|
||||
private void renderInitializer(WasmBinaryWriter output, int value) {
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
output.writeByte(0x10);
|
||||
output.writeLEB(value);
|
||||
output.writeByte(0x0F);
|
||||
} else {
|
||||
output.writeByte(0x41);
|
||||
output.writeLEB(value);
|
||||
output.writeByte(0x0B);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderData(WasmModule module) {
|
||||
if (module.getSegments().isEmpty()) {
|
||||
return;
|
||||
|
@ -342,9 +361,7 @@ public class WasmBinaryRenderer {
|
|||
section.writeLEB(segment.getOffset());
|
||||
} else {
|
||||
section.writeByte(0);
|
||||
section.writeByte(0x10);
|
||||
section.writeLEB(segment.getOffset());
|
||||
section.writeByte(0xF);
|
||||
renderInitializer(section, segment.getOffset());
|
||||
}
|
||||
|
||||
section.writeLEB(segment.getLength());
|
||||
|
@ -393,7 +410,7 @@ public class WasmBinaryRenderer {
|
|||
}
|
||||
|
||||
private void writeSection(int id, String name, byte[] data) {
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
output.writeByte(id);
|
||||
int length = data.length;
|
||||
if (id == 0) {
|
||||
|
|
|
@ -70,22 +70,26 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmBlock expression) {
|
||||
int blockDepth = expression.isLoop() & version == WasmBinaryVersion.V_0xB ? 2 : 1;
|
||||
int blockDepth = expression.isLoop() && version == WasmBinaryVersion.V_0xB ? 2 : 1;
|
||||
depth += blockDepth;
|
||||
blockDepths.put(expression, depth);
|
||||
writer.writeByte(expression.isLoop() ? 0x02 : 0x01);
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
writer.writeByte(expression.isLoop() ? 0x03 : 0x02);
|
||||
} else {
|
||||
writer.writeByte(expression.isLoop() ? 0x02 : 0x01);
|
||||
}
|
||||
writeBlockType(expression.getType());
|
||||
for (WasmExpression part : expression.getBody()) {
|
||||
part.acceptVisitor(this);
|
||||
}
|
||||
writer.writeByte(0x0F);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x0B : 0x0F);
|
||||
blockDepths.remove(expression);
|
||||
depth -= blockDepth;
|
||||
}
|
||||
|
||||
private void writeBlockType(WasmType type) {
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
writer.writeType(type);
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
writer.writeType(type, version);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +99,9 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
expression.getResult().acceptVisitor(this);
|
||||
}
|
||||
expression.getCondition().acceptVisitor(this);
|
||||
writer.writeByte(0x07);
|
||||
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x0D : 0x07);
|
||||
|
||||
if (version == WasmBinaryVersion.V_0xB) {
|
||||
writer.writeByte(expression.getResult() != null ? 1 : 0);
|
||||
}
|
||||
|
@ -107,7 +113,9 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
if (expression.getResult() != null) {
|
||||
expression.getResult().acceptVisitor(this);
|
||||
}
|
||||
writer.writeByte(0x06);
|
||||
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x0C : 0x06);
|
||||
|
||||
if (version == WasmBinaryVersion.V_0xB) {
|
||||
writer.writeByte(expression.getResult() != null ? 1 : 0);
|
||||
}
|
||||
|
@ -117,23 +125,27 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmSwitch expression) {
|
||||
expression.getSelector().acceptVisitor(this);
|
||||
writer.writeByte(0x08);
|
||||
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x0E : 0x08);
|
||||
|
||||
if (version == WasmBinaryVersion.V_0xB) {
|
||||
writer.writeByte(0);
|
||||
}
|
||||
|
||||
writer.writeLEB(expression.getTargets().size());
|
||||
for (WasmBlock target : expression.getTargets()) {
|
||||
int targetDepth = blockDepths.get(target);
|
||||
int relativeDepth = depth - targetDepth;
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
writer.writeLEB(relativeDepth);
|
||||
} else {
|
||||
writer.writeFixed(relativeDepth);
|
||||
}
|
||||
}
|
||||
|
||||
int defaultDepth = blockDepths.get(expression.getDefaultTarget());
|
||||
int relativeDepth = depth - defaultDepth;
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
writer.writeLEB(relativeDepth);
|
||||
} else {
|
||||
writer.writeFixed(relativeDepth);
|
||||
|
@ -143,7 +155,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmConditional expression) {
|
||||
expression.getCondition().acceptVisitor(this);
|
||||
writer.writeByte(0x03);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x04 : 0x03);
|
||||
writeBlockType(expression.getType());
|
||||
|
||||
++depth;
|
||||
|
@ -154,7 +166,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
blockDepths.remove(expression.getThenBlock());
|
||||
|
||||
if (!expression.getElseBlock().getBody().isEmpty()) {
|
||||
writer.writeByte(0x04);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x05 : 0x04);
|
||||
blockDepths.put(expression.getElseBlock(), depth);
|
||||
for (WasmExpression part : expression.getElseBlock().getBody()) {
|
||||
part.acceptVisitor(this);
|
||||
|
@ -163,7 +175,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
--depth;
|
||||
|
||||
writer.writeByte(0x0F);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x0B : 0x0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -171,7 +183,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
if (expression.getValue() != null) {
|
||||
expression.getValue().acceptVisitor(this);
|
||||
}
|
||||
writer.writeByte(0x09);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x0F : 0x09);
|
||||
if (version == WasmBinaryVersion.V_0xB) {
|
||||
writer.writeByte(expression.getValue() != null ? 1 : 0);
|
||||
}
|
||||
|
@ -188,38 +200,38 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmInt32Constant expression) {
|
||||
writer.writeByte(0x10);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x41 : 0x10);
|
||||
writer.writeSignedLEB(expression.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmInt64Constant expression) {
|
||||
writer.writeByte(0x11);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x42 : 0x11);
|
||||
writer.writeSignedLEB(expression.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmFloat32Constant expression) {
|
||||
writer.writeByte(0x13);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x43 : 0x13);
|
||||
writer.writeFixed(Float.floatToRawIntBits(expression.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmFloat64Constant expression) {
|
||||
writer.writeByte(0x12);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x44 : 0x12);
|
||||
writer.writeFixed(Double.doubleToRawLongBits(expression.getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmGetLocal expression) {
|
||||
writer.writeByte(0x14);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x20 : 0x14);
|
||||
writer.writeLEB(expression.getLocal().getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmSetLocal expression) {
|
||||
expression.getValue().acceptVisitor(this);
|
||||
writer.writeByte(0x15);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x21 : 0x15);
|
||||
writer.writeLEB(expression.getLocal().getIndex());
|
||||
}
|
||||
|
||||
|
@ -227,6 +239,177 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmIntBinary expression) {
|
||||
expression.getFirst().acceptVisitor(this);
|
||||
expression.getSecond().acceptVisitor(this);
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
render0xD(expression);
|
||||
} else {
|
||||
renderOld(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void render0xD(WasmIntBinary expression) {
|
||||
switch (expression.getType()) {
|
||||
case INT32:
|
||||
switch (expression.getOperation()) {
|
||||
case ADD:
|
||||
writer.writeByte(0x6A);
|
||||
break;
|
||||
case SUB:
|
||||
writer.writeByte(0x6B);
|
||||
break;
|
||||
case MUL:
|
||||
writer.writeByte(0x6C);
|
||||
break;
|
||||
case DIV_SIGNED:
|
||||
writer.writeByte(0x6D);
|
||||
break;
|
||||
case DIV_UNSIGNED:
|
||||
writer.writeByte(0x6E);
|
||||
break;
|
||||
case REM_SIGNED:
|
||||
writer.writeByte(0x6F);
|
||||
break;
|
||||
case REM_UNSIGNED:
|
||||
writer.writeByte(0x70);
|
||||
break;
|
||||
case AND:
|
||||
writer.writeByte(0x71);
|
||||
break;
|
||||
case OR:
|
||||
writer.writeByte(0x72);
|
||||
break;
|
||||
case XOR:
|
||||
writer.writeByte(0x73);
|
||||
break;
|
||||
case SHL:
|
||||
writer.writeByte(0x74);
|
||||
break;
|
||||
case SHR_UNSIGNED:
|
||||
writer.writeByte(0x75);
|
||||
break;
|
||||
case SHR_SIGNED:
|
||||
writer.writeByte(0x76);
|
||||
break;
|
||||
case ROTR:
|
||||
writer.writeByte(0x77);
|
||||
break;
|
||||
case ROTL:
|
||||
writer.writeByte(0x78);
|
||||
break;
|
||||
case EQ:
|
||||
writer.writeByte(0x46);
|
||||
break;
|
||||
case NE:
|
||||
writer.writeByte(0x47);
|
||||
break;
|
||||
case LT_SIGNED:
|
||||
writer.writeByte(0x48);
|
||||
break;
|
||||
case LT_UNSIGNED:
|
||||
writer.writeByte(0x49);
|
||||
break;
|
||||
case GT_SIGNED:
|
||||
writer.writeByte(0x4A);
|
||||
break;
|
||||
case GT_UNSIGNED:
|
||||
writer.writeByte(0x4B);
|
||||
break;
|
||||
case LE_SIGNED:
|
||||
writer.writeByte(0x4C);
|
||||
break;
|
||||
case LE_UNSIGNED:
|
||||
writer.writeByte(0x4D);
|
||||
break;
|
||||
case GE_SIGNED:
|
||||
writer.writeByte(0x4E);
|
||||
break;
|
||||
case GE_UNSIGNED:
|
||||
writer.writeByte(0x4F);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INT64:
|
||||
switch (expression.getOperation()) {
|
||||
case ADD:
|
||||
writer.writeByte(0x7C);
|
||||
break;
|
||||
case SUB:
|
||||
writer.writeByte(0x7D);
|
||||
break;
|
||||
case MUL:
|
||||
writer.writeByte(0x7E);
|
||||
break;
|
||||
case DIV_SIGNED:
|
||||
writer.writeByte(0x7F);
|
||||
break;
|
||||
case DIV_UNSIGNED:
|
||||
writer.writeByte(0x80);
|
||||
break;
|
||||
case REM_SIGNED:
|
||||
writer.writeByte(0x81);
|
||||
break;
|
||||
case REM_UNSIGNED:
|
||||
writer.writeByte(0x82);
|
||||
break;
|
||||
case AND:
|
||||
writer.writeByte(0x83);
|
||||
break;
|
||||
case OR:
|
||||
writer.writeByte(0x84);
|
||||
break;
|
||||
case XOR:
|
||||
writer.writeByte(0x85);
|
||||
break;
|
||||
case SHL:
|
||||
writer.writeByte(0x86);
|
||||
break;
|
||||
case SHR_UNSIGNED:
|
||||
writer.writeByte(0x87);
|
||||
break;
|
||||
case SHR_SIGNED:
|
||||
writer.writeByte(0x88);
|
||||
break;
|
||||
case ROTR:
|
||||
writer.writeByte(0x89);
|
||||
break;
|
||||
case ROTL:
|
||||
writer.writeByte(0x8A);
|
||||
break;
|
||||
case EQ:
|
||||
writer.writeByte(0x51);
|
||||
break;
|
||||
case NE:
|
||||
writer.writeByte(0x52);
|
||||
break;
|
||||
case LT_SIGNED:
|
||||
writer.writeByte(0x53);
|
||||
break;
|
||||
case LT_UNSIGNED:
|
||||
writer.writeByte(0x54);
|
||||
break;
|
||||
case GT_SIGNED:
|
||||
writer.writeByte(0x55);
|
||||
break;
|
||||
case GT_UNSIGNED:
|
||||
writer.writeByte(0x56);
|
||||
break;
|
||||
case LE_SIGNED:
|
||||
writer.writeByte(0x57);
|
||||
break;
|
||||
case LE_UNSIGNED:
|
||||
writer.writeByte(0x58);
|
||||
break;
|
||||
case GE_SIGNED:
|
||||
writer.writeByte(0x59);
|
||||
break;
|
||||
case GE_UNSIGNED:
|
||||
writer.writeByte(0x5A);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderOld(WasmIntBinary expression) {
|
||||
switch (expression.getType()) {
|
||||
case INT32:
|
||||
switch (expression.getOperation()) {
|
||||
|
@ -393,6 +576,99 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmFloatBinary expression) {
|
||||
expression.getFirst().acceptVisitor(this);
|
||||
expression.getSecond().acceptVisitor(this);
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
render0xD(expression);
|
||||
} else {
|
||||
renderOld(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void render0xD(WasmFloatBinary expression) {
|
||||
switch (expression.getType()) {
|
||||
case FLOAT32:
|
||||
switch (expression.getOperation()) {
|
||||
case ADD:
|
||||
writer.writeByte(0x92);
|
||||
break;
|
||||
case SUB:
|
||||
writer.writeByte(0x93);
|
||||
break;
|
||||
case MUL:
|
||||
writer.writeByte(0x94);
|
||||
break;
|
||||
case DIV:
|
||||
writer.writeByte(0x95);
|
||||
break;
|
||||
case MIN:
|
||||
writer.writeByte(0x96);
|
||||
break;
|
||||
case MAX:
|
||||
writer.writeByte(0x97);
|
||||
break;
|
||||
case EQ:
|
||||
writer.writeByte(0x5B);
|
||||
break;
|
||||
case NE:
|
||||
writer.writeByte(0x5C);
|
||||
break;
|
||||
case LT:
|
||||
writer.writeByte(0x5D);
|
||||
break;
|
||||
case GT:
|
||||
writer.writeByte(0x5E);
|
||||
break;
|
||||
case LE:
|
||||
writer.writeByte(0x5F);
|
||||
break;
|
||||
case GE:
|
||||
writer.writeByte(0x60);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FLOAT64:
|
||||
switch (expression.getOperation()) {
|
||||
case ADD:
|
||||
writer.writeByte(0xA0);
|
||||
break;
|
||||
case SUB:
|
||||
writer.writeByte(0xA1);
|
||||
break;
|
||||
case MUL:
|
||||
writer.writeByte(0xA2);
|
||||
break;
|
||||
case DIV:
|
||||
writer.writeByte(0xA3);
|
||||
break;
|
||||
case MIN:
|
||||
writer.writeByte(0xA4);
|
||||
break;
|
||||
case MAX:
|
||||
writer.writeByte(0xA5);
|
||||
break;
|
||||
case EQ:
|
||||
writer.writeByte(0x61);
|
||||
break;
|
||||
case NE:
|
||||
writer.writeByte(0x62);
|
||||
break;
|
||||
case LT:
|
||||
writer.writeByte(0x63);
|
||||
break;
|
||||
case GT:
|
||||
writer.writeByte(0x64);
|
||||
break;
|
||||
case LE:
|
||||
writer.writeByte(0x65);
|
||||
break;
|
||||
case GE:
|
||||
writer.writeByte(0x66);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderOld(WasmFloatBinary expression) {
|
||||
switch (expression.getType()) {
|
||||
case FLOAT32:
|
||||
switch (expression.getOperation()) {
|
||||
|
@ -480,39 +756,139 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmIntUnary expression) {
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
switch (expression.getType()) {
|
||||
case INT32:
|
||||
switch (expression.getOperation()) {
|
||||
case CLZ:
|
||||
writer.writeByte(0x57);
|
||||
break;
|
||||
case CTZ:
|
||||
writer.writeByte(0x58);
|
||||
break;
|
||||
case POPCNT:
|
||||
writer.writeByte(0x59);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INT64:
|
||||
switch (expression.getOperation()) {
|
||||
case CLZ:
|
||||
writer.writeByte(0x72);
|
||||
break;
|
||||
case CTZ:
|
||||
writer.writeByte(0x73);
|
||||
break;
|
||||
case POPCNT:
|
||||
writer.writeByte(0x74);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
switch (expression.getType()) {
|
||||
case INT32:
|
||||
switch (expression.getOperation()) {
|
||||
case CLZ:
|
||||
writer.writeByte(0x67);
|
||||
break;
|
||||
case CTZ:
|
||||
writer.writeByte(0x68);
|
||||
break;
|
||||
case POPCNT:
|
||||
writer.writeByte(0x69);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INT64:
|
||||
switch (expression.getOperation()) {
|
||||
case CLZ:
|
||||
writer.writeByte(0x79);
|
||||
break;
|
||||
case CTZ:
|
||||
writer.writeByte(0x7A);
|
||||
break;
|
||||
case POPCNT:
|
||||
writer.writeByte(0x7B);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (expression.getType()) {
|
||||
case INT32:
|
||||
switch (expression.getOperation()) {
|
||||
case CLZ:
|
||||
writer.writeByte(0x57);
|
||||
break;
|
||||
case CTZ:
|
||||
writer.writeByte(0x58);
|
||||
break;
|
||||
case POPCNT:
|
||||
writer.writeByte(0x59);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INT64:
|
||||
switch (expression.getOperation()) {
|
||||
case CLZ:
|
||||
writer.writeByte(0x72);
|
||||
break;
|
||||
case CTZ:
|
||||
writer.writeByte(0x73);
|
||||
break;
|
||||
case POPCNT:
|
||||
writer.writeByte(0x74);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmFloatUnary expression) {
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
render0xD(expression);
|
||||
} else {
|
||||
renderOld(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void render0xD(WasmFloatUnary expression) {
|
||||
switch (expression.getType()) {
|
||||
case FLOAT32:
|
||||
switch (expression.getOperation()) {
|
||||
case ABS:
|
||||
writer.writeByte(0x8B);
|
||||
break;
|
||||
case NEG:
|
||||
writer.writeByte(0x8C);
|
||||
break;
|
||||
case CEIL:
|
||||
writer.writeByte(0x8D);
|
||||
break;
|
||||
case FLOOR:
|
||||
writer.writeByte(0x8E);
|
||||
break;
|
||||
case TRUNC:
|
||||
writer.writeByte(0x8F);
|
||||
break;
|
||||
case NEAREST:
|
||||
writer.writeByte(0x90);
|
||||
break;
|
||||
case SQRT:
|
||||
writer.writeByte(0x91);
|
||||
break;
|
||||
case COPYSIGN:
|
||||
writer.writeByte(0x98);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FLOAT64:
|
||||
switch (expression.getOperation()) {
|
||||
case ABS:
|
||||
writer.writeByte(0x99);
|
||||
break;
|
||||
case NEG:
|
||||
writer.writeByte(0x9A);
|
||||
break;
|
||||
case CEIL:
|
||||
writer.writeByte(0x9B);
|
||||
break;
|
||||
case FLOOR:
|
||||
writer.writeByte(0x9C);
|
||||
break;
|
||||
case TRUNC:
|
||||
writer.writeByte(0x9D);
|
||||
break;
|
||||
case NEAREST:
|
||||
writer.writeByte(0x9E);
|
||||
break;
|
||||
case SQRT:
|
||||
writer.writeByte(0x9F);
|
||||
break;
|
||||
case COPYSIGN:
|
||||
writer.writeByte(0xA6);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderOld(WasmFloatUnary expression) {
|
||||
switch (expression.getType()) {
|
||||
case FLOAT32:
|
||||
switch (expression.getOperation()) {
|
||||
|
@ -576,7 +952,79 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmConversion expression) {
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
render0xD(expression);
|
||||
} else {
|
||||
renderOld(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private void render0xD(WasmConversion expression) {
|
||||
switch (expression.getSourceType()) {
|
||||
case INT32:
|
||||
switch (expression.getTargetType()) {
|
||||
case INT32:
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(expression.isSigned() ? 0xAC : 0xAD);
|
||||
break;
|
||||
case FLOAT32:
|
||||
writer.writeByte(expression.isSigned() ? 0xB2 : 0xB3);
|
||||
break;
|
||||
case FLOAT64:
|
||||
writer.writeByte(expression.isSigned() ? 0xB7 : 0xB8);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INT64:
|
||||
switch (expression.getTargetType()) {
|
||||
case INT32:
|
||||
writer.writeByte(0xA7);
|
||||
break;
|
||||
case INT64:
|
||||
break;
|
||||
case FLOAT32:
|
||||
writer.writeByte(expression.isSigned() ? 0xB4 : 0xB5);
|
||||
break;
|
||||
case FLOAT64:
|
||||
writer.writeByte(expression.isSigned() ? 0xB9 : 0xBA);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FLOAT32:
|
||||
switch (expression.getTargetType()) {
|
||||
case INT32:
|
||||
writer.writeByte(expression.isSigned() ? 0xA8 : 0xA9);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(expression.isSigned() ? 0xAE : 0xAF);
|
||||
break;
|
||||
case FLOAT32:
|
||||
break;
|
||||
case FLOAT64:
|
||||
writer.writeByte(0xBB);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FLOAT64:
|
||||
switch (expression.getTargetType()) {
|
||||
case INT32:
|
||||
writer.writeByte(expression.isSigned() ? 0xAA : 0xAB);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(expression.isSigned() ? 0xB0 : 0xB1);
|
||||
break;
|
||||
case FLOAT32:
|
||||
writer.writeByte(0xB6);
|
||||
break;
|
||||
case FLOAT64:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderOld(WasmConversion expression) {
|
||||
switch (expression.getSourceType()) {
|
||||
case INT32:
|
||||
switch (expression.getTargetType()) {
|
||||
|
@ -658,7 +1106,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
writer.writeByte(!expression.isImported() ? 0x16 : 0x18);
|
||||
writer.writeLEB(expression.getArguments().size());
|
||||
} else {
|
||||
writer.writeByte(0x16);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x10 : 0x16);
|
||||
}
|
||||
writer.writeLEB(functionIndex);
|
||||
}
|
||||
|
@ -671,10 +1119,10 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
for (WasmExpression argument : expression.getArguments()) {
|
||||
argument.acceptVisitor(this);
|
||||
}
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
if (version != WasmBinaryVersion.V_0xB) {
|
||||
expression.getSelector().acceptVisitor(this);
|
||||
}
|
||||
writer.writeByte(0x17);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x11 : 0x17);
|
||||
if (version == WasmBinaryVersion.V_0xB) {
|
||||
writer.writeLEB(expression.getArguments().size());
|
||||
}
|
||||
|
@ -685,6 +1133,10 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
signatureTypes[i + 1] = expression.getParameterTypes().get(i);
|
||||
}
|
||||
writer.writeLEB(signatureIndexes.get(new WasmSignature(signatureTypes)));
|
||||
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
writer.writeByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -692,28 +1144,50 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
expression.getOperand().acceptVisitor(this);
|
||||
if (version == WasmBinaryVersion.V_0xC) {
|
||||
writer.writeByte(0x0B);
|
||||
} else if (version == WasmBinaryVersion.V_0xD) {
|
||||
writer.writeByte(0x1A);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmLoadInt32 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x20);
|
||||
break;
|
||||
case UINT8:
|
||||
writer.writeByte(0x21);
|
||||
break;
|
||||
case INT16:
|
||||
writer.writeByte(0x22);
|
||||
break;
|
||||
case UINT16:
|
||||
writer.writeByte(0x23);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x2A);
|
||||
break;
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x2C);
|
||||
break;
|
||||
case UINT8:
|
||||
writer.writeByte(0x2D);
|
||||
break;
|
||||
case INT16:
|
||||
writer.writeByte(0x2E);
|
||||
break;
|
||||
case UINT16:
|
||||
writer.writeByte(0x2F);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x28);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x20);
|
||||
break;
|
||||
case UINT8:
|
||||
writer.writeByte(0x21);
|
||||
break;
|
||||
case INT16:
|
||||
writer.writeByte(0x22);
|
||||
break;
|
||||
case UINT16:
|
||||
writer.writeByte(0x23);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x2A);
|
||||
break;
|
||||
}
|
||||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
|
@ -722,28 +1196,54 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmLoadInt64 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x24);
|
||||
break;
|
||||
case UINT8:
|
||||
writer.writeByte(0x25);
|
||||
break;
|
||||
case INT16:
|
||||
writer.writeByte(0x26);
|
||||
break;
|
||||
case UINT16:
|
||||
writer.writeByte(0x27);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x28);
|
||||
break;
|
||||
case UINT32:
|
||||
writer.writeByte(0x29);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(0x2B);
|
||||
break;
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x30);
|
||||
break;
|
||||
case UINT8:
|
||||
writer.writeByte(0x31);
|
||||
break;
|
||||
case INT16:
|
||||
writer.writeByte(0x32);
|
||||
break;
|
||||
case UINT16:
|
||||
writer.writeByte(0x33);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x34);
|
||||
break;
|
||||
case UINT32:
|
||||
writer.writeByte(0x25);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(0x29);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x24);
|
||||
break;
|
||||
case UINT8:
|
||||
writer.writeByte(0x25);
|
||||
break;
|
||||
case INT16:
|
||||
writer.writeByte(0x26);
|
||||
break;
|
||||
case UINT16:
|
||||
writer.writeByte(0x27);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x28);
|
||||
break;
|
||||
case UINT32:
|
||||
writer.writeByte(0x29);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(0x2B);
|
||||
break;
|
||||
}
|
||||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
|
@ -752,7 +1252,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmLoadFloat32 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
writer.writeByte(0x2C);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x2A : 0x2C);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
}
|
||||
|
@ -760,7 +1260,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
@Override
|
||||
public void visit(WasmLoadFloat64 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
writer.writeByte(0x2D);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x2B : 0x2D);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
}
|
||||
|
@ -769,18 +1269,34 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmStoreInt32 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
writer.writeByte(0x2E);
|
||||
break;
|
||||
case INT16:
|
||||
case UINT16:
|
||||
writer.writeByte(0x2F);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x33);
|
||||
break;
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
writer.writeByte(0x3A);
|
||||
break;
|
||||
case INT16:
|
||||
case UINT16:
|
||||
writer.writeByte(0x3B);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x36);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
writer.writeByte(0x2E);
|
||||
break;
|
||||
case INT16:
|
||||
case UINT16:
|
||||
writer.writeByte(0x2F);
|
||||
break;
|
||||
case INT32:
|
||||
writer.writeByte(0x33);
|
||||
break;
|
||||
}
|
||||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
|
@ -790,22 +1306,42 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmStoreInt64 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
writer.writeByte(0x30);
|
||||
break;
|
||||
case INT16:
|
||||
case UINT16:
|
||||
writer.writeByte(0x31);
|
||||
break;
|
||||
case INT32:
|
||||
case UINT32:
|
||||
writer.writeByte(0x32);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(0x34);
|
||||
break;
|
||||
if (version == WasmBinaryVersion.V_0xD) {
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
writer.writeByte(0x3C);
|
||||
break;
|
||||
case INT16:
|
||||
case UINT16:
|
||||
writer.writeByte(0x3D);
|
||||
break;
|
||||
case INT32:
|
||||
case UINT32:
|
||||
writer.writeByte(0x3E);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(0x37);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
writer.writeByte(0x30);
|
||||
break;
|
||||
case INT16:
|
||||
case UINT16:
|
||||
writer.writeByte(0x31);
|
||||
break;
|
||||
case INT32:
|
||||
case UINT32:
|
||||
writer.writeByte(0x32);
|
||||
break;
|
||||
case INT64:
|
||||
writer.writeByte(0x34);
|
||||
break;
|
||||
}
|
||||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
|
@ -815,7 +1351,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmStoreFloat32 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
writer.writeByte(0x35);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x38 : 0x35);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
}
|
||||
|
@ -824,7 +1360,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
public void visit(WasmStoreFloat64 expression) {
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
writer.writeByte(0x36);
|
||||
writer.writeByte(version == WasmBinaryVersion.V_0xD ? 0x39 : 0x36);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
}
|
||||
|
|
|
@ -17,5 +17,6 @@ package org.teavm.backend.wasm.render;
|
|||
|
||||
public enum WasmBinaryVersion {
|
||||
V_0xB,
|
||||
V_0xC
|
||||
V_0xC,
|
||||
V_0xD
|
||||
}
|
||||
|
|
|
@ -27,23 +27,23 @@ public class WasmBinaryWriter {
|
|||
data[pointer++] = (byte) v;
|
||||
}
|
||||
|
||||
public void writeType(WasmType type) {
|
||||
public void writeType(WasmType type, WasmBinaryVersion version) {
|
||||
if (type == null) {
|
||||
writeByte(0);
|
||||
writeByte(version == WasmBinaryVersion.V_0xD ? 0x40 : 0);
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case INT32:
|
||||
writeByte(1);
|
||||
writeByte(version == WasmBinaryVersion.V_0xD ? 0x7F : 1);
|
||||
break;
|
||||
case INT64:
|
||||
writeByte(2);
|
||||
writeByte(version == WasmBinaryVersion.V_0xD ? 0x7E : 2);
|
||||
break;
|
||||
case FLOAT32:
|
||||
writeByte(3);
|
||||
writeByte(version == WasmBinaryVersion.V_0xD ? 0x7D : 3);
|
||||
break;
|
||||
case FLOAT64:
|
||||
writeByte(4);
|
||||
writeByte(version == WasmBinaryVersion.V_0xD ? 0x7C : 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ public final class TeaVMRunner {
|
|||
.withLongOpt("wasm-version")
|
||||
.withArgName("version")
|
||||
.hasArg()
|
||||
.withDescription("WebAssembly binary version (11, 12)")
|
||||
.withDescription("WebAssembly binary version (11, 12, 13)")
|
||||
.create());
|
||||
|
||||
if (args.length == 0) {
|
||||
|
@ -296,6 +296,9 @@ public final class TeaVMRunner {
|
|||
case 12:
|
||||
tool.setWasmVersion(WasmBinaryVersion.V_0xC);
|
||||
break;
|
||||
case 13:
|
||||
tool.setWasmVersion(WasmBinaryVersion.V_0xD);
|
||||
break;
|
||||
default:
|
||||
System.err.print("Wrong version value");
|
||||
printUsage(options);
|
||||
|
|
|
@ -99,7 +99,7 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
private DebugInformationBuilder debugEmitter;
|
||||
private JavaScriptTarget javaScriptTarget;
|
||||
private WasmTarget webAssemblyTarget;
|
||||
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0xC;
|
||||
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0xD;
|
||||
|
||||
public File getTargetDirectory() {
|
||||
return targetDirectory;
|
||||
|
|
|
@ -78,7 +78,7 @@ public class TeaVMCompileMojo extends AbstractTeaVMMojo {
|
|||
private TeaVMTool tool = new TeaVMTool();
|
||||
|
||||
@Parameter
|
||||
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0xC;
|
||||
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0xD;
|
||||
|
||||
@Override
|
||||
protected File getTargetDirectory() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user