🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Stack-based Epoch: round 1

Published August 09, 2008
Advertisement
9:01 PM
I bit the bullet this evening and started hacking on getting stack-based Epoch implemented. So far, progress has been good; local variables are pushed onto the stack when a scope is entered, and popped off the stack when the scope exits. I estimate that about 75% of the requisite work is finished at this point.

The next phase is to get function parameters working in a stack-based manner. I'm not entirely sure how to do this at the moment, given the way I've encapsulated function calling; but as with most things, the answer should become obvious once I've banged my head against it for a few minutes.


11:09 PM
The last couple of hours have been filled with a healthy mixture of scratching my head blankly, and procrastinating. Thus far, I have made no real progress in figuring out how to get function calling to work elegantly.

Pushing parameters onto the stack and then reading them is trivial, and in fact already implemented and (theoretically) working. The problem is associating names with parameters within the function scope. For example, consider this simple Epoch program:

entrypoint : () -> (){	testfunction(2, 40)}testfunction : (integer(foo), integer(bar)) -> (){	debugwritestring(lexicalcast(string, add(foo, bar)))}


This should output 42. However, there's a minor hangup. foo and bar are variables within the context of testfunction, since they are by-value parameters. But they are not the same as local variables defined within testfunction - local variables need to reserve stack space, but parameters do not (their stack space is allocated by pushing parameters onto the stack prior to invoking the function).

The problem is that I need a clean way to enter both foo and bar into the local variable scope without flagging them as needing stack space. I'd like to avoid something as inelegant as a bool NeedsStackSpace kind of hack.

And thus the search for a solution continues...


11:38 PM
My standin solution for the time being (which may well end up being permanent) is a little magic called ghosts. The actual scope for a function doesn't actually "know" about its parameters or return values - instead, it just has a "ghost entry" that points to the real scope owning those values. The actual parameter and return value scopes are independent, and generated during the function prologue. This solves the issue of the function knowing about the parameters/return values.

However, somewhere in the mix, I've introduced a bug that's causing scopes to get deleted twice. Oops. Once that's fixed, I think I can safely say that the first (shaky) implementation of stack-based function calling is working.


11:51 PM
Bug squished! Turns out I had a nasty case of a default parameter being set to true when it shouldn't have, in fact, ever had a default value to begin with.

As of this moment, the test program listed above works correctly - integral literal values are passed across the stack. However, nothing else is passed on the stack yet; so I have a lot of work ahead.

Specifically:
  • All literals should be passed on the stack

  • Variables need to have a copy of their values pushed onto the stack

  • Return values need to be pushed on the stack to allow proper nested function calls, like foo(bar(baz()))

  • All built-in operations need to be converted to accept stack parameters


Whew! Looks like it'll be a while before Epoch is really alive again...
0 likes 1 comments

Comments

Daerax
well at least the light is visible at the end of the tunnel now.
August 09, 2008 11:37 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement