当前位置: 首页>>代码示例>>C++>>正文


C++ STACK_GROW函数代码示例

本文整理汇总了C++中STACK_GROW函数的典型用法代码示例。如果您正苦于以下问题:C++ STACK_GROW函数的具体用法?C++ STACK_GROW怎么用?C++ STACK_GROW使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了STACK_GROW函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: exec_setup_stack

int
exec_setup_stack(struct lwp *l, struct exec_package *epp)
{
	u_long max_stack_size;
	u_long access_linear_min, access_size;
	u_long noaccess_linear_min, noaccess_size;

#ifndef	USRSTACK32
#define USRSTACK32	(0x00000000ffffffffL&~PGOFSET)
#endif

	if (epp->ep_flags & EXEC_32) {
		epp->ep_minsaddr = USRSTACK32;
		max_stack_size = MAXSSIZ;
	} else {
		epp->ep_minsaddr = USRSTACK;
		max_stack_size = MAXSSIZ;
	}
	epp->ep_ssize = l->l_proc->p_rlimit[RLIMIT_STACK].rlim_cur;

#ifdef PAX_ASLR
	pax_aslr_stack(l, epp, &max_stack_size);
#endif /* PAX_ASLR */

	l->l_proc->p_stackbase = epp->ep_minsaddr;
	
	epp->ep_maxsaddr = (u_long)STACK_GROW(epp->ep_minsaddr,
		max_stack_size);

	/*
	 * set up commands for stack.  note that this takes *two*, one to
	 * map the part of the stack which we can access, and one to map
	 * the part which we can't.
	 *
	 * arguably, it could be made into one, but that would require the
	 * addition of another mapping proc, which is unnecessary
	 */
	access_size = epp->ep_ssize;
	access_linear_min = (u_long)STACK_ALLOC(epp->ep_minsaddr, access_size);
	noaccess_size = max_stack_size - access_size;
	noaccess_linear_min = (u_long)STACK_ALLOC(STACK_GROW(epp->ep_minsaddr,
	    access_size), noaccess_size);
	if (noaccess_size > 0 && noaccess_size <= MAXSSIZ) {
		NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, noaccess_size,
		    noaccess_linear_min, NULL, 0, VM_PROT_NONE, VMCMD_STACK);
	}
	KASSERT(access_size > 0 && access_size <= MAXSSIZ);
	NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, access_size,
	    access_linear_min, NULL, 0, VM_PROT_READ | VM_PROT_WRITE,
	    VMCMD_STACK);

	return 0;
}
开发者ID:Tommmster,项目名称:netbsd-avr32,代码行数:53,代码来源:exec_subr.c

示例2: keeper_push_linda_storage

int keeper_push_linda_storage( struct s_Universe* U, lua_State* L, void* ptr, unsigned long magic_)
{
	struct s_Keeper* K = keeper_acquire( U->keepers, magic_);
	lua_State* KL = K ? K->L : NULL;
	if( KL == NULL) return 0;
	STACK_GROW( KL, 4);
	STACK_CHECK( KL);
	lua_pushlightuserdata( KL, fifos_key);                      // fifos_key
	lua_rawget( KL, LUA_REGISTRYINDEX);                         // fifos
	lua_pushlightuserdata( KL, ptr);                            // fifos ud
	lua_rawget( KL, -2);                                        // fifos storage
	lua_remove( KL, -2);                                        // storage
	if( !lua_istable( KL, -1))
	{
		lua_pop( KL, 1);                                          //
		STACK_MID( KL, 0);
		return 0;
	}
	// move data from keeper to destination state                  KEEPER                       MAIN
	lua_pushnil( KL);                                           // storage nil
	STACK_GROW( L, 5);
	STACK_CHECK( L);
	lua_newtable( L);                                                                        // out
	while( lua_next( KL, -2))                                   // storage key fifo
	{
		keeper_fifo* fifo = prepare_fifo_access( KL, -1);         // storage key fifo
		lua_pushvalue( KL, -2);                                   // storage key fifo key
		luaG_inter_move( U, KL, L, 1, eLM_FromKeeper);            // storage key fifo          // out key
		STACK_MID( L, 2);
		lua_newtable( L);                                                                      // out key keyout
		luaG_inter_move( U, KL, L, 1, eLM_FromKeeper);            // storage key               // out key keyout fifo
		lua_pushinteger( L, fifo->first);                                                      // out key keyout fifo first
		STACK_MID( L, 5);
		lua_setfield( L, -3, "first");                                                         // out key keyout fifo
		lua_pushinteger( L, fifo->count);                                                      // out key keyout fifo count
		STACK_MID( L, 5);
		lua_setfield( L, -3, "count");                                                         // out key keyout fifo
		lua_pushinteger( L, fifo->limit);                                                      // out key keyout fifo limit
		STACK_MID( L, 5);
		lua_setfield( L, -3, "limit");                                                         // out key keyout fifo
		lua_setfield( L, -2, "fifo");                                                          // out key keyout
		lua_rawset( L, -3);                                                                    // out
		STACK_MID( L, 1);
	}
	STACK_END( L, 1);
	lua_pop( KL, 1);                                            //
	STACK_END( KL, 0);
	keeper_release( K);
	return 1;
}
开发者ID:AlexShiLucky,项目名称:luapower-all,代码行数:50,代码来源:keeper.c

