Beispiel #1
0
struct ip_vs_service_user *
ipvs_get_service(u_int32_t fwmark, u_int16_t protocol, u_int32_t vaddr, u_int16_t vport)
{
	struct ip_vs_service_user *svc;
	socklen_t len;

	len = sizeof(*svc);
	if (!(svc = MALLOC(len)))
		return NULL;

	ipvs_cmd = GET_CMD(IP_VS_SO_GET_SERVICE);
	svc->fwmark = fwmark;
	svc->protocol = protocol;
	svc->addr = vaddr;
	svc->port = vport;
	if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_SERVICE,
		       (char *)svc, &len)) {
		FREE(svc);
		return NULL;
	}
	return svc;
}
Beispiel #2
0
struct ip_vs_get_dests *ipvs_get_dests(struct ip_vs_service_user *svc)
{
	struct ip_vs_get_dests *d;
	socklen_t len;

	len = sizeof(*d) + sizeof(struct ip_vs_dest_user)*svc->num_dests;
	if (!(d = MALLOC(len)))
		return NULL;

	ipvs_cmd = GET_CMD(IP_VS_SO_GET_DESTS);
	d->fwmark = svc->fwmark;
	d->protocol = svc->protocol;
	d->addr = svc->addr;
	d->port = svc->port;
	d->num_dests = svc->num_dests;

	if (getsockopt(sockfd, IPPROTO_IP,
		       IP_VS_SO_GET_DESTS, d, &len) < 0) {
		FREE(d);
		return NULL;
	}
	return d;
}
Beispiel #3
0
bool assembler::compile_call(asmgen & asg, const func_binary & fb, command cmd)
{
	int calltype = COMMAND_CODE(GET_CMD(fb, m_pos));
	m_pos++;

	if (calltype == CALL_FAKE)
	{
		setwarn(m_fk, "assembler not supprt fake call, change to normal call");
		calltype = CALL_NORMAL;
	}
	
	if (calltype == CALL_NORMAL)
	{
		int callpos = 0;
		GET_VARIANT_POS(fb, callpos, m_pos);
		m_pos++;

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

		std::vector<int> retvec;
		for (int i = 0; i < retnum; i++)
		{
			int ret = 0;
			GET_VARIANT_POS(fb, ret, m_pos);
			m_pos++;
			retvec.push_back(ret);
		}
		
		int argnum = COMMAND_CODE(GET_CMD(fb, m_pos));
		m_pos++;

		// 1.塞参数
		asg.variant_ps_clear();
		for (int i = 0; i < argnum; i++)
		{
			int arg = 0;
			GET_VARIANT_POS(fb, arg, m_pos);
			m_pos++;
			
			asg.variant_push(arg);
		}

		// 2.准备调用函数
		// 3.调用
		asg.call_func_param2((void *)&machine::static_call, m_fk, callpos);

		// 4.处理返回值
		for (int i = (int)retvec.size() - 1; i >= 0; i--)
		{
			int ret = retvec[i];
			asg.variant_pop(ret);
		}

		// 5.清理不需要的
		asg.variant_ps_clear();
	}
	else if (calltype == CALL_CLASSMEM)
	{
		int callpos = 0;
		GET_VARIANT_POS(fb, callpos, m_pos);
		m_pos++;

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

		std::vector<int> retvec;
		for (int i = 0; i < retnum; i++)
		{
			int ret = 0;
			GET_VARIANT_POS(fb, ret, m_pos);
			m_pos++;
			retvec.push_back(ret);
		}

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

		// 0.取出实际的函数名
		int classpos = 0;
		GET_VARIANT_POS(fb, classpos, m_pos + argnum - 1);
		int tmppos = 0;
		GET_TMP_POS(fb, tmppos);
		
		asg.call_func_param3((void*)&assembler_get_classmem_call, m_fk, classpos, callpos);
		asg.variant_from_rax(tmppos);

		// 1.塞参数
		asg.variant_ps_clear();
		for (int i = 0; i < argnum; i++)
		{
			int arg = 0;
			GET_VARIANT_POS(fb, arg, m_pos);
			m_pos++;
			
			asg.variant_push(arg);
		}

		// 2.准备调用函数
		// 3.调用
		asg.call_func_param2((void *)&machine::static_call, m_fk, tmppos);

		// 4.处理返回值
		for (int i = (int)retvec.size() - 1; i >= 0; i--)
		{
			int ret = retvec[i];
			asg.variant_pop(ret);
		}

		// 5.清理不需要的
		asg.variant_ps_clear();
	}
	
	return true;
}
Beispiel #4
0
bool assembler::compile_cmp_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++;

	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++;

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

	// 1.先计算结果
	switch (code)
	{
	case OPCODE_AND_JNE:
		asg.variant_and(dest, left, right);
		break;
	case OPCODE_OR_JNE:
		asg.variant_or(dest, left, right);
		break;
	case OPCODE_LESS_JNE:
		asg.variant_less(dest, left, right);
		break;
	case OPCODE_MORE_JNE:
		asg.variant_more(dest, left, right);
		break;
	case OPCODE_EQUAL_JNE:
		asg.variant_equal(dest, left, right);
		break;
	case OPCODE_MOREEQUAL_JNE:
		asg.variant_moreequal(dest, left, right);
		break;
	case OPCODE_LESSEQUAL_JNE:
		asg.variant_lessequal(dest, left, right);
		break;
	case OPCODE_NOTEQUAL_JNE:
		asg.variant_notequal(dest, left, right);
		break;
	default:
		assert(0);
		FKERR("[assembler] compile_cmp_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_cmp_jne caremap add %d %d", jmpoffset, jump_bytecode_pos);
	}
	else
	{
		asg.set_int(jmpoffset, jumppos - asg.size());
		FKLOG("compile_cmp_jne set jne add %d -> %d", jmpoffset, jumppos - asg.size());
	}
	
	return true;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
}