Skip to content

Support classes that operate like structs/value-types on the stack #2254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
leighmcculloch opened this issue Apr 8, 2022 · 8 comments
Open

Comments

@leighmcculloch
Copy link

leighmcculloch commented Apr 8, 2022

Something that would be useful for some applications of wasm modules is to be able to define structured types that are stored on the stack.

This is also useful in cases when it is desirable to avoid use of the heap/linear-memory, but code structure would benefit from storing multiple values inside a structure together, like a class.

This could be a decorator, similar to @unmanaged. It's worth noting that @unmanaged gets us part-way in that the memory the type uses on the heap is smaller and doesn't have the GC header.

It might look like this.

@stack
class Config {
  constructor(public field: u64) { }
}

I imagine there are a few terms that would suit, such as:

  • @stack
  • @struct
  • @valueType

Related to #2253

@MaxGraey
Copy link
Member

MaxGraey commented Apr 8, 2022

This may be possible via @record and tuples. But it required multi-values Wasm proposal. We have discussed this more than once in the chat room and in the issues

@graydon
Copy link

graydon commented Apr 8, 2022

As it happens we're only interested in types that are represented as single u64 values -- not enough wasm producers or consumers support multivalues to bother with that.

All this feature wants is a "newtype", a way of declaring some type that is representationally equal to an existing wasm type but type-disjoint, so it can't be used as an argument in an incorrect context.

@dcodeIO
Copy link
Member

dcodeIO commented Apr 9, 2022

So if I understand correctly, the type-disjoint bit is the difference to #2253 here, exposing the underlying value as a quasi field. The observation that this can quickly go into the direction of multi-value seems valid, though. Perhaps to recap the bits on multi-value, even though not exactly the same here but for reference: Options thought about so far are tuple types, say [i32, f64], but these would confuse TypeScript since it sees these as arrays. Another one, that is more aligned with this issue, was return types like : { a: i32, b: f64 }, which would work since there are no such object types yet (must be a class name), but has its own issues, like mandatory destructuring into multiple locals upon receiving such a return value, and of course, again the question what TS will do with it. Getting to the edge of what's possible to express with TS syntax.

@dcodeIO
Copy link
Member

dcodeIO commented Apr 9, 2022

Reminds me that there is a related mechanism already doing something similar:

@final @unmanaged
class Stacky<T> {
  @inline constructor(value: T) {
    return changetype<Stacky<T>>(value);
  }
  get value(): T {
    return changetype<T>(this);
  }
}

var stacky = new Stacky<usize>(42);
stacky.value;

Currently limited to usize, though. Needs some way to annotate the this type. Perhaps a starting point?

@jeaiii
Copy link

jeaiii commented Apr 19, 2022

Passing small classes by value (<= 32 bytes) would go a long way in making AssemblyScript a viable choice over C++ or Rust when targeting wasm

@yjhmelody
Copy link
Contributor

yjhmelody commented Jul 7, 2022

Proposal a style to create a stack value if could support this feature: a built function: let foo = stackNew<Foo>(...).

@yjhmelody
Copy link
Contributor

Return multi-value could be optimized to pass a new multi-value pointer as arg to hold it.

@gfusee
Copy link

gfusee commented Oct 7, 2022

Any news about this? It would be awesome to have structs like in Rust!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants