void CgCallBackNewCtored( // NEW OBJECT WAS CTOR'ED SE* se_del, // - state entry for delete during CTOR throw FN_CTL* fctl ) // - function information { cg_name expr; // - emitted expression patch_entry* pe; // - entry when patching cg_type type; // - not used CondInfoNewCtorBeg( fctl ); expr = CgExprPopType( &type ); CgCommaBefore( expr, type ); pe = CarveAlloc( carve_patch_se ); pe->se = se_del; expr = CgExprPopType( &type ); expr = CgCallBackLeft( expr , &callBackNewCtorBeg , pe , type ); expr = CgComma( emitPatch( &pe->patch ), expr, type ); CgExprPush( expr, type ); CondInfoNewCtorEnd( fctl ); expr = CgExprPopType( &type ); CgCommaOptional( expr, type ); pe = CarveAlloc( carve_patch_se ); pe->se = se_del; expr = CgExprPopType( &type ); expr = CgSideEffect( expr, emitPatch( &pe->patch ), type ); expr = CgCallBackRight( expr , &callBackNewCtorEnd , pe , type ); CgExprPush( expr, type ); }
void CgExprDtored( // DTOR CG EXPRESSION cg_name expr, // - expression cg_type type, // - expression type DGRP_FLAGS pop_type, // - type of popping destruction FN_CTL* fctl ) // - function control { #if 0 cg_type type; // - expression type switch( CgExprStackSize() ) { case 0 : break; case 1 : { boolean temp_dtoring = fctl->temp_dtoring; SYMBOL temp = getExprTempSym( &type, fctl, pop_type ); if( temp_dtoring ) { if( fctl->ctor_test ) { pop_type |= DGRP_CTOR; } CgDestructExprTemps( pop_type, fctl ); if( NULL != temp ) { CgExprPush( CgFetchSym( temp ), type ); } } } break; DbgDefault( "CgExprDtored -- too many temps" ); } #else SYMBOL temp; // - NULL or copied temp DbgVerify( 0 == CgExprStackSize(), "CgExprDtored -- more than one expr" ); if( expr != NULL ) { if( pop_type & DGRP_DONE ) { CGDone( expr ); temp = NULL; } else if( pop_type & DGRP_TRASH ) { CGTrash( expr ); temp = NULL; } else if( fctl->temp_dtoring ) { temp = CgVarTempTyped( type ); CGDone( CGLVAssign( CgSymbol( temp ), expr, type ) ); } else { CgExprPush( expr, type ); temp = NULL; } if( fctl->temp_dtoring ) { fctl->temp_dtoring = FALSE; if( fctl->ctor_test ) { pop_type |= DGRP_CTOR; } CgDestructExprTemps( pop_type, fctl ); if( NULL != temp ) { CgExprPush( CgFetchSym( temp ), type ); } } } #endif }
void CgExprPushWithAttr( // PUSH EXPR WITH ATTRIBUTES cg_name expr, // - expression cg_type type, // - expression type cg_sym_attr attr ) // - expression attribute { CgExprPush( CGAttr( expr, attr ), type ); }
void CondInfoSetFlag( // SET FLAG FOR CONDITIONAL DTOR BLOCK FN_CTL* fctl, // - function control bool set_flag ) // - true ==> set the flag; false ==> clear { COND_STK* stk; // - conditional entry cg_name op_flg; // - expression for flag setting cg_name op_mask; // - mask operand COND_INFO cond; // - conditional information patch_handle patch; // - handle for patch cg_op opcode; // - opcode for set/clr stk = PstkTopElement( &stack_cond_blks ); CondInfoSetup( stk->offset, &cond, fctl ); patch = BEPatch(); op_mask = CGPatchNode( patch, TY_UINT_1 ); if( set_flag ) { stk->mask_set = cond.mask; stk->handle_set = patch; opcode = O_OR; } else { stk->mask_clr = NOT_BITARR_MASK( cond.mask ); stk->handle_clr = patch; opcode = O_AND; } op_flg = CgSymbolPlusOffset( cond.sym, cond.offset ); op_flg = CGLVPreGets( opcode, op_flg, op_mask, TY_UINT_1 ); CgExprPush( op_flg, TY_POINTER ); }
void CgExprAttr( // SET CONST/VOLATILE/etc. ATTRIBUTES FOR EXPR cg_sym_attr attr ) // - attribute { cg_type type; // - expression type cg_name expr; // - top expression expr = CgExprPopType( &type ); expr = CGAttr( expr, attr ); CgExprPush( expr, type ); }
void CgCommaWithTopExpr( // PUSH COMMA'D EXPRESSION WITH TOP EXPR cg_name expr, // - rhs expression cg_type type ) // - rhs type { cg_name lhs; // - lhs expression if( CgExprPopGarbage() ) { lhs = NULL; } else { lhs = CgExprPop(); } CgExprPush( CgComma( lhs, expr, type ), type ); }
void CgCdArgDefine( // DEFINE CDOPT VALUE unsigned value ) // - cdopt value { cg_name expr; // - expression under construction cg_type type; // - expression type cdtor_entry* cd_entry; // - cdopt entry type = CgTypeOffset(); expr = CgOffset( value ); cd_entry = RingCarveAlloc( carver_cdtors, &ring_cdtors ); cd_entry->value = value; cd_entry->handle = CallStackTopHandle(); CgExprPush( expr, type ); }
// when expr is non-null, top of stack is replaced by: // // COMMA // | | // +---------+ +-------+ // | | // COMMA temp // | | // +----+ +----+ // | | // ASSIGN expr // | | // +-+ +-+ // | | // temp top // void CgCommaOptional( // EMIT OPTIONAL COMMA'ED EXPRESSION cg_name expr, // - expression or NULL cg_type type ) // - type of expression { cg_name orig; // - original expression cg_type orig_type; // - original expression type if( expr != NULL ) { if( ! CgExprPopGarbage() ) { orig = CgExprPopType( &orig_type ); expr = CgSideEffect( orig, expr, type ); } CgExprPush( expr, type ); } }
void CgCommaBefore( // EMIT COMMA'ED EXPRESSION BEFORE cg_name expr, // - expression cg_type type ) // - type of above expression { cg_name top_expr; // - expression on top cg_type top_type; // - type on top top_expr = CgExprPopType( &top_type ); if( top_expr == NULL ) { if( expr != NULL ) { CgDone( expr, type ); } } else { CgExprPush( CgComma( expr, top_expr, top_type ), top_type ); } }
static void condInfoCallBack( // SET A CALL-BACK void (*rtn)( void* ), // - call-back routine bool on_left ) // - true ==> call-back on left { cg_name expr; // - top expression cg_type type; // - top type COND_STK* stk; // - stack ptr stk = PstkTopElement( &stack_cond_blks ); expr = CgExprPopType( &type ); if( on_left ) { expr = CgCallBackLeft( expr, rtn, stk, type ); } else { expr = CgCallBackRight( expr, rtn, stk, type ); } CgExprPush( expr, type ); }
SE* DtorForDelBeg( // DTORING AREA TO BE DELETED: start FN_CTL* fctl, // - function information target_size_t elem_size, // - size of one element in area unsigned dlt1, // - entry type when one arg unsigned dlt2, // - entry type when two args SYMBOL op_del ) // - operator delete to be used { SE* se_dlt; // - entry allocated SYMBOL var; // - var containing address of delete area cg_name top_expr; // - top expression cg_type top_type; // - type of top expression cg_name emit; // - expression for state update patch_handle patch; // - patch handle for area if( DtmTabular( fctl ) ) { if( 2 == SymFuncArgList( op_del )->num_args ) { se_dlt = SeAlloc( dlt2 ); se_dlt->del_2_array.size = elem_size; } else { se_dlt = SeAlloc( dlt1 ); } se_dlt->del_1_array.op_del = op_del; var = CgVarRw( TY_POINTER, SC_AUTO ); if( se_dlt->base.gen ) { AutoRelRegister( var, &se_dlt->del_1_array.offset ); } top_expr = CgExprPopType( &top_type ); top_expr = CGLVAssign( CgSymbol( var ), top_expr, top_type ); top_expr = CgFetchType( top_expr, top_type ); emit = emitPatch( &patch ); top_expr = emitPatchCallBack( top_expr , emit , top_type , &patchForDtorDelBeg , patch , se_dlt ); CgExprPush( top_expr, top_type ); DbgSetState( "patchForDtorDelBeg", se_dlt ); } else { se_dlt = NULL; } return se_dlt; }
void DtorForDelEnd( // DTORING AREA TO BE DELETED: end FN_CTL* fctl, // - function information SE* se_dlt ) // - entry { cg_name emit; // - expression for state update patch_handle patch; // - patch handle for area cg_name top_expr; // - top expression cg_type top_type; // - type of top expression if( DtmTabular( fctl ) ) { DbgVerify( se_dlt != NULL, "DtorForDelEnd -- NULL entry" ); emit = emitPatch( &patch ); top_expr = CgExprPopType( &top_type ); top_expr = emitPatchCallBack( top_expr , emit , top_type , &patchForDtorDelEnd , patch , se_dlt ); CgExprPush( top_expr, top_type ); } }