[#83328] tcltklib and not init'ing tk — aakhter@... (Aamer Akhter)

Hello,

13 messages 2003/10/01

[#83391] mixing in class methods — "Mark J. Reed" <markjreed@...>

Okay, probably a dumb question, but: is there any way to define

22 messages 2003/10/01
[#83392] Re: mixing in class methods — Ryan Pavlik <rpav@...> 2003/10/01

On Thu, 2 Oct 2003 06:02:32 +0900

[#83397] Re: mixing in class methods — Gavin Sinclair <gsinclair@...> 2003/10/01

On Thursday, October 2, 2003, 7:08:00 AM, Ryan wrote:

[#83399] Re: mixing in class methods — "Mark J. Reed" <markjreed@...> 2003/10/02

On Thu, Oct 02, 2003 at 07:37:25AM +0900, Gavin Sinclair wrote:

[#83404] Re: mixing in class methods — "Gavin Sinclair" <gsinclair@...> 2003/10/02

> On Thu, Oct 02, 2003 at 07:37:25AM +0900, Gavin Sinclair wrote:

[#83416] C or C++? — "Joe Cheng" <code@...>

I'd like to start writing Ruby extensions. Does it make a difference

32 messages 2003/10/02
[#83435] Re: C or C++? — "Aleksei Guzev" <aleksei.guzev@...> 2003/10/02

[#83448] xml in Ruby — paul vudmaska <paul_vudmaska@...> 2003/10/02

The biggest problem i have with Ruby is the sleepness

[#83455] Re: xml in Ruby — Chad Fowler <chad@...> 2003/10/02

On Thu, 2 Oct 2003, paul vudmaska wrote:

[#83464] Re: xml in Ruby or no xml it's just a question — paul vudmaska <paul_vudmaska@...> 2003/10/02

>>--------

[#83470] Re: xml in Ruby — paul vudmaska <paul_vudmaska@...>

>>>

15 messages 2003/10/02

[#83551] xml + ruby — paul vudmaska <paul_vudmaska@...>

>>---------

20 messages 2003/10/03
[#83562] Re: xml + ruby — Austin Ziegler <austin@...> 2003/10/03

On Fri, 3 Oct 2003 16:11:46 +0900, paul vudmaska wrote:

[#83554] hash of hashes — Paul Argentoff <argentoff@...>

Hi all.

18 messages 2003/10/03

[#83675] fox-tool - interactive gui builder for fxruby — henon <user@...>

hi fellows,

15 messages 2003/10/05

[#83730] Re: Enumerable#inject is surprising me... — "Weirich, James" <James.Weirich@...>

> Does it surprise you?

17 messages 2003/10/06
[#83732] Re: Enumerable#inject is surprising me... — nobu.nokada@... 2003/10/07

Hi,

[#83801] Extension Language for a Text Editor — Nikolai Weibull <ruby-talk@...>

OK. So I'm going to write a text editor for my masters' thesis. The

35 messages 2003/10/08
[#83803] Re: Extension Language for a Text Editor — Ryan Pavlik <rpav@...> 2003/10/08

On Thu, 9 Oct 2003 05:06:32 +0900

[#83806] Re: Extension Language for a Text Editor — Nikolai Weibull <ruby-talk@...> 2003/10/08

* Ryan Pavlik <rpav@mephle.com> [Oct, 08 2003 22:30]:

[#83812] Re: Extension Language for a Text Editor — Ryan Pavlik <rpav@...> 2003/10/08

On Thu, 9 Oct 2003 06:09:29 +0900

[#83955] Re: Extension Language for a Text Editor — Nikolai Weibull <ruby-talk@...> 2003/10/09

* Ryan Pavlik <rpav@mephle.com> [Oct, 09 2003 09:10]:

[#84169] General Ruby Programming questions — Simon Kitching <simon@...>

21 messages 2003/10/15
[#84170] Re: General Ruby Programming questions — Florian Gross <flgr@...> 2003/10/15

Simon Kitching wrote:

[#84172] Re: General Ruby Programming questions — Simon Kitching <simon@...> 2003/10/15

Hi Florian..

[#84331] Re: Email Harvesting — Greg Vaughn <gvaughn@...>

Ryan Dlugosz said:

17 messages 2003/10/21
[#84335] Re: Email Harvesting — Hugh Sasse Staff Elec Eng <hgs@...> 2003/10/21

On Wed, 22 Oct 2003, Greg Vaughn wrote:

[#84343] Re: Email Harvesting — Ruben Vandeginste <Ruben.Vandeginste@...> 2003/10/22

On Wed, 22 Oct 2003 08:35:32 +0900, Hugh Sasse Staff Elec Eng

[#84341] Ruby-oriented Linux distro? — Hal Fulton <hal9000@...>

There's been some talk of something like this in the past.

15 messages 2003/10/22
[#84348] Re: Ruby-oriented Linux distro? — Gavin Sinclair <gsinclair@...> 2003/10/22

On Wednesday, October 22, 2003, 6:01:16 PM, Hal wrote:

[#84351] Re: Ruby-oriented Linux distro? — Andrew Walrond <andrew@...> 2003/10/22

On Wednesday 22 Oct 2003 11:02 am, Gavin Sinclair wrote:

[#84420] Struggling with variable arguments to block — "Gavin Sinclair" <gsinclair@...>

Hi -talk,

18 messages 2003/10/24
[#84428] Re: Struggling with variable arguments to block — matz@... (Yukihiro Matsumoto) 2003/10/24

Hi,

[#84604] ruby-dev summary 21637-21729 — Takaaki Tateishi <ttate@...>

Hello,

21 messages 2003/10/30
[#84787] Re: ruby-dev summary 21637-21729 — Paul Brannan <pbrannan@...> 2003/11/06

On Fri, Oct 31, 2003 at 07:01:28AM +0900, Takaaki Tateishi wrote:

[#84789] Re: ruby-dev summary 21637-21729 — matz@... (Yukihiro Matsumoto) 2003/11/06

Hi,

[#84792] Re: ruby-dev summary 21637-21729 — Paul Brannan <pbrannan@...> 2003/11/06

On Thu, Nov 06, 2003 at 11:17:59PM +0900, Yukihiro Matsumoto wrote:

[#84794] Re: ruby-dev summary 21637-21729 — matz@... (Yukihiro Matsumoto) 2003/11/06

Hi,

'unexpected return' caused by extension

From: "Nathaniel Talbott" <nathaniel@...>
Date: 2003-10-11 02:46:46 UTC
List: ruby-talk #84013
I'm writing my first (useful) Ruby extension, and I'm having issues. I'm
sure it's just a combination of my lack of C knowledge and lack of Ruby
knowledge, but I'd be extremely grateful for any pointers you might have.

Basically, I'm trying to write a better, faster profiler. I've attached all
of the interesting bits. When I run this on the tests from the most recent
Ruby (actually, just trying to get help!), I get the following error:

  ntalbott@solomon:~/cvs/ruby/test$ ruby -v -I ~/nprof -rnprofit runner.rb
--help
  /usr/local/lib/ruby/1.8/test/unit/autorunner.rb:10: unexpected return
  ruby 1.8.0 (2003-10-10) [i686-linux]

Running it without the extension works as expected. I'm sure I'm doing
something stupid... I promise to slap myself on the forehead when someone
shows me what it is.

Also, if you have any suggests regarding my C and/or Ruby/C style, please
let me know. I'm looking to improve as much as possible.

Thanks,


Nathaniel

<:((><

Attachments (4)

nprofit.rb (127 Bytes, text/x-ruby)
require 'nprof'

n = NProf.new
at_exit {
  set_trace_func(nil)
  #n.print_report
}
set_trace_func(n.method(:callback).to_proc)
nprof.rb (623 Bytes, text/x-ruby)
require 'nprofext'

class NProf
  class MethodInfo
    attr_reader :calls, :children

    def name
      sep = (@klass.kind_of?(Module) ? "." : "#")
      "#@klass#{sep}#@id"
    end

    def utime
      @times.utime
    end

    def stime
      @times.stime
    end
  end

  COLUMN_SEPARATOR = "    "
  def print_report(out=STDOUT)
    out.puts     ["calls", "utime", "stime", "child_count", "name"].join(COLUMN_SEPARATOR)
    @method_info.values.each do |m|
      out.printf((["%5d",  "%5.2f", "%5.2f", "%11d",        "%s\n"].join(COLUMN_SEPARATOR)), m.calls, m.utime, m.stime, m.children.size, m.name)
    end
  end
end
nprofext.c (5.13 KB, text/x-csrc)
#include "ruby.h"

/*
#define DEBUG(message) printf(message)
#define DEBUG_P(value) rb_p(value)

#define DEBUG(message) 
#define DEBUG_P(value) 
*/

VALUE cNProf;
VALUE cNProf_MethodInfo;

static VALUE mi_initialize(VALUE self, VALUE klass, VALUE id) {
  VALUE S_Tms = rb_const_get(rb_cStruct, rb_intern("Tms"));
  
  rb_iv_set(self, "@klass", klass);
  rb_iv_set(self, "@id", id);
  rb_iv_set(self, "@times", rb_struct_new(S_Tms, rb_float_new((double)0), rb_float_new((double)0)));
  rb_iv_set(self, "@children_times", rb_struct_new(S_Tms, rb_float_new((double)0), rb_float_new((double)0)));
  rb_iv_set(self, "@children", rb_hash_new());
  rb_iv_set(self, "@calls", INT2FIX(0));
}

double mi_sub_times(VALUE first, VALUE second) {
  double utime, stime;
  VALUE difference;
  VALUE name = rb_str_new2("utime");
  utime = NUM2DBL(rb_struct_aref(first, name)) - NUM2DBL(rb_struct_aref(second, name));
  name = rb_str_new2("stime");
  stime = NUM2DBL(rb_struct_aref(first, name)) - NUM2DBL(rb_struct_aref(second, name));
  difference = rb_struct_new(rb_const_get(rb_cStruct, rb_intern("Tms")), rb_float_new(utime), rb_float_new(stime), rb_float_new((double)0), rb_float_new((double)0));
  return difference;
}

double mi_add_times(VALUE first, VALUE second) {
  double utime, stime;
  VALUE name = rb_str_new2("utime");
  utime = NUM2DBL(rb_struct_aref(first, name)) + NUM2DBL(rb_struct_aref(second, name));
  name = rb_str_new2("stime");
  stime = NUM2DBL(rb_struct_aref(first, name)) + NUM2DBL(rb_struct_aref(second, name));
  return rb_struct_new(rb_const_get(rb_cStruct, rb_intern("Tms")), rb_float_new(utime), rb_float_new(stime), rb_float_new((double)0), rb_float_new((double)0));
}

void mi_add_in_times(VALUE mi, VALUE difference) {
  rb_iv_set(mi, "@times", mi_add_times(rb_iv_get(mi, "@times"), difference));
}

void mi_finish_child(VALUE parent, VALUE child_key, VALUE child_times) {
  rb_iv_set(parent, "@children_times", mi_add_times(rb_iv_get(parent, "@children_times"), child_times));
  rb_hash_aset(rb_iv_get(parent, "@children"), child_key, Qtrue);
}

static VALUE nprof_initialize(VALUE self) {
  rb_iv_set(self, "@stack", rb_ary_new());
  rb_iv_set(self, "@method_info", rb_hash_new());
}

static VALUE nprof_rattr_stack(VALUE self) {
  return rb_iv_get(self, "@stack");
}

static VALUE nprof_rattr_method_info(VALUE self) {
  return rb_iv_get(self, "@method_info");
}

VALUE nprof_start(VALUE args) {
  VALUE self = rb_ary_entry(args, 0);
  VALUE klass = rb_ary_entry(args, 1);
  VALUE id = rb_ary_entry(args, 2);
  VALUE stack = rb_iv_get(self, "@stack");
  VALUE now = rb_proc_times(rb_mProcess);
  VALUE method_info_hash, method_info_key, method_info, ary;

  ary = rb_ary_entry(stack, RARRAY(stack)->len - 1);
  
  method_info_hash = rb_iv_get(self, "@method_info");
  method_info_key = rb_ary_new3(2, klass, id);
  method_info = rb_hash_aref(method_info_hash, method_info_key);
  if(!RTEST(method_info)) {
    method_info = rb_funcall(cNProf_MethodInfo, rb_intern("new"), 2, klass, id);
    rb_hash_aset(method_info_hash, method_info_key, method_info);
  }
  rb_iv_set(method_info, "@calls", INT2FIX(NUM2INT(rb_iv_get(method_info, "@calls")) + 1));
  rb_ary_push(stack, rb_ary_new3(2, method_info, now));
  return Qnil;
}

VALUE nprof_finish(VALUE args) {
  VALUE self = rb_ary_entry(args, 0);
  VALUE klass = rb_ary_entry(args, 1);
  VALUE id = rb_ary_entry(args, 2);
  VALUE stack = rb_iv_get(self, "@stack");
  VALUE now = rb_proc_times(rb_mProcess);
  VALUE method_info_key, method_info, ary, then, difference;

  ary = rb_ary_pop(stack);
  if(!RTEST(ary))
    return Qnil;

  method_info = rb_ary_entry(ary, 0);
  then = rb_ary_entry(ary, 1);

  difference = mi_sub_times(now, then);
  mi_add_in_times(method_info, difference);
  
  ary = rb_ary_entry(stack, RARRAY(stack)->len - 1);
  if(RTEST(ary)) {
    method_info_key = rb_ary_new3(2, klass, id);
    mi_finish_child(rb_ary_entry(ary, 0), method_info_key, difference);
  }
  return Qnil;
}

VALUE nprof_err(VALUE args, VALUE error) {
  rb_funcall(rb_mKernel, rb_intern("set_trace_func"), 1, Qnil);
  rb_p(args);
  rb_p(error);
  return Qnil;
}

static VALUE nprof_callback(VALUE self, VALUE event, VALUE file, VALUE line, VALUE id, VALUE binding, VALUE klass) {
  char* event_string = STR2CSTR(event);
  VALUE args, eargs;
  
  if(!strcmp(event_string, "call") || !strcmp(event_string, "c-call")) {
    args = rb_ary_new3(3, self, klass, id);
    eargs = rb_ary_new3(3, line, klass, id);
    rb_rescue(nprof_start, args, nprof_err, eargs);
  } else if(!strcmp(event_string, "return") || !strcmp(event_string, "c-return")) {
    args = rb_ary_new3(3, self, klass, id);
    eargs = rb_ary_new3(3, line, klass, id);
    rb_rescue(nprof_finish, args, nprof_err, eargs);
  }

  return Qnil;
}

void Init_nprofext() {
  cNProf = rb_define_class("NProf", rb_cObject);
  rb_define_method(cNProf, "initialize", nprof_initialize, 0);
  rb_define_method(cNProf, "stack", nprof_rattr_stack, 0);
  rb_define_method(cNProf, "method_info", nprof_rattr_method_info, 0);
  rb_define_method(cNProf, "callback", nprof_callback, 6);

  cNProf_MethodInfo = rb_define_class_under(cNProf, "MethodInfo", rb_cObject);
  rb_define_method(cNProf_MethodInfo, "initialize", mi_initialize, 2);
}
extconf.rb (44 Bytes, text/x-ruby)
require 'mkmf'

create_makefile("nprofext")

In This Thread

Prev Next