Boost logo

Boost :

From: Steven Watanabe (steven_at_[hidden])
Date: 2007-04-04 17:07:31


Alexander Nasonov <alnsn <at> yandex.ru> writes:

>
> Steven Watanabe wrote:
> > I can make it work for msvc
> How?
>

#include <boost/config.hpp>

namespace boost {

namespace scope_exit {

#if (defined(BOOST_MSVC) && defined(_M_IX86)) || \
    (defined(__MWERKS__) && defined(__INTEL__ ))

struct jump_buffer {
    unsigned long return_;
    unsigned long esp_;
    unsigned long ebp_;
};

extern "C" {

__declspec(naked) int __fastcall set_jump(jump_buffer*) {
    __asm {
        mov edx, [esp]
        mov [ecx], edx
        mov [ecx + 4], esp
        mov [ecx + 8], ebp
        mov eax, 0
        ret
    }
}
__declspec(naked) int __fastcall long_jump(jump_buffer*, int) {
    __asm {
        mov ebx, [ecx]
        mov esp, [ecx + 4]
        mov ebp, [ecx + 8]
        mov [esp], ebx
        mov eax, edx
        ret
    }
}

}

#define BOOST_SCOPE_EXIT_USE_REGISTERS __asm {\
    __asm mov eax, 0\
    __asm mov ebx, 0\
    __asm mov ecx, 0\
    __asm mov edx, 0\
    __asm mov esi, 0\
    __asm mov edi, 0\
}

struct scope_exit_helper1 {
    jump_buffer cleanup;
    jump_buffer back;
    ~scope_exit_helper1() {
        BOOST_SCOPE_EXIT_USE_REGISTERS
        if(set_jump(&back) == 0) {
            long_jump(&cleanup, 1);
        }
    }
};

struct scope_exit_helper2 {
    jump_buffer* buf;
    scope_exit_helper2(jump_buffer* b) : buf(b) {}
    ~scope_exit_helper2() {
        if(buf) {
            long_jump(buf, 1);
        }
    }
    scope_exit_helper2(const scope_exit_helper2& other) : buf(other.buf) {
        const_cast<jump_buffer*&>(other.buf) = 0;
    }
    operator bool() const { return(false); }
};

#define BOOST_SCOPE_EXIT_PROTECT_STACK \
    if(true) __asm { \
        __asm sub esp, 512 \
        __asm jmp boost_scope_exit_label ## __LINE__ \
    } \
    else boost_scope_exit_label ## __LINE__:

#define BOOST_SCOPE_EXIT \
    ::boost::scope_exit::scope_exit_helper1 \
      boost_scope_exit_helper1 ## __LINE__; \
    BOOST_SCOPE_EXIT_USE_REGISTERS \
    if(::boost::scope_exit::set_jump( \
      &boost_scope_exit_helper1 ## __LINE__.cleanup) == 0) {} \
    else BOOST_SCOPE_EXIT_PROTECT_STACK \
    if(::boost::scope_exit::scope_exit_helper2\
       boost_scope_exit_helper2 = \
         (&boost_scope_exit_helper1 ## __LINE__.back)) {}\
    else

#endif

}

}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk