bool assembler::compile_jmp(asmgen & asg, const func_binary & fb, command cmd) { int jump_bytecode_pos = COMMAND_CODE(GET_CMD(fb, m_pos)); m_pos++; int jumppos = -1; if (m_posmap.find(jump_bytecode_pos) != m_posmap.end()) { jumppos = m_posmap[jump_bytecode_pos]; } asg.variant_jmp(jumppos); int jmpoffset = asg.size() - sizeof(int); if (jumppos == -1) { // 记录下来 m_caremap[jmpoffset] = jump_bytecode_pos; FKLOG("compile_jmp caremap add %d %d", jmpoffset, jump_bytecode_pos); } else { asg.set_int(jmpoffset, jumppos - asg.size()); FKLOG("compile_jmp set jne add %d -> %d", jmpoffset, jumppos - asg.size()); } 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; }
void myflexer::add_func_desc(func_desc_node * p) { FKLOG("add_func_desc %s %p", p->funcname.c_str(), p); String dump = p->dump(0); FKLOG("func %s dump %s", p->funcname.c_str(), dump.c_str()); m_funclist.push_back(p); }
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_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; }
FAKE_API void fkresumeps(fake * fk, bool & isend) { FKLOG("fkresumeps %p", fk); isend = false; // 上次的processor pool<processor>::node * n = 0; GET_CUR_PROCESSOR(n, fk->rn); if (UNLIKE(!n)) { variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = NILV; FKLOG("fkresumeps %p no processor", fk); CHECK_ERR(err); return; } // 先pop防止重入 POP_CUR_PROCESSOR(fk->rn); processor & pro = n->t; pro.run(); if (LIKE(!PROCESS_END(pro))) { // 重新塞入 PUSH_CUR_PROCESSOR(n, fk->rn); variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = NILV; FKLOG("fkresumeps %p not end", fk); CHECK_ERR(err); return; } // 结束了 variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = ROUTINE_GETRET(*pro.m_entryroutine); CHECK_ERR(err); POOL_PUSH(fk->pp, n); fk->rn.rundeps--; isend = true; FKLOG("fkresumeps %p OK", fk); }
// 调用函数 FAKE_API void fkrunps(fake * fk, const char * func) { FKLOG("fkrunps %p %s", fk, func); fk->rn.rundeps++; // 清空运行环境 fk->clearerr(); // 分配个 pool<processor>::node * n = 0; if (UNLIKE(POOL_EMPTY(fk->pp))) { POOL_GROW(fk->pp, pool<processor>::node, n); PROCESS_INI(n->t, fk); } POOL_POP(fk->pp, n); assert(ARRAY_EMPTY(n->t.m_pl.l)); assert(n->t.m_routine_num == 0); processor & pro = n->t; PROCESS_CLEAR(pro); variant funcv; V_SET_STRING(&funcv, func); routine * r = pro.start_routine(funcv, 0, 0); PUSH_CUR_PROCESSOR(n, fk->rn); // 单独执行,下次再跑run if (UNLIKE(fk->rn.stepmod)) { variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = NILV; FKLOG("fkrunps %p %s yield", fk, func); CHECK_ERR(err); return; } pro.run(); POP_CUR_PROCESSOR(fk->rn); variant * ret = 0; bool err = false; PS_PUSH_AND_GET(fk->ps, ret); *ret = ROUTINE_GETRET(*r); CHECK_ERR(err); POOL_PUSH(fk->pp, n); fk->rn.rundeps--; FKLOG("fkrunps %p %s OK", fk, func); }
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 compiler::compile_break_stmt(codegen & cg, break_stmt * bs) { FKLOG("[compiler] compile_break_stmt %p", bs); cg.push(MAKE_OPCODE(OPCODE_JMP), bs->lineno()); cg.push(EMPTY_CMD, bs->lineno()); // 先塞个位置 int jmppos = cg.byte_code_size() - 1; beak_pos_list & bplist = m_loop_break_pos_stack[m_loop_break_pos_stack.size() - 1]; bplist.push_back(jmppos); FKLOG("[compiler] compile_break_stmt %p OK", bs); return true; }
//错误函数 void myflexer::LexerError(const char* msg) { FKLOG("parse error : %s at line:%d near:%s\n", msg, lineno(), yytext); char buff[100]; tsnprintf(buff, sizeof(buff)-1, "%s at line(%d) near(%s)", msg, lineno(), yytext); m_error = buff; }
void * myflexer::malloc(size_t size, const char * name) { void * p = safe_fkmalloc(m_fk, size); FKLOG("flexer malloc %p %d %s", p, (int)size, name); m_nodelist.push_back((syntree_node*)p); return p; }
bool assembler::compile_return(asmgen & asg, const func_binary & fb, command cmd) { asg.variant_ps_clear(); if (GET_CMD(fb, m_pos) == EMPTY_CMD) { FKLOG("return empty"); m_pos++; asg.variant_jmp(fb.m_size); m_caremap[asg.size() - sizeof(int)] = fb.m_size; return true; } int retnum = COMMAND_CODE(GET_CMD(fb, m_pos)); m_pos++; for (int i = 0; i < retnum; i++) { int ret = 0; GET_VARIANT_POS(fb, ret, m_pos); m_pos++; asg.variant_push(ret); } asg.variant_jmp(fb.m_size); m_caremap[asg.size() - sizeof(int)] = fb.m_size; return true; }
void myflexer::add_const_desc(const char * name, syntree_node * p) { assert(p->gettype() == est_explicit_value); explicit_value_node * ev = dynamic_cast<explicit_value_node *>(p); assert(ev); FKLOG("add_const_desc %s = %s", name, ev->dump(0).c_str()); m_constmap[name] = ev; }
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_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 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_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 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; }
void myflexer::add_const_desc(const char * name, syntree_node * p) { explicit_value_node * ev = dynamic_cast<explicit_value_node *>(p); FKLOG("add_const_desc %s = %s", name, ev->str.c_str()); if (m_constmap[name]) { m_constmap[name]->recycle(); } m_constmap[name] = ev; }
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; }
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 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 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; }
FAKE_API void fkrunpsjit(fake * fk, const char * func) { FKLOG("fkrun %p %s", fk, func); #ifndef FK64 // 32位目前不支持 seterror(fk, efk_jit_error, fkgetcurfile(fk), fkgetcurline(fk), fkgetcurfunc(fk), "current platform not support jit"); return; #endif fk->rn.rundeps++; fk->clearerr(); fk->mac.clear(); variant funcv; V_SET_STRING(&funcv, func); fk->mac.call(funcv); fk->rn.rundeps--; FKLOG("fkrun %p %s OK", fk, func); }
bool Sprite::initWithFile(const std::string& filename) { FKAssert(filename.size()>0, "Invalid filename for sprite"); Texture2D *texture = new Texture2D(); FKLOG("create image here"); Image* image = dynamic_cast<Image*>(ResourceManager::thisManager()->createResource(filename.c_str(),ResourceManager::IMAGE_NAME)); image->load(false); texture->initWithImage(image); if (texture) { Rect rect = RectZero; rect.size = texture->getContentSize(); FKLOG("Sprite size:w %f,h %f",rect.size.width,rect.size.height); return initWithTexture(texture, rect); } // don't release here. // when load texture failed, it's better to get a "transparent" sprite then a crashed program // this->release(); return false; }
void GLGet(StackMode mode, Matrix4* out) { lazyInitialize(); switch(mode) { case GL_MODELVIEW: FKLOG("MV TOP:%s",modelviewStack->top->toString()); out->set(modelviewStack->top->get(),COLUMN_MAJOR); break; case GL_PROJECTION: FKLOG("P TOP:%s",projectionStack->top->toString()); out->set(projectionStack->top->get(),COLUMN_MAJOR); break; case GL_TEXTURE: FKLOG("Tex TOP:%s",textureStack->top->toString()); out->set(textureStack->top->get(),COLUMN_MAJOR); break; default: assert(1 && "Invalid matrix mode specified"); //TODO: Proper error handling break; } }
void codegen::output(const char * filename, const char * packagename, const char * name, func_binary * bin) { assert(m_byte_code_list.size() == m_byte_lineno_list.size()); bin->m_filename = stringdump(m_fk, filename, strlen(filename)); bin->m_packagename = stringdump(m_fk, packagename, strlen(packagename)); bin->m_name = stringdump(m_fk, name, strlen(name)); bin->m_maxstack = m_maxstackpos; bin->m_size = m_byte_code_list.size(); if (bin->m_size > 0) { bin->m_buff = (command *)safe_fkmalloc(m_fk, (bin->m_size * sizeof(command)), emt_func_binary); memcpy(bin->m_buff, &m_byte_code_list[0], bin->m_size * sizeof(command)); } bin->m_lineno_size = m_byte_lineno_list.size(); if (bin->m_lineno_size > 0) { bin->m_lineno_buff = (int *)safe_fkmalloc(m_fk, (bin->m_lineno_size * sizeof(int)), emt_func_binary); memcpy(bin->m_lineno_buff, &m_byte_lineno_list[0], bin->m_lineno_size * sizeof(int)); } bin->m_const_list_num = m_const_list.size(); if (bin->m_const_list_num > 0) { bin->m_const_list = (variant *)safe_fkmalloc(m_fk, (bin->m_const_list_num * sizeof(variant)), emt_func_binary); memcpy(bin->m_const_list, &m_const_list[0], bin->m_const_list_num * sizeof(variant)); } bin->m_container_addr_list_num = m_containeraddr_list.size(); if (bin->m_container_addr_list_num > 0) { bin->m_container_addr_list = (container_addr *)safe_fkmalloc(m_fk, (bin->m_container_addr_list_num * sizeof(container_addr)), emt_func_binary); memcpy(bin->m_container_addr_list, &m_containeraddr_list[0], bin->m_container_addr_list_num * sizeof(container_addr)); } bin->m_debug_stack_variant_info_num = m_debug_block_identifiers_list.size(); if (bin->m_debug_stack_variant_info_num > 0) { bin->m_debug_stack_variant_info = (stack_variant_info *)safe_fkmalloc(m_fk, (bin->m_debug_stack_variant_info_num * sizeof(stack_variant_info)), emt_func_binary); memcpy(bin->m_debug_stack_variant_info, &m_debug_block_identifiers_list[0], bin->m_debug_stack_variant_info_num * sizeof(stack_variant_info)); } bin->m_fresh++; FKLOG("codegen out %s %d", name, m_maxstackpos); }