Skip to content

Commit

Permalink
support WASM
Browse files Browse the repository at this point in the history
  • Loading branch information
zxh0 committed Oct 9, 2018
1 parent 8dc5e5f commit 8aa3af6
Show file tree
Hide file tree
Showing 35 changed files with 1,359 additions and 1 deletion.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ subprojects {
apply plugin: 'java'
//apply plugin: 'application'

sourceCompatibility = "1.8";
sourceCompatibility = "1.8"
//mainClassName = 'com.github.zxh0.luago.Main'

sourceCompatibility = '1.8'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ protected final void add(String name, FileComponent subComponent) {
components.add(subComponent);
}

protected final void clear() {
components.clear();
}

/**
* The returned string will be displayed by BytesTreeItem.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ private Menu createOpenMenu() {
openMenu.getItems().add(createOpenMenuItem(FileType.JAVA_JAR));
openMenu.getItems().add(createOpenMenuItem(FileType.JAVA_CLASS));
openMenu.getItems().add(createOpenMenuItem(FileType.LUA_BC));
openMenu.getItems().add(createOpenMenuItem(FileType.WASM));
openMenu.setMnemonicParsing(true);
return openMenu;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public enum FileType {
JAVA_JAR("/jar.png", "Java JAR", "*.jar"),
JAVA_CLASS("/java.png", "Java Class", "*.class"),
LUA_BC("/lua.png", "Lua Binary Chunk", "*.luac"),
WASM("/wasm.png", "WebAssembly Binary Code", "*.wasm"),
UNKNOWN("/file.png", "Unknown", "*.*"),
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

public class FileTypeInferer {

private static final byte[] wasmMagicNumber = {0, 'a', 's', 'm'};
private static final byte[] binaryChunkSig = {0x1B, 'L', 'u', 'a'};
private static final byte[] classMagicNumber = {
(byte) 0xCA,
Expand All @@ -24,6 +25,9 @@ public static FileType inferFileType(URL url) {
if (filename.endsWith(".luac")) {
return FileType.LUA_BC;
}
if (filename.endsWith(".wasm")) {
return FileType.WASM;
}
return FileType.UNKNOWN;
}

Expand All @@ -36,6 +40,9 @@ public static FileType inferFileType(byte[] data) {
if (Arrays.equals(magicNumber, binaryChunkSig)) {
return FileType.LUA_BC;
}
if (Arrays.equals(magicNumber, wasmMagicNumber)) {
return FileType.WASM;
}
}
return FileType.UNKNOWN;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.net.URL;
import java.util.function.Consumer;

import com.github.zxh.classpy.wasm.WasmBinParser;
import javafx.concurrent.Task;

public class OpenFileTask extends Task<OpenFileResult> {
Expand Down Expand Up @@ -49,6 +50,7 @@ private static FileComponent parse(byte[] data, FileType fileType) {
switch (fileType) {
case JAVA_CLASS: return new ClassFileParser().parse(data);
case LUA_BC: return new BinaryChunkParser().parse(data);
case WASM: return new WasmBinParser().parse(data);
default: return new FileComponent() {}; // todo
}
}
Expand Down
Binary file added classpy-gui/src/main/resources/wasm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions classpy-wasm/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
compile project(':classpy-common')
}
23 changes: 23 additions & 0 deletions classpy-wasm/src/main/java/com/github/zxh/classpy/wasm/Vector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.github.zxh.classpy.wasm;

import java.util.function.Supplier;

public class Vector extends WasmBinComponent {

private Supplier<? extends WasmBinComponent> supplier;

public Vector(Supplier<? extends WasmBinComponent> supplier) {
this.supplier = supplier;
}

@Override
protected void readContent(WasmBinReader reader) {
int length = readU32(reader, "length");
for (int i = 0; i < length; i++) {
WasmBinComponent element = supplier.get();
add(null, element);
element.read(reader);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.github.zxh.classpy.wasm;

import com.github.zxh.classpy.common.FileComponent;
import com.github.zxh.classpy.wasm.instructions.Expr;
import com.github.zxh.classpy.wasm.types.ValType;
import com.github.zxh.classpy.wasm.values.Byte;
import com.github.zxh.classpy.wasm.values.Bytes;
import com.github.zxh.classpy.wasm.values.Name;
import com.github.zxh.classpy.wasm.values.U32;

import java.util.function.Supplier;

public class WasmBinComponent extends FileComponent {

public final void read(WasmBinReader reader) {
try {
int offset = reader.getPosition();
readContent(reader);
int length = reader.getPosition() - offset;
super.setOffset(offset);
super.setLength(length);
} catch (Exception e) {
System.out.println("error parsing: " + getClass());
throw e;
}
}

protected void readContent(WasmBinReader reader) {
for (FileComponent fc : getComponents()) {
((WasmBinComponent) fc).read(reader);
}
}

protected void postRead() {

}

protected int readU32(WasmBinReader reader, String name) {
U32 u32 = new U32();
add(name, u32);
u32.read(reader);
return u32.getIntValue();
}

protected int readByte(WasmBinReader reader, String name) {
Byte b = new Byte();
add(name, b);
b.read(reader);
return b.getValue();
}

protected int readByte(WasmBinReader reader, String name, byte... expectedValues) {
Byte b = new Byte(expectedValues);
add(name, b);
b.read(reader);
return b.getValue();
}

protected byte[] readBytes(WasmBinReader reader, String name, int n) {
Bytes bytes = new Bytes(n);
add(name, bytes);
bytes.read(reader);
return bytes.getBytes();
}

protected <T extends WasmBinComponent> T read(WasmBinReader reader,
String name,
Supplier<T> supplier) {
T c = supplier.get();
add(name, c);
c.read(reader);
return c;
}

protected void readVector(WasmBinReader reader, String name,
Supplier<? extends WasmBinComponent> supplier) {
Vector vec = new Vector(supplier);
add(name, vec);
vec.read(reader);
}

protected void _byte(String name, byte... expectedValues) {
add(name, new Byte(expectedValues));
}

protected void u32(String name) {
add(name, new U32());
}

protected void name(String name) {
add(name, new Name());
}

protected void valType(String name) {
add(name, new ValType());
}

protected void expr(String name) {
add(name, new Expr());
}

protected void vector(String name,
Supplier<? extends WasmBinComponent> supplier) {
add(name, new Vector(supplier));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.github.zxh.classpy.wasm;

import com.github.zxh.classpy.wasm.sections.Section;

public class WasmBinFile extends WasmBinComponent {

protected void readContent(WasmBinReader reader) {
readBytes(reader, "magic", 4);
readBytes(reader, "version", 4);
readSections(reader);
}

private void readSections(WasmBinReader reader) {
while (reader.remaining() > 0) {
Section section = new Section();
add("section", section);
section.read(reader);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.github.zxh.classpy.wasm;

import com.github.zxh.classpy.common.FileComponent;
import com.github.zxh.classpy.common.FileParser;

public class WasmBinParser implements FileParser {

@Override
public WasmBinFile parse(byte[] data) {
WasmBinFile wasm = new WasmBinFile();
try {
wasm.read(new WasmBinReader(data));
postRead(wasm);
} catch (Exception e) {
e.printStackTrace(System.err);
}
return wasm;
}

private static void postRead(WasmBinComponent bc) {
for (FileComponent c : bc.getComponents()) {
postRead((WasmBinComponent) c);
}
bc.postRead();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.github.zxh.classpy.wasm;

import com.github.zxh.classpy.common.BytesReader;

import java.nio.ByteOrder;

public class WasmBinReader extends BytesReader {

public WasmBinReader(byte[] data) {
super(data, ByteOrder.LITTLE_ENDIAN); // ?
}

public long readU32() {
return readUnsignedLEB128(32);
}

public long readU64() {
return readUnsignedLEB128(64);
}

public long readS32() {
return readSignedLEB128(32);
}

public long readS64() {
return readSignedLEB128(64);
}

private long readUnsignedLEB128(int nBits) {
long result = 0;
for (int shift = 0; shift < nBits; shift += 7) {
int b = readByte();
result |= ((b & 0b0111_1111) << shift);
if ((b & 0b1000_0000) == 0) {
return result;
}
}

throw new RuntimeException("can not decode unsigned LEB128");
}

private long readSignedLEB128(int size) {
long result = 0;
int shift = 0;
//size = number of bits in signed integer;
byte b;
do{
b = readByte();
result |= ((b & 0b0111_1111) << shift);
shift += 7;
} while ((b & 0b1000_0000) != 0);

/* sign bit of byte is second high order bit (0x40) */
if ((shift < size) && ((b & 0b0100_0000) != 0)) {
/* sign extend */
result |= (~0 << shift);
}

return result;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.github.zxh.classpy.wasm.instructions;

import com.github.zxh.classpy.wasm.WasmBinComponent;
import com.github.zxh.classpy.wasm.WasmBinReader;

public class Expr extends WasmBinComponent {

@Override
protected void readContent(WasmBinReader reader) {
while (reader.remaining() > 0) {
Instr instr = read(reader, null, Instr::new);
if (instr.getOpcode() == 0x0B) { // end
break;
}
}
}

}
Loading

0 comments on commit 8aa3af6

Please sign in to comment.