]> granicus.if.org Git - php/commitdiff
Export API for fetching internal func default
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 9 Apr 2020 12:55:55 +0000 (14:55 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 9 Apr 2020 12:55:55 +0000 (14:55 +0200)
Make this functionality available outside reflection.

Zend/zend_API.c
Zend/zend_API.h
ext/reflection/php_reflection.c

index 47730ff3ed9cbf40e7ff2675e49d6cbe3fd71dc7..4db760482ae1f7d1d1e01ff5d413e5ecec835451 100644 (file)
@@ -30,6 +30,7 @@
 #include "zend_closures.h"
 #include "zend_inheritance.h"
 #include "zend_ini.h"
+#include "zend_smart_str.h"
 
 #include <stdarg.h>
 
@@ -4309,3 +4310,101 @@ ZEND_API zend_bool zend_is_countable(zval *countable) /* {{{ */
        }
 }
 /* }}} */
+
+static int get_default_via_ast(zval *default_value_zval, const char *default_value) {
+       zend_ast *ast;
+       zend_arena *ast_arena;
+
+       smart_str code = {0};
+       smart_str_appends(&code, "<?php ");
+       smart_str_appends(&code, default_value);
+       smart_str_appendc(&code, ';');
+       smart_str_0(&code);
+
+       ast = zend_compile_string_to_ast(code.s, &ast_arena, "");
+       smart_str_free(&code);
+
+       if (!ast) {
+               return FAILURE;
+       }
+
+       zend_ast_list *statement_list = zend_ast_get_list(ast);
+       zend_ast *const_expression_ast = statement_list->child[0];
+
+       zend_arena *original_ast_arena = CG(ast_arena);
+       uint32_t original_compiler_options = CG(compiler_options);
+       zend_file_context original_file_context;
+       CG(ast_arena) = ast_arena;
+       /* Disable constant substitution, to make getDefaultValueConstant() work. */
+       CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
+       zend_file_context_begin(&original_file_context);
+       zend_const_expr_to_zval(default_value_zval, const_expression_ast);
+       CG(ast_arena) = original_ast_arena;
+       CG(compiler_options) = original_compiler_options;
+       zend_file_context_end(&original_file_context);
+
+       zend_ast_destroy(ast);
+       zend_arena_destroy(ast_arena);
+
+       return SUCCESS;
+}
+
+static zend_string *try_parse_string(const char *str, size_t len, char quote) {
+       if (len == 0) {
+               return ZSTR_EMPTY_ALLOC();
+       }
+
+       for (size_t i = 0; i < len; i++) {
+               if (str[i] == '\\' || str[i] == quote) {
+                       return NULL;
+               }
+       }
+       return zend_string_init(str, len, 0);
+}
+
+ZEND_API int zend_get_default_from_internal_arg_info(
+               zval *default_value_zval, zend_internal_arg_info *arg_info)
+{
+       const char *default_value = arg_info->default_value;
+       if (!default_value) {
+               return FAILURE;
+       }
+
+       /* Avoid going through the full AST machinery for some simple and common cases. */
+       size_t default_value_len = strlen(default_value);
+       zend_ulong lval;
+       if (default_value_len == sizeof("null")-1
+                       && !memcmp(default_value, "null", sizeof("null")-1)) {
+               ZVAL_NULL(default_value_zval);
+               return SUCCESS;
+       } else if (default_value_len == sizeof("true")-1
+                       && !memcmp(default_value, "true", sizeof("true")-1)) {
+               ZVAL_TRUE(default_value_zval);
+               return SUCCESS;
+       } else if (default_value_len == sizeof("false")-1
+                       && !memcmp(default_value, "false", sizeof("false")-1)) {
+               ZVAL_FALSE(default_value_zval);
+               return SUCCESS;
+       } else if (default_value_len >= 2
+                       && (default_value[0] == '\'' || default_value[0] == '"')
+                       && default_value[default_value_len - 1] == default_value[0]) {
+               zend_string *str = try_parse_string(
+                       default_value + 1, default_value_len - 2, default_value[0]);
+               if (str) {
+                       ZVAL_STR(default_value_zval, str);
+                       return SUCCESS;
+               }
+       } else if (default_value_len == sizeof("[]")-1
+                       && !memcmp(default_value, "[]", sizeof("[]")-1)) {
+               ZVAL_EMPTY_ARRAY(default_value_zval);
+               return SUCCESS;
+       } else if (ZEND_HANDLE_NUMERIC_STR(default_value, default_value_len, lval)) {
+               ZVAL_LONG(default_value_zval, lval);
+               return SUCCESS;
+       }
+
+#if 0
+       fprintf(stderr, "Evaluating %s via AST\n", default_value);
+#endif
+       return get_default_via_ast(default_value_zval, default_value);
+}
index afc2ad8a7dbdce0fab3b578487c5a4cba49226c9..799f1760ba55b3e108bebb034be55f44762942a5 100644 (file)
@@ -592,6 +592,10 @@ ZEND_API zend_bool zend_is_iterable(zval *iterable);
 ZEND_API zend_bool zend_is_countable(zval *countable);
 
 ZEND_API ZEND_FUNCTION(display_disabled_function);
