Re: __CLASS__ patch - returns called class

From: Date: Fri, 05 Apr 2002 09:22:50 +0000
Subject: Re: __CLASS__ patch - returns called class
References: 1 2  Groups: php.dev 
Request: Send a blank email to php-dev+get-82128@lists.php.net to get a copy of this message
This should really be implemented 100% in compile time, if you touch zend_execute.c, BUZZ :) Anyway, incidentally, Jani implemented this very patch a few days ago. We'll probably import it within a couple of days after we verify that it doesn't cause any gotcha's... Zeev At 12:34 PM 4/5/2002, Alan Knowles wrote:
Any chance of sneeking this one in :) - patch attached usage: <? class testclass2 extends testclass { } class testclass { function test() {
       echo __CLASS__;
} } testclass2::test(); $t = new testclass2(); $t->test(); ?> prints testclass2 testclass2 extremely usefull for building mulitiple extendable constructors. regards alan diff -b -B -r -u php-4.2.0RC2/Zend/zend_compile.h ALAN_Zend/zend_compile.h
--- php-4.2.0RC2/Zend/zend_compile.h    Sun Feb 10 20:52:45 2002
+++ ALAN_Zend/zend_compile.h    Fri Apr  5 17:26:04 2002
@@ -81,7 +81,7 @@
        zend_uchar *arg_types;          /* MUST be the second element of this struct! */
        char *function_name;                    /* MUST be the third element of this struct! */
-
+         char *class_name;       /* set at execute time to record the active class */
        zend_uint *refcount;
        zend_op *opcodes;
@@ -114,7 +114,7 @@
        zend_uchar *arg_types;          /* MUST be the second element of this struct */
        char *function_name;                    /* MUST be the third element of this struct */
-
+        char *class_name;       /* set at execute time to record the active class */
        void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
} zend_internal_function; @@ -124,7 +124,7 @@
        zend_uchar *arg_types;          /* MUST be the second element of this struct */
        char *function_name;            /* MUST be the third element of this struct */
-
+        char *class_name;       /* set at execute time to record the active class */
        zend_uint var;
} zend_overloaded_function; @@ -135,6 +135,7 @@
                zend_uchar type;  /* never used */
                zend_uchar *arg_types;
                char *function_name;
+                char *class_name;       /* set at execute time to record the active class */
        } common;
        zend_op_array op_array;
diff -b -B -r -u php-4.2.0RC2/Zend/zend_execute.c ALAN_Zend/zend_execute.c
--- php-4.2.0RC2/Zend/zend_execute.c    Sun Jan  6 23:21:09 2002
+++ ALAN_Zend/zend_execute.c    Fri Apr  5 17:26:04 2002
@@ -1485,6 +1485,7 @@
                                        zend_function *function;
                                        HashTable *active_function_table;
                                        zval tmp;
+                                        char *class_name=NULL;
zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(fbc), EX(object).ptr);
                                        if (EX(opline)->extended_value & ZEND_CTOR_CALL) {
@@ -1521,6 +1522,7 @@
                                                        if (zend_hash_find(EG(class_table), EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.len+1, (void **) &ce)==FAILURE) { /* class doesn't exist */
zend_error(E_ERROR, "Undefined class name '%s'", EX(opline)->op1.u.constant.value.str.val);
                                                        }
+                                                        class_name =  ce->name;
active_function_table = &ce->function_table;
                                                } else { /* used for member function calls */
                                                        EX(object).ptr = _get_object_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1) TSRMLS_CC);
@@ -1564,6 +1566,7 @@
                                                zend_error(E_ERROR, "Call to undefined function:  %s()", function_name->value.str.val);
                                        }
                                        zval_dtor(&tmp);
+                                        function->common.class_name = class_name;
                                        EX(fbc) = function;
overloaded_function_call_cont:
                                        FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
@@ -1955,11 +1958,29 @@
                                NEXT_OPCODE();
                        case ZEND_FETCH_CONSTANT:
                                if (!zend_get_constant(EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.len, &EX(Ts)[EX(opline)->result.u.var].tmp_var TSRMLS_CC)) {
+                                       /*if (!strcmp(EX(opline)->op1.u.constant.value.str.val,"__FUNCTION__")) {
+                                                char *function_name = get_active_function_name(TSRMLS_C);
+                                                if (!function_name) function_name ="";
+ EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.val = function_name;
+ EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.len = strlen(function_name);
+ EX(Ts)[EX(opline)->result.u.var].tmp_var.type = IS_STRING;
+ zval_copy_ctor(&EX(Ts)[EX(opline)->result.u.var].tmp_var);
+                                       } else */
+                                       if (!strcmp(EX(opline)->op1.u.constant.value.str.val,"__CLASS__")) {
+                                                char *class_name = get_active_class_name(TSRMLS_C);
+                                                if (!class_name) class_name ="";
+ EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.val = class_name;
+ EX(Ts)[EX(opline)->result.u.var].tmp_var.value.str.len = strlen(class_name);
+ EX(Ts)[EX(opline)->result.u.var].tmp_var.type = IS_STRING;
+ zval_copy_ctor(&EX(Ts)[EX(opline)->result.u.var].tmp_var);
+                                        } else {
+
                                        zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.val); EX(Ts)[EX(opline)->result.u.var].tmp_var = EX(opline)->op1.u.constant; zval_copy_ctor(&EX(Ts)[EX(opline)->result.u.var].tmp_var);
+                                        }
                                }
                                NEXT_OPCODE();
                        case ZEND_INIT_ARRAY:
diff -b -B -r -u php-4.2.0RC2/Zend/zend_execute.h ALAN_Zend/zend_execute.h
--- php-4.2.0RC2/Zend/zend_execute.h    Sun Jan  6 23:21:09 2002
+++ ALAN_Zend/zend_execute.h    Fri Apr  5 17:26:04 2002
@@ -133,6 +133,7 @@ /* services */ ZEND_API char *get_active_function_name(TSRMLS_D); +ZEND_API char *get_active_class_name(TSRMLS_D); ZEND_API char *zend_get_executed_filename(TSRMLS_D); ZEND_API uint zend_get_executed_lineno(TSRMLS_D); ZEND_API zend_bool zend_is_executing(TSRMLS_D); diff -b -B -r -u php-4.2.0RC2/Zend/zend_execute_API.c ALAN_Zend/zend_execute_API.c
--- php-4.2.0RC2/Zend/zend_execute_API.c        Sun Jan  6 23:21:09 2002
+++ ALAN_Zend/zend_execute_API.c        Fri Apr  5 17:26:04 2002
@@ -218,6 +218,7 @@ ZEND_API char *get_active_function_name(TSRMLS_D) { +
        switch(EG(function_state_ptr)->function->type) {
                case ZEND_USER_FUNCTION: {
                                char *function_name = ((zend_op_array *) EG(function_state_ptr)->function)->function_name;
@@ -237,6 +238,28 @@
        }
} + +ZEND_API char *get_active_class_name(TSRMLS_D) +{ +
+        switch(EG(function_state_ptr)->function->type) {
+               case ZEND_USER_FUNCTION: {
+                               char *class_name = ((zend_op_array *) EG(function_state_ptr)->function)->class_name;
+
+                               if (class_name) {
+                                       return class_name;
+                               } else {
+                                       return "main";
+                               }
+                       }
+                       break;
+               case ZEND_INTERNAL_FUNCTION:
+                       return ((zend_internal_function *) EG(function_state_ptr)->function)->class_name;
+                       break;
+               default:
+                       return NULL;
+       }
+} ZEND_API char *zend_get_executed_filename(TSRMLS_D) { -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php


« previous php.dev (#82128) next »