Search in sources :

Example 6 with WasmMemory

use of org.graalvm.wasm.memory.WasmMemory in project graal by oracle.

the class WasmJsApiSuite method testInstantiateWithImportMemory.

@Test
public void testInstantiateWithImportMemory() throws IOException {
    runTest(context -> {
        final WebAssembly wasm = new WebAssembly(context);
        final WasmMemory memory = WebAssembly.memAlloc(4, 8);
        final Dictionary importObject = Dictionary.create(new Object[] { "host", Dictionary.create(new Object[] { "defaultMemory", memory }) });
        final WasmInstance instance = moduleInstantiate(wasm, binaryWithMemoryImport, importObject);
        try {
            final Object initZero = WebAssembly.instanceExport(instance, "initZero");
            Assert.assertEquals("Must be zero initially.", 0, memory.load_i32(null, 0));
            InteropLibrary.getUncached(initZero).execute(initZero);
            Assert.assertEquals("Must be 174 after initialization.", 174, memory.load_i32(null, 0));
        } catch (InteropException e) {
            throw new RuntimeException(e);
        }
    });
}
Also used : Dictionary(org.graalvm.wasm.api.Dictionary) WasmInstance(org.graalvm.wasm.WasmInstance) WebAssembly(org.graalvm.wasm.api.WebAssembly) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) InteropException(com.oracle.truffle.api.interop.InteropException) WasmMemory(org.graalvm.wasm.memory.WasmMemory) Test(org.junit.Test)

Example 7 with WasmMemory

use of org.graalvm.wasm.memory.WasmMemory in project graal by oracle.

the class WasmFileSuite method assertContextEqual.

private static void assertContextEqual(ContextState expectedState, ContextState actualState) {
    // Compare memories
    final WasmMemory expectedMemory = expectedState.memory();
    final WasmMemory actualMemory = actualState.memory();
    if (expectedMemory == null) {
        Assert.assertNull("Memory should be null", actualMemory);
    } else {
        Assert.assertNotNull("Memory should not be null", actualMemory);
        Assert.assertEquals("Mismatch in memory lengths", expectedMemory.byteSize(), actualMemory.byteSize());
        for (int ptr = 0; ptr < expectedMemory.byteSize(); ptr++) {
            byte expectedByte = (byte) expectedMemory.load_i32_8s(null, ptr);
            byte actualByte = (byte) actualMemory.load_i32_8s(null, ptr);
            Assert.assertEquals("Memory mismatch at offset " + ptr + ",", expectedByte, actualByte);
        }
    }
    // Compare globals
    final GlobalRegistry firstGlobals = expectedState.globals();
    final GlobalRegistry lastGlobals = actualState.globals();
    Assert.assertEquals("Mismatch in global counts.", firstGlobals.count(), lastGlobals.count());
    for (int address = 0; address < firstGlobals.count(); address++) {
        long first = firstGlobals.loadAsLong(address);
        long last = lastGlobals.loadAsLong(address);
        Assert.assertEquals("Mismatch in global at " + address + ". ", first, last);
    }
    // Check number of opened file descriptors
    Assert.assertEquals("Mismatch in file descriptor counts.", expectedState.openedFdCount, actualState.openedFdCount);
}
Also used : GlobalRegistry(org.graalvm.wasm.GlobalRegistry) WasmMemory(org.graalvm.wasm.memory.WasmMemory)

Example 8 with WasmMemory

use of org.graalvm.wasm.memory.WasmMemory in project graal by oracle.

the class BinaryParser method readDataSection.

