internals:engine

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
internals:engine [2010/04/20 10:41]
derick Moved FAQ here for now
internals:engine [2017/09/22 13:28] (current)
Line 5: Line 5:
   * each op_array has an array of literals (constant values)   * each op_array has an array of literals (constant values)
   * opocde operands don't contain zval directly any more but points to thistable instead   * opocde operands don't contain zval directly any more but points to thistable instead
-  * during compilation they are accessible by index e.gop_array->​literals[opline->​op1.constant].constant +  * during compilation they are accessible by index e.g: <​code>​op_array->​literals[opline->​op1.constant].constant</​code>​ 
-  * the pass_two() changes indexes into pointers so during execution they are accessible by opline->​op1.zv+  * the pass_two() changes indexes into pointers so during execution they are accessible by: <​code>​opline->​op1.zv</​code>​
  
 +===== Objects =====
 +See [[internals:​engine:​objects|here]].
  
 ===== FAQ ===== ===== FAQ =====
Line 24: Line 26:
  
  
-==== Throwing Exceptions ​on a 64bit Architecture ​====+==== Memory Management ==== 
 + 
 +  [12:00pm] scoates: ok.. last question for now, I think: should I explicitly destroy ​on RSHUTDOWN, or let the non-persistent flag take care of that? 
 +  [12:00pm] johannes_: always cleanup yourself 
 + 
 +Note here: while MM shutdown will take care of all allocated memory, it won't run any dtors etc., that's why it is important to clean up the resources properly - otherwise external dependencies can be messed up. And of course you'd get leaks reported in the debug mode.  
 + 
 +==== Causes for crashes ==== 
 + 
 +=== Throwing Exceptions ​===
  
 If throwing exceptions results in a segmentation fault on 64bit systems only, then be sure that you have: If throwing exceptions results in a segmentation fault on 64bit systems only, then be sure that you have:
Line 31: Line 42:
 (Remark: This header is always needed. The segfault might be caused by the fact, that C defaults the return value and parameters of undefined parameters to int. In cases where pointers and/or long data types are needed this might be wrong so a wrong function call is being made. A good compiler should give a warning. --johannes) (Remark: This header is always needed. The segfault might be caused by the fact, that C defaults the return value and parameters of undefined parameters to int. In cases where pointers and/or long data types are needed this might be wrong so a wrong function call is being made. A good compiler should give a warning. --johannes)
  
