reactos/rostests/tests/pseh2/psehtest.c
KJK::Hyperion dbd93ad414 PSEH 2 test suite - around 90 tests so far, and more coming
svn path=/trunk/; revision=38311
2008-12-23 19:47:30 +00:00

2437 lines
39 KiB
C

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pseh/pseh2.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define STANDALONE
#include <wine/test.h>
extern void no_op(void);
extern int return_arg(int);
extern int return_zero(void);
extern int return_positive(void);
extern int return_negative(void);
extern int return_one(void);
extern int return_minusone(void);
extern int return_zero_2(void *);
extern int return_positive_2(void *);
extern int return_negative_2(void *);
extern int return_one_2(void *);
extern int return_minusone_2(void *);
extern int return_zero_3(int);
extern int return_positive_3(int);
extern int return_negative_3(int);
extern int return_one_3(int);
extern int return_minusone_3(int);
extern int return_zero_4(void *, int);
extern int return_positive_4(void *, int);
extern int return_negative_4(void *, int);
extern int return_one_4(void *, int);
extern int return_minusone_4(void *, int);
extern void set_positive(int *);
static int call_test(int (*)(void));
#define DEFINE_TEST(NAME_) \
static int test_ ## NAME_(void); \
\
static void NAME_(void) { ok(call_test(test_ ## NAME_), "test failed\n"); } \
\
static int test_ ## NAME_(void)
/* Empty statements *///{{{
DEFINE_TEST(empty_1)
{
_SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END;
return 1;
}
DEFINE_TEST(empty_2)
{
_SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END;
return 1;
}
DEFINE_TEST(empty_3)
{
_SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END;
return 1;
}
DEFINE_TEST(empty_4)
{
_SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END;
return 1;
}
DEFINE_TEST(empty_5)
{
_SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
return 1;
}
DEFINE_TEST(empty_6)
{
_SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
return 1;
}
DEFINE_TEST(empty_7)
{
_SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
return 1;
}
DEFINE_TEST(empty_8)
{
_SEH2_TRY { _SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
return 1;
}
//}}}
/* Static exception filters *///{{{
DEFINE_TEST(execute_handler_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(EXCEPTION_CONTINUE_EXECUTION)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_search_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_CONTINUE_SEARCH)
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(execute_handler_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(12345)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(-12345)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* Dynamic exception filters *///{{{
DEFINE_TEST(execute_handler_3)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_one())
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_3)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_minusone())
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_search_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_zero())
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(execute_handler_4)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_positive())
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_4)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_negative())
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* Dynamic exception filters, using _SEH2_GetExceptionInformation() *///{{{
DEFINE_TEST(execute_handler_5)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_one_2(_SEH2_GetExceptionInformation()))
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_5)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_minusone_2(_SEH2_GetExceptionInformation()))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_search_3)
{
static int ret;
ret = return_positive();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_zero_2(_SEH2_GetExceptionInformation()))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(execute_handler_6)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_positive_2(_SEH2_GetExceptionInformation()))
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_6)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_negative_2(_SEH2_GetExceptionInformation()))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* Dynamic exception filters, using _SEH2_GetExceptionCode() *///{{{
DEFINE_TEST(execute_handler_7)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_one_3(_SEH2_GetExceptionCode()))
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_7)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_minusone_3(_SEH2_GetExceptionCode()))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_search_4)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_zero_3(_SEH2_GetExceptionCode()))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(execute_handler_8)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_positive_3(_SEH2_GetExceptionCode()))
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_8)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_negative_3(_SEH2_GetExceptionCode()))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* Dynamic exception filters, using _SEH2_GetExceptionInformation() and _SEH2_GetExceptionCode() *///{{{
DEFINE_TEST(execute_handler_9)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_one_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_9)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_minusone_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_search_5)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_zero_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(execute_handler_10)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(return_positive_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_10)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_positive();
}
_SEH2_EXCEPT(return_negative_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* Constant exception filters with side effects *///{{{
DEFINE_TEST(execute_handler_11)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(set_positive(&ret), EXCEPTION_EXECUTE_HANDLER)
{
ret = ret ? return_positive() : return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_11)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = ret ? return_positive() : return_zero();
}
_SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_EXECUTION)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_search_6)
{
static int ret;
static int ret2;
ret = return_zero();
ret2 = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
ret2 = return_zero();
}
_SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_SEARCH)
{
ret = return_zero();
ret2 = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(set_positive(&ret2), EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
ret2 = return_arg(ret2);
}
_SEH2_END;
return ret == return_positive() && ret2 == return_positive();
}
DEFINE_TEST(execute_handler_12)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(set_positive(&ret), 12345)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(continue_execution_12)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_arg(ret);
}
_SEH2_EXCEPT(set_positive(&ret), -12345)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* _SEH2_LEAVE *///{{{
DEFINE_TEST(leave_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_positive();
_SEH2_LEAVE;
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(leave_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_positive();
_SEH2_LEAVE;
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(leave_3)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_positive();
if(return_one())
_SEH2_LEAVE;
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(leave_4)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
int i;
int n = return_one() + return_one();
for(i = return_zero(); i < n; ++ i)
{
if(i == return_one())
{
ret = return_positive();
_SEH2_LEAVE;
}
}
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(leave_5)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
switch(return_one())
{
case 0: ret = return_zero();
case 1: ret = return_positive(); _SEH2_LEAVE;
case 2: ret = return_zero();
}
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(leave_6)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_LEAVE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
ret = return_positive();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* _SEH2_YIELD() *///{{{
static
int test_yield_1_helper(void)
{
_SEH2_TRY
{
_SEH2_YIELD(return return_positive());
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return return_zero());
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(yield_1)
{
return test_yield_1_helper() == return_positive();
}
static
int test_yield_2_helper(void)
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
_SEH2_YIELD(return return_zero());
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return return_positive());
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(yield_2)
{
return test_yield_2_helper() == return_positive();
}
static
int test_yield_3_helper(void)
{
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_YIELD(return return_positive());
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return return_zero());
}
_SEH2_END;
_SEH2_YIELD(return return_zero());
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return return_zero());
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(yield_3)
{
return test_yield_3_helper() == return_positive();
}
static
int test_yield_4_helper(void)
{
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
_SEH2_YIELD(return return_zero());
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return return_positive());
}
_SEH2_END;
_SEH2_YIELD(return return_zero());
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return return_zero());
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(yield_4)
{
return test_yield_4_helper() == return_positive();
}
static int test_yield_5_ret;
static
int test_yield_5_helper(void)
{
test_yield_5_ret = return_zero();
_SEH2_TRY
{
_SEH2_YIELD(return return_positive());
}
_SEH2_FINALLY
{
test_yield_5_ret = return_positive();
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(yield_5)
{
return test_yield_5_helper() == return_positive() && test_yield_5_ret == return_positive();
}
int test_yield_6_ret;
static
int test_yield_6_helper(void)
{
test_yield_6_ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_YIELD(return return_positive());
}
_SEH2_FINALLY
{
test_yield_6_ret = return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
test_yield_6_ret += return_one();
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(yield_6)
{
return test_yield_6_helper() == return_positive() && test_yield_6_ret == return_positive() + return_one();
}
//}}}
/* Termination blocks *///{{{
DEFINE_TEST(finally_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_arg(ret);
}
_SEH2_FINALLY
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(finally_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_arg(ret);
_SEH2_LEAVE;
}
_SEH2_FINALLY
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(finally_3)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_arg(ret);
_SEH2_YIELD(goto leave);
}
_SEH2_FINALLY
{
ret = return_positive();
}
_SEH2_END;
leave:
return ret == return_positive();
}
static int test_finally_4_ret;
static int test_finally_4_helper(void)
{
test_finally_4_ret = return_zero();
_SEH2_TRY
{
test_finally_4_ret = return_arg(test_finally_4_ret);
_SEH2_YIELD(return return_positive());
}
_SEH2_FINALLY
{
test_finally_4_ret = return_positive();
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(finally_4)
{
return test_finally_4_helper() == return_positive() && test_finally_4_ret;
}
DEFINE_TEST(finally_5)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_FINALLY
{
ret = return_positive();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(finally_6)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
ret = return_arg(ret);
}
_SEH2_FINALLY
{
if(ret == return_zero())
ret = return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(ret == return_positive())
ret = return_positive() + return_one();
}
_SEH2_END;
return ret == return_positive() + return_one();
}
DEFINE_TEST(finally_7)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
ret = return_arg(ret);
_SEH2_LEAVE;
}
_SEH2_FINALLY
{
if(ret == return_zero())
ret = return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(ret == return_positive())
ret = return_positive() + return_one();
}
_SEH2_END;
return ret == return_positive() + return_one();
}
DEFINE_TEST(finally_8)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
ret = return_arg(ret);
_SEH2_YIELD(goto leave);
}
_SEH2_FINALLY
{
if(ret == return_zero())
ret = return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(ret == return_positive())
ret = return_positive() + return_one();
}
_SEH2_END;
leave:
return ret == return_positive() + return_one();
}
static int test_finally_9_ret;
static int test_finally_9_helper(void)
{
test_finally_9_ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
test_finally_9_ret = return_arg(test_finally_9_ret);
_SEH2_YIELD(return return_positive());
}
_SEH2_FINALLY
{
if(test_finally_9_ret == return_zero())
test_finally_9_ret = return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(test_finally_9_ret == return_positive())
test_finally_9_ret = return_positive() + return_one();
}
_SEH2_END;
return return_zero();
}
DEFINE_TEST(finally_9)
{
return test_finally_9_helper() == return_positive() && test_finally_9_ret == return_positive() + return_one();
}
DEFINE_TEST(finally_10)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_FINALLY
{
if(ret == return_zero())
ret = return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(ret == return_positive())
ret = return_positive() + return_one();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive() + return_one();
}
DEFINE_TEST(finally_11)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_TRY
{
ret = return_arg(ret);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_FINALLY
{
ret = return_positive();
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
if(ret == return_positive())
ret += return_one();
}
_SEH2_END;
return ret == return_positive() + return_one();
}
DEFINE_TEST(finally_12)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_TRY
{
ret = return_arg(ret);
}
_SEH2_FINALLY
{
ret = return_positive();
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(ret == return_positive())
ret += return_one();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
if(ret == return_positive() + return_one())
ret += return_one();
}
_SEH2_END;
return ret == return_positive() + return_one() + return_one();
}
#if 0
static int test_finally_13_ret;
static
void test_finally_13_helper(void)
{
test_finally_13_ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
test_finally_13_ret = return_positive();
_SEH2_YIELD(return);
test_finally_13_ret = return_zero();
}
_SEH2_FINALLY
{
if(test_finally_13_ret == return_positive())
test_finally_13_ret += return_one();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(test_finally_13_ret == return_positive() + return_one())
test_finally_13_ret += return_one();
RaiseException(0xE00DEAD0, 0, 0, NULL);
test_finally_13_ret = return_zero();
}
_SEH2_END;
test_finally_13_ret = return_zero();
}
DEFINE_TEST(finally_13)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_arg(ret);
test_finally_13_helper();
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive() && test_finally_13_ret == return_positive() + return_one() + return_one();
}
static int test_finally_14_ret;
static
void test_finally_14_helper(void)
{
test_finally_14_ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_TRY
{
test_finally_14_ret = return_positive();
RaiseException(0xE00DEAD0, 0, 0, NULL);
test_finally_14_ret = return_zero();
}
_SEH2_FINALLY
{
if(test_finally_14_ret == return_positive())
test_finally_14_ret += return_one();
}
_SEH2_END;
}
_SEH2_FINALLY
{
if(test_finally_14_ret == return_positive() + return_one())
test_finally_14_ret += return_one();
RaiseException(0xE00DEAD0, 0, 0, NULL);
test_finally_14_ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
test_finally_14_ret = return_zero();
}
_SEH2_END;
test_finally_14_ret = return_zero();
}
DEFINE_TEST(finally_14)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_arg(ret);
test_finally_14_helper();
ret = return_zero();
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_positive();
}
_SEH2_END;
return ret == return_positive() && test_finally_14_ret == return_positive() + return_one() + return_one();
}
#endif
//}}}
/* _SEH2_GetExceptionInformation() *///{{{
static
int verify_xpointers(struct _EXCEPTION_POINTERS * ep, DWORD code, DWORD flags, DWORD argc, const ULONG_PTR * argv, int * ret, int filter)
{
*ret =
ep &&
ep->ExceptionRecord &&
ep->ContextRecord &&
ep->ExceptionRecord->ExceptionCode == code &&
ep->ExceptionRecord->ExceptionFlags == flags &&
ep->ExceptionRecord->NumberParameters == argc &&
(argv || !argc) &&
memcmp(ep->ExceptionRecord->ExceptionInformation, argv, sizeof(argv[0]) * argc) == 0;
if(*ret)
*ret = return_positive();
return filter;
}
DEFINE_TEST(xpointers_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER))
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER))
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_3)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_EXECUTE_HANDLER))
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_4)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_EXECUTE_HANDLER))
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_5)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_EXECUTE_HANDLER))
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_6)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_EXECUTE_HANDLER))
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_7)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_arg(ret);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_CONTINUE_EXECUTION))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_8)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, args);
ret = return_arg(ret);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_9)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 1, args);
ret = return_arg(ret);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 1, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_10)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 2, args);
ret = return_arg(ret);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 2, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_11)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 3, args);
ret = return_arg(ret);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 3, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_12)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_CONTINUE_SEARCH))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_13)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_CONTINUE_SEARCH))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_14)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_CONTINUE_SEARCH))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_15)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_CONTINUE_SEARCH))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xpointers_16)
{
static int ret;
static const ULONG_PTR args[] = { 1, 2, 12345 };
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args);
}
_SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_CONTINUE_SEARCH))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* _SEH2_GetExceptionCode() *///{{{
static
int verify_xcode(int code, int xcode, int * ret, int filter)
{
*ret = code == xcode;
if(*ret)
*ret = return_positive();
return filter;
}
DEFINE_TEST(xcode_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_EXECUTE_HANDLER))
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xcode_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_arg(ret);
}
_SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_EXECUTION))
{
ret = return_zero();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(xcode_3)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_SEARCH))
{
ret = return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
//}}}
/* _SEH2_AbnormalTermination() *///{{{
DEFINE_TEST(abnorm_1)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
ret = return_arg(ret);
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(abnorm_2)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_LEAVE;
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(abnorm_3)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_YIELD(goto leave);
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
}
_SEH2_END;
leave:
return ret == return_positive();
}
DEFINE_TEST(abnorm_4)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive();
}
DEFINE_TEST(abnorm_5)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
ret = return_arg(ret);
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
}
_SEH2_END;
return ret == return_positive() + return_one();
}
DEFINE_TEST(abnorm_6)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_LEAVE;
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
}
_SEH2_END;
}
_SEH2_FINALLY
{
ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
}
_SEH2_END;
return ret == return_positive() + return_one();
}
DEFINE_TEST(abnorm_7)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_YIELD(goto leave);
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
}
_SEH2_END;
}
_SEH2_FINALLY
{
ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
}
_SEH2_END;
leave:
return ret == return_positive() + return_one();
}
DEFINE_TEST(abnorm_8)
{
static int ret;
ret = return_zero();
_SEH2_TRY
{
_SEH2_TRY
{
_SEH2_TRY
{
RaiseException(0xE00DEAD0, 0, 0, NULL);
ret = return_zero();
}
_SEH2_FINALLY
{
ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
}
_SEH2_END;
}
_SEH2_FINALLY
{
ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
}
_SEH2_END;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = return_arg(ret);
}
_SEH2_END;
return ret == return_positive() + return_one();
}
//}}}
/* System support *///{{{
// TODO
//}}}
/* CPU faults *///{{{
// TODO
//}}}
#define USE_TEST_NAME_(NAME_) # NAME_
#define USE_TEST_NAME(NAME_) USE_TEST_NAME_(NAME_)
#define USE_TEST(NAME_) { USE_TEST_NAME(NAME_), NAME_ }
const struct test winetest_testlist[] =
{
USE_TEST(empty_1),
USE_TEST(empty_2),
USE_TEST(empty_3),
USE_TEST(empty_4),
USE_TEST(empty_5),
USE_TEST(empty_6),
USE_TEST(empty_7),
USE_TEST(empty_8),
USE_TEST(execute_handler_1),
USE_TEST(continue_execution_1),
USE_TEST(continue_search_1),
USE_TEST(execute_handler_2),
USE_TEST(continue_execution_2),
USE_TEST(execute_handler_3),
USE_TEST(continue_execution_3),
USE_TEST(continue_search_2),
USE_TEST(execute_handler_4),
USE_TEST(continue_execution_4),
USE_TEST(execute_handler_5),
USE_TEST(continue_execution_5),
USE_TEST(continue_search_3),
USE_TEST(execute_handler_6),
USE_TEST(continue_execution_6),
USE_TEST(execute_handler_7),
USE_TEST(continue_execution_7),
USE_TEST(continue_search_4),
USE_TEST(execute_handler_8),
USE_TEST(continue_execution_8),
USE_TEST(execute_handler_9),
USE_TEST(continue_execution_9),
USE_TEST(continue_search_5),
USE_TEST(execute_handler_10),
USE_TEST(continue_execution_10),
USE_TEST(execute_handler_11),
USE_TEST(continue_execution_11),
USE_TEST(continue_search_6),
USE_TEST(execute_handler_12),
USE_TEST(continue_execution_12),
USE_TEST(leave_1),
USE_TEST(leave_2),
USE_TEST(leave_3),
USE_TEST(leave_4),
USE_TEST(leave_5),
USE_TEST(leave_6),
USE_TEST(yield_1),
USE_TEST(yield_2),
USE_TEST(yield_3),
USE_TEST(yield_4),
USE_TEST(yield_5),
USE_TEST(yield_6),
USE_TEST(finally_1),
USE_TEST(finally_2),
USE_TEST(finally_3),
USE_TEST(finally_4),
USE_TEST(finally_5),
USE_TEST(finally_6),
USE_TEST(finally_7),
USE_TEST(finally_8),
USE_TEST(finally_9),
USE_TEST(finally_10),
USE_TEST(finally_11),
USE_TEST(finally_12),
#if 0
USE_TEST(finally_13),
USE_TEST(finally_14),
#endif
USE_TEST(xpointers_1),
USE_TEST(xpointers_2),
USE_TEST(xpointers_3),
USE_TEST(xpointers_4),
USE_TEST(xpointers_5),
USE_TEST(xpointers_6),
USE_TEST(xpointers_7),
USE_TEST(xpointers_8),
USE_TEST(xpointers_9),
USE_TEST(xpointers_10),
USE_TEST(xpointers_11),
USE_TEST(xpointers_12),
USE_TEST(xpointers_13),
USE_TEST(xpointers_14),
USE_TEST(xpointers_15),
USE_TEST(xpointers_16),
USE_TEST(xcode_1),
USE_TEST(xcode_2),
USE_TEST(xcode_3),
USE_TEST(abnorm_1),
USE_TEST(abnorm_2),
USE_TEST(abnorm_3),
USE_TEST(abnorm_4),
USE_TEST(abnorm_5),
USE_TEST(abnorm_6),
USE_TEST(abnorm_7),
USE_TEST(abnorm_8),
{ 0, 0 }
};
static
LONG WINAPI unhandled_exception(PEXCEPTION_POINTERS ExceptionInfo)
{
ok(0, "unhandled exception %08lX thrown from %p\n", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
return EXCEPTION_CONTINUE_SEARCH;
}
#if defined(_M_IX86)
struct volatile_context
{
void * esp;
void * ebp;
void * ebx;
void * esi;
void * edi;
};
#else
#error TODO
#endif
#if defined(__GNUC__)
static
__attribute__((noinline))
int sanity_check(int ret, struct volatile_context * before, struct volatile_context * after)
{
if(ret && memcmp(before, after, sizeof(before)))
ok(0, "volatile context corrupted\n");
return ret;
}
static
__attribute__((noinline))
int call_test(int (* func)(void))
{
static int ret;
static LPTOP_LEVEL_EXCEPTION_FILTER prev_unhandled_exception;
prev_unhandled_exception = SetUnhandledExceptionFilter(&unhandled_exception);
#if defined(__i386__)
static struct volatile_context before, after;
__asm__ __volatile__
(
"mov %%esp, 0x00 + %c[before]\n"
"mov %%ebp, 0x04 + %c[before]\n"
"mov %%ebx, 0x08 + %c[before]\n"
"mov %%esi, 0x0c + %c[before]\n"
"mov %%edi, 0x10 + %c[before]\n"
"call *%[test]\n"
"mov %%esp, 0x00 + %c[after]\n"
"mov %%ebp, 0x04 + %c[after]\n"
"mov %%ebx, 0x08 + %c[after]\n"
"mov %%esi, 0x0c + %c[after]\n"
"mov %%edi, 0x10 + %c[after]\n"
"push %[after]\n"
"push %[before]\n"
"push %[ret]\n"
"call %c[sanity_check]\n"
"pop %%ecx\n"
"pop %%ecx\n"
"pop %%ecx\n" :
[ret] "=a" (ret) :
[test] "r" (func), [before] "i" (&before), [after] "i" (&after), [sanity_check] "i" (&sanity_check) :
"ebx", "ecx", "edx", "esi", "edi", "flags", "memory"
);
#else
#error TODO
#endif
SetUnhandledExceptionFilter(prev_unhandled_exception);
return ret;
}
#else
#error TODO
#endif
/* EOF */