]> granicus.if.org Git - php/commitdiff
Optimized require_once/include_once (eliminated fopen() on second usage)
authorDmitry Stogov <dmitry@php.net>
Mon, 15 May 2006 15:31:50 +0000 (15:31 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 15 May 2006 15:31:50 +0000 (15:31 +0000)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index f3d9b6a76bd2de74dc8174d68cc2a7a7c121f887..b44e4517be4294fc2dcfa0d116a97939bd19db3e 100644 (file)
@@ -38,6 +38,9 @@
 #include "zend_vm.h"
 #include "zend_unicode.h"
 
+/* Virtual current working directory support */
+#include "tsrm_virtual_cwd.h"
+
 #define _CONST_CODE  0
 #define _TMP_CODE    1
 #define _VAR_CODE    2
index 5889bcfc0eab2fc760210c6b2318b589d4394804..9901ab06fc79ce7cc7e9a99ab4351620eba26285 100644 (file)
@@ -2761,16 +2761,28 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
        switch (Z_LVAL(opline->op2.u.constant)) {
                case ZEND_INCLUDE_ONCE:
                case ZEND_REQUIRE_ONCE: {
-                               int dummy = 1;
                                zend_file_handle file_handle;
+                               char cwd[MAXPATHLEN];
+                               cwd_state state;
 
-                               if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
+                               if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
+                                       cwd[0] = '\0';
+                               } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
+                                       cwd[0] = '\0';
+                               }
+
+                               state.cwd_length = strlen(cwd);
+                               state.cwd = zend_strndup(cwd, state.cwd_length);
 
+                               if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
+                                   zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) {
+                                       failure_retval=1;
+                               } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
                                        if (!file_handle.opened_path) {
                                                file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
                                        }
 
-                                       if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
+                                       if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
                                                new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
                                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
                                        } else {
@@ -2784,7 +2796,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
                                                zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
                                        }
                                }
-                               break;
+                               free(state.cwd);
                        }
                        break;
                case ZEND_INCLUDE:
index 8535ad8ea421ca0d5afb950912871411ba205f32..3b24001536ecf6c31eb2fdf22bee7ffa7909a6dc 100644 (file)
@@ -659,6 +659,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
                unsigned int function_name_strlen;
                zend_bool is_const = (IS_CONST == IS_CONST);
 
+
                if (is_const) {
                        function_name_strval = Z_UNIVAL(opline->op2.u.constant);
                        function_name_strlen = Z_UNILEN(opline->op2.u.constant);
@@ -1192,6 +1193,8 @@ static int ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
        zval *class_name;
 
+
+
        if (IS_CV == IS_UNUSED) {
                EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
                ZEND_VM_NEXT_OPCODE();
@@ -1880,16 +1883,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        switch (Z_LVAL(opline->op2.u.constant)) {
                case ZEND_INCLUDE_ONCE:
                case ZEND_REQUIRE_ONCE: {
-                               int dummy = 1;
                                zend_file_handle file_handle;
+                               char cwd[MAXPATHLEN];
+                               cwd_state state;
+
+                               if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
+                                       cwd[0] = '\0';
+                               } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
+                                       cwd[0] = '\0';
+                               }
 
-                               if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
+                               state.cwd_length = strlen(cwd);
+                               state.cwd = zend_strndup(cwd, state.cwd_length);
 
+                               if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
+                                   zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) {
+                                       failure_retval=1;
+                               } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
                                        if (!file_handle.opened_path) {
                                                file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
                                        }
 
-                                       if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
+                                       if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
                                                new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
                                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
                                        } else {
@@ -1903,7 +1918,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
                                        }
                                }
-                               break;
+                               free(state.cwd);
                        }
                        break;
                case ZEND_INCLUDE:
@@ -2013,8 +2028,8 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                }
                                        }
                                }
-                 ex = ex->prev_execute_data;
-                 } while (ex && ex->symbol_table == target_symbol_table);
+                               ex = ex->prev_execute_data;
+                       } while (ex && ex->symbol_table == target_symbol_table);
                }
        }
 
@@ -4376,16 +4391,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        switch (Z_LVAL(opline->op2.u.constant)) {
                case ZEND_INCLUDE_ONCE:
                case ZEND_REQUIRE_ONCE: {
-                               int dummy = 1;
                                zend_file_handle file_handle;
+                               char cwd[MAXPATHLEN];
+                               cwd_state state;
+
+                               if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
+                                       cwd[0] = '\0';
+                               } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
+                                       cwd[0] = '\0';
+                               }
 
-                               if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
+                               state.cwd_length = strlen(cwd);
+                               state.cwd = zend_strndup(cwd, state.cwd_length);
 
+                               if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
+                                   zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) {
+                                       failure_retval=1;
+                               } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
                                        if (!file_handle.opened_path) {
                                                file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
                                        }
 
-                                       if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
+                                       if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
                                                new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
                                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
                                        } else {
@@ -4399,7 +4426,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
                                        }
                                }
-                               break;
+                               free(state.cwd);
                        }
                        break;
                case ZEND_INCLUDE:
@@ -4509,8 +4536,8 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                }
                                        }
                                }
-                 ex = ex->prev_execute_data;
-                 } while (ex && ex->symbol_table == target_symbol_table);
+                               ex = ex->prev_execute_data;
+                       } while (ex && ex->symbol_table == target_symbol_table);
                }
        }
 
@@ -7469,16 +7496,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        switch (Z_LVAL(opline->op2.u.constant)) {
                case ZEND_INCLUDE_ONCE:
                case ZEND_REQUIRE_ONCE: {
-                               int dummy = 1;
                                zend_file_handle file_handle;
+                               char cwd[MAXPATHLEN];
+                               cwd_state state;
+
+                               if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
+                                       cwd[0] = '\0';
+                               } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
+                                       cwd[0] = '\0';
+                               }
 
-                               if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
+                               state.cwd_length = strlen(cwd);
+                               state.cwd = zend_strndup(cwd, state.cwd_length);
 
+                               if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
+                                   zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) {
+                                       failure_retval=1;
+                               } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
                                        if (!file_handle.opened_path) {
                                                file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
                                        }
 
-                                       if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
+                                       if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
                                                new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
                                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
                                        } else {
@@ -7492,7 +7531,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
                                        }
                                }
-                               break;
+                               free(state.cwd);
                        }
                        break;
                case ZEND_INCLUDE:
@@ -7602,8 +7641,8 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                }
                                        }
                                }
-                 ex = ex->prev_execute_data;
-                 } while (ex && ex->symbol_table == target_symbol_table);
+                               ex = ex->prev_execute_data;
+                       } while (ex && ex->symbol_table == target_symbol_table);
                }
        }
 
@@ -20094,16 +20133,28 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        switch (Z_LVAL(opline->op2.u.constant)) {
                case ZEND_INCLUDE_ONCE:
                case ZEND_REQUIRE_ONCE: {
-                               int dummy = 1;
                                zend_file_handle file_handle;
+                               char cwd[MAXPATHLEN];
+                               cwd_state state;
 
-                               if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
+                               if (IS_ABSOLUTE_PATH(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename))) {
+                                       cwd[0] = '\0';
+                               } else if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
+                                       cwd[0] = '\0';
+                               }
+
+                               state.cwd_length = strlen(cwd);
+                               state.cwd = zend_strndup(cwd, state.cwd_length);
 
+                               if (!virtual_file_ex(&state, Z_STRVAL_P(inc_filename), NULL, 1) &&
+                                   zend_hash_exists(&EG(included_files), state.cwd, state.cwd_length+1)) {
+                                       failure_retval=1;
+                               } else if (SUCCESS == zend_stream_open(Z_STRVAL_P(inc_filename), &file_handle TSRMLS_CC)) {
                                        if (!file_handle.opened_path) {
                                                file_handle.opened_path = estrndup(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename));
                                        }
 
-                                       if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
+                                       if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1)==SUCCESS) {
                                                new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
                                                zend_destroy_file_handle(&file_handle TSRMLS_CC);
                                        } else {
@@ -20117,7 +20168,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
                                        }
                                }
-                               break;
+                               free(state.cwd);
                        }
                        break;
                case ZEND_INCLUDE:
@@ -20227,8 +20278,8 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                                }
                                        }
                                }
-                 ex = ex->prev_execute_data;
-                 } while (ex && ex->symbol_table == target_symbol_table);
+                               ex = ex->prev_execute_data;
+                       } while (ex && ex->symbol_table == target_symbol_table);
                }
        }