• No se han encontrado resultados

El eudemonismo socrático: no utilitarismo,

In document SO C R A T E S (página 48-56)

As mentioned in Chapter 4, the state of the operational semantics is a tuple of pro- gram point, heap, and registers mapping. In the case where a method is returning a value, the return state is a pair of heap and a single value. In this section, we will walk through each of the formalized operational semantics and how it matched the definition that we have outlined in Chapter 4, or what it means if the instruction is not in the list. There is explicit mentioning of the register domain even though

§5.1 The Semantics of DVM 109

in theory this is not crucial. The reason we put them here is to ease the burden of having to prove that the registers involved are in the domain even though we already assumed that the registers involved in a method are total, meaning that every register involved in an operation will always be in the domain.

| nop : forall h m pc pc’ regs,

instructionAt m pc = Some DEX_Nop -> next m pc = Some pc’ ->

DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs))

Nop is not mentioned in the list, and basically, it stands for no operation. Upon reaching the program point with Nop, the state just transitions into its successor (next program point) without making any changes to the register nor the heap.

| const : forall h m pc pc’ regs regs’ k rt v, instructionAt m pc = Some (DEX_Const k rt v) -> In rt (DEX_Registers.dom regs) ->

next m pc = Some pc’ -> (-2^31 <= v < 2^31)%Z -> DEX_METHOD.valid_reg m rt ->

regs’ = DEX_Registers.update regs rt (Num (I (Int.const v))) -> DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs’))

Const updates the mapping register with a constant value v. It matched with the operational semantics rule of Const: Pm[i] =const(r,v)

⟨i,ρ,h⟩ ↝m,Norm⟨i+1,ρ⊕ {r↦v},h⟩. The up-

date of ρ⊕ {r ↦v} corresponds to the update of regs′, the next program points pc′

corresponds toi+1, and there are no changes to the heap.

| move_step_ok : forall h m pc pc’ regs regs’ k rt rs v, instructionAt m pc = Some (DEX_Move k rt rs) ->

