You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: php7/internal_types/functions.html
+1Lines changed: 1 addition & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -48,6 +48,7 @@ <h1>Functions<a class="headerlink" href="#functions" title="Link to this heading
48
48
<liclass="toctree-l2"><aclass="reference internal" href="functions/callables.html#structure-of-zend-fcall-info">Structure of <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcall_info</span></code></a></li>
49
49
<liclass="toctree-l2"><aclass="reference internal" href="functions/callables.html#structure-of-zend-fcall-info-cache">Structure of <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcall_info_cache</span></code></a></li>
50
50
<liclass="toctree-l2"><aclass="reference internal" href="functions/callables.html#zend-engine-api-for-callables">Zend Engine API for callables</a></li>
51
+
<liclass="toctree-l2"><aclass="reference internal" href="functions/callables.html#new-fci-fcc-api-in-php-8-3-0">New FCI/FCC API in PHP 8.3.0</a></li>
<p>Prior to PHP 7.3.0 there existed an <codeclass="docutils literal notranslate"><spanclass="pre">initialized</span></code> field. Now an FCC is considered initialized when
122
122
<codeclass="docutils literal notranslate"><spanclass="pre">function_handler</span></code> is set to a non-null pointer.</p>
123
123
</div>
124
+
<divclass="admonition note">
125
+
<pclass="admonition-title">Note</p>
126
+
<p>As of PHP 8.3.0, the FCC holds a <codeclass="docutils literal notranslate"><spanclass="pre">closure</span></code> field and a dedicated API to handle storing userland callables.
127
+
This new API is described below.</p>
128
+
</div>
124
129
<p>The <em>only</em> case where an FCC will be uninitialized is if the function is a trampoline, i.e. when the method
125
130
of a class does not exist but is handled by the magic methods <codeclass="docutils literal notranslate"><spanclass="pre">__call()</span></code>/<codeclass="docutils literal notranslate"><spanclass="pre">__callStatic()</span></code>.
126
131
This is because a trampoline is freed by ZPP as it is a newly allocated <codeclass="docutils literal notranslate"><spanclass="pre">zend_function</span></code> struct with the
@@ -160,9 +165,10 @@ <h2>Zend Engine API for callables<a class="headerlink" href="#zend-engine-api-fo
160
165
<pclass="admonition-title">Warning</p>
161
166
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcall_info_arg*()</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcall_info_call()</span></code> APIs should not be used.
162
167
The <codeclass="docutils literal notranslate"><spanclass="pre">zval</span><spanclass="pre">*args</span></code> parameter does <em>not</em> set the <codeclass="docutils literal notranslate"><spanclass="pre">params</span></code> field of the FCI directly.
163
-
Instead it expect it to be a PHP array (IS_ARRAY zval) containing positional arguments, which will be reallocated
164
-
into a new C array. As the <codeclass="docutils literal notranslate"><spanclass="pre">named_params</span></code> field accepts positional arguments, it is generally better to simply
165
-
assign the HashTable pointer of this argument to this field.
168
+
Instead it expect it to be a PHP array (<codeclass="docutils literal notranslate"><spanclass="pre">IS_ARRAY</span></code> zval) containing positional arguments,
169
+
which will be reallocated into a new C array.
170
+
As the <codeclass="docutils literal notranslate"><spanclass="pre">named_params</span></code> field accepts positional arguments, it is generally better to simply
171
+
assign the <codeclass="docutils literal notranslate"><spanclass="pre">HashTable</span></code> pointer of this argument to this field.
166
172
Moreover, as arguments to a userland call are predetermined and stack allocated it is better to assign the
167
173
<codeclass="docutils literal notranslate"><spanclass="pre">params</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">param_count</span></code> fields directly.</p>
168
174
</div>
@@ -207,6 +213,29 @@ <h2>Zend Engine API for callables<a class="headerlink" href="#zend-engine-api-fo
207
213
<p>If you want to call a method on an object if it exists use the <codeclass="docutils literal notranslate"><spanclass="pre">zend_call_method_if_exists()</span></code> function.</p>
208
214
</div>
209
215
</section>
216
+
<sectionid="new-fci-fcc-api-in-php-8-3-0">
217
+
<h2>New FCI/FCC API in PHP 8.3.0<aclass="headerlink" href="#new-fci-fcc-api-in-php-8-3-0" title="Link to this heading">¶</a></h2>
218
+
<p>PHP 8.3.0 added some new APIs to improve the handling and storage of FCCs and userland callables.
219
+
This was achieved by adding the <codeclass="docutils literal notranslate"><spanclass="pre">closure</span></code> field to the FCC.</p>
220
+
<p>First of all a new <codeclass="docutils literal notranslate"><spanclass="pre">ZEND_FCC_INITIALIZED(fcc)</span></code> macro to check if an FCC is initialized was added,
221
+
this is helper similar to the <codeclass="docutils literal notranslate"><spanclass="pre">ZEND_FCI_INITIALIZED(fci)</span></code> macro.</p>
222
+
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcc_addref()</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcc_dup()</span></code> functions will do all the necessary reference increments
223
+
to safely store an FCC in an internal object.
224
+
The <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcc_equals()</span></code> function, can be used if two FCCs are equal or not, which also supports trampolines.
225
+
The <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcc_dtor()</span></code> function must be used when releasing an FCC that was copied for internal storage.</p>
226
+
<p>If an internal object stores an FCC the <codeclass="docutils literal notranslate"><spanclass="pre">get_gc</span></code> object handler must be defined,
227
+
and add it to the GC buffer via <codeclass="docutils literal notranslate"><spanclass="pre">zend_get_gc_buffer_add_fcc()</span></code>.</p>
228
+
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">zend_get_callable_zval_from_fcc()</span></code> function will create a callable zval that can be returned to userland.</p>
should be used, as it will duplicate the op array of a trampoline.
232
+
The remaining parameters will be used to construct the FCI.</p>
233
+
<divclass="admonition note">
234
+
<pclass="admonition-title">Note</p>
235
+
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">zend_call_function_with_return_value(*fci,</span><spanclass="pre">*fcc,</span><spanclass="pre">zval</span><spanclass="pre">*retval)</span></code> function was also added in PHP 8.3.0
236
+
to replace the usage of <codeclass="docutils literal notranslate"><spanclass="pre">zend_fcall_info_call(fci,</span><spanclass="pre">fcc,</span><spanclass="pre">retval,</span><spanclass="pre">NULL)</span></code>.</p>
0 commit comments