Beispiel #1
0
/** Check if stack value is a C function.
 * @param idx stack index of value
 * @return true if value is a C function, false otherwise
 */
bool
LuaContext::is_cfunction(int idx)
{
  return lua_iscfunction(__L, idx);
}
Beispiel #2
0
/* Class index function
	* If the object is a userdata (ie, an object), it searches the field in
	* the alternative table stored in the corresponding "ubox" table.
*/
static int class_index_event (lua_State* L)
{
 int t = lua_type(L,1);
	if (t == LUA_TUSERDATA)
	{
		/* Access alternative table */
		#ifdef LUA_VERSION_NUM /* new macro on version 5.1 */
		lua_getfenv(L,1);
		if (!lua_rawequal(L, -1, TOLUA_NOPEER)) {
			lua_pushvalue(L, 2); /* key */
			lua_gettable(L, -2); /* on lua 5.1, we trade the "tolua_peers" lookup for a gettable call */
			if (!lua_isnil(L, -1))
				return 1;
		};
		#else
		lua_pushstring(L,"tolua_peers");
		lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: obj key ubox */
		lua_pushvalue(L,1);
		lua_rawget(L,-2);                       /* stack: obj key ubox ubox[u] */
		if (lua_istable(L,-1))
		{
			lua_pushvalue(L,2);  /* key */
			lua_rawget(L,-2);                      /* stack: obj key ubox ubox[u] value */
			if (!lua_isnil(L,-1))
				return 1;
		}
		#endif
		lua_settop(L,2);                        /* stack: obj key */
		/* Try metatables */
		lua_pushvalue(L,1);                     /* stack: obj key obj */
		while (lua_getmetatable(L,-1))
		{                                       /* stack: obj key obj mt */
			lua_remove(L,-2);                      /* stack: obj key mt */
			if (lua_isnumber(L,2))                 /* check if key is a numeric value */
			{
				/* try operator[] */
				lua_pushstring(L,".geti");
				lua_rawget(L,-2);                      /* stack: obj key mt func */
				if (lua_isfunction(L,-1))
				{
					lua_pushvalue(L,1);
					lua_pushvalue(L,2);
					lua_call(L,2,1);
					return 1;
				}
			}
			else
			{
			 lua_pushvalue(L,2);                    /* stack: obj key mt key */
				lua_rawget(L,-2);                      /* stack: obj key mt value */
				if (!lua_isnil(L,-1))
					return 1;
				else
					lua_pop(L,1);
				/* try C/C++ variable */
				lua_pushstring(L,".get");
				lua_rawget(L,-2);                      /* stack: obj key mt tget */
				if (lua_istable(L,-1))
				{
					lua_pushvalue(L,2);
					lua_rawget(L,-2);                      /* stack: obj key mt value */
					if (lua_iscfunction(L,-1))
					{
						lua_pushvalue(L,1);
						lua_pushvalue(L,2);
						lua_call(L,2,1);
						return 1;
					}
					else if (lua_istable(L,-1))
					{
						/* deal with array: create table to be returned and cache it in ubox */
						void* u = *((void**)lua_touserdata(L,1));
						lua_newtable(L);                /* stack: obj key mt value table */
						lua_pushstring(L,".self");
						lua_pushlightuserdata(L,u);
						lua_rawset(L,-3);               /* store usertype in ".self" */
						lua_insert(L,-2);               /* stack: obj key mt table value */
						lua_setmetatable(L,-2);         /* set stored value as metatable */
						lua_pushvalue(L,-1);            /* stack: obj key met table table */
						lua_pushvalue(L,2);             /* stack: obj key mt table table key */
						lua_insert(L,-2);               /*  stack: obj key mt table key table */
						storeatubox(L,1);               /* stack: obj key mt table */
						return 1;
					}
				}
			}
			lua_settop(L,3);
		}
		lua_pushnil(L);
		return 1;
	}
	else if (t== LUA_TTABLE)
	{
		module_index_event(L);
		return 1;
	}
	lua_pushnil(L);
	return 1;
}
Beispiel #3
0
lua_CFunction lua_getcfunction(lua_Object object) {
	if (!lua_iscfunction(object))
		return NULL;
	else
		return fvalue(luaA_protovalue(Address(object)));
}
int
ngx_http_lua_coroutine_create_helper(lua_State *L, ngx_http_request_t **pr,
    ngx_http_lua_ctx_t **pctx, ngx_http_lua_co_ctx_t **pcoctx)
{
    lua_State                     *mt;  /* the main thread */
    lua_State                     *co;  /* new coroutine to be created */
    ngx_http_request_t            *r;
    ngx_http_lua_main_conf_t      *lmcf;
    ngx_http_lua_ctx_t            *ctx;
    ngx_http_lua_co_ctx_t         *coctx; /* co ctx for the new coroutine */

    luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
                 "Lua function expected");

    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
    lua_rawget(L, LUA_GLOBALSINDEX);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (r == NULL) {
        return luaL_error(L, "no request found");
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (ctx == NULL) {
        return luaL_error(L, "no request ctx found");
    }

    ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
                               | NGX_HTTP_LUA_CONTEXT_ACCESS
                               | NGX_HTTP_LUA_CONTEXT_CONTENT);

    lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
    mt = lmcf->lua;

    /* create new coroutine on root Lua state, so it always yields
     * to main Lua thread
     */
    co = lua_newthread(mt);

    ngx_http_lua_probe_user_coroutine_create(r, L, co);

    coctx = ngx_http_lua_create_co_ctx(r, ctx);
    if (coctx == NULL) {
        return luaL_error(L, "out of memory");
    }

    coctx->co = co;
    coctx->co_status = NGX_HTTP_LUA_CO_SUSPENDED;

    /* make new coroutine share globals of the parent coroutine.
     * NOTE: globals don't have to be separated! */
    lua_pushvalue(L, LUA_GLOBALSINDEX);
    lua_xmove(L, co, 1);
    lua_replace(co, LUA_GLOBALSINDEX);

    lua_xmove(mt, L, 1);    /* move coroutine from main thread to L */

    lua_pushvalue(L, 1);    /* copy entry function to top of L*/
    lua_xmove(L, co, 1);    /* move entry function from L to co */

    if (pcoctx) {
        *pcoctx = coctx;
    }

    if (pctx) {
        *pctx = ctx;
    }

    if (pr) {
        *pr = r;
    }

    return 1;    /* return new coroutine to Lua */
}
Beispiel #5
0
/* Class index function
	* If the object is a userdata (ie, an object), it searches the field in 
	* the alternative table stored in the corresponding "peer" table.
*/
static int class_index_event (lua_State* L)
{
  int t = lua_type(L,1);
	if (t == LUA_TUSERDATA)
	{
		/* Access alternative table */
		lua_pushstring(L,"tolua_peer");
		lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: obj key peer */
		lua_pushvalue(L,1);
		lua_rawget(L,-2);                       /* stack: obj key peer peer[u] */
		if (lua_istable(L,-1))
		{
			lua_pushvalue(L,2);  /* key */
			lua_rawget(L,-2);                      /* stack: obj key peer peer[u] value */
			if (!lua_isnil(L,-1))
				return 1;
		}
		lua_settop(L,2);                        /* stack: obj key */
		/* Try metatables */
		lua_pushvalue(L,1);                     /* stack: obj key obj */
		while (lua_getmetatable(L,-1))
		{                                       /* stack: obj key obj mt */
			lua_remove(L,-2);                      /* stack: obj key mt */
			if (lua_isnumber(L,2))                 /* check if key is a numeric value */
			{
				/* try operator[] */
				lua_pushstring(L,".geti");    
				lua_rawget(L,-2);                      /* stack: obj key mt func */
				if (lua_isfunction(L,-1))
				{
					lua_pushvalue(L,1);
					lua_pushvalue(L,2);
					lua_call(L,2,1);
					return 1;
				}
   }
			else
			{
			 lua_pushvalue(L,2);                    /* stack: obj key mt key */
				lua_rawget(L,-2);                      /* stack: obj key mt value */
				if (!lua_isnil(L,-1))
					return 1;
				else
					lua_pop(L,1);
				/* try C/C++ variable */
				lua_pushstring(L,".get");    
				lua_rawget(L,-2);                      /* stack: obj key mt tget */
				if (lua_istable(L,-1))
				{
					lua_pushvalue(L,2);
					lua_rawget(L,-2);                      /* stack: obj key mt value */
					if (lua_iscfunction(L,-1))
					{
						lua_pushvalue(L,1);
						lua_pushvalue(L,2); 
						lua_call(L,2,1);
						return 1;
					}
					else if (lua_istable(L,-1))
					{
						/* deal with array: create table to be returned and cache it in peer */
						void* u = *((void**)lua_touserdata(L,1));
						lua_newtable(L);                /* stack: obj key mt value table */
						lua_pushstring(L,".self");
						lua_pushlightuserdata(L,u);
						lua_rawset(L,-3);               /* store usertype in ".self" */
						lua_insert(L,-2);               /* stack: obj key mt table value */
						lua_setmetatable(L,-2);         /* set stored value as metatable */
						lua_pushvalue(L,-1);            /* stack: obj key met table table */
						lua_pushvalue(L,2);             /* stack: obj key mt table table key */
						lua_insert(L,-2);               /*  stack: obj key mt table key table */
						storeatpeer(L,1);               /* stack: obj key mt table */
						return 1;
					}
				}
			}
			lua_settop(L,3);
		}
		lua_pushnil(L);
		return 1;
	}
	else if (t== LUA_TTABLE)
	{
		module_index_event(L);
		return 1;
	}
	lua_pushnil(L);
	return 1;
}
Beispiel #6
0
int LuaUtils_Introduce(lua_State *L)
{
  int n = LuaUtils_CheckParameter2(L, 1, 2, LuaUtils_IntroduceUsage);
  if (!lua_istable(L, 1))
    return LuaUtils_Error(L, "Not a table");

  if (n >= 2) {

    bool found = false;
    lua_pushstring(L, "__intrinsic");
    lua_gettable(L, -3);

    if (lua_islightuserdata(L, -1)) {

      const RegisterItem *items = lua_touserdata(L, -1);
      const char *library = items[0].name;
      const char *function = lua_tostring(L, 2);
      const char *usage = 0;

      for (const RegisterItem *item = items + 1; item->type; item++) {
        if (strcmp(function, "introduce") == 0)
          usage = LuaUtils_IntroduceUsage;
        if (strcmp(function, item->name) == 0)
          usage = item->usage;
        if (usage)
          break;
      }
      if (usage) {
        luaL_Buffer buffer;
        luaL_buffinit(L, &buffer);
        ExpandUsageToBuffer(&buffer, usage, library, function);
        luaL_pushresult(&buffer);
      } else {
        lua_pushstring(L, function);
        lua_gettable(L, -4);
        if (lua_isfunction(L, -1) && !lua_iscfunction(L, -1)) {
          Proto *proto = ((LClosure*) lua_topointer(L, -1))->p;
          luaL_Buffer buffer;
          luaL_buffinit(L, &buffer);
          luaL_addstring(&buffer, "[\"");
          luaL_addstring(&buffer, library);
          luaL_addchar(&buffer, '.');
          luaL_addstring(&buffer, function);
          luaL_addchar(&buffer, '(');
          for (uint16_t i = 0; i < proto->numparams; i++) {
            if (i) luaL_addchar(&buffer, ',');
            luaL_addstring(&buffer, getstr(proto->locvars[i].varname));
          }
          if (proto->is_vararg) {
            if (proto->numparams) luaL_addchar(&buffer, ',');
            luaL_addstring(&buffer, "...");
          }
          luaL_addstring(&buffer, ")\"]");
          luaL_pushresult(&buffer);
        } else
          lua_pushstring(L, "<unknown>");
      }
    }

  } else {

    luaL_Buffer buffer;
    luaL_buffinit(L, &buffer);
    luaL_addchar(&buffer, '[');

    uint16_t i = 0;
    {
      lua_pushnil(L);
      while (lua_next(L, -2)) {

        switch (lua_type(L, -1)) {

          case LUA_TBOOLEAN :
            // {"name":boolean},
            if (i++)
              luaL_addchar(&buffer, ',');
            luaL_addstring(&buffer, "{\"");
            luaL_addstring(&buffer, lua_tostring(L, -2));
            luaL_addstring(&buffer, "\":");
            luaL_addstring(&buffer, lua_toboolean(L, -1) ? "true" : "false");
            luaL_addchar(&buffer, '}');
            break;

          case LUA_TNUMBER :
            // {"name":number},
            if (i++)
              luaL_addchar(&buffer, ',');
            luaL_addstring(&buffer, "{\"");
            luaL_addstring(&buffer, lua_tostring(L, -2));
            luaL_addstring(&buffer, "\":");
            luaL_addstring(&buffer, lua_tostring(L, -1));
            luaL_addchar(&buffer, '}');
            break;

          case LUA_TUSERDATA :
          case LUA_TLIGHTUSERDATA :
            // "name",
            if (i++)
              luaL_addchar(&buffer, ',');
            luaL_addchar(&buffer, '"');
            luaL_addstring(&buffer, lua_tostring(L, -2));
            luaL_addchar(&buffer, '"');
            break;

        }
        lua_pop(L, 1);
      }
    }
    {
      lua_pushnil(L);
      while (lua_next(L, -2)) {
        if (lua_type(L, -1) == LUA_TFUNCTION) {
          // "name()",
          if (i++)
            luaL_addchar(&buffer, ',');
          luaL_addchar(&buffer, '"');
          luaL_addstring(&buffer, lua_tostring(L, -2));
          luaL_addstring(&buffer, "()\""); // TODO Hier "Usage"
        }
        lua_pop(L, 1);
      }
    }
    {
      lua_pushnil(L);
      while (lua_next(L, -2)) {
        if (lua_type(L, -1) == LUA_TTABLE) {
          // "name",
          if (i++)
            luaL_addchar(&buffer, ',');
          luaL_addchar(&buffer, '"');
          luaL_addstring(&buffer, lua_tostring(L, -2));
          luaL_addstring(&buffer, ".*\"");
        }
        lua_pop(L, 1);
      }
    }
    luaL_addchar(&buffer, ']');
    luaL_pushresult(&buffer);

  }
  return 1;
}
Beispiel #7
0
MethodBase *LSProfiler::getTopMethod(lua_State *L)
{
    int       top = lua_gettop(L);
    lua_Debug stack;

    // if we get a null result here, we are out of stack
    if (!lua_getstack(L, 0, &stack))
    {
        lua_settop(L, top);
        return NULL;
    }

    if (!lua_getinfo(L, "f", &stack))
    {
        lua_settop(L, top);
        return NULL;
    }

    bool iscfunc = false;
    if (lua_iscfunction(L, -1))
    {
        iscfunc = true;
    }


#ifdef LOOM_ENABLE_JIT
    // We do not receive line return hooks for native calls under JIT :(
    // So, if we want to profile native methods, we need to be under interpreted VM
    if (iscfunc)
    {
        lua_settop(L, top);
        return NULL;
    }
#endif


    lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMETHODLOOKUP);
    lua_pushvalue(L, -2);
    lua_rawget(L, -2);

    if (lua_isnil(L, -1))
    {
        lua_settop(L, top);
        return NULL;
    }

    MethodBase *methodBase = (MethodBase *)lua_topointer(L, -1);

    lua_settop(L, top);

    if (iscfunc && !methodBase->isNative())
    {
        return NULL;
    }

    if (shouldFilterFunction(methodBase->getFullMemberName()))
    {
        return NULL;
    }

    return methodBase;
}
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");
  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;
}
int
ngx_http_lua_coroutine_create_helper(lua_State *L, ngx_http_request_t *r,
    ngx_http_lua_ctx_t *ctx, ngx_http_lua_co_ctx_t **pcoctx)
{
    lua_State                     *vm;  /* the Lua VM */
    lua_State                     *co;  /* new coroutine to be created */
    ngx_http_lua_co_ctx_t         *coctx; /* co ctx for the new coroutine */

    luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
                  "Lua function expected");

    ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
                               | NGX_HTTP_LUA_CONTEXT_ACCESS
                               | NGX_HTTP_LUA_CONTEXT_CONTENT
                               | NGX_HTTP_LUA_CONTEXT_TIMER
                               | NGX_HTTP_LUA_CONTEXT_SSL_CERT);

    vm = ngx_http_lua_get_lua_vm(r, ctx);

    /* create new coroutine on root Lua state, so it always yields
     * to main Lua thread
     */
    co = lua_newthread(vm);

    ngx_http_lua_probe_user_coroutine_create(r, L, co);

    coctx = ngx_http_lua_get_co_ctx(co, ctx);
    if (coctx == NULL) {
        coctx = ngx_http_lua_create_co_ctx(r, ctx);
        if (coctx == NULL) {
            return luaL_error(L, "no memory");
        }

    } else {
        ngx_memzero(coctx, sizeof(ngx_http_lua_co_ctx_t));
        coctx->co_ref = LUA_NOREF;
    }

    coctx->co = co;
    coctx->co_status = NGX_HTTP_LUA_CO_SUSPENDED;

    /* make new coroutine share globals of the parent coroutine.
     * NOTE: globals don't have to be separated! */
    ngx_http_lua_get_globals_table(L);
    lua_xmove(L, co, 1);
    ngx_http_lua_set_globals_table(co);

    lua_xmove(vm, L, 1);    /* move coroutine from main thread to L */

    lua_pushvalue(L, 1);    /* copy entry function to top of L*/
    lua_xmove(L, co, 1);    /* move entry function from L to co */

    if (pcoctx) {
        *pcoctx = coctx;
    }

