コード例 #1
0
// __index metamethod handler.
// For proxied tables, return proxies of children, preferably cached
// For proxied strings, return methods
static int l_str_index(lua_State *L)
{
    // Look up cached value, and return it if present
    aux_push_weak_table(L, 1);
    lua_pushvalue(L, 1);
    lua_gettable(L, 3);
    lua_replace(L, 3);
    lua_pushvalue(L, 2);
    lua_rawget(L, 3);
    if(!lua_isnil(L, 4))
        return 1;
    lua_pop(L, 1);

    // Fetch the proxied value
    aux_push_weak_table(L, 0);
    lua_pushvalue(L, 1);
    lua_rawget(L, 4);
    lua_replace(L, 4);

    // Handle string methods
    if(lua_type(L, 4) == LUA_TSTRING)
    {
        lua_rawgeti(L, luaT_environindex, 4);
        lua_pushvalue(L, 2);
        lua_gettable(L, 5);
        return 1;
    }

    // Handle __random, as it shouldn't be cached
    if(lua_type(L, 2) == LUA_TSTRING)
    {
        size_t iLen;
        const char* sKey = lua_tolstring(L, 2, &iLen);
        if(iLen == 8 && strcmp(sKey, "__random") == 0)
        {
            aux_push_random_key(L);
            lua_replace(L, 2);
            lua_settop(L, 2);
            return l_str_index(L);
        }
    }

    // Fetch desired value
    lua_pushvalue(L, 2);
    lua_gettable(L, 4);
    lua_replace(L, 4);

    // Create new userdata proxy
    l_str_new_aux(L);
    aux_mk_table(L, 0, 2, 1, 2);
    lua_setfenv(L, 4);

    // Save to cache and return
    lua_pushvalue(L, 2);
    lua_pushvalue(L, 4);
    lua_rawset(L, 3);
    return 1;
}
コード例 #2
0
ファイル: th_lua_strings.cpp プロジェクト: tobylane/CorsixTH
// Create a new root-level userdata proxy
static int l_str_new(lua_State *L)
{
    // Pack extra arguments into a table
    int iNArgs = lua_gettop(L);
    lua_createtable(L, iNArgs - 2, 0);
    lua_replace(L, 1); // Value inserted by __call
    for(int i = iNArgs; i >= 3; --i)
        lua_rawseti(L, 1, i - 2);

    // Make proxy
    luaL_checkany(L, 2);
    l_str_new_aux(L);

    // Save extra arguments as reconstruction information
    lua_insert(L, 1);
    lua_setfenv(L, 1);
    return 1;
}
コード例 #3
0
ファイル: th_lua_strings.cpp プロジェクト: tobylane/CorsixTH
// Generic string method handler
// The name of the method is stored at upvalue 1
static int l_str_func(lua_State *L)
{
    int iArgCount = lua_gettop(L);
    lua_checkstack(L, iArgCount + 10);

    int iUserdataCount = 0;

    // Construct the resulting value
    aux_push_weak_table(L, 0);
    for(int i = 1; i <= iArgCount; ++i)
    {
        lua_pushvalue(L, i);
        if(lua_type(L, i) == LUA_TUSERDATA)
        {
            lua_rawget(L, iArgCount + 1);
            ++iUserdataCount;
        }
    }
    lua_pushvalue(L, luaT_upvalueindex(1));
    lua_gettable(L, iArgCount + 2);
    lua_replace(L, iArgCount + 1);
    lua_call(L, iArgCount, 1);

    // Trivial case of result not depending upon any proxies
    if(iUserdataCount == 0)
        return 1;

    // Wrap result in a proxy
    l_str_new_aux(L);

    // Create and save reconstruction information
    lua_createtable(L, iArgCount + 1, 0);
    lua_pushvalue(L, luaT_upvalueindex(1));
    lua_rawseti(L, -2, 1);
    for(int i = 1; i <= iArgCount; ++i)
    {
        lua_pushvalue(L, i);
        lua_rawseti(L, -2, i + 1);
    }
    lua_setfenv(L, -2);

    return 1;
}