summaryrefslogtreecommitdiffstats
path: root/libgo/runtime/go-recover.c
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-03 04:34:57 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-03 04:34:57 +0000
commite440a3286bc89368b8d3a8fd6accd47191790bf2 (patch)
tree38fe54a4f38ede5d949c915d66191f24a6fe5153 /libgo/runtime/go-recover.c
parenta641ee368e2614349084a9a7bda2ec2b0b2bc1cf (diff)
downloadppe42-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.c69
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;
+}
OpenPOWER on IntegriCloud