Skip to content
Open
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
1 change: 1 addition & 0 deletions wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This changelog summarizes major changes to the WebAssembly engine implemented in

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

## Version 25.0.0

Expand Down
19 changes: 11 additions & 8 deletions wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,17 @@ The `floyd` function is defined as separate and can be later exported.
```java
try (Context context = Context.newBuilder("wasm").option("wasm.Builtins", "wasi_snapshot_preview1").build()) {
// Evaluate the WebAssembly module
Source source = Source.newBuilder("wasm", new File("path/to/floyd.wasm")).name("example").build();
context.eval(source);

// Initialize the module and execute the floyd function
Value exampleModule = context.getBindings("wasm").getMember("example");
exampleModule.getMember("_initialize").executeVoid();
Value floydFunction = exampleModule.getMember("floyd");
floydFunction.execute();
Source source = Source.newBuilder("wasm", new File("path/to/floyd.wasm")).build();
Value exampleModule = context.eval(source);

// Initialize the module
Value exampleInstance = exampleModule.newInstance();
Value exampleExports = exampleInstance.getMember("exports");
exampleExports.getMember("_initialize").executeVoid();

// Execute the floyd function
Value floyd = exampleExports.getMember("floyd");
floyd.execute();
}
```

Expand Down
4 changes: 4 additions & 0 deletions wasm/mx.wasm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@
"org.graalvm.collections",
"static jdk.incubator.vector", # Vector API
],
"exports" : [
# Export WasmStruct supertype to Truffle Static Object class generator
"org.graalvm.wasm.struct",
],
},
"subDir" : "src",
"dependencies" : [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* SOFTWARE.
*/

package org.graalvm.wasm.api;
package org.graalvm.wasm.vector;

import com.oracle.truffle.api.CompilerDirectives;
import jdk.incubator.vector.ByteVector;
Expand All @@ -58,7 +58,7 @@

import java.util.function.Function;

import static org.graalvm.wasm.api.Vector128.BYTES;
import static org.graalvm.wasm.vector.Vector128.BYTES;

/**
* This is a JDK25-specific implementation of the GraalWasm SIMD proposal. It uses the {@link Vector
Expand All @@ -72,7 +72,7 @@ final class Vector128OpsVectorAPI implements Vector128Ops<ByteVector> {
private static final Vector128Ops<byte[]> fallbackOps = Vector128OpsFallback.create();

static Vector128Ops<ByteVector> create() {
return new Vector128OpsVectorAPI();
return new org.graalvm.wasm.vector.Vector128OpsVectorAPI();
}

private abstract static class Shape<E> {
Expand Down Expand Up @@ -350,21 +350,21 @@ public ByteVector unary(ByteVector xVec, int vectorOpcode) {
case Bytecode.VECTOR_F32X4_NEG -> unop(x, F32X4, VectorOperators.NEG);
case Bytecode.VECTOR_F32X4_SQRT -> unop(x, F32X4, VectorOperators.SQRT);
case Bytecode.VECTOR_F32X4_CEIL -> ceil(x, F32X4, I32X4, VectorOperators.REINTERPRET_F2I, VectorOperators.REINTERPRET_I2F,
Vector128OpsVectorAPI::getExponentFloats, FLOAT_SIGNIFICAND_WIDTH, I32X4.broadcast(FLOAT_SIGNIF_BIT_MASK));
org.graalvm.wasm.vector.Vector128OpsVectorAPI::getExponentFloats, FLOAT_SIGNIFICAND_WIDTH, I32X4.broadcast(FLOAT_SIGNIF_BIT_MASK));
case Bytecode.VECTOR_F32X4_FLOOR -> floor(x, F32X4, I32X4, VectorOperators.REINTERPRET_F2I, VectorOperators.REINTERPRET_I2F,
Vector128OpsVectorAPI::getExponentFloats, FLOAT_SIGNIFICAND_WIDTH, I32X4.broadcast(FLOAT_SIGNIF_BIT_MASK));
org.graalvm.wasm.vector.Vector128OpsVectorAPI::getExponentFloats, FLOAT_SIGNIFICAND_WIDTH, I32X4.broadcast(FLOAT_SIGNIF_BIT_MASK));
case Bytecode.VECTOR_F32X4_TRUNC -> trunc(x, F32X4, I32X4, VectorOperators.REINTERPRET_F2I, VectorOperators.REINTERPRET_I2F,
Vector128OpsVectorAPI::getExponentFloats, FLOAT_SIGNIFICAND_WIDTH, I32X4.broadcast(FLOAT_SIGNIF_BIT_MASK));
org.graalvm.wasm.vector.Vector128OpsVectorAPI::getExponentFloats, FLOAT_SIGNIFICAND_WIDTH, I32X4.broadcast(FLOAT_SIGNIF_BIT_MASK));
case Bytecode.VECTOR_F32X4_NEAREST -> nearest(x, F32X4, 1 << (FLOAT_SIGNIFICAND_WIDTH - 1));
case Bytecode.VECTOR_F64X2_ABS -> unop(x, F64X2, VectorOperators.ABS);
case Bytecode.VECTOR_F64X2_NEG -> unop(x, F64X2, VectorOperators.NEG);
case Bytecode.VECTOR_F64X2_SQRT -> unop(x, F64X2, VectorOperators.SQRT);
case Bytecode.VECTOR_F64X2_CEIL -> ceil(x, F64X2, I64X2, VectorOperators.REINTERPRET_D2L, VectorOperators.REINTERPRET_L2D,
Vector128OpsVectorAPI::getExponentDoubles, DOUBLE_SIGNIFICAND_WIDTH, I64X2.broadcast(DOUBLE_SIGNIF_BIT_MASK));
org.graalvm.wasm.vector.Vector128OpsVectorAPI::getExponentDoubles, DOUBLE_SIGNIFICAND_WIDTH, I64X2.broadcast(DOUBLE_SIGNIF_BIT_MASK));
case Bytecode.VECTOR_F64X2_FLOOR -> floor(x, F64X2, I64X2, VectorOperators.REINTERPRET_D2L, VectorOperators.REINTERPRET_L2D,
Vector128OpsVectorAPI::getExponentDoubles, DOUBLE_SIGNIFICAND_WIDTH, I64X2.broadcast(DOUBLE_SIGNIF_BIT_MASK));
org.graalvm.wasm.vector.Vector128OpsVectorAPI::getExponentDoubles, DOUBLE_SIGNIFICAND_WIDTH, I64X2.broadcast(DOUBLE_SIGNIF_BIT_MASK));
case Bytecode.VECTOR_F64X2_TRUNC -> trunc(x, F64X2, I64X2, VectorOperators.REINTERPRET_D2L, VectorOperators.REINTERPRET_L2D,
Vector128OpsVectorAPI::getExponentDoubles, DOUBLE_SIGNIFICAND_WIDTH, I64X2.broadcast(DOUBLE_SIGNIF_BIT_MASK));
org.graalvm.wasm.vector.Vector128OpsVectorAPI::getExponentDoubles, DOUBLE_SIGNIFICAND_WIDTH, I64X2.broadcast(DOUBLE_SIGNIF_BIT_MASK));
case Bytecode.VECTOR_F64X2_NEAREST -> nearest(x, F64X2, 1L << (DOUBLE_SIGNIFICAND_WIDTH - 1));
case Bytecode.VECTOR_I32X4_TRUNC_SAT_F32X4_S, Bytecode.VECTOR_I32X4_RELAXED_TRUNC_F32X4_S -> fromArray(fallbackOps.unary(x.toArray(), vectorOpcode)); // GR-51421
case Bytecode.VECTOR_I32X4_TRUNC_SAT_F32X4_U, Bytecode.VECTOR_I32X4_RELAXED_TRUNC_F32X4_U -> fromArray(fallbackOps.unary(x.toArray(), vectorOpcode)); // GR-51421
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public class WasmJsApiSuite {

private static WasmFunctionInstance createWasmFunctionInstance(WasmContext context, int[] paramTypes, int[] resultTypes, RootNode functionRootNode) {
WasmModule module = WasmModule.createBuiltin("dummyModule");
module.allocateFunctionType(paramTypes, resultTypes, context.getContextOptions().supportMultiValue());
module.allocateFunctionType(paramTypes, resultTypes, context.getContextOptions().supportMultiValue(), context.language());
WasmFunction func = module.declareFunction(0);
func.setTarget(functionRootNode.getCallTarget());
WasmInstance moduleInstance = context.contextStore().readInstance(module);
Expand Down Expand Up @@ -857,11 +857,13 @@ 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, noLimit);
limits = new ModuleLimits(noLimit, noLimit, noLimit, noLimit, noLimit, 6, noLimit, noLimit, noLimit, noLimit, 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, noLimit);
limits = new ModuleLimits(noLimit, noLimit, noLimit, noLimit, noLimit, 5, noLimit, noLimit, noLimit, noLimit, 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
Expand Up @@ -792,24 +792,19 @@ public void testInvalidElemHeaderElemType() {
testAssertion(b -> b.addElemHeader(SegmentMode.ACTIVE, 0, WasmType.I32_TYPE, 0, null, 1), "invalid elem type in elem header");
}

@Test
public void testElemNull() {
test(RuntimeBytecodeGen::addElemNull, new byte[]{0x10});
}

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

@Test
public void testElemMaxInlineFunctionIndex() {
test(b -> b.addElemFunctionIndex(15), new byte[]{0x0F});
test(b -> b.addElemFunctionIndex(31), new byte[]{0x1F});
}

@Test
public void testElemMinU8FunctionIndex() {
test(b -> b.addElemFunctionIndex(16), new byte[]{0x20, 0x10});
test(b -> b.addElemFunctionIndex(32), new byte[]{0x20, 0x20});
}

@Test
Expand All @@ -832,11 +827,6 @@ public void testElemMinI32FunctionIndex() {
test(b -> b.addElemFunctionIndex(65536), new byte[]{0x60, 0x00, 0x00, 0x01, 0x00});
}

@Test
public void testElemGlobalIndex() {
test(b -> b.addElemGlobalIndex(256), new byte[]{(byte) 0xC0, 0x00, 0x01});
}

@Test
public void testCodeEntryMin() {
test(b -> b.addCodeEntry(0, 0, 0, 0, 0), new byte[]{0x04, 0x00});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
import org.graalvm.polyglot.PolyglotException;
import org.graalvm.polyglot.Value;
import org.graalvm.wasm.WasmType;
import org.graalvm.wasm.constants.GlobalModifier;
import org.graalvm.wasm.constants.Mutability;
import org.graalvm.wasm.test.AbstractBinarySuite;
import org.junit.Assert;
import org.junit.Test;
Expand Down Expand Up @@ -308,7 +308,7 @@ public void testTableInitInvalidElementExpression() throws IOException {
context.eval(source);
Assert.fail("Should have thrown");
} catch (PolyglotException e) {
Assert.assertTrue("Expected type mismatch error", e.getMessage().contains("Invalid constant expression for table elem expression:"));
Assert.assertTrue("Expected type mismatch error", e.getMessage().contains("Expected result types [funcref], but got [i32]"));
}
});
}
Expand Down Expand Up @@ -874,7 +874,7 @@ public void testGlobalWithNull() throws IOException {
// (func (export "main") (type 0)
// global.get 0
// )
final byte[] binary = newBuilder().addGlobal(GlobalModifier.CONSTANT, WasmType.EXTERNREF_TYPE, "D0 6F 0B").addType(EMPTY_INTS, new int[]{WasmType.EXTERNREF_TYPE}).addFunction(0,
final byte[] binary = newBuilder().addGlobal(Mutability.CONSTANT, WasmType.EXTERNREF_TYPE, "D0 6F 0B").addType(EMPTY_INTS, new int[]{WasmType.EXTERNREF_TYPE}).addFunction(0,
EMPTY_INTS, "23 00 0B").addFunctionExport(0, "main").build();
runRuntimeTest(binary, instance -> {
Value main = instance.getMember("main");
Expand All @@ -890,7 +890,7 @@ public void testGlobalWithNullException() throws IOException {
// (func (export "main") (type 0)
// global.get 0
// )
final byte[] binary = newBuilder().addGlobal(GlobalModifier.CONSTANT, WasmType.EXNREF_TYPE, "D0 69 0B").addType(EMPTY_INTS, new int[]{WasmType.EXNREF_TYPE}).addFunction(0,
final byte[] binary = newBuilder().addGlobal(Mutability.CONSTANT, WasmType.EXNREF_TYPE, "D0 69 0B").addType(EMPTY_INTS, new int[]{WasmType.EXNREF_TYPE}).addFunction(0,
EMPTY_INTS, "23 00 0B").addFunctionExport(0, "main").build();
runRuntimeTest(binary, options -> options.option("wasm.Exceptions", "true"), instance -> {
Value main = instance.getMember("main");
Expand All @@ -914,7 +914,7 @@ public void testGlobalWithFunction() throws IOException {
// i32.const 0
// call_indirect 0 (type 0)
// )
final byte[] binary = newBuilder().addGlobal(GlobalModifier.CONSTANT, WasmType.FUNCREF_TYPE, "D2 00 0B").addTable(1, 1, WasmType.FUNCREF_TYPE).addType(EMPTY_INTS,
final byte[] binary = newBuilder().addGlobal(Mutability.CONSTANT, WasmType.FUNCREF_TYPE, "D2 00 0B").addTable(1, 1, WasmType.FUNCREF_TYPE).addType(EMPTY_INTS,
new int[]{WasmType.I32_TYPE}).addFunction(0, EMPTY_INTS, "41 01 0B").addFunction(0, EMPTY_INTS, "41 00 23 00 26 00 41 00 11 00 00 0B").addFunctionExport(
1, "main").build();
runRuntimeTest(binary, instance -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,12 @@ public static Collection<Object[]> data() {
// The type `C.types[x]` must be defined in the context.
stringCase(
"Function - invalid type index",
"Function type variable 1 out of range. (max 0)",
"Type variable 1 out of range. (max 0)",
"(type (func (result i32))) (func (export \"f\") (type 1))",
Failure.Type.INVALID),
stringCase(
"Function - invalid type index",
"Function type variable 1073741823 out of range. (max 0)",
"Type variable 1073741823 out of range. (max 0)",
"(type (func (result i32))) (func (export \"f\") (type 1073741823))",
Failure.Type.INVALID),

Expand Down Expand Up @@ -936,7 +936,7 @@ public static Collection<Object[]> data() {

// Indirect call with missing type
binaryCase("Call_indirect - missing type",
"Function type variable 1 out of range. (max 0)",
"Type variable 1 out of range. (max 0)",
// (module
// (type (func))
// (table 1 funcref)
Expand Down Expand Up @@ -968,7 +968,7 @@ public static Collection<Object[]> data() {
null),

binaryCase("Invalid instruction",
"Unknown opcode: 0x06",
"Legacy exception handling is not supported (opcode: 0x06)",

// (module
// (func
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
validation Function type variable 8128 out of range. (max 3)
validation Type variable 8128 out of range. (max 3)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file contains native-image arguments needed to build graal-wasm

Args = --initialize-at-build-time=org.graalvm.wasm \
-H:MaxRuntimeCompileMethods=2700 \
-H:MaxRuntimeCompileMethods=2850 \
-H:+UnlockExperimentalVMOptions \
-H:+VectorAPISupport \
--add-modules=jdk.incubator.vector
Loading