fleabitdev / glsp

The GameLisp scripting language
https://gamelisp.rs/
Apache License 2.0
395 stars 13 forks source link

Unnecessary and incorrect MakeStay instruction emitted when a captured variable is rebound to a local #34

Closed fleabitdev closed 3 years ago

fleabitdev commented 3 years ago
(let-fn outer ()
  (let captured 100)
  (let captured2 200)

  (let-fn inner ()
    (let unused captured2)
    captured)

  (prn (inner))) ; prints 200 rather than 100

Disassembly:

FN: inner

        basic params: 0
        (?) params:   0
        .. param:     no
        registers:    1 (0 locals, 1 scratch, 0 literals)
        stays:        2

        bytecode:
                LoadStay(dst_reg: scr0, stay_id: 0)
                MakeStay(src_reg: scr0, stay_id: 1)
                LoadStay(dst_reg: scr0, stay_id: 1)
                Return(src_reg: scr0)

        stays:

                stay_id 0 = Captured(0)
                stay_id 1 = Captured(1)

The MakeStay instruction is unnecessary, and it has an incorrect stay_id which causes it to overwrite another captured variable. Almost certainly something to do with variable aliasing in encoder.rs. Can probably fix this by switching off aliasing when the source variable is a captured stay.

fleabitdev commented 3 years ago

Fixed by af754e5