CE-Programming / toolchain

Toolchain and libraries for C/C++ programming on the TI-84+ CE calculator series
https://ce-programming.github.io/toolchain/index.html
GNU Lesser General Public License v3.0
527 stars 53 forks source link

os_RunPrgm Crash (TI-Basic Stop token) #459

Closed vitalash1 closed 1 year ago

vitalash1 commented 1 year ago

(main.c and compiled .8xp file) BUGREPRO.zip

When executing os_RunPrgm on a TI-BASIC program and hitting a Stop token, a ram clear occurs. This is undesirable behavior.

Reproduction steps

#include <ti/vars.h>

int main() {
    os_RunPrgm("A", 0, 0, 0);
    return 0;
}
mateoconlechuga commented 1 year ago

How should this be handled?

commandblockguy commented 1 year ago

I think it's somewhat reasonable (given how TI-BASIC programs handle it) to return to the homescreen when the Stop function is called, rather than calling the callback. Obviously, the calculator shouldn't reset if that happens. Re-launching the program and calling the callback function anyway might be desirable in some circumstances, but it might be better to leave this to individual programs to use a hook as necessary. There are a lot of other use cases where handling Stop is unnecessary, and installing a hook to flash and introducing a dependency on capnhook for no reason is undesirable.

vitalash1 commented 1 year ago

In my opinion, this should act the same way as if the program reached the end of the token-stream normally: it calls the callback, if supplied. That is what I expected would happen.

When I use Stop in a TI-BASIC program, it is to end the program. When I let the interpreter reach the end of the token stream, it is to end the program. I do not see why to differentiate those different kinds of "ending the program" as resulting in different behavior.

According to the documentation of os_RunPrgm, This argument may be left NULL if execution should not return to the calling program. One may already pass null to get the behavior of returning to home-screen. So why is it that when they choose to pass a callback, it may only be used sometimes?

I suppose these are a few possible functionalities one could want as a user of these C libraries writing a program:

Options Which functionality do you think the programmer would more often desire? "sometimes callback, sometimes home-screen?" Or "All callback/All home-screen?"

Personally, in my current project, I desire "all callback or no callback" functionality. Perhaps I'm biased, but my guess is that it is a more common need than "sometimes callback and sometimes homescreen."

I struggle to contrive examples where one would desire "sometimes callback and sometimes homescreen." I find it easier to contrive examples where one would desire "all callback or no callback."

calc84maniac commented 1 year ago

Strictly speaking, reaching the end of the token stream corresponds to Return, not Stop. Using Stop has the intent that any calling (TI-BASIC) programs are also exited.

vitalash1 commented 1 year ago

Strictly speaking, reaching the end of the token stream corresponds to Return, not Stop. Using Stop has the intent that any calling (TI-BASIC) programs are also exited.

I did not know that; I see.

I still personally believe that the callback should be respected if provided, and I'm curious what will be decided.

mateoconlechuga commented 1 year ago

The problem I can see happening is that Cesium already intercepts the stop token.

I'm not sure what to do :(

Someone should tell me what to do.

mateoconlechuga commented 1 year ago

Please try the latest nightly available here and let me know if the behavior is now as intended :)

Ended up chaining and creating token hook to handle the Stop token. I'll close this issue once behavior is confirmed!

vitalash1 commented 1 year ago

Everything seems to be working exactly as I'd like; thank you, Mateo!

Working when run via TI-OS cemu_eBjho3DXjg

Working when run via Cesium cemu_1x3nuKdWb4

mateoconlechuga commented 1 year ago

Great 👍