Object.thy
Back to the index of JVM0_ASCII
Object = Runtime +
(** array types **)
datatype
atype = T_INT
constdefs
type_of_atype :: "atype => field_desc"
"type_of_atype at == I"
datatype
arr_type = PA atype | AA cl_idx
constdefs
type_of_arr_type :: "[cpool,arr_type] => field_desc"
"type_of_arr_type cpool aty ==
case aty of
(PA at) => type_of_atype at
| (AA idx) => type_of_str (extract_Class cpool idx)"
(** Although both class instances and arrays are objects, the JVM creates and
manipulates class instances and arrays using distinct sets of instructions **)
datatype
create_object =
New cl_idx (* Create new object *)
| IAnewarray arr_type (* Create new array of prim/ref type *)
consts
exec_co :: "[create_object,'code classfiles,cpool,heap,opstack,p_count] =>
(xcpt option * heap * opstack * p_count)"
primrec
"exec_co (New idx) CFS cp hp stk pc =
(let oc = get_Id (extract_Class cp idx);
oref = newref hp;
hp' = hp(oref |-> Obj oc (init_obj CFS oc));
xp' = if is_interface (CFS !! oc)
then Some InstantiationError
else if !x. hp x ~= None
then Some OutOfMemory
else None
in (xp' , hp' , (Addr oref)#stk , pc+1))"
"exec_co (IAnewarray X) CFS cp hp stk pc =
(let fd = type_of_arr_type cp X;
count = get_Intg (hd stk);
xp' = if count < #0
then Some NegArrSize
else if !x. hp x ~= None
then Some OutOfMemory
else None;
aref = newref hp;
hp' = hp(aref |-> Arr fd (init_arr (default_val fd) count))
in
(xp' , hp' , (Addr aref)#(tl stk) , pc+1))"
datatype
manipulate_object =
Getfield fr_idx (* Fetch field from object *)
| Putfield fr_idx (* Set field in object *)
consts
exec_mo :: "[manipulate_object,cpool,heap,opstack,p_count] =>
(xcpt option * heap * opstack * p_count)"
primrec
"exec_mo (Getfield idx) cp hp stk pc =
(let oref = hd stk;
(oc,fs) = get_Obj (hp !! (get_Addr oref));
(fc,fn,fd) = extract_Fieldref cp idx;
xp' = if oref=Null
then Some NullPointer
else None
in
(xp' , hp , (fs !! (fc,fn))#(tl stk) , pc+1))"
"exec_mo (Putfield idx) cp hp stk pc =
(let (fval,oref)= (hd stk,hd (tl stk));
(oc,fs) = get_Obj (hp !! (get_Addr oref));
(fc,fn,fd) = extract_Fieldref cp idx;
hp' = hp(get_Addr oref |-> Obj oc (fs((fc,fn) |-> fval)));
xp' = if oref=Null
then Some NullPointer
else None
in
(xp' , hp' , tl (tl stk), pc+1))"
datatype
manipulate_array =
IAaload ins_type ("_ aload" 30) (* Load int/ref from array *)
| IAastore ins_type ("_ astore" 30) (* Store into int/ref array *)
consts
exec_ma :: "[manipulate_array,'code classfiles,heap,opstack,p_count] =>
(xcpt option * heap * opstack * p_count)"
primrec
"exec_ma (X aload) CFS hp stk pc =
(let (idx,aref) = (hd stk,hd (tl stk));
(fd,ad) = get_Arr (hp !! (get_Addr aref));
xp = if aref=Null
then Some NullPointer
else if length ad <= get_Nat idx
then Some IndOutBound
else None
in
(xp , hp , (ad ! (get_Nat idx)) # (tl (tl stk)) , pc+1))"
"exec_ma (X astore) CFS hp stk pc =
(let (val,idx,aref) = (hd stk,hd (tl stk),hd (tl (tl stk)));
(fd,ad) = get_Arr (hp !! (get_Addr aref));
hp' = hp(get_Addr aref |-> (Arr fd (ad[get_Nat idx := val])));
xp = if aref=Null
then Some NullPointer
else if length ad <= get_Nat idx
then Some IndOutBound
else if ~ (fd_compatible CFS hp X val fd)
then Some ArrStore
else None
in
(xp , hp' , tl (tl (tl stk)) , pc+1))"
datatype
check_object =
Checkcast cl_idx (* Check whether object is of given type *)
consts
exec_ch :: "[check_object,'code classfiles,cpool,heap,opstack,p_count]
=> (xcpt option * p_count)"
primrec
"exec_ch (Checkcast idx) CFS cp hp stk pc =
(let oref = hd stk;
ct = type_of_str (extract_Class cp idx);
ot = get_obj_type (hp !! (get_Addr oref));
xp = if oref=Null
then None
else if ~ (compatible CFS ot ct)
then Some ClassCast
else None
in
(xp , pc+1))"
end