-
Notifications
You must be signed in to change notification settings - Fork 149
Support matching bitstrings that are in fact binaries (size divisible by 8) #1978
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
886acf3
9a1b28e
72ba6a4
a8dffe3
6645014
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1333,10 +1333,6 @@ first_pass(<<?OP_BS_GET_BINARY2, Rest0/binary>>, MMod, MSt0, State0) -> | |
| {MSt5, BSOffsetReg0} = MMod:get_array_element(MSt4, MatchStateRegPtr, 2), | ||
| MSt6 = | ||
| if | ||
| Unit =/= 8 -> | ||
| MMod:call_primitive_last(MSt5, ?PRIM_RAISE_ERROR, [ | ||
| ctx, jit_state, offset, ?UNSUPPORTED_ATOM | ||
| ]); | ||
| FlagsValue =/= 0 -> | ||
| MMod:call_primitive_last(MSt5, ?PRIM_RAISE_ERROR, [ | ||
| ctx, jit_state, offset, ?UNSUPPORTED_ATOM | ||
|
|
@@ -1356,13 +1352,22 @@ first_pass(<<?OP_BS_GET_BINARY2, Rest0/binary>>, MMod, MSt0, State0) -> | |
| MSt11 = MMod:sub(MSt10, SizeReg, BSOffsetReg1), | ||
| {MSt11, SizeReg}; | ||
| is_integer(Size) -> | ||
| % SizeReg is binary size | ||
| % SizeReg contains binary size in bytes as a term | ||
| % Size is a tagged integer: (N bsl 4) bor 0xF | ||
| % SizeBytes is the raw byte count | ||
| SizeBytes = Size bsr 4, | ||
| MSt11 = MMod:sub(MSt10, SizeReg, SizeBytes), | ||
| MSt11 = | ||
| if | ||
| (Size * Unit) rem 8 =/= 0 -> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Size is a tagged integer so you don't want to multiply it by Unit. Since Unit may not be 8, you want to rename SizeBytes into SizeInUnits. |
||
| MMod:call_primitive_last(MSt10, ?PRIM_RAISE_ERROR, [ | ||
| ctx, jit_state, offset, ?UNSUPPORTED_ATOM | ||
| ]); | ||
| true -> | ||
| % Equivalent of SizeReg - (((SizeBytes * Unit) div 8) bsl 4) | ||
| MMod:sub(MSt10, SizeReg, (SizeBytes * Unit) bsl 1) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since SizeReg is the size in bytes I'm not sure this is correct |
||
| end, | ||
| MSt12 = cond_jump_to_label({{free, SizeReg}, '<', BSOffsetReg1}, Fail, MMod, MSt11), | ||
| {MSt12, SizeBytes}; | ||
| {MSt12, (SizeBytes * Unit) div 8}; | ||
| true -> | ||
| {MSt11, SizeValReg} = MMod:move_to_native_register(MSt10, Size), | ||
| MSt12 = MMod:if_else_block( | ||
|
|
@@ -1374,10 +1379,32 @@ first_pass(<<?OP_BS_GET_BINARY2, Rest0/binary>>, MMod, MSt0, State0) -> | |
| end, | ||
| fun(BSt0) -> | ||
| {BSt1, SizeValReg} = term_to_int(SizeValReg, 0, MMod, BSt0), | ||
| BSt2 = MMod:sub(BSt1, SizeReg, SizeValReg), | ||
| BSt3 = cond_jump_to_label({SizeReg, '<', BSOffsetReg1}, Fail, MMod, BSt2), | ||
| BSt4 = MMod:move_to_native_register(BSt3, SizeValReg, SizeReg), | ||
| MMod:free_native_registers(BSt4, [SizeValReg]) | ||
| {BSt2, SizeValReg2} = | ||
| if | ||
| is_integer(SizeValReg) -> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this cannot happen. |
||
| if | ||
| (SizeValReg * Unit) rem 8 =/= 0 -> | ||
| MMod:call_primitive_last(BSt1, ?PRIM_RAISE_ERROR, [ | ||
| ctx, jit_state, offset, ?UNSUPPORTED_ATOM | ||
| ]); | ||
| true -> | ||
| {BSt1, (SizeValReg * Unit) div 8} | ||
| end; | ||
| true -> | ||
| BBSt1 = MMod:mul(BSt1, SizeValReg, Unit), | ||
| BBSt2 = MMod:if_block( | ||
| BBSt1, {SizeValReg, '&', 16#7, '!=', 0}, fun(BlockSt) -> | ||
| MMod:call_primitive_last(BlockSt, ?PRIM_RAISE_ERROR, [ | ||
| ctx, jit_state, offset, ?UNSUPPORTED_ATOM | ||
| ]) | ||
| end | ||
| ), | ||
| MMod:shift_right(BBSt2, SizeValReg, 3) | ||
| end, | ||
| BSt3 = MMod:sub(BSt2, SizeReg, SizeValReg2), | ||
| BSt4 = cond_jump_to_label({SizeReg, '<', BSOffsetReg1}, Fail, MMod, BSt3), | ||
| BSt5 = MMod:move_to_native_register(BSt4, SizeValReg2, SizeReg), | ||
| MMod:free_native_registers(BSt5, [SizeValReg]) | ||
| end | ||
| ), | ||
| {MSt12, SizeReg} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is true.
SizeReg is just the size in bytes AFAIK, not a term. We got it from get_array_element(...,1): it's the second word of the boxed binary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I accidentally pushed a half baked thing. But I got suggested by
#1978 (comment)