threads icon indicating copy to clipboard operation
threads copied to clipboard

Why does WebAssembly.Global.prototype not have accessors for mutability and type?

Open lars-t-hansen opened this issue 7 years ago • 4 comments

The global has an accessor for value, but not for its mutability and type properties. If I read the value and I see '37' I can't infer the type, since that could be any of the three allowed numeric types.

Is this an oversight or a conscious design choice? cc @binji

lars-t-hansen avatar Jan 10 '18 13:01 lars-t-hansen

I'd say for the same reason that e.g. tables or modules do not currently support inquiring similar type information. All this should be added, but requires designing a coherent approach to reflecting Wasm types on the JS side. I think there was some related discussion on the design or spec repo, but I can't find it right now.

rossberg avatar Jan 10 '18 14:01 rossberg

Yeah, I was generally providing the minimal API that would support the desired functionality. But you're right, providing the type and mutability seem useful. Agreed with @rossberg that reflecting types is not clear just yet. We could easily provide a string property, but that's probably not what we'll want long term.

binji avatar Jan 10 '18 19:01 binji

We could easily provide a string property, but that's probably not what we'll want long term.

Probably not, but then the question is, why are we accepting strings in the descriptor when we create a WebAssembly.Global?

This seems analogous to the situation with WebAssembly.Global itself. Some things can only happen once wasm has evolved to a certain point and we have a clearer view of what's in front of us. To reach that point, wasm must however evolve, and the thing we can only do in earnest later we must start to do now. In the case of globals, we started by exporting the values; we are now trying to export WebAssembly.Global objects, and we will also accept those objects on import, so that we can talk about mutables. In the case of types, perhaps we must start by accepting them and revealing them as string names, but leave the door open to reflect & accept them as objects, later.

Can we enshrine this as some sort of design pattern? We seem to have made things work reasonably well with the @@toPrimitive hook for WebAssembly.Global (#73). For the type, we could stipulate that the result of the type accessor of a WebAssembly.Global instance is a string now but may be something else later and that comparing the returned value to a string, or using the returned value as the type property when creating a new WebAssembly.Global, will always work, but that inspecting the precise type of that returned value may change over time.

lars-t-hansen avatar Jan 11 '18 09:01 lars-t-hansen

Perhaps we should just byte and settle the type representation. In the other discussion I cannot find anymore I suggested simply encoding the type AST JSON-style, with objects and strings. For example, in TypeScript-ish notation:

type ValueType = "i32" | "i64" | "f32" | "f64"
type ElemType = "anyfunc"
type GlobalType = {value: ValueType, mutable: Bool}
type MemoryType = {limits: Limits}
type TableType = {limits: Limits, element: ElemType}
type Limits = {min: num, max?: num}
type FuncType = {params: ValueType[], results: ValueType[]}
type ExternType = {func: FuncType} | {memory: MemoryType} | {table: TableType} | {global: GlobalType}

Then each of the classes would have a type method returning a respective object (which should probably be frozen and cached per instance).

Ideally, the each constructor should then take a corresponding type argument. Unfortunately, the Memory and Table constructors already have slightly different schemes. As you say, we are at a similar point for the Global constructor. I suggest getting at least that one right. I suppose we could also extend the other two to accept either a type or the existing descriptors.

rossberg avatar Jan 11 '18 11:01 rossberg