In rt (DEX_Registers.dom regs) -> In rs (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some v = DEX_Registers.get regs rs -> DEX_METHOD.valid_reg m rt ->

DEX_METHOD.valid_reg m rs ->

regs’ = DEX_Registers.update regs rt v ->

Move copy a value stored in the source register to the target register. This cor- responds to the operational semantic rule Pm[i] =move(r,rs) rs∈dom(ρ)

⟨i,ρ,h⟩ ↝m,Norm⟨i+1,ρ⊕ {r↦ρ(rs)},h⟩ where the update of ρ⊕ {r ↦ ρ(rs)} corresponds to the update of regs′ and v cor- responds to the value of ρ(rs). There are no changes to the heap, so the next step also has the same heaph.

| goto_step_ok : forall h m pc regs o, instructionAt m pc = Some (DEX_Goto o) -> DEX_NormalStep p m (pc, (h, regs))

((DEX_OFFSET.jump pc o), (h, regs))

Just likeNop,Gotojust modifies a program point and does not change any registers nor the heap. It corresponds to Pm[i] =goto(t)

⟨i,ρ,h⟩ ↝ ⟨t,ρ,h⟩ where tcorresponds to the offset

jump.

| packedswitch_step_ok1 : forall h m pc l v r firstKey size list_offset n o,

instructionAt m pc =

Some (DEX_PackedSwitch r firstKey size list_offset) -> Some (Num (I v)) = DEX_Registers.get l r ->

(firstKey <= Int.toZ v < firstKey + (Z_of_nat size))%Z -> length list_offset = size ->

Z_of_nat n = ((Int.toZ v) - firstKey)%Z -> nth_error list_offset n = Some o ->

DEX_METHOD.valid_reg m r ->

DEX_NormalStep p m (pc, (h, l)) ((DEX_OFFSET.jump pc o), (h, l)) | packedswitch_step_ok2 : forall h m pc pc’ l v r firstKey size

list_offset,

instructionAt m pc =

Some (DEX_PackedSwitch r firstKey size list_offset) -> Some (Num (I v)) = DEX_Registers.get l r ->

length list_offset = size ->

(Int.toZ v < firstKey \/ firstKey + (Z_of_nat size) <= Int.toZ v)%Z -> next m pc = Some pc’ ->

DEX_METHOD.valid_reg m r ->

§5.1 The Semantics of DVM 111

In the case where the content of the register is within (f irstKey+size), then the program point will be transferred to the corresponding offset from the list. In the case where the value falls out of range, then the program point will be transferred to the next program point. There are no changes to the registers mapping nor the heap. The two rules correspond to these two scenarios.

| sparseswitch_step_ok1 : forall h m pc l v v’ o r size listkey, instructionAt m pc = Some (DEX_SparseSwitch r size listkey) -> length listkey = size ->

Some (Num (I v)) = DEX_Registers.get l r -> List.In (pair v’ o) listkey ->

v’ = Int.toZ v ->

DEX_METHOD.valid_reg m r ->

DEX_NormalStep p m (pc, (h, l)) ((DEX_OFFSET.jump pc o), (h, l)) | sparseswitch_step_ok2 : forall h m pc pc’ l v r size listkey,

instructionAt m pc = Some (DEX_SparseSwitch r size listkey) -> length listkey = size ->

Some (Num (I v)) = DEX_Registers.get l r ->

(forall v’ o, List.In (pair v’ o) listkey -> v’ <> Int.toZ v) -> next m pc = Some pc’ ->

DEX_METHOD.valid_reg m r ->

DEX_NormalStep p m (pc, (h, l)) (pc’, (h, l))

In the case where the content of the register is in one of the key offset pairs, then the program point will be transferred to the corresponding offset. If the value does not match any of the keys in the list, then the program point will be transferred to the next program point instead. Just likePackedswitch, there are no changes to the registers mapping nor the heap, and the two rules correspond to the two scenarios.

| ifcmp_step_jump : forall h m pc regs va vb cmp ra rb o, instructionAt m pc = Some (DEX_Ifcmp cmp ra rb o) -> In ra (DEX_Registers.dom regs) ->

In rb (DEX_Registers.dom regs) ->

Some (Num (I va)) = DEX_Registers.get regs ra -> Some (Num (I vb)) = DEX_Registers.get regs rb -> SemCompInt cmp (Int.toZ va) (Int.toZ vb) -> DEX_METHOD.valid_reg m ra ->

DEX_NormalStep p m (pc, (h, regs)) ((DEX_OFFSET.jump pc o), (h, regs))

| ifcmp_step_continue : forall h m pc pc’ regs va vb cmp ra rb o, instructionAt m pc = Some (DEX_Ifcmp cmp ra rb o) ->

In ra (DEX_Registers.dom regs) -> In rb (DEX_Registers.dom regs) ->

Some (Num (I va)) = DEX_Registers.get regs ra -> Some (Num (I vb)) = DEX_Registers.get regs rb -> ~SemCompInt cmp (Int.toZ va) (Int.toZ vb) -> next m pc = Some pc’ ->

DEX_METHOD.valid_reg m ra -> DEX_METHOD.valid_reg m rb ->

DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs)) | ifz_step_jump : forall h m pc regs v cmp r o,

instructionAt m pc = Some (DEX_Ifz cmp r o) -> In r (DEX_Registers.dom regs) ->

Some (Num (I v)) = DEX_Registers.get regs r -> SemCompInt cmp (Int.toZ v) (0) ->

DEX_METHOD.valid_reg m r ->

DEX_NormalStep p m (pc, (h, regs)) ((DEX_OFFSET.jump pc o), (h, regs))

| ifz_step_continue : forall h m pc pc’ regs v cmp r o, instructionAt m pc = Some (DEX_Ifz cmp r o) ->

In r (DEX_Registers.dom regs) ->

Some (Num (I v)) = DEX_Registers.get regs r -> ~SemCompInt cmp (Int.toZ v) (0) ->

next m pc = Some pc’ ->

DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs))

These rules correspond to the two operational semantics rules for ifz. If the test is true, then the program point will be transferred to the offset pointed by the instruc- tion. Otherwise, the instruction will fall through to the next instruction. There are no modifications to the registers mapping and the heap. These rules correspond to the operational semantics rule P[i]m=ifeq(r,j) ρ(r) =0

§5.1 The Semantics of DVM 113

Pm[i] =ifeq(r,t) ρ(r) ≠0

