mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Convert "switch" into series of "if". This allows better fast-path placement, additional specialization and makes final code less.
This commit is contained in:
parent
0040efb170
commit
aca6a1a1c9
@ -4352,68 +4352,64 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
|
||||
arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1;
|
||||
|
||||
ZEND_VM_C_LABEL(send_again):
|
||||
switch (Z_TYPE_P(args)) {
|
||||
case IS_ARRAY: {
|
||||
HashTable *ht = Z_ARRVAL_P(args);
|
||||
zval *arg, *top;
|
||||
zend_string *name;
|
||||
if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
|
||||
HashTable *ht = Z_ARRVAL_P(args);
|
||||
zval *arg, *top;
|
||||
zend_string *name;
|
||||
|
||||
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
|
||||
zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht));
|
||||
|
||||
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
|
||||
uint32_t i;
|
||||
int separate = 0;
|
||||
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_TMP_VAR && Z_IMMUTABLE_P(args)) {
|
||||
uint32_t i;
|
||||
int separate = 0;
|
||||
|
||||
/* check if any of arguments are going to be passed by reference */
|
||||
for (i = 0; i < zend_hash_num_elements(ht); i++) {
|
||||
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
|
||||
separate = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (separate) {
|
||||
zval_copy_ctor(args);
|
||||
ht = Z_ARRVAL_P(args);
|
||||
/* check if any of arguments are going to be passed by reference */
|
||||
for (i = 0; i < zend_hash_num_elements(ht); i++) {
|
||||
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num + i)) {
|
||||
separate = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
|
||||
if (name) {
|
||||
zend_error(E_EXCEPTION | E_ERROR, "Cannot unpack array with string keys");
|
||||
FREE_OP1();
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
top = ZEND_CALL_ARG(EX(call), arg_num);
|
||||
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
if (!Z_IMMUTABLE_P(args)) {
|
||||
ZVAL_MAKE_REF(arg);
|
||||
Z_ADDREF_P(arg);
|
||||
ZVAL_REF(top, Z_REF_P(arg));
|
||||
} else {
|
||||
ZVAL_DUP(top, arg);
|
||||
}
|
||||
} else if (Z_ISREF_P(arg)) {
|
||||
ZVAL_COPY(top, Z_REFVAL_P(arg));
|
||||
} else {
|
||||
ZVAL_COPY(top, arg);
|
||||
}
|
||||
|
||||
ZEND_CALL_NUM_ARGS(EX(call))++;
|
||||
arg_num++;
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
break;
|
||||
if (separate) {
|
||||
zval_copy_ctor(args);
|
||||
ht = Z_ARRVAL_P(args);
|
||||
}
|
||||
}
|
||||
case IS_OBJECT: {
|
||||
zend_class_entry *ce = Z_OBJCE_P(args);
|
||||
zend_object_iterator *iter;
|
||||
|
||||
if (!ce || !ce->get_iterator) {
|
||||
zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
|
||||
break;
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
|
||||
if (name) {
|
||||
zend_error(E_EXCEPTION | E_ERROR, "Cannot unpack array with string keys");
|
||||
FREE_OP1();
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
top = ZEND_CALL_ARG(EX(call), arg_num);
|
||||
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
|
||||
if (!Z_IMMUTABLE_P(args)) {
|
||||
ZVAL_MAKE_REF(arg);
|
||||
Z_ADDREF_P(arg);
|
||||
ZVAL_REF(top, Z_REF_P(arg));
|
||||
} else {
|
||||
ZVAL_DUP(top, arg);
|
||||
}
|
||||
} else if (Z_ISREF_P(arg)) {
|
||||
ZVAL_COPY(top, Z_REFVAL_P(arg));
|
||||
} else {
|
||||
ZVAL_COPY(top, arg);
|
||||
}
|
||||
|
||||
ZEND_CALL_NUM_ARGS(EX(call))++;
|
||||
arg_num++;
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
} else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) {
|
||||
zend_class_entry *ce = Z_OBJCE_P(args);
|
||||
zend_object_iterator *iter;
|
||||
|
||||
if (!ce || !ce->get_iterator) {
|
||||
zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
|
||||
} else {
|
||||
|
||||
iter = ce->get_iterator(ce, args, 0);
|
||||
if (UNEXPECTED(!iter)) {
|
||||
FREE_OP1();
|
||||
@ -4490,14 +4486,12 @@ ZEND_VM_C_LABEL(send_again):
|
||||
|
||||
ZEND_VM_C_LABEL(unpack_iter_dtor):
|
||||
zend_iterator_dtor(iter);
|
||||
break;
|
||||
}
|
||||
case IS_REFERENCE:
|
||||
args = Z_REFVAL_P(args);
|
||||
ZEND_VM_C_GOTO(send_again);
|
||||
break;
|
||||
default:
|
||||
zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
|
||||
} else if (EXPECTED(Z_ISREF_P(args))) {
|
||||
args = Z_REFVAL_P(args);
|
||||
ZEND_VM_C_GOTO(send_again);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
|
||||
}
|
||||
|
||||
FREE_OP1();
|
||||
@ -5568,6 +5562,7 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
||||
zval *container;
|
||||
zval *offset;
|
||||
zend_ulong hval;
|
||||
zend_string *key;
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
|
||||
@ -5590,47 +5585,43 @@ ZEND_VM_C_LABEL(unset_dim_again):
|
||||
ZEND_VM_C_LABEL(offset_again):
|
||||
SEPARATE_ARRAY(container);
|
||||
ht = Z_ARRVAL_P(container);
|
||||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_DOUBLE:
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
zend_hash_index_del(ht, hval);
|
||||
break;
|
||||
case IS_LONG:
|
||||
hval = Z_LVAL_P(offset);
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
key = Z_STR_P(offset);
|
||||
if (OP2_TYPE != IS_CONST) {
|
||||
if (ZEND_HANDLE_NUMERIC(key, hval)) {
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
}
|
||||
}
|
||||
ZEND_VM_C_LABEL(str_index_dim):
|
||||
if (ht == &EG(symbol_table)) {
|
||||
zend_delete_global_variable(key);
|
||||
} else {
|
||||
zend_hash_del(ht, key);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
ZEND_VM_C_LABEL(num_index_dim):
|
||||
zend_hash_index_del(ht, hval);
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (OP2_TYPE != IS_CONST) {
|
||||
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
}
|
||||
}
|
||||
if (ht == &EG(symbol_table)) {
|
||||
zend_delete_global_variable(Z_STR_P(offset));
|
||||
} else {
|
||||
zend_hash_del(ht, Z_STR_P(offset));
|
||||
}
|
||||
break;
|
||||
case IS_NULL:
|
||||
zend_hash_del(ht, STR_EMPTY_ALLOC());
|
||||
break;
|
||||
case IS_FALSE:
|
||||
hval = 0;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_TRUE:
|
||||
hval = 1;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_RESOURCE:
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
case IS_REFERENCE:
|
||||
offset = Z_REFVAL_P(offset);
|
||||
ZEND_VM_C_GOTO(offset_again);
|
||||
break;
|
||||
default:
|
||||
zend_error(E_WARNING, "Illegal offset type in unset");
|
||||
break;
|
||||
zend_hash_index_del(ht, hval);
|
||||
} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
ZEND_VM_C_GOTO(offset_again);
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
key = STR_EMPTY_ALLOC();
|
||||
ZEND_VM_C_GOTO(str_index_dim);
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
ZEND_VM_C_GOTO(num_index_dim);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Illegal offset type in unset");
|
||||
}
|
||||
} else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
|
||||
if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) {
|
||||
@ -6493,30 +6484,27 @@ ZEND_VM_C_LABEL(str_index_prop):
|
||||
hval = Z_LVAL_P(offset);
|
||||
ZEND_VM_C_LABEL(num_index_prop):
|
||||
value = zend_hash_index_find(ht, hval);
|
||||
} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
ZEND_VM_C_GOTO(isset_again);
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = STR_EMPTY_ALLOC();
|
||||
ZEND_VM_C_GOTO(str_index_prop);
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
} else {
|
||||
switch (Z_TYPE_P(offset)) {
|
||||
case IS_DOUBLE:
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
case IS_NULL:
|
||||
str = STR_EMPTY_ALLOC();
|
||||
ZEND_VM_C_GOTO(str_index_prop);
|
||||
case IS_FALSE:
|
||||
hval = 0;
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
case IS_TRUE:
|
||||
hval = 1;
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
case IS_RESOURCE:
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
ZEND_VM_C_GOTO(num_index_prop);
|
||||
case IS_REFERENCE:
|
||||
offset = Z_REFVAL_P(offset);
|
||||
ZEND_VM_C_GOTO(isset_again);
|
||||
default:
|
||||
zend_error(E_WARNING, "Illegal offset type in isset or empty");
|
||||
ZEND_VM_C_GOTO(isset_not_found);
|
||||
}
|
||||
zend_error(E_WARNING, "Illegal offset type in isset or empty");
|
||||
ZEND_VM_C_GOTO(isset_not_found);
|
||||
}
|
||||
|
||||
if (opline->extended_value & ZEND_ISSET) {
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user