Collect info about ruby-api

I have long been longing for a good description of ruby C api.
Therefore I have created a RubyAPI place at rubygarden.

http://www.rubygarden.org/ruby?RubyApi

I hope that every function in ‘ruby.h’ and ‘intern.h’ will become
documented (at least the most common functions). Eventualy with some
intuitive examples.

Please contribute if you know something which might be useful to others.

Tell me what you think: suggestions, comments, flames… etc :slight_smile:

BTW: im having serious trouble describing purpose with rb_protect(),
if someone can do a better job than me, I would be even more happy :slight_smile:

···


Simon Strandgaard

  1. rb_funcall3() what is purpose with it ?
    is there any understandable examples around ?

  2. rb_eval_string_wrap() how is it different from
    rb_eval_string_protect()… scoping ?
    is there any examples which demonstrates this
    difference ?

  3. http://www.rubygarden.org/ruby?RubyApi/RbProtect
    the description of purpose is not good,
    what should be written in order to improve it?

···

On Thu, 19 Jun 2003 17:54:02 +0200, Simon Strandgaard wrote:

I have long been longing for a good description of ruby C api.
Therefore I have created a RubyAPI place at rubygarden.

http://www.rubygarden.org/ruby?RubyApi

I hope that every function in ‘ruby.h’ and ‘intern.h’ will become
documented (at least the most common functions). Eventualy with some
intuitive examples.


Simon Strandgaard

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

I have long been longing for a good description of ruby C api.
Therefore I have created a RubyAPI place at rubygarden.

http://www.rubygarden.org/ruby?RubyApi

I am still learning, so this is just wonderful ! One minor request:
can we complete the code on :

http://www.rubygarden.org/ruby?RubyApi/RbClassNewInstance

I am still trying to figure out how to convert it into
a fully working C program (like all the other code examples).

Thanks,
– shanko

Hi,

  1. rb_funcall3() what is purpose with it ?
    is there any understandable examples around ?

It’s almost like rb_funcall2() but raises error when it tries to call
private method.

  1. rb_eval_string_wrap() how is it different from
    rb_eval_string_protect()… scoping ?
    is there any examples which demonstrates this
    difference ?

It evaluates string under anonymous module, just like "load(path, true).

  1. http://www.rubygarden.org/ruby?RubyApi/RbProtect
    the description of purpose is not good,
    what should be written in order to improve it?

Hmm.

						matz.
···

In message “Re: collect info about ruby-api” on 03/06/20, “Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com writes:

“Shashank Date” sdate@everestkc.net wrote in message

I am still trying to figure out how to convert it into
a fully working C program (like all the other code examples).

To be more specific, I am on WIN XP Pro, using VC++ 6.0
The following code does not work (it crashes and asks me if I
want to send the error report to Microsoft. Probably because I
do not know how “… to tell the Ruby’s garbage collector that
there is a new instance in town” )

I have tested all the other programs and they all work fine so I don’t
think there is a problem with setting up my VisualStudio 6.0 environment.

Any suggestions ?
TIA
– shanko

//-------------------------------------------------------------------
#include <ruby.h>
int main(int Argc, char **Argv) {

int argc;
VALUE argv[2];
VALUE class;
VALUE instance;

ruby_init();

argv[0] = INT2FIX(42);
argv[1] = rb_str_new2(“hello world”);
argc = 2;

/* ----- This does not work either:
class = rb_path2class(“TestClass”);
instance = rb_class_new_instance(argc, argv, class);
*/

class = rb_const_get(rb_cObject, rb_intern(“TestClass”));
instance = rb_funcall2(class, rb_intern(“new”), argc, argv);

ruby_finalize();
return 0;

}

//-------------------------------------------------------------------

  1. rb_funcall3() what is purpose with it ?
    is there any understandable examples around ?

It’s almost like rb_funcall2() but raises error when it tries to call
private method.

So rb_funcall3 is equal to a ruby-method call, like this:

