lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi Sean,
thanks for answer, your byte code example is very useful for me for
understanding.

I tried already what happens when I just put break somewhere outside
any loop, and then I also recognized that Lua then runs into a
function called "undefgoto" in file lparser.c ... so if such loops/
blocks/ break commands are just transformed to goto-constructs (which
is very straight forward of course, this really makes sense), then I
have bad luck in trying to recognize any loop construct during Lua
runtime.

To handle hardware inputs / outputs in a device with external
connections (possibly NOT nice electric signals, possibly e. g.
bouncing key signals or similar things), it is very useful to present
an easy function  to the user to allow "input delaying" (so a key will
e. g. not switch immediately, but only after e. g. 10 or 100
milliseconds "sure signal").

Such a delay function then typically in the main loop is used VERY
often ( e. g. 100-1000 times for a typical Lua IoT program). I am
working with this "restricted RAM" application ... I do NOT want  to
use 32 or even 64 bits per delay - 8bit is completely enough for
"standard delay applications". With 8 bit in some static reserved
memory, I need only 1kB. Any delay invocation of course needs its own
8-bit timer, so I would use a static C array for these 8 bit timer
values and index them in the order, the functions are invoked in my
Loop function (which is looped continuosly / much faster than the
delay times).

Alternatively I could program the delay functions with up values, thus
every function with its own timer upvalue. In normal/large RAM systems
like PC application this would work perfectly, buf if I have only ca.
20kB dynamic RAM left fpr my Lua variables, using upvalues would cost
much too much RAM (at least 8 kB RAM for 1000 delay timers - but I am
frightened that for each upvalue also some further things will be
defined, and then i easily would end with 16 or 32 kB... I had such
bad experience already one time with "mass allocation" of small
strings... also here I could NOT use the normal Lua string handling).

This "indexed use" of 8 bit delay values runs so far very nicely in my
main loop, I tested this already. Only restriction is, that these
delay functions must be invoked during EVERY main loop function run
(so NOT in any conditional block), and using them in a for loop also
would run into memory waste (one 8bit value for every for loop cycle).
So I want to check somehow, that the user does not by some accident
uses this "static delay" function in any if/for/while loop and also in
no subfunction. (for such cases I also offer a dynamic version of this
function, but really VERY MOST invocations typically will run in the
main loop).

Currently I check this "good programming practice" just by counting
the invocations during every run, and this count of course must not
overflow, and also it must be exaclty the same number during every
loop run... this is alerady "quite good checking", but if I could
check more directly, whether it is used inside a loop, this somehow of
course would be the 100% sure.. .



On Wed, Feb 16, 2022 at 9:27 AM Sean Conner <sean@conman.org> wrote:
>
> It was thus said that the Great Flyer31 Test once stated:
> > Hello,
> > in my C code I want to define some special Lua functions, which should
> > be only invoked inside a sort of "main function", and these functions
> > also should NOT be invoiked inside any code blocks if...end, as well
> > as not in any loops for ...end / while ...end / repeat ... until.
> >
> > Witth the debug interface and lua_getinfo I can get info about the
> > function currently active ... so I can restrict the invocation of this
> > "special function" easily to be called only insde my "main function".
> >
> > But I did not find an easy way to know, whether any "block"
> > (if/for/while/do/repeat) is active. Is there a way for my C code to
> > get this information?
>
>   In general, you cannot [1]. In particular, there is no way to detect if
> Lua is executing within a loop.  The following Lua code:
>
>         x = 1
>         while x < 10 do
>                 x = x + 1
>         end
>
> generates the following byte code (with label information added):
>
>                 vararggrep      0
>                 settabup        0 0 1k  ; x = 1
>         HERE    gettabup        0 0 0   ; read x
>                 lti             0 10 0  ; x < 10 ?
>                 jmp             THERE   ; if false, jump to THERE
>                 gettabup        0 0 0   ; read x
>                 mmbini          0 1 6 0 ; add 1 to value
>                 settabup        0 0 0   ; write to x
>                 jmp             HERE    ; jump back
>         THERE   return          0 1 1
>
>   The "while" statement has been replaced with a variable read, a comparison
> and a conditial jump.  A repeat/until statement is similar, except for the
> test is usually at the bottom of the loop.  There isn't anything in the code
> to say "This is a while loop" or "This is a for loop" or "This is a
> repeat/until" loop.
>
>   It seems, from your description, what you are trying to do is write a
> function for a user to call, but you don't trust the user to actually call
> the function at the right time (or the right number of times).  Perhaps if
> you explain what you are actually trying to do, it might elicit some better
> advice.
>
>   For example, without knowing anything else about the problem, I might
> suggest:
>
>         static bool foo_called = false;
>
>         static int foo(lua_State *L)
>         {
>           if (foo_called)
>             luaL_error(L,"I'm sorry Dave, I can't let you do that.");
>           foo_called = true;
>           /* ... rest of code */
>         }
>
>   But that would only allow the function to be called once, which may not be
> what you want it do to.  In fact, I can't think of a way to do what you are
> asking in any language (even Assembly, where you have complete control over
> all the code being run).
>
>   -spc
>
> [1]     You might want to read up on the "halting problem" which will go
>         into detail about what can and cannot be computed.