diff options
Diffstat (limited to 'Zend/zend_vm_gen.php')
-rwxr-xr-x | Zend/zend_vm_gen.php | 34 |
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) { |