Changeset 1405


Ignore:
Timestamp:
2013-09-26T11:33:09+02:00 (20 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.