@@ -235,24 +235,43 @@ class NQP::World is HLL::World {
235
235
else {
236
236
$ dummy := pir::clone__PP($ stub_code );
237
237
pir::assign__vPS($ dummy , $ name );
238
- if $ is_dispatcher && ! $ NEW_SER {
238
+ if $ is_dispatcher {
239
239
# The dispatcher will get cloned if more candidates are added in
240
240
# 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
+ }
256
275
}
257
276
if $ NEW_SER {
258
277
pir::setprop__vPsP($ dummy , ' STATIC_CODE_REF' , $ dummy );
@@ -281,8 +300,8 @@ class NQP::World is HLL::World {
281
300
self . get_slot_past_for_object($ dummy ),
282
301
PAST::Val. new ( : value($ past ) )
283
302
));
284
- self . add_fixup_task(: fixup_past($ fixups ));
285
303
}
304
+ self . add_fixup_task(: fixup_past($ fixups ));
286
305
287
306
# If it's a dispatcher, now need to wrap it in a code object,
288
307
# so we have a place to store the dispatch list.
@@ -313,14 +332,24 @@ class NQP::World is HLL::World {
313
332
: pirop(' set_sub_code_object vPP' ),
314
333
PAST::Val. new ( : value($ past ) ),
315
334
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
+ ))));
322
336
}
323
337
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
+
324
353
$ code_obj
325
354
}
326
355
else {
0 commit comments