Raku / old-issue-tracker

Tickets from RT
https://github.com/Raku/old-issue-tracker/issues
2 stars 1 forks source link

Wrapped method fails when precompiled #5222

Open p6rt opened 8 years ago

p6rt commented 8 years ago

Migrated from rt.perl.org#127860 (status was 'open')

Searchable as RT127860$

p6rt commented 8 years ago

From @jonathanstowe

It appears that the Metamodel​::WrapDispatcher can't find the candidate to execute when the wrapped method is pre-compiled.

This can be recreated in several ways, first by wrapping the method in an over-ridden add_method​:

lib/Vum.pm​:

class MetamodelX​::FooHOW is Metamodel​::ClassHOW {   method add_method(Mu \type, $name, &code) {   say "adding $name";   my &wrapper = method (|c) { say "running $name"; callsame; };   &code.wrap( &wrapper );   self.Metamodel​::ClassHOW​::add_method(type, $name, &code);   }   method compose(Mu \type) {   self.Metamodel​::ClassHOW​::compose(type);   } }

my package EXPORTHOW {   package SUPERSEDE {   constant class = MetamodelX​::FooHOW;   } }

And lib/Boo.pm :

use Vum;

#no precompilation;

class Boo {   has $.rabble;   method rack() {   say "rabble : ";   } }

And exercised with "perl6 -Ilib ..."​:

use Boo;

my $b = Boo.new(rabble => "hoodoo");

say $b.rack;

This will fail with​:

Cannot invoke this object   in method \ at /home/jonathan/devel/perl6/Vum/lib/Vum.pm (Vum) line 4   in any enter at gen/moar/m-Metamodel.nqp line 3947   in block \ at tt line 5

(Which points to the enter method of WrapDispatch.) Which would appear that it is not getting the appropriate Callable from .candidates[0]. With the "no precompilation" un-commented in Boo.pm this will work fine.

Just to check that this wasn't something mysterious in the MOP it can also be replicated with​:

lib/Wom.pm​:

module Wom {   multi sub trait_mod​:\(Method $m, :$brapped!) is export {   $m.wrap(method (|c) { say "wrapped"; callsame });   } }

lib/Bok.pm​:

use Wom;

#no precompilation;

class Bok {   has $.rabble;   method rack() is brapped {   say "rabble : ";   } }

And exercised with the similar script run with "perl6 -Ilib ..." :

use Bok;

my $b = Bok.new(rabble => "hoodoo");

say $b.rack;

Then this will also fail identically without the "no precompilation".

This afflicts OO​::Monitors in the ecosystem which cannot be used in a module that will be precompiled, and I suspect this is also at the heart of a problem with Staticish which similarly doesn't work if used in a module which is precompiled.

This is with​:

This is Rakudo version 2016.03-98-g61d231c built on MoarVM version 2016.03-84-g4afd7b6

p6rt commented 8 years ago

From @LLFourn

For reference this is another related to​:

https://rt.perl.org/Public/Bug/Display.html?id=125634

On Sat, Apr 9, 2016 at 7​:10 AM Jonathan Stowe \perl6\-bugs\-followup@​perl\.org wrote​:

# New Ticket Created by Jonathan Stowe # Please include the string​: [perl #​127860] # in the subject line of all future correspondence about this issue. # \<URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127860 >

It appears that the Metamodel​::WrapDispatcher can't find the candidate to execute when the wrapped method is pre-compiled.

This can be recreated in several ways, first by wrapping the method in an over-ridden add_method​:

lib/Vum.pm​:

class MetamodelX​::FooHOW is Metamodel​::ClassHOW { method add_method(Mu \type, $name, &code) { say "adding $name"; my &wrapper = method (|c) { say "running $name"; callsame; }; &code.wrap( &wrapper ); self.Metamodel​::ClassHOW​::add_method(type, $name, &code); } method compose(Mu \type) { self.Metamodel​::ClassHOW​::compose(type); } }

my package EXPORTHOW { package SUPERSEDE { constant class = MetamodelX​::FooHOW; } }

And lib/Boo.pm :

use Vum;

#no precompilation;

class Boo { has $.rabble; method rack() { say "rabble : "; } }

And exercised with "perl6 -Ilib ..."​:

use Boo;

my $b = Boo.new(rabble => "hoodoo");

say $b.rack;

This will fail with​:

Cannot invoke this object in method \ at /home/jonathan/devel/perl6/Vum/lib/Vum.pm (Vum) line 4 in any enter at gen/moar/m-Metamodel.nqp line 3947 in block \ at tt line 5

(Which points to the enter method of WrapDispatch.) Which would appear that it is not getting the appropriate Callable from .candidates[0]. With the "no precompilation" un-commented in Boo.pm this will work fine.

Just to check that this wasn't something mysterious in the MOP it can also be replicated with​:

lib/Wom.pm​:

module Wom { multi sub trait_mod​:\(Method $m, :$brapped!) is export { $m.wrap(method (|c) { say "wrapped"; callsame }); } }

lib/Bok.pm​:

use Wom;

#no precompilation;

class Bok { has $.rabble; method rack() is brapped { say "rabble : "; } }

And exercised with the similar script run with "perl6 -Ilib ..." :

use Bok;

my $b = Bok.new(rabble => "hoodoo");

say $b.rack;

Then this will also fail identically without the "no precompilation".

This afflicts OO​::Monitors in the ecosystem which cannot be used in a module that will be precompiled, and I suspect this is also at the heart of a problem with Staticish which similarly doesn't work if used in a module which is precompiled.

This is with​:

This is Rakudo version 2016.03-98-g61d231c built on MoarVM version 2016.03-84-g4afd7b6

p6rt commented 8 years ago

The RT System itself - Status changed from 'new' to 'open'

p6rt commented 8 years ago

From jns@gellyfish.co.uk

I'm actually surprised there are as few "Cannot invoke this object" tickets​:

https://rt.perl.org/Search/Simple.html?q=%22Cannot+invoke+this+object%2 2

A cursory survey of those would suggest that they all fall in a wider category of "code attribute of some type not surviving precompilation"

On Sat, 2016-04-09 at 03​:24 -0700, Lloyd Fournier via RT wrote​:

For reference this is another related to​:

https://rt.perl.org/Public/Bug/Display.html?id=125634

On Sat, Apr 9, 2016 at 7​:10 AM Jonathan Stowe \<perl6-bugs-followup@​pe rl.org> wrote​:

# New Ticket Created by  Jonathan Stowe # Please include the string​:  [perl #​127860] # in the subject line of all future correspondence about this issue. # \<URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127860 >

It appears that the Metamodel​::WrapDispatcher can't find the candidate to execute when the wrapped method is pre-compiled.

This can be recreated in several ways, first by wrapping the method in an over-ridden add_method​:

lib/Vum.pm​:

class MetamodelX​::FooHOW is Metamodel​::ClassHOW {     method add_method(Mu \type, $name, &code) {         say "adding $name";         my &wrapper = method (|c) { say "running $name"; callsame; };         &code.wrap( &wrapper );         self.Metamodel​::ClassHOW​::add_method(type, $name, &code);    }    method compose(Mu \type) {        self.Metamodel​::ClassHOW​::compose(type);    } }

my package EXPORTHOW {     package SUPERSEDE {        constant class = MetamodelX​::FooHOW;     } }

And lib/Boo.pm :

use Vum;

#no precompilation;

class Boo {    has $.rabble;    method rack() {       say "rabble : ";    } }

And exercised with "perl6 -Ilib ..."​:

use Boo;

my $b = Boo.new(rabble => "hoodoo");

say $b.rack;

This will fail with​:

Cannot invoke this object   in method \ at /home/jonathan/devel/perl6/Vum/lib/Vum.pm (Vum) line 4   in any enter at gen/moar/m-Metamodel.nqp line 3947   in block \ at tt line 5

(Which points to the enter method of WrapDispatch.) Which would appear that it is not getting the appropriate Callable from .candidates[0]. With the "no precompilation" un-commented in Boo.pm this will work fine.

Just to check that this wasn't something mysterious in the MOP it can also be replicated with​:

lib/Wom.pm​:

module Wom {    multi sub trait_mod​:\(Method $m, :$brapped!) is export {       $m.wrap(method (|c) { say "wrapped"; callsame });    } }

lib/Bok.pm​:

use Wom;

#no precompilation;

class Bok {    has $.rabble;    method rack() is brapped {       say "rabble : ";    } }

And exercised with the similar script run with "perl6 -Ilib ..." :

use Bok;

my $b = Bok.new(rabble => "hoodoo");

say $b.rack;

Then this will also fail identically without the "no precompilation".

This afflicts OO​::Monitors in the ecosystem which cannot be used in a module that will be precompiled, and I suspect this is also at the heart of a problem with Staticish which similarly doesn't work if used in a module which is precompiled.

This is with​:

This is Rakudo version 2016.03-98-g61d231c built on MoarVM version 2016.03-84-g4afd7b6