37
37
#include "Zend/Optimizer/zend_optimizer.h"
38
38
#include "Zend/zend_alloc.h"
39
39
#include "test_arginfo.h"
40
+ #include "tmp_methods_arginfo.h"
40
41
#include "zend_call_stack.h"
41
42
#include "zend_exceptions.h"
42
43
#include "zend_mm_custom_handlers.h"
43
44
#include "ext/uri/php_uri.h"
45
+ #include "zend_observer.h"
44
46
45
47
#if defined(HAVE_LIBXML ) && !defined(PHP_WIN32 )
46
48
# include <libxml/globals.h>
@@ -1023,16 +1025,38 @@ static ZEND_FUNCTION(zend_test_log_err_debug)
1023
1025
php_log_err_with_severity (ZSTR_VAL (str ), LOG_DEBUG );
1024
1026
}
1025
1027
1028
+ typedef struct _zend_test_object {
1029
+ zend_internal_function * tmp_method ;
1030
+ zend_object std ;
1031
+ } zend_test_object ;
1032
+
1026
1033
static zend_object * zend_test_class_new (zend_class_entry * class_type )
1027
1034
{
1028
- zend_object * obj = zend_objects_new (class_type );
1029
- object_properties_init (obj , class_type );
1030
- obj -> handlers = & zend_test_class_handlers ;
1031
- return obj ;
1035
+ zend_test_object * intern = zend_object_alloc (sizeof (zend_test_object ), class_type );
1036
+ zend_object_std_init (& intern -> std , class_type );
1037
+ object_properties_init (& intern -> std , class_type );
1038
+ return & intern -> std ;
1039
+ }
1040
+
1041
+ static void zend_test_class_free_obj (zend_object * object )
1042
+ {
1043
+ zend_test_object * intern = (zend_test_object * )((char * )object - XtOffsetOf (zend_test_object , std ));
1044
+
1045
+ if (intern -> tmp_method ) {
1046
+ zend_internal_function * func = intern -> tmp_method ;
1047
+ intern -> tmp_method = NULL ;
1048
+ zend_string_release_ex (func -> function_name , 0 );
1049
+ zend_free_internal_arg_info (func , false);
1050
+ efree (func );
1051
+ }
1052
+
1053
+ zend_object_std_dtor (object );
1032
1054
}
1033
1055
1034
1056
static zend_function * zend_test_class_method_get (zend_object * * object , zend_string * name , const zval * key )
1035
1057
{
1058
+ zend_test_object * intern = (zend_test_object * )((char * )(* object ) - XtOffsetOf (zend_test_object , std ));
1059
+
1036
1060
if (zend_string_equals_literal_ci (name , "test" )) {
1037
1061
zend_internal_function * fptr ;
1038
1062
@@ -1050,6 +1074,41 @@ static zend_function *zend_test_class_method_get(zend_object **object, zend_stri
1050
1074
fptr -> handler = ZEND_FN (zend_test_func );
1051
1075
fptr -> doc_comment = NULL ;
1052
1076
1077
+ return (zend_function * )fptr ;
1078
+ } else if (zend_string_equals_literal_ci (name , "testTmpMethodWithArgInfo" )) {
1079
+ if (intern -> tmp_method ) {
1080
+ return (zend_function * )intern -> tmp_method ;
1081
+ }
1082
+
1083
+ const zend_function_entry * entry = & class_ZendTestTmpMethods_methods [0 ];
1084
+ zend_internal_function * fptr = emalloc (sizeof (zend_internal_function ));
1085
+ memset (fptr , 0 , sizeof (zend_internal_function ));
1086
+ fptr -> type = ZEND_INTERNAL_FUNCTION ;
1087
+ fptr -> handler = entry -> handler ;
1088
+ fptr -> function_name = zend_string_init (entry -> fname , strlen (entry -> fname ), false);
1089
+ fptr -> scope = intern -> std .ce ;
1090
+ fptr -> prototype = NULL ;
1091
+ fptr -> T = ZEND_OBSERVER_ENABLED ;
1092
+ fptr -> fn_flags = ZEND_ACC_PUBLIC | ZEND_ACC_NEVER_CACHE ;
1093
+
1094
+ zend_internal_function_info * info = (zend_internal_function_info * )entry -> arg_info ;
1095
+
1096
+ uint32_t num_arg_info = 1 + entry -> num_args ;
1097
+ zend_arg_info * arg_info = safe_emalloc (num_arg_info , sizeof (zend_arg_info ), 0 );
1098
+ for (uint32_t i = 0 ; i < num_arg_info ; i ++ ) {
1099
+ zend_convert_internal_arg_info (& arg_info [i ], & entry -> arg_info [i ], i == 0 , false);
1100
+ }
1101
+
1102
+ fptr -> arg_info = arg_info + 1 ;
1103
+ fptr -> num_args = entry -> num_args ;
1104
+ if (info -> required_num_args == (uint32_t )-1 ) {
1105
+ fptr -> required_num_args = entry -> num_args ;
1106
+ } else {
1107
+ fptr -> required_num_args = info -> required_num_args ;
1108
+ }
1109
+
1110
+ intern -> tmp_method = fptr ;
1111
+
1053
1112
return (zend_function * )fptr ;
1054
1113
}
1055
1114
return zend_std_get_method (object , name , key );
@@ -1136,6 +1195,18 @@ static ZEND_METHOD(_ZendTestClass, variadicTest) {
1136
1195
object_init_ex (return_value , zend_get_called_scope (execute_data ));
1137
1196
}
1138
1197
1198
+ ZEND_METHOD (ZendTestTmpMethods , testTmpMethodWithArgInfo )
1199
+ {
1200
+ zend_object * obj ;
1201
+ zend_string * str ;
1202
+
1203
+ ZEND_PARSE_PARAMETERS_START (0 , 2 );
1204
+ Z_PARAM_OPTIONAL ;
1205
+ Z_PARAM_OBJ_OR_NULL (obj );
1206
+ Z_PARAM_STR (str );
1207
+ ZEND_PARSE_PARAMETERS_END ();
1208
+ }
1209
+
1139
1210
static ZEND_METHOD (_ZendTestChildClass , returnsThrowable )
1140
1211
{
1141
1212
ZEND_PARSE_PARAMETERS_NONE ();
@@ -1441,11 +1512,14 @@ PHP_MINIT_FUNCTION(zend_test)
1441
1512
register_ZendTestClass_dnf_property (zend_test_class );
1442
1513
zend_test_class -> create_object = zend_test_class_new ;
1443
1514
zend_test_class -> get_static_method = zend_test_class_static_method_get ;
1515
+ zend_test_class -> default_object_handlers = & zend_test_class_handlers ;
1444
1516
1445
1517
zend_test_child_class = register_class__ZendTestChildClass (zend_test_class );
1446
1518
1447
1519
memcpy (& zend_test_class_handlers , & std_object_handlers , sizeof (zend_object_handlers ));
1448
1520
zend_test_class_handlers .get_method = zend_test_class_method_get ;
1521
+ zend_test_class_handlers .free_obj = zend_test_class_free_obj ;
1522
+ zend_test_class_handlers .offset = XtOffsetOf (zend_test_object , std );
1449
1523
1450
1524
zend_test_gen_stub_flag_compatibility_test = register_class_ZendTestGenStubFlagCompatibilityTest ();
1451
1525
0 commit comments