assemblyscript
assemblyscript copied to clipboard
Support classes that operate like structs/value-types on the stack
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
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
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.
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.
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?
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
Proposal a style to create a stack value if could support this feature: a built function: let foo = stackNew<Foo>(...)
.
Return multi-value could be optimized to pass a new multi-value pointer as arg to hold it.
Any news about this? It would be awesome to have structs like in Rust!