/*
** Check whether a given upvalue from a given closure exists and
** returns its index
*/
static int checkupval (lua_State *L, int argf, int argnup) {
  int nup = (int)luaL_checkinteger(L, argnup);  /* upvalue index */
  luaL_checktype(L, argf, LUA_TFUNCTION);  /* closure */
  luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
                   "invalid upvalue index");
  return nup;
}
Exemple #2
0
LUABIND_API bool is_luabind_function(lua_State* L, int index)
{
    if (!lua_getupvalue(L, index, 2))
        return false;
    bool result = lua_touserdata(L, -1) == &function_tag;
    lua_pop(L, 1);
    return result;
}
Exemple #3
0
/* 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;
}
Exemple #4
0
static int is_composed( lua_State* L, int i ) {
  int r = 0;
  if( lua_tocfunction( L, i ) == composed &&
      lua_getupvalue( L, i, 1 ) ) {
    r = lua_tointeger( L, -1 );
    lua_pop( L, 1 );
  }
  return r;
}
Exemple #5
0
/**
 * @brief Copies the function on the top of src to the top of dst.
 *
 * It can be a Lua function or a C function.
 *
 * @param src source state
 * @param dst destination state
 */
static void sglua_copy_function(lua_State* src, lua_State* dst) {

  if (lua_iscfunction(src, -1)) {
    /* it's a C function */

    XBT_DEBUG("It's a C function");
    sglua_stack_dump("src before copying upvalues: ", src);

    /* get the function pointer */
    int function_index = lua_gettop(src);
    lua_CFunction f = lua_tocfunction(src, function_index);

    /* copy the upvalues */
    int i = 0;
    const char* upvalue_name = NULL;
    do {
      i++;
      upvalue_name = lua_getupvalue(src, function_index, i);

      if (upvalue_name != NULL) {
        XBT_DEBUG("Upvalue %s", upvalue_name);
        sglua_move_value(src, dst);
      }
    } while (upvalue_name != NULL);

    sglua_stack_dump("src before copying pointer: ", src);

    /* set the function */
    lua_pushcclosure(dst, f, i - 1);
    XBT_DEBUG("Function pointer copied");
  }
  else {
    /* it's a Lua function: dump it from src */

    s_sglua_buffer_t buffer;
    buffer.capacity = 128; /* an empty function uses 77 bytes */
    buffer.size = 0;
    buffer.data = xbt_new(char, buffer.capacity);

    /* copy the binary chunk from src into a buffer */
    _XBT_GNUC_UNUSED int error = lua_dump(src, sglua_memory_writer, &buffer);
    xbt_assert(!error, "Failed to dump the function from the source state: error %d",
        error);
    XBT_DEBUG("Fonction dumped: %zu bytes", buffer.size);

    /*
    fwrite(buffer.data, buffer.size, buffer.size, stderr);
    fprintf(stderr, "\n");
    */

    /* load the chunk into dst */
    error = luaL_loadbuffer(dst, buffer.data, buffer.size, "(dumped function)");
    xbt_assert(!error, "Failed to load the function into the destination state: %s",
        lua_tostring(dst, -1));
  }
}
Exemple #6
0
/*
** get (if 'get' is true) or set an upvalue from a closure
*/
static int auxupvalue (lua_State *L, int get) {
  const char *name;
  int n = (int)luaL_checkinteger(L, 2);  /* upvalue index */
  luaL_checktype(L, 1, LUA_TFUNCTION);  /* closure */
  name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
  if (name == NULL) return 0;
  lua_pushstring(L, name);
  lua_insert(L, -(get+1));  /* no-op if get is false */
  return get + 1;
}
Exemple #7
0
static int auxupvalue (lua_State *L, int get) {
  const char *name;
  int n = luaL_checkint(L, 2);
  luaL_checktype(L, 1, LUA_TFUNCTION);
  name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
  if (name == NULL) return 0;
  lua_pushstring(L, name);
  lua_insert(L, -(get+1));
  return get + 1;
}
void lua_compat_module_init(lua_State *L){
	lua_getglobal(L, "require");
	lua_getupvalue(L, -1, 1);
	lua_pushcclosure(L, ll_module, 1);
	lua_setglobal(L, "module");
	lua_getglobal(L, "package");
	lua_pushcfunction(L, ll_seeall);
	lua_setfield(L, -2, "seeall");
	lua_pop(L, 2);
}
Exemple #9
0
static int auxupvalue (lua_State *L, int get) {
  const char *name;
  int n = luaL_checkint(L, 2);
  luaL_checktype(L, 1, LUA_TFUNCTION);
  if (lua_iscfunction(L, 1)) return 0;  /* cannot touch C upvalues from Lua */
  name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
  if (name == NULL) return 0;
  lua_pushstring(L, name);
  lua_insert(L, -(get+1));
  return get + 1;
}
Exemple #10
0
/* copies upvalues between lua states' stacks */
static int luaproc_copyupvalues( lua_State *Lfrom, lua_State *Lto, 
                                 int funcindex ) {

  int i = 1;
  const char *str;
  size_t len;

  /* test the type of each upvalue and, if it's supported, copy it */
  while ( lua_getupvalue( Lfrom, funcindex, i ) != NULL ) {
    switch ( lua_type( Lfrom, -1 )) {
      case LUA_TBOOLEAN:
        lua_pushboolean( Lto, lua_toboolean( Lfrom, -1 ));
        break;
      case LUA_TNUMBER:
        copynumber( Lto, Lfrom, -1 );
        break;
      case LUA_TSTRING: {
        str = lua_tolstring( Lfrom, -1, &len );
        lua_pushlstring( Lto, str, len );
        break;
      }
      case LUA_TNIL:
        lua_pushnil( Lto );
        break;
      /* if upvalue is a table, check whether it is the global environment
         (_ENV) from the source state Lfrom. in case so, push in the stack of
         the destination state Lto its own global environment to be set as the
         corresponding upvalue; otherwise, treat it as a regular non-supported
         upvalue type. */
      case LUA_TTABLE:
        lua_pushglobaltable( Lfrom );
        if ( isequal( Lfrom, -1, -2 )) {
          lua_pop( Lfrom, 1 );
          lua_pushglobaltable( Lto );
          break;
        }
        lua_pop( Lfrom, 1 );
        /* FALLTHROUGH */
      default: /* value type not supported: table, function, userdata, etc. */
        lua_pushnil( Lfrom );
        lua_pushfstring( Lfrom, "failed to copy upvalue of unsupported type "
                                "'%s'", luaL_typename( Lfrom, -2 ));
        return FALSE;
    }
    lua_pop( Lfrom, 1 );
    if ( lua_setupvalue( Lto, 1, i ) == NULL ) {
      lua_pushnil( Lfrom );
      lua_pushstring( Lfrom, "failed to set upvalue" );
      return FALSE;
    }
    i++;
  }
  return TRUE;
}
Exemple #11
0
static int Lcallback(lua_State *L) {
    ls_EventSlot *slot = checkslot(L, 1);
    lua_settop(L, 2);
    lua_pushvalue(L, 1);
    setcbinfo(L, slot, 4);
    lua_getupvalue(L, -1, UV_SELF);
    if (!lua_isnone(L, 2)) {
        lua_pushvalue(L, 2);
        lua_setupvalue(L, -3, UV_CB);
    }
    return 1;
}
Exemple #12
0
static void recurryf( lua_State* L, int n ) {
  int req, rec, gaps, i, m;
  int idx = lua_gettop( L );
  luaL_checkstack( L, 4, "curry" );
  lua_getupvalue( L, idx, 1 );
  lua_getupvalue( L, idx, 2 );
  lua_getupvalue( L, idx, 3 );
  lua_getupvalue( L, idx, 4 );
  req = lua_tointeger( L, -4 );
  rec = lua_tointeger( L, -2 );
  gaps = lua_tointeger( L, -1 );
  m = gaps + ((req > rec) ? req - rec : 0);
  if( n > m ) {
    luaL_checkstack( L, rec+1, "curry" );
    lua_pushinteger( L, rec-gaps+n );
    lua_replace( L, -5 );
    for( i = 5; i <= rec+4; ++i )
      lua_getupvalue( L, idx, i );
    lua_pushcclosure( L, curried, rec+4 );
    lua_replace( L, idx );
  } else
    lua_pop( L, 4 );
}
Exemple #13
0
static int debug_getupvalue(lua_State *L, int get)
{
  int32_t n = lj_lib_checkint(L, 2);
  if (isluafunc(lj_lib_checkfunc(L, 1))) {
    const char *name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
    if (name) {
      lua_pushstring(L, name);
      if (!get) return 1;
      copyTV(L, L->top, L->top-2);
      L->top++;
      return 2;
    }
  }
  return 0;
}
Exemple #14
0
/**
 * A function should be used as a function pointer.  If this is a C closure
 * to a library function, we can use that library function's address directly.
 * This avoids a C closure for a Lua closure, the invocation of which would
 * look like this: FFI closure -> closure_handler -> lg_call_wrapper -> library
 * function.
 *
 * @return  1 on success, i.e. ar->arg->p has been set to the C function, or 0
 *  otherwise.
 */
