Changeset 1405


Ignore:
Timestamp:
2013-09-26T11:33:09+02:00 (13 months ago)
Author:
moo
Message:

rewrite try/catch handling to fix nested try/catch

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r1398 r1405  
    1212 * admin 
    1313   * make mkpassword.php easier for noob 
     14 * optimizer 
     15   * rewrite try/catch handling to fix nested try/catch 
    1416 
    15173.0.4 2013-09-?? 
  • trunk/mod_optimizer/xc_optimizer.c

    r1398 r1405  
    4545 
    4646    bbid_t     fall; 
    47 #ifdef ZEND_ENGINE_2 
    48     bbid_t     catch; 
    49 #endif 
    50 #ifdef ZEND_ENGINE_2_5 
    51     bbid_t     finally; 
    52 #endif 
    5347 
    5448    zend_uint  opnum; /* opnum after joining basic block */ 
     
    315309 
    316310    bb->fall       = BBID_INVALID; 
    317 #ifdef ZEND_ENGINE_2 
    318     bb->catch      = BBID_INVALID; 
    319 #endif 
    320 #ifdef ZEND_ENGINE_2_5 
    321     bb->finally    = BBID_INVALID; 
    322 #endif 
    323311 
    324312    if (opcodes) { 
     
    351339    op_flowinfo_t fi; 
    352340    zend_op *last = bb->opcodes + bb->count - 1; 
    353     bbid_t catchbbid = ZESW(BBID_INVALID, bb->catch); 
    354     bbid_t finallybbid; 
    355 #ifdef ZEND_ENGINE_2_5 
    356     finallybbid = BBID_INVALID; 
    357 #else 
    358     finallybbid = bb->finally; 
    359 #endif 
    360341 
    361342    op_get_flowinfo(&fi, last); 
     
    364345            "\n==== #%-3d cnt:%-3d lno:%-3d" 
    365346            " %c%c" 
    366             " op1:%-3d op2:%-3d ext:%-3d fal:%-3d cat:%-3d fnl:%-3d %s ====\n" 
     347            " op1:%-3d op2:%-3d ext:%-3d fal:%-3d %s ====\n" 
    367348            , bb->id, bb->count, bb->alloc ? -1 : line 
    368349            , bb->used ? 'U' : ' ', bb->alloc ? 'A' : ' ' 
    369             , fi.jmpout_op1, fi.jmpout_op2, fi.jmpout_ext, bb->fall, catchbbid, finallybbid, xc_get_opcode(last->opcode) 
     350            , fi.jmpout_op1, fi.jmpout_op2, fi.jmpout_ext, bb->fall, xc_get_opcode(last->opcode) 
    370351            ); 
    371352    op_print(op_array, line, bb->opcodes, last + 1); 
     
    428409        zend_bool isbbhead; 
    429410        bbid_t bbid; 
    430 #ifdef ZEND_ENGINE_2 
    431         bbid_t catchbbid; 
    432 #endif 
    433 #ifdef ZEND_ENGINE_2_5 
    434         bbid_t finallybbid; 
    435 #endif 
    436411    } oplineinfo_t; 
    437412    oplineinfo_t *oplineinfos = xc_do_alloca(count * sizeof(oplineinfo_t), opline_infos_use_heap); 
     
    460435    /* mark try start */ 
    461436    for (i = 0; i < op_array->last_try_catch; i ++) { 
    462         oplineinfos[op_array->try_catch_array[i].try_op].isbbhead = 1; 
    463         oplineinfos[op_array->try_catch_array[i].catch_op].isbbhead = 1; 
    464 #ifdef ZEND_ENGINE_2_5 
    465         oplineinfos[op_array->try_catch_array[i].finally_op].isbbhead = 1; 
    466 #endif 
     437#   define MARK_OP_BB_HEAD(name) \ 
     438        oplineinfos[op_array->try_catch_array[i].name].isbbhead = 1 
     439        MARK_OP_BB_HEAD(try_op); 
     440        MARK_OP_BB_HEAD(catch_op); 
     441#   ifdef ZEND_ENGINE_2_5 
     442        MARK_OP_BB_HEAD(finally_op); 
     443#   endif 
     444#   undef MARK_OP_BB_HEAD 
    467445    } 
    468446#endif 
     
    483461    /* }}} */ 
    484462#ifdef ZEND_ENGINE_2 
    485     /* {{{ fill op lines with catch id */ 
    486     for (i = 0; i < count; i ++) { 
    487         oplineinfos[i].catchbbid = BBID_INVALID; 
     463    /* {{{ convert try_catch_array.* from oplinenum to bbid */ 
     464    for (i = 0; i < op_array->last_try_catch; i ++) { 
     465#   define OPNUM_TO_BBID(name) \ 
     466        op_array->try_catch_array[i].name = oplineinfos[op_array->try_catch_array[i].name].bbid; 
     467        OPNUM_TO_BBID(try_op); 
     468        OPNUM_TO_BBID(catch_op); 
    488469#   ifdef ZEND_ENGINE_2_5 
    489         oplineinfos[i].finallybbid = BBID_INVALID; 
     470        OPNUM_TO_BBID(finally_op); 
    490471#   endif 
    491     } 
    492  
    493     for (i = 0; i < op_array->last_try_catch; i ++) { 
    494         zend_uint j; 
    495         zend_try_catch_element *e = &op_array->try_catch_array[i]; 
    496         zend_uint end = e->catch_op != 0 ? e->catch_op : e->finally_op; 
    497         for (j = e->try_op; j < end; j ++) { 
    498             oplineinfos[j].catchbbid   = e->catch_op   == 0 ? BBID_INVALID : oplineinfos[e->catch_op  ].bbid; 
    499 #   ifdef ZEND_ENGINE_2_5 
    500             oplineinfos[j].finallybbid = e->finally_op == 0 ? BBID_INVALID : oplineinfos[e->finally_op].bbid; 
    501 #   endif 
    502         } 
    503     } 
    504 #ifdef XCACHE_DEBUG 
    505     for (i = 0; i < count; i ++) { 
    506 #   ifdef ZEND_ENGINE_2_5 
    507         TRACE("catch/finallybbids[%d] = %d, %d", i, oplineinfos[i].catchbbid, oplineinfos[i].finallybbid); 
    508 #   else 
    509         TRACE("catchbbids[%d] = %d", i, oplineinfos[i].catchbbid); 
    510 #   endif 
    511     } 
    512 #endif 
     472#   undef OPNUM_TO_BBID 
     473    } 
    513474    /* }}} */ 
    514475#endif 
     
    524485        opline = op_array->opcodes + start; 
    525486        bb = bbs_new_bb_ex(bbs, opline, i - start); 
    526 #ifdef ZEND_ENGINE_2 
    527         bb->catch = oplineinfos[start].catchbbid; 
    528 #endif 
    529 #ifdef ZEND_ENGINE_2_5 
    530         bb->finally = oplineinfos[start].finallybbid; 
    531 #endif 
    532487 
    533488        /* last */ 
     
    567522{ 
    568523    int bbid; 
    569 #ifdef ZEND_ENGINE_2 
    570     bbid_t lastcatchbbid; 
    571 #endif 
    572 #ifdef ZEND_ENGINE_2_5 
    573     bbid_t lastfinallybbid; 
    574 #endif 
     524    zend_uint i; 
    575525 
    576526    for (bbid = 0; bbid < bbs_count(bbs); bbid ++) { 
     
    596546 
    597547#ifdef ZEND_ENGINE_2 
    598     lastcatchbbid = BBID_INVALID; 
     548    /* {{{ convert try_catch_array from bbid to oplinenum */ 
     549    for (i = 0; i < op_array->last_try_catch; i ++) { 
     550#   define BBID_TO_OPNUM(name) \ 
     551        op_array->try_catch_array[i].name = bbs_get(bbs, op_array->try_catch_array[i].name)->opnum; 
     552        BBID_TO_OPNUM(try_op); 
     553        BBID_TO_OPNUM(catch_op); 
    599554#   ifdef ZEND_ENGINE_2_5 
    600     lastfinallybbid = BBID_INVALID; 
     555        BBID_TO_OPNUM(finally_op); 
    601556#   endif 
    602     op_array->last_try_catch = 0; 
    603     for (bbid = 0; bbid < bbs_count(bbs); bbid ++) { 
    604         bb_t *bb = bbs_get(bbs, bbid); 
    605  
    606         if (lastcatchbbid != bb->catch 
    607 #   ifdef ZEND_ENGINE_2_5 
    608          || lastfinallybbid != bb->finally 
    609 #   endif 
    610         ) { 
    611             if (bb->catch != BBID_INVALID 
    612 #   ifdef ZEND_ENGINE_2_5 
    613              || bb->finally != BBID_INVALID 
    614 #   endif 
    615             ) { 
    616                 zend_uint try_op = bbs_get(bbs, bbid)->opnum; 
    617                 zend_uint catch_op   = bb->catch   == BBID_INVALID ? 0 : bbs_get(bbs, bb->catch )->opnum; 
    618 #   ifdef ZEND_ENGINE_2_5 
    619                 zend_uint finally_op = bb->finally == BBID_INVALID ? 0 : bbs_get(bbs, bb->finally)->opnum; 
    620 #   endif 
    621  
    622                 zend_bool already_in_try_catch = 0; 
    623                 int j; 
    624  
    625                 for (j = 0; j < op_array->last_try_catch; ++j) { 
    626                     zend_try_catch_element *element = &op_array->try_catch_array[j]; 
    627                     if (try_op >= element->try_op && try_op < element->catch_op 
    628                      && catch_op == element->catch_op 
    629 #   ifdef ZEND_ENGINE_2_5 
    630                      && finally_op == element->finally_op 
    631 #   endif 
    632                     ) { 
    633                         already_in_try_catch = 1; 
    634                         break; 
    635                     } 
    636                 } 
    637                 if (!already_in_try_catch) { 
    638                     int try_catch_offset = op_array->last_try_catch ++; 
    639  
    640                     op_array->try_catch_array = erealloc(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch); 
    641                     op_array->try_catch_array[try_catch_offset].try_op = try_op; 
    642                     op_array->try_catch_array[try_catch_offset].catch_op = catch_op; 
    643 #   ifdef ZEND_ENGINE_2_5 
    644                     op_array->try_catch_array[try_catch_offset].finally_op = finally_op; 
    645 #   endif 
    646                 } 
    647             } 
    648             lastcatchbbid = bb->catch; 
    649 #   ifdef ZEND_ENGINE_2_5 
    650             lastfinallybbid = bb->finally; 
    651 #   endif 
    652         } 
    653     } 
    654     /* it is impossible to have last bb catched */ 
     557#   undef BBID_TO_OPNUM(name) 
     558    } 
     559    /* }}} */ 
    655560#endif /* ZEND_ENGINE_2 */ 
    656561} 
Note: See TracChangeset for help on using the changeset viewer.