]> granicus.if.org Git - php/commitdiff
Implement $obj::static_func()
authorZeev Suraski <zeev@php.net>
Wed, 5 Mar 2003 13:25:33 +0000 (13:25 +0000)
committerZeev Suraski <zeev@php.net>
Wed, 5 Mar 2003 13:25:33 +0000 (13:25 +0000)
Zend/zend_compile.c
Zend/zend_execute.c
Zend/zend_language_parser.y

index 1840f6fbbb0c4cc3157d6d8dfc1820e52ac344dd..5dc8e1a87f639bd96c29ace079ae9e7cc0e7f437 100644 (file)
@@ -1208,29 +1208,33 @@ void do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRM
                SET_UNUSED(opline->op1);
        }
        CG(catch_begin) = fetch_class_op_number;
-       if(class_name) {
-               zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
-       }
-       if(class_name == NULL) {
-               SET_UNUSED(opline->op2);
-               opline->extended_value = ZEND_FETCH_CLASS_MAIN;
-       } else if ((class_name->u.constant.value.str.len == (sizeof("self") - 1)) &&
-               !memcmp(class_name->u.constant.value.str.val, "self", sizeof("self"))) {
-               SET_UNUSED(opline->op2);
-               opline->extended_value = ZEND_FETCH_CLASS_SELF;
-               zval_dtor(&class_name->u.constant);
-       } else if ((class_name->u.constant.value.str.len == (sizeof("parent") - 1)) &&
-               !memcmp(class_name->u.constant.value.str.val, "parent", sizeof("parent"))) {
-               SET_UNUSED(opline->op2);
-               opline->extended_value = ZEND_FETCH_CLASS_PARENT;
-               zval_dtor(&class_name->u.constant);
-       } else if ((class_name->u.constant.value.str.len == (sizeof("main") - 1)) &&
-               !memcmp(class_name->u.constant.value.str.val, "main", sizeof("main"))) {
+       if (class_name) {
+               if (class_name->op_type == IS_CONST) {
+                       zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
+                       if ((class_name->u.constant.value.str.len == (sizeof("self") - 1)) &&
+                               !memcmp(class_name->u.constant.value.str.val, "self", sizeof("self"))) {
+                               SET_UNUSED(opline->op2);
+                               opline->extended_value = ZEND_FETCH_CLASS_SELF;
+                               zval_dtor(&class_name->u.constant);
+                       } else if ((class_name->u.constant.value.str.len == (sizeof("parent") - 1)) &&
+                               !memcmp(class_name->u.constant.value.str.val, "parent", sizeof("parent"))) {
+                               SET_UNUSED(opline->op2);
+                               opline->extended_value = ZEND_FETCH_CLASS_PARENT;
+                               zval_dtor(&class_name->u.constant);
+                       } else if ((class_name->u.constant.value.str.len == (sizeof("main") - 1)) &&
+                               !memcmp(class_name->u.constant.value.str.val, "main", sizeof("main"))) {
+                               SET_UNUSED(opline->op2);
+                               opline->extended_value = ZEND_FETCH_CLASS_MAIN;
+                               zval_dtor(&class_name->u.constant);
+                       } else {
+                               opline->op2 = *class_name;
+                       }
+               } else {
+                       opline->op2 = *class_name;
+               }
+       } else {
                SET_UNUSED(opline->op2);
                opline->extended_value = ZEND_FETCH_CLASS_MAIN;
-               zval_dtor(&class_name->u.constant);
-       } else {
-               opline->op2 = *class_name;
        }
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
        opline->result.op_type = IS_CONST; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
index 39a7b01b3d69650ed54696e61d9e125312fb8f41..412e04380b7996bcee49a9edad049572da11af37 100644 (file)
@@ -2303,6 +2303,7 @@ int zend_import_const_handler(ZEND_OPCODE_HANDLER_ARGS)
 int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_class_entry **pce;
+       zend_class_entry *ce = NULL;
        zend_bool is_const;
        char *class_name_strval;
        zend_uint class_name_strlen;                                            
@@ -2335,48 +2336,59 @@ int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
        is_const = (EX(opline)->op2.op_type == IS_CONST);
 
        if (is_const) {
-               class_name_strval = EX(opline)->op2.u.constant.value.str.val;
-               class_name_strlen = EX(opline)->op2.u.constant.value.str.len;
+{
+                       class_name_strval = EX(opline)->op2.u.constant.value.str.val;
+                       class_name_strlen = EX(opline)->op2.u.constant.value.str.len;
+               }
        } else {
                class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
 
-               tmp = *class_name;
-               zval_copy_ctor(&tmp);
-               convert_to_string(&tmp);
-               zend_str_tolower(tmp.value.str.val, tmp.value.str.len);
+               if (class_name->type == IS_OBJECT) {
+                       ce = Z_OBJCE_P(class_name);
+               } else {
+                       tmp = *class_name;
+                       zval_copy_ctor(&tmp);
+                       convert_to_string(&tmp);
+                       zend_str_tolower(tmp.value.str.val, tmp.value.str.len);
 
-               class_name_strval = tmp.value.str.val;
-               class_name_strlen = tmp.value.str.len;
+                       class_name_strval = tmp.value.str.val;
+                       class_name_strlen = tmp.value.str.len;
+               }
        }
        
-       if (EX(opline)->op1.op_type == IS_UNUSED && EX(opline)->extended_value != ZEND_FETCH_CLASS_GLOBAL) {
-               retval = zend_lookup_class(class_name_strval, class_name_strlen, &pce TSRMLS_CC);
-
-               if(retval == FAILURE) {
-                       /* try namespace */
-                       if(zend_hash_find(&EG(global_namespace_ptr)->class_table, class_name_strval, class_name_strlen+1, (void **)&pce) == SUCCESS && (*pce)->type == ZEND_NAMESPACE) {
-                               retval = SUCCESS;
+       if (!ce) {
+               if (EX(opline)->op1.op_type == IS_UNUSED && EX(opline)->extended_value != ZEND_FETCH_CLASS_GLOBAL) {
+                       retval = zend_lookup_class(class_name_strval, class_name_strlen, &pce TSRMLS_CC);
+
+                       if(retval == FAILURE) {
+                               /* try namespace */
+                               if(zend_hash_find(&EG(global_namespace_ptr)->class_table, class_name_strval, class_name_strlen+1, (void **)&pce) == SUCCESS && (*pce)->type == ZEND_NAMESPACE) {
+                                       retval = SUCCESS;
+                               }
                        }
-               }
-
-       } else {
-               zend_namespace *ns;
-               /* Looking for namespace */
-               if(EX(opline)->extended_value == ZEND_FETCH_CLASS_GLOBAL) {
-                       ns = EG(global_namespace_ptr);
                } else {
-                       if (zend_hash_find(&EG(global_namespace_ptr)->class_table, EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.len+1, (void **)&pce) == FAILURE || (*pce)->type != ZEND_NAMESPACE) {
-                               zend_error(E_ERROR, "Namespace '%s' not found", EX(opline)->op1.u.constant.value.str.val);
+                       zend_namespace *ns;
+
+                       /* Looking for namespace */
+                       if(EX(opline)->extended_value == ZEND_FETCH_CLASS_GLOBAL) {
+                               ns = EG(global_namespace_ptr);
+                       } else {
+                               if (zend_hash_find(&EG(global_namespace_ptr)->class_table, EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.len+1, (void **)&pce) == FAILURE || (*pce)->type != ZEND_NAMESPACE) {
+                                       zend_error(E_ERROR, "Namespace '%s' not found", EX(opline)->op1.u.constant.value.str.val);
+                               }
+                               ns = *pce;
                        }
-                       ns = *pce;
+                       retval = zend_hash_find(&ns->class_table, class_name_strval, class_name_strlen+1, (void **)&pce);
+               }
+               if (retval==SUCCESS) {
+                       ce = *pce;
                }
-               retval = zend_hash_find(&ns->class_table, class_name_strval, class_name_strlen+1, (void **)&pce);
        }
 
        if (retval == FAILURE) {
                zend_error(E_ERROR, "Class '%s' not found", class_name_strval);
        } else {
-               EX_T(EX(opline)->result.u.var).EA.class_entry = *pce;
+               EX_T(EX(opline)->result.u.var).EA.class_entry = ce;
        }
        if (!is_const) {
                zval_dtor(&tmp);
@@ -3120,7 +3132,7 @@ int zend_new_handler(ZEND_OPCODE_HANDLER_ARGS)
                } else {
                        class_type = "abstract_class";
                }
-               zend_error(E_ERROR, "Cannot instantiate %s %s", class_type, EX_T(EX(opline)->op1.u.var).EA.class_entry->name);
+               zend_error(E_ERROR, "Cannot instantiate %s %s", class_type,  EX_T(EX(opline)->op1.u.var).EA.class_entry->name);
        }
        EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr;
        ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr);
index 31506e11dbb768e5bd519cc8fe0f0f830c3394ec..50d495fbd621639552dcf39fa7df8d719d8955cc 100644 (file)
@@ -643,7 +643,7 @@ function_call:
 
 parse_class_entry:
                T_NAMESPACE_NAME T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); }
-       |       T_STRING T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); }
+       |       static_or_variable_string T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); }
        |       T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, NULL TSRMLS_CC);  }
 ;