assemblyscript icon indicating copy to clipboard operation
assemblyscript copied to clipboard

compiler crash: class with externref field

Open bmartynov opened this issue 3 years ago • 6 comments

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)

bmartynov avatar May 19 '21 17:05 bmartynov

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

willemneal avatar May 19 '21 18:05 willemneal

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.

jtenner avatar May 19 '21 22:05 jtenner

Wouldn't that mean the field would be the index of the table?

willemneal avatar May 19 '21 23:05 willemneal

Afaik yes.

jtenner avatar May 20 '21 00:05 jtenner

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 :)

dcodeIO avatar May 20 '21 01:05 dcodeIO

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)

mrchantey avatar Apr 13 '22 10:04 mrchantey