示例#1
0
const char* luaC_pushdstring(lua_State* L, int idx, int lem)
{
	size_t len;
	lua_checkstack(L, 4);
	int t = lua_type(L, idx);
	lua_pushvalue(L, idx);						//|XX|
	lua_pushstring(L, "[");
	lua_pushstring(L, lua_typename(L, t));
	lua_pushstring(L, "]");
	lua_concat(L, 3);							//|TS|XX|
	lua_insert(L, -2);							//|XX|TS|
	const char* s = lua_tolstring(L, -1, &len);
	if (s == NULL) {
		if (t == LUA_TBOOLEAN) {
			if (lua_toboolean(L, -1)) lua_pushstring(L, "<true>"); else lua_pushstring(L, "<false>"); //|VS|XX|TS|
			lua_remove(L, -2);					//|VS|TS|
		} else {
			lua_pushstring(L, "");				//|""|XX|TS|
			lua_remove(L, -2);					//|""|TS|
		}
	} else if (t == LUA_TSTRING) {				//|VS|TS|
		lua_pushstring(L, "\"");				//|"|VS|TS|
		lua_pushstring(L, "\"");				//|"|"|VS|TS|
		lua_insert(L, -3);						//|"|VS|"|TS|
		lua_concat(L, 3);						//|VS|TS|
	}
	lua_concat(L, 2);							//|RS|
	s = lua_tolstring(L, -1, &len);
	if ((int)len >= lem) {
		lua_pushlstring(L, s, lem-1);			//|RS|RS|
		lua_remove(L, -2);						//|RS|
		lua_pushstring(L, ">");					//|>|RS|
		lua_concat(L, 2);						//|RS|
	}
	return lua_tostring(L, -1);
}
示例#2
0
文件: zsocket.c 项目: ajtulloch/lzmq
static int luazmq_skt_recvx (lua_State *L) {
  zsocket *skt = luazmq_getsocket(L);
  zmq_msg_t msg;
  int flags = luaL_optint(L,2,0);
  int i = 0;
  lua_settop(L, 1);

  while(1){
    int ret = zmq_msg_init(&msg);
    if(-1 == ret){
      ret = luazmq_fail(L, skt);
      {int j;for(j = ret; j >= 0; --j){
        lua_insert(L, 1);
      }}
      return ret + i;
    }

    ret = zmq_msg_recv(&msg, skt->skt, flags);
    if(-1 == ret){
      zmq_msg_close(&msg);
      ret = luazmq_fail(L, skt);
      {int j;for(j = ret; j >= 0; --j){
        lua_insert(L, 1);
      }}
      return ret + i;
    }

    i++;
    lua_checkstack(L, i);
    lua_pushlstring(L, zmq_msg_data(&msg), zmq_msg_size(&msg));
    ret = zmq_msg_more(&msg);
    zmq_msg_close(&msg);
    if(!ret) break;
  }
  return i;
}
示例#3
0
bool CLuaRules::AllowFeatureBuildStep(const CUnit* builder,
                                      const CFeature* feature, float part)
{
	if (!haveAllowFeatureBuildStep) {
		return true; // the call is not defined
	}

	LUA_CALL_IN_CHECK(L);
	lua_checkstack(L, 7);
	static const LuaHashString cmdStr("AllowFeatureBuildStep");
	if (!cmdStr.GetGlobalFunc(L)) {
		return true; // the call is not defined
	}

	lua_pushnumber(L, builder->id);
	lua_pushnumber(L, builder->team);
	lua_pushnumber(L, feature->id);
	lua_pushnumber(L, feature->def->id);
	lua_pushnumber(L, part);

	// call the function
	if (!RunCallIn(cmdStr, 5, 1)) {
		return true;
	}

	// get the results
	if (!lua_isboolean(L, -1)) {
		logOutput.Print("%s() bad return value\n", cmdStr.GetString().c_str());
		lua_pop(L, 1);
		return true;
	}

	const bool retval = !!lua_toboolean(L, -1);
	lua_pop(L, 1);
	return retval;
}
示例#4
0
bool CLuaRules::MoveCtrlNotify(const CUnit* unit, int data)
{
	if (!haveMoveCtrlNotify) {
		return false; // the call is not defined
	}

	LUA_CALL_IN_CHECK(L);
	lua_checkstack(L, 6);
	static const LuaHashString cmdStr("MoveCtrlNotify");
	if (!cmdStr.GetGlobalFunc(L)) {
		return false; // the call is not defined
	}

	// push the unit info
	lua_pushnumber(L, unit->id);
	lua_pushnumber(L, unit->unitDef->id);
	lua_pushnumber(L, unit->team);
	lua_pushnumber(L, data);

	// call the function
	if (!RunCallIn(cmdStr, 4, 1)) {
		return false;
	}

	// get the results
	if (!lua_isboolean(L, -1)) {
		logOutput.Print("%s() bad return value\n", cmdStr.GetString().c_str());
		lua_pop(L, 1);
		return false;
	}

	const bool retval = !!lua_toboolean(L, -1);
	lua_pop(L, 1);

	return retval;
}
示例#5
0
bool CLuaRules::AllowFeatureCreation(const FeatureDef* featureDef,
                                     int teamID, const float3& pos)
{
	if (!haveAllowFeatureCreation) {
		return true; // the call is not defined
	}

	LUA_CALL_IN_CHECK(L);
	lua_checkstack(L, 7);
	static const LuaHashString cmdStr("AllowFeatureCreation");
	if (!cmdStr.GetGlobalFunc(L)) {
		return true; // the call is not defined
	}

	lua_pushnumber(L, featureDef->id);
	lua_pushnumber(L, teamID);
	lua_pushnumber(L, pos.x);
	lua_pushnumber(L, pos.y);
	lua_pushnumber(L, pos.z);

	// call the function
	if (!RunCallIn(cmdStr, 5, 1)) {
		return true;
	}

	// get the results
	if (!lua_isboolean(L, -1)) {
		logOutput.Print("%s() bad return value\n", cmdStr.GetString().c_str());
		lua_pop(L, 1);
		return true;
	}

	const bool retval = !!lua_toboolean(L, -1);
	lua_pop(L, 1);
	return retval;
}
示例#6
0
static int path_append_helper(lua_State *L, int stackStart, int stackTop) {
  int concatBottom = stackTop;
  int newTop;
  int i;
  for (i = stackStart; i <= stackTop; ++i) {
    const char *path = luaL_checkstring(L, i);
    if (path[0] > 0) {
      if (*path == '/'  ||  *path == '\\'  ||  (path[0]  &&  path[1] == ':'))
        concatBottom = lua_gettop(L);

      lua_checkstack(L, 2);
      lua_pushvalue(L, i);
      lua_pushliteral(L, "/");
    }
  }

  newTop = lua_gettop(L);
  if (newTop - concatBottom > 0) {
    lua_remove(L, lua_gettop(L));
    --newTop;
  }
  lua_concat(L, newTop - concatBottom);
  return 1;
}
示例#7
0
void scriptapi_export(lua_State *L, Server *server)
{
	realitycheck(L);
	assert(lua_checkstack(L, 20));
	verbosestream<<"scriptapi_export()"<<std::endl;
	StackUnroller stack_unroller(L);

	// Store server as light userdata in registry
	lua_pushlightuserdata(L, server);
	lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server");

	// Register global functions in table minetest
	lua_newtable(L);
	luaL_register(L, NULL, minetest_f);
	lua_setglobal(L, "minetest");

	// Get the main minetest table
	lua_getglobal(L, "minetest");

	// Add tables to minetest
	lua_newtable(L);
	lua_setfield(L, -2, "object_refs");
	lua_newtable(L);
	lua_setfield(L, -2, "luaentities");

	// Register wrappers
	LuaItemStack::Register(L);
	InvRef::Register(L);
	NodeMetaRef::Register(L);
	NodeTimerRef::Register(L);
	ObjectRef::Register(L);
	EnvRef::Register(L);
	LuaPseudoRandom::Register(L);
	LuaPerlinNoise::Register(L);
	LuaPerlinNoiseMap::Register(L);
}
示例#8
0
文件: LuaRules.cpp 项目: rYuuk/spring
bool CLuaRules::DrawShield(const CUnit* unit, const CWeapon* weapon)
{
    if (!haveDrawShield)
        return false;

    LUA_CALL_IN_CHECK(L, false);
    lua_checkstack(L, 5);

    static const LuaHashString cmdStr(__FUNCTION__);

    if (!cmdStr.GetRegistryFunc(L))
        return false;

    const bool oldDrawState = LuaOpenGL::IsDrawingEnabled(L);
    LuaOpenGL::SetDrawingEnabled(L, true);

    lua_pushnumber(L, unit->id);
    lua_pushnumber(L, weapon->weaponNum);
    lua_pushnumber(L, game->GetDrawMode());

    const bool success = RunCallIn(cmdStr, 3, 1);
    LuaOpenGL::SetDrawingEnabled(L, oldDrawState);

    if (!success)
        return false;
    if (!lua_isboolean(L, -1)) {
        LOG_L(L_WARNING, "%s() bad return-type (bool expected, got %s)", __FUNCTION__, lua_typename(L, lua_type(L, -1)));
        lua_pop(L, 1);
        return false;
    }

    const bool retval = !!lua_toboolean(L, -1);

    lua_pop(L, 1);
    return retval;
}
示例#9
0
static void PushProfilePermissions(lua_State * L, const uint16_t &iProfile) {
    ProfileItem *Prof = ProfileMan->ProfilesTable[iProfile];

    lua_checkstack(L, 3); // we need 3 (1 table, 2 id, 3 value) empty slots in stack, check it to be sure

    lua_newtable(L);
    int t = lua_gettop(L);

    lua_pushliteral(L, "bIsOP");
    Prof->bPermissions[ProfileManager::HASKEYICON] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodGetNickList");
    Prof->bPermissions[ProfileManager::NODEFLOODGETNICKLIST] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodNMyINFO");
    Prof->bPermissions[ProfileManager::NODEFLOODMYINFO] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodSearch");
    Prof->bPermissions[ProfileManager::NODEFLOODSEARCH] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodPM");
    Prof->bPermissions[ProfileManager::NODEFLOODPM] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodMainChat");
    Prof->bPermissions[ProfileManager::NODEFLOODMAINCHAT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bMassMsg");
    Prof->bPermissions[ProfileManager::MASSMSG] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bTopic");
    Prof->bPermissions[ProfileManager::TOPIC] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bTempBan");
    Prof->bPermissions[ProfileManager::TEMP_BAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bTempUnban");
    Prof->bPermissions[ProfileManager::TEMP_UNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);
    
    lua_pushliteral(L, "bRefreshTxt");
    Prof->bPermissions[ProfileManager::REFRESHTXT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoTagCheck");
    Prof->bPermissions[ProfileManager::NOTAGCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bDelRegUser");
    Prof->bPermissions[ProfileManager::DELREGUSER] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bAddRegUser");
    Prof->bPermissions[ProfileManager::ADDREGUSER] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoChatLimits");
    Prof->bPermissions[ProfileManager::NOCHATLIMITS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoMaxHubCheck");
    Prof->bPermissions[ProfileManager::NOMAXHUBCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoSlotHubRatio");
    Prof->bPermissions[ProfileManager::NOSLOTHUBRATIO] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoSlotCheck");
    Prof->bPermissions[ProfileManager::NOSLOTCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoShareLimit");
    Prof->bPermissions[ProfileManager::NOSHARELIMIT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bClrPermBan");
    Prof->bPermissions[ProfileManager::CLRPERMBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bClrTempBan");
    Prof->bPermissions[ProfileManager::CLRTEMPBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bGetInfo");
    Prof->bPermissions[ProfileManager::GETINFO] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bGetBans");
    Prof->bPermissions[ProfileManager::GETBANLIST] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bRestartScripts");
    Prof->bPermissions[ProfileManager::RSTSCRIPTS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bRestartHub");
    Prof->bPermissions[ProfileManager::RSTHUB] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bTempOP");
    Prof->bPermissions[ProfileManager::TEMPOP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bGag");
    Prof->bPermissions[ProfileManager::GAG] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bRedirect");
    Prof->bPermissions[ProfileManager::REDIRECT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bBan");
    Prof->bPermissions[ProfileManager::BAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bUnban");
    Prof->bPermissions[ProfileManager::UNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);
    
    lua_pushliteral(L, "bKick");
    Prof->bPermissions[ProfileManager::KICK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bDrop");
    Prof->bPermissions[ProfileManager::DROP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bEnterFullHub");
    Prof->bPermissions[ProfileManager::ENTERFULLHUB] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bEnterIfIPBan");
    Prof->bPermissions[ProfileManager::ENTERIFIPBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bAllowedOPChat");
    Prof->bPermissions[ProfileManager::ALLOWEDOPCHAT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bSendFullMyinfos");
    Prof->bPermissions[ProfileManager::SENDFULLMYINFOS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);   
    
    lua_pushliteral(L, "bSendAllUserIP");
    Prof->bPermissions[ProfileManager::SENDALLUSERIP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t); 
    
    lua_pushliteral(L, "bRangeBan");
    Prof->bPermissions[ProfileManager::RANGE_BAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);
    
    lua_pushliteral(L, "bRangeUnban");
    Prof->bPermissions[ProfileManager::RANGE_UNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bRangeTempBan");
    Prof->bPermissions[ProfileManager::RANGE_TBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bRangeTempUnban");
    Prof->bPermissions[ProfileManager::RANGE_TUNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);
    
    lua_pushliteral(L, "bGetRangeBans");
    Prof->bPermissions[ProfileManager::GET_RANGE_BANS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bClearRangePermBans");
    Prof->bPermissions[ProfileManager::CLR_RANGE_BANS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bClearRangeTempBans");
    Prof->bPermissions[ProfileManager::CLR_RANGE_TBANS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);
    
    lua_pushliteral(L, "bNoIpCheck");
    Prof->bPermissions[ProfileManager::NOIPCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);
    
    lua_pushliteral(L, "bClose");
    Prof->bPermissions[ProfileManager::CLOSE] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoSearchLimits");
    Prof->bPermissions[ProfileManager::NOSEARCHLIMITS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodCTM");
    Prof->bPermissions[ProfileManager::NODEFLOODCTM] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodRCTM");
    Prof->bPermissions[ProfileManager::NODEFLOODRCTM] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodSR");
    Prof->bPermissions[ProfileManager::NODEFLOODSR] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoDefloodRecv");
    Prof->bPermissions[ProfileManager::NODEFLOODRECV] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoChatInterval");
    Prof->bPermissions[ProfileManager::NOCHATINTERVAL] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoPMInterval");
    Prof->bPermissions[ProfileManager::NOPMINTERVAL] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoSearchInterval");
    Prof->bPermissions[ProfileManager::NOSEARCHINTERVAL] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoMaxUsersSameIP");
    Prof->bPermissions[ProfileManager::NOUSRSAMEIP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);

    lua_pushliteral(L, "bNoReConnTime");
    Prof->bPermissions[ProfileManager::NORECONNTIME] == true ? lua_pushboolean(L, 1) : lua_pushnil(L);
    lua_rawset(L, t);
}
示例#10
0
bool luaW_toconfig(lua_State *L, int index, config &cfg)
{
	if (!lua_checkstack(L, LUA_MINSTACK))
		return false;

	// Get the absolute index of the table.
	index = lua_absindex(L, index);
	int initial_top = lua_gettop(L);

	switch (lua_type(L, index))
	{
		case LUA_TTABLE:
			break;
		case LUA_TUSERDATA:
		{
			if (vconfig * ptr = static_cast<vconfig *> (luaL_testudata(L, index, vconfigKey))) {
				cfg = ptr->get_parsed_config();
				return true;
			} else {
				return false;
			}
		}
		case LUA_TNONE:
		case LUA_TNIL:
			return true;
		default:
			return false;
	}

	// First convert the children (integer indices).
	for (int i = 1, i_end = lua_rawlen(L, index); i <= i_end; ++i)
	{
		lua_rawgeti(L, index, i);
		if (!lua_istable(L, -1)) return_misformed();
		lua_rawgeti(L, -1, 1);
		char const *m = lua_tostring(L, -1);
		if (!m) return_misformed();
		lua_rawgeti(L, -2, 2);
		if (!luaW_toconfig(L, -1, cfg.add_child(m)))
			return_misformed();
		lua_pop(L, 3);
	}

	// Then convert the attributes (string indices).
	for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1))
	{
		if (lua_isnumber(L, -2)) continue;
		if (!lua_isstring(L, -2)) return_misformed();
		config::attribute_value &v = cfg[lua_tostring(L, -2)];
		if (lua_istable(L, -1)) {
			int subindex = lua_absindex(L, -1);
			std::ostringstream str;
			for (int i = 1, i_end = lua_rawlen(L, subindex); i <= i_end; ++i, lua_pop(L, 1)) {
				lua_rawgeti(L, -1, i);
				config::attribute_value item;
				if (!luaW_toscalar(L, -1, item)) return_misformed();
				if (i > 1) str << ',';
				str << item;
			}
			// If there are any string keys, it's misformed
			for (lua_pushnil(L); lua_next(L, subindex); lua_pop(L, 1)) {
				if (!lua_isnumber(L, -2)) return_misformed();
			}
			v = str.str();
		} else if (!luaW_toscalar(L, -1, v)) return_misformed();
	}

	lua_settop(L, initial_top);
	return true;
}
示例#11
0
JNIEXPORT jint JNICALL Java_m_lua_Lua_checkStack
		(JNIEnv* env, jobject thiz, jlong nativeObj, jint sz) {
	pushJNIEnv(env, nativeObj);
	return (jint) lua_checkstack((lua_State*) nativeObj, (int) sz);
}
示例#12
0
int serialize_data(lua_sandbox* lsb, int index, output_data* output)
{
    output->m_pos = 0;
    switch (lua_type(lsb->m_lua, index)) {
    case LUA_TNUMBER:
        if (dynamic_snprintf(output, "%0.9g",
                             lua_tonumber(lsb->m_lua, index))) {
            return 1;
        }
        break;
    case LUA_TSTRING:
        // The stack is cleaned up on failure by preserve_global_data
        // but for clarity it is incrementally cleaned up anyway.
        lua_checkstack(lsb->m_lua, 4);
        lua_getglobal(lsb->m_lua, "string");
        if (!lua_istable(lsb->m_lua, -1)) {
            snprintf(lsb->m_error_message, ERROR_SIZE,
                     "serialize_data cannot access the string table");
            lua_pop(lsb->m_lua, 1); // Remove bogus string table.
            return 1;
        }
        lua_getfield(lsb->m_lua, -1, "format");
        if (!lua_isfunction(lsb->m_lua, -1)) {
            snprintf(lsb->m_error_message, ERROR_SIZE,
                     "serialize_data cannot access the string format function");
            lua_pop(lsb->m_lua, 2); // Remove the bogus format function and
                                    // string table.
            return 1;
        }
        lua_pushstring(lsb->m_lua, "%q");
        lua_pushvalue(lsb->m_lua, index - 3);
        if (lua_pcall(lsb->m_lua, 2, 1, 0) == 0) {
            if (dynamic_snprintf(output, "%s", lua_tostring(lsb->m_lua, -1))) {
                lua_pop(lsb->m_lua, 1); // Remove the string table.
                return 1;
            }
        } else {
            snprintf(lsb->m_error_message, ERROR_SIZE,
                     "serialize_data '%s'", lua_tostring(lsb->m_lua, -1));
            lua_pop(lsb->m_lua, 2); // Remove the error message and the string
                                    // table.
            return 1;
        }
        lua_pop(lsb->m_lua, 2); // Remove the pcall result and the string table.
        break;
    case LUA_TNIL:
        if (dynamic_snprintf(output, "nil")) {
            return 1;
        }
        break;
    case LUA_TBOOLEAN:
        if (dynamic_snprintf(output, "%s",
                             lua_toboolean(lsb->m_lua, index)
                             ? "true" : "false")) {
            return 1;
        }
        break;
    default:
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "serialize_data cannot preserve type '%s'",
                 lua_typename(lsb->m_lua, lua_type(lsb->m_lua, index)));
        return 1;
    }
    return 0;
}
示例#13
0
bool CLuaHandle::MapDrawCmd(int playerID, int type,
                            const float3* pos0,
                            const float3* pos1,
                            const string* label)
{
	if (!CheckModUICtrl()) {
		return false;
	}
	LUA_CALL_IN_CHECK(L);
	lua_checkstack(L, 9);
	static const LuaHashString cmdStr("MapDrawCmd");
	if (!PushUnsyncedCallIn(cmdStr)) {
		return false; // the call is not defined
	}

	int args;

	lua_pushnumber(L, playerID);

	if (type == CInMapDraw::NET_POINT) {
		HSTR_PUSH(L, "point");
		lua_pushnumber(L, pos0->x);
		lua_pushnumber(L, pos0->y);
		lua_pushnumber(L, pos0->z);
		lua_pushstring(L, label->c_str());
		args = 6;
	}
	else if (type == CInMapDraw::NET_LINE) {
		HSTR_PUSH(L, "line");
		lua_pushnumber(L, pos0->x);
		lua_pushnumber(L, pos0->y);
		lua_pushnumber(L, pos0->z);
		lua_pushnumber(L, pos1->x);
		lua_pushnumber(L, pos1->y);
		lua_pushnumber(L, pos1->z);
		args = 8;
	}
	else if (type == CInMapDraw::NET_ERASE) {
		HSTR_PUSH(L, "erase");
		lua_pushnumber(L, pos0->x);
		lua_pushnumber(L, pos0->y);
		lua_pushnumber(L, pos0->z);
		lua_pushnumber(L, 100.0f);  // radius
		args = 6;
	}
	else {
		logOutput.Print("Unknown MapDrawCmd() type");
		lua_pop(L, 2); // pop the function and playerID
		return false;
	}

	// call the routine
	if (!RunCallInUnsynced(cmdStr, args, 1)) {
		return false;
	}

	// take the event?
	if (!lua_isboolean(L, -1)) {
		lua_pop(L, 1);
		return false;
	}
	const bool retval = lua_toboolean(L, -1);
	lua_pop(L, 1);
	return retval;
}
示例#14
0
    int writeObjectRaw()
    {
        lua_State *L = m_L;
        uint8_t iType;

        // Save the index to the cache
        lua_pushvalue(L, 2);
        lua_pushnumber(L, (lua_Number)(m_iNextIndex++));
        lua_settable(L, 1);

        // Lookup the object in the permanents table
        lua_pushvalue(L, 2);
        lua_gettable(L, luaT_upvalueindex(1));
        if(lua_type(L, -1) != LUA_TNIL)
        {
            // Object is in the permanents table.

            uint8_t iType = PERSIST_TPERMANENT;
            writeByteStream(&iType, 1);

            // Replace self's environment with self (for call to writeStackObject)
            lua_pushvalue(L, luaT_upvalueindex(2));
            lua_replace(L, 1);

            // Write the key corresponding to the permanent object
            writeStackObject(-1);
        }
        else
        {
            // Object is not in the permanents table.
            lua_pop(L, 1);

            switch(lua_type(L, 2))
            {
            // LUA_TNIL handled in writeStackObject
            // LUA_TBOOLEAN handled in writeStackObject
            // LUA_TNUMBER handled in writeStackObject

            case LUA_TSTRING: {
                iType = LUA_TSTRING;
                writeByteStream(&iType, 1);
                // Strings are simple: length and then bytes (not null terminated)
                size_t iLength;
                const char *sString = lua_tolstring(L, 2, &iLength);
                writeVUInt(iLength);
                writeByteStream(reinterpret_cast<const uint8_t*>(sString), iLength);
                break; }

            case LUA_TTABLE: {
                // Replace self's environment with self (for calls to writeStackObject)
                lua_pushvalue(L, luaT_upvalueindex(2));
                lua_replace(L, 1);

                // Save env and insert prior to table
                lua_getfenv(L, 1);
                lua_insert(L, 2);

                int iTable = 3; table_reentry:

                // Handle the metatable
                if(lua_getmetatable(L, iTable))
                {
                    iType = PERSIST_TTABLE_WITH_META;
                    writeByteStream(&iType, 1);
                    writeStackObject(-1);
                    lua_pop(L, 1);
                }
                else
                {
                    iType = LUA_TTABLE;
                    writeByteStream(&iType, 1);
                }

                // Write the children as key, value pairs
                lua_pushnil(L);
                while(lua_next(L, iTable))
                {
                    writeStackObject(-2);
                    // The naive thing to do now would be writeStackObject(-1)
                    // but this can easily lead to Lua's C call stack limit
                    // being hit. To reduce the likelyhood of this happening,
                    // we check to see if about to write another table.
                    if(lua_type(L, -1) == LUA_TTABLE)
                    {
                        lua_pushvalue(L, -1);
                        lua_rawget(L, 2);
                        lua_pushvalue(L, -2);
                        lua_gettable(L, luaT_upvalueindex(1));
                        if(lua_isnil(L, -1) && lua_isnil(L, -2))
                        {
                            lua_pop(L, 2);
                            lua_checkstack(L, 10);
                            iTable += 2;
                            lua_pushvalue(L, iTable);
                            lua_pushnumber(L, (lua_Number)(m_iNextIndex++));
                            lua_settable(L, 2);
                            goto table_reentry; table_resume:
                            iTable -= 2;
                        }
                        else
                        {
                            lua_pop(L, 2);
                            writeStackObject(-1);
                        }
                    }
                    else
                        writeStackObject(-1);
                    lua_pop(L, 1);
                }

                // Write a nil to mark the end of the children (as nil is the
                // only value which cannot be used as a key in a table).
                iType = LUA_TNIL;
                writeByteStream(&iType, 1);
                if(iTable != 3)
                    goto table_resume;
                break; }

            case LUA_TFUNCTION:
                if(lua_iscfunction(L, 2))
                {
                    setErrorObject(2);
                    setError("Cannot persist C functions");
                }
                else
                {
                    iType = LUA_TFUNCTION;
                    writeByteStream(&iType, 1);

                    // Replace self's environment with self (for calls to writeStackObject)
                    lua_pushvalue(L, luaT_upvalueindex(2));
                    lua_replace(L, 1);

                    // Write the prototype (the part of a function which is common across
                    // multiple closures - see LClosure / Proto in Lua's lobject.h).
                    lua_Debug proto_info;
                    lua_pushvalue(L, 2);
                    lua_getinfo(L, ">Su", &proto_info);
                    writePrototype(&proto_info, 2);

                    // Write the values of the upvalues
                    // If available, also write the upvalue IDs (so that in
                    // the future, we could hypothetically rejoin shared
                    // upvalues). An ID is just an opaque sequence of bytes.
                    writeVUInt(proto_info.nups);
#if LUA_VERSION_NUM >= 502
                    writeVUInt(sizeof(void*));
#else
                    writeVUInt(0);
#endif
                    for(int i = 1; i <= proto_info.nups; ++i)
                    {
                        lua_getupvalue(L, 2, i);
                        writeStackObject(-1);
#if LUA_VERSION_NUM >= 502
                        void *pUpvalueID = lua_upvalueid(L, 2, i);
                        writeByteStream((uint8_t*)&pUpvalueID, sizeof(void*));
#endif
                    }

                    // Write the environment table
                    lua_getfenv(L, 2);
                    writeStackObject(-1);
                    lua_pop(L, 1);
                }
                break;

            case LUA_TUSERDATA:
                if(!_checkThatUserdataCanBeDepersisted(2))
                    break;

                // Replace self's environment with self (for calls to writeStackObject)
                lua_pushvalue(L, luaT_upvalueindex(2));
                lua_replace(L, 1);

                // Write type, metatable, and then environment
                iType = LUA_TUSERDATA;
                writeByteStream(&iType, 1);
                writeStackObject(-1);
                lua_getfenv(L, 2);
                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, 2);
                        lua_pushvalue(L, luaT_upvalueindex(2));
                        lua_call(L, 2, 0);
                    }
                }
                writeVUInt((uint64_t)0x42); // sync marker
                break;

            default:
                setError(lua_pushfstring(L, "Cannot persist %s values", luaL_typename(L, 2)));
                break;
            }
        }
        lua_pushnumber(L, 0);
        return 1;
    }
示例#15
0
int rx_gsub (lua_State *L, int is_function, int is_wide)
{
  size_t len, flen;
  TFarRegex* fr;
  FARAPIREGEXPCONTROL RegExpControl = GetRegExpControl(L);
  const wchar_t *s, *f;
  int max_rep_capture, ftype, n, matches, reps;
  luaL_Buffer out;
  struct RegExpSearch data;
  memset(&data, 0, sizeof(data));

  if (is_function) {
    if (is_wide)
      data.Text = check_utf16_string(L, 1, &len);
    else
      data.Text = check_utf8_string(L, 1, &len);
    fr = push_far_regex(L, RegExpControl, check_regex_pattern(L, 2, 5));
    lua_replace(L, 2);
  }
  else {
    fr = CheckFarRegex(L, 1);
    if (is_wide)
      data.Text = check_utf16_string(L, 2, &len);
    else
      data.Text = check_utf8_string(L, 2, &len);
  }

  data.Length = len;
  s = data.Text;
  f = NULL;
  flen = 0;
  max_rep_capture = 0;
  ftype = lua_type(L, 3);
  if (ftype == LUA_TSTRING) {
    const wchar_t* p;
    f = check_utf8_string(L, 3, &flen);
    for (p=f; *p; p++) {
      if (*p == L'%') {
        int n, ch;
        if ((ch = *++p) == 0) break;
        n = (ch >= L'0' && ch <= L'9') ? ch - L'0' :
            (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 :
            (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1;
        if (max_rep_capture < n) max_rep_capture = n;
      }
    }
  }
  else if (ftype != LUA_TTABLE && ftype != LUA_TFUNCTION)
    luaL_argerror(L, 3, "string or table or function");

  if (lua_isnoneornil(L, 4)) n = -1;
  else {
    n = (int)luaL_checkinteger(L, 4);
    if (n < 0) n = 0;
  }
  lua_settop(L, 3);

  data.Count = RegExpControl(fr->hnd, RECTL_BRACKETSCOUNT, 0, 0);
  if ( (ftype == LUA_TSTRING) &&
       !(max_rep_capture == 1 && data.Count == 1) &&
       (data.Count <= max_rep_capture))
    luaL_error(L, "replace string: invalid capture index");
  data.Match = (struct RegExpMatch*)lua_newuserdata(L, data.Count*sizeof(struct RegExpMatch));
  data.Match[0].end = -1;

  matches = reps = 0;
  luaL_buffinit(L, &out);

  while (n < 0 || reps < n) {
    int rep;
    intptr_t from, to;
    intptr_t prev_end = data.Match[0].end;
    if (!RegExpControl(fr->hnd, RECTL_SEARCHEX, 0, &data))
      break;
    if (data.Match[0].end == prev_end) {
      if (data.Position < data.Length) {
        luaL_addlstring(&out, (const char*)(s+data.Position), sizeof(wchar_t));
        data.Position++;
        continue;
      }
      break;
    }
    matches++;
    rep = 0;
    from = data.Match[0].start;
    to = data.Match[0].end;
    luaL_addlstring(&out, (const char*)(s + data.Position),
      (from - data.Position) * sizeof(wchar_t));
    if (ftype == LUA_TSTRING) {
      size_t i, start = 0;
      for (i=0; i<flen; i++) {
        if (f[i] == L'%') {
          if (++i < flen) {
            int ch = f[i];
            int n = (ch >= L'0' && ch <= L'9') ? ch - L'0' :
                    (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 :
                    (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1;
            if (n >= 0) {
              if (n==1 && data.Count==1) n = 0;
              luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t));
              if (data.Match[n].start >= 0) {
                luaL_addlstring(&out, (const char*)(s + data.Match[n].start),
                    (data.Match[n].end - data.Match[n].start) * sizeof(wchar_t));
              }
            }
            else { // delete the percent sign
              luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t));
              luaL_addlstring(&out, (const char*)(f+i), sizeof(wchar_t));
            }
            start = i+1;
          }
          else {
            luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t));
            start = flen;
            break;
          }
        }
      }
      rep++;
      luaL_addlstring(&out, (const char*)(f+start), (flen-start)*sizeof(wchar_t));
    }
    else if (ftype == LUA_TTABLE) {
      int n = data.Count==1 ? 0:1;
      if (data.Match[n].start >= 0) {
        if (is_wide)
          push_utf16_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start));
        else
          push_utf8_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start));
        lua_gettable(L, 3);
        if (lua_isstring(L, -1)) {
          if (!is_wide) {
            size_t len;
            const wchar_t* ws = check_utf8_string(L, -1, &len);
            lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t));
            lua_remove(L, -2);
          }
          luaL_addvalue(&out);
          rep++;
        }
        else if (lua_toboolean(L,-1))
          luaL_error(L, "invalid replacement type");
        else
          lua_pop(L, 1);
      }
    }
    else { // if (ftype == LUA_TFUNCTION)
      intptr_t i, skip = data.Count==1 ? 0:1;
      lua_checkstack(L, (int)(data.Count+1-skip));
      lua_pushvalue(L, 3);
      for (i=skip; i<data.Count; i++) {
        if (data.Match[i].start >= 0) {
          if (is_wide)
            push_utf16_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start));
          else
            push_utf8_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start));
        }
        else
          lua_pushboolean(L, 0);
      }
      if (lua_pcall(L, (int)(data.Count-skip), 1, 0) == 0) {
        if (lua_isstring(L, -1)) {
          if (!is_wide) {
            size_t len;
            const wchar_t* ws = check_utf8_string(L, -1, &len);
            lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t));
            lua_remove(L, -2);
          }
          luaL_addvalue(&out);
          rep++;
        }
        else if (lua_toboolean(L,-1))
          luaL_error(L, "invalid return type");
        else
          lua_pop(L, 1);
      }
      else
        luaL_error(L, lua_tostring(L, -1));
    }
    if (rep)
      reps++;
    else
      luaL_addlstring(&out, (const char*)(s+from), (to-from)*sizeof(wchar_t));
    if (data.Position < to)
      data.Position = to;
    else if (data.Position < data.Length) {
      luaL_addlstring(&out, (const char*)(s + data.Position), sizeof(wchar_t));
      data.Position++;
    }
    else
      break;
  }
  luaL_addlstring(&out, (const char*)(s + data.Position),
    (data.Length - data.Position) * sizeof(wchar_t));
  luaL_pushresult(&out);
  if (!is_wide) {
    push_utf8_string(L, (const wchar_t*)lua_tostring(L, -1), lua_objlen(L, -1) / sizeof(wchar_t));
  }
  lua_pushinteger(L, matches);
  lua_pushinteger(L, reps);
  return 3;
}
示例#16
0
/* Choose whether to do a regular or special persistence based on an object's
 * metatable. "default" is whether the object, if it doesn't have a __persist
 * entry, is literally persistable or not.
 * Pushes the unpersist closure and returns true if special persistence is
 * used. */
static int persistspecialobject(PersistInfo *pi, int defaction)
{
					/* perms reftbl ... obj */
	lua_checkstack(pi->L, 4);
	/* Check whether we should persist literally, or via the __persist
	 * metafunction */
	if(!lua_getmetatable(pi->L, -1)) {
		if(defaction) {
			{
				int zero = 0;
				pi->writer(pi->L, &zero, sizeof(int), pi->ud);
			}
			return 0;
		} else {
			lua_pushstring(pi->L, "Type not literally persistable by default");
			lua_error(pi->L);
		}
	}
					/* perms reftbl sptbl ... obj mt */
	lua_pushstring(pi->L, "__persist");
					/* perms reftbl sptbl ... obj mt "__persist" */
	lua_rawget(pi->L, -2);
					/* perms reftbl sptbl ... obj mt __persist? */
	if(lua_isnil(pi->L, -1)) {
					/* perms reftbl sptbl ... obj mt nil */
		lua_pop(pi->L, 2);
					/* perms reftbl sptbl ... obj */
		if(defaction) {
			{
				int zero = 0;
				pi->writer(pi->L, &zero, sizeof(int), pi->ud);
			}
			return 0;
		} else {
			lua_pushstring(pi->L, "Type not literally persistable by default");
			lua_error(pi->L);
			return 0; /* not reached */
		}
	} else if(lua_isboolean(pi->L, -1)) {
					/* perms reftbl sptbl ... obj mt bool */
		if(lua_toboolean(pi->L, -1)) {
					/* perms reftbl sptbl ... obj mt true */
			lua_pop(pi->L, 2);
					/* perms reftbl sptbl ... obj */
			{
				int zero = 0;
				pi->writer(pi->L, &zero, sizeof(int), pi->ud);
			}
			return 0;
		} else {
			lua_pushstring(pi->L, "Metatable forbade persistence");
			lua_error(pi->L);
			return 0; /* not reached */
		}
	} else if(!lua_isfunction(pi->L, -1)) {
		lua_pushstring(pi->L, "__persist not nil, boolean, or function");
		lua_error(pi->L);
	}
					/* perms reftbl ... obj mt __persist */
	lua_pushvalue(pi->L, -3);
					/* perms reftbl ... obj mt __persist obj */
#ifdef PLUTO_PASS_USERDATA_TO_PERSIST
	lua_pushlightuserdata(pi->L, (void*)pi->writer);
	lua_pushlightuserdata(pi->L, pi->ud);
					/* perms reftbl ... obj mt __persist obj ud */
	lua_call(pi->L, 3, 1);
					/* perms reftbl ... obj mt func? */
#else
	lua_call(pi->L, 1, 1);
					/* perms reftbl ... obj mt func? */
#endif
					/* perms reftbl ... obj mt func? */
	if(!lua_isfunction(pi->L, -1)) {
		lua_pushstring(pi->L, "__persist function did not return a function");
		lua_error(pi->L);
	}
					/* perms reftbl ... obj mt func */
	{
		int one = 1;
		pi->writer(pi->L, &one, sizeof(int), pi->ud);
	}
	persist(pi);
					/* perms reftbl ... obj mt func */
	lua_pop(pi->L, 2);
					/* perms reftbl ... obj */
	return 1;
}
示例#17
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);
    }
lsb_err_value preserve_global_data(lsb_lua_sandbox *lsb)
{

  if (!lsb->lua || !lsb->state_file) {
    return NULL;
  }
  lua_sethook(lsb->lua, NULL, 0, 0);

  // make sure the string library is loaded before we start
  lua_getglobal(lsb->lua, LUA_STRLIBNAME);
  if (!lua_istable(lsb->lua, -1)) {
    lua_getglobal(lsb->lua, "require");
    if (!lua_iscfunction(lsb->lua, -1)) {
      snprintf(lsb->error_message, LSB_ERROR_SIZE,
               "preserve_global_data 'require' function not found");
      return LSB_ERR_LUA;
    }
    lua_pushstring(lsb->lua, LUA_STRLIBNAME);
    if (lua_pcall(lsb->lua, 1, 1, 0)) {
      int len = snprintf(lsb->error_message, LSB_ERROR_SIZE,
                         "preserve_global_data failed loading 'string'");
      if (len >= LSB_ERROR_SIZE || len < 0) {
        lsb->error_message[LSB_ERROR_SIZE - 1] = 0;
      }
      return LSB_ERR_LUA;
    }
  }
  lua_pop(lsb->lua, 1);

  lua_pushvalue(lsb->lua, LUA_GLOBALSINDEX);

  FILE *fh = fopen(lsb->state_file, "wb" CLOSE_ON_EXEC);
  if (fh == NULL) {
    int len = snprintf(lsb->error_message, LSB_ERROR_SIZE,
                       "preserve_global_data could not open: %s",
                       lsb->state_file);
    if (len >= LSB_ERROR_SIZE || len < 0) {
      lsb->error_message[LSB_ERROR_SIZE - 1] = 0;
    }
    return LSB_ERR_LUA;;
  }

  lsb_err_value ret = NULL;
  serialization_data data;
  data.fh = fh;

// Clear the sandbox limits during preservation.
#ifdef LUA_JIT
  lua_gc(lsb->lua, LUA_GCSETMEMLIMIT, 0);
#else
//  size_t limit = lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT];
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = 0;
#endif
//  size_t cur_output_size = lsb->output.size;
//  size_t max_output_size = lsb->output.maxsize;
  lsb->output.maxsize = 0;
// end clear

  data.tables.size = 64;
  data.tables.pos = 0;
  data.tables.array = malloc(data.tables.size * sizeof(table_ref));
  if (data.tables.array == NULL || lsb_init_output_buffer(&data.keys, 0)) {
    snprintf(lsb->error_message, LSB_ERROR_SIZE,
             "preserve_global_data out of memory");
    ret = LSB_ERR_UTIL_OOM;
  } else {
    fprintf(data.fh, "if %s and %s ~= %d then return end\n",
            preservation_version,
            preservation_version,
            get_preservation_version(lsb->lua));
    ret = lsb_outputs(&data.keys, "_G", 2);
    if (!ret) {
      data.keys.pos += 1; // preserve the NUL in this use case
      data.globals = lua_topointer(lsb->lua, -1);
      lua_checkstack(lsb->lua, 2);
      lua_pushnil(lsb->lua);
      while (!ret && lua_next(lsb->lua, -2) != 0) {
        ret = serialize_kvp(lsb, &data, 0);
        lua_pop(lsb->lua, 1);
      }
    }
    lua_pop(lsb->lua, lua_gettop(lsb->lua));
    // Wipe the entire Lua stack.  Since incremental cleanup on failure
    // was added the stack should only contain table _G.
  }
  free(data.tables.array);
  lsb_free_output_buffer(&data.keys);
  fclose(fh);
  if (ret) remove(lsb->state_file);

// Uncomment if we start preserving state when not destroying the sandbox
// Note: serialization uses the output buffer, inprogress output can be
// destroyed if the user was collecting output between calls.
/*
// Restore the sandbox limits after preservation
#ifdef LUA_JIT
  lua_gc(lsb->lua, LUA_GCSETMEMLIMIT,
         lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT]);
#else
  lua_gc(lsb->lua, LUA_GCCOLLECT, 0);
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = limit;
  lsb->usage[LSB_UT_MEMORY][LSB_US_MAXIMUM] =
    lsb->usage[LSB_UT_MEMORY][LSB_US_CURRENT];
#endif
  lsb->output.maxsize = max_output_size;
  lsb_clear_output_buffer(lsb->output);
  if (lsb->output.size > cur_output_size) {
    void* ptr = realloc(lsb->output.data, cur_output_size);
    if (!ptr) return 1;
    lsb->output.data = ptr;
    lsb->output.size = cur_output_size;
  }
// end restore
*/
  return ret;
}
示例#19
0
 virtual bool readStackObject()
 {
     uint64_t iIndex;
     if(!readVUInt(iIndex))
     {
         setError("Expected stack object");
         return false;
     }
     lua_State *L = m_L;
     if(lua_type(L, 1) != LUA_TTABLE)
     {
         // Ensure that index #1 is self environment
         lua_getfenv(L, 1);
         lua_replace(L, 1);
     }
     if(iIndex >= PERSIST_TCOUNT)
     {
         iIndex += 1 - PERSIST_TCOUNT;
         if(iIndex < (uint64_t)INT_MAX)
             lua_rawgeti(L, 1, (int)iIndex);
         else
         {
             lua_pushnumber(L, (lua_Number)iIndex);
             lua_rawget(L, 1);
         }
         if(lua_isnil(L, -1))
         {
             setError("Cycle while depersisting permanent object key or userdata metatable");
             return false;
         }
     }
     else
     {
         uint8_t iType = (uint8_t)iIndex;
         switch(iType)
         {
         case LUA_TNIL:
             lua_pushnil(L);
             break;
         case PERSIST_TPERMANENT: {
             uint64_t iOldIndex = m_iNextIndex;
             ++m_iNextIndex; // Temporary marker
             lua_rawgeti(L, 1, 0); // Permanents table
             if(!readStackObject())
                 return false;
             lua_gettable(L, -2);
             lua_replace(L, -2);
             // Replace marker with actual object
             uint64_t iNewIndex = m_iNextIndex;
             m_iNextIndex = iOldIndex;
             saveStackObject();
             m_iNextIndex = iNewIndex;
             break; }
         case LUA_TBOOLEAN:
             lua_pushboolean(L, 0);
             break;
         case PERSIST_TTRUE:
             lua_pushboolean(L, 1);
             break;
         case LUA_TSTRING: {
             size_t iLength;
             if(!readVUInt(iLength))
                 return false;
             while(iLength > m_iStringBufferLength)
             {
                 m_iStringBufferLength *= 2;
                 m_sStringBuffer = (char*)realloc(m_sStringBuffer, m_iStringBufferLength);
             }
             if(!readByteStream((uint8_t*)m_sStringBuffer, iLength))
                 return false;
             lua_pushlstring(L, m_sStringBuffer, iLength);
             saveStackObject();
             break; }
         case LUA_TTABLE:
             lua_newtable(L);
             saveStackObject();
             if(!lua_checkstack(L, 8))
                 return false;
             if(!readTableContents())
                 return false;
             break;
         case PERSIST_TTABLE_WITH_META:
             lua_newtable(L);
             saveStackObject();
             if(!lua_checkstack(L, 8))
                 return false;
             if(!readStackObject())
                 return false;
             lua_setmetatable(L, -2);
             if(!readTableContents())
                 return false;
             break;
         case LUA_TNUMBER: {
             double fValue;
             if(!readByteStream(reinterpret_cast<uint8_t*>(&fValue), sizeof(double)))
                 return false;
             lua_pushnumber(L, fValue);
             break; }
         case LUA_TFUNCTION: {
             if(!lua_checkstack(L, 8))
                 return false;
             uint64_t iOldIndex = m_iNextIndex;
             ++m_iNextIndex; // Temporary marker
             if(!readStackObject())
                 return false;
             lua_call(L, 0, 2);
             // Replace marker with closure
             uint64_t iNewIndex = m_iNextIndex;
             m_iNextIndex = iOldIndex;
             saveStackObject();
             m_iNextIndex = iNewIndex;
             // Set upvalues
             lua_insert(L, -2);
             int iNups, i;
             if(!readVUInt(iNups))
                 return false;
             size_t iIDSize;
             if(!readVUInt(iIDSize))
                 return false;
             for(i = 0; i < iNups; ++i)
             {
                 if(!readStackObject())
                     return false;
                 // For now, just skip over the upvalue IDs. In the future,
                 // the ID may be used to rejoin shared upvalues.
                 if(!readByteStream(NULL, iIDSize))
                     return false;
             }
             lua_call(L, iNups, 0);
             // Read environment
             if(!readStackObject())
                     return false;
             lua_setfenv(L, -2);
             break; }
         case PERSIST_TPROTOTYPE: {
             if(!lua_checkstack(L, 8))
                 return false;
             uint64_t iOldIndex = m_iNextIndex;
             ++m_iNextIndex; // Temporary marker
             int iNups;
             if(!readVUInt(iNups))
                 return false;
             if(iNups == 0)
                 lua_pushliteral(L, "return function() end,");
             else
             {
                 lua_pushliteral(L, "local ");
                 lua_checkstack(L, (iNups + 1) * 2);
                 for(int i = 0; i < iNups; ++i)
                 {
                     if(i != 0)
                         lua_pushliteral(L, ",");
                     if(!readStackObject())
                         return false;
                     if(lua_type(L, -1) != LUA_TSTRING)
                     {
                         setError("Upvalue name not a string");
                         return false;
                     }
                 }
                 lua_concat(L, iNups * 2 - 1);
                 lua_pushliteral(L, ";return function(...)");
                 lua_pushvalue(L, -2);
                 lua_pushliteral(L, "=...end,");
                 lua_concat(L, 5);
             }
             // Fetch name and then lookup filename and code
             if(!readStackObject())
                 return false;
             lua_pushliteral(L, "@");
             lua_rawgeti(L, 1, -1);
             lua_pushvalue(L, -3);
             lua_gettable(L, -2);
             lua_replace(L, -2);
             if(lua_isnil(L, -1))
             {
                 setError(lua_pushfstring(L, "Unable to depersist prototype"
                     " \'%s\'", lua_tostring(L, -3)));
                 return false;
             }
             lua_concat(L, 2); // Prepend the @ to the filename
             lua_rawgeti(L, 1, -2);
             lua_pushvalue(L, -3);
             lua_gettable(L, -2);
             lua_replace(L, -2);
             lua_remove(L, -3);
             // Construct the closure factory
             LoadMultiBuffer_t ls;
             ls.s[0] = lua_tolstring(L, -3, &ls.i[0]);
             ls.s[1] = lua_tolstring(L, -1, &ls.i[1]);
             if(lua_load(L, LoadMultiBuffer_t::load_fn, &ls, lua_tostring(L, -2)) != 0)
             {
                 // Should never happen
                 lua_error(L);
                 return false;
             }
             lua_replace(L, -4);
             lua_pop(L, 2);
             // Replace marker with closure factory
             uint64_t iNewIndex = m_iNextIndex;
             m_iNextIndex = iOldIndex;
             saveStackObject();
             m_iNextIndex = iNewIndex;
             break; }
         case LUA_TUSERDATA: {
             bool bHasSetMetatable = false;
             uint64_t iOldIndex = m_iNextIndex;
             ++m_iNextIndex; // Temporary marker
             // Read metatable
             if(!readStackObject())
                 return false;
             lua_getfield(L, -1, "__depersist_size");
             if(!lua_isnumber(L, -1))
             {
                 setError("Userdata missing __depersist_size metafield");
                 return false;
             }
             lua_newuserdata(L, (size_t)lua_tonumber(L, -1));
             lua_replace(L, -2);
             // Replace marker with userdata
             uint64_t iNewIndex = m_iNextIndex;
             m_iNextIndex = iOldIndex;
             saveStackObject();
             m_iNextIndex = iNewIndex;
             // Perform immediate initialisation
             lua_getfield(L, -2, "__pre_depersist");
             if(lua_isnil(L, -1))
                 lua_pop(L, 1);
             else
             {
                 // Set metatable now, as pre-depersister may expect it
                 // NB: Setting metatable if there isn't a pre-depersister
                 // is not a good idea, as if there is an error while the
                 // environment table is being de-persisted, then the __gc
                 // handler of the userdata will eventually be called with
                 // the userdata's contents still being uninitialised.
                 lua_pushvalue(L, -3);
                 lua_setmetatable(L, -3);
                 bHasSetMetatable = true;
                 lua_pushvalue(L, -2);
                 lua_call(L, 1, 0);
             }
             // Read environment
             if(!readStackObject())
                 return false;
             lua_setfenv(L, -2);
             // Set metatable and read the raw data
             if(!bHasSetMetatable)
             {
                 lua_pushvalue(L, -2);
                 lua_setmetatable(L, -2);
             }
             lua_getfield(L, -2, "__depersist");
             if(lua_isnil(L, -1))
                 lua_pop(L, 1);
             else
             {
                 lua_pushvalue(L, -2);
                 lua_rawgeti(L, 1, -3);
                 lua_call(L, 2, 1);
                 if(lua_toboolean(L, -1) != 0)
                 {
                     lua_pop(L, 1);
                     lua_rawgeti(L, 1, -3);
                     lua_getmetatable(L, -1);
                     lua_replace(L, -2);
                     lua_pushvalue(L, -2);
                     lua_rawseti(L, -2, (int)lua_objlen(L, -2) + 1);
                 }
                 lua_pop(L, 1);
             }
             lua_replace(L, -2);
             uint64_t iSyncMarker;
             if(!readVUInt(iSyncMarker))
                 return false;
             if(iSyncMarker != 0x42)
             {
                 setError("sync fail");
                 return false;
             }
             break; }
         case PERSIST_TINTEGER: {
             uint16_t iValue;
             if(!readVUInt(iValue))
                 return false;
             lua_pushinteger(L, iValue);
             break; }
         default:
             lua_pushliteral(L, "Unable to depersist values of type \'");
             if(iType <= LUA_TTHREAD)
                 lua_pushstring(L, lua_typename(L, iType));
             else
             {
                 switch(iType)
                 {
                 case PERSIST_TPERMANENT:
                     lua_pushliteral(L, "permanent"); break;
                 case PERSIST_TTRUE:
                     lua_pushliteral(L, "boolean-true"); break;
                 case PERSIST_TTABLE_WITH_META:
                     lua_pushliteral(L, "table-with-metatable"); break;
                 case PERSIST_TINTEGER:
                     lua_pushliteral(L, "integer"); break;
                 case PERSIST_TPROTOTYPE:
                     lua_pushliteral(L, "prototype"); break;
                 case PERSIST_TRESERVED1:
                     lua_pushliteral(L, "reserved1"); break;
                 case PERSIST_TRESERVED2:
                     lua_pushliteral(L, "reserved2"); break;
                 }
             }
             lua_pushliteral(L, "\'");
             lua_concat(L, 3);
             setError(lua_tostring(L, -1));
             lua_pop(L, 1);
             return false;
         }
     }
     return true;
 }
示例#20
0
static int pmain(lua_State* L) {
  struct Smain* s = (struct Smain*)lua_touserdata(L, 1);
  int argc=s->argc;
  char** argv=s->argv;
  Proto* f;
  int scripts=0;
  int i;
  if (!lua_checkstack(L,argc)) fatal("too many input files");
  lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
  luaL_openlibs(L);  /* open libraries */
  lua_gc(L, LUA_GCRESTART, 0);
  /* compile each script from command line into a Lua function. */
  for (i=0; i<argc; i++) {
    const char* filename=IS("-") ? NULL : argv[i];
    if(IS("-L")) break;
    if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
    scripts++;
  }
  /* compile each preload library from the command line into a Lua function. */
  for (i=0; i<preloads; i++) {
    char* filename=preload_libs[i];
    char* p;
    /* try loading library as if it is a normal file. */
    if (luaL_loadfile(L,filename)!=0) {
      /* try pre-loading library with 'require' module loading system. */
      lua_getglobal(L, "require");
      lua_pushstring(L, filename);
      lua_pushboolean(L, 1);
      lua_call(L, 2, 1);
      if (lua_iscfunction(L, -1)) { /* make sure it is not a C-Function. */
        lua_pop(L, 1);
        lua_pushfstring(L, "\nCan't preload C module: '%s'\n", filename);
        lua_concat(L, 2);  /* accumulate with error from luaL_findfile */
        fatal(lua_tostring(L,-1));
      }
      if (!lua_isfunction(L, -1)) { /* did we get an error? */
        lua_pushliteral(L, "\n");
        lua_concat(L, 3);  /* accumulate with error from luaL_findfile */
        fatal(lua_tostring(L,-1));
      } else {
        lua_remove(L, -2); /* remove error from luaL_findfile. */
      }
    } else {
      /* convert filename into package name. */
      p= filename + strlen(filename);
      for(;p >= filename; p--) {
        if(p[0] == '.') { /* Remove file extension. */
          p[0] = '\0';
          continue;
        }
        if(p[0] == '/') { /* Remove file path. */
          preload_libs[i] = p+1;
          break;
        }
      }
    }
  }
  /* generate a new Lua function to combine all of the compiled scripts. */
  f=combine(L, scripts);
  if (listing) luaU_print(f,listing>1);
  if (c_code && !parse_only) {
    FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
    if (D==NULL) cannot("open");
    lua_lock(L);
    slua_dumper_dump(D, output, L, f, stripping);
    lua_unlock(L);
    if (ferror(D)) cannot("write");
    if (fclose(D)) cannot("close");
  }
  if (dumping && !parse_only) {
    FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
    if (D==NULL) cannot("open");
    lua_lock(L);
    luaU_dump(L,f,writer,D,stripping);
    lua_unlock(L);
    if (ferror(D)) cannot("write");
    if (fclose(D)) cannot("close");
  }
  return 0;
}
示例#21
0
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
  if (!lua_checkstack(L, space))
    luaL_error(L, "stack overflow (%s)", mes);
}
示例#22
0
文件: xsperf.c 项目: LuaDist/xstring
int main(int argc, char **argv) {
    lua_State *L;
    unsigned i, it;
    int c;
    unsigned long n;
    char *p;

    unsigned iters = 1000;
    param_type_t param_type = PARAM_UNSPEC;
    unsigned num_params = 0;
    typedef struct {
	size_t  size;
	char    *buf;
	xsbuf_t *xsbuf;
    } param_t;
    param_t params[MAXPARAM] = {{ 0 }};
    size_t max_param_size = 0;

    struct timespec real_start, real_end, proc_start, proc_end;
    double totalmem;
    int maxmem;

    while ((c = getopt(argc, argv, "i:" "x:" "LMSs:")) != EOF) {
	switch (c) {
	case 'i':
	    iters = strtoul(optarg, &p, 10);
	    if (*p) die("invalid iter count: -i%s\n", optarg);
	    break;
	case 'x':
	    n = strtoul(optarg, &p, 10);
	    if (*p || n > 1) die("invalid string param type (0/1): -x%s\n", optarg);
	    param_type = (param_type_t)n;
	    break;

	case 'L': n = LARGE;  goto add_param;
	case 'M': n = MEDIUM; goto add_param;
	case 'S': n = SMALL;  goto add_param;
	case 's':
	    n = strtoul(optarg, &p, 0);
	    if (*p == 'k') {
		n *= 1024;
		++p;
	    }
	    else if (*p == 'm') {
		n *= 1024 * 1024;
		++p;
	    }
	    if (*p || n < MINPARAMSIZE)
		die("invalid param size: -s%s\n", optarg);
	add_param:
	    if (num_params >= MAXPARAM)
		die("too many parameters; increase MAXPARAM\n");
	    if (!(p = calloc(n, 1)))
		die("Unable to allocate %lu for parameter %u\n", n, num_params + 1);
	    params[num_params].size = n;
	    params[num_params].buf  = p;
	    ++num_params;
	    if (n > max_param_size)
		max_param_size = n;
	    break;
	}
    }
    if (param_type < 0) die("must specify string param type (-x0 or -x1)\n");
    if (!num_params)    die("must specify at least one parameter size\n");

    printf("Test info:\n"
	   "  %u iterations\n"
	   "  %u %s strings: ",
	   iters,
	   num_params,
	   param_type ? "EXTERNAL" : "LUA");
    for (i = 0; i < num_params; ++i) {
	const size_t s = params[i].size;
	if (s >= 1024 && !(s & 1023))
	    printf(" %zuk", s / 1024);
	else
	    printf(" %zu", s);
    }
    printf("\n");

    /*
     * set up Lua environ
     */

    L = luaL_newstate();
    assert(L);
    luaL_openlibs(L);

    if (luaL_dofile(L, "xsperf.lua"))
	die("Can't load xsperf.lua: %s\n", lua_tostring(L, -1));
    lua_settop(L, 0);

    /*
     * run the test
     */

    srand48(getpid());

    lua_checkstack(L, 2 + num_params);

    if (clock_gettime(CLOCK_REALTIME, &real_start))
	die("Can't get starting real time: %s\n", strerror(errno));
    if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &proc_start))
	die("Can't get starting process time: %s\n", strerror(errno));

    totalmem = 0;
    maxmem = 0;

    for (it = 0; it < iters; ++it) {
	xsbuf_t *b;
	int mem;

	lua_getglobal(L, "test_iter");

	for (i = 0; i < num_params; ++i) {
	    const param_t *par = &params[i];

	    /* modify all the param strings to defeat hashing */
	    snprintf(par->buf, par->size, "param %2u: %lX", i + 1, (unsigned long)lrand48());

	    switch (param_type) {
	    case PARAM_LUASTRING:
		lua_pushlstring(L, par->buf, par->size);
		break;
	    case PARAM_XSTRING:
		b = xsbuf_new(par->buf, par->size);
		params[i].xsbuf = b;
		xstring_new(L, b);
		break;
	    case PARAM_UNSPEC: ; /* silence gcc warning */
	    }
	}

	if (lua_pcall(L, num_params, 0, 0))
	    die("Call #%u to test_iter() failed: %s\n", it + 1, lua_tostring(L, -1));

	if (param_type == PARAM_XSTRING) {
	    for (i = 0; i < num_params; ++i) {
		xsbuf_kill(   params[i].xsbuf);
		xsbuf_discard(params[i].xsbuf);
	    }
	}

	mem = lua_gc(L, LUA_GCCOUNT, 0);
	totalmem += mem;
	if (mem > maxmem)
	    maxmem = mem;
    }

    lua_gc(L, LUA_GCCOLLECT, 0);

    if (clock_gettime(CLOCK_REALTIME, &real_end))
	die("Can't get ending real time: %s\n", strerror(errno));
    if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &proc_end))
	die("Can't get ending process time: %s\n", strerror(errno));

    for (i = 0; i < num_params; ++i)
	free(params[i].buf);

    lua_close(L);

    printf("Done!\n");
    printf("User time:   %.3f\n", tsdiff(proc_start, proc_end));
    printf("Clock time:  %.3f\n", tsdiff(real_start, real_end));
    printf("Average mem: %.0f KiB\n", totalmem / iters);
    printf("Maximum mem: %d KiB\n", maxmem);

    return 0;
}
示例#23
0
/// Returns a table array containing all the file names of the
// files in the specified directory.
//
// <b>Important</b>: this function lists both files from actual directories on
// hard disk, and virtual directories loaded through
// @{blitwizard.loadResourceArchive|loaded zip resource archives}.
// Virtual files will take precedence over real files (you won't
// receive duplicates).
//
// If you don't want virtual files listed (e.g. because you want
// to examine any directory supplied by the user and not part of your
// project)
// @function ls
// @tparam string directory path, empty string ("") for current directory
// @tparam boolean virtual_files (optional) Specify true to list virtual files inside virtual directories aswell (the default behaviour), false to list only files in the actual file system on disk
// @usage
//   -- list all files in current directory:
//   for i,file in ipairs(os.ls("")) do
//       print("file name: " .. file)
//   end
int luafuncs_ls(lua_State *l) {
    const char *p = lua_tostring(l, 1);
    if (!p) {
        lua_pushstring(l, "First argument is not a valid path string");
        return lua_error(l);
    }
    char *pnative = file_getAbsolutePathFromRelativePath(p);
    char *pcross = strdup(pnative);
    char *pcrossResourceDir = strdup(pnative);
    if (!pnative || !pcross || !pcrossResourceDir) {
        free(pnative);
        free(pcross);
        free(pcrossResourceDir);
        return haveluaerror(l, "failed to allocate file paths");
    }
    file_makeSlashesNative(pnative);
    file_makeSlashesCrossplatform(pcross);
    file_makePathRelative(pcrossResourceDir, main_getRunDir());
    if (!file_IsPathRelative(pcrossResourceDir)) {
        free(pcrossResourceDir);
        pcrossResourceDir = NULL;
    }
    
    // check parameter if we want to list internal zip stuff or not:
    int list_virtual = 1;
    if (lua_gettop(l) >= 2 && lua_type(l, 2) != LUA_TNIL) {
        if (lua_type(l, 2) != LUA_TNUMBER) {
            free(pnative);
            free(pcross);
            free(pcrossResourceDir);
            return haveluaerror(l, badargument1, 2, "os.ls", "boolean or nil",
            lua_strtype(l, 2));
        }
        list_virtual = lua_toboolean(l, 2);
    }

    // get virtual filelist:
    char **filelist = NULL;
#ifdef USE_PHYSFS
    if (list_virtual && pcrossResourceDir) {
        filelist = resource_getFileList(pcrossResourceDir);
        //printf("got filelist for %s: %p\n", pcrossrelative, filelist);
        char **p = filelist;
        if (p) {
            while (*p) {
                assert(strlen(*p) <= 512);
                assert(*p[0] >= 32);
                p++;
            }
        }
    }
#endif

    // get iteration context for "real" on disk directory:
    struct filelistcontext *ctx = filelist_Create(pnative);

    if (!ctx && (!list_virtual || !filelist)) {
        char errmsg[500];
        snprintf(errmsg, sizeof(errmsg), "failed to ls folder: %s", pnative);
        errmsg[sizeof(errmsg)-1] = 0;
        lua_pushstring(l, errmsg);
        free(pnative);
        free(pcross);
        free(pcrossResourceDir);
        if (filelist) {
            size_t i = 0;
            while (filelist[i]) {
                free(filelist[i]);
                i++;
            }
            free(filelist);
        }
        return lua_error(l);
    }

    // create file listing table
    lua_newtable(l);

    // add all files/folders to file listing table
    char filenamebuf[500];
    int isdir;
    int returnvalue = 0;
    unsigned int i = 0;
    // loop through all files:
    if (ctx) {
        while ((returnvalue = filelist_GetNextFile(ctx,
                filenamebuf, sizeof(filenamebuf), &isdir)) == 1) {
            i++;
            lua_checkstack(l, 3);

            int duplicate = 0;
            // if we list against virtual folders too,
            // check for this being a duplicate:
            if (filelist) {
                unsigned int i2 = 0;
                while (filelist[i2]) {
                    if (strcasecmp(filelist[i2], filenamebuf) == 0) {
                        duplicate = 1;
                        break;
                    }
                    i2++;
                }
            }
            if (duplicate) {
                // don't add this one.
                i--;
                continue;
            }
            lua_pushinteger(l, i);
            lua_pushstring(l, filenamebuf);
            lua_settable(l, -3);
        }

        // free file list
        filelist_Free(ctx);
    }

    if (filelist) {
        // add file list to table:
        i = 0;
        while (filelist[i]) {
            lua_pushinteger(l, i + 1);
            lua_pushstring(l, filelist[i]);
            lua_settable(l, -3);
            i++;
        }

        // free virtual file list:
        i = 0;
        while (filelist[i]) {
            free(filelist[i]);
            i++;
        }
        free(filelist);
    }

    // process error during listing
    if (returnvalue < 0) {
        lua_pop(l, 1); // remove file listing table

        char errmsg[500];
        snprintf(errmsg, sizeof(errmsg),
            "Error while processing ls in folder: %s", pnative);
        errmsg[sizeof(errmsg)-1] = 0;
        lua_pushstring(l, errmsg);
        free(pnative);
        free(pcross);
        free(pcrossResourceDir);
        return lua_error(l);
    }

    // return file list
    free(pnative);
    free(pcross);
    free(pcrossResourceDir);
    return 1;
}
示例#24
0
static int ck_query(lua_State *L) {
    ck_errno = CK_ERR_OK;
    int n = lua_gettop(L);
    CKPackage *results = NULL;
    if (n != 2) {
        lua_pushstring(L, "Wrong number of arguments");
        lua_error(L);
    }
    if (!lua_isstring(L, 1) || !lua_isstring(L,2)) {
        lua_pushstring(L, "incorrect argument type");
        lua_error(L);
    }
    const char *qtype = luaL_checkstring(L, 1);
    const char *qstring = luaL_checkstring(L, 2);
    
    results = cronkite_get(qtype[0], qstring);
    if (!results) {
        // get ck_error and raise exception with it
        const char *errmsg = cronkite_strerror(ck_errno);
        lua_pushstring(L, errmsg);
        lua_error(L);
    }

    CKPackage *pkg = results;
    // lua tables start at 1
    int i = 1;
    lua_newtable(L);
    int outer_top = lua_gettop(L);
    int inner_top = 0;
    // ensure stack is large enough for building inner table in loop
    lua_checkstack(L, 30);
    while (pkg) {
        // push array index for parent table
        lua_pushinteger(L, i);

        // build new package table
        lua_newtable(L);
        inner_top = lua_gettop(L);
        lua_pushstring(L, "id");
        lua_pushstring(L, pkg->values[0]);
        lua_pushstring(L, "url");
        lua_pushstring(L, pkg->values[1]);
        lua_pushstring(L, "name");
        lua_pushstring(L, pkg->values[2]);
        lua_pushstring(L, "version");
        lua_pushstring(L, pkg->values[3]);
        lua_pushstring(L, "urlpath");
        lua_pushstring(L, pkg->values[4]);
        lua_pushstring(L, "license");
        lua_pushstring(L, pkg->values[5]);
        lua_pushstring(L, "numvotes");
        lua_pushstring(L, pkg->values[6]);
        lua_pushstring(L, "outofdate");
        lua_pushstring(L, pkg->values[7]);
        lua_pushstring(L, "categoryid");
        lua_pushstring(L, pkg->values[8]);
        lua_pushstring(L, "description");
        lua_pushstring(L, pkg->values[9]);
        // build inner table
        for (int j=0; j<10; j++) {
            lua_settable(L, inner_top);
        }
        // add inner table to the outer table
        lua_settable(L, outer_top);
        i++;
        pkg = pkg->next;
    }
    // do cronkite cleanup
    cronkite_cleanup(results);
    return 1;
}
示例#25
0
static int lluv_tcp_bind(lua_State *L){
  static const lluv_uv_const_t FLAGS[] = {
    { UV_TCP_IPV6ONLY ,   "ipv6only"   },

    { 0, NULL }
  };

  lluv_handle_t  *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN);
  struct sockaddr_storage sa; int err = lluv_check_addr(L, 2, &sa);
  unsigned int flags = 0;
  int top = lua_gettop(L);
  if(top > 5)lua_settop(L, top = 5);

  if((top > 4) || (!lua_isfunction(L, 4))){
    flags = lluv_opt_flags_ui(L, 4, flags, FLAGS);
  }

  if(err < 0){
    lua_checkstack(L, 3);

    lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3);

    if(!lua_isfunction(L, top)){
      return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1));
    }

    lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1));
    lua_remove(L, -2);
    lua_pushvalue(L, 1);
    lua_insert(L, -2);
    lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2);
    lua_settop(L, 1);
    return 1;
  }

  err = uv_tcp_bind(LLUV_H(handle, uv_tcp_t), (struct sockaddr *)&sa, flags);
  if(err < 0){
    lua_checkstack(L, 3);

    lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3);

    if(!lua_isfunction(L, top)){
      return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1));
    }

    lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1));
    lua_remove(L, -2);
    lua_pushvalue(L, 1);
    lua_insert(L, -2);
    lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2);
    lua_settop(L, 1);
    return 1;
  }

  if(lua_isfunction(L, top)){
    lua_pushvalue(L, 1);
    lua_pushnil(L);
    lluv_loop_defer_call(L,
      lluv_loop_by_handle(&handle->handle),
      lluv_push_addr(L, &sa) + 2
    );
  }

  lua_settop(L, 1);
  return 1;
}
示例#26
0
static void
rdns_regress_callback (struct rdns_reply *reply, void *arg)
{
	struct rdns_reply_entry *entry;
	char out[INET6_ADDRSTRLEN + 1];
	const struct rdns_request_name *name;

	//llpm_entry_add
	//printf("In the callback function with lcore = %u\n", rte_lcore_id());
	lua_State *tl = spam_tls[rte_lcore_id()];

	if (reply->code == RDNS_RC_NOERROR) {
		entry = reply->entries;
		while (entry != NULL) {
			if (entry->type == RDNS_REQUEST_A) {
				inet_ntop (AF_INET, &entry->content.a.addr, out, sizeof (out));
				printf ("%s has A record %s\n", (char *)arg, out);
		
				int ip4[4];
				sscanf(arg, "%d.%d.%d.%d.zen.spamhaus.org", &ip4[0], &ip4[1], &ip4[2], &ip4[3]);
				unsigned int ip = (ip4[3] << 24) + (ip4[2] << 16) + (ip4[1] << 8) + ip4[0];
				
				lua_checkstack(tl, 20);
				/* push functions and arguments */
				lua_getglobal(tl, "llpm_entry_add"); /* function to be called */

				lua_pushinteger(tl, ip);   /* push 1st argument */
				lua_pushinteger(tl, 32);   /* push 2nd argument */
				lua_pushinteger(tl, 1);   /* push 2nd argument */

				if (lua_pcall(tl, 3, 1, 0) != 0)
					error(tl, "error running function `llpm_entry_add': %s", lua_tostring(tl, -1));

				lua_pop(tl, 1);  /* pop returned value */
			}
			else if (entry->type == RDNS_REQUEST_AAAA) {
				inet_ntop (AF_INET6, &entry->content.aaa.addr, out, sizeof (out));
				printf ("%s has AAAA record %s\n", (char *)arg, out);
			}
			else if (entry->type == RDNS_REQUEST_SOA) {
				printf ("%s has SOA record %s %s %u %d %d %d\n",
						(char *)arg,
						entry->content.soa.mname,
						entry->content.soa.admin,
						entry->content.soa.serial,
						entry->content.soa.refresh,
						entry->content.soa.retry,
						entry->content.soa.expire);
			}
			else if (entry->type == RDNS_REQUEST_TLSA) {
				char *hex, *p;
				unsigned i;

				hex = malloc (entry->content.tlsa.datalen * 2 + 1);
				p = hex;

				for (i = 0; i < entry->content.tlsa.datalen; i ++) {
					sprintf (p, "%02x",  entry->content.tlsa.data[i]);
					p += 2;
				}

				printf ("%s has TLSA record (%d %d %d) %s\n",
						(char *)arg,
						(int)entry->content.tlsa.usage,
						(int)entry->content.tlsa.selector,
						(int)entry->content.tlsa.match_type,
						hex);

				free (hex);
			}
			entry = entry->next;
		}
	}
	else {
		name = rdns_request_get_name (reply->request, NULL);
		printf ("Cannot resolve %s record for %s: %s\n",
				rdns_strtype (name->type),
				(char *)arg,
				rdns_strerror (reply->code));
		
		int ip4[4];
		sscanf(arg, "%d.%d.%d.%d.zen.spamhaus.org", &ip4[0], &ip4[1], &ip4[2], &ip4[3]);
		unsigned int ip = (ip4[3] << 24) + (ip4[2] << 16) + (ip4[1] << 8) + ip4[0];

		//printf("%d.%d.%d.%d\n", ip4[3], ip4[2], ip4[1], ip4[0]);

		lua_checkstack(tl, 20);
		/* push functions and arguments */
		lua_getglobal(tl, "llpm_entry_add"); /* function to be called */

		lua_pushinteger(tl, ip);   /* push 1st argument */
		lua_pushinteger(tl, 32);   /* push 2nd argument */
		lua_pushinteger(tl, 0);   /* push 2nd argument */

		if (lua_pcall(tl, 3, 1, 0) != 0)
			error(tl, "error running function `llpm_entry_add': %s", lua_tostring(tl, -1));

		lua_pop(tl, 1);  /* pop returned value */
	}

	if (--remain_tests == 0 && finished == 1) {
		printf ("End of test cycle\n");
		rdns_resolver_release (reply->resolver);
	}
}
示例#27
0
/**
**  Append the fields (keys and values) of a Lua table to the Lua
**  source code.
**
**  @param table_index
**      The index of the table in the Lua stack.
**  @param is_root
**      True if the table is a global environment and this function
**      should generate a series of assignment statements.
**      False if the table is something else and this function should
**      generate a fieldlist for a tableconstructor.
**
**  @return
**      CSerializeLua::OK if it appended the fields as requested.
**      CSerializeLua::FAIL if something went seriously wrong and the
**      whole serialization should be aborted.
**      CSerializeLua::SKIP if is_root is false and the table contains
**      something that cannot be serialized.
**
** If is_root is true and the table contains a field that cannot be
** serialized, then this function just skips that field and continues
** serializing the rest of the table.  This is so that the global
** environment can be serialized even though it contains functions.
*/
CSerializeLua::Result CSerializeLua::AppendLuaFields(int table_index,
						     bool is_root)
{
	if (!lua_checkstack(this->lstate, 10))
		return FAIL;
	const int top_on_entry = lua_gettop(this->lstate);
	Assert(lua_istable(this->lstate, table_index));

	lua_Number seq = 1;
	bool is_first = true;
	lua_pushnil(this->lstate);
	while (lua_next(this->lstate, table_index)) {
		const int key_index = top_on_entry + 1;
		const int value_index = top_on_entry + 2;
		Result result;

		// If there's any problem with the field, then we
		// remove it from the output vector by truncating
		// back to this size.
		const size_t undo = this->output.size();

		if (!is_root) {
			if (is_first) {
				this->AppendChar('\n');
			} else {
				this->AppendCString(",\n");
			}
			this->AppendIndent();
		}

		// Append the key and and equals sign, if necessary.
		bool increment_seq = false;
		const int key_type = lua_type(this->lstate, key_index);
		if (is_root) {
			if (key_type != LUA_TSTRING) {
				goto skip_field;
			}

			size_t key_len;
			const char *key_str = lua_tolstring(this->lstate,
							    key_index,
							    &key_len);
			if (!IsIdentifier(key_str, key_len)
			    || IsBlacklistedGlobal(key_str)) {
				goto skip_field;
			}

			this->AppendChars(key_str, key_len);
			this->AppendCString(" = ");
		} else if (key_type == LUA_TSTRING) {
			size_t key_len;
			const char *key_str = lua_tolstring(this->lstate,
							    key_index,
							    &key_len);
			if (IsIdentifier(key_str, key_len)) {
				this->AppendChars(key_str, key_len);
			} else {
				this->AppendChar('[');
				this->AppendQuotedString(key_str, key_len);
				this->AppendChar(']');
			}
			this->AppendCString(" = ");
		} else if (key_type == LUA_TNUMBER) {
			if (lua_tonumber(this->lstate, key_index) == seq) {
				// Increment seq only after the value
				// has been successfully serialized.
				increment_seq = true;
			} else {
				this->AppendChar('[');
				result = this->AppendLuaAsString(key_index);
				if (result != OK) {
					return result;
				}
				this->AppendCString("] = ");
			}
		} else {
			goto skip_field;
		}

		result = this->AppendLuaValue(value_index);
		switch (result) {
		case OK:
			if (is_root) {
				this->AppendCString(";\n");
			}
			is_first = false;
			if (increment_seq)
				++seq;
			break;
		case SKIP:
		skip_field:
			this->output.resize(undo);
			if (!is_root) {
				lua_settop(this->lstate, top_on_entry);
				return SKIP;
			}
			break;
		case FAIL:
		default:
			lua_settop(this->lstate, top_on_entry);
			return result;
		}

		lua_pop(this->lstate, 1); // pop the value
	}

	if (!is_first && !is_root) {
		this->AppendChar(' ');
	}
	
	return OK;
}
示例#28
0
/* Persist all stack members
 */