示例3: fifo_pop

// in: fifo
// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number)
static void fifo_pop( lua_State* L, keeper_fifo* fifo, int count_)
{
	int fifo_idx = lua_gettop( L);           // ... fifo
	int i;
	// each iteration pushes a value on the stack!
	STACK_GROW( L, count_ + 2);
	// skip first item, we will push it last
	for( i = 1; i < count_; ++ i)
	{
		int const at = fifo->first + i;
		// push item on the stack
		lua_rawgeti( L, fifo_idx, at);         // ... fifo val
		// remove item from the fifo
		lua_pushnil( L);                       // ... fifo val nil
		lua_rawseti( L, fifo_idx, at);         // ... fifo val
	}
	// now process first item
	{
		int const at = fifo->first;
		lua_rawgeti( L, fifo_idx, at);         // ... fifo vals val
		lua_pushnil( L);                       // ... fifo vals val nil
		lua_rawseti( L, fifo_idx, at);         // ... fifo vals val
		lua_replace( L, fifo_idx);             // ... vals
	}
	{
		// avoid ever-growing indexes by resetting each time we detect the fifo is empty
		int const new_count = fifo->count - count_;
		fifo->first = (new_count == 0) ? 1 : (fifo->first + count_);
		fifo->count = new_count;
	}
}
开发者ID:AlexShiLucky,项目名称:luapower-all,代码行数:33,代码来源:keeper.c

示例4: lua_gc

const char *luaG_openlibs( lua_State *L, const char *libs ) {
    const char *p;
    unsigned len;

	if (!libs) return NULL;     // no libs, not even 'base'

    // 'lua.c' stops GC during initialization so perhaps its a good idea. :)
    //
    lua_gc(L, LUA_GCSTOP, 0);

    // Anything causes 'base' to be taken in
    //
    STACK_GROW(L,2);
    lua_pushcfunction( L, luaopen_base );
    lua_pushliteral( L, "" );
    lua_call( L, 1, 0 );

    for( p= libs; *p; p+=len ) {
        len=0;
        while (*p && !is_name_char(*p)) p++;    // bypass delimiters
        while (is_name_char(p[len])) len++;     // bypass name
        if (len && (!openlib( L, p, len )))
            break;
    }
    lua_gc(L, LUA_GCRESTART, 0);

    return *p ? p : NULL;
}
开发者ID:Rocket-Buddha,项目名称:GameCode4,代码行数:28,代码来源:tools.c

示例5: fifo_pop

