Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -386,22 +386,22 @@ public byte read(int addr) {
}

@Override
public byte[] readBytes(int addr, int len) {
public void readBytesInto(int addr, byte[] buf, int destOffset, int len) {
checkBounds(addr, len, sizeInBytes(), WasmRuntimeException::new);
byte[] result = new byte[len];
int destOffset = 0;
if (destOffset < 0 || len > buf.length - destOffset) {
throw new IndexOutOfBoundsException();
}
int remaining = len;
int a = addr;
while (remaining > 0) {
int pageIdx = a >>> PAGE_SHIFT;
int pageOffset = a & PAGE_MASK;
int chunk = Math.min(remaining, PAGE_SIZE - pageOffset);
System.arraycopy(pages[pageIdx], pageOffset, result, destOffset, chunk);
System.arraycopy(pages[pageIdx], pageOffset, buf, destOffset, chunk);
a += chunk;
destOffset += chunk;
remaining -= chunk;
}
return result;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,23 +360,23 @@ public byte read(int addr) {
}

@Override
public byte[] readBytes(int addr, int len) {
public void readBytesInto(int addr, byte[] buf, int destOffset, int len) {
checkBounds(addr, len, sizeInBytes(), WasmRuntimeException::new);
byte[] result = new byte[len];
int destOffset = 0;
if (destOffset < 0 || len > buf.length - destOffset) {
throw new IndexOutOfBoundsException();
}
int remaining = len;
int a = addr;
while (remaining > 0) {
int pageIdx = a >>> PAGE_SHIFT;
int pageOffset = a & PAGE_MASK;
int chunk = Math.min(remaining, PAGE_SIZE - pageOffset);
pages[pageIdx].position(pageOffset);
pages[pageIdx].get(result, destOffset, chunk);
pages[pageIdx].get(buf, destOffset, chunk);
a += chunk;
destOffset += chunk;
remaining -= chunk;
}
return result;
}

@Override
Expand Down
43 changes: 42 additions & 1 deletion runtime/src/main/java/com/dylibso/chicory/runtime/Memory.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
* Direct access to the memory (or a memory, if there are multiple) of the WASM virtual machine.
* <p>
* By design, WASM is little-endian and methods that read and write numeric data types reflect that. For example,
* {@link #writeI32(int, int)} writes out the 4 bytes of an integer, starting with the least significant, at the address.
*/
public interface Memory {

/**
Expand Down Expand Up @@ -365,7 +371,42 @@ default void write(int addr, byte[] data) {

byte read(int addr);

byte[] readBytes(int addr, int len);
/**
* Reads an arbitrary number of bytes returning a filled buffer.
*
* @param addr the start address
* @param len how many bytes to read
* @return the read bytes (length will be equal to {@code len})
* @throws WasmRuntimeException if the address and length specify an out-of-bounds memory range
*/
default byte[] readBytes(int addr, int len) {
byte[] result = new byte[len];
readBytesInto(addr, result, 0, len);
return result;
}

/**
* Reads an arbitrary number of bytes, sending them to the destination buffer starting from the offset.
*
* @param addr the start address
* @param buf the output buffer
* @param destOffset the offset in the output buffer from which to start writing
* @param len how many bytes to read
* @throws IndexOutOfBoundsException if {@code offset + len > buf.length}
* @throws WasmRuntimeException if the address and length specify an out-of-bounds memory range
*/
void readBytesInto(int addr, byte[] buf, int destOffset, int len);

/**
* Reads an arbitrary number of bytes, completely filling the destination buffer.
*
* @param addr the start address
* @param buf the output buffer, whose length will be the number of bytes read
* @throws WasmRuntimeException if the address and buffer length specify an out-of-bounds memory range
*/
default void readBytesInto(int addr, byte[] buf) {
readBytesInto(addr, buf, 0, buf.length);
}

void writeI32(int addr, int data);

Expand Down
Loading