Skip to content

Commit

Permalink
add wasm.Module Builders to conveniently run the parser
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaTP committed Jul 26, 2024
1 parent 3405d0a commit ef2ea6f
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.dylibso.chicory.runtime.HostImports;
import com.dylibso.chicory.runtime.Instance;
import com.dylibso.chicory.runtime.Module;
import com.dylibso.chicory.runtime.ModuleType;
import com.dylibso.chicory.wabt.Wat2Wasm;
import com.dylibso.chicory.wasm.ModuleType;
import com.dylibso.chicory.wasm.exceptions.MalformedException;
import java.io.File;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.dylibso.chicory.runtime.HostImports;
import com.dylibso.chicory.runtime.Instance;
import com.dylibso.chicory.runtime.Module;
import com.dylibso.chicory.runtime.ModuleType;
import com.dylibso.chicory.wabt.Wat2Wasm;
import com.dylibso.chicory.wasm.ModuleType;
import com.dylibso.chicory.wasm.exceptions.MalformedException;
import java.io.File;

Expand Down
3 changes: 3 additions & 0 deletions runtime/src/main/java/com/dylibso/chicory/runtime/Module.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.dylibso.chicory.runtime;

import static com.dylibso.chicory.wasm.ModuleType.BINARY;

import com.dylibso.chicory.log.Logger;
import com.dylibso.chicory.log.SystemLogger;
import com.dylibso.chicory.runtime.exceptions.WASMRuntimeException;
import com.dylibso.chicory.wasm.ModuleType;
import com.dylibso.chicory.wasm.Parser;
import com.dylibso.chicory.wasm.exceptions.InvalidException;
import com.dylibso.chicory.wasm.exceptions.MalformedException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ public CompilationUnit generate(
cu.addImport("com.dylibso.chicory.testing.TestModule");

// runtime imports
cu.addImport("com.dylibso.chicory.wasm.ModuleType");
cu.addImport("com.dylibso.chicory.wasm.exceptions.ChicoryException");
cu.addImport("com.dylibso.chicory.runtime.ExportFunction");
cu.addImport("com.dylibso.chicory.runtime.Instance");
cu.addImport("com.dylibso.chicory.runtime.Module");
cu.addImport("com.dylibso.chicory.runtime.ModuleType");

// base imports
cu.addImport("com.dylibso.chicory.wasm.exceptions.InvalidException");
Expand Down
9 changes: 4 additions & 5 deletions wabt/src/main/java/com/dylibso/chicory/wabt/Wast2Json.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ public boolean isLoggable(Logger.Level level) {
}
};
private static final com.dylibso.chicory.wasm.Module wasmModule =
Module.builder(Wast2Json.class.getResourceAsStream("/wast2json"))
.withInitialize(false)
.withStart(false)
.build()
.wasmModule();
com.dylibso.chicory.wasm.Module.builder(
Wast2Json.class.getResourceAsStream("/wast2json"))
.withLogger(logger)
.build();