// in: fifo
// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number)
static void fifo_pop( lua_State* L, keeper_fifo* fifo, int _count)
{
	int fifo_idx = lua_gettop( L);           // ... fifo
	int i;
	// each iteration pushes a value on the stack!
	STACK_GROW( L, _count + 2);
	// skip first item, we will push it last
	for( i = 1; i < _count; ++ i)
	{
		int const at = fifo->first + i;
		// push item on the stack
		lua_rawgeti( L, fifo_idx, at);         // ... fifo val
		// remove item from the fifo
		lua_pushnil( L);                       // ... fifo val nil
		lua_rawseti( L, fifo_idx, at);         // ... fifo val
	}
	// now process first item
	{
		int const at = fifo->first;
		lua_rawgeti( L, fifo_idx, at);         // ... fifo vals val
		lua_pushnil( L);                       // ... fifo vals val nil
		lua_rawseti( L, fifo_idx, at);         // ... fifo vals val
		lua_replace( L, fifo_idx);             // ... vals
	}
	fifo->first += _count;
	fifo->count -= _count;
}
开发者ID:AlexKordic,项目名称:lanes,代码行数:29,代码来源:keeper.c

示例6: keeper_call

/*
* Call a function ('func_name') in the keeper state, and pass on the returned
* values to 'L'.
*
* 'linda':          deep Linda pointer (used only as a unique table key, first parameter)
* 'starting_index': first of the rest of parameters (none if 0)
*
* Returns: number of return values (pushed to 'L') or -1 in case of error
*/
int keeper_call( lua_State *K, keeper_api_t _func, lua_State *L, void *linda, uint_t starting_index)
{
	int const args = starting_index ? (lua_gettop( L) - starting_index + 1) : 0;
	int const Ktos = lua_gettop( K);
	int retvals = -1;

	STACK_GROW( K, 2);

	PUSH_KEEPER_FUNC( K, _func);

	lua_pushlightuserdata( K, linda);

	if( (args == 0) || luaG_inter_copy( L, K, args) == 0) // L->K
	{
		lua_call( K, 1 + args, LUA_MULTRET);

		retvals = lua_gettop( K) - Ktos;
		if( (retvals > 0) && luaG_inter_move( K, L, retvals) != 0) // K->L
		{
			retvals = -1;
		}
	}
	// whatever happens, restore the stack to where it was at the origin
	lua_settop( K, Ktos);
	return retvals;
}
开发者ID:AntonioModer,项目名称:lua-files,代码行数:35,代码来源:keeper.c

示例7: populate_keepers

// cause each keeper state to populate its database of transferable functions with those from the specified module
// do do this we simply require the module inside the keeper state, then populate the lookup database
void populate_keepers( lua_State* L)
{
	size_t name_len;
	char const* name = luaL_checklstring( L, -1, &name_len);
	int i;

	DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "populate_keepers %s BEGIN\n" INDENT_END, name));
	DEBUGSPEW_CODE( ++ debugspew_indent_depth);

	for( i = 0; i < GNbKeepers; ++ i)
	{
		lua_State* K = GKeepers[i].L;
		int res;
		MUTEX_LOCK( &GKeepers[i].lock_);
		STACK_CHECK( K);
		STACK_GROW( K, 2);
		lua_getglobal( K, "require");
		lua_pushlstring( K, name, name_len);
		res = lua_pcall( K, 1, 1, 0);
		if( res != LUA_OK)
		{
			char const* err = luaL_checkstring( K, -1);
			luaL_error( L, "error requiring '%s' in keeper state: %s", name, err);
		}
		// after requiring the module, register the functions it exported in our name<->function database
		populate_func_lookup_table( K, -1, name);
		lua_pop( K, 1);
		STACK_END( K, 0);
		MUTEX_UNLOCK( &GKeepers[i].lock_);
	}
	DEBUGSPEW_CODE( -- debugspew_indent_depth);
}
开发者ID:AntonioModer,项目名称:lua-files,代码行数:34,代码来源:keeper.c

示例8: push_registry_subtable_mode

