(** [match_callstack] and allocations *)

(* Specifications: *)
Lemma match_callstack_alloc_right:
forall f m tm cs tf tm' sp le te cenv,
match_callstack f m tm cs (Mem.nextblock m) (Mem.nextblock tm) ->
Mem.alloc tm 0 tf.(fn_stackspace) = (tm', sp) ->
Mem.inject f m tm ->
match_temps f le te ->
(forall id, cenv!id = None) ->
match_callstack f m tm'
(Frame cenv tf empty_env le te sp (Mem.nextblock m) (Mem.nextblock m) :: cs)
(Mem.nextblock m) (Mem.nextblock tm').
Lemma match_callstack_alloc_left:
forall f1 m1 tm id cenv tf e le te sp lo cs sz m2 b f2 ofs,
match_callstack f1 m1 tm
(Frame (PTree.remove id cenv) tf e le te sp lo (Mem.nextblock m1) :: cs)
(Mem.nextblock m1) (Mem.nextblock tm) ->
Mem.alloc m1 0 sz = (m2, b) ->
cenv!id = Some ofs ->
inject_incr f1 f2 ->
f2 b = Some(sp, ofs) ->
(forall b', b' <> b -> f2 b' = f1 b') ->
e!id = None ->
match_callstack f2 m2 tm
(Frame cenv tf (PTree.set id (b, sz) e) le te sp lo (Mem.nextblock m2) :: cs)
(Mem.nextblock m2) (Mem.nextblock tm).
Lemma match_callstack_alloc_right:
forall f m tm cs tf tm' sp le te cenv,
match_callstack f m tm cs (Mem.nextblock m) (Mem.nextblock tm) ->
Mem.alloc tm 0 tf.(fn_stackspace) = (tm', sp) ->
Mem.inject f m tm ->
match_temps f le te ->
(forall id, cenv!id = None) ->
match_callstack f m tm'
(Frame cenv tf empty_env le te sp (Mem.nextblock m) (Mem.nextblock m) :: cs)
(Mem.nextblock m) (Mem.nextblock tm').
Lemma match_callstack_alloc_left:
forall f1 m1 tm id cenv tf e le te sp lo cs sz m2 b f2 ofs,
match_callstack f1 m1 tm
(Frame (PTree.remove id cenv) tf e le te sp lo (Mem.nextblock m1) :: cs)
(Mem.nextblock m1) (Mem.nextblock tm) ->
Mem.alloc m1 0 sz = (m2, b) ->
cenv!id = Some ofs ->
inject_incr f1 f2 ->
f2 b = Some(sp, ofs) ->
(forall b', b' <> b -> f2 b' = f1 b') ->
e!id = None ->
match_callstack f2 m2 tm
(Frame cenv tf (PTree.set id (b, sz) e) le te sp lo (Mem.nextblock m2) :: cs)
(Mem.nextblock m2) (Mem.nextblock tm).