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

  • From: David Olofson <david@xxxxxxxxxxx>
  • To: gameprogrammer@xxxxxxxxxxxxx
  • Date: Sun, 4 Apr 2004 19:48:54 +0200

On Saturday 03 April 2004 23.35, Bob Pendleton wrote:
> On Fri, 2004-04-02 at 03:30, David Olofson wrote:
[...upvalues, funcrefs and contexts...]
> > Any ideas? How do other languages with upvalues handle function
> > pointers/references?
>
> I assume that by an "upvalue" you mean a value defined in an outer
> scope?

Yes... (They're local variables of a function that forms an outer 
scope for local functions.)


> If so then the solution to the problem is to not delete
> contexts until you are actually done with them. If some one has a
> reference to a function, and the function is in a context, then you
> can't delete the context until the reference to the function is
> deleted.

Well, my gut feeling is that functions shouldn't send references to 
local functions to the "world outside", if those functions mess with 
local stuff. Thing is, locals are very much like C/C++/Pascal locals, 
which are allocated on the stack when a function is called (that is, 
they can exist in multiple instances if the function directly or 
indirectly calls itself), and they're supposed to be destroyed as the 
function exits.

Anyway, that's a matter of taste, I guess... The main reason why I'm 
doing it this way is that I want the VM to be RT safe, without 
opening up the can of words that is RT safe GC. (Maybe later... Right 
now, I just need this stuff to do the job ASAP.)


As to the implementation, my VM is stack-less, and just moves the 
register base around in the heap as needed. That is, the "call stack" 
is effectively a linked LIFO stack of register frames.

However, allocation of register frame space is currently done by means 
of a "top index", so it effectively works like a stack anyway. It 
would be pretty easy to allocate memory in a more malloc() style 
fashion, but the bad news is that the memory manager would have to be 
RT safe. I'm not terribly happy about code causing memory 
fragmentation for non-obvious reasons either.



> The easiest way to do that involves adding a garbage collector of
> some sort and it requires that contexts are savable. When you get a
> reference to a function you actually get a pair with a reference to
> the context and a reference to the function.

Yes... A bit like calling object member functions. That's what I 
thought of first, but then I ran into the context lifetime issue and 
realized I didn't like the whole concept of calling functions using 
upvalues like that.


> When you call the
> reference you instantiate the context and call the function.

That sounds seriously dangerous... How can you create such a context 
in a proper way, when it would normally be created implicitly when 
some function is called? (The context is effectively the locals 
belonging to one "call instance" of that function.)


> Take a look at continuations in Scheme for an example of a language
> that does something like what I just described. Also, try to find a
> copy of, Moses, Joel (1970) "The function of FUNCTION in LISP or
> why the FUNARG problem should be called the environment problem",
> M.I.T. Artificial Intelligence Memo 199, Cambridge, Mass.

Thanks! Interesting stuff.

ALGOL 60 and ALGOL 68 deal with it by simply not allowing functions to 
be returned...

That's sort of what I'd like to do, but how do you reliably prevent 
that when you have dynamic typing? Maybe I should just restrict 
function references to statically typed variables, so you can't 
accidentally pass functions to the wrong places without the compiler 
trapping it.


//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: