Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec module global instantiation is incorrect #571

Open
CharlieTap opened this issue Nov 1, 2024 · 4 comments
Open

Spec module global instantiation is incorrect #571

CharlieTap opened this issue Nov 1, 2024 · 4 comments

Comments

@CharlieTap
Copy link

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
@tlively
Copy link
Member

tlively commented Nov 1, 2024

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?

@rossberg
Copy link
Member

rossberg commented Nov 2, 2024

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.

@CharlieTap
Copy link
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
.

@CharlieTap
Copy link
Author

CharlieTap commented Nov 2, 2024

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants