I propose the following alternate guidelines.
First, the code would look something like this: STRING * concat (STRING* a, STRING* b, STRING* c) { PARROT_start(); PARROT_str_params_3(a, b, c); PARROT_str_local_2(d, e); d = string_concat(a, b); e = string_concat(d, c); PARROT_return(e); } Then, the rules would be: (1) start your functions with PARROT_start (2) register all parameters of type STRING * with PARROT_str_params (2') register all parameters of type PMC * with PARROT_pmc_params (3) declare the local variables of type STRING * with PARROT_str_local (3') declare the local variables of type PMC * with PARROT_pmc_local (4) use PARROT_return to exit the function (5) do not nest function calls (for instance, "e = string_concat (string_concat(a, b), c);" would be forbidden) The idea is to explicitly manage a stack of parrot objects, which can be traversed by the GC. This rules let a lot of freedom to the garbage collector: - it can garbage collect anything which is not rooted; - it can move objects (strings and PMCs) around; - objects do not need any additional field/flag; - exception can be implemented using longjmp; if an exception is raised, temporary allocated objects will be properly freed by the GC. Do you think that these rules would be too error-prone, or too cumbersome? -- Jerome