-==== Not yet categorized ​====+==== Hashes ​====
   [11:58am] scoates: what's the difference between zend_hash_[add] and zend_hash_quick_[add] ?   [11:58am] scoates: what's the difference between zend_hash_[add] and zend_hash_quick_[add] ?
   [11:58am] scoates: removal of gofaster loops? (-:   [11:58am] scoates: removal of gofaster loops? (-:
   [11:58am] Derick: with the 2nd one you can provide an already calculated hash-list index   [11:58am] Derick: with the 2nd one you can provide an already calculated hash-list index
-  [11:58am] Derick: plus some spaces ​ 
  
   [11:59am] scoates: and the hashtable will automatically grow on _add, right? the length passed to init is just a hint?   [11:59am] scoates: and the hashtable will automatically grow on _add, right? the length passed to init is just a hint?
   [11:59am] johannes_: right   [11:59am] johannes_: right
 +===== Unsorted =====
  
-  [12:00pm] scoates: ok.. last question for now, think: should I explicitly destroy on RSHUTDOWN, or let the non-persistent flag take care of that? +Add your random stuff here. I'll move it/update it/fix it (Derick)
-  [12:00pm] johannes_: always cleanup yourself +
-  [12:02pm] Derick: just like mommy told you +
-  [12:​02pm] ​Derick: :)+
  
-Note herewhile MM shutdown ​will take care of all allocated memory, it won'​t ​run any dtors etc., that's why it is important to clean up the resources properly ​otherwise external dependencies ​can be messed upAnd of course ​you'd get leaks reported in the debug mode+How to get %%__LINE__ and __FILE__%%?​ 
 +  * zend_get_executed_filename() and zend_get_executed_lineno() 
 + 
 +How do I detect the SAPI? 
 +  * The fastest way [to detect CLI] would beif (sapi_module.phpinfo_as_text) { ... } 
 +  * sapi_module is a true global, not a TSRM protected one 
 +  * sapi_module.name and sapi_module.pretty_name contain the name as char* 
 +  * sapi_module.phpinfo_as_text is a flag which can be set by different SAPIs to request text only phpinfo() output, currently only CLI and embed do that afaik, CGI does not. 
 + 
 + 
 +==== Extension Globals ===== 
 + 
 +To use extension globals (which are either true globals or thread local globals, depending on whether ZTS is enabled), follow these steps: 
 + 
 +- In php_extname.h,​ declare which global variables you need with: 
 + 
 +<​code>​ 
 +ZEND_BEGIN_MODULE_GLOBALS(extname) 
 + int var1;​ 
 + char *var2;​ 
 + .... 
 +ZEND_END_MODULE_GLOBALS(extname) 
 +</​code>​  
 + 
 +This will declare a structure (typedef'​d to zend_extname_globals) that will hold all your globals. 
 + 
 +- In php_extname.hadd <​code>​ZEND_EXTERN_MODULE_GLOBALS(extname);</​code>​. This will produce an allusion that will allow you to access the globals from every compile unit that includes php_extname.h In particular, this produces an allusion to an integer named extname_globals_id in ZTS builds or directly to a zend_extname_globals named extname_globals in non-ZTS builds. 
 + 
 +- In php_extname.h,​ define a macro named EXTNAME_G, like this: 
 +<​code>​ 
 +#ifdef ZTS 
 +# define EXTNAME_G(v) TSRMG(extname_globals_id,​ zend_extname_globals *, v) 
 +#else 
 +# define EXTNAME_G(v) (extname_globals.v) 
 +#endif 
 +</​code>​ 
 + 
 +This will allow you to access the globals in a consistent manner in both ZTS and non-ZTS builds, like this: 
 + 
 +<​code>​EXTNAME_G(var1)</​code>​ 
 + 
 +- Now that you have declared the type that aggregates the globals and the variable that holds the globals, you must define the globals. In extname.c, add 
 + 
 +<​code>​ZEND_DECLARE_MODULE_GLOBALS(extname);</​code>​ 
 + 
 +This produces a tentative definition of extname_globals_id or extname_globals (depending on whether ​it's a ZTS or non-ZTS build). 
 + 
 +- If you needn'​t ​do any startup operations on your variables, you would already have function extension globals in non-ZTS buildsTipicallyyou will also want to initialize some extension globals (for instance, to allocate some memory for the var2 extension global above) -- this is done with globals constructors and destructors. To make it work in ZTS builds and allow such operations, add the following to your zend_module_entry:​ 
 + 
 +<​code>​ 
 +zend_module_entry extname_module_entry = { 
 + ... 
 + ZEND_MODULE_INFO_N(extname),​ 
 + PHP_EXTNAME_VERSION,​ 
 + ZEND_MODULE_GLOBALS(extname),​ 
 + ZEND_MODULE_GLOBALS_CTOR_N(extname),​ //may be NULL 
 + ZEND_MODULE_GLOBALS_DTOR_N(extname),​ //may be NULL 
 + ... 
 +
 +</​code>​ 
 + 
 +Note: do not use ZEND_INIT_MODULE_GLOBALS/​ts_allocate_id. If used a shared extension, they will provoke an attempt to call the destructor after the module has been unloaded! Also, for all that is holy, do NOT initialize globals on MINIT (EXTNAME_G(var_ptr) = NULL), that won't work correctly in ZTS as it won't initialize ​the value in all threads. 
 + 
 +Now define the constructor and destructor functions:​ 
 + 
 +<​code>​ 
 +ZEND_MODULE_GLOBALS_CTOR_D(extname) 
 +
 + extname_globals->​arg2 = pemalloc(1024,​ 1); 
 +
 + 
 +ZEND_MODULE_GLOBALS_DTOR_D(extname) 
 +
 + pefree(extname_globals->​arg2,​ 1); 
 +
 +</​code>​ 
 + 
 +The globals constructor and destructor are NOT execute per-request,​ they are part of the module startup/​shutdown. The globals ​can store data across requestsIf you need to do per-request operations to the globals, use module-activate and module-deactivate callbacks.
  
 +Note: ZEND_MODULE_GLOBALS_CTOR_D will declare a function as receiving a zend_extname_globals*,​ not void* and zend_module_entry is supposed to contain a function pointer type that receives void*. I think this violates the C standard (the declarations are incompatible),​ but should however by safe since the arguments have the same size.
internals/engine.1271760060.txt.gz · Last modified: 2017/09/22 13:28 (external edit)