diff --git a/src/luaobject.cc b/src/luaobject.cc index f9e4182..38b7279 100644 --- a/src/luaobject.cc +++ b/src/luaobject.cc @@ -1,12 +1,15 @@ #define BUILDING_NODELUA #include #include "luaobject.h" +#include "utils.h" using namespace v8; LuaObject::LuaObject() {}; LuaObject::~LuaObject() {}; +Local LuaObject::functions = Object::New(); + void LuaObject::Init(Handle target) { // Prepare constructor template Local tpl = FunctionTemplate::New(New); @@ -15,10 +18,14 @@ void LuaObject::Init(Handle target) { // Prototype tpl->PrototypeTemplate()->Set(String::NewSymbol("doFile"), FunctionTemplate::New(DoFile)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("doString"), + FunctionTemplate::New(DoString)->GetFunction()); tpl->PrototypeTemplate()->Set(String::NewSymbol("getGlobal"), FunctionTemplate::New(GetGlobal)->GetFunction()); tpl->PrototypeTemplate()->Set(String::NewSymbol("setGlobal"), FunctionTemplate::New(SetGlobal)->GetFunction()); + tpl->PrototypeTemplate()->Set(String::NewSymbol("registerFunction"), + FunctionTemplate::New(RegisterFunction)->GetFunction()); tpl->PrototypeTemplate()->Set(String::NewSymbol("close"), FunctionTemplate::New(Close)->GetFunction()); @@ -30,8 +37,10 @@ Handle LuaObject::New(const Arguments& args) { HandleScope scope; LuaObject* obj = new LuaObject(); + obj->functions = Object::New(); obj->lua_ = lua_open(); luaL_openlibs(obj->lua_); + lua_register(obj->lua_, "nodelua", obj->LuaFunction); obj->Wrap(args.This()); return args.This(); @@ -52,14 +61,7 @@ Handle LuaObject::DoFile(const Arguments& args) { return scope.Close(Undefined()); } - if (!args[0]->IsString()) { - ThrowException(Exception::TypeError(String::New("Argument 1 Must Be A String"))); - return scope.Close(Undefined()); - } - - v8::String::AsciiValue arg_name(args[0]); - char *file_name = (char *) malloc(arg_name.length() + 1); - strcpy(file_name, *arg_name); + char *file_name = get_str(args[0]); LuaObject* obj = ObjectWrap::Unwrap(args.This()); if(luaL_dofile(obj->lua_, file_name)){ @@ -73,7 +75,7 @@ Handle LuaObject::DoFile(const Arguments& args) { } -Handle LuaObject::GetGlobal(const Arguments& args) { +Handle LuaObject::DoString(const Arguments& args) { HandleScope scope; if(args.Length() < 1){ @@ -81,27 +83,36 @@ Handle LuaObject::GetGlobal(const Arguments& args) { return scope.Close(Undefined()); } - if (!args[0]->IsString()) { - ThrowException(Exception::TypeError(String::New("Argument 1 Must Be A String"))); + char *lua_code = get_str(args[0]); + + LuaObject* obj = ObjectWrap::Unwrap(args.This()); + if(luaL_dostring(obj->lua_, lua_code)){ + char buf[1000]; + sprintf(buf, "Execution Of Lua Code Has Failed:\n%s\n", lua_tostring(obj->lua_, -1)); + ThrowException(Exception::TypeError(String::New(buf))); return scope.Close(Undefined()); } - v8::String::AsciiValue arg_name(args[0]); - char *global_name = (char *) malloc(arg_name.length() + 1); - strcpy(global_name, *arg_name); + return scope.Close(Undefined()); +} + + +Handle LuaObject::GetGlobal(const Arguments& args) { + HandleScope scope; + + if(args.Length() < 1){ + ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); + return scope.Close(Undefined()); + } + + char *global_name = get_str(args[0]); LuaObject* obj = ObjectWrap::Unwrap(args.This()); lua_getglobal(obj->lua_, global_name); - if(lua_isnumber(obj->lua_, -1)){ - return scope.Close(Number::New((int)lua_tonumber(obj->lua_, -1))); - }else if(lua_isstring(obj->lua_, -1)){ - return scope.Close(String::New((char *)lua_tostring(obj->lua_, -1))); - }else if(lua_isboolean(obj->lua_, -1)){ - return scope.Close(Boolean::New((int)lua_toboolean(obj->lua_, -1))); - } + Local val = lua_to_value(obj->lua_, -1); - return scope.Close(Undefined()); + return scope.Close(val); } @@ -113,19 +124,12 @@ Handle LuaObject::SetGlobal(const Arguments& args) { return scope.Close(Undefined()); } - if (!args[0]->IsString()) { - ThrowException(Exception::TypeError(String::New("Argument 1 Must Be A String"))); - return scope.Close(Undefined()); - } - - v8::String::AsciiValue arg_name(args[0]); - char *global_name = (char *) malloc(arg_name.length() + 1); - strcpy(global_name, *arg_name); + char *global_name = get_str(args[0]); LuaObject* obj = ObjectWrap::Unwrap(args.This()); if(args[1]->IsString()){ - v8::String::AsciiValue value(args[1]); + String::AsciiValue value(args[1]); char *value_str = (char *) malloc(value.length() + 1); strcpy(value_str, *value); lua_pushstring(obj->lua_, value_str); @@ -142,3 +146,55 @@ Handle LuaObject::SetGlobal(const Arguments& args) { return scope.Close(Undefined()); } + + +Handle LuaObject::RegisterFunction(const Arguments& args){ + HandleScope scope; + + if(args.Length() < 2){ + ThrowException(Exception::TypeError(String::New("Must Have 2 Arguments"))); + return scope.Close(Undefined()); + } + + if(!args[0]->IsString()){ + ThrowException(Exception::TypeError(String::New("Argument 1 Must Be A String"))); + return scope.Close(Undefined()); + } + + if(!args[1]->IsFunction()){ + ThrowException(Exception::TypeError(String::New("Argument 2 Must Be A Function"))); + return scope.Close(Undefined()); + } + + LuaObject* obj = ObjectWrap::Unwrap(args.This()); + obj->functions->Set(args[0]->ToString(), args[1]); + + return scope.Close(Undefined()); +} + +int LuaObject::LuaFunction(lua_State *L){ + int n = lua_gettop(L); + if(n < 1){ + lua_pushstring(L, "must have at least 1 argument"); + lua_error(L); + } + + if (!lua_isstring(L, 1)) { + lua_pushstring(L, "argument 1 must be a string"); + lua_error(L); + } + + Local func_name = String::New((char *)lua_tostring(L, 1)); + + const unsigned argc = n - 1; + Local* argv = new Local[argc]; + int i; + for(i = 1; i <= n; ++i){ + argv[i-1] = lua_to_value(L, i+1); + } + + Local func = Local::Cast(LuaObject::functions->Get(func_name)); + func->Call(Context::GetCurrent()->Global(), argc, argv); + + return 0; +} diff --git a/src/luaobject.h b/src/luaobject.h index d544f4f..d7e9e07 100644 --- a/src/luaobject.h +++ b/src/luaobject.h @@ -12,6 +12,8 @@ extern "C"{ class LuaObject : public node::ObjectWrap { public: static void Init(v8::Handle target); + static int LuaFunction(lua_State *L); + static v8::Local functions; private: LuaObject(); @@ -19,9 +21,12 @@ class LuaObject : public node::ObjectWrap { static v8::Handle New(const v8::Arguments& args); static v8::Handle DoFile(const v8::Arguments& args); + static v8::Handle DoString(const v8::Arguments& args); static v8::Handle GetGlobal(const v8::Arguments& args); static v8::Handle SetGlobal(const v8::Arguments& args); + static v8::Handle RegisterFunction(const v8::Arguments& args); static v8::Handle Close(const v8::Arguments& args); + lua_State *lua_; };