static void persistthread(PersistInfo *pi)
{
	size_t posremaining;
	lua_State *L2;
					/* perms reftbl ... thr */
	L2 = lua_tothread(pi->L, -1);
	lua_checkstack(pi->L, L2->top - L2->stack + 1);
	if(pi->L == L2) {
		lua_pushstring(pi->L, "Can't persist currently running thread");
		lua_error(pi->L);
		return; /* not reached */
	}

	/* Persist the stack */
	posremaining = revappendstack(L2, pi->L);
					/* perms reftbl ... thr (rev'ed contents of L2) */
	pi->writer(pi->L, &posremaining, sizeof(size_t), pi->ud);
	for(; posremaining > 0; posremaining--) {
		persist(pi);
		lua_pop(pi->L, 1);
	}
					/* perms reftbl ... thr */
	/* Now, persist the CallInfo stack. */
	{
		size_t i, numframes = (L2->ci - L2->base_ci) + 1;
		pi->writer(pi->L, &numframes, sizeof(size_t), pi->ud);
		for(i=0; i<numframes; i++) {
			CallInfo *ci = L2->base_ci + i;
			size_t stackbase = ci->base - L2->stack;
			size_t stackfunc = ci->func - L2->stack;
			size_t stacktop = ci->top - L2->stack;
			size_t savedpc = (ci != L2->base_ci) ?
				ci->savedpc - ci_func(ci)->l.p->code :
				0;
			pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud);
			pi->writer(pi->L, &stackfunc, sizeof(size_t), pi->ud);
			pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud);
			pi->writer(pi->L, &ci->nresults, sizeof(int), pi->ud);
			pi->writer(pi->L, &savedpc, sizeof(size_t), pi->ud);
		}
	}

	/* Serialize the state's other parameters, with the exception of upval stuff */
	{
		size_t stackbase = L2->base - L2->stack;
		size_t stacktop = L2->top - L2->stack;
		lua_assert(L2->nCcalls <= 1);
		pi->writer(pi->L, &L2->status, sizeof(lu_byte), pi->ud);
		pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud);
		pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud);
		pi->writer(pi->L, &L2->errfunc, sizeof(ptrdiff_t), pi->ud);
	}

	/* Finally, record upvalues which need to be reopened */
	/* See the comment above persistupval() for why we do this */
	{
		GCObject *gco;
		UpVal *uv;
					/* perms reftbl ... thr */
		for(gco = L2->openupval; gco != NULL; gco = uv->next) {
			size_t stackpos;
			uv = gco2uv(gco);

			/* Make sure upvalue is really open */
			lua_assert(uv->v != &uv->u.value);
			pushupval(pi->L, uv);
					/* perms reftbl ... thr uv */
			persist(pi);
			lua_pop(pi->L, 1);
					/* perms reftbl ... thr */
			stackpos = uv->v - L2->stack;
			pi->writer(pi->L, &stackpos, sizeof(size_t), pi->ud);
		}
					/* perms reftbl ... thr */
		lua_pushnil(pi->L);
					/* perms reftbl ... thr nil */
		persist(pi);
		lua_pop(pi->L, 1);
					/* perms reftbl ... thr */
	}
					/* perms reftbl ... thr */
}
示例#29
0
/*!
 Prepares a Lua state for, and catches errors from, CorsixTH_lua_main(). By
 executing in Lua mode as soon as possible, errors can be nicely caught
 sooner, hence this function does as little as possible and leaves the rest
 for CorsixTH_lua_main().
 */
