Require Import Coqlib.
Require Import Cplusconcepts.
Require Import CplusWf.
Require Import LayoutConstraints.
Require Import LibLists.
Require Import Tactics.
Require Import LibMaps.
Require Import Relations.
Load Param.
Open Scope Z_scope.
Notation var := (
ident) (
only parsing).
Section SimpleCompiler.
Variable (
A :
ATOM.t).
Record NATIVEOP :
Type :=
NativeOp {
nativeop :
Type;
sem :
nativeop ->
list (
sigT (
ATOM.val (
t :=
A))) ->
sigT (
ATOM.val (
t :=
A)) ->
Prop;
sembool :
sigT (
ATOM.val (
t :=
A)) ->
option bool;
tyTRUE : (
ATOM.ty A);
TRUE : (
ATOM.val (
t :=
A))
tyTRUE;
sembool_true :
sembool (
existT _ _ TRUE) =
Some true;
tyFALSE : (
ATOM.ty A);
FALSE : (
ATOM.val (
t :=
A))
tyFALSE;
sembool_false :
sembool (
existT _ _ FALSE) =
Some false;
semZ :
sigT (
ATOM.val (
t :=
A)) ->
option Z;
Zsem :
Z ->
sigT (
ATOM.val (
t :=
A));
Zsem_semZ :
forall z,
semZ (
Zsem z) =
Some z
}.
Variable NO :
NATIVEOP.
Variable OP :
OPTIM A.
4.3
Hypothesis is_dynamic_virtual_base :
forall hierarchy a b,
is_virtual_base_of hierarchy b a ->
is_dynamic OP hierarchy a.
Section Common.
Variable value :
Type.
Variable atom :
forall ty, (
ATOM.val (
t :=
A))
ty ->
value.
Variable specific_stmt :
Type.
Inductive common_stmt :
Type :=
|
skip
|
seq (
_ _ :
common_stmt)
|
test (
test :
var) (
ifso ifnot :
common_stmt)
|
block (
body :
common_stmt)
|
exit (
n :
nat)
|
loop (
body :
common_stmt)
|
native (
op :
nativeop NO) (
source :
list var) (
target :
var)
|
specific (
_ :
specific_stmt)
.
Variable globals :
Type.
Record state :
Type :=
State {
pc :
list (
list common_stmt);
vars :
PTree.t value;
global :
globals
}.
Inductive common_step :
state ->
state ->
Prop :=
|
common_step_skip :
forall stl blocks vars global,
common_step
(
State ((
skip ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars global)
|
common_step_seq :
forall stl s1 s2 vars blocks global,
common_step
(
State ((
seq s1 s2 ::
stl) ::
blocks)
vars global)
(
State ((
s1 ::
s2 ::
stl) ::
blocks)
vars global)
|
common_step_test :
forall vars varb tyb valb,
vars !
varb =
Some (@
atom tyb valb) ->
forall b,
sembool NO (
existT _ tyb valb) =
Some b ->
forall s ifso ifnot,
s = (
if b then ifso else ifnot) ->
forall stl blocks global,
common_step
(
State ((
test varb ifso ifnot ::
stl) ::
blocks)
vars global)
(
State ((
s ::
stl) ::
blocks)
vars global)
|
common_step_block :
forall stm stl blocks vars global,
common_step
(
State ((
block stm ::
stl) ::
blocks)
vars global)
(
State ((
stm ::
nil) ::
stl ::
blocks)
vars global)
|
common_step_exit_O :
forall stl blocks vars global,
common_step
(
State ((
exit O ::
stl) ::
blocks)
vars global)
(
State blocks vars global)
|
common_step_exit_S :
forall n stl stl'
blocks vars global,
common_step
(
State ((
exit (
S n) ::
stl) :: (
stl' ::
blocks))
vars global)
(
State ((
exit n ::
stl') ::
blocks)
vars global)
|
common_step_native :
forall args source vars,
map (
fun a :
sigT (
ATOM.val (
t :=
A)) =>
let (
ty,
va) :=
a in Some (
atom va))
args =
map (
fun v =>
PTree.get v vars)
source ->
forall op rty rva,
sem (
n :=
NO)
op args (
existT _ rty rva) ->
forall vars'
target,
vars' =
PTree.set target (
atom rva)
vars ->
forall stl blocks global,
common_step
(
State ((
native op source target ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars'
global)
.
End Common.
Section Source.
Inductive source_specific_stmt :
Type :=
C++ object-oriented features
|
source_null (
class :
ident) (
target :
var)
|
source_ptreq (
ptr1 ptr2 :
var) (
target :
var)
|
source_getfield (
class :
ident) (
field :
FieldSignature.t A) (
source :
var) (
target :
var)
|
source_putfield (
class :
ident) (
field :
FieldSignature.t A) (
source :
ident) (
newvalue :
var)
|
source_statcast (
from :
ident) (
to :
ident) (
source :
var) (
target :
var)
|
source_dyncast (
from :
ident) (
to :
ident) (
source :
var) (
target :
var)
|
source_arrayindex (
class :
ident) (
index :
var) (
source :
var) (
target :
var)
.
Section Sem.
Variable hierarchy :
PTree.t (
Class.t A).
Inductive valid_pointer_or_null (
g :
Globals.t A) :
Value.pointer A ->
Prop :=
|
valid_pointer_valid :
forall ptr,
Globals.valid_pointer hierarchy g ptr ->
valid_pointer_or_null g ptr
|
valid_pointer_null :
forall ty,
valid_pointer_or_null g (
Value.null A ty)
.
Notation state := (
state (
Value.t A)
source_specific_stmt (
Globals.t A)) (
only parsing).
Inductive source_step :
state ->
state ->
Prop :=
|
source_step_common :
forall s1 s2,
common_step (@
Value.atom A)
s1 s2 ->
source_step s1 s2
null pointer
|
source_step_null :
forall vars vars'
class target,
vars' =
PTree.set target (
Value.ptr (
Value.null A class))
vars ->
forall stl blocks global,
source_step
(
State ((
specific (
source_null class target) ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars'
global)
|
step_ptreq :
forall v1 ptr1 vars,
vars !
v1 =
Some (
Value.ptr ptr1) ->
forall global,
valid_pointer_or_null global ptr1 ->
forall v2 ptr2,
vars !
v2 =
Some (
Value.ptr ptr2) ->
valid_pointer_or_null global ptr2 ->
Value.type_of (
Value.ptr ptr1) =
Value.type_of (
Value.ptr ptr2) ->
forall b :
bool,
(
if b then (
Value.ptr ptr1 =
Value.ptr ptr2)
else (
Value.ptr ptr1 <>
Value.ptr ptr2)) ->
forall v,
v = (
if b then Value.atom _ (
TRUE NO)
else Value.atom _ (
FALSE NO)) ->
forall vars'
target,
vars' =
PTree.set target v vars ->
forall stl blocks,
source_step
(
State ((
specific (
source_ptreq v1 v2 target) ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars'
global)
get field
|
step_getfield :
forall vars source obj ar i h p hp,
vars !
source =
Some (
Value.ptr (@
Value.subobject _ obj ar i h p hp)) ->
forall global,
Globals.valid_pointer hierarchy global (
Value.subobject obj ar i h _ hp) ->
forall o, (
Globals.heap global) !
obj =
Some o ->
forall class c,
hierarchy !
class =
Some c ->
last p =
Some class ->
forall fs,
In fs (
Class.fields c) ->
forall v,
Object.get_field o (
ar,
i, (
h,
p),
fs) =
Some v ->
forall vars'
target,
vars' =
PTree.set target v vars ->
forall stl blocks,
source_step
(
State ((
specific (
source_getfield class fs source target) ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars'
global)
put field
|
step_putfield :
forall vars source obj ar i h p hp,
vars !
source =
Some (
Value.ptr (@
Value.subobject _ obj ar i h p hp)) ->
forall global,
Globals.valid_pointer hierarchy global (
Value.subobject obj ar i h _ hp) ->
forall o, (
Globals.heap global) !
obj =
Some o ->
forall class c,
hierarchy !
class =
Some c ->
last p =
Some class ->
forall fs,
In fs (
Class.fields c) ->
forall newvalue v,
vars !
newvalue =
Some v ->
forall o',
Object.put_field o (
ar,
i, (
h,
p),
fs)
v =
Some o' ->
forall global',
global' =
Globals.update global obj o' ->
forall stl blocks,
source_step
(
State ((
specific (
source_putfield class fs source newvalue) ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars global')
static cast
|
step_statcast :
forall vars source obj ar i h p hp,
vars !
source =
Some (
Value.ptr (@
Value.subobject _ obj ar i h p hp)) ->
real : class of the most derived object
from : static type of the pointer
to : class to which to cast
forall o global,
(
Globals.heap global) !
obj =
Some o ->
forall real from,
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar real i h p from ->
forall to h'
p',
static_cast hierarchy real h p from to h'
p' ->
forall hp'
target vars',
vars' =
PTree.set target (
Value.ptr (@
Value.subobject _ obj ar i h'
p'
hp'))
vars ->
forall stl blocks,
source_step
(
State ((
specific (
source_statcast from to source target) ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars'
global)
dynamic cast
|
step_dyncast :
forall vars source obj ar i h p hp,
vars !
source =
Some (
Value.ptr (@
Value.subobject _ obj ar i h p hp)) ->
real : class of the most derived object
from : static type of the pointer
to : class to which to cast
forall o global,
(
Globals.heap global) !
obj =
Some o ->
forall real from,
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar real i h p from ->
is_dynamic OP hierarchy from ->
forall newptr to,
(
forall h'
p',
dynamic_cast hierarchy real h p from to h'
p' ->
exists hp',
newptr = (@
Value.subobject _ obj ar i h'
p'
hp')) ->
((
forall h'
p',
dynamic_cast hierarchy real h p from to h'
p' ->
False) ->
newptr = (
Value.null _ to))->
(
forall h''
p'',
path hierarchy to p''
from h'' ->
False) ->
forall target vars',
vars' =
PTree.set target (
Value.ptr newptr)
vars ->
forall stl blocks,
source_step
(
State ((
specific (
source_dyncast from to source target) ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars'
global)
array index
|
step_arrayindex :
forall vars source obj ar i class hp,
vars !
source =
Some (
Value.ptr (@
Value.subobject _ obj ar i Class.Inheritance.Repeated (
class ::
nil)
hp)) ->
forall o global n,
(
Globals.heap global) !
obj =
Some o ->
valid_array_path hierarchy class n (
Object.class o) (
Object.arraysize o)
ar ->
0 <=
i <
n ->
forall index tyj vaj,
vars !
index =
Some (
Value.atom _ vaj) ->
forall j,
semZ NO (
existT _ tyj vaj) =
Some j ->
0 <=
i +
j <
n ->
forall vars'
target,
vars' =
PTree.set target (
Value.ptr (
Value.subobject obj ar (
i +
j)
Class.Inheritance.Repeated _ hp))
vars ->
forall stl blocks,
source_step
(
State ((
specific (
source_arrayindex class index source target) ::
stl) ::
blocks)
vars global)
(
State (
stl ::
blocks)
vars'
global)
.
End Sem.
End Source.
Section Target.
Variable (
PF :
PLATFORM A).
Inductive val :
Type :=
|
Ptr (
_ :
option Z)
|
Atom (
ty : (
ATOM.ty A)) (
_ : (
ATOM.val (
t :=
A))
ty)
.
Inductive memval :
Type :=
|
Vptr (
class :
ident) (
_ :
Class.Inheritance.t *
list ident)
|
Val (
_ :
val)
.
We assume all pointers to subobjects have the same size and alignment
Variable ptrsize :
Z.
Function val_size (
m :
val) :
Z :=
match m with
|
Ptr _ =>
ptrsize
|
Atom ty _ =>
typ_size PF (
Typ.atom ty)
end.
Function memval_size (
m :
memval) :
Z :=
match m with
|
Vptr _ _ =>
dynamic_type_data_size PF
|
Val v =>
val_size v
end.
Variable ptralign :
Z.
Function val_align (
m :
val) :
Z :=
match m with
|
Ptr _ =>
ptralign
|
Atom ty _ =>
typ_align PF (
Typ.atom ty)
end.
Function memval_align (
m :
memval) :
Z :=
match m with
|
Vptr _ _ =>
dynamic_type_data_align PF
|
Val v =>
val_align v
end.
Record MEMORY :
Type :=
Memory {
mem :
Type;
load :
Z ->
mem ->
Z ->
option memval;
store :
Z ->
mem ->
Z ->
memval ->
option mem;
Assume infinite memory
The following axiom is the only needed way to store a value into memory: it requires the alignment to divide the offset, and the chunk size to be equal to the size of the actual data being written.
store_some :
forall i mv,
(
memval_align mv |
i) ->
forall m,
store (
memval_size mv)
m i mv <>
None;
load_store_same :
forall i sz mv m m',
store sz m i mv =
Some m' ->
load sz m'
i =
Some mv;
load_store_other :
forall m i mv sz'
m',
store sz'
m i mv =
Some m' ->
forall j sz,
j +
sz <=
i \/
i +
sz' <=
j ->
load sz m'
j =
load sz m j;
H_ptrsize :
forall cn,
typ_size PF (
Typ.class cn) =
ptrsize;
H_ptralign :
forall cn,
typ_align PF (
Typ.class cn) =
ptralign
}.
Inductive target_specific_stmt :
Type :=
low-level memory operations
|
target_load (
chunksize :
Z) (
ptr :
var) (
off :
Z) (
target :
var)
|
target_store (
chunksize :
Z) (
ptr :
var) (
off :
Z) (
newvalue :
var)
vtable operations
|
dyncast_exists (
_ :
ident) (
vptr :
var) (
target :
var)
|
dyncast_offset (
_ :
ident) (
vptr :
var) (
target :
var)
|
vbase_offset (
_ :
ident) (
vptr :
var) (
target :
var)
pointer arith
|
null (
ptr' :
var)
|
ptrshift (
ptr :
var) (
off :
Z) (
ptr' :
var)
|
ptrshiftmult (
ptr :
var) (
delta :
var) (
factor :
Z) (
ptr' :
var)
|
ptreq (
ptr1 ptr2 :
var) (
target :
var)
.
The following record type abstracts accesses to virtual tables (e.g. dynamic cast via RTTI).
Virtual tables themselves are assumed to be located at a non-writable memory zone.
Record vtable :
Type :=
VTable {
dyncast_offsets :
ident ->
option (
option Z);
vbase_offsets :
ident ->
option Z
}.
Section Sem.
Variable vtables :
ident -> (
Class.Inheritance.t *
list ident) ->
option vtable.
Variable MEM :
MEMORY.
Notation state := (
state memval target_specific_stmt (
mem MEM)) (
only parsing).
Inductive step :
state ->
state ->
Prop :=
|
step_common :
forall s1 s2,
common_step (
fun ty va =>
Val (@
Atom ty va))
s1 s2 ->
step s1 s2
low-level memory load
|
step_load :
forall ptr z vars,
vars !
ptr =
Some (
Val (
Ptr (
Some z))) ->
forall sz m off v,
load (
m :=
MEM)
sz m (
z +
off) =
Some v ->
forall target vars',
vars' =
PTree.set target v vars ->
forall stl blocks,
step
(
State ((
specific (
target_load sz ptr off target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
low-level memory store
|
step_store :
forall ptr z vars,
vars !
ptr =
Some (
Val (
Ptr (
Some z))) ->
forall newvalue v,
vars !
newvalue =
Some v ->
forall m off m'
sz,
store (
m :=
MEM)
sz m (
z +
off)
v =
Some m' ->
forall stl blocks,
step
(
State ((
specific (
target_store sz ptr off newvalue) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars m')
dynamic cast offset retrieval from VTable : status
|
step_dyncast_exists :
forall vptr cn hp vars,
vars !
vptr =
Some (
Vptr cn hp) ->
forall vtbl,
vtables cn hp =
Some vtbl ->
cn : most derived class,
class : class to which dynamically cast
forall oz class,
dyncast_offsets vtbl class =
Some oz ->
forall b,
match oz with
|
None =>
b =
Atom (
FALSE NO)
|
_ =>
b =
Atom (
TRUE NO)
end ->
forall target vars',
vars' =
PTree.set target (
Val b)
vars ->
forall stl blocks m,
step
(
State ((
specific (
dyncast_exists class vptr target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
dynamic cast offset retrieval from VTable when successful
|
step_dyncast_offset :
forall vptr cn hp vars,
vars !
vptr =
Some (
Vptr cn hp) ->
forall vtbl,
vtables cn hp =
Some vtbl ->
cn : most derived class,
class : class to which dynamically cast
forall z class,
dyncast_offsets vtbl class =
Some (
Some z) ->
forall target vars',
vars' =
PTree.set target (
Val (
let (
ty,
va) :=
Zsem NO z in Atom va))
vars ->
forall stl blocks m,
step
(
State ((
specific (
dyncast_offset class vptr target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
virtual base offset retrieval from VTable
|
step_vbase_offset:
forall vptr cn hp vars,
vars !
vptr =
Some (
Vptr cn hp) ->
forall vtbl,
vtables cn hp =
Some vtbl ->
cn : most derived class,
class : virtual base of which to find the offset
forall z class,
vbase_offsets vtbl class =
Some z ->
forall target vars',
vars' =
PTree.set target (
Val (
let (
ty,
va) :=
Zsem NO z in Atom va))
vars ->
forall stl blocks m,
step
(
State ((
specific (
vbase_offset class vptr target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
null pointer
|
step_null :
forall vars vars'
target,
vars' =
PTree.set target (
Val (
Ptr None))
vars ->
forall stl blocks m,
step
(
State ((
specific (
null target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
constant shift
|
step_ptrshift :
forall z vars ptr,
vars !
ptr =
Some (
Val (
Ptr (
Some z))) ->
forall off vars'
target,
vars' =
PTree.set target (
Val (
Ptr (
Some (
z +
off))))
vars ->
forall stl blocks m,
step
(
State ((
specific (
ptrshift ptr off target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
variable shift (up to a constant factor)
|
step_ptrshiftmult :
forall z vars ptr,
vars !
ptr =
Some (
Val (
Ptr (
Some z))) ->
forall delta tyoff vaoff,
vars !
delta =
Some (
Val (@
Atom tyoff vaoff)) ->
forall off,
semZ NO (
existT _ _ vaoff) =
Some off ->
forall factor vars'
target,
vars' =
PTree.set target (
Val (
Ptr (
Some (
z +
off *
factor))))
vars ->
forall stl blocks m,
step
(
State ((
specific (
ptrshiftmult ptr delta factor target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
|
target_step_ptreq :
forall ptr1 oz1 vars,
vars !
ptr1 =
Some (
Val (
Ptr oz1)) ->
forall ptr2 oz2,
vars !
ptr2 =
Some (
Val (
Ptr oz2)) ->
forall b :
bool,
(
if b then (
oz1 =
oz2)
else (
oz1 <>
oz2)) ->
forall v,
v = (
if b then Val (
Atom (
TRUE NO))
else Val (
Atom (
FALSE NO))) ->
forall vars'
target,
vars' =
PTree.set target v vars ->
forall stl blocks m,
step
(
State ((
specific (
ptreq ptr1 ptr2 target) ::
stl) ::
blocks)
vars m)
(
State (
stl ::
blocks)
vars'
m)
.
End Sem.
End Target.
Section Compiler.
Variable PF :
PLATFORM A.
Variables psize palign :
Z.
Variable MEM :
MEMORY PF psize palign.
Variable hierarchy :
PTree.t (
Class.t A).
Variable offsets :
PTree.t (
LayoutConstraints.t A).
Hypothesis Hhier :
Well_formed_hierarchy.prop hierarchy.
We need this decision procedure to prove the invariant. Remember for instance that Theorem 5.4 is split into two parts: the empty part, and the non-empty part.
Variable is_empty_dec :
forall cl, {
is_empty OP hierarchy cl} + {~
is_empty OP hierarchy cl}.
Hypothesis intro :
forall ci o,
offsets !
ci =
Some o ->
class_level_prop OP PF offsets hierarchy ci o.
Hypothesis guard :
forall ci,
offsets !
ci <>
None ->
hierarchy !
ci <>
None.
Hypothesis exist :
forall ci,
hierarchy !
ci <>
None ->
offsets !
ci <>
None.
Hypothesis empty_prop :
forall (
ci :
positive) (
oc :
LayoutConstraints.t A),
offsets !
ci =
Some oc ->
disjoint_empty_base_offsets OP offsets hierarchy ci oc.
Notation GARBAGE := (
skip _) (
only parsing).
Definition paths :=
let (
T,
_) :=
Well_formed_hierarchy.paths Hhier in T.
Notation SrcVar := (
xO) (
only parsing).
Notation TmpVar := (
xI) (
only parsing).
Function specific_compiler (
s' :
source_specific_stmt) {
struct s'} :
common_stmt target_specific_stmt :=
Compilation of C++ specific instructions
match s'
with
Null pointer
|
source_null _ target =>
specific (
null (
SrcVar target))
Pointer equality
|
source_ptreq ptr1 ptr2 target =>
specific (
ptreq (
SrcVar ptr1) (
SrcVar ptr2) (
SrcVar target))
get field (scalar or structure)
|
source_getfield class field source target =>
match offsets !
class with
|
None =>
GARBAGE
|
Some o =>
match assoc (
FieldSignature.eq_dec (
A :=
A))
field (
field_offsets o)
with
|
None =>
GARBAGE
|
Some fo =>
match FieldSignature.type field with
|
FieldSignature.Scalar ty =>
specific (
target_load (
typ_size PF ty) (
SrcVar source)
fo (
SrcVar target))
|
_ =>
specific (
ptrshift (
SrcVar source)
fo (
SrcVar target))
end
end
end
put field (scalar only, cf. Object.put_field)
|
source_putfield class field source newvalue =>
match offsets !
class with
|
None =>
GARBAGE
|
Some o =>
match assoc (
FieldSignature.eq_dec (
A :=
A))
field (
field_offsets o)
with
|
None =>
GARBAGE
|
Some fo =>
match FieldSignature.type field with
|
FieldSignature.Scalar ty =>
specific (
target_store (
typ_size PF (
ty)) (
SrcVar source)
fo (
SrcVar newvalue))
|
_ =>
GARBAGE
end
end
end
dynamic cast : directly read into Vtable
|
source_dyncast from to source target =>
seq
(
specific (
target_load (
dynamic_type_data_size PF) (
SrcVar source) 0 (
TmpVar xH)))
(
seq
(
specific (
dyncast_exists to (
TmpVar xH) (
TmpVar (
xI xH))))
(
test (
TmpVar (
xI xH))
(
seq
(
specific (
dyncast_offset to (
TmpVar xH) (
TmpVar (
xO xH))))
(
specific (
ptrshiftmult (
SrcVar source) (
TmpVar (
xO xH)) 1 (
SrcVar target)))
)
(
specific (
null (
SrcVar target)))
)
)
static cast : two cases
|
source_statcast from to source target =>
match peq from to with
|
left _ =>
specific (
ptrshift (
SrcVar source) 0 (
SrcVar target))
|
_ =>
match plt from to with
|
left _ =>
match paths !
from with
|
None =>
GARBAGE
|
Some pfrom =>
match pfrom !
to with
|
None =>
GARBAGE
|
Some l =>
match filter (
fun hp :
_ *
_ =>
match hp with
| (
Class.Inheritance.Repeated,
_) =>
true
|
_ =>
false
end)
l with
|
nil =>
GARBAGE
| (
_,
p) ::
_ =>
match non_virtual_subobject_offset offsets 0
p with
|
None =>
GARBAGE
|
Some off =>
specific (
ptrshift (
SrcVar source) (0 -
off) (
SrcVar target))
end
end
end
end
|
right _ =>
match paths !
to with
|
None =>
GARBAGE
|
Some pto =>
match pto !
from with
|
Some ((
Class.Inheritance.Repeated,
p) ::
_) =>
match non_virtual_subobject_offset offsets 0
p with
|
None =>
GARBAGE
|
Some off =>
specific (
ptrshift (
SrcVar source)
off (
SrcVar target))
end
|
Some ((
Class.Inheritance.Shared,
b ::
p) ::
_) =>
match non_virtual_subobject_offset offsets 0 (
b ::
p)
with
|
None =>
GARBAGE
|
Some off =>
seq
(
specific (
target_load (
dynamic_type_data_size PF) (
SrcVar source) 0 (
TmpVar xH)))
(
seq
(
specific (
vbase_offset b (
TmpVar xH) (
TmpVar (
xO xH))))
(
seq
(
specific (
ptrshiftmult (
SrcVar source) (
TmpVar (
xO xH)) 1 (
TmpVar (
xI xH))))
(
specific (
ptrshift (
TmpVar (
xI xH))
off (
SrcVar target)))
)
)
end
|
_ =>
GARBAGE
end
end
end
end
array index
|
source_arrayindex class index source target =>
match offsets !
class with
|
None =>
GARBAGE
|
Some o =>
specific (
ptrshiftmult (
SrcVar source) (
SrcVar index) (
size o) (
SrcVar target))
end
end.
Function compile (
s :
common_stmt source_specific_stmt) {
struct s} :
common_stmt target_specific_stmt :=
match s with
|
skip =>
skip _
|
seq s1 s2 =>
seq (
compile s1) (
compile s2)
|
test var ifso ifnot =>
test (
SrcVar var) (
compile ifso) (
compile ifnot)
|
block s' =>
block (
compile s')
|
exit n =>
exit _ n
|
loop s' =>
loop (
compile s')
|
native op args res =>
native _ op (
map SrcVar args) (
SrcVar res)
|
specific s' =>
specific_compiler s'
end.
Construction of virtual tables
Dynamic cast for non-bases : show that if C is a class defining some behaviour (success or failure) to dyncast to X,
if X is not a base of C, then, for any base B of C, the dynamic cast to X has the same behaviour.
Lemma non_base_dyncast_stable :
forall real c x, (
forall h p,
path hierarchy x p c h ->
False) ->
forall h p h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
forall hc,
hierarchy !
c =
Some hc ->
forall b l,
path hierarchy b (
c ::
l)
c Class.Inheritance.Repeated ->
dynamic_cast hierarchy real h (
p ++
l)
b x h'
p'.
Proof.
Lemma non_base_dyncast_stable_recip :
forall real c x, (
forall h p,
path hierarchy x p c h ->
False) ->
forall hc,
hierarchy !
c =
Some hc ->
forall b l,
path hierarchy b (
c ::
l)
c Class.Inheritance.Repeated ->
forall h p,
path hierarchy c p real h ->
forall h'
p',
dynamic_cast hierarchy real h (
p ++
l)
b x h'
p' ->
dynamic_cast hierarchy real h p c x h'
p'.
Proof.
Inductive dyncast_offset_spec :
ident -> (
Class.Inheritance.t *
list ident) ->
ident ->
option Z ->
Prop :=
|
dyncast_offset_not_base_some :
forall real h p cn,
last p =
Some cn ->
forall x, (
forall h'
p',
path hierarchy x p'
cn h' ->
False) ->
forall h'
p',
dynamic_cast hierarchy real h p cn x h'
p' ->
forall z,
subobject_offset offsets real p =
Some z ->
forall z',
subobject_offset offsets real p' =
Some z' ->
forall res,
res =
z' -
z ->
dyncast_offset_spec real (
h,
p)
x (
Some res)
|
dyncast_offset_not_base_none :
forall real h p cn,
last p =
Some cn ->
forall x, (
forall h'
p',
path hierarchy x p'
cn h' ->
False) ->
(
forall h'
p',
dynamic_cast hierarchy real h p cn x h'
p' ->
False) ->
dyncast_offset_spec real (
h,
p)
x None
|
dyncast_offset_base_with_primary :
forall real h p cn,
last p =
Some cn ->
forall x h'
p',
path hierarchy x p'
cn h' ->
forall of,
offsets !
cn =
Some of ->
forall b,
primary_base of =
Some b ->
forall res,
dyncast_offset_spec real (
h,
p ++
b ::
nil)
x res ->
dyncast_offset_spec real (
h,
p)
x res
.
Lemma dyncast_offset_spec_correct :
forall l d,
is_primary_path offsets (
d ::
l) =
true ->
forall c,
path hierarchy c (
d ::
l)
d Class.Inheritance.Repeated ->
forall x, (
forall h'
p',
path hierarchy x p'
c h' ->
False) ->
forall real h p,
path hierarchy d p real h ->
(
forall h'
p',
dynamic_cast hierarchy real h (
p ++
l)
c x h'
p' ->
forall z,
subobject_offset offsets real (
p ++
l) =
Some z ->
forall z',
subobject_offset offsets real p' =
Some z' ->
dyncast_offset_spec real (
h,
p)
x (
Some (
z' -
z))) /\
((
forall h'
p',
dynamic_cast hierarchy real h (
p ++
l)
c x h'
p' ->
False) ->
dyncast_offset_spec real (
h,
p)
x None).
Proof.
induction l.
intros until 2.
generalize (
path_last H0).
injection 1;
intro;
subst.
intros.
rewrite <-
app_nil_end.
split.
intros.
econstructor.
eapply path_last.
eassumption.
assumption.
eassumption.
eassumption.
eassumption.
trivial.
intros.
econstructor.
eapply path_last.
eassumption.
assumption.
assumption.
intros until 1.
generalize H.
rewrite is_primary_path_equation.
case_eq (
offsets !
d);
try congruence.
intros until 1.
destruct (
option_eq_dec peq (
primary_base t) (
Some a)
);
try congruence.
intros.
assert (
path hierarchy c (
a ::
l)
a Class.Inheritance.Repeated).
inversion H2;
subst.
injection H5;
intros;
subst.
generalize H6.
destruct lt;
simpl;
try congruence.
injection 1;
intros;
subst.
functional inversion H7;
subst.
eleft.
reflexivity.
eassumption.
assumption.
assert (
path hierarchy a (
d ::
a ::
nil)
d Class.Inheritance.Repeated).
inversion H2;
subst.
generalize (
is_valid_repeated_subobject_split_left (
l1 :=
d ::
nil)
H8).
intros.
eleft with (
lt :=
d ::
nil).
reflexivity.
reflexivity.
assumption.
generalize (
path_concat H4 H6).
intro.
simpl in H7.
rewrite (
path_last H4)
in H7.
destruct (
peq d d);
try congruence.
generalize (
H7 _ _ (
refl_equal _)).
intros.
destruct (
Well_formed_hierarchy.paths Hhier).
invall.
assert (
(
exists h',
exists p',
path hierarchy x p'
d h') \/
forall h'
p',
path hierarchy x p'
d h' ->
False
).
case_eq (
hierarchy !
x).
intros.
assert (
hierarchy !
x <>
None)
by congruence.
assert (
x0 !
x <>
None)
by eauto.
case_eq (
x0 !
x);
try congruence.
intros.
generalize (
H10 _ _ H14).
destruct 1.
assert (
hierarchy !
d <>
None)
by eauto using path_defined_to.
assert (
t1 !
d <>
None)
by eauto.
case_eq (
t1 !
d);
try congruence.
intros.
destruct l0.
right.
intros.
generalize (
H16 _ _ H19 (
h',
p')).
simpl;
tauto.
generalize (
H16 _ _ H19 p0).
destruct 1.
destruct p0.
generalize (
H20 (
or_introl _ (
refl_equal _))).
eauto.
intros.
right.
intros.
eapply path_defined_to.
eexact H12.
assumption.
destruct H11.
invall.
generalize (
IHl _ H1 _ H5 _ H3 _ _ _ H8).
repeat rewrite app_ass.
simpl.
destruct 1.
split.
intros.
eapply dyncast_offset_base_with_primary.
eauto using path_last.
eassumption.
eassumption.
eassumption.
eauto.
intros.
eapply dyncast_offset_base_with_primary.
eauto using path_last.
eassumption.
eassumption.
eassumption.
eauto.
split.
intros.
assert (
hierarchy !
d <>
None)
by eauto using path_defined_from.
case_eq (
hierarchy !
d);
try congruence.
intros.
functional inversion H13;
subst.
destruct (
last_correct (
path_last H4)).
subst.
assert (
exists y,
b ::
y =
x1 ++
d ::
nil).
revert H17.
destruct x1;
simpl.
injection 1;
intros;
subst;
eauto.
injection 1;
intros;
subst;
eauto.
invall.
generalize H18.
rewrite H17.
rewrite app_ass.
simpl.
intro.
generalize (
non_virtual_subobject_offset_app_recip H20).
intros;
invall;
subst.
rewrite (
primary_path_offset intro H)
in H25.
injection H25;
intro;
subst.
eapply dyncast_offset_not_base_some.
eauto using path_last.
assumption.
eapply non_base_dyncast_stable_recip.
assumption.
eassumption.
eexact H2.
assumption.
eassumption.
rewrite <-
H22.
unfold subobject_offset.
rewrite H19.
rewrite H21.
rewrite H22.
eassumption.
eassumption.
reflexivity.
intros.
eapply dyncast_offset_not_base_none.
eauto using path_last.
assumption.
intros.
assert (
hierarchy !
d <>
None)
by eauto using path_defined_from.
case_eq (
hierarchy !
d);
try congruence.
intros.
eapply H12.
eapply non_base_dyncast_stable.
eassumption.
eassumption.
eassumption.
assumption.
Qed.
Corollary dyncast_offset_spec_reduce_path :
forall c x, (
forall h'
p',
path hierarchy x p'
c h' ->
False) ->
forall real h p,
path hierarchy c p real h ->
(
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
forall z,
subobject_offset offsets real p =
Some z ->
forall z',
subobject_offset offsets real p' =
Some z' ->
dyncast_offset_spec real (
h,
reduce_path offsets p)
x (
Some (
z' -
z))) /\
((
forall h'
p',
dynamic_cast hierarchy real h p c x h'
p' ->
False) ->
dyncast_offset_spec real (
h,
reduce_path offsets p)
x None).
Proof.
Lemma dyncast_offset_spec_func :
forall real hp x oz1,
dyncast_offset_spec real hp x oz1 ->
forall oz2,
dyncast_offset_spec real hp x oz2 ->
oz1 =
oz2.
Proof.
induction 1;
inversion 1;
subst;
try congruence;
replace cn0 with cn in *
by congruence.
generalize (
Well_formed_hierarchy.dynamic_cast_unique Hhier H1 H10).
congruence.
destruct (
H13 _ _ H1).
destruct (
H0 _ _ H9).
destruct (
H1 _ _ H7).
destruct (
H0 _ _ H6).
destruct (
H8 _ _ H0).
destruct (
H9 _ _ H0).
replace of0 with of in *
by congruence.
replace b0 with b in *
by congruence.
eauto.
Qed.
Lemma dyncast_offset_spec_exists :
forall real hp x,
{
oz |
dyncast_offset_spec real hp x oz} + {
forall oz,
dyncast_offset_spec real hp x oz ->
False}.
Proof.
Corollary dyncast_offset_strong :
forall real hp, {
dyo |
forall x y,
dyo x =
Some y <->
dyncast_offset_spec real hp x y
}.
Proof.
Function vboffsets (
class :
ident) (
hp :
Class.Inheritance.t *
list ident) (
vb :
ident) :
option Z :=
let (
h,
p) :=
hp in
match subobject_offset offsets class p with
|
None =>
None
|
Some off =>
match offsets !
class with
|
None =>
None
|
Some o =>
match (
virtual_base_offsets o) !
vb with
|
None =>
None
|
Some off' =>
Some (
off' -
off)
end
end
end
.
Definition vtables i hp :=
Some (
VTable
(
let (
y,
_) :=
dyncast_offset_strong i hp in y)
(
vboffsets i hp)
).
Lemma vtables_exist :
forall class h p to,
path hierarchy to p class h ->
is_dynamic OP hierarchy to ->
vtables class (
h,
p) <>
None.
Proof.
unfold vtables; congruence.
Qed.
Lemma vtables_prop :
forall class h p to,
path hierarchy to p class h ->
is_dynamic OP hierarchy to ->
forall dyncast_tbl vb_tbl,
vtables class (
h,
p) =
Some (
VTable dyncast_tbl vb_tbl) -> (
(
forall cn ooz,
dyncast_tbl cn =
Some ooz <->
dyncast_offset_spec class (
h,
p)
cn ooz) /\
vb_tbl =
vboffsets class (
h,
p)).
Proof.
unfold vtables.
injection 3;
intros;
subst.
split;
auto.
intros.
destruct (
dyncast_offset_strong class (
h,
p)).
auto.
Qed.
Opaque vtables.
offsets of objects (assumed to already exist)
Variable objects :
ident ->
option Z.
Section Invariant.
Variables (
s :
state (
Value.t A)
source_specific_stmt (
Globals.t A)) (
t :
state memval target_specific_stmt (
mem MEM)).
Fixpoint match_values (
v :
Value.t A) (
w :
memval) {
struct v} :
Prop :=
match v with
|
Value.atom ty va =>
w =
Val (
Atom va)
|
Value.ptr (
Value.null _) =>
w =
Val (
Ptr None)
|
Value.ptr (
Value.subobject obj ar i h p hp) =>
exists off,
w =
Val (
Ptr (
Some off)) /\
forall o, (
Globals.heap (
global s)) !
obj =
Some o ->
forall real from,
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar real i h p from ->
forall oh,
objects obj =
Some oh ->
relative_pointer_offset offsets (
Object.class o)
real ar i p =
Some (
off -
oh)
end.
Record invariant :=
invariant_intro {
invariant_stmt :
pc t =
map (
map compile) (
pc s);
invariant_valid :
Globals.valid (
global s);
invariant_vars :
forall v vr, (
vars s) !
v =
Some vr ->
exists vs, (
vars t) ! (
SrcVar v) =
Some vs /\
match_values vr vs;
invariant_objects :
forall obj o,
(
Globals.heap (
global s)) !
obj =
Some o ->
exists c,
offsets ! (
Object.class o) =
Some c /\
exists off,
objects obj =
Some off /\ (
align c |
off);
invariant_fields :
forall obj o,
(
Globals.heap (
global s)) !
obj =
Some o ->
forall ar real i h p from,
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar real i h p from ->
forall cfrom,
hierarchy !
from =
Some cfrom ->
forall fs,
In fs (
Class.fields cfrom) ->
forall ty,
FieldSignature.type fs =
FieldSignature.Scalar ty ->
forall vr,
Object.get_field o (
ar,
i, (
h,
p),
fs) =
Some vr ->
forall oh,
objects obj =
Some oh ->
forall off,
relative_pointer_offset offsets (
Object.class o)
real ar i p =
Some off ->
forall ofrom,
offsets !
from =
Some ofrom ->
forall foff,
assoc (
FieldSignature.eq_dec (
A :=
A))
fs (
field_offsets ofrom) =
Some foff ->
exists vs,
load (
m :=
MEM) (
typ_size PF (
ty)) (
global t) (
oh +
off +
foff) =
Some vs /\
match_values vr vs
;
invariant_vptr :
forall obj o,
(
Globals.heap (
global s)) !
obj =
Some o ->
forall ar real i h p from,
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar real i h p from ->
is_dynamic OP hierarchy from ->
forall oh,
objects obj =
Some oh ->
forall off,
relative_pointer_offset offsets (
Object.class o)
real ar i (
reduce_path offsets p) =
Some off ->
load (
m :=
MEM) (
dynamic_type_data_size PF) (
global t) (
oh +
off) =
Some (
Vptr real (
h,
reduce_path offsets p))
;
invariant_disjoint_objects :
forall obj1 obj2,
obj1 <>
obj2 ->
forall o1, ((
Globals.heap (
global s)) !
obj1 =
Some o1) ->
forall o2, ((
Globals.heap (
global s)) !
obj2 =
Some o2) ->
forall of1,
offsets ! (
Object.class o1) =
Some of1 ->
forall of2,
offsets ! (
Object.class o2) =
Some of2 ->
forall off1,
objects obj1 =
Some off1 ->
forall off2,
objects obj2 =
Some off2 ->
off1 +
Object.arraysize o1 *
size of1 <=
off2 \/
off2 +
Object.arraysize o2 *
size of2 <=
off1
}.
End Invariant.
Section Preservation.
Variables (
s :
state (
Value.t A)
source_specific_stmt (
Globals.t A)) (
t :
state memval target_specific_stmt (
mem MEM)) (
invar :
invariant s t).
Variables (
s' :
state (
Value.t A)
source_specific_stmt (
Globals.t A)) (
Hst :
source_step hierarchy s s').
Lemma map_variables :
forall source args,
map
(
fun a :
sigT (
ATOM.val (
t :=
A)) =>
let (
ty,
va) :=
a in Some (
Value.atom _ va))
args =
map (
fun v :
positive => (
vars s) !
v)
source ->
map
(
fun a :
sigT (
ATOM.val (
t :=
A)) =>
let (
ty,
va) :=
a in Some (
Val (
Atom va)))
args =
map (
fun v :
positive => (
vars t) !
v) (
map SrcVar source).
Proof.
induction source;
destruct args;
simpl;
try congruence.
destruct s0.
injection 1;
intros;
subst.
f_equal.
symmetry in H1;
symmetry.
destruct (
invariant_vars invar H1).
destruct H2.
simpl in H3.
subst.
assumption.
eauto.
Qed.
Lemma array_path_offset_right :
forall cn ar n cn'
n',
valid_array_path hierarchy cn'
n'
cn n ar ->
forall accu o,
array_path_offset offsets accu cn ar =
Some o ->
forall co',
offsets !
cn' =
Some co' ->
forall i, 0 <=
i <
n' ->
forall h p cl,
path hierarchy cl p cn'
h ->
forall z,
subobject_offset offsets cn'
p =
Some z ->
forall co,
offsets !
cl =
Some co ->
forall fs fz,
assoc (
FieldSignature.eq_dec (
A :=
A))
fs (
field_offsets co) =
Some fz ->
forall ty n'',
FieldSignature.type fs =
FieldSignature.Struct ty n'' ->
array_path_offset offsets accu cn (
ar ++ (
i, (
h,
p),
fs) ::
nil) =
Some (
o +
i *
size co' +
z +
fz).
Proof.
induction 1;
functional inversion 1;
subst;
simpl.
intros.
rewrite H2.
rewrite H5.
rewrite (
path_last H4).
rewrite H6.
rewrite H8.
rewrite H7.
trivial.
intros.
rewrite H13.
rewrite H16.
rewrite H18.
rewrite H19.
rewrite H20.
rewrite H21.
replace ci'0
with by in *
by congruence.
replace _x0 with by_n in *
by congruence.
erewrite IHvalid_array_path.
reflexivity.
assumption.
assumption.
assumption.
eassumption.
assumption.
eassumption.
assumption.
eassumption.
Qed.
Lemma match_values_align :
forall v w,
match_values s v w ->
typ_align PF
( (
Value.type_of v))
=
memval_align PF palign w
.
Proof.
destruct v;
simpl;
intros;
subst;
simpl;
trivial.
destruct p;
subst;
simpl;
eauto using H_ptralign.
invall;
subst;
simpl;
trivial.
destruct (
is_some_constr (
x:=
last l)
i);
simpl;
eauto using H_ptralign.
Qed.
Lemma match_values_size :
forall v w,
match_values s v w ->
typ_size PF
( (
Value.type_of v))
=
memval_size PF psize w
.
Proof.
destruct v;
simpl;
intros;
subst;
simpl;
trivial.
destruct p;
subst;
simpl;
eauto using H_ptrsize.
invall;
subst;
simpl;
trivial.
destruct (
is_some_constr (
x:=
last l)
i);
eauto using H_ptrsize.
Qed.
Lemma subobject_offset_reduce_path :
forall class h p to,
path hierarchy to p class h ->
subobject_offset offsets class p =
subobject_offset offsets class (
reduce_path offsets p).
Proof.
Corollary relative_pointer_offset_reduce_path :
forall class size ar real i h p from,
valid_relative_pointer hierarchy class size ar real i h p from ->
relative_pointer_offset offsets class real ar i p =
relative_pointer_offset offsets class real ar i (
reduce_path offsets p)
.
Proof.
Lemma path_repeated_virtual_base :
forall l to from,
path hierarchy to l from Class.Inheritance.Repeated ->
forall b,
is_virtual_base_of hierarchy b to ->
is_virtual_base_of hierarchy b from.
Proof.
induction l;
inversion 1;
subst;
try congruence.
injection H0;
intros;
subst.
functional inversion H2;
subst.
generalize (
path_last H).
injection 1;
intros;
subst.
assumption.
destruct lt;
simpl in H1;
try discriminate.
injection H1;
intros;
subst.
eright.
eassumption.
eassumption.
eapply IHl.
eleft.
reflexivity.
eassumption.
assumption.
assumption.
Qed.
Corollary path_virtual_base :
forall to l from h,
path hierarchy to l from h ->
forall b,
is_virtual_base_of hierarchy b to ->
is_virtual_base_of hierarchy b from.
Proof.
Lemma valid_array_path_offset :
forall to zto from zfrom p,
valid_array_path hierarchy to zto from zfrom p ->
offsets !
from <>
None ->
offsets !
to <>
None.
Proof.
Theorem preservation :
exists t',
clos_trans _ (
step vtables (
MEM :=
MEM))
t t' /\
invariant s'
t'.
Proof.
generalize map_variables match_values_align match_values_size.
intros map_vars0 match_values_align0 match_values_size0.
inversion invar.
Opaque Object.get_field Object.put_field PTree.get PTree.set non_virtual_subobject_offset.
inversion Hst;
subst;
destruct t;
simpl in *;
subst.
common
inversion H;
subst;
simpl in *;
subst;
try abstract (
esplit;
split; [
eleft;
econstructor;
econstructor |
constructor;
simpl;
trivial
]
).
test
destruct (
invariant_vars0 _ _ H0).
destruct H2.
simpl in H3.
subst.
esplit.
split.
eleft.
econstructor.
econstructor.
eassumption.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
destruct b;
trivial.
native
generalize (
map_vars0 _ _ H0).
intros.
esplit.
split.
eleft.
econstructor.
econstructor.
eexact H2.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
rewrite PTree.gss.
rewrite PTree.gss.
injection 1;
intros;
subst.
esplit.
split.
reflexivity.
simpl.
trivial.
rewrite PTree.gso;
eauto.
rewrite PTree.gso;
eauto.
intros.
destruct (
invariant_vars0 _ _ H3).
destruct H4.
esplit.
split.
eassumption.
destruct vr;
simpl in *;
trivial.
congruence.
null pointer
esplit.
split.
eleft.
eapply step_null.
reflexivity.
econstructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
rewrite PTree.gss.
rewrite PTree.gss.
injection 1;
intros;
subst.
esplit.
split.
reflexivity.
simpl.
trivial.
rewrite PTree.gso;
eauto.
rewrite PTree.gso;
eauto.
intros.
destruct (
invariant_vars0 _ _ H).
destruct H0.
esplit.
split.
eassumption.
destruct vr;
simpl in *;
trivial.
congruence.
ptreq
destruct (
invariant_vars0 _ _ H).
destruct H5.
simpl in H6.
destruct (
invariant_vars0 _ _ H1).
destruct H7.
simpl in H8.
assert (
exists pi2,
x0 =
Val (
Ptr pi2)).
destruct ptr2;
invall;
eauto.
assert (
exists pi1,
x =
Val (
Ptr pi1)).
destruct ptr1;
invall;
eauto.
invall;
subst.
esplit.
split.
eleft.
eapply target_step_ptreq with (
b :=
b).
eassumption.
eassumption.
2 :
reflexivity.
2 :
reflexivity.
destruct b.
injection H4;
intros;
subst.
destruct ptr2;
subst;
try congruence.
invall;
subst.
injection H6;
intros;
subst.
injection H8;
intros;
subst.
inversion H2;
subst.
inversion H9;
subst.
inversion H19;
subst.
refine (
_ (
relative_pointer_offset_exist Hhier intro guard _ (
Plt_succ _)
H19)).
2 :
intros;
eauto.
intros.
case_eq (
relative_pointer_offset offsets (
Object.class o)
through
arraypath index l);
try congruence.
intros.
destruct (
invariant_objects0 _ _ H15).
invall.
generalize (
H10 _ H15 _ _ H19 _ H21).
generalize (
H11 _ H15 _ _ H19 _ H21).
intros.
f_equal.
assert (
x -
x3 =
x0 -
x3)
by congruence.
omega.
destruct ptr1;
destruct ptr2;
invall;
try congruence.
injection H6;
intros;
subst.
injection H8;
intros;
subst.
inversion H0;
subst.
inversion H9;
subst.
inversion H19;
subst.
inversion H2;
subst.
inversion H17;
subst.
inversion H26;
subst.
assert (
forall i1,
(
let (
c,
_) :=
is_some_constr (
x:=
last l0)
i1 in
Typ.class c) =
Typ.class (
A :=
A)
to0).
rewrite (
path_last H23).
simpl.
intro i1.
destruct (
is_some_constr (
x :=
Some to0)
i1).
congruence.
assert (
forall i2,
(
let (
c,
_) :=
is_some_constr (
x:=
last l)
i2 in
Typ.class c) =
Typ.class (
A :=
A)
to).
rewrite (
path_last H16).
simpl.
intro i1.
destruct (
is_some_constr (
x :=
Some to)
i1).
congruence.
generalize i i0 H3.
intros ? ?.
rewrite H24.
rewrite H25.
injection 1;
intros;
subst.
refine (
_ (
relative_pointer_offset_exist Hhier intro guard _ (
Plt_succ _)
H19)).
2 :
intros;
eauto.
intros.
case_eq (
relative_pointer_offset offsets (
Object.class o)
through
arraypath index l);
try congruence.
intros.
destruct (
invariant_objects0 _ _ H15).
invall.
generalize (
H11 _ H15 _ _ H19 _ H31).
intros.
refine (
_ (
relative_pointer_offset_exist Hhier intro guard _ (
Plt_succ _)
H26)).
2 :
intros;
eauto.
intros.
case_eq (
relative_pointer_offset offsets (
Object.class o0)
through0
arraypath0 index0 l0);
try congruence.
intros.
destruct (
invariant_objects0 _ _ H22).
invall.
generalize (
H10 _ H22 _ _ H26 _ H36).
intros.
cut (
x <>
x0).
congruence.
destruct (
peq (
Object.index o0) (
Object.index o)).
replace o0 with o in *
by congruence.
replace x5 with x2 in *
by congruence.
replace x6 with x3 in *
by congruence.
assert (
offsets !
to0 <>
None)
by eauto using path_defined_to.
destruct (
is_empty_dec to0).
intro;
subst.
Theorem 4 empty
generalize (
disjoint_empty_base_offsets_disjoint_pointer_paths Hhier intro guard empty_prop i3 H38 H19 H26 H29 H34).
injection 1;
intros;
subst.
generalize (
is_some_eq i i0).
congruence.
assert (
((
arraypath,
index, (
inhkind,
l)) <> (
arraypath0,
index0, (
inhkind0,
l0)))
).
intro Habs.
injection Habs;
intros;
subst.
generalize (
is_some_eq i i0).
congruence.
Theorem 4 non-empty
generalize (
nonempty_distinct_offsets Hhier intro n H38 H19 H26 H29 H34 H39).
omega.
objets differents
generalize (
invariant_disjoint_objects0 _ _ n _ H22 _ H15 _ H35 _ H30 _ H36 _ H31).
intros.
destruct (
relative_pointer_offset_size intro H26 H34).
assert (
offsets !
to0 <>
None)
by eauto using path_defined_to.
case_eq (
offsets !
to0);
try congruence.
intros.
generalize (
H40 _ H35 _ H42).
intros.
generalize (
non_virtual_size_positive (
intro H42)).
intro.
destruct (
relative_pointer_offset_size intro H19 H29).
generalize (
H46 _ H30 _ H42).
omega.
et maintenant l'invariant
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
rewrite PTree.gss.
rewrite PTree.gss.
injection 1;
intros;
subst.
esplit.
split.
reflexivity.
destruct b;
simpl;
trivial.
rewrite PTree.gso;
eauto.
rewrite PTree.gso;
eauto.
intros.
destruct (
invariant_vars0 _ _ H9).
destruct H10.
esplit.
split.
eassumption.
destruct vr;
simpl in *;
trivial.
congruence.
getfield
assert (
hierarchy !
class <>
None)
by congruence.
assert (
offsets !
class <>
None)
by eauto.
case_eq (
offsets !
class);
try congruence.
intros.
generalize (
field_offsets_exist (
intro H8)
H2 H4).
case_eq (
assoc (
FieldSignature.eq_dec (
A :=
A))
fs (
field_offsets t0));
try congruence.
intros.
inversion H0;
subst.
inversion H18;
subst.
generalize (
path_last H15).
intros.
replace to with class in *
by congruence.
replace o0 with o in *
by congruence.
case_eq (
FieldSignature.type fs).
scalaire
intros.
destruct (
invariant_objects0 _ _ H1).
invall.
refine (
_ (
relative_pointer_offset_exist Hhier intro guard _ (
Plt_succ _)
H18)).
2 :
eauto.
case_eq (
relative_pointer_offset offsets (
Object.class o)
through ar i p
);
try congruence.
intros.
destruct (
invariant_fields0 _ _ H1 _ _ _ _ _ _ H18 _ H2 _ H4 _ H17 _ H5 _ H21 _ H19 _ H8 _ H9).
invall.
destruct (
invariant_vars0 _ _ H).
invall.
simpl in H27.
invall;
subst.
generalize (
H28 _ H1 _ _ H18 _ H21).
rewrite H19.
injection 1;
intros;
subst.
esplit.
split.
eleft.
eapply step_load.
eassumption.
replace (
x4 +
z)
with (
x0 + (
x4 -
x0) +
z)
by omega.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
intro v0.
destruct (
peq v0 target).
subst.
repeat rewrite PTree.gss.
injection 1;
intros;
subst.
esplit.
split.
reflexivity.
destruct vr;
simpl in H25;
trivial.
repeat rewrite PTree.gso;
eauto.
intros.
destruct (
invariant_vars0 _ _ H27).
destruct H29.
esplit.
split.
eassumption.
destruct vr;
simpl in H30;
trivial.
congruence.
structure
intros.
generalize H5.
Transparent Object.get_field.
unfold Object.get_field.
Opaque Object.get_field.
rewrite H17.
injection 1;
intros;
subst.
assert (
hierarchy !
struct <>
None)
by eauto using Well_formed_hierarchy.complete_struct.
assert (
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o) (
ar ++ (
i, (
h,
p),
fs) ::
nil)
struct 0
Class.Inheritance.Repeated (
struct ::
nil)
struct
).
econstructor.
eapply valid_array_path_concat.
eassumption.
econstructor.
assumption.
assumption.
eassumption.
eassumption.
assumption.
eassumption.
eleft with (
to_n :=
Zpos arraysize).
compute;
congruence.
omega.
omega.
compute;
trivial.
eleft with (
lt :=
nil).
reflexivity.
reflexivity.
simpl.
case_eq (
hierarchy !
struct);
congruence.
assert (
offsets !
struct <>
None)
by eauto.
refine (
_ (
relative_pointer_offset_exist Hhier intro guard _ (
Plt_succ _)
H18)).
2 :
eauto.
case_eq (
relative_pointer_offset offsets (
Object.class o)
through ar i
p
);
try congruence.
functional inversion 1.
intros;
subst.
generalize (
array_path_offset_right
H11 H25 H26 (
conj H12 H13)
H15 H27 H8 H9 H17).
intros.
case_eq (
offsets !
struct);
try congruence.
intros.
assert (
relative_pointer_offset offsets (
Object.class o)
struct (
ar ++ (
i, (
h,
p),
fs) ::
nil)
0 (
struct ::
nil) =
Some
(
z1 +
i *
size ofto +
z2 +
z)
).
unfold relative_pointer_offset.
rewrite H24.
rewrite H28.
unfold subobject_offset.
rewrite H28.
rewrite (
virtual_base_offsets_self (
intro H28)).
Transparent non_virtual_subobject_offset.
simpl.
Opaque non_virtual_subobject_offset.
f_equal;
omega.
destruct (
invariant_vars0 _ _ H).
invall.
simpl in H32.
invall.
subst.
destruct (
invariant_objects0 _ _ H1).
invall.
generalize (
H33 _ H1 _ _ H18 _ H34).
rewrite H23.
injection 1;
intros;
subst.
esplit.
split.
eleft.
eapply step_ptrshift.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
repeat rewrite PTree.gss.
injection 1;
intros;
subst.
esplit.
split.
reflexivity.
simpl.
esplit.
split.
reflexivity.
rewrite H1.
injection 1;
intro;
subst.
intros until 1.
rewrite H34.
injection 1;
intros;
subst.
inversion H39;
subst.
inversion H21;
subst.
generalize (
valid_array_path_last H41 H45).
intros;
subst.
rewrite H29.
f_equal;
omega.
repeat rewrite PTree.gso;
eauto.
intros.
destruct (
invariant_vars0 _ _ H37).
invall.
esplit.
split.
eassumption.
destruct vr;
simpl in *;
trivial.
congruence.
putfield
assert (
hierarchy !
class <>
None)
by congruence.
assert (
offsets !
class <>
None)
by eauto.
case_eq (
offsets !
class);
try congruence.
intros.
generalize (
field_offsets_exist (
intro H9)
H2 H4).
case_eq (
assoc (
FieldSignature.eq_dec (
A :=
A))
fs (
field_offsets t0));
try congruence.
intros.
inversion H0;
subst.
inversion H19;
subst.
generalize (
path_last H16).
intros.
replace to with class in *
by congruence.
replace o0 with o in *
by congruence.
destruct (
invariant_objects0 _ _ H1).
invall.
refine (
_ (
relative_pointer_offset_exist Hhier intro guard _ (
Plt_succ _)
H19)).
2 :
eauto.
case_eq (
relative_pointer_offset offsets (
Object.class o)
through ar i p
);
try congruence.
intros.
generalize (
Object.put_field_type H6).
intro.
Theorem 2
generalize (
field_align_prop Hhier intro H19 H18 H20 H9 (
f :=
fs)).
unfold field_align.
rewrite H23.
intro.
destruct (
H24 _ (
refl_equal _)
_ H10).
destruct (
invariant_vars0 _ _ H).
invall.
simpl in H29.
invall;
subst.
generalize (
H30 _ H1 _ _ H19 _ H21).
rewrite H18.
injection 1;
intros;
subst.
destruct (
invariant_vars0 _ _ H5).
destruct H29.
generalize (
Zdivide_trans _ _ _ H25 H22).
intros.
generalize (
Zdivide_plus_r _ _ _ H26 H32).
replace (
x3 -
x0 +
z +
x0)
with (
x3 +
z)
by omega.
rewrite (
match_values_align0 _ _ H31).
intro.
generalize (
store_some H33 (
m0 :=
global1)).
case_eq (
store (
memval_size PF psize x2)
global1 (
x3 +
z)
x2);
try congruence.
intros.
esplit.
split.
eleft.
eapply step_store.
eassumption.
eassumption.
rewrite (
match_values_size0 _ _ H31).
eassumption.
constructor;
simpl;
trivial.
eapply Globals.valid_update.
assumption.
eassumption.
eauto using Object.index_put_field.
intros.
destruct (
invariant_vars0 _ _ H36).
destruct H37.
esplit.
split.
eassumption.
destruct vr;
simpl;
trivial.
destruct p0;
simpl;
trivial.
simpl in H38.
destruct H38.
destruct H38.
esplit.
split.
eassumption.
destruct (
peq array (
Object.index o)).
subst.
rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
eauto.
rewrite PTree.gso;
try congruence;
eauto.
intro.
destruct (
peq obj (
Object.index o)).
subst.
rewrite PTree.gss.
injection 1;
intros;
subst.
rewrite (
Object.class_put_field H6).
eauto.
rewrite PTree.gso;
try congruence;
eauto.
intro obj.
destruct (
peq obj (
Object.index o)).
subst.
rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
intros.
replace oh with x0 in *
by congruence.
destruct (
cfield_dec (
ar0,
i0, (
h0,
p0),
fs0) (
ar,
i, (
h,
p),
fs)).
injection e;
intros until 5;
subst.
generalize (
Object.get_put_field_same H6).
rewrite H41.
injection 1;
intros;
subst.
inversion H37;
subst.
generalize (
valid_array_path_last H12 H47).
intros;
subst.
replace off with (
x3 -
x0)
in *
by congruence.
generalize (
path_last H50).
generalize (
path_last H16).
intros.
replace from with class in *
by congruence.
replace foff with z in *
by congruence.
replace (
x0 + (
x3 -
x0) +
z)
with (
x3 +
z)
by omega.
replace ty with (
Value.type_of v)
by congruence.
rewrite (
match_values_size0 _ _ H31).
rewrite (
load_store_same H34).
esplit.
split.
reflexivity.
destruct v;
trivial.
destruct p0;
trivial.
revert H31.
simpl.
destruct 1.
invall.
esplit.
split.
eassumption.
destruct (
peq array (
Object.index o)).
subst.
rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
eauto.
rewrite PTree.gso;
eauto.
generalize (
Object.get_field_type_scalar H41 H40).
intro;
subst.
assert (
(
ar,
i, (
h,
p),
fs) <> (
ar0,
i0, (
h0,
p0),
fs0)
)
by congruence.
rewrite (
Object.get_put_field_other H6 H46)
in H41.
generalize (
invariant_fields invar H1 H37 H38 H39 H40 H41 H42 H43 H44 H45).
simpl.
destruct 1.
destruct H47.
Theorem 1
generalize (
scalar_fields_disjoint
Hhier intro guard H37 H19 H43 H18 H44 H9 H45 H40 H10 H23 n).
repeat rewrite (
match_values_size0 _ _ H48).
repeat rewrite (
match_values_size0 _ _ H31).
intro.
rewrite (
match_values_size0 _ _ H48)
in H47.
rewrite (
load_store_other H34).
esplit.
split.
eassumption.
destruct vr;
trivial.
destruct p1;
trivial.
simpl in H48;
simpl.
destruct H48.
destruct H48.
esplit.
split.
eassumption.
destruct (
peq array (
Object.index o)).
subst.
repeat rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
eauto.
rewrite PTree.gso;
eauto.
omega.
autres objets
rewrite PTree.gso;
eauto.
intros.
generalize (
invariant_fields invar H36 H37 H38 H39 H40 H41 H42 H43 H44 H45).
simpl.
destruct 1.
destruct H46.
destruct (
relative_pointer_offset_size intro H19 H18).
generalize (
H49 _ H20 _ H9).
intros.
destruct (
relative_pointer_offset_size intro H37 H43).
destruct (
invariant_objects0 _ _ H36).
invall;
subst.
replace x6 with oh in *
by congruence.
generalize (
H52 _ H54 _ H44).
intros.
generalize (
invariant_disjoint_objects0 _ _ n _ H36 _ H15 _ H54 _ H20 _ H55 _ H21).
intros.
generalize (
field_offsets_low_bound (
intro H44)
H45).
intros.
generalize (
non_virtual_size_field_offsets (
intro H44)
H45).
unfold field_size.
generalize (
Object.get_field_type_scalar H41 H40).
intro;
subst.
rewrite H40.
intro.
generalize (
H59 _ (
refl_equal _)).
generalize (
field_offsets_low_bound (
intro H9)
H10).
intro.
generalize (
non_virtual_size_field_offsets (
intro H9)
H10).
unfold field_size.
rewrite H23.
intro.
generalize (
H61 _ (
refl_equal _)).
revert H46.
repeat rewrite (
match_values_size0 _ _ H47).
repeat rewrite (
match_values_size0 _ _ H31).
intros.
rewrite (
load_store_other H34).
2 :
omega.
esplit.
split.
eassumption.
destruct vr;
trivial.
destruct p1;
trivial.
destruct H47.
destruct H47.
esplit.
split.
eassumption.
simpl.
destruct (
peq array (
Object.index o)).
subst.
rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
eauto.
rewrite PTree.gso;
try congruence;
eauto.
intro.
destruct (
peq obj (
Object.index o)).
subst.
rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
intros.
replace x0 with oh in *
by congruence.
rewrite (
load_store_other H34).
eauto.
generalize H40.
rewrite <- (
relative_pointer_offset_reduce_path H37).
intro.
assert (
offsets !
from <>
None).
inversion H37;
subst;
eauto using path_defined_to.
Theorem 5
generalize (
scalar_field_dynamic_type_data_disjoint
Hhier intro guard H19 H37 H18 H41 H9 H42 H10 H23 H38).
rewrite (
match_values_size0 _ _ H31).
omega.
rewrite PTree.gso;
try congruence;
eauto.
intros.
rewrite (
load_store_other H34).
eauto.
destruct (
invariant_objects invar H36).
invall.
replace x5 with oh in *
by congruence.
generalize (
invariant_disjoint_objects invar n H36 H1 H42 H20 H43 H21).
assert (
offsets !
from <>
None).
inversion H37;
subst;
eauto using path_defined_to.
case_eq (
offsets !
from);
try congruence.
intros until 1.
generalize H40.
rewrite <- (
relative_pointer_offset_reduce_path H37).
intro.
generalize (
own_fields_offset_dynamic_low_bound (
intro H45)
H38).
generalize (
non_virtual_data_size_own_fields_offset (
intro H45)).
generalize (
dynamic_nonempty H38).
intro.
destruct (
relative_pointer_data_incl intro H37 H47 H46).
generalize (
H49 _ H42 _ H45).
generalize (
data_size_high_bound (
intro H42)).
assert ((
Object.arraysize o1 - 1) *
size x4 +
size x4 =
Object.arraysize o1 *
size x4).
ring.
destruct (
relative_pointer_offset_size intro H19 H18).
generalize (
H52 _ H20 _ H9).
generalize (
field_offsets_low_bound (
intro H9)
H10).
generalize (
non_virtual_size_field_offsets (
intro H9)
H10).
unfold field_size.
rewrite H23.
intro.
generalize (
H53 _ (
refl_equal _)).
rewrite (
match_values_size0 _ _ H31).
omega.
intros until 1.
destruct (
peq obj1 (
Object.index o)).
subst.
rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
rewrite PTree.gso;
try congruence;
eauto.
rewrite PTree.gso;
try congruence;
eauto.
destruct (
peq obj2 (
Object.index o)).
subst.
rewrite PTree.gss.
injection 2;
intro;
subst.
rewrite (
Object.class_put_field H6).
rewrite (
Object.arraysize_put_field H6).
eauto.
rewrite PTree.gso;
try congruence;
eauto.
destruct (
peq from to).
subst.
assert (
(
h',
p') = (
h,
p)
).
inversion H2;
subst.
generalize (
Well_formed_hierarchy.self_path_trivial Hhier H4).
injection 1;
intros;
subst.
generalize H6.
simpl.
rewrite (
path_last H3).
destruct (
peq to to);
try congruence.
rewrite <-
app_nil_end.
tauto.
generalize (
Well_formed_hierarchy.self_path_trivial Hhier H4).
injection 1;
intros;
subst.
generalize H6.
simpl.
rewrite (
path_last H3).
destruct (
peq to to);
try congruence.
rewrite <-
app_nil_end.
eauto.
injection H3;
intros;
subst.
generalize (
invariant_vars invar H).
simpl.
intro.
invall.
subst.
esplit.
split.
eleft.
eapply step_ptrshift.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
rewrite PTree.gss.
rewrite PTree.gss.
replace (
x0 + 0)
with x0 by omega.
injection 1;
intro;
subst.
esplit.
split.
reflexivity.
simpl.
eauto.
rewrite PTree.gso;
eauto.
intros.
generalize (
invariant_vars invar H5).
simpl.
destruct 1;
invall.
rewrite PTree.gso;
try congruence.
esplit.
split.
eassumption.
destruct vr;
trivial.
inversion H2;
subst.
generalize (
Well_formed_hierarchy.path_le Hhier H4).
intro.
destruct (
plt from to).
apply False_rect.
generalize (
Ple_Plt_trans H7 p1).
apply Plt_irrefl.
unfold paths.
destruct (
Well_formed_hierarchy.paths Hhier).
invall.
assert (
hierarchy !
to <>
None)
by eauto using path_defined_to.
assert (
x !
to <>
None)
by eauto.
case_eq (
x !
to);
try contradiction.
intros.
destruct (
H9 _ _ H12).
assert (
hierarchy !
from <>
None)
by eauto using path_defined_from.
assert (
t0 !
from <>
None)
by eauto.
case_eq (
t0 !
from);
try contradiction.
intros.
generalize (
H14 _ _ H17).
intro.
destruct (
H18 (
k,
p0)).
generalize (
H20 H4).
intros.
destruct l.
contradiction.
destruct (
H18 p1).
destruct p1.
generalize (
H22 (
or_introl _ (
refl_equal _))).
intro.
generalize (
H5 _ _ H24).
injection 1;
intros;
subst.
destruct t1.
refine (
_ (
non_virtual_subobject_offset_exist Hhier intro _ (
Plt_succ _)
H4 (
accu := 0))).
2 :
eauto.
case_eq (
non_virtual_subobject_offset offsets 0
l0);
try congruence.
intros.
destruct (
invariant_vars0 _ _ H).
invall.
simpl in H29.
invall.
subst.
destruct (
invariant_objects0 _ _ H0).
invall.
generalize (
H30 _ H0 _ _ H1 _ H31).
intros.
esplit.
split.
eleft.
eapply step_ptrshift.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
rewrite PTree.gss.
injection 1;
intros;
subst.
rewrite PTree.gss.
esplit.
split.
reflexivity.
simpl.
esplit.
split.
reflexivity.
rewrite H0.
injection 1;
intro;
subst.
intros until 1.
rewrite H31.
injection 1;
intros;
subst.
generalize H6.
simpl.
inversion H24;
subst.
simpl.
rewrite (
path_last H3).
destruct (
peq from from);
try congruence.
injection 1;
intros;
subst.
functional inversion H27;
subst.
inversion H35;
subst.
inversion H1;
subst.
generalize (
valid_array_path_last H48 H44).
intros;
subst.
unfold relative_pointer_offset.
rewrite H41.
rewrite H42.
functional inversion H43;
subst.
simpl.
unfold subobject_offset.
rewrite H53.
rewrite H56.
destruct (
last_correct (
path_last H3)).
change (
b ::
_x ++
lf)
with ((
b ::
_x) ++
lf).
generalize H52.
rewrite e0.
rewrite app_ass.
simpl.
intros.
generalize (
non_virtual_subobject_offset_rewrite H26 z2).
intro.
rewrite (
non_virtual_subobject_offset_app H54).
rewrite H55.
f_equal.
omega.
intro;
repeat rewrite PTree.gso;
try congruence.
intros.
destruct (
invariant_vars0 _ _ H33).
invall.
esplit.
split.
eassumption.
destruct vr;
trivial.
generalize (
path_path1 H4).
inversion 1;
subst.
inversion H28;
subst.
refine (
_ (
non_virtual_subobject_offset_exist Hhier intro _ (
Plt_succ _)
H28 (
accu := 0))).
2 :
eauto.
case_eq (
non_virtual_subobject_offset offsets 0 (
base ::
lf));
try congruence.
intros.
destruct (
invariant_vars0 _ _ H).
simpl in H32.
invall.
subst.
destruct (
invariant_objects0 _ _ H0).
invall.
assert (
is_dynamic OP hierarchy from).
eapply is_dynamic_virtual_base.
eassumption.
generalize (
H35 _ H0 _ _ H1 _ H36).
intro.
generalize H38.
rewrite (
relative_pointer_offset_reduce_path H1).
intro.
generalize (
invariant_vptr invar H0 H1 H32 H36 H39).
simpl.
replace (
x3 + (
x2 -
x3))
with x2 by omega.
intro.
destruct (
reduce_path_prefix offsets Hhier H3).
invall.
assert (
DYN :
is_dynamic OP hierarchy x4).
eapply primary_path_dynamic.
eassumption.
2 :
eassumption.
eapply path_last.
eassumption.
assumption.
auto.
generalize (
vtables_exist H41 DYN).
case_eq (
vtables real (
h,
reduce_path offsets p));
try congruence.
intros.
destruct v.
destruct (
vtables_prop H41 DYN H44).
subst vbase_offsets0.
functional inversion H38.
assert ((
virtual_base_offsets ofto) !
base <>
None).
eapply virtual_base_offsets_exist.
eauto.
eauto using path_virtual_base.
case_eq ((
virtual_base_offsets ofto) !
base);
try congruence.
intros.
case_eq (
Zsem NO (
z0 -
z2)).
intros.
esplit.
split.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_load.
eassumption.
replace (
x2 + 0)
with x2 by omega.
eassumption.
reflexivity.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_vbase_offset.
rewrite PTree.gss.
reflexivity.
eassumption.
unfold vbase_offsets.
unfold vboffsets.
rewrite <- (
subobject_offset_reduce_path H3).
rewrite H51.
rewrite H50.
rewrite H53.
reflexivity.
reflexivity.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_ptrshiftmult.
rewrite PTree.gso;
try congruence.
rewrite PTree.gso;
try congruence.
eassumption.
rewrite PTree.gss.
rewrite H54.
reflexivity.
rewrite <-
H54.
eapply Zsem_semZ.
reflexivity.
eleft.
eapply step_ptrshift.
rewrite PTree.gss.
replace ((
z0 -
z2) * 1)
with (
z0 -
z2)
by omega.
reflexivity.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v0 target).
subst v0.
rewrite PTree.gss.
injection 1;
intros;
subst vr.
rewrite PTree.gss.
esplit.
split.
reflexivity.
simpl.
esplit.
split.
reflexivity.
rewrite H0.
injection 1;
intro;
subst o0.
intros until 1.
inversion H57.
inversion H1.
generalize (
valid_array_path_last H58 H62).
intro.
subst real0.
rewrite H36.
injection 1;
intros;
subst x3.
generalize H6.
simpl.
injection 1;
intros;
subst h'
p'.
unfold relative_pointer_offset.
rewrite H49.
rewrite H50.
unfold subobject_offset.
rewrite H50.
rewrite H53.
rewrite (
non_virtual_subobject_offset_rewrite H29 z0).
f_equal.
omega.
rewrite PTree.gso.
intros.
destruct (
invariant_vars invar H55).
simpl in H56.
invall.
repeat (
rewrite PTree.gso;
try congruence).
esplit.
split.
eassumption.
destruct vr;
trivial.
assumption.
generalize (
Well_formed_hierarchy.path_le Hhier H4).
intro.
destruct (
plt from to).
assert (
hierarchy !
from <>
None)
by eauto using path_defined_to.
unfold paths.
destruct (
Well_formed_hierarchy.paths Hhier).
invall.
assert (
x !
from <>
None)
by eauto.
case_eq (
x !
from);
try congruence.
intros.
destruct (
H10 _ _ H12).
assert (
hierarchy !
to <>
None)
by eauto using path_defined_from.
assert (
t0 !
to <>
None)
by eauto.
case_eq (
t0 !
to);
try congruence.
intros.
generalize (
H14 _ _ H17
).
intros.
pose (
F :=(
fun hp0 :
Class.Inheritance.t *
list ident =>
let (
y,
_) :=
hp0 in
match y with
|
Class.Inheritance.Repeated =>
true
|
Class.Inheritance.Shared =>
false
end)).
fold F.
case_eq (
filter F l).
intros.
destruct (
H18 (
Class.Inheritance.Repeated,
p0)).
generalize (
H21 H4).
intro.
assert (
F (
Class.Inheritance.Repeated,
p0) =
true).
reflexivity.
destruct (
filter_In F (
Class.Inheritance.Repeated,
p0)
l).
generalize (
H25 (
conj H22 H23)).
rewrite H19.
simpl.
tauto.
intros.
destruct (
filter_In F p2 l).
generalize H20.
rewrite H19.
intro.
destruct (
H22 (
or_introl _ (
refl_equal _))).
destruct (
H18 p2).
generalize (
H25 H23).
destruct p2;
simpl in H24.
destruct t1;
try discriminate.
intro.
generalize (
H5 _ H27).
intros;
subst.
refine (
_ (
non_virtual_subobject_offset_exist Hhier intro _ (
Plt_succ _)
H27 (
accu := 0))).
2 :
eauto.
case_eq (
non_virtual_subobject_offset offsets 0
p0);
try congruence.
intros.
generalize (
invariant_vars invar H).
simpl.
destruct 1.
invall.
subst.
destruct (
invariant_objects invar H0).
invall.
generalize (
H32 _ H0 _ _ H1 _ H33).
intros.
inversion H1;
subst.
inversion H4;
subst.
generalize H6.
simpl.
rewrite (
path_last H3).
destruct (
peq to to);
try congruence.
injection 1;
intros;
subst.
assert (
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar real i h'
p'
to
).
econstructor.
eassumption.
assumption.
assumption.
assumption.
refine (
_ (
relative_pointer_offset_exist Hhier intro guard _ (
Plt_succ _)
H42)).
2 :
eauto.
case_eq (
relative_pointer_offset offsets (
Object.class o)
real ar i p'
);
try congruence.
intros.
functional inversion H43;
subst.
generalize H29.
unfold relative_pointer_offset.
rewrite H45.
rewrite H46.
functional inversion H47;
subst.
replace o0 with ofto in *
by congruence.
simpl.
unfold subobject_offset.
rewrite H48.
rewrite H51.
destruct (
last_correct (
path_last H3)).
revert H44.
change (
b ::
_x ++
lf)
with ((
b ::
_x) ++
lf).
intros.
rewrite e0 in H44,
H49.
revert H49.
rewrite app_ass;
simpl.
rewrite (
non_virtual_subobject_offset_app H44).
rewrite (
non_virtual_subobject_offset_rewrite H28).
injection 1;
intros.
esplit.
split.
eleft.
eapply step_ptrshift.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
rewrite PTree.gss.
injection 1;
intros;
subst.
rewrite PTree.gss.
esplit.
split.
reflexivity.
simpl.
esplit.
split.
reflexivity.
rewrite H0.
injection 1;
intro;
subst.
inversion 1;
subst.
generalize (
valid_array_path_last H35 H55).
intros;
subst.
rewrite H43.
f_equal.
replace x3 with oh in *
by congruence.
omega.
rewrite PTree.gso;
eauto.
intros.
generalize (
invariant_vars invar H52).
simpl.
destruct 1;
invall.
rewrite PTree.gso;
try congruence.
esplit.
split.
eassumption.
destruct vr;
trivial.
assert (
Zpos to <>
Zpos from)
by congruence.
unfold Plt,
Ple in *.
omegaContradiction.
generalize (
invariant_vars invar H).
simpl.
intro.
invall.
subst.
destruct (
invariant_objects invar H0).
invall.
generalize (
H9 _ H0 _ _ H1 _ H10).
intros.
functional inversion H7;
intros;
subst.
generalize H7.
rewrite (
relative_pointer_offset_reduce_path H1).
intro.
generalize (
invariant_vptr invar H0 H1 H2 H10 H16).
simpl.
replace (
x1 + (
x0 -
x1))
with x0 by omega.
intros.
inversion H1;
subst.
destruct (
reduce_path_prefix offsets Hhier H21).
invall.
assert (
is_dynamic OP hierarchy x2).
eapply primary_path_dynamic.
eassumption.
2 :
eassumption.
eauto using path_last.
assumption.
auto.
generalize (
vtables_exist H22 H25).
case_eq (
vtables real (
h,
reduce_path offsets p));
try congruence.
intros.
destruct v.
destruct (
vtables_prop H22 H25 H27).
destruct (
dyncast_offset_spec_reduce_path H5 H21).
destruct (
Well_formed_hierarchy.dynamic_cast_dec Hhier real h p from to).
invall.
assert (
path hierarchy to x5 real x4).
inversion H34;
eauto using path_concat.
refine (
_ (
subobject_offset_exist Hhier intro guard _ (
Plt_succ _)
H33)).
2 :
eauto.
case_eq (
subobject_offset offsets real x5);
try congruence.
intros.
generalize (
H31 _ _ H34 _ H15 _ H35).
intros.
destruct (
H29 to (
Some (
z -
z2))).
generalize (
H38 H36).
intros.
case_eq (
Zsem NO (
z -
z2)).
intros.
destruct (
H3 _ _ H34).
subst newptr.
esplit.
split.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_load.
eassumption.
replace (
x0 + 0)
with x0 by omega.
eassumption.
reflexivity.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_dyncast_exists.
rewrite PTree.gss.
reflexivity.
eassumption.
eassumption.
simpl.
reflexivity.
reflexivity.
eright.
eleft.
econstructor.
econstructor.
rewrite PTree.gss.
reflexivity.
eapply sembool_true.
simpl.
reflexivity.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_dyncast_offset.
rewrite PTree.gso;
try congruence.
rewrite PTree.gss.
reflexivity.
eassumption.
eassumption.
reflexivity.
eleft.
eapply step_ptrshiftmult.
repeat (
rewrite PTree.gso;
try congruence).
eassumption.
rewrite PTree.gss.
rewrite H40.
reflexivity.
rewrite <-
H40.
eapply Zsem_semZ.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v0 target).
subst v0.
rewrite PTree.gss.
injection 1;
intro;
subst vr.
rewrite PTree.gss.
replace ((
z -
z2) * 1)
with (
z -
z2)
by omega.
esplit.
split.
reflexivity.
simpl.
esplit.
split.
reflexivity.
rewrite H0.
injection 1;
intro;
subst o0.
inversion 1.
generalize (
valid_array_path_last H44 H18).
intro;
subst real0.
rewrite H10.
injection 1;
intro;
subst x1.
unfold relative_pointer_offset.
rewrite H13.
rewrite H14.
rewrite H35.
f_equal.
omega.
rewrite PTree.gso;
eauto.
intros.
repeat (
rewrite PTree.gso;
try congruence).
generalize (
invariant_vars invar H41).
simpl.
destruct 1;
invall.
esplit.
split.
eassumption.
destruct vr;
trivial.
generalize (
H32 f).
intros.
destruct (
H29 to None).
generalize (
H35 H33 ).
intros.
generalize (
H4 f).
intros;
subst newptr.
esplit.
split.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_load.
eassumption.
replace (
x0 + 0)
with x0 by omega.
eassumption.
reflexivity.
eright.
eleft.
econstructor.
econstructor.
eright.
eleft.
eapply step_dyncast_exists.
rewrite PTree.gss.
reflexivity.
eassumption.
eassumption.
simpl.
reflexivity.
reflexivity.
eright.
eleft.
econstructor.
econstructor.
rewrite PTree.gss.
reflexivity.
eapply sembool_false.
simpl.
reflexivity.
eleft.
eapply step_null.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst v.
rewrite PTree.gss.
injection 1;
intro;
subst vr.
rewrite PTree.gss.
esplit.
split.
reflexivity.
simpl;
trivial.
rewrite PTree.gso;
eauto.
intros.
repeat (
rewrite PTree.gso;
try congruence).
generalize (
invariant_vars invar H37).
simpl.
destruct 1;
invall.
esplit.
split.
eassumption.
destruct vr;
trivial.
destruct (
invariant_objects invar H0).
invall.
assert (
offsets ! (
Object.class o) <>
None)
by congruence.
assert (
offsets !
class <>
None)
by eauto using valid_array_path_offset.
case_eq (
offsets !
class);
try congruence.
intros.
assert (
hierarchy !
class <>
None)
by eauto.
assert (
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar class i Class.Inheritance.Repeated (
class ::
nil)
class
).
econstructor.
eassumption.
assumption.
assumption.
eleft with (
lt :=
nil).
reflexivity.
reflexivity.
simpl.
case_eq (
hierarchy !
class);
congruence.
assert (
valid_relative_pointer hierarchy (
Object.class o) (
Object.arraysize o)
ar class (
i +
j)
Class.Inheritance.Repeated (
class ::
nil)
class
).
econstructor.
eassumption.
assumption.
assumption.
eleft with (
lt :=
nil).
reflexivity.
reflexivity.
simpl.
case_eq (
hierarchy !
class);
congruence.
generalize (
invariant_vars invar H).
simpl.
destruct 1;
invall;
subst.
generalize (
H20 _ H0 _ _ H15 _ H8).
functional inversion 1;
subst.
replace t0 with ofto in *
by congruence.
generalize H23.
unfold subobject_offset.
rewrite H22.
rewrite (
virtual_base_offsets_self (
intro H22)).
Transparent non_virtual_subobject_offset.
simpl.
injection 1;
intros;
subst.
generalize (
invariant_vars invar H3).
simpl.
destruct 1;
invall;
subst.
esplit.
split.
eleft.
eapply step_ptrshiftmult.
eassumption.
eassumption.
eassumption.
reflexivity.
constructor;
simpl;
trivial.
intro.
destruct (
peq v target).
subst.
rewrite PTree.gss.
injection 1;
intro;
subst.
rewrite PTree.gss.
esplit.
split.
reflexivity.
simpl.
esplit.
split.
reflexivity.
rewrite H0.
injection 1;
intro;
subst o0.
inversion 1;
subst.
generalize (
valid_array_path_last H29 H1).
intro;
subst.
rewrite H8.
injection 1;
intros;
subst.
unfold relative_pointer_offset.
rewrite H21.
rewrite H22.
rewrite H23.
f_equal.
replace ((
i +
j) *
size ofto)
with (
i *
size ofto +
j *
size ofto)
by ring.
omega.
rewrite PTree.gso;
eauto.
intros.
repeat (
rewrite PTree.gso;
try congruence).
generalize (
invariant_vars invar H25).
simpl.
destruct 1;
invall;
subst.
esplit.
split.
eassumption.
destruct vr;
trivial.
Qed.
End Preservation.
End Compiler.
End SimpleCompiler.