// find
void buildin_string_find(fake * fk, interpreter * inter)
{
	BIF_CHECK_ARG_NUM(3);

	const char * findstr = fkpspopcstrptr(fk);
	int pos = fkpspop<int>(fk);
	const char * srcstr = 0;
	variant * v = 0;
	bool err = false;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_STRING(v, srcstr);
	CHECK_ERR(err);
	
	int len = srcstr ? v->data.str->sz : 0;
	if (pos >= 0 && pos < len && srcstr && findstr)
	{
		const char * find = strstr(srcstr + pos, findstr);
		if (find)
		{
			fkpspush<bool>(fk, true);
			fkpspush<int>(fk, (int)(find - srcstr));
		}
		else
		{
			fkpspush<bool>(fk, false);
			fkpspush<int>(fk, -1);
		}
	}
	else
	{
		fkpspush<bool>(fk, false);
		fkpspush<int>(fk, -1);
	}
}
// typeof
void buildin_typeof(fake * fk, interpreter * inter)
{
	bool err = false;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	const char * name = vartypetostring(v->type);
	fkpspush<const char *>(fk, name);
}
Exemple #3
0
FAKE_API uint64_t fkpspopuint64(fake * fk)
{
	bool err = false;
	uint64_t ret;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_UUID(v, ret);
	CHECK_ERR(err);
	return ret;
}
Exemple #4
0
FAKE_API bool fkpspopbool(fake * fk)
{
	bool err = false;
	bool ret;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_REAL(v, ret);
	CHECK_ERR(err);
	return ret;
}
Exemple #5
0
FAKE_API const char * fkpspopcstrptr(fake * fk)
{
	bool err = false;
	const char * ret = 0;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_STRING(v, ret);
	CHECK_ERR(err);
	return ret;
}
Exemple #6
0
FAKE_API unsigned int fkpspopuint(fake * fk)
{
	bool err = false;
	unsigned int ret;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_REAL(v, ret);
	CHECK_ERR(err);
	return ret;
}
Exemple #7
0
void debuging::resume(bool & isend)
{
	fake * fk = m_fk;
	fkpsclear(fk);
	fkresumeps(fk, isend);
	variant * ret = 0;
	bool err = false;
	PS_POP_AND_GET(fk->ps, ret);
	m_ret = *ret;
	CHECK_ERR(err);
}
// find not
void buildin_string_find_not(fake * fk, interpreter * inter)
{
	BIF_CHECK_ARG_NUM(3);

	const char * findstr = 0;
	variant * findv = 0;
	bool err = false;
	PS_POP_AND_GET(fk->ps, findv);
	V_GET_STRING(findv, findstr);
	CHECK_ERR(err);

	int pos = fkpspop<int>(fk);
	const char * srcstr = 0;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_STRING(v, srcstr);

	int len = srcstr ? v->data.str->sz : 0;
	int findlen = findstr ? findv->data.str->sz : 0;
	if (pos >= 0 && pos < len && srcstr && findstr)
	{
		for (int i = pos; i < len; i++)
		{
			if (strncmp(srcstr + i, findstr, findlen))
			{
				fkpspush<bool>(fk, true);
				fkpspush<int>(fk, i);
				return;
			}
		}
		fkpspush<bool>(fk, false);
		fkpspush<int>(fk, -1);
	}
	else
	{
		fkpspush<bool>(fk, false);
		fkpspush<int>(fk, -1);
	}
}
Exemple #9
0
FAKE_API void fkpspoppointer(fake * fk, void * & p, const char * type)
{
	bool err = false;
	const char * t = 0;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_POINTER(v, p, t);
	if (UNLIKE((p != 0 && !err && strcmp(t, type) != 0)))
	{
		err = true;
		seterror(fk, efk_run_data_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "variant get pointer %s fail, the variant type is %s", type, t);
		p = 0;
	}
	CHECK_ERR(err);
}
Exemple #10
0
// tostring
void buildin_tostring(fake * fk, interpreter * inter)
{
	// container
	bool err = false;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	if (v)
	{
		fkpspush<const char *>(fk, vartostring(v).c_str());
	}
	else
	{
		fkpspush<const char *>(fk, "");
	}
}
Exemple #11
0
// tonumber
void buildin_tonumber(fake * fk, interpreter * inter)
{
	bool err = false;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	double ret = 0;
	if (v->type == variant::STRING)
	{
	 	ret = atof(v->data.str->s);
	}
	else if (v->type == variant::REAL)
	{
		ret = v->data.real;
	}
	else if (v->type == variant::UUID)
	{
		ret = (double)v->data.uuid;
	}
	fkpspush<double>(fk, ret);
}
Exemple #12
0
// size
void buildin_size(fake * fk, interpreter * inter)
{
	bool err = false;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);
	int len = 0;
	if (v->type == variant::STRING)
	{
		len = v->data.str->sz;
	}
	else if (v->type == variant::ARRAY)
	{
		len = ARRAY_SIZE(v->data.va->va);
	}
	else if (v->type == variant::MAP)
	{
		len = v->data.vm->vm.size();
	}
	fkpspush<int>(fk, len);
}
// substr
void buildin_string_substr(fake * fk, interpreter * inter)
{
	BIF_CHECK_ARG_NUM(3);

	int count = fkpspop<int>(fk);
	int pos = fkpspop<int>(fk);
	const char * srcstr = 0;
	variant * v = 0;
	bool err = false;
	PS_POP_AND_GET(fk->ps, v);
	V_GET_STRING(v, srcstr);
	CHECK_ERR(err);
	
	int len = srcstr ? v->data.str->sz : 0;
	if (count == -1)
	{
		count = 0x7FFFFFFF;
	}
	if (count < 0)
	{
		fkpspush<const char *>(fk, "");
		return;
	}
	if ((uint32_t)((uint32_t)pos + (uint32_t)count) > (uint32_t)len)
	{
		count = len - pos;
	}
	
	if (pos >= 0 && pos < len && srcstr && count > 0)
	{
		char * buf = (char *)safe_fkmalloc(fk, count + 1, emt_tmp);
		buf[count] = 0;
		memcpy(buf, srcstr + pos, count);
		fkpspush<const char *>(fk, buf);
		safe_fkfree(fk, buf);
	}
	else
	{
		fkpspush<const char *>(fk, "");
	}
}
Exemple #14
0
void interpreter::call(const variant & func, int retnum, int * retpos)
{
	fake * fk = m_fk;
	paramstack * ps = getps(m_fk);
	const funcunion * f = m_fk->fm.get_func(func);
	bool & err = m_isend;
	USE(err);
	if (UNLIKE(!f))
	{
		FKERR("fkrun no func %s fail", vartostring(&func).c_str());
		m_isend = true;
		seterror(m_fk, efk_run_no_func_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "fkrun no func %s fail", vartostring(&func).c_str());
		return;
	}

	// 常规函数
	if (LIKE(f->havefb))
	{
		const func_binary * fb = &f->fb;
		variant * v = 0;

		// 准备栈大小
		int needsize = m_sp + BP_SIZE + retnum + FUNC_BINARY_MAX_STACK(*fb);
		if (UNLIKE(needsize > (int)ARRAY_MAX_SIZE(m_stack)))
		{
			int newsize = needsize + needsize * m_fk->cfg.array_grow_speed / 100;
			ARRAY_GROW(m_stack, newsize, variant);
		}

		// 老的bp
		int oldbp = m_bp;
		m_bp = m_sp;

		// 记录返回位置
		for (int i = 0; i < retnum; i++)
		{
			v = &ARRAY_GET(m_stack, m_bp);
			v->type = variant::NIL;
			v->data.buf = retpos[i];
			m_bp++;
		}

		// 记录返回值数目
		v = &ARRAY_GET(m_stack, m_bp);
		v->type = variant::NIL;
		v->data.buf = retnum;
		m_bp++;

		// 记录老的ip
		v = &ARRAY_GET(m_stack, m_bp);
		v->type = variant::NIL;
		v->data.buf = m_ip;
		m_bp++;

		// 记录profile
		if (UNLIKE(m_fk->pf.isopen()))
		{
			v = &ARRAY_GET(m_stack, m_bp);
			v->data.buf = fkgetmstick();
		}
		v->type = variant::NIL;
		m_bp++;

		// 记录老的fb
		v = &ARRAY_GET(m_stack, m_bp);
		v->type = variant::NIL;
		v->data.buf = (uint64_t)m_fb;
		m_bp++;

		// 记录老的bp
		v = &ARRAY_GET(m_stack, m_bp);
		v->type = variant::NIL;
		v->data.buf = oldbp;
		m_bp++;

		// 设置sp
		m_sp = m_bp + FUNC_BINARY_MAX_STACK(*fb);
		
		if (UNLIKE((int)ps->m_variant_list_num != FUNC_BINARY_PARAMNUM(*fb)))
		{
			FKERR("call func %s param not match", vartostring(&func).c_str());
			m_isend = true;
			seterror(m_fk, efk_run_param_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "call func %s param not match", vartostring(&func).c_str());
			return;
		}

		assert(FUNC_BINARY_PARAMNUM(*fb) <= REAL_MAX_FAKE_PARAM_NUM);
		assert(m_bp + FUNC_BINARY_PARAMNUM(*fb) <= (int)ARRAY_MAX_SIZE(m_stack));

		// 分配入参
		memcpy(&ARRAY_GET(m_stack, m_bp), ps->m_variant_list, FUNC_BINARY_PARAMNUM(*fb) * sizeof(variant));
		PS_CLEAR(*ps);

		// 重置ret
		V_SET_NIL(&m_ret[0]);

		// 标记
		FUNC_BINARY_USE(*fb)++;

		// 新函数
		m_fb = fb;
		m_ip = 0;

		return;
	}

	// 记录profile
	uint32_t s = 0;
	if (UNLIKE(m_fk->pf.isopen()))
	{
		s = fkgetmstick();
	}

	// 绑定函数
	if (f->haveff)
	{
		BIND_FUNC_CALL(f, this);
		FKLOG("call C func %s", vartostring(&func).c_str());
	}
	// 内置函数
	else if (f->havebif)
	{
		BUILDIN_FUNC_CALL(f, this);
		FKLOG("call buildin func %s", vartostring(&func).c_str());
	}
	else
	{
		assert(0);
		FKERR("fkrun no inter func %s fail", vartostring(&func).c_str());
		m_isend = true;
		seterror(m_fk, efk_run_no_func_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "fkrun no inter func %s fail", vartostring(&func).c_str());
		return;
	}

	// 返回值
	// 这种情况是直接跳过脚本调用了C函数
	if (UNLIKE(BP_END(m_bp)))
	{
		variant * cret;
		PS_POP_AND_GET(*ps, cret);
		m_isend = true;
		// 直接塞返回值
		m_ret[0] = *cret;
	}
	// 否则塞到当前堆栈上
	else
	{
		// 检查返回值数目对不对
		if (UNLIKE((int)ps->m_variant_list_num != retnum))
		{
			FKERR("native func %s param not match, give %d need %d", vartostring(&func).c_str(), (int)ps->m_variant_list_num, retnum);
			m_isend = true;
			seterror(m_fk, efk_run_param_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "native func %s param not match, give %d need %d", vartostring(&func).c_str(), (int)ps->m_variant_list_num, retnum);
			return;
		}
		
		// 塞返回值
		for (int i = 0; i < retnum; i++)
		{
			variant * ret;
			GET_VARIANT(*m_fb, m_bp, ret, retpos[i]);
			
			variant * cret;
			PS_GET(*ps, cret, i);
			
			*ret = *cret;
		}
	}
	
	if (UNLIKE(m_fk->pf.isopen()))
	{
		const char * name = 0;
		V_GET_STRING(&func, name);
		m_fk->pf.add_func_sample(name, fkgetmstick() - s);
	}

	return;
}
Exemple #15
0
// range
void buildin_range(fake * fk, interpreter * inter)
{
	BIF_CHECK_ARG_NUM(2);

	// pos
	int pos = fkpspop<int>(fk);

	// container
	bool err = false;
	variant * v = 0;
	PS_POP_AND_GET(fk->ps, v);

	if (v->type == variant::STRING)
	{
		if (pos >= 0 && pos < (int)v->data.str->sz)
		{
			char data[2];
			data[0] = v->data.str->s[pos];
			data[1] = 0;
			fkpspush<const char *>(fk, data);
		}
		else
		{
			fkpspush<const char *>(fk, "");
		}
	}
	else if (v->type == variant::ARRAY)
	{
		if (pos >= 0 && pos < (int)ARRAY_SIZE(v->data.va->va) && ARRAY_GET(v->data.va->va, pos))
		{
			variant * ret = 0;
			PS_PUSH_AND_GET(fk->ps, ret);
			if (ARRAY_GET(v->data.va->va, pos))
			{
				*ret = *(ARRAY_GET(v->data.va->va, pos));
			}
			else
			{
				*ret = NILV;
			}
		}
		else
		{
			fkpspush<bool>(fk, false);
		}
	}
	else if (v->type == variant::MAP)
	{
		if (pos >= 0 && pos < (int)v->data.vm->vm.size())
		{
			variant * key = 0;
			PS_PUSH_AND_GET(fk->ps, key);
			
			variant * value = 0;
			PS_PUSH_AND_GET(fk->ps, value);
			
			const fkhashmap<variant, variant *>::ele * e = v->data.vm->vm.at(pos);
			*key = e->k;
			*value = *(*e->t);
		}
		else
		{
			fkpspush<bool>(fk, false);
			fkpspush<bool>(fk, false);
		}
	}
	else
	{
		fkpspush<bool>(fk, false);
	}
}
Exemple #16
0
void interpreter::call(const variant & func)
{
    fake * fk = m_fk;
	const funcunion * f = m_fk->fm.get_func(func);
	if (UNLIKE(!f))
	{
		FKERR("fkrun no func %s fail", vartostring(&func).c_str());
		seterror(m_fk, efk_run_no_func_error, "fkrun no func %s fail", vartostring(&func).c_str());
		m_isend = true;
		return;
	}

	// 常规函数
	if (f->havefb)
	{
		const func_binary * fb = &f->fb;

		// 空函数处理
		if (UNLIKE(!FUNC_BINARY_CMDSIZE(*fb)))
		{
			// 所有都完
			if (ARRAY_EMPTY(m_stack_list))
			{
				FKLOG("call stack empty end");
				m_isend = true;
			}
			return;
		}

		// 压栈
		if (UNLIKE(ARRAY_SIZE(m_stack_list) >= ARRAY_MAX_SIZE(m_stack_list)))
		{
			int newsize = ARRAY_MAX_SIZE(m_stack_list) + 1 + ARRAY_MAX_SIZE(m_stack_list) * m_fk->cfg.array_grow_speed / 100;
			ARRAY_GROW(m_stack_list, newsize, stack);
		}
		ARRAY_PUSH_BACK(m_stack_list);
		stack & s = ARRAY_BACK(m_stack_list);
		m_cur_stack = &s;
		STACK_INI(s, m_fk, fb);
		if (UNLIKE(FUNC_BINARY_MAX_STACK(*fb) > (int)ARRAY_MAX_SIZE(s.m_stack_variant_list)))
		{
			ARRAY_GROW(s.m_stack_variant_list, FUNC_BINARY_MAX_STACK(*fb), variant);
		}

		// 记录profile
		beginfuncprofile();
		
		paramstack * ps = getps(m_fk);

		if (UNLIKE((int)ps->m_variant_list_num != FUNC_BINARY_PARAMNUM(*fb)))
		{
			FKERR("call func %s param not match", vartostring(&func).c_str());
			seterror(m_fk, efk_run_param_error, "call func %s param not match", vartostring(&func).c_str());
			m_isend = true;
			return;
		}

		assert(FUNC_BINARY_PARAMNUM(*fb) <= (int)ARRAY_MAX_SIZE(s.m_stack_variant_list));

		// 分配栈空间
		for (int i = 0; i < (int)FUNC_BINARY_PARAMNUM(*fb); i++)
		{
			SET_STACK(&(ps->m_variant_list[i]), s, i);
			FKLOG("call set %s to pos %d", (vartostring(&(ps->m_variant_list[i]))).c_str(), i);
		}
		
		ps->clear();

		// 重置ret
		V_SET_NIL(&m_ret[0]);

		// 标记
		FUNC_BINARY_USE(*fb)++;

		return;
	}

	// 记录profile
	uint32_t s = 0;
	if (m_fk->pf.isopen())
	{
		s = fkgetmstick();
	}

	// 绑定函数
	if (f->haveff)
	{
		BIND_FUNC_CALL(f, this);
		FKLOG("call C func %s", vartostring(&func).c_str());
	}
	// 内置函数
	else if (f->havebif)
	{
		BUILDIN_FUNC_CALL(f, this);
		FKLOG("call buildin func %s", vartostring(&func).c_str());
	}
	else
	{
		assert(0);
		FKERR("fkrun no inter func %s fail", vartostring(&func).c_str());
		seterror(m_fk, efk_run_no_func_error, "fkrun no inter func %s fail", vartostring(&func).c_str());
		m_isend = true;
		return;
	}

	// 返回值
	paramstack * theps = getps(m_fk);
    bool err = false;
	USE(err);

	// 这种情况是直接跳过脚本调用了C函数
	if (UNLIKE(ARRAY_EMPTY(m_stack_list)))
	{
    	variant * cret;
    	PS_POP_AND_GET(*theps, cret);
		m_isend = true;
		// 直接塞返回值
		m_ret[0] = *cret;
	}
	// 否则塞到当前堆栈上
	else
	{
		// 塞返回值
		m_cur_stack = &ARRAY_BACK(m_stack_list);
		const func_binary & fb = *m_cur_stack->m_fb;
		for (int i = 0; i < m_cur_stack->m_retnum; i++)
		{
			variant * ret;
			GET_VARIANT(*m_cur_stack, fb, ret, m_cur_stack->m_retvpos[i]);
			
        	variant * cret;
        	PS_GET(*theps, cret, i);
        	
			*ret = *cret;
		}
	}
    if (UNLIKE(err))
    {
        m_isend = true;
    }
    
	if (m_fk->pf.isopen())
	{
	    bool err = false;
		const char * name = 0;
		V_GET_STRING(&func, name);
		m_fk->pf.add_func_sample(name, fkgetmstick() - s);
	}

	return;
}