Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ci/common.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ local common_json = import "../common.json";

wasm:: {
downloads+: {
WABT_DIR: {name: 'wabt', version: '1.0.36', platformspecific: true},
WABT_DIR: {name: 'wabt', version: '1.0.37', platformspecific: true},
},
environment+: {
WABT_DIR: '$WABT_DIR/bin',
Expand All @@ -325,7 +325,7 @@ local common_json = import "../common.json";

wasm_ol8:: {
downloads+: {
WABT_DIR: {name: 'wabt', version: '1.0.36-ol8', platformspecific: true},
WABT_DIR: {name: 'wabt', version: '1.0.37-ol8', platformspecific: true},
},
environment+: {
WABT_DIR: '$WABT_DIR/bin',
Expand Down
9 changes: 6 additions & 3 deletions wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

This changelog summarizes major changes to the WebAssembly engine implemented in GraalVM (GraalWasm).

## Version 25.1.0

* Implemented the [exception handling](https://github.com/WebAssembly/exception-handling) proposal. This feature can be enabled with the experimental option `wasm.Exceptions=true`.

## Version 25.0.0

* BREAKING: Changed Context.eval of _wasm_ sources to return a compiled, but not yet instantiated, module object instead of the module instance.
Expand All @@ -27,14 +31,13 @@ This changelog summarizes major changes to the WebAssembly engine implemented in
* Added an implementation of the [SIMD](https://github.com/WebAssembly/simd) proposal using the JDK's Vector API. This improves peak performance when running WebAssembly code which makes heavy use of the new instructions in the SIMD proposal. This new implementation is always used in native image. On the JVM, it is opt-in and requires setting `--add-modules=jdk.incubator.vector`. Use of the incubating Vector API will result in the following warning message being printed to stderr:
```
WARNING: Using incubator modules: jdk.incubator.vector
```

```

## Version 24.2.0

* Updated developer metadata of Maven artifacts.
* Deprecated the `--wasm.AsyncParsingBinarySize` and `--wasm.AsyncParsingStackSize` options. These options no longer have any effect and will be removed in a future release.
* Implemented the [Relaxed SIMD](https://github.com/WebAssembly/relaxed-simd) proposal. This feature can be enabled with the options `--wasm.RelaxedSIMD`.
* Implemented the [Relaxed SIMD](https://github.com/WebAssembly/relaxed-simd) proposal. This feature can be enabled with the option `--wasm.RelaxedSIMD`.

## Version 24.1.0

Expand Down
2 changes: 1 addition & 1 deletion wasm/docs/contributor/TestsAndBenchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Building GraalWasm using the `mx build` command will also create the `wasm-tests.jar`, which contains the main test cases.
To run these tests, the WebAssembly binary toolkit is needed.

1. Download the binary of the [WebAssembly binary toolkit(wabt)](https://github.com/WebAssembly/wabt) and extract it.
1. Download the binary of the [WebAssembly binary toolkit(wabt)](https://github.com/WebAssembly/wabt) (**1.0.37** or higher) and extract it.

2. Set `WABT_DIR`:
```bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,29 @@ private byte[] generateGlobalSection() {
}
}

private static final class BinaryTags {
private final ByteArrayList attributes = new ByteArrayList();
private final ByteArrayList typeIndices = new ByteArrayList();

private void add(byte attribute, byte typeIndex) {
attributes.add(attribute);
typeIndices.add(typeIndex);
}

private byte[] generateTagSection() {
ByteArrayList b = new ByteArrayList();
b.add(getByte("0d"));
b.add((byte) 0); // length is patched at the end
b.add((byte) attributes.size());
for (int i = 0; i < attributes.size(); i++) {
b.add(attributes.get(i));
b.add(typeIndices.get(i));
}
b.set(1, (byte) (b.size() - 2));
return b.toArray();
}
}

private static final class BinaryCustomSections {
private final List<byte[]> names = new ArrayList<>();
private final List<byte[]> sections = new ArrayList<>();
Expand Down Expand Up @@ -373,6 +396,7 @@ protected static class BinaryBuilder {
private final BinaryElements binaryElements = new BinaryElements();
private final BinaryDatas binaryDatas = new BinaryDatas();
private final BinaryGlobals binaryGlobals = new BinaryGlobals();
private final BinaryTags binaryTags = new BinaryTags();

private final BinaryCustomSections binaryCustomSections = new BinaryCustomSections();

Expand Down Expand Up @@ -416,6 +440,11 @@ public BinaryBuilder addGlobal(byte mutability, byte valueType, String hexCode)
return this;
}

public BinaryBuilder addTag(byte attribute, byte typeIndex) {
binaryTags.add(attribute, typeIndex);
return this;
}

public BinaryBuilder addCustomSection(String name, byte[] section) {
binaryCustomSections.add(name, section);
return this;
Expand Down Expand Up @@ -443,8 +472,9 @@ public byte[] build() {
final byte[] codeSection = binaryFunctions.generateCodeSection();
final byte[] dataSection = binaryDatas.generateDataSection();
final byte[] customSections = binaryCustomSections.generateCustomSections();
final byte[] tagSection = binaryTags.generateTagSection();
final int totalLength = preamble.length + typeSection.length + functionSection.length + tableSection.length + memorySection.length + globalSection.length + exportSection.length +
elementSection.length + dataCountSection.length + codeSection.length + dataSection.length + customSections.length;
elementSection.length + dataCountSection.length + codeSection.length + dataSection.length + customSections.length + tagSection.length;
final byte[] binary = new byte[totalLength];
int length = 0;
System.arraycopy(preamble, 0, binary, length, preamble.length);
Expand All @@ -457,6 +487,8 @@ public byte[] build() {
length += tableSection.length;
System.arraycopy(memorySection, 0, binary, length, memorySection.length);
length += memorySection.length;
System.arraycopy(tagSection, 0, binary, length, tagSection.length);
length += tagSection.length;
System.arraycopy(globalSection, 0, binary, length, globalSection.length);
length += globalSection.length;
System.arraycopy(exportSection, 0, binary, length, exportSection.length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,13 +399,17 @@ private WasmTestStatus runTestCase(WasmCase testCase, Engine sharedEngine) {

EnumSet<WasmBinaryTools.WabtOption> options = EnumSet.noneOf(WasmBinaryTools.WabtOption.class);
String threadsOption = testCase.options().getProperty("wasm.Threads");
if (threadsOption != null && threadsOption.equals("true")) {
if ("true".equals(threadsOption)) {
options.add(WasmBinaryTools.WabtOption.THREADS);
}
String multiMemoryOption = testCase.options().getProperty("wasm.MultiMemory");
if (multiMemoryOption != null && multiMemoryOption.equals("true")) {
if ("true".equals(multiMemoryOption)) {
options.add(WasmBinaryTools.WabtOption.MULTI_MEMORY);
}
String exceptionsOption = testCase.options().getProperty("wasm.Exceptions");
if ("true".equals(exceptionsOption)) {
options.add(WasmBinaryTools.WabtOption.EXCEPTIONS);
}
ArrayList<Source> sources = testCase.getSources(options);

runInContexts(testCase, contextBuilder, sources, sharedEngine, testOut);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -854,11 +854,11 @@ public void testExportCountsLimit() throws IOException {
context.readModule(binaryWithMixedExports, limits);

final int noLimit = Integer.MAX_VALUE;
limits = new ModuleLimits(noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, 6, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit);
limits = new ModuleLimits(noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, 6, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit);
context.readModule(binaryWithMixedExports, limits);

try {
limits = new ModuleLimits(noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, 5, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit);
limits = new ModuleLimits(noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, 5, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit, noLimit);
context.readModule(binaryWithMixedExports, limits);
Assert.fail("Should have failed - export count exceeds the limit");
} catch (WasmException ex) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -50,6 +50,7 @@
import org.graalvm.wasm.test.suites.bytecode.MultiInstantiationSuite;
import org.graalvm.wasm.test.suites.control.BlockWithLocalsSuite;
import org.graalvm.wasm.test.suites.control.BranchBlockSuite;
import org.graalvm.wasm.test.suites.control.ExceptionSuite;
import org.graalvm.wasm.test.suites.control.IfThenElseSuite;
import org.graalvm.wasm.test.suites.control.LoopBlockSuite;
import org.graalvm.wasm.test.suites.control.MultiValueSuite;
Expand All @@ -62,9 +63,9 @@
import org.graalvm.wasm.test.suites.memory.MemorySuite;
import org.graalvm.wasm.test.suites.memory.MultiMemorySuite;
import org.graalvm.wasm.test.suites.memory.ThreadsSuite;
import org.graalvm.wasm.test.suites.validation.ReferenceTypesValidationSuite;
import org.graalvm.wasm.test.suites.table.TableSuite;
import org.graalvm.wasm.test.suites.validation.MultiValueValidationSuite;
import org.graalvm.wasm.test.suites.validation.ReferenceTypesValidationSuite;
import org.graalvm.wasm.test.suites.validation.ValidationSuite;
import org.graalvm.wasm.test.suites.wasi.WasiSuite;
import org.graalvm.wasm.test.suites.webassembly.EmscriptenSuite;
Expand Down Expand Up @@ -105,6 +106,7 @@
MultiInstantiationSuite.class,
MultiMemorySuite.class,
ThreadsSuite.class,
ExceptionSuite.class,
DebugValidationSuite.class,
DebugObjectFactorySuite.class
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

import org.graalvm.wasm.WasmType;
import org.graalvm.wasm.constants.Bytecode;
import org.graalvm.wasm.constants.ExceptionHandlerType;
import org.graalvm.wasm.constants.SegmentMode;
import org.graalvm.wasm.parser.bytecode.RuntimeBytecodeGen;
import org.junit.Assert;
Expand Down Expand Up @@ -168,7 +169,7 @@ public void testBrU8Max() {
expected[255] = (byte) 0xFF;
test(b -> {
for (int i = 0; i < 254; i++) {
b.add(0);
b.addOp(0);
}
b.addBranch(0);
}, expected);
Expand All @@ -194,7 +195,7 @@ public void testBrI32MinBackward() {
expected[259] = (byte) 0xFF;
test(b -> {
for (int i = 0; i < 255; i++) {
b.add(0);
b.addOp(0);
}
b.addBranch(0);
}, expected);
Expand All @@ -212,7 +213,7 @@ public void testBrIfU8Max() {
expected[255] = (byte) 0xFF;
test(b -> {
for (int i = 0; i < 254; i++) {
b.add(0);
b.addOp(0);
}
b.addBranchIf(0);
}, expected);
Expand All @@ -238,7 +239,7 @@ public void testBrIfI32MinBackward() {
expected[259] = (byte) 0xFF;
test(b -> {
for (int i = 0; i < 255; i++) {
b.add(0);
b.addOp(0);
}
b.addBranchIf(0);
}, expected);
Expand Down Expand Up @@ -448,52 +449,52 @@ public void testMemoryInstructionInvalidOpcodeI32() {

@Test
public void testAddMin() {
test(b -> b.add(0x00), new byte[]{0x00});
test(b -> b.addOp(0x00), new byte[]{0x00});
}

@Test
public void testAddMax() {
test(b -> b.add(0xFF), new byte[]{(byte) 0xFF});
test(b -> b.addOp(0xFF), new byte[]{(byte) 0xFF});
}

@Test
public void testInvalidAdd() {
testAssertion(b -> b.add(256), "opcode does not fit into byte");
testAssertion(b -> b.addOp(256), "opcode does not fit into byte");
}

@Test
public void testAddImmediateMin() {
test(b -> b.add(0x01, 0), new byte[]{0x01, 0x00, 0x00, 0x00, 0x00});
test(b -> b.addOp(0x01, 0), new byte[]{0x01, 0x00, 0x00, 0x00, 0x00});
}

@Test
public void testAddImmediateMax() {
test(b -> b.add(0x01, 0xFFFFFFFF), new byte[]{0x01, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
test(b -> b.addOp(0x01, 0xFFFFFFFF), new byte[]{0x01, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
}

@Test
public void testInvalidAddImmediate() {
testAssertion(b -> b.add(256, 0), "opcode does not fit into byte");
testAssertion(b -> b.addOp(256, 0), "opcode does not fit into byte");
}

@Test
public void testAddImmediate64Max() {
test(b -> b.add(0x01, 0xFFFFFFFFFFFFFFFFL), new byte[]{0x01, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
test(b -> b.addOp(0x01, 0xFFFFFFFFFFFFFFFFL), new byte[]{0x01, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
}

@Test
public void testInvalidAddImmediate64() {
testAssertion(b -> b.add(256, 0xFFL), "opcode does not fit into byte");
testAssertion(b -> b.addOp(256, 0xFFL), "opcode does not fit into byte");
}

@Test
public void testAddImmediateMax2() {
test(b -> b.add(0x01, 0, 0xFFFFFFFF), new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
test(b -> b.addOp(0x01, 0, 0xFFFFFFFF), new byte[]{0x01, 0x00, 0x00, 0x00, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
}

@Test
public void testInvalidAddImmediate2() {
testAssertion(b -> b.add(256, 0, 0), "opcode does not fit into byte");
testAssertion(b -> b.addOp(256, 0, 0), "opcode does not fit into byte");
}

@Test
Expand Down Expand Up @@ -686,6 +687,11 @@ public void testElemHeaderExternref() {
test(b -> b.addElemHeader(SegmentMode.ACTIVE, 8, WasmType.EXTERNREF_TYPE, 0, null, -1), new byte[]{0x40, 0x20, 0x08});
}

@Test
public void testElemHeaderExnref() {
test(b -> b.addElemHeader(SegmentMode.ACTIVE, 8, WasmType.EXNREF_TYPE, 0, null, -1), new byte[]{0x40, 0x30, 0x08});
}

@Test
public void testElemHeaderMinU8TableIndex() {
test(b -> b.addElemHeader(SegmentMode.ACTIVE, 0, WasmType.FUNCREF_TYPE, 1, null, -1), new byte[]{0x50, 0x10, 0x00, 0x01});
Expand Down Expand Up @@ -915,4 +921,15 @@ public void testCodeEntryLocals() {
public void testCodeEntryResults() {
test(b -> b.addCodeEntry(0, 0, 0, 0, 1), new byte[]{0x05, 0x00});
}

@Test
public void testCatchExceptionHandler() {
test(b -> b.addExceptionHandler(5, 10, ExceptionHandlerType.CATCH, 0, 10), new byte[]{0x05, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00});
}

@Test
public void testCatchRefExceptionHandler() {
test(b -> b.addExceptionHandler(0, 12, ExceptionHandlerType.CATCH_REF, 1, 256),
new byte[]{0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00});
}
}
Loading