Skip to content

Commit c767819

Browse files
committed
Extract as zend_compile_string_to_ast() function
This avoids the dependency on language scanner headers. The function is exactly the same as the one used by ext/ast, so this functionality is also more broadly useful.
1 parent 534697e commit c767819

File tree

5 files changed

+51
-49
lines changed

5 files changed

+51
-49
lines changed

Zend/zend_compile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ ZEND_API void function_add_ref(zend_function *function);
771771
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type);
772772
ZEND_API zend_op_array *compile_string(zval *source_string, const char *filename);
773773
ZEND_API zend_op_array *compile_filename(int type, zval *filename);
774+
ZEND_API zend_ast *zend_compile_string_to_ast(
775+
zend_string *code, zend_arena **ast_arena, const char *filename);
774776
ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...);
775777
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle);
776778
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size);

Zend/zend_language_scanner.l

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,42 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type)
653653
return op_array;
654654
}
655655

656+
ZEND_API zend_ast *zend_compile_string_to_ast(
657+
zend_string *code, zend_arena **ast_arena, const char *filename) {
658+
zval code_zv;
659+
zend_bool original_in_compilation;
660+
zend_lex_state original_lex_state;
661+
zend_ast *ast;
662+
663+
ZVAL_STR_COPY(&code_zv, code);
664+
665+
original_in_compilation = CG(in_compilation);
666+
CG(in_compilation) = 1;
667+
668+
zend_save_lexical_state(&original_lex_state);
669+
if (zend_prepare_string_for_scanning(&code_zv, filename) == SUCCESS) {
670+
CG(ast) = NULL;
671+
CG(ast_arena) = zend_arena_create(1024 * 32);
672+
LANG_SCNG(yy_state) = yycINITIAL;
673+
674+
if (zendparse() != 0) {
675+
zend_ast_destroy(CG(ast));
676+
zend_arena_destroy(CG(ast_arena));
677+
CG(ast) = NULL;
678+
}
679+
}
680+
681+
/* restore_lexical_state changes CG(ast) and CG(ast_arena) */
682+
ast = CG(ast);
683+
*ast_arena = CG(ast_arena);
684+
685+
zend_restore_lexical_state(&original_lex_state);
686+
CG(in_compilation) = original_in_compilation;
687+
688+
zval_dtor(&code_zv);
689+
690+
return ast;
691+
}
656692

657693
zend_op_array *compile_filename(int type, zval *filename)
658694
{

ext/reflection/Makefile.frag

Lines changed: 0 additions & 4 deletions
This file was deleted.

ext/reflection/config.m4

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
PHP_NEW_EXTENSION(reflection, php_reflection.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
2-
PHP_ADD_MAKEFILE_FRAGMENT

ext/reflection/php_reflection.c

Lines changed: 13 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131

3232
#include "zend.h"
3333
#include "zend_API.h"
34-
#include "zend_language_scanner.h"
35-
#include "zend_language_scanner_defs.h"
3634
#include "zend_exceptions.h"
3735
#include "zend_operators.h"
3836
#include "zend_constants.h"
@@ -1330,67 +1328,38 @@ static int _reflection_param_get_default_arg_info(zend_function *fptr, zend_inte
13301328
return FAILURE;
13311329
}
13321330

1333-
zval code_zv;
1334-
zend_bool original_in_compilation;
1335-
uint32_t original_compiler_options;
1336-
zend_lex_state original_lex_state;
13371331
zend_ast *ast;
13381332
zend_arena *ast_arena;
1339-
int success = FAILURE;
13401333

13411334
smart_str code = {0};
13421335
smart_str_appends(&code, "<?php ");
13431336
smart_str_appends(&code, arg_info->default_value);
13441337
smart_str_appendc(&code, ';');
13451338
smart_str_0(&code);
13461339

1347-
ZVAL_STR_COPY(&code_zv, code.s);
1340+
ast = zend_compile_string_to_ast(code.s, &ast_arena, "");
13481341
smart_str_free(&code);
13491342

1350-
original_in_compilation = CG(in_compilation);
1351-
original_compiler_options = CG(compiler_options);
1352-
zend_save_lexical_state(&original_lex_state);
1353-
1354-
CG(in_compilation) = 1;
1355-
CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
1356-
1357-
if (zend_prepare_string_for_scanning(&code_zv, "") == SUCCESS) {
1358-
CG(ast) = NULL;
1359-
CG(ast_arena) = zend_arena_create(1024 * 32);
1360-
LANG_SCNG(yy_state) = yycINITIAL;
1361-
1362-
if (zendparse() != 0) {
1363-
zend_ast_destroy(CG(ast));
1364-
zend_arena_destroy(CG(ast_arena));
1365-
CG(ast) = NULL;
1366-
}
1343+
if (!ast) {
1344+
zend_throw_exception_ex(reflection_exception_ptr, 0, "Internal error: Failed to retrieve the default value");
1345+
return FAILURE;
13671346
}
13681347

1369-
ast = CG(ast);
1370-
ast_arena = CG(ast_arena);
1371-
1372-
if (ast) {
1373-
zend_ast_list *statement_list = zend_ast_get_list(ast);
1374-
zend_ast *const_expression_ast = statement_list->child[0];
1375-
if (const_expression_ast) {
1376-
zend_const_expr_to_zval(default_value_zval, const_expression_ast);
1377-
success = SUCCESS;
1378-
}
1379-
}
1348+
zend_ast_list *statement_list = zend_ast_get_list(ast);
1349+
zend_ast *const_expression_ast = statement_list->child[0];
13801350

1381-
zend_restore_lexical_state(&original_lex_state);
1351+
zend_arena *original_ast_arena = CG(ast_arena);
1352+
uint32_t original_compiler_options = CG(compiler_options);
1353+
CG(ast_arena) = ast_arena;
1354+
CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
1355+
zend_const_expr_to_zval(default_value_zval, const_expression_ast);
1356+
CG(ast_arena) = original_ast_arena;
13821357
CG(compiler_options) = original_compiler_options;
1383-
CG(in_compilation) = original_in_compilation;
13841358

1385-
zval_dtor(&code_zv);
13861359
zend_ast_destroy(ast);
13871360
zend_arena_destroy(ast_arena);
13881361

1389-
if (success == FAILURE) {
1390-
zend_throw_exception_ex(reflection_exception_ptr, 0, "Internal error: Failed to retrieve the default value");
1391-
}
1392-
1393-
return success;
1362+
return SUCCESS;
13941363
}
13951364

13961365
/* {{{ Preventing __clone from being called */

0 commit comments

Comments
 (0)