Closed Bug 1675602 Opened 3 months ago Closed 1 month ago

Use WebAssembly's type system for TypedObject's


(Core :: Javascript: WebAssembly, task, P3)




85 Branch
Tracking Status
firefox85 --- fixed


(Reporter: rhunt, Assigned: rhunt)


(Depends on 1 open bug, Blocks 1 open bug)



(12 files)

47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review
47 bytes, text/x-phabricator-request
Details | Review

We only allow typed objects to be constructed by wasm. We should replace the TypedObject type system with WebAssembly's to simplify code and reuse infrastructure.

This is a non-functional change. Adds a FuncDesc similar to TableDesc and GlobalDesc
instead of the the array-of-structs funcTypes and funcTypeIndices. This will be
expanded in a later commit that removes FuncTypeIdDesc from TypeDef.

A later commit will re-use TypeDef for a wasm::TypeContext that
can be used during compilation and at runtime. Currently
TypeDef::IsFunction indicates there is a FuncTypeIdDesc which
describes the runtime representation of a function runtime-type.

This commit removes FuncTypeIdDesc from TypeDef and moves it to
ModuleEnvironment so that TypeDef can be used at runtime.

Depends on D96212

This commit is a non-functional change to rename FuncTypeIdDesc
to TypeIdDesc. A later commit will re-use this type for all types
that require a runtime representation, not just functions.

Depends on D96213

Currently function types needed for runtime signature checks (can't fit in an
immediate) are transferred through wasm::Metadata. This commit generalizes this
method to transfer a vector of TypeDef's representing all types that need a
runtime representation. Type indices are renumbered for function types that
are omitted because they fit in an immediate.

The dense structTypes_ vector in Instance is recreated as a stopgap during
instantiation. StructType::moduleIndex_ is removed and TypeIdDesc allocates
global data space to store the index to the dense structTypes_ vector in
Instance. The baseline compiler loads the index before calling
narrow. This is suboptimal and a stopgap until the TypeIdDesc allocates space
for a TypeDescr* later in this commit stack and the structTypes_ vector
is removed.

Depends on D96214

This commit introduces wasm::TypeContext as a semantic type index space
over wasm funcs, structs, and arrays. Module validation is updated
to use this.

Depends on D96215

Introduce a global wasm::TypeContext for storing and managing
wasm types at execution time for instances.

Depends on D96216

wasm::Val and WasmGlobalObject both have a tagged WebAssembly value
implementation. Replace WasmGlobalObject's implementation with
wasm::Val's. wasm::Val gains the ability to have proper write
barriers as a result.

Depends on D96217

There are two independent implementations of ToWebAssemblyValue/
ToJSValue. One in WasmJS.cpp and another in WasmInstance.cpp. The
first was moved to WasmTypes.cpp in the previous commit. This commit
moves the second over to WasmTypes.cpp as well. A later commit
will unify the two implementations.

Depends on D96218

A previous commit added ValType::isExposable() for types
that have no JS representation (currently (ref T) and v128).

This commit changes stub generation to check !isExposable()
instead of !isV128() so that (ref T) will be excluded.

Depends on D96219

The major difference between the two separate implementations
of ToJSValue is that the one operating on void* to have
!isExposable() filtered out by callers and generates a plausible
value for !isExposable() values. This allows the function to be
used by the debugger and not trigger errors in functions that have

This commit unifies both ToJSValue implementations to expect
!isExposable() values filtered out by callers and will return
a plausible value (now 'undefined') for users like debuggers
who want something. All callers that expect an error now check
isExposable() before calling the coercion function.

Depends on D96220

This commit combines the two independent ToWebAssemblyValue and
ToJSValue implementations now that they have the same functional

Depends on D96221

This commit removes TypedObject's type system (StructTypeDescr,
ArrayTypeDescr, ScalarTypeDescr) and replaces it with a
wasm::TypeHandle to a wasm::TypeDef inside the global
wasm::TypeContext. TypeDescr is left as a JSObject that
wraps a wasm::TypeHandle for a TypedObject. In the future
it will likely be re-used for a RttValue.

When instantiating a module, types are transferred to
the global context and TypeDescr objects wrapping the type handles
are created. The TypeDescr objects are placed in TlsData
for the TypeIdDesc corresponding to the StructType.

Depends on D96222

The first several patches here work to create an 'execution-time' representation of WebAssembly types.

  • Removing compilation-time or module-local information from StructType/FuncType
  • Copying a TypeDefVector with correct index space to wasm::Module/Instance
  • Adding a TypeContext used for module compilation and for the global runtime

Then there are several patches which simplify our Wasm/JS coercion code for later re-use in TypedObjects

  • Combining tagged wasm::Val with WasmGlobalObject, using ToWebAssemblyValue/ToJSValue (from WasmJS.cpp) for both
  • Unifying the two independent ToWebAssemblyValue/ToJSValue implementation behaviors around non-exposable types (e.g. v128, (ref T)) (from WasmJS.cpp/WasmInstance.cpp)
  • Combining the two ToWebAssemblyValue/ToJSValue functions

Then the final patch does the real work of using the runtime type representation and Wasm/JS features with TypedObjects

  • ArrayTypeDescr/StructTypeDescr are gone
  • TypeDescr wraps a handle to global wasm::TypeContext (TODO: wasm types are leaked over runtime and not collected)
    • TypeDescr is a good candidate for a future RttValue
  • TypedObject uses Wasm type information for struct layout/property types
  • TypedObject uses ToJSValue for reading typed memory

There are several functional changes from this.

  • Property access is done through indexing (e.g. t[1] not t._1)
  • i64 fields re-use bigint behavior from ToJSValue (no more t._1_low/t._1_high)
  • struct.narrow works across module boundaries
  • no more StructType/ArrayType constructors that are observable from typedObject.constructor

There are some r+ patches which didn't land and no activity in this bug for 2 weeks.
:rhunt, could you have a look please?
For more information, please visit auto_nag documentation.

Flags: needinfo?(rhunt)
Pushed by
Replace ModuleEnvironment::funcTypes with FuncDesc. r=lth
Remove FuncTypeIdDesc from TypeDef. r=lth
Rename FuncTypeIdDesc to TypeIdDesc. r=lth
Transfer TypeDefVector to runtime through wasm::Metadata. r=lth
Introduce wasm::TypeContext and use in ModuleEnvironment. r=lth
Add global wasm::TypeContext to JSContext. r=lth
Combine wasm::Val and WasmGlobalObject implementations. r=lth
Move other ToWebAssemblyValue/ToJSValue implementations to WasmTypes.h. r=lth
Use ValType::isExposable in function entry and exits. r=lth
Unify handling of unexposable types between coercion functions. r=lth
Combine ToWebAssemblyValue and ToJSValue implementations. r=lth
Use WebAssembly's type system for TypedObject. r=lth
Flags: needinfo?(rhunt)
Depends on: 1687417
You need to log in before you can comment on or make changes to this bug.