mirror of
https://github.com/fluencelabs/asmble
synced 2025-04-25 06:42:22 +00:00
92 lines
2.6 KiB
Java
92 lines
2.6 KiB
Java
package run.jvm.emscripten;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteOrder;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
public class Mem {
|
|
public static final int TOTAL_STACK = 5242880;
|
|
public static final int TOTAL_MEMORY = 16777216;
|
|
|
|
private static int alignTo16(int num) {
|
|
return ((int) Math.ceil(num / 16.0)) * 16;
|
|
}
|
|
|
|
final ByteBuffer buf;
|
|
private int counter = 0;
|
|
|
|
public Mem(int staticBump) {
|
|
this(ByteBuffer.allocateDirect(TOTAL_MEMORY), staticBump);
|
|
}
|
|
|
|
public Mem(ByteBuffer buf, int staticBump) {
|
|
this.buf = buf.order(ByteOrder.LITTLE_ENDIAN);
|
|
// Emscripten sets where "stack top" can start in mem at position 1024.
|
|
// See https://github.com/WebAssembly/binaryen/issues/979
|
|
int staticTop = 1024 + staticBump + 16;
|
|
int stackBase = alignTo16(staticTop);
|
|
int stackTop = stackBase + TOTAL_STACK;
|
|
buf.putInt(1024, stackTop);
|
|
}
|
|
|
|
|
|
public byte[] getBulk(int index, int len) {
|
|
byte[] ret = new byte[len];
|
|
if (len > 0) {
|
|
ByteBuffer dup = buf.duplicate();
|
|
dup.position(index);
|
|
dup.get(ret);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public byte[] getCStringBytes(int index) {
|
|
if (index == 0) return new byte[0];
|
|
// Not really sure the highest performing approach. What we're going to do though is just
|
|
// find the first index of 0, then get the array.
|
|
int len = 0;
|
|
while (buf.get(index + len) != 0) len++;
|
|
return getBulk(index, len);
|
|
}
|
|
|
|
public String getCString(int index) {
|
|
byte[] bytes = getCStringBytes(index);
|
|
if (bytes.length == 0) return "";
|
|
return new String(getCStringBytes(index), StandardCharsets.ISO_8859_1);
|
|
}
|
|
|
|
public synchronized int putCString(String str) {
|
|
// For now we'll just trust it doesn't already contain a 0
|
|
int ret = allocate(str.getBytes(StandardCharsets.ISO_8859_1));
|
|
allocate((byte) 0);
|
|
return ret;
|
|
}
|
|
|
|
public int putIntArray(int[] arr) {
|
|
int ret = counter;
|
|
for (int i = 0; i < arr.length; i++) {
|
|
buf.putInt(counter, arr[i]);
|
|
counter += 4;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public int allocate(byte b) {
|
|
int ret = counter;
|
|
buf.put(counter, b);
|
|
counter++;
|
|
return ret;
|
|
}
|
|
|
|
public int allocate(byte[] bytes) {
|
|
int ret = counter;
|
|
if (bytes.length > 0) {
|
|
ByteBuffer dup = buf.duplicate();
|
|
dup.position(counter);
|
|
dup.put(bytes);
|
|
counter += bytes.length;
|
|
}
|
|
return ret;
|
|
}
|
|
}
|