Skip to main content
gamedev.net
🔒 Locked

Lua: Loading lua script's functions WITHOUT executing the script. Possible?

Started by Luth 13 replies 2.1k views
Original Post
Luth
Luth
Title kinda says it all. I want to load a lua file, for example:
Quote:
function Foo() return 1 end print("Executed");
and invoke Foo, such as:
lua_getglobal(L, "Foo");

/* call the function with 0 arguments, return 1 result */
if(lua_pcall(L, 0, 1, 0) != 0)
{
	std::string _sErr = lua_tostring(L, -1);
	lua_pop(L, 1); // remove error message
	throw(_sErr);
}

/* get the result */
int_ret;
GetLuaValue(_ret, L, -1);
lua_pop(L, 1);

without it executing the line: print("Executed"); Is it possible? If so, how?
Sneftel
Sneftel
Setting the global variable Foo to be equal to a function which returns 1 is one of the two things that script does. I suppose you could put in a return statement between those two things to stop it doing the second, but it seems a weird thing to do. What are you trying to accomplish?
Merick Zero
Merick Zero
Basically, what you want to do is load a bunch of lua functions from a script, right? All you really have to do is put the functions you want to load into a script and use dofile. I.E. if you have a set of functions (and only the functions, no extra commands like that print statement) in a file called system.lua then using luaL_dofile( L, "system.lua" ) should be enough put them in the lua state so they can be retrieved with getglobal
owl
owl
yes, erase the "print("Executed");" part from the script.
[size="2"]I like the Walrus best.
Luth
Luth
Yes, I just want to load the functions.

Yes, I CAN just erase the extraneous parts from the script, but that defeats the purpose of finding a way to do what I wanted. ;)

From your responses, it seems to me that there is no way to map the functions without it actually executing any extraneous lines of script in the file. I kinda thought that was the case, but I figured it'd be better to check with people who know more than I.

Thanks. :)

(Also, I didn't mean to cause any confusion, but I accidentally left out the part of the code with luaL_loadfile and the extra lua_pcall [which does the same as dofile, which was mentioned in reply])
Sneftel
Sneftel
Quote:
Original post by Luth
From your responses, it seems to me that there is no way to map the functions without it actually executing any extraneous lines of script in the file.)

No, there are plenty of ways. There's just no general purpose silver bullet works-every-time rays. For the last time, what are you trying to accomplish.
Luth
Luth
Quote:
Original post by Merick Zero
Basically, what you want to do is load a bunch of lua functions from a script, right?


Quote:
Original post by Luth
Yes, I just want to load the functions.


Load up "somefile.lua", map the functions so they can be invoked, and not run any extraneous code that might lie in the script file outside of a function ... end pair. Later on, a task which I haven't tackled yet, I'd like to unload that file and those functions so that "Foo" cannot be invoked.

Sorry if that wasn't clear enough. It made sense to me.
Sneftel
Sneftel
When I am in my car, what I am trying to "do" is push my right foot downwards onto the pedal which is below my foot. What I am trying to "accomplish" is go see the new Fantastic Four movie. (I have poor taste.)

Now, you're posting at gamedev.net as opposed to dofunnythingswithluafornoreason.net, so I'm guessing that there is some larger goal underlying your desire not to print("Executed"). Possibly even something having to do with games. Perhaps you're trying to queue up functions early to improve performance, or perhaps the script is autogenerated by a tool you can't modify but you just want utility functions from the script, or... who knows? Ideally, you know, and you can tell us, and we can use that information to figure out what you should do to accomplish that which you are trying to accomplish.
Luth
Luth
Ideally I would know, but actually, I don't. As the situation would have it, I want to load a script, check to see if a function "Foo" exists (havent done that yet), and if so, call it, and only it, then unload the script (so that Foo cant be called again) and move on.

Ideally, the situation where a script has extraneous code will not occur, but players will do funny things with scripts. This is mostly a "Hm, I wonder if this can be done in lua" for the sake of actually learning whether or not this can be done, and not actually for the goal of accomplishing a specific task. I much prefer learning to crossing off tasks on a ToDo list. I know... weird.

I'd like to give you "This why I'm doing this, yadda yadda yadda..." but it just isnt there for me to give. To use your metaphor, I'm trying to push my right foot down on the pedal just to see if I can drive; I have no particular destination. (Though, I could sure go for an In-N-Out Burger right about now....)
rip-off
rip-off
Quote:
Original post by Luth
Ideally I would know, but actually, I don't. As the situation would have it, I want to load a script, check to see if a function "Foo" exists (havent done that yet), and if so, call it, and only it, then unload the script (so that Foo cant be called again) and move on.

Ideally, the situation where a script has extraneous code will not occur, but players will do funny things with scripts. This is mostly a "Hm, I wonder if this can be done in lua" for the sake of actually learning whether or not this can be done, and not actually for the goal of accomplishing a specific task. I much prefer learning to crossing off tasks on a ToDo list. I know... weird.

