mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-14 15:31:31 +00:00
Portable not-so-smart Heap
This commit is contained in:
4
portable-assembly.d.ts
vendored
4
portable-assembly.d.ts
vendored
@ -41,6 +41,10 @@ declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;
|
|||||||
declare function sqrt<T = f32 | f64>(value: T): T;
|
declare function sqrt<T = f32 | f64>(value: T): T;
|
||||||
/** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */
|
/** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */
|
||||||
declare function trunc<T = f32 | f64>(value: T): T;
|
declare function trunc<T = f32 | f64>(value: T): T;
|
||||||
|
/** Loads a value of the specified type from memory. Type must be `u8`. */
|
||||||
|
declare function load<T = u8>(offset: usize): T;
|
||||||
|
/** Stores a value of the specified type to memory. Type must be `u8`. */
|
||||||
|
declare function store<T = u8>(offset: usize, value: T): void;
|
||||||
/** Emits an unreachable operation that results in a runtime error when executed. */
|
/** Emits an unreachable operation that results in a runtime error when executed. */
|
||||||
declare function unreachable(): any; // sic
|
declare function unreachable(): any; // sic
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
require("../../portable-assembly"); // not inherited from tsconfig by ts-node otherwise :(
|
require("../../portable-assembly");
|
||||||
|
|
||||||
// Copy Binaryen exports to global scope
|
// Copy Binaryen exports to global scope
|
||||||
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
||||||
@ -13,9 +13,17 @@ for (var key in binaryen)
|
|||||||
globalScope[key] = binaryen[key];
|
globalScope[key] = binaryen[key];
|
||||||
|
|
||||||
// Use Binaryen's heap
|
// Use Binaryen's heap
|
||||||
Object.defineProperties(globalScope['Heap'] = {
|
Object.defineProperties(globalScope["Heap"] = {
|
||||||
allocate: binaryen._malloc,
|
allocate: function allocate(size) {
|
||||||
dispose: binaryen._free
|
if (!size) return 0; // should be safe in our case
|
||||||
|
return binaryen._malloc(size);
|
||||||
|
},
|
||||||
|
dispose: function dispose(ptr) {
|
||||||
|
if (ptr) binaryen._free(ptr);
|
||||||
|
},
|
||||||
|
copy: function copy(dest, src, n) {
|
||||||
|
return binaryen._memcpy(dest, src, n);
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
free: { get: function() { return binaryen.HEAPU8.length; } },
|
free: { get: function() { return binaryen.HEAPU8.length; } },
|
||||||
used: { get: function() { return 0; } },
|
used: { get: function() { return 0; } },
|
||||||
@ -24,7 +32,7 @@ Object.defineProperties(globalScope['Heap'] = {
|
|||||||
globalScope["store"] = function store(ptr, val) {
|
globalScope["store"] = function store(ptr, val) {
|
||||||
binaryen.HEAPU8[ptr] = val;
|
binaryen.HEAPU8[ptr] = val;
|
||||||
};
|
};
|
||||||
globalScope["load"] = function load_u8(ptr) {
|
globalScope["load"] = function load(ptr) {
|
||||||
return binaryen.HEAPU8[ptr];
|
return binaryen.HEAPU8[ptr];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,9 +9,13 @@ let HEAP_OFFSET: usize = HEAP_START; // HEAP_START is a constant generated by th
|
|||||||
class Heap {
|
class Heap {
|
||||||
|
|
||||||
static allocate(size: usize): usize {
|
static allocate(size: usize): usize {
|
||||||
|
if (!size) return 0;
|
||||||
|
const len: i32 = current_memory();
|
||||||
|
if (HEAP_OFFSET + size > <usize>len << 16)
|
||||||
|
if(grow_memory(max<i32>(<i32>ceil<f64>(<f64>size / 65536), len * 2 - len)) < 0)
|
||||||
|
unreachable();
|
||||||
const ptr: usize = HEAP_OFFSET;
|
const ptr: usize = HEAP_OFFSET;
|
||||||
assert(ptr + size <= (<usize>current_memory() << 16));
|
if ((HEAP_OFFSET += size) & ALIGN_MASK) // align next offset
|
||||||
if (((HEAP_OFFSET += size) & ALIGN_MASK) != 0) // align next offset
|
|
||||||
HEAP_OFFSET = (HEAP_OFFSET | ALIGN_MASK) + 1;
|
HEAP_OFFSET = (HEAP_OFFSET | ALIGN_MASK) + 1;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,34 @@
|
|||||||
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
||||||
|
|
||||||
globalScope["Heap"] = {
|
var HEAP = new Uint8Array(65536);
|
||||||
allocate: function() { throw new Error("not implemented"); },
|
var HEAP_OFFSET = 0;
|
||||||
dispose: function() { throw new Error("not implemented"); },
|
|
||||||
used: 0,
|
Object.defineProperties(globalScope["Heap"] = {
|
||||||
free: 0,
|
allocate: function allocate(size) {
|
||||||
size: 0
|
if (!size) return 0;
|
||||||
|
if (HEAP_OFFSET + size > HEAP.length) {
|
||||||
|
var oldHeap = HEAP;
|
||||||
|
HEAP = new Uint8Array(Math.max(HEAP.length + size, HEAP.length * 2));
|
||||||
|
HEAP.set(oldHeap);
|
||||||
|
}
|
||||||
|
var ptr = HEAP_OFFSET;
|
||||||
|
if ((HEAP_OFFSET += size) & 7)
|
||||||
|
HEAP_OFFSET = (HEAP_OFFSET | 7) + 1;
|
||||||
|
return ptr;
|
||||||
|
},
|
||||||
|
dispose: function dispose() { },
|
||||||
|
copy: function copy(dest, src, n) {
|
||||||
|
HEAP.set(HEAP.subarray(src, src + n), dest);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
used: { get: function get_used() { return HEAP_OFFSET; } },
|
||||||
|
free: { get: function get_free() { return HEAP.length - HEAP_OFFSET; } },
|
||||||
|
size: { get: function get_size() { return HEAP.length; } }
|
||||||
|
});
|
||||||
|
globalScope["store"] = function store(ptr, val) {
|
||||||
|
binaryen.HEAPU8[ptr] = val;
|
||||||
|
};
|
||||||
|
globalScope["load"] = function load(ptr) {
|
||||||
|
return binaryen.HEAPU8[ptr];
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user