Skip to content

Commit 576fb54

Browse files
committed
Update JIT, add tests
1 parent 7bb58f2 commit 576fb54

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

libs/jit/src/jit.erl

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,10 +1324,6 @@ first_pass(<<?OP_BS_GET_BINARY2, Rest0/binary>>, MMod, MSt0, State0) ->
13241324
{MSt5, BSOffsetReg0} = MMod:get_array_element(MSt4, MatchStateRegPtr, 2),
13251325
MSt6 =
13261326
if
1327-
Unit =/= 8 ->
1328-
MMod:call_primitive_last(MSt5, ?PRIM_RAISE_ERROR, [
1329-
ctx, jit_state, offset, ?UNSUPPORTED_ATOM
1330-
]);
13311327
FlagsValue =/= 0 ->
13321328
MMod:call_primitive_last(MSt5, ?PRIM_RAISE_ERROR, [
13331329
ctx, jit_state, offset, ?UNSUPPORTED_ATOM
@@ -1349,9 +1345,17 @@ first_pass(<<?OP_BS_GET_BINARY2, Rest0/binary>>, MMod, MSt0, State0) ->
13491345
is_integer(Size) ->
13501346
% SizeReg is binary size
13511347
% SizeVal is a constant
1352-
MSt11 = MMod:sub(MSt10, SizeReg, Size bsl 4),
1348+
MSt11 =
1349+
if
1350+
(Size * Unit) rem 8 =/= 0 ->
1351+
MMod:call_primitive_last(MSt10, ?PRIM_RAISE_ERROR, [
1352+
ctx, jit_state, offset, ?UNSUPPORTED_ATOM
1353+
]);
1354+
true ->
1355+
MMod:sub(MSt10, SizeReg, (Size * Unit) div 8)
1356+
end,
13531357
MSt12 = cond_jump_to_label({{free, SizeReg}, '<', BSOffsetReg1}, Fail, MMod, MSt11),
1354-
{MSt12, Size bsl 4};
1358+
{MSt12, (Size * Unit) div 8};
13551359
true ->
13561360
{MSt11, SizeValReg} = MMod:move_to_native_register(MSt10, Size),
13571361
MSt12 = MMod:if_else_block(
@@ -1363,10 +1367,29 @@ first_pass(<<?OP_BS_GET_BINARY2, Rest0/binary>>, MMod, MSt0, State0) ->
13631367
end,
13641368
fun(BSt0) ->
13651369
{BSt1, SizeValReg} = term_to_int(SizeValReg, 0, MMod, BSt0),
1366-
BSt2 = MMod:sub(BSt1, SizeReg, SizeValReg),
1367-
BSt3 = cond_jump_to_label({SizeReg, '<', BSOffsetReg1}, Fail, MMod, BSt2),
1368-
BSt4 = MMod:move_to_native_register(BSt3, SizeValReg, SizeReg),
1369-
MMod:free_native_registers(BSt4, [SizeValReg])
1370+
{BSt2, SizeValReg2} = if
1371+
is_integer(SizeValReg) ->
1372+
if
1373+
(SizeValReg * Unit) rem 8 =/= 0 ->
1374+
MMod:call_primitive_last(BSt1, ?PRIM_RAISE_ERROR, [
1375+
ctx, jit_state, offset, ?UNSUPPORTED_ATOM
1376+
]);
1377+
true ->
1378+
{BSt1, (SizeValReg * Unit) div 8}
1379+
end;
1380+
true ->
1381+
BBSt1 = MMod:mul(BSt1, SizeValReg, Unit),
1382+
BBSt2 = MMod:if_block(BBSt1, {SizeValReg, '&', 16#7, '!=', 0}, fun(BlockSt) ->
1383+
MMod:call_primitive_last(BlockSt, ?PRIM_RAISE_ERROR, [
1384+
ctx, jit_state, offset, ?UNSUPPORTED_ATOM
1385+
])
1386+
end),
1387+
MMod:shift_right(BBSt2, SizeValReg, 3)
1388+
end,
1389+
BSt3 = MMod:sub(BSt2, SizeReg, SizeValReg2),
1390+
BSt4 = cond_jump_to_label({SizeReg, '<', BSOffsetReg1}, Fail, MMod, BSt3),
1391+
BSt5 = MMod:move_to_native_register(BSt4, SizeValReg2, SizeReg),
1392+
MMod:free_native_registers(BSt5, [SizeValReg])
13701393
end
13711394
),
13721395
{MSt12, SizeReg}

tests/erlang_tests/test_bs.erl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ start() ->
9999

100100
ok = test_bs_skip_bits2_little(),
101101

102+
ok = test_bs_match_bitstring_modifier(),
103+
ok = test_bs_create_bitstring_modifier(),
104+
102105
0.
103106

104107
test_pack_small_ints({A, B, C}, Expect) ->
@@ -532,6 +535,37 @@ test_bs_match_string_select() ->
532535
test_bs_skip_bits2_little() ->
533536
ok = check_x86_64_jt(id(<<16#e9, 0:32>>)).
534537

538+
test_bs_match_bitstring_modifier() ->
539+
ok =
540+
try
541+
bitstring_match(id(<<123, 234, 245>>), id(15)),
542+
unexpected
543+
catch
544+
error:unsupported -> ok
545+
end,
546+
547+
{<<123, 234>>, <<245>>} = bitstring_match(id(<<123, 234, 245>>), id(16)),
548+
ok.
549+
550+
bitstring_match(BS, Size) ->
551+
<<Matched:Size/bitstring, Rest/bits>> = BS,
552+
{Matched, Rest}.
553+
554+
test_bs_create_bitstring_modifier() ->
555+
ok =
556+
try
557+
bitstring_join(id(<<123, 234>>), id(15), id(<<245, 256>>), id(8)),
558+
unexpected
559+
catch
560+
error:unsupported -> ok
561+
end,
562+
563+
<<123, 234, 245>> = bitstring_join(id(<<123, 234>>), id(16), id(<<245, 256>>), id(8)),
564+
ok.
565+
566+
bitstring_join(BS1, Size1, BS2, Size2) ->
567+
<<BS1:Size1/bitstring, BS2:Size2/bitstring>>.
568+
535569
check_x86_64_jt(<<>>) -> ok;
536570
check_x86_64_jt(<<16#e9, _Offset:32/little, Tail/binary>>) -> check_x86_64_jt(Tail);
537571
check_x86_64_jt(Bin) -> {unexpected, Bin}.

0 commit comments

Comments
 (0)