Class OwnershipStatements

java.lang.Object
org.ek9lang.compiler.phase7.support.OwnershipStatements

public final class OwnershipStatements extends Object
THE value-ownership statements of IR generation (D-O11, EK9_IR_OWNERSHIP_STAGE1_DESIGN.md §11) - hold one and call it, never build an OwnershipInstr by hand: each method states ONE ownership fact where a value is made, declared, stored or handed over, in the ownership form (OWN, DROP_AT_EXIT, SLOT_DECLARE, SLOT_ASSIGN, FIELD_ASSIGN). Phase 7 states ownership only this way; RETAIN, RELEASE and SCOPE_REGISTER are OwnershipLowering's output, never phase 7's (ratchet loweredOwnershipOpcodes).

Stateless: every scope it names is passed in. VariableMemoryManagement is the sibling that decides, for an evaluated value, whether the current scope owns it or borrows it, and states that through these.

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    armResultFresh(String chainResult, String value, DebugInfo debugInfo)
    THE move of a value just made, by one arm of a chain, into the chain's result - which is empty when an arm runs, since exactly one arm sets it (EK9_IR_OWNERSHIP_MODEL.md §4, merges): SLOT_ASSIGN r, v [consume, init], lowered to STORE r, v.
    borrowInScope(String variable, String scopeId, DebugInfo debugInfo)
    THE borrow with an explicit registration scope, for a body that pushes no frame (synthesis - tidy plan decision 3): a value that arrived at +0 (a CAST of a parameter, a LOAD) is owned for that scope and dropped at its exit.
    declaredOwnedSlot(String slot, String typeName, String scopeId, boolean typed, DebugInfo debugInfo)
    THE declaration of a compiler-made slot its scope owns and that nothing initialises where it is declared - it is only ever rebound (a stream join accumulator, a type-boundary out-variable): the scope releases its LAST value (A10).
    declaredSlot(String slot, String typeName, String owner, DebugInfo debugInfo)
    THE declaration of a named slot and of its owner: a local is owned by the scope that declares it, a parameter or returning variable by the CALLER (OwnershipInstr.CALLER), a property by its OBJECT (OwnershipInstr.OBJECT).
    droppedAtExit(String value, String scopeId, DebugInfo debugInfo)
    THE value-ownership function (D-O11, EK9_IR_OWNERSHIP_STAGE1_DESIGN.md §11): states, where a value is made, that the scope owns it - DROP_AT_EXIT, dropped at every exit of the scope's activation (lowered to SCOPE_REGISTER).
    escaping(String value, DebugInfo debugInfo)
    THE extra count a value takes so that it outlives the region it was evaluated in - a chain arm's value handed out as the chain's result while the arm's region still drops its own count (EK9_IR_OWNERSHIP_MODEL.md §4, an escape): OWN v.
    fieldAssigned(FieldTarget field, String value, OwnershipInstr.AssignMode mode, boolean init, DebugInfo debugInfo)
    THE store of a value into an object's FIELD (family 6): drop the field's old value and store the new one - [copy] takes the field's own reference to a value something else still owns, [consume] moves an owned value in; init is the fact that the field is empty here (a constructor's first store), so there is nothing to drop.
    handedOver(String target, String source, DebugInfo debugInfo)
    THE hand-over of a slot's value to another slot that is empty here, after which the source slot is done with: a control-flow expression's returning variable handed to the expression's result (J3).
    initialised(String slot, String value, DebugInfo debugInfo)
    THE first value of a local declared with one (x <- v): the slot takes its own reference to a value its scope still owns, and the declaring scope owns the slot.
    initialisedFresh(String slot, String value, DebugInfo debugInfo)
    THE first value of a local declared with a value just made (x <- Call()): the slot takes the producer's count, so the value is neither registered with a scope nor retained again (EK9_IR_OWNERSHIP_MODEL.md §6, [consume]).
    propertyAssigned(String property, String value, boolean init, DebugInfo debugInfo)
    THE store of a value into a PROPERTY named as a slot of its object (this.p): the property takes its own reference to a value something else still owns, and drops the value it replaces unless it is empty here (init, a property initialiser's first store).
    rebound(String slot, String value, DebugInfo debugInfo)
    THE rebinding of a slot that already holds a value - drop the old one, take a reference to the new one: SLOT_ASSIGN x, v [copy] (lowered: RELEASE x; STORE x, v; RETAIN x).
    reboundFresh(String slot, String value, DebugInfo debugInfo)
    THE rebinding of a slot to a value just made (x := Call()): drop the old value and move the new one in.
    returnFresh(String returnVariable, String value, DebugInfo debugInfo)
    THE move of a value just made into the returning variable: the return variable takes the producer's count, so the value is neither registered with a scope nor retained again (EK9_IR_OWNERSHIP_MODEL.md §6, [consume]).
    returnSlot(String returnVariable, String typeName, DebugInfo debugInfo)
    THE declaration of the return variable: owned by the CALLER, never released by a scope here - SLOT_DECLARE rtn, T, CALLER (lowered to REFERENCE rtn, T).
    storeReturn(String returnVariable, String value, DebugInfo debugInfo)
    THE store of a result into the returning variable (tidy plan 8a rule 3): SLOT_ASSIGN rtn, v [copy, init] - the return variable takes its own reference to a value its scope still owns, into a slot that is empty here - which lowers to exactly STORE rtn, v; RETAIN rtn.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • OwnershipStatements

      public OwnershipStatements()
  • Method Details

    • borrowInScope

      public List<IRInstr> borrowInScope(String variable, String scopeId, DebugInfo debugInfo)
      THE borrow with an explicit registration scope, for a body that pushes no frame (synthesis - tidy plan decision 3): a value that arrived at +0 (a CAST of a parameter, a LOAD) is owned for that scope and dropped at its exit. OWN v; DROP_AT_EXIT v, s - lowered to a RETAIN and a SCOPE_REGISTER.
      Parameters:
      variable - the borrowed value
      scopeId - the scope that releases it
      debugInfo - debug information
      Returns:
      the OWN and DROP_AT_EXIT
    • droppedAtExit

      public List<IRInstr> droppedAtExit(String value, String scopeId, DebugInfo debugInfo)
      THE value-ownership function (D-O11, EK9_IR_OWNERSHIP_STAGE1_DESIGN.md §11): states, where a value is made, that the scope owns it - DROP_AT_EXIT, dropped at every exit of the scope's activation (lowered to SCOPE_REGISTER). A freshly produced (+1) value only: the scope's drop consumes the producer's count, so it is never RETAINed as well (that is the borrow form, and on a producer it leaks one object per execution).
      Parameters:
      value - the produced value
      scopeId - the scope that owns it
      debugInfo - debug information
      Returns:
      the instruction stating the owner
    • declaredSlot

      public List<IRInstr> declaredSlot(String slot, String typeName, String owner, DebugInfo debugInfo)
      THE declaration of a named slot and of its owner: a local is owned by the scope that declares it, a parameter or returning variable by the CALLER (OwnershipInstr.CALLER), a property by its OBJECT (OwnershipInstr.OBJECT). SLOT_DECLARE x, T, owner - the owner's drop of the slot's current value is part of the declaration, so nothing registers the slot later. Every named variable has an owner (V-M).
      Parameters:
      slot - the variable
      typeName - its type
      owner - the declaring scope, OwnershipInstr.CALLER or OwnershipInstr.OBJECT
      debugInfo - debug information
      Returns:
      the declaration
    • declaredOwnedSlot

      public List<IRInstr> declaredOwnedSlot(String slot, String typeName, String scopeId, boolean typed, DebugInfo debugInfo)
      THE declaration of a compiler-made slot its scope owns and that nothing initialises where it is declared - it is only ever rebound (a stream join accumulator, a type-boundary out-variable): the scope releases its LAST value (A10). SLOT_DECLARE x, T, s [typed] (lowered: the declaration and SCOPE_REGISTER x, s straight after it).
    • initialised

      public List<IRInstr> initialised(String slot, String value, DebugInfo debugInfo)
      THE first value of a local declared with one (x <- v): the slot takes its own reference to a value its scope still owns, and the declaring scope owns the slot. SLOT_ASSIGN x, v [copy, init] (the owner is the declaredSlot(String, String, String, DebugInfo) declaration's); lowered to STORE x, v; RETAIN x.
      Parameters:
      slot - the declared local, empty here
      value - its first value
      debugInfo - debug information
      Returns:
      the instructions that initialise the slot
    • initialisedFresh

      public List<IRInstr> initialisedFresh(String slot, String value, DebugInfo debugInfo)
      THE first value of a local declared with a value just made (x <- Call()): the slot takes the producer's count, so the value is neither registered with a scope nor retained again (EK9_IR_OWNERSHIP_MODEL.md §6, [consume]). SLOT_ASSIGN x, v [consume, init] (lowered: STORE x, v and the declaration's SCOPE_REGISTER x, s).

      Only for a fresh (+1) value that nothing reads after this; the verifier (V-C) rejects a use after the move.

    • reboundFresh

      public List<IRInstr> reboundFresh(String slot, String value, DebugInfo debugInfo)
      THE rebinding of a slot to a value just made (x := Call()): drop the old value and move the new one in. SLOT_ASSIGN x, v [consume] (lowered: RELEASE x; STORE x, v). Only for a fresh (+1) value nothing reads after this.
    • storeReturn

      public List<IRInstr> storeReturn(String returnVariable, String value, DebugInfo debugInfo)
      THE store of a result into the returning variable (tidy plan 8a rule 3): SLOT_ASSIGN rtn, v [copy, init] - the return variable takes its own reference to a value its scope still owns, into a slot that is empty here - which lowers to exactly STORE rtn, v; RETAIN rtn. The value stays owned where it was made; rtn is never registered with a scope - its RETAIN is the +1 the caller receives.
      Parameters:
      returnVariable - the returning variable
      value - the (already owned) value it now holds
      debugInfo - debug information
      Returns:
      the SLOT_ASSIGN
    • returnFresh

      public List<IRInstr> returnFresh(String returnVariable, String value, DebugInfo debugInfo)
      THE move of a value just made into the returning variable: the return variable takes the producer's count, so the value is neither registered with a scope nor retained again (EK9_IR_OWNERSHIP_MODEL.md §6, [consume]). SLOT_ASSIGN rtn, v [consume, init], which lowers to a bare STORE rtn, v.

      Only for a fresh (+1) value that nothing reads after this; the verifier (V-C) rejects a use after the move.

      Parameters:
      returnVariable - the returning variable, empty here
      value - the value just made
      debugInfo - debug information
      Returns:
      the instructions that hand the value to the caller
    • rebound

      public List<IRInstr> rebound(String slot, String value, DebugInfo debugInfo)
      THE rebinding of a slot that already holds a value - drop the old one, take a reference to the new one: SLOT_ASSIGN x, v [copy] (lowered: RELEASE x; STORE x, v; RETAIN x). An accumulator (rtn built up field by field) is the common case.
    • escaping

      public List<IRInstr> escaping(String value, DebugInfo debugInfo)
      THE extra count a value takes so that it outlives the region it was evaluated in - a chain arm's value handed out as the chain's result while the arm's region still drops its own count (EK9_IR_OWNERSHIP_MODEL.md §4, an escape): OWN v.
    • handedOver

      public List<IRInstr> handedOver(String target, String source, DebugInfo debugInfo)
      THE hand-over of a slot's value to another slot that is empty here, after which the source slot is done with: a control-flow expression's returning variable handed to the expression's result (J3). The target takes the source's count - SLOT_ASSIGN target, source [consume, init], lowered to STORE target, source (the model's reserved SLOT_TAKE then a move, written as one assignment: nothing drops the source after it).
    • armResultFresh

      public List<IRInstr> armResultFresh(String chainResult, String value, DebugInfo debugInfo)
      THE move of a value just made, by one arm of a chain, into the chain's result - which is empty when an arm runs, since exactly one arm sets it (EK9_IR_OWNERSHIP_MODEL.md §4, merges): SLOT_ASSIGN r, v [consume, init], lowered to STORE r, v.

      Only for a fresh (+1) value that nothing reads after this; the verifier (V-C) rejects a use after the move.

    • fieldAssigned

      public List<IRInstr> fieldAssigned(FieldTarget field, String value, OwnershipInstr.AssignMode mode, boolean init, DebugInfo debugInfo)
      THE store of a value into an object's FIELD (family 6): drop the field's old value and store the new one - [copy] takes the field's own reference to a value something else still owns, [consume] moves an owned value in; init is the fact that the field is empty here (a constructor's first store), so there is nothing to drop. FIELD_ASSIGN, lowered to [RELEASE_FIELD;] STORE_FIELD[; RETAIN v] - the value retained AFTER the store, never the "pre-take" RETAIN before it (equivalent, as nothing can throw between them; EK9_IR_OWNERSHIP_MODEL.md §6).
      Parameters:
      field - the field stored into
      value - the value stored
      mode - consume or copy
      init - the field is provably empty here
      debugInfo - debug information
      Returns:
      the instructions that store the field
    • returnSlot

      public List<IRInstr> returnSlot(String returnVariable, String typeName, DebugInfo debugInfo)
      THE declaration of the return variable: owned by the CALLER, never released by a scope here - SLOT_DECLARE rtn, T, CALLER (lowered to REFERENCE rtn, T).
    • propertyAssigned

      public List<IRInstr> propertyAssigned(String property, String value, boolean init, DebugInfo debugInfo)
      THE store of a value into a PROPERTY named as a slot of its object (this.p): the property takes its own reference to a value something else still owns, and drops the value it replaces unless it is empty here (init, a property initialiser's first store). SLOT_ASSIGN this.p, v [copy] - lowered to RELEASE this.p; STORE this.p, v; RETAIN this.p. Its owner is the OBJECT (OwnershipInstr.OBJECT, declared by the property's SLOT_DECLARE); a field stored through STORE_FIELD is fieldAssigned(FieldTarget, String, OwnershipInstr.AssignMode, boolean, DebugInfo).