I think the central issue is that PyPy uses a copying GC, which means pointers to objects aren't stable by default. The article implies that this is a consequence of having a generational GC, but you can have a non-copying generational GC, which Lua 5.2 and 5.4 actually have.[1]
[1] Lua 5.3 dropped the generational GC because real-world results didn't justify the complexity, but apparently for 5.4 they came up with a better design.
Object stability precludes bump-pointer allocation of short-lived temporaries though, and in a very allocation-y language like Python, that's a pretty important.
[1] Lua 5.3 dropped the generational GC because real-world results didn't justify the complexity, but apparently for 5.4 they came up with a better design.