Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Yoann Laissus
wine
Commits
0691998e
Commit
0691998e
authored
25 years ago
by
Alexandre Julliard
Browse files
Options
Downloads
Patches
Plain Diff
Fixed a few bugs, and improved the exception macros (based on
suggestions by Sergei Turchanov).
parent
9fe7a254
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/wine/exception.h
+90
-37
90 additions, 37 deletions
include/wine/exception.h
win32/except.c
+8
-5
8 additions, 5 deletions
win32/except.c
with
98 additions
and
42 deletions
include/wine/exception.h
+
90
−
37
View file @
0691998e
...
...
@@ -15,7 +15,7 @@
*
* They should be used like this:
*
* __TRY
()
* __TRY
* {
* do some stuff that can raise an exception
* }
...
...
@@ -23,11 +23,11 @@
* {
* handle the exception here
* }
* __ENDTRY
()
* __ENDTRY
*
* or
*
* __TRY
()
* __TRY
* {
* do some stuff that can raise an exception
* }
...
...
@@ -40,52 +40,86 @@
*
* The finally_func must be defined with the WINE_FINALLY_FUNC macro.
*
* Warning: you cannot use return, break, or continue inside a __TRY
* or __EXCEPT block.
* Warning: inside a __TRY or __EXCEPT block, 'break' or 'continue' statements
* break out of the current block. 'return' causes disaster and must
* never be used.
*
* -- AJ
*/
#define __TRY() \
do { __WINE_FRAME __f; int __state = -1; \
while (__state != 2) switch(__state) \
{ case 0:
/* try */
/* Define this if you want to use your compiler built-in __try/__except support.
* This is only useful when compiling to a native Windows binary, as the built-in
* compiler exceptions will most certainly not work under Winelib.
*/
#ifdef USE_COMPILER_EXCEPTIONS
#define __TRY __try
#define __EXCEPT(func,arg) __except((func)(GetExceptionInformation(),GetExceptionCode(),(arg)))
#define __FINALLY(func,arg) __finally { (func)(!AbnormalTermination(),(arg)); }
#define __ENDTRY
/*nothing*/
#else
/* USE_COMPILER_EXCEPTIONS */
#define __TRY \
do { __WINE_FRAME __f; \
int __first = 1; \
for (;;) if (!__first) \
{ \
do {
#define __EXCEPT(func,arg) \
__state = 2; break; \
case -1:
/* init */
\
__f.frame.Handler = (PEXCEPTION_HANDLER)WINE_exception_handler; \
__f.u.e.filter = (func); \
__f.u.e.param = (LPVOID)(arg); \
EXC_push_frame( &__f.frame ); \
__state = setjmp( __f.u.e.jmp); \
break; \
case 1:
/* except */
#define __ENDTRY() \
__state++; break; \
} \
EXC_pop_frame( &__f.frame ); \
} while(0); \
EXC_pop_frame( &__f.frame ); \
break; \
} else { \
__f.frame.Handler = (PEXCEPTION_HANDLER)WINE_exception_handler; \
__f.u.e.filter = (func); \
__f.u.e.param = (LPVOID)(arg); \
EXC_push_frame( &__f.frame ); \
if (setjmp( __f.u.e.jmp)) { \
EXC_pop_frame( &__f.frame ); \
do {
#define __ENDTRY \
} while (0); \
break; \
} \
__first = 0; \
} \
} while (0);
#define __FINALLY(func,arg) \
__state = 2; break; \
case -1:
/* init */
\
__f.frame.Handler = (PEXCEPTION_HANDLER)WINE_finally_handler; \
__f.u.f.finally_func = (func); \
__f.u.f.param = (LPVOID)(arg); \
EXC_push_frame( &__f.frame ); \
__ENDTRY()
} while(0); \
EXC_pop_frame( &__f.frame ); \
(func)( TRUE, (LPVOID)(arg) ); \
break; \
} else { \
__f.frame.Handler = (PEXCEPTION_HANDLER)WINE_finally_handler; \
__f.u.f.finally_func = (func); \
__f.u.f.param = (LPVOID)(arg); \
EXC_push_frame( &__f.frame ); \
__first = 0; \
} \
} while (0);
#define WINE_EXCEPTION_FILTER(func,arg) DWORD WINAPI func( EXCEPTION_POINTERS *__eptr, LPVOID arg )
#define WINE_FINALLY_FUNC(func,arg) void WINAPI func( LPVOID arg )
#define GetExceptionInformation() (__eptr)
#define GetExceptionCode() (__eptr->ExceptionRecord->ExceptionCode)
/* Dummy structure for using GetExceptionCode in filter as well as in handler */
typedef
struct
{
union
{
struct
{
DWORD
code
;
}
e
;
}
u
;
}
__WINE_DUMMY_FRAME
;
typedef
DWORD
(
*
CALLBACK
__WINE_FILTER
)(
PEXCEPTION_POINTERS
,
__WINE_DUMMY_FRAME
,
LPVOID
);
typedef
void
(
*
CALLBACK
__WINE_FINALLY
)(
BOOL
,
LPVOID
);
#define WINE_EXCEPTION_FILTER(func,arg) \
DWORD WINAPI func( EXCEPTION_POINTERS *__eptr, __WINE_DUMMY_FRAME __f, LPVOID arg )
#define WINE_FINALLY_FUNC(func,arg) \
void WINAPI func( BOOL __normal, LPVOID arg )
typedef
DWORD
(
*
CALLBACK
__WINE_FILTER
)(
PEXCEPTION_POINTERS
,
LPVOID
);
typedef
void
(
*
CALLBACK
__WINE_FINALLY
)(
LPVOID
);
#define GetExceptionInformation() (__eptr)
#define GetExceptionCode() (__f.u.e.code)
#define AbnormalTermination() (!__normal)
typedef
struct
{
...
...
@@ -96,6 +130,7 @@ typedef struct
{
__WINE_FILTER
filter
;
LPVOID
param
;
DWORD
code
;
jmp_buf
jmp
;
}
e
;
struct
/* finally data */
...
...
@@ -111,18 +146,36 @@ extern DWORD WINAPI WINE_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_
extern
DWORD
WINAPI
WINE_finally_handler
(
PEXCEPTION_RECORD
record
,
EXCEPTION_FRAME
*
frame
,
CONTEXT
*
context
,
LPVOID
pdispatcher
);
#endif
/* USE_COMPILER_EXCEPTIONS */
static
inline
EXCEPTION_FRAME
*
EXC_push_frame
(
EXCEPTION_FRAME
*
frame
)
{
#if defined(__GNUC__) && defined(__i386__)
EXCEPTION_FRAME
*
prev
;
__asm__
__volatile__
(
".byte 0x64
\n\t
movl (0),%0"
"
\n\t
movl %0,(%1)"
"
\n\t
.byte 0x64
\n\t
movl %1,(0)"
:
"=&r"
(
prev
)
:
"r"
(
frame
)
:
"memory"
);
return
prev
;
#else
TEB
*
teb
=
NtCurrentTeb
();
frame
->
Prev
=
teb
->
except
;
teb
->
except
=
frame
;
return
frame
;
return
frame
->
Prev
;
#endif
}
static
inline
EXCEPTION_FRAME
*
EXC_pop_frame
(
EXCEPTION_FRAME
*
frame
)
{
#if defined(__GNUC__) && defined(__i386__)
__asm__
__volatile__
(
".byte 0x64
\n\t
movl %0,(0)"
:
:
"r"
(
frame
->
Prev
)
:
"memory"
);
return
frame
->
Prev
;
#else
NtCurrentTeb
()
->
except
=
frame
->
Prev
;
return
frame
->
Prev
;
#endif
}
#endif
/* __WINE_WINE_EXCEPTION_H */
This diff is collapsed.
Click to expand it.
win32/except.c
+
8
−
5
View file @
0691998e
...
...
@@ -110,14 +110,17 @@ DWORD WINAPI WINE_exception_handler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *
{
__WINE_FRAME
*
wine_frame
=
(
__WINE_FRAME
*
)
frame
;
if
(
record
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
))
if
(
record
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
|
EH_NESTED_CALL
))
return
ExceptionContinueSearch
;
if
(
wine_frame
->
u
.
e
.
filter
)
{
EXCEPTION_POINTERS
ptrs
;
__WINE_DUMMY_FRAME
dummy
;
ptrs
.
ExceptionRecord
=
record
;
ptrs
.
ContextRecord
=
context
;
switch
(
wine_frame
->
u
.
e
.
filter
(
&
ptrs
,
wine_frame
->
u
.
e
.
param
))
dummy
.
u
.
e
.
code
=
record
->
ExceptionCode
;
switch
(
wine_frame
->
u
.
e
.
filter
(
&
ptrs
,
dummy
,
wine_frame
->
u
.
e
.
param
))
{
case
EXCEPTION_CONTINUE_SEARCH
:
return
ExceptionContinueSearch
;
...
...
@@ -126,8 +129,8 @@ DWORD WINAPI WINE_exception_handler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *
case
EXCEPTION_EXECUTE_HANDLER
:
break
;
default:
/* FIXME: should probably raise a nested exception here */
return
ExceptionContinueSearch
;
MESSAGE
(
"Invalid return value from exception filter
\n
"
);
assert
(
FALSE
)
;
}
}
RtlUnwind
(
frame
,
0
,
record
,
0
);
...
...
@@ -147,6 +150,6 @@ DWORD WINAPI WINE_finally_handler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *fr
if
(
!
(
record
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
)))
return
ExceptionContinueSearch
;
wine_frame
->
u
.
f
.
finally_func
(
wine_frame
->
u
.
f
.
param
);
wine_frame
->
u
.
f
.
finally_func
(
FALSE
,
wine_frame
->
u
.
f
.
param
);
return
ExceptionContinueSearch
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment