summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_gen.php
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_vm_gen.php')
-rwxr-xr-xZend/zend_vm_gen.php34
1 files changed, 34 insertions, 0 deletions
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 2c2a64b294..e3dceaa829 100755
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -793,6 +793,7 @@ function gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec=null)
"/opline->extended_value\s*&\s*~\s*ZEND_ISEMPTY/" => isset($extra_spec['ISSET']) ?
($extra_spec['ISSET'] == 0 ? "\\0" : "opline->extended_value")
: "\\0",
+ "/IS_OBSERVER/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "1" : "0",
"/OBSERVER_FCALL_BEGIN_HANDLERS\(\s*(.*)\s*\)/" => isset($extra_spec['OBSERVER']) ?
($extra_spec['OBSERVER'] == 0 ? "" : "zend_observer_maybe_fcall_call_begin(\\1)")
: "",
@@ -1004,6 +1005,8 @@ function is_inline_hybrid_handler($name, $hot, $op1, $op2, $extra_spec) {
function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno, $opcode, $extra_spec = null, &$switch_labels = array()) {
global $definition_file, $prefix, $opnames, $gen_order;
+ static $used_observer_handlers = array();
+
if (isset($opcode['alias']) && ($spec || $kind != ZEND_VM_KIND_SWITCH)) {
return;
}
@@ -1037,6 +1040,26 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno,
}
}
+ /* Skip all specialization for OBSERVER handlers */
+ if (isset($extra_spec["OBSERVER"]) && $extra_spec["OBSERVER"] == 1) {
+ if (isset($extra_spec["RETVAL"])) {
+ if ($extra_spec["RETVAL"] == 0) {
+ unset($extra_spec["RETVAL"]);
+ } else {
+ return;
+ }
+ }
+ if ($op1 != "ANY" || $op2 != "ANY") {
+ if (!isset($used_observer_handlers[$kind][$opcode["op"]])) {
+ $used_observer_handlers[$kind][$opcode["op"]] = true;
+ $op1 = "ANY";
+ $op2 = "ANY";
+ } else {
+ return;
+ }
+ }
+ }
+
if (ZEND_VM_LINES) {
out($f, "#line $lineno \"$definition_file\"\n");
}
@@ -1364,6 +1387,17 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
}
}
+ /* Skip all specialization for OBSERVER handlers */
+ if (isset($extra_spec["OBSERVER"]) && $extra_spec["OBSERVER"] == 1) {
+ if (isset($extra_spec["RETVAL"])) {
+ unset($extra_spec["RETVAL"]);
+ }
+ if ($op1 != "ANY" || $op2 != "ANY") {
+ $op1 = "ANY";
+ $op2 = "ANY";
+ }
+ }
+
// Emit pointer to specialized handler
$spec_name = $dsc["op"]."_SPEC".$prefix[$op1].$prefix[$op2].extra_spec_name($extra_spec);
switch ($kind) {