@ -44,7 +44,7 @@ class CodeV1Test {
@Test
void validCode ( ) {
String codeHex =
"0xEF0001 01000C 020003 000b 0002 0008 030000 00 00000000 02010001 01000002 60016002b00001b00002b1 01b1 60005360106000f3" ;
"0xEF0001 01000C 020003 000b 0002 0008 030000 00 00000000 02010001 01000002 60016002e30001e30002e4 01e4 60005360106000f3" ;
final EOFLayout layout = EOFLayout . parseEOF ( Bytes . fromHexString ( codeHex . replace ( " " , "" ) ) ) ;
String validationError = validateCode ( layout ) ;
@ -54,7 +54,7 @@ class CodeV1Test {
@ParameterizedTest
@ValueSource (
strings = { "3000" , "5000" , "5c000000" , "60005d 000000" , "60005 e01000000" , "fe00" , "0000" } )
strings = { "3000" , "5000" , "e0000000" , "6000e1 000000" , "6000e2 01000000" , "fe00" , "0000" } )
void testValidOpcodes ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
assertThat ( validationError ) . isNull ( ) ;
@ -90,15 +90,15 @@ class CodeV1Test {
private static Stream < Arguments > testRjumpValidImmediateArguments ( ) {
return Stream . of (
"5c 000000" ,
"5c 00010000" ,
"5c 00010000000000" ,
"5c 0100" + NOOP_HEX . repeat ( 256 ) + ZERO_HEX ,
"5c 7fff" + NOOP_HEX . repeat ( 32767 ) + ZERO_HEX ,
"5c fffd0000" ,
"005c fffc00" ,
NOOP_HEX . repeat ( 253 ) + "5c ff0000" ,
NOOP_HEX . repeat ( 32765 ) + "5c 800000" )
"e0 000000" ,
"e0 00010000" ,
"e0 00010000000000" ,
"e0 0100" + NOOP_HEX . repeat ( 256 ) + ZERO_HEX ,
"e0 7fff" + NOOP_HEX . repeat ( 32767 ) + ZERO_HEX ,
"e0 fffd0000" ,
"00e0 fffc00" ,
NOOP_HEX . repeat ( 253 ) + "e0 ff0000" ,
NOOP_HEX . repeat ( 32765 ) + "e0 800000" )
. map ( Arguments : : arguments ) ;
}
@ -111,16 +111,16 @@ class CodeV1Test {
private static Stream < Arguments > testRjumpiValidImmediateArguments ( ) {
return Stream . of (
"60015d 000000" ,
"60015d 00010000" ,
"60015d 00010000000000" ,
"60015d 0100" + "5b" . repeat ( 256 ) + ZERO_HEX ,
"60015d 7fff" + "5b" . repeat ( 32767 ) + ZERO_HEX ,
"60015d fffd0000" ,
"60015d fffb00" ,
NOOP_HEX . repeat ( 252 ) + "60015d ff0000" ,
NOOP_HEX . repeat ( 32763 ) + "60015d 800000" ,
"5d 000000" )
"6001e1 000000" ,
"6001e1 00010000" ,
"6001e1 00010000000000" ,
"6001e1 0100" + "5b" . repeat ( 256 ) + ZERO_HEX ,
"6001e1 7fff" + "5b" . repeat ( 32767 ) + ZERO_HEX ,
"6001e1 fffd0000" ,
"6001e1 fffb00" ,
NOOP_HEX . repeat ( 252 ) + "6001e1 ff0000" ,
NOOP_HEX . repeat ( 32763 ) + "6001e1 800000" ,
"e1 000000" )
. map ( Arguments : : arguments ) ;
}
@ -133,14 +133,14 @@ class CodeV1Test {
private static Stream < Arguments > rjumptableValidImmediateArguments ( ) {
return Stream . of (
"60015 e01000000" ,
"60015 e02000000010000" ,
"60015 e03000000040100" + "5b" . repeat ( 256 ) + ZERO_HEX ,
"60015 e040000000401007fff" + "5b" . repeat ( 32767 ) + ZERO_HEX ,
"60015 e01fffc0000" ,
"5b" . repeat ( 248 ) + "60015 e02fffaff0000" ,
"5b" . repeat ( 32760 ) + "60015 e02fffa800000" ,
"5 e01000000" )
"6001e2 01000000" ,
"6001e2 02000000010000" ,
"6001e2 03000000040100" + "5b" . repeat ( 256 ) + ZERO_HEX ,
"6001e2 040000000401007fff" + "5b" . repeat ( 32767 ) + ZERO_HEX ,
"6001e2 01fffc0000" ,
"5b" . repeat ( 248 ) + "6001e2 02fffaff0000" ,
"5b" . repeat ( 32760 ) + "6001e2 02fffa800000" ,
"e2 01000000" )
. map ( Arguments : : arguments ) ;
}
@ -157,12 +157,11 @@ class CodeV1Test {
IntStream . of ( 0x1e , 0x1f ) ,
IntStream . rangeClosed ( 0x21 , 0x2f ) ,
IntStream . rangeClosed ( 0x49 , 0x4f ) ,
// IntStream.of(0x5f), // PUSH0
IntStream . rangeClosed ( 0xa5 , 0xaf ) ,
IntStream . rangeClosed ( 0xb3 , 0xbf ) ,
IntStream . rangeClosed ( 0xb0 , 0xbf ) ,
IntStream . rangeClosed ( 0xc0 , 0xcf ) ,
IntStream . rangeClosed ( 0xd0 , 0xdf ) ,
IntStream . rangeClosed ( 0xe0 , 0xef ) ,
IntStream . rangeClosed ( 0xe5 , 0xef ) ,
IntStream . of ( 0xf6 , 0xf7 , 0xf8 , 0xf9 , 0xfb , 0xfc ) )
. flatMapToInt ( i - > i )
. mapToObj ( i - > String . format ( "%02x" , i ) + ZERO_HEX )
@ -185,14 +184,14 @@ class CodeV1Test {
}
@ParameterizedTest
@ValueSource ( strings = { "5c" , "5c 00" } )
@ValueSource ( strings = { "e0" , "e0 00" } )
void testRjumpTruncatedImmediate ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
assertThat ( validationError ) . isEqualTo ( "Truncated relative jump offset" ) ;
}
@ParameterizedTest
@ValueSource ( strings = { "60015d" , "60015d 00" } )
@ValueSource ( strings = { "6001e1" , "6001e1 00" } )
void testRjumpiTruncatedImmediate ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
assertThat ( validationError ) . isEqualTo ( "Truncated relative jump offset" ) ;
@ -201,12 +200,12 @@ class CodeV1Test {
@ParameterizedTest
@ValueSource (
strings = {
"60015 e" ,
"60015 e01" ,
"60015 e0100" ,
"60015 e030000" ,
"60015 e0300000001" ,
"60015 e030000000100"
"6001e2 " ,
"6001e2 01" ,
"6001e2 0100" ,
"6001e2 030000" ,
"6001e2 0300000001" ,
"6001e2 030000000100"
} )
void testRjumpvTruncatedImmediate ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
@ -216,14 +215,14 @@ class CodeV1Test {
@ParameterizedTest
@ValueSource (
strings = {
"5c 0000" ,
"5c 000100" ,
"5c fffc00" ,
"60015d 0000" ,
"60015d 000100" ,
"60015d fffa00" ,
"60015 e01000100" ,
"60015 e01fff900"
"e0 0000" ,
"e0 000100" ,
"e0 fffc00" ,
"6001e1 0000" ,
"6001e1 000100" ,
"6001e1 fffa00" ,
"6001e2 01000100" ,
"6001e2 01fff900"
} )
void testRjumpsOutOfBounds ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
@ -235,47 +234,47 @@ class CodeV1Test {
@ValueSource (
strings = {
// RJUMP into RJUMP immediate
"5c ffff00" ,
"5c fffe00" ,
"5c00015c 000000" ,
"5c00025c 000000" ,
"e0 ffff00" ,
"e0 fffe00" ,
"e00001e0 000000" ,
"e00002e0 000000" ,
// RJUMPI into RJUMP immediate
"60015d00015c 000000" ,
"60015d00025c 000000" ,
"6001e10001e0 000000" ,
"6001e10002e0 000000" ,
// RJUMPV into RJUMP immediate
"60015e0100015c 000000" ,
"60015e0100025c 000000" ,
"6001e2010001e0 000000" ,
"6001e2010002e0 000000" ,
// RJUMP into RJUMPI immediate
"5c000360015d 000000" ,
"5c000460015d 000000" ,
"e000036001e1 000000" ,
"e000046001e1 000000" ,
// RJUMPI into RJUMPI immediate
"60015d ffff00" ,
"60015d fffe00" ,
"60015d000360015d 000000" ,
"60015d000460015d 000000" ,
"6001e1 ffff00" ,
"6001e1 fffe00" ,
"6001e100036001e1 000000" ,
"6001e100046001e1 000000" ,
// RJUMPV into RJUMPI immediate
"60015e01000360015d 000000" ,
"60015e01000460015d 000000" ,
"6001e20100036001e1 000000" ,
"6001e20100046001e1 000000" ,
// RJUMP into RJUMPV immediate
"5c00015e 01000000" ,
"5c00025e 01000000" ,
"5c00035e 01000000" ,
"e00001e2 01000000" ,
"e00002e2 01000000" ,
"e00003e2 01000000" ,
// RJUMPI into RJUMPV immediate
"60015d00015e 01000000" ,
"60015d00025e 01000000" ,
"60015d00035e 01000000" ,
"6001e10001e2 01000000" ,
"6001e10002e2 01000000" ,
"6001e10003e2 01000000" ,
// RJUMPV into RJUMPV immediate
"60015 e01ffff00" ,
"60015 e01fffe00" ,
"60015 e01fffd00" ,
"60015 e0100015 e01000000" ,
"60015 e0100025 e01000000" ,
"60015 e0100035 e01000000" ,
"60015 e0100015 e020000fff400" ,
"60015 e0100025 e020000fff400" ,
"60015 e0100035 e020000fff400" ,
"60015 e0100045 e020000fff400" ,
"60015 e0100055 e020000fff400"
"6001e2 01ffff00" ,
"6001e2 01fffe00" ,
"6001e2 01fffd00" ,
"6001e2 010001e2 01000000" ,
"6001e2 010002e2 01000000" ,
"6001e2 010003e2 01000000" ,
"6001e2 010001e2 020000fff400" ,
"6001e2 010002e2 020000fff400" ,
"6001e2 010003e2 020000fff400" ,
"6001e2 010004e2 020000fff400" ,
"6001e2 010005e2 020000fff400"
} )
void testRjumpsIntoImmediate ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
@ -291,21 +290,21 @@ class CodeV1Test {
. mapToObj (
offset - >
Stream . of (
String . format ( "5c 00%02x" , offset )
String . format ( "e0 00%02x" , offset )
+ // RJUMP offset
String . format ( "%02x" , 0x60 + n - 1 )
+ // PUSHn
ZERO_HEX . repeat ( n )
+ // push data
ZERO_HEX , // STOP
String . format ( "60015d 00%02x" , offset )
String . format ( "6001e1 00%02x" , offset )
+ // PUSH1 1 RJUMI offset
String . format ( "%02x" , 0x60 + n - 1 )
+ // PUSHn
ZERO_HEX . repeat ( n )
+ // push data
ZERO_HEX , // STOP
String . format ( "60015 e0100%02x" , offset )
String . format ( "6001e2 0100%02x" , offset )
+ String . format ( "%02x" , 0x60 + n - 1 )
+ // PUSHn
ZERO_HEX . repeat ( n )
@ -318,21 +317,21 @@ class CodeV1Test {
}
@ParameterizedTest
@ValueSource ( strings = { "60015 e0000" } )
@ValueSource ( strings = { "6001e2 0000" } )
void testRjumpvEmptyTable ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
assertThat ( validationError ) . isEqualTo ( "Empty jump table" ) ;
}
@ParameterizedTest
@ValueSource ( strings = { "b0" , "b0 00" } )
@ValueSource ( strings = { "e3" , "e3 00" } )
void testCallFTruncated ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
assertThat ( validationError ) . isEqualTo ( "Truncated CALLF" ) ;
}
@ParameterizedTest
@ValueSource ( strings = { "b2" , "b2 00" } )
@ValueSource ( strings = { "e5" , "e5 00" } )
@Disabled ( "Out of Shahghai, will likely return in Cancun or Prague" )
void testJumpCallFTruncated ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 1 ) ;
@ -340,14 +339,14 @@ class CodeV1Test {
}
@ParameterizedTest
@ValueSource ( strings = { "b00004" , "b003ff" , "b0 ffff" } )
@ValueSource ( strings = { "e30004" , "e303ff" , "e3 ffff" } )
void testCallFWrongSection ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 3 ) ;
assertThat ( validationError ) . startsWith ( "CALLF to non-existent section -" ) ;
}
@ParameterizedTest
@ValueSource ( strings = { "b20004" , "b203ff" , "b2 ffff" } )
@ValueSource ( strings = { "e50004" , "e503ff" , "e5 ffff" } )
@Disabled ( "Out of Shahghai, will likely return in Cancun or Prague" )
void testJumpFWrongSection ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 3 ) ;
@ -355,14 +354,14 @@ class CodeV1Test {
}
@ParameterizedTest
@ValueSource ( strings = { "b0000100" , "b0000200" , "b0 000000" } )
@ValueSource ( strings = { "e3000100" , "e3000200" , "e3 000000" } )
void testCallFValid ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 3 ) ;
assertThat ( validationError ) . isNull ( ) ;
}
@ParameterizedTest
@ValueSource ( strings = { "b20001" , "b20002" , "b2 0000" } )
@ValueSource ( strings = { "e50001" , "e50002" , "e5 0000" } )
@Disabled ( "Out of Shahghai, will likely return in Cancun or Prague" )
void testJumpFValid ( final String code ) {
final String validationError = validateCode ( Bytes . fromHexString ( code ) , 3 ) ;
@ -378,26 +377,26 @@ class CodeV1Test {
private static Stream < Arguments > immediateContainsOpcodeArguments ( ) {
return Stream . of (
// 0x5c byte which could be interpreted a RJUMP, but it's not because it's in PUSH data
"605c 001000" ,
"61005c 001000" ,
// 0x5d byte which could be interpreted a RJUMPI, but it's not because it's in PUSH data
"605d 001000" ,
"61005d 001000" ,
// 0x5 e byte which could be interpreted a RJUMPV, but it's not because it's in PUSH data
"605 e01000000" ,
"61005 e01000000" ,
// 0xe0 byte which could be interpreted a RJUMP, but it's not because it's in PUSH data
"60e0 001000" ,
"6100e0 001000" ,
// 0xe1 byte which could be interpreted a RJUMPI, but it's not because it's in PUSH data
"60e1 001000" ,
"6100e1 001000" ,
// 0xe2 byte which could be interpreted a RJUMPV, but it's not because it's in PUSH data
"60e2 01000000" ,
"6100e2 01000000" ,
// 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMP data
// offset = -160
"5b" . repeat ( 160 ) + "5c ff6000" ,
"5b" . repeat ( 160 ) + "e0 ff6000" ,
// 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMPI
// data
// offset = -160
"5b" . repeat ( 160 ) + "5d ff6000" ,
"5b" . repeat ( 160 ) + "e1 ff6000" ,
// 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMPV
// data
// offset = -160
"5b" . repeat ( 160 ) + "5 e01ff6000" )
"5b" . repeat ( 160 ) + "e2 01ff6000" )
. map ( Arguments : : arguments ) ;
}
@ -497,48 +496,48 @@ class CodeV1Test {
static Stream < Arguments > stackRJumpForward ( ) {
return Stream . of (
Arguments . of ( "RJUMP 0" , null , 0 , List . of ( List . of ( "5C 0000 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of ( "RJUMP 0" , null , 0 , List . of ( List . of ( "e0 0000 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"RJUMP 1 w/ dead code" ,
"Dead code detected in section 0" ,
0 ,
List . of ( List . of ( "5C 0001 43 00" , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "e0 0001 43 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"RJUMP 2 w/ dead code" ,
"Dead code detected in section 0" ,
0 ,
List . of ( List . of ( "5C 0002 43 50 00" , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "e0 0002 43 50 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"RJUMP 3 and -10" ,
null ,
0 ,
List . of ( List . of ( "5C0003 01 50 00 6001 6001 5C fff6" , 0 , 0 , 2 ) ) ) ) ;
List . of ( List . of ( "e00003 01 50 00 6001 6001 e0 fff6" , 0 , 0 , 2 ) ) ) ) ;
}
static Stream < Arguments > stackRJumpBackward ( ) {
return Stream . of (
Arguments . of ( "RJUMP -3" , null , 0 , List . of ( List . of ( "5C fffd" , 0 , 0 , 0 ) ) ) ,
Arguments . of ( "RJUMP -4" , null , 0 , List . of ( List . of ( "5B 5C fffc" , 0 , 0 , 0 ) ) ) ,
Arguments . of ( "RJUMP -3" , null , 0 , List . of ( List . of ( "e0 fffd" , 0 , 0 , 0 ) ) ) ,
Arguments . of ( "RJUMP -4" , null , 0 , List . of ( List . of ( "5B e0 fffc" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"RJUMP -4 unmatched stack" ,
"Jump into code stack height (0) does not match previous value (1)" ,
0 ,
List . of ( List . of ( "43 5C fffc" , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "43 e0 fffc" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"RJUMP -4 unmatched stack" ,
"Jump into code stack height (1) does not match previous value (0)" ,
0 ,
List . of ( List . of ( "43 50 5C fffc 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of ( "RJUMP -3 matched stack" , null , 0 , List . of ( List . of ( "43 50 5C fffd" , 0 , 0 , 1 ) ) ) ,
List . of ( List . of ( "43 50 e0 fffc 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of ( "RJUMP -3 matched stack" , null , 0 , List . of ( List . of ( "43 50 e0 fffd" , 0 , 0 , 1 ) ) ) ,
Arguments . of (
"RJUMP -4 matched stack" , null , 0 , List . of ( List . of ( "43 50 5B 5C fffc" , 0 , 0 , 1 ) ) ) ,
"RJUMP -4 matched stack" , null , 0 , List . of ( List . of ( "43 50 5B e0 fffc" , 0 , 0 , 1 ) ) ) ,
Arguments . of (
"RJUMP -5 matched stack" , null , 0 , List . of ( List . of ( "43 50 43 5C fffb" , 0 , 0 , 1 ) ) ) ,
"RJUMP -5 matched stack" , null , 0 , List . of ( List . of ( "43 50 43 e0 fffb" , 0 , 0 , 1 ) ) ) ,
Arguments . of (
"RJUMP -4 unmatched stack" ,
"Jump into code stack height (0) does not match previous value (1)" ,
0 ,
List . of ( List . of ( "43 50 43 5C fffc 50 00" , 0 , 0 , 0 ) ) ) ) ;
List . of ( List . of ( "43 50 43 e0 fffc 50 00" , 0 , 0 , 0 ) ) ) ) ;
}
static Stream < Arguments > stackRJumpI ( ) {
@ -547,61 +546,61 @@ class CodeV1Test {
"RJUMPI Each branch ending with STOP" ,
null ,
0 ,
List . of ( List . of ( "60ff 6001 5D 0002 50 00 50 00" , 0 , 0 , 2 ) ) ) ,
List . of ( List . of ( "60ff 6001 e1 0002 50 00 50 00" , 0 , 0 , 2 ) ) ) ,
Arguments . of (
"RJUMPI One branch ending with RJUMP" ,
null ,
0 ,
List . of ( List . of ( "60ff 6001 5D0004 50 5C 0001 50 00" , 0 , 0 , 2 ) ) ) ,
List . of ( List . of ( "60ff 6001 e10004 50 e0 0001 50 00" , 0 , 0 , 2 ) ) ) ,
Arguments . of (
"RJUMPI Fallthrough" ,
null ,
0 ,
List . of ( List . of ( "60ff 6001 5D 0004 80 80 50 50 50 00" , 0 , 0 , 3 ) ) ) ,
List . of ( List . of ( "60ff 6001 e1 0004 80 80 50 50 50 00" , 0 , 0 , 3 ) ) ) ,
Arguments . of (
"RJUMPI Offset 0" , null , 0 , List . of ( List . of ( "60ff 6001 5D 0000 50 00" , 0 , 0 , 2 ) ) ) ,
"RJUMPI Offset 0" , null , 0 , List . of ( List . of ( "60ff 6001 e1 0000 50 00" , 0 , 0 , 2 ) ) ) ,
Arguments . of (
"Simple loop (RJUMPI offset = -5)" ,
null ,
0 ,
List . of ( List . of ( "6001 60ff 81 02 80 5D fffa 50 50 00" , 0 , 0 , 3 ) ) ) ,
List . of ( List . of ( "6001 60ff 81 02 80 e1 fffa 50 50 00" , 0 , 0 , 3 ) ) ) ,
Arguments . of (
"RJUMPI One branch increasing max stack more stack than another" ,
null ,
0 ,
List . of ( List . of ( "6001 5D 0007 30 30 30 50 50 50 00 30 50 00" , 0 , 0 , 3 ) ) ) ,
List . of ( List . of ( "6001 e1 0007 30 30 30 50 50 50 00 30 50 00" , 0 , 0 , 3 ) ) ) ,
Arguments . of (
"RJUMPI One branch increasing max stack more stack than another II" ,
null ,
0 ,
List . of ( List . of ( "6001 5D 0003 30 50 00 30 30 30 50 50 50 00" , 0 , 0 , 3 ) ) ) ,
List . of ( List . of ( "6001 e1 0003 30 50 00 30 30 30 50 50 50 00" , 0 , 0 , 3 ) ) ) ,
Arguments . of (
"RJUMPI Missing stack argument" ,
"Operation 0x5D requires stack of 1 but only has 0 items" ,
"Operation 0xE1 requires stack of 1 but only has 0 items" ,
0 ,
List . of ( List . of ( "5D 0000 00" , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "e1 0000 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"Stack underflow one branch" ,
"Operation 0x02 requires stack of 2 but only has 1 items" ,
0 ,
List . of ( List . of ( "60ff 6001 5D 0002 50 00 02 50 00" , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "60ff 6001 e1 0002 50 00 02 50 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"Stack underflow another branch" ,
"Operation 0x02 requires stack of 2 but only has 1 items" ,
0 ,
List . of ( List . of ( "60ff 6001 5D 0002 02 00 19 50 00" , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "60ff 6001 e1 0002 02 00 19 50 00" , 0 , 0 , 0 ) ) ) ,
// this depends on requiring stacks to be "clean" returns
Arguments . of (
"RJUMPI Stack not empty in the end of one branch" ,
null ,
0 ,
List . of ( List . of ( "60ff 6001 5D 0002 50 00 19 00" , 0 , 0 , 2 ) ) ) ,
List . of ( List . of ( "60ff 6001 e1 0002 50 00 19 00" , 0 , 0 , 2 ) ) ) ,
// this depends on requiring stacks to be "clean" returns
Arguments . of (
"RJUMPI Stack not empty in the end of one branch II" ,
null ,
0 ,
List . of ( List . of ( "60ff 6001 5D 0002 19 00 50 00" , 0 , 0 , 2 ) ) ) ) ;
List . of ( List . of ( "60ff 6001 e1 0002 19 00 50 00" , 0 , 0 , 2 ) ) ) ) ;
}
static Stream < Arguments > stackCallF ( ) {
@ -610,99 +609,99 @@ class CodeV1Test {
"0 input 0 output" ,
null ,
0 ,
List . of ( List . of ( "B0 0001 00" , 0 , 0 , 0 ) , List . of ( "b1 " , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "e3 0001 00" , 0 , 0 , 0 ) , List . of ( "e4 " , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"0 inputs, 0 output 3 sections" ,
null ,
0 ,
List . of ( List . of ( "B0 0002 00" , 0 , 0 , 0 ) , List . of ( "b1 " , 1 , 1 , 1 ) , List . of ( "b1 " , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "e3 0002 00" , 0 , 0 , 0 ) , List . of ( "e4 " , 1 , 1 , 1 ) , List . of ( "e4 " , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"more than 0 inputs" ,
null ,
0 ,
List . of ( List . of ( "30 B0 0001 00" , 0 , 0 , 1 ) , List . of ( "00" , 1 , 0 , 1 ) ) ) ,
List . of ( List . of ( "30 e3 0001 00" , 0 , 0 , 1 ) , List . of ( "00" , 1 , 0 , 1 ) ) ) ,
Arguments . of (
"forwarding an argument" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "B0 0002 00" , 1 , 0 , 1 ) , List . of ( "00" , 1 , 0 , 1 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e3 0002 00" , 1 , 0 , 1 ) , List . of ( "00" , 1 , 0 , 1 ) ) ) ,
Arguments . of (
"more than 1 inputs" ,
null ,
0 ,
List . of ( List . of ( "30 80 B0 0001 00" , 0 , 0 , 2 ) , List . of ( "00" , 2 , 0 , 2 ) ) ) ,
List . of ( List . of ( "30 80 e3 0001 00" , 0 , 0 , 2 ) , List . of ( "00" , 2 , 0 , 2 ) ) ) ,
Arguments . of (
"more than 0 outputs" ,
null ,
0 ,
List . of ( List . of ( "B0 0001 50 00" , 0 , 0 , 1 ) , List . of ( "3000" , 0 , 1 , 1 ) ) ) ,
List . of ( List . of ( "e3 0001 50 00" , 0 , 0 , 1 ) , List . of ( "3000" , 0 , 1 , 1 ) ) ) ,
Arguments . of (
"more than 0 outputs 3 sections" ,
null ,
0 ,
List . of (
List . of ( "B0 0002 50 00" , 0 , 0 , 1 ) ,
List . of ( "e3 0002 50 00" , 0 , 0 , 1 ) ,
List . of ( "00" , 0 , 0 , 0 ) ,
List . of ( "30305000" , 0 , 1 , 2 ) ) ) ,
Arguments . of (
"more than 1 outputs" ,
null ,
0 ,
List . of ( List . of ( "B0 0001 50 50 00" , 0 , 0 , 2 ) , List . of ( "303000" , 0 , 2 , 2 ) ) ) ,
List . of ( List . of ( "e3 0001 50 50 00" , 0 , 0 , 2 ) , List . of ( "303000" , 0 , 2 , 2 ) ) ) ,
Arguments . of (
"more than 0 inputs, more than 0 outputs" ,
null ,
0 ,
List . of (
List . of ( "30 30 B0 0001 50 50 50 00" , 0 , 0 , 3 ) ,
List . of ( "30 30 B0 0001 50 50 00" , 2 , 3 , 5 ) ) ) ,
Arguments . of ( "recursion" , null , 0 , List . of ( List . of ( "B0 0000 00" , 0 , 0 , 0 ) ) ) ,
List . of ( "30 30 e3 0001 50 50 50 00" , 0 , 0 , 3 ) ,
List . of ( "30 30 e3 0001 50 50 00" , 2 , 3 , 5 ) ) ) ,
Arguments . of ( "recursion" , null , 0 , List . of ( List . of ( "e3 0000 00" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"recursion 2 inputs" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "B0 0000 00" , 2 , 0 , 2 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e3 0000 00" , 2 , 0 , 2 ) ) ) ,
Arguments . of (
"recursion 2 inputs 2 outputs" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "B0 0000 50 50 00" , 2 , 2 , 2 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e3 0000 50 50 00" , 2 , 2 , 2 ) ) ) ,
Arguments . of (
"recursion 2 inputs 1 output" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "30 30 B0 0001 50 50 50 00" , 2 , 1 , 4 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "30 30 e3 0001 50 50 50 00" , 2 , 1 , 4 ) ) ) ,
Arguments . of (
"multiple CALLFs with different types" ,
null ,
1 ,
List . of (
List . of ( "00" , 0 , 0 , 0 ) ,
List . of ( "44 B00002 80 80 B00003 44 80 B0 0004 50 50 00" , 0 , 0 , 3 ) ,
List . of ( "44 e30002 80 80 e30003 44 80 e3 0004 50 50 00" , 0 , 0 , 3 ) ,
List . of ( "3030505000" , 1 , 1 , 3 ) ,
List . of ( "50505000" , 3 , 0 , 3 ) ,
List . of ( "00" , 2 , 2 , 2 ) ) ) ,
Arguments . of (
"underflow" ,
"Operation 0xB0 requires stack of 1 but only has 0 items" ,
"Operation 0xE3 requires stack of 1 but only has 0 items" ,
0 ,
List . of ( List . of ( "B0 0001 00" , 0 , 0 , 0 ) , List . of ( "00" , 1 , 0 , 0 ) ) ) ,
List . of ( List . of ( "e3 0001 00" , 0 , 0 , 0 ) , List . of ( "00" , 1 , 0 , 0 ) ) ) ,
Arguments . of (
"underflow 2" ,
"Operation 0xB0 requires stack of 2 but only has 1 items" ,
"Operation 0xE3 requires stack of 2 but only has 1 items" ,
0 ,
List . of ( List . of ( "30 B0 0001 00" , 0 , 0 , 0 ) , List . of ( "00" , 2 , 0 , 2 ) ) ) ,
List . of ( List . of ( "30 e3 0001 00" , 0 , 0 , 0 ) , List . of ( "00" , 2 , 0 , 2 ) ) ) ,
Arguments . of (
"underflow 3" ,
"Operation 0xB0 requires stack of 1 but only has 0 items" ,
"Operation 0xE3 requires stack of 1 but only has 0 items" ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "50 B0 0001 00" , 1 , 0 , 1 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "50 e3 0001 00" , 1 , 0 , 1 ) ) ) ,
Arguments . of (
"underflow 4" ,
"Operation 0xB0 requires stack of 3 but only has 2 items" ,
"Operation 0xE3 requires stack of 3 but only has 2 items" ,
0 ,
List . of (
List . of ( "44 B00001 80 B0 0002 00" , 0 , 0 , 0 ) ,
List . of ( "44 e30001 80 e3 0002 00" , 0 , 0 , 0 ) ,
List . of ( "00" , 1 , 1 , 1 ) ,
List . of ( "00" , 3 , 0 , 3 ) ) ) ) ;
}
@ -713,63 +712,63 @@ class CodeV1Test {
"0 outputs at section 0" ,
null ,
0 ,
List . of ( List . of ( "B1 " , 0 , 0 , 0 ) , List . of ( "00" , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "e4 " , 0 , 0 , 0 ) , List . of ( "00" , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"0 outputs at section 1" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "B1 " , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e4 " , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"0 outputs at section 2" ,
null ,
2 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "00" , 1 , 1 , 1 ) , List . of ( "B1 " , 0 , 0 , 0 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "00" , 1 , 1 , 1 ) , List . of ( "e4 " , 0 , 0 , 0 ) ) ) ,
Arguments . of (
"more than 0 outputs section 0" ,
null ,
0 ,
List . of ( List . of ( "44 50 B1 " , 0 , 0 , 1 ) , List . of ( "4400" , 0 , 1 , 1 ) ) ) ,
List . of ( List . of ( "44 50 e4 " , 0 , 0 , 1 ) , List . of ( "4400" , 0 , 1 , 1 ) ) ) ,
Arguments . of (
"more than 0 outputs section 0" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "44 B1 " , 0 , 1 , 1 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "44 e4 " , 0 , 1 , 1 ) ) ) ,
Arguments . of (
"more than 1 outputs section 1" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "44 80 B1 " , 0 , 2 , 2 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "44 80 e4 " , 0 , 2 , 2 ) ) ) ,
Arguments . of (
"Forwarding return values" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "B1 " , 1 , 1 , 1 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e4 " , 1 , 1 , 1 ) ) ) ,
Arguments . of (
"Forwarding of return values 2" ,
null ,
1 ,
List . of (
List . of ( "00" , 0 , 0 , 0 ) , List . of ( "B00002 B1 " , 0 , 1 , 1 ) , List . of ( "3000" , 0 , 1 , 1 ) ) ) ,
List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e30002 e4 " , 0 , 1 , 1 ) , List . of ( "3000" , 0 , 1 , 1 ) ) ) ,
Arguments . of (
"Multiple RETFs" ,
null ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "5D0003 44 80 B1 30 80 B1 " , 1 , 2 , 2 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e10003 44 80 e4 30 80 e4 " , 1 , 2 , 2 ) ) ) ,
Arguments . of (
"underflow 1" ,
"Section return (RETF) calculated height 0x0 does not match configured height 0x1" ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "B1 " , 0 , 1 , 0 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e4 " , 0 , 1 , 0 ) ) ) ,
Arguments . of (
"underflow 2" ,
"Section return (RETF) calculated height 0x1 does not match configured height 0x2" ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "44 B1 " , 0 , 2 , 1 ) ) ) ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "44 e4 " , 0 , 2 , 1 ) ) ) ,
Arguments . of (
"underflow 3" ,
"Section return (RETF) calculated height 0x1 does not match configured height 0x2" ,
1 ,
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "5D0003 44 80 B1 30 B1 " , 1 , 2 , 2 ) ) ) ) ;
List . of ( List . of ( "00" , 0 , 0 , 0 ) , List . of ( "e10003 44 80 e4 30 e4 " , 1 , 2 , 2 ) ) ) ) ;
}
static Stream < Arguments > stackUnreachable ( ) {
@ -783,12 +782,12 @@ class CodeV1Test {
"Max stack not changed by unreachable code RETf" ,
"Dead code detected in section 0" ,
0 ,
List . of ( List . of ( "30 50 B1 30 30 30 50 50 50 00" , 0 , 0 , 1 ) ) ) ,
List . of ( List . of ( "30 50 e4 30 30 30 50 50 50 00" , 0 , 0 , 1 ) ) ) ,
Arguments . of (
"Max stack not changed by unreachable code RJUMP" ,
"Dead code detected in section 0" ,
0 ,
List . of ( List . of ( "30 50 5C 0006 30 30 30 50 50 50 00" , 0 , 0 , 1 ) ) ) ,
List . of ( List . of ( "30 50 e0 0006 30 30 30 50 50 50 00" , 0 , 0 , 1 ) ) ) ,
Arguments . of (
"Stack underflow in unreachable code" ,
"Dead code detected in section 0" ,
@ -798,12 +797,12 @@ class CodeV1Test {
"Stack underflow in unreachable code RETF" ,
"Dead code detected in section 0" ,
0 ,
List . of ( List . of ( "30 50 B1 50 00" , 0 , 0 , 1 ) ) ) ,
List . of ( List . of ( "30 50 e4 50 00" , 0 , 0 , 1 ) ) ) ,
Arguments . of (
"Stack underflow in unreachable code RJUMP" ,
"Dead code detected in section 0" ,
0 ,
List . of ( List . of ( "30 50 5C 0001 50 00" , 0 , 0 , 1 ) ) ) ) ;
List . of ( List . of ( "30 50 e0 0001 50 00" , 0 , 0 , 1 ) ) ) ) ;
}
static Stream < Arguments > stackHeight ( ) {
@ -812,12 +811,12 @@ class CodeV1Test {
"Stack height mismatch backwards" ,
"Jump into code stack height (0) does not match previous value (1)" ,
0 ,
List . of ( List . of ( "30 5C fffc00" , 0 , 0 , 1 ) ) ) ,
List . of ( List . of ( "30 e0 fffc00" , 0 , 0 , 1 ) ) ) ,
Arguments . of (
"Stack height mismatch forwards" ,
"Jump into code stack height (3) does not match previous value (0)" ,
0 ,
List . of ( List . of ( "305D 0003303030303000" , 0 , 0 , 2 ) ) ) ) ;
List . of ( List . of ( "30e1 0003303030303000" , 0 , 0 , 2 ) ) ) ) ;
}
static Stream < Arguments > invalidInstructions ( ) {