Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Allow mutable global imports to be used in init expressions? #5

Open
lars-t-hansen opened this issue Mar 22, 2018 · 8 comments
Open

Comments

@lars-t-hansen
Copy link
Collaborator

This is actually a somewhat compelling use case:

(module
  (global $g1 (import "foo" "bar") (mut i32))
  (global $g2 i32 (get_global $g1)))

My understanding from Luke is that previously, we did not allow global initializers to reference mutable globals in order to avoid circularities in initialization (not the only way to avoid that but an obvious way). With importable mutable globals there would not have been a circularity problem in referencing them from initializers, but we did not have importable mutable globals. Now we do. So should we lift the restriction to allow the above example to work?

@binji
Copy link
Member

binji commented Mar 22, 2018

I thought that we were preventing circular dependencies by preventing defined globals from using referencing non-imported globals in their init expression, and mutability was orthogonal.

In any case, another thing to consider is that we use init expressions for data and element offsets as well. Not sure if that matters much.

Since we're single threaded, and the threads proposal makes globals thread-local, it seems like importing mutable globals here should be safe enough.

@jfbastien
Copy link
Member

How would this interact with ES6 module integration? /cc @linclark

@lukewagner
Copy link
Member

The original goal was indeed to prevent circularity by limiting the init-exprs of defined (i.e., non-imported) globals to imported globals. (I forgot the constness requirement was added, but it's not technically an observable restriction in the v.1 spec since global imports must be const.)

The current way we're thinking about ESM integration is that instantiation (during the overall module loader Instantiation phase) takes a "snapshot" of its imported bindings, so I think there is no problem with imported mutable globals here since the core wasm spec would specify taking a snapshot during instantiation.

[To wit, lest anyone else be initially confused, reading the validation rules for init expressions suggests that any (imported or defined) const global can be used, however, module validation only includes imported globals in the C.globals context field when validating init expressions.]

@lukewagner
Copy link
Member

Oh, and +1 to the proposal to drop the const requirement when validating get_global in init exprs.

@binji
Copy link
Member

binji commented Mar 22, 2018

[To wit, lest anyone else be initially confused, reading the validation rules for init expressions suggests that any (imported or defined) const global can be used, however, module validation only includes imported globals in the C.globals context field when validating init expressions.]

Folks have been confused by this a few times, I recall. Perhaps we should add a note to the validation section to this effect.

@lukewagner
Copy link
Member

Good point; I'll note this in the validation spec review.

@xtuc
Copy link

xtuc commented Mar 23, 2018

How would this interact with ES6 module integration

My solution to not having the ES modules live bindings in wasm was to fake importable mutable globals (details here). To answer your question that would definitely help.

@titzer
Copy link

titzer commented Mar 26, 2018

I don't understand the use case properly. Is the idea that one global is an immutable cache of another, imported mutable global? If so, I think forcing the module to do this explicitly in its start function is better.

Importing mutable things is fraught with peril, particularly globals, since we have not specified how globals are shared at the core WASM level. As such they might in the future apply to imported mutable globals which are concurrently modified. This exposes the access order of the initialization and also interacts with the memory model, which would require definition of synchronization associated with the imports.

In essence, I think we'll end up with an inherently racy mechanism in the future, which won't be fixable without an implicit lock protecting all mutable globals across all modules, which might actually be impossible.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants