From 67f4e73a55784998702fe6c37479e23a9b73b2c7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 15 Apr 2022 16:54:36 -0700 Subject: [PATCH] Add InstructionSequence#type method This method returns a symbol representing the type of the instruction sequence object. --- iseq.c | 22 ++++++++++++++++++++++ test/ruby/test_iseq.rb | 7 +++++++ 2 files changed, 29 insertions(+) diff --git a/iseq.c b/iseq.c index 129d6d3b2c..5e80dcb0db 100644 --- a/iseq.c +++ b/iseq.c @@ -1624,6 +1624,27 @@ iseqw_inspect(VALUE self) } } +static VALUE +iseqw_type(VALUE self) +{ + const rb_iseq_t *iseq = iseqw_check(self); + const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); + + switch(body->type) { +#define CASE_TYPE(t) case ISEQ_TYPE_ ## t: return ID2SYM(rb_intern(#t)); break; + CASE_TYPE(TOP); + CASE_TYPE(METHOD); + CASE_TYPE(BLOCK); + CASE_TYPE(CLASS); + CASE_TYPE(RESCUE); + CASE_TYPE(ENSURE); + CASE_TYPE(EVAL); + CASE_TYPE(MAIN); + CASE_TYPE(PLAIN); +#undef CASE_TYPE + } +} + /* * Returns the path of this instruction sequence. * @@ -3915,6 +3936,7 @@ Init_ISeq(void) rb_cISeq = rb_define_class_under(rb_cRubyVM, "InstructionSequence", rb_cObject); rb_undef_alloc_func(rb_cISeq); rb_define_method(rb_cISeq, "inspect", iseqw_inspect, 0); + rb_define_method(rb_cISeq, "type", iseqw_type, 0); rb_define_method(rb_cISeq, "disasm", iseqw_disasm, 0); rb_define_method(rb_cISeq, "disassemble", iseqw_disasm, 0); rb_define_method(rb_cISeq, "to_a", iseqw_to_a, 0); diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index 2a18ff02e1..53c4d40bc7 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -167,6 +167,13 @@ def obj.foo(*) nil.instance_eval{ ->{super} } end end end + def test_type + iseq = RubyVM::InstructionSequence.of(method(__method__)) + assert_equal :METHOD, iseq.type + iseq = RubyVM::InstructionSequence.of(->() { }) + assert_equal :BLOCK, iseq.type + end + def test_disasm_encoding src = "\u{3042} = 1; \u{3042}; \u{3043}" asm = compile(src).disasm -- 2.36.0