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; }
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; }
const char * profile::dump() { std::vector<sortele> sortelevec; for (const stringhashmap::ele * p = m_shh.first(); p != 0; p = m_shh.next()) { const profilefuncele & ele = *p->t; sortelevec.push_back(std::make_pair(p->k, ele)); } std::sort(sortelevec.begin(), sortelevec.end(), profilefuncelesort()); m_dumpstr.clear(); m_dumpstr += "Call Func:\n"; for (int i = 0; i < (int)sortelevec.size(); i++) { const sortele & se = sortelevec[i]; const profilefuncele & ele = se.second; char buff[1024]; tsnprintf(buff, sizeof(buff)-1, "\tFunc[%s]\tCalls[%d]\tTotalTime(ms)[%u]\tPerCallTime(ms)[%u]\n", se.first.c_str(), ele.callnum, ele.calltime, ele.callnum ? ele.calltime / ele.callnum : 0); m_dumpstr += buff; } m_dumpstr += "Code Num:\n"; for (int i = 0; i < OPCODE_MAX; i++) { m_dumpstr += "\t"; m_dumpstr += OpCodeStr(i); for (int j = 0; j < (int)(20 - strlen(OpCodeStr(i))); j++) { m_dumpstr += " "; } m_dumpstr += fkitoa(m_codetype[i]); m_dumpstr += "\n"; } return m_dumpstr.c_str(); }
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; }
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; }
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; }
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; }
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; }