Example #1
0
    void init()
    {
        lua_State *L = m_L;
        lua_createtable(L, 1, 8); // Environment
        lua_pushvalue(L, 2); // Permanent objects
        lua_rawseti(L, -2, 1);
        lua_createtable(L, 1, 0); // Environment metatable
        lua_pushvalue(L, 2); // Permanent objects
        lua_pushvalue(L, 1); // self
        lua_pushcclosure(L, l_writer_mt_index, 2);
        lua_setfield(L, -2, "__index");
        lua_setmetatable(L, -2);
        lua_setfenv(L, 1);
        lua_createtable(L, 1, 4); // Metatable
        lua_pushcclosure(L, l_crude_gc<LuaPersistBasicWriter>, 0);
        lua_setfield(L, -2, "__gc");
        lua_pushvalue(L, luaT_upvalueindex(1)); // Prototype persistance names
        lua_rawseti(L, -2, 1);
        lua_setmetatable(L, 1);

        m_iNextIndex = 1;
        m_iDataLength = 0;
        m_bHadError = false;
    }
Example #2
0
bool CLuaHandleSynced::SetupUnsyncedFunction(lua_State *L, const char* funcName)
{
	// copy the function from UNSYNCED into
	// the registry, and setfenv() it to UNSYNCED
	lua_settop(L, 0);
	unsyncedStr.GetRegistry(L);
	if (!lua_istable(L, -1)) {
		lua_settop(L, 0);
// FIXME		LOG_L(L_ERROR, "missing UNSYNCED table for %s", name.c_str());
		return false;
	}
	const int unsynced = lua_gettop(L);

	lua_pushstring(L, funcName);

	lua_pushstring(L, funcName);
	lua_gettable(L, unsynced);
	if (lua_isnil(L, -1)) {
		lua_rawset(L, LUA_REGISTRYINDEX);
		lua_settop(L, 0);
		return true;
	}
	else if (!lua_isfunction(L, -1)) {
		lua_settop(L, 0);
		LOG_L(L_WARNING, "%s in %s is not a function",
				funcName, GetName().c_str());
		return false;
	}
	lua_pushvalue(L, unsynced);
	lua_setfenv(L, -2);

	lua_rawset(L, LUA_REGISTRYINDEX);

	lua_settop(L, 0);
	return true;
}
Example #3
0
// Generates a temporary file, and returns a file handle as well as the file name
int mkstemp(lua_State *L)
{
	std::string templ;
	if (lua_gettop(L) > 0) {
		templ = LuaHelpers::pops(L);
	}

	FILE **pf = (FILE **)lua_newuserdata(L, sizeof *pf);
	*pf = 0;
	luaL_getmetatable(L, LUA_FILEHANDLE);
	lua_setmetatable(L, -2);

	// Register custom __close() function
	// (From lua posix module by Luiz Henrique de Figueiredo)
	lua_getfield(L, LUA_REGISTRYINDEX, "PEPPER_UTILS_FILE");
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		lua_newtable(L);
		lua_pushvalue(L, -1);
		lua_pushcfunction(L, fclose);
		lua_setfield(L, -2, "__close");
		lua_setfield(L, LUA_REGISTRYINDEX, "PEPPER_UTILS_FILE");
	}
	lua_setfenv(L, -2);

	// Gemerate the file
	std::string filename;
	try {
		*pf = sys::fs::mkstemp(&filename, templ);
	} catch (const PepperException &ex) {
		return LuaHelpers::pushError(L, ex.what(), ex.where());
	}

	LuaHelpers::push(L, filename);
	return 2;
}
Example #4
0
static int l_create_server(lua_State *L) {
	const char *msg = NULL;
	struct httpserver *hs = NULL;
	struct mg_server *server = NULL;
	hs = (struct httpserver*)lua_newuserdata(L, sizeof(struct httpserver));
	memset(hs, 0, sizeof(struct httpserver));
	server = mg_create_server(L, ev_handler);
	if (!hs || !server) {
		msg = "mg_create_server fail";
		goto error_ret;
	}
	hs->server = server; 
	luaL_getmetatable(L, META_HTTPAUTH);
	lua_setmetatable(L, -2);
	lua_createtable(L, 1, 0);
    lua_setfenv(L, -2);
	return 1;
error_ret:
	if (server) 
		mg_destroy_server(&server);
	lua_pushnil(L);
	lua_pushfstring(L, "%s", msg);
	return 2;
}
/**
 * Set environment table for the given code closure.
 *
 * Before:
 *         | code closure | <- top
 *         |      ...     |
 *
 * After:
 *         | code closure | <- top
 *         |      ...     |
 * */
static void
ngx_http_lua_header_filter_by_lua_env(lua_State *L, ngx_http_request_t *r)
{
    /*  set nginx request pointer to current lua thread's globals table */
    ngx_http_lua_set_req(L, r);

    /**
     * we want to create empty environment for current script
     *
     * newt = {}
     * newt["_G"] = newt
     * setmetatable(newt, {__index = _G})
     *
     * if a function or symbol is not defined in our env, __index will lookup
     * in the global env.
     *
     * all variables created in the script-env will be thrown away at the end
     * of the script run.
     * */
    ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */);

    /*  {{{ initialize ngx.* namespace */
    lua_pushlightuserdata(L, &ngx_http_lua_headerfilterby_ngx_key);
    lua_rawget(L, LUA_REGISTRYINDEX);
    lua_setfield(L, -2, "ngx");
    /*  }}} */

    /*  {{{ make new env inheriting main thread's globals table */
    lua_createtable(L, 0, 1 /* nrec */);   /* the metatable for the new env */
    ngx_http_lua_get_globals_table(L);
    lua_setfield(L, -2, "__index");
    lua_setmetatable(L, -2);    /*  setmetatable({}, {__index = _G}) */
    /*  }}} */

    lua_setfenv(L, -2);    /*  set new running env for the code closure */
}
Example #6
0
	/* l_obj[".c_instance"] = c_obj */

	return 0;
}

