void CbPutClass(ClassStruct *c) { I8 i; if (!c) return; if (c->ptr_cnt>4) { PrintFErr("put_class ptrcnt=%d\r\n",c->ptr_cnt); while (TRUE) //TODO: SwapInNext; } for (i=0;iptr_cnt;i++) PutChar('*'); c-=sizeof(ClassStruct)*c->ptr_cnt; if (c->str) PutS(c->str); else { PrintFErr("put_class str=NULL\r\n"); while (TRUE) //TODO: SwapInNext; } PutChar(CH_SPACE); } void CbPutIcParam(IcParam *p) { if (p->ptype) PrintF("%Z %Z %Z ", p->type&IT_MASK,"ST_IT_TYPES", p->ptype&IT_MASK,"ST_IT_TYPES", p->type>>4,"ST_TY_TYPES"); else PrintF("%Z %Z ", p->type&IT_MASK,"ST_IT_TYPES", p->type>>4,"ST_TY_TYPES"); switch (p->type>>4) { case TY_IMM>>4: PrintF("#%X",p->disp); break; case TY_REG>>4: PrintF("%Z",p->reg,"ST_U8_REGS"); break; case TY_DISP>>4: PrintF("%X[%Z]",p->disp,p->reg,"ST_U8_REGS"); break; case TY_RIP_DISP32>>4: PrintF("[%X]",p->disp); break; } } void CbPutIc(IntermediateCode *tempi) { U8 opcode=tempi->ic_opcode; if (opcode>=EC_END_EXP && opcode!=EC_NOP1) { PrintF("%15ts %016X ", SysTextSub(opcode,"ST_INTERMEDIATE_CODE")+4, tempi->ic_data); if (tempi->r.type&TY_MASK) { CbPutIcParam(&tempi->r); cout "<-"; } if (tempi->p1.type&TY_MASK) CbPutIcParam(&tempi->p1); cout ","; if (tempi->p2.type&TY_MASK) CbPutIcParam(&tempi->p2); cout ","; if (tempi->p3.type&TY_MASK) CbPutIcParam(&tempi->p3); cout " "; CbPutClass(tempi->ic_class); if (tempi->ic_flags & ICF_P3_TO_DOUBLE) PutS("$$FG,LTBLUE$$p3d$$FG$$ "); if (tempi->ic_flags & ICF_P3_TO_INT) PutS("$$FG,GREEN$$p3i$$FG$$ "); if (tempi->ic_flags & ICF_P2_TO_DOUBLE) PutS("$$FG,LTBLUE$$p2d$$FG$$ "); if (tempi->ic_flags & ICF_P2_TO_INT) PutS("$$FG,GREEN$$p2i$$FG$$ "); if (tempi->ic_flags & ICF_P1_TO_DOUBLE) PutS("$$FG,LTBLUE$$p1d$$FG$$ "); if (tempi->ic_flags & ICF_P1_TO_INT) PutS("$$FG,GREEN$$p1i$$FG$$ "); if (tempi->ic_flags & ICF_R_TO_DOUBLE) PutS("$$FG,LTBLUE$$rd$$FG$$ "); if (tempi->ic_flags & ICF_R_TO_INT) PutS("$$FG,GREEN$$ri$$FG$$ "); if (tempi->ic_flags & ICF_USE_DOUBLE) PutS("[double] "); if (tempi->ic_flags & ICF_USE_UNSIGNED) PutS("[unsigned] "); if (tempi->ic_flags & ICF_USE_INT) PutS("[int] "); if (tempi->ic_flags & ICF_NO_DEPEND_RESULT) PutS("-DEP "); if (tempi->ic_flags & ICF_DEPEND_RESULT) PutS("+DEP "); if (tempi->ic_flags & ICF_NOT_ADDRESS) PutS("(NOT_ADDRESS) "); if (tempi->ic_flags & ICF_PUSH_RESULT) PutS("(PUSH) "); if (tempi->ic_flags & ICF_PUSH_CMP) PutS("(PUSH_CMP) "); if (tempi->ic_flags & ICF_POP_CMP) PutS("(POP_CMP) "); if (tempi->ic_flags & ICF_RCX_CMP) PutS("(RCX_CMP) "); if (tempi->ic_flags & ICF_RCX_CMP2) PutS("(RCX_CMP2) "); CrLf; } } void CbInitOutPtrs(LexCbStack *ll) { CodeBlk *cb=MAllocZ(sizeof(CodeBlk)); cb->next=NULL; ll->cb_out_first=cb; ll->cb_out_last=cb; ll->cb_misc_list=NULL; ll->cb_misc_list_end=&ll->cb_misc_list; ll->cb_out_ptr=&cb->data; ll->cb_out_end=ll->cb_out_ptr+sizeof(IntermediateCode)*CB_IC_CNT; ll->cb_last_out_ptr=&cb->data; } void CbInitInPtrs(LexCbStack *ll) { CodeBlk *cb=ll->cb_out_first; ll->cb_in_first=cb; ll->cb_in_ptr=&cb->data; ll->cb_in_end=ll->cb_in_ptr+sizeof(IntermediateCode)*CB_IC_CNT; } void CbPutAllIc(LexStruct *lx) { IntermediateCode *tempi; CbInitInPtrs(&lx->cb); tempi=lx->cb.cb_in_ptr; while (tempi->ic_opcode) { if (tempi->ic_flags&ICF_TRACE) CbPutIc(tempi); tempi+=sizeof(IntermediateCode); } } void CbAddIc(LexStruct *lx, U8 opcode_and_precidence,U8 arg, ClassStruct *c,U8 flags=0) { IntermediateCode *tempi=lx->cb.cb_out_ptr; CodeBlk *cb,*cb1; lx->cb.cb_last_out_ptr=tempi; tempi->ic_opcode=opcode_and_precidence.u2[0]; tempi->ic_precidence=opcode_and_precidence.u2[1]; tempi->ic_data=arg; tempi->ic_class=c; if (Bt(&lx->flags,LFf_OPT_TRACE)) { Bts(&lx->flags,LFf_OPT_TRACE_PRESENT); flags|=ICF_TRACE; } tempi->ic_flags=flags; tempi->ic_line=lx->lag_line_num; if (lx->flags & LF_PARSE_TRACE) CbPutIc(tempi); tempi+=sizeof(IntermediateCode); if (tempi>=lx->cb.cb_out_end) { cb=MAllocZ(sizeof(CodeBlk)); cb->next=NULL; cb1=lx->cb.cb_out_last; cb1->next=cb; lx->cb.cb_out_last=cb; tempi=&cb->data; lx->cb.cb_out_end=tempi+sizeof(IntermediateCode)*CB_IC_CNT; } lx->cb.cb_out_ptr=tempi; } IntermediateCode *CbGetIc1(LexCbStack *lx) { IntermediateCode *tempi=lx->cb_in_ptr, *tempi1=tempi+sizeof(IntermediateCode); CodeBlk *cb; if (tempi1>=lx->cb_in_end) { cb=tempi1-sizeof(IntermediateCode)*CB_IC_CNT-offset(CodeBlk.data); cb=cb->next; tempi1=&cb->data; lx->cb_in_end=tempi1+sizeof(IntermediateCode)*CB_IC_CNT; } lx->cb_in_ptr=tempi1; return tempi; } void CbPush(LexStruct *lx) { LexCbStack *templ=MAlloc(sizeof(LexCbStack)); MemCpy(templ,&lx->cb,sizeof(LexCbStack)); if (lx->cb.cb_misc_list_end==&lx->cb.cb_misc_list) templ->cb_misc_list_end=&templ->cb_misc_list; lx->cb.cb_next=templ; } void CbPop(LexStruct *lx) { LexCbStack *templ=lx->cb.cb_next; MemCpy(&lx->cb,templ,sizeof(LexCbStack)); if (templ->cb_misc_list_end==&templ->cb_misc_list) lx->cb.cb_misc_list_end=&lx->cb.cb_misc_list; Free(templ); } CbMiscStruct *CbFindGotoLabel(LexStruct *lx,I1 *name) { CbMiscStruct *templ=lx->cb.cb_misc_list; while (templ) { if (templ->type==CBMT_GOTO_LABEL) { if (!StrCmp(templ->str,name)) return templ; } templ=templ->next; } return NULL; } CbMiscStruct *CbMiscNew(LexStruct *lx,U8 t) { CbMiscStruct *result=MAllocZ(sizeof(CbMiscStruct)); lx->cb.cb_misc_list_end->next=result; lx->cb.cb_misc_list_end=result; result->address=INVALID_PTR; result->type=t; return result; } void DelCbMiscList(LexStruct *lx) { CbMiscStruct *mc=lx->cb.cb_misc_list,*mc1; while (mc) { mc1=mc->next; if (mc->type==CBMT_GOTO_LABEL && !mc->address) { lx->cb.cb_misc_list=NULL; //prevent recursion PrintFErr("%S%s\r\n","ST_UNDEFINED_GOTO_LABEL",mc->str); throw(EXCEPT_COMPILER,1); } Free(mc->str); Free(mc->jmp_table); Free(mc); mc=mc1; } } LexStruct *CbPopNoFree(LexStruct *lx) { LexCbStack *templ=lx->cb.cb_next; MemCpy(&lx->cb,templ,sizeof(LexCbStack)); if (templ->cb_misc_list_end==&templ->cb_misc_list) lx->cb.cb_misc_list_end=&lx->cb.cb_misc_list; return templ; } void CbAppend(LexStruct *lx, LexCbStack *ll) { IntermediateCode *tempi; CbInitInPtrs(ll); do { tempi=CbGetIc1(ll); if (tempi->ic_opcode) { CbAddIc(lx,tempi->ic_opcode+tempi->ic_precidence<<16,tempi->ic_data, tempi->ic_class,tempi->ic_flags); } } while (tempi->ic_opcode); DelLinkedList(ll->cb_out_first); if (ll->cb_misc_list_end!=&ll->cb_misc_list) { lx->cb.cb_misc_list_end->next=ll->cb_misc_list; lx->cb.cb_misc_list_end=ll->cb_misc_list_end; } Free(ll); } void CbCombine(LexStruct *lx) { CodeBlk *cb=lx->cb.cb_out_first,*cb1,*cb2; I8 i=0,j=sizeof(IntermediateCode)*CB_IC_CNT; void *ptr; while (cb) { i++; cb=cb->next; } if (i>1) { cb1=MAlloc(i*j+offset(CodeBlk.data)); cb1->next=NULL; cb=lx->cb.cb_out_first; ptr=&cb1->data; while (cb) { cb2=cb->next; MemCpy(ptr,&cb->data,j); ptr+=j; Free(cb); cb=cb2; } lx->cb.cb_out_first=cb1; } } U1 *CbCompile(LexStruct *lx,ClassStruct *fun_class, U8 *code_size,DbgInfo **dbg_info,U8 *type=NULL) { U1 *result; I8 register_offsets[NUM_REGS],min_line=MAX_I8,max_line=0; if (dbg_info) *dbg_info=NULL; CbCombine(lx); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) { if (Bt(&lx->pass_trace_mask,0)) { coutln "$$IV 1$$Before Pass 1:$$IV 0$$"; CbPutAllIc(lx); } } CmpOptPass1(lx,fun_class,TRUE); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) { if (Bt(&lx->pass_trace_mask,1)) { coutln "$$IV 1$$After Pass 1:$$IV 0$$"; CbPutAllIc(lx); } } CmpOptPass2(lx,fun_class,register_offsets); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) { if (Bt(&lx->pass_trace_mask,2)) { coutln "$$IV 1$$After Pass 2:$$IV 0$$"; CbPutAllIc(lx); } } CmpOptPass3(lx,register_offsets,type); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) { if (Bt(&lx->pass_trace_mask,3)) { coutln "$$IV 1$$After Pass 3:$$IV 0$$"; CbPutAllIc(lx); } } CmpOptPass4(lx); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) { if (Bt(&lx->pass_trace_mask,4)) { coutln "$$IV 1$$After Pass 4:$$IV 0$$"; CbPutAllIc(lx); } } CmpOptPass5(lx,fun_class); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) { if (Bt(&lx->pass_trace_mask,5)) { coutln "$$IV 1$$After Pass 5:$$IV 0$$"; CbPutAllIc(lx); } } if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) if (Bt(&lx->pass_trace_mask,6)) coutln "$$IV 1$$Pass 6:$$IV 0$$"; CmpOptPass678(lx,fun_class,register_offsets,NULL,6,dbg_info,&min_line,&max_line); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) if (Bt(&lx->pass_trace_mask,7)) coutln "$$IV 1$$Pass 7:$$IV 0$$"; *code_size=CmpOptPass678(lx,fun_class,register_offsets,NULL,7,dbg_info,&min_line,&max_line); result=MAlloc(*code_size); if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) if (Bt(&lx->pass_trace_mask,8)) coutln "$$IV 1$$Pass 8:$$IV 0$$"; *code_size=CmpOptPass678(lx,fun_class,register_offsets,result,8,dbg_info,&min_line,&max_line); DelLinkedList(lx->cb.cb_out_first); DelCbMiscList(lx); if (Bt(&lx->flags,LFf_COMPILE_TRACE)) { if (lx->a) { if (lx->a->seg_size==16) CallExtStr("Dasm2",result,*code_size,16); else if (lx->a->seg_size==64) CallExtStr("Dasm2",result,*code_size,64); else CallExtStr("Dasm2",result,*code_size,32); } else CallExtStr("Dasm2",result,*code_size,64); } return result; } void DelHashTable(SysHashTable *tempht) { I8 i; SysHashEntry *temph,*temph1; ClassStruct *tempc; GlblVarStruct *tempg; if (!tempht) return; for (i=0;i<=tempht->mask;i++) { temph=tempht->body[i]; while (temph) { temph1=temph->next; if (!(temph->type&HTT_DICT_WORD)) Free(temph->str); if (temph->type & (HTT_FUNCTION | HTT_CLASS | HTT_STR_CONST | HTT_GLBL_VAR | HTT_SYS_SYMBOL)) { Free(temph->source_link); Free(temph->index); if (temph->type & (HTT_FUNCTION | HTT_CLASS)) { tempc=temph; Free(tempc->debug); Free(tempc->import_name); DelMemberList(tempc); //assumes code not on heap } else if (temph->type&HTT_STR_CONST) Free(temph><(StrConstStruct *)->data); else if (temph->type&HTT_GLBL_VAR) { tempg=temph; DelLinkedList(tempg->dim_list); Free(tempg->import_name); } } Free(temph); temph=temph1; } } Free(tempht); }