+
+ZEND_API int zend_get_default_from_internal_arg_info(
+               zval *default_value_zval, zend_internal_arg_info *arg_info);
+
 END_EXTERN_C()
 
 #if ZEND_DEBUG
index 5f7f5270a1c9d0dbe8a7a72f8c264a709e998ee5..058d2d59d22b397cb8ccb2f8cb9ca13b4647e915 100644 (file)
@@ -1292,106 +1292,10 @@ static void reflection_class_constant_factory(zend_string *name_str, zend_class_
 }
 /* }}} */
 
-static int get_default_via_ast(zval *default_value_zval, const char *default_value) {
-       zend_ast *ast;
-       zend_arena *ast_arena;
-
-       smart_str code = {0};
-       smart_str_appends(&code, "<?php ");
-       smart_str_appends(&code, default_value);
-       smart_str_appendc(&code, ';');
-       smart_str_0(&code);
-
-       ast = zend_compile_string_to_ast(code.s, &ast_arena, "");
-       smart_str_free(&code);
-
-       if (!ast) {
-               return FAILURE;
-       }
-
-       zend_ast_list *statement_list = zend_ast_get_list(ast);
-       zend_ast *const_expression_ast = statement_list->child[0];
-
-       zend_arena *original_ast_arena = CG(ast_arena);
-       uint32_t original_compiler_options = CG(compiler_options);
-       zend_file_context original_file_context;
-       CG(ast_arena) = ast_arena;
-       /* Disable constant substitution, to make getDefaultValueConstant() work. */
-       CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
-       zend_file_context_begin(&original_file_context);
-       zend_const_expr_to_zval(default_value_zval, const_expression_ast);
-       CG(ast_arena) = original_ast_arena;
-       CG(compiler_options) = original_compiler_options;
-       zend_file_context_end(&original_file_context);
-
-       zend_ast_destroy(ast);
-       zend_arena_destroy(ast_arena);
-
-       return SUCCESS;
-}
-
-static zend_string *try_parse_string(const char *str, size_t len, char quote) {
-       if (len == 0) {
-               return ZSTR_EMPTY_ALLOC();
-       }
-
-       for (size_t i = 0; i < len; i++) {
-               if (str[i] == '\\' || str[i] == quote) {
-                       return NULL;
-               }
-       }
-       return zend_string_init(str, len, 0);
-}
-
-static int get_default_from_arg_info(zval *default_value_zval, zend_internal_arg_info *arg_info)
-{
-       const char *default_value = arg_info->default_value;
-       if (!default_value) {
-               return FAILURE;
-       }
-
-       /* Avoid going through the full AST machinery for some simple and common cases. */
-       size_t default_value_len = strlen(default_value);
-       zend_ulong lval;
-       if (default_value_len == sizeof("null")-1
-                       && !memcmp(default_value, "null", sizeof("null")-1)) {
-               ZVAL_NULL(default_value_zval);
-               return SUCCESS;
-       } else if (default_value_len == sizeof("true")-1
-                       && !memcmp(default_value, "true", sizeof("true")-1)) {
-               ZVAL_TRUE(default_value_zval);
-               return SUCCESS;
-       } else if (default_value_len == sizeof("false")-1
-                       && !memcmp(default_value, "false", sizeof("false")-1)) {
-               ZVAL_FALSE(default_value_zval);
-               return SUCCESS;
-       } else if (default_value_len >= 2
-                       && (default_value[0] == '\'' || default_value[0] == '"')
-                       && default_value[default_value_len - 1] == default_value[0]) {
-               zend_string *str = try_parse_string(
-                       default_value + 1, default_value_len - 2, default_value[0]);
-               if (str) {
-                       ZVAL_STR(default_value_zval, str);
-                       return SUCCESS;
-               }
-       } else if (default_value_len == sizeof("[]")-1
-                       && !memcmp(default_value, "[]", sizeof("[]")-1)) {
-               ZVAL_EMPTY_ARRAY(default_value_zval);
-               return SUCCESS;
-       } else if (ZEND_HANDLE_NUMERIC_STR(default_value, default_value_len, lval)) {
-               ZVAL_LONG(default_value_zval, lval);
-               return SUCCESS;
-       }
-
-#if 0
-       fprintf(stderr, "Evaluating %s via AST\n", default_value);
-#endif
-       return get_default_via_ast(default_value_zval, default_value);
-}
-
 static int get_parameter_default(zval *result, parameter_reference *param) {
        if (param->fptr->type == ZEND_INTERNAL_FUNCTION) {
-               return get_default_from_arg_info(result, (zend_internal_arg_info*) param->arg_info);
+               return zend_get_default_from_internal_arg_info(
+                       result, (zend_internal_arg_info *) param->arg_info);
        } else {
                zval *default_value = get_default_from_recv((zend_op_array *) param->fptr, param->offset);
                if (!default_value) {