#ifdef LUA_VERSION_NUM /* lua 5.1 */
static int tolua_bnd_setpeer(lua_State *L)
{

	/* stack: userdata, table */
	if (!lua_isuserdata(L, -2))
	{
		lua_pushstring(L, "Invalid argument #1 to setpeer: userdata expected.");
		lua_error(L);
	}

	if (lua_isnil(L, -1))
	{

		lua_pop(L, 1);
		lua_pushvalue(L, TOLUA_NOPEER);
	}
#if LUA_VERSION_NUM > 501
	lua_setuservalue(L, -2);
#else
	lua_setfenv(L, -2);
#endif

	return 0;
}
Example #7
0
LUALIB_API int luaopen_io(lua_State * L)
{
    createmeta(L);
    /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
    lua_createtable(L, 2, 1);
    lua_replace(L, LUA_ENVIRONINDEX);
    /* open library */
    luaL_register(L, LUA_IOLIBNAME, iolib);
    /* create (and set) default files */
    createstdfile(L, stdin, IO_INPUT, "stdin");
    createstdfile(L, stdout, IO_OUTPUT, "stdout");
    createstdfile(L, stderr, 0, "stderr");
    /* create environment for 'popen' */
    lua_getfield(L, -1, "popen");
    lua_createtable(L, 0, 1);
    lua_pushcfunction(L, io_pclose);
    lua_setfield(L, -2, "__close");
    lua_setfenv(L, -2);
    lua_pop(L, 1);              /* pop 'popen' */
    /* set default close function */
    lua_pushcfunction(L, io_fclose);
    lua_setfield(L, LUA_ENVIRONINDEX, "__close");
    return 1;
}
Example #8
0
static void unpersistfunction(int ref, UnpersistInfo *upi) {
	/* perms reftbl ... */
	LClosure *lcl;
	int i;
	lu_byte nupvalues;

	verify(luaZ_read(&upi->zio, &nupvalues, sizeof(lu_byte)) == 0);

	lcl = (LClosure*)luaF_newLclosure(upi->L, nupvalues, &upi->L->_gt);
	pushclosure(upi->L, (Closure*)lcl);

	/* perms reftbl ... func */
	/* Put *some* proto in the closure, before the GC can find it */
	lcl->p = makefakeproto(upi->L, nupvalues);

	/* Also, we need to temporarily fill the upvalues */
	lua_pushnil(upi->L);
	/* perms reftbl ... func nil */
	for(i=0; i<nupvalues; i++) {
		lcl->upvals[i] = makeupval(upi->L, -1);
	}
	lua_pop(upi->L, 1);
	/* perms reftbl ... func */

	/* I can't see offhand how a function would ever get to be self-
	 * referential, but just in case let's register it early */
	registerobject(ref, upi);

	/* Now that it's safe, we can get the real proto */
	unpersist(upi);
	/* perms reftbl ... func proto? */
	lua_assert(lua_type(upi->L, -1) == LUA_TPROTO);
	/* perms reftbl ... func proto */
	lcl->p = toproto(upi->L, -1);
	lua_pop(upi->L, 1);
	/* perms reftbl ... func */

	for(i=0; i<nupvalues; i++) {
		/* perms reftbl ... func */
		unpersist(upi);
		/* perms reftbl ... func func2 */
		unboxupval(upi->L);
		/* perms reftbl ... func upval */
		lcl->upvals[i] = toupval(upi->L, -1);
		lua_pop(upi->L, 1);
		/* perms reftbl ... func */
	}
	/* perms reftbl ... func */

	/* Finally, the fenv */
	unpersist(upi);
	/* perms reftbl ... func fenv/nil? */
	lua_assert(lua_type(upi->L, -1) == LUA_TNIL ||
	           lua_type(upi->L, -1) == LUA_TTABLE);
	/* perms reftbl ... func fenv/nil */
	if(!lua_isnil(upi->L, -1)) {
		/* perms reftbl ... func fenv */
		lua_setfenv(upi->L, -2);
		/* perms reftbl ... func */
	} else {
		/* perms reftbl ... func nil */
		lua_pop(upi->L, 1);
		/* perms reftbl ... func */
	}
	/* perms reftbl ... func */
}
Example #9
0
void thread_particle_init(particle_thread *pt, plist *l)
{
	lua_State *L = pt->L;
	particles_type *ps = l->ps;
	int tile_w, tile_h;
	int base_size = 0;

	// Load the particle definition
	// Returns: generator_fct:1, update_fct:2, max:3, gl:4, no_stop:5
	if (!luaL_loadfile(L, ps->name_def))
	{
		// Make a new table to serve as environment for the function
		lua_newtable(L);
		if (!luaL_loadstring(L, ps->args))
		{
			lua_pushvalue(L, -2); // Copy the evn table
			lua_setfenv(L, -2); // Set it as the function env
			if (lua_pcall(L, 0, 0, 0))
			{
				printf("Particle args init error %x (%s): %s\n", (int)l, ps->args, lua_tostring(L, -1));
				lua_pop(L, 1);
			}
		}
		else
		{
			lua_pop(L, 1);
			printf("Loading particle arguments failed: %s\n", ps->args);
		}

		// Copy tile_w and tile_h for compatibility with old code
		lua_pushstring(L, "engine");
		lua_newtable(L);

		lua_pushstring(L, "Map");
		lua_newtable(L);

		lua_pushstring(L, "tile_w");
		lua_pushstring(L, "tile_w");
		lua_gettable(L, -7);
		tile_w = lua_tonumber(L, -1);
		lua_settable(L, -3);
		lua_pushstring(L, "tile_h");
		lua_pushstring(L, "tile_h");
		lua_gettable(L, -7);
		tile_h = lua_tonumber(L, -1);
		lua_settable(L, -3);

		lua_settable(L, -3);
		lua_settable(L, -3);

		// The metatable which references the global space
		lua_newtable(L);
		lua_pushstring(L, "__index");
		lua_pushvalue(L, LUA_GLOBALSINDEX);
		lua_settable(L, -3);

		// Set the environment metatable
		lua_setmetatable(L, -2);

		// Set the environment
		lua_pushvalue(L, -1);
		lua_setfenv(L, -3);
		lua_insert(L, -2);

		// Call the method
		if (lua_pcall(L, 0, 5, 0))
		{
			printf("Particle run error %x (%s): %s\n", (int)l, ps->args, lua_tostring(L, -1));
			lua_pop(L, 1);
		}

		// Check base size
		lua_pushstring(L, "base_size");
		lua_gettable(L, -7);
		base_size = lua_tonumber(L, -1);
		lua_pop(L, 1);
		lua_remove(L, -6);
	}
	else { lua_pop(L, 1); return; }

	int nb = lua_isnumber(L, 3) ? lua_tonumber(L, 3) : 1000;
	nb = (nb * ps->density) / 100;
	if (!nb) nb = 1;
	ps->nb = nb;
	ps->no_stop = lua_toboolean(L, 5);

	ps->zoom = 1;
	if (base_size)
	{
		ps->zoom = (((float)tile_w + (float)tile_h) / 2) / (float)base_size;
	}

	int batch = nb;
	ps->batch_nb = 0;
	ps->vertices = calloc(2*4*batch, sizeof(GLfloat)); // 2 coords, 4 vertices per particles
	ps->colors = calloc(4*4*batch, sizeof(GLfloat)); // 4 color data, 4 vertices per particles
	ps->texcoords = calloc(2*4*batch, sizeof(GLshort));
	ps->particles = calloc(nb, sizeof(particle_type));

	// Locate the updator
	lua_getglobal(L, "__fcts");
	l->updator_ref = lua_objlen(L, -1) + 1;
	lua_pushnumber(L, lua_objlen(L, -1) + 1);
	lua_pushvalue(L, 2);
	lua_rawset(L, -3);
	lua_pop(L, 1);

	// Grab all parameters
	lua_pushvalue(L, 1);

	lua_pushstring(L, "system_rotation");
	lua_gettable(L, -2);
	ps->rotate = lua_tonumber(L, -1); lua_pop(L, 1);

	lua_pushstring(L, "system_rotationv");
	lua_gettable(L, -2);
	ps->rotate_v = lua_tonumber(L, -1); lua_pop(L, 1);

	lua_pushstring(L, "engine");
	lua_gettable(L, -2);
	ps->engine = lua_tonumber(L, -1); lua_pop(L, 1);

	lua_pushstring(L, "blend_mode");
	lua_gettable(L, -2);
	ps->blend_mode = lua_tonumber(L, -1); lua_pop(L, 1);

	lua_pushstring(L, "generator");
	lua_gettable(L, -2);
	if (lua_isnil(L, -1))
	{
		lua_pop(L, 1);
		l->generator_ref = LUA_NOREF;
	}
	else
	{
		lua_getglobal(L, "__fcts");
		l->generator_ref = lua_objlen(L, -1) + 1;
		lua_pushnumber(L, lua_objlen(L, -1) + 1);
		lua_pushvalue(L, -3);
		lua_rawset(L, -3);
		lua_pop(L, 2);
	}

	if (l->generator_ref == LUA_NOREF)
	{
		lua_pushstring(L, "base");
		lua_gettable(L, -2);
		ps->base = (float)lua_tonumber(L, -1);
		lua_pop(L, 1);

		getinitfield(L, "life", &(ps->life_min), &(ps->life_max));

		getinitfield(L, "angle", &(ps->angle_min), &(ps->angle_max));
		getinitfield(L, "anglev", &(ps->anglev_min), &(ps->anglev_max));
		getinitfield(L, "anglea", &(ps->anglea_min), &(ps->anglea_max));

		getinitfield(L, "size", &(ps->size_min), &(ps->size_max));
		getinitfield(L, "sizev", &(ps->sizev_min), &(ps->sizev_max));
		getinitfield(L, "sizea", &(ps->sizea_min), &(ps->sizea_max));

		getinitfield(L, "r", &(ps->r_min), &(ps->r_max));
		getinitfield(L, "rv", &(ps->rv_min), &(ps->rv_max));
		getinitfield(L, "ra", &(ps->ra_min), &(ps->ra_max));

		getinitfield(L, "g", &(ps->g_min), &(ps->g_max));
		getinitfield(L, "gv", &(ps->gv_min), &(ps->gv_max));
		getinitfield(L, "ga", &(ps->ga_min), &(ps->ga_max));

		getinitfield(L, "b", &(ps->b_min), &(ps->b_max));
		getinitfield(L, "bv", &(ps->bv_min), &(ps->bv_max));
		getinitfield(L, "ba", &(ps->ba_min), &(ps->ba_max));

		getinitfield(L, "a", &(ps->a_min), &(ps->a_max));
		getinitfield(L, "av", &(ps->av_min), &(ps->av_max));
		getinitfield(L, "aa", &(ps->aa_min), &(ps->aa_max));
//		printf("Particle emiter using default generator\n");
	}
	else
	{
//		printf("Particle emiter using custom generator\n");
	}
	lua_pop(L, 1);

	// Pop all returns
	lua_pop(L, 5);

	// Push a special emitter
	lua_newtable(L);
	lua_pushstring(L, "ps");
	lua_newtable(L);

	lua_pushstring(L, "emit");
	lua_pushlightuserdata(L, l);
	lua_pushcclosure(L, particles_emit, 1);
	lua_settable(L, -3);

	lua_settable(L, -3);

	lua_getglobal(L, "__fcts");
	l->emit_ref = lua_objlen(L, -1) + 1;
	lua_pushnumber(L, lua_objlen(L, -1) + 1);
	lua_pushvalue(L, -3);
	lua_rawset(L, -3);
	lua_pop(L, 1);
	lua_pop(L, 1);

	free((char*)ps->name_def);
	free((char*)ps->args);
	ps->name_def = ps->args = NULL;
	ps->init = TRUE;
}
static ngx_int_t
ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
{
    int                  cc_ref;
    ngx_int_t            rc;
    lua_State           *cc;
    ngx_http_lua_ctx_t  *ctx;
    ngx_http_cleanup_t  *cln;

    /*  {{{ new coroutine to handle request */
    cc = ngx_http_lua_new_thread(r, L, &cc_ref);

    if (cc == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "lua: failed to create new coroutine "
                      "to handle request");

        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    /*  move code closure to new coroutine */
    lua_xmove(L, cc, 1);

    /*  set closure's env table to new coroutine's globals table */
    lua_pushvalue(cc, LUA_GLOBALSINDEX);
    lua_setfenv(cc, -2);

    /*  save reference of code to ease forcing stopping */
    lua_pushvalue(cc, -1);
    lua_setglobal(cc, GLOBALS_SYMBOL_RUNCODE);

    /*  save nginx request in coroutine globals table */
    lua_pushlightuserdata(cc, r);
    lua_setglobal(cc, GLOBALS_SYMBOL_REQUEST);
    /*  }}} */

    /*  {{{ initialize request context */
    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);

    dd("ctx = %p", ctx);

    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ngx_http_lua_reset_ctx(r, L, ctx);

    ctx->entered_access_phase = 1;

    ctx->cc = cc;
    ctx->cc_ref = cc_ref;

    /*  }}} */

    /*  {{{ register request cleanup hooks */
    if (ctx->cleanup == NULL) {
        cln = ngx_http_cleanup_add(r, 0);
        if (cln == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        cln->handler = ngx_http_lua_request_cleanup;
        cln->data = r;
        ctx->cleanup = &cln->handler;
    }
    /*  }}} */

    rc = ngx_http_lua_run_thread(L, r, ctx, 0);

    dd("returned %d", (int) rc);

    if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        return rc;
    }

    if (rc == NGX_AGAIN) {
        return NGX_DONE;
    }

    if (rc == NGX_DONE) {
        ngx_http_finalize_request(r, NGX_DONE);
        return NGX_DONE;
    }

    if (rc >= NGX_HTTP_OK && rc < NGX_HTTP_SPECIAL_RESPONSE) {
        return rc;
    }

    if (rc == NGX_OK) {
        return NGX_OK;
    }

    return NGX_DECLINED;
}
Example #11
0
/*
** Create a new 'ktable' to the pattern at the top of the stack.
*/
static void newktable (lua_State *L, int n) {
  lua_createtable(L, n, 0);  /* create a fresh table */
  lua_setfenv(L, -2);  /* set it as 'ktable' for pattern */
}
Example #12
0
// __depersist metamethod handler
static int l_str_depersist(lua_State *L)
{
    lua_settop(L, 2);
    lua_insert(L, 1);
    LuaPersistReader *pReader = (LuaPersistReader*)lua_touserdata(L, 1);

    // Read the instructions for re-creating the value
    if(!pReader->readStackObject())
        return 0;
    if(lua_type(L, 3) == LUA_TBOOLEAN && lua_toboolean(L, 3) == 1)
    {
        // The current code uses a boolean marker to indicate that the
        // instructions were stored in the environment. Replace the marker
        // with them.
        lua_getfenv(L, 2);
        lua_replace(L, 3);
    }
    else
    {
        // Older versions of the code wrote the instructions here, or nil for
        // no instructions. Convert nil to the empty table, and store the
        // instructions as the userdata's environment.
        if(lua_type(L, 3) == LUA_TNIL)
        {
            lua_newtable(L);
            lua_replace(L, 3);
        }
        lua_pushvalue(L, 3);
        lua_setfenv(L, 2);
    }

    // Prepare t, k for saving the value
    aux_push_weak_table(L, 0);
    lua_pushvalue(L, 2);

    if(lua_objlen(L, 3) == 0)
    {
        // No instructions provided, so read the value itself
        if(!pReader->readStackObject())
            return 0;
    }
    else
    {
        // The instructions are a table of values; unpack them and replace
        // proxies with their values.
        bool bIsIndexOperation = false;
        int iCount = (int)lua_objlen(L, 3);
        lua_checkstack(L, iCount + 1);
        for(int i = 1; i <= iCount; ++i)
        {
            lua_rawgeti(L, 3, i);
            if(lua_type(L, -1) == LUA_TUSERDATA)
            {
                if(i == 1)
                    bIsIndexOperation = true;
                lua_rawget(L, 4);
            }
        }

        if(iCount == 2 && bIsIndexOperation)
        {
            // If there were two values, and the first was a proxy, then the
            // instruction is to perform a table lookup.
            lua_gettable(L, -2);
            lua_replace(L, -2);
        }
        else
        {
            // Otherwise, the first value was a method or method name.
            if(lua_type(L, 6) != LUA_TFUNCTION)
            {
                lua_pushvalue(L, 6);
                lua_gettable(L, 7);
                lua_replace(L, 6);
            }
            lua_call(L, iCount - 1, 1);
        }
    }

    // Save the value
    lua_rawset(L, 4);
    return 0;
}
Example #13
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;
 }
