Library Sem_Heap


Semantics of heap instructions

@author Patryk Czarnik, Jacek Chrząszcz

Require Import Logic.
Require Import Relations.
Require Import List.
Require Import Common.
Require Import ValuesNTypes.
Require Import ProgramStructures.
Require Import Heap.
Require Import ZArith.
Require Import Program.
Require Import RuntimeStructures.
Require Import AllStructures.
Require Import Sem_Monitor.

Module of this type provides detailed semantics of heap instructions THeapInstr.
Module Type SEM_HEAP.
  Declare Module M_AllStructures : ALL_STRUCTURES.

  Declare Module M_Sem_Monitor : SEM_MONITOR
    with Module M_AllStructures := M_AllStructures.

  Import M_AllStructures.
  Import M_Program.M_ProgramStructures.M_ValuesAndTypes.
  Import M_Program.M_ProgramStructures.
  Import M_ProgramStructuresFacts.
  Import M_Program.
  Import M_RuntimeStructures.M_Heap.
  Import M_RuntimeStructures.

  Open Local Scope Z_scope.
  Import List.ListNotations.

  Inductive semGet: TGetOpTProgramTThreadIdTHeap → (list TValue) → TResultOrException (list TValue) → Prop :=
  | SemGet_getstatic: cn field p thid h v,

    getStaticField h thid cn field = Some v
    semGet (Op_getstatic cn field) p thid h [] (Result [v])

  | SemGet_getfield: cn field p thid h loc obj v,
    
    
    loc null
    get h thid loc = HV_Object obj
    getObjectField obj field = Some v
    semGet (Op_getfield cn field) p thid h [VRef loc] (Result [v])

  | SemGet_getfield_null: cn fn p thid h,
    semGet (Op_getfield cn fn) p thid h [VRef null] (Exception StandardNames.NullPointerException)

  | SemGet_array: aik t p thid h loc size arr idx v av,
    loc null
    get h thid loc = HV_Array arr
    getArrayComponentType arr = t
    arrayKindOfType t = aik
    kindOfValue v = kindOfArrayKind aik
    getArraySize arr = size
    validIndex size idx
    getArrayCell arr idx = Some av
    transformAToValue av = v
    semGet (Op_getarray aik) p thid h [VInt idx; VRef loc] (Result [v])

  | SemGet_array_null: aik p thid h idx,
    semGet (Op_getarray aik) p thid h [VInt idx; VRef null] (Exception StandardNames.NullPointerException)

  | SemGet_array_out: aik t p thid h loc size arr idx,
    loc null
    get h thid loc = HV_Array arr
    getArrayComponentType arr = t
    arrayKindOfType t = aik
    getArraySize arr = size
    ¬ validIndex size idx
    semGet (Op_getarray aik) p thid h [VInt idx; VRef loc] (Exception StandardNames.ArrayIndexOutOfBoundsException)

  | SemGet_arrayLength: p thid h loc arr size,
    loc null
    get h thid loc = HV_Array arr
    getArraySize arr = size
    semGet Op_array_length p thid h [VRef loc] (Result [VInt size])

  | SemGet_arrayLength_null: p thid h,
    semGet Op_array_length p thid h [VRef null] (Exception StandardNames.NullPointerException)

  | SemGet_instanceOf_true: required_rt p thid h loc actual_rt,
    loc null
    getReferenceType h thid loc = Some actual_rt
    subtypeRef p actual_rt required_rt
    semGet (Op_instanceof required_rt) p thid h [VRef loc] (Result [VInt M_Numeric_Int.one])

  | SemGet_instanceOf_false: required_rt p thid h loc actual_rt,
    loc null
    getReferenceType h thid loc = Some actual_rt
    ¬ subtypeRef p actual_rt required_rt
    semGet (Op_instanceof required_rt) p thid h [VRef loc] (Result [VInt M_Numeric_Int.zero])
  
  | SemGet_instanceOf_null: required_rt p thid h,
    semGet (Op_instanceof required_rt) p thid h [VRef null] (Result [VInt M_Numeric_Int.zero])
  
  | SemGet_checkCast_true: required_rt p thid h loc actual_rt,
    loc null
    getReferenceType h thid loc = Some actual_rt
    subtypeRef p actual_rt required_rt
    semGet (Op_checkcast required_rt) p thid h [VRef loc] (Result [VRef loc])

  | SemGet_checkCast_false: required_rt p thid h loc actual_rt,
    loc null
    getReferenceType h thid loc = Some actual_rt
    ¬ subtypeRef p actual_rt required_rt
    semGet (Op_checkcast required_rt) p thid h [VRef loc] (Exception StandardNames.ClassCastException)
  
  | SemGet_checkCast_null: required_rt p thid h,
    semGet (Op_checkcast required_rt) p thid h [VRef null] (Result [VRef null])
  .

  Inductive semPut: TPutOpTProgramTThreadId → (list TValue × THeap) → TResultOrException (list TValue × THeap) → Prop :=
  | SemPut_putstatic: cn field p thid h h' v,
    setStaticField h thid cn field v = Some h'
    semPut (Op_putstatic cn field) p thid ([v], h) (Result ([], h'))

  | SemPut_putfield: cn fn p thid h h' loc obj obj' v,
    
    loc null
    get h thid loc = HV_Object obj
    setObjectField obj fn v = obj'
    set h thid loc (HV_Object obj') = h'
    semPut (Op_putfield cn fn) p thid ([v; VRef loc], h) (Result ([], h'))

  | SemPut_putfield_null: cn fn p thid h v,
    semPut (Op_putfield cn fn) p thid ([VRef null; v], h) (Exception StandardNames.NullPointerException)

  | SemPut_array: aik p t thid h h' loc size arr arr' idx v av,
    get h thid loc = HV_Array arr
    getArrayComponentType arr = t
    arrayKindOfType t = aik
    kindOfValue v = kindOfArrayKind aik
    getArraySize arr = size
    validIndex size idx
    transformAFromValue t v = Some av
    arr' = setArrayCell arr idx av
    h' = set h thid loc (HV_Array arr') →
    semPut (Op_putarray aik) p thid ([v; VInt idx; VRef loc], h) (Result ([], h'))
  

  | SemPut_array_null: aik p thid h idx v,
    kindOfValue v = kindOfArrayKind aik
    semPut (Op_putarray aik) p thid ([v; VInt idx; VRef null], h) (Exception StandardNames.NullPointerException)

  | SemPut_array_indexOutOfBounds: aik p t thid h loc size arr idx v,
    get h thid loc = HV_Array arr
    getArrayComponentType arr = t
    arrayKindOfType t = aik
    kindOfValue v = kindOfArrayKind aik
    getArraySize arr = size
    ¬ validIndex size idx
    semPut (Op_putarray aik) p thid ([v; VInt idx; VRef loc], h) (Exception StandardNames.ArrayIndexOutOfBoundsException)
  .

  Parameter makeMultiArray: TReferenceTypelist TValueTThreadIdTHeap → (THeap × TLoc).

  Inductive madeMultiArrayInd: TTypelist TValueTThreadIdTHeapTHeapTAValueProp :=
  | MadeMultiArray_step:
     t size sizes thid h h' loc arr,
    get h' thid loc = HV_Array arr
    getArrayComponentType arr = t
    getArraySize arr = size
    ( i inner_val, validIndex (getArraySize arr) i
       getArrayCell arr i = Some inner_val
       madeMultiArrayInd t sizes thid h h' inner_val) →
    madeMultiArrayInd (ReferenceType (RTArray t)) (cons (VInt size) sizes) thid h h' (VARef loc)

  | MadeMultiArray_end:
     t thid h h',
    madeMultiArrayInd t nil thid h h' (defaultArrayValueForType t)
  .

  Axiom PmakeMultiArray: rt sizes thid h h' loc,
    makeMultiArray rt sizes thid h = (h', loc) madeMultiArrayInd (ReferenceType rt) sizes thid h h' (VARef loc).

  Inductive semNew: TNewOpTProgramTThreadId → (list TValue × THeap) → TResultOrException (list TValue × THeap) → Prop :=
  | SemNew_object: p cn class thid loc obj h h',
    getClass p cn = Some class
    initObject (getEmptyObject class) = obj
    loc = freshLocation h
    h' = set h thid loc (HV_Object obj) →
    semNew (Op_newobject cn) p thid ([], h) (Result ([VRef loc], h'))

  | SemNew_array: p bt thid loc arr size h h',
    initArray (BaseType bt) size = arr
    freshLocation h = loc
    set h thid loc (HV_Array arr) = h'
    semNew (Op_newarray bt) p thid ([VInt size], h) (Result ([VRef loc], h'))

  | SemNew_array_neg: p bt thid size h,
    M_Numeric_Int.toZ size < 0 →
    semNew (Op_newarray bt) p thid ([VInt size], h) (Exception StandardNames.NegativeArraySizeException)

  | SemNew_refarray: p rt thid loc arr size h h',
    M_Numeric_Int.toZ size 0 →
    initArray (ReferenceType rt) size = arr
    freshLocation h = loc
    set h thid loc (HV_Array arr) = h'
    semNew (Op_newarray_ref rt) p thid ([VInt size], h) (Result ([VRef loc], h'))

  | SemNew_refarray_neg: p rt thid size h,
    M_Numeric_Int.toZ size < 0 →
    semNew (Op_newarray_ref rt) p thid ([VInt size], h) (Exception StandardNames.NegativeArraySizeException)

  | SemNew_multiarray: p rt dimensions thid loc sizes h h',
    (dimensions > 0)%nat
    dimensions = length sizes
    ( size, In (VInt size) sizesM_Numeric_Int.toZ size 0) →
    makeMultiArray rt sizes thid h = (h', loc)
    semNew (Op_newmultiarray rt dimensions) p thid (sizes, h) (Result ([VRef loc], h'))

  | SemNew_multiarray_negativeSize: p rt dimensions thid sizes h,
    (dimensions > 0)%nat
    dimensions = length sizes
    ( size, In (VInt size) sizes M_Numeric_Int.toZ size < 0) →
    semNew (Op_newmultiarray rt dimensions) p thid (sizes, h) (Exception StandardNames.NegativeArraySizeException)
  .

  Inductive semHeap (p: TProgram) (code: TCode): THeapInstrTThreadId → ((list TValue) × THeap) → TResultOrException ((list TValue) × THeap) → Prop:=
  | SemHeap_get: get_op thid vs vs' h,
    semGet get_op p thid h vs (Result vs') →
    semHeap p code (HI_Get get_op) thid (vs, h) (Result (vs', h))

  | SemHeap_put: put_op thid vs h vs' h',
    semPut put_op p thid (vs, h) (Result (vs', h')) →
    semHeap p code (HI_Put put_op) thid (vs, h) (Result (vs', h'))

  | SemHeap_new: new_op thid vs h vs' h',
    semNew new_op p thid (vs, h) (Result (vs', h')) →
    semHeap p code (HI_New new_op) thid (vs, h) (Result (vs', h'))

  | SemHeap_monitor: mon_op thid h h' loc,
    M_Sem_Monitor.semMonitor mon_op thid loc h (Result h') →
    semHeap p code (HI_Monitor mon_op) thid ([VRef loc], h) (Result ([], h'))
  .
End SEM_HEAP.