Pass By Reference Emulation

Inlined Functions

When an inlined function passes a variable as a parameter and also assigns the result to the same variable, we can, in some cases optimize this to avoid copy on writes. If the same variable is returned, then this will work, however, we may still have to assign it if another value is returned:

function set_name( sequence person, sequence name )
    person[NAME] = name
    return person
end function

user = set_name( user, name )

In this case, the inline check needs to detect whether the variable being assigned to is being passed. We can't do this with certainty on the first pass, since the function might be part of a larger expression:

user = set_name( user, name ) & 1

However, we can determine if this situation is possible by looking for the parameters in the code gen stack (cg_stack). If we find one in the stack prior to the data for the function call, we can defer the inline until after other parsing has completed. At that point, we'll know the identity of the target of the function. In the above example, the target will be a temporary variable.

Once we detect this situation, we can adjust the inlined result. First, even though the variable may be assigned, it won't be 'protected' by using a temp. Any RETURNF opcodes that return the target can be optimized to a jump to the end of the inlined code. Any other RETURNF opcode will assign to the target as normal.

Non-Inlined Functions

It may be possible to emulate pass by reference for functions that are not inlined when they take the form:

target = some_func( target,...)

The translator is probably the easiest. We can easily detect this when emitting translated code. If the refcount for target is 1, then we have an opportunity to optimize. We can avoid adding a reference count in this case, so that it can be edited in place within the function.

In the interpreter, it's likely to be more difficult. The easiest approach may be to define a new opcode, say FUNC_BYREF, where we can check for the passed variable, and adjust its reference count, if need be. More difficult is that the RETURNF opcode calls Ref() on the returned value. One solution might be to add a RETURNF_REF opcode that could reduce the reference count on the variable in question if necessary.


Quick Links

User menu

Not signed in.

Misc Menu