예제 #1
0
wxString wxLuaCheckStack::DumpStack(const wxString& msg)
{
    wxCHECK_MSG(m_luaState, wxEmptyString, wxT("Invalid lua_State"));

    lua_State* L = m_luaState;
    int i, count = lua_gettop(L);
    wxString str;
    wxString retStr;

    str.Printf(wxT("wxLuaCheckStack::DumpStack(L=%p), '%s':'%s', items %d, starting top %d\n"), L, m_msg.c_str(), msg.c_str(), count, m_top);
    retStr += str;
    OutputMsg(str);

    wxLuaState wxlState(L);

    for (i = 1; i <= count; i++)
    {
        int wxl_type = 0;
        wxString value;
        int l_type = wxLuaDebugData::GetTypeValue(L, i, &wxl_type, value);

        str.Printf(wxT("  idx %d: l_type = %d, wxl_type = %d : '%s'='%s'\n"),
                i, l_type, wxl_type, wxluaT_typename(L, wxl_type).c_str(), value.c_str());
        retStr += str;
        OutputMsg(str);
    }

    return retStr;
}
// %override wxLua_function_typename
// %function wxString typename(int wxluaarg_tag)
static int LUACALL wxLua_function_typename(lua_State *L)
{
    // int wxluaarg_tag
    int wxl_type = (int)wxlua_getnumbertype(L, 1);
    // call wxlua_getwxluatypename
    wxString returns = wxluaT_typename(L, wxl_type);
    // push the result string
    wxlua_pushwxString(L, returns);

    return 1;
}
예제 #3
0
wxString wxLuaDebugData::GetUserDataInfo(lua_State *L, int stack_idx, bool full_userdata)
{
    wxCHECK_MSG(L, wxEmptyString, wxT("Invalid lua_State"));

    void* udata = lua_touserdata(L, stack_idx);

    wxString s(wxString::Format(wxT("%p"), udata));

    if (!full_userdata)
    {
        // Convert our known keys to something more readable
        if ((udata == &wxlua_lreg_types_key) ||
            (udata == &wxlua_lreg_refs_key) ||
            (udata == &wxlua_lreg_debug_refs_key) ||
            (udata == &wxlua_lreg_classes_key) ||
            (udata == &wxlua_lreg_derivedmethods_key) ||
            (udata == &wxlua_lreg_wxluastate_key) ||
            (udata == &wxlua_lreg_wxluabindings_key) ||
            (udata == &wxlua_lreg_weakobjects_key) ||
            (udata == &wxlua_lreg_gcobjects_key) ||
            (udata == &wxlua_lreg_evtcallbacks_key) ||
            (udata == &wxlua_lreg_windestroycallbacks_key) ||
            (udata == &wxlua_lreg_callbaseclassfunc_key) ||
            (udata == &wxlua_lreg_wxeventtype_key) ||
            (udata == &wxlua_lreg_wxluastatedata_key) ||
            (udata == &wxlua_lreg_regtable_key) ||

            (udata == &wxlua_metatable_type_key) ||
            (udata == &wxlua_lreg_topwindows_key) ||
            (udata == &wxlua_metatable_wxluabindclass_key))
        {
            const char* ss = *(const char**)udata;
            s += wxString::Format(wxT(" (%s)"), lua2wx(ss).c_str());
        }
    }
    else // is full userdata
    {
        int wxl_type = wxluaT_type(L, stack_idx);

        if (wxlua_iswxuserdatatype(wxl_type))
        {
            s += wxString::Format(wxT(" (wxltype %d)"), wxl_type);

            wxString wxltypeName(wxluaT_typename(L, wxl_type));
            if (!wxltypeName.IsEmpty())
                s += wxString::Format(wxT(" '%s'"), wxltypeName.c_str());
        }
    }

    return s;
}
// %override wxLua_function_type
// %function int type(int wxluaarg_tag)
static int LUACALL wxLua_function_type(lua_State *L)
{
    int ltype = lua_type(L, 1);
    const char* ltypename = lua_typename(L, ltype);

    int wxl_type = wxluaT_type(L, 1);
    wxString wxltypeName = wxluaT_typename(L, wxl_type);

    // push the results
    lua_pushstring(L, wx2lua(wxltypeName));
    lua_pushnumber(L, wxl_type);

    lua_pushstring(L, ltypename);
    lua_pushnumber(L, ltype);

    return 4;
}
예제 #5
0
wxString wxLuaCheckStack::DumpTable(int stack_idx, const wxString& tablename, const wxString& msg, wxSortedArrayString& tableArray, int indent)
{
    wxCHECK_MSG(m_luaState, wxEmptyString, wxT("Invalid lua_State"));

    lua_State* L = m_luaState;
    wxLuaState wxlState(L);
    wxString indentStr;
    wxString s;

    // We only do tables, return error message
    if (!lua_istable(L, stack_idx))
    {
        s.Printf(wxT("wxLuaCheckStack::DumpTable(L=%p) stack idx %d is not a table.\n"), L, stack_idx);
        OutputMsg(s);
        return s;
    }

    if (indent == 0)
    {
        // First time through print header
        s.Printf(wxT("wxLuaCheckStack::DumpTable(L=%p) Table: '%s'\n"), L, tablename.c_str());
        OutputMsg(s);
    }
    else if (indent > 10)
    {
        // Don't let things get out of hand...
        s.Printf(wxT("wxLuaCheckStack::DumpTable(L=%p) Table depth > 10! Truncating: '%s'\n"), L, tablename.c_str());
        OutputMsg(s);
        return s;
    }
    else
    {
        indentStr = wxString(wxT(' '), indent*2) + wxT(">");
    }

    wxString title = wxString::Format(wxT("%sTable Level %d : name '%s'\n"), indentStr.c_str(), indent, tablename.c_str());
    s += title;
    OutputMsg(title);

    lua_pushvalue(L, stack_idx); // push the table to read the top of the stack

    lua_pushnil(L);
    while (lua_next(L, -2) != 0)
    {
        int keyType = 0, valueType = 0;
        wxString key, value;

        wxLuaDebugData::GetTypeValue(L, -2, &keyType,   key);
        wxLuaDebugData::GetTypeValue(L, -1, &valueType, value);

        wxString info = wxString::Format(wxT("%s%-32s\t%-16s\t%-20s\t%-16s\n"),
                indentStr.c_str(), key.c_str(), wxluaT_typename(L, keyType).c_str(), value.c_str(), wxluaT_typename(L, valueType).c_str());
        s += info;
        OutputMsg(info);

        if (tableArray.Index(value) == wxNOT_FOUND)
        {
            if (valueType == WXLUA_TTABLE)
            {
                tableArray.Add(value);
                s += DumpTable(lua_gettop(L), tablename + wxT(".") + key, msg, tableArray, indent+1);
            }
            else
            {
                tableArray.Add(value);
            }
        }

        lua_pop(L, 1); // pop value
    }

    lua_pop(L, 1); // pop pushed table

    return s;
}
예제 #6
0
int wxLuaDebugData::EnumerateTable(lua_State* L, int tableRef, int nIndex, wxArrayInt& references)
{
    wxCHECK_MSG(L, 0, wxT("Invalid lua_State"));
    wxCHECK_MSG(M_DEBUGREFDATA != NULL, 0, wxT("Invalid ref data"));

    int count = 0;

    int wxl_keytype   = WXLUA_TNONE;
    int wxl_valuetype = WXLUA_TNONE;
    wxString value;
    wxString name;

    if (tableRef == LUA_GLOBALSINDEX)
    {
        lua_pushglobaltable(L);
        GetTypeValue(L, -1, &wxl_valuetype, value);

        int flag_type = 0;
        int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
        lua_pop(L, 1); // pop globals table

        Add(new wxLuaDebugItem(wxT("Globals"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type));
    }
#if LUA_VERSION_NUM < 502
    // LUA_ENVIRONINDEX is no longer in 5.2
    else if (tableRef == LUA_ENVIRONINDEX)
    {
        lua_pushvalue(L, LUA_ENVIRONINDEX);
        GetTypeValue(L, -1, &wxl_valuetype, value);

        int flag_type = 0;
        int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
        lua_pop(L, 1); // pop environment table

        Add(new wxLuaDebugItem(wxT("Environment"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type));
    }
#endif // LUA_VERSION_NUM < 502
    else if (tableRef == LUA_REGISTRYINDEX)
    {
        lua_pushvalue(L, LUA_REGISTRYINDEX);
        GetTypeValue(L, -1, &wxl_valuetype, value);

        int flag_type = 0;
        int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
        lua_pop(L, 1); // pop registry table

        Add(new wxLuaDebugItem(wxT("Registry"), WXLUA_TNONE, value, WXLUA_TTABLE, wxEmptyString, val_ref, 0, flag_type));
    }
    else
    {
        // push the table onto the stack to iterate through
        if (wxluaR_getref(L, tableRef, &wxlua_lreg_debug_refs_key))
        {
            if (lua_isnil(L, -1))
            {
                // assert so we don't crash mysteriously inside Lua on nil
                lua_pop(L, 1); // pop nil
                wxFAIL_MSG(wxT("Invalid wxLua debug reference"));
                return count;
            }

            // Check to see if this is a wxLua LUA_REGISTRYINDEX table
            void *lightuserdata_reg_key = NULL;
            lua_pushlightuserdata(L, &wxlua_lreg_regtable_key); // push key
            lua_rawget(L, LUA_REGISTRYINDEX);
            lua_pushvalue(L, -2); // push value (table we're iterating)
            lua_rawget(L, -2);
            lightuserdata_reg_key = lua_touserdata(L, -1); // returns NULL for nil
            lua_pop(L, 2); // pop wxlua_lreg_regtable_key table and (nil or lightuserdata)

            // Check if this table/userdata has a metatable
            if (lua_getmetatable(L, -1)) // if no metatable then nothing is pushed
            {
                // get the type and value
                GetTypeValue(L, -1, &wxl_valuetype, value);

                int flag_type = 0;
                int val_ref = RefTable(L, -1, &flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);

                // leading space so it's first when sorted
                Add(new wxLuaDebugItem(wxT(" __metatable"), WXLUA_TTABLE, value, wxl_valuetype, wxEmptyString, val_ref, nIndex, flag_type));
                ++count;

                lua_pop(L, 1); // pop metatable
            }

            // start iterating
            if (lua_istable(L, -1))
            {
            lua_pushnil(L);
            while (lua_next(L, -2) != 0)
            {
                // value at -1, key at -2, table at -3

                // get the key type and value
                int lua_key_type = GetTypeValue(L, -2, &wxl_keytype, name);
                // get the value type and value
                int lua_value_type = GetTypeValue(L, -1, &wxl_valuetype, value);

                // Handle items within the wxLua LUA_REGISTRYINDEX tables to give more information
                if (lightuserdata_reg_key != NULL)
                {
                    if (lightuserdata_reg_key == &wxlua_lreg_types_key)
                    {
                        value += wxString::Format(wxT(" (%s)"), wxluaT_typename(L, (int)lua_tonumber(L, -2)).c_str());
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_classes_key)
                    {
                        wxLuaBindClass* wxlClass = (wxLuaBindClass*)lua_touserdata(L, -1);
                        value += wxLuaBindClassString(wxlClass);
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_wxluabindings_key)
                    {
                        wxLuaBinding* binding = (wxLuaBinding*)lua_touserdata(L, -2);
                        name = wxString::Format(wxT("wxLuaBinding(%s) -> %s"), name.c_str(), binding->GetBindingName().c_str());
                        value += wxT(" = ") + binding->GetLuaNamespace();
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_evtcallbacks_key)
                    {
                        wxLuaEventCallback* wxlCallback = (wxLuaEventCallback*)lua_touserdata(L, -2);
                        wxCHECK_MSG(wxlCallback, count, wxT("Invalid wxLuaEventCallback"));

                        wxString s(wxlCallback->GetInfo());
                        name  = s.BeforeFirst(wxT('|'));
                        value = s.AfterFirst(wxT('|'));
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_windestroycallbacks_key)
                    {
                        // only handle t[wxWindow*] = wxLuaWinDestroyCallback*
                        wxLuaWinDestroyCallback* wxlDestroyCallBack = (wxLuaWinDestroyCallback*)lua_touserdata(L, -1);
                        wxCHECK_MSG(wxlDestroyCallBack, count, wxT("Invalid wxLuaWinDestroyCallback"));

                        wxString s(wxlDestroyCallBack->GetInfo());
                        name  = s.BeforeFirst(wxT('|'));
                        value = s.AfterFirst(wxT('|'));
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_topwindows_key)
                    {
                        wxWindow* win = (wxWindow*)lua_touserdata(L, -2);
                        name += wxT(" ") + wxString(win->GetClassInfo()->GetClassName());
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_gcobjects_key)
                    {
                        int wxl_type_ = (int)lua_tonumber(L, -1);
                        name = wxString::Format(wxT("%s(%s)"), wxluaT_typename(L, wxl_type_).c_str(), name.c_str());
                    }
                    else if (lightuserdata_reg_key == &wxlua_lreg_weakobjects_key)
                    {
                        wxString names_weak;

                        // iterate the table of userdata
                        lua_pushnil(L);
                        while (lua_next(L, -2) != 0)
                        {
                            // value = -1, key = -2, table = -3
                            int wxl_type_weak = (int)lua_tonumber(L, -2);
                            if (!names_weak.IsEmpty()) names_weak += wxT(", ");
                            names_weak += wxString::Format(wxT("%s(%d)"), wxluaT_typename(L, wxl_type_weak).c_str(), wxl_type_weak);
                            lua_pop(L, 1); // pop value, lua_next will pop key at end
                        }

                        name = wxString::Format(wxT("%s (%s)"), names_weak.c_str(), name.c_str());
                    }
                }

                // For these keys we know what is in the value to give more information
                if (lua_key_type == LUA_TLIGHTUSERDATA)
                {
                    void* key = lua_touserdata(L, -2);

                    if (key == &wxlua_lreg_wxeventtype_key)
                    {
                        wxEventType eventType = (wxEventType)lua_tonumber(L, -1);
                        const wxLuaBindEvent* wxlEvent = wxLuaBinding::FindBindEvent(eventType);

                        if (wxlEvent != NULL)
                        {
                            value = wxString::Format(wxT("%d = %s : %s"), eventType, lua2wx(wxlEvent->name).c_str(), wxluaT_typename(L, *wxlEvent->wxluatype).c_str());
                        }
                    }
                    else if (key == &wxlua_metatable_type_key)
                    {
                        value += wxString::Format(wxT(" (%s)"), wxluaT_typename(L, (int)lua_tonumber(L, -1)).c_str());
                    }
                    else if (key == &wxlua_metatable_wxluabindclass_key)
                    {
                        wxLuaBindClass* wxlClass = (wxLuaBindClass*)lua_touserdata(L, -1);
                        value += wxLuaBindClassString(wxlClass);
                    }
                    else if (key == &wxlua_lreg_debug_refs_key)
                    {
                        value += wxT(" Note: You cannot traverse refed tables");
                    }
                }

                // ----------------------------------------------------------
                // Handle the key

                int key_flag_type = 0;
                int key_ref = LUA_NOREF;

                // don't ref anything in this table since it's already refed
                if ((lua_key_type == LUA_TTABLE) && (lightuserdata_reg_key != &wxlua_lreg_debug_refs_key))
                {
                    key_ref = RefTable(L, -2, &key_flag_type, WXLUA_DEBUGITEM_KEY_REF, references);
                }
                else if (lua_key_type == LUA_TUSERDATA)
                {
                    if (lua_getmetatable(L, -2)) // doesn't push anything if nil
                    {
                        key_ref = RefTable(L, -2, &key_flag_type, WXLUA_DEBUGITEM_KEY_REF, references);
                        lua_pop(L, 1);
                    }
                }

                // only add the key if we refed it so it can be viewed in the stack dialog
                if (key_flag_type != 0)
                {
                    Add(new wxLuaDebugItem(name, wxl_keytype, value, wxl_valuetype, wxEmptyString, key_ref, nIndex, key_flag_type));
                    ++count;
                }

                // ----------------------------------------------------------
                // Handle the value

                int val_flag_type = 0;
                int val_ref = LUA_NOREF;

                // don't ref anything in this table since it's already refed
                if ((lua_value_type == LUA_TTABLE) && (lightuserdata_reg_key != &wxlua_lreg_debug_refs_key))
                {
                    val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
                }
                else if (lua_value_type == LUA_TUSERDATA)
                {
                    if (lua_getmetatable(L, -1)) // doesn't push anything if nil
                    {
                        val_ref = RefTable(L, -1, &val_flag_type, WXLUA_DEBUGITEM_VALUE_REF, references);
                        lua_pop(L, 1);
                    }
                }

                // Add the value, but not if the value doesn't expand and the key was already added
                if ((key_flag_type == 0) || ((key_flag_type != 0) && (val_flag_type != 0)))
                {
                    Add(new wxLuaDebugItem(name, wxl_keytype, value, wxl_valuetype, wxEmptyString, val_ref, nIndex, val_flag_type));
                    ++count;
                }

                lua_pop(L, 1); // pop value, leave key
            }
            }

            lua_pop(L, 1); // remove reference
        }
    }

    return count;
}
예제 #7
0
bool wxLuaDebugTarget::EvaluateExpr(int exprRef, const wxString &strExpr) // FIXME - check this code
{
    wxString strResult(wxT("Error"));
    int      nReference = LUA_NOREF;

    EnterLuaCriticalSection();
    {
        lua_State* L = m_wxlState.GetLuaState();

        if (wxStrpbrk(strExpr.c_str(), wxT(" ~=<>+-*/%(){}[]:;,.\"'")) != NULL)
        {
            // an expression
            int nOldTop = lua_gettop(L);

            wxLuaCharBuffer charbuf(strExpr);
            int nResult = luaL_loadbuffer(L, charbuf.GetData(), charbuf.Length(), "debug");

            if (nResult == 0)
                nResult = lua_pcall(L, 0, LUA_MULTRET, 0);  // call main

            if (nResult != 0)
                wxlua_pushwxString(L, wxlua_LUA_ERR_msg(nResult));

            else if (lua_gettop(L) == nOldTop)
                lua_pushliteral(L, "OK");

            nReference = m_wxlState.wxluaR_Ref(-1, &wxlua_lreg_refs_key);
            lua_settop(L, nOldTop); // throw out all return values
        }
        else
        {
             lua_Debug ar = INIT_LUA_DEBUG;
             int       iLevel = 0;
             bool      fFound = false;

             while (lua_getstack(L, iLevel++, &ar) != 0)
             {
                int       iIndex = 0;
                wxString name = lua2wx(lua_getlocal(L, &ar, ++iIndex));
                if (!name.IsEmpty())
                {
                    if (strExpr == name)
                    {
                        nReference = m_wxlState.wxluaR_Ref(-1, &wxlua_lreg_refs_key);
                        fFound = true;
                        break;
                    }

                    lua_pop(L, 1);
                }

                if (fFound)
                    break;

                name = lua2wx(lua_getlocal(L, &ar, ++iIndex));
             }

             if (!fFound)
             {
                  int nOldTop = lua_gettop(L);
                  lua_pushvalue(L, LUA_GLOBALSINDEX);
                  lua_pushnil(L);
                  while (lua_next(L, -2) != 0)
                  {
                      if (lua_type(L, -2) == LUA_TSTRING)
                      {
                          wxString name = lua2wx(lua_tostring(L, -2));
                          if (strExpr == name)
                          {
                              nReference = m_wxlState.wxluaR_Ref(-1, &wxlua_lreg_refs_key); // reference value
                              lua_pop(L, 2);    // pop key and value
                              fFound = true;
                              break;
                          }
                      }

                      lua_pop(L, 1);  // removes 'value';
                  }
                  lua_settop(L, nOldTop); // the table of globals.
             }
        }

        if (m_wxlState.wxluaR_GetRef(nReference, &wxlua_lreg_refs_key))
        {
            m_wxlState.wxluaR_Unref(nReference, &wxlua_lreg_refs_key);

            int wxl_type = 0;
            wxString value;
            wxLuaDebugData::GetTypeValue(L, -1, &wxl_type, value);

            strResult.Printf(wxT("%s : %s"), wxluaT_typename(L, wxl_type).c_str(), value.c_str());

            lua_pop(L, 1);
        }
    }
    LeaveLuaCriticalSection();

    return NotifyEvaluateExpr(exprRef, strResult);
}