When exactly "from" is nil, which of L and from are the "stream stack".
If you ask about the value of the from parameter, it may seem that there is not so much of it,. It would be permissible to use it only if the C function executing the resume itself was called from a coroutine.
L is the stack on which you put the arguments to resume (and the initial function if this is the initial resume call). So this best fits the term "thread stack".
What are the exact requirements for resuming a coroutine?
As indicated in the docs for lua_status , you can resume a stream if the stream status is LUA_OK or LUA_YIELD .
Note that there is a difference between resuming a thread and resuming a coroutine. lua_resume resumes the stream. If the status is LUA_OK , then it does not have an active coroutine, so you create a new coroutine and, therefore, must provide a function. If the stream is LUA_YIELD , then resuming the stream will resume the received coroutine.
Is it possible to change the state of L between the initial lua_resume () and the second, which actually resumes?
Of course it can; should be. In the end, you get the return / exit values as values placed in L When you are about to resume it, you must delete these values and put the new values on the stack as the values that will be returned from the Lua yield function.
So yes, you can change it. But there are rules about what you can do. Two of them:
Rule number 1: You can not poke things that do not belong to you.
Let's say the Lua stack looks like this, right in front of your initial resume (growing from left to right):
[A][B][C][F][1][2][3]
F is the function you want to run. 1, 2 and 3 are parameters. So you pass 3 like nargs . A , B and C are just any material you put on this stack.
If the coroutine is inferior, your stack looks like this:
[A][B][C][LOTS OF STUFF][a][b][c]
LOTS OF STUFF represents an arbitrary amount of stack data created by coroutine processing. There is no way to know how much or how little will be there.
a , b and c are the values passed to yield in Lua. You can play with them at your pleasure. You can even reach back and poke at A , B and C through their absolute stack indices 1, 2 and 3.
What you cannot do is change LOTS OF STUFF . This data represents the received state of the coroutine. You are not allowed to change this. At all. You probably also cannot remove any items below it. Therefore, you cannot even delete A , B or C
Rule number 2: You must resume exactly from where the stack stopped.
After the coroutine has lost, you can remove some things from the stack and add them to it (according to rule No. 1). Let's say the stack looks like this:
[A][B][C][LOTS OF STUFF][a][Q][R][D]
a is one of the original return values, and other things are temporary values that you created during this time. So now it's time to resume the coroutine. You have several new options for passing, 1 and 2. How do you do this?
Your first step should be to clean up. You should return your stack to this point:
[A][B][C][LOTS OF STUFF]
After that, you can press 1 and 2, and then resume the coroutine with nargs as 2.
If so, how will the state know where / what function to resume?
The LOTS OF STUFF above reports “where / which function to resume”.
How to create a new thread correctly so that it shares the execution context (global variables, environment, etc.) with the parent thread
The "execution context" is not associated with a thread. These things are related to functions, not threads. Therefore, if you want a function to share the same environment as another function, then they must use the same environment as this function.
How these functions are performed (coroutines or not) is not related to the fact that their environment.
And finally, in any case - how can I get a full stack trace for debugging in the error handler (for example, caused by an error from lua_pcall) that takes into account / knows about calls through the resume?
You can not.
When lua_resume crashes due to an error, it leaves information on the stack to track what happened between the resume and the place that generated the error. But he cannot know how the resume itself happened. This is what you have to do, depending on how you resumed this coroutine from the very beginning.
The purpose of the from field is not to connect the renewer to the renewed one.