Exemplo n.º 1
0
/** Set function environment.
 * Sets the table on top of the stack as environment of the function
 * at the given stack index.
 * @param idx stack index of function
 */
void
LuaContext::setfenv(int idx)
{
#if LUA_VERSION_NUM > 501
  //                                         stack: ... func@idx ... env
  // find _ENV
  int n = 0;
  const char *val_name;
  while ((val_name = lua_getupvalue(__L, idx, ++n)) != NULL) {  // ... env upval
    if (strcmp(val_name, "_ENV") == 0) {
      // found environment
      break;
    } else {
      // we're not interested, remove value from stack
      lua_pop(__L, 1);                                          // ... env
    }
  }

  // found an environment
  if (val_name != NULL) {                                       // ... env upval
    // create a new simple up value
    luaL_loadstring(__L, "");                                   // ... env upval chunk
    lua_pushvalue(__L, -3);                                     // ... env upval chunk env
    lua_setupvalue(__L, -2, 1);                                 // ... env upval func
    int act_idx = idx > 0 ? idx : idx - 2;
    lua_upvaluejoin(__L, act_idx, n, -1, 1);                        // ... env upval chunk
    lua_pop(__L, 3);                                            // ...
  } else {
    throw Exception("No environment found");
  }
#else
  lua_setfenv(__L, idx);
#endif
}
Exemplo n.º 2
0
static int db_upvaluejoin (lua_State *L) {
  int n1 = checkupval(L, 1, 2);
  int n2 = checkupval(L, 3, 4);
  luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
  luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
  lua_upvaluejoin(L, 1, n1, 3, n2);
  return 0;
}
Exemplo n.º 3
0
int luaT_setfenv52(lua_State *L, int iIndex)
{
    int iType = lua_type(L, iIndex);
    switch(iType)
    {
    case LUA_TUSERDATA:
        lua_setuservalue(L, iIndex);
        return 1;
    case LUA_TFUNCTION:
        if(lua_iscfunction(L, iIndex))
        {
            // Our convention: upvalue at #1 is environment
            if(lua_setupvalue(L, iIndex, 1) == nullptr)
            {
                lua_pop(L, 1);
                return 0;
            }
            return 1;
        }
        else
        {
            // Language convention: upvalue called _ENV is environment, which
            // might be shared with other functions.
            const char* sUpName = nullptr;
            for(int i = 1; (sUpName = lua_getupvalue(L, iIndex, i)) ; ++i)
            {
                lua_pop(L, 1); // lua_getupvalue puts the value on the stack, but we just want to replace it
                if(std::strcmp(sUpName, "_ENV") == 0)
                {
                    luaL_loadstring(L, "local upv = ... return function() return upv end");
                    lua_insert(L, -2);
                    lua_call(L, 1, 1);
                    lua_upvaluejoin(L, iIndex, i, -1, 1);
                    lua_pop(L, 1);
                    return 1;
                }
            }
            lua_pop(L, 1);
            return 0;
        }
    default:
        return 0;
    }
}
Exemplo n.º 4
0
void LuaDebug::UpvalueJoin(int funcindex1, int n1, int funcindex2, int n2) const
{
	return lua_upvaluejoin(L(), funcindex1, n1, funcindex2, n2);
}