⟨i,ρ,h⟩ ↝m,Norm⟨i+1,ρ,h⟩ where the test is not true.

| ineg_step : forall h m pc regs regs’ pc’ rt rs v, instructionAt m pc = Some (DEX_Ineg rt rs) -> In rt (DEX_Registers.dom regs) ->

In rs (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Num (I v)) = DEX_Registers.get regs rs -> DEX_METHOD.valid_reg m rt ->

DEX_METHOD.valid_reg m rs ->

regs’ = DEX_Registers.update regs rt (Num (I (Int.neg v))) -> DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs’))

| inot_step : forall h m pc regs regs’ pc’ rt rs v, instructionAt m pc = Some (DEX_Inot rt rs) -> In rt (DEX_Registers.dom regs) ->

In rs (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Num (I v)) = DEX_Registers.get regs rs -> DEX_METHOD.valid_reg m rt ->

DEX_METHOD.valid_reg m rs ->

regs’ = DEX_Registers.update regs rt (Num (I (Int.not v))) -> DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs’))

| i2b_step_ok : forall h m pc pc’ regs regs’ rt rs v, instructionAt m pc = Some (DEX_I2b rt rs) ->

In rt (DEX_Registers.dom regs) -> In rs (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Num (I v)) = DEX_Registers.get regs rs -> DEX_METHOD.valid_reg m rt ->

DEX_METHOD.valid_reg m rs ->

regs’ = DEX_Registers.update regs rt (Num (I (b2i (i2b v)))) -> DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs’))

| i2s_step_ok : forall h m pc pc’ regs regs’ rt rs v, instructionAt m pc = Some (DEX_I2s rt rs) ->

In rt (DEX_Registers.dom regs) -> In rs (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Num (I v)) = DEX_Registers.get regs rs -> DEX_METHOD.valid_reg m rt ->

DEX_METHOD.valid_reg m rs ->

regs’ = DEX_Registers.update regs rt (Num (I (s2i (i2s v)))) -> DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs’))

The four instructions here are unary operators, and they have similar operational semantics except that each instruction has a different effect. i2s convert integer to short, i2b convert integer to byte, ineg gives the two’s complement of the value contained in the register andinotgives the one’s complement of the value contained in the register. The program point will then be transferred into the next instruction.

| ibinop_step_ok : forall h m pc pc’ regs regs’ op rt ra rb va vb, instructionAt m pc = Some (DEX_Ibinop op rt ra rb) ->

In rt (DEX_Registers.dom regs) -> In ra (DEX_Registers.dom regs) -> In rb (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Num (I va)) = DEX_Registers.get regs ra -> Some (Num (I vb)) = DEX_Registers.get regs rb -> DEX_METHOD.valid_reg m rt ->

DEX_METHOD.valid_reg m ra -> DEX_METHOD.valid_reg m rb ->

regs’ = DEX_Registers.update regs rt (Num (I (SemBinopInt op va vb))) ->

DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs’))

| ibinopconst_step_ok : forall h m pc pc’ regs regs’ op rt r va v, instructionAt m pc = Some (DEX_IbinopConst op rt r v) ->

In r (DEX_Registers.dom regs) -> In rt (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Num (I va)) = DEX_Registers.get regs r -> DEX_METHOD.valid_reg m rt ->

DEX_METHOD.valid_reg m r ->

regs’ = DEX_Registers.update regs rt

§5.1 The Semantics of DVM 115

DEX_NormalStep p m (pc, (h, regs)) (pc’, (h, regs’))

These two instructions have very similar operational semantics corresponding to binop: Pm[i] =binop(op,r,ra,rb) ra,rb∈dom(ρ) n=ρ(ra)opρ(rb)

⟨i,ρ,h⟩ ↝m,Norm⟨i+1,ρ⊕ {r↦n},h⟩ . The regis-

ters mapping will update the value with the result of applying the binary operation to the values. The program point will then be transferred to the next instruction.

| new : forall h m pc pc’ regs regs’ c rt loc h’, instructionAt m pc = Some (DEX_New rt c) -> In rt (DEX_Registers.dom regs) ->

next m pc = Some pc’ ->

DEX_Heap.new h p (DEX_Heap.DEX_LocationObject c) = Some (pair loc h’) -> regs’ = DEX_Registers.update regs rt (Ref loc) ->