/*
* Does what the original 'push_registry_subtable' function did, but adds an optional mode argument to it
*/
void push_registry_subtable_mode( lua_State* L, void* key_, const char* mode_)
{
	STACK_GROW( L, 3);
	STACK_CHECK( L);

	lua_pushlightuserdata( L, key_);                      // key
	lua_rawget( L, LUA_REGISTRYINDEX);                    // {}|nil

	if( lua_isnil( L, -1))
	{
		lua_pop( L, 1);                                     //
		lua_newtable( L);                                   // {}
		lua_pushlightuserdata( L, key_);                    // {} key
		lua_pushvalue( L, -2);                              // {} key {}

		// _R[key_] = {}
		lua_rawset( L, LUA_REGISTRYINDEX);                  // {}

		// Set its metatable if requested
		if( mode_)
		{
			lua_newtable( L);                                 // {} mt
			lua_pushliteral( L, "__mode");                    // {} mt "__mode"
			lua_pushstring( L, mode_);                        // {} mt "__mode" mode
			lua_rawset( L, -3);                               // {} mt
			lua_setmetatable( L, -2);                         // {}
		}
	}
	STACK_END( L, 1);
	ASSERT_L( lua_istable( L, -1));
}
开发者ID:HighlandersFRC,项目名称:2015-lua,代码行数:34,代码来源:deep.c

示例9: luaG_newdeepuserdata

/*
* Create a deep userdata
*
*   proxy_ud= deep_userdata( idfunc [, ...] )
*
* Creates a deep userdata entry of the type defined by 'idfunc'.
* Other parameters are passed on to the 'idfunc' "new" invocation.
*
* 'idfunc' must fulfill the following features:
*
*   lightuserdata = idfunc( eDO_new [, ...] )      -- creates a new deep data instance
*   void = idfunc( eDO_delete, lightuserdata )     -- releases a deep data instance
*   tbl = idfunc( eDO_metatable )                  -- gives metatable for userdata proxies
*
* Reference counting and true userdata proxying are taken care of for the
* actual data type.
*
* Types using the deep userdata system (and only those!) can be passed between
* separate Lua states via 'luaG_inter_move()'.
*
* Returns:  'proxy' userdata for accessing the deep data via 'luaG_todeep()'
*/
int luaG_newdeepuserdata( lua_State* L, luaG_IdFunction idfunc)
{
	char const* errmsg;
	DEEP_PRELUDE* prelude = DEEP_MALLOC( sizeof(DEEP_PRELUDE));
	if( prelude == NULL)
	{
		return luaL_error( L, "couldn't not allocate deep prelude: out of memory");
	}

	prelude->refcount = 0; // 'push_deep_proxy' will lift it to 1
	prelude->idfunc = idfunc;

	STACK_GROW( L, 1);
	STACK_CHECK( L);
	{
		int oldtop = lua_gettop( L);
		prelude->deep = idfunc( L, eDO_new);
		if( prelude->deep == NULL)
		{
			luaL_error( L, "idfunc(eDO_new) failed to create deep userdata (out of memory)");
		}

		if( lua_gettop( L) - oldtop != 0)
		{
			luaL_error( L, "Bad idfunc(eDO_new): should not push anything on the stack");
		}
	}
	errmsg = push_deep_proxy( get_universe( L), L, prelude, eLM_LaneBody);  // proxy
	if( errmsg != NULL)
	{
		luaL_error( L, errmsg);
	}
	STACK_END( L, 1);
	return 1;
}
开发者ID:HighlandersFRC,项目名称:2015-lua,代码行数:57,代码来源:deep.c

示例10: get_idfunc

/*
* Return the registered ID function for 'index' (deep userdata proxy),
* or NULL if 'index' is not a deep userdata proxy.
*/
static inline luaG_IdFunction get_idfunc( lua_State* L, int index, enum eLookupMode mode_)
{
	// when looking inside a keeper, we are 100% sure the object is a deep userdata
	if( mode_ == eLM_FromKeeper)
	{
		DEEP_PRELUDE** proxy = (DEEP_PRELUDE**) lua_touserdata( L, index);
		// we can (and must) cast and fetch the internally stored idfunc
		return (*proxy)->idfunc;
	}
	else
	{
		// essentially we are making sure that the metatable of the object we want to copy is stored in our metatable/idfunc database
		// it is the only way to ensure that the userdata is indeed a deep userdata!
		// of course, we could just trust the caller, but we won't
		luaG_IdFunction ret;
		STACK_GROW( L, 1);
		STACK_CHECK( L);

		if( !lua_getmetatable( L, index))       // deep ... metatable?
		{
			return NULL;    // no metatable: can't be a deep userdata object!
		}

		// replace metatable with the idfunc pointer, if it is actually a deep userdata
		get_deep_lookup( L);                    // deep ... idfunc|nil

		ret = (luaG_IdFunction) lua_touserdata( L, -1); // NULL if not a userdata
		lua_pop( L, 1);
		STACK_END( L, 0);
		return ret;
	}
}
开发者ID:HighlandersFRC,项目名称:2015-lua,代码行数:36,代码来源:deep.c

