
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