assemblyscript
assemblyscript copied to clipboard
compiler crash: class with externref field
code to reproduce:
// @ts-ignore
@external("http", "_request_get")
declare function _http_request_get(s: string): externref;
class Builder {
inner: externref;
private constructor(inner: externref) {
this.inner = inner;
}
static get(url: string): Builder {
const inner = _http_request_get(url);
return new Builder(inner);
}
}
export function invoke(): void {
let builder = Builder.get("ya.ru");
}
compiler version: "assemblyscript": "^0.18.31" npm version: 7.5.3
stacktrace
▌ Whoops, the AssemblyScript compiler has crashed during compile :-(
▌
▌ Here is a stack trace that may or may not be useful:
▌
▌ AssertionError: assertion failed
▌ at assert (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/std/portable/index.js:199:9)
▌ at h.finishResolveClass (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/resolver.ts:3101:13)
▌ at h.resolveClass (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/resolver.ts:2970:10)
▌ at h.resolveClassInclTypeArguments (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/resolver.ts:3316:17)
▌ at h.resolveNamedType (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/resolver.ts:252:29)
▌ at h.resolveType (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/resolver.ts:154:21)
▌ at h.resolveFunction (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/resolver.ts:2749:23)
▌ at h.maybeInferCall (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/resolver.ts:808:17)
▌ at f.compileCallExpression (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:6243:46)
▌ at f.compileExpression (<cut>/wasm/rt_test/node_modules/assemblyscript/dist/webpack:/assemblyscript/src/compiler.ts:3435:21)
Can confirm a repro with asc --enable reference-types ...
It seems that the offending line: https://github.com/AssemblyScript/assemblyscript/blob/3d52206988b5506aaaea872eb4599a4fcfab5fe6/src/resolver.ts#L3101
In order to store an extern ref, don't we require a Table set? We can't store externrefs on the heap as far as I can remember.
Wouldn't that mean the field would be the index of the table?
Afaik yes.
Background: Doesn't happen automatically currently, because then we'd have to GC table entries via RC from heap objects hooked with a finalizer or something. Not yet supported :)
In the meantime here's a hack to maintain references. The idea is to store them in a javascript map, and use ids to retrieve when needed.
//imports.js
let externId = 0
const externMap = new Map()
return {
set: val => {
const id = externId++
externMap.set(id, val)
return id
},
get: id => externMap.get(id),
delete: id => externMap.delete(id)
}
//myAssemblyscriptClass.ts
//...
const myExtern = doSomethingExternal()
this.externId = imports.set(myExtern)
//later on
const myExtern = imports.get(this.externId)