Example #14
0
    apr_status_t LuaAction::run(ActionCtx *actionCtx) const
    {
        RUM_PTRC_ACTION(actionCtx->reqCtx()->pool(),
                       "LuaAction::run(ActionCtx *actionCtx), "
                       "actionCtx: " << (void *)actionCtx);


        RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_DEBUG,
                       "LuaAction: executing chunk");


        int lStatus;
        apr_status_t aStatus;
        ReqCtx *reqCtx = actionCtx->reqCtx();
        lua_State *L = reqCtx->luaState();
        if (L == 0)
        {
            RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                           "aborting Lua action due to errors");
            return APR_EGENERAL;
        }
        lua_pop(L, lua_gettop(L));

        // if custom error handler is defined, push it onto the stack,
        // otherwise use debug.traceback
        if (reqCtx->config().errHandlerChunk())
        {
            const Blob *chunk = reqCtx->config().errHandlerChunk();
            lStatus = luaL_loadbuffer(L,
                                      static_cast<const char *>(chunk->data()),
                                      chunk->size(),
                                      "<ErrorHandler>");
            if (lStatus) {
                const char *msg = lua_tostring(L, -1);
                RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                               "failed to load ErrorHandler Lua chunk: "
                               << msg);
                return APR_EGENERAL;
            }
        }
        else
        {
            // push debug.traceback onto stack
            lua_getglobal(L, "debug");
            lua_getfield(L, -1, "traceback");
            lua_remove(L, -2);
        }

        // create Lua sandbox environment which inherits from main environment
        lua_newtable(L);
        lua_newtable(L);
        lua_pushliteral(L, "__index");
        lua_pushvalue(L, LUA_GLOBALSINDEX);
        lua_settable(L, -3);
        lua_setmetatable(L, -2);
        int envTableIdx = lua_gettop(L);

        // make sure scripts can't access real global _G
        lua_pushliteral(L, "_G");
        lua_pushvalue(L, -2);
        lua_settable(L, -3);

        // add sandbox env to registry so that interactive_lua() can access it
        lua_pushlightuserdata(L, sandboxEnvRegKey());
        lua_pushvalue(L, envTableIdx);
        lua_settable(L, LUA_REGISTRYINDEX);


        // create "rum" table in sandbox environment
        lua_pushvalue(L, envTableIdx);
        lua_newtable(L);
        lua_pushvalue(L, -1);
        int tos = lua_gettop(L);
        aStatus = setRumFields(L, actionCtx);
        if (aStatus != APR_SUCCESS)
        {
            RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                           "aborting Lua action due to errors");
            return APR_EGENERAL;
        }
        lua_pop(L, lua_gettop(L) - tos);
        lua_setfield(L, -3, "rum");
        tos = lua_gettop(L);
        // the "rum" table is now at the top of the stack


        // have the global "rum" proxy table inherit from the real
        // "rum" table in the sandbox environment we just created
        lua_getglobal(L, "rum");
        lua_getmetatable(L, -1);
        lua_pushvalue(L, -3);
        lua_setfield(L, -2, "__index");
        lua_pop(L, 2);


        // load and run CommonPreAction Lua chunks in sandbox
        StaticStrBuffer<32> nameBuf;
        nameBuf << "ruleIdx:" << actionCtx->ruleIdx();
        apr_ssize_t i;
        apr_ssize_t numCPA = reqCtx->config().commonPreActions().size();
        for (i = 0; i < numCPA; i++)
        {
            const Blob *chunk = reqCtx->config().commonPreActions()[i];
            lStatus = luaL_loadbuffer(L,
                                      static_cast<const char *>(chunk->data()),
                                      chunk->size(),
                                      nameBuf.asStr());
            if (lStatus) {
                const char *msg = lua_tostring(L, -1);
                RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                               "failed to load CommonPreAction Lua chunk: "
                               << msg);
                return APR_EGENERAL;
            }
            lua_pushvalue(L, envTableIdx);
            lua_setfenv(L, -2);
            lStatus = lua_pcall(L, 0, 0, 1);
            if (lStatus) {
                const char *msg = lua_tostring(L, -1);
                RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                               "failed to execute CommonPreAction Lua chunk: "
                               << msg);
                return APR_EGENERAL;
            }
        }


        // load and run Lua chunk in same sandbox as CommonPreAction
        lStatus = luaL_loadbuffer(L,
                                  static_cast<const char *>(chunk_->data()),
                                  chunk_->size(),
                                  nameBuf.asStr());
        if (lStatus) {
            const char *msg = lua_tostring(L, -1);
            RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                           "failed to load Lua chunk: " << msg);
            return APR_EGENERAL;
        }
        lua_pushvalue(L, envTableIdx);
        lua_setfenv(L, -2);
        lStatus = lua_pcall(L, 0, 1, 1);
        if (lStatus) {
            const char *msg = lua_tostring(L, -1);
            RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                           "failed to execute Lua chunk: " << msg);
            return APR_EGENERAL;
        }

        // process optionally returned value
        aStatus = RUM_DEFAULT;
        if (lua_type(L, -1) == LUA_TNUMBER)
        {
            aStatus = static_cast<apr_status_t>(lua_tointeger(L, -1));
            RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_INFO,
                           "integer return code from action: " << aStatus);
            if ((aStatus != RUM_OK) &&
                (aStatus != RUM_DELAYED_OK) &&
                (aStatus != RUM_RELOOKUP) &&
                (aStatus != RUM_DECLINED))
            {
                RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                               "invalid return code from action: " << aStatus);
                return APR_EGENERAL;
            }
        }
        else if (lua_type(L, -1) == LUA_TNIL)
        {
            RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_INFO,
                           "nil return code from action");
        }
        else
        {
            RUM_LOG_ACTION(actionCtx->reqCtx()->logger(), APLOG_ERR,
                           "invalid non-integer return code from action");
            return APR_EGENERAL;
        }
        lua_pop(L, 1);


