Look at computer exploits. There are many ways to run ‘arbitrary’ code even in cases where the code itself is ‘unchangable’. All you need is some mutable data storage[1] and an immutable state machine[2] to build an interpreter, and then you’re effectively running mutable code[3].
Now, some of these can be mitigated. That being said, it’s very much a cat-and-mouse game.
Look at computer exploits. There are many ways to run ‘arbitrary’ code even in cases where the code itself is ‘unchangable’. All you need is some mutable data storage[1] and an immutable state machine[2] to build an interpreter, and then you’re effectively running mutable code[3].
Now, some of these can be mitigated. That being said, it’s very much a cat-and-mouse game.
Including ‘weird’ storage mechanisms, not just intended ones. Storing data in TLB state? Sure. It’s limited, but not nothing. Etc. Etc.
Including ‘weird’ state machines, not just intended ones. See also return-oriented programming.
A naive interpreter will be slower than running native, but this ‘just’ motivates the AI to try to move to a better computational substrate.