private final File input;
private final File output;
Expand Down
8 changes: 3 additions & 5 deletions wabt/src/main/java/com/dylibso/chicory/wabt/Wat2Wasm.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@
public final class Wat2Wasm {
private static final Logger logger = new SystemLogger();
private static final com.dylibso.chicory.wasm.Module wasmModule =
Module.builder(Wat2Wasm.class.getResourceAsStream("/wat2wasm"))
.withInitialize(false)
.withStart(false)
.build()
.wasmModule();
com.dylibso.chicory.wasm.Module.builder(Wat2Wasm.class.getResourceAsStream("/wat2wasm"))
.withLogger(logger)
.build();

private Wat2Wasm() {}

Expand Down
161 changes: 161 additions & 0 deletions wasm/src/main/java/com/dylibso/chicory/wasm/Module.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import static java.util.Objects.requireNonNull;

import com.dylibso.chicory.log.Logger;
import com.dylibso.chicory.log.SystemLogger;
import com.dylibso.chicory.wasm.exceptions.ChicoryException;
import com.dylibso.chicory.wasm.exceptions.InvalidException;
import com.dylibso.chicory.wasm.types.CodeSection;
import com.dylibso.chicory.wasm.types.CustomSection;
import com.dylibso.chicory.wasm.types.DataCountSection;
Expand All @@ -16,9 +20,20 @@
import com.dylibso.chicory.wasm.types.StartSection;
import com.dylibso.chicory.wasm.types.TableSection;
import com.dylibso.chicory.wasm.types.TypeSection;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;

public class Module {
private final HashMap<String, CustomSection> customSections;
Expand Down Expand Up @@ -151,4 +166,150 @@ public ElementSection elementSection() {
public void setElementSection(ElementSection elementSection) {
this.elementSection = requireNonNull(elementSection);
}

/**
* Creates a {@link Builder} for the specified {@link InputStream}
*
* @param input the input stream
* @return a {@link Builder} for reading the module definition from the specified input stream
*/
public static Builder builder(InputStream input) {
return new Builder(() -> input);
}

/**
* Creates a {@link Builder} for the specified {@link com.dylibso.chicory.wasm.Module}
*
* @param wasmModule the already parsed Wasm module
* @return a {@link Builder} for reading the module definition from the specified input stream
*/
public static Builder builder(com.dylibso.chicory.wasm.Module wasmModule) {
return new Builder(wasmModule);
}

/**
* Creates a {@link Builder} for the specified {@link ByteBuffer}
*
* @param buffer the buffer
* @return a {@link Builder} for reading the module definition from the specified buffer
*/
public static Builder builder(ByteBuffer buffer) {
return builder(buffer.array());
}

/**
* Creates a {@link Builder} for the specified byte array
*
* @param buffer the buffer
* @return a {@link Builder} for reading the module definition from the specified buffer
*/
public static Builder builder(byte[] buffer) {
return new Builder(() -> new ByteArrayInputStream(buffer));
}

/**
* Creates a {@link Builder} for the specified {@link File} resource
*
* @param file the path of the resource
* @return a {@link Builder} for reading the module definition from the specified file
*/
public static Builder builder(File file) {
return new Builder(
() -> {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
throw new IllegalArgumentException(
"File not found at path: " + file.getPath(), e);
}
});
}

/**
* Creates a {@link Builder} for the specified classpath resource
*
* @param classpathResource the name of the resource
* @return a {@link Builder} for reading the module definition from the specified resource
*/
public static Builder builder(String classpathResource) {
return new Builder(
() -> {
InputStream is =
Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream(classpathResource);
if (is == null) {
throw new IllegalArgumentException(
"Resource not found at classpath: " + classpathResource);
}
return is;
});
}

/**
* Creates a {@link Builder} for the specified {@link Path} resource
*
* @param path the path of the resource
* @return a {@link Builder} for reading the module definition from the specified path
*/
public static Builder builder(Path path) {
return new Builder(
() -> {
try {
return Files.newInputStream(path);
} catch (IOException e) {
throw new IllegalArgumentException("Error opening file: " + path, e);
}
});
}

public static class Builder {
private final Module parsed;
private final Supplier<InputStream> inputStreamSupplier;
private Logger logger;
private ModuleType moduleType = ModuleType.BINARY;

private Builder(Supplier<InputStream> inputStreamSupplier) {
this.inputStreamSupplier = Objects.requireNonNull(inputStreamSupplier);
this.parsed = null;
}

private Builder(Module parsed) {
this.parsed = Objects.requireNonNull(parsed);
this.inputStreamSupplier = null;
}

public Builder withLogger(Logger logger) {
this.logger = logger;
return this;
}

public Builder withType(ModuleType type) {
this.moduleType = type;
return this;
}

public Module build() {
final Logger logger = this.logger != null ? this.logger : new SystemLogger();
final Parser parser = new Parser(logger);

Module parsed = this.parsed;
if (parsed == null) {
try (final InputStream is = inputStreamSupplier.get()) {
parsed = parser.parseModule(is);
} catch (IOException e) {
throw new ChicoryException(e);
}
}

switch (this.moduleType) {
case BINARY:
return parsed;
default:
throw new InvalidException(
"Text format parsing is not implemented, but you can use wat2wasm"
+ " through Chicory.");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.dylibso.chicory.runtime;
package com.dylibso.chicory.wasm;

public enum ModuleType {
TEXT,
Expand Down

0 comments on commit ef2ea6f

Please sign in to comment.