Skip to content

Commit

Permalink
Fix handling of generic method names.
Browse files Browse the repository at this point in the history
On JVM (and MoarVM, for that matter) the name associated with a code
object is stored statically, not in the actual code ref itself like on
Parrot. This is generally more efficient (saves a field in closures),
but we relied on it. This prevented declaring more than one user
defined operator in Rakudo on JVM, which busted various tests. On
Parrot, we keep the same approach as today.
  • Loading branch information
jnthn committed Jul 6, 2013
1 parent 3fbb512 commit 445550b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
51 changes: 51 additions & 0 deletions src/core/NQPRoutine.nqp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,32 @@ my knowhow NQPRoutine {
nqp::setcodename($!do, $name);
}

method !reify_name($name) {
#?if parrot
nqp::setcodename($!do, $name);
self
#?endif
#?if !parrot
# Make a fresh underlying VM code ref.
my $do := nqp::freshcoderef($!do);

# Clone and attach the code object.
my $der := nqp::clone(self);
nqp::bindattr($der, NQPRoutine, '$!do', $do);
nqp::setcodeobj($do, $der);

# If needed, arrange for a fixup of the cloned code-ref.
unless nqp::isnull($!clone_callback) {
$!clone_callback($!do, $do, $der);
}

# Update name.
nqp::setcodename($do, $name);

$der
#?endif
}

method name() {
nqp::getcodename($!do)
}
Expand Down Expand Up @@ -458,6 +484,31 @@ my knowhow NQPRegex {
method !set_name($name) {
nqp::setcodename($!do, $name);
}
method !reify_name($name) {
#?if parrot
nqp::setcodename($!do, $name);
self
#?endif
#?if !parrot
# Make a fresh underlying VM code ref.
my $do := nqp::freshcoderef($!do);

# Clone and attach the code object.
my $der := nqp::clone(self);
nqp::bindattr($der, NQPRegex, '$!do', $do);
nqp::setcodeobj($do, $der);

# If needed, arrange for a fixup of the cloned code-ref.
unless nqp::isnull($!clone_callback) {
$!clone_callback($!do, $do, $der);
}

# Update name.
nqp::setcodename($do, $name);

$der
#?endif
}
}
nqp::setinvokespec(NQPRegex, NQPRegex, '$!do', nqp::null);
nqp::setboolspec(NQPRegex, 5, nqp::null());
2 changes: 1 addition & 1 deletion src/how/NQPParametricRoleHOW.nqp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ knowhow NQPParametricRoleHOW {
!! nqp::iterval($_).clone();
if nqp::substr($name, 0, 12) eq '!!LATENAME!!' {
$name := nqp::atkey($pad, nqp::substr($name, 12));
$meth.'!set_name'($name);
$meth := $meth.'!reify_name'($name);
}
$irole.HOW.add_method($irole, $name, $meth);
}
Expand Down

0 comments on commit 445550b

Please sign in to comment.