@@ -2594,6 +2594,42 @@ first_pass_bs_create_bin_compute_size(
25942594) ->
25952595 MSt1 = verify_is_integer (Src , Fail , MMod , MSt0 ),
25962596 {MSt1 , AccLiteralSize0 + 32 , AccSizeReg0 , State0 };
2597+ first_pass_bs_create_bin_compute_size (
2598+ float , Src , Size , _SegmentUnit , Fail , AccLiteralSize0 , AccSizeReg0 , MMod , MSt0 , State0
2599+ ) ->
2600+ MSt1 = verify_is_number (Src , Fail , MMod , MSt0 ),
2601+ % Verify and get the float size (defaults to 64 if nil)
2602+ case Size of
2603+ ? TERM_NIL ->
2604+ {MSt1 , AccLiteralSize0 + 64 , AccSizeReg0 , State0 };
2605+ _ ->
2606+ {MSt2 , SizeValue } = term_to_int (Size , Fail , MMod , MSt1 ),
2607+ if
2608+ is_integer (SizeValue ) ->
2609+ % If size is a literal, compiler would only allow 16/32/64.
2610+ {MSt2 , AccLiteralSize0 + SizeValue , AccSizeReg0 , State0 };
2611+ is_atom (SizeValue ) ->
2612+ % Check if size is 16, 32, or 64 using 'and' of '!=' checks
2613+ MSt3 = cond_raise_badarg_or_jump_to_fail_label (
2614+ {'and' , [
2615+ {SizeValue , '!=' , 16 },
2616+ {SizeValue , '!=' , 32 },
2617+ {SizeValue , '!=' , 64 }
2618+ ]},
2619+ Fail ,
2620+ MMod ,
2621+ MSt2
2622+ ),
2623+ case AccSizeReg0 of
2624+ undefined ->
2625+ {MSt3 , AccLiteralSize0 , SizeValue , State0 };
2626+ _ ->
2627+ MSt4 = MMod :add (MSt3 , AccSizeReg0 , SizeValue ),
2628+ MSt5 = MMod :free_native_registers (MSt4 , [SizeValue ]),
2629+ {MSt5 , AccLiteralSize0 , AccSizeReg0 , State0 }
2630+ end
2631+ end
2632+ end ;
25972633first_pass_bs_create_bin_compute_size (
25982634 integer , Src , Size , SegmentUnit , Fail , AccLiteralSize0 , AccSizeReg0 , MMod , MSt0 , State0
25992635) ->
@@ -2749,6 +2785,31 @@ first_pass_bs_create_bin_insert_value(
27492785 MMod , MSt6 , Offset , SizeValue , 1
27502786 ),
27512787 {MSt7 , NewOffset , CreatedBin };
2788+ first_pass_bs_create_bin_insert_value (
2789+ float , Flags , Src , Size , _SegmentUnit , Fail , CreatedBin , Offset , MMod , MSt0
2790+ ) ->
2791+ % Src is a term (boxed float or integer)
2792+ {MSt1 , SrcReg } = MMod :move_to_native_register (MSt0 , Src ),
2793+ {MSt2 , FlagsValue } = decode_flags_list (Flags , MMod , MSt1 ),
2794+ % Get the float size (defaults to 64 if nil)
2795+ {MSt3 , SizeValue } =
2796+ case Size of
2797+ ? TERM_NIL ->
2798+ {MSt2 , 64 };
2799+ _ ->
2800+ term_to_int (Size , Fail , MMod , MSt2 )
2801+ end ,
2802+ % Call single primitive with size parameter
2803+ {MSt4 , BoolResult } = MMod :call_primitive (MSt3 , ? PRIM_BITSTRING_INSERT_FLOAT , [
2804+ CreatedBin , Offset , {free , SrcReg }, SizeValue , {free , FlagsValue }
2805+ ]),
2806+ MSt5 = cond_raise_badarg_or_jump_to_fail_label (
2807+ {'(bool)' , {free , BoolResult }, '==' , false }, Fail , MMod , MSt4
2808+ ),
2809+ {MSt6 , NewOffset } = first_pass_bs_create_bin_insert_value_increment_offset (
2810+ MMod , MSt5 , Offset , SizeValue , 1
2811+ ),
2812+ {MSt6 , NewOffset , CreatedBin };
27522813first_pass_bs_create_bin_insert_value (
27532814 string , _Flags , Src , Size , SegmentUnit , Fail , CreatedBin , Offset , MMod , MSt0
27542815) ->
@@ -3326,6 +3387,13 @@ verify_is_any_integer(Arg1, Fail, MMod, MSt0) ->
33263387 Arg1 , ? TERM_INTEGER_TAG , ? TERM_BOXED_POSITIVE_INTEGER , Fail , MMod , MSt0
33273388 ).
33283389
3390+ verify_is_number (Arg1 , Fail , MMod , MSt0 ) ->
3391+ {MSt1 , Reg } = MMod :copy_to_native_register (MSt0 , Arg1 ),
3392+ {MSt2 , IsNumber } = MMod :call_primitive (MSt1 , ? PRIM_TERM_IS_NUMBER , [{free , Reg }]),
3393+ cond_raise_badarg_or_jump_to_fail_label (
3394+ {'(bool)' , {free , IsNumber }, '==' , false }, Fail , MMod , MSt2
3395+ ).
3396+
33293397% %-----------------------------------------------------------------------------
33303398% % @doc Test if Arg1 is a binary, jump to FailLabel if it isn't or raise
33313399% % badarg if FailLabel is 0
0 commit comments