private void readDataSection(WasmContext linkedContext, WasmInstance linkedInstance) {
    final int numDataSegments = readLength();
    module.limits().checkDataSegmentCount(numDataSegments);
    for (int dataSegmentId = 0; dataSegmentId != numDataSegments; ++dataSegmentId) {
        readMemoryIndex();
        // Data dataOffset expression must be a constant expression with result type i32.
        // https://webassembly.github.io/spec/core/syntax/modules.html#data-segments
        // https://webassembly.github.io/spec/core/valid/instructions.html#constant-expressions
        // Read the offset expression.
        byte instruction = read1();
        // Read the offset expression.
        int offsetAddress = -1;
        int offsetGlobalIndex = -1;
        switch(instruction) {
            case Instructions.I32_CONST:
                offsetAddress = readSignedInt32();
                break;
            case Instructions.GLOBAL_GET:
                offsetGlobalIndex = readGlobalIndex();
                break;
            default:
                throw WasmException.format(Failure.TYPE_MISMATCH, "Invalid instruction for table offset expression: 0x%02X", instruction);
        }
        readEnd();
        final int byteLength = readLength();
        if (linkedInstance != null) {
            if (offsetGlobalIndex != -1) {
                int offsetGlobalAddress = linkedInstance.globalAddress(offsetGlobalIndex);
                offsetAddress = linkedContext.globals().loadAsInt(offsetGlobalAddress);
            }
            // Reading of the data segment is called after linking, so initialize the memory
            // directly.
            final WasmMemory memory = linkedInstance.memory();
            Assert.assertUnsignedIntLessOrEqual(offsetAddress, WasmMath.toUnsignedIntExact(memory.byteSize()), Failure.DATA_SEGMENT_DOES_NOT_FIT);
            Assert.assertUnsignedIntLessOrEqual(offsetAddress + byteLength, WasmMath.toUnsignedIntExact(memory.byteSize()), Failure.DATA_SEGMENT_DOES_NOT_FIT);
            for (int writeOffset = 0; writeOffset != byteLength; ++writeOffset) {
                final byte b = read1();
                memory.store_i32_8(null, offsetAddress + writeOffset, b);
            }
        } else {
            // Reading of the data segment occurs during parsing, so add a linker action.
            final byte[] dataSegment = new byte[byteLength];
            for (int writeOffset = 0; writeOffset != byteLength; ++writeOffset) {
                byte b = read1();
                dataSegment[writeOffset] = b;
            }
            final int currentDataSegmentId = dataSegmentId;
            final int currentOffsetAddress = offsetAddress;
            final int currentOffsetGlobalIndex = offsetGlobalIndex;
            module.addLinkAction((context, instance) -> context.linker().resolveDataSegment(context, instance, currentDataSegmentId, currentOffsetAddress, currentOffsetGlobalIndex, byteLength, dataSegment));
        }
    }
}
Also used : WasmMemory(org.graalvm.wasm.memory.WasmMemory)

Example 9 with WasmMemory

use of org.graalvm.wasm.memory.WasmMemory in project graal by oracle.

the class Linker method resolveDataSegment.

