Reported by: firstname.lastname@example.org
An interpreter's recursion limit can be changed via the "recursion_limit" method on the ParrotInterpreter class. This is ostensibly a method that one calls against a particular interpreter object to read/write that interpreter's recursion limit, but actually the method always operates on the interpreter that is running the method call. It completely ignores its actual invocant. Example:
$ cat t57.pir
$P0 = get_global "maininterp"
.sub main :main
$P0 = getinterp
set_global "maininterp", $P0
.const "Sub" foo = "foo"
$P1 = new "Task", foo
$I0 = $P0."recursion_limit"()
$ ./parrot t57.pir
I use a sleep because there doesn't seem to be any synchronisation primitive built in at the level I'm working with. The "A"/"B" outputs confirm that the sleep has had the intended effect. The recursion limit is retrieved from the main interpreter after there has been a call against the same interpreter object to set the limit to 2000, but the retrieved value is the default 1000.
Reading and writing the recursion limit of the currently running interpreter are perfectly reasonable operations to support, but they should be presented as opcodes or as standalone subroutines. It is highly misleading to present them as methods on some invocant object that is unrelated to the operation. On the other hand, if there is to be this method on interpreter objects, it should operate on the interpreter represented by its invocant. (It's also fine to have both types of interface, as long as each is individually in a sensible form.)
The current interface for "recursion_limit" supports a get-and-set operation, whereby a new limit is set and the old limit returned. Maintaining atomicity of this usage raises problems if the method is changed to be able to operate on interpreters other than the current one.
A certain freedom of approach to this bug arises from the fact that the method is presently undocumented.
Summary of my parrot 5.7.0 configuration:
configdate='Sat Oct 5 12:42:43 2013 GMT'