Ejemplo n.º 1
0
/*
* 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;
}
Ejemplo n.º 2
0
/*
* 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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 5
0
 static lua_CFunction get(lua_State* L,  int index = -1) {
     return lua_tocfunction(L, index);
 }
Ejemplo n.º 6
0
lua_CFunction  LuaAgent::ToCFunction(int idx)
{
    return lua_tocfunction(luaState,idx);
}
Ejemplo n.º 7
0
LuaCFunc luaToFunction(lua_State* plua_state, int index)
{
    return (LuaCFunc)lua_tocfunction(plua_state, index);
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
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;
	}
Ejemplo n.º 14
0
LUABIND_API bool is_luabind_function(lua_State* L, int index)
{
    return lua_tocfunction(L, index) == &function_dispatcher;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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()));
    }
}
Ejemplo n.º 17
0
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)
    }
Ejemplo n.º 18
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_; 
} 
Ejemplo n.º 20
0
 static c_closure get(lua_State* L, int index = -1) {
     return c_closure(lua_tocfunction(L, index), -1);
 }
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
lua_CFunction l_data_type<lua_CFunction>::get(lua_State *l, int n)
{
	luaL_checktype(l, n, LUA_TFUNCTION);
	return lua_tocfunction(l, n);
}
Ejemplo n.º 25
0
    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);
    }
Ejemplo n.º 26
0
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);
}
Ejemplo n.º 27
0
static int aux_close (lua_State *L) {
  lua_getfenv(L, 1);
  lua_getfield(L, -1, "__close");
  return (lua_tocfunction(L, -1))(L);
}
Ejemplo n.º 28
0
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;
}