package org.graalvm.wasm.test;
import com.oracle.truffle.api.TruffleLanguage;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.PolyglotException;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.io.ByteSequence;
import org.graalvm.wasm.WasmContext;
import org.graalvm.wasm.memory.UnsafeWasmMemory;
import org.graalvm.wasm.utils.Assert;
import org.junit.Test;
import java.io.IOException;
import static org.graalvm.wasm.test.WasmTestUtils.hexStringToByteArray;
import static org.graalvm.wasm.utils.WasmBinaryTools.compileWat;
public class WasmPolyglotTestSuite {
@Test
public void testEmpty() throws IOException {
try (Context context = Context.newBuilder().build()) {
context.parse(Source.newBuilder("wasm", ByteSequence.create(new byte[0]), "someName").build());
} catch (PolyglotException pex) {
Assert.assertTrue("Must be a syntax error.", pex.isSyntaxError());
Assert.assertTrue("Must not be an internal error.", !pex.isInternalError());
}
}
@Test
public void test42() throws IOException {
Context.Builder contextBuilder = Context.newBuilder("wasm");
Source.Builder sourceBuilder = Source.newBuilder("wasm",
ByteSequence.create(binaryReturnConst),
"main");
Source source = sourceBuilder.build();
Context context = contextBuilder.build();
context.eval(source);
Value mainFunction = context.getBindings("wasm").getMember("main").getMember("main");
Value result = mainFunction.execute();
Assert.assertEquals("Should be equal: ", 42, result.asInt());
}
@Test
public void unsafeMemoryFreed() throws IOException {
Context.Builder contextBuilder = Context.newBuilder("wasm");
Source.Builder sourceBuilder = Source.newBuilder("wasm",
ByteSequence.create(binaryReturnConst),
"main");
Source source = sourceBuilder.build();
contextBuilder.allowExperimentalOptions(true);
contextBuilder.option("wasm.UseUnsafeMemory", "true");
Context context = contextBuilder.build();
context.enter();
context.eval(source);
final Value mainModule = context.getBindings("wasm").getMember("main");
mainModule.getMember("main").execute();
final TruffleLanguage.Env env = WasmContext.getCurrent().environment();
final UnsafeWasmMemory memory = (UnsafeWasmMemory) env.asGuestValue(mainModule.getMember("memory"));
Assert.assertTrue("Memory should have been allocated.", !memory.freed());
context.close();
Assert.assertTrue("Memory should have been freed.", memory.freed());
}
@Test
public void overwriteElement() throws IOException, InterruptedException {
final ByteSequence test = ByteSequence.create(compileWat("test", textOverwriteElement));
Context.Builder contextBuilder = Context.newBuilder("wasm");
Source.Builder sourceBuilder = Source.newBuilder("wasm", test, "main");
Source source = sourceBuilder.build();
Context context = contextBuilder.build();
context.eval(source);
Value mainFunction = context.getBindings("wasm").getMember("main").getMember("main");
Value result = mainFunction.execute();
Assert.assertEquals("Should be equal: ", 11, result.asInt());
}
private static final byte[] binaryReturnConst = hexStringToByteArray(
"0061736d010000000108026000006000",
"017f0303020001040501700101010503",
"0100010615037f01418088040b7f0041",
"8088040b7f004180080b072c04046d61",
"696e0001066d656d6f727902000b5f5f",
"686561705f6261736503010a5f5f6461",
"74615f656e6403020a090202000b0400",
"412a0b");
private static final String textOverwriteElement = "(module" +
" (table 10 funcref)\n" +
" (type (func (result i32)))\n" +
" (func $f (result i32)\n" +
" i32.const 7)\n" +
" (func $g (result i32)\n" +
" i32.const 11)\n" +
" (func (result i32)\n" +
" i32.const 3\n" +
" call_indirect (type 0))\n" +
" (export \"main\" (func 2))\n" +
" (elem (i32.const 0) $f)\n" +
" (elem (i32.const 3) $f)\n" +
" (elem (i32.const 7) $f)\n" +
" (elem (i32.const 5) $f)\n" +
" (elem (i32.const 3) $g)\n" +
")";
}