示例11: keeper_call

/*
* Call a function ('func_name') in the keeper state, and pass on the returned
* values to 'L'.
*
* 'linda':          deep Linda pointer (used only as a unique table key, first parameter)
* 'starting_index': first of the rest of parameters (none if 0)
*
* Returns: number of return values (pushed to 'L') or -1 in case of error
*/
int keeper_call( lua_State *K, keeper_api_t _func, lua_State *L, void *linda, uint_t starting_index)
{
	int const args = starting_index ? (lua_gettop( L) - starting_index + 1) : 0;
	int const Ktos = lua_gettop( K);
	int retvals = -1;

	STACK_GROW( K, 2);

	PUSH_KEEPER_FUNC( K, _func);

	lua_pushlightuserdata( K, linda);

	if( (args == 0) || luaG_inter_copy( L, K, args, eLM_ToKeeper) == 0) // L->K
	{
		lua_call( K, 1 + args, LUA_MULTRET);

		retvals = lua_gettop( K) - Ktos;
		// note that this can raise a luaL_error while the keeper state (and its mutex) is acquired
		// this may interrupt a lane, causing the destruction of the underlying OS thread
		// after this, another lane making use of this keeper can get an error code from the mutex-locking function
		// when attempting to grab the mutex again (WINVER <= 0x400 does this, but locks just fine, I don't know about pthread)
		if( (retvals > 0) && luaG_inter_move( K, L, retvals, eLM_FromKeeper) != 0) // K->L
		{
			retvals = -1;
		}
	}
	// whatever happens, restore the stack to where it was at the origin
	lua_settop( K, Ktos);
	return retvals;
}
开发者ID:AlexKordic,项目名称:lanes,代码行数:39,代码来源:keeper.c

示例12: push_registry_subtable

/*
* Push a registry subtable (keyed by unique 'token') onto the stack.
* If the subtable does not exist, it is created and chained.
*/
static
void push_registry_subtable( lua_State *L, void *token ) {

    STACK_GROW(L,3);

  STACK_CHECK(L)
    
    lua_pushlightuserdata( L, token );
    lua_rawget( L, LUA_REGISTRYINDEX );
        //
        // [-1]: nil/subtable
    
    if (lua_isnil(L,-1)) {
        lua_pop(L,1);
        lua_newtable(L);                    // value
        lua_pushlightuserdata( L, token );  // key
        lua_pushvalue(L,-2);
            //
            // [-3]: value (2nd ref)
            // [-2]: key
            // [-1]: value

        lua_rawset( L, LUA_REGISTRYINDEX );
    }
  STACK_END(L,1)

    ASSERT_L( lua_istable(L,-1) );
}
开发者ID:Rocket-Buddha,项目名称:GameCode4,代码行数:32,代码来源:tools.c

示例13: populate_keepers

