We just focus on several main parts of the infrastructure, namely the registers map- ping, class definition, method definition and heap definition.
Registers Mapping The main difference between DVM and JVM is the registers, which is implemented as a mapping from a register to a value. It is implemented as a mapping module which has three main functions: getis a function which takes a mapping and a variable and return a value, update is a function which takes a mapping, a variable x, and a valuev, and return a new mapping where the content of variablex isv, such that:
1. if we update a variable xin the mapping with valuev, then the content ofx in the new mapping will bev(get_update_new); and
2. if a variable x is not modified, then the content of x in the new mapping will be the constant (get_update_old).
These two properties will be useful when we prove soundness.
Module Type DEX_REGISTERS. Parameter t : Type.
Parameter get : t-> DEX_Reg -> option DEX_value. Parameter update : t -> DEX_Reg -> DEX_value -> t. Parameter dom : t -> list DEX_Reg.
§5.1 The Semantics of DVM 103
Parameter get_update_new :
forall l x v, get (update l x v) x = Some v. Parameter get_update_old :
forall l x y v, x<>y -> get (update l x v) y = get l y. End DEX_REGISTERS.
ClassEach class is distinguished by its name. A class may have a direct superclass, and class names form a hierarchy based on the superclass relation. Each class is also distinguished by the list of interfaces it implemented, and list of fields and methods which it has. Since DEXI and DEXO do not use any of those features, we just use the class itself as the container of the program without having to worry about class hierarchy and interface implemented. But it is useful to retain this structure for a complete formalization of DEX.
Module Type DEX_CLASS_TYPE.
Parameter name : DEX_Class -> DEX_ClassName. (** direct superclass *)
Parameter superClass : DEX_Class -> option DEX_ClassName. (** list of implemented interfaces *)
Parameter superInterfaces : DEX_Class -> list DEX_InterfaceName. Parameter field : DEX_Class -> DEX_ShortFieldName ->
option DEX_Field.
Parameter definedFields : DEX_Class -> list DEX_Field. Parameter in_definedFields_field_some : forall c f,
In f (definedFields c) ->
field c (DEX_FIELDSIGNATURE.name (DEX_FIELD.signature f)) = Some f.
Parameter field_some_in_definedFields : forall c f sfn, field c sfn = Some f -> In f (definedFields c).
Parameter method : DEX_Class -> DEX_ShortMethodSignature -> option DEX_Method.
Parameter method_signature_prop : forall cl mid m,
method cl mid = Some m -> mid = DEX_METHOD.signature m. Definition defined_Method (cl:DEX_Class) (m:DEX_Method) :=
method cl (DEX_METHOD.signature m) = Some m. (* modifiers *)
Parameter isFinal : DEX_Class -> bool. Parameter isPublic : DEX_Class -> bool. Parameter isAbstract : DEX_Class -> bool.
End DEX_CLASS_TYPE.
MethodThe method container is separated from its body because it is possible for a method to be abstract, that is its body needs to be fleshed out in the method of the class that implements the abstract method. The body of the method itself specifies the first address, the relationship between program points, and a mapping from program points to instructions. We also require that there are no duplicate registers (which is true by definition).
Module Type DEX_METHOD_TYPE.
Parameter signature : DEX_Method -> DEX_ShortMethodSignature. (** A method that is not abstract has an empty method body *) Parameter body : DEX_Method -> option DEX_BytecodeMethod. (* modifiers *)
Parameter isFinal : DEX_Method -> bool. Parameter isStatic : DEX_Method -> bool. Parameter isNative : DEX_Method -> bool.
Definition isAbstract (m : DEX_Method) : bool := match body m with
None => true | Some _ => false end.
Parameter visibility : DEX_Method -> DEX_Visibility. Definition valid_reg (m:DEX_Method) (x:DEX_Reg) : Prop :=
forall bm, body m = Some bm ->
(Reg_toN x) <= (DEX_BYTECODEMETHOD.max_locals bm). (* DEX additional for locR *)
Definition within_locR (m:DEX_Method) (x:DEX_Reg) : Prop :=
forall bm, body m = Some bm -> In x (DEX_BYTECODEMETHOD.locR bm). End DEX_METHOD_TYPE.
Module Type DEX_BYTECODEMETHOD_TYPE.
Parameter firstAddress : DEX_BytecodeMethod -> DEX_PC. Parameter nextAddress : DEX_BytecodeMethod -> DEX_PC ->
option DEX_PC.
Parameter instructionAt : DEX_BytecodeMethod -> DEX_PC -> option DEX_Instruction.
§5.1 The Semantics of DVM 105
Parameter max_locals : DEX_BytecodeMethod -> nat. (** max number of elements on the operand stack *)
Parameter max_operand_stack_size : DEX_BytecodeMethod -> nat. (* DEX for type system *)
Parameter locR : DEX_BytecodeMethod -> list DEX_Reg. Parameter regs : DEX_BytecodeMethod -> list DEX_Reg. Parameter noDup_regs : forall bm, NoDup (regs (bm)).
Definition DefinedInstruction (bm:DEX_BytecodeMethod) (pc:DEX_PC) : Prop := exists i, instructionAt bm pc = Some i.
End DEX_BYTECODEMETHOD_TYPE.
HeapThe implementation of heap in DEX is the same as the one in JVM except that we only implement the dynamic field for objects (we do not implement array and static field). Heap is implemented as a mapping from an address to the reference of the object. There are three main interfaces to the heap, namely get, update, and new. Getis a function which returns the reference of the object,updateis a function which updates the reference of the object contained in the mentioned address, and newis a function to allocate a new object in the heap.
Module Type DEX_HEAP. Parameter t : Type.
Inductive DEX_AdressingMode : Set :=
| DEX_DynamicField : DEX_Location -> DEX_FieldSignature -> DEX_AdressingMode.
Inductive DEX_LocationType : Type :=
| DEX_LocationObject : DEX_ClassName -> DEX_LocationType. Parameter get : t -> DEX_AdressingMode -> option DEX_value. Parameter update : t -> DEX_AdressingMode -> DEX_value -> t. Parameter typeof : t -> DEX_Location -> option DEX_LocationType. Parameter new : t -> DEX_Program -> DEX_LocationType ->
option (DEX_Location * t).
Inductive Compat (h:t) : DEX_AdressingMode -> Prop := | CompatObject : forall cn loc f,
typeof h loc = Some (DEX_LocationObject cn) -> Compat h (DEX_DynamicField loc f).
Parameter get_update_same : forall h am v, Compat h am -> get (update h am v) am = Some v.
get (update h am1 v) am2 = get h am2.
Parameter get_uncompat : forall h am, ~ Compat h am -> get h am = None.
Parameter typeof_update_same : forall h loc am v, typeof (update h am v) loc = typeof h loc.
Parameter new_fresh_location : forall (h:t) (p:DEX_Program) (lt:DEX_LocationType) (loc:DEX_Location) (h’:t),
new h p lt = Some (loc,h’) -> typeof h loc = None.
Parameter new_typeof : forall (h:t) (p:DEX_Program) (lt:DEX_LocationType) (loc:DEX_Location) (h’:t), new h p lt = Some (loc,h’) ->
typeof h’ loc = Some lt.
Parameter new_typeof_old : forall (h:t) (p:DEX_Program) (lt:DEX_LocationType) (loc loc’:DEX_Location) (h’:t), new h p lt = Some (loc,h’) ->
loc <> loc’ ->
typeof h’ loc’ = typeof h loc’.
Parameter new_defined_object_field : forall (h:t) (p:DEX_Program) (cn:DEX_ClassName) (fs:DEX_FieldSignature) (f:DEX_Field) (loc:DEX_Location) (h’:t),
new h p (DEX_LocationObject cn) = Some (loc,h’) -> is_defined_field p cn fs f ->
get h’ (DEX_DynamicField loc fs) = Some (init_field_value f). Parameter new_undefined_object_field : forall (h:t) (p:DEX_Program)
(cn:DEX_ClassName) (fs:DEX_FieldSignature) (loc:DEX_Location) (h’:t), new h p (DEX_LocationObject cn) = Some (loc,h’) ->
~ defined_field p cn fs ->
get h’ (DEX_DynamicField loc fs) = None. Parameter new_object_no_change :
forall (h:t) (p:DEX_Program) (cn:DEX_ClassName) (loc:DEX_Location) (h’:t) (am:DEX_AdressingMode),
new h p (DEX_LocationObject cn) = Some (loc,h’) -> (forall (fs:DEX_FieldSignature), am <>
(DEX_DynamicField loc fs)) -> get h’ am = get h am. End DEX_HEAP.
§5.1 The Semantics of DVM 107