diff options
author | Andi Gutmans <andi@php.net> | 2002-11-05 19:37:31 +0000 |
---|---|---|
committer | Andi Gutmans <andi@php.net> | 2002-11-05 19:37:31 +0000 |
commit | c4978680055e21bcb22f453bdc08bb1c6ad70578 (patch) | |
tree | 0e924fc92b76eb938c080cf81b9fcbb1a3cd60b8 | |
parent | f40e3b8548f838af757c2bd6f4d82caebdfd8be0 (diff) | |
download | php-git-c4978680055e21bcb22f453bdc08bb1c6ad70578.tar.gz |
- Add support for static methods. Basically methods which are defined as
- static don't have $this. That's the whole difference.
-rw-r--r-- | Zend/zend_compile.c | 3 | ||||
-rw-r--r-- | Zend/zend_compile.h | 18 | ||||
-rw-r--r-- | Zend/zend_execute.c | 39 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 11 |
4 files changed, 39 insertions, 32 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9d820d39dc..dfd78fe72a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -896,7 +896,7 @@ void zend_do_free(znode *op1 TSRMLS_DC) } } -void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference TSRMLS_DC) +void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, int is_static TSRMLS_DC) { zend_op_array op_array; char *name = function_name->u.constant.value.str.val; @@ -911,6 +911,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n op_array.function_name = name; op_array.arg_types = NULL; op_array.return_reference = return_reference; + op_array.is_static = is_static; op_array.scope = CG(active_class_entry); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 5860eecdd4..b611ec80ba 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -94,6 +94,7 @@ struct _zend_op_array { zend_uchar *arg_types; /* MUST be the second element of this struct! */ char *function_name; /* MUST be the third element of this struct! */ zend_class_entry *scope; /* MUST be the fourth element of this struct! */ + zend_bool is_static; /* MUST be the fifth element of this struct! */ zend_uint *refcount; @@ -128,22 +129,11 @@ typedef struct _zend_internal_function { zend_uchar *arg_types; /* MUST be the second element of this struct! */ char *function_name; /* MUST be the third element of this struct! */ zend_class_entry *scope; /* MUST be the fourth element of this struct! */ + zend_bool is_static; /* MUST be the fifth element of this struct! */ void (*handler)(INTERNAL_FUNCTION_PARAMETERS); } zend_internal_function; - -typedef struct _zend_overloaded_function { - zend_uchar type; /* MUST be the first element of this struct! */ - - zend_uchar *arg_types; /* MUST be the second element of this struct! */ - char *function_name; /* MUST be the third element of this struct! */ - zend_class_entry *scope; /* MUST be the fourth element of this struct! */ - - zend_uint var; -} zend_overloaded_function; - - typedef union _zend_function { zend_uchar type; /* MUST be the first element of this struct! */ @@ -152,11 +142,11 @@ typedef union _zend_function { zend_uchar *arg_types; char *function_name; zend_class_entry *scope; + zend_bool is_static; } common; zend_op_array op_array; zend_internal_function internal_function; - zend_overloaded_function overloaded_function; } zend_function; @@ -298,7 +288,7 @@ void zend_do_add_char(znode *result, znode *op1, znode *op2 TSRMLS_DC); void zend_do_add_string(znode *result, znode *op1, znode *op2 TSRMLS_DC); void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC); -void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference TSRMLS_DC); +void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, int is_static TSRMLS_DC); void zend_do_end_function_declaration(znode *function_token TSRMLS_DC); void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, zend_uchar pass_type TSRMLS_DC); int zend_do_begin_function_call(znode *function_name TSRMLS_DC); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index f4921e6442..ea04efea67 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2262,15 +2262,19 @@ int zend_init_method_call_handler(ZEND_OPCODE_HANDLER_ARGS) zend_error(E_ERROR, "Call to undefined function: %s()", function_name_strval); } - if (!PZVAL_IS_REF(EX(object))) { - EX(object)->refcount++; /* For $this pointer */ + if (EX(fbc)->common.is_static) { + EX(object) = NULL; } else { - zval *this_ptr; - ALLOC_ZVAL(this_ptr); - *this_ptr = *EX(object); - INIT_PZVAL(this_ptr); - zval_copy_ctor(this_ptr); - EX(object) = this_ptr; + if (!PZVAL_IS_REF(EX(object))) { + EX(object)->refcount++; /* For $this pointer */ + } else { + zval *this_ptr; + ALLOC_ZVAL(this_ptr); + *this_ptr = *EX(object); + INIT_PZVAL(this_ptr); + zval_copy_ctor(this_ptr); + EX(object) = this_ptr; + } } if (EX(fbc)->type == ZEND_USER_FUNCTION) { @@ -2312,10 +2316,6 @@ int zend_init_static_method_call_handler(ZEND_OPCODE_HANDLER_ARGS) function_name_strval = tmp.value.str.val; function_name_strlen = tmp.value.str.len; } - - if ((EX(object) = EG(This))) { - EX(object)->refcount++; - } ce = EX_T(EX(opline)->op1.u.var).EA.class_entry; @@ -2332,6 +2332,14 @@ int zend_init_static_method_call_handler(ZEND_OPCODE_HANDLER_ARGS) EX(fbc) = function; + if (function->common.is_static) { + EX(object) = NULL; + } else { + if ((EX(object) = EG(This))) { + EX(object)->refcount++; + } + } + NEXT_OPCODE(); } @@ -2408,7 +2416,7 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS) EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr; - if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) { + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr); INIT_ZVAL(*(EX_T(EX(opline)->result.u.var).var.ptr)); ((zend_internal_function *) EX(function_state).function)->handler(EX(opline)->extended_value, EX_T(EX(opline)->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC); @@ -2418,7 +2426,7 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS) if (!return_value_used) { zval_ptr_dtor(&EX_T(EX(opline)->result.u.var).var.ptr); } - } else if (EX(function_state).function->type==ZEND_USER_FUNCTION) { + } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) { HashTable *calling_symbol_table; EX_T(EX(opline)->result.u.var).var.ptr = NULL; @@ -2462,6 +2470,7 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS) ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr); INIT_ZVAL(*(EX_T(EX(opline)->result.u.var).var.ptr)); + /* Not sure what should be done here if it's a static method */ if (EX(object)) { Z_OBJ_HT_P(EX(object))->call_method(EX(fbc)->common.function_name, EX(opline)->extended_value, EX_T(EX(opline)->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC); } else { @@ -2512,6 +2521,7 @@ int zend_do_fcall_handler(ZEND_OPCODE_HANDLER_ARGS) zend_ptr_stack_n_push(&EG(arg_types_stack), 3, EX(fbc), EX(object), EX(calling_scope)); do { + /* if (EG(scope)) { if (zend_hash_find(&EG(scope)->function_table, fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function) == SUCCESS) { if ((EX(object) = EG(This))) { @@ -2521,6 +2531,7 @@ int zend_do_fcall_handler(ZEND_OPCODE_HANDLER_ARGS) break; } } + */ if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) { zend_error(E_ERROR, "Unknown function: %s()\n", fname->value.str.val); } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index f9b6212983..e2dae8de0d 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -273,7 +273,7 @@ class_declaration_statement: 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 TSRMLS_CC); } + T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 0, $3.op_type, 0 TSRMLS_CC); } '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); } ; @@ -438,11 +438,16 @@ class_statement_list: class_statement: class_variable_declaration ';' | class_constant_declaration ';' - | T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 1, $3.op_type TSRMLS_CC); } '(' - parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); } + | is_static 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.u.constant.value.lval TSRMLS_CC); } '(' + parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); } | T_CLASS T_STRING extends_from '{' { zend_do_begin_class_declaration(&$1, &$2, &$3 TSRMLS_CC); } class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); } ; +is_static: + T_STATIC { $$.u.constant.value.lval = 1; } + | /* empty */ { $$.u.constant.value.lval = 0; } +; + is_reference: /* empty */ { $$.op_type = ZEND_RETURN_VAL; } | '&' { $$.op_type = ZEND_RETURN_REF; } |