asm-js / validator

A reference validator for asm.js.
Apache License 2.0
1.78k stars 154 forks source link

Fround annotations break hoisting semantics #111

Open ghost opened 9 years ago

ghost commented 9 years ago

Regarding argument annotations, the last sentence of section 5.1 of the spec reads:

... the third [form annotates] as type float. In the latter case, Lookup(Δ, Γ, f) must be fround.

But f's variable environment Γ does not yet exist. It is constructed during ValidateFunction(Δ, f), which necessarily occurs after the "completed" global environment Δ is constructed, and therefore after f's argument annotations are inspected (according to the procedure given in section 6.1).

This raises a deeper concern relating to JavaScript's variable hoisting semantics and float-annotated arguments (and returns), best explained by a simple example:

function M(std) {
  "use asm"
  var f = std.Math.fround
  function g(x) {
    x = f(x)
    var f = 1
    return f(x)
  }
  return g
}

Without AOT compilation, M(window)(0), for example, raises an exception, but with AOT compilation, no such exception is raised. This suffices to contradict (in section 1):

the execution semantics [of asm.js] is simply that of JavaScript

Variable hoisting only causes such problems when a function f contains a local variable whose identifier is equal to that of a global variable that imports Math.fround. Otherwise, in terms of f's observational behaviour, it is immaterial whether its local variable declarations are in fact hoisted above its argument annotations. A straightforward solution follows; ValidateFunction(Δ, f) must insist that the identifier x of each local variable is such that Δ(x) ≠ imm fround.

ghost commented 9 years ago

Update:

A related issue. Consider the following valid module, according to both the specification and OdinMonkey:

function M(std) {
  "use asm"
  var f = std.Math.fround
  function g(f) {
    f = f(f)
  }
  return g
}

Without AOT compilation, M(window)(0), for example, raises an exception, but with AOT compilation, no such exception is raised. It follows that ValidateFunction(Δ, f) must also insist that the identifier x of each argument annotation is such that Δ(x) ≠ imm fround.