Ruby
1.9.3p448(2013-06-27revision41675)
Main Page
Modules
Data Structures
Files
File List
Globals
eval_jump.c
Go to the documentation of this file.
1
/* -*-c-*- */
2
/*
3
* from eval.c
4
*/
5
6
#include "
eval_intern.h
"
7
8
/* exit */
9
10
void
11
rb_call_end_proc
(
VALUE
data)
12
{
13
rb_proc_call
(data,
rb_ary_new
());
14
}
15
16
/*
17
* call-seq:
18
* at_exit { block } -> proc
19
*
20
* Converts _block_ to a +Proc+ object (and therefore
21
* binds it at the point of call) and registers it for execution when
22
* the program exits. If multiple handlers are registered, they are
23
* executed in reverse order of registration.
24
*
25
* def do_at_exit(str1)
26
* at_exit { print str1 }
27
* end
28
* at_exit { puts "cruel world" }
29
* do_at_exit("goodbye ")
30
* exit
31
*
32
* <em>produces:</em>
33
*
34
* goodbye cruel world
35
*/
36
37
static
VALUE
38
rb_f_at_exit
(
void
)
39
{
40
VALUE
proc;
41
42
if
(!
rb_block_given_p
()) {
43
rb_raise
(
rb_eArgError
,
"called without a block"
);
44
}
45
proc =
rb_block_proc
();
46
rb_set_end_proc
(
rb_call_end_proc
, proc);
47
return
proc;
48
}
49
50
struct
end_proc_data
{
51
void (*
func
) ();
52
VALUE
data
;
53
int
safe
;
54
struct
end_proc_data
*
next
;
55
};
56
57
static
struct
end_proc_data
*
end_procs
, *
ephemeral_end_procs
;
58
59
void
60
rb_set_end_proc
(
void
(*
func
)(
VALUE
),
VALUE
data
)
61
{
62
struct
end_proc_data
*
link
=
ALLOC
(
struct
end_proc_data
);
63
struct
end_proc_data
**
list
;
64
rb_thread_t
*th =
GET_THREAD
();
65
66
if
(th->
top_wrapper
) {
67
list = &
ephemeral_end_procs
;
68
}
69
else
{
70
list = &
end_procs
;
71
}
72
link->
next
= *
list
;
73
link->
func
=
func
;
74
link->
data
=
data
;
75
link->
safe
=
rb_safe_level
();
76
*list =
link
;
77
}
78
79
void
80
rb_mark_end_proc
(
void
)
81
{
82
struct
end_proc_data
*
link
;
83
84
link =
end_procs
;
85
while
(link) {
86
rb_gc_mark
(link->
data
);
87
link = link->
next
;
88
}
89
link =
ephemeral_end_procs
;
90
while
(link) {
91
rb_gc_mark
(link->
data
);
92
link = link->
next
;
93
}
94
}
95
96
void
97
rb_exec_end_proc
(
void
)
98
{
99
struct
end_proc_data
*
volatile
link
;
100
int
status;
101
volatile
int
safe
=
rb_safe_level
();
102
rb_thread_t
*th =
GET_THREAD
();
103
VALUE
errinfo = th->
errinfo
;
104
105
while
(ephemeral_end_procs) {
106
link =
ephemeral_end_procs
;
107
ephemeral_end_procs = link->
next
;
108
109
PUSH_TAG
();
110
if
((status =
EXEC_TAG
()) == 0) {
111
rb_set_safe_level_force
(link->
safe
);
112
(*link->
func
) (link->
data
);
113
}
114
POP_TAG
();
115
if
(status) {
116
error_handle
(status);
117
if
(!
NIL_P
(th->
errinfo
)) errinfo = th->
errinfo
;
118
}
119
xfree
(link);
120
}
121
122
while
(end_procs) {
123
link =
end_procs
;
124
end_procs = link->
next
;
125
126
PUSH_TAG
();
127
if
((status =
EXEC_TAG
()) == 0) {
128
rb_set_safe_level_force
(link->
safe
);
129
(*link->
func
) (link->
data
);
130
}
131
POP_TAG
();
132
if
(status) {
133
error_handle
(status);
134
if
(!
NIL_P
(th->
errinfo
)) errinfo = th->
errinfo
;
135
}
136
xfree
(link);
137
}
138
rb_set_safe_level_force
(safe);
139
th->
errinfo
= errinfo;
140
}
141
142
void
143
Init_jump
(
void
)
144
{
145
rb_define_global_function
(
"at_exit"
,
rb_f_at_exit
, 0);
146
}
147
Generated on Fri Jun 28 2013 02:34:31 for Ruby by
1.8.3