int lg_use_c_closure(struct argconv_t *ar)
{
    lua_State *L = ar->L;

    lua_CFunction func = lua_tocfunction(L, ar->index);
    if (!func || func != &lg_call_wrapper)
	return 0;

    // the first upvalue of this closure is a struct fi
    if (lua_getupvalue(L, ar->index, 1)) {
	struct func_info *fi = (struct func_info*) lua_touserdata(L, -1);
	ar->arg->p = fi->func;
	lua_pop(L, 1);
	return 1;
    }

    return 0;
}
Exemple #15
0
bool CMLuaScript::GetScriptEnviroment(lua_State *L)
{
	lua_Debug ar;
	if (lua_getstack(L, 1, &ar) == 0 || lua_getinfo(L, "f", &ar) == 0 || lua_iscfunction(L, -1))
	{
		lua_pop(L, 1);
		return false;
	}

	const char *env = lua_getupvalue(L, -1, 1);
	if (!env || mir_strcmp(env, "_ENV") != 0)
	{
		lua_pop(L, 1);
		return false;
	}

	return true;
}
Exemple #16
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;
    }
}
Exemple #17
0
int find_upvalues(lua_State *L, lua_Debug *ar, const char *var_name) {
    printf("find upvalus\n");
    lua_getinfo(L, "uf", ar);
    if(lua_isfunction(L, -1) == 0) {
        printf("not is a function");
        return 0;
    }
    int i;
    const char *upname;
    for(i=1; i<=ar->nups; i++) {
        upname = lua_getupvalue(L, -1, i);
        if(upname != NULL && strcmp(upname, var_name) == 0) {
            return 1;
        }
        lua_pop(L, 1);
    }
    lua_pop(L, 1);
    return 0;
}
static char * luasandbox_timer_get_cfunction_name(lua_State *L)
{
	static char buffer[1024];
	TSRMLS_FETCH();

	lua_CFunction f = lua_tocfunction(L, -1);
	if (!f) {
		return NULL;
	}
	if (f != luasandbox_call_php) {
		return NULL;
	}

	lua_getupvalue(L, -1, 1);
#if PHP_VERSION_ID < 70000
	zval ** callback_pp = (zval**)lua_touserdata(L, -1);
	if (!callback_pp || !*callback_pp) {
		return NULL;
	}
	char * callback_name;
	zend_bool ok = zend_is_callable(*callback_pp, IS_CALLABLE_CHECK_SILENT, &callback_name TSRMLS_CC);
#else
	zval * callback_p = (zval*)lua_touserdata(L, -1);
	if (!callback_p) {
		return NULL;
	}
	zend_string * callback_name;
	zend_bool ok = zend_is_callable(callback_p, IS_CALLABLE_CHECK_SILENT, &callback_name);
#endif
	if (ok) {
		snprintf(buffer, sizeof(buffer), "%s",
#if PHP_VERSION_ID < 70000
			callback_name
#else
			ZSTR_VAL(callback_name)
#endif
		);
		return buffer;
	} else {
		return NULL;
	}
}
Exemple #19
0
static void magnet_setfenv_mainfn(lua_State *L, int funcIndex) { /* (-1, 0, -) */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
	/* set "_ENV" upvalue, which should be the first upvalue of a "main" lua
	 * function if it uses any global names
	 */

	const char* first_upvalue_name = lua_getupvalue(L, funcIndex, 1);
	if (NULL == first_upvalue_name) return; /* doesn't have any upvalues */
	lua_pop(L, 1); /* only need the name of the upvalue, not the value */

	if (0 != strcmp(first_upvalue_name, "_ENV")) return;

	if (NULL == lua_setupvalue(L, funcIndex, 1)) {
		/* pop value if lua_setupvalue didn't set the (not existing) upvalue */
		lua_pop(L, 1);
	}
#else
	lua_setfenv(L, funcIndex);
#endif
}
Exemple #20
0
/**
 * The specified Lua value might contain a closure created with the function
 * above, or contain a .  If so, return the func_info embedded in it, otherwise raise an
 * error.
 */
