/* * Return the registered ID function for 'index' (deep userdata proxy), * or NULL if 'index' is not a deep userdata proxy. */ static lua_CFunction get_idfunc( lua_State *L, int index ) { lua_CFunction ret; index= STACK_ABS(L,index); STACK_GROW(L,1); STACK_CHECK(L) if (!lua_getmetatable( L, index )) return NULL; // no metatable // [-1]: metatable of [index] get_deep_lookup(L); // // [-1]: idfunc/nil ret= lua_tocfunction(L,-1); lua_pop(L,1); STACK_END(L,0) return ret; }
/* * Create a deep userdata * * proxy_ud= deep_userdata( idfunc [, ...] ) * * Creates a deep userdata entry of the type defined by 'idfunc'. * Other parameters are passed on to the 'idfunc' "new" invocation. * * 'idfunc' must fulfill the following features: * * lightuserdata= idfunc( "new" [, ...] ) -- creates a new deep data instance * void= idfunc( "delete", lightuserdata ) -- releases a deep data instance * tbl= idfunc( "metatable" ) -- gives metatable for userdata proxies * * Reference counting and true userdata proxying are taken care of for the * actual data type. * * Types using the deep userdata system (and only those!) can be passed between * separate Lua states via 'luaG_inter_move()'. * * Returns: 'proxy' userdata for accessing the deep data via 'luaG_todeep()' */ int luaG_deep_userdata( lua_State *L ) { lua_CFunction idfunc= lua_tocfunction( L,1 ); int pushed; DEEP_PRELUDE *prelude= DEEP_MALLOC( sizeof(DEEP_PRELUDE) ); ASSERT_L(prelude); prelude->refcount= 0; // 'luaG_push_proxy' will lift it to 1 STACK_GROW(L,1); STACK_CHECK(L) // Replace 'idfunc' with "new" in the stack (keep possible other params) // lua_remove(L,1); lua_pushliteral( L, "new" ); lua_insert(L,1); // lightuserdata= idfunc( "new" [, ...] ) // pushed= idfunc(L); if ((pushed!=1) || lua_type(L,-1) != LUA_TLIGHTUSERDATA) luaL_error( L, "Bad idfunc on \"new\": did not return light userdata" ); prelude->deep= lua_touserdata(L,-1); ASSERT_L(prelude->deep); lua_pop(L,1); // pop deep data luaG_push_proxy( L, idfunc, prelude ); // // [-1]: proxy userdata STACK_END(L,1) return 1; }
static int wslua_attribute_dispatcher (lua_State *L) { lua_CFunction cfunc = NULL; const gchar *fieldname = lua_shiftstring(L,2); /* remove the field name */ const gchar *classname = NULL; const gchar *type = NULL; /* the userdata object is at index 1, fieldname was at 2 but no longer, now we get the getter/setter table at upvalue 1 */ if (!lua_istable(L, lua_upvalueindex(1))) return luaL_error(L, "Accessor dispatcher cannot retrieve the metatable"); lua_rawgetfield(L, lua_upvalueindex(1), fieldname); /* field's cfunction is now at -1 */ if (!lua_iscfunction(L, -1)) { lua_pop(L,1); /* pop whatever we got before */ /* check if there's a methods table */ if (lua_istable(L, lua_upvalueindex(2))) { lua_rawgetfield(L, lua_upvalueindex(2), fieldname); if (lua_iscfunction(L,-1)) { /* we found a method for Lua to call, so give it back to Lua */ return 1; } lua_pop(L,1); /* pop whatever we got before */ } classname = wslua_typeof(L, 1); type = wslua_typeof(L, lua_upvalueindex(1)); lua_pop(L, 1); /* pop the nil/invalid getfield result */ return luaL_error(L, "No such '%s' %s attribute/field for object type '%s'", fieldname, type, classname); } cfunc = lua_tocfunction(L, -1); lua_pop(L, 1); /* pop the cfunction */ /* the stack is now as if it had been calling the getter/setter c-function directly, so do it */ return (*cfunc)(L); }
int Global_addon::regmod(lua_State *L) { // Create a shortcut to string.format as sprintf lua_getglobal(L, "string"); lua_getfield(L, -1, "format"); sprintf = lua_tocfunction(L, -1); lua_setglobal(L, "sprintf"); lua_pop(L, 1); // Pop string module // Other functions lua_pushcfunction(L, Global_addon::printf); lua_setglobal(L, "printf"); lua_pushcfunction(L, Global_addon::unpack2); lua_setglobal(L, "unpack2"); lua_pushcfunction(L, Global_addon::include); lua_setglobal(L, "include"); // Clear our included list (in case it is dirty from last time) includedList.clear(); return MicroMacro::ERR_OK; }
static lua_CFunction get(lua_State* L, int index = -1) { return lua_tocfunction(L, index); }
lua_CFunction LuaAgent::ToCFunction(int idx) { return lua_tocfunction(luaState,idx); }
LuaCFunc luaToFunction(lua_State* plua_state, int index) { return (LuaCFunc)lua_tocfunction(plua_state, index); }
int MyCPrint( lua_State* L ) { // 获取参数数量 int nArgs = lua_gettop(L); for (int i = 1; i <= nArgs; i++) { // 获取参数类型 size_t nLen = 0; int bRet = 0; LUA_INTEGER nRet = 0; LUA_NUMBER dblRet = 0; const void* pAddr = NULL; const char* szRet = NULL; lua_State* pL = NULL; lua_CFunction pFunc = 0; int nType = lua_type(L, i); switch (nType) { case LUA_TNIL: printf("参数 %d 类型为:NIL\n", i); break; case LUA_TBOOLEAN: bRet = lua_toboolean(L, i); printf("参数 %d 类型为:BOOLEAN value = %s\n", i, (!!bRet ? "true" : "false")); break; case LUA_TLIGHTUSERDATA: pAddr = lua_touserdata(L, i); printf("参数 %d 类型为:LIGHTUSERDATA pointer = 0x%08X\n", i, (int)pAddr); break; case LUA_TNUMBER: nRet = lua_tointeger(L, i); dblRet = lua_tonumber(L, i); if (nRet < dblRet) // 浮点数 { printf("参数 %d 类型为:NUMBER value = %g\n", i, dblRet); } else { printf("参数 %d 类型为:NUMBER value = %ld\n", i, nRet); } break; case LUA_TSTRING: nLen = lua_objlen(L, i); szRet = lua_tostring(L, i); printf("参数 %d 类型为:STRING len = %u value = %s\n", i, nLen, szRet); break; case LUA_TTABLE: nLen = lua_objlen(L, i); pAddr = lua_topointer(L, i); printf("参数 %d 类型为:TABLE len = %u pointer = 0x%p\n", i, nLen, (int)pAddr); break; case LUA_TFUNCTION: nLen = lua_objlen(L, i); pFunc = lua_tocfunction(L, i); printf("参数 %d 类型为:FUNCTION len = %u pointer = 0x%p\n", i, nLen, (int)pFunc); break; case LUA_TUSERDATA: pAddr = lua_touserdata(L, i); printf("参数 %d 类型为:USERDATA pointer = 0x%p\n", i, (int)pAddr); break; case LUA_TTHREAD: pL = lua_tothread(L, i); printf("参数 %d 类型为:THREAD pointer = 0x%p\n", i, (int)pL); break; default: nLen = lua_objlen(L, i); szRet = lua_typename(L, i); printf("参数 %d 类型未知!len = %u typename = %s\n", i, nLen, szRet); break; } } return 0; }
bool VRSDClientLuaImplementation::GetSubSymbolsForLocal(char* LocalName, DynArray_cl<VRSDScriptSymbol>& SubSymbols, unsigned int& SubSymbolCount) { VASSERT(m_pLuaState); if(!m_pLuaState || !m_pActivationRecord) return false; SubSymbolCount = 0; // we can only get local symbols without a crash if we are really in a Lua code execution path if(strcmp(m_pActivationRecord->what, "Lua")) return true; VLuaStackCleaner stackCleaner(m_pLuaState); ScopedBooleanToTrue disableDebugCallback(m_bDebuggerRetrievingValues); char* pSymbolName = NULL; int iLocalIndex = 1; VMemoryTempBuffer<512> copyBuffer(LocalName); // operate on a copy string in the tokenizer VStringTokenizerInPlace Tokenizer(copyBuffer.AsChar(), '.'); char* pCurrent = Tokenizer.Next(); while((pSymbolName = (char*)lua_getlocal(m_pLuaState, m_pActivationRecord, iLocalIndex)) != NULL) { //stack: .., localX, TOP // check if this local variable is the one we want if(!strcmp(pSymbolName, pCurrent)) { //the local is already on the stack if(LookupPath(Tokenizer) != HKV_SUCCESS) return false; // now we can iterate over the contents of the table // first key for the iteration lua_pushnil(m_pLuaState); //stack: .., localX, {field}, nil, TOP //access the last field while (lua_next(m_pLuaState, -2) != 0) //stack: .., localX, {field}, key, value TOP { // we only want string fields and numeric fields // (lua_isstring returns also true for numbers, using // tostring later on will cast the number to a string) int iKeyType = lua_type(m_pLuaState, -2); if (iKeyType==LUA_TNUMBER || iKeyType==LUA_TSTRING) { VString sKeyBuffer; //this if prevents a conversion of number on the Lua stack if(iKeyType==LUA_TNUMBER) sKeyBuffer.Format("%1.0f", lua_tonumber(m_pLuaState, -2)); else sKeyBuffer = lua_tostring(m_pLuaState, -2); if(!sKeyBuffer.IsEmpty()) { int iValueType = lua_type(m_pLuaState, -1); VString sValueBuffer; // table member variable switch (iValueType) { case LUA_TTABLE: // add a symbol for the table AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), "table", VRSDScriptSymbol::SYMBOL_TABLE); break; case LUA_TNUMBER: // numeric member variable sValueBuffer.Format("%f", lua_tonumber(m_pLuaState, -1)); AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_NUMBER); break; case LUA_TSTRING: AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), lua_tostring(m_pLuaState, -1), VRSDScriptSymbol::SYMBOL_STRING); break; case LUA_TFUNCTION: sValueBuffer.Format("function:0x%p", lua_tocfunction(m_pLuaState, -1)); AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_FUNCTION); break; case LUA_TBOOLEAN: AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), lua_toboolean(m_pLuaState, -1) ? "true" : "false", VRSDScriptSymbol::SYMBOL_BOOLEAN); break; case LUA_TNIL: AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), "nil", VRSDScriptSymbol::SYMBOL_CLASS); break; case LUA_TTHREAD: sValueBuffer.Format("thread:0x%p", lua_tothread(m_pLuaState, -1)); AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_CLASS); break; case LUA_TUSERDATA: sValueBuffer.Format("userdata:0x%p", lua_touserdata(m_pLuaState, -1)); AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_USERDATA); break; default: AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), "unknown", VRSDScriptSymbol::SYMBOL_STRING); break; } } } // remove the value, keep the key for the next iteration lua_pop(m_pLuaState, 1); //stack: .., localX, {field}, key, TOP } return true; } // clean up the stack and increment the index to get the next local variable lua_pop(m_pLuaState, 1); //stack: .., TOP iLocalIndex++; } return true; }
LUAMOD_API int luaopen_profile(lua_State *L) { luaL_checkversion(L); luaL_Reg l[] = { { "start", lstart }, { "stop", lstop }, { "resume", lresume }, { "yield", lyield }, { "resume_co", lresume_co }, { "yield_co", lyield_co }, { NULL, NULL }, }; luaL_newlibtable(L,l); lua_newtable(L); // table thread->start time lua_newtable(L); // table thread->total time lua_newtable(L); // weak table lua_pushliteral(L, "kv"); lua_setfield(L, -2, "__mode"); lua_pushvalue(L, -1); lua_setmetatable(L, -3); lua_setmetatable(L, -3); lua_pushnil(L); // cfunction (coroutine.resume or coroutine.yield) luaL_setfuncs(L,l,3); int libtable = lua_gettop(L); lua_getglobal(L, "coroutine"); lua_getfield(L, -1, "resume"); lua_CFunction co_resume = lua_tocfunction(L, -1); if (co_resume == NULL) return luaL_error(L, "Can't get coroutine.resume"); lua_pop(L,1); lua_getfield(L, libtable, "resume"); lua_pushcfunction(L, co_resume); lua_setupvalue(L, -2, 3); lua_pop(L,1); lua_getfield(L, libtable, "resume_co"); lua_pushcfunction(L, co_resume); lua_setupvalue(L, -2, 3); lua_pop(L,1); lua_getfield(L, -1, "yield"); lua_CFunction co_yield = lua_tocfunction(L, -1); if (co_yield == NULL) return luaL_error(L, "Can't get coroutine.yield"); lua_pop(L,1); lua_getfield(L, libtable, "yield"); lua_pushcfunction(L, co_yield); lua_setupvalue(L, -2, 3); lua_pop(L,1); lua_getfield(L, libtable, "yield_co"); lua_pushcfunction(L, co_yield); lua_setupvalue(L, -2, 3); lua_pop(L,1); lua_settop(L, libtable); return 1; }
static bool inter_copy_func(lua_State* from, lua_State* to, int cache, int i){ ASSERT(lua_isfunction(from, i)); if(push_cached_func(from, to, cache, i)){ lua_remove(to, -2); // remove the key return true; } int to_top = lua_gettop(to); bool ret = true; bool needToPush = (i != lua_gettop(from)); if(needToPush) lua_pushvalue(from, i); luaL_Buffer b; luaL_buffinit(from, &b); lua_CFunction cfunc = NULL; if(lua_dump(from, buf_writer, &b) == 0) { luaL_pushresult(&b); size_t sz; char const* s = lua_tolstring(from, -1, &sz); if(!luaL_loadbuffer(to, s, sz, NULL)){ ret = false; // todo: error out }else{ // cache the function // ... key, function lua_insert(to, -2); // ... function, key lua_pushvalue(to, -2); // ... function, key, function lua_rawset(to, cache); // ... function } lua_pop(from, 1); // pop the compilied source }else{ // c function? cfunc = lua_tocfunction(from, i); ret = cfunc != NULL; // c function won't be cached because the closure could be different lua_pop(to, 1); // pop th key } if(needToPush) lua_pop(from, 1); // copy the upvalues int j = 0; for(;ret && lua_getupvalue(from, i, j+1) != NULL; ++j) { ret = inter_copy_one(from, to, cache, lua_gettop(from)); lua_pop(from, 1); } if(ret == false){ return false; } if(cfunc != NULL){ lua_pushcclosure(to, cfunc, j); }else{ for(;j>0;--j){ lua_setupvalue(to, to_top + 1, j); } } ASSERT(lua_isfunction(to, -1)); return true; }
int Thermal::help(lua_State* L) { if(lua_gettop(L) == 0) { lua_pushstring(L, "Generates a the random thermal field of a *SpinSystem*"); lua_pushstring(L, "1 *3Vector* or *SpinSystem*, 1 Optional *Random*: System Size and built in RNG"); lua_pushstring(L, ""); //output, empty return 3; } if(lua_istable(L, 1)) { return 0; } if(!lua_iscfunction(L, 1)) { return luaL_error(L, "help expect zero arguments or 1 function."); } lua_CFunction func = lua_tocfunction(L, 1); if(func == l_apply) { lua_pushstring(L, "Generates a the random thermal field of a *SpinSystem*"); lua_pushstring(L, "1 *SpinSystem*, 1 Optional *Random*,: The first argument is the spin system which will receive the field. The second optional argument is a random number generator that is used as a source of random values, if absent then the RNG supplied in the constructor will be used."); lua_pushstring(L, ""); return 3; } if(func == l_scalesite) { lua_pushstring(L, "Scale the thermal field at a site. This allows non-uniform thermal effects over a lattice."); lua_pushstring(L, "1 *3Vector*, 1 Number: The vectors define the lattice sites that will have a scaled thermal effect, the number is the how the thermal field is scaled."); lua_pushstring(L, ""); return 3; } if(func == l_settemp) { lua_pushstring(L, "Sets the base value of the temperature. "); lua_pushstring(L, "1 number: temperature of the system."); lua_pushstring(L, ""); return 3; } if(func == l_gettemp) { lua_pushstring(L, "Gets the base value of the temperature. "); lua_pushstring(L, ""); lua_pushstring(L, "1 number: temperature of the system."); return 3; } if(func == l_getscalearray) { lua_pushstring(L, "Get an array representing the thermal scale at each site. This array is connected to the Operator so changes to the returned array will change the Operator."); lua_pushstring(L, ""); lua_pushstring(L, "1 Array: The thermal scale of the sites."); return 3; } if(func == l_setscalearray) { lua_pushstring(L, "Set an array representing the new thermal scale at each site."); lua_pushstring(L, "1 Array: The thermal scale of the sites."); lua_pushstring(L, ""); return 3; } if(func == l_rng) { lua_pushstring(L, "Get the *Random* number generator supplied at initialization"); lua_pushstring(L, ""); lua_pushstring(L, "1 *Random* or 1 nil: RNG"); return 3; } return SpinOperation::help(L); }
static int install(lua_State *L) { int type= lua_type(L, 1); SIGN_HANDLER_FUN domain = NULL; printf("args type : "); switch (type){ case LUA_TNIL: printf("1\n"); break; case LUA_TNUMBER: printf("2\n"); break; case LUA_TBOOLEAN: printf("3\n"); break; case LUA_TSTRING: printf("4\n"); lua_func_cmds = lua_tostring (L, 1); break; case LUA_TTABLE: printf("5\n"); break; case LUA_TFUNCTION: printf("6\n"); lua_CFunction sig_handler = lua_tocfunction (L, 1); lua_cpcall(L, sig_handler, NULL); break; case LUA_TUSERDATA: printf("7\n"); break; case LUA_TTHREAD: printf("8\n"); break; case LUA_TLIGHTUSERDATA: printf("9\n"); break; default: printf("10\n"); break; } //int test=0; { void run_lua_string(int signum){ //test++; //printf("--------sign %d-------\n", signum); lua_State *L = lua_open(); luaopen_base(L); luaL_openlibs(L); if(luaL_dostring(L, lua_func_cmds)){ const char* errMsg = lua_tostring(L, -1); printf("%s\n", errMsg); }; //luaL_dostring(L, "print('xxxxxxxx')"); lua_close(L); //return test; } //test = run_lua_string(); //lua_pushnumber(L, test); domain = run_lua_string; }
LUABIND_API bool is_luabind_function(lua_State* L, int index) { return lua_tocfunction(L, index) == &function_dispatcher; }
int luaopen_testlib_profile(lua_State *L) { // #ifdef DEBUG_LOG // printf("%s\n", __FUNCTION__); // #endif luaL_checkversion(L); luaL_Reg l[] = { { "start", lstart }, { "stop", lstop }, { "resume", lresume }, { "yield", lyield }, { "resume_co", lresume_co }, { "yield_co", lyield_co }, { NULL, NULL }, }; luaL_newlibtable(L,l); lua_newtable(L); // table thread->start time lua_newtable(L); // table thread->total time lua_newtable(L); // weak table lua_pushliteral(L, "kv"); // 同lua_pushstring,复制一个string lua_setfield(L, -2, "__mode"); // -2指向的weak table,key:__mode, value:栈顶, weak_table[__mode] = kv, pop出value lua_pushvalue(L, -1); // 复制一个weak table引用在栈顶 lua_setmetatable(L, -3); // pop出上面复制的weak table,设置为total time table的metatable lua_setmetatable(L, -3); // pop出第一个weak table,设置为start time table的metatable lua_pushnil(L); // cfunction (coroutine.resume or coroutine.yield), 留出位置给下面设置lua自己的协程函数 luaL_setfuncs(L,l,3); // 所有函数共享3个upvalues,这里调用完毕会pop出上面三个value int libtable = lua_gettop(L); // libtable的index栈位置 lua_getglobal(L, "coroutine"); lua_getfield(L, -1, "resume"); // coroutine table里的resume key对应的value压顶 lua_CFunction co_resume = lua_tocfunction(L, -1); // 取出lua自己的resume的c函数 if (co_resume == NULL) return luaL_error(L, "Can't get coroutine.resume"); lua_pop(L,1); lua_getfield(L, libtable, "resume"); // libtable里的resume key对应的函数压顶 lua_pushcfunction(L, co_resume); // lua自己的resume函数压顶 lua_setupvalue(L, -2, 3); // -2指向的闭包,该闭包的第3个upvalue,设置为栈顶的lua自己的resume函数,pop出栈顶 lua_pop(L,1); // pop出resume闭包 lua_getfield(L, libtable, "resume_co"); lua_pushcfunction(L, co_resume); lua_setupvalue(L, -2, 3); lua_pop(L,1); lua_getfield(L, -1, "yield"); lua_CFunction co_yield = lua_tocfunction(L, -1); // 取出lua自己的yield c函数 if (co_yield == NULL) return luaL_error(L, "Can't get coroutine.yield"); lua_pop(L,1); lua_getfield(L, libtable, "yield"); lua_pushcfunction(L, co_yield); lua_setupvalue(L, -2, 3); lua_pop(L,1); lua_getfield(L, libtable, "yield_co"); lua_pushcfunction(L, co_yield); lua_setupvalue(L, -2, 3); lua_pop(L,1); lua_settop(L, libtable); return 1; }
void BinReader::readMethodBase(MethodBase *mbase) { readMemberInfo(mbase); int numMethodAttributes = bytes->readInt(); for (int i = 0; i < numMethodAttributes; i++) { const char *methodAttr = readPoolString(); if (!strcmp(methodAttr, "static")) { mbase->attr.isStatic = true; } else if (!strcmp(methodAttr, "public")) { mbase->attr.isPublic = true; } else if (!strcmp(methodAttr, "private")) { mbase->attr.isPrivate = true; } else if (!strcmp(methodAttr, "protected")) { mbase->attr.isProtected = true; } else if (!strcmp(methodAttr, "native")) { mbase->attr.isNative = true; } else if (!strcmp(methodAttr, "virtual")) { mbase->attr.isVirtual = true; } else if (!strcmp(methodAttr, "supercall")) { mbase->attr.hasSuperCall = true; } else if (!strcmp(methodAttr, "operator")) { mbase->attr.isOperator = true; } } if (bytes->readBoolean()) { mbase->setTemplateInfo(readTemplateTypes()); } // parameters int numParamaters = bytes->readInt(); for (int i = 0; i < numParamaters; i++) { ParameterInfo *param = lmNew(NULL) ParameterInfo(); mbase->parameters.push_back(param); const char *name = readPoolString(); Type *ptype = NULL; if (bytes->readBoolean()) { ptype = getType(readPoolString()); } bool hasDefault = bytes->readBoolean(); bool isVarArg = bytes->readBoolean(); int numTemplateTypes = bytes->readInt(); for (int j = 0; j < numTemplateTypes; j++) { Type *ttype = getType(readPoolString()); param->addTemplateType(ttype); } param->position = (int)i; param->name = name; param->member = mbase; param->parameterType = ptype; param->attributes.hasDefault = hasDefault; param->attributes.isVarArgs = isVarArg; } // find first default argument for (UTsize i = 0; i < mbase->parameters.size(); i++) { if (mbase->parameters.at(i)->attributes.hasDefault) { mbase->firstDefaultArg = i; break; } } if (mbase->isNative()) { // empty bytecode bytes->readString(); lua_CFunction function = NULL; lua_State *L = vm->VM(); int top = lua_gettop(L); lua_settop(L, top); lsr_pushmethodbase(L, mbase); if (!lua_isnil(L, -1)) { function = lua_tocfunction(L, -1); if (!function) { if (lua_isuserdata(L, -1)) { mbase->setFastCall((void *)lua_topointer(L, -1)); } } } lua_pop(L, 1); if (!mbase->isFastCall()) { if (!function) { if (mbase->declaringType->isPrimitive() && mbase->isStatic()) { LSError("Missing primitive native function %s:%s", mbase->declaringType->getFullName().c_str(), mbase->name.c_str()); } else if (!mbase->declaringType->isPrimitive()) { LSError("Missing native function %s:%s", mbase->declaringType->getFullName().c_str(), mbase->name.c_str()); } } else { if (mbase->declaringType->isPrimitive() && !mbase->isStatic()) { LSError("Unnecessary primitive native instance function %s:%s", mbase->declaringType->getFullName().c_str(), mbase->name.c_str()); } } } } else { mbase->setByteCode(ByteCode::decode64(bytes->readString())); } }
static void inter_copy_func( lua_State *L2, uint_t L2_cache_i, lua_State *L, uint_t i ) { lua_CFunction cfunc= lua_tocfunction( L,i ); unsigned n; ASSERT_L( L2_cache_i != 0 ); STACK_GROW(L,2); STACK_CHECK(L) if (!cfunc) { // Lua function luaL_Buffer b; const char *s; size_t sz; int tmp; const char *name= NULL; #if 0 // "To get information about a function you push it onto the // stack and start the what string with the character '>'." // { lua_Debug ar; lua_pushvalue( L, i ); lua_getinfo(L, ">n", &ar); // fills 'name' and 'namewhat', pops function name= ar.namewhat; fprintf( stderr, "NAME: %s\n", name ); // just gives NULL } #endif // 'lua_dump()' needs the function at top of stack // if (i!=-1) lua_pushvalue( L, i ); luaL_buffinit(L,&b); tmp= lua_dump(L, buf_writer, &b); ASSERT_L(tmp==0); // // "value returned is the error code returned by the last call // to the writer" (and we only return 0) luaL_pushresult(&b); // pushes dumped string on 'L' s= lua_tolstring(L,-1,&sz); ASSERT_L( s && sz ); if (i!=-1) lua_remove( L, -2 ); // Note: Line numbers seem to be taken precisely from the // original function. 'name' is not used since the chunk // is precompiled (it seems...). // // TBD: Can we get the function's original name through, as well? // if (luaL_loadbuffer(L2, s, sz, name) != 0) { // chunk is precompiled so only LUA_ERRMEM can happen // "Otherwise, it pushes an error message" // STACK_GROW( L,1 ); luaL_error( L, "%s", lua_tostring(L2,-1) ); } lua_pop(L,1); // remove the dumped string STACK_MID(L,0) }
inline lua_CFunction to<lua_CFunction>(lua_State* L, int index) { LUNA_INDEX_ASSERT(L, index); return lua_tocfunction(L, index); }
static inline int _cloneNoTable(lua_State *L, const int idx, lua_State *L_, const int r_lv ) { int ret_= 1; switch(lua_type(L, idx ) ) { case LUA_TSTRING: { size_t l; const char *s= lua_tolstring(L, idx, &l ); lua_pushlstring(L_, s, l ); } break; case LUA_TNUMBER: lua_pushnumber(L_, lua_tonumber(L, idx ) ); break; case LUA_TLIGHTUSERDATA: lua_pushlightuserdata(L_, lua_touserdata(L, idx ) ); break; case LUA_TBOOLEAN: lua_pushboolean(L_, lua_toboolean(L, idx ) ); break; case LUA_TUSERDATA: { // userdata 的 meta 暂时不能拷贝 const size_t l= lua_objlen(L, idx ); memmove(lua_newuserdata(L_, l ), lua_touserdata(L, idx ), l ); if(0) //屏蔽 meta 处理 if(lua_getmetatable(L, idx ) ) { const int k= _cloneRecursion(L, lua_gettop(L ), L_, ((0<= r_lv )? r_lv: -1 ) ); lua_pop(L, 1 ); if((0<= r_lv )&& lua_istable(L_, -1 )&& (0< k ) ) printf("%*.s__{%3d}\n", (r_lv- 1 )* 2, "", k ); lua_setmetatable(L_, -2 ); } } break; case LUA_TFUNCTION: if(lua_iscfunction(L, idx ) ) { int j= 1; lua_CFunction f= lua_tocfunction(L, idx ); for(j= 1; UPVALUE_MAX>= j; ++j ) { //设置函数的 upvalue if(!lua_getupvalue(L, idx, j ) ) break; _cloneRecursion(L, lua_gettop(L ), L_, ((0<= r_lv )? (r_lv+ 1 ): -1 ) ); lua_pop(L, 1 ); } lua_pushcclosure(L_, f, j- 1 ); } else { int j= 1; DUMP_CB ud; memset(&ud, 0, sizeof(ud ) ); lua_pushvalue(L, idx ); lua_dump(L, writer_CB, &ud ); if(ud.p ) { //载入函数到新的栈 lua_load(L_, reader_CB, &ud, (char * )0 ); free(ud.p ); } lua_pop(L, 1 ); for(j= 1; UPVALUE_MAX>= j; ++j ) { //设置函数的 upvalue if(!lua_getupvalue(L, idx, j ) ) break; printf("upvalue %d\n", j ); _cloneRecursion(L, lua_gettop(L ), L_, ((0<= r_lv )? (r_lv+ 1 ): -1 ) ); lua_pop(L, 1 ); lua_setupvalue(L_, -2, j ); } } break; case LUA_TNIL: lua_pushnil(L_ ); break; case LUA_TNONE: case LUA_TTHREAD: //? default: ret_= 0; break; } return ret_; }
static c_closure get(lua_State* L, int index = -1) { return c_closure(lua_tocfunction(L, index), -1); }
static void* reserve_code(struct jit* jit, lua_State* L, size_t sz) { struct page* page; size_t off = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->off : 0; size_t size = (jit->pagenum > 0) ? jit->pages[jit->pagenum-1]->size : 0; if (off + sz >= size) { int i; uint8_t* pdata; cfunction func; /* need to create a new page */ jit->pages = (struct page**) realloc(jit->pages, (++jit->pagenum) * sizeof(jit->pages[0])); size = ALIGN_UP(sz + LINKTABLE_MAX_SIZE + sizeof(struct page), jit->align_page_size); page = (struct page*) AllocPage(size); jit->pages[jit->pagenum-1] = page; pdata = (uint8_t*) page; page->size = size; page->off = sizeof(struct page); lua_newtable(L); #define ADDFUNC(DLL, NAME) \ lua_pushliteral(L, #NAME); \ func = DLL ? (cfunction) GetProcAddressA(DLL, #NAME) : NULL; \ func = func ? func : (cfunction) &NAME; \ lua_pushcfunction(L, (lua_CFunction) func); \ lua_rawset(L, -3) ADDFUNC(NULL, check_double); ADDFUNC(NULL, check_float); ADDFUNC(NULL, check_uint64); ADDFUNC(NULL, check_int64); ADDFUNC(NULL, check_int32); ADDFUNC(NULL, check_uint32); ADDFUNC(NULL, check_uintptr); ADDFUNC(NULL, check_enum); ADDFUNC(NULL, check_typed_pointer); ADDFUNC(NULL, check_typed_cfunction); ADDFUNC(NULL, check_complex_double); ADDFUNC(NULL, check_complex_float); ADDFUNC(NULL, unpack_varargs_stack); ADDFUNC(NULL, unpack_varargs_stack_skip); ADDFUNC(NULL, unpack_varargs_reg); ADDFUNC(NULL, unpack_varargs_float); ADDFUNC(NULL, unpack_varargs_int); ADDFUNC(NULL, push_cdata); ADDFUNC(NULL, push_int); ADDFUNC(NULL, push_uint); ADDFUNC(NULL, lua_pushinteger); ADDFUNC(NULL, push_float); ADDFUNC(jit->kernel32_dll, SetLastError); ADDFUNC(jit->kernel32_dll, GetLastError); ADDFUNC(jit->lua_dll, luaL_error); ADDFUNC(jit->lua_dll, lua_pushnumber); ADDFUNC(jit->lua_dll, lua_pushboolean); ADDFUNC(jit->lua_dll, lua_gettop); ADDFUNC(jit->lua_dll, lua_rawgeti); ADDFUNC(jit->lua_dll, lua_pushnil); ADDFUNC(jit->lua_dll, lua_callk); ADDFUNC(jit->lua_dll, lua_settop); ADDFUNC(jit->lua_dll, lua_remove); //CHANGES: BEGIN ADDFUNC(jit->lua_dll, lua_pushlightuserdata); //CHANGES: END #undef ADDFUNC for (i = 0; extnames[i] != NULL; i++) { if (strcmp(extnames[i], "FUNCTION") == 0) { shred(pdata + page->off, 0, JUMP_SIZE); jit->function_extern = i; } else { lua_getfield(L, -1, extnames[i]); func = (cfunction) lua_tocfunction(L, -1); if (func == NULL) { luaL_error(L, "internal error: missing link for %s", extnames[i]); } compile_extern_jump(jit, L, func, pdata + page->off); lua_pop(L, 1); } page->off += JUMP_SIZE; } page->freed = page->off; lua_pop(L, 1); } else { page = jit->pages[jit->pagenum-1]; EnableWrite(page, page->size); } return (uint8_t*) page + page->off; }
static int inject_payload(lua_State* lua) { static const char* default_type = "txt"; static const char* func_name = "inject_payload"; void* luserdata = lua_touserdata(lua, lua_upvalueindex(1)); if (NULL == luserdata) { return luaL_error(lua, "%s invalid lightuserdata", func_name); } lua_sandbox* lsb = (lua_sandbox*)luserdata; int n = lua_gettop(lua); if (n > 2) { lsb_output(lsb, 3, n, 1); lua_pop(lua, n - 2); } size_t len = 0; const char* output = lsb_get_output(lsb, &len); if (!len) return 0; if (n > 0) { if (lua_type(lua, 1) != LUA_TSTRING) { return luaL_error(lua, "%s() payload_type argument must be a string", func_name); } } if (n > 1) { if (lua_type(lua, 2) != LUA_TSTRING) { return luaL_error(lua, "%s() payload_name argument must be a string", func_name); } } // build up a heka message table lua_createtable(lua, 0, 2); // message lua_createtable(lua, 0, 2); // Fields if (n > 0) { lua_pushvalue(lua, 1); } else { lua_pushstring(lua, default_type); } lua_setfield(lua, -2, "payload_type"); if (n > 1) { lua_pushvalue(lua, 2); lua_setfield(lua, -2, "payload_name"); } lua_setfield(lua, -2, "Fields"); lua_pushstring(lua, "inject_payload"); lua_setfield(lua, -2, "Type"); lua_pushlstring(lua, output, len); lua_setfield(lua, -2, "Payload"); lua_replace(lua, 1); // use inject_message to actually deliver it lua_getglobal(lua, "inject_message"); lua_CFunction fp = lua_tocfunction(lua, -1); lua_pop(lua, 1); // remove function pointer if (fp) { fp(lua); } else { return luaL_error(lua, "%s() failed to call inject_message", func_name); } return 0; }
/*** Install a signal handler for this signal number. Although this is the same API as signal(2), it uses sigaction for guaranteed semantics. @function signal @see signal.lua @int signum @tparam[opt=SIG_DFL] function handler function, or `SIG_IGN` or `SIG_DFL` constants @param[opt] flags the `sa_flags` element of `struct sigaction` @treturn function previous handler function @see sigaction(2) */ static int Psignal (lua_State *L) { struct sigaction sa, oldsa; int sig = checkint(L, 1), ret; void (*handler)(int) = sig_postpone; checknargs(L, 3); /* Check handler is OK */ switch (lua_type(L, 2)) { case LUA_TNIL: case LUA_TSTRING: handler = Fsigmacros[luaL_checkoption(L, 2, "SIG_DFL", Ssigmacros)]; break; case LUA_TFUNCTION: if (lua_tocfunction(L, 2) == sig_handler_wrap) { lua_getupvalue(L, 2, 1); handler = lua_touserdata(L, -1); lua_pop(L, 1); } break; default: argtypeerror(L, 2, "function, string or nil"); break; } /* Set up C signal handler, getting old handler */ sa.sa_handler = handler; sa.sa_flags = optint(L, 3, 0); sigfillset(&sa.sa_mask); ret = sigaction(sig, &sa, &oldsa); if (ret == -1) return 0; /* Set Lua handler if necessary */ if (handler == sig_postpone) { lua_pushlightuserdata(L, &signalL); /* We could use an upvalue, but we need this for sig_handle anyway. */ lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, 1); lua_pushvalue(L, 2); lua_rawset(L, -3); lua_pop(L, 1); } /* Push old handler as result */ if (oldsa.sa_handler == sig_postpone) { lua_pushlightuserdata(L, &signalL); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, 1); lua_rawget(L, -2); } else if (oldsa.sa_handler == SIG_DFL) lua_pushstring(L, "SIG_DFL"); else if (oldsa.sa_handler == SIG_IGN) lua_pushstring(L, "SIG_IGN"); else { lua_pushinteger(L, sig); lua_pushlightuserdata(L, oldsa.sa_handler); lua_pushcclosure(L, sig_handler_wrap, 2); } return 1; }
lua_CFunction l_data_type<lua_CFunction>::get(lua_State *l, int n) { luaL_checktype(l, n, LUA_TFUNCTION); return lua_tocfunction(l, n); }
virtual void fastWriteStackObject(int iIndex) { lua_State *L = m_L; if(lua_type(L, iIndex) != LUA_TUSERDATA) { writeStackObject(iIndex); return; } // Convert index from relative to absolute if(iIndex < 0 && iIndex > LUA_REGISTRYINDEX) iIndex = lua_gettop(L) + 1 + iIndex; // Check for no cycle lua_getfenv(L, 1); lua_pushvalue(L, iIndex); lua_rawget(L, -2); lua_rawgeti(L, -2, 1); lua_pushvalue(L, iIndex); lua_gettable(L, -2); lua_replace(L, -2); if(!lua_isnil(L, -1) || !lua_isnil(L, -2)) { lua_pop(L, 3); writeStackObject(iIndex); return; } lua_pop(L, 2); // Save the index to the cache lua_pushvalue(L, iIndex); lua_pushnumber(L, (lua_Number)(m_iNextIndex++)); lua_settable(L, -3); if(!_checkThatUserdataCanBeDepersisted(iIndex)) return; // Write type, metatable, and then environment uint8_t iType = LUA_TUSERDATA; writeByteStream(&iType, 1); writeStackObject(-1); lua_getfenv(L, iIndex); writeStackObject(-1); lua_pop(L, 1); // Write the raw data if(lua_type(L, -1) == LUA_TTABLE) { lua_getfield(L, -1, "__persist"); if(lua_isnil(L, -1)) lua_pop(L, 1); else { lua_pushvalue(L, iIndex); lua_checkstack(L, 20); lua_CFunction fn = lua_tocfunction(L, -2); fn(L); lua_pop(L, 2); } } writeVUInt((uint64_t)0x42); // sync marker lua_pop(L, 1); }
int Array<T>::help(lua_State* L) { if(lua_gettop(L) == 0) { lua_pushstring(L, "Class for 3D Data Arrays"); lua_pushstring(L, "0 to 3 Integers: Length of each dimension X, Y and Z. Default values are 1."); lua_pushstring(L, ""); //output, empty return 3; } if(!lua_iscfunction(L, 1)) { return luaL_error(L, "help expects zero arguments or 1 function."); } lua_CFunction func = lua_tocfunction(L, 1); if(func == &(l_sameSize<T>)) { lua_pushstring(L, "Test if a given array has the same dimensions"); lua_pushstring(L, "1 Array"); lua_pushstring(L, "1 Boolean: True if sizes match"); return 3; } if(func == &(l_setAll<T>)) { lua_pushstring(L, "Set all values in the array to the given value"); lua_pushstring(L, "1 Value: The new value for all element entries"); lua_pushstring(L, ""); return 3; } if(func == &(l_zero<T>)) { lua_pushstring(L, "Set all values in the array 0"); lua_pushstring(L, ""); lua_pushstring(L, ""); return 3; } if(func == &(l_get_nx<T>)) { lua_pushstring(L, "Return the size of the X dimension"); lua_pushstring(L, ""); lua_pushstring(L, "1 Integer: Size fo the X dimension"); return 3; } if(func == &(l_get_ny<T>)) { lua_pushstring(L, "Return the size of the Y dimension"); lua_pushstring(L, ""); lua_pushstring(L, "1 Integer: Size fo the Y dimension"); return 3; } if(func == &(l_get_nz<T>)) { lua_pushstring(L, "Return the size of the Z dimension"); lua_pushstring(L, ""); lua_pushstring(L, "1 Integer: Size fo the Z dimension"); return 3; } return LuaBaseObject::help(L); }
static int aux_close (lua_State *L) { lua_getfenv(L, 1); lua_getfield(L, -1, "__close"); return (lua_tocfunction(L, -1))(L); }
int GetLuabindInfo (lua_State* L) { int numArgs = lua_gettop(L); //if there are no arguments, return nil if(numArgs == 0) { lua_pushnil(L); return 1; } //if there is more than 1 argument, silently discard additional ones if(numArgs > 1) { lua_pop(L, numArgs - 1); } //is it a luabind function? if(luabind::detail::is_luabind_function(L, -1)) { GetLuabindFunctionInfo(L).push(L); return 1; } //is it a luabind class? if(luabind::detail::is_class_rep(L, -1)) //this is not exported in the official luabind build but it is in my fork { const luabind::detail::class_rep* crep = (const luabind::detail::class_rep*)lua_touserdata(L, -1); //create table containing information luabind::object info = luabind::newtable(L); //this is a class info["type"] = "class"; //we know its name info["name"] = crep->name(); //get static members (functions, classes, whatever there may be) luabind::object staticMemberFunctions = luabind::newtable(L); luabind::object classScope = luabind::newtable(L); { int staticMemberFunctionCounter = 0; //copy the whole default table into scope crep->get_default_table(L); // stack: crep default table int index = lua_gettop(L); lua_pushnil(L); //initialize lua_next - stack: crep default table, nil //iterate through table (in no particular order) - pops key, pushes next key/value pair returning 1 (or 0 and pushing nothing once done) while(lua_next(L, index) != 0) { #ifdef _DEBUG int stacksize = lua_gettop(L); #endif //stack: crep default table, key, value if(luabind::detail::is_luabind_function(L, -1)) { luabind::object funcInfo = GetLuabindFunctionInfo(L); funcInfo["actualName"] = lua_tostring(L, -2); staticMemberFunctions[++staticMemberFunctionCounter] = funcInfo; lua_pop(L, 1); //stack: crep default table, key } else { classScope.push(L); //stack: crep default table, key, value, class scope table lua_pushvalue(L, -3); lua_pushvalue(L, -3); //stack: crep default table, key, value, target table, key, value lua_settable(L, -3); //stack: crep default table, key, value, target table lua_pop(L, 2); //stack: crep default table, key } #ifdef _DEBUG assert(stacksize - 1 == lua_gettop(L)); #endif } //stack: crep default table lua_pop(L, 1); //crep default table } info["staticMemberFunctions"] = staticMemberFunctions; info["scope"] = classScope; //get static constants (from enums) luabind::object constants = luabind::newtable(L); { int counter = 0; for(std::map<const char*, int, luabind::detail::ltstr>::const_iterator it = crep->get_static_constants().begin(); it != crep->get_static_constants().end(); ++it) //this does not exist in the official luabind build but it does in my fork { luabind::object constantInfo = luabind::newtable(L); constantInfo["name"] = it->first; constantInfo["value"] = it->second; constants[++counter] = constantInfo; } } info["constants"] = constants; //get member functions & properties luabind::object methods = luabind::newtable(L); luabind::object properties = luabind::newtable(L); { int counterM = 0; int counterP = 0; // push table on stack crep->get_table(L); int index = lua_gettop(L); lua_pushnil(L); //initialize lua_next //iterate through table (in no particular order) - pops key, pushes next key/value pair returning 1 (or 0 and pushing nothing once done) while(lua_next(L, index) != 0) { //is it a property? if(lua_tocfunction(L, -1) == &luabind::detail::property_tag) { //unfortunately we cannot find out much more than the name of a property... luabind::object propInfo = luabind::newtable(L); propInfo["name"] = lua_tostring(L, -2); properties[++counterP] = propInfo; } else //no property, probably a function { if(luabind::detail::is_luabind_function(L, -1)) { luabind::object funcInfo = GetLuabindFunctionInfo(L); methods[++counterM] = funcInfo; #ifdef _DEBUG std::string keyName(lua_tostring(L, -2)); assert(keyName == funcInfo["name"]); #endif } else { //stuff in get_table that is no luabind function has most likely been added from Lua and is basically a static member. classScope.push(L); //stack: crep table, key, value, scope table lua_pushvalue(L, -3); //stack: crep table, key, value, scope table, key lua_pushvalue(L, -3); //stack: crep table, key, value, scope table, key, value lua_settable(L, -3); //stack: crep table, key, value, scope table lua_pop(L, 1); //stack: crep table, key, value } } //pop value from stack (key is consumed by next) lua_pop(L, 1); //stack: crep table, key } lua_pop(L, 1); //pop crep table } info["properties"] = properties; info["methods"] = methods; //return gathered information info.push(L); return 1; } //not a luabind object lua_pop(L, 1); lua_pushnil(L); return 1; }