Skip to content
This repository
Browse code

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
Jonathan Worthington authored February 21, 2012

Showing 1 changed file with 38 additions and 24 deletions. Show diff stats Hide diff stats

  1. 62  src/NQP/World.pm
62  src/NQP/World.pm
@@ -11,6 +11,11 @@ class NQP::World is HLL::World {
11 11
     # to a list of code objects.
12 12
     has %!code_objects_to_fix_up;
13 13
     
  14
+    # Mapping of PAST::Stmts node containing fixups, keyed by sub ID. If
  15
+    # we do dynamic compilation then we do the fixups immediately and
  16
+    # then clear this list.
  17
+    has %!code_object_fixup_list;
  18
+    
14 19
     # Creates a new lexical scope and puts it on top of the stack.
15 20
     method push_lexpad($/) {
16 21
         # Create pad, link to outer and add to stack.
@@ -214,6 +219,7 @@ class NQP::World is HLL::World {
214 219
             # list.
215 220
             if $have_code_type {
216 221
                 %!code_objects_to_fix_up{$past.subid()} := [$dummy];
  222
+                %!code_object_fixup_list{$past.subid()} := $fixups;
217 223
                 if self.is_precompilation_mode() {
218 224
                     pir::setprop__vPsP($dummy, 'CLONE_CALLBACK', sub ($orig, $clone, $code_obj) {
219 225
                         %!code_objects_to_fix_up{$past.subid()}.push($code_obj);
@@ -222,19 +228,18 @@ class NQP::World is HLL::World {
222 228
                 else {
223 229
                     pir::setprop__vPsP($dummy, 'CLONE_CALLBACK', sub ($orig, $clone, $code_obj) {
224 230
                         # Emit fixup code.
225  
-                        my $clone_idx := self.add_root_code_ref($clone, $past);
226 231
                         self.add_object($code_obj);
227  
-                        $fixups.push(PAST::Stmts.new(
228  
-                            PAST::Op.new(
229  
-                                :pirop('assign vPP'),
230  
-                                self.get_slot_past_for_code_ref_at($clone_idx),
231  
-                                PAST::Val.new( :value(pir::getprop__PsP('PAST', $orig)) )
232  
-                            ),
  232
+                        $fixups.push(PAST::Op.new(
  233
+                            :pirop('setattribute vPPsP'),
  234
+                            self.get_ref($code_obj),
  235
+                            self.get_ref($code_type),
  236
+                            '$!do',
233 237
                             PAST::Op.new(
234  
-                                :pirop('set_sub_code_object vPP'),
235  
-                                self.get_slot_past_for_code_ref_at($clone_idx),
  238
+                                :pirop('set_sub_code_object 0PP'),
  239
+                                PAST::Op.new( :pirop('clone PP'), PAST::Val.new( :value($past) ) ),
236 240
                                 self.get_ref($code_obj)
237  
-                            )));
  241
+                            )
  242
+                        ));
238 243
                             
239 244
                         # Add to dynamic compilation fixup list.
240 245
                         %!code_objects_to_fix_up{$past.subid()}.push($code_obj);
@@ -243,14 +248,7 @@ class NQP::World is HLL::World {
243 248
             }
244 249
         }
245 250
         
246  
-        # For fixup, need to assign the method body we actually compiled
247  
-        # onto the one that went into the SC.
248  
-        $fixups.push(PAST::Op.new(
249  
-            :pirop('assign vPP'),
250  
-            self.get_slot_past_for_code_ref_at($code_ref_idx),
251  
-            PAST::Val.new( :value($past) )
252  
-        ));
253  
-        
  251
+        # Add fixups task node; it'll get populated or cleared during the compile.
254 252
         self.add_fixup_task(:fixup_past($fixups));
255 253
         
256 254
         # Provided we have the code type, now wrap what we have up in a
@@ -263,22 +261,38 @@ class NQP::World is HLL::World {
263 261
                 if $is_dispatcher;
264 262
             my $slot := self.add_object($code_obj);
265 263
 
266  
-            # Add fixup task.
  264
+            # Add deserialization fixup task.
267 265
             self.add_fixup_task(
268 266
                 :deserialize_past(PAST::Op.new(
269 267
                     :pirop('set_sub_code_object vPP'),
270 268
                     PAST::Val.new( :value($past) ),
271 269
                     self.get_ref($code_obj)
272  
-                )),
273  
-                :fixup_past(PAST::Op.new(
274  
-                    :pirop('set_sub_code_object vPP'),
275  
-                    self.get_slot_past_for_code_ref_at($code_ref_idx),
276  
-                    self.get_ref($code_obj)
277 270
                 )));
278 271
             
  272
+            # Add fixup of the code object and the $!do attribute.
  273
+            $fixups.push(PAST::Op.new(
  274
+                :pirop('setattribute vPPsP'),
  275
+                self.get_ref($code_obj),
  276
+                self.get_ref($code_type),
  277
+                '$!do',
  278
+                PAST::Val.new( :value($past) )
  279
+            ));
  280
+            $fixups.push(PAST::Op.new(
  281
+                :pirop('set_sub_code_object vPP'),
  282
+                PAST::Val.new( :value($past) ),
  283
+                self.get_ref($code_obj)
  284
+            ));
  285
+            
279 286
             $code_obj
280 287
         }
281 288
         else {
  289
+            # For fixup, if we have no code body, we need to assign the method body
  290
+            # we actually compiled into the one that went into the SC.
  291
+            $fixups.push(PAST::Op.new(
  292
+                :pirop('assign vPP'),
  293
+                self.get_slot_past_for_code_ref_at($code_ref_idx),
  294
+                PAST::Val.new( :value($past) )
  295
+            ));
282 296
             return $dummy;
283 297
         }
284 298
     }

0 notes on commit 92b0fbc

Please sign in to comment.
Something went wrong with that request. Please try again.