DEX_NormalStep p m (pc,(h,regs)) (pc’,(h’,regs’))

The operational semantics of new: Pm[i] =new(r,c) l=fresh(h)

⟨i,ρ,h⟩ ↝ ⟨i+1,ρ⊕ {r↦l},h⊕ {l↦default(c)}⟩

matches this instruction. The heap is updated with a mapping to the new object, and the register mapping is updated with the corresponding fresh location. The program point is then transferred to the next instruction.

| iput : forall h m pc pc’ regs f rs ro loc cn k v, instructionAt m pc = Some (DEX_Iput k rs ro f) -> In rs (DEX_Registers.dom regs) ->

In ro (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Ref loc) = DEX_Registers.get regs ro -> Some v = DEX_Registers.get regs rs ->

DEX_Heap.typeof h loc = Some (DEX_Heap.DEX_LocationObject cn) -> defined_field p cn f ->

assign_compatible p h v (DEX_FIELDSIGNATURE.type (snd f)) -> DEX_NormalStep p m (pc,(h,regs))

(pc’,(DEX_Heap.update h (DEX_Heap.DEX_DynamicField loc f) v, regs))

The semantics Pm[i] =iput(rs,ro,f) ρ(ro) ∈dom(h) f ∈dom(h(ρ(ro)))

⟨i,ρ,h⟩ ↝n,Norm⟨i+1,ρ,os,h⊕ {ρ(ro) ↦h(ρ(ro)) ⊕ {f ↦ρ(rs)}}⟩

matches this instruction. The field f of the object in the heap which corresponds to the object referenced by ro is updated with the value that is contained inrs. There are no up- dates to the registers mapping, and then the program will continue execution with the next instruction. Although in Figure 4.2 there are more semantics for iput, but only one is applicable in this case. This is because DEXO does not have exception handling mechanism hence the other possible semantics do not apply.

| getfield : forall h m pc pc’ regs regs’ rt ro loc f k v cn, instructionAt m pc = Some (DEX_Iget k rt ro f) ->

In rt (DEX_Registers.dom regs) -> In ro (DEX_Registers.dom regs) -> next m pc = Some pc’ ->

Some (Ref loc) = DEX_Registers.get regs ro ->

DEX_Heap.typeof h loc = Some (DEX_Heap.DEX_LocationObject cn) -> defined_field p cn f ->

DEX_Heap.get h (DEX_Heap.DEX_DynamicField loc f) = Some v -> regs’ = DEX_Registers.update regs rt v ->

DEX_NormalStep p m (pc,(h, regs)) (pc’,(h, regs’))

The operational semantics Pm[i] =iget(r,ro,f) ρ(ro) ∈dom(h) f ∈dom(h(ρ(ro)))

⟨i,ρ,h⟩ ↝m,Norm⟨i+1,ρ⊕ {r↦h(ρ(ro)).f},h⟩ matches with this instruction. The registers mapping will be updated with the value from the field f of the object in the heap which is referred by ro. There are no changes to the heap, and the execution will continue with the next execution. Like iput, there is only one semantics applicable since DEXO does not have exception handling mechanism.

| void_return : forall h m pc regs,

instructionAt m pc = Some DEX_Return ->

DEX_METHODSIGNATURE.result (DEX_METHOD.signature m) = None -> DEX_ReturnStep p m (pc, (h, regs)) (h, Normal None)

| vreturn : forall h m pc regs val t k rs,

instructionAt m pc = Some (DEX_VReturn k rs) -> In rs (DEX_Registers.dom regs) ->

DEX_METHODSIGNATURE.result (DEX_METHOD.signature m) = Some t -> assign_compatible p h val t ->

compat_ValKind_value k val ->

Some val = DEX_Registers.get regs rs ->

DEX_ReturnStep p m (pc, (h, regs)) (h, Normal (Some val))

In the case where the method is not returning a value, the method execution will stop there. When a method is method is returning a value, the content of the register will become the return value. It corresponds to the rule P[i]m =return(rs) rs∈dom(ρ)

⟨i,ρ,h⟩ ↝m,Normρ(rs),h .

§5.1 The Semantics of DVM 117

In document SO C R A T E S (página 48-56)