@@ -2563,6 +2563,42 @@ first_pass_bs_create_bin_compute_size(
25632563) ->
25642564 MSt1 = verify_is_integer (Src , Fail , MMod , MSt0 ),
25652565 {MSt1 , AccLiteralSize0 + 32 , AccSizeReg0 , State0 };
2566+ first_pass_bs_create_bin_compute_size (
2567+ float , Src , Size , _SegmentUnit , Fail , AccLiteralSize0 , AccSizeReg0 , MMod , MSt0 , State0
2568+ ) ->
2569+ MSt1 = verify_is_number (Src , Fail , MMod , MSt0 ),
2570+ % Verify and get the float size (defaults to 64 if nil)
2571+ case Size of
2572+ ? TERM_NIL ->
2573+ {MSt1 , AccLiteralSize0 + 64 , AccSizeReg0 , State0 };
2574+ _ ->
2575+ {MSt2 , SizeValue } = term_to_int (Size , Fail , MMod , MSt1 ),
2576+ if
2577+ is_integer (SizeValue ) ->
2578+ % If size is a literal, compiler would only allow 16/32/64.
2579+ {MSt2 , AccLiteralSize0 + SizeValue , AccSizeReg0 , State0 };
2580+ is_atom (SizeValue ) ->
2581+ % Check if size is 16, 32, or 64 using 'and' of '!=' checks
2582+ MSt3 = cond_raise_badarg_or_jump_to_fail_label (
2583+ {'and' , [
2584+ {SizeValue , '!=' , 16 },
2585+ {SizeValue , '!=' , 32 },
2586+ {SizeValue , '!=' , 64 }
2587+ ]},
2588+ Fail ,
2589+ MMod ,
2590+ MSt2
2591+ ),
2592+ case AccSizeReg0 of
2593+ undefined ->
2594+ {MSt3 , AccLiteralSize0 , SizeValue , State0 };
2595+ _ ->
2596+ MSt4 = MMod :add (MSt3 , AccSizeReg0 , SizeValue ),
2597+ MSt5 = MMod :free_native_registers (MSt4 , [SizeValue ]),
2598+ {MSt5 , AccLiteralSize0 , AccSizeReg0 , State0 }
2599+ end
2600+ end
2601+ end ;
25662602first_pass_bs_create_bin_compute_size (
25672603 integer , Src , Size , SegmentUnit , Fail , AccLiteralSize0 , AccSizeReg0 , MMod , MSt0 , State0
25682604) ->
@@ -2718,6 +2754,31 @@ first_pass_bs_create_bin_insert_value(
27182754 MMod , MSt6 , Offset , SizeValue , 1
27192755 ),
27202756 {MSt7 , NewOffset , CreatedBin };
2757+ first_pass_bs_create_bin_insert_value (
2758+ float , Flags , Src , Size , _SegmentUnit , Fail , CreatedBin , Offset , MMod , MSt0
2759+ ) ->
2760+ % Src is a term (boxed float or integer)
2761+ {MSt1 , SrcReg } = MMod :move_to_native_register (MSt0 , Src ),
2762+ {MSt2 , FlagsValue } = decode_flags_list (Flags , MMod , MSt1 ),
2763+ % Get the float size (defaults to 64 if nil)
2764+ {MSt3 , SizeValue } =
2765+ case Size of
2766+ ? TERM_NIL ->
2767+ {MSt2 , 64 };
2768+ _ ->
2769+ term_to_int (Size , Fail , MMod , MSt2 )
2770+ end ,
2771+ % Call single primitive with size parameter
2772+ {MSt4 , BoolResult } = MMod :call_primitive (MSt3 , ? PRIM_BITSTRING_INSERT_FLOAT , [
2773+ CreatedBin , Offset , {free , SrcReg }, SizeValue , {free , FlagsValue }
2774+ ]),
2775+ MSt5 = cond_raise_badarg_or_jump_to_fail_label (
2776+ {'(bool)' , {free , BoolResult }, '==' , false }, Fail , MMod , MSt4
2777+ ),
2778+ {MSt6 , NewOffset } = first_pass_bs_create_bin_insert_value_increment_offset (
2779+ MMod , MSt5 , Offset , SizeValue , 1
2780+ ),
2781+ {MSt6 , NewOffset , CreatedBin };
27212782first_pass_bs_create_bin_insert_value (
27222783 string , _Flags , Src , Size , SegmentUnit , Fail , CreatedBin , Offset , MMod , MSt0
27232784) ->
@@ -3313,6 +3374,13 @@ verify_is_any_integer(Arg1, Fail, MMod, MSt0) ->
33133374 MSt0
33143375 ).
33153376
3377+ verify_is_number (Arg1 , Fail , MMod , MSt0 ) ->
3378+ {MSt1 , Reg } = MMod :copy_to_native_register (MSt0 , Arg1 ),
3379+ {MSt2 , IsNumber } = MMod :call_primitive (MSt1 , ? PRIM_TERM_IS_NUMBER , [{free , Reg }]),
3380+ cond_raise_badarg_or_jump_to_fail_label (
3381+ {'(bool)' , {free , IsNumber }, '==' , false }, Fail , MMod , MSt2
3382+ ).
3383+
33163384% %-----------------------------------------------------------------------------
33173385% % @doc Test if Arg1 is a binary, jump to FailLabel if it isn't or raise
33183386% % badarg if FailLabel is 0
0 commit comments