mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-27 02:40:51 +01:00
Added G-Wasm project sources
This commit is contained in:
parent
cee78fd0f5
commit
8b1acdf9d7
@ -12,18 +12,25 @@ plugins {
|
|||||||
description = "G-Earth"
|
description = "G-Earth"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://jitpack.io")
|
// maven("https://jitpack.io")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: move dependency version declarations to different gradle file
|
* TODO: move dependency version declarations to different gradle file
|
||||||
*/
|
*/
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.github.dorving:G-Wasm:minimal-SNAPSHOT")
|
implementation(project(":G-Wasm"))
|
||||||
|
// implementation("com.github.dorving:G-Wasm:minimal-SNAPSHOT")
|
||||||
implementation("at.favre.lib:bytes:1.5.0")
|
implementation("at.favre.lib:bytes:1.5.0")
|
||||||
implementation("com.github.tulskiy:jkeymaster:1.3")
|
implementation("com.github.tulskiy:jkeymaster:1.3") {
|
||||||
implementation("com.github.ganskef:littleproxy-mitm:1.1.0")
|
exclude("org.slf4j", "slf4j-api")
|
||||||
|
}
|
||||||
|
implementation("com.github.ganskef:littleproxy-mitm:1.1.0") {
|
||||||
|
exclude("org.slf4j", "slf4j-api")
|
||||||
|
exclude("org.slf4j", "slf4j-log4j12")
|
||||||
|
}
|
||||||
implementation("commons-io:commons-io:2.10.0")
|
implementation("commons-io:commons-io:2.10.0")
|
||||||
implementation("javax.websocket:javax.websocket-api:1.1")
|
implementation("javax.websocket:javax.websocket-api:1.1")
|
||||||
implementation("org.apache.maven:maven-artifact:3.6.3")
|
implementation("org.apache.maven:maven-artifact:3.6.3")
|
||||||
@ -31,12 +38,15 @@ dependencies {
|
|||||||
implementation("org.eclipse.jetty.websocket:javax-websocket-server-impl:9.4.43.v20210629") {
|
implementation("org.eclipse.jetty.websocket:javax-websocket-server-impl:9.4.43.v20210629") {
|
||||||
exclude("javax.websocket", "javax.websocket-client-api")
|
exclude("javax.websocket", "javax.websocket-client-api")
|
||||||
}
|
}
|
||||||
|
implementation("com.dustinredmond.fxtrayicon:FXTrayIcon:4.0.1")
|
||||||
implementation("org.eclipse.jetty:jetty-http:9.4.43.v20210629")
|
implementation("org.eclipse.jetty:jetty-http:9.4.43.v20210629")
|
||||||
implementation("org.fxmisc.richtext:richtextfx:0.10.5")
|
implementation("org.fxmisc.richtext:richtextfx:0.10.5")
|
||||||
implementation("org.json:json:20190722")
|
implementation("org.json:json:20190722")
|
||||||
implementation("org.jsoup:jsoup:1.14.2")
|
implementation("org.jsoup:jsoup:1.14.2")
|
||||||
implementation("org.slf4j:slf4j-jdk14:2.0.0-alpha0")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3")
|
||||||
|
// implementation("org.slf4j:slf4j-jdk14:2.0.0-alpha0")
|
||||||
|
implementation("ch.qos.logback:logback-core:1.3.5")
|
||||||
|
implementation("ch.qos.logback:logback-classic:1.3.5")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
@ -74,11 +84,14 @@ tasks.getByName("assemble") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven("/Users/stanvanderbend/.m2/repository")
|
||||||
|
}
|
||||||
publications {
|
publications {
|
||||||
create<MavenPublication>("maven") {
|
create<MavenPublication>("maven") {
|
||||||
groupId = "karth.gearth"
|
groupId = "karth.gearth"
|
||||||
artifactId = "gearth"
|
artifactId = "gearth"
|
||||||
version = "1.5.2"
|
version = "1.5.3"
|
||||||
from(components["java"])
|
from(components["java"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
G-Wasm/.gitignore
vendored
Normal file
11
G-Wasm/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# intelliJ
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
out/
|
||||||
|
|
||||||
|
# self experiments
|
||||||
|
src/main/java/misc/
|
||||||
|
|
||||||
|
# maven
|
||||||
|
bin/
|
||||||
|
**/target/
|
4
G-Wasm/README.md
Normal file
4
G-Wasm/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# G-Wasm
|
||||||
|
Java disassembler&assembler for WebAssembly
|
||||||
|
|
||||||
|
#### For the G-Wasm version that is used in G-Earth, go to the branch named "minimal" (runs 8x more memory efficient & 3.5x faster)
|
13
G-Wasm/build.gradle.kts
Normal file
13
G-Wasm/build.gradle.kts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
java
|
||||||
|
`java-library`
|
||||||
|
}
|
||||||
|
|
||||||
|
description = "G-Wasm"
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
}
|
60
G-Wasm/pom.xml
Normal file
60
G-Wasm/pom.xml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>G-Earth</groupId>
|
||||||
|
<artifactId>G-Wasm</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>2.5</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${project.build.directory}/bin</outputDirectory>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>wasm.GWasm</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>/src/main/resources</directory>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
27
G-Wasm/src/main/java/wasm/GWasm.java
Normal file
27
G-Wasm/src/main/java/wasm/GWasm.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package wasm;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class GWasm {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, InvalidOpCodeException {
|
||||||
|
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
Module module = new Module("C:\\Users\\jonas\\Desktop\\Projects\\Jznnp\\S\\habbo2020\\rawfiles\\0.23.0_(534)\\habbo2020-global-prod.wasm.gz", true, new ArrayList<>());
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
|
||||||
|
System.out.println("Disassemble time: " + (end - start));
|
||||||
|
|
||||||
|
start = System.currentTimeMillis();
|
||||||
|
module.assembleToFile("C:\\Users\\jonas\\Desktop\\Projects\\Jznnp\\S\\habbo2020\\rawfiles\\0.23.0_(534)\\out\\habbo2020-global-prod.wasm.gz", true);
|
||||||
|
end = System.currentTimeMillis();
|
||||||
|
|
||||||
|
System.out.println("Assemble time: " + (end - start));
|
||||||
|
|
||||||
|
System.out.println("hi");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package wasm.disassembly;
|
||||||
|
|
||||||
|
public class InvalidOpCodeException extends Exception {
|
||||||
|
|
||||||
|
public InvalidOpCodeException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
9
G-Wasm/src/main/java/wasm/disassembly/WASMOpCode.java
Normal file
9
G-Wasm/src/main/java/wasm/disassembly/WASMOpCode.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package wasm.disassembly;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public abstract class WASMOpCode {
|
||||||
|
|
||||||
|
public abstract void assemble(OutputStream out) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package wasm.disassembly.conventions;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public interface Assembler<B> {
|
||||||
|
|
||||||
|
void assemble(B b, OutputStream out) throws IOException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package wasm.disassembly.conventions;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface Creator<B> {
|
||||||
|
|
||||||
|
B create(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package wasm.disassembly.conventions;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CustomVector<B> extends WASMOpCode {
|
||||||
|
|
||||||
|
private List<B> elements;
|
||||||
|
private Assembler<B> assembler;
|
||||||
|
|
||||||
|
public CustomVector(BufferedInputStream in, Creator<B> creator, Assembler<B> assembler, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
long length = WUnsignedInt.read(in, 32);
|
||||||
|
elements = new ArrayList<>(1);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
elements.add(creator.create(in, module));
|
||||||
|
}
|
||||||
|
this.assembler = assembler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomVector(List<B> elements, Assembler<B> assembler) {
|
||||||
|
this.elements = elements;
|
||||||
|
this.assembler = assembler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(elements.size(), out, 32);
|
||||||
|
for (B b : elements) {
|
||||||
|
assembler.assemble(b, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<B> getElements() {
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElements(List<B> elements) {
|
||||||
|
this.elements = elements;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package wasm.disassembly.conventions;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Vector<B extends WASMOpCode> extends WASMOpCode {
|
||||||
|
|
||||||
|
private List<B> elements;
|
||||||
|
|
||||||
|
public Vector(BufferedInputStream in, Creator<B> creator, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
long length = WUnsignedInt.read(in, 32);
|
||||||
|
elements = new ArrayList<>(1);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
elements.add(creator.create(in, module));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector(List<B> elements) {
|
||||||
|
this.elements = elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(elements.size(), out, 32);
|
||||||
|
for (B b : elements) {
|
||||||
|
b.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<B> getElements() {
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElements(List<B> elements) {
|
||||||
|
this.elements = elements;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package wasm.disassembly.instructions;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Expression extends WASMOpCode {
|
||||||
|
|
||||||
|
private List<Instr> instructions;
|
||||||
|
|
||||||
|
public Expression(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
instructions = new ArrayList<>();
|
||||||
|
InstrType type;
|
||||||
|
while ((type = InstrFactory.disassembleType(in)) != InstrType.END) {
|
||||||
|
instructions.add(InstrFactory.disassemble(in, type, module));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression(List<Instr> instructions) {
|
||||||
|
this.instructions = instructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
for(Instr instr : instructions) {
|
||||||
|
instr.assemble(out);
|
||||||
|
}
|
||||||
|
out.write(InstrType.END.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Instr> getInstructions() {
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstructions(List<Instr> instructions) {
|
||||||
|
this.instructions = instructions;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package wasm.disassembly.instructions;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public abstract class Instr extends WASMOpCode {
|
||||||
|
|
||||||
|
private InstrType instrType;
|
||||||
|
|
||||||
|
public Instr(InstrType instrType) throws IOException {
|
||||||
|
this.instrType = instrType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(instrType.val);
|
||||||
|
assemble2(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void assemble2(OutputStream out) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
public InstrType getInstrType() {
|
||||||
|
return instrType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstrType(InstrType instrType) {
|
||||||
|
this.instrType = instrType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package wasm.disassembly.instructions;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.control.*;
|
||||||
|
import wasm.disassembly.instructions.memory.Mem0Instr;
|
||||||
|
import wasm.disassembly.instructions.memory.MemInstr;
|
||||||
|
import wasm.disassembly.instructions.misc.SingleByteInstr;
|
||||||
|
import wasm.disassembly.instructions.numeric.*;
|
||||||
|
import wasm.disassembly.instructions.variable.GlobalVariableInstr;
|
||||||
|
import wasm.disassembly.instructions.variable.LocalVariableInstr;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class InstrFactory {
|
||||||
|
|
||||||
|
public static InstrType disassembleType(BufferedInputStream in) throws IOException, InvalidOpCodeException {
|
||||||
|
InstrType type = InstrType.from_val(in.read());
|
||||||
|
if (type == null) {
|
||||||
|
throw new InvalidOpCodeException("Invalid instruction prefix");
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Map<InstrType, InstrSupplier> map;
|
||||||
|
static {
|
||||||
|
map = new HashMap<>();
|
||||||
|
|
||||||
|
// control instructions
|
||||||
|
map.put(InstrType.UNREACHABLE, SingleByteInstr::new);
|
||||||
|
map.put(InstrType.NOP, SingleByteInstr::new);
|
||||||
|
|
||||||
|
map.put(InstrType.BLOCK, BlockInstr::new);
|
||||||
|
map.put(InstrType.LOOP, BlockInstr::new);
|
||||||
|
map.put(InstrType.IF, IfElseInstr::new);
|
||||||
|
|
||||||
|
map.put(InstrType.BR, BranchInstr::new);
|
||||||
|
map.put(InstrType.BR_IF, BranchInstr::new);
|
||||||
|
map.put(InstrType.BR_TABLE, BranchTableInstr::new);
|
||||||
|
|
||||||
|
map.put(InstrType.RETURN, SingleByteInstr::new);
|
||||||
|
map.put(InstrType.CALL, CallInstr::new);
|
||||||
|
map.put(InstrType.CALL_INDIRECT, CallIndirectInstr::new);
|
||||||
|
|
||||||
|
|
||||||
|
// parametric instructions
|
||||||
|
map.put(InstrType.DROP, SingleByteInstr::new);
|
||||||
|
map.put(InstrType.SELECT, SingleByteInstr::new);
|
||||||
|
|
||||||
|
|
||||||
|
// variable instructions
|
||||||
|
for (int i = 0x20; i <= 0x22; i++) map.put(InstrType.from_val(i), LocalVariableInstr::new);
|
||||||
|
for (int i = 0x23; i <= 0x24; i++) map.put(InstrType.from_val(i), GlobalVariableInstr::new);
|
||||||
|
|
||||||
|
|
||||||
|
// memory instructions
|
||||||
|
for (int i = 0x28; i <= 0x3E; i++) map.put(InstrType.from_val(i), MemInstr::new);
|
||||||
|
for (int i = 0x3F; i <= 0x40; i++) map.put(InstrType.from_val(i), Mem0Instr::new);
|
||||||
|
|
||||||
|
|
||||||
|
// numeric instructions
|
||||||
|
map.put(InstrType.I32_CONST, NumericI32ConstInstr::new);
|
||||||
|
map.put(InstrType.I64_CONST, NumericI64ConstInstr::new);
|
||||||
|
map.put(InstrType.F32_CONST, NumericF32ConstInstr::new);
|
||||||
|
map.put(InstrType.F64_CONST, NumericF64ConstInstr::new);
|
||||||
|
for (int i = 0x45; i <= 0xC4; i++) map.put(InstrType.from_val(i), NumericInstr::new);
|
||||||
|
map.put(InstrType.IXX_TRUNC_SAT_FXX_SU, TruncSatInstr::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instr disassemble(BufferedInputStream in, InstrType instrType, Module module) throws InvalidOpCodeException, IOException {
|
||||||
|
if (instrType == InstrType.END || instrType == InstrType.ELSE) {
|
||||||
|
throw new InvalidOpCodeException("Instruction invalid as a standalone instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instrType == null) {
|
||||||
|
throw new InvalidOpCodeException("Invalid instruction prefix");
|
||||||
|
}
|
||||||
|
|
||||||
|
return map.get(instrType).get(in, instrType, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package wasm.disassembly.instructions;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface InstrSupplier {
|
||||||
|
|
||||||
|
Instr get(BufferedInputStream in, InstrType type, Module module) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,233 @@
|
|||||||
|
package wasm.disassembly.instructions;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum InstrType {
|
||||||
|
|
||||||
|
// control instructions
|
||||||
|
UNREACHABLE(0x00),
|
||||||
|
NOP(0x01),
|
||||||
|
BLOCK(0x02),
|
||||||
|
LOOP(0x03),
|
||||||
|
IF(0x04),
|
||||||
|
ELSE(0x05),
|
||||||
|
|
||||||
|
END(0x0B),
|
||||||
|
BR(0x0C),
|
||||||
|
BR_IF(0x0D),
|
||||||
|
BR_TABLE(0x0E),
|
||||||
|
RETURN(0x0F),
|
||||||
|
CALL(0x10),
|
||||||
|
CALL_INDIRECT(0x11),
|
||||||
|
|
||||||
|
|
||||||
|
// parametric instructions
|
||||||
|
DROP(0x1A),
|
||||||
|
SELECT(0x1B),
|
||||||
|
|
||||||
|
|
||||||
|
// variable instructions
|
||||||
|
LOCAL_GET(0x20),
|
||||||
|
LOCAL_SET(0x21),
|
||||||
|
LOCAL_TEE(0x22),
|
||||||
|
GLOBAL_GET(0x23),
|
||||||
|
GLOBAL_SET(0x24),
|
||||||
|
|
||||||
|
|
||||||
|
// memory instructions
|
||||||
|
I32_LOAD(0x28),
|
||||||
|
I64_LOAD(0x29),
|
||||||
|
F32_LOAD(0x2A),
|
||||||
|
F64_LOAD(0x2B),
|
||||||
|
I32_LOAD8_S(0x2C),
|
||||||
|
I32_LOAD8_U(0x2D),
|
||||||
|
I32_LOAD16_S(0x2E),
|
||||||
|
I32_LOAD16_U(0x2F),
|
||||||
|
I64_LOAD8_S(0x30),
|
||||||
|
I64_LOAD8_U(0x31),
|
||||||
|
I64_LOAD16_S(0x32),
|
||||||
|
I64_LOAD16_U(0x33),
|
||||||
|
I64_LOAD32_S(0x34),
|
||||||
|
I64_LOAD32_U(0x35),
|
||||||
|
|
||||||
|
I32_STORE(0x36),
|
||||||
|
I64_STORE(0x37),
|
||||||
|
F32_STORE(0x38),
|
||||||
|
F64_STORE(0x39),
|
||||||
|
I32_STORE8(0x3A),
|
||||||
|
I32_STORE16(0x3B),
|
||||||
|
I64_STORE8(0X3C),
|
||||||
|
I64_STORE16(0x3D),
|
||||||
|
I64_STORE32(0x3E),
|
||||||
|
|
||||||
|
MEMORY_SIZE(0x3F),
|
||||||
|
MEMORY_GROW(0x40),
|
||||||
|
|
||||||
|
|
||||||
|
// numeric instructions
|
||||||
|
I32_CONST(0x41),
|
||||||
|
I64_CONST(0x42),
|
||||||
|
F32_CONST(0x43),
|
||||||
|
F64_CONST(0x44),
|
||||||
|
|
||||||
|
I32_EQZ(0x45),
|
||||||
|
I32_EQ(0x46),
|
||||||
|
I32_NE(0x47),
|
||||||
|
I32_LT_S(0x48),
|
||||||
|
I32_LT_U(0x49),
|
||||||
|
I32_GT_S(0x4A),
|
||||||
|
I32_GT_U(0x4B),
|
||||||
|
I32_LE_S(0x4C),
|
||||||
|
I32_LE_U(0x4D),
|
||||||
|
I32_GE_S(0x4E),
|
||||||
|
I32_GE_U(0x4F),
|
||||||
|
|
||||||
|
I64_EQZ(0x50),
|
||||||
|
I64_EQ(0x51),
|
||||||
|
I64_NE(0x52),
|
||||||
|
I64_LT_S(0x53),
|
||||||
|
I64_LT_U(0x54),
|
||||||
|
I64_GT_S(0x55),
|
||||||
|
I64_GT_U(0x56),
|
||||||
|
I64_LE_S(0x57),
|
||||||
|
I64_LE_U(0x58),
|
||||||
|
I64_GE_S(0x59),
|
||||||
|
I64_GE_U(0x5A),
|
||||||
|
|
||||||
|
F32_EQ(0x5B),
|
||||||
|
F32_NE(0x5C),
|
||||||
|
F32_LT(0x5D),
|
||||||
|
F32_GT(0x5E),
|
||||||
|
F32_LE(0x5F),
|
||||||
|
F32_GE(0x60),
|
||||||
|
|
||||||
|
F64_EQ(0x61),
|
||||||
|
F64_NE(0x62),
|
||||||
|
F64_LT(0x63),
|
||||||
|
F64_GT(0x64),
|
||||||
|
F64_LE(0x65),
|
||||||
|
F64_GE(0x66),
|
||||||
|
|
||||||
|
I32_CLZ(0x67),
|
||||||
|
I32_CTZ(0x68),
|
||||||
|
I32_POPCNT(0x69),
|
||||||
|
I32_ADD(0x6A),
|
||||||
|
I32_SUB(0x6B),
|
||||||
|
I32_MUL(0x6C),
|
||||||
|
I32_DIV_S(0x6D),
|
||||||
|
I32_DIV_U(0x6E),
|
||||||
|
I32_REM_S(0x6F),
|
||||||
|
I32_REM_U(0x70),
|
||||||
|
I32_AND(0x71),
|
||||||
|
I32_OR(0x72),
|
||||||
|
I32_XOR(0x73),
|
||||||
|
I32_SHL(0x74),
|
||||||
|
I32_SHR_S(0x75),
|
||||||
|
I32_SHR_U(0x76),
|
||||||
|
I32_ROTL(0x77),
|
||||||
|
I32_ROTR(0x78),
|
||||||
|
|
||||||
|
I64_CLZ(0x79),
|
||||||
|
I64_CTZ(0x7A),
|
||||||
|
I64_POPCNT(0x7B),
|
||||||
|
I64_ADD(0x7C),
|
||||||
|
I64_SUB(0x7D),
|
||||||
|
I64_MUL(0x7E),
|
||||||
|
I64_DIV_S(0x7F),
|
||||||
|
I64_DIV_U(0x80),
|
||||||
|
I64_REM_S(0x81),
|
||||||
|
I64_REM_U(0x82),
|
||||||
|
I64_AND(0x83),
|
||||||
|
I64_OR(0x84),
|
||||||
|
I64_XOR(0x85),
|
||||||
|
I64_SHL(0x86),
|
||||||
|
I64_SHR_S(0x87),
|
||||||
|
I64_SHR_U(0x88),
|
||||||
|
I64_ROTL(0x89),
|
||||||
|
I64_ROTR(0x8A),
|
||||||
|
|
||||||
|
F32_ABS(0x8B),
|
||||||
|
F32_NEG(0x8C),
|
||||||
|
F32_CEIL(0x8D),
|
||||||
|
F32_FLOOR(0x8E),
|
||||||
|
F32_TRUNC(0x8F),
|
||||||
|
F32_NEAREST(0x90),
|
||||||
|
F32_SQRT(0x91),
|
||||||
|
F32_ADD(0x92),
|
||||||
|
F32_SUB(0x93),
|
||||||
|
F32_MUL(0x94),
|
||||||
|
F32_DIV(0x95),
|
||||||
|
F32_MIN(0x96),
|
||||||
|
F32_MAX(0x97),
|
||||||
|
F32_COPYSIGN(0x98),
|
||||||
|
|
||||||
|
F64_ABS(0x99),
|
||||||
|
F64_NEG(0x9A),
|
||||||
|
F64_CEIL(0x9B),
|
||||||
|
F64_FLOOR(0x9C),
|
||||||
|
F64_TRUNC(0x9D),
|
||||||
|
F64_NEAREST(0x9E),
|
||||||
|
F64_SQRT(0x9F),
|
||||||
|
F64_ADD(0xA0),
|
||||||
|
F64_SUB(0xA1),
|
||||||
|
F64_MUL(0xA2),
|
||||||
|
F64_DIV(0xA3),
|
||||||
|
F64_MIN(0xA4),
|
||||||
|
F64_MAX(0xA5),
|
||||||
|
F64_COPYSIGN(0xA6),
|
||||||
|
|
||||||
|
I32_WRAP_I64(0xA7),
|
||||||
|
I32_TRUNC_F32_S(0xA8),
|
||||||
|
I32_TRUNC_F32_U(0xA9),
|
||||||
|
I32_TRUNC_F64_S(0xAA),
|
||||||
|
I32_TRUNC_F64_U(0xAB),
|
||||||
|
I64_EXTEND_I32_S(0xAC),
|
||||||
|
I64_EXTEND_I32_U(0xAD),
|
||||||
|
I64_TRUNC_F32_S(0xAE),
|
||||||
|
I64_TRUNC_F32_U(0xAF),
|
||||||
|
I64_TRUNC_F64_S(0xB0),
|
||||||
|
I64_TRUNC_F64_U(0xB1),
|
||||||
|
F32_CONVERT_I32_S(0xB2),
|
||||||
|
F32_CONVERT_I32_U(0xB3),
|
||||||
|
F32_CONVERT_I64_S(0xB4),
|
||||||
|
F32_CONVERT_I64_U(0xB5),
|
||||||
|
F32_DEMOTE_F64(0xB6),
|
||||||
|
F64_CONVERT_I32_S(0xB7),
|
||||||
|
F64_CONVERT_I32_U(0xB8),
|
||||||
|
F64_CONVERT_I64_S(0xB9),
|
||||||
|
F64_CONVERT_I64_U(0xBA),
|
||||||
|
F64_PROMOTE_F32(0xBB),
|
||||||
|
I32_REINTERPRET_F32(0xBC),
|
||||||
|
I64_REINTERPRET_F64(0xBD),
|
||||||
|
F32_REINTERPRET_I32(0xBE),
|
||||||
|
F64_REINTERPRET_I64(0xBF),
|
||||||
|
|
||||||
|
I32_EXTEND8_S(0xC0),
|
||||||
|
I32_EXTENDS16_S(0xC1),
|
||||||
|
I64_EXTEND8_S(0xC2),
|
||||||
|
I64_EXTENDS16_6(0xC3),
|
||||||
|
I64_EXTENDS32_S(0xC4),
|
||||||
|
|
||||||
|
IXX_TRUNC_SAT_FXX_SU(0xFC);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int val;
|
||||||
|
InstrType(int val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, InstrType> map = new HashMap<>();
|
||||||
|
static {
|
||||||
|
for (InstrType valType : InstrType.values()) {
|
||||||
|
map.put(valType.val, valType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InstrType from_val(int val) {
|
||||||
|
return map.get(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package wasm.disassembly.instructions.control;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrFactory;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BlockInstr extends Instr {
|
||||||
|
|
||||||
|
private List<Instr> blockInstructions;
|
||||||
|
private BlockType blockType;
|
||||||
|
|
||||||
|
public BlockInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
|
||||||
|
blockType = new BlockType(in, module);
|
||||||
|
|
||||||
|
blockInstructions = new ArrayList<>(4);
|
||||||
|
InstrType type;
|
||||||
|
while ((type = InstrFactory.disassembleType(in)) != InstrType.END) {
|
||||||
|
blockInstructions.add(InstrFactory.disassemble(in, type, module));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockInstr(InstrType instrType, List<Instr> blockInstructions, BlockType blockType) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.blockInstructions = blockInstructions;
|
||||||
|
this.blockType = blockType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
blockType.assemble(out);
|
||||||
|
for(Instr instr : blockInstructions) {
|
||||||
|
instr.assemble(out);
|
||||||
|
}
|
||||||
|
out.write(InstrType.END.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Instr> getBlockInstructions() {
|
||||||
|
return blockInstructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockInstructions(List<Instr> blockInstructions) {
|
||||||
|
this.blockInstructions = blockInstructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockType getBlockType() {
|
||||||
|
return blockType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockType(BlockType blockType) {
|
||||||
|
this.blockType = blockType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package wasm.disassembly.instructions.control;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.types.ValType;
|
||||||
|
import wasm.disassembly.values.WSignedLong;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class BlockType extends WASMOpCode {
|
||||||
|
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
public BlockType(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
in.mark(1);
|
||||||
|
int first = in.read();
|
||||||
|
|
||||||
|
if (first == 0x40) {
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
|
else if (ValType.from_val(first) != null) {
|
||||||
|
value = ValType.from_val(first);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
in.reset();
|
||||||
|
value = WSignedLong.read(in, 33);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockType(Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
if (value == null) {
|
||||||
|
out.write(0x40);
|
||||||
|
}
|
||||||
|
else if (value instanceof ValType) {
|
||||||
|
out.write(((ValType)value).val);
|
||||||
|
}
|
||||||
|
else if (value instanceof Long) {
|
||||||
|
WSignedLong.write((Long)value, out, 33);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new InvalidOpCodeException("Invalid block type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return value == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValueType() {
|
||||||
|
return value != null && value instanceof ValType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSignedInteger() {
|
||||||
|
return value != null && value instanceof Long;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.control;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.LabelIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class BranchInstr extends Instr {
|
||||||
|
|
||||||
|
private LabelIdx labelIdx;
|
||||||
|
|
||||||
|
public BranchInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
labelIdx = new LabelIdx(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BranchInstr(InstrType instrType, LabelIdx labelIdx) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.labelIdx = labelIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
labelIdx.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LabelIdx getLabelIdx() {
|
||||||
|
return labelIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabelIdx(LabelIdx labelIdx) {
|
||||||
|
this.labelIdx = labelIdx;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package wasm.disassembly.instructions.control;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Creator;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.LabelIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class BranchTableInstr extends Instr {
|
||||||
|
|
||||||
|
private Vector<LabelIdx> table;
|
||||||
|
private LabelIdx labelIdx;
|
||||||
|
|
||||||
|
public BranchTableInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
table = new Vector<>(in, LabelIdx::new, module);
|
||||||
|
labelIdx = new LabelIdx(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BranchTableInstr(InstrType instrType, Vector<LabelIdx> table, LabelIdx labelIdx) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.table = table;
|
||||||
|
this.labelIdx = labelIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
table.assemble(out);
|
||||||
|
labelIdx.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector<LabelIdx> getTable() {
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTable(Vector<LabelIdx> table) {
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LabelIdx getLabelIdx() {
|
||||||
|
return labelIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabelIdx(LabelIdx labelIdx) {
|
||||||
|
this.labelIdx = labelIdx;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package wasm.disassembly.instructions.control;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.indices.TypeIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class CallIndirectInstr extends Instr {
|
||||||
|
|
||||||
|
private TypeIdx typeIdx;
|
||||||
|
|
||||||
|
public CallIndirectInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
typeIdx = new TypeIdx(in, module);
|
||||||
|
if (in.read() != 0x00) {
|
||||||
|
throw new InvalidOpCodeException("Unexpected non-zero byte");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallIndirectInstr(InstrType instrType, TypeIdx typeIdx) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.typeIdx = typeIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
typeIdx.assemble(out);
|
||||||
|
out.write(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeIdx getTypeIdx() {
|
||||||
|
return typeIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeIdx(TypeIdx typeIdx) {
|
||||||
|
this.typeIdx = typeIdx;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.control;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class CallInstr extends Instr {
|
||||||
|
|
||||||
|
private FuncIdx funcIdx;
|
||||||
|
|
||||||
|
public CallInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
funcIdx = new FuncIdx(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallInstr(FuncIdx funcIdx) throws IOException {
|
||||||
|
super(InstrType.CALL); // can only be call instr
|
||||||
|
this.funcIdx = funcIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
funcIdx.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FuncIdx getFuncIdx() {
|
||||||
|
return funcIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFuncIdx(FuncIdx funcIdx) {
|
||||||
|
this.funcIdx = funcIdx;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package wasm.disassembly.instructions.control;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrFactory;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class IfElseInstr extends Instr {
|
||||||
|
|
||||||
|
private List<Instr> ifInstructions;
|
||||||
|
private List<Instr> elseInstructions;
|
||||||
|
|
||||||
|
private BlockType blockType;
|
||||||
|
|
||||||
|
|
||||||
|
public IfElseInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
|
||||||
|
blockType = new BlockType(in, module);
|
||||||
|
ifInstructions = new ArrayList<>(2);
|
||||||
|
elseInstructions = null;
|
||||||
|
List<Instr> currentBlock = ifInstructions;
|
||||||
|
|
||||||
|
InstrType type;
|
||||||
|
while ((type = InstrFactory.disassembleType(in)) != InstrType.END) {
|
||||||
|
if (type == InstrType.ELSE) {
|
||||||
|
elseInstructions = new ArrayList<>(2);
|
||||||
|
currentBlock = elseInstructions;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentBlock.add(InstrFactory.disassemble(in, type, module));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
blockType.assemble(out);
|
||||||
|
for(Instr instr : ifInstructions) {
|
||||||
|
instr.assemble(out);
|
||||||
|
}
|
||||||
|
if (elseInstructions != null) {
|
||||||
|
out.write(InstrType.ELSE.val);
|
||||||
|
for(Instr instr : elseInstructions) {
|
||||||
|
instr.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write(InstrType.END.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IfElseInstr(InstrType instrType, List<Instr> ifInstructions, List<Instr> elseInstructions, BlockType blockType) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.ifInstructions = ifInstructions;
|
||||||
|
this.elseInstructions = elseInstructions;
|
||||||
|
this.blockType = blockType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Instr> getIfInstructions() {
|
||||||
|
return ifInstructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIfInstructions(List<Instr> ifInstructions) {
|
||||||
|
this.ifInstructions = ifInstructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Instr> getElseInstructions() {
|
||||||
|
return elseInstructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElseInstructions(List<Instr> elseInstructions) {
|
||||||
|
this.elseInstructions = elseInstructions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockType getBlockType() {
|
||||||
|
return blockType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockType(BlockType blockType) {
|
||||||
|
this.blockType = blockType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package wasm.disassembly.instructions.memory;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Mem0Instr extends Instr {
|
||||||
|
public Mem0Instr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
if (in.read() != 0x00) {
|
||||||
|
throw new InvalidOpCodeException("Unexpected non-zero byte");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException {
|
||||||
|
out.write(0x00);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package wasm.disassembly.instructions.memory;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class MemArg extends WASMOpCode {
|
||||||
|
|
||||||
|
private long align;
|
||||||
|
private long offset;
|
||||||
|
|
||||||
|
public MemArg(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
align = WUnsignedInt.read(in, 32);
|
||||||
|
offset = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemArg(long align, long offset) {
|
||||||
|
this.align = align;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(align, out, 32);
|
||||||
|
WUnsignedInt.write(offset, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAlign() {
|
||||||
|
return align;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlign(long align) {
|
||||||
|
this.align = align;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffset(long offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package wasm.disassembly.instructions.memory;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class MemInstr extends Instr {
|
||||||
|
|
||||||
|
private MemArg memArg;
|
||||||
|
|
||||||
|
public MemInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
memArg = new MemArg(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemInstr(InstrType instrType, MemArg memArg) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.memArg = memArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
memArg.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemArg getMemArg() {
|
||||||
|
return memArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemArg(MemArg memArg) {
|
||||||
|
this.memArg = memArg;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package wasm.disassembly.instructions.misc;
|
||||||
|
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class SingleByteInstr extends Instr {
|
||||||
|
public SingleByteInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.numeric;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WFloat;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class NumericF32ConstInstr extends Instr {
|
||||||
|
|
||||||
|
private float constValue;
|
||||||
|
|
||||||
|
public NumericF32ConstInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
constValue = WFloat.read(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumericF32ConstInstr(float constValue) throws IOException {
|
||||||
|
super(InstrType.F32_CONST);
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException {
|
||||||
|
WFloat.write(constValue, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getConstValue() {
|
||||||
|
return constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConstValue(float constValue) {
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.numeric;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WDouble;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class NumericF64ConstInstr extends Instr {
|
||||||
|
|
||||||
|
private double constValue;
|
||||||
|
|
||||||
|
public NumericF64ConstInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
constValue = WDouble.read(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumericF64ConstInstr(float constValue) throws IOException {
|
||||||
|
super(InstrType.F64_CONST);
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException {
|
||||||
|
WDouble.write(constValue, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getConstValue() {
|
||||||
|
return constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConstValue(double constValue) {
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.numeric;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WSignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class NumericI32ConstInstr extends Instr {
|
||||||
|
|
||||||
|
private int constValue;
|
||||||
|
|
||||||
|
public NumericI32ConstInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
constValue = WSignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumericI32ConstInstr(int constValue) throws IOException {
|
||||||
|
super(InstrType.I32_CONST);
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WSignedInt.write(constValue, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConstValue() {
|
||||||
|
return constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConstValue(int constValue) {
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.numeric;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WSignedLong;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class NumericI64ConstInstr extends Instr {
|
||||||
|
|
||||||
|
private long constValue;
|
||||||
|
|
||||||
|
public NumericI64ConstInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
constValue = WSignedLong.read(in, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumericI64ConstInstr(long constValue) throws IOException {
|
||||||
|
super(InstrType.I64_CONST);
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WSignedLong.write(constValue, out, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getConstValue() {
|
||||||
|
return constValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConstValue(long constValue) {
|
||||||
|
this.constValue = constValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package wasm.disassembly.instructions.numeric;
|
||||||
|
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class NumericInstr extends Instr {
|
||||||
|
|
||||||
|
public NumericInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package wasm.disassembly.instructions.numeric;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class TruncSatInstr extends Instr {
|
||||||
|
|
||||||
|
private long type;
|
||||||
|
|
||||||
|
public TruncSatInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
type = WUnsignedInt.read(in, 32);
|
||||||
|
if (type < 0 || type > 7) {
|
||||||
|
throw new InvalidOpCodeException("Invalid opcode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TruncSatInstr(InstrType instrType, long type) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(type, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(long type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.variable;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.GlobalIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class GlobalVariableInstr extends Instr {
|
||||||
|
|
||||||
|
private GlobalIdx globalIdx;
|
||||||
|
|
||||||
|
public GlobalVariableInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
globalIdx = new GlobalIdx(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalVariableInstr(InstrType instrType, GlobalIdx globalIdx) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.globalIdx = globalIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
globalIdx.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalIdx getGlobalIdx() {
|
||||||
|
return globalIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGlobalIdx(GlobalIdx globalIdx) {
|
||||||
|
this.globalIdx = globalIdx;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.instructions.variable;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.LocalIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class LocalVariableInstr extends Instr {
|
||||||
|
|
||||||
|
private LocalIdx localIdx;
|
||||||
|
|
||||||
|
public LocalVariableInstr(BufferedInputStream in, InstrType instrType, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(instrType);
|
||||||
|
localIdx = new LocalIdx(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalVariableInstr(InstrType instrType, LocalIdx localIdx) throws IOException {
|
||||||
|
super(instrType);
|
||||||
|
this.localIdx = localIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
localIdx.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalIdx getLocalIdx() {
|
||||||
|
return localIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalIdx(LocalIdx localIdx) {
|
||||||
|
this.localIdx = localIdx;
|
||||||
|
}
|
||||||
|
}
|
31
G-Wasm/src/main/java/wasm/disassembly/modules/Magic.java
Normal file
31
G-Wasm/src/main/java/wasm/disassembly/modules/Magic.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package wasm.disassembly.modules;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class Magic extends WASMOpCode {
|
||||||
|
|
||||||
|
private static final byte[] EXPECTED_MAGIC = new byte[]{0x00, 0x61, 0x73, 0x6D};
|
||||||
|
|
||||||
|
|
||||||
|
public Magic(BufferedInputStream in) throws IOException, InvalidOpCodeException {
|
||||||
|
byte[] magic = new byte[4];
|
||||||
|
in.read(magic);
|
||||||
|
|
||||||
|
if (!Arrays.equals(magic, EXPECTED_MAGIC)) {
|
||||||
|
throw new InvalidOpCodeException("Invalid magic");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Magic() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(EXPECTED_MAGIC);
|
||||||
|
}
|
||||||
|
}
|
253
G-Wasm/src/main/java/wasm/disassembly/modules/Module.java
Normal file
253
G-Wasm/src/main/java/wasm/disassembly/modules/Module.java
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
package wasm.disassembly.modules;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.modules.sections.code.CodeSection;
|
||||||
|
import wasm.disassembly.modules.sections.custom.CustomSection;
|
||||||
|
import wasm.disassembly.modules.sections.custom.CustomSectionFactory;
|
||||||
|
import wasm.disassembly.modules.sections.data.DataSection;
|
||||||
|
import wasm.disassembly.modules.sections.element.ElementSection;
|
||||||
|
import wasm.disassembly.modules.sections.export.ExportSection;
|
||||||
|
import wasm.disassembly.modules.sections.function.FunctionSection;
|
||||||
|
import wasm.disassembly.modules.sections.global.GlobalSection;
|
||||||
|
import wasm.disassembly.modules.sections.imprt.ImportSection;
|
||||||
|
import wasm.disassembly.modules.sections.memory.MemorySection;
|
||||||
|
import wasm.disassembly.modules.sections.start.StartSection;
|
||||||
|
import wasm.disassembly.modules.sections.table.TableSection;
|
||||||
|
import wasm.disassembly.modules.sections.type.TypeSection;
|
||||||
|
import wasm.misc.StreamReplacement;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
public class Module extends WASMOpCode {
|
||||||
|
|
||||||
|
private Magic magic;
|
||||||
|
private Version version;
|
||||||
|
|
||||||
|
private TypeSection typeSection;
|
||||||
|
private ImportSection importSection;
|
||||||
|
private FunctionSection functionSection;
|
||||||
|
private TableSection tableSection;
|
||||||
|
private MemorySection memorySection;
|
||||||
|
private GlobalSection globalSection;
|
||||||
|
private ExportSection exportSection;
|
||||||
|
private StartSection startSection;
|
||||||
|
private ElementSection elementSection;
|
||||||
|
private CodeSection codeSection;
|
||||||
|
private DataSection dataSection;
|
||||||
|
|
||||||
|
private List<List<CustomSection>> customSectionsList;
|
||||||
|
|
||||||
|
public final List<StreamReplacement> streamReplacements;
|
||||||
|
|
||||||
|
|
||||||
|
public Module(BufferedInputStream in, List<StreamReplacement> streamReplacements) throws IOException, InvalidOpCodeException {
|
||||||
|
this.streamReplacements = streamReplacements;
|
||||||
|
|
||||||
|
customSectionsList = new ArrayList<>();
|
||||||
|
|
||||||
|
magic = new Magic(in);
|
||||||
|
version = new Version(in);
|
||||||
|
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
typeSection = isNextSection(in, 1) ? new TypeSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
importSection = isNextSection(in, 2) ? new ImportSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
functionSection = isNextSection(in, 3) ? new FunctionSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
tableSection = isNextSection(in, 4) ? new TableSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
memorySection = isNextSection(in, 5) ? new MemorySection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
globalSection = isNextSection(in , 6) ? new GlobalSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
exportSection = isNextSection(in, 7) ? new ExportSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
startSection = isNextSection(in, 8) ? new StartSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
elementSection = isNextSection(in, 9) ? new ElementSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
codeSection = isNextSection(in, 10) ? new CodeSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
dataSection = isNextSection(in, 11) ? new DataSection(in, this) : null;
|
||||||
|
disassembleCustomSections(in);
|
||||||
|
exportSection.addShittyExports(this);
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Module(String fileName, boolean gzip, List<StreamReplacement> streamReplacements) throws IOException, InvalidOpCodeException {
|
||||||
|
this(new BufferedInputStream(gzip ?
|
||||||
|
new GZIPInputStream(new FileInputStream(new File(fileName))) :
|
||||||
|
new FileInputStream(new File(fileName)))
|
||||||
|
, streamReplacements
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disassembleCustomSections(BufferedInputStream in) throws IOException, InvalidOpCodeException {
|
||||||
|
List<CustomSection> customSections = new ArrayList<>();
|
||||||
|
|
||||||
|
while (isNextSection(in, 0)) {
|
||||||
|
customSections.add(CustomSectionFactory.get(in, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
in.reset();
|
||||||
|
customSectionsList.add(customSections);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNextSection(BufferedInputStream in, int id) throws IOException {
|
||||||
|
in.mark(1);
|
||||||
|
if (in.read() == id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
in.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
magic.assemble(out);
|
||||||
|
version.assemble(out);
|
||||||
|
|
||||||
|
Section[] sections = new Section[]{typeSection, importSection, functionSection, tableSection,
|
||||||
|
memorySection, globalSection, exportSection, startSection, elementSection, codeSection,
|
||||||
|
dataSection};
|
||||||
|
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
assembleCustomSections(out, i);
|
||||||
|
if (sections[i] != null) {
|
||||||
|
sections[i].assemble(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assembleCustomSections(out, 11);
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assembleCustomSections(OutputStream out, int location) throws IOException, InvalidOpCodeException {
|
||||||
|
for(CustomSection section : customSectionsList.get(location)) {
|
||||||
|
section.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assembleToFile(String fileName, boolean gzip) throws IOException, InvalidOpCodeException {
|
||||||
|
assemble(gzip ? new GZIPOutputStream(new FileOutputStream(fileName)) : new FileOutputStream(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Magic getMagic() {
|
||||||
|
return magic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMagic(Magic magic) {
|
||||||
|
this.magic = magic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(Version version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSection getTypeSection() {
|
||||||
|
return typeSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeSection(TypeSection typeSection) {
|
||||||
|
this.typeSection = typeSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportSection getImportSection() {
|
||||||
|
return importSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImportSection(ImportSection importSection) {
|
||||||
|
this.importSection = importSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionSection getFunctionSection() {
|
||||||
|
return functionSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFunctionSection(FunctionSection functionSection) {
|
||||||
|
this.functionSection = functionSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableSection getTableSection() {
|
||||||
|
return tableSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableSection(TableSection tableSection) {
|
||||||
|
this.tableSection = tableSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemorySection getMemorySection() {
|
||||||
|
return memorySection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemorySection(MemorySection memorySection) {
|
||||||
|
this.memorySection = memorySection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalSection getGlobalSection() {
|
||||||
|
return globalSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGlobalSection(GlobalSection globalSection) {
|
||||||
|
this.globalSection = globalSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportSection getExportSection() {
|
||||||
|
return exportSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportSection(ExportSection exportSection) {
|
||||||
|
this.exportSection = exportSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StartSection getStartSection() {
|
||||||
|
return startSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartSection(StartSection startSection) {
|
||||||
|
this.startSection = startSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElementSection getElementSection() {
|
||||||
|
return elementSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElementSection(ElementSection elementSection) {
|
||||||
|
this.elementSection = elementSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeSection getCodeSection() {
|
||||||
|
return codeSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCodeSection(CodeSection codeSection) {
|
||||||
|
this.codeSection = codeSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataSection getDataSection() {
|
||||||
|
return dataSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDataSection(DataSection dataSection) {
|
||||||
|
this.dataSection = dataSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<List<CustomSection>> getCustomSectionsList() {
|
||||||
|
return customSectionsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomSectionsList(List<List<CustomSection>> customSectionsList) {
|
||||||
|
this.customSectionsList = customSectionsList;
|
||||||
|
}
|
||||||
|
}
|
40
G-Wasm/src/main/java/wasm/disassembly/modules/Version.java
Normal file
40
G-Wasm/src/main/java/wasm/disassembly/modules/Version.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package wasm.disassembly.modules;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Version extends WASMOpCode {
|
||||||
|
|
||||||
|
byte[] version;
|
||||||
|
|
||||||
|
|
||||||
|
public Version(BufferedInputStream in) throws IOException {
|
||||||
|
version = new byte[4];
|
||||||
|
in.read(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version(byte[] version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version() {
|
||||||
|
version = new byte[]{1, 0, 0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(byte[] version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package wasm.disassembly.modules.indices;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class FuncIdx extends WASMOpCode {
|
||||||
|
|
||||||
|
private long x;
|
||||||
|
|
||||||
|
|
||||||
|
// public int ref; // debugging purpose
|
||||||
|
|
||||||
|
public FuncIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
x = WUnsignedInt.read(in, 32)
|
||||||
|
+ module.streamReplacements.size();
|
||||||
|
|
||||||
|
|
||||||
|
// ref = CodeSection.currentI; // debugging purpose
|
||||||
|
}
|
||||||
|
|
||||||
|
public FuncIdx(long x, Module module) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(x, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return (obj instanceof FuncIdx && ((FuncIdx)obj).getX() == x);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package wasm.disassembly.modules.indices;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class GlobalIdx extends WASMOpCode {
|
||||||
|
|
||||||
|
private long x;
|
||||||
|
|
||||||
|
public GlobalIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
x = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalIdx(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(x, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package wasm.disassembly.modules.indices;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class LabelIdx extends WASMOpCode {
|
||||||
|
|
||||||
|
private long l;
|
||||||
|
|
||||||
|
public LabelIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
l = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LabelIdx(long l) {
|
||||||
|
this.l = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(l, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getL() {
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setL(long l) {
|
||||||
|
this.l = l;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package wasm.disassembly.modules.indices;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class LocalIdx extends WASMOpCode {
|
||||||
|
|
||||||
|
private long x;
|
||||||
|
|
||||||
|
public LocalIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
x = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalIdx(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(x, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package wasm.disassembly.modules.indices;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class MemIdx extends WASMOpCode {
|
||||||
|
|
||||||
|
private long x;
|
||||||
|
|
||||||
|
public MemIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
x = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemIdx(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(x, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package wasm.disassembly.modules.indices;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class TableIdx extends WASMOpCode {
|
||||||
|
|
||||||
|
private long x;
|
||||||
|
|
||||||
|
public TableIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
x = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableIdx(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(x, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package wasm.disassembly.modules.indices;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class TypeIdx extends WASMOpCode {
|
||||||
|
|
||||||
|
private long x;
|
||||||
|
|
||||||
|
public TypeIdx(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
x = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeIdx(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(x, out, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return (obj instanceof TypeIdx && ((TypeIdx)obj).getX() == x);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package wasm.disassembly.modules.sections;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public abstract class Section extends WASMOpCode {
|
||||||
|
|
||||||
|
private int sectionId;
|
||||||
|
private long size;
|
||||||
|
protected Module module;
|
||||||
|
|
||||||
|
public Section(BufferedInputStream in, Module module, int sectionId) throws IOException, InvalidOpCodeException {
|
||||||
|
this.module = module;
|
||||||
|
this.sectionId = sectionId;
|
||||||
|
size = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Section(Module module, int sectionId, long size) {
|
||||||
|
this.module = module;
|
||||||
|
this.sectionId = sectionId;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Section(Module module, int sectionId) {
|
||||||
|
this(module, sectionId, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(sectionId);
|
||||||
|
|
||||||
|
ByteArrayOutputStream fakeOutputStream = new ByteArrayOutputStream();
|
||||||
|
assemble2(fakeOutputStream);
|
||||||
|
byte[] asbytes = fakeOutputStream.toByteArray();
|
||||||
|
WUnsignedInt.write(asbytes.length, out, 32);
|
||||||
|
fakeOutputStream.close();
|
||||||
|
out.write(asbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void assemble2(OutputStream out) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
|
||||||
|
public int getSectionId() {
|
||||||
|
return sectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package wasm.disassembly.modules.sections;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface SectionSupplier {
|
||||||
|
|
||||||
|
Section get(BufferedInputStream in) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package wasm.disassembly.modules.sections.code;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Code extends WASMOpCode {
|
||||||
|
|
||||||
|
private Func code;
|
||||||
|
|
||||||
|
public Code(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
long sizeInBytes = WUnsignedInt.read(in, 32); // don't use
|
||||||
|
code = new Func(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Code(Func code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
ByteArrayOutputStream codeBuffer = new ByteArrayOutputStream();
|
||||||
|
code.assemble(codeBuffer);
|
||||||
|
byte[] codeInBytes = codeBuffer.toByteArray();
|
||||||
|
WUnsignedInt.write(codeInBytes.length, out, 32);
|
||||||
|
out.write(codeInBytes);
|
||||||
|
codeBuffer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Func getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(Func code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
package wasm.disassembly.modules.sections.code;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.instructions.Expression;
|
||||||
|
import wasm.disassembly.instructions.Instr;
|
||||||
|
import wasm.disassembly.instructions.InstrType;
|
||||||
|
import wasm.disassembly.instructions.control.CallInstr;
|
||||||
|
import wasm.disassembly.instructions.variable.LocalVariableInstr;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.indices.LocalIdx;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
import wasm.misc.StreamReplacement;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CodeSection extends Section {
|
||||||
|
|
||||||
|
public static final int CODE_SECTION_ID = 10;
|
||||||
|
|
||||||
|
// public static int currentI = 0;
|
||||||
|
|
||||||
|
public final byte[] asBytes;
|
||||||
|
public long length;
|
||||||
|
public int copiesLength;
|
||||||
|
// private Vector<Code> codesEntries;
|
||||||
|
|
||||||
|
public CodeSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, CODE_SECTION_ID);
|
||||||
|
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
Code[] copies = new Code[module.streamReplacements.size()];
|
||||||
|
|
||||||
|
// codesEntries = new Vector<>(in, Code::new, module);
|
||||||
|
length = WUnsignedInt.read(in, 32);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
Code code = new Code(in, module);
|
||||||
|
|
||||||
|
|
||||||
|
Func func = code.getCode();
|
||||||
|
for (int j = 0; j < module.streamReplacements.size(); j++) {
|
||||||
|
|
||||||
|
if (module.getFunctionSection().matchesSearchFunctionsTypes.get(j).contains(i)) {
|
||||||
|
|
||||||
|
if (module.streamReplacements.get(j).codeMatches(func)) {
|
||||||
|
StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(j).getReplacementType();
|
||||||
|
if (actionTaken == StreamReplacement.ReplacementType.HOOK) {
|
||||||
|
CallInstr call = new CallInstr(new FuncIdx(j, module));
|
||||||
|
|
||||||
|
List<Instr> newInstrs = new ArrayList<>();
|
||||||
|
for (int k = 0; k < module.streamReplacements.get(j).getFuncType().getParameterType().typeList().size(); k++) {
|
||||||
|
newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
|
||||||
|
}
|
||||||
|
newInstrs.add(call);
|
||||||
|
newInstrs.addAll(func.getExpression().getInstructions());
|
||||||
|
func.getExpression().setInstructions(newInstrs);
|
||||||
|
}
|
||||||
|
else if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
|
||||||
|
copies[j] = new Code(new Func(func.getLocalss(), new Expression(func.getExpression().getInstructions())));
|
||||||
|
|
||||||
|
CallInstr call = new CallInstr(new FuncIdx(j, module));
|
||||||
|
List<Instr> newInstrs = new ArrayList<>();
|
||||||
|
for (int k = 0; k < module.streamReplacements.get(j).getFuncType().getParameterType().typeList().size(); k++) {
|
||||||
|
newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(k)));
|
||||||
|
}
|
||||||
|
newInstrs.add(call);
|
||||||
|
func.getExpression().setInstructions(newInstrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
code.assemble(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Code code : copies) {
|
||||||
|
if (code != null) {
|
||||||
|
code.assemble(buffer);
|
||||||
|
length++;
|
||||||
|
copiesLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asBytes = buffer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public CodeSection(Module module, List<Code> codesEntries) {
|
||||||
|
// super(module, CODE_SECTION_ID);
|
||||||
|
// this.codesEntries = new Vector<>(codesEntries);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
// codesEntries.assemble(out);
|
||||||
|
|
||||||
|
WUnsignedInt.write(length, out, 32);
|
||||||
|
out.write(asBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public Code getCodeByIdx(FuncIdx funcIdx) {
|
||||||
|
// return codesEntries.getElements().get((int)(funcIdx.getX()) - module.getImportSection().getTotalFuncImports());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public Func getByIdx(FuncIdx funcIdx) {
|
||||||
|
// return getCodeByIdx(funcIdx).getCode();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public List<Code> getCodesEntries() {
|
||||||
|
// return codesEntries.getElements();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void setCodesEntries(List<Code> codesEntries) {
|
||||||
|
// this.codesEntries = new Vector<>(codesEntries);
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package wasm.disassembly.modules.sections.code;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.instructions.Expression;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.types.ValType;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Func extends WASMOpCode {
|
||||||
|
|
||||||
|
private Vector<Locals> localss; // intended double s
|
||||||
|
private Expression expression;
|
||||||
|
|
||||||
|
|
||||||
|
public Func(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
localss = new Vector<>(in, Locals::new, module);
|
||||||
|
expression = new Expression(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Func(List<Locals> localss, Expression expression) {
|
||||||
|
this.localss = new Vector<>(localss);
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Func(ValType[] localVariables, Expression expression) {
|
||||||
|
setLocalVariables(localVariables);
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
localss.assemble(out);
|
||||||
|
expression.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Locals> getLocalss() {
|
||||||
|
return localss.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalss(List<Locals> localss) {
|
||||||
|
this.localss = new Vector<>(localss);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression getExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpression(Expression expression) {
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalVariables(ValType[] locals) {
|
||||||
|
List<Locals> localss = new ArrayList<>();
|
||||||
|
|
||||||
|
Locals current = null;
|
||||||
|
for (ValType valType : locals) {
|
||||||
|
if (current == null || current.getValType() != valType) {
|
||||||
|
if (current != null) localss.add(current);
|
||||||
|
current = new Locals(1, valType);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
current.setAmount(current.getAmount() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current != null) localss.add(current);
|
||||||
|
this.localss = new Vector<>(localss);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package wasm.disassembly.modules.sections.code;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.types.ValType;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Locals extends WASMOpCode {
|
||||||
|
|
||||||
|
private long amount;
|
||||||
|
private ValType valType;
|
||||||
|
|
||||||
|
public Locals(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
amount = WUnsignedInt.read(in, 32);
|
||||||
|
valType = ValType.from_val(in.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locals(long amount, ValType valType) {
|
||||||
|
this.amount = amount;
|
||||||
|
this.valType = valType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WUnsignedInt.write(amount, out, 32);
|
||||||
|
out.write(valType.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValType getValType() {
|
||||||
|
return valType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValType(ValType valType) {
|
||||||
|
this.valType = valType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof Locals)) return false;
|
||||||
|
Locals other = (Locals) obj;
|
||||||
|
return amount == other.amount && valType.val == other.valType.val;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public abstract class CustomSection extends Section {
|
||||||
|
|
||||||
|
public static final int CUSTOM_SECTION_ID = 0;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public CustomSection(Module module, long size, String name) throws IOException, InvalidOpCodeException {
|
||||||
|
super(module, CUSTOM_SECTION_ID, size);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WName.write(name, out);
|
||||||
|
assemble3(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void assemble3(OutputStream out) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.custom.namesection.NameSection;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class CustomSectionFactory {
|
||||||
|
|
||||||
|
public static CustomSection get(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
long size = WUnsignedInt.read(in, 32);
|
||||||
|
String name = WName.read(in);
|
||||||
|
|
||||||
|
if (name.equals("name")) {
|
||||||
|
return new NameSection(in, module, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnImplementedCustomSection(in, module, size, name);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.custom.CustomSection;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class UnImplementedCustomSection extends CustomSection {
|
||||||
|
|
||||||
|
private byte[] bytes;
|
||||||
|
|
||||||
|
public UnImplementedCustomSection(BufferedInputStream in, Module module, long size, String name) throws IOException, InvalidOpCodeException {
|
||||||
|
super(module, size, name);
|
||||||
|
|
||||||
|
ByteArrayOutputStream nameOut = new ByteArrayOutputStream();
|
||||||
|
WName.write(name, nameOut);
|
||||||
|
|
||||||
|
bytes = new byte[(int)size - nameOut.toByteArray().length];
|
||||||
|
in.read(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble3(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBytes() {
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBytes(byte[] bytes) {
|
||||||
|
this.bytes = bytes;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.custom.CustomSection;
|
||||||
|
import wasm.disassembly.modules.sections.custom.namesection.subsections.FunctionNamesSubSection;
|
||||||
|
import wasm.disassembly.modules.sections.custom.namesection.subsections.LocalNamesSubSection;
|
||||||
|
import wasm.disassembly.modules.sections.custom.namesection.subsections.ModuleNameSubSection;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class NameSection extends CustomSection {
|
||||||
|
|
||||||
|
private ModuleNameSubSection moduleName;
|
||||||
|
private FunctionNamesSubSection functionNames;
|
||||||
|
private LocalNamesSubSection localNames;
|
||||||
|
|
||||||
|
public NameSection(BufferedInputStream in, Module module, long size) throws IOException, InvalidOpCodeException {
|
||||||
|
super(module, size, "name");
|
||||||
|
|
||||||
|
moduleName = isNextSection(in, 0) ? new ModuleNameSubSection(in, module) : null;
|
||||||
|
functionNames = isNextSection(in, 1) ? new FunctionNamesSubSection(in, module) : null;
|
||||||
|
localNames = isNextSection(in, 2) ? new LocalNamesSubSection(in, module) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameSection(Module module, long size, String name, ModuleNameSubSection moduleName, FunctionNamesSubSection functionNames, LocalNamesSubSection localNames) throws IOException, InvalidOpCodeException {
|
||||||
|
super(module, size, name);
|
||||||
|
this.moduleName = moduleName;
|
||||||
|
this.functionNames = functionNames;
|
||||||
|
this.localNames = localNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleNameSubSection getModuleName() {
|
||||||
|
return moduleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModuleName(ModuleNameSubSection moduleName) {
|
||||||
|
this.moduleName = moduleName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionNamesSubSection getFunctionNames() {
|
||||||
|
return functionNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFunctionNames(FunctionNamesSubSection functionNames) {
|
||||||
|
this.functionNames = functionNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalNamesSubSection getLocalNames() {
|
||||||
|
return localNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalNames(LocalNamesSubSection localNames) {
|
||||||
|
this.localNames = localNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble3(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
if (moduleName != null) moduleName.assemble(out);
|
||||||
|
if (functionNames != null) functionNames.assemble(out);
|
||||||
|
if (localNames != null) localNames.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNextSection(BufferedInputStream in, int id) throws IOException {
|
||||||
|
in.mark(1);
|
||||||
|
if (in.read() == id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
in.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Creator;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.sections.custom.namesection.subsections.namemaps.NameMap;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class FunctionNamesSubSection extends SubSection {
|
||||||
|
|
||||||
|
public static final int FUNCTION_NAMES_SUBSECTION_ID = 1;
|
||||||
|
private NameMap<FuncIdx> nameMap;
|
||||||
|
|
||||||
|
public FunctionNamesSubSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, FUNCTION_NAMES_SUBSECTION_ID);
|
||||||
|
nameMap = new NameMap<>(in, module, FuncIdx::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionNamesSubSection(NameMap<FuncIdx> nameMap) {
|
||||||
|
super(FUNCTION_NAMES_SUBSECTION_ID);
|
||||||
|
this.nameMap = nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameMap<FuncIdx> getNameMap() {
|
||||||
|
return nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNameMap(NameMap<FuncIdx> nameMap) {
|
||||||
|
this.nameMap = nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
nameMap.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Creator;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.indices.LocalIdx;
|
||||||
|
import wasm.disassembly.modules.sections.custom.namesection.subsections.namemaps.IndirectNameMap;
|
||||||
|
import wasm.disassembly.modules.sections.custom.namesection.subsections.namemaps.NameMap;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class LocalNamesSubSection extends SubSection {
|
||||||
|
|
||||||
|
public static final int LOCAL_NAMES_SUBSECTION_ID = 2;
|
||||||
|
private IndirectNameMap<FuncIdx, LocalIdx> indirectNameMap;
|
||||||
|
|
||||||
|
public LocalNamesSubSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, LOCAL_NAMES_SUBSECTION_ID);
|
||||||
|
indirectNameMap = new IndirectNameMap<>(in, module, FuncIdx::new, LocalIdx::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalNamesSubSection(IndirectNameMap<FuncIdx, LocalIdx> indirectNameMap) {
|
||||||
|
super(LOCAL_NAMES_SUBSECTION_ID);
|
||||||
|
this.indirectNameMap = indirectNameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndirectNameMap<FuncIdx, LocalIdx> getIndirectNameMap() {
|
||||||
|
return indirectNameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndirectNameMap(IndirectNameMap<FuncIdx, LocalIdx> indirectNameMap) {
|
||||||
|
this.indirectNameMap = indirectNameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
indirectNameMap.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class ModuleNameSubSection extends SubSection {
|
||||||
|
|
||||||
|
public static final int MODULE_NAME_SUBSECTION_ID = 0;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public ModuleNameSubSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, MODULE_NAME_SUBSECTION_ID);
|
||||||
|
name = WName.read(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleNameSubSection(String name) {
|
||||||
|
super(MODULE_NAME_SUBSECTION_ID);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WName.write(name, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public abstract class SubSection extends WASMOpCode {
|
||||||
|
|
||||||
|
private long size;
|
||||||
|
private int subSectionId;
|
||||||
|
|
||||||
|
public SubSection(BufferedInputStream in, int subSectionId) throws IOException, InvalidOpCodeException {
|
||||||
|
this.subSectionId = subSectionId;
|
||||||
|
size = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubSection(int subSectionId) {
|
||||||
|
this.subSectionId = subSectionId;
|
||||||
|
size = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(subSectionId);
|
||||||
|
|
||||||
|
ByteArrayOutputStream fakeOutputStream = new ByteArrayOutputStream();
|
||||||
|
assemble2(fakeOutputStream);
|
||||||
|
byte[] asbytes = fakeOutputStream.toByteArray();
|
||||||
|
WUnsignedInt.write(asbytes.length, out, 32);
|
||||||
|
out.write(asbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void assemble2(OutputStream out) throws IOException, InvalidOpCodeException;
|
||||||
|
|
||||||
|
public int getSubSectionId() {
|
||||||
|
return subSectionId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections.namemaps;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.conventions.Creator;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class IndirectNameAssoc<Idx extends WASMOpCode, InnerIdx extends WASMOpCode> extends WASMOpCode {
|
||||||
|
|
||||||
|
private Idx idx;
|
||||||
|
private NameMap<InnerIdx> nameMap;
|
||||||
|
|
||||||
|
public IndirectNameAssoc(BufferedInputStream in, Module module, Creator<Idx> creator, Creator<InnerIdx> innerCreator) throws IOException, InvalidOpCodeException {
|
||||||
|
idx = creator.create(in, module);
|
||||||
|
nameMap = new NameMap<>(in, module, innerCreator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndirectNameAssoc(Idx idx, NameMap<InnerIdx> nameMap) {
|
||||||
|
this.idx = idx;
|
||||||
|
this.nameMap = nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Idx getIdx() {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdx(Idx idx) {
|
||||||
|
this.idx = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameMap<InnerIdx> getNameMap() {
|
||||||
|
return nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNameMap(NameMap<InnerIdx> nameMap) {
|
||||||
|
this.nameMap = nameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
idx.assemble(out);
|
||||||
|
nameMap.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections.namemaps;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.conventions.Creator;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class IndirectNameMap<Idx extends WASMOpCode, InnerIdx extends WASMOpCode> extends WASMOpCode {
|
||||||
|
|
||||||
|
private Vector<IndirectNameAssoc<Idx, InnerIdx>> idxAndMaps;
|
||||||
|
|
||||||
|
public IndirectNameMap(BufferedInputStream in, Module module, Creator<Idx> creator, Creator<InnerIdx> innerCreator) throws IOException, InvalidOpCodeException {
|
||||||
|
idxAndMaps = new Vector<>(in, (in1, m) -> new IndirectNameAssoc<>(in1, m, creator, innerCreator), module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndirectNameMap(Vector<IndirectNameAssoc<Idx, InnerIdx>> idxAndMaps) {
|
||||||
|
this.idxAndMaps = idxAndMaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IndirectNameAssoc<Idx, InnerIdx>> getIdxAndMaps() {
|
||||||
|
return idxAndMaps.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdxAndMaps(List<IndirectNameAssoc<Idx, InnerIdx>> idxAndMaps) {
|
||||||
|
this.idxAndMaps = new Vector<>(idxAndMaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
idxAndMaps.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections.namemaps;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.conventions.Creator;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class NameAssoc<Idx extends WASMOpCode> extends WASMOpCode {
|
||||||
|
|
||||||
|
private Idx idx;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public NameAssoc(BufferedInputStream in, Module module, Creator<Idx> creator) throws IOException, InvalidOpCodeException {
|
||||||
|
idx = creator.create(in, module);
|
||||||
|
name = WName.read(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameAssoc(Idx idx, String name) {
|
||||||
|
this.idx = idx;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Idx getIdx() {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdx(Idx idx) {
|
||||||
|
this.idx = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
idx.assemble(out);
|
||||||
|
WName.write(name, out);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package wasm.disassembly.modules.sections.custom.namesection.subsections.namemaps;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.conventions.Creator;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NameMap<Idx extends WASMOpCode> extends WASMOpCode {
|
||||||
|
|
||||||
|
private Vector<NameAssoc<Idx>> idxAndNames;
|
||||||
|
|
||||||
|
public NameMap(BufferedInputStream in, Module module, Creator<Idx> creator) throws IOException, InvalidOpCodeException {
|
||||||
|
idxAndNames = new Vector<>(in, (in1, m) -> new NameAssoc<>(in1, m, creator), module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameMap(Vector<NameAssoc<Idx>> idxAndNames) {
|
||||||
|
this.idxAndNames = idxAndNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NameAssoc<Idx>> getIdxAndNames() {
|
||||||
|
return idxAndNames.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdxAndNames(List<NameAssoc<Idx>> idxAndNames) {
|
||||||
|
this.idxAndNames = new Vector<>(idxAndNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
idxAndNames.assemble(out);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package wasm.disassembly.modules.sections.data;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.instructions.Expression;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.MemIdx;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Data extends WASMOpCode {
|
||||||
|
|
||||||
|
private MemIdx dataMemId;
|
||||||
|
private Expression offset;
|
||||||
|
private byte[] data;
|
||||||
|
|
||||||
|
|
||||||
|
public Data(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
dataMemId = new MemIdx(in, module);
|
||||||
|
offset = new Expression(in, module);
|
||||||
|
long length = WUnsignedInt.read(in, 32);
|
||||||
|
data = new byte[(int)length];
|
||||||
|
in.read(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data(MemIdx dataMemId, Expression offset, byte[] data) {
|
||||||
|
this.dataMemId = dataMemId;
|
||||||
|
this.offset = offset;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
dataMemId.assemble(out);
|
||||||
|
offset.assemble(out);
|
||||||
|
WUnsignedInt.write(data.length, out, 32);
|
||||||
|
out.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public MemIdx getDataMemId() {
|
||||||
|
return dataMemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDataMemId(MemIdx dataMemId) {
|
||||||
|
this.dataMemId = dataMemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffset(Expression offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(byte[] data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package wasm.disassembly.modules.sections.data;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.modules.sections.element.Elem;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DataSection extends Section {
|
||||||
|
|
||||||
|
public static final int DATA_SECTION_ID = 11;
|
||||||
|
private final byte[] asBytes;
|
||||||
|
private long length;
|
||||||
|
|
||||||
|
// private Vector<Data> dataSegments;
|
||||||
|
|
||||||
|
public DataSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, DATA_SECTION_ID);
|
||||||
|
// dataSegments = new Vector<>(in, Data::new, module);
|
||||||
|
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
length = WUnsignedInt.read(in, 32);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
new Data(in, module).assemble(buffer);
|
||||||
|
}
|
||||||
|
asBytes = buffer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public DataSection(Module module, List<Data> dataSegments) {
|
||||||
|
// super(module, DATA_SECTION_ID);
|
||||||
|
// this.dataSegments = new Vector<>(dataSegments);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
// dataSegments.assemble(out);
|
||||||
|
|
||||||
|
WUnsignedInt.write(length, out, 32);
|
||||||
|
out.write(asBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// public List<Data> getDataSegments() {
|
||||||
|
// return dataSegments.getElements();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void setDataSegments(List<Data> dataSegments) {
|
||||||
|
// this.dataSegments = new Vector<>(dataSegments);
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package wasm.disassembly.modules.sections.element;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.instructions.Expression;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.indices.TableIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Elem extends WASMOpCode {
|
||||||
|
|
||||||
|
private TableIdx tableIdx;
|
||||||
|
private Expression offset;
|
||||||
|
private Vector<FuncIdx> init;
|
||||||
|
|
||||||
|
public Elem(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
tableIdx = new TableIdx(in, module);
|
||||||
|
offset = new Expression(in, module);
|
||||||
|
init = new Vector<>(in, FuncIdx::new, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Elem(TableIdx tableIdx, Expression offset, Vector<FuncIdx> init) {
|
||||||
|
this.tableIdx = tableIdx;
|
||||||
|
this.offset = offset;
|
||||||
|
this.init = init;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
tableIdx.assemble(out);
|
||||||
|
offset.assemble(out);
|
||||||
|
init.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableIdx getTableIdx() {
|
||||||
|
return tableIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableIdx(TableIdx tableIdx) {
|
||||||
|
this.tableIdx = tableIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffset(Expression offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector<FuncIdx> getInit() {
|
||||||
|
return init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInit(Vector<FuncIdx> init) {
|
||||||
|
this.init = init;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package wasm.disassembly.modules.sections.element;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.TypeIdx;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ElementSection extends Section {
|
||||||
|
|
||||||
|
public static final int ELEMENT_SECTION_ID = 9;
|
||||||
|
|
||||||
|
// private Vector<Elem> elementSegments;
|
||||||
|
|
||||||
|
private final byte[] asBytes;
|
||||||
|
private long length;
|
||||||
|
|
||||||
|
public ElementSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, ELEMENT_SECTION_ID);
|
||||||
|
// elementSegments = new Vector<>(in, Elem::new, module);
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
length = WUnsignedInt.read(in, 32);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
new Elem(in, module).assemble(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
asBytes = buffer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public ElementSection(Module module, List<Elem> elementSegments) {
|
||||||
|
// super(module, ELEMENT_SECTION_ID);
|
||||||
|
// this.elementSegments = new Vector<>(elementSegments);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
// elementSegments.assemble(out);
|
||||||
|
|
||||||
|
WUnsignedInt.write(length, out, 32);
|
||||||
|
out.write(asBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public List<Elem> getElementSegments() {
|
||||||
|
// return elementSegments.getElements();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void setElementSegments(List<Elem> elementSegments) {
|
||||||
|
// this.elementSegments = new Vector<>(elementSegments);
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package wasm.disassembly.modules.sections.export;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Export extends WASMOpCode {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private ExportDesc exportDesc;
|
||||||
|
|
||||||
|
public Export(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
name = WName.read(in);
|
||||||
|
exportDesc = new ExportDesc(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Export(String name, ExportDesc exportDesc) {
|
||||||
|
this.name = name;
|
||||||
|
this.exportDesc = exportDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WName.write(name, out);
|
||||||
|
exportDesc.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportDesc getExportDesc() {
|
||||||
|
return exportDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportDesc(ExportDesc exportDesc) {
|
||||||
|
this.exportDesc = exportDesc;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package wasm.disassembly.modules.sections.export;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.indices.GlobalIdx;
|
||||||
|
import wasm.disassembly.modules.indices.MemIdx;
|
||||||
|
import wasm.disassembly.modules.indices.TableIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class ExportDesc extends WASMOpCode {
|
||||||
|
|
||||||
|
private WASMOpCode exportValue;
|
||||||
|
private int exportType;
|
||||||
|
|
||||||
|
|
||||||
|
public ExportDesc(BufferedInputStream in, Module module) throws InvalidOpCodeException, IOException {
|
||||||
|
exportType = in.read();
|
||||||
|
if (exportType < 0x00 || exportType > 0x03) {
|
||||||
|
throw new InvalidOpCodeException("invalid exportdesc type");
|
||||||
|
}
|
||||||
|
|
||||||
|
exportValue = exportType == 0x00 ? new FuncIdx(in, module) :
|
||||||
|
(exportType == 0x01 ? new TableIdx(in, module) :
|
||||||
|
(exportType == 0x02 ? new MemIdx(in, module) :
|
||||||
|
new GlobalIdx(in, module)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportDesc(WASMOpCode exportValue, int exportType) {
|
||||||
|
this.exportValue = exportValue;
|
||||||
|
this.exportType = exportType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportDesc(FuncIdx funcIdx) {
|
||||||
|
this(funcIdx, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportDesc(TableIdx tableIdx) {
|
||||||
|
this(tableIdx, 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportDesc(MemIdx memIdx) {
|
||||||
|
this(memIdx, 0x02);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportDesc(GlobalIdx globalIdx) {
|
||||||
|
this(globalIdx, 0x03);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(exportType);
|
||||||
|
exportValue.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public WASMOpCode getExportValue() {
|
||||||
|
return exportValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportValue(WASMOpCode exportValue) {
|
||||||
|
this.exportValue = exportValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExportType() {
|
||||||
|
return exportType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportType(int exportType) {
|
||||||
|
this.exportType = exportType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package wasm.disassembly.modules.sections.export;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.misc.StreamReplacement;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ExportSection extends Section {
|
||||||
|
|
||||||
|
public static final int EXPORT_SECTION_ID = 7;
|
||||||
|
|
||||||
|
private Vector<Export> exports;
|
||||||
|
|
||||||
|
public ExportSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, EXPORT_SECTION_ID);
|
||||||
|
exports = new Vector<>(in, Export::new, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExportSection(Module module, List<Export> exports) {
|
||||||
|
super(module, EXPORT_SECTION_ID);
|
||||||
|
this.exports = new Vector<>(exports);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
exports.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Export> getExports() {
|
||||||
|
return exports.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExports(List<Export> exports) {
|
||||||
|
this.exports = new Vector<>(exports);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void addShittyExports(Module module) {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < module.streamReplacements.size(); i++) {
|
||||||
|
StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(i).getReplacementType();
|
||||||
|
if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
|
||||||
|
getExports().add(new Export(module.streamReplacements.get(i).getExportName(), new ExportDesc(new FuncIdx(
|
||||||
|
module.getCodeSection().length + module.getImportSection().getTotalFuncImports() -
|
||||||
|
module.getCodeSection().copiesLength + count, module
|
||||||
|
))));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
package wasm.disassembly.modules.sections.function;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.TypeIdx;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
import wasm.misc.StreamReplacement;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class FunctionSection extends Section {
|
||||||
|
|
||||||
|
public static final int FUNCTION_SECTION_ID = 3;
|
||||||
|
|
||||||
|
// private Vector<TypeIdx> typeIdxVector;
|
||||||
|
private final byte[] asBytes;
|
||||||
|
private long length;
|
||||||
|
|
||||||
|
public List<Set<Integer>> matchesSearchFunctionsTypes = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
public FunctionSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, FUNCTION_SECTION_ID);
|
||||||
|
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
List<TypeIdx> searchFunctions = new ArrayList<>();
|
||||||
|
for (int i = 0; i < module.streamReplacements.size(); i++) {
|
||||||
|
StreamReplacement f = module.streamReplacements.get(i);
|
||||||
|
searchFunctions.add(module.getTypeSection().getTypeIdxForFuncType(f.getFuncType()));
|
||||||
|
matchesSearchFunctionsTypes.add(new HashSet<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// typeIdxVector = new Vector<>(in, TypeIdx::new, module);
|
||||||
|
length = WUnsignedInt.read(in, 32);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
TypeIdx typeIdx = new TypeIdx(in, module);
|
||||||
|
for (int j = 0; j < searchFunctions.size(); j++) {
|
||||||
|
if (typeIdx.equals(searchFunctions.get(j))) {
|
||||||
|
matchesSearchFunctionsTypes.get(j).add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typeIdx.assemble(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < module.streamReplacements.size(); i++) {
|
||||||
|
StreamReplacement.ReplacementType actionTaken = module.streamReplacements.get(i).getReplacementType();
|
||||||
|
// new function will be created
|
||||||
|
if (actionTaken == StreamReplacement.ReplacementType.HOOKCOPYEXPORT) {
|
||||||
|
searchFunctions.get(i).assemble(buffer);
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asBytes = buffer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public FunctionSection(Module module, List<TypeIdx> typeIdxList) {
|
||||||
|
// super(module, FUNCTION_SECTION_ID);
|
||||||
|
// this.typeIdxVector = new Vector<>(typeIdxList);
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
// typeIdxVector.assemble(out);
|
||||||
|
WUnsignedInt.write(length, out, 32);
|
||||||
|
out.write(asBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public TypeIdx getByIdx(FuncIdx funcIdx) {
|
||||||
|
// return typeIdxVector.getElements().get((int)(funcIdx.getX()) - module.getImportSection().getTotalFuncImports());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public List<TypeIdx> getTypeIdxVector() {
|
||||||
|
// return typeIdxVector.getElements();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void setTypeIdxVector(List<TypeIdx> typeIdxVector) {
|
||||||
|
// this.typeIdxVector = new Vector<>(typeIdxVector);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package wasm.disassembly.modules.sections.global;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.instructions.Expression;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.types.GlobalType;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Global extends WASMOpCode {
|
||||||
|
|
||||||
|
private GlobalType globalType;
|
||||||
|
private Expression expression;
|
||||||
|
|
||||||
|
public Global(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
globalType = new GlobalType(in, module);
|
||||||
|
expression = new Expression(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Global(GlobalType globalType, Expression expression) {
|
||||||
|
this.globalType = globalType;
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
globalType.assemble(out);
|
||||||
|
expression.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalType getGlobalType() {
|
||||||
|
return globalType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGlobalType(GlobalType globalType) {
|
||||||
|
this.globalType = globalType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression getExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpression(Expression expression) {
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package wasm.disassembly.modules.sections.global;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GlobalSection extends Section {
|
||||||
|
|
||||||
|
public static final int GLOBAL_SECTION_ID = 6;
|
||||||
|
|
||||||
|
private Vector<Global> globals;
|
||||||
|
|
||||||
|
|
||||||
|
public GlobalSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, GLOBAL_SECTION_ID);
|
||||||
|
globals = new Vector<>(in, Global::new, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalSection(Module module, List<Global> globals) {
|
||||||
|
super(module, GLOBAL_SECTION_ID);
|
||||||
|
this.globals = new Vector<>(globals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
globals.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Global> getGlobals() {
|
||||||
|
return globals.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGlobals(List<Global> globals) {
|
||||||
|
this.globals = new Vector<>(globals);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package wasm.disassembly.modules.sections.imprt;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WName;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Import extends WASMOpCode {
|
||||||
|
|
||||||
|
private String module;
|
||||||
|
private String name;
|
||||||
|
private ImportDesc importDescription;
|
||||||
|
|
||||||
|
public Import(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
this.module = WName.read(in);
|
||||||
|
name = WName.read(in);
|
||||||
|
importDescription = new ImportDesc(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Import(String module, String name, ImportDesc importDescription) {
|
||||||
|
this.module = module;
|
||||||
|
this.name = name;
|
||||||
|
this.importDescription = importDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
WName.write(module, out);
|
||||||
|
WName.write(name, out);
|
||||||
|
importDescription.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModule() {
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModule(String module) {
|
||||||
|
this.module = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportDesc getImportDescription() {
|
||||||
|
return importDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImportDescription(ImportDesc importDescription) {
|
||||||
|
this.importDescription = importDescription;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package wasm.disassembly.modules.sections.imprt;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.indices.TypeIdx;
|
||||||
|
import wasm.disassembly.types.GlobalType;
|
||||||
|
import wasm.disassembly.types.MemType;
|
||||||
|
import wasm.disassembly.types.TableType;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class ImportDesc extends WASMOpCode {
|
||||||
|
|
||||||
|
private WASMOpCode importValue;
|
||||||
|
private int importType;
|
||||||
|
|
||||||
|
public ImportDesc(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
importType = in.read();
|
||||||
|
if (importType < 0x00 || importType > 0x03) {
|
||||||
|
throw new InvalidOpCodeException("invalid importdesc type");
|
||||||
|
}
|
||||||
|
|
||||||
|
importValue = importType == 0x00 ? new TypeIdx(in, module) :
|
||||||
|
(importType == 0x01 ? new TableType(in, module) :
|
||||||
|
(importType == 0x02 ? new MemType(in, module) :
|
||||||
|
new GlobalType(in, module)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportDesc(WASMOpCode importValue, int importType) {
|
||||||
|
this.importValue = importValue;
|
||||||
|
this.importType = importType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportDesc(TypeIdx typeIdx) {
|
||||||
|
this(typeIdx, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportDesc(TableType tableType) {
|
||||||
|
this(tableType, 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportDesc(MemType memType) {
|
||||||
|
this(memType, 0x02);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportDesc(GlobalType globalType) {
|
||||||
|
this(globalType, 0x03);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(importType);
|
||||||
|
importValue.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WASMOpCode getImportValue() {
|
||||||
|
return importValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImportValue(WASMOpCode importValue) {
|
||||||
|
this.importValue = importValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getImportType() {
|
||||||
|
return importType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImportType(int importType) {
|
||||||
|
this.importType = importType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
package wasm.disassembly.modules.sections.imprt;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.types.FuncType;
|
||||||
|
import wasm.disassembly.types.ResultType;
|
||||||
|
import wasm.misc.StreamReplacement;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImportSection extends Section {
|
||||||
|
|
||||||
|
public static final int IMPORT_SECTION_ID = 2;
|
||||||
|
private Module module;
|
||||||
|
|
||||||
|
private int totalFuncImports;
|
||||||
|
|
||||||
|
private Vector<Import> imports;
|
||||||
|
|
||||||
|
|
||||||
|
public ImportSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, IMPORT_SECTION_ID);
|
||||||
|
this.module = module;
|
||||||
|
imports = new Vector<>(in, Import::new, module);
|
||||||
|
|
||||||
|
totalFuncImports = 0;
|
||||||
|
|
||||||
|
int first = -1;
|
||||||
|
for (int i = 0; i < imports.getElements().size(); i++) {
|
||||||
|
Import imprt = imports.getElements().get(i);
|
||||||
|
|
||||||
|
if (imprt.getImportDescription().getImportType() == 0) {
|
||||||
|
if (totalFuncImports == 0) {
|
||||||
|
first = i;
|
||||||
|
}
|
||||||
|
totalFuncImports++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Import> newImports = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (StreamReplacement streamReplacement : module.streamReplacements) {
|
||||||
|
newImports.add(new Import("env", streamReplacement.getImportName(), new ImportDesc(
|
||||||
|
module.getTypeSection().getTypeIdxForFuncType(new FuncType(
|
||||||
|
streamReplacement.getFuncType().getParameterType(),
|
||||||
|
streamReplacement.getReplacementType() == StreamReplacement.ReplacementType.HOOK ? new ResultType(Collections.emptyList()) :
|
||||||
|
streamReplacement.getFuncType().getResultType()
|
||||||
|
))
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Import> f = new ArrayList<>(imports.getElements().subList(0, first));
|
||||||
|
f.addAll(newImports);
|
||||||
|
f.addAll(imports.getElements().subList(first, imports.getElements().size()));
|
||||||
|
imports.setElements(f);
|
||||||
|
totalFuncImports += newImports.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportSection(Module module, List<Import> imports) {
|
||||||
|
super(module, IMPORT_SECTION_ID);
|
||||||
|
this.imports = new Vector<>(imports);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
imports.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Import> getImports() {
|
||||||
|
return imports.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImports(List<Import> imports) {
|
||||||
|
this.imports = new Vector<>(imports);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public List<FuncIdx> importFunctions(List<Import> functions) throws InvalidOpCodeException {
|
||||||
|
// for (Import imprt : functions) {
|
||||||
|
// if (imprt.getImportDescription().getImportType() != 0) {
|
||||||
|
// throw new InvalidOpCodeException("Tried to import non-function as function");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (FuncIdx funcIdx : module.getAllFuncIdxs()) {
|
||||||
|
// if (funcIdx.getX() >= totalFuncImports) {
|
||||||
|
// funcIdx.setX(funcIdx.getX() + functions.size());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// List<FuncIdx> newFuncIdxs = new ArrayList<>();
|
||||||
|
// for (long i = totalFuncImports; i < totalFuncImports + functions.size(); i++) {
|
||||||
|
// newFuncIdxs.add(new FuncIdx(i, module));
|
||||||
|
// }
|
||||||
|
// imports.getElements().addAll(functions);
|
||||||
|
// totalFuncImports += functions.size();
|
||||||
|
// return newFuncIdxs;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public FuncIdx importFunction(Import function) throws InvalidOpCodeException {
|
||||||
|
// return importFunctions(Collections.singletonList(function)).get(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public Import getByIdx(FuncIdx funcIdx) {
|
||||||
|
return imports.getElements().get((int)funcIdx.getX());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalFuncImports() {
|
||||||
|
return totalFuncImports;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package wasm.disassembly.modules.sections.memory;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.types.MemType;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Mem extends WASMOpCode {
|
||||||
|
|
||||||
|
private MemType memType;
|
||||||
|
|
||||||
|
public Mem(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
memType = new MemType(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mem(MemType memType) {
|
||||||
|
this.memType = memType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
memType.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public MemType getMemType() {
|
||||||
|
return memType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemType(MemType memType) {
|
||||||
|
this.memType = memType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package wasm.disassembly.modules.sections.memory;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MemorySection extends Section {
|
||||||
|
|
||||||
|
public static final int MEMORY_SECTION_ID = 5;
|
||||||
|
|
||||||
|
private Vector<Mem> memories;
|
||||||
|
|
||||||
|
|
||||||
|
public MemorySection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, MEMORY_SECTION_ID);
|
||||||
|
memories = new Vector<>(in, Mem::new, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemorySection(Module module, List<Mem> memories) {
|
||||||
|
super(module, MEMORY_SECTION_ID);
|
||||||
|
this.memories = new Vector<>(memories);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
memories.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Mem> getMemories() {
|
||||||
|
return memories.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemories(List<Mem> memories) {
|
||||||
|
this.memories = new Vector<>(memories);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package wasm.disassembly.modules.sections.start;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Start extends WASMOpCode {
|
||||||
|
|
||||||
|
private FuncIdx funcIdx;
|
||||||
|
|
||||||
|
public Start(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
funcIdx = new FuncIdx(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Start(FuncIdx funcIdx) {
|
||||||
|
this.funcIdx = funcIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
funcIdx.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FuncIdx getFuncIdx() {
|
||||||
|
return funcIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFuncIdx(FuncIdx funcIdx) {
|
||||||
|
this.funcIdx = funcIdx;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package wasm.disassembly.modules.sections.start;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class StartSection extends Section {
|
||||||
|
|
||||||
|
public static final int START_SECTION_ID = 8;
|
||||||
|
|
||||||
|
private Start start;
|
||||||
|
|
||||||
|
public StartSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, START_SECTION_ID);
|
||||||
|
start = new Start(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StartSection(Module module, Start start) {
|
||||||
|
super(module, START_SECTION_ID);
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
start.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Start getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStart(Start start) {
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package wasm.disassembly.modules.sections.table;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.types.TableType;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Table extends WASMOpCode {
|
||||||
|
|
||||||
|
private TableType tableType;
|
||||||
|
|
||||||
|
public Table(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
tableType = new TableType(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Table(TableType tableType) {
|
||||||
|
this.tableType = tableType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
tableType.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableType getTableType() {
|
||||||
|
return tableType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableType(TableType tableType) {
|
||||||
|
this.tableType = tableType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package wasm.disassembly.modules.sections.table;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TableSection extends Section {
|
||||||
|
|
||||||
|
public static final int TABLE_SECTION_ID = 4;
|
||||||
|
|
||||||
|
private Vector<Table> tables;
|
||||||
|
|
||||||
|
|
||||||
|
public TableSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, TABLE_SECTION_ID);
|
||||||
|
tables = new Vector<>(in, Table::new, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableSection(Module module, List<Table> tables) {
|
||||||
|
super(module, TABLE_SECTION_ID);
|
||||||
|
this.tables = new Vector<>(tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
tables.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Table> getTables() {
|
||||||
|
return tables.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTables(List<Table> tables) {
|
||||||
|
this.tables = new Vector<>(tables);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package wasm.disassembly.modules.sections.type;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.conventions.Vector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.indices.FuncIdx;
|
||||||
|
import wasm.disassembly.modules.indices.TypeIdx;
|
||||||
|
import wasm.disassembly.modules.sections.Section;
|
||||||
|
import wasm.disassembly.types.FuncType;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TypeSection extends Section {
|
||||||
|
|
||||||
|
public static final int TYPE_SECTION_ID = 1;
|
||||||
|
|
||||||
|
private Vector<FuncType> functionTypes;
|
||||||
|
|
||||||
|
|
||||||
|
public TypeSection(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
super(in, module, TYPE_SECTION_ID);
|
||||||
|
functionTypes = new Vector<>(in, FuncType::new, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSection(Module module, List<FuncType> functionTypes) {
|
||||||
|
super(module, TYPE_SECTION_ID);
|
||||||
|
this.functionTypes = new Vector<>(functionTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble2(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
functionTypes.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public FuncType getByFuncIdx(FuncIdx funcIdx) {
|
||||||
|
// return getByTypeIdx(module.getFunctionSection().getByIdx(funcIdx));
|
||||||
|
// }
|
||||||
|
|
||||||
|
public List<FuncType> getFunctionTypes() {
|
||||||
|
return functionTypes.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FuncType getByTypeIdx(TypeIdx typeIdx) {
|
||||||
|
return functionTypes.getElements().get((int)(typeIdx.getX()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFunctionTypes(List<FuncType> functionTypes) {
|
||||||
|
this.functionTypes = new Vector<>(functionTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeIdx getTypeIdxForFuncType(FuncType newFuncType) {
|
||||||
|
for (int i = 0; i < getFunctionTypes().size(); i++) {
|
||||||
|
FuncType funcType = getFunctionTypes().get(i);
|
||||||
|
if (funcType.equals(newFuncType)) {
|
||||||
|
return new TypeIdx(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFunctionTypes().add(newFuncType);
|
||||||
|
return new TypeIdx(getFunctionTypes().size() - 1);
|
||||||
|
}
|
||||||
|
}
|
26
G-Wasm/src/main/java/wasm/disassembly/types/ElemType.java
Normal file
26
G-Wasm/src/main/java/wasm/disassembly/types/ElemType.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum ElemType {
|
||||||
|
FUNCREF(0x70);
|
||||||
|
|
||||||
|
|
||||||
|
public int val;
|
||||||
|
ElemType(int val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, ElemType> map = new HashMap<>();
|
||||||
|
static {
|
||||||
|
for (ElemType valType : ElemType.values()) {
|
||||||
|
map.put(valType.val, valType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ElemType from_val(int val) {
|
||||||
|
return map.get(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
G-Wasm/src/main/java/wasm/disassembly/types/FuncType.java
Normal file
68
G-Wasm/src/main/java/wasm/disassembly/types/FuncType.java
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.modules.sections.code.Func;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class FuncType extends WASMOpCode {
|
||||||
|
|
||||||
|
private ResultType parameterType;
|
||||||
|
private ResultType resultType;
|
||||||
|
|
||||||
|
public FuncType(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
if (in.read() != 0x60) throw new InvalidOpCodeException("Function types must be encoded with 0x60");
|
||||||
|
|
||||||
|
parameterType = new ResultType(in, module);
|
||||||
|
resultType = new ResultType(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FuncType(ResultType parameterType, ResultType resultType) {
|
||||||
|
this.parameterType = parameterType;
|
||||||
|
this.resultType = resultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(0x60);
|
||||||
|
parameterType.assemble(out);
|
||||||
|
resultType.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultType getParameterType() {
|
||||||
|
return parameterType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParameterType(ResultType parameterType) {
|
||||||
|
this.parameterType = parameterType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultType getResultType() {
|
||||||
|
return resultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultType(ResultType resultType) {
|
||||||
|
this.resultType = resultType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof FuncType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FuncType other = (FuncType) obj;
|
||||||
|
|
||||||
|
return parameterType.equals(other.parameterType) &&
|
||||||
|
resultType.equals(other.resultType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return parameterType + " -> " + resultType;
|
||||||
|
}
|
||||||
|
}
|
47
G-Wasm/src/main/java/wasm/disassembly/types/GlobalType.java
Normal file
47
G-Wasm/src/main/java/wasm/disassembly/types/GlobalType.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class GlobalType extends WASMOpCode {
|
||||||
|
|
||||||
|
private ValType valType;
|
||||||
|
private Mutability mutability;
|
||||||
|
|
||||||
|
public GlobalType(BufferedInputStream in, Module module) throws IOException {
|
||||||
|
valType = ValType.from_val(in.read());
|
||||||
|
mutability = Mutability.from_val(in.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalType(ValType valType, Mutability mutability) {
|
||||||
|
this.valType = valType;
|
||||||
|
this.mutability = mutability;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(valType.val);
|
||||||
|
out.write(mutability.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValType getValType() {
|
||||||
|
return valType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValType(ValType valType) {
|
||||||
|
this.valType = valType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mutability getMutability() {
|
||||||
|
return mutability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMutability(Mutability mutability) {
|
||||||
|
this.mutability = mutability;
|
||||||
|
}
|
||||||
|
}
|
62
G-Wasm/src/main/java/wasm/disassembly/types/Limits.java
Normal file
62
G-Wasm/src/main/java/wasm/disassembly/types/Limits.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
import wasm.disassembly.values.WUnsignedInt;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Limits extends WASMOpCode {
|
||||||
|
|
||||||
|
private long min;
|
||||||
|
private long max;
|
||||||
|
|
||||||
|
public Limits(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
int flag = in.read();
|
||||||
|
if (flag == 0x00) {
|
||||||
|
min = WUnsignedInt.read(in, 32);
|
||||||
|
max = -1;
|
||||||
|
}
|
||||||
|
else if (flag == 0x01) {
|
||||||
|
min = WUnsignedInt.read(in, 32);
|
||||||
|
max = WUnsignedInt.read(in, 32);
|
||||||
|
}
|
||||||
|
else throw new InvalidOpCodeException("Function types must be encoded with 0x00 or 0x01");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Limits(long min, long max) {
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(max == -1 ? 0x00 : 0x01);
|
||||||
|
WUnsignedInt.write(min, out, 32);
|
||||||
|
if (max != -1) {
|
||||||
|
WUnsignedInt.write(max, out, 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMin() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMax() {
|
||||||
|
return max != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMin(long min) {
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMax(long max) {
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
}
|
34
G-Wasm/src/main/java/wasm/disassembly/types/MemType.java
Normal file
34
G-Wasm/src/main/java/wasm/disassembly/types/MemType.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class MemType extends WASMOpCode {
|
||||||
|
|
||||||
|
private Limits limits;
|
||||||
|
|
||||||
|
public MemType(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
limits = new Limits(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemType(Limits limits) {
|
||||||
|
this.limits = limits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
limits.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Limits getLimits() {
|
||||||
|
return limits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimits(Limits limits) {
|
||||||
|
this.limits = limits;
|
||||||
|
}
|
||||||
|
}
|
26
G-Wasm/src/main/java/wasm/disassembly/types/Mutability.java
Normal file
26
G-Wasm/src/main/java/wasm/disassembly/types/Mutability.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum Mutability {
|
||||||
|
CONST(0x00),
|
||||||
|
VAR(0x01);
|
||||||
|
|
||||||
|
public int val;
|
||||||
|
Mutability(int val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, Mutability> map = new HashMap<>();
|
||||||
|
static {
|
||||||
|
for (Mutability valType : Mutability.values()) {
|
||||||
|
map.put(valType.val, valType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mutability from_val(int val) {
|
||||||
|
return map.get(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
70
G-Wasm/src/main/java/wasm/disassembly/types/ResultType.java
Normal file
70
G-Wasm/src/main/java/wasm/disassembly/types/ResultType.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.conventions.CustomVector;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ResultType extends WASMOpCode {
|
||||||
|
|
||||||
|
private CustomVector<ValType> vector;
|
||||||
|
|
||||||
|
public ResultType(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
vector = new CustomVector<>(
|
||||||
|
in,
|
||||||
|
(in1, m) -> ValType.from_val(in1.read()),
|
||||||
|
(valType, out) -> out.write(valType.val),
|
||||||
|
module
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultType(List<ValType> valTypes) {
|
||||||
|
vector = new CustomVector<>(
|
||||||
|
valTypes,
|
||||||
|
(valType, out) -> out.write(valType.val)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultType(CustomVector<ValType> vector) {
|
||||||
|
this.vector = vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
vector.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ValType> typeList() {
|
||||||
|
return vector.getElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomVector<ValType> getVector() {
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVector(CustomVector<ValType> vector) {
|
||||||
|
this.vector = vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof ResultType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType other = (ResultType) obj;
|
||||||
|
return vector.getElements().equals(other.vector.getElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "(" + vector.getElements().stream().map(Enum::name).collect(Collectors.joining(" ")) + ")";
|
||||||
|
}
|
||||||
|
}
|
50
G-Wasm/src/main/java/wasm/disassembly/types/TableType.java
Normal file
50
G-Wasm/src/main/java/wasm/disassembly/types/TableType.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
import wasm.disassembly.modules.Module;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class TableType extends WASMOpCode {
|
||||||
|
|
||||||
|
private ElemType elemType;
|
||||||
|
private Limits limits;
|
||||||
|
|
||||||
|
public TableType(BufferedInputStream in, Module module) throws IOException, InvalidOpCodeException {
|
||||||
|
elemType = ElemType.from_val(in.read());
|
||||||
|
if (elemType == null) {
|
||||||
|
throw new InvalidOpCodeException("No such element type");
|
||||||
|
}
|
||||||
|
limits = new Limits(in, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TableType(ElemType elemType, Limits limits) {
|
||||||
|
this.elemType = elemType;
|
||||||
|
this.limits = limits;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void assemble(OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
out.write(elemType.val);
|
||||||
|
limits.assemble(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ElemType getElemType() {
|
||||||
|
return elemType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElemType(ElemType elemType) {
|
||||||
|
this.elemType = elemType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Limits getLimits() {
|
||||||
|
return limits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimits(Limits limits) {
|
||||||
|
this.limits = limits;
|
||||||
|
}
|
||||||
|
}
|
29
G-Wasm/src/main/java/wasm/disassembly/types/ValType.java
Normal file
29
G-Wasm/src/main/java/wasm/disassembly/types/ValType.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package wasm.disassembly.types;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum ValType {
|
||||||
|
I32(0x7f),
|
||||||
|
I64(0x7e),
|
||||||
|
F32(0x7d),
|
||||||
|
F64(0x7c);
|
||||||
|
|
||||||
|
|
||||||
|
public int val;
|
||||||
|
ValType(int val) {
|
||||||
|
this.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, ValType> map = new HashMap<>();
|
||||||
|
static {
|
||||||
|
for (ValType valType : ValType.values()) {
|
||||||
|
map.put(valType.val, valType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ValType from_val(int val) {
|
||||||
|
return map.get(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
G-Wasm/src/main/java/wasm/disassembly/values/WDouble.java
Normal file
22
G-Wasm/src/main/java/wasm/disassembly/values/WDouble.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package wasm.disassembly.values;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class WDouble {
|
||||||
|
|
||||||
|
public static double read(BufferedInputStream in) throws IOException {
|
||||||
|
byte[] bytes = new byte[8];
|
||||||
|
in.read(bytes);
|
||||||
|
return ByteBuffer.wrap(bytes).getDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(double value, OutputStream out) throws IOException {
|
||||||
|
byte[] bytes = new byte[8];
|
||||||
|
ByteBuffer.wrap(bytes).putDouble(value);
|
||||||
|
out.write(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
G-Wasm/src/main/java/wasm/disassembly/values/WFloat.java
Normal file
22
G-Wasm/src/main/java/wasm/disassembly/values/WFloat.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package wasm.disassembly.values;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class WFloat {
|
||||||
|
|
||||||
|
public static float read(BufferedInputStream in) throws IOException {
|
||||||
|
byte[] bytes = new byte[4];
|
||||||
|
in.read(bytes);
|
||||||
|
return ByteBuffer.wrap(bytes).getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(float value, OutputStream out) throws IOException {
|
||||||
|
byte[] bytes = new byte[4];
|
||||||
|
ByteBuffer.wrap(bytes).putFloat(value);
|
||||||
|
out.write(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
G-Wasm/src/main/java/wasm/disassembly/values/WName.java
Normal file
25
G-Wasm/src/main/java/wasm/disassembly/values/WName.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package wasm.disassembly.values;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
import wasm.disassembly.WASMOpCode;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class WName {
|
||||||
|
|
||||||
|
public static String read(BufferedInputStream in) throws IOException, InvalidOpCodeException {
|
||||||
|
long length = WUnsignedInt.read(in, 32);
|
||||||
|
byte[] arr = new byte[(int)length];
|
||||||
|
in.read(arr);
|
||||||
|
return new String(arr, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(String value, OutputStream out) throws IOException, InvalidOpCodeException {
|
||||||
|
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||||
|
WUnsignedInt.write(bytes.length, out, 32);
|
||||||
|
out.write(bytes);
|
||||||
|
}
|
||||||
|
}
|
59
G-Wasm/src/main/java/wasm/disassembly/values/WSignedInt.java
Normal file
59
G-Wasm/src/main/java/wasm/disassembly/values/WSignedInt.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package wasm.disassembly.values;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class WSignedInt {
|
||||||
|
|
||||||
|
|
||||||
|
// everything with N <= 32
|
||||||
|
public static int read(BufferedInputStream in, int N) throws InvalidOpCodeException, IOException {
|
||||||
|
if (N > 32) throw new InvalidOpCodeException("Invalid integer size");
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
int cur;
|
||||||
|
int count = 0;
|
||||||
|
int signBits = -1;
|
||||||
|
|
||||||
|
int limit = N/7 + (N%7 != 0 ? 1 : 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
cur = (in.read()) & 0xff;
|
||||||
|
result |= (cur & 0x7f) << (count * 7);
|
||||||
|
signBits <<= 7;
|
||||||
|
count++;
|
||||||
|
} while (((cur & 0x80) == 0x80) && count < limit);
|
||||||
|
|
||||||
|
if ((cur & 0x80) == 0x80) {
|
||||||
|
throw new InvalidOpCodeException("invalid LEB128 sequence");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign extend if appropriate
|
||||||
|
if (((signBits >> 1) & result) != 0 ) {
|
||||||
|
result |= signBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(int value, OutputStream out, int N) throws InvalidOpCodeException, IOException {
|
||||||
|
if (N > 32) throw new InvalidOpCodeException("Invalid integer size");
|
||||||
|
|
||||||
|
int remaining = value >> 7;
|
||||||
|
boolean hasMore = true;
|
||||||
|
int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
|
||||||
|
|
||||||
|
while (hasMore) {
|
||||||
|
hasMore = (remaining != end)
|
||||||
|
|| ((remaining & 1) != ((value >> 6) & 1));
|
||||||
|
|
||||||
|
out.write((byte)((value & 0x7f) | (hasMore ? 0x80 : 0)));
|
||||||
|
value = remaining;
|
||||||
|
remaining >>= 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package wasm.disassembly.values;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class WSignedLong {
|
||||||
|
|
||||||
|
// everything with N > 32 && N <= 64
|
||||||
|
public static long read(BufferedInputStream in, int N) throws InvalidOpCodeException, IOException {
|
||||||
|
long result = 0;
|
||||||
|
long cur;
|
||||||
|
int count = 0;
|
||||||
|
long signBits = -1;
|
||||||
|
|
||||||
|
long limit = N/7 + (N%7 != 0 ? 1 : 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
cur = (in.read()) & 0xff;
|
||||||
|
result |= (cur & 0x7f) << (count * 7);
|
||||||
|
signBits <<= 7;
|
||||||
|
count++;
|
||||||
|
} while (((cur & 0x80) == 0x80) && count < limit);
|
||||||
|
|
||||||
|
if ((cur & 0x80) == 0x80) {
|
||||||
|
throw new InvalidOpCodeException("invalid LEB128 sequence");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign extend if appropriate
|
||||||
|
if (((signBits >> 1) & result) != 0 ) {
|
||||||
|
result |= signBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(long value, OutputStream out, int N) throws InvalidOpCodeException, IOException {
|
||||||
|
long remaining = value >> 7;
|
||||||
|
boolean hasMore = true;
|
||||||
|
long end = ((value & Long.MIN_VALUE) == 0) ? 0 : -1;
|
||||||
|
|
||||||
|
while (hasMore) {
|
||||||
|
hasMore = (remaining != end)
|
||||||
|
|| ((remaining & 1) != ((value >> 6) & 1));
|
||||||
|
|
||||||
|
out.write((byte)((value & 0x7f) | (hasMore ? 0x80 : 0)));
|
||||||
|
value = remaining;
|
||||||
|
remaining >>= 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package wasm.disassembly.values;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class WUnsignedInt {
|
||||||
|
|
||||||
|
// everything with N <= 63
|
||||||
|
public static long read(BufferedInputStream in, int N) throws InvalidOpCodeException, IOException, IOException {
|
||||||
|
if (N >= 64) throw new InvalidOpCodeException("Invalid integer size");
|
||||||
|
|
||||||
|
long result = 0;
|
||||||
|
long cur;
|
||||||
|
int count = 0;
|
||||||
|
int limit = N/7 + (N%7 != 0 ? 1 : 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
cur = in.read() & 0xff;
|
||||||
|
result |= (cur & 0x7f) << (count * 7);
|
||||||
|
count++;
|
||||||
|
} while (((cur & 0x80) == 0x80) && count < limit);
|
||||||
|
|
||||||
|
if ((cur & 0x80) == 0x80) {
|
||||||
|
throw new InvalidOpCodeException("invalid LEB128 sequence");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(long value, OutputStream out, int N) throws InvalidOpCodeException, IOException {
|
||||||
|
if (N >= 64) throw new InvalidOpCodeException("Invalid integer size");
|
||||||
|
|
||||||
|
long remaining = value >>> 7;
|
||||||
|
|
||||||
|
while (remaining != 0) {
|
||||||
|
out.write((byte)((value & 0x7f) | 0x80));
|
||||||
|
value = remaining;
|
||||||
|
remaining >>>= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write((byte)(value & 0x7f));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package wasm.disassembly.values;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class WUnsignedLong {
|
||||||
|
|
||||||
|
// everything with N > 63
|
||||||
|
public static BigInteger read(BufferedInputStream in, int N) throws InvalidOpCodeException, IOException, IOException {
|
||||||
|
BigInteger result = BigInteger.ZERO;
|
||||||
|
long cur;
|
||||||
|
int count = 0;
|
||||||
|
int limit = N/7 + (N%7 != 0 ? 1 : 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
cur = in.read() & 0xff;
|
||||||
|
result = result.or(BigInteger.valueOf(cur & 0x7f).shiftLeft(count * 7));
|
||||||
|
count++;
|
||||||
|
} while (((cur & 0x80) == 0x80) && count < limit);
|
||||||
|
|
||||||
|
if ((cur & 0x80) == 0x80) {
|
||||||
|
throw new InvalidOpCodeException("invalid LEB128 sequence");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void write(BigInteger value, OutputStream out, int N) throws InvalidOpCodeException, IOException {
|
||||||
|
long remaining = value.shiftRight(7).longValueExact();
|
||||||
|
long l_value = -1;
|
||||||
|
boolean first = true;
|
||||||
|
|
||||||
|
while (remaining != 0) {
|
||||||
|
if (first) {
|
||||||
|
out.write((byte) ((value.longValue() & 0x7f) | 0x80));
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.write((byte) ((l_value & 0x7f) | 0x80));
|
||||||
|
}
|
||||||
|
l_value = remaining;
|
||||||
|
remaining >>>= 7;
|
||||||
|
}
|
||||||
|
if (first) {
|
||||||
|
out.write((byte) (value.longValue() & 0x7f));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out.write((byte) (l_value & 0x7f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user