struct func_info *lg_get_closure(lua_State *L, int index)
{
    lua_CFunction f;
    struct func_info *fi;

    // verify that this is actually a closure with the correct C function.
    f = lua_tocfunction(L, index);
    if (!f)
	LG_ERROR(2, "Not a C function, but a %s.",
	    lua_typename(L, lua_type(L, index)));
    if (f != &lg_call_wrapper)
	LG_ERROR(3, "Invalid closure.");

    // the first upvalue is the func_info structure.
    lua_getupvalue(L, index, 1);
    fi = (struct func_info*) lua_touserdata(L, -1);
    if (!fi)
	LG_ERROR(4, "Invalid closure (upvalue 1 not a userdata)");

    return fi;
}
Exemple #21
0
//*****************************************************************************
int LuaBindings::GetUpValue(LuaStack stack)
{
    DebugContext *  pDebugContext   = GetContextIfPaused(stack);
    if (pDebugContext != NULL)
    {
        int             funcindex       = lua_tointeger(stack, 2);
        int             uvindex         = lua_tointeger(stack, 3);
        int             nlevels         = lua_tointeger(stack, 4);
        int             frame           = lua_tointeger(stack, 5);

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

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

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

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

    return 2;
}
Exemple #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);
}
Exemple #23
0
/***
Install a signal handler for this signal number.
Although this is the same API as signal(2), it uses sigaction for guaranteed semantics.
@function signal
@see signal.lua
@int signum
@tparam[opt=SIG_DFL] function handler function, or `SIG_IGN` or `SIG_DFL` constants
@param[opt] flags the `sa_flags` element of `struct sigaction`
@treturn function previous handler function
@see sigaction(2)
*/
static int
Psignal (lua_State *L)
{
	struct sigaction sa, oldsa;
	int sig = checkint(L, 1), ret;
	void (*handler)(int) = sig_postpone;

	checknargs(L, 3);

	/* Check handler is OK */
	switch (lua_type(L, 2))
	{
		case LUA_TNIL:
		case LUA_TSTRING:
			handler = Fsigmacros[luaL_checkoption(L, 2, "SIG_DFL", Ssigmacros)];
			break;
		case LUA_TFUNCTION:
			if (lua_tocfunction(L, 2) == sig_handler_wrap)
			{
				lua_getupvalue(L, 2, 1);
				handler = lua_touserdata(L, -1);
				lua_pop(L, 1);
			}
			break;
		default:
			argtypeerror(L, 2, "function, string or nil");
			break;
	}

	/* Set up C signal handler, getting old handler */
	sa.sa_handler = handler;
	sa.sa_flags = optint(L, 3, 0);
	sigfillset(&sa.sa_mask);
	ret = sigaction(sig, &sa, &oldsa);
	if (ret == -1)
		return 0;

	/* Set Lua handler if necessary */
	if (handler == sig_postpone)
	{
		lua_pushlightuserdata(L, &signalL); /* We could use an upvalue, but we need this for sig_handle anyway. */
		lua_rawget(L, LUA_REGISTRYINDEX);
		lua_pushvalue(L, 1);
		lua_pushvalue(L, 2);
		lua_rawset(L, -3);
		lua_pop(L, 1);
	}

	/* Push old handler as result */
	if (oldsa.sa_handler == sig_postpone)
	{
		lua_pushlightuserdata(L, &signalL);
		lua_rawget(L, LUA_REGISTRYINDEX);
		lua_pushvalue(L, 1);
		lua_rawget(L, -2);
	} else if (oldsa.sa_handler == SIG_DFL)
		lua_pushstring(L, "SIG_DFL");
	else if (oldsa.sa_handler == SIG_IGN)
		lua_pushstring(L, "SIG_IGN");
	else
	{
		lua_pushinteger(L, sig);
		lua_pushlightuserdata(L, oldsa.sa_handler);
		lua_pushcclosure(L, sig_handler_wrap, 2);
	}
	return 1;
}
Exemple #24
0
static void pack_value(lua_State *L, mar_Buffer *buf, int val, int *idx)
{
    size_t l;
    int val_type = lua_type(L, val);
    buf_write(L, (void*)&val_type, MAR_CHR, buf);
    switch (val_type) {
    case LUA_TBOOLEAN: {
        int int_val = lua_toboolean(L, val);
        buf_write(L, (void*)&int_val, MAR_CHR, buf);
        break;
    }
    case LUA_TSTRING: {
        const char *str_val = lua_tolstring(L, val, &l);
        buf_write(L, (void*)&l, MAR_I32, buf);
        buf_write(L, str_val, l, buf);
        break;
    }
    case LUA_TNUMBER: {
        lua_Number num_val = lua_tonumber(L, val);
        buf_write(L, (void*)&num_val, MAR_I64, buf);
        break;
    }
    case LUA_TTABLE: {
        int tag, ref;
        lua_pushvalue(L, val);
        lua_rawget(L, 2);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1);
            if (luaL_getmetafield(L, val, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, val-1);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, 2);

                lua_pushvalue(L, val-1);
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }
                lua_newtable(L);
                lua_pushvalue(L, -2);
                lua_rawseti(L, -2, 1);
                lua_remove(L, -2);

                buf_init(L, &rec_buf);
                mar_pack(L, &rec_buf, idx);


                buf_write(L, (void*)&tag, MAR_CHR, buf);
                buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data, rec_buf.head, buf);
                buf_done(L, &rec_buf);
                lua_pop(L, 1);
            }
            else {
                tag = MAR_TVAL;

                lua_pushvalue(L, val);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, 2);

                lua_pushvalue(L, val);
                buf_init(L, &rec_buf);
                mar_pack(L, &rec_buf, idx);

                buf_write(L, (void*)&tag, MAR_CHR, buf);
                buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data,rec_buf.head, buf);
                buf_done(L, &rec_buf);
                lua_pop(L, 1);

            }
        }
        break;
    }
    case LUA_TFUNCTION: {
        int tag, ref;
        lua_pushvalue(L, val);
        lua_rawget(L, 2);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            int i;
            lua_Debug ar;
            lua_pop(L, 1);

            tag = MAR_TVAL;
            lua_pushvalue(L, val);
            lua_pushinteger(L, (*idx)++);
            lua_rawset(L, 2);

            lua_pushvalue(L, val);
            buf_init(L, &rec_buf);
            lua_dump(L, (lua_Writer)buf_write, &rec_buf);

            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
	    buf_write(L, rec_buf.data, rec_buf.head, buf);
	    buf_done(L, &rec_buf);
	    lua_pop(L, 1);

            lua_pushvalue(L, val);
            lua_getinfo(L, ">uS", &ar);
            if (ar.what[0] != 'L') {
                luaL_error(L, "attempt to persist a C function");
            }

            lua_newtable(L);
            for (i=1; i <= ar.nups; i++) {
                lua_getupvalue(L, -2, i);
                lua_rawseti(L, -2, i);
            }

            buf_init(L, &rec_buf);
            mar_pack(L, &rec_buf, idx);

            buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
	    buf_write(L, rec_buf.data, rec_buf.head, buf);
	    buf_done(L, &rec_buf);
	    lua_pop(L, 1);
        }

        break;
    }
    case LUA_TUSERDATA: {
        int tag, ref;
        lua_pushvalue(L, val);
        lua_rawget(L, 2);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1);
            if (luaL_getmetafield(L, val, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, val-1);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, 2);

                lua_pushvalue(L, val-1);
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }
                lua_newtable(L);
                lua_pushvalue(L, -2);
                lua_rawseti(L, -2, 1);
                lua_remove(L, -2);

                buf_init(L, &rec_buf);
                mar_pack(L, &rec_buf, idx);

                buf_write(L, (void*)&tag, MAR_CHR, buf);
                buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
		buf_write(L, rec_buf.data, rec_buf.head, buf);
		buf_done(L, &rec_buf);
		lua_pop(L, 1);
            }
            else {
                tag = MAR_TVAL;
                buf_write(L, (void*)&tag, MAR_CHR, buf);
            }
        }
        break;
    }
    case LUA_TTHREAD: break; /* just give them a nil during unpack */
    default:
        luaL_error(L, "invalid value type");
    }
}
static inline int _cloneNoTable(lua_State *L, const int idx, 
	lua_State *L_, const int r_lv ) { 
	int ret_= 1; switch(lua_type(L, idx ) ) { 
		case LUA_TSTRING: { 
			size_t l; const char *s= lua_tolstring(L, idx, &l ); 
			lua_pushlstring(L_, s, l ); 
		} break; 
		case LUA_TNUMBER: 
		lua_pushnumber(L_, lua_tonumber(L, idx ) ); 
		break; 
		case LUA_TLIGHTUSERDATA: 
		lua_pushlightuserdata(L_, lua_touserdata(L, idx ) ); 
		break; 
		case LUA_TBOOLEAN: 
		lua_pushboolean(L_, lua_toboolean(L, idx ) ); 
		break; 
		case LUA_TUSERDATA: { // userdata 的 meta 暂时不能拷贝 
			const size_t l= lua_objlen(L, idx ); 
			memmove(lua_newuserdata(L_, l ), 
				lua_touserdata(L, idx ), l ); if(0) //屏蔽 meta 处理 
			if(lua_getmetatable(L, idx ) ) { 
				const int k= _cloneRecursion(L, lua_gettop(L ), L_, 
					((0<= r_lv )? r_lv: -1 ) ); lua_pop(L, 1 ); 
				if((0<= r_lv )&& lua_istable(L_, -1 )&& (0< k ) ) 
					printf("%*.s__{%3d}\n", (r_lv- 1 )* 2, "", k ); 
				lua_setmetatable(L_, -2 ); 
			} 
		} break; 
		case LUA_TFUNCTION: 
		if(lua_iscfunction(L, idx ) ) { 
			int j= 1; lua_CFunction f= lua_tocfunction(L, idx ); 
			for(j= 1; UPVALUE_MAX>= j; ++j ) { 
				//设置函数的 upvalue 
				if(!lua_getupvalue(L, idx, j ) ) break; 
				_cloneRecursion(L, lua_gettop(L ), L_, 
					((0<= r_lv )? (r_lv+ 1 ): -1 ) ); lua_pop(L, 1 ); 
			} lua_pushcclosure(L_, f, j- 1 ); 
		} else 
		{ int j= 1; DUMP_CB ud; memset(&ud, 0, sizeof(ud ) ); 
			lua_pushvalue(L, idx ); lua_dump(L, writer_CB, &ud ); 
			if(ud.p ) { //载入函数到新的栈 
				lua_load(L_, reader_CB, &ud, (char * )0 ); free(ud.p ); 
			} lua_pop(L, 1 ); 
			for(j= 1; UPVALUE_MAX>= j; ++j ) { 
				//设置函数的 upvalue 
				if(!lua_getupvalue(L, idx, j ) ) break; 
printf("upvalue %d\n", j ); 
				_cloneRecursion(L, lua_gettop(L ), L_, 
					((0<= r_lv )? (r_lv+ 1 ): -1 ) ); lua_pop(L, 1 ); 
				lua_setupvalue(L_, -2, j ); 
			} 
		} break; 
		case LUA_TNIL: 
		lua_pushnil(L_ ); 
		break; 
		case LUA_TNONE: 
		case LUA_TTHREAD: //?
		default: 
		ret_= 0; break; 
	} 
	return ret_; 
} 
Exemple #26
0
const char * LuaDebug::GetUpvalue(int funcindex, int n) const
{
	return lua_getupvalue(L(), funcindex, n);
}
Exemple #27
0
static void mar_encode_value(lua_State *L, mar_Buffer *buf, int val, size_t *idx, int nowrap)
{
    size_t l;
    int val_type = lua_type(L, val);
    lua_pushvalue(L, val);

    buf_write(L, (void*)&val_type, MAR_CHR, buf);
    switch (val_type) {
    case LUA_TBOOLEAN: {
        int int_val = lua_toboolean(L, -1);
        buf_write(L, (void*)&int_val, MAR_CHR, buf);
        break;
    }
    case LUA_TSTRING: {
        const char *str_val = lua_tolstring(L, -1, &l);
        buf_write(L, (void*)&l, MAR_I32, buf);
        buf_write(L, str_val, l, buf);
        break;
    }
    case LUA_TNUMBER: {
        lua_Number num_val = lua_tonumber(L, -1);
        buf_write(L, (void*)&num_val, MAR_I64, buf);
        break;
    }
    case LUA_TLIGHTUSERDATA: {
        if(nowrap) 
           luaL_error(L, "light userdata not permitted");
        void * ptr_val = lua_touserdata(L, -1);
        long long v = (long long)ptr_val;
        buf_write(L, (char*)&v, MAR_I64, buf);
        break;
    }
    case LUA_TTABLE: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1); /* pop nil */
            if (luaL_getmetafield(L, -1, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, -2); /* self */
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }

                lua_remove(L, -2); /* __persist */

                lua_newtable(L);
                lua_pushvalue(L, -2); /* callback */
                lua_rawseti(L, -2, 1);

                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx, nowrap);

                buf_write(L, (void*)&tag, MAR_CHR, buf);
                buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data, rec_buf.head, buf);
                buf_done(L, &rec_buf);
                lua_pop(L, 1);
            }
            else {
                tag = MAR_TVAL;

                lua_pushvalue(L, -1);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, SEEN_IDX);

                lua_pushvalue(L, -1);
                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx, nowrap);
                lua_pop(L, 1);

                buf_write(L, (void*)&tag, MAR_CHR, buf);
                buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data,rec_buf.head, buf);
                buf_done(L, &rec_buf);
            }
        }
        break;
    }
    case LUA_TFUNCTION: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            int i;
            lua_Debug ar;
            lua_pop(L, 1); /* pop nil */

            lua_pushvalue(L, -1);
            lua_getinfo(L, ">nuS", &ar);
            //printf("Function name='%s' type='%s' nups=%d\n",ar.namewhat,ar.what,ar.nups);
            if (ar.what[0] != 'L') {
                luaL_error(L, "attempt to persist a C function '%s'", ar.name);
            }
            tag = MAR_TVAL;
            lua_pushvalue(L, -1);
            lua_pushinteger(L, (*idx)++);
            lua_rawset(L, SEEN_IDX);

            lua_pushvalue(L, -1);
            buf_init(L, &rec_buf);
            lua_dump(L, (lua_Writer)buf_write, &rec_buf);

            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
            buf_write(L, rec_buf.data, rec_buf.head, buf);
            buf_done(L, &rec_buf);
            lua_pop(L, 1);

            lua_newtable(L);
            for (i=1; i <= ar.nups; i++) {            	
					 #if LUA_VERSION_NUM > 501
						const char * str=lua_getupvalue(L, -2, i);
					 	if(!strncmp(str,"_ENV",4)) {
		  					//printf("Stripping _ENV\n");
					 		lua_pop(L,1);
					 		lua_pushliteral(L,LEDA_ENV_MARKER);
					 	}
					#else
						lua_getupvalue(L, -2, i);
               #endif
               lua_rawseti(L, -2, i);
            }
            buf_init(L, &rec_buf);
            mar_encode_table(L, &rec_buf, idx, nowrap);

            buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
            buf_write(L, rec_buf.data, rec_buf.head, buf);
            buf_done(L, &rec_buf);
            lua_pop(L, 1);
        }

        break;
    }
    case LUA_TUSERDATA: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (void*)&tag, MAR_CHR, buf);
            buf_write(L, (void*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1); /* pop nil */
            if (!nowrap && luaL_getmetafield(L, -1, "__wrap")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, -2);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, SEEN_IDX);

                lua_pushvalue(L, -2);
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__wrap must return a function");
                }
                lua_newtable(L);
                lua_pushvalue(L, -2);
                lua_rawseti(L, -2, 1);
                lua_remove(L, -2);

                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx, nowrap);

                buf_write(L, (void*)&tag, MAR_CHR, buf);
                buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
		          buf_write(L, rec_buf.data, rec_buf.head, buf);
		          buf_done(L, &rec_buf);
            } else if (luaL_getmetafield(L, -1, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, -2);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, SEEN_IDX);

                lua_pushvalue(L, -2);
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }
                lua_newtable(L);
                lua_pushvalue(L, -2);
                lua_rawseti(L, -2, 1);
                lua_remove(L, -2);

                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx, nowrap);

                buf_write(L, (void*)&tag, MAR_CHR, buf);
                buf_write(L, (void*)&rec_buf.head, MAR_I32, buf);
		          buf_write(L, rec_buf.data, rec_buf.head, buf);
		          buf_done(L, &rec_buf);
            }
            else {
                luaL_error(L, "attempt to encode userdata (no __wrap hook - or not permited - and no __persist hook)");
            }
            lua_pop(L, 1);
        }
        break;
    }
    case LUA_TNIL: break;
    default:
        luaL_error(L, "invalid value type (%s)", lua_typename(L, val_type));
    }
    lua_pop(L, 1);
}
Exemple #28
0
    int writeObjectRaw()
    {
        lua_State *L = m_L;
        uint8_t iType;

        // Save the index to the cache
        lua_pushvalue(L, 2);
        lua_pushnumber(L, (lua_Number)(m_iNextIndex++));
        lua_settable(L, 1);

        // Lookup the object in the permanents table
        lua_pushvalue(L, 2);
        lua_gettable(L, luaT_upvalueindex(1));
        if(lua_type(L, -1) != LUA_TNIL)
        {
            // Object is in the permanents table.

            uint8_t iType = PERSIST_TPERMANENT;
            writeByteStream(&iType, 1);

            // Replace self's environment with self (for call to writeStackObject)
            lua_pushvalue(L, luaT_upvalueindex(2));
            lua_replace(L, 1);

            // Write the key corresponding to the permanent object
            writeStackObject(-1);
        }
        else
        {
            // Object is not in the permanents table.
            lua_pop(L, 1);

            switch(lua_type(L, 2))
            {
            // LUA_TNIL handled in writeStackObject
            // LUA_TBOOLEAN handled in writeStackObject
            // LUA_TNUMBER handled in writeStackObject

            case LUA_TSTRING: {
                iType = LUA_TSTRING;
                writeByteStream(&iType, 1);
                // Strings are simple: length and then bytes (not null terminated)
                size_t iLength;
                const char *sString = lua_tolstring(L, 2, &iLength);
                writeVUInt(iLength);
                writeByteStream(reinterpret_cast<const uint8_t*>(sString), iLength);
                break; }

            case LUA_TTABLE: {
                // Replace self's environment with self (for calls to writeStackObject)
                lua_pushvalue(L, luaT_upvalueindex(2));
                lua_replace(L, 1);

                // Save env and insert prior to table
                lua_getfenv(L, 1);
                lua_insert(L, 2);

                int iTable = 3; table_reentry:

                // Handle the metatable
                if(lua_getmetatable(L, iTable))
                {
                    iType = PERSIST_TTABLE_WITH_META;
                    writeByteStream(&iType, 1);
                    writeStackObject(-1);
                    lua_pop(L, 1);
                }
                else
                {
                    iType = LUA_TTABLE;
                    writeByteStream(&iType, 1);
                }

                // Write the children as key, value pairs
                lua_pushnil(L);
                while(lua_next(L, iTable))
                {
                    writeStackObject(-2);
                    // The naive thing to do now would be writeStackObject(-1)
                    // but this can easily lead to Lua's C call stack limit
                    // being hit. To reduce the likelyhood of this happening,
                    // we check to see if about to write another table.
                    if(lua_type(L, -1) == LUA_TTABLE)
                    {
                        lua_pushvalue(L, -1);
                        lua_rawget(L, 2);
                        lua_pushvalue(L, -2);
                        lua_gettable(L, luaT_upvalueindex(1));
                        if(lua_isnil(L, -1) && lua_isnil(L, -2))
                        {
                            lua_pop(L, 2);
                            lua_checkstack(L, 10);
                            iTable += 2;
                            lua_pushvalue(L, iTable);
                            lua_pushnumber(L, (lua_Number)(m_iNextIndex++));
                            lua_settable(L, 2);
                            goto table_reentry; table_resume:
                            iTable -= 2;
                        }
                        else
                        {
                            lua_pop(L, 2);
                            writeStackObject(-1);
                        }
                    }
                    else
                        writeStackObject(-1);
                    lua_pop(L, 1);
                }

                // Write a nil to mark the end of the children (as nil is the
                // only value which cannot be used as a key in a table).
                iType = LUA_TNIL;
                writeByteStream(&iType, 1);
                if(iTable != 3)
                    goto table_resume;
                break; }

            case LUA_TFUNCTION:
                if(lua_iscfunction(L, 2))
                {
                    setErrorObject(2);
                    setError("Cannot persist C functions");
                }
                else
                {
                    iType = LUA_TFUNCTION;
                    writeByteStream(&iType, 1);

                    // Replace self's environment with self (for calls to writeStackObject)
                    lua_pushvalue(L, luaT_upvalueindex(2));
                    lua_replace(L, 1);

                    // Write the prototype (the part of a function which is common across
                    // multiple closures - see LClosure / Proto in Lua's lobject.h).
                    lua_Debug proto_info;
                    lua_pushvalue(L, 2);
                    lua_getinfo(L, ">Su", &proto_info);
                    writePrototype(&proto_info, 2);

                    // Write the values of the upvalues
                    // If available, also write the upvalue IDs (so that in
                    // the future, we could hypothetically rejoin shared
                    // upvalues). An ID is just an opaque sequence of bytes.
                    writeVUInt(proto_info.nups);
#if LUA_VERSION_NUM >= 502
                    writeVUInt(sizeof(void*));
#else
                    writeVUInt(0);
#endif
                    for(int i = 1; i <= proto_info.nups; ++i)
                    {
                        lua_getupvalue(L, 2, i);
                        writeStackObject(-1);
#if LUA_VERSION_NUM >= 502
                        void *pUpvalueID = lua_upvalueid(L, 2, i);
                        writeByteStream((uint8_t*)&pUpvalueID, sizeof(void*));
#endif
                    }

                    // Write the environment table
                    lua_getfenv(L, 2);
                    writeStackObject(-1);
                    lua_pop(L, 1);
                }
                break;

            case LUA_TUSERDATA:
                if(!_checkThatUserdataCanBeDepersisted(2))
                    break;

                // Replace self's environment with self (for calls to writeStackObject)
                lua_pushvalue(L, luaT_upvalueindex(2));
                lua_replace(L, 1);

                // Write type, metatable, and then environment
                iType = LUA_TUSERDATA;
                writeByteStream(&iType, 1);
                writeStackObject(-1);
                lua_getfenv(L, 2);
                writeStackObject(-1);
                lua_pop(L, 1);

                // Write the raw data
                if(lua_type(L, -1) == LUA_TTABLE)
                {
                    lua_getfield(L, -1, "__persist");
                    if(lua_isnil(L, -1))
                        lua_pop(L, 1);
                    else
                    {
                        lua_pushvalue(L, 2);
                        lua_pushvalue(L, luaT_upvalueindex(2));
                        lua_call(L, 2, 0);
                    }
                }
                writeVUInt((uint64_t)0x42); // sync marker
                break;

            default:
                setError(lua_pushfstring(L, "Cannot persist %s values", luaL_typename(L, 2)));
                break;
            }
        }
        lua_pushnumber(L, 0);
        return 1;
    }
