Option 4:
Include fetchtype and subelement during runtime JIT callback allowing
JIT callback to only do work necessary to prepare for the read/write
call being performed.
e.g.
int php_example_jit_callback(int str_type, zstr str, int str_len,
int stage, zval *container, int fetch_type, zval *element);
Where str_type/str/str_len indicate the name of the variable being
JITed, stage is one of COMPILETIME or RUNTIME, container is the
autoglobal itself.
Fetch_type is ZEND_FETCH_(DIM_|OBJ_)?_(R|W|RW), and element is the
specific property/offset (only applicable for DIM/OBJ fetches, NULL for
plain fetch.
Advantages: Gives maximum flexibility to the implementation. In the
case of http request encoding, it allows the decoder to differentiate
between requests for a single element and fetches which want to retreive
the entire array (e.g. foreach).
Disadvantages: Adds a lot of complexity to the fetching of autoglobals
and qand effectively doubles the amount of callback work being done for
autoglobal objects. Will also confuse implementers on what the
difference between this fetch callback is and the
(read|write)_(dimension|property) callbacks used by objects.
Okay, in attempting an implementation of this, I got reminded
none-too-gently by the engine that it's not quite as simple as I'd
remembered:
<?php
$g = $_GET;
$f = $_POST['foo'];
?>
compiled vars: !0 = $g, !1 = $f
line # op fetch operands
----------------------------------------------
2 0 FETCH_R global $0, '_GET'
1 ASSIGN $1, !0, $0
3 2 FETCH_R global $2, '_POST'
3 FETCH_DIM_R $3, $2, 'foo'
4 ASSIGN $4, !1, $3
Autoglobals aren't treated as CVs (as, for some reason, I was thinking
they were) so at the time of initial fetch, it's difficult to know if
the whole var is being fetched (as in the case of the line 2 assignment,
or if it's being fetched so that a subelement can be fetched later (as
in the case of the line 3 assignment).
The solution I'm tempted to pursue for this is to back up yet another
step and make autoglobals be CVs by extending the zend_compiled_variable
struct to contain a flag indicating how the var should be fetched (the
determination for which happens during fetch_simple_var during the
compilation. This would then yield an opcode stack like the following:
compiled vars: !0* = $_GET, !1 = $g, !2* = $_POST, !3 = $f
line # op fetch operands
----------------------------------------------
2 0 ASSIGN $0, !1, !0*
3 1 FETCH_DIM_R $1, !2*, 'foo'
2 ASSIGN $2, !3, $1
(The * notation indicating that cv->fetch_type == ZEND_FETCH_GLOBAL)
Once that's applied (basicly as a stand-alone speed improvement, since
globals are turned into CV fetches), the RT-JIT can be done using the
plan I'd already formulated for Option 4. *THEN* we can apply
runtime-JIT to http input encoding detection.
Just keeping the conversation in the open and hoping anyone which
critiques will voice them sooner rather than later.
-Sara
Two steps forward, one step back.
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php