EG
在PHP的源码中,大量充斥着EG、PG这种宏定义。在zend_globals_macros.h中,可以看到EG的定义:
#ifdef ZTS
# define EG(v) TSRMG(executor_globals_id, zend_executor_globals *, v)
#else
# define EG(v) (executor_globals.v)
extern ZEND_API zend_executor_globals executor_globals;
#endif
ZTS表示线程安全。比如使用EG(function_table)的话,那么就会使用executor_globals.function_table。而zend_executor_globals在该文件中,也可以看到:
typedef struct _zend_executor_globals zend_executor_globals;
可以看到zend_executor_globals只是_zend_executor_globals的一个别名。而_zend_executor_globals则是在zend_globals.h中被定义:
struct _zend_executor_globals {
zval **return_value_ptr_ptr;
zval uninitialized_zval;
zval *uninitialized_zval_ptr;
zval error_zval;
zval *error_zval_ptr;
zend_ptr_stack arg_types_stack;
/* symbol table cache */
HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
HashTable **symtable_cache_limit;
HashTable **symtable_cache_ptr;
zend_op **opline_ptr;
HashTable *active_symbol_table;
HashTable symbol_table; /* main symbol table */
HashTable included_files; /* files already included */
JMP_BUF *bailout;
int error_reporting;
int orig_error_reporting;
int exit_status;
zend_op_array *active_op_array;
HashTable *function_table; /* function symbol table */
HashTable *class_table; /* class table */
HashTable *zend_constants; /* constants table */
zend_class_entry *scope;
zend_class_entry *called_scope; /* Scope of the calling class */
zval *This;
long precision;
int ticks_count;
zend_bool in_execution;
HashTable *in_autoload;
zend_function *autoload_func;
zend_bool full_tables_cleanup;
/* for extended information support */
zend_bool no_extensions;
#ifdef ZEND_WIN32
zend_bool timed_out;
OSVERSIONINFOEX windows_version_info;
#endif
HashTable regular_list;
HashTable persistent_list;
zend_vm_stack argument_stack;
int user_error_handler_error_reporting;
zval *user_error_handler;
zval *user_exception_handler;
zend_stack user_error_handlers_error_reporting;
zend_ptr_stack user_error_handlers;
zend_ptr_stack user_exception_handlers;
zend_error_handling_t error_handling;
zend_class_entry *exception_class;
/* timeout support */
int timeout_seconds;
int lambda_count;
HashTable *ini_directives;
HashTable *modified_ini_directives;
zend_ini_entry *error_reporting_ini_entry;
zend_objects_store objects_store;
zval *exception, *prev_exception;
zend_op *opline_before_exception;
zend_op exception_op[3];
struct _zend_execute_data *current_execute_data;
struct _zend_module_entry *current_module;
zend_property_info std_property_info;
zend_bool active;
zend_op *start_op;
void *saved_fpu_cw_ptr;
#if XPFPA_HAVE_CW
XPFPA_CW_DATATYPE saved_fpu_cw;
#endif
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
};
所以可以得知,EG宏的主要功能是查找全局变量_zend_executor_globals中的成员。比如EG(function_table)便是查找_zend_executor_globals中的function_table成员。
CG
类似上面的EG。这里的CG也不难得出是引用某个全局的变量。在php源码中,通常在在某个宏是以G结束的,则是使用某个全局的变量。
#ifdef ZTS
# define CG(v) TSRMG(compiler_globals_id, zend_compiler_globals *, v)
int zendparse(void *compiler_globals);
#else
# define CG(v) (compiler_globals.v)
extern ZEND_API struct _zend_compiler_globals compiler_globals;
int zendparse(void);
#endif
_zend_compiler_globals也是在zend_globals.h中定义:
struct _zend_compiler_globals {
zend_stack bp_stack;
zend_stack switch_cond_stack;
zend_stack foreach_copy_stack;
zend_stack object_stack;
zend_stack declare_stack;
zend_class_entry *active_class_entry;
/* variables for list() compilation */
zend_llist list_llist;
zend_llist dimension_llist;
zend_stack list_stack;
zend_stack function_call_stack;
char *compiled_filename;
int zend_lineno;
char *heredoc;
int heredoc_len;
zend_op_array *active_op_array;
HashTable *function_table; /* function symbol table */
HashTable *class_table; /* class table */
HashTable filenames_table;
HashTable *auto_globals;
zend_bool parse_error;
zend_bool in_compilation;
zend_bool short_tags;
zend_bool asp_tags;
zend_declarables declarables;
zend_bool unclean_shutdown;
zend_bool ini_parser_unbuffered_errors;
zend_llist open_files;
long catch_begin;
struct _zend_ini_parser_param *ini_parser_param;
int interactive;
zend_uint start_lineno;
zend_bool increment_lineno;
znode implementing_class;
zend_uint access_type;
char *doc_comment;
zend_uint doc_comment_len;
zend_uint compiler_options; /* set of ZEND_COMPILE_* constants */
zval *current_namespace;
HashTable *current_import;
zend_bool in_namespace;
zend_bool has_bracketed_namespaces;
zend_compiler_context context;
zend_stack context_stack;
/* interned strings */
char *interned_strings_start;
char *interned_strings_end;
char *interned_strings_top;
char *interned_strings_snapshot_top;
HashTable interned_strings;
const zend_encoding **script_encoding_list;
size_t script_encoding_list_size;
zend_bool multibyte;
zend_bool detect_unicode;
zend_bool encoding_declared;
#ifdef ZTS zval ***static_members_table; int last_static_member; #endif };