]> granicus.if.org Git - php/commitdiff
- Add support for static methods. Basically methods which are defined as
authorAndi Gutmans <andi@php.net>
Tue, 5 Nov 2002 19:37:31 +0000 (19:37 +0000)
committerAndi Gutmans <andi@php.net>
Tue, 5 Nov 2002 19:37:31 +0000 (19:37 +0000)
- static don't have $this. That's the whole difference.

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_language_parser.y

index 9d820d39dcf74c8b4f97b091582e06fe16d3e3e3..dfd78fe72a49951d9755e9b0404bd6fa1088a88f 100644 (file)
@@ -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);
 
index 5860eecdd4cc865ae49945a01383a6e481a6f18b..b611ec80ba867b300eaf3b27d64bd69f142cb7cd 100644 (file)
@@ -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);
index f4921e64425de6adbd01db41ab2064a19f4e960f..ea04efea67b749aae87e5f123f01c5df50534f80 100644 (file)
@@ -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);
                }
index f9b6212983a5280d3a4e600d055d036a24c9267c..e2dae8de0d3a3bb153b4bdfaf2eb52ca84e97180 100644 (file)
@@ -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; }