int SDL_main(int argc, char** argv, JNIEnv* env) {
	jEnv = env;
	/*
	 char dir[255];
	 getcwd(dir,sizeof(dir));

	 LOGI(dir);
	 */
	struct compile_time_lua_check {
		// Lua 5.1, not 5.0, is required
		int lua_5_point_1_required[LUA_VERSION_NUM >= 501 ? 1 : -1];

		// Lua numbers must be doubles so that the mantissa has at least
		// 32 bits (floats only have 24 bits)
		int number_is_double[types_equal<lua_Number, double>::result];
	};

	bool bRun = true;

	while (bRun) {
		lua_State *L = NULL;

		L = luaL_newstate();

		if (L == NULL) {
			fprintf(stderr, "Fatal error starting CorsixTH: "
					"Cannot open Lua state.\n");
			return 0;
		}
		lua_atpanic(L, CorsixTH_lua_panic);
		luaL_openlibs(L);
		lua_register(L, "showkeyboard", showkeyboard);
		lua_register(L, "hidekeyboard", hidekeyboard);
		lua_settop(L, 0);
		lua_pushcfunction(L, CorsixTH_lua_stacktrace);
		lua_pushcfunction(L, CorsixTH_lua_main);

		// Move command line parameters onto the Lua stack
		lua_checkstack(L, argc);
		for (int i = 0; i < argc; ++i) {
			lua_pushstring(L, argv[i]);
		}

		if (lua_pcall(L, argc, 0, 1) != 0) {
			const char* err = lua_tostring(L, -1);
			if (err != NULL) {
				fprintf(stderr, "%s\n", err);
			} else {
				fprintf(stderr, "An error has occured in CorsixTH:\n"
						"Uncaught non-string Lua error\n");
			}
			lua_pushcfunction(L, Bootstrap_lua_error_report);
			lua_insert(L, -2);
			if (lua_pcall(L, 1, 0, 0) != 0) {
				fprintf(stderr, "%s\n", lua_tostring(L, -1));
			}
		}

		lua_getfield(L, LUA_REGISTRYINDEX, "_RESTART");
		bRun = lua_toboolean(L, -1) != 0;

		// Get cleanup functions out of the Lua state (but don't run them yet)
		std::stack<void(*)(void)> stkCleanup;
		lua_getfield(L, LUA_REGISTRYINDEX, "_CLEANUP");
		if (lua_type(L, -1) == LUA_TTABLE) {
			for (unsigned int i = 1; i <= lua_objlen(L, -1); ++i) {
				lua_rawgeti(L, -1, (int) i);
				stkCleanup.push((void(*)(void))lua_touserdata(L, -1));lua_pop
				(L, 1);
			}
		}

		lua_close(L);

		// The cleanup functions are executed _after_ the Lua state is fully
		// closed, and in reserve order to that in which they were registered.
		while (!stkCleanup.empty()) {
			if (stkCleanup.top() != NULL)
				stkCleanup.top()();
			stkCleanup.pop();
		}

		if (bRun) {
			printf("Restarting...\n");
		}
	}
	return 0;
}
示例#30
0
/* Top-level delegating persist function
 */
static void persist(PersistInfo *pi)
{
					/* perms reftbl ... obj */
	lua_checkstack(pi->L, 2);
	/* If the object has already been written, write a reference to it */
	lua_pushvalue(pi->L, -1);
					/* perms reftbl ... obj obj */
	lua_rawget(pi->L, 2);
					/* perms reftbl ... obj ref? */
	if(!lua_isnil(pi->L, -1)) {
					/* perms reftbl ... obj ref */
		int zero = 0;
		int ref = (int)lua_touserdata(pi->L, -1);
		pi->writer(pi->L, &zero, sizeof(int), pi->ud);
		pi->writer(pi->L, &ref, sizeof(int), pi->ud);
		lua_pop(pi->L, 1);
					/* perms reftbl ... obj ref */
#ifdef PLUTO_DEBUG
		printindent(pi->level);
		printf("0 %d\n", ref);
#endif
		return;
	}
					/* perms reftbl ... obj nil */
	lua_pop(pi->L, 1);
					/* perms reftbl ... obj */
	/* If the object is nil, write the pseudoreference 0 */
	if(lua_isnil(pi->L, -1)) {
		int zero = 0;
		/* firsttime */
		pi->writer(pi->L, &zero, sizeof(int), pi->ud);
		/* ref */
		pi->writer(pi->L, &zero, sizeof(int), pi->ud);
#ifdef PLUTO_DEBUG
		printindent(pi->level);
		printf("0 0\n");
#endif
		return;
	}
	{
		/* indicate that it's the first time */
		int one = 1;
		pi->writer(pi->L, &one, sizeof(int), pi->ud);
	}
	lua_pushvalue(pi->L, -1);
					/* perms reftbl ... obj obj */
	lua_pushlightuserdata(pi->L, (void*)(++(pi->counter)));
					/* perms reftbl ... obj obj ref */
	lua_rawset(pi->L, 2);
					/* perms reftbl ... obj */

	pi->writer(pi->L, &pi->counter, sizeof(int), pi->ud);


	/* At this point, we'll give the permanents table a chance to play. */
	{
		lua_pushvalue(pi->L, -1);
					/* perms reftbl ... obj obj */
		lua_gettable(pi->L, 1);
					/* perms reftbl ... obj permkey? */
		if(!lua_isnil(pi->L, -1)) {
					/* perms reftbl ... obj permkey */
			int type = PLUTO_TPERMANENT;
#ifdef PLUTO_DEBUG
			printindent(pi->level);
			printf("1 %d PERM\n", pi->counter);
			pi->level++;
#endif
			pi->writer(pi->L, &type, sizeof(int), pi->ud);
			persist(pi);
			lua_pop(pi->L, 1);
					/* perms reftbl ... obj */
#ifdef PLUTO_DEBUG
			pi->level--;
#endif
			return;
		} else {
					/* perms reftbl ... obj nil */
			lua_pop(pi->L, 1);
					/* perms reftbl ... obj */
		}
					/* perms reftbl ... obj */
	}
	{
		int type = lua_type(pi->L, -1);
		pi->writer(pi->L, &type, sizeof(int), pi->ud);

#ifdef PLUTO_DEBUG
		printindent(pi->level);
		printf("1 %d %d\n", pi->counter, type);
		pi->level++;
#endif
	}

	switch(lua_type(pi->L, -1)) {
		case LUA_TBOOLEAN:
			persistboolean(pi);
			break;
		case LUA_TLIGHTUSERDATA:
			persistlightuserdata(pi);
			break;
		case LUA_TNUMBER:
			persistnumber(pi);
			break;
		case LUA_TSTRING:
			persiststring(pi);
			break;
		case LUA_TTABLE:
			persisttable(pi);
			break;
		case LUA_TFUNCTION:
			persistfunction(pi);
			break;
		case LUA_TTHREAD:
			persistthread(pi);
			break;
		case LUA_TPROTO:
			persistproto(pi);
			break;
		case LUA_TUPVAL:
			persistupval(pi);
			break;
		case LUA_TUSERDATA:
			persistuserdata(pi);
			break;
		default:
			lua_assert(0);
	}
#ifdef PLUTO_DEBUG
	pi->level--;
#endif
}