-
Notifications
You must be signed in to change notification settings - Fork 452
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
Should we allow module-defined globals in get_global initializer expressions? #367
Comments
V8 also follows initialization order in parsing the binary. The import section, which can declare imported (immutable) globals, must appear before any sections that can have initializer expressions, including globals themselves. Therefore it's sufficient to parse the import section and add each imported global to a list of globals. Then when parsing the globals section, checking that the initializer expressions is valid is a simple check that they can only refer to previously declared globals. Otherwise it's an error; cycles are not allowed. Since only immutable globals can be imported, at instantiation time, all imports are resolved in the order they were declared in the imports section, and there is only a single JS-level access to the imports object for each global. So imported immutable globals are initialized with (number) values before beginning the initialization of the other globals. |
Yes, as the presence of the tests indicate, it is intended behaviour that initializer expressions can only refer to previous globals (precisely to avoid cycles). Like many other details of validation, the design docs just don't mention this. As @titzer says, imports always have to occur before all internal definitions, so that case is also well-defined. I'm not sure I understand what you are getting at in the rest of your comment. An engine is of course free to handle or compile initialisation any way it sees fit, including "inlining" other expressions, as long as it has the observable behaviour of the specified semantics. So I am not aware of any disagreement between design and spec on this. Can you clarify what fixes you think are needed specifically? |
That it is technically doable is indeed irrefutable. My question was rather that the design doc says:
In this case, we have edit (still not a question :)) So is the design doc lagging behind, or the ml-proto deviating from the design? |
Ah, I see, thanks! Yes, that's indeed inconsistent between design and spec. I hadn't noticed it. I don't have any particular preference regarding which one should be adjusted. Presumably, implementations run the test suite, so would match what the spec says. As @titzer said, V8 does. |
(SM implements what was written in the design doc and we're just now updating to run the latest test suite, hence this issue.) I know they can both be implemented easily, but there does seem to be a categorical difference: if Thus, I'd slightly prefer to change the interpreter/tests to match the design doc. |
On Thu, Oct 27, 2016 at 11:11 AM, Benjamin Bouvier <notifications@github.com
|
@titzer There's still the apparent ordering dependency and, technically, as long as we don't allow |
So could we design as-is and fix the interpreter/test to match? (This is a conservative start and could be relaxed later.) |
I have developed a minor preference for allowing it, because it would be the only place where we'd make a distinction between uses of imported and internal definitions, which is a bit odd. |
Agreed we're in "light preference" territory, but I think there will need to be a restriction on the index either way: the difference is whether it's simply "only the imports" vs. "only preceding" and the latter also seems a bit special. |
I'm OK with making the restriction to immutable imports for now. @rossberg-chromium pointed out that this extra restriction would need to be part of the formal spec, but as the formalization right now is currently more general than implementations in other areas, I suppose this is OK. |
Okay, I will change the interpreter then. |
Here you go: #383. |
Thanks! |
Merge pull request #2174 from Cellule:wasm/elem Check if a table is present when reading an element section Validate the init_expr for element and data segments Disallow internal global in init_expr The issue WebAssembly/spec#367 made me realize we were doing the same thing the spec interpreter was which was not according to the design documents Check the type of init_expr for globals
Merge pull request #2174 from Cellule:wasm/elem Check if a table is present when reading an element section Validate the init_expr for element and data segments Disallow internal global in init_expr The issue WebAssembly/spec#367 made me realize we were doing the same thing the spec interpreter was which was not according to the design documents Check the type of init_expr for globals
Replace them with assert false, to indicate that those aren't supposed to happen, rather than unimplemented.
https://github.com/WebAssembly/design/blob/master/Modules.md#initializer-expression says that the only globals allowed in
get_global
initializer expressions should be immutable imports:There are tests in
memory.wast
that use module-defined globals inget_global
initializer expressions:https://github.com/WebAssembly/spec/blob/master/interpreter/test/memory.wast#L13-L16
In particular, since globals can be initialized with initializer expressions, we can have cycles:
The spec interpreter refuses this because it follows initialization order, and
$bar
is not known when we define$foo
. I just found out there's actually a test for this inglobals.wast
, so this is probably intended behavior here, and probably the reasonable choice if we want to allow module-defined globals to appear in global initializer expressions.What if we have an imported global, and another global is initialized by
get_global
on this imported global? (that's equivalent to the second global importing the same field, modulo JS strange behavior (if there's a proxy/getter on the imported object field))In general, instead of doing a
get_global
with a module-defined global $foo as an operand, in an initializer expression of global $bar, a wasm generator can just use the initializer expression of $foo for initializing $bar, preventing a spurious indirection here.In any cases, it seems that either the design repository is not up to date, or the ml-proto is drifting a bit away from the design.
The text was updated successfully, but these errors were encountered: