<br><br><div class="gmail_quote">On Mon, Apr 7, 2008 at 11:23 AM, Richard Dale &lt;<a href="mailto:richard.j.dale@gmail.com">richard.j.dale@gmail.com</a>&gt; wrote:<br><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="gmail_quote"><div><br>Although it made the STACK_LEVEL_MAX figure bigger (15987856 in the above example), it didn&#39;t make any difference. I wonder if Ruby is getting the stack direction wrong, I&#39;ve no idea - so I&#39;ll do a bit of googling and investigate further.<br>

</div></div></blockquote><div>Doh! The problem isn&#39;t that Ruby is going off the end of the stack, it&#39;s that it is dropping below where it believes the stack started. So if I make the stack huge it doesn&#39;t have any effect on this underflow. When a ruby plasma plugin is loaded the RUBY_INIT_STACK macro will assume that the stack starts where it happens to be for the plugin loader code. It really needs to be run in main() though as that is where the real root of the stack. One way to work round this is to call RUBY_INIT_STACK at every entry point to the Ruby code (eg virtual method callbacks, and slot invocations). But make sure it is only called once if a virtual method calls another virtual method for instance by incrementing and decrementing a global &#39;nested_calls&#39; count. Swig uses a couple of macros to do that:<br>
<br>/*<br>&nbsp; If your swig extension is to be run within an embedded ruby and has<br>&nbsp; director callbacks, you should set -DRUBY_EMBEDDED during compilation.&nbsp; <br>&nbsp; This will reset ruby&#39;s stack frame on each entry point from the main <br>
&nbsp; program the first time a virtual director function is invoked (in a <br>&nbsp; non-recursive way).<br>&nbsp; If this is not done, you run the risk of Ruby trashing the stack.<br>*/<br><br>#ifdef RUBY_EMBEDDED<br><br>#&nbsp; define SWIG_INIT_STACK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !swig_virtual_calls ) { RUBY_INIT_STACK } \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++swig_virtual_calls;<br>#&nbsp; define SWIG_RELEASE_STACK --swig_virtual_calls;<br>#&nbsp; define Ruby_DirectorTypeMismatchException(x) \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rb_raise( rb_eTypeError, x ); return c_result;<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static unsigned int swig_virtual_calls = 0;<br><br>#else&nbsp; /* normal non-embedded extension */<br><br>#&nbsp; define SWIG_INIT_STACK<br>#&nbsp; define SWIG_RELEASE_STACK<br>#&nbsp; define Ruby_DirectorTypeMismatchException(x) \<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw Swig::DirectorTypeMismatchException( x );<br><br>#endif&nbsp; /* RUBY_EMBEDDED *<br><br>&nbsp;Another way might be to provide a longjmp target in the Plasma main() function that the Ruby extension code could jump to and then call RUBY_INIT_STACK there. <br>
<br>Another way would be to always assume that Plasma will load Ruby code, and introduce a link time dependency and just call RUBY_INIT_STACK/ruby_init() in the main(), but I don&#39;t think that is very elegant.<br><br>-- Richard<br>
<br></div></div>