#if 0 //bgt -- eliminate in favor of return codes
        // check status flags
        if (actionCtx->lastAction())
        {
            aStatus = RUM_LAST_ACTION;
        }
        else if (actionCtx->relookup())
        {
            aStatus = RUM_RELOOKUP;
        }
#endif


        return aStatus;
    }
/**
 * Set environment table for the given code closure.
 *
 * Before:
 *         | code closure | <- top
 *         |      ...     |
 *
 * After:
 *         | code closure | <- top
 *         |      ...     |
 * */
static void
ngx_http_lua_set_by_lua_env(lua_State *L, ngx_http_request_t *r, size_t nargs,
        ngx_http_variable_value_t *args)
{
    /*  set nginx request pointer to current lua thread's globals table */
    lua_pushlightuserdata(L, r);
    lua_setglobal(L, GLOBALS_SYMBOL_REQUEST);

    /**
     * we want to create empty environment for current script
     *
     * setmetatable({}, {__index = _G})
     *
     * if a function or symbol is not defined in our env, __index will lookup
     * in the global env.
     *
     * all variables created in the script-env will be thrown away at the end
     * of the script run.
     * */
    lua_newtable(L);    /*  new empty environment aka {} */

    /*  override 'print' function */
    lua_pushcfunction(L, ngx_http_lua_print);
    lua_setfield(L, -2, "print");

    /*  {{{ initialize ngx.* namespace */
    lua_newtable(L);    /*  ngx.* */

    lua_newtable(L);    /*  .arg table aka {} */

    lua_newtable(L);    /*  the metatable for new param table */
    lua_pushinteger(L, nargs);    /*  1st upvalue: argument number */
    lua_pushlightuserdata(L, args);    /*  2nd upvalue: pointer to arguments */

    lua_pushcclosure(L, ngx_http_lua_param_get, 2);
        /*  binding upvalues to __index meta-method closure */

    lua_setfield(L, -2, "__index");
    lua_setmetatable(L, -2);    /*  tie the metatable to param table */

    lua_setfield(L, -2, "arg");    /*  set ngx.arg table */

    /* {{{ register reference maps */
    lua_newtable(L);    /* ngx.var */

    lua_newtable(L); /* metatable for ngx.var */
    lua_pushcfunction(L, ngx_http_lua_var_get);
    lua_setfield(L, -2, "__index");
    lua_pushcfunction(L, ngx_http_lua_var_set);
    lua_setfield(L, -2, "__newindex");
    lua_setmetatable(L, -2);

    lua_setfield(L, -2, "var");
    /*  }}} */

#if (NGX_PCRE)
    /* {{{ ngx.re table */

    lua_newtable(L);    /* .re */

    lua_pushcfunction(L, ngx_http_lua_ngx_re_match);
    lua_setfield(L, -2, "match");

    lua_pushcfunction(L, ngx_http_lua_ngx_re_gmatch);
    lua_setfield(L, -2, "gmatch");

    lua_pushcfunction(L, ngx_http_lua_ngx_re_sub);
    lua_setfield(L, -2, "sub");

    lua_pushcfunction(L, ngx_http_lua_ngx_re_gsub);
    lua_setfield(L, -2, "gsub");

    lua_setfield(L, -2, "re");

    /* }}} */
#endif /* NGX_PCRE */

    lua_pushcfunction(L, ngx_http_lua_ngx_escape_uri);
    lua_setfield(L, -2, "escape_uri");

    lua_pushcfunction(L, ngx_http_lua_ngx_unescape_uri);
    lua_setfield(L, -2, "unescape_uri");

    lua_pushcfunction(L, ngx_http_lua_ngx_quote_sql_str);
    lua_setfield(L, -2, "quote_sql_str");

    lua_pushcfunction(L, ngx_http_lua_ngx_decode_base64);
    lua_setfield(L, -2, "decode_base64");

    lua_pushcfunction(L, ngx_http_lua_ngx_encode_base64);
    lua_setfield(L, -2, "encode_base64");

    lua_pushcfunction(L, ngx_http_lua_ngx_md5_bin);
    lua_setfield(L, -2, "md5_bin");

    lua_pushcfunction(L, ngx_http_lua_ngx_md5);
    lua_setfield(L, -2, "md5");

    lua_pushcfunction(L, ngx_http_lua_ngx_time);
    lua_setfield(L, -2, "get_now_ts"); /* deprecated */

    lua_pushcfunction(L, ngx_http_lua_ngx_utctime);
    lua_setfield(L, -2, "utctime");

    lua_pushcfunction(L, ngx_http_lua_ngx_localtime);
    lua_setfield(L, -2, "get_now"); /* deprecated */

    lua_pushcfunction(L, ngx_http_lua_ngx_time);
    lua_setfield(L, -2, "time");

    lua_pushcfunction(L, ngx_http_lua_ngx_localtime);
    lua_setfield(L, -2, "localtime");

    lua_pushcfunction(L, ngx_http_lua_ngx_today);
    lua_setfield(L, -2, "get_today"); /* deprecated */

    lua_pushcfunction(L, ngx_http_lua_ngx_today);
    lua_setfield(L, -2, "today");

    lua_pushcfunction(L, ngx_http_lua_ngx_http_time);
    lua_setfield(L, -2, "http_time");

	lua_pushcfunction(L, ngx_http_lua_ngx_parse_http_time);
    lua_setfield(L, -2, "parse_http_time");

    lua_pushcfunction(L, ngx_http_lua_ngx_cookie_time);
    lua_setfield(L, -2, "cookie_time");

    lua_pushcfunction(L, ngx_http_lua_ngx_log);
    lua_setfield(L, -2, "log");

    ngx_http_lua_inject_log_consts(L);

    /* ngx. getter and setter */
    lua_createtable(L, 0, 2); /* metatable for .ngx */
    lua_pushcfunction(L, ngx_http_lua_ngx_get);
    lua_setfield(L, -2, "__index");
    lua_pushcfunction(L, ngx_http_lua_ngx_set);
    lua_setfield(L, -2, "__newindex");
    lua_setmetatable(L, -2);

    lua_setfield(L, -2, "ngx");
    /*  }}} */

    /*  {{{ make new env inheriting main thread's globals table */
    lua_newtable(L);    /*  the metatable for the new env */
    lua_pushvalue(L, LUA_GLOBALSINDEX);
    lua_setfield(L, -2, "__index");
    lua_setmetatable(L, -2);    /*  setmetatable({}, {__index = _G}) */
    /*  }}} */

    lua_setfenv(L, -2);    /*  set new running env for the code closure */
}
ngx_int_t
ngx_http_lua_content_by_chunk(lua_State *L, ngx_http_request_t *r)
{
    int                      cc_ref;
    lua_State               *cc;
    ngx_http_lua_ctx_t      *ctx;
    ngx_http_cleanup_t      *cln;

    dd("content by chunk");

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);

    if (ctx == NULL) {
        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_ctx_t));
        if (ctx == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        dd("setting new ctx, ctx = %p", ctx);

        ctx->cc_ref = LUA_NOREF;
        ctx->ctx_ref = LUA_NOREF;

        ngx_http_set_ctx(r, ctx, ngx_http_lua_module);

    } else {
        dd("reset ctx");
        ngx_http_lua_reset_ctx(r, L, ctx);
    }

    ctx->entered_content_phase = 1;

    /*  {{{ new coroutine to handle request */
    cc = ngx_http_lua_new_thread(r, L, &cc_ref);

    if (cc == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "(lua-content-by-chunk) failed to create new coroutine "
                "to handle request");

        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    /*  move code closure to new coroutine */
    lua_xmove(L, cc, 1);

    /*  set closure's env table to new coroutine's globals table */
    lua_pushvalue(cc, LUA_GLOBALSINDEX);
    lua_setfenv(cc, -2);

    /*  save reference of code to ease forcing stopping */
    lua_pushvalue(cc, -1);
    lua_setglobal(cc, GLOBALS_SYMBOL_RUNCODE);

    /*  save nginx request in coroutine globals table */
    lua_pushlightuserdata(cc, r);
    lua_setglobal(cc, GLOBALS_SYMBOL_REQUEST);
    /*  }}} */

    ctx->cc = cc;
    ctx->cc_ref = cc_ref;

    /*  {{{ register request cleanup hooks */
    if (ctx->cleanup == NULL) {
        cln = ngx_http_cleanup_add(r, 0);
        if (cln == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        cln->handler = ngx_http_lua_request_cleanup;
        cln->data = r;
        ctx->cleanup = &cln->handler;
    }
    /*  }}} */

    return ngx_http_lua_run_thread(L, r, ctx, 0);
}
Example #17
0
bool CLuaVMClass::loadFromPackage(weak_ptr<CPackage> package)
{
	_package = package;

	shared_ptr<CPackage> locked = package.lock();
	if ( locked == nullptr ) return false;

	shared_ptr<CLuaVM> host = getLuaHost().lock();

	lua_State *L = host->getState();
	_functions.clear();

	CCodeAsset* luaMain = castAsset<CCodeAsset>( locked->findAssetByName("main.code") );
	if ( luaMain == nullptr )
	{
		log(LOG_ERROR, "Failed to load 'main.code'");
		return false;
	}

	if (luaL_loadbuffer(L, luaMain->getCodeBuffer(), luaMain->getCodeLength(), *luaMain->getName()))
	{
		std::cout << "Lua: " << *luaMain->getName() << " : " << lua_tostring(L, -1) << std::endl;
		lua_pop(L, 1);
		return false;	
	}

	lua_newtable(L);

	lua_pushlightuserdata(L, this);
	lua_setfield(L, -2, "__klass");

	lua_newtable(L);
	_locals = makeShared<LuaVMReference>(getLuaHost(), -1);
	lua_setfield(L, -2, "__locals");

	lua_newtable(L);
	lua_pushcclosure(L, CLuaVMClass::metaTopLevelGet, 0);
	lua_setfield(L, -2, "__index");

	lua_pushcclosure(L, CLuaVMClass::metaTopLevelSet, 0);
	lua_setfield(L, -2, "__newindex");

	lua_setmetatable(L, -2);
	lua_setfenv(L, -2);

	if (lua_pcall(L, 0, 0, 0)) {
		std::cout << "Lua: " << lua_tostring(L, -1) << std::endl;
		lua_pop(L, 1);
		return false;
	}

	for ( uint32 i=0; i<locked->getNumAssets(); ++i )
	{
		CCodeAsset* lib = castAsset<CCodeAsset>( locked->getAsset(i) );
		if ( lib && lib != luaMain )
		{
		
			if (luaL_loadbuffer(L, lib->getCodeBuffer(), lib->getCodeLength(), *lib->getName()))
			{
				std::cout << "Lua: " << *lib->getName() << " : " << lua_tostring(L, -1) << std::endl;
				lua_pop(L, 1);
			}
			else
			{
			
				if (lua_pcall(L, 0, 0, 0)) {
					std::cout << "Lua: " << lua_tostring(L, -1) << std::endl;
					lua_pop(L, 1);
				}

			}

		}
	}

	return true;
}
Example #18
0
void SavedVariables::Load(lua_State *L){
	auto FilePath = boostfs::absolute(FileName, SavedVariablesFolderPath);

	//just silently return if nothing has been saved before. The container table should have default values set in it by the owner
	if(!boostfs::exists(FilePath)){
		return;
	}

	int ContainerIndex = LUA_GLOBALSINDEX;

	//add these 2 early to the stack so we don't have to deal with fun shifting stack indexs
	if(ContainerTable.is_valid()) {
		ContainerTable.push(L);
		ContainerIndex = lua_gettop(L);
	}

	lua_newtable(L);

	int EnvTable = lua_gettop(L); 


	//adapted from http://danwellman.com/vws.html
	if(LuaModule::LoadLuaFile(L,FilePath, "") == 0){
		//Set the chunk's environment to a table

		//import the constructors for Vector and Angles
		lua_getfield(L, LUA_GLOBALSINDEX, "Vector");
		lua_setfield(L, EnvTable, "Vector");
		lua_getfield(L, LUA_GLOBALSINDEX, "Angles");
		lua_setfield(L, EnvTable, "Angles");
    lua_getfield(L, LUA_GLOBALSINDEX, "Color");
    lua_setfield(L, EnvTable, "Color");

		lua_pushvalue(L, EnvTable);
		if (!lua_setfenv(L, -2)){
			assert(false && "Chunk must be loaded");
		}

		//Push the chunk to the top, required by pcall
		lua_pushvalue(L, EnvTable+1);
		//Remove the old chunk
		lua_remove(L, EnvTable+1);

		//Call the chunk, it then inserts any globals into the environment table
		if (lua_pcall(L, 0, 0, 0) == 0){
			for (auto it = VariableNames.begin(), end = VariableNames.end(); it != end; ++it){
				const char* FieldName = it->c_str();

				lua_getfield(L, EnvTable, FieldName);

				if (lua_isnil(L, -1)){
					lua_pop(L, 1);
				}else{
					lua_setfield(L, ContainerIndex, FieldName);
				}
			}
			
			if(ContainerTable.is_valid()) lua_pop(L, 1);

			//Pop environment table
			lua_pop(L, 1);

		 return;
		}
	}

	//we got an error while either parsing the saved variables file or when running it an error string should of been pushed onto the stack
	size_t len = 0;
	const char* s = lua_tolstring(L, -1, &len);

	if(s != NULL){
		throw exception(s);
	}else{
		throw std::runtime_error(string("Unknown error while loading saved variables from ")+FileName.string());
	}
}
Example #19
0
// Initializes uv_process_t and starts the process.
int luv_spawn(lua_State* L) {
  int before = lua_gettop(L);
  uv_pipe_t* stdin_stream = (uv_pipe_t*)luv_checkudata(L, 1, "pipe");
  uv_pipe_t* stdout_stream = (uv_pipe_t*)luv_checkudata(L, 2, "pipe");
  uv_pipe_t* stderr_stream = (uv_pipe_t*)luv_checkudata(L, 3, "pipe");
  const char* command = luaL_checkstring(L, 4);
  luaL_checktype(L, 5, LUA_TTABLE); // args
  luaL_checktype(L, 6, LUA_TTABLE); // options

  // Parse the args array
  size_t argc = lua_objlen(L, 5) + 1;
  char** args = malloc(argc + 1);
  args[0] = (char*)command;
  int i;
  for (i = 1; i < argc; i++) {
    lua_rawgeti(L, 5, i);
    args[i] = (char*)lua_tostring(L, -1);
    lua_pop(L, 1);
  }
  args[argc] = NULL;

  // Get the cwd
  lua_getfield(L, 6, "cwd");
  char* cwd = (char*)lua_tostring(L, -1);
  lua_pop(L, 1);

  // Get the env
  lua_getfield(L, 6, "env");
  char** env = NULL;
  if (lua_type(L, -1) == LUA_TTABLE) {
    argc = lua_objlen(L, -1);
    env = malloc(argc + 1);
    for (i = 0; i < argc; i++) {
      lua_rawgeti(L, -1, i + 1);
      env[i] = (char*)lua_tostring(L, -1);
      lua_pop(L, 1);
    }
    env[argc] = NULL;
  }
  lua_pop(L, 1);

  uv_process_options_t options;
  options.exit_cb = luv_process_on_exit;
  options.file = command;
  options.args = args;
  options.env = env;
  options.cwd = cwd;
  options.stdin_stream = stdin_stream;
  options.stdout_stream = stdout_stream;
  options.stderr_stream = stderr_stream;

  // Create the userdata
  uv_process_t* handle = (uv_process_t*)lua_newuserdata(L, sizeof(uv_process_t));
  int r = uv_spawn(uv_default_loop(), handle, options);
  free(args);
  if (env) free(env);
  if (r) {
    uv_err_t err = uv_last_error(uv_default_loop());
    return luaL_error(L, "spawn: %s", uv_strerror(err));
  }

  // Set metatable for type
  luaL_getmetatable(L, "luv_process");
  lua_setmetatable(L, -2);

  // Create a local environment for storing stuff
  lua_newtable(L);
  lua_setfenv (L, -2);

  // Store a reference to the userdata in the handle
  luv_ref_t* ref = (luv_ref_t*)malloc(sizeof(luv_ref_t));
  ref->L = L;
  lua_pushvalue(L, -1); // duplicate so we can _ref it
  ref->r = luaL_ref(L, LUA_REGISTRYINDEX);
  handle->data = ref;

  assert(lua_gettop(L) == before + 1);
  // return the userdata
  return 1;
}
Example #20
0
static int js_generator(lua_State *L) {
    yajl_print_t   print = NULL;
    void *         ctx   = NULL;
    yajl_gen*      handle;

    luaL_checktype(L, 1, LUA_TTABLE);

    /* {args}, ?, tbl */
    lua_newtable(L);

    /* Validate and save in fenv so it isn't gc'ed: */
    lua_getfield(L, 1, "printer");
    if ( ! lua_isnil(L, -1) ) {
        js_printer_ctx* print_ctx;

        luaL_checktype(L, -1, LUA_TFUNCTION);

        lua_pushvalue(L, -1);

        /* {args}, ?, tbl, printer, printer */
        lua_setfield(L, -3, "printer");

        print_ctx = (js_printer_ctx*)
            lua_newuserdata(L, sizeof(js_printer_ctx));
        /* {args}, ?, tbl, printer, printer_ctx */

        lua_setfield(L, -3, "printer_ctx");
        /* {args}, ?, tbl, printer */

        lua_getfield(L, LUA_REGISTRYINDEX, "yajl.refs");
        /* {args}, ?, tbl, printer, refs */
        lua_insert(L, -2);
        /* {args}, ?, tbl, refs, printer */
        print_ctx->printer_ref = luaL_ref(L, -2);
        print_ctx->L = L;
        print = &js_printer;
        ctx   = print_ctx;
    }
    lua_pop(L, 1);
    /* {args}, ?, tbl */

    /* Sucks that yajl's generator doesn't keep track of this for me
       (this is a stack of strings "array" and "object" so I can keep
       track of what to "close"): */
    lua_newtable(L);
    lua_setfield(L, -2, "stack");

    /* {args}, ?, tbl */
    handle = (yajl_gen*)lua_newuserdata(L, sizeof(yajl_gen));
    *handle = yajl_gen_alloc(NULL);
    /* {args}, ?, tbl, ud */

    if ( print ) {
        yajl_gen_config(*handle, yajl_gen_print_callback, print, ctx);
    }

    /* Get the indent and save so it isn't gc'ed: */
    lua_getfield(L, 1, "indent");
    if ( ! lua_isnil(L, -1) ) {
        yajl_gen_config(*handle, yajl_gen_beautify, 1);
        yajl_gen_config(*handle, yajl_gen_indent_string, lua_tostring(L, -1));
        lua_setfield(L, -3, "indent");
    } else {
        lua_pop(L, 1);
    }
    /* {args}, ?, tbl, ud */

    /* {args}, ?, tbl, ud, meta */
    luaL_getmetatable(L, "yajl.generator.meta");
    lua_setmetatable(L, -2);
    /* {args}, ?, tbl, ud */

    lua_insert(L, -2);
    /* {args}, ?, ud, tbl */
    lua_setfenv(L, -2);

    return 1;
}
static handler_t magnet_attract(server *srv, connection *con, plugin_data *p, buffer *name) {
	lua_State *L;
	int lua_return_value = -1;
	/* get the script-context */


	L = script_cache_get_script(srv, con, p->cache, name);

	if (lua_isstring(L, -1)) {
		log_error_write(srv, __FILE__, __LINE__,
				"sbss",
				"loading script",
				name,
				"failed:",
				lua_tostring(L, -1));

		lua_pop(L, 1);

		assert(lua_gettop(L) == 0); /* only the function should be on the stack */

		con->http_status = 500;
		con->mode = DIRECT;

		return HANDLER_FINISHED;
	}

	lua_pushstring(L, "lighty.srv");
	lua_pushlightuserdata(L, srv);
	lua_settable(L, LUA_REGISTRYINDEX); /* registery[<id>] = srv */

	lua_pushstring(L, "lighty.con");
	lua_pushlightuserdata(L, con);
	lua_settable(L, LUA_REGISTRYINDEX); /* registery[<id>] = con */

	lua_atpanic(L, magnet_atpanic);

	/**
	 * we want to create empty environment for our script
	 *
	 * setmetatable({}, {__index = _G})
	 *
	 * if a function, symbol is not defined in our env, __index will lookup
	 * in the global env.
	 *
	 * all variables created in the script-env will be thrown
	 * away at the end of the script run.
	 */
	lua_newtable(L); /* my empty environment aka {}              (sp += 1) */

	/* we have to overwrite the print function */
	lua_pushcfunction(L, magnet_print);                       /* (sp += 1) */
	lua_setfield(L, -2, "print"); /* -1 is the env we want to set(sp -= 1) */

	/**
	 * lighty.request[] has the HTTP-request headers
	 * lighty.content[] is a table of string/file
	 * lighty.header[] is a array to set response headers
	 */

	lua_newtable(L); /* lighty.*                                 (sp += 1) */

	lua_newtable(L); /*  {}                                      (sp += 1) */
	lua_newtable(L); /* the meta-table for the request-table     (sp += 1) */
	lua_pushcfunction(L, magnet_reqhdr_get);                  /* (sp += 1) */
	lua_setfield(L, -2, "__index");                           /* (sp -= 1) */
	lua_setmetatable(L, -2); /* tie the metatable to request     (sp -= 1) */
	lua_setfield(L, -2, "request"); /* content = {}              (sp -= 1) */

	lua_newtable(L); /*  {}                                      (sp += 1) */
	lua_newtable(L); /* the meta-table for the request-table     (sp += 1) */
	lua_pushcfunction(L, magnet_env_get);                     /* (sp += 1) */
	lua_setfield(L, -2, "__index");                           /* (sp -= 1) */
	lua_pushcfunction(L, magnet_env_set);                     /* (sp += 1) */
	lua_setfield(L, -2, "__newindex");                        /* (sp -= 1) */
	lua_setmetatable(L, -2); /* tie the metatable to request     (sp -= 1) */
	lua_setfield(L, -2, "env"); /* content = {}                  (sp -= 1) */

	lua_newtable(L); /*  {}                                      (sp += 1) */
	lua_newtable(L); /* the meta-table for the request-table     (sp += 1) */
	lua_pushcfunction(L, magnet_status_get);                  /* (sp += 1) */
	lua_setfield(L, -2, "__index");                           /* (sp -= 1) */
	lua_pushcfunction(L, magnet_status_set);                  /* (sp += 1) */
	lua_setfield(L, -2, "__newindex");                        /* (sp -= 1) */
	lua_setmetatable(L, -2); /* tie the metatable to request     (sp -= 1) */
	lua_setfield(L, -2, "status"); /* content = {}               (sp -= 1) */

	/* add empty 'content' and 'header' tables */
	lua_newtable(L); /*  {}                                      (sp += 1) */
	lua_setfield(L, -2, "content"); /* content = {}              (sp -= 1) */

	lua_newtable(L); /*  {}                                      (sp += 1) */
	lua_setfield(L, -2, "header"); /* header = {}                (sp -= 1) */

	lua_pushinteger(L, MAGNET_RESTART_REQUEST);
	lua_setfield(L, -2, "RESTART_REQUEST");

	lua_pushcfunction(L, magnet_stat);                        /* (sp += 1) */
	lua_setfield(L, -2, "stat"); /* -1 is the env we want to set (sp -= 1) */

	lua_setfield(L, -2, "lighty"); /* lighty.*                   (sp -= 1) */

	lua_newtable(L); /* the meta-table for the new env           (sp += 1) */
	lua_pushvalue(L, LUA_GLOBALSINDEX);                       /* (sp += 1) */
	lua_setfield(L, -2, "__index"); /* { __index = _G }          (sp -= 1) */
	lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) (sp -= 1) */


	lua_setfenv(L, -2); /* on the stack should be a modified env (sp -= 1) */

	if (lua_pcall(L, 0, 1, 0)) {
		log_error_write(srv, __FILE__, __LINE__,
			"ss",
			"lua_pcall():",
			lua_tostring(L, -1));
		lua_pop(L, 1); /* remove the error-msg and the function copy from the stack */

		assert(lua_gettop(L) == 1); /* only the function should be on the stack */

		con->http_status = 500;
		con->mode = DIRECT;

		return HANDLER_FINISHED;
	}

	/* we should have the function-copy and the return value on the stack */
	assert(lua_gettop(L) == 2);

	if (lua_isnumber(L, -1)) {
		/* if the ret-value is a number, take it */
		lua_return_value = (int)lua_tonumber(L, -1);
	}
	lua_pop(L, 1); /* pop the ret-value */

	magnet_copy_response_header(srv, con, p, L);

	if (lua_return_value > 99) {
		con->http_status = lua_return_value;
		con->file_finished = 1;

		/* try { ...*/
		if (0 == setjmp(exceptionjmp)) {
			magnet_attach_content(srv, con, p, L);
			if (!chunkqueue_is_empty(con->write_queue)) {
				con->mode = p->id;
			}
		} else {
			/* } catch () { */
			con->http_status = 500;
			con->mode = DIRECT;
		}

		assert(lua_gettop(L) == 1); /* only the function should be on the stack */

		/* we are finished */
		return HANDLER_FINISHED;
	} else if (MAGNET_RESTART_REQUEST == lua_return_value) {
		assert(lua_gettop(L) == 1); /* only the function should be on the stack */

		return HANDLER_COMEBACK;
	} else {
		assert(lua_gettop(L) == 1); /* only the function should be on the stack */

		return HANDLER_GO_ON;
	}
}
Example #22
0
TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
{
 if (value == NULL)
  lua_pushnil(L);
 else
 {
  luaL_getmetatable(L, type);
  lua_pushstring(L,"tolua_ubox");
  lua_rawget(L,-2);        /* stack: mt ubox */
  if (lua_isnil(L, -1)) {
	  lua_pop(L, 1);
	  lua_pushstring(L, "tolua_ubox");
	  lua_rawget(L, LUA_REGISTRYINDEX);
  };
  lua_pushlightuserdata(L,value);
  lua_rawget(L,-2);                       /* stack: mt ubox ubox[u] */
  if (lua_isnil(L,-1))
  {
   lua_pop(L,1);                          /* stack: mt ubox */
   lua_pushlightuserdata(L,value);
   *(void**)lua_newuserdata(L,sizeof(void *)) = value;   /* stack: mt ubox u newud */
   lua_pushvalue(L,-1);                   /* stack: mt ubox u newud newud */
   lua_insert(L,-4);                      /* stack: mt newud ubox u newud */
   lua_rawset(L,-3);                      /* stack: mt newud ubox */
   lua_pop(L,1);                          /* stack: mt newud */
   /*luaL_getmetatable(L,type);*/
   lua_pushvalue(L, -2);			/* stack: mt newud mt */
   lua_setmetatable(L,-2);			/* stack: mt newud */

   #ifdef LUA_VERSION_NUM
   lua_pushvalue(L, TOLUA_NOPEER);
   lua_setfenv(L, -2);
   #endif
  }
  else
  {
   /* check the need of updating the metatable to a more specialized class */
   lua_insert(L,-2);                       /* stack: mt ubox[u] ubox */
   lua_pop(L,1);                           /* stack: mt ubox[u] */
   lua_pushstring(L,"tolua_super");
   lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: mt ubox[u] super */
   lua_getmetatable(L,-2);                 /* stack: mt ubox[u] super mt */
   lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] */
			if (lua_istable(L,-1))
			{
				lua_pushstring(L,type);                 /* stack: mt ubox[u] super super[mt] type */
				lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] flag */
				if (lua_toboolean(L,-1) == 1)   /* if true */
				{
					lua_pop(L,3);	/* mt ubox[u]*/
					lua_remove(L, -2);
					return;
				}
			}
			/* type represents a more specilized type */
			/*luaL_getmetatable(L,type);             // stack: mt ubox[u] super super[mt] flag mt */
			lua_pushvalue(L, -5);					/* stack: mt ubox[u] super super[mt] flag mt */
			lua_setmetatable(L,-5);                /* stack: mt ubox[u] super super[mt] flag */
			lua_pop(L,3);                          /* stack: mt ubox[u] */
  }
  lua_remove(L, -2);	/* stack: ubox[u]*/
 }
}
static int
ngx_http_lua_ngx_timer_at(lua_State *L)
{
    int                      nargs, co_ref;
    u_char                  *p;
    lua_State               *mt;  /* the main thread */
    lua_State               *co;
    ngx_msec_t               delay;
    ngx_event_t             *ev;
    ngx_http_request_t      *r;
    ngx_connection_t        *saved_c = NULL;
#if 0
    ngx_http_connection_t   *hc;
#endif

    ngx_http_lua_timer_ctx_t      *tctx;
    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");
    }

    if (ngx_exiting) {
        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");
        }

        lmcf->watcher->fd = -2;  /* to work around the -1 check in
                                    ngx_worker_process_cycle */
        lmcf->watcher->idle = 1;
        lmcf->watcher->read->handler = ngx_http_lua_abort_pending_timers;
        lmcf->watcher->data = lmcf;
    }

    mt = lmcf->lua;

    co = lua_newthread(mt);

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

    ngx_http_lua_probe_user_coroutine_create(r, L, co);

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

    /* co stack: global_tb */

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

    /* co stack: global_tb */

    lua_replace(co, LUA_GLOBALSINDEX);

    /* co stack: <empty> */

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

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

    /* L stack: time func [args] thread */
    /* mt 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 */

    lua_pushvalue(co, LUA_GLOBALSINDEX);
    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) {
        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");
    }

    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;

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

    lmcf->pending_timers++;

    ngx_add_timer(ev, delay);

    lua_pushinteger(L, 1);
    return 1;
}
Example #24
0
static void
commit_lua_upload(indigo_cxn_id_t cxn_id, of_object_t *msg)
{
    uint16_t flags;
    of_bsn_lua_upload_flags_get(msg, &flags);

    /* TODO use stronger hash function */
    uint32_t new_checksum = murmur_hash(xbuf_data(&upload_chunks),
                                        xbuf_length(&upload_chunks),
                                        0);
    if (!(flags & OFP_BSN_LUA_UPLOAD_FORCE) && checksum == new_checksum) {
        AIM_LOG_VERBOSE("Skipping Lua commit, checksums match");
        goto cleanup;
    }

    checksum = 0;

    reset_lua();

    uint32_t offset = 0;
    while (offset < xbuf_length(&upload_chunks)) {
        struct upload_chunk *chunk = xbuf_data(&upload_chunks) + offset;
        offset += sizeof(*chunk) + chunk->size;

        AIM_LOG_VERBOSE("Loading Lua chunk %s, %u bytes", chunk->filename, chunk->size);

        char name[64];
        snprintf(name, sizeof(name), "=%s", chunk->filename);

        if (luaL_loadbuffer(lua, chunk->data, chunk->size, name) != 0) {
            AIM_LOG_ERROR("Failed to load code: %s", lua_tostring(lua, -1));
            indigo_cxn_send_error_reply(
                cxn_id, msg, OF_ERROR_TYPE_BAD_REQUEST, OF_REQUEST_FAILED_EPERM);
            goto cleanup;
        }

        /* Set the environment of the new chunk to the sandbox */
        lua_getglobal(lua, "sandbox");
        lua_setfenv(lua, -2);

        if (lua_pcall(lua, 0, 1, 0) != 0) {
            AIM_LOG_ERROR("Failed to execute code %s: %s", chunk->filename, lua_tostring(lua, -1));
            indigo_cxn_send_error_reply(
                cxn_id, msg, OF_ERROR_TYPE_BAD_REQUEST, OF_REQUEST_FAILED_EPERM);
            goto cleanup;
        }

        /* Save the return value in the "modules" table, used by require */
        char *module_name = aim_strdup(chunk->filename);
        char *dot = strrchr(module_name, '.');
        if (dot) *dot = 0; /* strip file extension */
        lua_getglobal(lua, "modules");
        lua_pushstring(lua, module_name);
        lua_pushvalue(lua, -3); /* return value from pcall */
        lua_rawset(lua, -3); /* modules[filename] = return_value */
        lua_pop(lua, 2); /* pop modules and return value */
        free(module_name);
    }

    checksum = new_checksum;

cleanup:
    cleanup_lua_upload();
    return;
}
Example #25
0
JNIEXPORT jint JNICALL Java_m_lua_Lua_setFEnv
		(JNIEnv* env, jobject thiz, jlong nativeObj, jint idx) {
	pushJNIEnv(env, nativeObj);
	return (jint) lua_setfenv((lua_State*) nativeObj, idx);
}
Example #26
0
int LuaParser::Include(lua_State* L)
{
	if (currentParser == NULL) {
		luaL_error(L, "invalid call to Include() after execution");
	}

	// filename [, fenv]
	const string filename = luaL_checkstring(L, 1);
	if (!LuaIO::IsSimplePath(filename)) {
		luaL_error(L, "bad pathname");
	}
	string modes = luaL_optstring(L, 3, currentParser->accessModes.c_str());
	modes = CFileHandler::AllowModes(modes, currentParser->accessModes);

	CFileHandler fh(filename, modes);
	if (!fh.FileExists()) {
		char buf[1024];
		SNPRINTF(buf, sizeof(buf),
		         "Include() file missing '%s'\n", filename.c_str());
		lua_pushstring(L, buf);
 		lua_error(L);
	}

	string code;
	if (!fh.LoadStringData(code)) {
		char buf[1024];
		SNPRINTF(buf, sizeof(buf),
		         "Include() could not load '%s'\n", filename.c_str());
		lua_pushstring(L, buf);
 		lua_error(L);
	}

	int error = luaL_loadbuffer(L, code.c_str(), code.size(), filename.c_str());
	if (error != 0) {
		char buf[1024];
		SNPRINTF(buf, sizeof(buf), "error = %i, %s, %s\n",
		         error, filename.c_str(), lua_tostring(L, -1));
		lua_pushstring(L, buf);
		lua_error(L);
	}

	// set the chunk's fenv to the current fenv, or a user table
	if (lua_istable(L, 2)) {
		lua_pushvalue(L, 2); // user fenv
	} else {
		LuaUtils::PushCurrentFuncEnv(L, __FUNCTION__);
	}

	// set the include fenv to the current function's fenv
	if (lua_setfenv(L, -2) == 0) {
		luaL_error(L, "Include(): error with setfenv");
	}

	const int paramTop = lua_gettop(L) - 1;

	error = lua_pcall(L, 0, LUA_MULTRET, 0);

	if (error != 0) {
		char buf[1024];
		SNPRINTF(buf, sizeof(buf), "error = %i, %s, %s\n",
		         error, filename.c_str(), lua_tostring(L, -1));
		lua_pushstring(L, buf);
		lua_error(L);
	}

	currentParser->accessedFiles.insert(StringToLower(filename));

	return lua_gettop(L) - paramTop;
}
Example #27
0
/*
** copy 'ktable' of element 'idx' to new tree (on top of stack)
*/
static void copyktable (lua_State *L, int idx) {
  lua_getfenv(L, idx);
  lua_setfenv(L, -2);
}
Example #28
0
TOLUA_API int toluafix_remove_ccobject_by_refid(lua_State* L, int refid)
{
	void* ptr = NULL;
    const char* type = NULL;
    void** ud = NULL;
    if (refid == 0) return -1;
    
    // get ptr from tolua_refid_ptr_mapping
    lua_pushstring(L, TOLUA_REFID_PTR_MAPPING);
    lua_rawget(L, LUA_REGISTRYINDEX);                               /* stack: refid_ptr */
    lua_pushinteger(L, refid);                                      /* stack: refid_ptr refid */
    lua_rawget(L, -2);                                              /* stack: refid_ptr ptr */
    ptr = lua_touserdata(L, -1);
    lua_pop(L, 1);                                                  /* stack: refid_ptr */
    if (ptr == NULL)
    {
        lua_pop(L, 1);
        // Lua stack has closed, C++ object not in Lua.
        // printf("[LUA ERROR] remove CCObject with NULL ptr, refid: %d\n", refid);
        return -2;
    }
    
    // remove ptr from tolua_refid_ptr_mapping
    lua_pushinteger(L, refid);                                      /* stack: refid_ptr refid */
    lua_pushnil(L);                                                 /* stack: refid_ptr refid nil */
    lua_rawset(L, -3);                     /* delete refid_ptr[refid], stack: refid_ptr */
    lua_pop(L, 1);                                                  /* stack: - */
    
    
    // get type from tolua_refid_type_mapping
    lua_pushstring(L, TOLUA_REFID_TYPE_MAPPING);
    lua_rawget(L, LUA_REGISTRYINDEX);                               /* stack: refid_type */
    lua_pushinteger(L, refid);                                      /* stack: refid_type refid */
    lua_rawget(L, -2);                                              /* stack: refid_type type */
    if (lua_isnil(L, -1))
    {
        lua_pop(L, 2);
        printf("[LUA ERROR] remove CCObject with NULL type, refid: %d, ptr: %p\n", refid, ptr);
        return -1;
    }
    
    type = lua_tostring(L, -1);
    lua_pop(L, 1);                                                  /* stack: refid_type */
    
    // remove type from tolua_refid_type_mapping
    lua_pushinteger(L, refid);                                      /* stack: refid_type refid */
    lua_pushnil(L);                                                 /* stack: refid_type refid nil */
    lua_rawset(L, -3);                    /* delete refid_type[refid], stack: refid_type */
    lua_pop(L, 1);                                                  /* stack: - */
    
    // get ubox
    luaL_getmetatable(L, type);                                     /* stack: mt */
    lua_pushstring(L, "tolua_ubox");                                /* stack: mt key */
    lua_rawget(L, -2);                                              /* stack: mt ubox */
    if (lua_isnil(L, -1))
    {
        // use global ubox
        lua_pop(L, 1);                                              /* stack: mt */
        lua_pushstring(L, "tolua_ubox");                            /* stack: mt key */
        lua_rawget(L, LUA_REGISTRYINDEX);                           /* stack: mt ubox */
    };
    
    
    // cleanup root
    tolua_remove_value_from_root(L, ptr);
    
    lua_pushlightuserdata(L, ptr);                                  /* stack: mt ubox ptr */
    lua_rawget(L,-2);                                               /* stack: mt ubox ud */
    if (lua_isnil(L, -1))
    {
        // Lua object has released (GC), C++ object not in ubox.
        //printf("[LUA ERROR] remove CCObject with NULL ubox, refid: %d, ptr: %x, type: %s\n", refid, (int)ptr, type);
        lua_pop(L, 3);
        return -3;
    }

    // cleanup peertable
    lua_pushvalue(L, LUA_REGISTRYINDEX);
    lua_setfenv(L, -2);

    ud = (void**)lua_touserdata(L, -1);
    lua_pop(L, 1);                                                  /* stack: mt ubox */
    if (ud == NULL)
    {
        printf("[LUA ERROR] remove CCObject with NULL userdata, refid: %d, ptr: %p, type: %s\n", refid, ptr, type);
        lua_pop(L, 2);
        return -1;
    }
    
    // clean userdata
    *ud = NULL;
    
    lua_pushlightuserdata(L, ptr);                                  /* stack: mt ubox ptr */
    lua_pushnil(L);                                                 /* stack: mt ubox ptr nil */
    lua_rawset(L, -3);                             /* ubox[ptr] = nil, stack: mt ubox */
    
    lua_pop(L, 2);
    //printf("[LUA] remove CCObject, refid: %d, ptr: %x, type: %s\n", refid, (int)ptr, type);
    return 0;
}
static ngx_int_t
ngx_http_lua_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r)
{
    int                      co_ref;
    lua_State               *co;
    ngx_int_t                rc;
    ngx_connection_t        *c;
    ngx_http_lua_ctx_t      *ctx;
    ngx_http_cleanup_t      *cln;

    ngx_http_lua_loc_conf_t     *llcf;

    /*  {{{ new coroutine to handle request */
    co = ngx_http_lua_new_thread(r, L, &co_ref);

    if (co == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "lua: failed to create new coroutine to handle request");

        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    /*  move code closure to new coroutine */
    lua_xmove(L, co, 1);

    /*  set closure's env table to new coroutine's globals table */
    lua_pushvalue(co, LUA_GLOBALSINDEX);
    lua_setfenv(co, -2);

    /*  save nginx request in coroutine globals table */
    lua_pushlightuserdata(co, &ngx_http_lua_request_key);
    lua_pushlightuserdata(co, r);
    lua_rawset(co, LUA_GLOBALSINDEX);
    /*  }}} */

    /*  {{{ initialize request context */
    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);

    dd("ctx = %p", ctx);

    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ngx_http_lua_reset_ctx(r, L, ctx);

    ctx->entered_rewrite_phase = 1;

    ctx->cur_co_ctx = &ctx->entry_co_ctx;
    ctx->cur_co_ctx->co = co;
    ctx->cur_co_ctx->co_ref = co_ref;

    /*  }}} */

    /*  {{{ register request cleanup hooks */
    if (ctx->cleanup == NULL) {
        cln = ngx_http_cleanup_add(r, 0);
        if (cln == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        cln->handler = ngx_http_lua_request_cleanup;
        cln->data = r;
        ctx->cleanup = &cln->handler;
    }
    /*  }}} */

    ctx->context = NGX_HTTP_LUA_CONTEXT_REWRITE;

    llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);

    if (llcf->check_client_abort) {
        r->read_event_handler = ngx_http_lua_rd_check_broken_connection;

    } else {
        r->read_event_handler = ngx_http_block_reading;
    }

    rc = ngx_http_lua_run_thread(L, r, ctx, 0);

    if (rc == NGX_ERROR || rc > NGX_OK) {
        return rc;
    }

    c = r->connection;

    if (rc == NGX_AGAIN) {
        rc = ngx_http_lua_run_posted_threads(c, L, r, ctx);

        if (rc == NGX_OK) {
            return NGX_DECLINED;
        }

        return rc;
    }

    if (rc == NGX_DONE) {
        ngx_http_finalize_request(r, NGX_DONE);
        rc = ngx_http_lua_run_posted_threads(c, L, r, ctx);

        if (rc == NGX_OK) {
            return NGX_DECLINED;
        }

        return rc;
    }

    return NGX_DECLINED;
}
Example #30
0
static int new_check (lua_State *L) {
  int ret = 0;
  libuv_check_t *check = NULL;
  uv_check_t *uvcheck = NULL;
  libuv_loop_t *loop = NULL;

  /* [ userdata ] */
  /* DUMP_STACK(L); */

  TRACE("arguments: L = %p\n", L);
  assert(L != NULL);

  /* get first argument */
  loop = (libuv_loop_t *)lua_touserdata(L, 1); /* [userdata ] */
  if (loop == NULL) {
    /* TODO: error */
    return 0;
  }
  TRACE("get libuv_loop_t (%p)\n", loop);
  assert(loop->uvloop != NULL);
  lua_pop(L, 1); /* [ ] */
  assert(lua_gettop(L) == 0);

  /* create libuv_check_t */
  check = (libuv_check_t *)lua_newuserdata(L, sizeof(libuv_check_t)); /* [ userdata ] */
  if (check == NULL) {
    /* TODO: error */
    return 0;
  }
  TRACE("create libuv_check_t (%p)\n", check);
  assert(check != NULL);

  /* create uv_check_t */
  uvcheck = (uv_check_t *)malloc(sizeof(uv_check_t));
  if (uvcheck == NULL) {
    /* TODO: error */
    return 0;
  }
  TRACE("create uv_check_t (%p)\n", uvcheck);
  assert(uvcheck != NULL);

  /* libuv_check_t settings */
  check->uvcheck = uvcheck;
  check->L = L;
  check->ref = LUA_NOREF;

  /* set envriment table to userdata */
  lua_newtable(L); /* [ userdata, table ] */
  lua_setfenv(L, -2); /* [ userdata ] */
  assert(lua_gettop(L) == 1);

  /* set metatable */
  luaL_getmetatable(L, CHECK_T); /* [ userdata, metatable ] */
  lua_setmetatable(L, -2); /* [ userdata ] */
  TRACE("set metatable to userdata\n");

  /* initialize check */
  ret = uv_check_init(loop->uvloop, check->uvcheck);
  if (ret) {
    /* TODO: error */
    return 0;
  }
  TRACE("uv_check_init: ret = %d\n", ret);

  /* return userdata */
  return 1;
}