Skip Menu |

This queue is for tickets about the ExtUtils-XSpp CPAN distribution.

Report information
The Basics
Id: 73053
Status: open
Priority: 0/
Queue: ExtUtils-XSpp

People
Owner: Nobody in particular
Requestors: mellery [...] yahoo.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.1602
Fixed in: (no value)



Subject: Missing CLASS declaration in code generated for methods that return instances of their own class
The general use-case I'm trying to support is an instance method that returns another instance of it's own type. I'm using ExtUtils::XSpp ver 0.1602 with perl 5.14.2. OS is 64 bit Ubuntu 10.04. Consider the Animal class that is part of the XSpp-Example included with the distro. If I add an instance method to the class: Animal MakeTwin() const; with an implementation like: Animal Animal::MakeTwin() const { return Animal(fName); } and then add it to the xsp file for the Animal class: Animal & MakeTwin(); When the code is generated by xspp, we get (I've removed various # declarations): XS_EUPXS(XS_Animal_MakeTwin); XS_EUPXS(XS_Animal_MakeTwin) { dVAR; dXSARGS; if (items != 1) croak_xs_usage(cv, "THIS"); { Animal * THIS; Animal * RETVAL; if( sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG) ) THIS = (Animal *)SvIV((SV*)SvRV( ST(0) )); else{ warn( "Animal::MakeTwin() -- THIS is not a blessed SV reference" ); XSRETURN_UNDEF; } ; try { RETVAL = new Animal( THIS->MakeTwin() ); } catch (std::exception& e) { croak("Caught C++ exception of type or derived from 'std::exception': %s", e.what()); } catch (...) { croak("Caught C++ exception of unknown type"); } ST(0) = sv_newmortal(); sv_setref_pv( ST(0), CLASS, (void*)RETVAL ); } XSRETURN(1); } ..which looks almost correct, but the declaration of CLASS is missing, causing the compiler error: buildtmp/Example.c: In function ‘void XS_Animal_MakeTwin(PerlInterpreter*, CV*)’: buildtmp/Example.c:371: error: ‘CLASS’ was not declared in this scope If there is a workaround for this use case, that would be fine too. Thanks.
Subject: Re: [rt.cpan.org #73053] Missing CLASS declaration in code generated for methods that return instances of their own class
Date: Mon, 12 Dec 2011 08:45:38 +0100
To: bug-ExtUtils-XSpp [...] rt.cpan.org
From: Steffen Mueller <smueller [...] cpan.org>
On 12/06/2011 06:56 PM, https://me.yahoo.com/melleryopenid#1b5ba via RT wrote: Show quoted text
> Tue Dec 06 12:56:02 2011: Request 73053 was acted upon. > Transaction: Ticket created by https://me.yahoo.com/melleryopenid#1b5ba > Queue: ExtUtils-XSpp > Subject: Missing CLASS declaration in code generated for methods that > return instances of their own class > Broken in: 0.1602 > Severity: Normal > Owner: Nobody > Requestors: mellery@yahoo.com > Status: new > Ticket<URL: https://rt.cpan.org/Ticket/Display.html?id=73053> > > > The general use-case I'm trying to support is an instance method that > returns another instance of it's own type. > > I'm using ExtUtils::XSpp ver 0.1602 with perl 5.14.2. OS is 64 bit > Ubuntu 10.04. > > Consider the Animal class that is part of the XSpp-Example included with > the distro. > > If I add an instance method to the class: > > Animal MakeTwin() const; > > with an implementation like: > > Animal Animal::MakeTwin() const > { > return Animal(fName); > } > > and then add it to the xsp file for the Animal class: > > Animal& MakeTwin(); > > When the code is generated by xspp, we get (I've removed various # > declarations): > > XS_EUPXS(XS_Animal_MakeTwin); > XS_EUPXS(XS_Animal_MakeTwin) > { > dVAR; dXSARGS; > if (items != 1) > croak_xs_usage(cv, "THIS"); > { > Animal * THIS; > Animal * RETVAL; > > if( sv_isobject(ST(0))&& (SvTYPE(SvRV(ST(0))) == SVt_PVMG) ) > THIS = (Animal *)SvIV((SV*)SvRV( ST(0) )); > else{ > warn( "Animal::MakeTwin() -- THIS is not a blessed SV reference" ); > XSRETURN_UNDEF; > } > ; > try { > RETVAL = new Animal( THIS->MakeTwin() ); > } > catch (std::exception& e) { > croak("Caught C++ exception of type or derived from > 'std::exception': %s", e.what()); > } > catch (...) { > croak("Caught C++ exception of unknown type"); > } > ST(0) = sv_newmortal(); > sv_setref_pv( ST(0), CLASS, (void*)RETVAL ); > } > XSRETURN(1); > } > > ..which looks almost correct, but the declaration of CLASS is missing, > causing the compiler error: > > buildtmp/Example.c: In function ‘void > XS_Animal_MakeTwin(PerlInterpreter*, CV*)’: > buildtmp/Example.c:371: error: ‘CLASS’ was not declared in this scope
Known problem. I wish we had a general fix for this. I have, at various times, tinkered with somewhat better cludges than the one below. Though none has convinced me as a good idea. Embedded typemaps (in XS code) as ParseXS version 3 supports should make this possible, but alas, no time to implement this yet. Show quoted text
> If there is a workaround for this use case, that would be fine too. Thanks.
The problem is that CLASS is only generated by xsubpp for special cases. The workaround is to define another typemap for such a case. If you want to return a Dog*, have the following typemap and use DogStatic* in place of Dog*. This requires including "typedef DogStatic* Dog*" somewhere early in the C code. The typemap workaround is simply inlining the class name into a copy of the O_OBJECT typemap. This is gruesome and untested: Dog * O_OBJECT DogStatic * O_DOG_OBJECT INPUT O_DOG_OBJECT if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) $var = ($type)SvIV((SV*)SvRV( $arg )); else{ warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" ); XSRETURN_UNDEF; } OUTPUT O_DOG_OBJECT sv_setref_pv( $arg, "Dog", (void*)$var ); Cheers, Steffen
Subject: Re: [rt.cpan.org #73053] Missing CLASS declaration in code generated for methods that return instances of their own class
Date: Mon, 12 Dec 2011 13:15:57 -0800 (PST)
To: "bug-ExtUtils-XSpp [...] rt.cpan.org" <bug-ExtUtils-XSpp [...] rt.cpan.org>
From: Michael Ellery <mellery [...] yahoo.com>
Thanks for your response. I tried to implement your proposed workaround, but I wasn't able to make it work (your c typedef syntax is not quite right, so I had to guess at what you meant there..). I get an error when building: "No typemap for type DogStatic*". I'm probably missing something obvious, but it's not clear to me what that is. In any event, I appreciate your advice. If you have time to modify the Dog/Animal example to show how to do this, I would appreciate it. If you want to just mark this as "not supported", I completely understand. Thanks,  Mike *-----------------------------* * Michael Ellery * * mellery@yahoo.com * *-----------------------------* Show quoted text
________________________________ From: Steffen Mueller via RT <bug-ExtUtils-XSpp@rt.cpan.org> To: mellery@yahoo.com Sent: Sunday, December 11, 2011 11:45 PM Subject: Re: [rt.cpan.org #73053] Missing CLASS declaration in code generated for methods that return instances of their own class <URL: https://rt.cpan.org/Ticket/Display.html?id=73053 > On 12/06/2011 06:56 PM, https://me.yahoo.com/melleryopenid#1b5ba via RT wrote:
> Tue Dec 06 12:56:02 2011: Request 73053 was acted upon. > Transaction: Ticket created by https://me.yahoo.com/melleryopenid#1b5ba >        Queue: ExtUtils-XSpp >      Subject: Missing CLASS declaration in code generated for methods that >  return instances of their own class >    Broken in: 0.1602 >      Severity: Normal >        Owner: Nobody >    Requestors: mellery@yahoo.com >        Status: new >  Ticket<URL: https://rt.cpan.org/Ticket/Display.html?id=73053> > > > The general use-case I'm trying to support is an instance method that > returns another instance of it's own type. > > I'm using ExtUtils::XSpp ver 0.1602 with perl 5.14.2. OS is 64 bit > Ubuntu 10.04. > > Consider the Animal class that is part of the XSpp-Example included with > the distro. > > If I add an instance method to the class: > >    Animal MakeTwin() const; > > with an implementation like: > >    Animal Animal::MakeTwin() const >    { >      return Animal(fName); >    } > > and then add it to the xsp file for the Animal class: > >    Animal&  MakeTwin(); > > When the code is generated by xspp, we get (I've removed various # > declarations): > >    XS_EUPXS(XS_Animal_MakeTwin); >    XS_EUPXS(XS_Animal_MakeTwin) >    { >      dVAR; dXSARGS; >      if (items != 1) >        croak_xs_usage(cv,  "THIS"); >      { >      Animal *    THIS; >      Animal *    RETVAL; > >      if( sv_isobject(ST(0))&&  (SvTYPE(SvRV(ST(0))) == SVt_PVMG) ) >          THIS = (Animal *)SvIV((SV*)SvRV( ST(0) )); >      else{ >          warn( "Animal::MakeTwin() -- THIS is not a blessed SV reference" ); >          XSRETURN_UNDEF; >      } > ; >      try { >        RETVAL = new Animal( THIS->MakeTwin() ); >      } >      catch (std::exception&  e) { >        croak("Caught C++ exception of type or derived from > 'std::exception': %s", e.what()); >      } >      catch (...) { >        croak("Caught C++ exception of unknown type"); >      } >      ST(0) = sv_newmortal(); >      sv_setref_pv( ST(0), CLASS, (void*)RETVAL ); >      } >      XSRETURN(1); >    } > > ..which looks almost correct, but the declaration of CLASS is missing, > causing the compiler error: > >    buildtmp/Example.c: In function ‘void > XS_Animal_MakeTwin(PerlInterpreter*, CV*)’: >    buildtmp/Example.c:371: error: ‘CLASS’ was not declared in this scope
Known problem. I wish we had a general fix for this. I have, at various times, tinkered with somewhat better cludges than the one below. Though none has convinced me as a good idea. Embedded typemaps (in XS code) as ParseXS version 3 supports should make this possible, but alas, no time to implement this yet.
> If there is a workaround for this use case, that would be fine too. Thanks.
The problem is that CLASS is only generated by xsubpp for special cases. The workaround is to define another typemap for such a case. If you want to return a Dog*, have the following typemap and use DogStatic* in place of Dog*. This requires including "typedef DogStatic* Dog*" somewhere early in the C code. The typemap workaround is simply inlining the class name into a copy of the O_OBJECT typemap. This is gruesome and untested: Dog *        O_OBJECT DogStatic *    O_DOG_OBJECT INPUT O_DOG_OBJECT         if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )                 $var = ($type)SvIV((SV*)SvRV( $arg ));         else{                 warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );                 XSRETURN_UNDEF;         } OUTPUT O_DOG_OBJECT         sv_setref_pv( $arg, "Dog", (void*)$var ); Cheers, Steffen
Subject: Re: [rt.cpan.org #73053] Missing CLASS declaration in code generated for methods that return instances of their own class
Date: Tue, 13 Dec 2011 08:08:30 +0100
To: bug-ExtUtils-XSpp [...] rt.cpan.org
From: Steffen Mueller <smueller [...] cpan.org>
On 12/12/2011 10:16 PM, Michael A. Ellery via RT wrote: Show quoted text
> Queue: ExtUtils-XSpp Ticket<URL: > https://rt.cpan.org/Ticket/Display.html?id=73053> > > Thanks for your response. I tried to implement your proposed > workaround, but I wasn't able to make it work (your c typedef syntax > is not quite right, so I had to guess at what you meant there..). I > get an error when building: "No typemap for type DogStatic*". I'm > probably missing something obvious, but it's not clear to me what > that is. In any event, I appreciate your advice. If you have time to > modify the Dog/Animal example to show how to do this, I would > appreciate it. If you want to just mark this as "not supported", I > completely understand.
I've committed an example to XSpp-Example/. See https://github.com/tsee/extutils-xspp and more specifically commit ce8803f84c839b4ed5e3d8ca6a6aee3ee263e0c9 I wish I had a better solution for you. Best regards, Steffen
Subject: Re: [rt.cpan.org #73053] Missing CLASS declaration in code generated for methods that return instances of their own class
Date: Tue, 13 Dec 2011 20:33:26 -0800 (PST)
To: "bug-ExtUtils-XSpp [...] rt.cpan.org" <bug-ExtUtils-XSpp [...] rt.cpan.org>
From: Michael Ellery <mellery [...] yahoo.com>
great - thanks for the sample update. I was able to get my stuff working based on this example. One other question - do you know if there is an easy way to export static class methods with XSPP? Since these don't need an instance to operate on, I'm assuming the generated XS code would be considerable different than a standard instance method...probably a bit simpler since they are really just function calls with the extra class namespace qualifier. If you have a quick solution for that, I'd appreciate it..otherwise I'll just omit it from my module. Thanks, Mike Ellery   *-----------------------------* * Michael Ellery * * mellery@yahoo.com * *-----------------------------* Show quoted text
________________________________ From: Steffen Mueller via RT <bug-ExtUtils-XSpp@rt.cpan.org> To: mellery@yahoo.com Sent: Monday, December 12, 2011 11:08 PM Subject: Re: [rt.cpan.org #73053] Missing CLASS declaration in code generated for methods that return instances of their own class <URL: https://rt.cpan.org/Ticket/Display.html?id=73053 > On 12/12/2011 10:16 PM, Michael A. Ellery via RT wrote:
> Queue: ExtUtils-XSpp Ticket<URL: > https://rt.cpan.org/Ticket/Display.html?id=73053> > > Thanks for your response. I tried to implement your proposed > workaround, but I wasn't able to make it work (your c typedef syntax > is not quite right, so I had to guess at what you meant there..). I > get an error when building: "No typemap for type DogStatic*". I'm > probably missing something obvious, but it's not clear to me what > that is. In any event, I appreciate your advice. If you have time to > modify the Dog/Animal example to show how to do this, I would > appreciate it. If you want to just mark this as "not supported", I > completely understand.
I've committed an example to XSpp-Example/. See https://github.com/tsee/extutils-xspp and more specifically commit ce8803f84c839b4ed5e3d8ca6a6aee3ee263e0c9 I wish I had a better solution for you. Best regards, Steffen
Subject: Re: [rt.cpan.org #73053] Missing CLASS declaration in code generated for methods that return instances of their own class
Date: Wed, 14 Dec 2011 08:04:09 +0100
To: bug-ExtUtils-XSpp [...] rt.cpan.org
From: Steffen Mueller <smueller [...] cpan.org>
On 12/14/2011 05:33 AM, Michael A. Ellery via RT wrote: Show quoted text
> Queue: ExtUtils-XSpp Ticket<URL: > https://rt.cpan.org/Ticket/Display.html?id=73053> > > great - thanks for the sample update. I was able to get my stuff > working based on this example. > > One other question - do you know if there is an easy way to export > static class methods with XSPP? Since these don't need an instance to > operate on, I'm assuming the generated XS code would be considerable > different than a standard instance method...probably a bit simpler > since they are really just function calls with the extra class > namespace qualifier. If you have a quick solution for that, I'd > appreciate it..otherwise I'll just omit it from my module.
I just pushed a commit to github (master branch) that adds an example of a class method. It's really rather simple and works the way I'd expect it to work. Also added two lines of documentation. If you find underdocumented things as you explore XS++, please do submit patches or at least ask us to add documentation. Best regards, Steffen
Show quoted text
> I just pushed a commit to github (master branch) that adds an example of > a class method. It's really rather simple and works the way I'd expect > it to work. Also added two lines of documentation. > > If you find underdocumented things as you explore XS++, please do submit > patches or at least ask us to add documentation. > > Best regards, > Steffen
works great - thanks for that update.