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; }
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_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_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; }
static ERL_NIF_TERM nif_pcap_findalldevs(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { pcap_if_t *alldevsp = NULL; char errbuf[PCAP_ERRBUF_SIZE] = {0}; ERL_NIF_TERM dev = {0}; if (pcap_findalldevs(&alldevsp, errbuf) < 0) return enif_make_tuple2(env, atom_error, enif_make_string(env, errbuf, ERL_NIF_LATIN1)); dev = enif_make_list(env, 0); /* similar to inet:getifaddrs/0, except return binaries * for addresses: * [{"lo", [ * {description, "..."}, * {flag, [loopback]}, * {address, <<>>}, * {netmask, <<>>}, * {broaddr, <<>>}, * {dstaddr, <<>>} * ]}] */ for ( ; alldevsp != NULL; alldevsp = alldevsp->next) { ERL_NIF_TERM attr = {0}; ERL_NIF_TERM flags = {0}; pcap_addr_t *sa = NULL; /* interface attributes */ attr = enif_make_list(env, 0); /* interface flags */ flags = enif_make_list(env, 0); if (alldevsp->description) attr = enif_make_list_cell(env, enif_make_tuple2(env, atom_description, enif_make_string(env, alldevsp->description, ERL_NIF_LATIN1)), attr); if (alldevsp->flags & PCAP_IF_LOOPBACK) { flags = enif_make_list_cell(env, atom_loopback, flags); attr = enif_make_list_cell(env, enif_make_tuple2(env, atom_flag, flags), attr); } for (sa = alldevsp->addresses; sa != NULL; sa = sa->next) { if (sa->addr == NULL) continue; switch (sa->addr->sa_family) { case PF_INET: case PF_INET6: break; default: /* unsupported */ continue; } /* address */ MAKE_ADDR(env, attr, addr, sa); /* netmask */ MAKE_ADDR(env, attr, netmask, sa); /* broadaddr */ MAKE_ADDR(env, attr, broadaddr, sa); /* dstaddr */ MAKE_ADDR(env, attr, dstaddr, sa); } dev = enif_make_list_cell(env, enif_make_tuple2(env, enif_make_string(env, alldevsp->name, ERL_NIF_LATIN1), attr), dev); } pcap_freealldevs(alldevsp); return enif_make_tuple2(env, atom_ok, dev); ERR: pcap_freealldevs(alldevsp); /* MAKE_ADDR macro */ return enif_make_tuple2(env, atom_error, atom_enomem); }
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 compiler::compile_switch_stmt(codegen & cg, switch_stmt * ss) { FKLOG("[compiler] compile_switch_stmt %p", ss); command caseleft; command caseresult; cg.push_stack_identifiers(); // caseleft if (!compile_node(cg, ss->cmp)) { FKERR("[compiler] compile_switch_stmt cmp fail"); return false; } caseleft = m_cur_addr; // caseresult int despos = cg.alloc_stack_identifier(); caseresult = MAKE_ADDR(ADDR_STACK, despos); switch_caselist_node * scln = dynamic_cast<switch_caselist_node *>(ss->caselist); std::vector<int> jmpswitchposlist; // 挨个和case的比较 for (int i = 0; i < (int)scln->list.size(); i++) { command oper = MAKE_OPCODE(OPCODE_EQUAL); command left = caseleft; command right = 0; command dest = caseresult; switch_case_node * scn = dynamic_cast<switch_case_node *>(scln->list[i]); // right if (!compile_node(cg, scn->cmp)) { FKERR("[compiler] compile_switch_stmt case cmp fail"); return false; } right = m_cur_addr; // push case cg.push(oper, scn->lineno()); cg.push(left, scn->lineno()); cg.push(right, scn->lineno()); cg.push(dest, scn->lineno()); // push jmp cg.push(MAKE_OPCODE(OPCODE_JNE), scn->lineno()); cg.push(dest, scn->lineno()); cg.push(EMPTY_CMD, scn->lineno()); // 先塞个位置 int jnepos = cg.byte_code_size() - 1; // build block if (scn->block) { cg.push_stack_identifiers(); if (!compile_node(cg, scn->block)) { FKERR("[compiler] compile_switch_stmt block fail"); return false; } cg.pop_stack_identifiers(); } // 跳出switch块 cg.push(MAKE_OPCODE(OPCODE_JMP), scn->lineno()); cg.push(EMPTY_CMD, scn->lineno()); // 先塞个位置 int jmpswitchpos = cg.byte_code_size() - 1; jmpswitchposlist.push_back(jmpswitchpos); // 跳转出case块 cg.set(jnepos, MAKE_POS(cg.byte_code_size())); } // default if (ss->def) { cg.push_stack_identifiers(); if (!compile_node(cg, ss->def)) { FKERR("[compiler] compile_switch_stmt default fail"); return false; } cg.pop_stack_identifiers(); } cg.pop_stack_identifiers(); // 塞跳出的 for (int i = 0; i < (int)jmpswitchposlist.size(); i++) { cg.set(jmpswitchposlist[i], MAKE_POS(cg.byte_code_size())); } FKLOG("[compiler] compile_switch_stmt %p OK", ss); return true; }
bool compiler::compile_struct_pointer(codegen & cg, struct_pointer_node * sn) { FKLOG("[compiler] compile_struct_pointer %p", sn); fake * fk = m_fk; String name = sn->str; std::vector<String> tmp; do { int pos = name.find("->"); if (pos == -1) { tmp.push_back(name); break; } tmp.push_back(name.substr(0, pos)); name = name.substr(pos + 2); } while (1); if (tmp.size() < 2) { FKERR("[compiler] compile_struct_pointer pointer %s fail", sn->str.c_str()); return false; } String connname = tmp[0]; // 编译con command con = 0; // 看看是否是全局常量定义 variant * gcv = m_fk->pa.get_const_define(connname.c_str()); if (gcv) { int pos = cg.getconst(*gcv); con = MAKE_ADDR(ADDR_CONST, pos); } else { int pos = cg.getvariable(connname); if (pos == -1) { FKERR("[compiler] compile_struct_pointer variable not found %s", connname.c_str()); compile_seterror(sn, m_fk, efk_compile_variable_not_found, "variable %s not found", connname.c_str()); return false; } con = MAKE_ADDR(ADDR_STACK, pos); } for (int i = 1; i < (int)tmp.size(); i++) { String keystr = tmp[i]; // 编译key variant v; v = fk->sh.allocsysstr(keystr.c_str()); int pos = cg.getconst(v); command key = MAKE_ADDR(ADDR_CONST, pos); // 获取容器的位置 int addrpos = cg.getcontaineraddr(con, key); m_cur_addr = MAKE_ADDR(ADDR_CONTAINER, addrpos); con = m_cur_addr; } FKLOG("[compiler] compile_struct_pointer %p OK", sn); return true; }
bool compiler::compile_math_expr_node(codegen & cg, math_expr_node * mn) { FKLOG("[compiler] compile_math_expr_node %p", mn); command oper = 0; command left = 0; command right = 0; command dest = 0; if (mn->oper == "+") { oper = MAKE_OPCODE(OPCODE_PLUS); } else if (mn->oper == "-") { oper = MAKE_OPCODE(OPCODE_MINUS); } else if (mn->oper == "*") { oper = MAKE_OPCODE(OPCODE_MULTIPLY); } else if (mn->oper == "/") { oper = MAKE_OPCODE(OPCODE_DIVIDE); } else if (mn->oper == "%") { oper = MAKE_OPCODE(OPCODE_DIVIDE_MOD); } else if (mn->oper == "..") { oper = MAKE_OPCODE(OPCODE_STRING_CAT); } else { FKERR("[compiler] compile_math_expr_node error oper type fail"); compile_seterror(mn, m_fk, efk_compile_math_type_error, "compile math oper type %s error", mn->oper.c_str()); return false; } // left if (!compile_node(cg, mn->left)) { FKERR("[compiler] compile_math_expr_node left fail"); return false; } left = m_cur_addr; // right if (!compile_node(cg, mn->right)) { FKERR("[compiler] compile_math_expr_node left 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, mn->lineno()); cg.push(left, mn->lineno()); cg.push(right, mn->lineno()); cg.push(dest, mn->lineno()); FKLOG("[compiler] compile_math_expr_node %p OK", mn); return true; }
bool compiler::compile_function_call_node(codegen & cg, function_call_node * fn) { FKLOG("[compiler] compile_function_call_node %p", fn); fake * fk = m_fk; myflexer * mf = m_mf; int ret_num = m_func_ret_num; m_func_ret_num = 1; // 参数 std::vector<command> arglist; if (fn->arglist) { for (int i = 0; i < (int)fn->arglist->arglist.size(); i++) { syntree_node* sn = fn->arglist->arglist[i]; if (!compile_node(cg, sn)) { FKERR("[compiler] compile_function_call_node arg fail"); return false; } arglist.push_back(m_cur_addr); } } // 调用位置 command callpos; if (!fn->prefunc) { String func = fn->fuc; // 1 检查变量 int pos = cg.getvariable(func); if (pos != -1) { // 是用变量来调用函数 callpos = MAKE_ADDR(ADDR_STACK, pos); } // 2 检查struct else if (mf->is_have_struct(func)) { // 直接替换成map variant v; v = fk->sh.allocsysstr(MAP_FUNC_NAME); pos = cg.getconst(v); callpos = MAKE_ADDR(ADDR_CONST, pos); } // 3 检查本地函数 else if (mf->is_have_func(func)) { // 申请字符串变量 variant v; // 拼上包名 String pname = fkgen_package_name(mf->get_package(), func); v = fk->sh.allocsysstr(pname.c_str()); pos = cg.getconst(v); callpos = MAKE_ADDR(ADDR_CONST, pos); } // 4 直接字符串使用 else { // 申请字符串变量 variant v; v = fk->sh.allocsysstr(func.c_str()); pos = cg.getconst(v); callpos = MAKE_ADDR(ADDR_CONST, pos); } } else { if (!compile_node(cg, fn->prefunc)) { FKERR("[compiler] compile_function_call_node arg fail"); return false; } callpos = m_cur_addr; } // oper command oper; oper = MAKE_OPCODE(OPCODE_CALL); // 调用类型 command calltype; if (fn->fakecall) { calltype = MAKE_POS(CALL_FAKE); } else if (fn->classmem_call) { calltype = MAKE_POS(CALL_CLASSMEM); } else { calltype = MAKE_POS(CALL_NORMAL); } // 参数个数 command argnum; argnum = MAKE_POS(arglist.size()); if (arglist.size() > MAX_FAKE_PARAM_NUM) { FKERR("[compiler] compile_function_call_node arg too much"); compile_seterror(fn, m_fk, efk_compile_variable_not_found, "arg too much"); return false; } // 返回值个数 command retnum; retnum = MAKE_POS(ret_num); // 返回值 std::vector<command> ret; for (int i = 0; i < ret_num; i++) { int retpos = cg.alloc_stack_identifier(); ret.push_back(MAKE_ADDR(ADDR_STACK, retpos)); m_cur_addrs[i] = ret[i]; } m_cur_addr = ret[0]; cg.push(oper, fn->lineno()); cg.push(calltype, fn->lineno()); cg.push(callpos, fn->lineno()); cg.push(retnum, fn->lineno()); for (int i = 0; i < ret_num; i++) { cg.push(ret[i], fn->lineno()); } cg.push(argnum, fn->lineno()); for (int i = 0; i < (int)arglist.size(); i++) { cg.push(arglist[i], fn->lineno()); } FKLOG("[compiler] compile_function_call_node %p OK", fn); return true; }