Skip to content

Commit

Permalink
Fix memory initialization for dynamically linked modules (#543)
Browse files Browse the repository at this point in the history
An imported memory should not be zeroed during initialization.
  • Loading branch information
andreaTP authored Sep 27, 2024
1 parent 5a28338 commit 5e27ede
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ public Instance initialize(boolean start) {
globals[i].setInstance(this);
}

if (memory != null) {
if (memory != null && imports.memories().length == 0) {
memory.zero();
memory.initialize(this, dataSegments);
} else if (imports.memories().length > 0) {
imports.memories()[0].memory().initialize(this, dataSegments);
Expand Down
2 changes: 0 additions & 2 deletions runtime/src/main/java/com/dylibso/chicory/runtime/Memory.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ public void initialize(Instance instance, DataSegment[] dataSegments) {
return;
}

this.zero();

for (var s : dataSegments) {
if (s instanceof ActiveDataSegment) {
var segment = (ActiveDataSegment) s;
Expand Down
78 changes: 78 additions & 0 deletions wasi/src/test/java/com/dylibso/chicory/wasi/WasiPreview1Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import com.dylibso.chicory.runtime.ExternalValues;
import com.dylibso.chicory.runtime.Instance;
import com.dylibso.chicory.runtime.Memory;
import com.dylibso.chicory.runtime.Store;
import com.dylibso.chicory.wasm.Module;
import com.dylibso.chicory.wasm.Parser;
import com.dylibso.chicory.wasm.types.MemoryLimits;
import com.dylibso.chicory.wasm.types.Value;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Random;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -80,6 +82,82 @@ public void shouldRunWasiDemoJavyModule() {
assertEquals(fakeStdout.output(), "{\"foo\":3,\"newBar\":\"baz!\"}");
}

@Test
public void shouldUseQuickJsProvider() {
ByteArrayInputStream stdin = new ByteArrayInputStream("".getBytes(UTF_8));
var stdout = new ByteArrayOutputStream();
var stderr = new ByteArrayOutputStream();

var wasiOpts =
WasiOptions.builder()
.withStdout(stdout)
.withStderr(stderr)
.withStdin(stdin)
.build();
var logger = new SystemLogger();

var wasi = new WasiPreview1(logger, wasiOpts);
var quickjs =
Instance.builder(loadModule("compiled/quickjs-provider.javy-dynamic.wasm"))
.withExternalValues(new ExternalValues(wasi.toHostFunctions()))
.build();

var greetingMsg = "Hello QuickJS!";

byte[] jsCode = ("console.log(\"" + greetingMsg + "\");").getBytes(UTF_8);
var ptr =
quickjs.export("canonical_abi_realloc")
.apply(
Value.i32(0), // original_ptr
Value.i32(0), // original_size
Value.i32(1), // alignment
Value.i32(jsCode.length) // new size
)[0];

quickjs.memory().write(ptr.asInt(), jsCode);
var aggregatedCodePtr =
quickjs.export("compile_src").apply(ptr, Value.i64(jsCode.length))[0];

var codePtr = quickjs.memory().readI32(aggregatedCodePtr.asInt()); // 32 bit
var codeLength = quickjs.memory().readU32(aggregatedCodePtr.asInt() + 4);

quickjs.export("eval_bytecode").apply(codePtr, codeLength);

// stderr?
assertEquals(greetingMsg + "\n", stderr.toString(UTF_8));
}

@Test
public void shouldUseDynamicallyLinkedJavyModules() {
ByteArrayInputStream stdin = new ByteArrayInputStream("".getBytes(UTF_8));
var stdout = new ByteArrayOutputStream();
var stderr = new ByteArrayOutputStream();

var wasiOpts =
WasiOptions.builder()
.withStdout(stdout)
.withStderr(stderr)
.withStdin(stdin)
.build();
var logger = new SystemLogger();

var wasi = new WasiPreview1(logger, wasiOpts);
var quickjs =
Instance.builder(loadModule("compiled/quickjs-provider.javy-dynamic.wasm"))
.withExternalValues(new ExternalValues(wasi.toHostFunctions()))
.build();

var store = new Store();
store.register("javy_quickjs_provider_v1", quickjs);

Instance.builder(loadModule("compiled/hello-world.js.javy-dynamic.wasm"))
.withExternalValues(store.toExternalValues())
.build();

// stderr?
assertEquals("Hello world dynamic Javy!\n", stderr.toString(UTF_8));
}

@Test
public void shouldRunTinyGoModule() {
var wasiOpts = WasiOptions.builder().build();
Expand Down
11 changes: 10 additions & 1 deletion wasm-corpus/src/main/resources/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ compileJavy() {
(set -x; javy compile $1 -o "./compiled/$filename.javy.wasm")
}

compileJavyDynamic() {
filename=$(basename "$1")
(set -x; javy emit-provider -o "./compiled/quickjs-provider.javy-dynamic.wasm" && \
javy compile -d $1 -o "./compiled/$filename.javy-dynamic.wasm")
}

compileTinyGo() {
filename=$(basename "$1")
(set -x; tinygo build -o "./compiled/$filename.tiny.wasm" -target=wasi $1)
Expand Down Expand Up @@ -61,6 +67,9 @@ compile() {
javy)
compileJavy $2
;;
javy-dynamic)
compileJavyDynamic $2
;;
tinygo)
compileTinyGo $2
;;
Expand All @@ -81,7 +90,7 @@ lang="${1:-all}"
path="${2:-all}"

if [[ "$lang" == "all" ]]; then
langs=("wat" "rust" "c" "javy" "tinygo", "go", "dotnet")
langs=("wat" "rust" "c" "javy" "javy-dynamic" "tinygo", "go", "dotnet")
else
langs=("$lang")
fi
Expand Down
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions wasm-corpus/src/main/resources/javy-dynamic/hello-world.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log("Hello world dynamic Javy!");

0 comments on commit 5e27ede

Please sign in to comment.