#ifdef NGX_LUA_USE_ASSERT
    coctx->co_top = 1;
#endif

    return 1;    /* return new coroutine to Lua */
}
Beispiel #10
0
int NativeDelegate::__op_minusassignment(lua_State *L)
{
    NativeDelegate *delegate = (NativeDelegate *)lualoom_getnativepointer(L, 1,
                                                                          "system.NativeDelegate");

    if (!delegate)
    {
        LSError("Unable to get native delegate on += operator");
    }

    if (!delegate->_callbackCount)
    {
        return 0;
    }

    delegate->setVM(L);

    delegate->getCallbacks(L);

    int tidx = lua_gettop(L);

    if (!lua_istable(L, tidx))
    {
        LSError("Bad native delegates table");
    }

    if (lua_isfunction(L, 2) || lua_iscfunction(L, 2))
    {
        int idx = -1;
        for (int i = 0; i < delegate->_callbackCount; i++)
        {
            lua_rawgeti(L, tidx, i);
            if (lua_equal(L, 2, -1))
            {
                idx = i;
                lua_pop(L, 1);
                break;
            }
            lua_pop(L, 1);
        }


        // this function was never added in the first place
        if (idx == -1)
        {
            return 0;
        }

        // shift the other delegates down
        lua_pushnumber(L, (double)idx);
        lua_pushnil(L);
        lua_settable(L, tidx);

        int ntable = 0;
        if (delegate->_callbackCount > 1)
        {
            // temp table
            lua_newtable(L);
            ntable = lua_gettop(L);

            int c = 0;
            for (int nidx = 0; nidx < delegate->_callbackCount; nidx++)
            {
                lua_pushnumber(L, (double)nidx);
                lua_gettable(L, tidx);
                if (lua_isnil(L, -1))
                {
                    lua_pop(L, 1);
                    continue;
                }

                lua_pushnumber(L, (double)c);
                lua_pushvalue(L, -2);
                lua_settable(L, ntable);
                // pop lua_function
                lua_pop(L, 1);
                c++;
            }
        }

        // clear it
        delegate->_callbackCount--;

        // and copy from new temp table
        for (int nidx = 0; nidx < delegate->_callbackCount; nidx++)
        {
            lua_pushnumber(L, (double)nidx);
            lua_pushnumber(L, (double)nidx);
            lua_gettable(L, ntable);
            lua_settable(L, tidx);
        }
    }
    else
    {
        LSError("Unknown type on NativeDelegate -= operator");
    }

    return 0;
}
Beispiel #11
0
bool LuaInterface::isCFunction(int index)
{
    assert(hasIndex(index));
    return lua_iscfunction(L, index);
}
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);
}
Beispiel #13
0
 bool Environment::isCFunction(int index) {
     return lua_iscfunction(L, index);
 }
