zengl v1.2.1的版本,该版本修复v1.2.0中的函数调用的BUG,v1.2.0中当函数定义在函数调用之后时,函数调用就找不到正确的函数入口地址,该版本通过增加ZL_R_DT_LDFUNID指令操作数类型来解决此BUG...
clsTestOther.testOther(); class clsTestOther m; n; fun testOther() print 'i am in testOther'; print 'hello zengl'; endfun endclass |
ZL_VOID zengl_AsmGenCodes(ZL_VOID * VM_ARG,ZL_INT nodenum) { ............................ //省略N行代码 case ZL_ST_ASM_CODE_INFUNCALL: //如果是函数调用,就输出相应的汇编代码 ............................ //省略N行代码 else run->AddInst(VM_ARG,compile->gencode_struct.pc++,nodenum, ZL_R_IT_JMP,ZL_R_DT_NONE,0, ZL_R_DT_LDADDR,compile->SymFunTable.funs[tmpFunID].LDAdr); //对应汇编指令 类似 "JMP adr%d" 如果找到函数的信息 .......... break; ............................ //省略N行代码 } |
ZL_VOID zengl_AsmGenCodes(ZL_VOID * VM_ARG,ZL_INT nodenum) { ............................ //省略N行代码 case ZL_ST_ASM_CODE_INFUNCALL: //如果是函数调用,就输出相应的汇编代码 ............................ //省略N行代码 else run->AddInst(VM_ARG,compile->gencode_struct.pc++,nodenum, ZL_R_IT_JMP,ZL_R_DT_NONE,0, ZL_R_DT_LDFUNID,tmpFunID); //对应汇编指令 类似 "JMP funid%d" 如果找到函数的信息 .......... break; ............................ //省略N行代码 } |
/* 将所有的伪地址替换为真实的汇编代码位置,从而完成链接工作 */ ZL_VOID zengl_LDAddrListReplaceAll(ZL_VOID * VM_ARG) { ............................ //省略N行代码 for(j=1;j<=2;j++) { if(j==1) op_data = &run->inst_list.insts[i].dest; else op_data = &run->inst_list.insts[i].src; if(op_data->type == ZL_R_DT_LDFUNID) //如果是函数ID,则将函数ID先转为该函数的伪地址,再由该伪地址得到真实的汇编位置 { op_data->val.num = compile->SymFunTable.funs[op_data->val.num].LDAdr; op_data->type = ZL_R_DT_LDADDR; } if(op_data->type == ZL_R_DT_LDADDR) { if(compile->LDAddrList.addr[op_data->val.num].isvalid == ZL_FALSE) compile->exit(VM_ARG,ZL_ERR_CP_LD_INVALID_ADDR_INDEX,op_data->val.num,op_data->val.num); op_data->val.num = compile->LDAddrList.addr[op_data->val.num].loc; op_data->type = ZL_R_DT_NUM; } } ............................ //省略N行代码 } |
/*API接口,用户可以通过此接口在中途停止脚本*/ ZL_EXPORT ZL_EXP_VOID zenglApi_Stop(ZL_EXP_VOID * VM_ARG) { ZENGL_RUN_TYPE * run = &((ZENGL_VM_TYPE *)VM_ARG)->run; if(VM_ARG == ZL_NULL) return; if(run->isDestroyed) return; if(run->isinRunning) { run->isUserWantStop = ZL_TRUE; } } |