-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Lua 5.4 to-be-closed #45
Conversation
Does not support errors, coroutines yet
Codecov Report
@@ Coverage Diff @@
## lua5.4 #45 +/- ##
==========================================
+ Coverage 86.08% 86.35% +0.26%
==========================================
Files 90 90
Lines 9827 9920 +93
==========================================
+ Hits 8460 8566 +106
+ Misses 1076 1063 -13
Partials 291 291
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me so far!
This allows stopping a suspended (not dead) coroutine and cleanup all of its pending to-be-closed variables.
To-be-closed variables are a new feature of Lua 5.4: https://www.lua.org/manual/5.4/manual.html#3.3.8
See added tests in
locals.lua
for working examples andthread.lua
for coroutine tests, including the use ofcoroutine.close()
.The feature is under-specified somewhat in the Lua docs.
Need to support
Approach
I try to give a succinct explanation of the implementation approach.
Height of a lexical scope
During AST -> IR compilation, a height is assigned to each lexical scope. If L2 is a lexical scope with parent L1, then
If L is a root lexical scope (i.e. it is the outermost block in a function body) then
Code generation
There are 2 new opcodes:
clpush <reg>
: push the contents of<reg>
onto the close stackcltrunc h
: truncate the close stack to heighth
(h
is encoded in the opcode and must be known at compile time)This is how the opcodes are inserted
local x <close> = val
), aclpush r1
instruction is emitted, wherer1
is the register containingval
.cltrunc h
instruction is emitted whereh
is the height of the parent scope ofL
cltrunc h
instruction is emitted whereh
is the height of the lexical scope of the jump destination.Runtime
There are two aspects to the runtime machinery - normal execution of Lua continutaions and error handling
Normal execution of Lua continuations
Each Lua continuation maintains a close stack, which is a stack of Lua values. It starts empty and is modified as follows
clpush <reg>
pushes the value of<reg>
on top of the close stackcltrunc h
pops values from the top of the close stack and executes their__close
metamethod until the height of the close stack is at mosth
.cltrunc 0
instruction is executed.Error handling
If there is an error, then all close stacks in the "call stack" should be called until the error is caught. This is achieve by adding a
Cleanup()
method to theruntime.Cont
interface, which must be implemented by each continuation type. The runtime loop will call those in turn down the call stack when an error is encountered. For a Lua continuation,Cleanup()
is roughly equivalent tocltrunc 0
.