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();
}
}
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);
}
{
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);
}
HANDLE_EXCEPTION();
}
-
+
if (iter->funcs->rewind) {
iter->funcs->rewind(iter);
}
-
+
for (; iter->funcs->valid(iter) == SUCCESS; ) {
zval *val;
} else {
zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
}
-
+
FREE_OP1();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
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;
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;
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;
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;
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);
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);
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) {
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);
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])) {
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");
!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) {