// cause each keeper state to populate its database of transferable functions with those from the specified module
void populate_keepers( lua_State *L)
{
	size_t name_len;
	char const *name = luaL_checklstring( L, -1, &name_len);
	size_t package_path_len;
	char const *package_path;
	size_t package_cpath_len;
	char const *package_cpath;
	int i;

	// we need to make sure that package.path & package.cpath are the same in the keepers
// than what is currently in use when the module is required in the caller's Lua state
	STACK_CHECK(L)
	STACK_GROW( L, 3);
	lua_getglobal( L, "package");
	lua_getfield( L, -1, "path");
	package_path = luaL_checklstring( L, -1, &package_path_len);
	lua_getfield( L, -2, "cpath");
	package_cpath = luaL_checklstring( L, -1, &package_cpath_len);

	for( i = 0; i < GNbKeepers; ++ i)
	{
		lua_State *K = GKeepers[i].L;
		int res;
		MUTEX_LOCK( &GKeepers[i].lock_);
		STACK_CHECK(K)
		STACK_GROW( K, 2);
		lua_getglobal( K, "package");
		lua_pushlstring( K, package_path, package_path_len);
		lua_setfield( K, -2, "path");
		lua_pushlstring( K, package_cpath, package_cpath_len);
		lua_setfield( K, -2, "cpath");
		lua_pop( K, 1);
		lua_getglobal( K, "require");
		lua_pushlstring( K, name, name_len);
		res = lua_pcall( K, 1, 0, 0);
		if( res != 0)
		{
			char const *err = luaL_checkstring( K, -1);
			luaL_error( L, "error requiring '%s' in keeper state: %s", name, err);
		}
		STACK_END(K, 0)
		MUTEX_UNLOCK( &GKeepers[i].lock_);
	}
	lua_pop( L, 3);
	STACK_END(L, 0)
}
开发者ID:Abyss116,项目名称:luaplus51-all,代码行数:48,代码来源:keeper.c

示例14: fifo_peek

// in: fifo
// out: ...|nothing
// expects exactly 1 value on the stack!
// currently only called with a count of 1, but this may change in the future
// function assumes that there is enough data in the fifo to satisfy the request
static void fifo_peek( lua_State* L, keeper_fifo* fifo, int _count)
{
	int i;
	STACK_GROW( L, _count);
	for( i = 0; i < _count; ++ i)
	{
		lua_rawgeti( L, 1, fifo->first + i);
	}
}
开发者ID:AlexKordic,项目名称:lanes,代码行数:14,代码来源:keeper.c

示例15: keepercall_set

//in: linda_ud key [val]
int keepercall_set( lua_State* L)
{
	STACK_GROW( L, 6);
	// make sure we have a value on the stack
	if( lua_gettop( L) == 2)                          // ud key val?
	{
		lua_pushnil( L);                                // ud key nil
	}

	// retrieve fifos associated with the linda
	push_table( L, 1);                                // ud key val fifos
	lua_replace( L, 1);                               // fifos key val

	if( !lua_isnil( L, 3)) // set/replace contents stored at the specified key?
	{
		keeper_fifo* fifo;
		lua_pushvalue( L, -2);                          // fifos key val key
		lua_rawget( L, 1);                              // fifos key val fifo|nil
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		if( fifo == NULL) // might be NULL if we set a nonexistent key to nil
		{
			lua_pop( L, 1);                               // fifos key val
			fifo_new( L);                                 // fifos key val fifo
			lua_pushvalue( L, 2);                         // fifos key val fifo key
			lua_pushvalue( L, -2);                        // fifos key val fifo key fifo
			lua_rawset( L, 1);                            // fifos key val fifo
		}
		else // the fifo exists, we just want to clear its contents
		{
			// empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
			lua_newtable( L);                             // fifos key val fifo {}
			lua_setuservalue( L, -2);                     // fifos key val fifo
			fifo->first = 1;
			fifo->count = 0;
		}
		fifo = prepare_fifo_access( L, -1);
		lua_insert( L, -2);                             // fifos key fifo val
		fifo_push( L, fifo, 1);                         // fifos key fifo
	}
	else // val == nil                                // fifos key nil
	{
		keeper_fifo* fifo;
		lua_pop( L, 1);                                 // fifos key
		lua_rawget( L, 1);                              // fifos fifo|nil
		// empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		if( fifo != NULL) // might be NULL if we set a nonexistent key to nil
		{
			lua_newtable( L);                             // fifos fifo {}
			lua_setuservalue( L, -2);                     // fifos fifo
			fifo->first = 1;
			fifo->count = 0;
		}
	}
	return 0;
}
开发者ID:AlexKordic,项目名称:lanes,代码行数:57,代码来源:keeper.c


注:本文中的STACK_GROW函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。