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.

Spec module global instantiation is incorrect #571

Open

Description

@CharlieTap

As globals can now have initial expressions that point to other globals, it's not possible to compute all the initialiser expressions into a vector ahead of global allocation.

For example

(module (global $g i32 (i32.const 0)) (global i32 (global.get $g)))

The second initialiser here would call global.get on a yet to be allocated global

Instead we should probably do

for each global in module

  1. compute initial value
  2. allocate global

Activity

  1. tlively commented on Nov 1, 2024

    @tlively
    Member

    If you allocate the vector to hold the globals and then evaluate the initializer expressions, there's no problem, right? Is there a specific part of the spec that says something incorrect?

  2. rossberg commented on Nov 2, 2024

    @rossberg
    Member

    The Instantiation section actually has a note addressing this:

    [...] Similarly, module allocation and the evaluation of global and table initializers as well as element segments are mutually recursive because the global initialization values val*g, ref t, and element segment contents (ref ) are passed to the module allocator while depending on the module instance moduleinst and store 𝑆′ returned by allo- cation. Again, this recursion is just a specification device. In practice, the initialization values can be determined beforehand by staging module allocation such that first, the module’s own function instances are pre-allocated in the store, then the initializer expressions are evaluated in order, allocating globals on the way, then the rest of the module instance is allocated, and finally the new function instances’ module fields are set to that module instance. This is possible because validation ensures that initialization expressions cannot actually call a function, only take their reference.

    That said, I have plans to refactor the module rules to be more sequential, but that's currently low priority.

  3. CharlieTap commented on Nov 2, 2024

    @CharlieTap
    Author

    Hey @tlively

    Sure so here on allocation it mentions passing in the global initializer values as a prior, it's impossible to compute these before allocation because their expressions can call global get and globals are not yet allocated.

    The allocation function for modules requires a suitable list of external values that are assumed to match the import vector of the module, a list of initialization values for the module’s globals, and list of reference vectors for the module’s element segments.

    Let
    be the module to allocate and
    the vector of external values providing the module’s imports,
    the initialization values of the module’s globals,
    the initializer reference of the module’s tables, and
    the reference vectors of the module’s element segments.

    ...

    For each global
    in
    , do:

    Let
    be the global type obtained by instantiating
    in
    defined below.

    Let
    be the global address resulting from allocating
    with initializer value
    .

  4. CharlieTap commented on Nov 2, 2024

    @CharlieTap
    Author

    This also applies to element segment initial expressions also in the spec, data segments are already after module allocation so they are fine as they are.

    @rossberg
    It's actually a slightly different problem to what you linked, the allocation depending on a partial instance problem has been the case prior to the gc spec. This issue specifically relates global initializer values and element segment values now including global.get as a const express and thus having to come after global allocation

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

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