Ruby
1.9.3p551(2014-11-13revision48407)
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 endproc;
100
struct
end_proc_data
volatile *
link
;
101
int
status;
102
volatile
int
safe
=
rb_safe_level
();
103
rb_thread_t
*th =
GET_THREAD
();
104
VALUE
errinfo = th->
errinfo
;
105
106
while
(ephemeral_end_procs) {
107
link =
ephemeral_end_procs
;
108
ephemeral_end_procs = link->
next
;
109
endproc = *
link
;
110
xfree
((
void
*)link);
111
link = &endproc;
112
113
PUSH_TAG
();
114
if
((status =
EXEC_TAG
()) == 0) {
115
rb_set_safe_level_force
(link->
safe
);
116
(*link->
func
) (link->
data
);
117
}
118
POP_TAG
();
119
if
(status) {
120
error_handle
(status);
121
if
(!
NIL_P
(th->
errinfo
)) errinfo = th->
errinfo
;
122
}
123
}
124
125
while
(end_procs) {
126
link =
end_procs
;
127
end_procs = link->
next
;
128
endproc = *
link
;
129
xfree
((
void
*)link);
130
link = &endproc;
131
132
PUSH_TAG
();
133
if
((status =
EXEC_TAG
()) == 0) {
134
rb_set_safe_level_force
(link->
safe
);
135
(*link->
func
) (link->
data
);
136
}
137
POP_TAG
();
138
if
(status) {
139
error_handle
(status);
140
if
(!
NIL_P
(th->
errinfo
)) errinfo = th->
errinfo
;
141
}
142
}
143
144
rb_set_safe_level_force
(safe);
145
th->
errinfo
= errinfo;
146
}
147
148
void
149
Init_jump
(
void
)
150
{
151
rb_define_global_function
(
"at_exit"
,
rb_f_at_exit
, 0);
152
}
153
Generated on Fri Nov 14 2014 16:03:52 for Ruby by
1.8.3