Author Topic: Fun coding tricks  (Read 2686 times)

0 Members and 1 Guest are viewing this topic.

Offline WMCoolmon

  • Purveyor of space crack
  • 213
The problem:

I had a variable arguments function set up to pass internal C variables along to the scripting system. As a consequence, values could be any type, including int, float, long, double, or even a custom struct used to pass object handle data (ie a ship handle).

Or in other words, take this:
Code: [Select]
void script_state::SetHookVar(char *name, char format, void *data)
and pass the data to this:

Code: [Select]
int ade_set_args(lua_State *L, char *fmt, ...)
However, ade_set_args was a lowlevel API function. It couldn't be used by any other part of the code to set global hook-specific variables (eg hv.Player) outside of the lua code itself, and I needed that high-level function call in order to be able to pass variable data along to the scripting system in other parts of the code. Unfortunately, I couldn't get the varargs working inside of a function inside of another varargs function and still have the lower-level function be usable by other parts of the code.

The solution:

Cheat. By casting the pointer to ade_odata (the custom struct) and then dereferencing it, I instructed the compiler to always copy that much of the stack for the function to use. Since float, double, etc are all smaller than the custom struct, they'll always be copied along (with a bit of garbage). As long as the format string is set correctly, the compiler only uses the proper amount of stack space.

Code: [Select]
ade_set_args(LuaState, fmt, *(ade_odata*)data)
To this day, I haven't heard of any problems.
-C

 

Offline Flipside

  • əp!sd!l£
  • 212
Good stuff :)

Fortunately, I've never been in a position where I've had to pass an unknown type to a function, it's always been 'visible' from both ends, as it were, but then, I've not really got involved with scripting languages beyond ASP, and that really wasn't by choice.

 

Offline Topgun

  • 210
but doesn't that mean the func uses more memory than necessary?
not that it doesn't work.

 

Offline WMCoolmon

  • Purveyor of space crack
  • 213
Not that I know of. Even if it does, ade_odata (IIRC) is only two variables - an int with the ID of the handle type (eg ship, weapon, subsystem, etc) and a pointer to the data that's going to be moved to the Lua interface. I can't think of any application that you would ever be coding for today that it would be an issue. If 4 bytes really made that much difference, I'd expect you to be doing the coding in ASM.
-C

  

Offline Topgun

  • 210
I am not talking about the stack. I mean in the free store. but whatever.