1
0
mirror of https://github.com/fluencelabs/assemblyscript synced 2025-07-28 20:52:12 +00:00

support normal arrays

This commit is contained in:
dcode
2019-05-25 01:14:26 +02:00
parent 9620f18249
commit c34ed66fd9
42 changed files with 831 additions and 468 deletions

@@ -10,25 +10,28 @@ const STRING_ID = 1;
const ARRAYBUFFERVIEW_ID = 2;
// Runtime type information
const ARRAY = 1 << 0;
const SET = 1 << 1;
const MAP = 1 << 2;
const VAL_ALIGN = 1 << 4;
const VAL_SIGNED = 1 << 9;
const VAL_FLOAT = 1 << 10;
const VAL_NULLABLE = 1 << 11;
const VAL_MANAGED = 1 << 12;
const KEY_ALIGN = 1 << 13;
const KEY_SIGNED = 1 << 18;
const KEY_FLOAT = 1 << 19;
const KEY_NULLABLE = 1 << 20;
const KEY_MANAGED = 1 << 21;
const ARRAYBUFFERVIEW = 1 << 0;
const ARRAY = 1 << 1;
const SET = 1 << 2;
const MAP = 1 << 3;
const VAL_ALIGN = 1 << 5;
const VAL_SIGNED = 1 << 10;
const VAL_FLOAT = 1 << 11;
const VAL_NULLABLE = 1 << 12;
const VAL_MANAGED = 1 << 13;
const KEY_ALIGN = 1 << 14;
const KEY_SIGNED = 1 << 19;
const KEY_FLOAT = 1 << 20;
const KEY_NULLABLE = 1 << 21;
const KEY_MANAGED = 1 << 22;
// ArrayBufferView layout
const ABV_BUFFER_OFFSET = 0;
const ABV_DATASTART_OFFSET = 4;
const ABV_DATALENGTH_OFFSET = 8;
const ABV_SIZE = 12;
// Array(BufferView) layout
const ARRAYBUFFERVIEW_BUFFER_OFFSET = 0;
const ARRAYBUFFERVIEW_DATASTART_OFFSET = 4;
const ARRAYBUFFERVIEW_DATALENGTH_OFFSET = 8;
const ARRAYBUFFERVIEW_SIZE = 12;
const ARRAY_LENGTH_OFFSET = 12;
const ARRAY_SIZE = 16;
const BIGINT = typeof BigUint64Array !== "undefined";
const THIS = Symbol();
@@ -169,15 +172,16 @@ function postInstantiate(baseModule, instance) {
/** Allocates a new array in the module's memory and returns its retained pointer. */
function __allocArray(id, values) {
const info = getInfo(id);
if (!(info & ARRAY)) throw Error("not an array: " + id + " @ " + info);
if (!(info & (ARRAYBUFFERVIEW | ARRAY))) throw Error("not an array: " + id + " @ " + info);
const align = getAlign(VAL_ALIGN, info);
const length = values.length;
const buf = alloc(length << align, ARRAYBUFFER_ID);
const arr = alloc(ABV_SIZE, id);
const arr = alloc(ARRAYBUFFERVIEW_SIZE, id);
checkMem();
U32[arr + ABV_BUFFER_OFFSET >>> 2] = retain(buf);
U32[arr + ABV_DATASTART_OFFSET >>> 2] = buf;
U32[arr + ABV_DATALENGTH_OFFSET >>> 2] = length << align;
U32[arr + ARRAYBUFFERVIEW_BUFFER_OFFSET >>> 2] = retain(buf);
U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2] = buf;
U32[arr + ARRAYBUFFERVIEW_DATALENGTH_OFFSET >>> 2] = length << align;
if (info & ARRAY) U32[arr + ARRAY_LENGTH_OFFSET >>> 2] = length;
const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
for (let i = 0; i < length; ++i) view[(buf >> align) + i] = values[i];
if (info & VAL_MANAGED) for (let i = 0; i < length; ++i) retain(values[i]);
@@ -191,10 +195,12 @@ function postInstantiate(baseModule, instance) {
checkMem();
const id = U32[arr + ID_OFFSET >>> 2];
const info = getInfo(id);
if (!(info & ARRAY)) throw Error("not an array: " + id);
if (!(info & (ARRAYBUFFERVIEW | ARRAY))) throw Error("not an array: " + id);
const align = getAlign(VAL_ALIGN, info);
var buf = U32[arr + ABV_DATASTART_OFFSET >>> 2];
const length = U32[buf + SIZE_OFFSET >>> 2] >>> align;
var buf = U32[arr + ARRAYBUFFERVIEW_DATASTART_OFFSET >>> 2];
const length = info & ARRAY
? U32[arr + ARRAY_LENGTH_OFFSET >>> 2]
: U32[buf + SIZE_OFFSET >>> 2] >>> align;
const view = getView(align, info & VAL_SIGNED, info & VAL_FLOAT);
return Array.from(view.slice(buf >>>= align, buf + length));
}