cat test.rb
class Test
private
def test
puts "ok"
end
end
Test.new.test # is rb_funcall3 going on ?
ruby test.rb
test.rb:7: private method `test’ called for #Test:0x8106cc8 (NoMethodError)

Furthermore rb_funcall + rb_funcall2 can access any function, even
private ones!

cat main.c
#include <ruby.h>
int main(int argc, char argv[]) {
VALUE data;
ruby_init();
data = rb_eval_string(“class Test\nprivate\ndef test\nputs “ok”\nend\nend\nTest.new”);
rb_funcall(data, rb_intern(“test”), 0); /
outputs ‘ok’ /
/rb_funcall2(data, rb_intern(“test”), 0, 0);/ /
outputs ‘ok’ /
/rb_funcall3(data, rb_intern(“test”), 0, 0);/ /
fails as its suppose to */
ruby_finalize();
return 0;
}
./a.out
ok

People can access private-methods by an accident… I think that rb_funcall
and rb_funcall2 is behaving in God mode (disrespecting privacy :slight_smile:
Shouldn’t rb_funcall3 be advertised a lot more ???

  1. rb_eval_string_wrap() how is it different from
    rb_eval_string_protect()… scoping ?
    is there any examples which demonstrates this
    difference ?

It evaluates string under anonymous module, just like "load(path, true).

Sorry, I don’t understand…

rb_eval_string_wrap(), evaluates under anonymous module.

rb_eval_string_protect(), evaluates under ??current context??.

I don’t think I understand the consequences putting it under a anonymous
module… can someone enligthen me ?
Examples would be really nice :slight_smile:

···

On Fri, 20 Jun 2003 10:52:26 +0900, Yukihiro Matsumoto wrote:

In message “Re: collect info about ruby-api” > on 03/06/20, “Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com writes:


Simon Strandgaard

“Shashank Date” sdate@everestkc.net wrote in message

I am still trying to figure out how to convert it into
a fully working C program (like all the other code examples).

Sorry… I couldn’t think of any good cutnpaste-example when I
wrote the text about rb_class_new_instance(). If anyone has ideas for
better examples they are welcome.

To be more specific, I am on WIN XP Pro, using VC++ 6.0
The following code does not work (it crashes and asks me if I
want to send the error report to Microsoft. Probably because I
do not know how “… to tell the Ruby’s garbage collector that
there is a new instance in town” )

There is 2 ways you can inform GC about the new instance.
#1 rb_define_variable(name, instance);
by naming the instance, so it can be accessed by its
Ruby-variable-name. Use this if you want to share an
instance between Ruby and you extension/embedding code.

#2 rb_gc_register_address(&instance);
don’t want to assign a name to the instance.
Use this if you want to keep some variables private to
your extension/embedding code.
It cannot be accessed from a ruby-script.

I have tested all the other programs and they all work fine so I don’t
think there is a problem with setting up my VisualStudio 6.0 environment.

OK… nice to know. I was worried that it wouldn’t work on windows.
Perhaps you can add a short guide to rubygarden about how you have
setup’ed compilation on windows ?

//-------------------------------------------------------------------
#include <ruby.h>
int main(int Argc, char **Argv) {

int argc;
VALUE argv[2];
VALUE class;
VALUE instance;

ruby_init();

argv[0] = INT2FIX(42);
argv[1] = rb_str_new2(“hello world”);
argc = 2;

/* ----- This does not work either:
class = rb_path2class(“TestClass”);
instance = rb_class_new_instance(argc, argv, class);
*/

class = rb_const_get(rb_cObject, rb_intern(“TestClass”));
^^^^^^^^^

‘TestClass’ does not exist… Try with a class-name which exists, perhaps:
String, Array, …
Besides that you code looks ok :slight_smile:

instance = rb_funcall2(class, rb_intern(“new”), argc, argv);
ruby_finalize();
return 0;

}

//-------------------------------------------------------------------

#include <ruby.h>
int main(int argc, char *argv[]) {
int n;
VALUE args[2];
VALUE klass;
VALUE instance;

ruby_init();
args[0] = INT2FIX(4);
args[1] = rb_str_new2("ok");
n = 2;
klass = rb_path2class("Array");
instance = rb_class_new_instance(n, args, klass);

/* tell GC that there is a new instance in town. */
rb_gc_register_address(&instance);

rb_p(instance);

ruby_finalize();
return 0;

}

./a.out
[“ok”, “ok”, “ok”, “ok”]

···

On Mon, 23 Jun 2003 21:44:52 +0000, Shashank Date wrote:


Simon Strandgaard

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

There is 2 ways you can inform GC about the new instance.
#1 rb_define_variable(name, instance);
by naming the instance, so it can be accessed by its
Ruby-variable-name. Use this if you want to share an
instance between Ruby and you extension/embedding code.

#2 rb_gc_register_address(&instance);
don’t want to assign a name to the instance.
Use this if you want to keep some variables private to
your extension/embedding code.
It cannot be accessed from a ruby-script.

This did help … although I haven’t yet tried method# 1

OK… nice to know. I was worried that it wouldn’t work on windows.
Perhaps you can add a short guide to rubygarden about how you have
setup’ed compilation on windows ?

Sure … first let me learn how to modify the contents of rubygarden.

#include <ruby.h>
int main(int argc, char *argv[]) {
int n;
VALUE args[2];
VALUE klass;
VALUE instance;

ruby_init();
args[0] = INT2FIX(4);
args[1] = rb_str_new2(“ok”);
n = 2;
klass = rb_path2class(“Array”);
instance = rb_class_new_instance(n, args, klass);

I tried replacing the above two lines by :

 klass = rb_const_get(rb_cObject, rb_intern("Array"));
 instance = rb_funcall2(klass, rb_intern("new"), argc, argv);

but my program crashed. Am I missing something ?

/* tell GC that there is a new instance in town. */
rb_gc_register_address(&instance);

rb_p(instance);

ruby_finalize();
return 0;
}

Yes, your code worked … thanks for sharing your valuable insight.
– Shashank

Hi,

To be more specific, I am on WIN XP Pro, using VC++ 6.0
The following code does not work (it crashes and asks me if I
want to send the error report to Microsoft. Probably because I
do not know how “… to tell the Ruby’s garbage collector that
there is a new instance in town” )

There is 2 ways you can inform GC about the new instance.
#1 rb_define_variable(name, instance);
by naming the instance, so it can be accessed by its
Ruby-variable-name. Use this if you want to share an
instance between Ruby and you extension/embedding code.

#2 rb_gc_register_address(&instance);
don’t want to assign a name to the instance.
Use this if you want to keep some variables private to
your extension/embedding code.
It cannot be accessed from a ruby-script.

#3 Init_stack(address)
tell GC the machine stack limit.

#include <ruby.h>
int main(int argc, char *argv[]) {
int n;
VALUE args[2];
VALUE klass;
VALUE instance;

ruby_init();
Init_stack(&argc); /* arbitrary higher address */

args[0] = INT2FIX(4);
args[1] = rb_str_new2(“ok”);
n = 2;
klass = rb_path2class(“Array”);
instance = rb_class_new_instance(n, args, klass);

#if 0 /* no need */

/* tell GC that there is a new instance in town. */
rb_gc_register_address(&instance);
#endif

rb_p(instance);

ruby_finalize();
return 0;
}

Better solution is separating from “args[0] = …” through
ruby_finalize() to another function.

···

At Tue, 24 Jun 2003 16:03:29 +0900, Simon Strandgaard wrote:


Nobu Nakada

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

OK… nice to know. I was worried that it wouldn’t work on windows.
Perhaps you can add a short guide to rubygarden about how you have
setup’ed compilation on windows ?

Sure … first let me learn how to modify the contents of rubygarden.

At the bottom there is a link, labeled 'Edit text of this page’
You can do anonymous editing, but for other wiki-fans sake I suggest that
register yourself.

http://www.rubygarden.org/ruby?RubyApi/HowtoCompile

#include <ruby.h>
int main(int argc, char *argv[]) {
int n;
VALUE args[2];
VALUE klass;
VALUE instance;

ruby_init();
args[0] = INT2FIX(4);
args[1] = rb_str_new2(“ok”);
n = 2;
klass = rb_path2class(“Array”);
instance = rb_class_new_instance(n, args, klass);

I tried replacing the above two lines by :

 klass = rb_const_get(rb_cObject, rb_intern("Array"));
 instance = rb_funcall2(klass, rb_intern("new"), argc, argv);

but my program crashed. Am I missing something ?

The 2nd line is ‘int main(int argc, char *argv[])’… If
you use ‘argc’ or ‘argv’ you will then be refering to these.
The reason that your program chrashed is because Ruby expects an
array of VALUEs… you supplied ‘argv’ which is ‘char **’.

If you look in the Ruby-source, in ‘ruby.h’ you can see that
VALUE simply is: typedef unsigned long VALUE;

Try write this instead:

klass = rb_const_get(rb_cObject, rb_intern("Array"));
instance = rb_funcall2(klass, rb_intern("new"), n, args);
···

On Tue, 24 Jun 2003 23:36:19 +0000, Shashank Date wrote:

/* tell GC that there is a new instance in town. */
rb_gc_register_address(&instance);

rb_p(instance);

ruby_finalize();
return 0;
}


Simon Strandgaard

#3 Init_stack(address)
tell GC the machine stack limit.

I never heard about this before, what does it do ?
Can you give me a more lengthy description of it :slight_smile:

grep Init_stack *.h

It doesn’t seems to something public available to the embedding/extension
Rubyist’s. To me it looks like an internal routine.

#if 0 /* no need */

/* tell GC that there is a new instance in town. */
rb_gc_register_address(&instance);
#endif

Yes it not necessary for this small program, but for bigger pieces of code
where GC takes place… then I think its necessary.

Better solution is separating from “args[0] = …” through
ruby_finalize() to another function.

Me don’t understand ?
I am very interested hearing about ruby_finalize… so I can fill in some
better description, here:
http://www.rubygarden.org/ruby?RubyApi/RubyFinalize

···

On Wed, 25 Jun 2003 22:57:53 +0900, nobu.nokad wrote:


Simon Strandgaard

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

I tried replacing the above two lines by :

 klass = rb_const_get(rb_cObject, rb_intern("Array"));
 instance = rb_funcall2(klass, rb_intern("new"), argc, argv);

Sorry, I meant :
instance = rb_funcall2(klass, rb_intern(“new”), n, args);

but my program crashed. Am I missing something ?

Try write this instead:

klass = rb_const_get(rb_cObject, rb_intern("Array"));
instance = rb_funcall2(klass, rb_intern("new"), n, args);

But still did not work :frowning:

Thanks a lot for your attention and support.
– shanko

#3 Init_stack(address)
tell GC the machine stack limit.

I never heard about this before, what does it do ?
Can you give me a more lengthy description of it :slight_smile:

The GC of Ruby is conservative: it will scan the stack to find VALUEs.
This means at any moment it can take the stack pointer and scan from
there to the beginning of the stack. Init_stack takes the address of one
local variable (in the stack) and records it as the bottom of the stack
(highest address in x86).

grep Init_stack *.h

It doesn’t seems to something public available to the embedding/extension
Rubyist’s. To me it looks like an internal routine.

There’s lots of functions not declared in the headers…

···

On Wed, Jun 25, 2003 at 10:21:37PM +0900, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 22:57:53 +0900, nobu.nokad wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
’_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

I’d crawl over an acre of ‘Visual This++’ and ‘Integrated Development
That’ to get to gcc, Emacs, and gdb. Thank you.
– Vance Petree, Virginia Power

Hi,

grep Init_stack *.h

It doesn’t seems to something public available to the embedding/extension
Rubyist’s. To me it looks like an internal routine.

Yes, it’s an internal but would be necessary to embed (see
eruby). And I think it should have other name, e.g.
ruby_stack_init.

#if 0 /* no need */

/* tell GC that there is a new instance in town. */
rb_gc_register_address(&instance);
#endif

Yes it not necessary for this small program, but for bigger pieces of code
where GC takes place… then I think its necessary.

It worked even if rb_gc_start() was before `rb_p’.

