Definite initialization implementation for property behaviors


(Joe Groff) #1

Hey Chris (and interested onlookers). I wanted your feedback on how to handle definite initialization with property behaviors. Behavior properties behave a lot like computed properties, so it's tricky to track their initialization behavior with our traditional storage-based analysis. For initialization purposes, the behavior property acts kind of like a proxy for the instantiated storage from the behavior declaration. For instance, if you have an `NSCopying` behavior, then an assignment that initializes the behavior property should trigger the `init` logic for the underlying storage, invoking `.copy()` on the initial value. I'm thinking we can represent this in raw SIL with a `mark_uninitialized_behavior` instruction that abstractly represents the behavior property, with references to its storage and its initialization/setter logic:

  // Build references to the behavior's initializer and setter
  %init = function_ref @NSCopying.init
  %set = function_ref @NSCopying.set
  // Get the address of the storage
  %storage = ref_element_addr %self, #Type.property.[NSCopying].storage
  // Build the initialization marker
  %property = mark_uninitialized_behavior %self, %storage, init %init, set %set
  ...
  // Initialization
  assign %a to %property
  // Reassignment
  assign %b to %property

DI would then turn `assign`-ments that initialize %property into `apply %init(%storage)`, and reassignments into `apply %set(%self)`. Does that seem like a reasonable implementation approach?

-Joe


(Chris Lattner) #2

Hey Chris (and interested onlookers). I wanted your feedback on how to handle definite initialization with property behaviors. Behavior properties behave a lot like computed properties, so it's tricky to track their initialization behavior with our traditional storage-based analysis. For initialization purposes, the behavior property acts kind of like a proxy for the instantiated storage from the behavior declaration. For instance, if you have an `NSCopying` behavior, then an assignment that initializes the behavior property should trigger the `init` logic for the underlying storage, invoking `.copy()` on the initial value. I'm thinking we can represent this in raw SIL with a `mark_uninitialized_behavior` instruction that abstractly represents the behavior property,

This makes sense to me.

with references to its storage and its initialization/setter logic:

// Build references to the behavior's initializer and setter
%init = function_ref @NSCopying.init
%set = function_ref @NSCopying.set
// Get the address of the storage
%storage = ref_element_addr %self, #Type.property.[NSCopying].storage
// Build the initialization marker
%property = mark_uninitialized_behavior %self, %storage, init %init, set %set

Ah, I see why you can’t reuse the existing mark_uninitialized instruction with another mode. I agree with adding a new mark_uninitialized_behavior instruction, this is a very clever way to handle this!

...
// Initialization
assign %a to %property
// Reassignment
assign %b to %property

DI would then turn `assign`-ments that initialize %property into `apply %init(%storage)`, and reassignments into `apply %set(%self)`. Does that seem like a reasonable implementation approach?

It does! Very nice,

-Chris

···

On Mar 2, 2016, at 9:24 AM, Joe Groff <jgroff@apple.com> wrote: