aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-18 10:52:19 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-18 10:52:19 +0000
commite9e08a5b105a3ea8ea54a856e977376d2dcd1ab9 (patch)
tree8fa38993784c982e7177cbff014ff26bdc8e0037 /gc.c
parentca5cfbe1ab76588420ef73b2d445e329352fde5f (diff)
downloadruby-e9e08a5b105a3ea8ea54a856e977376d2dcd1ab9.tar.gz
gc.c: reduce EXEC_TAGs
* gc.c (run_finalizer): set and restore safe level here to reduce nested EXEC_TAGs. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/gc.c b/gc.c
index 2bb5f7a5b0..195be83ec6 100644
--- a/gc.c
+++ b/gc.c
@@ -2551,34 +2551,32 @@ static VALUE
run_single_final(VALUE arg)
{
VALUE *args = (VALUE *)arg;
- rb_eval_cmd(args[0], args[1], (int)args[2]);
- return Qnil;
+
+ return rb_check_funcall(args[0], idCall, 1, args+1);
}
static void
run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
{
long i;
- int status;
- VALUE args[3];
- VALUE objid = nonspecial_obj_id(obj);
+ VALUE args[2];
+ const int safe = rb_safe_level();
+ const VALUE errinfo = rb_errinfo();
- if (RARRAY_LEN(table) > 0) {
- args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
- }
- else {
- args[1] = 0;
- }
+ args[1] = nonspecial_obj_id(obj);
- args[2] = (VALUE)rb_safe_level();
for (i=0; i<RARRAY_LEN(table); i++) {
- VALUE final = RARRAY_AREF(table, i);
- args[0] = RARRAY_AREF(final, 1);
- args[2] = FIX2INT(RARRAY_AREF(final, 0));
- status = 0;
+ const VALUE final = RARRAY_AREF(table, i);
+ const VALUE cmd = RARRAY_AREF(final, 1);
+ const int level = OBJ_TAINTED(cmd) ?
+ RUBY_SAFE_LEVEL_MAX : FIX2INT(RARRAY_AREF(final, 0));
+ int status = 0;
+
+ args[0] = cmd;
+ rb_set_safe_level_force(level);
rb_protect(run_single_final, (VALUE)args, &status);
- if (status)
- rb_set_errinfo(Qnil);
+ rb_set_safe_level_force(safe);
+ rb_set_errinfo(errinfo);
}
}