Bug #4438 ยป 0001-check-rescue-clause-arguments.patch
compile.c | ||
---|---|---|
case NODE_ARGSPUSH:
|
||
only_special_literals = 0;
|
||
COMPILE(cond_seq, "when/cond splat", vals);
|
||
ADD_INSN1(cond_seq, nd_line(vals), checkincludearray, Qtrue);
|
||
ADD_INSN1(cond_seq, nd_line(vals), checkincludearray, INT2FIX(0));
|
||
ADD_INSNL(cond_seq, nd_line(vals), branchif, l1);
|
||
break;
|
||
default:
|
||
... | ... | |
case NODE_ARGSPUSH:
|
||
ADD_INSN(ret, nd_line(vals), putnil);
|
||
COMPILE(ret, "when2/cond splat", vals);
|
||
ADD_INSN1(ret, nd_line(vals), checkincludearray, Qfalse);
|
||
ADD_INSN1(ret, nd_line(vals), checkincludearray, INT2FIX(1));
|
||
ADD_INSN(ret, nd_line(vals), pop);
|
||
ADD_INSNL(ret, nd_line(vals), branchif, l1);
|
||
break;
|
||
... | ... | |
switch (nd_type(narg)) {
|
||
case NODE_ARRAY:
|
||
while (narg) {
|
||
ADD_INSN1(ret, nd_line(narg), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
|
||
COMPILE(ret, "rescue arg", narg->nd_head);
|
||
ADD_SEND(ret, nd_line(narg), ID2SYM(id_core_check_rescuable), INT2FIX(1));
|
||
ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
|
||
ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
|
||
ADD_INSNL(ret, nd_line(node), branchif, label_hit);
|
||
... | ... | |
case NODE_ARGSPUSH:
|
||
ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
|
||
COMPILE(ret, "rescue/cond splat", narg);
|
||
ADD_INSN1(ret, nd_line(node), checkincludearray, Qtrue);
|
||
ADD_INSN1(ret, nd_line(node), checkincludearray, INT2FIX(2));
|
||
ADD_INSN(ret, nd_line(node), swap);
|
||
ADD_INSN(ret, nd_line(node), pop);
|
||
ADD_INSNL(ret, nd_line(node), branchif, label_hit);
|
id.c | ||
---|---|---|
REGISTER_SYMID(id_core_hash_merge_ary, "core#hash_merge_ary");
|
||
REGISTER_SYMID(id_core_hash_merge_ptr, "core#hash_merge_ptr");
|
||
REGISTER_SYMID(id_core_hash_merge_kwd, "core#hash_merge_kwd");
|
||
REGISTER_SYMID(id_core_check_rescuable, "core#check_rescuable");
|
||
REGISTER_SYMID(idEach, "each");
|
||
REGISTER_SYMID(idLength, "length");
|
insns.def | ||
---|---|---|
ary = rb_Array(ary);
|
||
}
|
||
if (flag == Qtrue) {
|
||
switch (flag) {
|
||
case INT2FIX(0):
|
||
/* NODE_CASE */
|
||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||
/* TODO: fix me (use another method dispatch) */
|
||
... | ... | |
break;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
break;
|
||
case INT2FIX(1):
|
||
obj = Qfalse;
|
||
/* NODE_WHEN */
|
||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||
... | ... | |
break;
|
||
}
|
||
}
|
||
break;
|
||
case INT2FIX(2):
|
||
/* NODE_RESBODY */
|
||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||
void rb_vm_error_invalid_rescue(VALUE);
|
||
VALUE mod = RARRAY_PTR(ary)[i];
|
||
if (!rb_obj_is_kind_of(mod, rb_cModule)) {
|
||
rb_vm_error_invalid_rescue(mod);
|
||
}
|
||
if (RTEST(rb_funcall2(mod, idEqq, 1, &obj))) {
|
||
result = Qtrue;
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
parse.y | ||
---|---|---|
%nonassoc id_core_hash_merge_ary
|
||
%nonassoc id_core_hash_merge_ptr
|
||
%nonassoc id_core_hash_merge_kwd
|
||
%nonassoc id_core_check_rescuable
|
||
%token tLAST_TOKEN
|
||
test/ruby/test_exception.rb | ||
---|---|---|
end
|
||
end
|
||
Bug4438 = '[ruby-core:35364]'
|
||
def test_rescue_single_argument
|
||
assert_raise(TypeError, Bug4438) do
|
||
begin
|
||
raise
|
||
rescue 1
|
||
end
|
||
end
|
||
end
|
||
def test_rescue_splat_argument
|
||
assert_raise(TypeError, Bug4438) do
|
||
begin
|
||
raise
|
||
rescue *Array(1)
|
||
end
|
||
end
|
||
end
|
||
def test_raise_with_wrong_number_of_arguments
|
||
assert_raise(TypeError) { raise nil }
|
||
assert_raise(TypeError) { raise 1, 1 }
|
vm.c | ||
---|---|---|
return hash;
|
||
}
|
||
void
|
||
rb_vm_error_invalid_rescue(VALUE mod)
|
||
{
|
||
rb_raise(rb_eTypeError, "class or module required for rescue clause");
|
||
}
|
||
static VALUE
|
||
m_core_check_rescuable(VALUE recv, VALUE mod)
|
||
{
|
||
if (!rb_obj_is_kind_of(mod, rb_cModule)) {
|
||
vm_pop_frame(GET_THREAD());
|
||
rb_vm_error_invalid_rescue(mod);
|
||
}
|
||
return mod;
|
||
}
|
||
extern VALUE *rb_gc_stack_start;
|
||
extern size_t rb_gc_stack_maxsize;
|
||
#ifdef __ia64
|
||
... | ... | |
rb_define_method_id(klass, id_core_hash_merge_ary, m_core_hash_merge_ary, 2);
|
||
rb_define_method_id(klass, id_core_hash_merge_ptr, m_core_hash_merge_ptr, -1);
|
||
rb_define_method_id(klass, id_core_hash_merge_kwd, m_core_hash_merge_kwd, 2);
|
||
rb_define_method_id(klass, id_core_check_rescuable, m_core_check_rescuable, 1);
|
||
rb_obj_freeze(fcore);
|
||
rb_gc_register_mark_object(fcore);
|
||
rb_mRubyVMFrozenCore = fcore;
|