diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 7d72d4ec4e9..1937703f0b2 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -123,6 +123,7 @@ enum _zend_ast_kind { ZEND_AST_USE, ZEND_AST_USE_ELEM, ZEND_AST_NAMESPACE, + ZEND_AST_HALT_COMPILER, }; typedef unsigned short zend_ast_kind; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index eb7a8f1fd5d..381580c4e68 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6348,8 +6348,6 @@ void zend_compile_namespace(zend_ast *ast TSRMLS_DC) { zend_string *name; zend_bool with_bracket = stmt_ast != NULL; - // TODO.AST errors! - /* handle mixed syntax declaration or nested namespaces */ if (!CG(has_bracketed_namespaces)) { if (Z_TYPE(CG(current_namespace)) != IS_UNDEF) { @@ -6420,6 +6418,25 @@ void zend_compile_namespace(zend_ast *ast TSRMLS_DC) { } } +void zend_compile_halt_compiler(zend_ast *ast TSRMLS_DC) { + zend_ast *offset_ast = ast->child[0]; + long offset = Z_LVAL_P(zend_ast_get_zval(offset_ast)); + + zend_string *filename, *name; + const char const_name[] = "__COMPILER_HALT_OFFSET__"; + + if (CG(has_bracketed_namespaces) && CG(in_namespace)) { + zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); + } + + filename = zend_get_compiled_filename(TSRMLS_C); + name = zend_mangle_property_name(const_name, sizeof(const_name) - 1, + filename->val, filename->len, 0); + + zend_register_long_constant(name->val, name->len, offset, CONST_CS, 0 TSRMLS_CC); + STR_RELEASE(name); +} + void zend_compile_binary_op(znode *result, zend_ast *ast TSRMLS_DC) { zend_ast *left_ast = ast->child[0]; zend_ast *right_ast = ast->child[1]; @@ -7368,6 +7385,9 @@ void zend_compile_stmt(zend_ast *ast TSRMLS_DC) { case ZEND_AST_NAMESPACE: zend_compile_namespace(ast TSRMLS_CC); break; + case ZEND_AST_HALT_COMPILER: + zend_compile_halt_compiler(ast TSRMLS_CC); + break; default: { znode result; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 81e961dede0..c0d50622e7b 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -247,7 +247,11 @@ top_statement: statement { $$.u.ast = $1.u.ast; } | function_declaration_statement { $$.u.ast = $1.u.ast; } | class_declaration_statement { $$.u.ast = $1.u.ast; } - | T_HALT_COMPILER '(' ')' ';' { AN($$); zend_do_halt_compiler_register(TSRMLS_C); YYACCEPT; } + | T_HALT_COMPILER '(' ')' ';' + { zval offset_zv; ZVAL_LONG(&offset_zv, zend_get_scanned_file_offset(TSRMLS_C)); + $$.u.ast = zend_ast_create_unary(ZEND_AST_HALT_COMPILER, + zend_ast_create_zval(&offset_zv)); + /*YYACCEPT;*/ } | T_NAMESPACE namespace_name ';' { $$.u.ast = zend_ast_create_binary(ZEND_AST_NAMESPACE, AST_ZVAL(&$2), NULL); zend_discard_doc_comment(TSRMLS_C); }