Skip to content

Commit f84c925

Browse files
ttuegelrv-jenkins
authored andcommitted
Use Bytes for the Haskell backend (#596)
* Makefile: separate tangles * data: separate tanglers for bytes/nobytes * Use Bytes for Haskell backend * test totalSupply spec * data.md: #range is substrBytes * evm.md: #computeValidJumpDests: No owise * TMP sum-to-n-spec.k: Remove edsl.k * revert #range impl * Revert "test totalSupply spec" This reverts commit 5f0e965. * Restore deps/k * deps/k: Use BYTES-HOOKED with Haskell backend * optimize #parseByteStack function * add functional to alignHexString * fix merkle-spec.k * update .nobytes version of #parseHexBytes * update search expected output * fix typo * fix side condition
1 parent f9036d5 commit f84c925

File tree

8 files changed

+67
-62
lines changed

8 files changed

+67
-62
lines changed

Makefile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,10 @@ llvm_kompiled := $(llvm_dir)/$(MAIN_DEFN_FILE)-kompiled/interpreter
180180

181181
# Tangle definition from *.md files
182182

183-
concrete_tangle := .k:not(.node):not(.symbolic),.standalone,.concrete
184-
symbolic_tangle := .k:not(.node):not(.concrete),.standalone,.symbolic
185-
node_tangle := .k:not(.standalone):not(.symbolic),.node,.concrete
183+
concrete_tangle := .k:not(.node):not(.symbolic):not(.nobytes),.standalone,.concrete,.bytes
184+
java_tangle := .k:not(.node):not(.concrete):not(.bytes),.standalone,.symbolic,.nobytes
185+
haskell_tangle := .k:not(.node):not(.concrete):not(.nobytes),.standalone,.symbolic,.bytes
186+
node_tangle := .k:not(.standalone):not(.symbolic):not(.nobytes),.node,.concrete,.bytes
186187

187188
defn: $(defn_files)
188189
ocaml-defn: $(ocaml_files)
@@ -202,11 +203,11 @@ $(llvm_dir)/%.k: %.md $(TANGLER)
202203

203204
$(java_dir)/%.k: %.md $(TANGLER)
204205
@mkdir -p $(java_dir)
205-
pandoc --from markdown --to "$(TANGLER)" --metadata=code:"$(symbolic_tangle)" $< > $@
206+
pandoc --from markdown --to "$(TANGLER)" --metadata=code:"$(java_tangle)" $< > $@
206207

207208
$(haskell_dir)/%.k: %.md $(TANGLER)
208209
@mkdir -p $(haskell_dir)
209-
pandoc --from markdown --to "$(TANGLER)" --metadata=code:"$(symbolic_tangle)" $< > $@
210+
pandoc --from markdown --to "$(TANGLER)" --metadata=code:"$(haskell_tangle)" $< > $@
210211

211212
$(node_dir)/%.k: %.md $(TANGLER)
212213
@mkdir -p $(node_dir)

asm.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Operator `#revOps` can be used to reverse a program.
4040
// -------------------------------------------------------
4141
```
4242

43-
```{.k .symbolic}
43+
```{.k .nobytes}
4444
syntax ByteArray ::= #asmOpCodes ( OpCodes, ByteArray ) [function, klabel(#asmOpCodesAux)]
4545
// ------------------------------------------------------------------------------------------
4646
rule #asmOpCodes( OPS ) => #asmOpCodes(#revOps(OPS), .ByteArray)
@@ -50,7 +50,7 @@ Operator `#revOps` can be used to reverse a program.
5050
rule #asmOpCodes( .OpCodes, WS ) => WS
5151
```
5252

53-
```{.k .concrete}
53+
```{.k .bytes}
5454
syntax ByteArray ::= #asmOpCodes ( OpCodes, StringBuffer ) [function, klabel(#asmOpCodesAux)]
5555
// ---------------------------------------------------------------------------------------------
5656
rule #asmOpCodes( OPS ) => #asmOpCodes(OPS, .StringBuffer)

data.md

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module EVM-DATA
4040
imports JSON
4141
```
4242

43-
```{.k .concrete}
43+
```{.k .concrete .bytes}
4444
imports BYTES
4545
```
4646

@@ -517,10 +517,10 @@ The local memory of execution is a byte-array (instead of a word-array).
517517
- `#sizeByteArray` calculates the size of a `ByteArray`.
518518
- `#padToWidth(N, WS)` and `#padRightToWidth` make sure that a `WordStack` is the correct size.
519519

520-
```{.k .concrete}
520+
```{.k .bytes}
521521
syntax ByteArray = Bytes
522-
syntax ByteArray ::= ".ByteArray" [function]
523-
// --------------------------------------------
522+
syntax ByteArray ::= ".ByteArray" [function, functional]
523+
// --------------------------------------------------------
524524
rule .ByteArray => .Bytes
525525
526526
syntax Int ::= #asWord ( ByteArray ) [function, smtlib(asWord)]
@@ -562,7 +562,7 @@ The local memory of execution is a byte-array (instead of a word-array).
562562
rule #padToWidth(N, WS) => padLeftBytes(WS, N, 0)
563563
```
564564

565-
```{.k .symbolic}
565+
```{.k .nobytes}
566566
syntax ByteArray = WordStack
567567
syntax ByteArray ::= ".ByteArray" [function]
568568
// --------------------------------------------
@@ -721,7 +721,7 @@ We are using the polymorphic `Map` sort for these word maps.
721721
- `WM [ N := WS ]` assigns a contiguous chunk of $WM$ to $WS$ starting at position $W$.
722722
- `#range(M, START, WIDTH)` reads off $WIDTH$ elements from $WM$ beginning at position $START$ (padding with zeros as needed).
723723

724-
```{.k .concrete}
724+
```{.k .bytes}
725725
syntax Map ::= Map "[" Int ":=" ByteArray "]" [function, klabel(mapWriteBytes)]
726726
// -------------------------------------------------------------------------------
727727
rule WM[ N := WS ] => WM [ N := WS, 0, #sizeByteArray(WS) ]
@@ -739,7 +739,7 @@ We are using the polymorphic `Map` sort for these word maps.
739739
rule #range(WM, I, J, WIDTH, WS) => #range(WM, I +Int 1, J +Int 1, WIDTH, WS [ J <- {WM[I] orDefault 0}:>Int ]) [owise]
740740
```
741741

742-
```{.k .symbolic}
742+
```{.k .nobytes}
743743
syntax Map ::= Map "[" Int ":=" ByteArray "]" [function, functional]
744744
// --------------------------------------------------------------------
745745
rule [mapWriteBytes.base]: WM[ N := .WordStack ] => WM
@@ -788,6 +788,7 @@ These parsers can interperet hex-encoded strings as `Int`s, `ByteArray`s, and `M
788788

789789
- `#parseHexWord` interprets a string as a single hex-encoded `Word`.
790790
- `#parseHexBytes` interprets a string as a hex-encoded stack of bytes.
791+
- `#alignHexString` makes sure that the length of a (hex)string is even.
791792
- `#parseByteStack` interprets a string as a hex-encoded stack of bytes, but makes sure to remove the leading "0x".
792793
- `#parseByteStackRaw` casts a string as a stack of bytes, ignoring any encoding.
793794
- `#parseWordStack` interprets a JSON list as a stack of `Word`.
@@ -805,36 +806,41 @@ These parsers can interperet hex-encoded strings as `Int`s, `ByteArray`s, and `M
805806
rule #parseWord("") => 0
806807
rule #parseWord(S) => #parseHexWord(S) requires lengthString(S) >=Int 2 andBool substrString(S, 0, 2) ==String "0x"
807808
rule #parseWord(S) => String2Int(S) [owise]
809+
810+
syntax String ::= #alignHexString ( String ) [function, functional]
811+
// -------------------------------------------------------------------
812+
rule #alignHexString(S) => S requires lengthString(S) modInt 2 ==Int 0
813+
rule #alignHexString(S) => "0" +String S requires notBool lengthString(S) modInt 2 ==Int 0
808814
```
809815

810-
```{.k .concrete}
816+
```{.k .bytes}
811817
syntax ByteArray ::= #parseHexBytes ( String ) [function]
812-
| #parseByteStack ( String ) [function]
818+
| #parseHexBytesAux ( String ) [function]
819+
| #parseByteStack ( String ) [function, memo]
813820
| #parseByteStackRaw ( String ) [function]
814-
// -------------------------------------------------------------
821+
// -------------------------------------------------------------------
815822
rule #parseByteStack(S) => #parseHexBytes(replaceAll(S, "0x", ""))
816-
rule #parseHexBytes("") => .ByteArray
817-
rule #parseHexBytes(S) => #parseHexBytes("0" +String S)
818-
requires notBool lengthString(S) modInt 2 ==Int 0
819-
rule #parseHexBytes(S) => Int2Bytes(1, #parseHexWord(substrString(S, 0, 2)), BE) +Bytes #parseHexBytes(substrString(S, 2, lengthString(S)))
820-
requires lengthString(S) modInt 2 ==Int 0
821-
andBool lengthString(S) >Int 0
823+
824+
rule #parseHexBytes(S) => #parseHexBytesAux(#alignHexString(S))
825+
rule #parseHexBytesAux("") => .ByteArray
826+
rule #parseHexBytesAux(S) => Int2Bytes(1, String2Base(substrString(S, 0, 2), 16), BE) +Bytes #parseHexBytesAux(substrString(S, 2, lengthString(S)))
827+
requires lengthString(S) >=Int 2
822828
823829
rule #parseByteStackRaw(S) => String2Bytes(S)
824830
```
825831

826-
```{.k .symbolic}
832+
```{.k .nobytes}
827833
syntax ByteArray ::= #parseHexBytes ( String ) [function]
834+
| #parseHexBytesAux ( String ) [function]
828835
| #parseByteStack ( String ) [function]
829836
| #parseByteStackRaw ( String ) [function]
830837
// -------------------------------------------------------------
831838
rule #parseByteStack(S) => #parseHexBytes(replaceAll(S, "0x", ""))
832-
rule #parseHexBytes("") => .WordStack
833-
rule #parseHexBytes(S) => #parseHexBytes("0" +String S)
834-
requires notBool lengthString(S) modInt 2 ==Int 0
835-
rule #parseHexBytes(S) => #parseHexWord(substrString(S, 0, 2)) : #parseHexBytes(substrString(S, 2, lengthString(S)))
836-
requires lengthString(S) modInt 2 ==Int 0
837-
andBool lengthString(S) >Int 0
839+
840+
rule #parseHexBytes(S) => #parseHexBytesAux(#alignHexString(S))
841+
rule #parseHexBytesAux("") => .WordStack
842+
rule #parseHexBytesAux(S) => #parseHexWord(substrString(S, 0, 2)) : #parseHexBytesAux(substrString(S, 2, lengthString(S)))
843+
requires lengthString(S) >=Int 2
838844
839845
rule #parseByteStackRaw(S) => ordChar(substrString(S, 0, 1)) : #parseByteStackRaw(substrString(S, 1, lengthString(S))) requires lengthString(S) >=Int 1
840846
rule #parseByteStackRaw("") => .WordStack
@@ -860,13 +866,13 @@ We need to interperet a `ByteArray` as a `String` again so that we can call `Kec
860866
- `#unparseByteStack` turns a stack of bytes (as a `ByteArray`) into a `String`.
861867
- `#padByte` ensures that the `String` interperetation of a `Int` is wide enough.
862868

863-
```{.k .concrete}
869+
```{.k .bytes}
864870
syntax String ::= #unparseByteStack ( ByteArray ) [function, klabel(unparseByteStack), symbol]
865871
// ----------------------------------------------------------------------------------------------
866872
rule #unparseByteStack(WS) => Bytes2String(WS)
867873
```
868874

869-
```{.k .symbolic}
875+
```{.k .nobytes}
870876
syntax String ::= #unparseByteStack ( ByteArray ) [function, klabel(unparseByteStack), symbol]
871877
| #unparseByteStack ( ByteArray , StringBuffer ) [function, klabel(#unparseByteStackAux)]
872878
// ---------------------------------------------------------------------------------------------------------

evm.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,16 +1374,16 @@ The various `CALL*` (and other inter-contract control flow) operations will be d
13741374
rule #computeValidJumpDests(PGM) => #computeValidJumpDests(PGM, 0, .List)
13751375
```
13761376

1377-
```{.k .symbolic}
1377+
```{.k .nobytes}
13781378
rule #computeValidJumpDests(.WordStack, _, RESULT) => List2Set(RESULT)
13791379
rule #computeValidJumpDests(91 : WS, I, RESULT) => #computeValidJumpDests(WS, I +Int 1, ListItem(I) RESULT)
13801380
rule #computeValidJumpDests(W : WS, I, RESULT) => #computeValidJumpDests(#drop(#widthOpCode(W), W : WS), I +Int #widthOpCode(W), RESULT) requires W =/=Int 91
13811381
```
13821382

1383-
```{.k .concrete}
1383+
```{.k .bytes}
13841384
rule #computeValidJumpDests(PGM, I, RESULT) => List2Set(RESULT) requires I >=Int #sizeByteArray(PGM)
13851385
rule #computeValidJumpDests(PGM, I, RESULT) => #computeValidJumpDests(PGM, I +Int 1, ListItem(I) RESULT) requires I <Int #sizeByteArray(PGM) andBool PGM [ I ] ==Int 91
1386-
rule #computeValidJumpDests(PGM, I, RESULT) => #computeValidJumpDests(PGM, I +Int #widthOpCode(PGM [ I ]), RESULT) [owise]
1386+
rule #computeValidJumpDests(PGM, I, RESULT) => #computeValidJumpDests(PGM, I +Int #widthOpCode(PGM [ I ]), RESULT) requires I <Int #sizeByteArray(PGM) andBool notBool PGM [ I ] ==Int 91
13871387
```
13881388

13891389
```k
@@ -2180,7 +2180,7 @@ There are several helpers for calculating gas (most of them also specified in th
21802180
rule #allBut64th(N) => N -Int (N /Int 64)
21812181
```
21822182

2183-
```{.k .symbolic}
2183+
```{.k .nobytes}
21842184
syntax Int ::= G0 ( Schedule , ByteArray , Bool ) [function]
21852185
// ------------------------------------------------------------
21862186
rule G0(SCHED, .WordStack, true) => Gtxcreate < SCHED >
@@ -2190,7 +2190,7 @@ There are several helpers for calculating gas (most of them also specified in th
21902190
rule G0(SCHED, N : REST, ISCREATE) => Gtxdatanonzero < SCHED > +Int G0(SCHED, REST, ISCREATE) requires N =/=Int 0
21912191
```
21922192

2193-
```{.k .concrete}
2193+
```{.k .bytes}
21942194
syntax Int ::= G0 ( Schedule , ByteArray , Bool ) [function]
21952195
| G0 ( Schedule , ByteArray , Int , Int ) [function, klabel(G0data)]
21962196
| G0 ( Schedule , Bool ) [function, klabel(G0base)]

tests/interactive/search/branching-invalid.evm.search-expected

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
_0
3333
#Equals
3434
<output>
35-
.WordStack
35+
b""
3636
</output>
3737
}
3838
#And
@@ -65,7 +65,7 @@
6565
#Equals
6666
<callState>
6767
<program>
68-
96 : 3 : 96 : 4 : 1 : 96 : 8 : 20 : 96 : 12 : 87 : 254 : 91 : 0 : .WordStack
68+
b"6003600401600814600c57fe5b00"
6969
</program>
7070
<jumpDests>
7171
SetItem ( 12 )
@@ -77,7 +77,7 @@
7777
.Account
7878
</caller>
7979
<callData>
80-
.WordStack
80+
b""
8181
</callData>
8282
<callValue>
8383
0
@@ -172,7 +172,7 @@
172172
0
173173
</receiptsRoot>
174174
<logsBloom>
175-
.WordStack
175+
b""
176176
</logsBloom>
177177
<difficulty>
178178
0
@@ -190,7 +190,7 @@
190190
0
191191
</timestamp>
192192
<extraData>
193-
.WordStack
193+
b""
194194
</extraData>
195195
<mixHash>
196196
0

tests/interactive/search/straight-line.evm.search-expected

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
_0
3333
#Equals
3434
<output>
35-
.WordStack
35+
b""
3636
</output>
3737
}
3838
#And
@@ -65,7 +65,7 @@
6565
#Equals
6666
<callState>
6767
<program>
68-
127 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 3 : 127 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 0 : 4 : 1 : 254 : .WordStack
68+
b"7f00000000000000000000000000000000000000000000000000000000000000037f000000000000000000000000000000000000000000000000000000000000000401fe"
6969
</program>
7070
<jumpDests>
7171
.Set
@@ -77,7 +77,7 @@
7777
.Account
7878
</caller>
7979
<callData>
80-
.WordStack
80+
b""
8181
</callData>
8282
<callValue>
8383
0
@@ -172,7 +172,7 @@
172172
0
173173
</receiptsRoot>
174174
<logsBloom>
175-
.WordStack
175+
b""
176176
</logsBloom>
177177
<difficulty>
178178
0
@@ -190,7 +190,7 @@
190190
0
191191
</timestamp>
192192
<extraData>
193-
.WordStack
193+
b""
194194
</extraData>
195195
<mixHash>
196196
0

tests/specs/examples/sum-to-n-spec.k

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
requires "asm.k"
2-
requires "edsl.k"
32

43
module VERIFICATION
5-
imports EDSL
64
imports EVM-ASSEMBLY
75

86
rule #sizeWordStack ( WS , N:Int )

tests/specs/functional/merkle-spec.k

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,31 @@ endmodule
1414
module MERKLE-SPEC
1515
imports VERIFICATION
1616

17-
rule <k> runMerkle ( MerkleUpdate( .MerkleTree, .WordStack, VALUE ) )
18-
=> doneMerkle( MerkleLeaf( .WordStack, VALUE ) ) </k>
17+
rule <k> runMerkle ( MerkleUpdate( .MerkleTree, .ByteArray, VALUE ) )
18+
=> doneMerkle( MerkleLeaf( .ByteArray, VALUE ) ) </k>
1919

2020
// Update on MerkleLeaf
21-
rule <k> runMerkle ( MerkleUpdate( MerkleLeaf( 6 : 7 : .WordStack, _ ), 6 : 7 : .WordStack, V ) )
22-
=> doneMerkle( MerkleLeaf ( 6 : 7 : .WordStack, V ) ) </k>
21+
rule <k> runMerkle ( MerkleUpdate( MerkleLeaf( #parseByteStack("0x0607"), _ ), #parseByteStack("0x0607"), V ) )
22+
=> doneMerkle( MerkleLeaf ( #parseByteStack("0x0607"), V ) ) </k>
2323

24-
rule <k> runMerkle ( MerkleUpdate( MerkleLeaf( 6 : 7 : .WordStack, _ ), 6 : 8 : .WordStack, _ ) )
25-
=> doneMerkle( MerkleExtension( 6 : .WordStack, _ ) ) </k>
24+
rule <k> runMerkle ( MerkleUpdate( MerkleLeaf( #parseByteStack("0x0607"), _ ), #parseByteStack("0x0608"), _ ) )
25+
=> doneMerkle( MerkleExtension( #parseByteStack("0x06"), _ ) ) </k>
2626

27-
rule <k> runMerkle ( MerkleUpdate( MerkleLeaf( 5 : .WordStack, _ ), 6 : .WordStack, _ ) )
27+
rule <k> runMerkle ( MerkleUpdate( MerkleLeaf( #parseByteStack("0x05"), _ ), #parseByteStack("0x06"), _ ) )
2828
=> doneMerkle( MerkleBranch( _, _ ) ) </k>
2929

3030
// Update on MerkleExtension
31-
rule <k> runMerkle ( MerkleUpdate( MerkleExtension( 6 : .WordStack, .MerkleTree ), 6 : .WordStack, V ) )
32-
=> doneMerkle( MerkleExtension( 6 : .WordStack, MerkleLeaf( .WordStack, V ) ) ) </k>
31+
rule <k> runMerkle ( MerkleUpdate( MerkleExtension( #parseByteStack("0x06"), .MerkleTree ), #parseByteStack("0x06"), V ) )
32+
=> doneMerkle( MerkleExtension( #parseByteStack("0x06"), MerkleLeaf( .ByteArray, V ) ) ) </k>
3333

34-
rule <k> runMerkle ( MerkleUpdate( MerkleExtension( 7 : .WordStack, _ ), 6 : .WordStack, _ ) )
34+
rule <k> runMerkle ( MerkleUpdate( MerkleExtension( #parseByteStack("0x07"), _ ), #parseByteStack("0x06"), _ ) )
3535
=> doneMerkle( MerkleBranch( _, _ ) ) </k>
3636

37-
rule <k> runMerkle ( MerkleUpdate( MerkleExtension( 7 : 8 : .WordStack, _ ), 7 : 9 : .WordStack, _ ) )
38-
=> doneMerkle( MerkleExtension( 7 : .WordStack, MerkleBranch( _, _ ) ) ) </k>
37+
rule <k> runMerkle ( MerkleUpdate( MerkleExtension( #parseByteStack("0x0708"), _ ), #parseByteStack("0x0709"), _ ) )
38+
=> doneMerkle( MerkleExtension( #parseByteStack("0x07"), MerkleBranch( _, _ ) ) ) </k>
3939

4040
// Update on MerkleBranch
41-
rule <k> runMerkle ( MerkleUpdate( MerkleBranch( M, _ ), .WordStack, V ) )
41+
rule <k> runMerkle ( MerkleUpdate( MerkleBranch( M, _ ), .ByteArray, V ) )
4242
=> doneMerkle( MerkleBranch( M, V ) ) </k>
4343

4444
rule <k> runMerkle ( .MerkleBranch )

0 commit comments

Comments
 (0)