Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / runtime / go-defer.c
blob6425f0586a75df7d4c8fb8e46e41d4d55a0d2ba8
1 /* go-defer.c -- manage the defer stack.
3 Copyright 2009 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
7 #include <stddef.h>
9 #include "go-alloc.h"
10 #include "go-panic.h"
11 #include "go-defer.h"
13 /* This function is called each time we need to defer a call. */
15 void
16 __go_defer (void *frame, void (*pfn) (void *), void *arg)
18 struct __go_defer_stack *n;
20 if (__go_panic_defer == NULL)
21 __go_panic_defer = ((struct __go_panic_defer_struct *)
22 __go_alloc (sizeof (struct __go_panic_defer_struct)));
24 n = (struct __go_defer_stack *) __go_alloc (sizeof (struct __go_defer_stack));
25 n->__next = __go_panic_defer->__defer;
26 n->__frame = frame;
27 n->__panic = __go_panic_defer->__panic;
28 n->__pfn = pfn;
29 n->__arg = arg;
30 n->__retaddr = NULL;
31 __go_panic_defer->__defer = n;
34 /* This function is called when we want to undefer the stack. */
36 void
37 __go_undefer (void *frame)
39 if (__go_panic_defer == NULL)
40 return;
41 while (__go_panic_defer->__defer != NULL
42 && __go_panic_defer->__defer->__frame == frame)
44 struct __go_defer_stack *d;
45 void (*pfn) (void *);
47 d = __go_panic_defer->__defer;
48 pfn = d->__pfn;
49 d->__pfn = NULL;
51 if (pfn != NULL)
52 (*pfn) (d->__arg);
54 __go_panic_defer->__defer = d->__next;
55 __go_free (d);
59 /* This function is called to record the address to which the deferred
60 function returns. This may in turn be checked by __go_can_recover.
61 The frontend relies on this function returning false. */
63 _Bool
64 __go_set_defer_retaddr (void *retaddr)
66 if (__go_panic_defer != NULL && __go_panic_defer->__defer != NULL)
67 __go_panic_defer->__defer->__retaddr = retaddr;
68 return 0;