diff options
author | Andrei Zmievski <andrei@php.net> | 2003-03-31 20:42:01 +0000 |
---|---|---|
committer | Andrei Zmievski <andrei@php.net> | 2003-03-31 20:42:01 +0000 |
commit | 5657b8369119dab9c81deb036d7a43c83df332cb (patch) | |
tree | 74f0557311da249690b7b2efdc08512cdcc03d5d | |
parent | 383808e9d3e17d2ca2cb513d5d7d6b1dd9681c12 (diff) | |
download | php-git-5657b8369119dab9c81deb036d7a43c83df332cb.tar.gz |
Multi-purpose patch:
- The fields of zend_namespace were not completely initialized which
led to a variety of problems.
- The occurrence of class/interface/namespace definition is now
captured.
- Functions/classes/interfaces/namespaces can be preceded by doc
comments which are stored for use by extensions.
-rw-r--r-- | Zend/zend.h | 6 | ||||
-rw-r--r-- | Zend/zend_compile.c | 69 | ||||
-rw-r--r-- | Zend/zend_compile.h | 12 | ||||
-rw-r--r-- | Zend/zend_globals.h | 2 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 27 | ||||
-rw-r--r-- | Zend/zend_language_scanner.l | 16 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 11 |
7 files changed, 111 insertions, 32 deletions
diff --git a/Zend/zend.h b/Zend/zend.h index 3cf15371f0..a2212446ff 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -335,6 +335,12 @@ struct _zend_class_entry { zend_class_entry **interfaces; zend_uint num_interfaces; + char *filename; + zend_uint line_start; + zend_uint line_end; + char *doc_comment; + zend_uint doc_comment_len; + /* old handlers */ #if 0 void (*handle_function_call)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8de33ae5a0..38f0ead9bf 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -977,7 +977,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n op_array.ns = CG(active_namespace); op_array.prototype = NULL; - op_array.line_start = CG(zend_lineno); + op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); if (is_method) { char *short_class_name = CG(active_class_entry)->name; @@ -1071,12 +1071,16 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n } -void zend_do_end_function_declaration(znode *function_token TSRMLS_DC) +void zend_do_end_function_declaration(znode *function_token, znode *doc_comment TSRMLS_DC) { zend_do_extended_info(TSRMLS_C); zend_do_return(NULL, 0 TSRMLS_CC); pass_two(CG(active_op_array) TSRMLS_CC); - CG(active_op_array)->line_end = CG(zend_lineno); + CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C); + if (doc_comment && doc_comment->op_type != IS_UNUSED) { + CG(active_op_array)->doc_comment = doc_comment->u.constant.value.str.val; + CG(active_op_array)->doc_comment_len = doc_comment->u.constant.value.str.len; + } CG(active_op_array) = function_token->u.op_array; /* Pop the switch and foreach seperators */ @@ -2202,6 +2206,8 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod new_class_entry->num_interfaces = 0; zend_initialize_class_data(new_class_entry, 1 TSRMLS_CC); + new_class_entry->filename = zend_get_compiled_filename(TSRMLS_C); + new_class_entry->line_start = zend_get_compiled_lineno(TSRMLS_C); new_class_entry->ce_flags |= class_token->u.constant.value.lval; if (parent_class_name->op_type != IS_UNUSED) { @@ -2245,10 +2251,17 @@ static void do_verify_abstract_class(TSRMLS_D) } -void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRMLS_DC) +void zend_do_end_class_declaration(znode *class_token, znode *parent_token, znode *doc_comment TSRMLS_DC) { do_inherit_parent_constructor(CG(active_class_entry)); + CG(active_class_entry)->line_end = zend_get_compiled_lineno(TSRMLS_C); + + if (doc_comment && doc_comment->op_type != IS_UNUSED) { + CG(active_class_entry)->doc_comment = doc_comment->u.constant.value.str.val; + CG(active_class_entry)->doc_comment_len = doc_comment->u.constant.value.str.len; + } + if (CG(active_class_entry)->num_interfaces > 0) { CG(active_class_entry)->interfaces = (zend_class_entry **) emalloc(sizeof(zend_class_entry *)*CG(active_class_entry)->num_interfaces); } @@ -3279,7 +3292,6 @@ int zendlex(znode *zendlval TSRMLS_DC) retval = lex_scan(&zendlval->u.constant TSRMLS_CC); switch (retval) { case T_COMMENT: - case T_DOC_COMMENT: case T_OPEN_TAG: case T_WHITESPACE: retval = zendlex(zendlval TSRMLS_CC); @@ -3318,12 +3330,30 @@ void zend_destroy_property_info(zend_property_info *property_info) void zend_init_namespace(zend_namespace *ns TSRMLS_DC) { + ns->refcount = 1; + ns->constants_updated = 0; + ns->ce_flags = 0; + + ns->filename = NULL; + ns->doc_comment = NULL; + ns->doc_comment_len = 0; + zend_hash_init(&ns->function_table, 10, NULL, ZEND_FUNCTION_DTOR, 0); zend_hash_init(&ns->class_table, 10, NULL, ZEND_CLASS_DTOR, 0); zend_hash_init(&ns->constants_table, 10, NULL, ZVAL_PTR_DTOR, 0); ALLOC_HASHTABLE(ns->static_members); zend_hash_init(ns->static_members, 0, NULL, ZVAL_PTR_DTOR, 0); + + ns->parent = NULL; + ns->ns = NULL; ns->constructor = NULL; + ns->destructor = NULL; + ns->clone = NULL; + ns->__get = NULL; + ns->__set = NULL; + ns->__call = NULL; + ns->create_object = NULL; + ns->type = ZEND_NAMESPACE; } @@ -3346,6 +3376,7 @@ void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC) ns->name_length = ns_name->u.constant.value.str.len; zend_hash_add(&CG(global_namespace).class_table, ns->name, ns->name_length+1, (void **)&ns, sizeof(zend_namespace *), NULL); zend_init_namespace(ns TSRMLS_CC); + ns->line_start = zend_get_compiled_lineno(TSRMLS_C); } opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3367,11 +3398,34 @@ void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC) CG(function_table) = &ns->function_table; } -void zend_do_end_namespace(znode *ns_token TSRMLS_DC) +void zend_do_end_namespace(znode *ns_token, znode *doc_comment TSRMLS_DC) { zend_namespace *ns = ns_token->u.previously_active_namespace; zend_op *opline; + /* + * If the filename field has not been initialized yet, it means that we are + * on the first definition of namespace and should capture the definition + * information. + */ + if (CG(active_namespace)->filename == NULL) { + CG(active_namespace)->filename = zend_get_compiled_filename(TSRMLS_C); + CG(active_namespace)->line_end = zend_get_compiled_lineno(TSRMLS_C); + } + + if (doc_comment && doc_comment->op_type != IS_UNUSED) { + /* + * Do not overwrite previously declared doc comment in case the namespace is + * split over several parts. + */ + if (CG(active_namespace)->doc_comment == NULL) { + CG(active_namespace)->doc_comment = doc_comment->u.constant.value.str.val; + CG(active_namespace)->doc_comment_len = doc_comment->u.constant.value.str.len; + } else { + zval_dtor(&doc_comment->u.constant); + } + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_START_NAMESPACE; @@ -3436,6 +3490,9 @@ void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers ce->constants_updated = 0; ce->ce_flags = 0; + ce->doc_comment = NULL; + ce->doc_comment_len = 0; + zend_hash_init_ex(&ce->default_properties, 0, NULL, ZVAL_PTR_DTOR, persistent_hashes, 0); zend_hash_init_ex(&ce->properties_info, 0, NULL, (dtor_func_t) zend_destroy_property_info, persistent_hashes, 0); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index c522fc01b1..f2b7b8b27a 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -148,8 +148,10 @@ struct _zend_op_array { zend_bool uses_this; char *filename; - int line_start; - int line_end; + zend_uint line_start; + zend_uint line_end; + char *doc_comment; + zend_uint doc_comment_len; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; }; @@ -318,7 +320,7 @@ void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC); int zend_do_verify_access_types(znode *current_access_type, znode *new_modifier); void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC); -void zend_do_end_function_declaration(znode *function_token TSRMLS_DC); +void zend_do_end_function_declaration(znode *function_token, znode *doc_comment TSRMLS_DC); void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, znode *class_type, zend_uchar pass_type TSRMLS_DC); int zend_do_begin_function_call(znode *function_name TSRMLS_DC); void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC); @@ -360,7 +362,7 @@ void zend_do_case_after_statement(znode *result, znode *case_token TSRMLS_DC); void zend_do_default_before_statement(znode *case_list, znode *default_token TSRMLS_DC); void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name TSRMLS_DC); -void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRMLS_DC); +void zend_do_end_class_declaration(znode *class_token, znode *parent_token, znode *doc_comment TSRMLS_DC); void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_type TSRMLS_DC); void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC); @@ -449,7 +451,7 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce); void zend_class_add_ref(zend_class_entry **ce); void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC); -void zend_do_end_namespace(znode *ns_token TSRMLS_DC); +void zend_do_end_namespace(znode *ns_token, znode *doc_comment TSRMLS_DC); void zend_init_namespace(zend_namespace *ns TSRMLS_DC); void zend_do_declare_namespace_var(znode *name, znode *value TSRMLS_DC); void zend_do_declare_namespace_constant(znode *name, znode *value TSRMLS_DC); diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 3ac7e6aaff..ac335fc473 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -85,8 +85,6 @@ struct _zend_compiler_globals { int comment_start_line; char *heredoc; int heredoc_len; - char *doc_comment; - int doc_comment_len; zend_op_array *active_op_array; diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index b95d3a8c84..35689198b6 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -179,6 +179,7 @@ inner_statement: statement: unticked_statement { zend_do_ticks(TSRMLS_C); } + | doc_comment { zend_do_free(&$1 TSRMLS_CC); } unticked_statement { zend_do_ticks(TSRMLS_C); } ; unticked_statement: @@ -284,17 +285,27 @@ is_reference: unticked_function_declaration_statement: - T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 0, $3.op_type, NULL TSRMLS_CC); } - '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); } + optional_doc_comment T_FUNCTION { $2.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$5, 0, $4.op_type, NULL TSRMLS_CC); } + '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2, &$1 TSRMLS_CC); } ; unticked_class_declaration_statement: - class_entry_type T_STRING extends_from - { zend_do_begin_class_declaration(&$1, &$2, &$3 TSRMLS_CC); } + optional_doc_comment class_entry_type T_STRING extends_from + { zend_do_begin_class_declaration(&$2, &$3, &$4 TSRMLS_CC); } implements_list '{' class_statement_list - '}' { zend_do_end_class_declaration(&$1, &$2 TSRMLS_CC); } + '}' { zend_do_end_class_declaration(&$2, &$4, &$1 TSRMLS_CC); } +; + +optional_doc_comment: + /* empty */ { $$.op_type = IS_UNUSED; } + | doc_comment { $$ = $1; } +; + + +doc_comment: + T_DOC_COMMENT { $$ = $1; } ; @@ -305,7 +316,7 @@ class_entry_type: ; namespace_declaration_statement: - T_NAMESPACE namespace_name '{' { zend_do_begin_namespace(&$1, &$2 TSRMLS_CC); } namespace_statement_list '}' { zend_do_end_namespace(&$1 TSRMLS_CC); } + optional_doc_comment T_NAMESPACE namespace_name '{' { zend_do_begin_namespace(&$2, &$3 TSRMLS_CC); } namespace_statement_list '}' { zend_do_end_namespace(&$2, &$1 TSRMLS_CC); } ; namespace_statement_list: @@ -503,7 +514,9 @@ class_statement: variable_modifiers { CG(access_type) = $1.u.constant.value.lval; } class_variable_declaration ';' | class_constant_declaration ';' | method_modifiers T_FUNCTION { $2.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$5, 1, $4.op_type, &$1 TSRMLS_CC); } '(' - parameter_list ')' method_body { zend_do_abstract_method(&$5, &$1, &$10 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); } + parameter_list ')' method_body { zend_do_abstract_method(&$5, &$1, &$10 TSRMLS_CC); zend_do_end_function_declaration(&$2, NULL TSRMLS_CC); } + | doc_comment method_modifiers T_FUNCTION { $3.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$3, &$6, 1, $5.op_type, &$2 TSRMLS_CC); } '(' + parameter_list ')' method_body { zend_do_abstract_method(&$6, &$2, &$11 TSRMLS_CC); zend_do_end_function_declaration(&$3, &$1 TSRMLS_CC); } ; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 16fd9efa6c..800261580f 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -124,8 +124,6 @@ void startup_scanner(TSRMLS_D) { CG(heredoc) = NULL; CG(heredoc_len)=0; - CG(doc_comment) = NULL; - CG(doc_comment_len) = 0; SCNG(yy_start_stack_ptr) = 0; SCNG(yy_start_stack_depth) = 0; } @@ -137,10 +135,6 @@ void shutdown_scanner(TSRMLS_D) efree(CG(heredoc)); CG(heredoc_len)=0; } - if (CG(doc_comment)) { - efree(CG(doc_comment)); - CG(doc_comment_len) = 0; - } } END_EXTERN_C() @@ -1176,7 +1170,7 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL} } } -<ST_IN_SCRIPTING>"/** "{NEWLINE} { +<ST_IN_SCRIPTING>"/**"{NEWLINE} { CG(comment_start_line) = CG(zend_lineno); BEGIN(ST_DOC_COMMENT); yymore(); @@ -1194,11 +1188,9 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL} } <ST_DOC_COMMENT>"*/" { - if (CG(doc_comment)) { - efree(CG(doc_comment)); - } - CG(doc_comment) = estrndup(yytext, yyleng); - CG(doc_comment_len) = yyleng; + zendlval->value.str.val = (char *)estrndup(yytext, yyleng); + zendlval->value.str.len = yyleng; + zendlval->type = IS_STRING; HANDLE_NEWLINES(yytext, yyleng); BEGIN(ST_IN_SCRIPTING); return T_DOC_COMMENT; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 11e6c9c4b4..31ddb4557e 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -74,6 +74,8 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz op_array->function_name = NULL; op_array->filename = zend_get_compiled_filename(TSRMLS_C); + op_array->doc_comment = NULL; + op_array->doc_comment_len = 0; op_array->arg_types = NULL; @@ -157,6 +159,9 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce) if (ce->num_interfaces > 0) { efree(ce->interfaces); } + if (ce->doc_comment) { + efree(ce->doc_comment); + } efree(ce); break; case ZEND_INTERNAL_CLASS: @@ -184,6 +189,9 @@ ZEND_API void destroy_zend_namespace(zend_namespace **pns) zend_hash_destroy(&ns->constants_table); zend_hash_destroy(ns->static_members); FREE_HASHTABLE(ns->static_members); + if (ns->doc_comment) { + efree(ns->doc_comment); + } efree(ns->name); efree(ns); } @@ -229,6 +237,9 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC) if (op_array->function_name) { efree(op_array->function_name); } + if (op_array->doc_comment) { + efree(op_array->doc_comment); + } if (op_array->arg_types) { efree(op_array->arg_types); } |