//----------------------------------------------------------------//
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);

}
Exemple #30
0
    void writePrototype(lua_Debug *pProtoInfo, int iInstanceIndex)
    {
        lua_State *L = m_L;

        // Sanity checks
        if(pProtoInfo->source[0] != '@')
        {
            // @ denotes that the source was a file
            // (http://www.lua.org/manual/5.1/manual.html#lua_Debug)
            setError("Can only persist Lua functions defined in source files");
            return;
        }
        if(strcmp(pProtoInfo->what, "Lua") != 0)
        {
            // what == "C" should have been caught by writeObjectRaw().
            // what == "tail" should be impossible.
            // Hence "Lua" and "main" should be the only values seen.
            // NB: Chunks are not functions defined *in* source files, because
            // chunks *are* source files.
            setError(lua_pushfstring(L, "Cannot persist entire Lua chunks (%s)", pProtoInfo->source + 1));
            lua_pop(L, 1);
            return;
        }

        // Attempt cached lookup (prototypes are not publicly visible Lua objects,
        // and hence cannot be cached in the normal way of self's environment).
        lua_getmetatable(L, 1);
        lua_pushfstring(L, "%s:%d", pProtoInfo->source + 1, pProtoInfo->linedefined);
        lua_pushvalue(L, -1);
        lua_rawget(L, -3);
        if(!lua_isnil(L, -1))
        {
            uint64_t iValue = (uint64_t)lua_tonumber(L, -1);
            lua_pop(L, 3);
            writeVUInt(iValue + PERSIST_TCOUNT - 1);
            return;
        }
        lua_pop(L, 1);
        lua_pushvalue(L, -1);
        lua_pushnumber(L, (lua_Number)m_iNextIndex++);
        lua_rawset(L, -4);

        uint8_t iType = PERSIST_TPROTOTYPE;
        writeByteStream(&iType, 1);

        // Write upvalue names
        writeVUInt(pProtoInfo->nups);
        for(int i = 1; i <= pProtoInfo->nups; ++i)
        {
            lua_pushstring(L, lua_getupvalue(L, iInstanceIndex, i));
            writeStackObject(-1);
            lua_pop(L, 2);
        }

        // Write the function's persist name
        lua_rawgeti(L, -2, 1);
        lua_replace(L, -3);
        lua_rawget(L, -2);
        if(lua_isnil(L, -1))
        {
            setError(lua_pushfstring(L, "Lua functions must be given a unique "
                "persistable name in order to be persisted (attempt to persist"
                " %s:%d)", pProtoInfo->source + 1, pProtoInfo->linedefined));
            lua_pop(L, 2);
            return;
        }
        writeStackObject(-1);
        lua_pop(L, 2);
    }