WasmKit icon indicating copy to clipboard operation
WasmKit copied to clipboard

Typed Function References Draft

Open iainsmith opened this issue 11 months ago • 3 comments

Function References Overview Link

👋 I started looking at adding support for the function-references extension. This is very much a work in progress, that I'd appreciate feedback on. I'm still building up context on the codebase, so I suspect I'm missing several fairly obvious issues. If you do check it out locally, feel free to push improvements directly to my branch, and I'll pull them in.

So far:

  • [x] Updated WatParser to support (ref null? $variable) syntax
  • [x] Configure spec tests to run the wast tests for function-references & GC
    • [x] Make SpectestResult top level so that we can track partially implemented proposals.
  • [x] Added an instruction for call_ref (that's not passing the call_ref.wast tests yet)

TODO:

  • [ ] Get call_ref implemented correctly (and stop leaving references on the stack)
  • [x] Add remaining instructions
  • [ ] Get all the Function reference wast test passing
  • [ ] Check the benchmarks

Questions:

I punted on separating out a HeapType struct/enum for now, as I wasn't sure what shape it would land up in, and how big the knock on change would be. Do you have a shape in mind for a HeapType or shall I keep going with the extra cases for ReferenceType for now?

I'm hoping to have more time to work on this, but it will depend on other commitments.


I've got 8/34 of the initial call_ref.wast tests passing, while the rest are failing with Expected i32 on the stack top but got ref(WasmTypes.ReferenceType.funcRef) . Run testFunctionReferencesProposals if you want to reproduce it locally.

iainsmith avatar Jan 04 '25 01:01 iainsmith

Thanks @iainsmith!

I punted on separating out a HeapType struct/enum for now, as I wasn't sure what shape it would land up in, and how big the knock on change would be. Do you have a shape in mind for a HeapType or shall I keep going with the extra cases for ReferenceType for now?

I would suggest following the structure used in the spec like:

/// Reference types
public struct ReferenceType: Equatable, Hashable {
    public var isNullable: Bool
    public var heapType: HeapType

    public static var funcRef: ReferenceType {
        ReferenceType(isNullable: true, heapType: .func)
    }

    public static var externRef: ReferenceType {
        ReferenceType(isNullable: true, heapType: .func)
    }

    public init(isNullable: Bool, heapType: HeapType) {
        self.isNullable = isNullable
        self.heapType = heapType
    }
}

public enum HeapType: Equatable, Hashable {
    /// A reference to any kind of function.
    case `func`
    /// An external host data.
    case extern
}

kateinoigakukun avatar Jan 04 '25 06:01 kateinoigakukun

I added tail-call support in the main branch because function-ref proposal depends on the proposal.

  • https://github.com/swiftwasm/WasmKit/pull/170
  • https://github.com/swiftwasm/WasmKit/pull/171

It might also be a good example to see how to implement a new proposal in WasmKit.

kateinoigakukun avatar Jan 04 '25 14:01 kateinoigakukun

@iainsmith do you have any imminent plans to get this over the finish line?

I wonder if we could get parsing done first and merge that. Full spec implementation could come in a future PR.

MaxDesiatov avatar Oct 07 '25 11:10 MaxDesiatov