Skip to content

Add partial wasm codegen for token definitions#155

Open
rvcas wants to merge 4 commits into
mainfrom
token-codegen
Open

Add partial wasm codegen for token definitions#155
rvcas wants to merge 4 commits into
mainfrom
token-codegen

Conversation

@rvcas

@rvcas rvcas commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Replaces the token codegen stub in starstream-to-wasm with real Component-Model output, mirroring the existing utxo codegen. For a token MyToken { ... } it now emits:

export my-token: interface {
  resource token {
    mint: static func() -> token;
  }
  record storage { supply: s32, ... }
  get-storage: func(self: borrow<token>) -> storage;
  set-storage: func(storage: storage) -> token;
}

What's emitted

  • mint is compiled as a constructor: it spawns a fresh token resource at entry (reusing the UtxoMain spawn path in visit_function) and returns an owned token handle, exported as [static]token.<name>. Multiple mints → multiple static constructors.
  • Storage → mutable wasm globals plus the storage record and get-storage/set-storage exports, identical to utxos.
  • burn, impl Token attach/detach, and plain helpers are compiled and validated (real core functions, storage-checked) but not exported yet — see TODOs.

Supporting changes

  • Generalized the resource machinery: UtxoContext/current_utxoResourceContext/current_resource, and generate_storage_exports now takes (name, ty) so tokens and utxos share it (pure refactor).
  • Lowered Type::TokenAny/Type::TokenNamed to an i32 core handle — star_to_core_types has a _ => Err fallthrough that previously missed them (compiled, but errored on a method's self param).

TODOs left (deliberately deferred)

  • TODO(token-burn) — the WIT shape of burn is undecided (consuming [method]token.burn(self: own<token>) vs a resource-drop). Body compiled, not exported.
  • TODO(token-impl-export)attach/detach take a Utxo, i.e. a foreign resource referenced from inside the token interface. The current resource-index model (raw indices shared with world_type) conflates that borrow with the token's own resource, so exporting them produced wrong WIT (borrow<token> instead of borrow<utxo>). Correctly emitting cross-resource references needs encoder index-space work; compiled-but-unexported until then.
  • indexed storage is carried inert (per team decision to handle later).
  • Runtime (starstream-runtime-next) has no token support; out of scope.

rvcas added 4 commits June 25, 2026 11:06
Replace the token codegen stub with real Component-Model output, mirroring
the existing `utxo` codegen:

- Generalize the resource machinery: rename UtxoContext/current_utxo to
  ResourceContext/current_resource and make generate_storage_exports take
  (name, ty) so tokens and utxos share it.
- `mint fn` is compiled as a constructor: it spawns a fresh token resource
  at entry (reusing the UtxoMain spawn path in visit_function) and returns an
  owned token handle, exported as `[static]token.<name>`.
- Storage globals are emitted with the same `storage` record plus
  `get-storage`/`set-storage` exports as utxos.
- Lower `Type::TokenAny`/`Type::TokenNamed` to an i32 core handle (the
  `_ => Err` fallthrough in star_to_core_types previously missed them).

`burn`, the `impl Token` `attach`/`detach` methods, and plain helpers are
compiled and validated but not exported yet:

- TODO(token-burn): the WIT shape of `burn` is undecided.
- TODO(token-impl-export): `attach`/`detach` take a `Utxo`, i.e. a foreign
  resource referenced from inside the token interface. The current
  resource-index model conflates it with the token's own resource, so the
  emitted WIT would be wrong; this needs cross-resource index handling.

`indexed` storage is carried inert. Adds token_mint / token_mint_burn
codegen fixtures and updates the spec's token status note.

Signed-off-by: rvcas <x@rvcas.dev>
Signed-off-by: rvcas <x@rvcas.dev>
Per design clarification: `mint`/`burn` carry no special wasm semantics —
what they do is a runtime concern — so they are generated as ordinary
functions distinguished only by export naming.

- `mint fn` stays a `[static]token.<name>` constructor returning an owned
  token handle.
- `burn fn` is now exported as a plain `[static]token.<name>` function with
  its declared signature (previously compiled but unexported).

`impl Token`'s `attach`/`detach` remain compiled-but-unexported: their `Utxo`
parameter is a foreign resource referenced from inside the token interface,
which the current shared resource-index model mis-resolves to the token's own
resource (it would emit `borrow<token>` instead of `borrow<utxo>`). Exporting
them needs proper cross-resource references in the component encoder.

Signed-off-by: rvcas <x@rvcas.dev>
`Token` is a built-in ABI, so `impl Token` is now generated exactly like a
`utxo`'s `impl <Abi>`: each method is exported as a `[method]` on the token
resource. This drops the earlier hold-back of attach/detach.

The `Utxo` parameter of attach/detach renders as `borrow<token>` rather than
`borrow<utxo>`. This is the same shared resource-index mechanism the utxo
ABI-impl path already uses for foreign-resource parameters (it only looks
correct for utxos because a utxo's own resource is itself named `utxo`), so it
is a pre-existing general codegen limitation, not token-specific.

Signed-off-by: rvcas <x@rvcas.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant