@@ -215,7 +215,7 @@ class NQP::World is HLL::World {
215
215
# Registers a code object, and gives it a dynamic compilation thunk.
216
216
# Makes a real code object if it's a dispatcher.
217
217
method create_code ($ past , $ name , $ is_dispatcher ) {
218
- # For methods , we need a "stub" that we'll clone and use for the
218
+ # For code refs , we need a "stub" that we'll clone and use for the
219
219
# compile-time representation. If it ever gets invoked it'll go
220
220
# and compile the code and run it.
221
221
# XXX Lexical environment.
@@ -233,13 +233,7 @@ class NQP::World is HLL::World {
233
233
$ dummy := $ past <compile_time_dummy >;
234
234
}
235
235
else {
236
- # What we create depends on whether it's a dispatcher or not.
237
- # If it is a dispatcher, set the PMC type it uses and then use
238
- # that for the dummy.
239
- if $ is_dispatcher {
240
- $ past . pirflags(' :instanceof("DispatcherSub")' );
241
- $ dummy := pir::assign__0PP(pir::new__Ps(' DispatcherSub' ), $ stub_code );
242
-
236
+ if $ is_dispatcher && ! $ NEW_SER {
243
237
# The dispatcher will get cloned if more candidates are added in
244
238
# a subclass; this makes sure that we fix up the clone also.
245
239
pir::setprop__vPsP($ dummy , ' CLONE_CALLBACK' , sub ($ orig , $ clone ) {
@@ -251,9 +245,7 @@ class NQP::World is HLL::World {
251
245
));
252
246
});
253
247
}
254
- else {
255
- $ dummy := pir::clone__PP($ stub_code );
256
- }
248
+ $ dummy := pir::clone__PP($ stub_code );
257
249
pir::assign__vPS($ dummy , $ name );
258
250
if $ NEW_SER {
259
251
pir::setprop__vPsP($ dummy , ' STATIC_CODE_REF' , $ dummy );
@@ -269,8 +261,7 @@ class NQP::World is HLL::World {
269
261
pir::setprop__vPsP($ dummy , ' PAST' , $ past );
270
262
271
263
# For fixup, need to assign the method body we actually compiled
272
- # onto the one that went into the SC. Deserializing is easier -
273
- # just the straight meta-method call.
264
+ # onto the one that went into the SC.
274
265
if $ NEW_SER {
275
266
$ fixups . push (PAST::Op. new (
276
267
: pirop(' assign vPP' ),
@@ -286,8 +277,39 @@ class NQP::World is HLL::World {
286
277
self . add_fixup_task(: fixup_past($ fixups ));
287
278
}
288
279
289
- # Hand back the code object.
290
- return $ dummy ;
280
+ # If it's a dispatcher, now need to wrap it in a code object,
281
+ # so we have a place to store the dispatch list.
282
+ if $ is_dispatcher {
283
+ # Create it now.
284
+ my $ code_type := self . find_sym([' NQPRoutine' ]);
285
+ my $ code_obj := nqp ::create($ code_type );
286
+ nqp ::bindattr($ code_obj , $ code_type , ' $!do' , $ dummy );
287
+ nqp ::bindattr($ code_obj , $ code_type , ' $!dispatchees' , nqp ::list());
288
+ my $ slot := self . add_object($ code_obj );
289
+
290
+ # Deserialization code.
291
+ unless $ NEW_SER {
292
+ self . add_fixup_task(: deserialize_past(PAST::Stmts. new (
293
+ self . add_object_to_cur_sc_past($ slot ,
294
+ PAST::Op. new ( : pirop(' repr_instance_of__PP' ), self . get_ref($ code_type ) )),
295
+ PAST::Op. new ( : pirop(' setattribute__vPPsP' ),
296
+ self . get_ref($ code_obj ),
297
+ self . get_ref($ code_type ),
298
+ ' $!do' ,
299
+ PAST::Val. new ( : value($ past ) )),
300
+ PAST::Op. new ( : pirop(' setattribute__vPPsP' ),
301
+ self . get_ref($ code_obj ),
302
+ self . get_ref($ code_type ),
303
+ ' $!dispatchees' ,
304
+ PAST::Op. new ( : pasttype(' list' ) ))
305
+ )));
306
+ }
307
+
308
+ $ code_obj
309
+ }
310
+ else {
311
+ return $ dummy ;
312
+ }
291
313
}
292
314
293
315
# Creates a meta-object for a package, adds it to the root objects and
@@ -365,9 +387,9 @@ class NQP::World is HLL::World {
365
387
# Deserialization code - goes away with new serializer.
366
388
unless $ NEW_SER {
367
389
my $ slot_past := self . get_slot_past_for_object($ obj );
368
- my $ code_past := pir::getprop__PsP(' PAST' , $ code ) ??
369
- PAST::Val . new ( : value(pir::getprop__PsP( ' PAST ' , $ code )) ) !!
370
- self . get_slot_past_for_object( $ code );
390
+ my $ code_past := nqp ::isnull( pir::getprop__PsP(' PAST' , $ code ) ) ??
391
+ self . get_slot_past_for_object( $ code ) !!
392
+ PAST::Val . new ( : value(pir::getprop__PsP( ' PAST ' , $ code )) );
371
393
self . add_fixup_task(
372
394
: deserialize_past(PAST::Op. new (
373
395
: pasttype(' callmethod' ), : name($ meta_method_name ),
0 commit comments