Invoking return through a function?

bartc bc at freeuk.com
Tue Oct 31 08:33:37 EDT 2017


On 31/10/2017 05:32, Steve D'Aprano wrote:
> On Tue, 31 Oct 2017 02:34 pm, Chris Angelico wrote:

>> No, I don't think you do understand them correctly - or at least, I
>> don't know of any way for a C macro to jump into the middle of a
>> function.
> 
> I presume a macro could contain a call to longjmp, yes? Since longjmp can jump
> into another function (albeit only one which has prepared for it in advance),
> so can the macro.
> 
> https://stackoverflow.com/questions/21355110/how-to-goto-into-different-function-in-c
> 
> And what about assembly? Couldn't you jump into a function from assembly? Of
> course the stack will be all wrong, but if you're using assembly you have to
> manage that yourself.

I've used jumping-into-functions quite a bit, mainly to implement 
threaded code as used to code fast byte-code dispatchers.

The actual jump is done in inline assembly (and usually via a function 
pointer; no actual named label is used), but it needs HLL support to 
ensure the functions you're jumping into have special entry and exit 
code (no stack frames or anything).

The main problem with a HLL goto into a HLL function is that the label 
names in the function will not be visible from the goto site. Otherwise 
it might be possible, with some provisos (eg. any stack frame the 
function uses may not be properly set up).

gcc-C probably has some extensions to do something similar (label 
pointers for example which can be stored in global data, although you 
have to execute the function normally first to set them up).

None of this would be routine however. Python thinks it's a cut above 
other languages as it manages without gotos, forgetting that gotos are 
most likely needed in its implementation, so that someone has done the 
dirty work!

(CPython compiled with gcc almost certainly uses label pointers in its 
dispatcher, although I believe the gotos are still into the same function.)

>> 2) setjmp/longjmp, which is not actually a "goto", but more of a
>> "multi-level return"
> 
> Right-oh. So sort of like an exception then.

I've implemented setjmp/longjmp, but find them unintuitive to use. When 
I had to use arbitrary jumps from one function to another in the past 
(error recovery for example, what people use exceptions for now), I just 
used inline assembly. It was a lot simpler:

  assem
      mov [spvalue],sp        # set up recovery data in globals
      mov [bpvalue],bp
      mov [recoverylabel],recoverypt
  end
  .... do normal work.

  recoverypt:                 # here when something has gone wrong


When you want to get to the recovery point from anywhere (probably you'd 
put this in a function):

  assem
      mov sp,[spvalue]
      mov bp,[bpvalue]
      jmp [recoverylabel]
  end

-- 
bartc



More information about the Python-list mailing list