Open
Description
The current mechanism for handling with copied contexts after a fork leaks because only simulator-side accesses to the contexts are forwarded to their copies. When the simulation code itself accesses any old contexts, such as via Context>>#methodReturnContext
, the accesses are not forwarded. The exact scope of this issue is unclear, but below are some examples.
Possible solutions
- Approach 1: Treat all context instances as symbolic and forward all read hooks to their copied instances, if any. Forward all write hooks, analogously.
- This would be holistic, but likely will reduce performance.
- Also, would it be nice if simulated code could explicitly access other forks via a metaprogramming interface (similar to accessing the data structure behind vectors)?
- Approach 2: Create an explicit
Context
subclass that uses special code/primitives to access the relevant state. This would not be holistic. - Approach 3: As soon as any context instance is put on the stack, replace it. Would require some other hooks, though, might be more expensive and increase complexity.
Failing examples
c := Object newSubclass.
c compile: 'foo: x
[^ x factorial]
"value" "<- works"
ensure: []'.
o := c new.
(TDBRetracingSimulator forMemory: TDBMemory new atTimes: (1 to: 3))
evaluate:
[o foo: thisContext tdbRetracingTimeIndex]
In other cases, a BlockCannotReturn
is signaled from the simulated code when attempting a non-local return within an unwind context.
See #rangeRetracingForkAccess
for more examples.