@@ -768,7 +768,6 @@ PHP_FUNCTION(bcscale)
768
768
769
769
static zend_class_entry * bc_num_ce ;
770
770
static zend_object_handlers bc_num_obj_handlers ;
771
- #define IS_BC_NUM (zval ) (Z_TYPE_P(zval) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zval), bc_num_ce))
772
771
773
772
static inline bc_num_obj * bc_num_obj_from_obj (zend_object * obj ) {
774
773
return (bc_num_obj * )((char * )(obj ) - XtOffsetOf (bc_num_obj , std ));
@@ -787,6 +786,7 @@ static zend_object *bc_num_create_obj(zend_class_entry *ce)
787
786
zend_object_std_init (& intern -> std , ce );
788
787
object_properties_init (& intern -> std , ce );
789
788
rebuild_object_properties (& intern -> std );
789
+ intern -> num = NULL ;
790
790
791
791
return & intern -> std ;
792
792
}
@@ -796,39 +796,39 @@ static zend_object *bc_num_create_obj(zend_class_entry *ce)
796
796
static void bc_num_free_obj (zend_object * object )
797
797
{
798
798
bc_num_obj * intern = bc_num_obj_from_obj (object );
799
- if (intern -> bc_num ) {
800
- bc_free_num (& intern -> bc_num );
799
+ if (intern -> num ) {
800
+ bc_free_num (& intern -> num );
801
801
}
802
- efree ( intern -> bc_num ) ;
802
+ intern -> num = NULL ;
803
803
zend_object_std_dtor (& intern -> std );
804
804
}
805
805
/* }}} */
806
806
807
807
/* {{{ bc_num_obj_handlers.clone_obj */
808
808
static zend_object * bc_num_clone_obj (zend_object * object )
809
809
{
810
- bc_num_obj * old_obj = bc_num_obj_from_obj (object );
811
- bc_num_obj * new_obj = bc_num_obj_from_obj (bc_num_create_obj (old_obj -> std .ce ));
810
+ bc_num_obj * original = bc_num_obj_from_obj (object );
811
+ bc_num_obj * clone = bc_num_obj_from_obj (bc_num_create_obj (original -> std .ce ));
812
812
813
- zend_objects_clone_members (& new_obj -> std , & old_obj -> std );
814
- new_obj -> bc_num = bc_copy_num (old_obj -> bc_num );
813
+ zend_objects_clone_members (& clone -> std , & original -> std );
814
+ clone -> num = bc_copy_num (original -> num );
815
815
816
- return & new_obj -> std ;
816
+ return & clone -> std ;
817
817
}
818
818
/* }}} */
819
819
820
- static zend_result convert_zval_to_bc_num (zval * zv , bc_num * num , bool * should_free )
820
+ static zend_result convert_zval_to_bc_num (zval * zv , bc_num * num )
821
821
{
822
- * should_free = false ;
822
+ bc_num tmp ;
823
823
824
824
switch (Z_TYPE_P (zv )) {
825
825
case IS_LONG :
826
826
case IS_STRING :
827
827
{
828
828
zend_string * str = zval_get_string (zv );
829
- bc_init_num (num );
830
- * should_free = true;
831
- if (! bc_str2num ( num , ZSTR_VAL ( str ), 0 )) {
829
+ bc_init_num (& tmp );
830
+ if (! bc_str2num ( & tmp , ZSTR_VAL ( str ), 0 )) {
831
+ bc_free_num ( & tmp );
832
832
zend_string_release (str );
833
833
return FAILURE ;
834
834
}
@@ -837,48 +837,46 @@ static zend_result convert_zval_to_bc_num(zval *zv, bc_num *num, bool *should_fr
837
837
break ;
838
838
case IS_OBJECT :
839
839
if (instanceof_function (Z_OBJCE_P (zv ), bc_num_ce )) {
840
- * num = bc_num_obj_from_zval (zv )-> bc_num ;
840
+ tmp = bc_num_obj_from_zval (zv )-> num ;
841
841
} else {
842
842
zend_argument_type_error (0 , "must be of type int, string, or BcNum, %s given" , zend_zval_value_name (zv ));
843
843
return FAILURE ;
844
844
}
845
845
break ;
846
846
}
847
847
848
+ * num = tmp ;
848
849
return SUCCESS ;
849
850
}
850
851
851
852
static zend_result bc_num_calculation (zval * result , zval * op1 , zval * op2 , bc_num_calculation_type type , bool is_operator )
852
853
{
853
- bc_num num1 , num2 ;
854
+ bc_num num1 = NULL , num2 = NULL , result_num = NULL ;
854
855
bc_num_obj * result_obj ;
855
- bool should_free1 , should_free2 , should_free_result = false;
856
856
857
- if (convert_zval_to_bc_num (op1 , & num1 , & should_free1 ) == FAILURE || convert_zval_to_bc_num (op2 , & num2 , & should_free2 ) == FAILURE ) {
857
+ if (convert_zval_to_bc_num (op1 , & num1 ) == FAILURE || convert_zval_to_bc_num (op2 , & num2 ) == FAILURE ) {
858
858
goto cleanup ;
859
859
}
860
860
861
- result_obj = bc_num_obj_from_obj (bc_num_create_obj (bc_num_ce ));
862
- bc_init_num (& result_obj -> bc_num );
863
- should_free_result = true;
861
+ bc_init_num (& result_num );
864
862
865
863
size_t scale = MAX (num1 -> n_scale , num2 -> n_scale );
866
864
867
865
switch (type ) {
868
866
case BC_NUM_ADD :
869
- bc_add (num1 , num2 , & result_obj -> bc_num , scale );
867
+ bc_add (num1 , num2 , & result_num , scale );
870
868
break ;
871
869
case BC_NUM_SUB :
872
- bc_sub (num1 , num2 , & result_obj -> bc_num , scale );
870
+ bc_sub (num1 , num2 , & result_num , scale );
873
871
break ;
874
872
case BC_NUM_MUL :
875
- bc_multiply (num1 , num2 , & result_obj -> bc_num , scale );
873
+ bc_multiply (num1 , num2 , & result_num , scale );
876
874
break ;
877
875
case BC_NUM_DIV :
878
- bc_divide (num1 , num2 , & result_obj -> bc_num , scale );
876
+ bc_divide (num1 , num2 , & result_num , scale );
879
877
break ;
880
878
case BC_NUM_MOD :
881
- bc_modulo (num1 , num2 , & result_obj -> bc_num , scale );
879
+ bc_modulo (num1 , num2 , & result_num , scale );
882
880
break ;
883
881
case BC_NUM_POW :
884
882
{
@@ -887,32 +885,34 @@ static zend_result bc_num_calculation(zval *result, zval *op1, zval *op2, bc_num
887
885
zend_argument_value_error (is_operator ? 0 : 1 , "exponent is too large" );
888
886
goto cleanup ;
889
887
}
890
- bc_raise (num1 , bc_num2long (num2 ), & result_obj -> bc_num , scale );
888
+ bc_raise (num1 , bc_num2long (num2 ), & result_num , scale );
891
889
}
892
890
break ;
893
891
EMPTY_SWITCH_DEFAULT_CASE ()
894
892
}
895
893
896
- if (should_free1 ) {
894
+ if (num1 && Z_TYPE_P ( op1 ) != IS_OBJECT ) {
897
895
bc_free_num (& num1 );
898
896
}
899
- if (should_free2 ) {
897
+ if (num2 && Z_TYPE_P ( op2 ) != IS_OBJECT ) {
900
898
bc_free_num (& num2 );
901
899
}
902
900
903
- result_obj -> bc_num -> n_scale = scale ;
901
+ result_num -> n_scale = scale ;
902
+ result_obj = bc_num_obj_from_obj (bc_num_create_obj (bc_num_ce ));
903
+ result_obj -> num = result_num ;
904
904
ZVAL_OBJ (result , & result_obj -> std );
905
905
return SUCCESS ;
906
906
907
907
cleanup :
908
- if (should_free1 ) {
908
+ if (num1 && Z_TYPE_P ( op1 ) != IS_OBJECT ) {
909
909
bc_free_num (& num1 );
910
910
}
911
- if (should_free2 ) {
911
+ if (num2 && Z_TYPE_P ( op2 ) != IS_OBJECT ) {
912
912
bc_free_num (& num2 );
913
913
}
914
- if (should_free_result ) {
915
- bc_free_num (& result_obj -> bc_num );
914
+ if (result_num ) {
915
+ bc_free_num (& result_num );
916
916
}
917
917
return FAILURE ;
918
918
}
@@ -952,23 +952,20 @@ static int bc_num_do_operation(uint8_t opcode, zval *result, zval *op1, zval *op
952
952
/* {{{ bc_num_obj_handlers.compare */
953
953
static int bc_num_compare (zval * z1 , zval * z2 )
954
954
{
955
- bc_num_obj * obj1 ;
956
- bc_num_obj * obj2 ;
957
-
958
955
ZEND_COMPARE_OBJECTS_FALLBACK (z1 , z2 );
959
956
960
- obj1 = bc_num_obj_from_zval (z1 );
961
- obj2 = bc_num_obj_from_zval (z2 );
957
+ bc_num_obj * intern1 = bc_num_obj_from_zval (z1 );
958
+ bc_num_obj * intern2 = bc_num_obj_from_zval (z2 );
962
959
963
- return bc_compare (obj1 -> bc_num , obj2 -> bc_num );
960
+ return bc_compare (intern1 -> num , intern2 -> num );
964
961
}
965
962
/* }}} */
966
963
967
964
/* {{{ bc_num_obj_handlers.get_properties_for */
968
965
static HashTable * bc_num_get_properties_for (zend_object * object , zend_prop_purpose purpose )
969
966
{
970
967
HashTable * props ;
971
- bc_num_obj * bc_num_obj ;
968
+ bc_num_obj * intern ;
972
969
973
970
switch (purpose ) {
974
971
case ZEND_PROP_PURPOSE_DEBUG :
@@ -982,12 +979,12 @@ static HashTable *bc_num_get_properties_for(zend_object *object, zend_prop_purpo
982
979
}
983
980
984
981
zval zv ;
985
- bc_num_obj = bc_num_obj_from_obj (object );
982
+ intern = bc_num_obj_from_obj (object );
986
983
props = zend_array_dup (zend_std_get_properties (object ));
987
984
988
- ZVAL_STR (& zv , bc_num2str (bc_num_obj -> bc_num ));
985
+ ZVAL_STR (& zv , bc_num2str (intern -> num ));
989
986
zend_hash_str_update (props , "num" , sizeof ("num" )- 1 , & zv );
990
- ZVAL_LONG (& zv , bc_num_obj -> bc_num -> n_scale );
987
+ ZVAL_LONG (& zv , intern -> num -> n_scale );
991
988
zend_hash_str_update (props , "scale" , sizeof ("scale" )- 1 , & zv );
992
989
993
990
return props ;
@@ -1022,17 +1019,22 @@ static void bc_num_register_class(void)
1022
1019
/* {{{ Creates new BcNum */
1023
1020
PHP_METHOD (BcNum , __construct )
1024
1021
{
1025
- zend_string * num_str ;
1022
+ zend_string * num_str , * num_str_tmp ;
1023
+ zend_long num_l ;
1026
1024
zend_long scale_param ;
1027
1025
bool scale_param_is_null = 1 ;
1028
1026
int scale ;
1029
1027
1030
1028
ZEND_PARSE_PARAMETERS_START (1 , 2 )
1031
- Z_PARAM_STR (num_str )
1029
+ Z_PARAM_STR_OR_LONG (num_str , num_l )
1032
1030
Z_PARAM_OPTIONAL
1033
1031
Z_PARAM_LONG_OR_NULL (scale_param , scale_param_is_null )
1034
1032
ZEND_PARSE_PARAMETERS_END ();
1035
1033
1034
+ if (!num_str ) {
1035
+ num_str_tmp = zend_long_to_str (num_l );
1036
+ }
1037
+
1036
1038
if (scale_param_is_null ) {
1037
1039
scale = BCG (bc_precision );
1038
1040
} else if (scale_param < 0 || scale_param > INT_MAX ) {
@@ -1042,22 +1044,32 @@ PHP_METHOD(BcNum, __construct)
1042
1044
scale = (int ) scale_param ;
1043
1045
}
1044
1046
1045
- bc_num_obj * obj = bc_num_obj_from_zval (ZEND_THIS );
1046
- bc_init_num (& obj -> bc_num );
1047
+ bc_num_obj * intern = bc_num_obj_from_zval (ZEND_THIS );
1047
1048
1048
- if (php_str2num (& obj -> bc_num , ZSTR_VAL (num_str )) == FAILURE ) {
1049
+ bc_num num ;
1050
+ bc_init_num (& num );
1051
+
1052
+ if (php_str2num (& num , ZSTR_VAL (num_str ?: num_str_tmp )) == FAILURE ) {
1049
1053
zend_argument_value_error (1 , "is not well-formed" );
1050
- bc_free_num (& obj -> bc_num );
1054
+ bc_free_num (& num );
1055
+ if (num_str_tmp ) {
1056
+ zend_string_release (num_str_tmp );
1057
+ }
1051
1058
RETURN_THROWS ();
1052
1059
}
1053
1060
1054
- if (obj -> bc_num -> n_scale < scale ) {
1055
- char * nptr = (char * ) (obj -> bc_num -> n_value + obj -> bc_num -> n_len + obj -> bc_num -> n_scale );
1056
- for (int count = scale - obj -> bc_num -> n_scale ; count > 0 ; count -- ) {
1061
+ if (num_str_tmp ) {
1062
+ zend_string_release (num_str_tmp );
1063
+ }
1064
+
1065
+ if (num -> n_scale < scale ) {
1066
+ char * nptr = (char * ) (num -> n_value + num -> n_len + num -> n_scale );
1067
+ for (int count = scale - num -> n_scale ; count > 0 ; count -- ) {
1057
1068
* nptr ++ = 0 ;
1058
1069
}
1059
1070
}
1060
- obj -> bc_num -> n_scale = scale ;
1071
+ num -> n_scale = scale ;
1072
+ intern -> num = num ;
1061
1073
}
1062
1074
/* }}} */
1063
1075
0 commit comments