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);
}
});
}
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);
}
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));
}
}
}
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);
}
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());
}
Aggregations