Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Remove anyref #254

Closed
Closed
@RossTate

Description

@RossTate

The Overview describes the purpose of anyref to be to support the sort of uniform representation typically used by polymorphically or dynamically typed GC languages. However, we have seen that these languages are not using anyref for their uniform representation. In short, no one has first-class values corresponding to function references, and as such everyone is using eqref for its uniform representation at the least. So there appears to be no particularly good reason to have anyref.

On the other hand, there are good reasons to not have anyref:

  1. The subtyping externref <: anyref forces JS values to be coerced to and from externref. For example, V8 uses SMIs, which conflict with i31ref, and so the coercion to externref requires boxing SMIs and requires unboxing i31ref-values-as-JS-values, and the reverse coercion has to do the opposite. Removing anyref would enable us to eliminate this coercion.
  2. When we were discussing long-term JS API considerations, one thing that came up was being able to access fields of typed JS objects directly from within WebAssembly. One way we could do this would be to import externref field accessors/members. However, the coercions required by the externref <: anyref subtyping prevent this, since those fields would store JS values in their "native" JS representation rather than their wasm representation. Removing anyref would enable us to have direct field accessors/members into typed JS objects.
  3. The instance-object model we're currently using means that many translations of GC languages into WebAssembly have to use closures where they would normally have just code pointers. Indeed, we're seeing substantial overheads in specifically the translations using function references, and my experiments (outside of wasm) suggest that using closures in place of code pointers indeed causes substantial overhead due to the extra chained load on a key language operation. One way we could reduce this overhead is to use a wide representation for function references, so that the code pointer sits alongside its environment (typically the instance-object) in memory, thereby reducing a chained load to a parallel load (and also likely improving locality). However, the funcref <: anyref subtyping forces function references to be represented the same as data references, preventing this optimization. Removing anyref could help us overcome the performance issues the current proposal is facing.

So, because anyref is not needed for its intended purpose, and because its presence obstructs various features and optimizations, I propose we remove it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions