Skip to content

Commit

Permalink
Fix native subs declared in BEGIN blocks and role bodies
Browse files Browse the repository at this point in the history
When a native sub was declared within a BEGIN block or a role body, the
replacement code body did not stick but was replaced with the original stub
when the containing block was compiled dynamically.

Fix by removing the code object from the map of objects needing fixup.
Fixes GH #3235 and #3243
  • Loading branch information
niner committed Oct 18, 2019
1 parent 9f1794c commit e45bb34
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
15 changes: 13 additions & 2 deletions lib/NativeCall.pm6
Expand Up @@ -564,8 +564,12 @@ our role Native[Routine $r, $libname where Str|Callable|List|IO::Path|Distributi

method setup-nativecall() {
$!name = self.name;

# finish compilation of the original routine so our changes won't
# become undone right afterwards
my Mu \compstuff := nqp::getattr(self, Code, q<@!compstuff>);
compstuff[1]() unless nqp::isnull(compstuff);

my $replacement := -> |args {
self.create-optimized-call() unless
$!optimized-body # Already have the optimized body
Expand All @@ -578,8 +582,15 @@ our role Native[Routine $r, $libname where Str|Callable|List|IO::Path|Distributi

nqp::nativecall($!rettype, self, $args)
};
nqp::bindattr(self, Code, '$!do', nqp::getattr($replacement, Code, '$!do'));
nqp::setcodename(nqp::getattr(self, Code, '$!do'), $!name);

if $*W { # prevent compile_in_context from undoing our replacement
my $cuid := nqp::getcodecuid(nqp::getattr(self, Code, '$!do'));
nqp::deletekey($*W.context().sub_id_to_code_object(), $cuid);
}

my $do := nqp::getattr($replacement, Code, '$!do');
nqp::bindattr(self, Code, '$!do', $do);
nqp::setcodename($do, $!name);
}
}

Expand Down
20 changes: 19 additions & 1 deletion t/04-nativecall/00-misc.t
@@ -1,10 +1,28 @@
use lib <t/packages/ t/04-nativecall lib>;
use NativeCall;
use Test;
use Test::Helpers;
use CompileTestLib;
compile_test_lib '00-misc';

plan 1;
plan 3;

{ # https://github.com/rakudo/rakudo/issues/3235
role Foo {
sub calloc(size_t, size_t --> Pointer) is native(Str) { !!! };
method test() {
calloc(1, 1)
}
};

isa-ok Foo.test, Pointer;

my &calloc := BEGIN {
sub calloc(size_t, size_t --> Pointer) is native(Str) { !!! };
};

isa-ok calloc(1, 1), Pointer;
}

{ # https://github.com/rakudo/rakudo/issues/1576
(my $dir := make-temp-dir).add('Foo.pm6').spurt:
Expand Down

0 comments on commit e45bb34

Please sign in to comment.