This is indeed a bug with the JavaScript code generator. The trigger is 
`unsafeAddr v` (that is, taking the address of an immutable parameter).

* * *

To provide some background: in order to allow indirectly modifying a variable 
that is of value type in the final JavaScript code, the code generator "boxes" 
the value by turning it into a 1-element array.

Examples of indirect modifications:
    
    
    proc p(x: var int) =
      x = 2
    
    proc test() =
      var i = 0
      var pointerToI = addr i
      pointerToI[] = 1 # an indirect modification
      doAssert i == 1 # it needs to be observable on `i`
      
      p(i) # also an indirect modification
      doAssert i == 2
    
    test()
    
    
    Run

When reading from or assigning to the location normally, the underlying value 
is accessed via `location[0]`. When taking the address of the boxed location, 
the box (i.e., 1-element array) itself is assigned to the pointer (not entirely 
true, but that's roughly how it work).

Only variables that are potentially modified through an indirection store a 
"boxed" value. The compiler figures out the set of variables by analyzing all 
`addr` operands, hidden address-of operands, and arguments to `var` parameters.

The concrete problem your running into here is that an immutable parameter 
cannot be promoted to use a boxed value. Since `v` has its address taken, 
whenever emitting an access to `v`, it is, incorrectly, unboxed, thus resulting 
in errors at run-time.

* * *

For fixing this bug in the compiler, there are two possible solutions:

  1. for immutable parameters that have their address taken, `jsgen` needs to 
box the value, store it in a temporary, and redirect all usage of the parameter 
to this temporary (what you've effectively done with your workaround)
  2. `jsgen` never treats immutable parameters as being boxed and instead 
creates a boxed value ad-hoc when taking the parameter's address


Reply via email to