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; }
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; }
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; }
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; }
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; }
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; }
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 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; }
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; }
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; }
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; }
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); }
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; }
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 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; }
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; }
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 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }