Permalink
Browse files

The patch we promised - redesigned the compilation/execution API:

Advantages:
- Smaller memory footprint for the op arrays
- Slightly faster compilation times (due to saved erealloc() calls and faster zend_op
  initialization)
- include_once() & require_once() share the same file list
- Consistency between include() and require() - this mostly means that return()
  works inside require()'d files just as it does in include() files (it used to
  be meaningless in require()'d files, most of the time (see below))
- Made require() consistent with itself.  Before, if the argument was not a constant
  string, require() took the include() behavior (with return()).
- Removed lots of duplicate code.
Bottom line - require() and include() are very similar now;  require() is simply an include()
which isn't allowed to fail.  Due to the erealloc() calls for large op arrays, require()
didn't end up being any faster than include() in the Zend engine.
  • Loading branch information...
1 parent 609577d commit c06692e9ec92bdbe22e7a4149b5365635c4ad950 @zsuraski zsuraski committed Aug 9, 2000
Showing with 93 additions and 236 deletions.
  1. +4 −6 Zend/zend-parser.y
  2. +23 −138 Zend/zend-scanner.l
  3. +33 −1 Zend/zend.c
  4. +1 −18 Zend/zend_builtin_functions.c
  5. +7 −23 Zend/zend_compile.c
  6. +7 −10 Zend/zend_compile.h
  7. +10 −9 Zend/zend_execute.c
  8. +3 −14 Zend/zend_execute_API.c
  9. +0 −4 Zend/zend_globals.h
  10. +5 −13 Zend/zend_opcode.c
