Closed Dunbaratu closed 8 years ago
Mind pointing me at the "maybe compile function"? I've been trying to trace it up, but got myself a bit confused, but would love to take a look at this, especially as it would offer a workaround for the lib_exec breakage (since users could time/version-stamp files prior to execution).
@gisikw In general one hint about getting a dump of what the actual opcodes of a program look like is this: Just put a runtime-error in the bottom of the script - something that will compile but will barf when it runs it. I usually use print 1 / 0.
to force a divide-by-zero runtime exception for this purpose. Anyway, the point is that when you get such a runtime exception, the program dumps a bit of the program out to the output log file as part of the error. If you're running the debug DLL (the one compiled from source here, rather than the public one) then it tends to print the entire program's opcodes out (the public one just prints a few lines of context, I believe) on any runtime error.
If you want to look at the section of the compiler that builds this "maybe compile function", it's in this file: src/kOS.Safe/Compilation/KS/Compiler.cs -- look for a method titled PreProcessRunInstruction()
That method has a big chunk of opcodes it inserts into the program that effectively does this:
Create a low level "function" that will be put into the the top of the program as follows:
load()
. call that function, and it will leave the newly loaded program instruction pointer on the stack as its return value that defines where the entry point of the newly compiled program is. Assign the program's pointer variable (the thing that started as -1, that you checked against in step 1 above) to this value.Then when you actually visit the run statement for real in a later pass of the compiler (the method called VisitRunStatement), where the 'run' command was, you should make an OpcodeCall to the above pre-built maybe-compile-function.
It's a bit messy because of the indirect call inserted here - when you run a program it needs to nest two sets of arguments and arg bottom markers onto the stack because of the intermediary 'maybe-compile' function that happens before the actual call to the program.
Just a warning, the thing I intend to make a PR for tonight may affect the method mentioned above so be careful to re-read it after that PR is merged.
Cheers!
oops - it's called PreProcessRunStatement, not PreProcessRunInstruction.
Currently (0.18.1 and before) You cannot RUN on a varying filename string.
i.e. you can do this:
but you cannot do this:
And the main reason for this restriction is that the compiler, at compile time builds the thing we've been calling the "maybe compile function" in the program header before the values of variables are known and it needs to know the hardcoded filename at that time, because it's using that to choose the name of the program instruction pointer variable.
But this seriously needs to be fixed before we can allow multiple directories to work.
Here's one approach: When the compiler builds the "maybe compile function", instead of building one per instance of
run
, just build one global one only, no matter how manyrun
statements there are. However, make it able to receive the name of the program instruction pointer variable as an argument. This is essentially an indirect pass by reference (i.e. pass in the instruction pointer variable so it can be set by the maybe-compile-function, rather than its value). Such a pass by reference would be impossible in kerboscript directly, but we can do it in the underlying kRISC, by just pushing the variable name as a bareword string with an asterisk at the end of it.