I'd like to give you "This why I'm doing this, yadda yadda yadda..." but it just isnt there for me to give. To use your metaphor, I'm trying to push my right foot down on the pedal just to see if I can drive; I have no particular destination. (Though, I could sure go for an In-N-Out Burger right about now....)


Lua would be easy enough to parse I imagine, just write something to gather the stuff between function... and end (obviously making sure which end matches up with the function and which matches up with the if,do and for etc statements inside the function.
Discard the rest, execute that.

Anyway, remember if the players want to be stupid, let them. Do you really care if "Executed" gets printed somewhere, given that you will never see it. [smile]
Luth
Luth
Quote:
Original post by rip-off
Lua would be easy enough to parse I imagine, just write something to gather the stuff between function... and end (obviously making sure which end matches up with the function and which matches up with the if,do and for etc statements inside the function.
Discard the rest, execute that.

Anyway, remember if the players want to be stupid, let them. Do you really care if "Executed" gets printed somewhere, given that you will never see it. [smile]


Yeah, I thought about making a parser, but again, that kinda defeats the purpose. The purpose, again, is to see whether or not you can load just a function (or all functions) from a lua script without actually "executing" it. It seems to me that it cannot be done (without a file data parser, or some other extra-lua solution); which is as good an answer as any I could have hoped for. If someone knows better, then let me know.

So, as for the other parts that I was curious about:
1) Can you test to see if a script, once loaded and "executed" (dofile), contains a specific function, "Foo" (other than writing a file parser to find "function Foo")?
2) Once you've done everything you wanted to do with said script, (how) can it be unloaded, so that "Foo" is no longer a valid function to call?

[Edited by - Luth on June 19, 2007 5:52:26 PM]
rip-off
rip-off
Quote:
Original post by Luth
Quote:
Original post by rip-off
Lua would be easy enough to parse I imagine, just write something to gather the stuff between function... and end (obviously making sure which end matches up with the function and which matches up with the if,do and for etc statements inside the function.
Discard the rest, execute that.

Anyway, remember if the players want to be stupid, let them. Do you really care if "Executed" gets printed somewhere, given that you will never see it. [smile]


Yeah, I thought about making a parser, but again, that kinda defeats the purpose. The purpose, again, is to see whether or not you can load just a function (or all functions) from a lua script without actually "executing" it. It seems to me that it cannot be done (without a file data parser, or some other extra-lua solution); which is as good an answer as any I could have hoped for. If someone knows better, then let me know.

So, as for the other parts that I was curious about:
1) Can you test to see if a script, once loaded and "executed" (dofile), contains a specific function, "Foo" (other than writing a file parser to find "function Foo")?
2) Once you've done everything you wanted to do with said script, (how) can it be unloaded, so that "Foo" is no longer a valid function to call?


I can't imagine any easy way to do it outside making a completely isolated lua_State for just that script, running it and discarding it afterwards. Other than that you could try take some snapshot of the state and rollback somehow, but that seems messy to implement and easily broken.

Again, you seem to be imposing arbitrary rules on your scripts for no reason (at least no reason you are willing to give Sneftel).
Luth
Luth
Again: For the original question (as noted in the title of the thread), I had no purpose, goal, or objective other than simply learning if it could be done. Since it seems we've concluded it cant, I think its probably best to take these two new questions and put them in their own thread. It seems you're having a bit of a tough time taking them separately. Hopefully this'll help.
zenakuten
zenakuten
the simple solution:

-- create noop function
function noop() end

temp = print
print = noop
dofile"userscript.lua"
print = temp


the general solution:

lua_loadbuffer() -- load script
lua_getfenv() -- get scripts environment
-- for i,v in pairs(_G) do if type(v) == "function" then _G = noop end end
lua_setfenv() -- set scripts new environment, now full of noops
lua_pcall() -- execute buffer so functions are loaded, any extraneous functions are called as noops


This way you replace all functions in the script's environment with noop. You'll most likely need a list of functions you want left alone and functions you want to noop. It's not very pretty but it would work, at least for functions. The user could still do something like:

for i=1,100000000 do
for j = 1,100000000 do
local k = i + j
end
end


Anything more than this will require parsing the functions out and executing them individually.
jorelmb
jorelmb
Hey, and what about putting a global function in LUA like this:

function loadFunction( funcName )if (funcName == "foo"){     loadedFunction = function (...) { ... }} elseif (funcName == "goo"){     loadedFunction = function (...) { ... }...end


so, you first load the "loadFunction" and call it with a function name. Now you have the new function in the loadedFunction variable the new function. You call this one and then you set to nil both "loadFunction" and "loadedFunction" or something like that...

However I haven't tested this so I don't know if it can work.

------------------------------"Carpe Diem!""Failure is the prequel of success".-:Jimbo:-.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.