@@ -583,25 +583,6 @@ func TestValidateBlockTypecheck(t *testing.T) {
583583 },
584584 err : UnmatchedOpError (operators .Loop ),
585585 },
586- {
587- name : "dangling if" ,
588- // (i32.const 0) (if) (block (nop))
589- code : []byte {
590- operators .I32Const , 0 ,
591- operators .If , byte (wasm .BlockTypeEmpty ),
592- operators .Block , byte (wasm .BlockTypeEmpty ), operators .Nop , operators .End ,
593- },
594- err : UnmatchedOpError (operators .If ),
595- },
596- {
597- name : "dangling else" ,
598- // (block (nop)) (else (nop))
599- code : []byte {
600- operators .Block , byte (wasm .BlockTypeEmpty ), operators .Nop , operators .End ,
601- operators .Else , operators .Nop , operators .End ,
602- },
603- err : UnmatchedOpError (operators .Else ),
604- },
605586 {
606587 name : "dangling end" ,
607588 // (block (nop)) (nop) (end)
@@ -879,31 +860,156 @@ func TestValidateBlockTypecheck(t *testing.T) {
879860 err : nil ,
880861 },
881862 {
882- name : "if i32-i32 " ,
883- // (i32.const 0) (if (result i32) (i32.const 0)) (drop )
863+ name : "brtable void-void " ,
864+ // (block (block ( i32.const 0) (brtable 0 0 1)) )
884865 code : []byte {
866+ operators .Block , byte (wasm .BlockTypeEmpty ),
867+ operators .Block , byte (wasm .BlockTypeEmpty ),
885868 operators .I32Const , 0 ,
886- operators .If , byte (wasm .ValueTypeI32 ),
869+ operators .BrTable ,
870+ /* target count */ 2 ,
871+ 0 , 0 , 1 ,
872+ operators .End ,
873+ operators .End ,
874+ },
875+ err : nil ,
876+ },
877+ {
878+ name : "brtable i64-i32" ,
879+ // (block (return i64) (i64.const 0) (block (return i64) (i32.const 0) (brtable 0 0 1)))
880+ code : []byte {
881+ operators .Block , byte (wasm .ValueTypeI64 ),
882+ operators .I64Const , 0 ,
883+ operators .Block , byte (wasm .ValueTypeI32 ),
887884 operators .I32Const , 0 ,
885+ operators .BrTable ,
886+ /* target count */ 2 ,
887+ 0 , 0 , 1 ,
888+ operators .End ,
889+ operators .I32Const , 0 ,
890+ operators .End ,
891+ },
892+ err : InvalidTypeError {wasm .ValueTypeI64 , wasm .ValueTypeI32 },
893+ },
894+ {
895+ name : "brtable invalid default branch" ,
896+ // (i32.const 0) (br_table 1)
897+ code : []byte {
898+ operators .I32Const , 0 ,
899+ operators .BrTable ,
900+ /* target count */ 0 ,
901+ 1 ,
902+ },
903+ err : InvalidLabelError (1 ),
904+ },
905+ {
906+ name : "brtable invalid entry branch" ,
907+ // (i32.const 0) (br_table 3 0)
908+ code : []byte {
909+ operators .I32Const , 0 ,
910+ operators .BrTable ,
911+ /* target count */ 1 ,
912+ 3 , 0 ,
913+ },
914+ err : InvalidLabelError (3 ),
915+ },
916+ {
917+ name : "brtable default i32-i32" ,
918+ // (block (return i32) (i32.const 0) (i32.const 0) (br_table 0 0))
919+ code : []byte {
920+ operators .Block , byte (wasm .ValueTypeI32 ),
921+ operators .I32Const , 0 ,
922+ operators .I32Const , 0 ,
923+ operators .BrTable ,
924+ /* target count */ 0 ,
925+ 0 ,
888926 operators .End ,
889927 operators .Drop ,
890928 },
891929 err : nil ,
892930 },
931+ }
932+
933+ for i := range tcs {
934+ tc := tcs [i ]
935+ t .Run (tc .name , func (t * testing.T ) {
936+ t .Parallel ()
937+
938+ mod := wasm.Module {}
939+ sig := wasm.FunctionSig {Form : 0x60 /* Must always be 0x60 */ }
940+ fn := wasm.FunctionBody {Module : & mod , Code : tc .code }
941+
942+ _ , err := verifyBody (& sig , & fn , & mod )
943+ if err != tc .err {
944+ t .Fatalf ("verify returned '%v', want '%v'" , err , tc .err )
945+ }
946+ })
947+ }
948+ }
949+
950+ func TestValidateIfBlock (t * testing.T ) {
951+ tcs := []struct {
952+ name string
953+ code []byte
954+ err error
955+ }{
893956 {
894- name : "if else i32-i32-i32 " ,
895- // (i32.const 0) (if (result i32) (i32.const 0) (else (i32.const 1))) (drop )
957+ name : "if nominal " ,
958+ // (i32.const 0) (if (nop )
896959 code : []byte {
897960 operators .I32Const , 0 ,
898- operators .If , byte (wasm .ValueTypeI32 ),
961+ operators .If , byte (wasm .BlockTypeEmpty ),
962+ operators .Nop ,
963+ operators .End ,
964+ },
965+ err : nil ,
966+ },
967+ {
968+ name : "if else nominal" ,
969+ // (i32.const 0) (if (nop) (else (nop))
970+ code : []byte {
899971 operators .I32Const , 0 ,
972+ operators .If , byte (wasm .BlockTypeEmpty ),
973+ operators .Nop ,
900974 operators .Else ,
901- operators .I32Const , 1 ,
975+ operators .Nop ,
976+ operators .End ,
977+ },
978+ err : nil ,
979+ },
980+ {
981+ name : "if else with value nominal" ,
982+ // (i32.const 0) (if (result i64) (i64.const 1) (else (i64.const 2)) (drop)
983+ code : []byte {
984+ operators .I32Const , 0 ,
985+ operators .If , byte (wasm .ValueTypeI64 ),
986+ operators .I64Const , 1 ,
987+ operators .Else ,
988+ operators .I64Const , 2 ,
902989 operators .End ,
903990 operators .Drop ,
904991 },
905992 err : nil ,
906993 },
994+ {
995+ name : "dangling if" ,
996+ // (i32.const 0) (if) (block (nop))
997+ code : []byte {
998+ operators .I32Const , 0 ,
999+ operators .If , byte (wasm .BlockTypeEmpty ),
1000+ operators .Block , byte (wasm .BlockTypeEmpty ), operators .Nop , operators .End ,
1001+ },
1002+ err : UnmatchedOpError (operators .If ),
1003+ },
1004+ {
1005+ name : "dangling else" ,
1006+ // (block (nop)) (else (nop))
1007+ code : []byte {
1008+ operators .Block , byte (wasm .BlockTypeEmpty ), operators .Nop , operators .End ,
1009+ operators .Else , operators .Nop , operators .End ,
1010+ },
1011+ err : UnmatchedOpError (operators .Else ),
1012+ },
9071013 {
9081014 name : "if else i32-i32-i64" ,
9091015 // (i32.const 0) (if (result i32) (i32.const 0) (else (i64.const 1))) (drop)
@@ -919,96 +1025,95 @@ func TestValidateBlockTypecheck(t *testing.T) {
9191025 err : InvalidTypeError {wasm .ValueTypeI32 , wasm .ValueTypeI64 },
9201026 },
9211027 {
922- name : "if void -i32" ,
923- // (i32.const 0) (if (result i32 ) (i32.const 0)) (drop)
1028+ name : "if else i64 -i32-i64 " ,
1029+ // (i32.const 0) (if (result i64 ) (i32.const 0) (else (i64.const 1) )) (drop)
9241030 code : []byte {
9251031 operators .I32Const , 0 ,
926- operators .If , byte (wasm .BlockTypeEmpty ),
1032+ operators .If , byte (wasm .ValueTypeI64 ),
9271033 operators .I32Const , 0 ,
1034+ operators .Else ,
1035+ operators .I64Const , 1 ,
9281036 operators .End ,
9291037 operators .Drop ,
9301038 },
931- err : UnbalancedStackErr ( wasm .ValueTypeI32 ) ,
1039+ err : InvalidTypeError { wasm .ValueTypeI64 , wasm . ValueTypeI32 } ,
9321040 },
9331041 {
934- name : "if i32-void " ,
935- // (i32.const 0) (if (nop) )
1042+ name : "if else i64- i32-i32 " ,
1043+ // (i32.const 0) (if (result i64) (i32.const 0) (else (i64.const 1))) (drop )
9361044 code : []byte {
9371045 operators .I32Const , 0 ,
938- operators .If , byte (wasm .ValueTypeI32 ),
939- operators .Nop ,
1046+ operators .If , byte (wasm .ValueTypeI64 ),
1047+ operators .I32Const , 0 ,
1048+ operators .Else ,
1049+ operators .I32Const , 1 ,
9401050 operators .End ,
1051+ operators .Drop ,
9411052 },
942- err : ErrStackUnderflow ,
1053+ err : InvalidTypeError { wasm . ValueTypeI64 , wasm . ValueTypeI32 } ,
9431054 },
9441055 {
945- name : "brtable void-void " ,
946- // (block (block ( i32.const 0) (brtable 0 0 1)) )
1056+ name : "if void-i32 " ,
1057+ // (i32.const 0) (if (result i32) (i32.const 0)) (drop )
9471058 code : []byte {
948- operators .Block , byte (wasm .BlockTypeEmpty ),
949- operators .Block , byte (wasm .BlockTypeEmpty ),
9501059 operators .I32Const , 0 ,
951- operators .BrTable ,
952- /* target count */ 2 ,
953- 0 , 0 , 1 ,
954- operators .End ,
1060+ operators .If , byte (wasm .BlockTypeEmpty ),
1061+ operators .I32Const , 0 ,
9551062 operators .End ,
1063+ operators .Drop ,
9561064 },
957- err : nil ,
1065+ err : UnbalancedStackErr ( wasm . ValueTypeI32 ) ,
9581066 },
9591067 {
960- name : "brtable i64- i32" ,
961- // (block (return i64) (i64 .const 0) (block (return i64) ( i32.const 0 ) (brtable 0 0 1) ))
1068+ name : "if i32-void " ,
1069+ // (i32 .const 0) (if (result i32) (nop ))
9621070 code : []byte {
963- operators .Block , byte (wasm .ValueTypeI64 ),
964- operators .I64Const , 0 ,
965- operators .Block , byte (wasm .ValueTypeI32 ),
966- operators .I32Const , 0 ,
967- operators .BrTable ,
968- /* target count */ 2 ,
969- 0 , 0 , 1 ,
970- operators .End ,
9711071 operators .I32Const , 0 ,
1072+ operators .If , byte (wasm .ValueTypeI32 ),
1073+ operators .Nop ,
9721074 operators .End ,
9731075 },
974- err : InvalidTypeError { wasm . ValueTypeI64 , wasm . ValueTypeI32 } ,
1076+ err : ErrStackUnderflow ,
9751077 },
9761078 {
977- name : "brtable invalid default branch " ,
978- // (i32.const 0) (br_table 1 )
1079+ name : "if i32 missing else " ,
1080+ // (i32.const 0) (if (nop) )
9791081 code : []byte {
9801082 operators .I32Const , 0 ,
981- operators .BrTable ,
982- /* target count */ 0 ,
983- 1 ,
1083+ operators .If , byte (wasm .ValueTypeI32 ),
1084+ operators .I32Const , 0 ,
1085+ operators .End ,
1086+ operators .Drop ,
9841087 },
985- err : InvalidLabelError ( 1 ),
1088+ err : UnmatchedIfValueErr ( wasm . ValueTypeI32 ),
9861089 },
9871090 {
988- name : "brtable invalid entry branch " ,
989- // (i32.const 0) (br_table 3 0 )
1091+ name : "if with else missing main block result " ,
1092+ // (i32.const 0) (if (result i32) (nop) else (i32.const 0) )
9901093 code : []byte {
9911094 operators .I32Const , 0 ,
992- operators .BrTable ,
993- /* target count */ 1 ,
994- 3 , 0 ,
1095+ operators .If , byte (wasm .ValueTypeI32 ),
1096+ operators .Nop ,
1097+ operators .Else ,
1098+ operators .I32Const , 0 ,
1099+ operators .End ,
1100+ operators .Drop ,
9951101 },
996- err : InvalidLabelError ( 3 ) ,
1102+ err : ErrStackUnderflow ,
9971103 },
9981104 {
999- name : "brtable default i32-i32 " ,
1000- // (block (return i32) (i32 .const 0) (i32.const 0) (br_table 0 0 ))
1105+ name : "if with else missing else block result " ,
1106+ // (i32.const 0) (if (result i32) (i32 .const 0) else (nop ))
10011107 code : []byte {
1002- operators .Block , byte (wasm .ValueTypeI32 ),
10031108 operators .I32Const , 0 ,
1109+ operators .If , byte (wasm .ValueTypeI32 ),
10041110 operators .I32Const , 0 ,
1005- operators .BrTable ,
1006- /* target count */ 0 ,
1007- 0 ,
1111+ operators .Else ,
1112+ operators .Nop ,
10081113 operators .End ,
10091114 operators .Drop ,
10101115 },
1011- err : nil ,
1116+ err : ErrStackUnderflow ,
10121117 },
10131118 }
10141119
0 commit comments