Beispiel #14
0
void ShipType::Init()
{
	static bool isInitted = false;
	if (isInitted)
		return;
	isInitted = true;

	// load all ship definitions
	namespace fs = FileSystem;
	for (fs::FileEnumerator files(fs::gameDataFiles, "ships", fs::FileEnumerator::Recurse); !files.Finished(); files.Next()) {
		const fs::FileInfo &info = files.Current();
		if (ends_with_ci(info.GetPath(), ".json")) {
			const std::string id(info.GetName().substr(0, info.GetName().size()-5));
			try {
				ShipType st = ShipType(id, info.GetPath());
				types.insert(std::make_pair(st.id, st));

				// assign the names to the various lists
				switch( st.tag ) {
				case TAG_SHIP:				player_ships.push_back(id);				break;
				case TAG_STATIC_SHIP:		static_ships.push_back(id);				break;
				case TAG_MISSILE:			missile_ships.push_back(id);			break;
					break;
				case TAG_NONE:
				default:
					break;
				}
			} catch (ShipTypeLoadError) {
				// TODO: Actual error handling would be nice.
				Error("Error while loading Ship data (check stdout/output.txt).\n");
			}
		}
	}

#if ALLOW_LUA_SHIP_DEF
	lua_State *l = luaL_newstate();

	LUA_DEBUG_START(l);

	luaL_requiref(l, "_G", &luaopen_base, 1);
	luaL_requiref(l, LUA_DBLIBNAME, &luaopen_debug, 1);
	luaL_requiref(l, LUA_MATHLIBNAME, &luaopen_math, 1);
	lua_pop(l, 3);

	LuaConstants::Register(l);
	LuaVector::Register(l);
	LUA_DEBUG_CHECK(l, 0);

	// provide shortcut vector constructor: v = vector.new
	lua_getglobal(l, LuaVector::LibName);
	lua_getfield(l, -1, "new");
	assert(lua_iscfunction(l, -1));
	lua_setglobal(l, "v");
	lua_pop(l, 1); // pop the vector library table

	LUA_DEBUG_CHECK(l, 0);

	// register ship definition functions
	lua_register(l, "define_ship", define_ship);
	lua_register(l, "define_static_ship", define_static_ship);
	lua_register(l, "define_missile", define_missile);

	LUA_DEBUG_CHECK(l, 0);

	// load all ship definitions
	namespace fs = FileSystem;
	for (fs::FileEnumerator files(fs::gameDataFiles, "ships", fs::FileEnumerator::Recurse); !files.Finished(); files.Next()) {
		const fs::FileInfo &info = files.Current();
		if (ends_with_ci(info.GetPath(), ".lua")) {
			const std::string name = info.GetName();
			s_currentShipFile = name.substr(0, name.size() - 4);
			if (ShipType::types.find(s_currentShipFile) == ShipType::types.end())
			{
				pi_lua_dofile(l, info.GetPath());
				s_currentShipFile.clear();
			}
		}
	}

	LUA_DEBUG_END(l, 0);

	lua_close(l);
#endif

	//remove unbuyable ships from player ship list
	ShipType::player_ships.erase(
		std::remove_if(ShipType::player_ships.begin(), ShipType::player_ships.end(), ShipIsUnbuyable),
		ShipType::player_ships.end());

	if (ShipType::player_ships.empty())
		Error("No playable ships have been defined! The game cannot run.");
}
Beispiel #15
0
void LSProfiler::getCurrentStack(lua_State *L, utStack<MethodBase *>& stack)
{
    int       top = lua_gettop(L);
    lua_Debug lstack;
    int       stackFrame = 0;

    MethodBase *lastMethod = NULL;

    while (true)
    {
        // if we get a null result here, we are out of stack
        if (!lua_getstack(L, stackFrame++, &lstack))
        {
            lua_settop(L, top);
            return;
        }

        // something bad in denmark
        if (!lua_getinfo(L, "f", &lstack))
        {
            lua_settop(L, top);
            return;
        }

        bool cfunc = false;
        if (lua_iscfunction(L, -1))
        {
            cfunc = true;
        }

        lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMETHODLOOKUP);
        lua_pushvalue(L, -2);
        lua_rawget(L, -2);

        if (lua_isnil(L, -1))
        {
            lua_settop(L, top);
            continue;
        }

        MethodBase *methodBase = (MethodBase *)lua_topointer(L, -1);

        lua_settop(L, top);

#ifdef LOOM_ENABLE_JIT
        // We do not receive line return hooks for native calls under JIT :(
        // So, don't add to initial stack
        if (cfunc)
        {
            continue;
        }
#endif


        if (shouldFilterFunction(methodBase->getFullMemberName()))
        {
            continue;
        }

        // we only want the root call, not the pcall wrapper
        if (cfunc && (lastMethod == methodBase))
        {
            continue;
        }

        lastMethod = methodBase;

        stack.push(methodBase);
    }
}
Beispiel #16
0
//*****************************************************************************
bool LuaUtils::TransferValueToStack(LuaStack    inStack,
                                    LuaStack    outStack,
                                    int         ntop,
                                    int         levels,
                                    const char *varname)
{
    if (levels < 0)
        return false;

    // convert relative to absolute indexing if necessary
    if (ntop < 0)
        ntop = (lua_gettop(inStack) + 1 + ntop);

    lua_newtable(outStack);

    // push variable name
    if (varname != NULL)
    {
        lua_pushstring(outStack, varname);
        lua_setfield(outStack, -2, "name");
    }

    // push the variable type
    int top_type = lua_type(inStack, ntop);
    lua_pushstring(outStack, lua_typename(inStack, top_type));
    lua_setfield(outStack, -2, "type");

    // finally push the value
    if (lua_isnil(inStack, ntop))
    {
        lua_pushnil(outStack);
        lua_setfield(outStack, -2, "value");
    }
    else if (lua_isboolean(inStack, ntop))
    {
        lua_pushboolean(outStack, lua_toboolean(inStack, ntop));
        lua_setfield(outStack, -2, "value");
    }
    else if (lua_isnumber(inStack, ntop))
    {
        lua_pushnumber(outStack, lua_tonumber(inStack, ntop));
        lua_setfield(outStack, -2, "value");
    }
    else if (lua_isstring(inStack, ntop))
    {
        lua_pushstring(outStack, lua_tostring(inStack, ntop));
        lua_setfield(outStack, -2, "value");
    }
    else if (lua_islightuserdata(inStack, ntop))
    {
        lua_pushlightuserdata(outStack, lua_touserdata(inStack, ntop));
        lua_setfield(outStack, -2, "value");
    }
    else if (lua_isuserdata(inStack, ntop)  ||
             lua_iscfunction(inStack, ntop) ||
             lua_isfunction(inStack, ntop)  ||
             lua_isthread(inStack, ntop))
    {
        lua_pushfstring(outStack, "%p", lua_topointer(inStack, ntop));
        lua_setfield(outStack, -2, "value");
    }
    else if (lua_istable(inStack, ntop))
    {
        if (levels == 0)
        {
            lua_pushboolean(outStack, true);
            lua_setfield(outStack, -2, "raw");

            // whether to send only a summary!
            lua_pushfstring(outStack, "%p", lua_topointer(inStack, ntop));
        }
        else
        {
            lua_newtable(outStack);

            int index = 1;

            lua_pushnil(inStack);
            while (lua_next(inStack, ntop) != 0)
            {
                // printf("%s - %s\n", lua_typename(inStack, lua_type(inStack, -2)), lua_typename(inStack, lua_type(inStack, -1)));

                int newtop      = lua_gettop(inStack);
                int keyindex    = newtop - 1;
                int valindex    = newtop;

                lua_pushinteger(outStack, index++);
                lua_newtable(outStack);

                // uses 'key' at index top-1 and 'value' at index top
                if (LuaUtils::TransferValueToStack(inStack, outStack, keyindex, 0))
                {
                    lua_setfield(outStack, -2, "key");

                    if (LuaUtils::TransferValueToStack(inStack, outStack, valindex, levels - 1))
                        lua_setfield(outStack, -2, "value");
                }

                lua_settable(outStack, -3);

                // remove 'value', keeps 'key' for next iteration
                lua_pop(inStack, 1);
            }
        }

        lua_setfield(outStack, -2, "value");
    }
    else
    {
        lua_pushstring(outStack, "Unknown type.");
        lua_setfield(outStack, -2, "value");
    }

    return true;
}
Beispiel #17
0
static int tek_lib_exec_run(lua_State *L)
{
	struct LuaExecTask *lexec = tek_lib_exec_check(L);
	struct TExecBase *TExecBase = lexec->exec;
	struct LuaExecChild *ctx;
	const char *fname = TNULL;
	const char *chunk = TNULL;
	const char *taskname = TNULL;
	size_t extralen = 0;
	struct THook hook;
	TTAGITEM tags[2];
	int nremove = 1;
	TBOOL abort = TTRUE;
	
	for (;;)
	{
		if (lua_istable(L, 1))
		{
			lua_getfield(L, 1, "abort");
			if (lua_isboolean(L, -1))
				abort = lua_toboolean(L, -1);
			lua_pop(L, 1);
			lua_getfield(L, 1, "taskname");
			taskname = lua_tostring(L, -1);
			nremove = 2;
			lua_getfield(L, 1, "func");
			if (!lua_isnoneornil(L, -1))
				break;
			lua_pop(L, 1);
			lua_getfield(L, 1, "filename");
			if (!lua_isnoneornil(L, -1))
				break;
			lua_pop(L, 1);
			lua_getfield(L, 1, "chunk");
			if (!lua_isnoneornil(L, -1))
			{
				chunk = luaL_checklstring(L, -1, &extralen);
				break;
			}
			luaL_error(L, "required argument missing");
		}
		lua_pushvalue(L, 1);
		break;
	}
	
	if (!chunk)
	{
		if (lua_type(L, -1) == LUA_TSTRING)
			fname = luaL_checklstring(L, -1, &extralen);
		else if (lua_isfunction(L, -1) && !lua_iscfunction(L, -1))
			chunk = tek_lib_exec_dump(L, &extralen);
		else
			luaL_error(L, "not a Lua function, filename or table");
	}
	
	ctx = lua_newuserdata(L, sizeof(struct LuaExecChild) + extralen + 1);
	memset(ctx, 0, sizeof *ctx);
	ctx->exec = lexec->exec;
	ctx->parent = lexec;
	ctx->taskname = tek_lib_exec_taskname(ctx->atomname, taskname);
	ctx->abort = abort;
	
	if (fname)
	{
		ctx->fname = (char *) (ctx + 1);
		strcpy(ctx->fname, (char *) fname);
	}
	else if (chunk)
	{
		memcpy(ctx + 1, chunk, extralen);
		ctx->chunklen = extralen;
	}
	
	/* remove arguments under userdata */
	while (nremove--)
		lua_remove(L, -2);

	ctx->numargs = lua_gettop(L) - 2;
	
	/* push arg[0] on the stack, will be extraarg */
	lua_getglobal(L, "arg");
	if (lua_istable(L, -1))
	{
		lua_rawgeti(L, -1, 0);
		lua_remove(L, -2);
	}
	if (lua_type(L, -1) != LUA_TSTRING)
	{
		lua_pop(L, 1);
		lua_pushnil(L);
	}
	ctx->args = tek_lib_exec_getargs(L, TExecBase, 2, ctx->numargs++, 1);
	lua_pop(L, 1);
	
	ctx->L = lua_newstate(tek_lib_exec_allocf, TExecBase);
	if (ctx->L == TNULL)
	{
		tek_lib_exec_freeargs(TExecBase, ctx->args, ctx->numargs);
		luaL_error(L, "cannot create interpreter");
	}
	
	tags[0].tti_Tag = TTask_UserData;
	tags[0].tti_Value = (TTAG) ctx;
	tags[1].tti_Tag = TTAG_DONE;
	TInitHook(&hook, tek_lib_exec_run_dispatch, ctx);
	ctx->task = TCreateTask(&hook, tags);
	if (ctx->task == TNULL)
	{
		tek_lib_exec_freectxargs(ctx);
		lua_pop(L, 1);
		lua_pushnil(L);
		return 1;
	}
	
	lua_getfield(L, LUA_REGISTRYINDEX, TEK_LIB_TASK_CLASSNAME);
	lua_setmetatable(L, -2);
	lua_pushvalue(L, -1);
	ctx->ref = luaL_ref(L, lua_upvalueindex(2));
	if (ctx->abort)
		tek_lib_exec_register_task_hook(L, TExecBase);
	return 1;
}
static int
ngx_http_lua_ngx_timer_at(lua_State *L)
{
    int                      nargs, co_ref;
    u_char                  *p;
    lua_State               *vm;  /* the main thread */
    lua_State               *co;
    ngx_msec_t               delay;
    ngx_event_t             *ev = NULL;
    ngx_http_request_t      *r;
    ngx_connection_t        *saved_c = NULL;
    ngx_http_lua_ctx_t      *ctx;
#if 0
    ngx_http_connection_t   *hc;
#endif

    ngx_http_lua_timer_ctx_t      *tctx = NULL;
    ngx_http_lua_main_conf_t      *lmcf;
#if 0
    ngx_http_core_main_conf_t     *cmcf;
#endif

    nargs = lua_gettop(L);
    if (nargs < 2) {
        return luaL_error(L, "expecting at least 2 arguments but got %d",
                          nargs);
    }

    delay = (ngx_msec_t) (luaL_checknumber(L, 1) * 1000);

    luaL_argcheck(L, lua_isfunction(L, 2) && !lua_iscfunction(L, 2), 2,
                  "Lua function expected");

    r = ngx_http_lua_get_req(L);
    if (r == NULL) {
        return luaL_error(L, "no request");
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);

    if (ngx_exiting && delay > 0) {
        lua_pushnil(L);
        lua_pushliteral(L, "process exiting");
        return 2;
    }

    lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);

    if (lmcf->pending_timers >= lmcf->max_pending_timers) {
        lua_pushnil(L);
        lua_pushliteral(L, "too many pending timers");
        return 2;
    }

    if (lmcf->watcher == NULL) {
        /* create the watcher fake connection */

        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
                       "lua creating fake watcher connection");

        if (ngx_cycle->files) {
            saved_c = ngx_cycle->files[0];
        }

        lmcf->watcher = ngx_get_connection(0, ngx_cycle->log);

        if (ngx_cycle->files) {
            ngx_cycle->files[0] = saved_c;
        }

        if (lmcf->watcher == NULL) {
            return luaL_error(L, "no memory");
        }

        /* to work around the -1 check in ngx_worker_process_cycle: */
        lmcf->watcher->fd = (ngx_socket_t) -2;

        lmcf->watcher->idle = 1;
        lmcf->watcher->read->handler = ngx_http_lua_abort_pending_timers;
        lmcf->watcher->data = lmcf;
    }

    vm = ngx_http_lua_get_lua_vm(r, ctx);

    co = lua_newthread(vm);

    /* L stack: time func [args] thread */

    ngx_http_lua_probe_user_coroutine_create(r, L, co);

    lua_createtable(co, 0, 0);  /* the new globals table */

    /* co stack: global_tb */

    lua_createtable(co, 0, 1);  /* the metatable */
    ngx_http_lua_get_globals_table(co);
    lua_setfield(co, -2, "__index");
    lua_setmetatable(co, -2);

    /* co stack: global_tb */

    ngx_http_lua_set_globals_table(co);

    /* co stack: <empty> */

    dd("stack top: %d", lua_gettop(L));

    lua_xmove(vm, L, 1);    /* move coroutine from main thread to L */

    /* L stack: time func [args] thread */
    /* vm stack: empty */

    lua_pushvalue(L, 2);    /* copy entry function to top of L*/

    /* L stack: time func [args] thread func */

    lua_xmove(L, co, 1);    /* move entry function from L to co */

    /* L stack: time func [args] thread */
    /* co stack: func */

    ngx_http_lua_get_globals_table(co);
    lua_setfenv(co, -2);

    /* co stack: func */

    lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key);
    lua_rawget(L, LUA_REGISTRYINDEX);

    /* L stack: time func [args] thread corountines */

    lua_pushvalue(L, -2);

    /* L stack: time func [args] thread coroutines thread */

    co_ref = luaL_ref(L, -2);
    lua_pop(L, 1);

    /* L stack: time func [args] thread */

    if (nargs > 2) {
        lua_pop(L, 1);  /* L stack: time func [args] */
        lua_xmove(L, co, nargs - 2);  /* L stack: time func */

        /* co stack: func [args] */
    }

    p = ngx_alloc(sizeof(ngx_event_t) + sizeof(ngx_http_lua_timer_ctx_t),
                  r->connection->log);
    if (p == NULL) {
        goto nomem;
    }

    ev = (ngx_event_t *) p;

    ngx_memzero(ev, sizeof(ngx_event_t));

    p += sizeof(ngx_event_t);

    tctx = (ngx_http_lua_timer_ctx_t *) p;

    tctx->premature = 0;
    tctx->co_ref = co_ref;
    tctx->co = co;
    tctx->main_conf = r->main_conf;
    tctx->srv_conf = r->srv_conf;
    tctx->loc_conf = r->loc_conf;
    tctx->lmcf = lmcf;

    tctx->pool = ngx_create_pool(128, ngx_cycle->log);
    if (tctx->pool == NULL) {
        goto nomem;
    }

    if (r->connection) {
        tctx->listening = r->connection->listening;

    } else {
        tctx->listening = NULL;
    }

    if (r->connection->addr_text.len) {
        tctx->client_addr_text.data = ngx_palloc(tctx->pool,
                                                 r->connection->addr_text.len);
        if (tctx->client_addr_text.data == NULL) {
            goto nomem;
        }

        ngx_memcpy(tctx->client_addr_text.data, r->connection->addr_text.data,
                   r->connection->addr_text.len);
        tctx->client_addr_text.len = r->connection->addr_text.len;

    } else {
        tctx->client_addr_text.len = 0;
        tctx->client_addr_text.data = NULL;
    }

    if (ctx && ctx->vm_state) {
        tctx->vm_state = ctx->vm_state;
        tctx->vm_state->count++;

    } else {
        tctx->vm_state = NULL;
    }

    ev->handler = ngx_http_lua_timer_handler;
    ev->data = tctx;
    ev->log = ngx_cycle->log;

    lmcf->pending_timers++;

    ngx_add_timer(ev, delay, NGX_FUNC_LINE);

    lua_pushinteger(L, 1);
    return 1;

