Archived

This topic is now archived and is closed to further replies.

Craazer

How do you think LUA handles script functions?

Recommended Posts

Hi I readed lua tutorial found here in gamedev and according to that lua can register function''s very easily like this: lua_register( luaVM, "addNPC", l_addNPC ); So can some one brighten a bit how does that register work? First the info about parameters what l_addNPC uses must be stored and then maybe some sort of asm code to call the function. Or?

Share this post


Link to post
Share on other sites
Hey,

Sorry, I don''t have the source in front of me atm, but lua_register is just a macro. Find the definition in one of the headers and it''s all right there.

Kory

Share this post


Link to post
Share on other sites
quote:
Original post by kspansel
Hey,

Sorry, I don''t have the source in front of me atm, but lua_register is just a macro. Find the definition in one of the headers and it''s all right there.

Kory


Oh right actualy I knew it''s a macro but ain''t that code unavaible becose it''s in libary? Well i''ll look it for more.

Share this post


Link to post
Share on other sites
quote:
Original post by Craazer
So can some one brighten a bit how does that register work? First the info about parameters what l_addNPC uses must be stored and then maybe some sort of asm code to call the function. Or?
All functions registered to Lua must take one argument, a pointer to a lua_state, and return an integer. RTFM.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
he''s not asking how to use the functions, he''s asking what
the lua interpreter code is actually doing when you register
a function, and when you call it...

As was mentioned before, you can look through the lua code,
as it''s open source, and discover this for yourself. I assume
it adds some new entry in the lua_state so the interpreter
will recognize the function, and when called, makes an external call by mangling the C function name you give it.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
just because something is open source doesn''t mean it''s wasy for everyone to understand every little thing it does. Do all of you understand every tidbit of carmack''s work? Don''t lie.
Give the guy a break would you?

Share this post


Link to post
Share on other sites
quote:
Original post by Craazer
Hi I readed lua tutorial found here in gamedev and according to that lua can register function''s very easily like this:
lua_register( luaVM, "addNPC", l_addNPC );

So can some one brighten a bit how does that register work? First the info about parameters what l_addNPC uses must be stored and then maybe some sort of asm code to call the function. Or?


I don''t know how the first part work, maybe lua just don''t do any check (params ar put on the stack, the function is called and that''s all).
The second part, yes, is some little asm code.

This is taken for an article by Scott Bilas, and I used it in my scripting engine



DWORD Call_cdecl( const void* args, size_t sz, DWORD func )

{

DWORD rc; // here''s our return value...

__asm

{

mov ecx, sz // get size of buffer

mov esi, args // get buffer

sub esp, ecx // allocate stack space

mov edi, esp // start of destination stack frame

shr ecx, 2 // make it dwords

rep movsd // copy params to real stack

call [func] // call the function

mov rc, eax // save the return value

add esp, sz // restore the stack pointer

}

return ( rc );

}



DWORD Call_stdcall( const void* args, size_t sz, DWORD func )

{

DWORD rc; // here''s our return value...

__asm

{

mov ecx, sz // get size of buffer

mov esi, args // get buffer

sub esp, ecx // allocate stack space

mov edi, esp // start of destination stack frame

shr ecx, 2 // make it dwords

rep movsd // copy it

call [func] // call the function

mov rc, eax // save the return value

}

return ( rc );

}



Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Why do you need ASM? What''s wrong with C? And what does that last post have to do with any of this? Aren''t we talking about LUA?

Share this post


Link to post
Share on other sites
quote:
Original post by Craazer
Hi I readed lua tutorial found here in gamedev and according to that lua can register function''s very easily like this:
lua_register( luaVM, "addNPC", l_addNPC );

So can some one brighten a bit how does that register work? First the info about parameters what l_addNPC uses must be stored and then maybe some sort of asm code to call the function. Or?

As far as I know, all it does is associate the string ''addNPC'' with a function pointer to l_addNPC in a table inside luaVM. There''s no ASM, and no need to store details about parameters because all functions that you give to Lua have the same parameters. This is possible because everything in Lua is done via the stack that is provided to you. It just looks up the relevant function pointer whenever the specified name is found in the script you give it.



[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

Share this post


Link to post
Share on other sites
Just in case someone is actually interested in how this might be implemented, here is a simple implementation


#include <iostream>
#include <map>
#include <string>

//A typedef for our function pointer to make things easier

//The return type/args can be changed at will, and you won''t

//need to change any other parts of this code

typedef int (*FunctionType)(int,int);

//Typedef a std::map that maps FunctionTypes to std::strings

typedef std::map<std::string,FunctionType> FunctionMap;

//This will hold our data, it will map FunctionType to it''s name

//as stored in a std::string

FunctionMap TheFunctionMap;

//This will add a function to our map

void RegisterFunction(std::string& Name,FunctionType Func)
{
//Note that if you register a function with the same name

//twice, it will overwrite the old one

TheFunctionMap[Name] = Func;
}

//Will call the function with the matching name, using

//Arg1 and Arg2. If the function is found, will return

//whatever the function returns. If it is not found

//returns 0. A better method should be used for telling,

//the caller when the function couldn''t be found...

//throwing an exception would probably be better,

//but that is left as an excersise to the reader.

//(If anyone reads this that is!)

//

int CallFunction(std::string& Name,int Arg1,int Arg2)
{
//First find the function in the map

FunctionMap::iterator iter = TheFunctionMap.find(Name);

if(iter != TheFunctionMap.end())
{
//We found a function with the given name, so call it

return (*iter)(Arg1,Arg2);
}

return 0;
}


//A few sample functions


void AddEm(int Num1,int Num2)
{
return (Num1+Num2);
}

void SubtractEm(int Num1,int Num2)
{
return (Num1-Num2);
}

void MultiplyEm(int Num1,int Num2)
{
return (Num1*Num2);
}

void DivideEm(int Num1,int Num2)
{
return (Num1/Num2);
}


int main()
{
//A driver func


RegisterFunction("Add",AddEm);
RegisterFunction("Subtract",SubtractEm);
RegisterFunction("Multiply",MultiplyEm);
RegisterFunction("Divide",DivideEm);

std::cout << "Calling function ''Add'' on ''5'' and ''2''...It returned " << CallFunction("Add",5,2) << std::endl;

return 0;
}


I don''t think that''ll compile without a couple minor changes (passing character literals when the function is expecting a string reference I think would cause it to fail), but that doesn''t really matter. The example here is kinda stupid too, but this kind of thing can be extremely useful, especially in scripting situations.

Share this post


Link to post
Share on other sites