CONTROLLER 0 crashes
Root / SmileBASIC Bug Reports / [.]
hakkeCreated:
CONTROLLER doesn't have an explanation and every other value that isn't 0 will actually give errors and don't crash SB though.
...
CONTROLLER shouldn't be here. It should only be there in SB BIG. I guess SmileBoom was accidentally forgetting to delete this command in the 3DS version, since it's only purpose seems to be giving errors and crashing SB.CONTROLLER doesn't have an explanation and every other value that isn't 0 will actually give errors and don't crash SB though.It's BIG compatibility...
CONTROLLER shouldn't be here. It should only be there in SB BIG. I guess SmileBoom was accidentally forgetting to delete this command in the 3DS version, since it's only purpose seems to be giving errors and crashing SB.
Well, why is it here? It hasn't a compatibility at all!!!!!!!!!!!!!!!!CONTROLLER doesn't have an explanation and every other value that isn't 0 will actually give errors and don't crash SB though.It's BIG compatibility...
CONTROLLER shouldn't be here. It should only be there in SB BIG. I guess SmileBoom was accidentally forgetting to delete this command in the 3DS version, since it's only purpose seems to be giving errors and crashing SB.
Would you rather have Syntax Error on 0:190 from a BIG program, or a specialized error code that explains something more? My point is bad anyways since the error code from CONTROLLER doesn't really help youWell, why is it here? It hasn't a compatibility at all!!!!!!!!!!!!!!!!CONTROLLER doesn't have an explanation and every other value that isn't 0 will actually give errors and don't crash SB though.It's BIG compatibility...
CONTROLLER shouldn't be here. It should only be there in SB BIG. I guess SmileBoom was accidentally forgetting to delete this command in the 3DS version, since it's only purpose seems to be giving errors and crashing SB.
I don't have a Wii U to test it...... Well, why is it here? It hasn't a compatibility at all!!!Would you rather have Syntax Error on 0:190 from a BIG program, or a specialized error code that explains something more? My point is bad anyways since the error code from CONTROLLER doesn't really help you.
There is absolutely no reason for CONTROLLER to do anything other than throw Incompatible statement (which is the error they added SPECIFICALLY for when you use a function that isn't supported in the current mode or system) because the output of CONTROLLER(0) isn't even useful in the 3DS version anyway.
Pretty much every program that will use the CONTROLLER function will also have XON WIIU, which is an Incompatible statement on 3DS, so there's no reason for CONTROLLER to do anything different. Its output in 3DS mode pretty much amounts to "this 3DS is a 3DS," which you knew already.
Amusingly, there isn't a "command" form for CONTROLLER even in BIG; it's always to be called as a function expression. It's crashing on syntax that is entirely illegal and should throw an error anyway.
Some post I did earlier
I tested something out:>print Controller(0) 1 >TestSomeThings=Controller(0) >print TestSomeThings 1 >print Controller(1) Incompatible statement (CONTROLLER) >Controller 0 ...Crash!
Insight:
The CONTROLLER function is quite a hacky addition.
TL;DR it doesn't check if an output argument exists, it blindly tries to write to it and so it crashes.
This is so bad, this bug is also present in BIG. While I don't want to learn PowerPC assembly, I bet the underlying code is mostly the same, which still includes the missing output argument check.
Actually, that's just how syntax works that CONTROLLER 0 and CONTROLLER(0) behave the same, as the interpreter tries to evaluate values ahead of time.
It's only:
CONTROLLER 0 OUT A%
V%=CONTROLLER(0)
that do work properly, as there the first one defines an output argument with OUT and the second is defined before the instruction with the equal sign. It's only a matter if there is an output argument, not how it's written. Man, I'd like my past self from 4yrs ago to see this, he'd probably be mind-blown.
Digging deeper
Let's look at the assembly code (This is from the european 3.6.0 release, it may be different for you.) This is hardcoded behaviour. It cares if only 1 argument exists and that argument is 0. Now the funny stuff at loc_0015C288: The first LDR sets the active pointer into the first output argument of the argument table. If there is no output argument, it points to a dummy entry that's all NULL'ed out. The second LDR on R1 just makes it so we can read pointers from it... This sounds like we're getting into an issue now. Alas, the third LDR is the one that finally crashes, since it reads from [NULL,#0x14] -> 0x00000014, which doesn't point to valid memory obviously and thus crashes. But if there is an argument, this would make R2 a function pointer that just sets the value set in R1 of the argument pointed to by R0. However, because of not checking the count of output arguments, you can have as many output arguments as SB3 allows (which in 3.6.0+ appears to be 256 or so), although the rest will be of null type where anything you do to it causes the "Uninitialized variable used" error. At least I'm finally starting to get a grasp on ARM assembly. :)Evidently something has gone wrong in the parsing stage. No form of CONTROLLER exists that provides no return value so this should at least be "syntax error" or "wrong number of return values." It's true that the actual function doesn't sanity check if its return slot is valid but the parser should have all of the information available to do argument and return checking anyway. Maybe they just put it in wrong?
Replying to:snail_
Evidently something has gone wrong in the parsing stage. No form of CONTROLLER exists that provides no return value so this should at least be "syntax error" or "wrong number of return values." It's true that the actual function doesn't sanity check if its return slot is valid but the parser should have all of the information available to do argument and return checking anyway. Maybe they just put it in wrong?
Well no. The parser doesn't care about the argument/output variable count, it just prepares the argument table for the underlying function (CONTROLLER, ABS, etc.) to use it. That way, each function is responsible for how the arguments and output variables are handled.
The function tables only have pairs of pointers, which is the UTF16 string of the command/function and the pointer to the C function that handles this. There's no other metadata appended to these entries, so the parser can't even know what demands each function has, they do that for themselves.
Actually, WAIT and VSYNC are good examples. The parser just gives the function all arguments and those 2 functions only check if 1 argument exists and use it. The rest are unused but evaluated anyway, as the evaluation is done by the parser and it assumes it gets used somehow. (although string variables feel weird, they aren't exposed on the argument table directly, will have to do more observation there.) You can use OUT or the function() syntax on commands that don't output anything. The "Undefined variable used" error actually stems from using the variables after the function call and not while assigning.
This is probably to be inline with BASIC DEF'd commands that can be wildly different, so instead of personalizing the call, the parser just gives all details the function would need. Just that in DEF, the argument and output count is handled automatically, not so in hardcoded functions.
That explains why replacing any BASIC command/function with a custom one is quite easy. (given it can only output cryptic error codes, like "Internal error" or a silent exit, such as CHKMML that prints the error manually before exiting)
Replying to:CyberYoshi64
Well no. The parser doesn't care about the argument/output variable count, it just prepares the argument table for the underlying function (CONTROLLER, ABS, etc.) to use it. That way, each function is responsible for how the arguments and output variables are handled.
The function tables only have pairs of pointers, which is the UTF16 string of the command/function and the pointer to the C function that handles this. There's no other metadata appended to these entries, so the parser can't even know what demands each function has, they do that for themselves.
Actually, WAIT and VSYNC are good examples. The parser just gives the function all arguments and those 2 functions only check if 1 argument exists and use it. The rest are unused but evaluated anyway, as the evaluation is done by the parser and it assumes it gets used somehow. (although string variables feel weird, they aren't exposed on the argument table directly, will have to do more observation there.) You can use OUT or the function() syntax on commands that don't output anything. The "Undefined variable used" error actually stems from using the variables after the function call and not while assigning.
This is probably to be inline with BASIC DEF'd commands that can be wildly different, so instead of personalizing the call, the parser just gives all details the function would need. Just that in DEF, the argument and output count is handled automatically, not so in hardcoded functions.
That explains why replacing any BASIC command/function with a custom one is quite easy. (given it can only output cryptic error codes, like "Internal error" or a silent exit, such as CHKMML that prints the error manually before exiting)
You're right, I was mistaken