1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2006-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% Originally based on Per Gustafsson's test suite. 21%% 22 23-module(bs_bincomp_SUITE). 24 25-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 26 init_per_group/2,end_per_group/2, 27 byte_aligned/1,bit_aligned/1,extended_byte_aligned/1, 28 extended_bit_aligned/1,mixed/1,filters/1,trim_coverage/1, 29 nomatch/1,sizes/1,general_expressions/1, 30 no_generator/1,zero_pattern/1,multiple_segments/1]). 31 32-include_lib("common_test/include/ct.hrl"). 33 34suite() -> [{ct_hooks,[ts_install_cth]}]. 35 36all() -> 37 [byte_aligned, bit_aligned, extended_byte_aligned, 38 extended_bit_aligned, mixed, filters, trim_coverage, 39 nomatch, sizes, general_expressions, 40 no_generator, zero_pattern, multiple_segments]. 41 42groups() -> 43 []. 44 45init_per_suite(Config) -> 46 test_lib:recompile(?MODULE), 47 Config. 48 49end_per_suite(_Config) -> 50 ok. 51 52init_per_group(_GroupName, Config) -> 53 Config. 54 55end_per_group(_GroupName, Config) -> 56 Config. 57 58byte_aligned(Config) when is_list(Config) -> 59 cs_init(), 60 <<"abcdefg">> = cs(<< <<(X+32)>> || <<X>> <= <<"ABCDEFG">> >>), 61 <<"AxyzBxyzCxyz">> = cs(<< <<X, "xyz">> || <<X>> <= <<"ABC">> >>), 62 <<1:32/little,2:32/little,3:32/little,4:32/little>> = 63 cs(<< <<X:32/little>> || <<X:32>> <= <<1:32,2:32,3:32,4:32>> >>), 64 cs(<<1:32/little,2:32/little,3:32/little,4:32/little>> = 65 << <<X:32/little>> || <<X:16>> <= <<1:16,2:16,3:16,4:16>> >>), 66 cs_end(). 67 68bit_aligned(Config) when is_list(Config) -> 69 cs_init(), 70 <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> = 71 cs(<< <<(X+32):7>> || <<X>> <= <<"ABCDEFG">> >>), 72 <<"ABCDEFG">> = cs(<< <<(X-32)>> || <<X:7>> <= id(<<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>>) >>), 73 <<1:31/little,2:31/little,3:31/little,4:31/little>> = 74 cs(<< <<X:31/little>> || <<X:31>> <= <<1:31,2:31,3:31,4:31>> >>), 75 <<1:31/little,2:31/little,3:31/little,4:31/little>> = 76 cs(<< <<X:31/little>> || <<X:15>> <= <<1:15,2:15,3:15,4:15>> >>), 77 cs_end(). 78 79extended_byte_aligned(Config) when is_list(Config) -> 80 cs_init(), 81 <<"abcdefg">> = cs(<< <<(X+32)>> || X <- "ABCDEFG" >>), 82 "abcdefg" = [(X+32) || <<X>> <= <<"ABCDEFG">>], 83 <<1:32/little,2:32/little,3:32/little,4:32/little>> = 84 cs(<< <<X:32/little>> || X <- [1,2,3,4] >>), 85 [256,512,768,1024] = 86 [X || <<X:16/little>> <= <<1:16,2:16,3:16,4:16>>], 87 cs_end(). 88 89extended_bit_aligned(Config) when is_list(Config) -> 90 cs_init(), 91 <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> = 92 cs(<< <<(X+32):7>> || X <- "ABCDEFG" >>), 93 "ABCDEFG" = [(X-32) || <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>>], 94 <<1:31/little,2:31/little,3:31/little,4:31/little>> = 95 cs(<< <<X:31/little>> || X <- [1,2,3,4] >>), 96 [256,512,768,1024] = 97 [X || <<X:15/little>> <= <<1:15,2:15,3:15,4:15>>], 98 cs_end(). 99 100mixed(Config) when is_list(Config) -> 101 cs_init(), 102 <<2,3,3,4,4,5,5,6>> = 103 cs(<< <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>> >>), 104 <<2,3,3,4,4,5,5,6>> = 105 cs(<< <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, Y <- [1,2] >>), 106 <<2,3,3,4,4,5,5,6>> = 107 cs(<< <<(X+Y)>> || X <- [1,2,3,4], Y <- [1,2] >>), 108 One = id([1,2,3,4]), 109 Two = id([1,2]), 110 <<2,3,3,4,4,5,5,6>> = 111 cs(<< <<(X+Y)>> || X <- One, Y <- Two >>), 112 [2,3,3,4,4,5,5,6] = 113 [(X+Y) || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>>], 114 [2,3,3,4,4,5,5,6] = 115 [(X+Y) || <<X>> <= <<1,2,3,4>>, Y <- [1,2]], 116 <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> = 117 cs(<< <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, 118 <<Y:3>> <= <<1:3,2:3>> >>), 119 <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> = 120 cs(<< <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, Y <- [1,2] >>), 121 <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> = 122 cs(<< <<(X+Y):3>> || X <- [1,2,3,4], Y <- [1,2] >>), 123 <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> = 124 cs_default(<< <<(X+Y):3>> || {X,Y} <- [{1,1},{1,2},{2,1},{2,2}, 125 {3,1},{3,2},{4,1},{4,2}] >>), 126 [2,3,3,4,4,5,5,6] = 127 [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, <<Y:3>> <= <<1:3,2:3>>], 128 [2,3,3,4,4,5,5,6] = 129 [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, {_,Y} <- [{a,1},{b,2}]], 130 131 %% OTP-16899: Nested binary comprehensions would fail to load. 132 <<0,1,0,2,0,3,99>> = mixed_nested([1,2,3]), 133 134 <<1>> = cs_default(<< <<X>> || L <- [[1]], X <- L >>), 135 136 %% The compiler would crash in v3_kernel. 137 <<42:32,75:32,253:32,(42 bsl 8 bor 75):32>> = 138 cs_default(mixed_size(id([8,16]), <<42,75,253>>)), 139 140 silly_lc_bc(5), 141 142 gen_data(0), 143 gen_data(256), 144 gen_data(512), 145 146 <<1,2,3>> = cs_default(match_context_1(<<1,2,3>>)), 147 <<4,5,6>> = cs_default(match_context_2(<<4,5,6>>)), 148 149 <<255>> = over_complex_generator(), 150 {'EXIT',_} = catch float_segment_size(), 151 152 cs_end(). 153 154mixed_nested(L) -> 155 << << << << E:16 >> || E <- L >> || true >>/binary, 99:(id(8))>>. 156 157mixed_size(List, Bin) -> 158 << <<X:32>> || Size <- List, <<X:Size>> <= Bin >>. 159 160silly_lc_bc(N) when N > 0 -> 161 Bin = iolist_to_binary(silly_lc(N)), 162 Bin = cs(silly_bc(N)), 163 Size = byte_size(Bin), 164 Size = 5 bsl N, 165 silly_lc_bc(N - 1); 166silly_lc_bc(_) -> ok. 167 168silly_bc(0) -> 169 <<0, 1, 2, 3, 4>>; 170silly_bc(N) -> 171 << <<X, X>> || <<X>> <= silly_bc(N - 1) >>. 172 173silly_lc(0) -> 174 [0, 1, 2, 3, 4]; 175silly_lc(N) -> 176 [[X, X] || X <- silly_lc(N - 1)]. 177 178gen_data(Size) -> 179 Data = cs(<< <<C>> || C <- lists:seq(0, Size-1) >>), 180 Data = << <<C>> || _ <- lists:seq(1, Size div 256), 181 C <- lists:seq(0, 255) >>. 182 183match_context_1(<<B/binary>>) -> 184 << <<V>> || <<V>> <= B >>. 185 186match_context_2(<<B/binary>>) -> 187 do_match_context_2(B). 188 189do_match_context_2(B) -> 190 << <<V>> || <<V>> <= B >>. 191 192%% Would crash beam_ssa_bc_size when the no_copt option was given. 193over_complex_generator() -> 194 << 195 <<255>> || 196 <<0:2>> <= <<0:2>>, 197 <<_:8>> <= 198 case true of 199 true -> 200 <<8>>; 201 [6.6 | bad_tail] -> 202 ok; 203 [3 | 4] -> 204 error 205 end 206 >>. 207 208float_segment_size() -> 209 try 210 V = 0.79 211 of 212 _ -> 213 %% Would crash beam_ssa_bc_size when trying to 214 %% interpret V * U = 0.79 * 8 as a size. 215 << 216 0 || <<5.9:V/unit:8-float>> <= 42 217 >> 218 catch 219 _:_ -> 220 error 221 end. 222 223filters(Config) when is_list(Config) -> 224 cs_init(), 225 <<"BDF">> = 226 cs_default(<< <<(X-32)>> || 227 <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>>, 228 X rem 2 == 0>>), 229 <<"abc">> = cs_default(<< <<(X+32)>> || 230 X <- "ABCDEFG", 231 is_less_than(X, $D)>>), 232 <<"efg">> = cs_default(<< <<(X+32)>> || 233 X <- "ABCDEFG", 234 not is_less_than(X, $E)>>), 235 <<"b">> = cs_default(<< <<(X+32)>> || 236 X <- "ABCDEFG", 237 is_less_than(X, $D), 238 X rem 2 == 0>>), 239 <<"eg">> = cs_default(<< <<(X+32)>> || 240 X <- "ABCDEFG", 241 not is_less_than(X, $E), 242 X rem 2 == 1>>), 243 <<1,3>> = cs_default(<< <<(length(L))>> || 244 L <- [[],[a],[],[x,y,z]], 245 case L of 246 [] -> false; 247 [_|_] -> true 248 end >>), 249 <<77,42>> = cs_default(<< <<B>> || <<B>> <- [<<77>>,<<1,2>>,<<42>>] >>), 250 251 %% Filtering by a non-matching pattern. 252 <<"abd">> = cs_default(<< <<X:8>> || 253 <<0:1,X:7>> <= <<$a:8,$b:8,1:1,$c:7,$d:8, 254 1:1,$e:7,0:4>> >>), 255 256 <<42,42>> = cs_default(<< <<42:8>> || 42 <- [1,2,3,42,43,42] >>), 257 cs_end(). 258 259is_less_than(X, C) when X < C -> true; 260is_less_than(_, _) -> false. 261 262trim_coverage(Config) when is_list(Config) -> 263 <<0,0,0,2,0,0,5,48,0,11,219,174,0,0,0,0>> = coverage_materialiv(a, b, {1328,777134}), 264 <<67,40,0,0,66,152,0,0,69,66,64,0>> = coverage_trimmer([42,19,777]), 265 <<0,0,2,43,0,0,3,9,0,0,0,3,64,8,0,0,0,0,0,0, 266 64,68,0,0,0,0,0,0,192,171,198,0,0,0,0,0>> = 267 coverage_lightfv(555, 777, {3.0,40.0,-3555.0}), 268 <<"abcabc">> = coverage_strange(0, <<"abc">>), 269 ok. 270 271coverage_materialiv(A, B, Params) -> 272 A = id(A), 273 B = id(B), 274 <<(tuple_size(Params)):32, 275 (<< <<C:32>> || C <- tuple_to_list(Params)>>)/binary, 276 0:(((1+tuple_size(Params)) rem 2)*32)>>. 277 278coverage_lightfv(Light, Pname, Params) -> 279 id(<<Light:32,Pname:32,(size(Params)):32, 280 (<< <<C:64/float>> || C <- tuple_to_list(Params)>>)/binary, 281 0:(((1+size(Params)) rem 2)*32)>>). 282 283coverage_trimmer(Params) -> 284 X = id(0), 285 Y = id(1), 286 id({X,Y}), 287 << <<(begin {A,B,D} = id({C,C,C}), id(0), 288 coverage_summer(A, B, C, D) end):32/float>> || 289 C <- Params >>. 290 291coverage_summer(A, B, C, D) -> A+B+C+D. 292 293coverage_strange(V, Bin) -> 294 << 295 << <<X>> || <<X/utf8>> <= Bin >>/bits, 296 << <<Y>> || <<Y>> <= Bin>>: 297 case V of 298 V -> 299 3; 300 0 -> 301 receive 302 whatever -> 303 1 304 end 305 end/bytes>>. 306 307nomatch(Config) when is_list(Config) -> 308 Bin = id(<<1,2,3,4,5>>), 309 <<>> = << <<X:8>> || X = {_,_} = [_|_] <- [1,2,3] >>, 310 [] = [X || <<X:all/binary>> <= Bin], 311 [] = [X || <<X:bad/binary>> <= Bin], 312 <<>> = << <<X:32>> || <<X:all/binary>> <= Bin >>, 313 <<>> = << <<X:32>> || <<X:bad/binary>> <= Bin >>, 314 315 <<>> = << <<"a">> || <<_:1/float>> <= Bin>>, 316 317 NaN = <<(-1):32>>, 318 <<>> = << <<"a">> || <<_:32/float>> <= NaN >>, 319 320 <<1:32,2:32,3:32>> = nomatch_1(<<1,2,3>>, 8), 321 <<>> = nomatch_1(<<1,2,3>>, bad), 322 323 <<>> = << <<>> || <<_:8>> <= <<>> >>, 324 325 ok. 326 327nomatch_1(Bin, Size) -> 328 << <<X:32>> || <<X:Size>> <= Bin >>. 329 330sizes(Config) when is_list(Config) -> 331 cs_init(), 332 Fun0 = fun(List) -> 333 cs(<< <<E:8>> || E <- List >>) 334 end, 335 <<>> = Fun0([]), 336 <<1>> = Fun0([1]), 337 <<1,2>> = Fun0([1,2]), 338 <<1,2,3>> = Fun0([1,2,3]), 339 340 Fun1 = fun(List) -> 341 cs(<< <<E:16>> || E <- List >>) 342 end, 343 <<>> = Fun1([]), 344 <<1:16>> = Fun1([1]), 345 <<1:16,2:16>> = Fun1([1,2]), 346 <<1:16,2:16,3:16>> = Fun1([1,2,3]), 347 348 Fun2 = fun(List) -> 349 cs(<< <<E:4>> || E <- List >>) 350 end, 351 <<>> = Fun2([]), 352 <<1:4>> = Fun2([1]), 353 <<1:4,13:4>> = Fun2([1,13]), 354 <<1:4,13:4,7:4>> = Fun2([1,13,7]), 355 <<0:1000/unit:8>> = Fun2(lists:duplicate(2000, 0)), 356 357 Fun3 = fun(List) -> 358 cs(<< <<E:3>> || E <- List >>) 359 end, 360 <<>> = Fun3([]), 361 <<40,177,29:5>> = Fun3([1,2,1,3,0,7,5]), 362 <<0:512/unit:3>> = Fun3(lists:duplicate(512, 0)), 363 364 Fun4 = fun(List, Size) -> 365 cs(<< <<E:Size>> || E <- List >>) 366 end, 367 <<>> = Fun4([], 8), 368 <<42:6>> = Fun4([42], 6), 369 <<42:16>> = Fun4([42], 16), 370 371 Fun5 = fun(List, Sz1, Sz2, Sz3) -> 372 cs(<< <<E:Sz1,(E+1):Sz2/unit:8,(E+2):Sz3/unit:8>> || E <- List >>) 373 end, 374 <<>> = Fun5([], 1, 1, 1), 375 <<7:3,8:40,9:56>> = Fun5([7], 3, 5, 7), 376 377 Fun5a = fun(List, Sz1, Sz2, Sz3) -> 378 cs(<< <<"abc",E:Sz1,(E+1):Sz2/unit:8,"qqq",(E+2):Sz3/unit:8,"xyz">> || 379 E <- List >>) 380 end, 381 <<>> = Fun5a([], 1, 1, 1), 382 <<"abc",7:3,8:40,"qqq",9:56,"xyz">> = Fun5a([7], 3, 5, 7), 383 384 Fun6 = fun(List, Size) -> 385 cs(<< <<E:8,(E+1):Size>> || E <- List >>) 386 end, 387 <<>> = Fun6([], 42), 388 <<42,43:20>> = Fun6([42], 20), 389 390 %% Binary generators. 391 392 Fun10 = fun(Bin) -> 393 cs(<< <<E:16>> || <<E:8>> <= id(Bin) >>) 394 end, 395 <<>> = Fun10(<<>>), 396 <<1:16>> = Fun10(<<1>>), 397 <<1:16,2:16>> = Fun10(<<1,2>>), 398 399 Fun11 = fun(Bin) -> 400 cs(<< <<E:8>> || <<E:16>> <= id(Bin) >>) 401 end, 402 <<>> = Fun11(<<>>), 403 <<1>> = Fun11(<<1:16>>), 404 <<1,2>> = Fun11(<<1:16,2:16>>), 405 <<1,2>> = Fun11(<<1:16,2:16,0:1>>), 406 <<1,2>> = Fun11(<<1:16,2:16,0:7>>), 407 <<1,2>> = Fun11(<<1:16,2:16,42:8>>), 408 <<1,2>> = Fun11(<<1:16,2:16,42:9>>), 409 <<1,2>> = Fun11(<<1:16,2:16,255:15>>), 410 411 Fun12 = fun(Bin, Sz1, Sz2) -> 412 cs(<< <<E:Sz1>> || <<E:Sz2>> <= id(Bin) >>) 413 end, 414 <<>> = Fun12(<<>>, 1, 1), 415 Binary = list_to_binary(lists:seq(0, 255)), 416 Binary = Fun12(Binary, 1, 1), 417 Binary = Fun12(Binary, 4, 4), 418 Binary = Fun12(Binary, 8, 8), 419 <<17:9,19:9>> = Fun12(<<17:6,19:6>>, 9, 6), 420 421 Fun13 = fun(Sz) -> 422 cs(<< <<C:8>> || <<C:4>> <= <<1:4,2:4,3:4,0:Sz>> >>) 423 end, 424 <<1,2,3>> = Fun13(0), 425 <<1,2,3,0>> = Fun13(4), 426 <<1,2,3,0>> = Fun13(5), 427 <<1,2,3,0>> = Fun13(6), 428 <<1,2,3,0>> = Fun13(7), 429 <<1,2,3,0,0>> = Fun13(8), 430 431 <<0:3>> = cs_default(<< <<0:S>> || S <- [0,1,2] >>), 432 <<0:3>> = cs_default(<< <<0:S>> || <<S>> <= <<0,1,2>> >>), 433 434 Fun14 = fun(L, B) -> 435 cs_default(<< <<X:32>> || Size <- L, <<X:Size>> <= B >>) 436 end, 437 <<$a:32,$b:32,$c:32,($a bsl 8 bor $b):32>> = Fun14([8,16], <<"abc">>), 438 <<$a:32,$b:32,$c:32>> = Fun14([8,bad], <<"abc">>), 439 440 {'EXIT',_} = (catch << <<C:4>> || <<C:8>> <= {1,2,3} >>), 441 442 cs_end(), 443 ok. 444 445-define(BAD(E), {'EXIT',{badarg,_}} = (catch << (E) || _ <- [1,2,3] >>)). 446-define(BAD_V(E), {'EXIT',{badarg,_}} = (catch << (E) || I <- [1,2,3] >>)). 447 448general_expressions(_) -> 449 cs_init(), 450 451 <<1,2,3>> = cs(<< begin <<1,2,3>> end || _ <- [1] >>), 452 <<"abc">> = cs(<< begin <<"abc">> end || _ <- [1] >>), 453 <<1,2,3>> = cs_default(<< begin 454 I = <<(I0+1)>>, 455 id(I) 456 end || <<I0>> <= <<0,1,2>> >>), 457 <<1,2,3>> = cs_default(<< I || I <- [<<1,2>>,<<3>>] >>), 458 <<1,2,3>> = cs_default(<< (id(<<I>>)) || I <- [1,2,3] >>), 459 <<2,4>> = cs_default(<< case I rem 2 of 460 0 -> <<I>>; 461 1 -> <<>> 462 end || I <- [1,2,3,4,5] >>), 463 <<2,3,4,5,6,7>> = cs_default(<< << (id(<<J>>)) || J <- [2*I,2*I+1] >> || 464 I <- [1,2,3] >>), 465 <<1,2,2,3,4,4>> = cs_default(<< if 466 I rem 2 =:= 0 -> <<I,I>>; 467 true -> <<I>> 468 end || I <- [1,2,3,4] >>), 469 self() ! <<42>>, 470 <<42>> = cs_default(<< receive B -> B end || _ <- [1] >>), 471 <<10,5,3>> = cs_default(<< try 472 <<(10 div I)>> 473 catch _:_ -> 474 <<>> 475 end || I <- [0,1,2,3] >>), 476 477 <<3:4,16#A:4,7:4>> = cs(hstring_to_bitstring("3A7")), 478 <<0:3,1:3,2:3,3:3,4:3,5:3,6:3,7:3>> = cs(encode_chars_compact_map("ABCDEFGH", id(3), id({$A,8}))), 479 480 cs_end(), 481 482 %% Failing expressions. 483 ?BAD(bad_atom), 484 ?BAD(42), 485 ?BAD(42.0), 486 ?BAD_V({ok,I}), 487 ?BAD_V([I]), 488 ?BAD_V(fun() -> I end), 489 490 ok. 491 492hstring_to_bitstring(L) -> 493 << <<(hex_to_int(D)):4>> || D <- L >>. 494 495hex_to_int(D) when $0 =< D, D =< $9 -> D - $0; 496hex_to_int(D) when $A =< D, D =< $F -> D - ($A - 10). 497 498encode_chars_compact_map(Val, NumBits, {Lb,Limit}) -> 499 << <<(enc_char_cm(C, Lb, Limit)):NumBits>> || C <- Val >>. 500 501enc_char_cm(C0, Lb, Limit) -> 502 C = C0 - Lb, 503 if 504 0 =< C, C < Limit -> 505 C; 506 true -> 507 error(illegal) 508 end. 509 510-undef(BAD). 511 512no_generator(_Config) -> 513 [<<"abc">>] = [<<(id(<<"abc">>)) || true >>], 514 {<<>>} = {<<(id(<<"abc">>)) || false >>}, 515 516 %% Would crash the compiler when compiled with +no_type_opt. 517 {'EXIT',{badarg,_}} = (catch << (catch "\001") || true >>), 518 519 ok. 520 521zero_pattern(Config) -> 522 case is_atom(Config) of 523 true -> 524 %% Patterns that match zero bits loops forever, so we must 525 %% be careful not to execute them. 526 _ = << <<>> || <<>> <= <<>> >>, 527 _ = << <<42>> || <<>> <= <<42>> >>, 528 _ = << 529 <<>> || 530 <<>> <= << >>, 531 <<3:back>> <= << >> 532 >>, 533 _ = << 534 <<>> || 535 <<>> <= <<>>, 536 <<>> <- << <<>> || area >> 537 >>; 538 false -> 539 ok 540 end. 541 542multiple_segments(_Config) -> 543 cs_init(), 544 545 [1,2] = matched_out_size(<<4, 1:4, 4, 2:4>>), 546 [42] = matched_out_size(<<16, 42:16, 72>>), 547 548 [] = do_multiple_segments_1(<<>>), 549 [] = do_multiple_segments_1(<<1>>), 550 [] = do_multiple_segments_1(<<1,2>>), 551 [] = do_multiple_segments_1(<<1,2,3>>), 552 [1,4] = do_multiple_segments_1(<<99,0,1,1,2,3,4,4>>), 553 554 [] = do_multiple_segments_2(<<1,2>>), 555 [6] = do_multiple_segments_2(<<1,2,3>>), 556 [6,15] = do_multiple_segments_2(<<1,2,3,4,5,6,7,8>>), 557 558 cs_end(), 559 ok. 560 561matched_out_size(Gen) -> 562 Bin = cs_default(<< <<X>> || <<S,X:S>> <= Gen >>), 563 List = [X || <<S,X:S>> <= Gen], 564 Bin = list_to_binary(List), 565 List. 566 567do_multiple_segments_1(Gen) -> 568 Bin = cs_default(<< <<V>> || <<V,V>> <= Gen >>), 569 List = [V || <<V,V>> <= Gen], 570 Bin = list_to_binary(List), 571 List. 572 573do_multiple_segments_2(Gen) -> 574 Bin = cs(<< <<(A+B+C)>> || <<A,B,C>> <= Gen >>), 575 List = [A+B+C || <<A,B,C>> <= Gen], 576 Bin = list_to_binary(List), 577 List. 578 579cs_init() -> 580 erts_debug:set_internal_state(available_internal_state, true), 581 ok. 582 583cs_end() -> 584 erts_debug:set_internal_state(available_internal_state, false), 585 ok. 586 587%% Verify that the allocated size is exact (rounded up to the nearest byte). 588cs(Bin) -> 589 case ?MODULE of 590 bs_bincomp_no_opt_SUITE -> 591 ok; 592 bs_bincomp_no_ssa_opt_SUITE -> 593 ok; 594 bs_bincomp_post_opt_SUITE -> 595 ok; 596 _ -> 597 ByteSize = byte_size(Bin), 598 {refc_binary,ByteSize,{binary,ByteSize},_} = 599 erts_debug:get_internal_state({binary_info,Bin}) 600 end, 601 Bin. 602 603%% Verify that the allocated size of the binary is the default size. 604cs_default(Bin) -> 605 ByteSize = byte_size(Bin), 606 {refc_binary,ByteSize,{binary,256},_} = 607 erts_debug:get_internal_state({binary_info,Bin}), 608 Bin. 609 610id(I) -> I. 611