mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
- Add support for static methods. Basically methods which are defined as
- static don't have $this. That's the whole difference.
This commit is contained in:
parent
f40e3b8548
commit
c497868005
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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; }
|
||||
|
Loading…
Reference in New Issue
Block a user