void resolveDataSegment(WasmContext context, WasmInstance instance, int dataSegmentId, int offsetAddress, int offsetGlobalIndex, int byteLength, byte[] data) {
    assertTrue(instance.symbolTable().memoryExists(), String.format("No memory declared or imported in the module '%s'", instance.name()), Failure.UNSPECIFIED_MALFORMED);
    final Runnable resolveAction = () -> {
        WasmMemory memory = instance.memory();
        Assert.assertNotNull(memory, String.format("No memory declared or imported in the module '%s'", instance.name()), Failure.UNSPECIFIED_MALFORMED);
        int baseAddress;
        if (offsetGlobalIndex != -1) {
            final int offsetGlobalAddress = instance.globalAddress(offsetGlobalIndex);
            assertTrue(offsetGlobalAddress != -1, "The global variable '" + offsetGlobalIndex + "' for the offset of the data segment " + dataSegmentId + " in module '" + instance.name() + "' was not initialized.", Failure.UNSPECIFIED_MALFORMED);
            baseAddress = context.globals().loadAsInt(offsetGlobalAddress);
        } else {
            baseAddress = offsetAddress;
        }
        Assert.assertUnsignedIntLessOrEqual(baseAddress, WasmMath.toUnsignedIntExact(memory.byteSize()), Failure.DATA_SEGMENT_DOES_NOT_FIT);
        Assert.assertUnsignedIntLessOrEqual(baseAddress + byteLength, WasmMath.toUnsignedIntExact(memory.byteSize()), Failure.DATA_SEGMENT_DOES_NOT_FIT);
        for (int writeOffset = 0; writeOffset != byteLength; ++writeOffset) {
            byte b = data[writeOffset];
            memory.store_i32_8(null, baseAddress + writeOffset, b);
        }
    };
    final ArrayList<Sym> dependencies = new ArrayList<>();
    if (instance.symbolTable().importedMemory() != null) {
        dependencies.add(new ImportMemorySym(instance.name(), instance.symbolTable().importedMemory()));
    }
    if (dataSegmentId > 0) {
        dependencies.add(new DataSym(instance.name(), dataSegmentId - 1));
    }
    if (offsetGlobalIndex != -1) {
        dependencies.add(new InitializeGlobalSym(instance.name(), offsetGlobalIndex));
    }
    resolutionDag.resolveLater(new DataSym(instance.name(), dataSegmentId), dependencies.toArray(new Sym[dependencies.size()]), resolveAction);
}
Also used : DataSym(org.graalvm.wasm.Linker.ResolutionDag.DataSym) ImportMemorySym(org.graalvm.wasm.Linker.ResolutionDag.ImportMemorySym) ElemSym(org.graalvm.wasm.Linker.ResolutionDag.ElemSym) ExportMemorySym(org.graalvm.wasm.Linker.ResolutionDag.ExportMemorySym) ExportTableSym(org.graalvm.wasm.Linker.ResolutionDag.ExportTableSym) InitializeGlobalSym(org.graalvm.wasm.Linker.ResolutionDag.InitializeGlobalSym) ExportFunctionSym(org.graalvm.wasm.Linker.ResolutionDag.ExportFunctionSym) CodeEntrySym(org.graalvm.wasm.Linker.ResolutionDag.CodeEntrySym) CallsiteSym(org.graalvm.wasm.Linker.ResolutionDag.CallsiteSym) ImportMemorySym(org.graalvm.wasm.Linker.ResolutionDag.ImportMemorySym) ExportGlobalSym(org.graalvm.wasm.Linker.ResolutionDag.ExportGlobalSym) ImportFunctionSym(org.graalvm.wasm.Linker.ResolutionDag.ImportFunctionSym) Sym(org.graalvm.wasm.Linker.ResolutionDag.Sym) ImportTableSym(org.graalvm.wasm.Linker.ResolutionDag.ImportTableSym) ImportGlobalSym(org.graalvm.wasm.Linker.ResolutionDag.ImportGlobalSym) DataSym(org.graalvm.wasm.Linker.ResolutionDag.DataSym) ArrayList(java.util.ArrayList) InitializeGlobalSym(org.graalvm.wasm.Linker.ResolutionDag.InitializeGlobalSym) WasmMemory(org.graalvm.wasm.memory.WasmMemory)

Example 10 with WasmMemory

use of org.graalvm.wasm.memory.WasmMemory in project graal by oracle.

the class WasmFileSuite method saveContext.

private static ContextState saveContext(WasmContext context) {
    Assert.assertTrue("Currently, only 0 or 1 memories can be saved.", context.memories().count() <= 1);
    final WasmMemory currentMemory = context.memories().count() == 1 ? context.memories().memory(0).duplicate() : null;
    final GlobalRegistry globals = context.globals().duplicate();
    return new ContextState(currentMemory, globals, context.fdManager().size());
}
Also used : GlobalRegistry(org.graalvm.wasm.GlobalRegistry) WasmMemory(org.graalvm.wasm.memory.WasmMemory)

Aggregations

WasmMemory (org.graalvm.wasm.memory.WasmMemory)23 ByteArrayWasmMemory (org.graalvm.wasm.memory.ByteArrayWasmMemory)6 UnsafeWasmMemory (org.graalvm.wasm.memory.UnsafeWasmMemory)6 WasmJsApiException (org.graalvm.wasm.exception.WasmJsApiException)4 Test (org.junit.Test)4 WasmFunction (org.graalvm.wasm.WasmFunction)3 WasmInstance (org.graalvm.wasm.WasmInstance)3 WasmTable (org.graalvm.wasm.WasmTable)3 InteropException (com.oracle.truffle.api.interop.InteropException)2 InteropLibrary (com.oracle.truffle.api.interop.InteropLibrary)2 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 GlobalRegistry (org.graalvm.wasm.GlobalRegistry)2 ExportMemorySym (org.graalvm.wasm.Linker.ResolutionDag.ExportMemorySym)2 ImportMemorySym (org.graalvm.wasm.Linker.ResolutionDag.ImportMemorySym)2 SymbolTable (org.graalvm.wasm.SymbolTable)2 WasmContext (org.graalvm.wasm.WasmContext)2 WasmFunctionInstance (org.graalvm.wasm.WasmFunctionInstance)2