[gameprogrammer] Re: Scripting engines: Upvalues and function refs

  • From: David Olofson <david@xxxxxxxxxxx>
  • To: gameprogrammer@xxxxxxxxxxxxx
  • Date: Mon, 5 Apr 2004 11:50:16 +0200

On Sunday 04 April 2004 16.08, Stephane Marchesin wrote:
[...]
> >     1. When calling via references, you have no clue
> >        what you're calling at compile time. (Not a
> >        major issue in itself, though the run time
> >        checking will impact performance a bit.)
>
> That's more a feature than an issue, IMO :)

Well, yes - or I wouldn't bother to mess things up with function 
references in the first place. ;-)

The issue part is that you may call functions that use upvalues 
(locals of parent functions, basically) that no longer exist. (Same 
thing that happens in C++ if you create a local/stack instance of a 
class in a function and return a function pointer to a member 
function of that class.)


> >     2. All directly callable functions are actually
> >        local functions, and may try to use upvalues.
> >        What looks like global variables in a module
> >        are actually locals of the top level function,
> >        and "normal" functions access them as upvalues.
>
> Attach an implicit reference to the corresponding context to the
> function. i.e., if a function calls upvalues, it has a reference to
> the corresponding frame(s).

Each call register frame (where the return address and stuff is 
stored) contains a reference to the register frame of the closest 
lexical parent function on the call stack.


> >     3. You can't easilly tell what register frame to
> >        pass as "upvalue frame" to a function.
>
> First, look at the implicit reference(s), the go through the call
> stack.

That's the easy part. My call stack is effectively a linked list of 
"upvalue contexts", so I just climb it the appropriate number of 
levels, which can be calculated at compile time.

The problem is that I need to make sure the call stack is still valid 
when a function is called, which is a problem when the normal 
procedure is to remove stuff from the stack as functions return.


> >     4. You may end up violating the scoping rules,
> >        trying to call functions that are not callable
> >        from the current context. (Even if you grab
> >        the function reference when the function has
> >        a valid context, that context may no longer
> >        exist when someone decides to call via that
> >        reference!)
>
> I think a reference counter would do. Although you would need one
> counter per object,

One *could* manage entire call frames as objects...


> it's probably more realtime safe than a garbage
> collector.
> (and of course here, the implicit reference that a function can
> have on a given frame must also be counted).

Actually, reference counting tends to be the *worst* approach for RT 
systems. It may not be much of an issue with simple code (or rather, 
simple data structures), but the problem with basic RC is that you 
easilly end up constructing large trees of objects that are destroyed 
at "random" while your code is running. All of a sudden, just 
throwing an object away can become an operation with very 
unpredictable execution time.


> I tend to dislike garbage collectors (probably since the time of
> the amstrad CPC, where your program written in basic would slow
> down to a crawl when the garbage collector kicked in) but that's
> just a personal view :)

Well, GCs *are* trouble in RT systems, unless they're designed for it. 
However, a properly done GC can actually *help* an RT system. A GC 
allows you to leave the destruction work for later, so you can avoid 
taking that hit in the timing critical code paths.


> In both cases, you might also need to handle the "cyclical
> reference" problem, where two or more objects are kept alive only
> because they have references to each other (that really depends on
> your language, whether or not you have objects able to reference
> themselves).

Normal GCs tend to trace references starting at the root, and thus 
avoid the cyclical reference problem; another advantage over 
reference counting.


//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
|  Free/Open Source audio engine for games and multimedia.  |
| MIDI, modular synthesis, real time effects, scripting,... |
`-----------------------------------> http://audiality.org -'
   --- http://olofson.net --- http://www.reologica.se ---


Other related posts: