karl3ļ¼ writeme.com wrote:
> > GPT-4
> > User
> > Come up with an analog to "goto" in python that engages the raw
> > interpreter and/or bytecode systems of python to function.
> > i want to try!
> 
> omigod this sounds really hard. options:
> - is there a way to halt interpretation during a function?
> - alternatively, we could use ctypes to modify whatever python uses as an 
> instruction pointer
> 
> hmmmmmmmmmmmmmmmmm 1304
> 
> so, yes, there is a way to halt interpretation during a function, it's called 
> 'yield'.
> there's also access to the call stack but i think the access is read-only.
> the problem with 'yield' is:
> - (a) i think it turns the function into a generator upon use
> - (b) if it's bundled into a goto() function it will interrupt the goto() 
> body rather than the surrounding code
> 
> here's a third option:
> - mutate the source code live using runtime preprocessing like old javascript 
> second language interpreters did
> 
> options again:
> - find an in-python way to halt function executation midway
> - use ctypes to modify the runtime at runtime
> - post-process the running sourcecode, say in a nonreturning function with 
> injects controlflow to hide its nonreturn
> 
> but i'm guessing what i originally meant was more along the lines of:
> - instrument the calling function to behave as if there were a goto statement 
> where your function is called
> 
> ok so the idea is maybe along the lines of, let's make a goto() function in 
> python that emulates goto in C.
> the approaches of interest (despite there being many other interesting ones!) 
> are either:
> (a) validate that callers are decorated with a recompiler
> or
> (b) identify the caller and mutate them mid-call to change their behavior
> 
> although (b) is preferred because it doesn't require a decorator, it might be 
> unreasonable hard i'm not sure. for example it's likely not possible to 
> mutate code mid-call (although it could be); it likely only affects the next 
> call.
> 
> let's see! this sounds hard :s
> 1308
> > def a():
> > ...     b = 1
> > ...     b += 1
> > ...     return b
> > ... 
> > import dis
> > dis.dis(a)
> >   1           0 RESUME                   0
> > 2           2 LOAD_CONST               1 (1)
>               4 STORE_FAST               0 (b)
> 
>   3           6 LOAD_FAST                0 (b)
>               8 LOAD_CONST               1 (1)
>              10 BINARY_OP               13 (+=)
>              14 STORE_FAST               0 (b)
> 
>   4          16 LOAD_FAST                0 (b)
>              18 RETURN_VALUE
> 
> let's see what happens if i remove line 3 from the function and try to inject 
> it using a caller-modifier or something? :s :s :s this won't work
> > list(a.__code__.co_code)
> > [151, 0, 100, 1, 125, 0, 124, 0, 100, 1, 122, 13, 0, 0, 125, 0, 124, 0, 83, 
> > 0]
> > looks like maybe
> 151=RESUME_1
> 100=LOAD_CONST_1
> 125=STORE_FAST_1
> 124=LOAD_FAST_1
> 122=BINARY_OP_3
> 83=RETURN_VALUE_1
> and it uses an indexable stack or something
> 
> 1313
> 
> 1317
> here's a cool thing you can do. this function disassembles itself. it shows a 
> call to the function to get the stack frame and pass it to the disassembler:
> > import sys
> > def disassemble_self():
> > ...     dis.dis(sys._getframe().f_code.co_code)
> > ... 
> > disassemble_self()
> >           0 RESUME                   0
> >           2 LOAD_GLOBAL              0
> >          14 LOAD_METHOD              0
> >          36 LOAD_GLOBAL              2
> >          48 LOAD_METHOD              2
> >          70 PRECALL                  0
> >          74 CALL                     0
> >          84 LOAD_ATTR                3
> >          94 LOAD_ATTR                4
> >         104 PRECALL                  1
> >         108 CALL                     1
> >         118 POP_TOP
> >         120 LOAD_CONST               0
> >         122 RETURN_VALUE
> >

oops:

>>> exec(disassemble_self.__code__.replace(co_code=a.__code__.co_code))
Segmentation fault

Reply via email to