Ejemplo n.º 1
0
bool compiler::compile_assign_stmt(codegen & cg, assign_stmt * as)
{
	FKLOG("[compiler] compile_assign_stmt %p", as);

	command var = 0;
	command value = 0;

	if (!compile_node(cg, as->value))
	{
		FKERR("[compiler] compile_assign_stmt value fail");
		return false;
	}
	value = m_cur_addr;
	FKLOG("[compiler] compile_assign_stmt value = %d", m_cur_addr);

	m_new_var = as->isnew;
	if (!compile_node(cg, as->var))
	{
		FKERR("[compiler] compile_assign_stmt var fail");
		return false;
	}
	m_new_var = false;
	var = m_cur_addr;
	FKLOG("[compiler] compile_assign_stmt var = %d", m_cur_addr);
	
	cg.push(MAKE_OPCODE(OPCODE_ASSIGN), as->lineno());
	cg.push(var, as->lineno());
	cg.push(value, as->lineno());
	FKLOG("[compiler] compile_assign_stmt %p OK", as);
	
	return true;
}
Ejemplo n.º 2
0
bool compiler::compile_return_value_list(codegen & cg, return_value_list_node * rn)
{
	FKLOG("[compiler] compile_return_value_list %p", rn);

	if (rn->returnlist.size() > MAX_FAKE_RETURN_NUM)
	{
		FKERR("[compiler] compile_return_value_list return too much");
		compile_seterror(rn, m_fk, efk_compile_variable_not_found, "return too much");
		return false;
	}
	
	command tmp[MAX_FAKE_RETURN_NUM];
	for (int i = 0; i < (int)rn->returnlist.size(); i++)
	{
		if (!compile_node(cg, rn->returnlist[i]))
		{
			FKERR("[compiler] compile_return_value_list value fail");
			return false;
		}
		tmp[i] = m_cur_addr;
	}
	memcpy(m_cur_addrs, tmp, sizeof(command) * MAX_FAKE_RETURN_NUM);
	m_cur_addr = m_cur_addrs[0];

	FKLOG("[compiler] compile_return_value_list %p OK", rn);

	return true;
}
Ejemplo n.º 3
0
bool compiler::compile_continue_stmt(codegen & cg, continue_stmt * cs)
{
	FKLOG("[compiler] compile_continue_stmt %p", cs);

	if (m_loop_continue_pos_stack.empty())
	{
		FKERR("[compiler] compile_continue_stmt no loop to continue");
		compile_seterror(cs, m_fk, efk_compile_loop_error, "no loop to continue");
		return false;
	}

	int continuepos = m_loop_continue_pos_stack[m_loop_continue_pos_stack.size() - 1];
	
	cg.push(MAKE_OPCODE(OPCODE_JMP), cs->lineno());
	cg.push(MAKE_POS(continuepos), cs->lineno());
	
	if (continuepos == -1)
	{
		// 一会统一设置
		int pos = cg.byte_code_size() - 1;
		continue_end_pos_list & cplist = m_continue_end_pos_stack[m_continue_end_pos_stack.size() - 1];
		cplist.push_back(pos);
	}

	FKLOG("[compiler] compile_continue_stmt %p OK", cs);
	
	return true;
}
Ejemplo n.º 4
0
bool compiler::compile_return_stmt(codegen & cg, return_stmt * rs)
{
	FKLOG("[compiler] compile_return_stmt %p", rs);

	if (rs->returnlist)
	{
		if (!compile_node(cg, rs->returnlist))
		{
			FKERR("[compiler] compile_return_stmt ret fail");
			return false;
		}

		cg.push(MAKE_OPCODE(OPCODE_RETURN), rs->lineno());
		cg.push(MAKE_POS(rs->returnlist->returnlist.size()), rs->lineno());
		for (int i = 0; i < (int)rs->returnlist->returnlist.size(); i++)
		{
			cg.push(m_cur_addrs[i], rs->lineno());
		}
	}
	else
	{
		cg.push(MAKE_OPCODE(OPCODE_RETURN), rs->lineno());
		cg.push(MAKE_POS(0), rs->lineno());
	}

	FKLOG("[compiler] compile_return_stmt %p OK", rs);
	
	return true;
}
Ejemplo n.º 5
0
bool compiler::compile_const_head()
{
	FKLOG("[compiler] compile_const_head");
	
	myflexer * mf = m_mf;

	// 注册全局常量表
	explicit_value_map & evm = mf->get_const_map();
	for (explicit_value_map::iterator it = evm.begin(); it != evm.end(); it++)
	{   
		String name = it->first;
		explicit_value_node* ev = it->second;
		
		variant v;
		if (!compile_explicit_value_node_to_variant(ev, v))
		{
			FKERR("[compiler] compile_explicit_value_node_to_variant %s %s fail", name.c_str(), ev->str.c_str());
			return false;
		}
		
		String constname = fkgen_package_name(m_mf->get_package(), name);

		m_fk->pa.reg_const_define(constname.c_str(), v, ev->lineno());
		FKLOG("[compiler] reg_const_define %s %s", constname.c_str(), vartostring(&v).c_str());
	}
	
	return true;
}
Ejemplo n.º 6
0
bool compiler::compile()
{
	if (!compile_const_head())
	{
		FKERR("[compiler] compile_const_head fail");
		return false;
	}

	if (!compile_body())
	{
		FKERR("[compiler] compile_body fail");
		return false;
	}
	
	return true;
}
Ejemplo n.º 7
0
bool assembler::compile_single(asmgen & asg, const func_binary & fb, command cmd)
{
	int code = COMMAND_CODE(cmd);

	int left = 0;
	GET_VARIANT_POS(fb, left, m_pos);
	m_pos++;

	assert(ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_STACK || ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_CONTAINER);
	int dest = 0;
	GET_VARIANT_POS(fb, dest, m_pos);
	m_pos++;

	switch (code)
	{
	case OPCODE_NOT:
		asg.variant_not(dest, left);
		break;
	default:
		assert(0);
		FKERR("[assembler] compile_single err code %d %s", code, OpCodeStr(code));
		break;
	}
	
	return true;
}
Ejemplo n.º 8
0
bool compiler::compile_multi_assign_stmt(codegen & cg, multi_assign_stmt * as)
{
	FKLOG("[compiler] compile_multi_assign_stmt %p", as);

	// 目前多重赋值只支持a,b,c = myfunc1(),需要告诉func1多返回几个值
	m_func_ret_num = as->varlist->varlist.size();

	// 编译value
	if (!compile_node(cg, as->value))
	{
		FKERR("[compiler] compile_multi_assign_stmt value fail");
		return false;
	}

	// 挨个编译var
	std::vector<command> varlist;
	for (int i = 0; i < (int)as->varlist->varlist.size(); i++)
	{
		m_new_var = as->isnew;
		if (!compile_node(cg, as->varlist->varlist[i]))
		{
			FKERR("[compiler] compile_multi_assign_stmt var fail");
			return false;
		}
		m_new_var = false;
		varlist.push_back(m_cur_addr);
	}

	// 挨个赋值
	for (int i = 0; i < (int)as->varlist->varlist.size(); i++)
	{
		command var = 0;
		command value = 0;

		var = varlist[i];
		value = m_cur_addrs[i];

		cg.push(MAKE_OPCODE(OPCODE_ASSIGN), as->lineno());
		cg.push(var, as->lineno());
		cg.push(value, as->lineno());
	}

	FKLOG("[compiler] compile_multi_assign_stmt %p OK", as);

	return true;
}
Ejemplo n.º 9
0
bool assembler::compile(binary * bin)
{
	FKLOG("[assembler] compile binary %p", bin);

#ifndef FK64
	// 32位目前不支持
	return true;
#endif

	if (!m_isopen)
	{
		return true;
	}
	
	for (const fkhashmap<variant, funcunion>::ele * p = m_fk->fm.m_shh.first(); p != 0; p = m_fk->fm.m_shh.next())
	{
		const funcunion & f = *p->t;
		if (f.havefb && FUNC_BINARY_FRESH(f.fb))
		{
			const func_binary & fb = f.fb;
			if (FUNC_BINARY_BACKUP(fb))
			{
				const func_binary & bkfb = *FUNC_BINARY_BACKUP(fb);
				if (!compile_func(bkfb))
				{
					FKERR("[assembler] compile compile_func %s fail", FUNC_BINARY_NAME(bkfb));
					return false;
				}
				FUNC_BINARY_FRESH(bkfb)--;
			}
			else
			{
				if (!compile_func(fb))
				{
					FKERR("[assembler] compile compile_func %s fail", FUNC_BINARY_NAME(fb));
					return false;
				}
				FUNC_BINARY_FRESH(fb)--;
			}
		}
	}
	
	FKLOG("[assembler] compile binary %d ok \n%s", bin, m_native->dump().c_str());

	return true;
}
Ejemplo n.º 10
0
bool compiler::compile_var_node(codegen & cg, var_node * vn)
{
	FKLOG("[compiler] compile_var_node %p", vn);

	// 确保当前block没有
	if (cg.get_cur_variable_pos(vn->str) != -1)
	{
		FKERR("[compiler] compile_var_node variable has define %s", vn->str.c_str());
		compile_seterror(vn, m_fk, efk_compile_variable_has_define, "variable %s has define", vn->str.c_str());
		return false;
	}

	// 看看是否是常量定义
	myflexer * mf = m_mf;
	explicit_value_map & evm = mf->get_const_map();
	if (evm.find(vn->str) != evm.end())
	{   
		FKERR("[compiler] compile_var_node variable has defined const %s", vn->str.c_str());
		compile_seterror(vn, m_fk, efk_compile_variable_has_define, "variable %s has defined const", vn->str.c_str());
		return false;
	}

	// 看看是否是全局常量定义
	variant * gcv = m_fk->pa.get_const_define(vn->str.c_str());
	if (gcv)
	{
		FKERR("[compiler] compile_var_node variable has defined global const %s", vn->str.c_str());
		compile_seterror(vn, m_fk, efk_compile_variable_has_define, "variable %s has defined global const", vn->str.c_str());
		return false;
	}

	// 申请栈上空间
	int pos = cg.add_stack_identifier(vn->str, vn->lineno());
	if (pos == -1)
	{
		FKERR("[compiler] compile_var_node variable has define %s", vn->str.c_str());
		compile_seterror(vn, m_fk, efk_compile_stack_identifier_error, "double %s identifier error", vn->str.c_str());
		return false;
	}
	m_cur_addr = MAKE_ADDR(ADDR_STACK, pos);

	FKLOG("[compiler] compile_var_node %p OK", vn);
	
	return true;
}
Ejemplo n.º 11
0
bool compiler::compile_container_get(codegen & cg, container_get_node * cn)
{
	FKLOG("[compiler] compile_container_get %p", cn);

	// 编译con
	command con = 0;

	// 看看是否是全局常量定义
	variant * gcv = m_fk->pa.get_const_define(cn->container.c_str());
	if (gcv)
	{
		int pos = cg.getconst(*gcv);
		con = MAKE_ADDR(ADDR_CONST, pos);
	}
	else
	{
		int pos = cg.getvariable(cn->container);
		if (pos == -1)
		{
			FKERR("[compiler] compile_container_get variable not found %s", cn->container.c_str());
			compile_seterror(cn, m_fk, efk_compile_variable_not_found, "variable %s not found", cn->container.c_str());
			return false;
		}
		con = MAKE_ADDR(ADDR_STACK, pos);
	}

	// 编译key
	command key = 0;
	if (!compile_node(cg, cn->key))
	{
		FKERR("[compiler] compile_container_get key fail");
		return false;
	}
	key = m_cur_addr;

	// 返回
	int addrpos = cg.getcontaineraddr(con, key);
	m_cur_addr = MAKE_ADDR(ADDR_CONTAINER, addrpos);
	
	FKLOG("[compiler] compile_container_get %p OK", cn);

	return true;
}
Ejemplo n.º 12
0
FAKE_API void fkpushfunctor(fake * fk, const char * prefix, const char * name, fkfunctor ff)
{
	FKLOG("fkpushfunctor %p %s %s", fk, prefix, name);
	String tmp = (String)prefix + name;
	if (UNLIKE(tmp.size() >= MAX_FAKE_REG_FUNC_NAME_LEN))
	{
		seterror(fk, efk_reg_func_toolong, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "reg func name too long, func %s, max %d", tmp.c_str(), MAX_FAKE_REG_FUNC_NAME_LEN);
		FKERR("reg func name too long, func %s, max %d", tmp.c_str(), MAX_FAKE_REG_FUNC_NAME_LEN);
		return;
	}
	fk->bf.addfunc(fk->sh.allocsysstr(tmp.c_str()), ff);
}
Ejemplo n.º 13
0
bool assembler::compile_single_jne(asmgen & asg, const func_binary & fb, command cmd)
{
	int code = COMMAND_CODE(cmd);

	int left = 0;
	GET_VARIANT_POS(fb, left, m_pos);
	m_pos++;

	assert(ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_STACK || ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_CONTAINER);
	int dest = 0;
	GET_VARIANT_POS(fb, dest, m_pos);
	m_pos++;

	int jump_bytecode_pos = COMMAND_CODE(GET_CMD(fb, m_pos));
	m_pos++;

	// 1.先计算结果
	switch (code)
	{
	case OPCODE_NOT_JNE:
		asg.variant_not(dest, left);
		break;
	default:
		assert(0);
		FKERR("[assembler] compile_single_jne err code %d %s", code, OpCodeStr(code));
		break;
	}

	// 2.再jne
	int jumppos = -1;
	if (m_posmap.find(jump_bytecode_pos) != m_posmap.end())
	{
		jumppos = m_posmap[jump_bytecode_pos];
	}

	asg.variant_jne(dest, jumppos);

	int jmpoffset = asg.size() - sizeof(int);
	if (jumppos == -1)
	{
		// 记录下来
		m_caremap[jmpoffset] = jump_bytecode_pos;
		FKLOG("compile_single_jne caremap add %d %d", jmpoffset, jump_bytecode_pos);
	}
	else
	{
		asg.set_int(jmpoffset, jumppos - asg.size());
		FKLOG("compile_single_jne set jne add %d -> %d", jmpoffset, jumppos - asg.size());
	}
	
	return true;
}
Ejemplo n.º 14
0
bool assembler::compile_cmp(asmgen & asg, const func_binary & fb, command cmd)
{
	int code = COMMAND_CODE(cmd);

	int left = 0;
	GET_VARIANT_POS(fb, left, m_pos);
	m_pos++;

	int right = 0;
	GET_VARIANT_POS(fb, right, m_pos);
	m_pos++;

	assert(ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_STACK || ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_CONTAINER);
	int dest = 0;
	GET_VARIANT_POS(fb, dest, m_pos);
	m_pos++;

	switch (code)
	{
	case OPCODE_AND:
		asg.variant_and(dest, left, right);
		break;
	case OPCODE_OR:
		asg.variant_or(dest, left, right);
		break;
	case OPCODE_LESS:
		asg.variant_less(dest, left, right);
		break;
	case OPCODE_MORE:
		asg.variant_more(dest, left, right);
		break;
	case OPCODE_EQUAL:
		asg.variant_equal(dest, left, right);
		break;
	case OPCODE_MOREEQUAL:
		asg.variant_moreequal(dest, left, right);
		break;
	case OPCODE_LESSEQUAL:
		asg.variant_lessequal(dest, left, right);
		break;
	case OPCODE_NOTEQUAL:
		asg.variant_notequal(dest, left, right);
		break;
	default:
		assert(0);
		FKERR("[assembler] compile_cmp err code %d %s", code, OpCodeStr(code));
		break;
	}

	return true;
}
Ejemplo n.º 15
0
bool compiler::compile_block(codegen & cg, block_node * blocknode)
{
	FKLOG("[compiler] compile_block block_node %p", blocknode);

	for (int i = 0; i < (int)blocknode->stmtlist.size(); i++)
	{
		syntree_node * stmt = blocknode->stmtlist[i];
		if (!compile_node(cg, stmt))
		{
			FKERR("[compiler] compile_block compile_node %p fail %s", blocknode, stmt->gettypename());
			return false;
		}
	}
	
	FKLOG("[compiler] compile_block block_node %p OK", blocknode);
	
	return true;
}
Ejemplo n.º 16
0
bool compiler::compile_explicit_value(codegen & cg, explicit_value_node * ev)
{
	FKLOG("[compiler] compile_explicit_value %p %s", ev, ev->str.c_str());

	variant v;
	if (!compile_explicit_value_node_to_variant(ev, v))
	{
		FKERR("[compiler] compile_explicit_value_node_to_variant %s fail", ev->str.c_str());
		return false;
	}

	int pos = cg.getconst(v);
	m_cur_addr = MAKE_ADDR(ADDR_CONST, pos);

	FKLOG("[compiler] compile_explicit_value %p OK", ev);
	
	return true;
}
Ejemplo n.º 17
0
bool assembler::compile_math(asmgen & asg, const func_binary & fb, command cmd)
{
	int code = COMMAND_CODE(cmd);

	int left = 0;
	GET_VARIANT_POS(fb, left, m_pos);
	m_pos++;
	
	int right = 0;
	GET_VARIANT_POS(fb, right, m_pos);
	m_pos++;

	assert (ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_STACK || ADDR_TYPE(COMMAND_CODE(GET_CMD(fb, m_pos))) == ADDR_CONTAINER);
	int dest = 0;
	GET_VARIANT_POS(fb, dest, m_pos);
	m_pos++;

	switch (code)
	{
	case OPCODE_PLUS:
		asg.variant_add(dest, left, right);
		break;
	case OPCODE_MINUS:
		asg.variant_sub(dest, left, right);
		break;
	case OPCODE_MULTIPLY:
		asg.variant_mul(dest, left, right);
		break;
	case OPCODE_DIVIDE:
		asg.variant_div(dest, left, right);
		break;
	case OPCODE_DIVIDE_MOD:
		asg.variant_div_mod(dest, left, right);
		break;
	default:
		assert(0);
		FKERR("[assembler] compile_math err code %d %s", code, OpCodeStr(code));
		break;
	}
	
	return true;
}
Ejemplo n.º 18
0
bool compiler::compile_yield_stmt(codegen & cg, yield_stmt * ys)
{
	FKLOG("[compiler] compile_yield_stmt %p", ys);

	// 编译time
	command time = 0;
	if (!compile_node(cg, ys->time))
	{
		FKERR("[compiler] compile_sleep_stmt time fail");
		return false;
	}
	time = m_cur_addr;

	cg.push(MAKE_OPCODE(OPCODE_YIELD), ys->lineno());
	cg.push(time, ys->lineno());
	
	FKLOG("[compiler] compile_yield_stmt %p OK", ys);

	return true;
}
Ejemplo n.º 19
0
bool compiler::compile_variable_node(codegen & cg, variable_node * vn)
{
	FKLOG("[compiler] compile_variable_node %p", vn);

	// 看看是否是全局常量定义
	String constname = fkgen_package_name(m_mf->get_package(), vn->str.c_str());
	variant * gcv = m_fk->pa.get_const_define(constname.c_str());
	if (gcv)
	{
		int pos = cg.getconst(*gcv);
		m_cur_addr = MAKE_ADDR(ADDR_CONST, pos);
		FKLOG("[compiler] compile_variable_node %p OK", vn);
		return true;
	}

	// 从当前堆栈往上找
	int pos = cg.getvariable(vn->str);
	if (pos == -1)
	{
		// 是不是需要new出来
		if (m_new_var)
		{
			var_node tmp;
			tmp.str = vn->str;
			return compile_var_node(cg, &tmp);
		}
		else
		{
			FKERR("[compiler] compile_variable_node variable not found %s", vn->str.c_str());
			compile_seterror(vn, m_fk, efk_compile_variable_not_found, "variable %s not found", vn->str.c_str());
			return false;
		}
	}
	m_cur_addr = MAKE_ADDR(ADDR_STACK, pos);

	FKLOG("[compiler] compile_variable_node %p OK", vn);
	
	return true;
}
Ejemplo n.º 20
0
bool compiler::compile_body()
{
	myflexer * mf = m_mf;
	func_desc_list & funclist = mf->get_func_list();
	FKLOG("[compiler] compile_body funclist %d", funclist.size());

	for (int i = 0; i < (int)funclist.size(); i++)
	{
		func_desc_node * funcnode = funclist[i];
		if (!compile_func(funcnode))
		{   
			FKERR("[compiler] compile_body %s fail", funcnode->funcname.c_str());
			return false;
		}
	}
	
	FKLOG("[compiler] compile_body funclist %d ok dump \n%s", funclist.size(), m_fk->bin.dump().c_str());

	FKLOG("[compiler] compile_body funcmap %d ok dump \n%s", m_fk->fm.size(), m_fk->fm.dump().c_str());

	return true;
}
Ejemplo n.º 21
0
bool parser::parse_include(const String & srcname, const String & includename)
{
	// 拼include的名字
	String dir = srcname;
	std::replace(dir.begin(), dir.end(), '\\', '/');
	int pos = dir.find_last_of('/');
	if (pos == -1)
	{
		dir = "";
	}
	else
	{
		dir = dir.substr(0, pos + 1);
	}
	dir += includename;

	// 解析
	if (!parse(dir.c_str()))
	{
		FKERR("parse_include %s fail", dir.c_str());
		return false;
	}
	return true;
}
Ejemplo n.º 22
0
bool assembler::compile_next(asmgen & asg, const func_binary & fb)
{
	command cmd = GET_CMD(fb, m_pos);
	int type = COMMAND_TYPE(cmd);
	int code = COMMAND_CODE(cmd);

	USE(type);
	FKLOG("[assembler] compile_next cmd %d %d %s", type, code, OpCodeStr(code));
		
	assert (type == COMMAND_OPCODE);

	m_pos++;

	m_conposnum = 0;
	memset(m_conpos, 0, sizeof(m_conpos));

	bool ret = false;
	USE(ret);
	// 执行对应命令,放一起switch效率更高,cpu有缓存
	switch (code)
	{
	case OPCODE_ASSIGN:
		{
			ret = compile_assign(asg, fb, cmd);
		}
		break;
	case OPCODE_RETURN:
		{
			ret = compile_return(asg, fb, cmd);
		}
		break;
	case OPCODE_PLUS:
	case OPCODE_MINUS:
	case OPCODE_MULTIPLY:
	case OPCODE_DIVIDE:
	case OPCODE_DIVIDE_MOD:
		{
			ret = compile_math(asg, fb, cmd);
		}
		break;
	case OPCODE_PLUS_ASSIGN:
	case OPCODE_MINUS_ASSIGN:
	case OPCODE_MULTIPLY_ASSIGN:
	case OPCODE_DIVIDE_ASSIGN:
	case OPCODE_DIVIDE_MOD_ASSIGN:
		{
			ret = compile_math_assign(asg, fb, cmd);
		}
		break;
	case OPCODE_AND:
	case OPCODE_OR:
	case OPCODE_LESS:
	case OPCODE_MORE:
	case OPCODE_EQUAL:
	case OPCODE_MOREEQUAL:
	case OPCODE_LESSEQUAL:
	case OPCODE_NOTEQUAL:
		{
			ret = compile_cmp(asg, fb, cmd);
		}
		break;
	case OPCODE_AND_JNE:
	case OPCODE_OR_JNE:
	case OPCODE_LESS_JNE:
	case OPCODE_MORE_JNE:
	case OPCODE_EQUAL_JNE:
	case OPCODE_MOREEQUAL_JNE:
	case OPCODE_LESSEQUAL_JNE:
	case OPCODE_NOTEQUAL_JNE:
		{
			ret = compile_cmp_jne(asg, fb, cmd);
		}
		break;
	case OPCODE_NOT:
		{
			ret = compile_single(asg, fb, cmd);
		}
		break;
	case OPCODE_NOT_JNE:
		{
			ret = compile_single_jne(asg, fb, cmd);
		}
		break;
	case OPCODE_JNE:
		{
			ret = compile_jne(asg, fb, cmd);
		}
		break;
	case OPCODE_JMP:
		{
			ret = compile_jmp(asg, fb, cmd);
		}
		break;
	case OPCODE_CALL:
		{
			ret = compile_call(asg, fb, cmd);
		}
		break;
	case OPCODE_SLEEP:
	case OPCODE_YIELD:
		{
			setwarn(m_fk, "assembler only support SLEEP or YIELD, skip code");
			ret = true;
			m_pos++;
		}
		break;
	case OPCODE_FORBEGIN:
	case OPCODE_FORLOOP:
		{
			FKERR("assembler dont support for i -> n, j");
			compile_seterror(fb, cmd, efk_jit_error, "assembler dont support for i -> n, j");
			return false;
		}
		break;
	default:
		assert(0);
		FKERR("[assembler] compile_next err code %d %s", code, OpCodeStr(code));
		compile_seterror(fb, cmd, efk_jit_error, "compile_next err code %d %s", code, OpCodeStr(code));
		return false;
	}
	return ret;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
int interpreter::run(int cmdnum)
{
	fake * fk = m_fk;
	bool & err = m_isend;
	int i = 0;
	
	// 栈溢出检查
	if (UNLIKE((int)ARRAY_MAX_SIZE(m_stack) > m_fk->cfg.stack_max))
	{	
		m_isend = true;
		seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "stack too big %d", ARRAY_MAX_SIZE(m_stack));
		return 0;
	}

	// 切换检查
	if (UNLIKE(m_sleeping))
	{
		if (LIKE(m_yieldtime))
		{
			m_yieldtime--;
			return 0;
		}
		else if (LIKE(fkgetmstick() < m_wakeuptime))
		{
			return 0;
		}
		else
		{
			m_wakeuptime = 0;
		}
	}
	
	if (UNLIKE(m_isend))
	{
		return 0;
	}
	
	while (1)
	{
		// 当前函数走完
		if (UNLIKE(m_ip >= (int)FUNC_BINARY_CMDSIZE(*m_fb)))
		{
			FKLOG("pop stack %s", FUNC_BINARY_NAME(*m_fb));
			
			// 记录profile
			if (UNLIKE(m_fk->pf.isopen()))
			{
				uint32_t calltime = 0;
				BP_GET_CALLTIME(m_bp, calltime);
				m_fk->pf.add_func_sample(FUNC_BINARY_NAME(*m_fb), fkgetmstick() - calltime);
			}
			
			// 标记
			FUNC_BINARY_USE(*m_fb)--;
			
			// 更新
			if (UNLIKE(!FUNC_BINARY_USE(*m_fb) && FUNC_BINARY_BACKUP(*m_fb)))
			{
				FUNC_BINARY_BACKUP_MOVE(*m_fb);
			}
			
			// 出栈
			int oldretnum = 0;
			BP_GET_RETNUM(m_bp, oldretnum);
			int callbp = 0;
			BP_GET_BP(m_bp, callbp);
			BP_GET_FB(m_bp, m_fb);
			BP_GET_IP(m_bp, m_ip);
			int oldbp = m_bp;
			m_sp = m_bp - BP_SIZE - oldretnum;
			m_bp = callbp;
			
			// 所有都完
			if (UNLIKE(BP_END(m_bp)))
			{
				FKLOG("stack empty end");
				m_isend = true;
				break;
			}
			// 塞返回值
			else
			{
				for (int i = 0; i < oldretnum; i++)
				{
					int oldretpos = 0;
					BP_GET_RETPOS(oldbp, oldretnum, oldretpos, i);
					
					variant * ret;
					GET_VARIANT(*m_fb, m_bp, ret, oldretpos);
					*ret = m_ret[i];
				}
			}
			continue;
		}

		int code = COMMAND_CODE(GET_CMD(*m_fb, m_ip));

		FKLOG("next %d %d %s", COMMAND_TYPE(GET_CMD(*m_fb, m_ip)), code, OpCodeStr(code));
			
		assert (COMMAND_TYPE(GET_CMD(*m_fb, m_ip)) == COMMAND_OPCODE);

		m_ip++;

		if (UNLIKE(m_fk->pf.isopen()))
		{
			m_fk->pf.add_code_sample(code);
		}

		// 执行对应命令,放一起switch效率更高,cpu有缓存
		switch (code)
		{
		case OPCODE_ASSIGN:
			{
				// 赋值dest,必须为栈上或容器内
				if (UNLIKE(!(CHECK_STACK_POS(*m_fb, m_ip) || CHECK_CONTAINER_POS(*m_fb, m_ip))))
				{	
					err = true;
					seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "interpreter assign error, dest is not stack or container, type %s", POS_TYPE_NAME(*m_fb, m_ip));
					break;
				}

				variant * varv = 0;
				LOG_VARIANT(*m_fb, m_ip, "var");
				GET_VARIANT(*m_fb, m_bp, varv, m_ip);
				m_ip++;
				
				// 赋值来源
				const variant * valuev = 0;
				LOG_VARIANT(*m_fb, m_ip, "value");
				GET_VARIANT(*m_fb, m_bp, valuev, m_ip);
				m_ip++;

				// 赋值
				*varv = *valuev;

				FKLOG("assign %s to %s", (vartostring(valuev)).c_str(), (vartostring(varv)).c_str());
			}
			break;
		case OPCODE_PLUS:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, PLUS);
			}
			break;
		case OPCODE_MINUS:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MINUS);
			}
			break;
		case OPCODE_MULTIPLY:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MULTIPLY);
			}
			break;
		case OPCODE_DIVIDE:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, DIVIDE);
			}
			break;
		case OPCODE_DIVIDE_MOD:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, DIVIDE_MOD);
			}
			break;
		case OPCODE_AND:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, AND);
			}
			break;
		case OPCODE_OR:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, OR);
			}
			break;
		case OPCODE_LESS:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, LESS);
			}
			break;
		case OPCODE_MORE:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MORE);
			}
			break;
		case OPCODE_EQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, EQUAL);
			}
			break;
		case OPCODE_MOREEQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MOREEQUAL);
			}
			break;
		case OPCODE_LESSEQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, LESSEQUAL);
			}
			break;
		case OPCODE_NOTEQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, NOTEQUAL);
			}
			break;
		case OPCODE_NOT:
			{
				MATH_SINGLE_OPER(*m_fb, m_bp, m_ip, NOT);
			}
			break;
		case OPCODE_AND_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, AND_JNE);
			}
			break;
		case OPCODE_OR_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, OR_JNE);
			}
			break;
		case OPCODE_LESS_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, LESS_JNE);
			}
			break;
		case OPCODE_MORE_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, MORE_JNE);
			}
			break;
		case OPCODE_EQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, EQUAL_JNE);
			}
			break;
		case OPCODE_MOREEQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, MOREEQUAL_JNE);
			}
			break;
		case OPCODE_LESSEQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, LESSEQUAL_JNE);
			}
			break;
		case OPCODE_NOTEQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, NOTEQUAL_JNE);
			}
			break;
		case OPCODE_NOT_JNE:
			{
				MATH_SINGLE_OPER_JNE(*m_fb, m_bp, m_ip, NOT_JNE);
			}
			break;
		case OPCODE_JNE:
			{
				const variant * cmp = 0;
				LOG_VARIANT(*m_fb, m_ip, "cmp");
				GET_VARIANT(*m_fb, m_bp, cmp, m_ip);
				m_ip++;

				int ip = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;
				
				if (!(V_ISBOOL(cmp)))
				{
					FKLOG("jne %d", ip);
					m_ip = ip;
				}
				else
				{
					FKLOG("not jne %d", ip);
				}
			}
			break;
		case OPCODE_JMP:
			{
				int ip = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;
				
				FKLOG("jmp %d", ip);

				m_ip = ip;
			}
			break;
		case OPCODE_PLUS_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, PLUS);
			}
			break;
		case OPCODE_MINUS_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, MINUS);
			}
			break;
		case OPCODE_MULTIPLY_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, MULTIPLY);
			}
			break;
		case OPCODE_DIVIDE_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, DIVIDE);
			}
			break;
		case OPCODE_DIVIDE_MOD_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, DIVIDE_MOD);
			}
			break;
		case OPCODE_CALL:
			{
				int calltype = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;

				const variant * callpos = 0;
				LOG_VARIANT(*m_fb, m_ip, "callpos");
				GET_VARIANT(*m_fb, m_bp, callpos, m_ip);
				m_ip++;

				int retnum = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;
				
				int retpos[MAX_FAKE_RETURN_NUM];

				for (int i = 0; i < retnum; i++)
				{
					assert(CHECK_STACK_POS(*m_fb, m_ip));
					retpos[i] = m_ip;
					m_ip++;
				}
				
				int argnum = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;

				paramstack & ps = *getps(m_fk);
				PS_CLEAR(ps);
				for (int i = 0; i < argnum; i++)
				{
					variant * arg = 0;
					LOG_VARIANT(*m_fb, m_ip, "arg");
					GET_VARIANT(*m_fb, m_bp, arg, m_ip);
					m_ip++;

					variant * argdest = 0;
					PS_PUSH_AND_GET(ps, argdest);
					*argdest = *arg;
				}
				
				if (LIKE(calltype == CALL_NORMAL))
				{
					call(*callpos, retnum, retpos);
				}
				else
				{
					m_processor->start_routine(*callpos, retnum, retpos);
				}
			}
			break;
		case OPCODE_RETURN:
			{
				int returnnum = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				if (UNLIKE(!returnnum))
				{
					FKLOG("return empty");
					m_ip = (*m_fb).m_size;
					break;
				}
				m_ip++;

				// 塞给ret
				for (int i = 0; i < returnnum; i++)
				{
					const variant * ret = 0;
					LOG_VARIANT(*m_fb, m_ip, "ret");
					GET_VARIANT(*m_fb, m_bp, ret, m_ip);
					m_ip++;

					m_ret[i] = *ret;

					FKLOG("return %s", (vartostring(&m_ret[i])).c_str());
				}
				
				m_ip = (*m_fb).m_size;
			}
			break;
		case OPCODE_FORBEGIN:
			{
				// 赋值dest,必须为栈上或容器内
				if (UNLIKE(!(CHECK_STACK_POS(*m_fb, m_ip) || CHECK_CONTAINER_POS(*m_fb, m_ip))))
				{	
					err = true;
					seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "interpreter assign error, dest is not stack or container, type %s", POS_TYPE_NAME(*m_fb, m_ip));
					break;
				}

				// var
				variant * varv = 0;
				LOG_VARIANT(*m_fb, m_ip, "var");
				GET_VARIANT(*m_fb, m_bp, varv, m_ip);
				m_ip++;
				
				// begin
				const variant * beginv = 0;
				LOG_VARIANT(*m_fb, m_ip, "begin");
				GET_VARIANT(*m_fb, m_bp, beginv, m_ip);
				m_ip++;

				// end
				const variant * endv = 0;
				LOG_VARIANT(*m_fb, m_ip, "endv");
				GET_VARIANT(*m_fb, m_bp, endv, m_ip);
				m_ip++;

				// add
				const variant * addv = 0;
				LOG_VARIANT(*m_fb, m_ip, "addv");
				GET_VARIANT(*m_fb, m_bp, addv, m_ip);
				m_ip++;

				int jneip = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;

				// 赋值
				*varv = *beginv;

				// 增长
				if (LIKE(addv->data.real > 0))
				{
					// 判断是否超出
					if (UNLIKE(varv->data.real >= endv->data.real))
					{
						m_ip = jneip;
					}
				}
				else
				{
					// 判断是否小
					if (UNLIKE(varv->data.real <= endv->data.real))
					{
						m_ip = jneip;
					}
				}
			}
			break;
		case OPCODE_FORLOOP:
			{
				// var
				variant * varv = 0;
				LOG_VARIANT(*m_fb, m_ip, "var");
				GET_VARIANT(*m_fb, m_bp, varv, m_ip);
				m_ip++;
				
				// end
				const variant * endv = 0;
				LOG_VARIANT(*m_fb, m_ip, "endv");
				GET_VARIANT(*m_fb, m_bp, endv, m_ip);
				m_ip++;

				// add
				const variant * addv = 0;
				LOG_VARIANT(*m_fb, m_ip, "addv");
				GET_VARIANT(*m_fb, m_bp, addv, m_ip);
				m_ip++;

				int continueip = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;

				// 赋值
				V_PLUS(varv, varv, addv);

				// 增长
				if (LIKE(addv->data.real > 0))
				{
					// 判断是否超出
					if (UNLIKE(varv->data.real < endv->data.real))
					{
						m_ip = continueip;
					}
				}
				else
				{
					// 判断是否小
					if (UNLIKE(varv->data.real > endv->data.real))
					{
						m_ip = continueip;
					}
				}
			}
			break;
		case OPCODE_SLEEP:
			{
				const variant * time = 0;
				LOG_VARIANT(*m_fb, m_ip, "time");
				GET_VARIANT(*m_fb, m_bp, time, m_ip);
				m_ip++;

				uint32_t sleeptime = 0;
				V_GET_REAL(time, sleeptime);

				m_wakeuptime = fkgetmstick() + sleeptime;
				m_sleeping = true;
				return i + 1;
			}
			break;
		case OPCODE_YIELD:
			{
				const variant * time = 0;
				LOG_VARIANT(*m_fb, m_ip, "time");
				GET_VARIANT(*m_fb, m_bp, time, m_ip);
				m_ip++;

				V_GET_REAL(time, m_yieldtime);
				m_sleeping = true;
				return i + 1;
			}
			break;
		default:
			assert(0);
			FKERR("next err code %d %s", code, OpCodeStr(code));
			break;
		}
		
		if (UNLIKE(err))
		{
			// 发生错误
			m_isend = true;
		}

		if (UNLIKE(m_isend))
		{
			break;
		}
		
		i++;
		
		if (UNLIKE(i >= cmdnum))
		{
			break;
		}
	}
	
	return i;
}
Ejemplo n.º 25
0
bool parser::parse(const char * filename)
{
	fake * fk = m_fk;

	if (!filename)
	{
		FKERR("parse filename is empty");
		seterror(fk, efk_parse_file_fail, "", 0, "", "parse filename is empty");
		return false;
	}
	
	FKLOG("parse %p %s", fk, filename);

	m_parse_dep++;

	// 检查深度
	if (m_parse_dep >= m_fk->cfg.include_deps)
	{
		FKERR("parse %s file too deep %d", filename, m_parse_dep);
		seterror(fk, efk_parse_file_fail, filename, 0, "", "parse %s file too deep %d", filename, m_parse_dep);
		return false;
	}

	// 检查当前文件是否在解析中
	if (is_parsing(filename))
	{
		FKERR("parse open %s fail", fk, filename);
		seterror(fk, efk_parse_file_fail, filename, 0, "", "already parsing %s file...include list \n%s", filename, get_parsing_file_list());
		return false;
	}

	// 加入
	m_parsing_file_list.push_back(filename);

	// 清空错误
	fk->clearerr();

	// 输入源文件
	FKLOG("parse inputfile %p %s", fk, filename);
	myflexer mf(fk);
	mf.clear();
	bool b = mf.inputfile(filename);
	if (!b)
	{
		FKERR("parse open %s fail", fk, filename);
		return false;
	}

	// 进行语法解析
	int ret = yyparse((void *)&mf); 
	if (ret != 0)
	{
		FKERR("parse yyparse %s fail ret %d", fk, filename, ret);
		seterror(fk, efk_parse_file_fail, filename, mf.get_error_line(), "", "parse %s file fail for reason : %s", filename, mf.get_error());
		return false;
	}
	
	FKLOG("parse yyparse %p %s OK", fk, filename);

	// 解析前置文件
	for (int i = 0; i < (int)mf.get_include_list().size(); i++)
	{
		String & name = mf.get_include_list()[i];
		if (!parse_include(filename, name))
		{
			FKERR("%s parse_include %s fail", filename, name.c_str());
			return false;
		}
	}

	// 编译
	FKLOG("parse compile %p %s", fk, filename);
	compiler mc(fk, &mf);
	mc.clear();
	b = mc.compile();
	if (!b)
	{
		FKERR("parse %s compile %s fail", fk, filename);
		return false;
	}

	// jit
	fk->as.clear();
	assembler & as = fk->as;
	b = as.compile(&fk->bin);
	if (!b)
	{
		FKERR("fkparse %s jit %s fail", fk, filename);
		return false;
	}
	
	// 弹出
	assert(m_parsing_file_list.back() == (String)filename);
	m_parsing_file_list.pop_back();
	
	FKLOG("parse %p %s OK", fk, filename);
	
	return true;
}
Ejemplo n.º 26
0
bool parser::parsestr(const char * str)
{
	fake * fk = m_fk;
	
	FKLOG("parsestr %p %s", fk, str);

	// 清空错误
	fk->clearerr();

	// 输入
	myflexer mf(fk);
	mf.clear();
	bool b = mf.inputstr(str);
	if (!b)
	{
		FKERR("parse inputstr %s fail", fk, str);
		return false;
	}

	// 进行语法解析
	int ret = yyparse((void *)&mf); 
	if (ret != 0)
	{
		FKERR("parse yyparse %s fail ret %d", fk, str, ret);
		seterror(fk, efk_parse_file_fail, "", mf.get_error_line(), "", "parse string fail for reason : %s", mf.get_error());
		return false;
	}
	
	FKLOG("parse yyparse %p %s OK", fk, str);

	// 解析前置文件
	for (int i = 0; i < (int)mf.get_include_list().size(); i++)
	{
		String & name = mf.get_include_list()[i];
		if (!parse_include("", name))
		{
			FKERR("%s parse_include %s fail", "", name.c_str());
			return false;
		}
	}

	// 编译
	FKLOG("parse compile %p %s", fk, str);
	compiler mc(fk, &mf);
	mc.clear();
	b = mc.compile();
	if (!b)
	{
		FKERR("parse %s compile %s fail", fk, str);
		return false;
	}

	// jit 先放弃
	fk->as.clear();
	assembler & as = fk->as;
	b = as.compile(&fk->bin);
	if (!b)
	{
		FKERR("parse %s jit %s fail", fk, str);
		return false;
	}
	
	FKLOG("parse %p %s OK", fk, str);
	
	return true;
}
Ejemplo n.º 27
0
int interpreter::run(int cmdnum)
{
	fake * fk = m_fk;
	bool & err = m_isend;
	int i = 0;
	
	// 栈溢出检查
	if (UNLIKE((int)ARRAY_MAX_SIZE(m_stack) > m_fk->cfg.stack_max))
	{	
		m_isend = true;
		seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "stack too big %d", ARRAY_MAX_SIZE(m_stack));
		return 0;
	}

	// 切换检查
	if (UNLIKE(m_sleeping))
	{
		if (LIKE(m_yieldtime))
		{
			m_yieldtime--;
			return 0;
		}
		else if (LIKE(fkgetmstick() < m_wakeuptime))
		{
			return 0;
		}
		else
		{
			m_wakeuptime = 0;
		}
	}
	
	if (UNLIKE(m_isend))
	{
		return 0;
	}
	
	while (1)
	{
		// 当前函数走完
		if (UNLIKE(m_ip >= (int)FUNC_BINARY_CMDSIZE(*m_fb)))
		{
			FKLOG("pop stack %s", FUNC_BINARY_NAME(*m_fb));
			
			// 记录profile
			if (UNLIKE(m_fk->pf.isopen()))
			{
				uint32_t calltime = 0;
				BP_GET_CALLTIME(m_bp, calltime);
				m_fk->pf.add_func_sample(FUNC_BINARY_NAME(*m_fb), fkgetmstick() - calltime);
			}
			
			// 标记
			FUNC_BINARY_USE(*m_fb)--;
			
			// 更新
			if (UNLIKE(!FUNC_BINARY_USE(*m_fb) && FUNC_BINARY_BACKUP(*m_fb)))
			{
				FUNC_BINARY_BACKUP_MOVE(*m_fb);
			}
			
			// 出栈
			int oldretnum = 0;
			BP_GET_RETNUM(m_bp, oldretnum);
			int callbp = 0;
			BP_GET_BP(m_bp, callbp);
			BP_GET_FB(m_bp, m_fb);
			BP_GET_IP(m_bp, m_ip);
			int oldbp = m_bp;
			m_sp = m_bp - BP_SIZE - oldretnum;
			m_bp = callbp;
			
			// 所有都完
			if (UNLIKE(BP_END(m_bp)))
			{
				FKLOG("stack empty end");
				m_isend = true;
				break;
			}
			// 塞返回值
			else
			{
				for (int i = 0; i < oldretnum; i++)
				{
					int oldretpos = 0;
					BP_GET_RETPOS(oldbp, oldretnum, oldretpos, i);
					
					variant * ret;
					GET_VARIANT(*m_fb, m_bp, ret, oldretpos);
					*ret = m_ret[i];
				}
			}
			continue;
		}

		int code = COMMAND_CODE(GET_CMD(*m_fb, m_ip));

		FKLOG("next %d %d %s", COMMAND_TYPE(GET_CMD(*m_fb, m_ip)), code, OpCodeStr(code));
			
		assert (COMMAND_TYPE(GET_CMD(*m_fb, m_ip)) == COMMAND_OPCODE);

		m_ip++;

		if (UNLIKE(m_fk->pf.isopen()))
		{
			m_fk->pf.add_code_sample(code);
		}

		// 执行对应命令,放一起switch效率更高,cpu有缓存
		switch (code)
		{
		case OPCODE_ASSIGN:
			{
				// 赋值dest,必须为栈上或容器内
				if (UNLIKE(!(CHECK_STACK_POS(*m_fb, m_ip) || CHECK_CONTAINER_POS(*m_fb, m_ip))))
				{	
					err = true;
					seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "interpreter assign error, dest is not stack or container, type %s", POS_TYPE_NAME(*m_fb, m_ip));
					break;
				}

				variant * varv = 0;
				LOG_VARIANT(*m_fb, m_ip, "var");
				GET_VARIANT(*m_fb, m_bp, varv, m_ip);
				if (UNLIKE(CHECK_CONST_MAP_POS(varv) || CHECK_CONST_ARRAY_POS(varv)))
				{
					err = true;
					seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "interpreter assign error, dest is const container");
					break;
				}
				m_ip++;
				
				// 赋值来源
				const variant * valuev = 0;
				LOG_VARIANT(*m_fb, m_ip, "value");
				GET_VARIANT(*m_fb, m_bp, valuev, m_ip);
				m_ip++;

				// 赋值
				*varv = *valuev;

				FKLOG("assign %s to %s", (vartostring(valuev)).c_str(), (vartostring(varv)).c_str());
			}
			break;
		case OPCODE_PLUS:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, PLUS);
			}
			break;
		case OPCODE_MINUS:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MINUS);
			}
			break;
		case OPCODE_MULTIPLY:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MULTIPLY);
			}
			break;
		case OPCODE_DIVIDE:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, DIVIDE);
			}
			break;
		case OPCODE_DIVIDE_MOD:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, DIVIDE_MOD);
			}
			break;
		case OPCODE_STRING_CAT:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, STRING_CAT);
			}
			break;
		case OPCODE_AND:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, AND);
			}
			break;
		case OPCODE_OR:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, OR);
			}
			break;
		case OPCODE_LESS:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, LESS);
			}
			break;
		case OPCODE_MORE:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MORE);
			}
			break;
		case OPCODE_EQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, EQUAL);
			}
			break;
		case OPCODE_MOREEQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, MOREEQUAL);
			}
			break;
		case OPCODE_LESSEQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, LESSEQUAL);
			}
			break;
		case OPCODE_NOTEQUAL:
			{
				MATH_OPER(*m_fb, m_bp, m_ip, NOTEQUAL);
			}
			break;
		case OPCODE_NOT:
			{
				MATH_SINGLE_OPER(*m_fb, m_bp, m_ip, NOT);
			}
			break;
		case OPCODE_AND_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, AND_JNE);
			}
			break;
		case OPCODE_OR_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, OR_JNE);
			}
			break;
		case OPCODE_LESS_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, LESS_JNE);
			}
			break;
		case OPCODE_MORE_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, MORE_JNE);
			}
			break;
		case OPCODE_EQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, EQUAL_JNE);
			}
			break;
		case OPCODE_MOREEQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, MOREEQUAL_JNE);
			}
			break;
		case OPCODE_LESSEQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, LESSEQUAL_JNE);
			}
			break;
		case OPCODE_NOTEQUAL_JNE:
			{
				MATH_OPER_JNE(*m_fb, m_bp, m_ip, NOTEQUAL_JNE);
			}
			break;
		case OPCODE_NOT_JNE:
			{
				MATH_SINGLE_OPER_JNE(*m_fb, m_bp, m_ip, NOT_JNE);
			}
			break;
		case OPCODE_JNE:
			{
				const variant * cmp = 0;
				LOG_VARIANT(*m_fb, m_ip, "cmp");
				GET_VARIANT(*m_fb, m_bp, cmp, m_ip);
				m_ip++;

				int ip = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;
				
				if (!(V_ISBOOL(cmp)))
				{
					FKLOG("jne %d", ip);
					m_ip = ip;
				}
				else
				{
					FKLOG("not jne %d", ip);
				}
			}
			break;
		case OPCODE_JMP:
			{
				int ip = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;
				
				FKLOG("jmp %d", ip);

				m_ip = ip;
			}
			break;
		case OPCODE_PLUS_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, PLUS);
			}
			break;
		case OPCODE_MINUS_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, MINUS);
			}
			break;
		case OPCODE_MULTIPLY_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, MULTIPLY);
			}
			break;
		case OPCODE_DIVIDE_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, DIVIDE);
			}
			break;
		case OPCODE_DIVIDE_MOD_ASSIGN:
			{
				MATH_ASSIGN_OPER(*m_fb, m_bp, m_ip, DIVIDE_MOD);
			}
			break;
		case OPCODE_CALL:
			{
				int calltype = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;

				const variant * callpos = 0;
				LOG_VARIANT(*m_fb, m_ip, "callpos");
				GET_VARIANT(*m_fb, m_bp, callpos, m_ip);
				m_ip++;

				int retnum = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;
				
				int retpos[MAX_FAKE_RETURN_NUM];

				for (int i = 0; i < retnum; i++)
				{
					assert(CHECK_STACK_POS(*m_fb, m_ip) || CHECK_CONTAINER_POS(*m_fb, m_ip));
					retpos[i] = m_ip;
					m_ip++;
				}
				
				int argnum = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				m_ip++;

				paramstack & ps = *getps(m_fk);
				PS_CLEAR(ps);
				for (int i = 0; i < argnum; i++)
				{
					variant * arg = 0;
					LOG_VARIANT(*m_fb, m_ip, "arg");
					GET_VARIANT(*m_fb, m_bp, arg, m_ip);
					m_ip++;

					variant * argdest = 0;
					PS_PUSH_AND_GET(ps, argdest);
					*argdest = *arg;
				}
				
				if (LIKE(calltype == CALL_NORMAL))
				{
					call(*callpos, retnum, retpos);
				}
				else if (LIKE(calltype == CALL_CLASSMEM))
				{
					void * classptr = 0;
					const char * classprefix = 0;

					// prefix
					variant * classvar;
					PS_GET(ps, classvar, PS_SIZE(ps) - 1);
					V_GET_POINTER(classvar, classptr, classprefix);

					if (UNLIKE(err))
					{
						break;
					}

					// mem func name
					const char * funcname = 0;
					V_GET_STRING(callpos, funcname);
					
					if (UNLIKE(err))
					{
						break;
					}

					if (UNLIKE(!classptr))
					{
						err = true;
						seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "interpreter class mem call error, the class ptr is null, type %s", classprefix);
						break;
					}

					// whole name
					char wholename[MAX_FAKE_REG_FUNC_NAME_LEN];
					if (UNLIKE(classvar->data.ponter->typesz + callpos->data.str->sz >= MAX_FAKE_REG_FUNC_NAME_LEN))
					{
						err = true;
						seterror(fk, efk_run_inter_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "interpreter class mem call error, the name is too long, func %s %s", classprefix, funcname);
						break;
					}
					memcpy(wholename, classprefix, classvar->data.ponter->typesz);
					memcpy(wholename + classvar->data.ponter->typesz, funcname, callpos->data.str->sz);
					wholename[classvar->data.ponter->typesz + callpos->data.str->sz] = 0;

					// call it
					variant tmp;
					V_SET_STRING(&tmp, wholename);

					call(tmp, retnum, retpos);
				}
				else
				{
					m_processor->start_routine(*callpos, retnum, retpos);
				}
			}
			break;
		case OPCODE_RETURN:
			{
				int returnnum = COMMAND_CODE(GET_CMD(*m_fb, m_ip));
				if (UNLIKE(!returnnum))
				{
					FKLOG("return empty");
					m_ip = (*m_fb).m_size;
					break;
				}
				m_ip++;

				// 塞给ret
				for (int i = 0; i < returnnum; i++)
				{
					const variant * ret = 0;
					LOG_VARIANT(*m_fb, m_ip, "ret");
					GET_VARIANT(*m_fb, m_bp, ret, m_ip);
					m_ip++;

					m_ret[i] = *ret;

					FKLOG("return %s", (vartostring(&m_ret[i])).c_str());
				}
				
				m_ip = (*m_fb).m_size;
			}
			break;
		case OPCODE_SLEEP:
			{
				const variant * time = 0;
				LOG_VARIANT(*m_fb, m_ip, "time");
				GET_VARIANT(*m_fb, m_bp, time, m_ip);
				m_ip++;

				uint32_t sleeptime = 0;
				V_GET_REAL(time, sleeptime);

				m_wakeuptime = fkgetmstick() + sleeptime;
				m_sleeping = true;
				return i + 1;
			}
			break;
		case OPCODE_YIELD:
			{
				const variant * time = 0;
				LOG_VARIANT(*m_fb, m_ip, "time");
				GET_VARIANT(*m_fb, m_bp, time, m_ip);
				m_ip++;

				V_GET_REAL(time, m_yieldtime);
				m_sleeping = true;
				return i + 1;
			}
			break;
		default:
			assert(0);
			FKERR("next err code %d %s", code, OpCodeStr(code));
			break;
		}
		
		if (UNLIKE(err))
		{
			// 发生错误
			m_isend = true;

			// 清除当前栈上函数的使用标记
			{
				int ip = m_ip;
				int bp = m_bp;
				const func_binary * fb = m_fb;

				while (!BP_END(bp))
				{
					// 标记
					FUNC_BINARY_USE(*fb)--;
					
					// 更新
					if (UNLIKE(!FUNC_BINARY_USE(*fb) && FUNC_BINARY_BACKUP(*fb)))
					{
						FUNC_BINARY_BACKUP_MOVE(*fb);
					}
					
					BP_GET_FB(bp, fb);
					BP_GET_IP(bp, ip);
					int callbp = 0;
					BP_GET_BP(bp, callbp);
					bp = callbp;
					if (BP_END(bp))
					{
						break;
					}
				}
			}
		}

		if (UNLIKE(m_isend))
		{
			break;
		}
		
		i++;
		
		if (UNLIKE(i >= cmdnum))
		{
			break;
		}
	}
	
	return i;
}
Ejemplo n.º 28
0
bool compiler::compile_cmp_stmt(codegen & cg, cmp_stmt * cs)
{
	FKLOG("[compiler] compile_cmp_stmt %p", cs);

	int deps = m_cmp_deps;
	m_cmp_deps++;

	command oper = 0;
	command left = 0;
	command right = 0;
	command dest = 0;   

	if (cs->cmp != "not")
	{
		// oper
		if (cs->cmp == "&&")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_AND_JNE) : MAKE_OPCODE(OPCODE_AND);
		}
		else if (cs->cmp == "||")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_OR_JNE) : MAKE_OPCODE(OPCODE_OR);
		}
		else if (cs->cmp == "<")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_LESS_JNE) : MAKE_OPCODE(OPCODE_LESS);
		}
		else if (cs->cmp == ">")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_MORE_JNE) : MAKE_OPCODE(OPCODE_MORE);
		}
		else if (cs->cmp == "==")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_EQUAL_JNE) : MAKE_OPCODE(OPCODE_EQUAL);
		}
		else if (cs->cmp == ">=")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_MOREEQUAL_JNE) : MAKE_OPCODE(OPCODE_MOREEQUAL);
		}
		else if (cs->cmp == "<=")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_LESSEQUAL_JNE) : MAKE_OPCODE(OPCODE_LESSEQUAL);
		}
		else if (cs->cmp == "!=")
		{
			oper = !deps ? MAKE_OPCODE(OPCODE_NOTEQUAL_JNE) : MAKE_OPCODE(OPCODE_NOTEQUAL);
		}
		else if (cs->cmp == "true")
		{
			variant v;
			V_SET_REAL((&v), 1);
			int pos = cg.getconst(v);
			m_cur_addr = MAKE_ADDR(ADDR_CONST, pos);
			
			m_cmp_deps--;
			m_cmp_jne = false;
			
			return true;
		}
		else if (cs->cmp == "false")
		{
			variant v;
			V_SET_REAL((&v), 0);
			int pos = cg.getconst(v);
			m_cur_addr = MAKE_ADDR(ADDR_CONST, pos);
			
			m_cmp_deps--;
			m_cmp_jne = false;
			
			return true;
		}
		else if (cs->cmp == "is")
		{
			// left
			if (!compile_node(cg, cs->left))
			{
				FKERR("[compiler] compile_cmp_stmt left fail");
				return false;
			}
			
			m_cmp_deps--;
			m_cmp_jne = false;
			
			return true;
		}
		else
		{
			FKERR("[compiler] compile_cmp_stmt cmp error %s", cs->cmp.c_str());
			compile_seterror(cs, m_fk, efk_compile_cmp_error, "cmp error %s", cs->cmp.c_str());
			return false;
		}
		
		// left
		if (!compile_node(cg, cs->left))
		{
			FKERR("[compiler] compile_cmp_stmt left fail");
			return false;
		}
		left = m_cur_addr;

		// right
		if (!compile_node(cg, cs->right))
		{
			FKERR("[compiler] compile_cmp_stmt right fail");
			return false;
		}
		right = m_cur_addr;

		// result
		int despos = cg.alloc_stack_identifier();
		dest = MAKE_ADDR(ADDR_STACK, despos);
		m_cur_addr = dest;
		
		cg.push(oper, cs->lineno());
		cg.push(left, cs->lineno());
		cg.push(right, cs->lineno());
		cg.push(dest, cs->lineno());
	}
	/* "not" */
	else
	{
		oper = !deps ? MAKE_OPCODE(OPCODE_NOT_JNE) : MAKE_OPCODE(OPCODE_NOT);
		
		// left
		if (!compile_node(cg, cs->left))
		{
			FKERR("[compiler] compile_cmp_stmt left fail");
			return false;
		}
		left = m_cur_addr;
	
		int despos = cg.alloc_stack_identifier();
		dest = MAKE_ADDR(ADDR_STACK, despos);
		m_cur_addr = dest;
	
		cg.push(oper, cs->lineno());
		cg.push(left, cs->lineno());
		cg.push(dest, cs->lineno());
	}
	
	m_cmp_deps--;
	if (!deps)
	{
		m_cmp_jne = true;
	}
	
	FKLOG("[compiler] compile_cmp_stmt %p OK", cs);
	
	return true;
}
Ejemplo n.º 29
0
bool assembler::compile_func(const func_binary & fb)
{
	FKLOG("[assembler] compile_func func_binary %p", &fb);

	clear();

	asmgen asg(m_fk);

	asg.start_func();

	int stacksize = (fb.m_maxstack + fb.m_const_list_num + MAX_ASSEMBLER_CONTAINER_NUM + 1) * variant_size;
	FKLOG("[assembler] compile_func stack size %d", stacksize);
	asg.alloc_stack(stacksize);

	asg.copy_param(FUNC_BINARY_PARAMNUM(fb));

	asg.copy_const(fb.m_const_list, fb.m_const_list_num, fb.m_maxstack);

	// loop
	m_pos = 0;
	while (m_pos < (int)fb.m_size)
	{
		m_posmap[m_pos] = asg.size();
		FKLOG("posmap %d %d", m_pos, asg.size());
		if (!compile_next(asg, fb))
		{
			FKERR("[assembler] compile_func compile_next %d fail", m_pos);
			return false;
		}
	}
	// end
	m_posmap[m_pos] = asg.size();

	// link jmp pos
	for (caremap::iterator it = m_caremap.begin(); it != m_caremap.end(); it++)
	{
		int jumpposoff = it->first;
		int bytecodepos = it->second;
		if (m_posmap.find(bytecodepos) != m_posmap.end())
		{
			int pos = m_posmap[bytecodepos];
			asg.set_int(jumpposoff, pos - (jumpposoff + sizeof(int)));
			FKLOG("loop set %d -> %d %d", jumpposoff, pos - (jumpposoff + sizeof(int)), pos);
		}
		else
		{
			assert(0);
		}
	}
	
	asg.stop_func();
	func_native nt;
	FUNC_NATIVE_INI(nt);
	asg.output(FUNC_BINARY_FILENAME(fb), FUNC_BINARY_PACKAGENAME(fb), FUNC_BINARY_NAME(fb), &nt);
	variant fv = m_fk->sh.allocsysstr(FUNC_BINARY_NAME(fb));
	m_native->add_func(fv, nt);
	
	String str = asg.source();

	FKLOG("[assembler] compile_func binary %p ok\n%s", &fb, str.c_str());

	return true;
}
Ejemplo n.º 30
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;
}