Beispiel #1
0
static int auxresume (lua_State *L, lua_State *co, int narg) {
	int status, stacks;
	int ismain = lua_pushthread(L);
	lua_pop(L, 1);
	if (ismain) {
		lua_pushliteral(L, "cannot call resume in main thread");
		return -1;  /* error flag */
	}
	if (!lua_checkstack(co, narg)) {
		lua_pushliteral(L, "too many arguments to resume");
		return -1;  /* error flag */
	}
	if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
		lua_pushliteral(L, "cannot resume dead coroutine");
		return -1;  /* error flag */
	}
	lua_xmove(L, co, narg);
	context_lua_t *lctx = context_lua_t::lua_get_context(L);
	while (((status = lua_resume(co, L, narg)) == LUA_YIELD) && lctx->yielding_up()) { /* can happen only when status == LUA_YIELD */
		if ((stacks = lua_checkstack(L, LUA_MINSTACK)) && lua_isyieldable(L)) { /* reserve LUA_MINSTACK stack for resume result */
			return lua_yieldk(L, 0, 0, coresume_continue); /* yield again! n(0) result to yield and ctx(0) is not allowed */
		} else { /* lua_gettop(co) must be 0 since context_lua_t::lua_yield_send yield 0 result */
			int yieldup_status = stacks ? NL_EYIELD : NL_ESTACKLESS;
			lctx->yielding_finalize(NULL, yieldup_status);
			lua_pushboolean(co, 0); /* stack on co must be enough since we have checked it at last yield */
			lua_pushinteger(co, yieldup_status);
			lua_pushnil(co);
			lua_pushnil(co);
			narg = 4;
		}
	}
	if (status == LUA_OK || status == LUA_YIELD) {
		int nres = lua_gettop(co);
		if (!lua_checkstack(L, nres + 1)) {
			lua_pop(co, nres);  /* remove results anyway */
			lua_pushliteral(L, "too many results to resume");
			return -1;  /* error flag */
		}
		lua_xmove(co, L, nres);  /* move yielded values */
		return nres;
	} else {
		lua_xmove(co, L, 1);  /* move error message */
		return -1;  /* error flag */
	}
}
Beispiel #2
0
	int jass_call_closure(lua_State* L)
	{								   
		if (!is_gaming())
		{
			lua_pushnil(L);
			return 1;
		}
		int result = jass_call_native_function(L, (const jass::func_value*)lua_tointeger(L, lua_upvalueindex(1)));
		if (lua_isyieldable(L))
		{
			jass_vm_t* thread = get_jass_thread();
			if (thread && thread->has_sleep)
			{
				thread->opcode -= jass::trampoline_size() / sizeof(jass::opcode);
				return lua_yield(L, 0);
			}
		}
		return result;
	}
static int luaB_yieldable (lua_State *L) {
  lua_pushboolean(L, lua_isyieldable(L));
  return 1;
}
Beispiel #4
0
	int jass_call_native_function(lua_State* L, const jass::func_value* nf, uintptr_t func_address)
	{
		LUA_PERFTRACE(kJassCall);

		if (!lua_isyieldable(L) && nf->has_sleep())
		{
			printf("Wanring: %s is disable.\n", lua_tostring(L, lua_upvalueindex(1)));
			lua_pushnil(L);
			return 1;
		}

		size_t param_size = nf->get_param().size();

		if ((int)param_size > lua_gettop(L))
		{
			lua_pushnil(L);
			return 1;
		}

		jass::call_param param(param_size);

		for (size_t i = 0; i < param_size; ++i)
		{
			jass::variable_type vt = nf->get_param()[i];
			switch (vt)
			{
			case jass::TYPE_BOOLEAN:
				param.push(i, jassbind::read_boolean(L, i + 1));
				break;
			case jass::TYPE_CODE:
				param.push(i, jassbind::read_code(L, i + 1));
				break;
			case jass::TYPE_HANDLE:
				param.push(i, jassbind::read_handle(L, i + 1));
				break;
			case jass::TYPE_INTEGER:
				param.push(i, jassbind::read_integer(L, i + 1));
				break;
			case jass::TYPE_REAL:
				param.push_real(i, jassbind::read_real(L, i + 1));
				break;
			case jass::TYPE_STRING:
				param.push(i, lua_tostring(L, i + 1));
				break;
			default:
				param.push(i, 0);
				break;
			}
		}

		if (func_address == 0) func_address = nf->get_address();

		uintptr_t retval = 0;
		if (runtime::catch_crash)
		{
			retval = safe_jass_call(L, func_address, param.data(), param_size);
		}
		else
		{
			retval = jass::call(func_address, param.data(), param_size);
		}


		if (nf->get_return() == jass::TYPE_STRING)
		{
			retval = get_jass_vm()->string_table->get(retval);
		}

		return jass_push(L, nf->get_return(), retval) ? 1 : 0;
	}