View
@@ -47,7 +47,7 @@
%pure_parser
%expect 4
-%left T_INCLUDE T_INCLUDE_ONCE T_EVAL
+%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
%left ','
%left T_LOGICAL_OR
%left T_LOGICAL_XOR
@@ -105,8 +105,6 @@
%token T_FUNCTION
%token T_CONST
%token T_RETURN
-%token T_REQUIRE
-%token T_REQUIRE_ONCE
%token T_USE
%token T_GLOBAL
%token T_STATIC
@@ -197,9 +195,7 @@ unticked_statement:
| T_ECHO echo_expr_list ';'
| T_INLINE_HTML { do_echo(&$1 CLS_CC); }
| expr ';' { do_free(&$1 CLS_CC); }
- | T_REQUIRE expr ';' { do_require(&$2, 0 CLS_CC); }
- | T_REQUIRE_ONCE use_filename ';' { do_require(&$2, 1 CLS_CC); }
- | T_USE use_filename ';' { use_filename($2.u.constant.value.str.val, $2.u.constant.value.str.len CLS_CC); zval_dtor(&$2.u.constant); }
+ | T_USE use_filename ';' { zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()"); zval_dtor(&$2.u.constant); }
| T_UNSET '(' unset_variables ')' ';'
| T_FOREACH '(' expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
| T_DECLARE { do_declare_begin(CLS_C); } '(' declare_list ')' declare_statement { do_declare_end(CLS_C); }
@@ -720,6 +716,8 @@ internal_functions_in_yacc:
| T_INCLUDE expr { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); }
| T_INCLUDE_ONCE expr { do_include_or_eval(ZEND_INCLUDE_ONCE, &$$, &$2 CLS_CC); }
| T_EVAL '(' expr ')' { do_include_or_eval(ZEND_EVAL, &$$, &$3 CLS_CC); }
+ | T_REQUIRE expr { do_include_or_eval(ZEND_REQUIRE, &$$, &$2 CLS_CC); }
+ | T_REQUIRE_ONCE use_filename { do_include_or_eval(ZEND_REQUIRE_ONCE, &$$, &$2 CLS_CC); }
;
View
@@ -243,7 +243,7 @@ ZEND_API void zend_close_file_handle(zend_file_handle *file_handle CLS_DC)
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
{
- char *file_path;
+ char *file_path=NULL;
#ifndef ZTS
switch (file_handle->type) {
@@ -324,87 +324,55 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
END_EXTERN_C()
-ZEND_API zend_op_array *zend_compile_files(int type CLS_DC, int file_count, ...)
-{
- va_list files;
- zend_op_array *op_array;
-
- va_start(files, file_count);
- op_array = zend_v_compile_files(type CLS_CC, file_count, files);
- va_end(files);
- return op_array;
-}
-
-
-ZEND_API zend_op_array *v_compile_files(int type CLS_DC, int file_count, va_list files)
+ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle CLS_DC)
{
zend_lex_state original_lex_state;
zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
zend_op_array *original_active_op_array = CG(active_op_array);
zend_op_array *retval=NULL;
- int i;
int compiler_result;
- int compiled_files=0;
- int last_file=0;
+ zend_bool compilation_successful=0;
znode retval_znode;
zend_bool original_in_compilation = CG(in_compilation);
- zend_file_handle **file_handles = (zend_file_handle **) do_alloca(file_count * sizeof(zend_file_handle *));
retval_znode.op_type = IS_CONST;
retval_znode.u.constant.type = IS_LONG;
retval_znode.u.constant.value.lval = 1;
retval_znode.u.constant.is_ref = 0;
retval_znode.u.constant.refcount = 1;
- init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE);
save_lexical_state(&original_lex_state CLS_CC);
retval = op_array; /* success oriented */
- for (i=0; i<file_count; i++) {
- file_handles[i] = va_arg(files, zend_file_handle *);
- if (file_handles[i]) {
- last_file = i;
- }
- }
-
- for (i=0; i<file_count; i++) {
- if (!file_handles[i]) {
- continue;
- }
- if (open_file_for_scanning(file_handles[i] CLS_CC)==FAILURE) {
- zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handles[i]->filename);
- } else {
- CG(in_compilation) = 1;
- CG(active_op_array) = op_array;
- compiler_result = zendparse(CLS_C);
- zend_close_file_handle(file_handles[i] CLS_CC);
- if (i == last_file) {
- do_return(&retval_znode, 0 CLS_CC);
- }
- restore_lexical_state(&original_lex_state CLS_CC);
- CG(in_compilation) = original_in_compilation;
- if (compiler_result==1) { /* parser error */
- CG(unclean_shutdown) = 1;
- retval = NULL;
- break;
- }
- compiled_files++;
+ if (open_file_for_scanning(file_handle CLS_CC)==FAILURE) {
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+ compilation_successful=0;
+ } else {
+ init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE CLS_CC);
+ CG(in_compilation) = 1;
+ CG(active_op_array) = op_array;
+ compiler_result = zendparse(CLS_C);
+ zend_close_file_handle(file_handle CLS_CC);
+ do_return(&retval_znode, 0 CLS_CC);
+ restore_lexical_state(&original_lex_state CLS_CC);
+ CG(in_compilation) = original_in_compilation;
+ if (compiler_result==1) { /* parser error */
+ CG(unclean_shutdown) = 1;
+ retval = NULL;
}
+ compilation_successful=1;
}
if (retval) {
- if (compiled_files>0) {
- CG(active_op_array) = original_active_op_array;
+ CG(active_op_array) = original_active_op_array;
+ if (compilation_successful) {
pass_two(op_array);
} else {
- CG(active_op_array) = original_active_op_array;
- destroy_op_array(op_array);
efree(op_array);
retval = NULL;
}
}
- free_alloca(file_handles);
return retval;
}
@@ -435,7 +403,7 @@ zend_op_array *compile_filename(int type, zval *filename CLS_DC ELS_DC)
error_reporting = EG(error_reporting);
EG(error_reporting) = 0;
}
- retval = zend_compile_files(type CLS_CC, 1, &file_handle);
+ retval = zend_compile_file(&file_handle CLS_CC);
if (type==ZEND_REQUIRE) {
EG(error_reporting) = error_reporting;
@@ -496,13 +464,12 @@ zend_op_array *compile_string(zval *source_string CLS_DC)
convert_to_string(&tmp);
source_string = &tmp;
- init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE);
save_lexical_state(&original_lex_state CLS_CC);
if (prepare_string_for_scanning(source_string CLS_CC)==FAILURE) {
- destroy_op_array(op_array);
efree(op_array);
retval = NULL;
} else {
+ init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE CLS_CC);
CG(active_op_array) = op_array;
#ifndef ZTS
BEGIN(ST_IN_SCRIPTING);
@@ -520,7 +487,6 @@ zend_op_array *compile_string(zval *source_string CLS_DC)
do_return(NULL, 0 CLS_CC);
CG(active_op_array) = original_active_op_array;
pass_two(op_array);
- pass_include_eval(op_array);
retval = op_array;
}
}
@@ -531,87 +497,6 @@ zend_op_array *compile_string(zval *source_string CLS_DC)
BEGIN_EXTERN_C()
-int require_filename(char *filename, zend_bool unique CLS_DC)
-{
- zend_file_handle file_handle;
-
- file_handle.type = ZEND_HANDLE_FILENAME;
- file_handle.filename = filename;
- file_handle.free_filename = 0;
- if (require_file(&file_handle, unique CLS_CC)==FAILURE) {
- zend_bailout();
- return FAILURE; /* will never get here */
- }
- return SUCCESS;
-}
-
-
-int use_filename(char *filename, uint filename_length CLS_DC)
-{
- zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()");
- return FAILURE;
-
-#if 0
- zend_file_handle file_handle;
-
- file_handle.filename = (char *) emalloc(filename_length + zend_uv.import_use_extension_length);
- memcpy(file_handle.filename, filename, filename_length);
- memcpy(file_handle.filename+filename_length, zend_uv.import_use_extension, zend_uv.import_use_extension_length);
- file_handle.filename[filename_length+zend_uv.import_use_extension_length] = 0;
- file_handle.free_filename = 1;
-
- file_handle.type = ZEND_HANDLE_FILENAME;
- if (require_file(&file_handle, 1 CLS_CC)==FAILURE) {
- efree(file_handle.filename);
- zend_bailout();
- return FAILURE; /* will never get here */
- }
- return SUCCESS;
-#endif
-}
-
-
-int require_file(zend_file_handle *file_handle, zend_bool unique CLS_DC)
-{
- zend_lex_state original_lex_state;
- int compiler_result;
-
- save_lexical_state(&original_lex_state CLS_CC);
- if (open_file_for_scanning(file_handle CLS_CC)==FAILURE) {
- zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
- return FAILURE;
- }
- if (file_handle->opened_path) {
- if (unique) {
- zend_file_handle *pfh;
-
- if (zend_hash_add(&CG(used_files), file_handle->opened_path, strlen(file_handle->opened_path)+1, file_handle, sizeof(zend_file_handle), (void **) &pfh)==FAILURE) {
- zend_close_file_handle(file_handle CLS_CC);
- restore_lexical_state(&original_lex_state CLS_CC);
- return SUCCESS;
- } else {
- /* pfh is a copy we only save for get_used_files() */
- pfh->type = ZEND_HANDLE_FILENAME;
- if (pfh->filename) {
- pfh->filename = estrdup(pfh->filename);
- pfh->free_filename = 1;
- }
- if (pfh->opened_path) {
- pfh->opened_path = strdup(pfh->opened_path);
- }
- }
- }
- }
- compiler_result = zendparse(CLS_C);
- zend_close_file_handle(file_handle CLS_CC);
- restore_lexical_state(&original_lex_state CLS_CC);
- if (compiler_result==1) {
- zend_bailout();
- }
- return SUCCESS;
-}
-
-
int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini)
{
zend_lex_state original_lex_state;
View
@@ -357,7 +357,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
zend_get_ini_entry_p = utility_functions->get_ini_entry;
zend_ticks_function = utility_functions->ticks_function;
- zend_v_compile_files = v_compile_files;
+ zend_compile_file = compile_file;
zend_execute = execute;
zend_startup_extensions();
@@ -692,3 +692,35 @@ ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ..
va_end(args);
#endif
}
+
+
+ZEND_API int zend_execute_scripts(int type CLS_DC ELS_DC, int file_count, ...)
+{
+ va_list files;
+ int i;
+ zend_file_handle *file_handle;
+
+ va_start(files, file_count);
+ for (i=0; i<file_count; i++) {
+ file_handle = va_arg(files, zend_file_handle *);
+ if (!file_handle) {
+ continue;
+ }
+ EG(active_op_array) = zend_compile_file(file_handle CLS_CC);
+ if (EG(active_op_array)) {
+ zend_execute(EG(active_op_array) ELS_CC);
+ zval_ptr_dtor(EG(return_value_ptr_ptr));
+ EG(return_value_ptr_ptr) = &EG(global_return_value_ptr);
+ EG(global_return_value_ptr) = NULL;
+ destroy_op_array(EG(active_op_array));
+ efree(EG(active_op_array));
+ } else if (type==ZEND_REQUIRE) {
+ va_end(files);
+ return FAILURE;
+ }
+ }
+ va_end(files);
+
+ return SUCCESS;
+}
+
@@ -47,7 +47,6 @@ static ZEND_FUNCTION(leak);
#ifdef ZEND_TEST_EXCEPTIONS
static ZEND_FUNCTION(crash);
#endif
-static ZEND_FUNCTION(get_required_files);
static ZEND_FUNCTION(get_included_files);
static ZEND_FUNCTION(is_subclass_of);
static ZEND_FUNCTION(get_class_vars);
@@ -91,8 +90,8 @@ static zend_function_entry builtin_functions[] = {
#ifdef ZEND_TEST_EXCEPTIONS
ZEND_FE(crash, NULL)
#endif
- ZEND_FE(get_required_files, NULL)
ZEND_FE(get_included_files, NULL)
+ ZEND_FALIAS(get_required_files, get_included_files, NULL)
ZEND_FE(is_subclass_of, NULL)
ZEND_FE(get_class_vars, NULL)
ZEND_FE(get_object_vars, NULL)
@@ -713,22 +712,6 @@ static int copy_import_use_file(zend_file_handle *fh, zval *array)
}
-/* {{{ proto array get_required_files(void)
- Returns an array with the file names that were require_once()'d */
-ZEND_FUNCTION(get_required_files)
-{
- CLS_FETCH();
-
- if (ZEND_NUM_ARGS() != 0) {
- ZEND_WRONG_PARAM_COUNT();
- }
-
- array_init(return_value);
- zend_hash_apply_with_argument(&CG(used_files), (apply_func_arg_t) copy_import_use_file, return_value);
-}
-/* }}} */
-
-
/* {{{ proto array get_included_files(void)
Returns an array with the file names that were include_once()'d */
ZEND_FUNCTION(get_included_files)
Oops, something went wrong.

0 comments on commit c06692e

Please sign in to comment.