void interpreter::get_running_call_stack_frame_info(int frame, const char * & stackinfo, const char * & func, const char * & file, int & line) const { stackinfo = ""; func = ""; file = ""; line = 0; if (!m_fb) { return; } m_fk->rn.cur_runinginfo.clear(); int deps = 0; int ip = m_ip; int bp = m_bp; const func_binary * fb = m_fb; while (!BP_END(bp)) { if (deps >= frame) { func = fb ? FUNC_BINARY_NAME(*fb) : ""; file = fb ? FUNC_BINARY_FILENAME(*fb) : ""; line = fb ? GET_CMD_LINENO(*fb, ip) : 0; m_fk->rn.cur_runinginfo += "#"; m_fk->rn.cur_runinginfo += fkitoa(deps); m_fk->rn.cur_runinginfo += " "; m_fk->rn.cur_runinginfo += func; m_fk->rn.cur_runinginfo += " at "; m_fk->rn.cur_runinginfo += file; m_fk->rn.cur_runinginfo += ":"; m_fk->rn.cur_runinginfo += fkitoa(line); m_fk->rn.cur_runinginfo += "\n"; stackinfo = m_fk->rn.cur_runinginfo.c_str(); return; } 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; } deps++; } }
void assembler::compile_seterror(const func_binary & fb, command cmd, efkerror err, const char *fmt, ...) { char errorstr[512]; va_list ap; va_start(ap, fmt); vsnprintf(errorstr, sizeof(errorstr) - 1, fmt, ap); va_end(ap); errorstr[sizeof(errorstr) - 1] = 0; seterror(m_fk, err, FUNC_BINARY_FILENAME(fb), FUNC_BINARY_LINENO(fb, m_pos), FUNC_BINARY_NAME(fb), "assembler %llu, %s", cmd, errorstr); }
FAKE_API const char * fkgetfuncfile(fake * fk, const char * func) { variant funcv; V_SET_STRING(&funcv, func); const funcunion * f = fk->fm.get_func(funcv); if (f && f->havefb) { return FUNC_BINARY_FILENAME(f->fb); } return ""; }
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; }
const char * interpreter::get_running_call_stack() const { if (!m_fb) { return ""; } m_fk->rn.cur_runinginfo.clear(); int deps = 0; int ip = m_ip; int bp = m_bp; const func_binary * fb = m_fb; while (!BP_END(bp)) { m_fk->rn.cur_runinginfo += "#"; m_fk->rn.cur_runinginfo += fkitoa(deps); m_fk->rn.cur_runinginfo += " "; m_fk->rn.cur_runinginfo += fb ? FUNC_BINARY_NAME(*fb) : ""; m_fk->rn.cur_runinginfo += " at "; m_fk->rn.cur_runinginfo += fb ? FUNC_BINARY_FILENAME(*fb) : ""; m_fk->rn.cur_runinginfo += ":"; m_fk->rn.cur_runinginfo += fb ? fkitoa(GET_CMD_LINENO(*fb, ip)) : 0; m_fk->rn.cur_runinginfo += "\n"; for (int j = 0; fb && j < FUNC_BINARY_MAX_STACK(*fb); j++) { m_fk->rn.cur_runinginfo += " "; String variant_name; for (int i = 0; i < fb->m_debug_stack_variant_info_num; i++) { const stack_variant_info & info = fb->m_debug_stack_variant_info[i]; if (info.pos == j) { variant_name += info.name; variant_name += "(line:"; variant_name += fkitoa(info.line); variant_name += ") "; } } if (variant_name.empty()) { variant_name = "(anonymous)"; } m_fk->rn.cur_runinginfo += variant_name; m_fk->rn.cur_runinginfo += "\t["; m_fk->rn.cur_runinginfo += fkitoa(j); m_fk->rn.cur_runinginfo += "]\t"; variant * v = 0; GET_STACK(bp, v, j); m_fk->rn.cur_runinginfo += vartostring(v); m_fk->rn.cur_runinginfo += "\n"; } 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; } deps++; } return m_fk->rn.cur_runinginfo.c_str(); }