Closed brabalan closed 6 years ago
Dealt with 07f480c1dc1758afb7a31bbe53b838ba95131221
Shadowing is broken when binding to variables in patterns. This may also apply to tuple patterns and elsewhere in the codebase.
ppf_match_binders
needs to be changed to only use var
if not shadowing, and each caller to it.
binders
is a list of strstr,should be list of strstr*bool (corresponding to check shadowing).
Chase the resulting type errors:
Similar with tuple_component_bind
.
Test for pattern binders added in 9c8d4c3
Fix committed in fe7d1526
Do not use the environment to detect shadowing: detect shadowing for the wrong reason.
The only time a var is not fine is a match for the same value. Non-monadic let with the same value.
Restrict shadowing check.
1) Handle our own list of variable declarations. List of things declared in current JS scope. 2) Disable shadowing. 3) Name reuse in monadic calls are not shadowed, so should be fine.
Alternative approach: do automatic renaming to avoid shadowing
ppf_ident_name
takes an additional shadow map argument sm
to rename the identifier, pass an empty map to not rename anythingdo_check_shadowing
takes the map as argument and use it to compute the renamed name, it returns the updated map
Function argument patterns do not need a shadowing check, as they shadow in both JS and ML.
Todo
ppf_match_binders
to always introduce var
apply_dest
to always introduce var
Scoping still possibly broken. In jsjsref, running the following test results in a failed heap lookup in the first field dereferencing. This is resulting from a location being compared with an object value. Somewhere a type-cast hasn't stuck. This is either due to the type-casting function being incorrectly compiled, or more likely due to miscompilation of the complex scoping of the base
variable in get_value
in JsInterpreter.ml. base
is rebound 5 locations in this function, including with let%ret
and let%OBJECT_ret
binders.
var x = { a : { c : 1 } };
x.a.b = 2;
x.a.x = x;
x
get_value
is miscompiled. In particular:
let_ret(..., function(_tuple_arg_5) {
var base𝟙 = _tuple_arg_5[1];
var s𝟘 = _tuple_arg_5[0];
return ( object_internal_get(s, base𝟘, get_referenced_name(v𝟘), get_this_value(v𝟘)));
})
corresponds to
let%ret (s, base) = ...
in object_internal_get s base (get_referenced_name v) (get_this_value v)
It would appear that a tuple pattern in a monadic let binding is not updating the shadowing map.
Whilst fixing this, I've noticed much duplicated code for various sections of the compiler, particularly in function compilation having a monad special case.
I'm also finding that mixing in of logged, unlogged, token generation and psuedocode modes make reading the core compilation code extremely hard to read. In the long run it may be worth refactoring the code generation to output to a JS AST, which then has further passes to generate the various variants of output.
We should always use shadowing for state. For instance
should be