diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-03 04:34:57 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-03 04:34:57 +0000 |
commit | e440a3286bc89368b8d3a8fd6accd47191790bf2 (patch) | |
tree | 38fe54a4f38ede5d949c915d66191f24a6fe5153 /libgo/runtime/go-recover.c | |
parent | a641ee368e2614349084a9a7bda2ec2b0b2bc1cf (diff) | |
download | ppe42-gcc-e440a3286bc89368b8d3a8fd6accd47191790bf2.tar.gz ppe42-gcc-e440a3286bc89368b8d3a8fd6accd47191790bf2.zip |
Add Go frontend, libgo library, and Go testsuite.
gcc/:
* gcc.c (default_compilers): Add entry for ".go".
* common.opt: Add -static-libgo as a driver option.
* doc/install.texi (Configuration): Mention libgo as an option for
--enable-shared. Mention go as an option for --enable-languages.
* doc/invoke.texi (Overall Options): Mention .go as a file name
suffix. Mention go as a -x option.
* doc/frontends.texi (G++ and GCC): Mention Go as a supported
language.
* doc/sourcebuild.texi (Top Level): Mention libgo.
* doc/standards.texi (Standards): Add section on Go language.
Move references for other languages into their own section.
* doc/contrib.texi (Contributors): Mention that I contributed the
Go frontend.
gcc/testsuite/:
* lib/go.exp: New file.
* lib/go-dg.exp: New file.
* lib/go-torture.exp: New file.
* lib/target-supports.exp (check_compile): Match // Go.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167407 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/runtime/go-recover.c')
-rw-r--r-- | libgo/runtime/go-recover.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/libgo/runtime/go-recover.c b/libgo/runtime/go-recover.c new file mode 100644 index 00000000000..4de122e3b3e --- /dev/null +++ b/libgo/runtime/go-recover.c @@ -0,0 +1,69 @@ +/* go-recover.c -- support for the go recover function. + + Copyright 2010 The Go Authors. All rights reserved. + Use of this source code is governed by a BSD-style + license that can be found in the LICENSE file. */ + +#include "interface.h" +#include "go-panic.h" +#include "go-defer.h" + +/* This is called by a thunk to see if the real function should be + permitted to recover a panic value. Recovering a value is + permitted if the thunk was called directly by defer. RETADDR is + the return address of the function which is calling + __go_can_recover--this is, the thunk. */ + +_Bool +__go_can_recover (const void* retaddr) +{ + struct __go_defer_stack *d; + const char* ret; + const char* dret; + + if (__go_panic_defer == NULL) + return 0; + d = __go_panic_defer->__defer; + if (d == NULL) + return 0; + + /* The panic which this function would recover is the one on the top + of the panic stack. We do not want to recover it if that panic + was on the top of the panic stack when this function was + deferred. */ + if (d->__panic == __go_panic_defer->__panic) + return 0; + + /* D->__RETADDR is the address of a label immediately following the + call to the thunk. We can recover a panic if that is the same as + the return address of the thunk. We permit a bit of slack in + case there is any code between the function return and the label, + such as an instruction to adjust the stack pointer. */ + + ret = (const char *) retaddr; + dret = (const char *) d->__retaddr; + return ret <= dret && ret + 16 >= dret; +} + +/* This is only called when it is valid for the caller to recover the + value on top of the panic stack, if there is one. */ + +struct __go_empty_interface +__go_recover () +{ + struct __go_panic_stack *p; + + if (__go_panic_defer == NULL + || __go_panic_defer->__panic == NULL + || __go_panic_defer->__panic->__was_recovered) + { + struct __go_empty_interface ret; + + ret.__type_descriptor = NULL; + ret.__object = NULL; + return ret; + } + p = __go_panic_defer->__panic; + p->__was_recovered = 1; + return p->__arg; +} |