nomem:

    if (tctx && tctx->pool) {
        ngx_destroy_pool(tctx->pool);
    }

    if (ev) {
        ngx_free(ev);
    }

    lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key);
    lua_rawget(L, LUA_REGISTRYINDEX);
    luaL_unref(L, -1, co_ref);

    return luaL_error(L, "no memory");
}
Beispiel #19
0
void ShipType::Init()
{
	static bool isInitted = false;
	if (isInitted) return;
	isInitted = true;

	lua_State *l = luaL_newstate();

	LUA_DEBUG_START(l);

	luaL_requiref(l, "_G", &luaopen_base, 1);
	luaL_requiref(l, LUA_DBLIBNAME, &luaopen_debug, 1);
	luaL_requiref(l, LUA_MATHLIBNAME, &luaopen_math, 1);
	lua_pop(l, 3);

	LuaConstants::Register(l);
	LuaVector::Register(l);
	LUA_DEBUG_CHECK(l, 0);

	// provide shortcut vector constructor: v = vector.new
	lua_getglobal(l, LuaVector::LibName);
	lua_getfield(l, -1, "new");
	assert(lua_iscfunction(l, -1));
	lua_setglobal(l, "v");
	lua_pop(l, 1); // pop the vector library table

	LUA_DEBUG_CHECK(l, 0);

	// register ship definition functions
	lua_register(l, "define_ship", define_ship);
	lua_register(l, "define_static_ship", define_static_ship);
	lua_register(l, "define_missile", define_missile);

	LUA_DEBUG_CHECK(l, 0);

	// load all ship definitions
	namespace fs = FileSystem;
	for (fs::FileEnumerator files(fs::gameDataFiles, "ships", fs::FileEnumerator::Recurse);
			!files.Finished(); files.Next()) {
		const fs::FileInfo &info = files.Current();
		if (ends_with(info.GetPath(), ".lua")) {
			const std::string name = info.GetName();
			s_currentShipFile = name.substr(0, name.size()-4);
			pi_lua_dofile(l, info.GetPath());
			s_currentShipFile.clear();
		}
	}

	LUA_DEBUG_END(l, 0);

	lua_close(l);

	//remove unbuyable ships from player ship list
	ShipType::player_ships.erase(
		std::remove_if(ShipType::player_ships.begin(), ShipType::player_ships.end(), ShipIsUnbuyable),
		ShipType::player_ships.end());

	if (ShipType::player_ships.empty())
		Error("No playable ships have been defined! The game cannot run.");

	//collect ships that can fit atmospheric shields
	for (std::vector<ShipType::Id>::const_iterator it = ShipType::player_ships.begin();
		it != ShipType::player_ships.end(); ++it) {
		const ShipType &ship = ShipType::types[*it];
		if (ship.equipSlotCapacity[Equip::SLOT_ATMOSHIELD] != 0)
			ShipType::playable_atmospheric_ships.push_back(*it);
	}

	if (ShipType::playable_atmospheric_ships.empty())
		Error("No ships can fit atmospheric shields! The game cannot run.");
}
Beispiel #20
0
lsb_err_value lsb_init(lsb_lua_sandbox *lsb, const char *state_file)
{
  if (!lsb) {
    return LSB_ERR_UTIL_NULL;
  }

  if (lsb->state != LSB_UNKNOWN) {
    lsb_terminate(lsb, LSB_ERR_INIT);
    return LSB_ERR_INIT;
  }

  if (state_file && strlen(state_file) > 0) {
    lsb->state_file = malloc(strlen(state_file) + 1);
    if (!lsb->state_file) {
      lsb_terminate(lsb, LSB_ERR_UTIL_OOM);
      return LSB_ERR_UTIL_OOM;
    }
    strcpy(lsb->state_file, state_file);
  }

#ifndef LUA_JIT
  size_t mem_limit = lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT];
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = 0;
#endif

  preload_modules(lsb->lua);
  // load package module
  lua_pushcfunction(lsb->lua, luaopen_package);
  lua_pushstring(lsb->lua, LUA_LOADLIBNAME);
  lua_call(lsb->lua, 1, 1);
  lua_newtable(lsb->lua);
  lua_setmetatable(lsb->lua, -2);
  lua_pop(lsb->lua, 1);

  // load base module
  lua_getglobal(lsb->lua, "require");
  if (!lua_iscfunction(lsb->lua, -1)) {
    snprintf(lsb->error_message, LSB_ERROR_SIZE,
             "lsb_init() 'require' not found");
    lsb_terminate(lsb, NULL);
    return LSB_ERR_LUA;
  }
  lua_pushstring(lsb->lua, LUA_BASELIBNAME);
  if (lua_pcall(lsb->lua, 1, 0, 0)) {
    snprintf(lsb->error_message, LSB_ERROR_SIZE,
             "lsb_init %s", lua_tostring(lsb->lua, -1));
    lsb_terminate(lsb, NULL);
    return LSB_ERR_LUA;
  }

  if (lsb->usage[LSB_UT_INSTRUCTION][LSB_US_LIMIT] != 0) {
    lua_sethook(lsb->lua, instruction_manager, LUA_MASKCOUNT,
                (int)lsb->usage[LSB_UT_INSTRUCTION][LSB_US_LIMIT]);
  } else {
    lua_sethook(lsb->lua, NULL, 0, 0);
  }
#ifdef LUA_JIT
  // todo limit
  lua_gc(lsb->lua, LUA_GCSETMEMLIMIT,
         (int)lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT]);
#else
  lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = mem_limit;
#endif
  lua_CFunction pf = lua_atpanic(lsb->lua, unprotected_panic);
  int jump = setjmp(g_jbuf);
  if (jump || luaL_dofile(lsb->lua, lsb->lua_file) != 0) {
    int len = snprintf(lsb->error_message, LSB_ERROR_SIZE, "%s",
                       lua_tostring(lsb->lua, -1));
    if (len >= LSB_ERROR_SIZE || len < 0) {
      lsb->error_message[LSB_ERROR_SIZE - 1] = 0;
    }
    lsb_terminate(lsb, NULL);
    return LSB_ERR_LUA;
  } else {
    lua_gc(lsb->lua, LUA_GCCOLLECT, 0);
    lsb->usage[LSB_UT_INSTRUCTION][LSB_US_CURRENT] = instruction_usage(lsb);
    if (lsb->usage[LSB_UT_INSTRUCTION][LSB_US_CURRENT]
        > lsb->usage[LSB_UT_INSTRUCTION][LSB_US_MAXIMUM]) {
      lsb->usage[LSB_UT_INSTRUCTION][LSB_US_MAXIMUM] =
          lsb->usage[LSB_UT_INSTRUCTION][LSB_US_CURRENT];
    }
    lsb->state = LSB_RUNNING;
    if (lsb->state_file) {
      lsb_err_value ret = restore_global_data(lsb);
      if (ret) return ret;
    }
  }
  lua_atpanic(lsb->lua, pf);
  return NULL;
}
Beispiel #21
0
/* Newindex function
    * It first searches for a C/C++ varaible to be set.
    * Then, it either stores it in the alternative ubox table (in the case it is
    * an object) or in the own table (that represents the class or module).
*/
static int class_newindex_event (lua_State* L)
{
    int t = lua_type(L,1);
    if (t == LUA_TUSERDATA)
    {
        /* Try accessing a C/C++ variable to be set */
        lua_getmetatable(L,1);
        while (lua_istable(L,-1))                /* stack: t k v mt */
        {
            if (lua_isnumber(L,2))                 /* check if key is a numeric value */
            {
                /* try operator[] */
                lua_pushstring(L,".seti");
                lua_rawget(L,-2);                      /* stack: obj key mt func */
                if (lua_isfunction(L,-1))
                {
                    lua_pushvalue(L,1);
                    lua_pushvalue(L,2);
                    lua_pushvalue(L,3);
                    lua_call(L,3,0);
                    return 0;
                }
            }
            else
            {
                lua_pushstring(L,".set");
                lua_rawget(L,-2);                      /* stack: t k v mt tset */
                if (lua_istable(L,-1))
                {
                    lua_pushvalue(L,2);
                    lua_rawget(L,-2);                     /* stack: t k v mt tset func */
                    if (lua_iscfunction(L,-1))
                    {
                        lua_pushvalue(L,1);
                        lua_pushvalue(L,3);
                        lua_call(L,2,0);
                        return 0;
                    }
                    lua_pop(L,1);                          /* stack: t k v mt tset */
                }
                lua_pop(L,1);                           /* stack: t k v mt */
                if (!lua_getmetatable(L,-1))            /* stack: t k v mt mt */
                    lua_pushnil(L);
                lua_remove(L,-2);                       /* stack: t k v mt */
            }
        }
        lua_settop(L,3);                          /* stack: t k v */

        /* then, store as a new field */
        storeatubox(L,1);
    }
    else if (t== LUA_TTABLE)
    {
        lua_getmetatable(L,1);  /* stack: t k v mt */
        lua_pushstring(L,".set");
        lua_rawget(L,-2);       /* stack: t k v mt tset */
        if (lua_istable(L,-1)) {
            lua_pushvalue(L,2);  /* stack: t k v mt tset k */
            lua_rawget(L,-2);
            if (lua_iscfunction(L,-1)) {  /* ... func */
                lua_pushvalue(L,1); /* ... func t */
                lua_pushvalue(L,3); /* ... func t v */
                lua_call(L,2,0);
                return 0;
            }
        }
		lua_settop(L,3);
        class_backup_before_newindex(L);
		lua_settop(L,3);
        lua_getmetatable(L,1);  /* stack: t k v mt */
        lua_replace(L, 1);      /* stack: mt k v */
		lua_rawset(L,1);
    }
    return 0;
}