mirror of
https://github.com/php/php-src.git
synced 2026-04-03 22:22:18 +02:00
Support the same handler for multiple opcodes
This commit is contained in:
committed by
Dmitry Stogov
parent
e8525c2f68
commit
a7580899f3
@@ -1496,7 +1496,7 @@ ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY)
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
|
||||
ZVAL_NULL(var_ptr);
|
||||
ZVAL_NULL(var_ptr);
|
||||
ZVAL_UNDEFINED_OP1();
|
||||
}
|
||||
|
||||
@@ -2234,7 +2234,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_fast_copy):
|
||||
}
|
||||
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
|
||||
|
||||
|
||||
if (OP2_TYPE != IS_CONST) {
|
||||
zend_tmp_string_release(tmp_name);
|
||||
}
|
||||
@@ -5528,10 +5528,10 @@ ZEND_VM_HANDLER(147, ZEND_ADD_ARRAY_UNPACK, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1;
|
||||
|
||||
|
||||
SAVE_OPLINE();
|
||||
op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
|
||||
ZEND_VM_C_LABEL(add_unpack_again):
|
||||
if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) {
|
||||
HashTable *ht = Z_ARRVAL_P(op1);
|
||||
@@ -5572,11 +5572,11 @@ ZEND_VM_C_LABEL(add_unpack_again):
|
||||
}
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
|
||||
if (iter->funcs->rewind) {
|
||||
iter->funcs->rewind(iter);
|
||||
}
|
||||
|
||||
|
||||
for (; iter->funcs->valid(iter) == SUCCESS; ) {
|
||||
zval *val;
|
||||
|
||||
@@ -5625,7 +5625,7 @@ ZEND_VM_C_LABEL(add_unpack_again):
|
||||
} else {
|
||||
zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
|
||||
}
|
||||
|
||||
|
||||
FREE_OP1();
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
@@ -8677,7 +8677,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_DOUBLE && op2_info =
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL|ZEND_IS_IDENTICAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
@@ -8689,7 +8689,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_inf
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
}
|
||||
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL|ZEND_IS_IDENTICAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
@@ -8701,7 +8701,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_i
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
}
|
||||
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL|ZEND_IS_NOT_IDENTICAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
@@ -8713,7 +8713,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
}
|
||||
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL|ZEND_IS_NOT_IDENTICAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
|
||||
@@ -59193,7 +59193,6 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
spec = 2512 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_EQUAL:
|
||||
case ZEND_IS_IDENTICAL:
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
@@ -59210,7 +59209,6 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
spec = 2612 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_NOT_EQUAL:
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
@@ -59227,6 +59225,38 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
spec = 2762 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_EQUAL:
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2537 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2612 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_NOT_EQUAL:
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2687 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2762 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_SMALLER:
|
||||
if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
|
||||
@@ -2394,19 +2394,22 @@ function gen_vm($def, $skel) {
|
||||
strpos($line,"ZEND_VM_HOT_OBJ_TYPE_SPEC_HANDLER(") === 0) {
|
||||
// Parsing opcode handler's definition
|
||||
if (preg_match(
|
||||
"/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_)?TYPE_SPEC_HANDLER\(\s*([A-Z_]+)\s*,\s*((?:[^(,]|\([^()]*|(?R)*\))*),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
|
||||
"/^ZEND_VM_(HOT_|INLINE_|HOT_OBJ_|HOT_SEND_|HOT_NOCONST_|HOT_NOCONSTCONST_)?TYPE_SPEC_HANDLER\(\s*([A-Z_|]+)\s*,\s*((?:[^(,]|\([^()]*|(?R)*\))*),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
|
||||
$line,
|
||||
$m) == 0) {
|
||||
die("ERROR ($def:$lineno): Invalid ZEND_VM_TYPE_HANDLER_HANDLER definition.\n");
|
||||
}
|
||||
$hot = !empty($m[1]) ? $m[1] : false;
|
||||
$orig_op = $m[2];
|
||||
if (!isset($opnames[$orig_op])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
|
||||
}
|
||||
$orig_code = $opnames[$orig_op];
|
||||
$condition = $m[3];
|
||||
$orig_op_list = $m[2];
|
||||
$code = $extra_num++;
|
||||
foreach (explode('|', $orig_op_list) as $orig_op) {
|
||||
if (!isset($opnames[$orig_op])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
|
||||
}
|
||||
$orig_code = $opnames[$orig_op];
|
||||
$condition = $m[3];
|
||||
$opcodes[$orig_code]['type_spec'][$code] = $condition;
|
||||
}
|
||||
$op = $m[4];
|
||||
$op1 = parse_operand_spec($def, $lineno, $m[5], $flags1);
|
||||
$op2 = parse_operand_spec($def, $lineno, $m[6], $flags2);
|
||||
@@ -2418,7 +2421,6 @@ function gen_vm($def, $skel) {
|
||||
if (isset($opcodes[$code])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$code' is already defined.\n");
|
||||
}
|
||||
$opcodes[$orig_code]['type_spec'][$code] = $condition;
|
||||
$used_extra_spec["TYPE"] = 1;
|
||||
$opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags,"hot"=>$hot,"is_type_spec"=>true);
|
||||
if (isset($m[10])) {
|
||||
@@ -2818,13 +2820,6 @@ function gen_vm($def, $skel) {
|
||||
if (isset($dsc['type_spec'])) {
|
||||
$orig_op = $dsc['op'];
|
||||
out($f, "\t\tcase $orig_op:\n");
|
||||
// XXX: Copy the specializations for LONG == LONG and DOUBLE != DOUBLE to work for ===/!== as well.
|
||||
// (Those are currently the only specializations)
|
||||
if ($orig_op === 'ZEND_IS_EQUAL') {
|
||||
out($f, "\t\tcase ZEND_IS_IDENTICAL:\n");
|
||||
} elseif ($orig_op === 'ZEND_IS_NOT_EQUAL') {
|
||||
out($f, "\t\tcase ZEND_IS_NOT_IDENTICAL:\n");
|
||||
}
|
||||
if (isset($dsc["spec"]["COMMUTATIVE"])) {
|
||||
out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
|
||||
out($f, "\t\t\t\tzend_swap_operands(op);\n");
|
||||
@@ -2864,10 +2859,8 @@ function gen_vm($def, $skel) {
|
||||
!isset($dsc['type_spec']) &&
|
||||
isset($dsc["spec"]["COMMUTATIVE"])) {
|
||||
$orig_op = $dsc['op'];
|
||||
if (!in_array($orig_op, ['ZEND_IS_IDENTICAL', 'ZEND_IS_NOT_IDENTICAL'])) {
|
||||
out($f, "\t\tcase $orig_op:\n");
|
||||
$has_commutative = true;
|
||||
}
|
||||
out($f, "\t\tcase $orig_op:\n");
|
||||
$has_commutative = true;
|
||||
}
|
||||
}
|
||||
if ($has_commutative) {
|
||||
|
||||
Reference in New Issue
Block a user