To reproduce:
asinit .index.ts to:import "allocator/tlsf";
export function add(a: i32, b: i32): i32 {
new Array<i32>(a);
return a + b;
}
npm run asbuildnode index.js causes an error: TypeError: WebAssembly Instantiation: Import #0 module="env" error: module is not an object or functionYeah, asbuild script needs update. For now you can use this code for index.js:
const fs = require("fs");
const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/optimized.wasm"));
const imports = {
env: {
abort(msgPtr, filePtr, line, column) {
throw new Error(`index.ts: abort at [${ line }:${ column }]`);
}
}
};
Object.defineProperty(module, "exports", {
get: () => new WebAssembly.Instance(compiled, imports).exports
});
This is more a question than an issue, but what's the recommended way to handle unmanaged (heap-allocated but not garbage-collected) objects?
The best I've figured out so far is this:
@unmanaged
class Point {
x: f64;
y: f64;
public sum(): f64 {
return this.x + this.y;
}
}
function alloc_point(x: f64, y: f64): Point {
let p = changetype<Point>(memory.allocate(sizeof<f64>() + sizeof<f64>())); // sizeof<Point> is size of pointer...
p.x = x;
p.y = y;
return p;
}
function free_point(p: Point): void {
memory.free(changetype<usize>(p));
}
export function test(a: f64, b: f64): f64 {
let p = alloc_point(a, b);
let res = p.sum();
free_point(p);
return res;
}
The disadvantage is that I need to write alloc_X and free_X functions for every type (requires casts if there are readonly or private members). It would be nice to have emplacement and destructors like in c++ so we could have unique_ptr and arrays that store their elements by-value instead of storing pointers. Is there an issue already open similar to this?
Note that emplacement-style signatures can be typed in typescript:
type CtrParams<Ctr> = Ctr extends new (...args: infer P) => unknown ? P : never;
type CtrReturn<Ctr> = Ctr extends new (...args: any[]) => infer T ? T : never;
class Point { constructor(readonly a: number, readonly b: number) {} }
declare class ByValueArray<TCtr> {
emplace(...params: CtrParams<TCtr>): CtrReturn<TCtr>;
}
let v = new ByValueArray<typeof Point>();
let p: Point = v.emplace(1, 2);
You could use:
function alloc<T>(): T {
return changetype<T>(memory.allocate(offsetof<T>()));
}
function free<T>(obj: T): void {
memory.free(changetype<usize>(obj));
}
var p = alloc<Point>();
...
free(p);
Here, offsetof<Point>() returns the size of a Point structure with all fields layed out.
Closing this issue for now as it hasn't received any replies recently. Feel free to reopen it if necessary!
Most helpful comment
Yeah, asbuild script needs update. For now you can use this code for
index.js: