Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Bring the code object fixup mechanism in line with the one in Rakudo …

…(essentially, it fixes up by setting the $!do rather than mucking round with assign vtable).
  • Loading branch information...
commit 92b0fbc812491751062c4797579c77397eaf9aa3 1 parent b9e1d10
@jnthn jnthn authored
Showing with 38 additions and 24 deletions.
  1. +38 −24 src/NQP/World.pm
View
62 src/NQP/World.pm
@@ -11,6 +11,11 @@ class NQP::World is HLL::World {
# to a list of code objects.
has %!code_objects_to_fix_up;
+ # Mapping of PAST::Stmts node containing fixups, keyed by sub ID. If
+ # we do dynamic compilation then we do the fixups immediately and
+ # then clear this list.
+ has %!code_object_fixup_list;
+
# Creates a new lexical scope and puts it on top of the stack.
method push_lexpad($/) {
# Create pad, link to outer and add to stack.
@@ -214,6 +219,7 @@ class NQP::World is HLL::World {
# list.
if $have_code_type {
%!code_objects_to_fix_up{$past.subid()} := [$dummy];
+ %!code_object_fixup_list{$past.subid()} := $fixups;
if self.is_precompilation_mode() {
pir::setprop__vPsP($dummy, 'CLONE_CALLBACK', sub ($orig, $clone, $code_obj) {
%!code_objects_to_fix_up{$past.subid()}.push($code_obj);
@@ -222,19 +228,18 @@ class NQP::World is HLL::World {
else {
pir::setprop__vPsP($dummy, 'CLONE_CALLBACK', sub ($orig, $clone, $code_obj) {
# Emit fixup code.
- my $clone_idx := self.add_root_code_ref($clone, $past);
self.add_object($code_obj);
- $fixups.push(PAST::Stmts.new(
- PAST::Op.new(
- :pirop('assign vPP'),
- self.get_slot_past_for_code_ref_at($clone_idx),
- PAST::Val.new( :value(pir::getprop__PsP('PAST', $orig)) )
- ),
+ $fixups.push(PAST::Op.new(
+ :pirop('setattribute vPPsP'),
+ self.get_ref($code_obj),
+ self.get_ref($code_type),
+ '$!do',
PAST::Op.new(
- :pirop('set_sub_code_object vPP'),
- self.get_slot_past_for_code_ref_at($clone_idx),
+ :pirop('set_sub_code_object 0PP'),
+ PAST::Op.new( :pirop('clone PP'), PAST::Val.new( :value($past) ) ),
self.get_ref($code_obj)
- )));
+ )
+ ));
# Add to dynamic compilation fixup list.
%!code_objects_to_fix_up{$past.subid()}.push($code_obj);
@@ -243,14 +248,7 @@ class NQP::World is HLL::World {
}
}
- # For fixup, need to assign the method body we actually compiled
- # onto the one that went into the SC.
- $fixups.push(PAST::Op.new(
- :pirop('assign vPP'),
- self.get_slot_past_for_code_ref_at($code_ref_idx),
- PAST::Val.new( :value($past) )
- ));
-
+ # Add fixups task node; it'll get populated or cleared during the compile.
self.add_fixup_task(:fixup_past($fixups));
# Provided we have the code type, now wrap what we have up in a
@@ -263,22 +261,38 @@ class NQP::World is HLL::World {
if $is_dispatcher;
my $slot := self.add_object($code_obj);
- # Add fixup task.
+ # Add deserialization fixup task.
self.add_fixup_task(
:deserialize_past(PAST::Op.new(
:pirop('set_sub_code_object vPP'),
PAST::Val.new( :value($past) ),
self.get_ref($code_obj)
- )),
- :fixup_past(PAST::Op.new(
- :pirop('set_sub_code_object vPP'),
- self.get_slot_past_for_code_ref_at($code_ref_idx),
- self.get_ref($code_obj)
)));
+ # Add fixup of the code object and the $!do attribute.
+ $fixups.push(PAST::Op.new(
+ :pirop('setattribute vPPsP'),
+ self.get_ref($code_obj),
+ self.get_ref($code_type),
+ '$!do',
+ PAST::Val.new( :value($past) )
+ ));
+ $fixups.push(PAST::Op.new(
+ :pirop('set_sub_code_object vPP'),
+ PAST::Val.new( :value($past) ),
+ self.get_ref($code_obj)
+ ));
+
$code_obj
}
else {
+ # For fixup, if we have no code body, we need to assign the method body
+ # we actually compiled into the one that went into the SC.
+ $fixups.push(PAST::Op.new(
+ :pirop('assign vPP'),
+ self.get_slot_past_for_code_ref_at($code_ref_idx),
+ PAST::Val.new( :value($past) )
+ ));
return $dummy;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.