Better solution is separating from “args[0] = …” through
ruby_finalize() to another function.

Me don’t understand ?

It’s just the line before return.

Index: eval.c

···

At Wed, 25 Jun 2003 22:21:37 +0900, Simon Strandgaard wrote:

RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.469
diff -u -2 -p -r1.469 eval.c
— eval.c 24 Jun 2003 08:59:34 -0000 1.469
+++ eval.c 25 Jun 2003 23:44:51 -0000
@@ -1144,5 +1144,4 @@ char **rb_origenviron;

void rb_call_inits _((void));
-void Init_stack _((void*));
void Init_heap _((void));
void Init_ext _((void));
@@ -1169,5 +1168,5 @@ ruby_init()
#endif

  • Init_stack((void*)&state);
  • ruby_stack_init((void*)&state);
    Init_heap();
    PUSH_SCOPE();
    @@ -1303,5 +1302,5 @@ ruby_options(argc, argv)
    int state;
  • Init_stack((void*)&state);
  • ruby_stack_init((void*)&state);
    PUSH_TAG(PROT_NONE);
    if ((state = EXEC_TAG()) == 0) {
    @@ -1364,5 +1363,5 @@ ruby_exec()
    volatile NODE *tmp;
  • Init_stack((void*)&tmp);
  • ruby_stack_init((void*)&tmp);
    ruby_running = 1;
    PUSH_TAG(PROT_NONE);
    @@ -9321,5 +9320,5 @@ rb_thread_create(fn, arg)
    void *arg;
    {
  • Init_stack((VALUE*)&arg);
  • ruby_stack_init((VALUE*)&arg);
    return rb_thread_start_0(fn, arg, rb_thread_alloc(rb_cThread));
    }
    Index: gc.c
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/gc.c,v
    retrieving revision 1.137
    diff -u -2 -p -r1.137 gc.c
    — gc.c 16 Jun 2003 07:14:36 -0000 1.137
    +++ gc.c 25 Jun 2003 23:48:59 -0000
    @@ -1282,6 +1282,6 @@ stack_growup_p(addr)

void
-Init_stack(addr)

  • VALUE *addr;
    +ruby_stack_init(ptr)
  • void *ptr;
    {
    #if defined(human68k)
    @@ -1289,5 +1289,6 @@ Init_stack(addr)
    rb_gc_stack_start = _SEND;
    #else
  • if (!addr) addr = (VALUE *)&addr;
  • VALUE *const addr = ptr ? ptr : (VALUE *)&ptr;
  • if (rb_gc_stack_start) {
    if (stack_growup_p(addr)) {
    @@ -1318,8 +1319,16 @@ Init_stack(addr)

void
+Init_stack(addr)

  • void *addr;
    +{
  • if (!addr) addr = (void *)&addr;
  • ruby_stack_init(addr);
    +}

+void
Init_heap()
{
if (!rb_gc_stack_start) {

  • Init_stack(0);
  • ruby_stack_init(0);
    }
    add_heap();
    Index: intern.h
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/intern.h,v
    retrieving revision 1.124
    diff -u -2 -p -r1.124 intern.h
    — intern.h 20 Jun 2003 07:11:40 -0000 1.124
    +++ intern.h 25 Jun 2003 23:37:28 -0000
    @@ -222,4 +222,5 @@ VALUE rb_find_file _((VALUE));
    /* gc.c /
    NORETURN(void rb_memerror __((void)));
    +void ruby_stack_init _((void
    ));
    int ruby_stack_check _((void));
    int ruby_stack_length _((VALUE**));


Nobu Nakada

#3 Init_stack(address)
tell GC the machine stack limit.

I never heard about this before, what does it do ?
Can you give me a more lengthy description of it :slight_smile:

Simon, remember how the GC works: Every time it runs, it marks all objects
that are still reachable, from either global variables, or from local
variables that are currently somewhere on the execution stack.

Your two methods would declare your variables global.

Nobu’s suggested to rely on the fact that objects currently referenced
from local variables also get marked.

Local variables are references that live on the stack.

The Init_stack method corrects ruby’s idea of where the C stack starts.
All objects referenced from the C stack will be marked during a GC run.

grep Init_stack *.h

It doesn’t seems to something public available to the embedding/extension
Rubyist’s. To me it looks like an internal routine.

It will be called from ruby_init. You can avoid calling it explicitly if
you do all your work from within another function after you called
ruby_init, like this:

main(int argc, char * argv[]){
ruby_init();
do_the_work(argc, argv);
}
do_the_work(int argc, char * argv[]){
VALUE x1 = …
VALUE x2 = …

}

Then you can RELY on the fact that none of your objects pointed to by
x1, x2, etc, will be destroyed before the do_the_work function returns.

No need to register objects as globals!

If you can’t believe this, then learn about it yourself:

You have to have an understanding of how the C stack is generally used for
function call parameters and local variables. Maybe
http://www.codeproject.com/tips/stackdumper.asp, section 1.1 can serve as
an introduction.

And you need an idea of how the garbage collector works. The C code in the
file “gc.c” is very readable, if you ignore all the switch/case branches
that mention some NODE objects.

Tobias

···

On Wed, 25 Jun 2003, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 22:57:53 +0900, nobu.nokad wrote:

Can you post the whole program, then I will se what I can do ?

···

On Wed, 25 Jun 2003 09:29:41 +0000, Shashank Date wrote:

but my program crashed. Am I missing something ?

But still did not work :frowning:


Simon Strandgaard

Sorry I don’t understand Nobu’s reason to added Init_stack as number 3rd
item in the list of possible ways to register an instance.

Is Init_stack really a 3rd possiblitity to do registring ?

···

On Wed, 25 Jun 2003 23:48:00 +0900, Mauricio Fernández wrote:

On Wed, Jun 25, 2003 at 10:21:37PM +0900, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 22:57:53 +0900, nobu.nokad wrote:

#3 Init_stack(address)
tell GC the machine stack limit.

I never heard about this before, what does it do ?
Can you give me a more lengthy description of it :slight_smile:

The GC of Ruby is conservative: it will scan the stack to find VALUEs.
This means at any moment it can take the stack pointer and scan from
there to the beginning of the stack. Init_stack takes the address of one
local variable (in the stack) and records it as the bottom of the stack
(highest address in x86).


Simon Strandgaard

#3 Init_stack(address)
tell GC the machine stack limit.

I never heard about this before, what does it do ?
Can you give me a more lengthy description of it :slight_smile:

Simon, remember how the GC works: Every time it runs, it marks all objects
that are still reachable, from either global variables, or from local
variables that are currently somewhere on the execution stack.

Yes I know mark&sweep GC.

Your two methods would declare your variables global.

Yes. I know there is other methods.
The reason why I suggested these 2 methods is because I want to avoid
confusing people… No one would have understod me if I had
presented all posible methods.

These 2 methods represent the only two distinct ways you can tell GC that
there is a new instance in town.
#1 export a C variable into Ruby.
#2 non-export… not visible within Ruby.

I have no insigth in what Init_stack does… I am guessing it belongs to
the second category?

Nobu’s suggested to rely on the fact that objects currently referenced
from local variables also get marked.

Local variables are references that live on the stack.

The Init_stack method corrects ruby’s idea of where the C stack starts.
All objects referenced from the C stack will be marked during a GC run.

I don’t know anything about Ruby + stack… tell me more ?

It is not because I don’t know what a stack is… I have done assembler
programming, written compiler, cpu emulator, operating system… I think
I know what a stack is :slight_smile:

I just don’t understand the purpose+goal with Init_stack.

It doesn’t seems to something public available to the embedding/extension
Rubyist’s. To me it looks like an internal routine.

It will be called from ruby_init. You can avoid calling it explicitly if
you do all your work from within another function after you called
ruby_init, like this:
[snip code]
Then you can RELY on the fact that none of your objects pointed to by
x1, x2, etc, will be destroyed before the do_the_work function returns.

I don’t see where Init_stack enters the picture ?

If you can’t believe this, then learn about it yourself:

I already know what a stack is…

And you need an idea of how the garbage collector works. The C code in the
file “gc.c” is very readable, if you ignore all the switch/case branches
that mention some NODE objects.

I have not read ‘gc.c’ closely… I know mark&sweep.
I don’t know much about Ruby’s internals (NODE ???).

I am still curious…

  • what can Init_stack be used for?
  • when is it supposed to be used?
  • any ‘short’ example of usage?

Im listening :slight_smile:

···

On Thu, 26 Jun 2003 12:17:14 +0200, Tobias Peters wrote:

On Wed, 25 Jun 2003, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 22:57:53 +0900, nobu.nokad wrote:


Simon Strandgaard

It doesn’t register one specific instance, but sets the top of the stack
(which will be scanned afterwards) so that the value can be found later.

You have to call this (directly or via another function) at the
beginning of your program.

Some references:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66013
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66025

···

On Wed, Jun 25, 2003 at 11:43:34PM +0900, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 23:48:00 +0900, Mauricio Fernández wrote:

On Wed, Jun 25, 2003 at 10:21:37PM +0900, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 22:57:53 +0900, nobu.nokad wrote:

#3 Init_stack(address)
tell GC the machine stack limit.

I never heard about this before, what does it do ?
Can you give me a more lengthy description of it :slight_smile:

The GC of Ruby is conservative: it will scan the stack to find VALUEs.
This means at any moment it can take the stack pointer and scan from
there to the beginning of the stack. Init_stack takes the address of one
local variable (in the stack) and records it as the bottom of the stack
(highest address in x86).

Sorry I don’t understand Nobu’s reason to added Init_stack as number 3rd
item in the list of possible ways to register an instance.

Is Init_stack really a 3rd possiblitity to do registring ?


_ _

__ __ | | ___ _ __ ___ __ _ _ __
’_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Your job is being a professor and researcher: That’s one hell of a good excuse
for some of the brain-damages of minix.
– Linus Torvalds to Andrew Tanenbaum

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

Can you post the whole program, then I will see what I can do ?

Try commenting out the line marked by <===== below.
Thanks again.
– shanko
//----------------------------------------------------------------

#include <ruby.h>

int main(int Argc, char **Argv) {

int argc;
VALUE argv[2];
VALUE klass;
VALUE instance;

ruby_init();
Init_stack(&argc); // tell GC the machine stack limit.

argv[0] = INT2FIX(5);
argc = 2;

klass = rb_path2class(“Array”);
argv[1] = rb_str_new2(“hello”);
instance = rb_class_new_instance(argc, argv, klass);
rb_p(instance);

// Uncommenting the next line will cause the program to crash
// klass = rb_const_get(rb_cObject, rb_intern(“Array”)); <=====
argv[1] = rb_str_new2(“world”);
instance= rb_funcall2(klass, rb_intern(“new”), argc, argv);

//No need, see [ruby-talk 74400]
//rb_gc_register_address(&instance);

rb_p(instance);

ruby_finalize();
return 0;

}
//-------------------------------------------------------------------