php-5.6.26源代码 - 如何用C语言支持“类似异常”机制

 

代码编写在文件php-5.6.26\Zend\zend.h
    #define zend_bailout()        _zend_bailout(__FILE__, __LINE__)
    
    #ifdef HAVE_SIGSETJMP
    #    define SETJMP(a) sigsetjmp(a, 0) // 设置跳转点
    #    define LONGJMP(a,b) siglongjmp(a, b) // 进行跳转
    #    define JMP_BUF sigjmp_buf
    #else
    #    define SETJMP(a) setjmp(a)
    #    define LONGJMP(a,b) longjmp(a, b)
    #    define JMP_BUF jmp_buf
    #endif
    
    #define zend_try                                                \
        {                                                            \
            JMP_BUF *__orig_bailout = EG(bailout);                    \
            JMP_BUF __bailout;                                        \
                                                                    \
            EG(bailout) = &__bailout;                                \
            if (SETJMP(__bailout)==0) { // 设置跳转点
    #define zend_catch                                                \
            } else {                                                \
                EG(bailout) = __orig_bailout;
    #define zend_end_try()                                            \
            }                                                        \
            EG(bailout) = __orig_bailout;                            \
        }
    #define zend_first_try        EG(bailout)=NULL;    zend_try
    
使用例子
    // 宏代码
    zend_try {
        /* 2 = Count of deprecation structs */
        for (i = 0; i < 2; i++) {
            const char **p = directives[i].directives;
    
            while(*p) {
                long value;
    
                if (cfg_get_long((char*)*p, &value) == SUCCESS && value) {
                    zend_error(directives[i].error_level, directives[i].phrase, *p);
                }
    
                ++p;
            }
        }
    } zend_catch {
        retval = FAILURE;
    } zend_end_try();
    
    // 宏展开
    {
        {                                                            
            JMP_BUF *__orig_bailout = EG(bailout);                    
            JMP_BUF __bailout;                                        
                                                                    
            EG(bailout) = &__bailout;                                
            if (SETJMP(__bailout)==0) {
                /* 2 = Count of deprecation structs */
                for (i = 0; i < 2; i++) {
                    const char **p = directives[i].directives;
            
                    while(*p) {
                        long value;
            
                        if (cfg_get_long((char*)*p, &value) == SUCCESS && value) {
                            zend_error(directives[i].error_level, directives[i].phrase, *p);
                        }
            
                        ++p;
                    }
                 }
             } else {                                                
                EG(bailout) = __orig_bailout;
             }                                                        
             EG(bailout) = __orig_bailout;                            
          }
    }
    

 

posted on 2018-03-23 10:57  周~~  阅读(164)  评论(0)    收藏  举报

导航