Ability to use leave inside a filter block - cil

I am writing an interpreter of CIL code, and now it is time to interpreter leave in a filter block.
How to handle it?
First idea was is that this is an invalid instruction being in a filter block, so such a code can't be executed. But then I looked at the standard and found strange things.
The standard ECMA-335 says that leave can be used (!) to exit a filter block:
The leave instruction is similar to the br instruction, but the former can be used to exit a try,
filter, or catch block whereas the ordinary branch instructions can only be used in such a
block to transfer control within it.
At the same time:
Control cannot be transferred out of a filter block except through the use of a throw instruction or
executing the final endfilter instruction. In particular, it is not valid to execute a ret or leave
instruction within a filter block.
Seems to be a contradiction.

Related

Why is ⎕SIGNAL not caught by :: error guards?

{11::¯1 ⋄ 2÷0}⍬
¯1
{11::¯1 ⋄ ⎕SIGNAL 11}⍬
DOMAIN ERROR
Why is the first signal caught, while the second is not?
As per the documentation for ⎕SIGNAL (my emphasis):
The state indicator is cut back to exit from the function or operator containing the line that invoked ⎕SIGNAL, or is cut back to exit the Execute (⍎) expression that invoked ⎕SIGNAL. If executed within a nested dfn, the state indicator is cut back to exit from the capsule containing the line that invoked ⎕SIGNAL. An error is then generated.
In other words, by the time ⎕SIGNAL is done doing its thing, we're already outside the dfn and thus the dfn's error guard (::) is not in effect any more.
To work around this, you have to use ⎕SIGNAL in a separate capsule. For example, you can define a cover function outside the function where you want to use it:
Signal←{⎕SIGNAL ⍵}
{11::¯1 ⋄ Signal 11}⍬
¯1
Alternatively, you can put ⎕SIGNAL in its own execution capsule:
{11::¯1 ⋄ ⍎'⎕SIGNAL 11'}⍬
¯1

How does an interpreter resolve function calls or branch(jump) statement?

I know the question seems a bit broad. I tried searching for answers, couldn't find much.If anyone could describe or point me to the right source.
Assuming a bytecode-based interpreter, the usual way to do this would be as follows:
You have a variable, the program counter, which tells you the index of the instruction to execute. Usually you increase that counter by 1, but when executing a branch, you instead set it to the target location of the jump.
For function calls you do the same thing, but you also push the old value of the counter plus one onto the call stack. Then when you execute the return instruction, you pop the value of the stack and set the counter to that.

set a breakpoint, when called: return and continue

I know how to do this in gdb. I'd attach, and follow with:
break myfunction
commands
return
cont
end
cont
I'm wondering if there's a way of doing this in c? I already have my code working for reading memory addresses and writing to memory addresses. And it automatically finds the pid and does related stuff. I'm stuck with implementing that use of breakpoints.
If you are talking about some sort of hand-written debugger, you can use IP value to set a breakpoint; Literally, when IP hits some certain value, you stop the program being debugged and perform some routine (for example, heading away to debugger process). To use function names, you should use symbol tables like it is done in GDB.
It's not quite clear what you are trying to achieve.
The GDB sequence you've show will simply make myfunction immediately return.
Assuming you want your mini-debugger to have the same effect, simply write the opcode for ret (0xC3 on x86) to the address of myfunction; no need to do the breakpoint at all.

Is using fflush(stdout) as fprintf() argument safe?

To I came upon this line of code:
fprintf(stdout, "message", fflush(stdout));
Note that the message does not contain any %-tag.
Is that safe in visual c++? fflush() returns 0 on success and EOF on failure. What will fprintf() do with this extra parameter?
I first thought that this was a strange hack to add a fflush() call without needing an extra line. But written like this, the fflush() call will be executed before the fprintf() call so it does not flush the message being printed right now but the ones waiting to be flushed, if any... am I right?
It's safe. Here's what C (C99 atleast, paragraph
7.19.6.1) says about it
If the format is exhausted while
arguments remain, the excess arguments
shall be evaluated but are otherwise
ignored.
If the goal was to avoid a line, i'd rather do
fflush(stdout); fprintf(stdout, "message");
if for nothing else than to prevent the person later reading that code to hunt me down with a bat.
fprintf doesn't know the exact number of parameters, it only tries to load one argument per '%'. If you provide less arguments than '%', it results in undefined behavior, if you provide more arguments, they are ignored.
Ad second question, yes, this would only flush messages in queue, the new message won't be flushed.
I think fprintf is using varargs to process parameters, so any extra parameters should be safely ignored (not that it's a good practice or anything). And you are right that fflush will be called before fprintf, so this is kind of a pointless hack.
With enough warning flags enabled (like -Wall for gcc) you will get a warning

How to really trap all errors with $etrap in Intersystems Caché?

I've been banging my head a lot because of this. In the way that $etrap (error handling special variable) was conceived you must be careful to really trap all errors. I've been partially successful in doing this. But I'm still missing something, because when run in user mode (application mode) there are internal Cache library errors that are still halting the application.
What I did was:
ProcessX(var)
set sc=$$ProcessXProtected(var)
w !,"after routine call"
quit sc
ProcessXProtected(var)
new $etrap
;This stops Cache from processing the error before this context. Code
; will resume at the line [w !,"after routine call"] above
set $etrap="set $ECODE = """" quit:$quit 0 quit"
set sc=1
set sc=$$ProcessHelper(var)
quit sc
ProcessHelper(var)
new $etrap
; this code tells Cache to keep unwindind error handling context up
; to the previous error handling.
set $etrap="quit:$quit 0 quit"
do AnyStuff^Anyplace(var)
quit 1
AnyStuffFoo(var)
; Call anything, which might in turn call many sub routines
; The important point is that we don't know how many contexts
; will be created from now on. So we must trap all errors, in any
; case.
;Call internal Cache library
quit
After all this, I can see that when I call the program from a prompt it works! But when I call from Cache Terminal Script (application mode, I was told) it fails and aborts the program (the error trapping mechanism doesn't work as expected).
Is is possible that an old-style error trap ($ZTRAP) is being set only in Usermode?
The documentation on this is pretty good, so I won't repeat it all here, but a key point is that $ZTRAP isn't New-ed in the same way as $ETRAP. In a way, it is "implicitly new-ed", in that its value only applies to the current stack level and subsequent calls. It reverts to any previous value once you Quit up past the level it was set in.
Also, I'm not sure if there's a defined order of precedence between $ETRAP and $ZTRAP handlers, but if $ZTRAP is of higher precedence, that would override your $ETRAPs.
You could try setting $ZTRAP yourself right before you call the library function. Set it to something different than $ETRAP so you can be sure which one was triggered.
Even that might not help though. If $ZTRAP is being set within the library function, the new value will be in effect, so this won't make a difference. This would only help you if the value of $ZTRAP came from somewhere further up the stack.
You didn't mention what library function caused this. My company has source code for some library functions, so if you can tell me the function name I'll see what I can find. Please give me the value of $ZVersion too so I can be sure we're talking about the same version of Cache.