summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-03-22 13:02:49 +0300
committerDmitry Stogov <dmitry@zend.com>2018-03-22 13:02:49 +0300
commite6c179834bd44b41289778543b470ad3e9ee16bb (patch)
tree22447fc3cf4a80619ee39dbc21d039cc3819b3fc
parentd1c6bda2bb3ac4cea97f57c8cb3561e08763fb48 (diff)
downloadphp-git-e6c179834bd44b41289778543b470ad3e9ee16bb.tar.gz
Allow extra specialisation for ISSET/ISEMPTY handlers
-rw-r--r--Zend/zend_vm_execute.h1
-rw-r--r--Zend/zend_vm_gen.php36
2 files changed, 35 insertions, 2 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 66915b5ab8..1c0a3d3553 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -316,6 +316,7 @@ static zend_uchar zend_user_opcodes[256] = {0,
#define SPEC_RULE_SMART_BRANCH 0x00200000
#define SPEC_RULE_DIM_OBJ 0x00400000
#define SPEC_RULE_COMMUTATIVE 0x00800000
+#define SPEC_RULE_ISSET 0x01000000
static const uint32_t *zend_spec_handlers;
static const void * const *zend_opcode_handlers;
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 74beb1af1d..94ed5a20f9 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -792,6 +792,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name, $extra_sp
"/opline->extended_value\s*==\s*0/",
"/opline->extended_value\s*==\s*ZEND_ASSIGN_DIM/",
"/opline->extended_value\s*==\s*ZEND_ASSIGN_OBJ/",
+ "/opline->extended_value\s*&\s*ZEND_ISSET/",
+ "/opline->extended_value\s*&\s*~\s*ZEND_ISSET/",
),
array(
$op1_type[$op1],
@@ -858,6 +860,12 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name, $extra_sp
isset($extra_spec['DIM_OBJ']) ?
($extra_spec['DIM_OBJ'] == 2 ? "1" : "0")
: "\\0",
+ isset($extra_spec['ISSET']) ?
+ ($extra_spec['ISSET'] == 0 ? "0" : "1")
+ : "\\0",
+ isset($extra_spec['ISSET']) ?
+ ($extra_spec['ISSET'] == 0 ? "opline->extended_value" : "\\0")
+ : "\\0",
),
$code);
@@ -1490,6 +1498,13 @@ function extra_spec_name($extra_spec) {
$s .= "_OBJ";
}
}
+ if (isset($extra_spec["ISSET"])) {
+ if ($extra_spec["ISSET"] == 0) {
+ $s .= "_EMPTY";
+ } else {
+ $s .= "_SET";
+ }
+ }
return $s;
}
@@ -1513,6 +1528,9 @@ function extra_spec_flags($extra_spec) {
if (isset($extra_spec["COMMUTATIVE"])) {
$s[] = "SPEC_RULE_COMMUTATIVE";
}
+ if (isset($extra_spec["ISSET"])) {
+ $s[] = "SPEC_RULE_ISSET";
+ }
return $s;
}
@@ -1707,6 +1725,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
out($f,"#define SPEC_RULE_SMART_BRANCH 0x00200000\n");
out($f,"#define SPEC_RULE_DIM_OBJ 0x00400000\n");
out($f,"#define SPEC_RULE_COMMUTATIVE 0x00800000\n");
+ out($f,"#define SPEC_RULE_ISSET 0x01000000\n");
out($f,"\n");
out($f,"static const uint32_t *zend_spec_handlers;\n");
out($f,"static const void * const *zend_opcode_handlers;\n");
@@ -2171,6 +2190,9 @@ function parse_spec_rules($def, $lineno, $str) {
case "COMMUTATIVE":
$ret["COMMUTATIVE"] = array(1);
break;
+ case "ISSET":
+ $ret["ISSET"] = array(0, 1);
+ break;
default:
die("ERROR ($def:$lineno): Wrong specialization rules '$str'\n");
}
@@ -2570,7 +2592,8 @@ function gen_vm($def, $skel) {
isset($used_extra_spec["RETVAL"]) ||
isset($used_extra_spec["QUICK_ARG"]) ||
isset($used_extra_spec["SMART_BRANCH"]) ||
- isset($used_extra_spec["DIM_OBJ"])) {
+ isset($used_extra_spec["DIM_OBJ"]) ||
+ isset($used_extra_spec["ISSET"])) {
$else = "";
out($f, "\tif (spec & SPEC_EXTRA_MASK) {\n");
@@ -2609,6 +2632,10 @@ function gen_vm($def, $skel) {
out($f, "\t\t}\n");
$else = "else ";
}
+ if (isset($used_extra_spec["ISSET"])) {
+ out($f, "\t\t{$else}if (spec & SPEC_RULE_ISSET) offset = offset * 2 + (op->extended_value & ZEND_ISSET);\n");
+ $else = "else ";
+ }
out($f, "\t}\n");
}
out($f, "\treturn zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];\n");
@@ -2653,7 +2680,8 @@ function gen_vm($def, $skel) {
isset($used_extra_spec["RETVAL"]) ||
isset($used_extra_spec["QUICK_ARG"]) ||
isset($used_extra_spec["SMART_BRANCH"]) ||
- isset($used_extra_spec["DIM_OBJ"])) {
+ isset($used_extra_spec["DIM_OBJ"]) ||
+ isset($used_extra_spec["ISSET"])) {
$else = "";
out($f, "\tif (spec & SPEC_EXTRA_MASK) {\n");
@@ -2692,6 +2720,10 @@ function gen_vm($def, $skel) {
out($f, "\t\t}\n");
$else = "else ";
}
+ if (isset($used_extra_spec["ISSET"])) {
+ out($f, "\t\t{$else}if (spec & SPEC_RULE_ISSET) offset = offset * 2 + (op->extended_value & ZEND_ISSET);\n");
+ $else = "else ";
+ }
out($f, "\t}\n");
}