Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
e976b8b2
Commit
e976b8b2
authored
Apr 23, 1997
by
Mike Stump
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add setjmp/longjmp exception handling.
From-SVN: r13968
parent
2284f91b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
262 additions
and
50 deletions
+262
-50
gcc/calls.c
+3
-21
gcc/except.h
+54
-10
gcc/expr.c
+0
-0
gcc/expr.h
+6
-9
gcc/flags.h
+0
-4
gcc/function.h
+2
-1
gcc/libgcc2.c
+166
-0
gcc/stmt.c
+0
-0
gcc/toplev.c
+2
-4
gcc/tree.def
+22
-1
gcc/tree.h
+7
-0
No files found.
gcc/calls.c
View file @
e976b8b2
...
...
@@ -590,7 +590,6 @@ expand_call (exp, target, ignore)
int
old_pending_adj
=
0
;
int
old_stack_arg_under_construction
;
int
old_inhibit_defer_pop
=
inhibit_defer_pop
;
tree
old_cleanups
=
cleanups_this_call
;
rtx
call_fusage
=
0
;
register
tree
p
;
register
int
i
,
j
;
...
...
@@ -720,17 +719,6 @@ expand_call (exp, target, ignore)
/* If inlining succeeded, return. */
if
((
HOST_WIDE_INT
)
temp
!=
-
1
)
{
if
(
flag_short_temps
)
{
/* Perform all cleanups needed for the arguments of this
call (i.e. destructors in C++). It is ok if these
destructors clobber RETURN_VALUE_REG, because the
only time we care about this is when TARGET is that
register. But in C++, we take care to never return
that register directly. */
expand_cleanups_to
(
old_cleanups
);
}
#ifdef ACCUMULATE_OUTGOING_ARGS
/* If the outgoing argument list must be preserved, push
the stack before executing the inlined function if it
...
...
@@ -1979,8 +1967,9 @@ expand_call (exp, target, ignore)
/* If value type not void, return an rtx for the value. */
/* If there are cleanups to be called, don't use a hard reg as target. */
if
(
cleanups_this_call
!=
old_cleanups
/* If there are cleanups to be called, don't use a hard reg as target.
We need to double check this and see if it matters anymore. */
if
(
any_pending_cleanups
()
&&
target
&&
REG_P
(
target
)
&&
REGNO
(
target
)
<
FIRST_PSEUDO_REGISTER
)
target
=
0
;
...
...
@@ -2153,13 +2142,6 @@ expand_call (exp, target, ignore)
}
#endif
if
(
flag_short_temps
)
{
/* Perform all cleanups needed for the arguments of this call
(i.e. destructors in C++). */
expand_cleanups_to
(
old_cleanups
);
}
/* If size of args is variable or this was a constructor call for a stack
argument, restore saved stack-pointer value. */
...
...
gcc/except.h
View file @
e976b8b2
...
...
@@ -82,8 +82,35 @@ struct eh_queue {
};
/* Start an exception handling region. All instructions emitted after
this point are considered to be part of the region until
expand_eh_region_end () is invoked. */
extern
void
expand_eh_region_start
PROTO
((
void
));
/* Start an exception handling region for the given cleanup action.
All instructions emitted after this point are considered to be part
of the region until expand_eh_region_end () is invoked. CLEANUP is
the cleanup action to perform. The return value is true if the
exception region was optimized away. If that case,
expand_eh_region_end does not need to be called for this cleanup,
nor should it be.
This routine notices one particular common case in C++ code
generation, and optimizes it so as to not need the exception
region. */
extern
int
expand_eh_region_start_tree
PROTO
((
tree
));
/* End an exception handling region. The information about the region
is found on the top of ehstack.
HANDLER is either the cleanup for the exception region, or if we're
marking the end of a try block, HANDLER is integer_zero_node.
HANDLER will be transformed to rtl when expand_leftover_cleanups ()
is invoked. */
extern
void
expand_eh_region_end
PROTO
((
tree
));
/* Push RLABEL or TLABEL onto LABELSTACK. Only one of RLABEL or TLABEL
...
...
@@ -101,16 +128,6 @@ extern rtx pop_label_entry PROTO((struct label_node **labelstack));
extern
tree
top_label_entry
PROTO
((
struct
label_node
**
labelstack
));
/* The stack used to keep track of the exception region corresponding to
the current instruction. */
extern
struct
eh_stack
ehstack
;
/* A queue used to track closed exception regions whose handlers have
not been emitted yet. */
extern
struct
eh_queue
ehqueue
;
/* A set of insns for the catch clauses in the current function. They
will be emitted at the end of the current function. */
...
...
@@ -233,3 +250,30 @@ extern rtx eh_saved_pc_rtx;
unnecessary exception regions. Invoked from jump_optimize (). */
extern
void
exception_optimize
PROTO
((
void
));
/* Get the dynamic handler chain. */
extern
rtx
get_dynamic_handler_chain
PROTO
((
void
));
/* Get the dynamic cleanup chain. */
extern
rtx
get_dynamic_cleanup_chain
PROTO
((
void
));
/* Throw an exception. */
extern
void
emit_throw
PROTO
((
void
));
/* One to use setjmp/longjmp method of generating code. */
extern
int
exceptions_via_longjmp
;
/* One to enable asynchronous exception support. */
extern
int
asynchronous_exceptions
;
/* One to protect cleanup actions with a handler that calls
__terminate, zero otherwise. */
extern
int
protect_cleanup_actions_with_terminate
;
#ifdef TREE_CODE
extern
tree
protect_with_terminate
PROTO
((
tree
));
#endif
gcc/expr.c
View file @
e976b8b2
This diff is collapsed.
Click to expand it.
gcc/expr.h
View file @
e976b8b2
...
...
@@ -108,12 +108,6 @@ extern tree nonlocal_labels;
These are the arguments to function calls that have already returned. */
extern
int
pending_stack_adjust
;
/* A list of all cleanups which belong to the arguments of
function calls being expanded by expand_call. */
#ifdef TREE_CODE
/* Don't lose if tree.h not included. */
extern
tree
cleanups_this_call
;
#endif
/* When temporaries are created by TARGET_EXPRs, they are created at
this level of temp_slot_level, so that they can remain allocated
until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
...
...
@@ -359,6 +353,12 @@ extern rtx memset_libfunc;
extern
rtx
bzero_libfunc
;
extern
rtx
throw_libfunc
;
extern
rtx
sjthrow_libfunc
;
extern
rtx
sjpopnthrow_libfunc
;
extern
rtx
terminate_libfunc
;
extern
rtx
setjmp_libfunc
;
extern
rtx
longjmp_libfunc
;
extern
rtx
get_dynamic_handler_chain_libfunc
;
extern
rtx
eqhf2_libfunc
;
extern
rtx
nehf2_libfunc
;
...
...
@@ -705,9 +705,6 @@ extern void clear_pending_stack_adjust PROTO((void));
extern
void
do_pending_stack_adjust
PROTO
((
void
));
#ifdef TREE_CODE
/* Expand all cleanups up to OLD_CLEANUPS. */
extern
void
expand_cleanups_to
PROTO
((
tree
));
/* Generate code to evaluate EXP and jump to LABEL if the value is zero. */
extern
void
jumpifnot
PROTO
((
tree
,
rtx
));
...
...
gcc/flags.h
View file @
e976b8b2
...
...
@@ -308,10 +308,6 @@ extern int flag_schedule_insns_after_reload;
extern
int
flag_delayed_branch
;
/* Nonzero means to run cleanups after CALL_EXPRs. */
extern
int
flag_short_temps
;
/* Nonzero means pretend it is OK to examine bits of target floats,
even if that isn't true. The resulting code will have incorrect constants,
but the same series of instructions that the native compiler would make. */
...
...
gcc/function.h
View file @
e976b8b2
...
...
@@ -135,11 +135,12 @@ struct function
struct
label_node
*
false_label_stack
;
struct
label_node
*
caught_return_label_stack
;
tree
protect_list
;
rtx
dhc
;
rtx
dcc
;
/* For expr.c. */
int
pending_stack_adjust
;
int
inhibit_defer_pop
;
tree
cleanups_this_call
;
rtx
saveregs_value
;
rtx
apply_args_value
;
rtx
forced_labels
;
...
...
gcc/libgcc2.c
View file @
e976b8b2
...
...
@@ -3102,6 +3102,172 @@ EH_TABLE_LOOKUP
#else
void
__default_terminate
()
{
abort
();
}
void
(
*
__terminate_func
)()
=
__default_terminate
;
void
__terminate
()
{
(
*
__terminate_func
)();
}
/* Calls to __sjthrow are generated by the compiler when an exception
is raised when using the setjmp/longjmp exception handling codegen
method. */
extern
longjmp
(
void
*
,
int
);
extern
void
*
__eh_type
;
static
void
*
top_elt
[
2
];
void
**
__dynamic_handler_chain
=
top_elt
;
/* Routine to get the head of the current thread's dynamic handler chain
use for exception handling.
TODO: make thread safe. */
void
***
__get_dynamic_handler_chain
()
{
return
&
__dynamic_handler_chain
;
}
/* This is used to throw an exception when the setjmp/longjmp codegen
method is used for exception handling.
We call __terminate if there are no handlers left (we know this
when the dynamic handler chain is top_elt). Otherwise we run the
cleanup actions off the dynamic cleanup stack, and pop the top of
the dynamic handler chain, and use longjmp to transfer back to the
associated handler. */
void
__sjthrow
()
{
void
***
dhc
=
__get_dynamic_handler_chain
();
void
*
jmpbuf
;
void
(
*
func
)(
void
*
,
int
);
void
*
arg
;
void
***
cleanup
;
/* The cleanup chain is one word into the buffer. Get the cleanup
chain. */
cleanup
=
(
void
***
)
&
(
*
dhc
)[
1
];
/* If there are any cleanups in the chain, run them now. */
if
(
cleanup
[
0
])
{
double
store
[
200
];
void
**
buf
=
(
void
**
)
store
;
buf
[
1
]
=
0
;
buf
[
0
]
=
(
*
dhc
);
/* try { */
if
(
!
setjmp
(
&
buf
[
2
]))
{
*
dhc
=
buf
;
while
(
cleanup
[
0
])
{
func
=
(
void
(
*
)(
void
*
,
int
))
cleanup
[
0
][
1
];
arg
=
(
void
*
)
cleanup
[
0
][
2
];
/* Update this before running the cleanup. */
cleanup
[
0
]
=
(
void
**
)
cleanup
[
0
][
0
];
(
*
func
)(
arg
,
2
);
}
*
dhc
=
buf
[
0
];
}
/* catch (...) */
else
{
__terminate
();
}
}
/* We must call terminate if we try and rethrow an exception, when
there is no exception currently active and when there are no
handlers left. */
if
(
!
__eh_type
||
(
*
dhc
)
==
top_elt
)
__terminate
();
/* Find the jmpbuf associated with the top element of the dynamic
handler chain. The jumpbuf starts two words into the buffer. */
jmpbuf
=
&
(
*
dhc
)[
2
];
/* Then we pop the top element off the dynamic handler chain. */
*
dhc
=
(
void
**
)(
*
dhc
)[
0
];
/* And then we jump to the handler. */
#ifdef USE_BUILTIN_SETJMP
__builtin_longjmp
(
jmpbuf
,
1
);
#else
longjmp
(
jmpbuf
,
1
);
#endif
}
/* Run cleanups on the dynamic cleanup stack for the current dynamic
handler, then pop the handler off the dynamic handler stack, and
then throw. This is used to skip the first handler, and transfer
control to the next handler in the dynamic handler stack. */
void
__sjpopnthrow
()
{
void
***
dhc
=
__get_dynamic_handler_chain
();
void
*
jmpbuf
;
void
(
*
func
)(
void
*
,
int
);
void
*
arg
;
void
***
cleanup
;
/* The cleanup chain is one word into the buffer. Get the cleanup
chain. */
cleanup
=
(
void
***
)
&
(
*
dhc
)[
1
];
/* If there are any cleanups in the chain, run them now. */
if
(
cleanup
[
0
])
{
double
store
[
200
];
void
**
buf
=
(
void
**
)
store
;
buf
[
1
]
=
0
;
buf
[
0
]
=
(
*
dhc
);
/* try { */
if
(
!
setjmp
(
&
buf
[
2
]))
{
*
dhc
=
buf
;
while
(
cleanup
[
0
])
{
func
=
(
void
(
*
)(
void
*
,
int
))
cleanup
[
0
][
1
];
arg
=
(
void
*
)
cleanup
[
0
][
2
];
/* Update this before running the cleanup. */
cleanup
[
0
]
=
(
void
**
)
cleanup
[
0
][
0
];
(
*
func
)(
arg
,
2
);
}
*
dhc
=
buf
[
0
];
}
/* catch (...) */
else
{
__terminate
();
}
}
/* Then we pop the top element off the dynamic handler chain. */
*
dhc
=
(
void
**
)(
*
dhc
)[
0
];
__sjthrow
();
}
typedef
struct
{
void
*
start
;
void
*
end
;
...
...
gcc/stmt.c
View file @
e976b8b2
This diff is collapsed.
Click to expand it.
gcc/toplev.c
View file @
e976b8b2
...
...
@@ -528,10 +528,6 @@ int flag_shared_data;
int
flag_delayed_branch
;
/* Nonzero means to run cleanups after CALL_EXPRs. */
int
flag_short_temps
;
/* Nonzero if we are compiling pure (sharable) code.
Value is 1 if we are doing reasonable (i.e. simple
offset into offset table) pic. Value is 2 if we can
...
...
@@ -646,6 +642,8 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{
"pic"
,
&
flag_pic
,
1
},
{
"PIC"
,
&
flag_pic
,
2
},
{
"exceptions"
,
&
flag_exceptions
,
1
},
{
"sjlj-exceptions"
,
&
exceptions_via_longjmp
,
1
},
{
"asynchronous-exceptions"
,
&
asynchronous_exceptions
,
1
},
{
"profile-arcs"
,
&
profile_arc_flag
,
1
},
{
"test-coverage"
,
&
flag_test_coverage
,
1
},
{
"branch-probabilities"
,
&
flag_branch_probabilities
,
1
},
...
...
gcc/tree.def
View file @
e976b8b2
...
...
@@ -458,7 +458,10 @@ DEFTREECODE (METHOD_CALL_EXPR, "method_call_expr", "e", 4)
manages to act on the proper value.
The cleanup is executed by the first enclosing CLEANUP_POINT_EXPR, if
it exists, otherwise it is the responsibility of the caller to manually
call expand_cleanups_to, as needed. */
call expand_start_target_temps/expand_end_target_temps, as needed.
This differs from TRY_CATCH_EXPR in that operand 2 is always
evaluated when an exception isn't throw when cleanups are run. */
DEFTREECODE (WITH_CLEANUP_EXPR, "with_cleanup_expr", "e", 3)
/* Specify a cleanup point.
...
...
@@ -689,6 +692,24 @@ DEFTREECODE (PREDECREMENT_EXPR, "predecrement_expr", "e", 2)
DEFTREECODE (PREINCREMENT_EXPR, "preincrement_expr", "e", 2)
DEFTREECODE (POSTDECREMENT_EXPR, "postdecrement_expr", "e", 2)
DEFTREECODE (POSTINCREMENT_EXPR, "postincrement_expr", "e", 2)
/* Evalute operand 1. If and only if an exception is thrown during
the evaluation of operand 1, evaluate operand 2.
This differs from WITH_CLEANUP_EXPR, in that operand 2 is never
evaluated unless an exception is throw. */
DEFTREECODE (TRY_CATCH_EXPR, "try_catch_expr", "e", 2)
/* Pop the top element off the dynamic handler chain. Used in
conjunction with setjmp/longjmp based exception handling, see
except.c for more details. This is meant to be used only by the
exception handling backend, expand_dhc_cleanup specifically. */
DEFTREECODE (POPDHC_EXPR, "popdhc_expr", "s", 0)
/* Pop the top element off the dynamic cleanup chain. Used in
conjunction with the exception handling. This is meant to be used
only by the exception handling backend. */
DEFTREECODE (POPDCC_EXPR, "popdcc_expr", "s", 0)
/* These types of expressions have no useful value,
and always have side effects. */
...
...
gcc/tree.h
View file @
e976b8b2
...
...
@@ -1690,7 +1690,14 @@ extern void expand_null_return PROTO((void));
extern
void
expand_return
PROTO
((
tree
));
extern
void
expand_start_bindings
PROTO
((
int
));
extern
void
expand_end_bindings
PROTO
((
tree
,
int
,
int
));
extern
void
start_cleanup_deferal
PROTO
((
void
));
extern
void
end_cleanup_deferal
PROTO
((
void
));
extern
void
mark_block_as_eh_region
PROTO
((
void
));
extern
void
mark_block_as_not_eh_region
PROTO
((
void
));
extern
int
is_eh_region
PROTO
((
void
));
extern
int
conditional_context
PROTO
((
void
));
extern
tree
last_cleanup_this_contour
PROTO
((
void
));
extern
int
expand_dhc_cleanup
PROTO
((
void
));
extern
void
expand_start_case
PROTO
((
int
,
tree
,
tree
,
char
*
));
extern
void
expand_end_case
PROTO
((
tree
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment