Skip to content

Commit 08757d6

Browse files
committed
Various fixes to handling of code refs. NQP with the serializer now passes all of t\nqp. \o/ Doesn't mean were there yet, mind; role serialization is still busted, meaning that QRegex can't be compiled. But...closer.
1 parent 25e15e6 commit 08757d6

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

src/NQP/World.pm

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -235,24 +235,43 @@ class NQP::World is HLL::World {
235235
else {
236236
$dummy := pir::clone__PP($stub_code);
237237
pir::assign__vPS($dummy, $name);
238-
if $is_dispatcher && !$NEW_SER {
238+
if $is_dispatcher {
239239
# The dispatcher will get cloned if more candidates are added in
240240
# a subclass; this makes sure that we fix up the clone also.
241-
pir::setprop__vPsP($dummy, 'CLONE_CALLBACK', sub ($orig, $clone, $dispatcher_code_obj) {
242-
self.add_code_LEGACY($clone);
243-
self.add_object($dispatcher_code_obj);
244-
$fixups.push(PAST::Stmts.new(
245-
PAST::Op.new(
246-
:pirop('assign vPP'),
247-
self.get_slot_past_for_object($clone),
248-
PAST::Val.new( :value(pir::getprop__PsP('PAST', $orig)) )
249-
),
250-
PAST::Op.new(
251-
:pirop('set_sub_code_object vPP'),
252-
self.get_slot_past_for_object($clone),
253-
self.get_ref($dispatcher_code_obj)
254-
)));
255-
});
241+
if $NEW_SER && !self.is_precompilation_mode() {
242+
pir::setprop__vPsP($dummy, 'CLONE_CALLBACK', sub ($orig, $clone, $dispatcher_code_obj) {
243+
my $clone_idx := self.add_root_code_ref($clone, $past);
244+
self.add_object($dispatcher_code_obj);
245+
$fixups.push(PAST::Stmts.new(
246+
PAST::Op.new(
247+
:pirop('assign vPP'),
248+
self.get_slot_past_for_code_ref_at($clone_idx),
249+
PAST::Val.new( :value(pir::getprop__PsP('PAST', $orig)) )
250+
),
251+
PAST::Op.new(
252+
:pirop('set_sub_code_object vPP'),
253+
self.get_slot_past_for_code_ref_at($clone_idx),
254+
self.get_ref($dispatcher_code_obj)
255+
)));
256+
});
257+
}
258+
elsif !$NEW_SER {
259+
pir::setprop__vPsP($dummy, 'CLONE_CALLBACK', sub ($orig, $clone, $dispatcher_code_obj) {
260+
self.add_code_LEGACY($clone);
261+
self.add_object($dispatcher_code_obj);
262+
$fixups.push(PAST::Stmts.new(
263+
PAST::Op.new(
264+
:pirop('assign vPP'),
265+
self.get_slot_past_for_object($clone),
266+
PAST::Val.new( :value(pir::getprop__PsP('PAST', $orig)) )
267+
),
268+
PAST::Op.new(
269+
:pirop('set_sub_code_object vPP'),
270+
self.get_slot_past_for_object($clone),
271+
self.get_ref($dispatcher_code_obj)
272+
)));
273+
});
274+
}
256275
}
257276
if $NEW_SER {
258277
pir::setprop__vPsP($dummy, 'STATIC_CODE_REF', $dummy);
@@ -281,8 +300,8 @@ class NQP::World is HLL::World {
281300
self.get_slot_past_for_object($dummy),
282301
PAST::Val.new( :value($past) )
283302
));
284-
self.add_fixup_task(:fixup_past($fixups));
285303
}
304+
self.add_fixup_task(:fixup_past($fixups));
286305

287306
# If it's a dispatcher, now need to wrap it in a code object,
288307
# so we have a place to store the dispatch list.
@@ -313,14 +332,24 @@ class NQP::World is HLL::World {
313332
:pirop('set_sub_code_object vPP'),
314333
PAST::Val.new( :value($past) ),
315334
self.get_ref($code_obj)
316-
))),
317-
:fixup_past(PAST::Op.new(
318-
:pirop('set_sub_code_object vPP'),
319-
self.get_slot_past_for_object($dummy),
320-
self.get_ref($code_obj)
321-
)));
335+
))));
322336
}
323337

338+
# Add fixup task.
339+
self.add_fixup_task(
340+
:deserialize_past(PAST::Op.new(
341+
:pirop('set_sub_code_object vPP'),
342+
PAST::Val.new( :value($past) ),
343+
self.get_ref($code_obj)
344+
)),
345+
:fixup_past(PAST::Op.new(
346+
:pirop('set_sub_code_object vPP'),
347+
($NEW_SER ??
348+
self.get_slot_past_for_code_ref_at($code_ref_idx) !!
349+
self.get_slot_past_for_object($dummy)),
350+
self.get_ref($code_obj)
351+
)));
352+
324353
$code_obj
325354
}
326355
else {

0 commit comments

Comments
 (0)