Implement reference counting (#592)

This commit is contained in:
Daniel Wirtz
2019-06-05 23:15:39 +02:00
committed by GitHub
parent 3ed76a97f0
commit 0484a6b740
601 changed files with 261645 additions and 146131 deletions

View File

@ -21,44 +21,87 @@ assert(proto.F64 instanceof Float64Array);
// should export memory
assert(module.memory instanceof WebAssembly.Memory);
assert(typeof module.memory.free === "function");
assert(typeof module.memory.copy === "function");
// should be able to get an exported string
assert.strictEqual(module.getString(module.COLOR), "red");
assert.strictEqual(module.__getString(module.COLOR), "red");
// should be able to allocate and work with a new string
var str = "Hello world!𤭢";
var ptr = module.newString(str);
assert.strictEqual(module.getString(ptr), str);
assert.strictEqual(module.strlen(ptr), str.length);
{
let str = "Hello world!𤭢";
let ref = module.__retain(module.__allocString(str));
assert.strictEqual(module.__getString(ref), str);
assert.strictEqual(module.strlen(ref), str.length);
module.__release(ref);
}
// should be able to allocate a typed array and sum up its values
var arr = [1, 2, 3, 4, 5, 0x7fffffff];
ptr = module.newArray(new Int32Array(arr));
assert.strictEqual(module.sum(ptr), arr.reduce((a, b) => a + b, 0) | 0);
// should be able to allocate a typed array
{
var arr = [1, 2, 3, 4, 5, 0x80000000 | 0];
let ref = module.__retain(module.__allocArray(module.INT32ARRAY_ID, arr));
assert(module.__instanceof(ref, module.INT32ARRAY_ID));
// should be able to get a view on an internal typed array
assert.deepEqual(module.getArray(Int32Array, ptr), arr);
// should be able to get the values of an array
assert.deepEqual(module.__getArray(ref), arr);
// should be able to free and reuse the space of an internal typed array
module.freeArray(ptr);
var ptr2 = module.newArray(new Int32Array(arr));
assert.strictEqual(ptr, ptr2);
// should be able to get a view on an array
assert.deepEqual(module.__getArrayView(ref), new Int32Array(arr));
// should be able to just call a function with variable arguments
// should be able to sum up its values
assert.strictEqual(module.sum(ref), arr.reduce((a, b) => (a + b) | 0, 0) | 0);
// should be able to release no longer needed references
module.__release(ref);
try { module.__release(ref); assert(false); } catch (e) {};
}
// should be able to distinguish between signed and unsigned
{
let arr = [1, -1 >>> 0, 0x80000000];
let ref = module.__retain(module.__allocArray(module.UINT32ARRAY_ID, arr));
assert(module.__instanceof(ref, module.UINT32ARRAY_ID));
assert.deepEqual(module.__getArray(ref), arr);
module.__release(ref);
try { module.__release(ref); assert(false); } catch (e) {};
}
// should be able to distinguish between integer and float
{
let arr = [0.0, 1.5, 2.5];
let ref = module.__retain(module.__allocArray(module.FLOAT32ARRAY_ID, arr));
assert(module.__instanceof(ref, module.FLOAT32ARRAY_ID));
assert.deepEqual(module.__getArray(ref), arr);
module.__release(ref);
try { module.__release(ref); assert(false); } catch (e) {};
}
// should be able to work with normal arrays
{
let arr = [1, 2, 3, 4, 5];
let ref = module.__retain(module.__allocArray(module.ARRAYI32_ID, arr));
assert(module.__instanceof(ref, module.ARRAYI32_ID));
module.changeLength(ref, 3);
assert.deepEqual(module.__getArray(ref), [1, 2, 3]);
module.__release(ref);
try { module.__release(ref); assert(false); } catch (e) {};
}
// should be able to correctly call a function with variable arguments
assert.strictEqual(module.varadd(), 3);
assert.strictEqual(module.varadd(2, 3), 5);
assert.strictEqual(module.varadd(2), 4);
// TBD: table is no more exported by default to allow more optimizations
// should be able to get a function from the table and just call it with variable arguments
var fn = module.getFunction(module.varadd_ptr);
assert.strictEqual(fn(), 3);
assert.strictEqual(fn(2, 3), 5);
assert.strictEqual(fn(2), 4);
// var fn = module.getFunction(module.varadd_ref);
// assert.strictEqual(fn(), 3);
// assert.strictEqual(fn(2, 3), 5);
// assert.strictEqual(fn(2), 4);
// should be able to create a new function and call it from WASM
ptr = module.newFunction(module.varadd);
assert.strictEqual(module.calladd(ptr, 2, 3), 5);
// ref = module.newFunction(module.varadd);
// assert.strictEqual(module.calladd(ref, 2, 3), 5);
// should be able to use a class
var car = new module.Car(5);
@ -68,6 +111,7 @@ car.openDoors();
assert.strictEqual(car.isDoorsOpen, 1);
car.closeDoors();
assert.strictEqual(car.isDoorsOpen, 0);
module.__release(car); // uses Car.prototype.valueOf to obtain `thisPtr`
// should be able to use trace
module.dotrace(42);
module.dotrace(42);