Project

General

Profile

Feature #13265 ยป 0001-Add-TracePoint-for-basic-operation-redefinition.patch

Patch for feature - magaudet (Matthew Gaudet), 03/01/2017 02:40 PM

View differences:

include/ruby/ruby.h
2056 2056
#define RUBY_EVENT_ALL       0x00ff
2057 2057

  
2058 2058
/* for TracePoint extended events */
2059
#define RUBY_EVENT_B_CALL            0x0100
2060
#define RUBY_EVENT_B_RETURN          0x0200
2061
#define RUBY_EVENT_THREAD_BEGIN      0x0400
2062
#define RUBY_EVENT_THREAD_END        0x0800
2063
#define RUBY_EVENT_FIBER_SWITCH      0x1000
2064
#define RUBY_EVENT_TRACEPOINT_ALL    0xffff
2059
#define RUBY_EVENT_B_CALL               0x0100
2060
#define RUBY_EVENT_B_RETURN             0x0200
2061
#define RUBY_EVENT_THREAD_BEGIN         0x0400
2062
#define RUBY_EVENT_THREAD_END           0x0800
2063
#define RUBY_EVENT_FIBER_SWITCH         0x1000
2064
#define RUBY_EVENT_BASIC_OP_REDEFINED   0x2000
2065
#define RUBY_EVENT_TRACEPOINT_ALL       0xffff
2065 2066

  
2066 2067
/* special events */
2067 2068
#define RUBY_EVENT_SPECIFIED_LINE         0x010000
test/ruby/test_settracefunc.rb
1599 1599
    assert_equal [[:c_call, :itself, :alias_itself], [:c_return, :itself, :alias_itself]], events
1600 1600
    events.clear
1601 1601
  end
1602

  
1603
  def test_basic_op_redefinition_tracepoint
1604
     events = []
1605
     TracePoint.new(:basic_op_redefined) { |tp|
1606
        next if !target_thread?
1607
        events << [tp.event, tp.basic_operation_redefined ]
1608
     }.enable { 
1609
     String.class_eval do 
1610
      def +(s)
1611
        self.concat(s)
1612
      end
1613
     end
1614
     }
1615
     assert_equal events.length, 1, "Events #{events}"
1616
     assert_equal events[0][0], :basic_op_redefined
1617
     assert_equal events[0][1][:klass], String
1618
     assert_equal events[0][1][:bop], :BOP_PLUS
1619
  end
1602 1620
end
vm.c
1483 1483
	    int flag = vm_redefinition_check_flag(klass);
1484 1484

  
1485 1485
	    ruby_vm_redefined_flag[bop] |= flag;
1486
	    EXEC_EVENT_HOOK(GET_THREAD(), RUBY_EVENT_BASIC_OP_REDEFINED, GET_THREAD()->cfp->self, 0, 0, klass, bop);
1486 1487
	}
1487 1488
    }
1488 1489
}
vm_trace.c
598 598
	C(thread_end, THREAD_END);
599 599
	C(fiber_switch, FIBER_SWITCH);
600 600
	C(specified_line, SPECIFIED_LINE);
601
        C(basic_op_redefined, BASIC_OP_REDEFINED);
601 602
      case RUBY_EVENT_LINE | RUBY_EVENT_SPECIFIED_LINE: CONST_ID(id, "line"); return id;
602 603
#undef C
603 604
      default:
......
706 707
    C(specified_line, SPECIFIED_LINE);
707 708
    C(a_call, A_CALL);
708 709
    C(a_return, A_RETURN);
710
    C(basic_op_redefined, BASIC_OP_REDEFINED);
709 711
#undef C
710 712
    rb_raise(rb_eArgError, "unknown event: %"PRIsVALUE, rb_sym2str(sym));
711 713
}
......
854 856
}
855 857

  
856 858
VALUE
859
rb_tracearg_basic_op_redefined(rb_trace_arg_t *trace_arg)
860
{
861
   const char * basic_operator_names[] = {
862
    "BOP_PLUS",
863
    "BOP_MINUS",
864
    "BOP_MULT",
865
    "BOP_DIV",
866
    "BOP_MOD",
867
    "BOP_EQ",
868
    "BOP_EQQ",
869
    "BOP_LT",
870
    "BOP_LE",
871
    "BOP_LTLT",
872
    "BOP_AREF",
873
    "BOP_ASET",
874
    "BOP_LENGTH",
875
    "BOP_SIZE",
876
    "BOP_EMPTY_P",
877
    "BOP_SUCC",
878
    "BOP_GT",
879
    "BOP_GE",
880
    "BOP_NOT",
881
    "BOP_NEQ",
882
    "BOP_MATCH",
883
    "BOP_FREEZE",
884
    "BOP_MAX",
885
    "BOP_MIN",
886
    NULL
887
   };
888

  
889
   VALUE bop, klass, hash;
890
   if (trace_arg->event & (RUBY_EVENT_BASIC_OP_REDEFINED)) {
891
      /* ok */
892
   }
893
   else {
894
      rb_raise(rb_eRuntimeError, "not supported by this event");
895
   }
896
   if (trace_arg->data == Qundef) {
897
      rb_bug("tp_basic_op_redefined_m: unreachable");
898
   }
899
   bop   = trace_arg->data;
900
   klass = trace_arg->klass;
901

  
902
   if (bop > BOP_LAST_) {
903
      rb_bug("rb_tracearg_basic_op_redefined: Invalid bop %d", bop);
904
   }
905

  
906
   hash  = rb_hash_new();
907
   rb_hash_aset(hash, ID2SYM(rb_intern("klass")),klass);
908
   rb_hash_aset(hash, ID2SYM(rb_intern("bop")), ID2SYM(rb_intern(basic_operator_names[bop])));
909
   return hash;
910
}
911

  
912

  
913
VALUE
857 914
rb_tracearg_raised_exception(rb_trace_arg_t *trace_arg)
858 915
{
859 916
    if (trace_arg->event & (RUBY_EVENT_RAISE)) {
......
1009 1066
    return rb_tracearg_raised_exception(get_trace_arg());
1010 1067
}
1011 1068

  
1069
/*
1070
 * klass and basic operation redefined on :basic_op_redefinition event.
1071
 */
1072
static VALUE
1073
tracepoint_basic_operation_redefined(VALUE tpval)
1074
{
1075
   return rb_tracearg_basic_op_redefined(get_trace_arg());
1076
}
1077

  
1012 1078
static void
1013 1079
tp_call_trace(VALUE tpval, rb_trace_arg_t *trace_arg)
1014 1080
{
......
1502 1568
    rb_define_method(rb_cTracePoint, "self", tracepoint_attr_self, 0);
1503 1569
    rb_define_method(rb_cTracePoint, "return_value", tracepoint_attr_return_value, 0);
1504 1570
    rb_define_method(rb_cTracePoint, "raised_exception", tracepoint_attr_raised_exception, 0);
1571
    rb_define_method(rb_cTracePoint, "basic_operation_redefined", tracepoint_basic_operation_redefined, 0);
1505 1572

  
1506 1573
    rb_define_singleton_method(rb_cTracePoint, "stat", tracepoint_stat_s, 0);
1507 1574

  
1508
-