WebAssembly / WebAssembly/component-model

Proposal: simple instance lowering?

Open
#8 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
WebAssembly
Stars
1.4k
Forks
130
Avg merge
2d 1h
Merged PRs (30d)
15

Description

Overview of current problem

Assume there is an interface named example with this definition (in wit):

func1: function(x: string) -> string
func2: function(y: list<s32>)
func3: function(z: tuple<s8, s64>)

And a component imports the example interface as an instance:

(component
  (module (;0;) ...) ;; inner core implementation module
  (type (;0;) (func (param "x" string) (result string)))
  (type (;1;) (list s32))
  (type (;2;) (func (param "y" (type 1))))
  (type (;3;) (tuple s8 s64))
  (type (;4;) (func (param "z" (type 3))))
  (type (;5;) 
    (instance
      (alias outer 1 (type (;0;) 0))
      (export "func1" (type 0))
      (alias outer 1 (type (;1;) 2))
      (export "func2" (type 1))
      (alias outer 1 (type (;2;) 4))
      (export "func3" (type 2))
    )
  )
  (import "example" (instance (;0;) (type 5)))
  (module (;1;) ...) ;; shim module for use with `into` option for import lowering
  (instance (;1;) (instantiate (module 1)))
  ;; begin lowering boilerplate
  (alias export (instance 0) "func1" (func (;0;)))
  (alias export (instance 0) "func2" (func (;1;)))
  (alias export (instance 0) "func3" (func (;2;)))
  (func (;3;) (canon.lower utf8 (into (instance 1)) (func 0)))
  (func (;4;) (canon.lower utf8 (into (instance 1)) (func 1)))
  (func (;5;) (canon.lower utf8 (into (instance 1)) (func 2)))
  (instance (;2;) core (export "func1" (func 3)) (export "func2" (func 4)) (export "func3" (func 5)))
  ;; end lowering boilerplate
  ;; we now have instance 2 (a lowered form of instance 0) that the core implementation module may import
  (instance (;3;) (instantiate (module 0) (with "example" (instance 2))))
  ...
)

To be able to pass the instance import through to the inner core module, we must iterate all of the functions exported on the instance, alias them into the component's function index space, lower each individual function, create a new core instance with the lowered functions, and then finally pass the instance through as an instantiation argument.

This is potentially a lot of boilerplate needed to lower each imported instance to the inner core module; additionally both the aliased functions and their lowered forms don't really need to exist in the component's function index space as they only serve as something temporary to synthesize the instance being imported by the core implementation module.

Proposal

Add a way to declare lowered instances to both the text and binary formats. A lowered instance is a new instance with a core instance type that exports functions of the same names as the component instance type, but with lowered function types as if each exported function were explicitly lowered.

Binary format change
instanceexpr ::=
               ...
               | 0x03 opt*:<canonopt>* i:<instanceidx> => (instance lower i))
Text format change
instanceexpr ::=
               ...
               lower <canonopt>* (instance <instanceidx>)
Validation
  • i:instanceidx is a component instance type that only exports functions.
  • The canonical options are validated according to the same rules as lowering functions; applies to all
    functions exported by the instance.
Production

Produces an instance of core instance type where all exports are functions of the lowered function types.

Example

Lowering an instance of type:

(type
  (instance
    (type (;0;) (func (param "x" string) (result string)))
    (type (;1;) (list s32))
    (type (;2;) (func (param "y" (type 1))))
    (type (;3;) (tuple s8 s64))
    (type (;4;) (func (param "z" (type 3))))
    (export "func1" (type 0))
    (export "func2" (type 2))
    (export "func3" (type 4))
  )
)

Produces an instance of (hypothetical) core type:

(type
  (instance core
    (type (func (param i32 i32 i32)))
    (type (func (param i32 i32)))
    (type (func (param i32 i64)))
    (export "func1" (type 0))
    (export "func2" (type 1))
    (export "func3" (type 2))
  )
)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the instanceexpr grammar and the proposal's binary and text format sections. Then trace the validation and production requirements for lowering an instance, using the provided WAT examples as the expected behavior. Done means both formats support lowered instances with validated canonical options and lowered function exports.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.