Esempio n. 1
0
static void getlocal (void) {
  lua_Object func = lua_stackedfunction(luaL_check_int(1));
  lua_Object val;
  char *name;
  if (func == LUA_NOOBJECT)  /* level out of range? */
    return;  /* return nil */
  else if (lua_getparam(2) != LUA_NOOBJECT) {  /* 2nd argument? */
    if ((val = lua_getlocal(func, findlocal(func, 2), &name)) != LUA_NOOBJECT) {
      lua_pushobject(val);
      lua_pushstring(name);
    }
    /* else return nil */
  }
  else {  /* collect all locals in a table */
    lua_Object result = lua_createtable();
    int i;
    for (i=1; ;i++) {
      if ((val = lua_getlocal(func, i, &name)) == LUA_NOOBJECT)
        break;
      lua_pushobject(result);
      lua_pushstring(name);
      lua_pushobject(val);
      lua_settable();  /* result[name] = value */
    }
    lua_pushobject(result);
  }
}
Esempio n. 2
0
static int db_getlocal (lua_State *L) {
  int arg;
  lua_State *L1 = getthread(L, &arg);
  lua_Debug ar;
  const char *name;
  int nvar = luaL_checkint(L, arg+2);  /* local-variable index */
  if (lua_isfunction(L, arg + 1)) {  /* function argument? */
    lua_pushvalue(L, arg + 1);  /* push function */
    lua_pushstring(L, lua_getlocal(L, NULL, nvar));  /* push local name */
    return 1;
  }
  else {  /* stack-level argument */
    if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
      return luaL_argerror(L, arg+1, "level out of range");
    name = lua_getlocal(L1, &ar, nvar);
    if (name) {
      lua_xmove(L1, L, 1);  /* push local value */
      lua_pushstring(L, name);  /* push name */
      lua_pushvalue(L, -2);  /* re-order */
      return 2;
    }
    else {
      lua_pushnil(L);  /* no name (nor value) */
      return 1;
    }
  }
}
Esempio n. 3
0
static bool dump_local(struct luadebug_debugger *session, const char *option)
{
	int i;
	const char *local;
	const int index = option ? atoi(option) : -1;

	if (index < 0) {
		session->user->print(session->user, "Locals\n");
		for (i=1; (local = lua_getlocal(session->L, &session->frame, i)); ++i) {
			session->user->print(session->user, "  #%d\t%s = ", i, local);
			pprint(session->L, session->user, -1, false, NULL);
			lua_pop(session->L, 1);
		}
	}
	else {
		local = lua_getlocal(session->L, &session->frame, index);
		if (!local) {
			session->user->print(session->user, RED "invalid local index '%d'\n" CLEAR, index);
		}
		else {
			session->user->print(session->user, "  #%d\t%s = ", index, local);
			pprint(session->L, session->user, -1, true, NULL);
			lua_pop(session->L, 1);
		}
	}

	return false;
}
Esempio n. 4
0
int wxLuaDebugData::EnumerateStackEntry(lua_State* L, int stack_frame, wxArrayInt& references)
{
    wxCHECK_MSG(L, 0, wxT("Invalid lua_State"));
    wxCHECK_MSG(M_DEBUGREFDATA != NULL, 0, wxT("Invalid ref data"));

    lua_Debug luaDebug = INIT_LUA_DEBUG;
    int count = 0;

    if (lua_getstack(L, stack_frame, &luaDebug) != 0)
    {
        int stack_idx  = 1;
        wxString name(lua2wx(lua_getlocal(L, &luaDebug, stack_idx)));

        while (!name.IsEmpty())
        {
            //wxPrintf(wxT("%s lua_getlocal :%s\n"), lua_Debug_to_wxString(luaDebug).c_str(), name.c_str());

            int wxl_valuetype = WXLUA_TNONE;
            wxString value;
            wxString source(lua2wx(luaDebug.source));

            int lua_value_type = GetTypeValue(L, -1, &wxl_valuetype, value);

            int val_flag_type = 0;
            int val_ref = LUA_NOREF;

            if (lua_value_type == LUA_TTABLE)
            {
                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(new wxLuaDebugItem(name, WXLUA_TNONE, value, wxl_valuetype, source, val_ref, 0, val_flag_type));
            ++count;

            lua_pop(L, 1); // remove variable value

            name = lua2wx(lua_getlocal(L, &luaDebug, ++stack_idx));
        }
    }

    return count;
}
Esempio n. 5
0
void set_lua_variable(lua_State *l, char *name, int value)
{
  /* See if there's a local variable that matches the given name.
   * If we find it, then set the value. If not, we'll keep walking back
   * up the stack levels until we've exhausted all of the closures.
   * At that point, set a global instead. */

  lua_Debug ar;
  int stacksize = get_call_stack_size(l);
  int stacklevel,i;

  /* This C call is stacklevel 0; the function that called is, 1; and so on. */
  for (stacklevel=0; stacklevel<stacksize; stacklevel++) {
    const char *local_name;
    lua_getstack(l, stacklevel, &ar);
    lua_getinfo(l, "nSluf", &ar); /* get all the info there is. Could probably be whittled down. */
    i=1;
    while ( (local_name=lua_getlocal(l, &ar, i++)) ) {
      if (!strcmp(name, local_name)) {
	/* Found the local! Set it, and exit. */
	lua_pop(l, 1);              // pop the local's old value
	lua_pushinteger(l, value);  // push the new value
	lua_setlocal(l, &ar, i-1); // set the value (note: i was incremented)
	lua_pop(l, 2);
	return;
      }
      lua_pop(l, 1);
    }
  }  

  /* Didn't find a local with that name anywhere. Set it as a global. */
  lua_pushinteger(l, value);
  lua_setglobal(l, name);
  lua_pop(l, 3);
}
Esempio n. 6
0
File: luafuncs.c Progetto: MAP94/bam
/* error function */
int lf_errorfunc(lua_State *L)
{
	int depth = 0;
	int frameskip = 1;
	lua_Debug frame;

	if(session.report_color)
		printf("\033[01;31m%s\033[00m\n", lua_tostring(L,-1));
	else
		printf("%s\n", lua_tostring(L,-1));
	
	if(session.lua_backtrace)
	{
		printf("backtrace:\n");
		while(lua_getstack(L, depth, &frame) == 1)
		{
			depth++;
			
			lua_getinfo(L, "nlSf", &frame);

			/* check for functions that just report errors. these frames just confuses more then they help */
			if(frameskip && strcmp(frame.short_src, "[C]") == 0 && frame.currentline == -1)
				continue;
			frameskip = 0;
			
			/* print stack frame */
			printf("  %s(%d): %s %s\n", frame.short_src, frame.currentline, frame.name, frame.namewhat);
			
			/* print all local variables for the frame */
			if(session.lua_locals)
			{
				int i;
				const char *name = 0;
				
				i = 1;
				while((name = lua_getlocal(L, &frame, i)) != NULL)
				{
					printf("    %s = ", name);
					debug_print_lua_value(L,-1);
					printf("\n");
					lua_pop(L,1);
					i++;
				}
				
				i = 1;
				while((name = lua_getupvalue(L, -1, i)) != NULL)
				{
					printf("    upvalue #%d: %s ", i-1, name);
					debug_print_lua_value(L, -1);
					lua_pop(L,1);
					i++;
				}
			}
		}
	}
	
	return 1;
}
Esempio n. 7
0
//*****************************************************************************
int LuaBindings::GetLocals(LuaStack stack)
{
    DebugContext *  pDebugContext   = GetContextIfPaused(stack);
    if (pDebugContext != NULL)
    {
        int             frame           = lua_tointeger(stack, 2);
        lua_Debug debug;
        LuaDebug pFrameDebug = pDebugContext->GetDebug();
        if (frame > 0)
        {
            pFrameDebug = &debug;
            lua_getstack(pDebugContext->pStack, frame, pFrameDebug);
        }

        lua_pushinteger(stack, 0);
        lua_newtable(stack);

        // and get all the locals now!!!
        for (int i = 1, nitems = 0;;i++)
        {
            const char *varname = lua_getlocal(pDebugContext->pStack, pFrameDebug, i);

            if (varname == NULL)
                break ;

            // pop the variable value off - we do not return this (or
            // should we?)
            lua_pop(pDebugContext->pStack, 1);

            // ignore temporaries?
            // if (strncmp("(*", varname, 2) != 0)
            {
                // push the new variable index
                lua_pushinteger(stack, ++nitems);

                // push a table to hold the variable info
                lua_newtable(stack);

                // push the index and the variable name
                lua_pushinteger(stack, i);
                lua_setfield(stack, -2, "index");

                lua_pushstring(stack, varname);
                lua_setfield(stack, -2, "name");

                lua_settable(stack, -3);
            }
        }
    }

    return 2;
}
Esempio n. 8
0
// -----------------------------------------------------------------------
// Retrieve a global or local variable
int Read_Ref_Argument(lua_State *L, int idx, lua_Debug *local, int NewString)
{
    char *Variable_Name = (char *) luaL_checkstring(L, idx);
    char *local_name;
    int i;
    int j;

Read_Again:
    memset(local, 0, sizeof(lua_Debug));
    // See if it's a local variable
    i = 0;
    while(lua_getstack(L, i, local))
    {
        j = 1;
        while(local_name = (char *) lua_getlocal(L, local, j))
        {
            if(strcmp(Variable_Name, local_name) == 0)
            {
                // This is the variable
                return(-j);
            }
            // Nope, remove it from the stack
            lua_pop(L, 1);
            j++;
        }
        i++;
    }
    // See if it's a global one
    lua_getfield(L, LUA_GLOBALSINDEX, Variable_Name);
    local->name = Variable_Name;
    if(lua_isnil(L, -1))
    {
        // Didn't find it: create it as a global variable.
        lua_pop(L, 1);

        if(NewString)
        {
            lua_pushstring(L, "");
            lua_setglobal(L, Variable_Name);
        }
        else
        {
            lua_pushnumber(L, 0);
            lua_setglobal(L, Variable_Name);
        }
        goto Read_Again;
    }
    else
    {
        return(idx);
    }
}
Esempio n. 9
0
static void
mark_thread(lua_State *L, lua_State *dL, const void * parent, const char *desc) {
	const void * t = readobject(L, dL, parent, desc);
	if (t == NULL)
		return;
	int level = 0;
	lua_State *cL = lua_tothread(L,-1);
	if (cL == L) {
		level = 1;
	} else {
		// mark stack
		int top = lua_gettop(cL);
		luaL_checkstack(cL, 1, NULL);
		int i;
		char tmp[16];
		for (i=0;i<top;i++) {
			lua_pushvalue(cL, i+1);
			sprintf(tmp, "[%d]", i+1);
			mark_object(cL, dL, cL, tmp);
		}
	}
	lua_Debug ar;
	luaL_Buffer b;
	luaL_buffinit(dL, &b);
	while (lua_getstack(cL, level, &ar)) {
		char tmp[128];
		lua_getinfo(cL, "Sl", &ar);
		luaL_addstring(&b, ar.short_src);
		if (ar.currentline >=0) {
			char tmp[16];
			sprintf(tmp,":%d ",ar.currentline);
			luaL_addstring(&b, tmp);
		}

		int i,j;
		for (j=1;j>-1;j-=2) {
			for (i=j;;i+=j) {
				const char * name = lua_getlocal(cL, &ar, i);
				if (name == NULL)
					break;
				snprintf(tmp, sizeof(tmp), "%s : %s:%d",name,ar.short_src,ar.currentline);
				mark_object(cL, dL, t, tmp);
			}
		}

		++level;
	}
	luaL_addstring(&b, "thread: ");
	luaL_pushresult(&b);
	lua_rawsetp(dL, SOURCE, t);
	lua_pop(L,1);
}
Esempio n. 10
0
static int
search_local_var(lua_State *state, lua_Debug *ar, const char* var) {
    int         i;
    const char *name;

    for(i = 1; (name = lua_getlocal(state, ar, i)) != NULL; i++) {
        if(strcmp(var,name) == 0) {
            return i;
        }
        // not match, pop out the var's value
        lua_pop(state, 1);
    }
    return 0;
}
Esempio n. 11
0
int find_locals(lua_State *L, lua_Debug *ar, const char *var_name) {
    int index = 1;
    const char *name;
    while((name = lua_getlocal(L, ar, index)) != NULL) {
        if(strcmp(name, var_name) == 0) {
            return index;
        }
        if(strcmp(name, "(*temporary)") == 0) {
            lua_pop(L, 1);
            break;
        }
        index++;
        lua_pop(L, 1);
    }
    return 0;
}
Esempio n. 12
0
static int getlocal (lua_State *L) {
  lua_Debug ar;
  const char *name;
  if (!lua_getstack(L, luaL_checkint(L, 1), &ar))  /* level out of range? */
    return luaL_argerror(L, 1, "level out of range");
  name = lua_getlocal(L, &ar, luaL_checkint(L, 2));
  if (name) {
    lua_pushstring(L, name);
    lua_pushvalue(L, -2);
    return 2;
  }
  else {
    lua_pushnil(L);
    return 1;
  }
}
bool VRSDClientLuaImplementation::GetLocalType(const char* pVariableName, char * pUserDataTypeName)
{
  VASSERT(m_pLuaState);

  if(!m_pLuaState || !m_pActivationRecord)
    return false;

  // we can only get local symbols without a crash if we are really in a Lua code execution path
  if(strcmp(m_pActivationRecord->what, "Lua"))
    return true;

  VLuaStackCleaner stackCleaner(m_pLuaState);
  ScopedBooleanToTrue disableDebugHook(m_bDebuggerRetrievingValues);

  const char* pSymbolName = NULL;
  int iLocalIndex = 1;

  VMemoryTempBuffer<512> copyBuffer(pVariableName); // operate on a copy string in the tokenizer

  VStringTokenizerInPlace Tokenizer(copyBuffer.AsChar(), '.');
  char* pCurrent = Tokenizer.Next();

  pUserDataTypeName[0] = 0;

  while((pSymbolName = lua_getlocal(m_pLuaState, m_pActivationRecord, iLocalIndex)) != NULL)
  {                                                             //stack: ..., localX, TOP
    // check if this local variable is the one we want
    if(!strcmp(pSymbolName, pCurrent))
    {
      // there is already the local on the stack
      if(LookupPath(Tokenizer) != HKV_SUCCESS)
        return false;

      const char * szName = VSWIG_Lua_typename(m_pLuaState, -1);
      sprintf(pUserDataTypeName, "%s", szName);

      return pUserDataTypeName[0] != 0;
    }

    // clean up the stack and increment the index to get the next local variable
    lua_pop(m_pLuaState, 1);                                    //stack: ..., TOP
    iLocalIndex++;
  }

  return false;
}
bool VRSDClientLuaImplementation::GetUserDataPointerFromLocal(const char* szVariable, void** ppUserData, void ** ppEnvironment)
{
  VASSERT(m_pLuaState);

  if(!m_pLuaState || !m_pActivationRecord)
    return false;

  // we can only get local symbols without a crash if we are really in a Lua code execution path
  if(strcmp(m_pActivationRecord->what, "Lua"))
    return true;

  ScopedBooleanToTrue disableDebugHook(m_bDebuggerRetrievingValues);
  VLuaStackCleaner stackCleaner(m_pLuaState);


  char* pSymbolName = NULL;
  int iLocalIndex = 1;

  VMemoryTempBuffer<512> copyBuffer(szVariable); // operate on a copy string in the tokenizer
  
  VStringTokenizerInPlace Tokenizer(copyBuffer.AsChar(), '.');
  char* pCurrent = Tokenizer.Next();

  while((pSymbolName = (char*)lua_getlocal(m_pLuaState, m_pActivationRecord, iLocalIndex)) != NULL)
  {                                                       //Stack: ..., localX, TOP
    // check if this local variable is the one we want
    if(!strcmp(pSymbolName, pCurrent))
    {
      VLuaStackCleaner innerStackCleaner(m_pLuaState);
      //there is already the local on the stack...
      if(LookupPath(Tokenizer) != HKV_SUCCESS)
        return false;

      // now the variable is at the top of the stack
      *ppUserData = lua_touserdata(m_pLuaState, -1);    //Stack: ..., localX, {field}, TOP
      *ppEnvironment = m_pLuaState;
      return true;
    }

    // remove the value and update the index to get the next local variable
    lua_pop(m_pLuaState, 1);
    iLocalIndex++;
  }

  return false;
}
Esempio n. 15
0
void CDbgLuaHelper::DrawLocalVariables()
{
    debugger()->ClearLocalVariables();

    int nLevel = debugger()->GetStackTraceLevel();
    lua_Debug ar;
    if ( lua_getstack (L, nLevel, &ar) )
    {
        int i = 1;
        const char *name;
        while ((name = lua_getlocal(L, &ar, i++)) != NULL) {
            DrawVariable(L,name,true);

            lua_pop(L, 1);  /* remove variable value */
        }
    }
}
Esempio n. 16
0
bool CDbgLuaHelper::GetCalltip(const char *szWord, char *szCalltip)
{
    int nLevel = debugger()->GetStackTraceLevel();
    lua_Debug ar;
    if ( lua_getstack (L, nLevel, &ar) )
    {
        int i = 1;
        const char *name;
        while ((name = lua_getlocal(L, &ar, i++)) != NULL) {
            if ( xr_strcmp(name, szWord)==0 )
            {
                char szRet[64];
                Describe(szRet, -1);
                sprintf(szCalltip, "local %s : %s ", name, szRet);
                lua_pop(L, 1);  /* remove variable value */
                return true;
            }

            lua_pop(L, 1);  /* remove variable value */
        }
    }

    lua_pushvalue(L, LUA_GLOBALSINDEX);

    lua_pushnil(L);  /* first key */
    while (lua_next(L, -2))
    {
        const char* name = lua_tostring(L, -2);
        if ( xr_strcmp(name, szWord)==0 )
        {
            char szRet[64];
            Describe(szRet, -1);
            sprintf(szCalltip, "global %s : %s ", name, szRet);

            lua_pop(L, 3);  /* remove table, key, value */

            return true;
        }

        lua_pop(L, 1); // pop value, keep key for next iteration;
    }
    lua_pop(L, 1); // pop table of globals;

    return false;
}
Esempio n. 17
0
static int findlocal (lua_Object func, int arg) {
  lua_Object v = lua_getparam(arg);
  if (lua_isnumber(v))
    return (int)lua_getnumber(v);
  else {
    char *name = luaL_check_string(arg);
    int i = 0;
    int result = -1;
    char *vname;
    while (lua_getlocal(func, ++i, &vname) != LUA_NOOBJECT) {
      if (strcmp(name, vname) == 0)
        result = i;  /* keep looping to get the last var with this name */
    }
    if (result == -1)
      luaL_verror("no local variable `%.50s' at given level", name);
    return result;
  }
}
bool VRSDClientLuaImplementation::IsLocalUserDataOfType(const char* Name, const char* Type)
{
  VASSERT(m_pLuaState);

  if(!m_pLuaState || !m_pActivationRecord)
    return false;

  // we can only get local symbols without a crash if we are really in a Lua code execution path
  if(strcmp(m_pActivationRecord->what, "Lua"))
    return true;

  VLuaStackCleaner stackCleaner(m_pLuaState);
  ScopedBooleanToTrue disableDebugHook(m_bDebuggerRetrievingValues);

  const char* pSymbolName = NULL;
  int iLocalIndex = 1;

  VMemoryTempBuffer<512> copyBuffer(Name); // operate on a copy string in the tokenizer
  
  VStringTokenizerInPlace Tokenizer(copyBuffer.AsChar(), '.');
  char* pCurrent = Tokenizer.Next();

  while((pSymbolName = lua_getlocal(m_pLuaState, m_pActivationRecord, iLocalIndex)) != NULL)
  {                                                             //stack: ..., localX, TOP
    // check if this local variable is the one we want
    if(!strcmp(pSymbolName, pCurrent))
    {
      VLuaStackCleaner innerStackCleaner(m_pLuaState);
      // there is already the local on the stack

      if(LookupPath(Tokenizer) != HKV_SUCCESS)
        return false;

      // now the variable is at the top of the stack
      return LUA_TestUserData(m_pLuaState, -1, Type) != NULL;
    }

    // increment the index to get the next local variable
    iLocalIndex++;
    lua_pop(m_pLuaState, 1);
  }
 
  return false;
}
Esempio n. 19
0
static int db_getlocal (lua_State *L) {
  int arg;
  lua_State *L1 = getthread(L, &arg);
  lua_Debug ar;
  const char *name;
  if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar))  /* out of range? */
    return luaL_argerror(L, arg+1, "level out of range");
  name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
  if (name) {
    lua_xmove(L1, L, 1);
    lua_pushstring(L, name);
    lua_pushvalue(L, -2);
    return 2;
  }
  else {
    lua_pushnil(L);
    return 1;
  }
}
Esempio n. 20
0
LuaObject LuaState::GetLocalByName( int level, const char* name )
{
	lua_State * L = GetCState();
	lua_Debug ar;
	int i;
	const char *localName;
	if (lua_getstack(L, level, &ar) == 0)
		return LuaObject(this);  /* failure: no such level in the stack */
	i = 1;
	while ((localName = lua_getlocal(L, &ar, i++)) != NULL) {
		if (strcmp(name, localName) == 0)
		{
			LuaObject obj(this, -1);
			lua_pop(L, 1);
			return obj;
		}
		lua_pop(L, 1);  /* remove variable value */
	}
	return LuaObject(this);
}
Esempio n. 21
0
//*****************************************************************************
int LuaBindings::GetLocal(LuaStack stack)
{
    DebugContext *  pDebugContext   = GetContextIfPaused(stack);
    if (pDebugContext != NULL)
    {
        int             lvindex         = lua_tointeger(stack, 2);
        int             nlevels         = lua_tointeger(stack, 3);
        int             frame           = lua_tointeger(stack, 4);

        lua_Debug debug;
        LuaDebug pFrameDebug = pDebugContext->GetDebug();
        if (frame > 0)
        {
            pFrameDebug = &debug;
            lua_getstack(pDebugContext->pStack, frame, pFrameDebug);
        }

        const char *varname = lua_getlocal(pDebugContext->pStack, pFrameDebug, lvindex);
        if (varname == NULL)
        {
            lua_pushinteger(stack, -1);
            lua_pushstring(stack, "Invalid variable index.");
        }
        else
        {
            // output code - 0 => success
            lua_pushinteger(stack, 0);

            // local variable value
            LuaUtils::TransferValueToStack(pDebugContext->pStack, stack, -1, nlevels, varname);

            // pop the value of the local variable 
            // of the stack being debugged!!
            lua_pop(pDebugContext->pStack, 1);
        }
    }

    return 2;
}
Esempio n. 22
0
int capture_env(struct lua_State *L, int frame)
{
	int i;
	const char *local;
	lua_Debug ar;
	LUA_STACK_MARK(L);

	if (!lua_getstack(L, frame, &ar)) {
		return -1;
	}

	lua_getinfo(L, "f", &ar);

	lua_newtable(L);

	for (i=1; (local = lua_getlocal(L, &ar, i)); ++i) {
		lua_setfield(L, -2, local);
	}

	for (i=1; (local = lua_getupvalue(L, -2, i)); ++i) {
		lua_setfield(L, -2, local);
	}

	lua_newtable(L);
	lua_getfenv(L, -3);
	lua_setfield(L, -2, "__index");
	lua_getfenv(L, -3);
	lua_setfield(L, -2, "__newindex");
	lua_setmetatable(L, -2);

	lua_remove(L, -2);

	LUA_STACK_CHECK(L, 1);

	return lua_gettop(L);
}
Esempio n. 23
0
void CDbgLuaHelper::CoverGlobals()
{
    lua_newtable(L);  // save there globals covered by locals

    int nLevel = debugger()->GetStackTraceLevel();
    lua_Debug ar;
    if ( lua_getstack (L, nLevel, &ar) )
    {
        int i = 1;
        const char *name;
        while ((name = lua_getlocal(L, &ar, i++)) != NULL) { /* SAVE lvalue */
            lua_pushstring(L, name);	/* SAVE lvalue name */
            lua_pushvalue(L, -1);	/* SAVE lvalue name name */
            lua_pushvalue(L, -1);	/* SAVE lvalue name name name */
            lua_insert(L, -4);		/* SAVE name lvalue name name */
            lua_rawget(L, LUA_GLOBALSINDEX);	/* SAVE name lvalue name gvalue */

            lua_rawset(L, -5);	// save global value in local table
            /* SAVE name lvalue */

            lua_rawset(L, LUA_GLOBALSINDEX); /* SAVE */
        }
    }
}
bool VRSDClientLuaImplementation::UpdateLocalVariable(const char* Variable, const char* NewValue)
{
  if(!Variable || !NewValue)
    return false;

  VASSERT(m_pLuaState);

  if(!m_pLuaState || !m_pActivationRecord)
    return false;

  // we can only get local symbols without a crash if we are really in a Lua code execution path
  if(strcmp(m_pActivationRecord->what, "Lua"))
    return true;

  VLuaStackCleaner stackCleaner(m_pLuaState);
  ScopedBooleanToTrue disableDebugHook(m_bDebuggerRetrievingValues);

  const char* pSymbolName = NULL;
  int iLocalIndex = 1;

  VMemoryTempBuffer<512> copyBuffer(Variable); // operate on a copy string in the tokenizer
  
  VStringTokenizerInPlace Tokenizer(copyBuffer.AsChar(), '.');
  char* pCurrent = Tokenizer.Next();
  int i = 0;
  const char* pLastField = NULL;

  // go through all local variables
  while((pSymbolName = lua_getlocal(m_pLuaState, m_pActivationRecord, iLocalIndex)) != NULL)
  {
    // check if this local variable is the one we want
    if(!strcmp(pSymbolName, pCurrent))
    {
      VLuaStackCleaner innerStackCleaner(m_pLuaState);
      if(LookupPath(Tokenizer, &pLastField) != HKV_SUCCESS)
        return false;

      // now the variable is at the top of the stack, update its value
      int iLuaType = lua_type(m_pLuaState, -1);

      // pop off the field again
      lua_pop(m_pLuaState, 1);

      bool bIsIntegerKey = false;
      if(pLastField && VStringUtil::IsIntegerString(pLastField))
      {
        bIsIntegerKey = true;
        lua_pushnumber(m_pLuaState, (LUA_NUMBER)atoi(pLastField));
      }

      if (!PushValue(iLuaType, NewValue))
      {
        return false;
      }

      if(Tokenizer.GetTokenCount() > 1)
      {
        VASSERT(pLastField != NULL);
        if(bIsIntegerKey)
        {
          lua_settable(m_pLuaState, -3);
        }
        else
        {
          lua_setfield(m_pLuaState, -2, pLastField);
        }
      }
      else
      {
        lua_setlocal(m_pLuaState, m_pActivationRecord, iLocalIndex);
      }

      break;
    }

    // clean up the stack and increment the index to get the next local variable
    lua_pop(m_pLuaState, 1);
    iLocalIndex++;
  }

  return true;
}
Esempio n. 25
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);
}
Esempio n. 26
0
const char * LuaDebug::GetLocal(const lua_Debug * ar, int n) const
{
	return lua_getlocal(L(), ar, n);
}
Esempio n. 27
0
/***
check whether the calling function's argument have the expected types.

`checks( [level], t_1, ..., t_n)` causes an error if the type of
argument #`i` in stack frame #`level` isn't as described by `t_i`, for
i in `[1...n]`.  `level` is optional, it defaults to one (checks the
function immediately calling `checks`).

@function [parent=#global] checks
@param level the number of stack levels to ignore in the error message,
 should it be produced. Optional, defaults to 1.
@param varargs one type string per expected argument.
@return nothing on success, throw an error on failure.
*/
static int checks( lua_State *L) {
    lua_Debug ar;
    int level=1, i=1, r;
    if( lua_isnumber( L, 1)) { i = 2; level = lua_tointeger( L, 1); }
    r = lua_getstack( L, level, & ar);
    if( ! r) luaL_error( L, "checks() must be called within a Lua function");

    /* loop for each checked argument in stack frame. */
    for( /* i already initialized. */; ! lua_isnoneornil( L, i); i++) {

        const char *expectedType = luaL_checkstring( L, i); // -
        lua_getlocal( L, & ar, i);  // val (value whose type is checked)

        /* 1. Check for nil if type is optional. */
        if( '?' == expectedType[0]) {
            if( ! expectedType[1]   /* expectedType == "?".   */
            || lua_isnoneornil( L, -1)) { /* actualType   == "nil". */
                lua_pop( L, 1); continue; // -
            }
            expectedType++;
        }

        const char *actualType = lua_typename( L, lua_type( L, -1));

        /* 1'. if the template is "!", check for non-nilness. */
        if( '!' == expectedType[0] && '\0' == expectedType[1]) {
            if( lua_isnoneornil( L, -1)) { // val==nil
                return error( L, level, i, "non-nil", actualType);
            } else { // val~=nil
                lua_pop( L, 1); continue; // -
            }
        }

        /* 2. Check real type. */
        if( matches( actualType, expectedType)) {
            lua_pop( L, 1); continue; // -
        }

        /* 3. Check for type name in metatable. */
        if( lua_getmetatable( L, -1)) {       // val, mt
            lua_getfield( L, -1, "__type");   // val, mt, __type?
            if( lua_isstring( L, -1)) {       // val, mt, __type
                if( matches( luaL_checkstring( L, -1), expectedType)) {
                    lua_pop( L, 3); continue; // -
                } else { /* non-matching __type field. */
                    lua_pop( L, 2);           // val
                }
            } else { /* no __type field. */
                lua_pop( L, 2);               // val
            }
        } else { /* no metatable. */ }        // val

        /* 4. Check for a custom typechecking function.  */
        lua_getfield( L, LUA_REGISTRYINDEX, "checkers");         // val, checkers
        const char *p = expectedType;
        while( 1) {
            const char *q = strchr( p, '|');
            if( ! q) q = p + strlen( p);
            lua_pushlstring( L, p, q-p);                // val, checkers, expType
            lua_gettable( L, -2);             // val, checkers, checkers.expType?
            if( lua_isfunction( L, -1)) {
                lua_pushvalue( L, -3);    // val, checkers, checkers.expType, val
                r = lua_pcall( L, 1, 1, 0);       // val, checkers, result || msg
                if( ! r && lua_toboolean( L, -1)) {// val, checkers, result==true
                    lua_pop( L, 3);                                          // -
                    break;
                } else {                               // val, checkers, errormsg
                    lua_pop( L, 1);                              // val, checkers
                }
            } else { /* no such custom checker */           // val, checkers, nil
                lua_pop( L, 1);                                  // val, checkers
            }
            if( ! *q) { /* last possible expected type. */
                lua_pop( L, 2);
                return error( L, level, i, expectedType, actualType);
            } else {
                p = q+1;
            }
        } /* for each expected type */
    } /* for each i */
    return 0;
}
bool VRSDClientLuaImplementation::GetSubSymbolsForLocal(char* LocalName, DynArray_cl<VRSDScriptSymbol>& SubSymbols, unsigned int& SubSymbolCount)
{
  VASSERT(m_pLuaState);

  if(!m_pLuaState || !m_pActivationRecord)
    return false;
  
  SubSymbolCount = 0;

  // we can only get local symbols without a crash if we are really in a Lua code execution path
  if(strcmp(m_pActivationRecord->what, "Lua"))
    return true;

  VLuaStackCleaner stackCleaner(m_pLuaState);
  ScopedBooleanToTrue disableDebugCallback(m_bDebuggerRetrievingValues);

  char* pSymbolName = NULL;
  int iLocalIndex = 1;

  VMemoryTempBuffer<512> copyBuffer(LocalName); // operate on a copy string in the tokenizer
  
  VStringTokenizerInPlace Tokenizer(copyBuffer.AsChar(), '.');
  char* pCurrent = Tokenizer.Next();

  while((pSymbolName = (char*)lua_getlocal(m_pLuaState, m_pActivationRecord, iLocalIndex)) != NULL)
  {                                                       //stack: .., localX, TOP
    // check if this local variable is the one we want
    if(!strcmp(pSymbolName, pCurrent))
    {
      //the local is already on the stack
      if(LookupPath(Tokenizer) != HKV_SUCCESS)
        return false;

      // now we can iterate over the contents of the table
      // first key for the iteration
      lua_pushnil(m_pLuaState);                           //stack: .., localX, {field}, nil, TOP

      //access the last field
      while (lua_next(m_pLuaState, -2) != 0)              //stack: .., localX, {field}, key, value TOP
      {
        // we only want string fields and numeric fields
        // (lua_isstring returns also true for numbers, using
        // tostring later on will cast the number to a string)
        int iKeyType = lua_type(m_pLuaState, -2);
        if (iKeyType==LUA_TNUMBER || iKeyType==LUA_TSTRING)
        {  
          VString sKeyBuffer;

          //this if prevents a conversion of number on the Lua stack
          if(iKeyType==LUA_TNUMBER) sKeyBuffer.Format("%1.0f", lua_tonumber(m_pLuaState, -2));
          else                      sKeyBuffer = lua_tostring(m_pLuaState, -2);

          if(!sKeyBuffer.IsEmpty())
          {
            int iValueType = lua_type(m_pLuaState, -1);
            VString sValueBuffer;

            // table member variable
            switch (iValueType) 
            {
              case LUA_TTABLE:
                // add a symbol for the table
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), "table", VRSDScriptSymbol::SYMBOL_TABLE);
                break;
            
              case LUA_TNUMBER:
                // numeric member variable
                sValueBuffer.Format("%f", lua_tonumber(m_pLuaState, -1));
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_NUMBER);
                break;

              case LUA_TSTRING:
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), lua_tostring(m_pLuaState, -1), VRSDScriptSymbol::SYMBOL_STRING);
                break;

              case LUA_TFUNCTION:
                sValueBuffer.Format("function:0x%p", lua_tocfunction(m_pLuaState, -1));
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_FUNCTION);
                break;
              
              case LUA_TBOOLEAN:
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), lua_toboolean(m_pLuaState, -1) ? "true" : "false", VRSDScriptSymbol::SYMBOL_BOOLEAN);
                break;

              case LUA_TNIL:
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), "nil", VRSDScriptSymbol::SYMBOL_CLASS);
                break;

              case LUA_TTHREAD:
                sValueBuffer.Format("thread:0x%p", lua_tothread(m_pLuaState, -1));
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_CLASS);
                break;

              case LUA_TUSERDATA:
                sValueBuffer.Format("userdata:0x%p", lua_touserdata(m_pLuaState, -1));
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), sValueBuffer.AsChar(), VRSDScriptSymbol::SYMBOL_USERDATA);
                break;
            
              default:
                AddSymbol(SubSymbols, SubSymbolCount, sKeyBuffer.AsChar(), "unknown", VRSDScriptSymbol::SYMBOL_STRING);
                break;
            }
          }
        }

        // remove the value, keep the key for the next iteration
        lua_pop(m_pLuaState, 1);                        //stack: .., localX, {field}, key, TOP
      }
      return true;
    }

    // clean up the stack and increment the index to get the next local variable
    lua_pop(m_pLuaState, 1);                            //stack: .., TOP
    iLocalIndex++;
  }

  return true;
}
bool VRSDClientLuaImplementation::GetLocalSymbols(DynArray_cl<VRSDScriptSymbol>& LocalSymbols, unsigned int& LocalSymbolCount)
{
  VASSERT(m_pLuaState);

  if(!m_pLuaState || !m_pActivationRecord)
    return false;

  LocalSymbolCount = 0;

  // we can only get local symbols without a crash if we are really in a Lua code execution path
  if(strcmp(m_pActivationRecord->what, "Lua"))
    return true;

  const char* pSymbolName = NULL;
  int iLocalIndex = 1;

  while((pSymbolName = lua_getlocal(m_pLuaState, m_pActivationRecord, iLocalIndex)) != NULL)
  {
    // skip lua internal temporary variables (they start with an '(')
    if(pSymbolName[0] != '(')
    {
      // if the variable is a table, get all child variables (one level deep only)
      if(lua_istable(m_pLuaState, -1))
      {
        // add a symbol for the table
        AddSymbol(LocalSymbols, LocalSymbolCount, pSymbolName, "table", VRSDScriptSymbol::SYMBOL_TABLE);
      }
      // numeric member variable
      else if(lua_type(m_pLuaState, -1) == LUA_TNUMBER)
      {
        char buffer[32];
        sprintf(buffer, "%f", lua_tonumber(m_pLuaState, -1));
        AddSymbol(LocalSymbols, LocalSymbolCount, pSymbolName, buffer, VRSDScriptSymbol::SYMBOL_NUMBER);
      }
      // string member variable
      else if(lua_type(m_pLuaState, -1) == LUA_TSTRING)
      {
        AddSymbol(LocalSymbols, LocalSymbolCount, pSymbolName, lua_tostring(m_pLuaState, -1), VRSDScriptSymbol::SYMBOL_STRING);
      }
      else if(lua_isfunction(m_pLuaState, -1))
      {
        AddSymbol(LocalSymbols, LocalSymbolCount, pSymbolName, "function", VRSDScriptSymbol::SYMBOL_FUNCTION);
      }
      else if(lua_isuserdata(m_pLuaState, -1))
      {
        char buffer[128];
        swig_type_info* type = (swig_type_info *)LUA_GetSwigType(m_pLuaState, -1);
        void * pUserData = lua_touserdata(m_pLuaState, -1);

        if(type)
        {
          vis_snprintf(buffer, 128, "userdata:0x%p [%s: 0x%p]", pUserData, type->str, ((swig_lua_userdata*)pUserData)->ptr);
        }
        else
        {
          vis_snprintf(buffer, 128, "userdata:0x%p", lua_touserdata(m_pLuaState, -1));
        }
        AddSymbol(LocalSymbols, LocalSymbolCount, pSymbolName, buffer, VRSDScriptSymbol::SYMBOL_USERDATA);
      }
      else if(lua_isboolean(m_pLuaState, -1))
      {
        int iBoolVal = lua_toboolean(m_pLuaState, -1);
        AddSymbol(LocalSymbols, LocalSymbolCount, pSymbolName, iBoolVal ? "true" : "false", VRSDScriptSymbol::SYMBOL_BOOLEAN);
      }
      else if(lua_isnil(m_pLuaState, -1))
      {
        AddSymbol(LocalSymbols, LocalSymbolCount, pSymbolName, "nil", VRSDScriptSymbol::SYMBOL_CLASS);
      }
    }

    // clean up the stack and increment the index to get the next local variable
    lua_pop(m_pLuaState, 1);
    iLocalIndex++;
  }


  return true;
}
Esempio n. 30
0
//----------------------------------------------------------------//
void MOAIHarness::ReceiveVariableGet(lua_State *L, json_t* node)
{
	// Get the keys to traverse to the target variable
	json_t* np_keys = json_object_get(node, "Keys");
	if (np_keys == NULL || json_typeof(np_keys) != JSON_ARRAY)
		return;
	
	// Check to see if we were actually provided keys
	size_t keyCount = json_array_size(np_keys);
	if (keyCount == 0)
		return;

	// Get the root key name (which has to be a string)
	json_t* np_root_key = json_array_get(np_keys, 0);
	if (json_typeof(np_root_key) != JSON_STRING)
		return;
	std::string root(json_string_value(np_root_key));

	// Get the stack level to look for loval variables at
	json_t* np_stack_level = json_object_get(node, "Level");
	if (np_stack_level == NULL || json_typeof(np_stack_level) != JSON_INTEGER)
		return;
	json_int_t level = json_integer_value(np_stack_level);

	// Check for the root name in the local namespace
	bool found = false;
	lua_Debug ar;
	if (lua_getstack(L, (int)level, &ar))
	{
		// Look for a local variable match
		const char* localName;
		for (int local = 1; (localName = lua_getlocal(L, &ar, local)) != 0; ++local)
		{
			if (root == localName)
			{
				found = true;
				break;
			}
			lua_pop(L, 1);
		}

		if (!found)
		{
			// Push the function onto the stack
			lua_getinfo(L, "f", &ar);

			// Look for an upvalue match
			const char* upvalueName;
			for (int upvalue = 1; (upvalueName = lua_getupvalue(L, -1, upvalue)) != 0; ++upvalue)
			{
				if (root == upvalueName)
				{
					found = true;
					break;
				}
				lua_pop(L, 1);
			}

			// Pop the function off the stack
			lua_remove(L, found ? -2 : -1);
		}
	}

	// Check for the root name in the global namespace
	if (!found)
	{
		lua_getglobal(L, root.c_str());
	}

	// Traverse through our child keys
	for (size_t childIndex = 1; !lua_isnil(L, -1) && childIndex < keyCount; ++childIndex)
	{
		json_t* np_key = json_array_get(np_keys, childIndex);
		bool valid = true;

		// First check for complex type keys
		if (json_typeof(np_key) == JSON_OBJECT)
		{
			// Check for the correct datapair encoding for keys
			json_t* anticonflict = json_object_get(np_key, JSON_DATAPAIR_ANTICONFLICT_KEY);
			json_t* np_type = json_object_get(np_key, JSON_DATAPAIR_NAME_KEY);
			json_t* np_data = json_object_get(np_key, JSON_DATAPAIR_DATA_KEY);
			bool isDatapair =
				anticonflict && json_typeof(anticonflict) == JSON_STRING && strcmp(json_string_value(anticonflict), JSON_DATAPAIR_ANTICONFLICT_VALUE) == 0 &&
				np_type && json_typeof(np_type) == JSON_STRING &&
				np_data && json_typeof(np_data) == JSON_INTEGER;				
			if (isDatapair && lua_istable(L, -1))
			{
				// Iterate through the keys of the table, looking for complex
				// types with the same type and address
				const char* keyType = json_string_value(np_type);
				json_int_t keyPtr = json_integer_value(np_data);
				bool keyFound = false;
				lua_pushnil(L);
				while (lua_next(L, -2) != 0)
				{
					// If this key is a complex type, compare its
					// type and address
					if (const void* ptr = lua_topointer(L, -2))
					{
						int type = lua_type(L, -2);
						if ((int)ptr == (int)keyPtr && strcmp(keyType, lua_typename(L, type)) == 0)
						{
							// Pop the table and key off the stack, leaving the value
							lua_remove(L, -2);
							lua_remove(L, -2);
							keyFound = true;
							break;
						}
					}
					lua_pop(L, 1);
				}
				if (keyFound)
				{
					continue;
				}
			}
			valid = false;
		}

		// Push the key onto the stack
		switch (json_typeof(np_key))
		{
		case JSON_STRING:
			lua_pushstring(L, json_string_value(np_key));
			break;
		case JSON_INTEGER:
			lua_pushinteger(L, (lua_Integer)json_integer_value(np_key));
			break;
		case JSON_REAL:
			lua_pushnumber(L, (lua_Number)json_real_value(np_key));
			break;
		case JSON_TRUE:
		case JSON_FALSE:
			lua_pushboolean(L, json_typeof(np_key) == JSON_TRUE);
			break;
		default:
			valid = false;
			break;
		}

		// If we don't have a valid key, just pop the table off the
		// stack and return a nil value
		if (!valid)
		{
			lua_pop(L, 1);
			lua_pushnil(L);
		}
		
		// Otherwise, call a function to get the table value
		else
		{
			lua_pushcfunction(L, MOAIHarness::VariableGetCallback);
			lua_insert(L, -3);

			// If an error occurred getting the value, just push nil
			if (lua_pcall(L, 2, 1, 0))
			{
				lua_pushnil(L);
			}
		}
	}

	// Convert the result to a json object
	json_t* result = MOAIHarness::ConvertStackIndexToJSON(L, -1, true);
	lua_pop(L, 1);

	// Return the result to the caller
	SendVariableGetResult(np_keys, result);
	json_decref(result);

}