[WebAssembly] Support grow memory in brk() (#39)

This commit is contained in:
Sam Clegg 2018-01-16 17:20:44 -08:00 committed by GitHub
parent 2c356f0738
commit 9064441edc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -21,8 +21,9 @@
* both as a hobbling libc and a linker/loader, including dynamic linking. * both as a hobbling libc and a linker/loader, including dynamic linking.
*/ */
const PAGE_SIZE = (64 * 1024);
var heap_size_bytes = 16 * 1024 * 1024; var heap_size_bytes = 16 * 1024 * 1024;
var heap_size_pages = heap_size_bytes / (64 * 1024); var heap_size_pages = heap_size_bytes / PAGE_SIZE;
var memory = new WebAssembly.Memory({initial: heap_size_pages, maximum: heap_size_pages}) var memory = new WebAssembly.Memory({initial: heap_size_pages, maximum: heap_size_pages})
var heap; var heap;
var heap_end; var heap_end;
@ -41,14 +42,15 @@ if (typeof process === 'object' && typeof require === 'function') { // This is n
arguments = process['argv'].slice(2); arguments = process['argv'].slice(2);
} }
function setHeap(h) { function setHeap(m) {
heap = h memory = m
heap = m.buffer
heap_uint8 = new Uint8Array(heap); heap_uint8 = new Uint8Array(heap);
heap_uint32 = new Uint32Array(heap); heap_uint32 = new Uint32Array(heap);
heap_size_bytes = heap.byteLength; heap_size_bytes = heap.byteLength;
} }
setHeap(memory.buffer) setHeap(memory)
// Heap access helpers. // Heap access helpers.
function charFromHeap(ptr) { return String.fromCharCode(heap_uint8[ptr]); } function charFromHeap(ptr) { return String.fromCharCode(heap_uint8[ptr]); }
@ -1355,8 +1357,10 @@ function syscall_writev(fd, iov, iovcnt) {
function syscall_brk(value) { function syscall_brk(value) {
if (value > heap_size_bytes) { if (value > heap_size_bytes) {
print('brk failed: memsize: ' + heap_size_bytes + ' requested: ' + value); var inc = value - heap_size_bytes;
return -1; var inc_pages = Math.ceil(inc / PAGE_SIZE);
memory.grow(inc_pages);
setHeap(memory);
} }
if (value != 0) if (value != 0)
heap_end = value; heap_end = value;
@ -1440,7 +1444,7 @@ function load_wasm(file_path) {
// the one we created. In this way this code works with modules that // the one we created. In this way this code works with modules that
// import or export their memory. // import or export their memory.
if (instance.exports.memory) if (instance.exports.memory)
setHeap(instance.exports.memory.buffer); setHeap(instance.exports.memory);
return instance; return instance;
} }
@ -1465,9 +1469,10 @@ for (var i = arguments.length - 1; i > 0; --i) {
// Load the main module once the ffi object has been fully populated. // Load the main module once the ffi object has been fully populated.
var main_module = arguments[0]; var main_module = arguments[0];
modules[0] = load_wasm(main_module); modules[0] = load_wasm(main_module);
heap_end = modules[0].exports.__heap_base heap_end = modules[0].exports.__heap_base;
// TODO check that `main` exists in modules[0].exports and error out if not. if (!(modules[i].exports.main instanceof Function))
throw new Error('main() not found');
try { try {
var ret = modules[0].exports.main(); var ret = modules[0].exports.main();