@@ -6668,7 +6668,7 @@ ZEND_VM_COLD_CONST_HANDLER(125, ZEND_FE_RESET_RW, CONST|TMP|VAR|CV, JMP_ADDR)
6668
6668
}
6669
6669
}
6670
6670
6671
- ZEND_VM_HANDLER ( 78 , ZEND_FE_FETCH_R , VAR , ANY , JMP_ADDR )
6671
+ ZEND_VM_HELPER ( zend_fe_fetch_object_helper , ANY , ANY )
6672
6672
{
6673
6673
USE_OPLINE
6674
6674
zval * array ;
@@ -6677,126 +6677,98 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
6677
6677
HashTable * fe_ht ;
6678
6678
HashPosition pos ;
6679
6679
Bucket * p ;
6680
+ zend_object_iterator * iter ;
6680
6681
6681
6682
array = EX_VAR (opline -> op1 .var );
6682
6683
SAVE_OPLINE ();
6683
- if (EXPECTED (Z_TYPE_P (array ) == IS_ARRAY )) {
6684
- fe_ht = Z_ARRVAL_P (array );
6685
- pos = Z_FE_POS_P (array );
6684
+
6685
+ ZEND_ASSERT (Z_TYPE_P (array ) == IS_OBJECT );
6686
+ if ((iter = zend_iterator_unwrap (array )) == NULL ) {
6687
+ /* plain object */
6688
+
6689
+ fe_ht = Z_OBJPROP_P (array );
6690
+ pos = zend_hash_iterator_pos (Z_FE_ITER_P (array ), fe_ht );
6686
6691
p = fe_ht -> arData + pos ;
6687
6692
while (1 ) {
6688
6693
if (UNEXPECTED (pos >= fe_ht -> nNumUsed )) {
6689
6694
/* reached end of iteration */
6690
- ZEND_VM_C_LABEL (fe_fetch_r_exit ):
6691
- ZEND_VM_SET_RELATIVE_OPCODE (opline , opline -> extended_value );
6692
- ZEND_VM_CONTINUE ();
6695
+ ZEND_VM_C_GOTO (fe_fetch_r_exit );
6693
6696
}
6694
6697
pos ++ ;
6695
6698
value = & p -> val ;
6696
6699
value_type = Z_TYPE_INFO_P (value );
6697
- ZEND_ASSERT (value_type != IS_INDIRECT );
6698
6700
if (EXPECTED (value_type != IS_UNDEF )) {
6699
- break ;
6701
+ if (UNEXPECTED (value_type == IS_INDIRECT )) {
6702
+ value = Z_INDIRECT_P (value );
6703
+ value_type = Z_TYPE_INFO_P (value );
6704
+ if (EXPECTED (value_type != IS_UNDEF )
6705
+ && EXPECTED (zend_check_property_access (Z_OBJ_P (array ), p -> key , 0 ) == SUCCESS )) {
6706
+ break ;
6707
+ }
6708
+ } else if (EXPECTED (Z_OBJCE_P (array )-> default_properties_count == 0 )
6709
+ || !p -> key
6710
+ || zend_check_property_access (Z_OBJ_P (array ), p -> key , 1 ) == SUCCESS ) {
6711
+ break ;
6712
+ }
6700
6713
}
6701
6714
p ++ ;
6702
6715
}
6703
- Z_FE_POS_P ( array ) = pos ;
6716
+ EG ( ht_iterators )[ Z_FE_ITER_P ( array )]. pos = pos ;
6704
6717
if (RETURN_VALUE_USED (opline )) {
6705
- if (!p -> key ) {
6718
+ if (UNEXPECTED ( !p -> key ) ) {
6706
6719
ZVAL_LONG (EX_VAR (opline -> result .var ), p -> h );
6707
- } else {
6720
+ } else if ( ZSTR_VAL ( p -> key )[ 0 ]) {
6708
6721
ZVAL_STR_COPY (EX_VAR (opline -> result .var ), p -> key );
6722
+ } else {
6723
+ const char * class_name , * prop_name ;
6724
+ size_t prop_name_len ;
6725
+ zend_unmangle_property_name_ex (
6726
+ p -> key , & class_name , & prop_name , & prop_name_len );
6727
+ ZVAL_STRINGL (EX_VAR (opline -> result .var ), prop_name , prop_name_len );
6709
6728
}
6710
6729
}
6711
6730
} else {
6712
- zend_object_iterator * iter ;
6713
-
6714
- ZEND_ASSERT (Z_TYPE_P (array ) == IS_OBJECT );
6715
- if ((iter = zend_iterator_unwrap (array )) == NULL ) {
6716
- /* plain object */
6717
-
6718
- fe_ht = Z_OBJPROP_P (array );
6719
- pos = zend_hash_iterator_pos (Z_FE_ITER_P (array ), fe_ht );
6720
- p = fe_ht -> arData + pos ;
6721
- while (1 ) {
6722
- if (UNEXPECTED (pos >= fe_ht -> nNumUsed )) {
6723
- /* reached end of iteration */
6724
- ZEND_VM_C_GOTO (fe_fetch_r_exit );
6725
- }
6726
- pos ++ ;
6727
- value = & p -> val ;
6728
- value_type = Z_TYPE_INFO_P (value );
6729
- if (EXPECTED (value_type != IS_UNDEF )) {
6730
- if (UNEXPECTED (value_type == IS_INDIRECT )) {
6731
- value = Z_INDIRECT_P (value );
6732
- value_type = Z_TYPE_INFO_P (value );
6733
- if (EXPECTED (value_type != IS_UNDEF )
6734
- && EXPECTED (zend_check_property_access (Z_OBJ_P (array ), p -> key , 0 ) == SUCCESS )) {
6735
- break ;
6736
- }
6737
- } else if (EXPECTED (Z_OBJCE_P (array )-> default_properties_count == 0 )
6738
- || !p -> key
6739
- || zend_check_property_access (Z_OBJ_P (array ), p -> key , 1 ) == SUCCESS ) {
6740
- break ;
6741
- }
6742
- }
6743
- p ++ ;
6744
- }
6745
- EG (ht_iterators )[Z_FE_ITER_P (array )].pos = pos ;
6746
- if (RETURN_VALUE_USED (opline )) {
6747
- if (UNEXPECTED (!p -> key )) {
6748
- ZVAL_LONG (EX_VAR (opline -> result .var ), p -> h );
6749
- } else if (ZSTR_VAL (p -> key )[0 ]) {
6750
- ZVAL_STR_COPY (EX_VAR (opline -> result .var ), p -> key );
6751
- } else {
6752
- const char * class_name , * prop_name ;
6753
- size_t prop_name_len ;
6754
- zend_unmangle_property_name_ex (
6755
- p -> key , & class_name , & prop_name , & prop_name_len );
6756
- ZVAL_STRINGL (EX_VAR (opline -> result .var ), prop_name , prop_name_len );
6757
- }
6731
+ const zend_object_iterator_funcs * funcs = iter -> funcs ;
6732
+ if (EXPECTED (++ iter -> index > 0 )) {
6733
+ /* This could cause an endless loop if index becomes zero again.
6734
+ * In case that ever happens we need an additional flag. */
6735
+ funcs -> move_forward (iter );
6736
+ if (UNEXPECTED (EG (exception ) != NULL )) {
6737
+ UNDEF_RESULT ();
6738
+ HANDLE_EXCEPTION ();
6758
6739
}
6759
- } else {
6760
- const zend_object_iterator_funcs * funcs = iter -> funcs ;
6761
- if (EXPECTED (++ iter -> index > 0 )) {
6762
- /* This could cause an endless loop if index becomes zero again.
6763
- * In case that ever happens we need an additional flag. */
6764
- funcs -> move_forward (iter );
6740
+ if (UNEXPECTED (funcs -> valid (iter ) == FAILURE )) {
6741
+ /* reached end of iteration */
6765
6742
if (UNEXPECTED (EG (exception ) != NULL )) {
6766
6743
UNDEF_RESULT ();
6767
6744
HANDLE_EXCEPTION ();
6768
6745
}
6769
- if (UNEXPECTED (funcs -> valid (iter ) == FAILURE )) {
6770
- /* reached end of iteration */
6771
- if (UNEXPECTED (EG (exception ) != NULL )) {
6772
- UNDEF_RESULT ();
6773
- HANDLE_EXCEPTION ();
6774
- }
6775
- ZEND_VM_C_GOTO (fe_fetch_r_exit );
6776
- }
6777
- }
6778
- value = funcs -> get_current_data (iter );
6779
- if (UNEXPECTED (EG (exception ) != NULL )) {
6780
- UNDEF_RESULT ();
6781
- HANDLE_EXCEPTION ();
6782
- }
6783
- if (!value ) {
6784
- /* failure in get_current_data */
6785
- ZEND_VM_C_GOTO (fe_fetch_r_exit );
6746
+ ZEND_VM_C_LABEL (fe_fetch_r_exit ):
6747
+ ZEND_VM_SET_RELATIVE_OPCODE (opline , opline -> extended_value );
6748
+ ZEND_VM_CONTINUE ();
6786
6749
}
6787
- if (RETURN_VALUE_USED (opline )) {
6788
- if (funcs -> get_current_key ) {
6789
- funcs -> get_current_key (iter , EX_VAR (opline -> result .var ));
6790
- if (UNEXPECTED (EG (exception ) != NULL )) {
6791
- UNDEF_RESULT ();
6792
- HANDLE_EXCEPTION ();
6793
- }
6794
- } else {
6795
- ZVAL_LONG (EX_VAR (opline -> result .var ), iter -> index );
6750
+ }
6751
+ value = funcs -> get_current_data (iter );
6752
+ if (UNEXPECTED (EG (exception ) != NULL )) {
6753
+ UNDEF_RESULT ();
6754
+ HANDLE_EXCEPTION ();
6755
+ }
6756
+ if (!value ) {
6757
+ /* failure in get_current_data */
6758
+ ZEND_VM_C_GOTO (fe_fetch_r_exit );
6759
+ }
6760
+ if (RETURN_VALUE_USED (opline )) {
6761
+ if (funcs -> get_current_key ) {
6762
+ funcs -> get_current_key (iter , EX_VAR (opline -> result .var ));
6763
+ if (UNEXPECTED (EG (exception ) != NULL )) {
6764
+ UNDEF_RESULT ();
6765
+ HANDLE_EXCEPTION ();
6796
6766
}
6767
+ } else {
6768
+ ZVAL_LONG (EX_VAR (opline -> result .var ), iter -> index );
6797
6769
}
6798
- value_type = Z_TYPE_INFO_P (value );
6799
6770
}
6771
+ value_type = Z_TYPE_INFO_P (value );
6800
6772
}
6801
6773
6802
6774
if (EXPECTED (OP2_TYPE == IS_CV )) {
@@ -6814,6 +6786,64 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit):
6814
6786
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION ();
6815
6787
}
6816
6788
6789
+ ZEND_VM_HOT_HANDLER (78 , ZEND_FE_FETCH_R , VAR , ANY , JMP_ADDR )
6790
+ {
6791
+ USE_OPLINE
6792
+ zval * array ;
6793
+ zval * value ;
6794
+ uint32_t value_type ;
6795
+ HashTable * fe_ht ;
6796
+ HashPosition pos ;
6797
+ Bucket * p ;
6798
+
6799
+ array = EX_VAR (opline -> op1 .var );
6800
+ if (UNEXPECTED (Z_TYPE_P (array ) != IS_ARRAY )) {
6801
+ ZEND_VM_DISPATCH_TO_HELPER (zend_fe_fetch_object_helper );
6802
+ }
6803
+ fe_ht = Z_ARRVAL_P (array );
6804
+ pos = Z_FE_POS_P (array );
6805
+ p = fe_ht -> arData + pos ;
6806
+ while (1 ) {
6807
+ if (UNEXPECTED (pos >= fe_ht -> nNumUsed )) {
6808
+ /* reached end of iteration */
6809
+ ZEND_VM_SET_RELATIVE_OPCODE (opline , opline -> extended_value );
6810
+ ZEND_VM_CONTINUE ();
6811
+ }
6812
+ pos ++ ;
6813
+ value = & p -> val ;
6814
+ value_type = Z_TYPE_INFO_P (value );
6815
+ ZEND_ASSERT (value_type != IS_INDIRECT );
6816
+ if (EXPECTED (value_type != IS_UNDEF )) {
6817
+ break ;
6818
+ }
6819
+ p ++ ;
6820
+ }
6821
+ Z_FE_POS_P (array ) = pos ;
6822
+ if (RETURN_VALUE_USED (opline )) {
6823
+ if (!p -> key ) {
6824
+ ZVAL_LONG (EX_VAR (opline -> result .var ), p -> h );
6825
+ } else {
6826
+ ZVAL_STR_COPY (EX_VAR (opline -> result .var ), p -> key );
6827
+ }
6828
+ }
6829
+
6830
+ if (EXPECTED (OP2_TYPE == IS_CV )) {
6831
+ zval * variable_ptr = EX_VAR (opline -> op2 .var );
6832
+ SAVE_OPLINE ();
6833
+ zend_assign_to_variable (variable_ptr , value , IS_CV , EX_USES_STRICT_TYPES ());
6834
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION ();
6835
+ } else {
6836
+ zval * res = EX_VAR (opline -> op2 .var );
6837
+ zend_refcounted * gc = Z_COUNTED_P (value );
6838
+
6839
+ ZVAL_COPY_VALUE_EX (res , value , gc , value_type );
6840
+ if (Z_TYPE_INFO_REFCOUNTED (value_type )) {
6841
+ GC_ADDREF (gc );
6842
+ }
6843
+ ZEND_VM_NEXT_OPCODE ();
6844
+ }
6845
+ }
6846
+
6817
6847
ZEND_VM_HANDLER (126 , ZEND_FE_FETCH_RW , VAR , ANY , JMP_ADDR )
6818
6848
{
6819
6849
USE_OPLINE
0 commit comments