@@ -2832,14 +2832,21 @@ function gen_vm($def, $skel) {
2832
2832
out ($ f , "\treturn (spec & SPEC_START_MASK) + offset; \n" );
2833
2833
}
2834
2834
out ($ f , "} \n\n" );
2835
+
2836
+ out ($ f , "static zend_always_inline uint32_t zend_vm_get_opcode_handler_spec_ex(uint8_t opcode, zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info, bool swap_operands); \n\n" );
2837
+
2838
+ // Generate zend_vm_get_opcode_handler_spec() function
2839
+ out ($ f , "static zend_always_inline uint32_t zend_vm_get_opcode_handler_spec(uint8_t opcode, zend_op* op, bool swap_operands) \n" );
2840
+ out ($ f , "{ \n" );
2841
+ out ($ f , "\tuint32_t all_types = MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_UNDEF; \n" );
2842
+ out ($ f , "\treturn zend_vm_get_opcode_handler_spec_ex(opcode, op, all_types, all_types, all_types, swap_operands); \n" );
2843
+ out ($ f , "} \n\n" );
2844
+
2835
2845
out ($ f , "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC \n" );
2836
2846
out ($ f , "static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op) \n" );
2837
2847
out ($ f , "{ \n" );
2838
- if (!ZEND_VM_SPEC ) {
2839
- out ($ f , "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)]; \n" );
2840
- } else {
2841
- out ($ f , "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)]; \n" );
2842
- }
2848
+ out ($ f , "\t/* Casting away const is safe, as we're not swapping operands. */ \n" );
2849
+ out ($ f , "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_spec(opcode, (zend_op*)op, false)]; \n" );
2843
2850
out ($ f , "} \n" );
2844
2851
out ($ f , "#endif \n\n" );
2845
2852
@@ -2848,11 +2855,11 @@ function gen_vm($def, $skel) {
2848
2855
out ($ f , "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID \n" );
2849
2856
out ($ f ,"static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op) \n" );
2850
2857
out ($ f , "{ \n" );
2851
- out ($ f , "\tuint32_t spec = zend_spec_handlers[opcode]; \n" );
2852
2858
if (!ZEND_VM_SPEC ) {
2853
- out ($ f , "\treturn zend_opcode_handler_funcs[spec ]; \n" );
2859
+ out ($ f , "\treturn zend_opcode_handler_funcs[zend_spec_handlers[opcode] ]; \n" );
2854
2860
} else {
2855
- out ($ f , "\treturn zend_opcode_handler_funcs[zend_vm_get_opcode_handler_idx(spec, op)]; \n" );
2861
+ out ($ f , "\t/* Casting away const is safe, as we're not swapping operands. */ \n" );
2862
+ out ($ f , "\treturn zend_opcode_handler_funcs[zend_vm_get_opcode_handler_spec(opcode, (zend_op*)op, false)]; \n" );
2856
2863
}
2857
2864
out ($ f , "} \n\n" );
2858
2865
out ($ f , "#endif \n\n" );
@@ -2861,26 +2868,20 @@ function gen_vm($def, $skel) {
2861
2868
// Generate zend_vm_get_opcode_handler() function
2862
2869
out ($ f , "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler(zend_op* op) \n" );
2863
2870
out ($ f , "{ \n" );
2864
- out ($ f , "\tuint8_t opcode = zend_user_opcodes[op->opcode]; \n" );
2865
- if (!ZEND_VM_SPEC ) {
2866
- out ($ f , "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)]; \n" );
2867
- } else {
2868
- out ($ f , "\n" );
2869
- out ($ f , "\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) { \n" );
2870
- out ($ f , "\t\tif (op->op1_type < op->op2_type) { \n" );
2871
- out ($ f , "\t\t\tzend_swap_operands(op); \n" );
2872
- out ($ f , "\t\t} \n" );
2873
- out ($ f , "\t} \n" );
2874
- out ($ f , "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)]; \n" );
2875
- }
2871
+ out ($ f , "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_spec(zend_user_opcodes[op->opcode], op, true)]; \n" );
2876
2872
out ($ f , "} \n\n" );
2877
2873
2878
2874
// Generate zend_vm_set_opcode_handler_ex() function
2879
2875
out ($ f , "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info) \n" );
2880
2876
out ($ f , "{ \n" );
2881
- out ($ f , "\tuint8_t opcode = zend_user_opcodes[op->opcode]; \n" );
2877
+ out ($ f , "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_spec_ex(zend_user_opcodes[op->opcode], op, op1_info, op2_info, res_info, true)]; \n" );
2878
+ out ($ f , "} \n\n" );
2879
+
2880
+ // Generate zend_vm_get_opcode_handler_spec_ex() function
2881
+ out ($ f , "static zend_always_inline uint32_t zend_vm_get_opcode_handler_spec_ex(uint8_t opcode, zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info, bool swap_operands) \n" );
2882
+ out ($ f , "{ \n" );
2882
2883
if (!ZEND_VM_SPEC ) {
2883
- out ($ f , "\t op->handler = zend_opcode_handlers[ zend_vm_get_opcode_handler_idx(opcode, op)] ; \n" );
2884
+ out ($ f , "\t return zend_vm_get_opcode_handler_idx(opcode, op); \n" );
2884
2885
} else {
2885
2886
out ($ f , "\tuint32_t spec = zend_spec_handlers[opcode]; \n" );
2886
2887
if (isset ($ used_extra_spec ["TYPE " ])) {
@@ -2890,7 +2891,7 @@ function gen_vm($def, $skel) {
2890
2891
$ orig_op = $ dsc ['op ' ];
2891
2892
out ($ f , "\t\tcase $ orig_op: \n" );
2892
2893
if (isset ($ dsc ["spec " ]["COMMUTATIVE " ])) {
2893
- out ($ f , "\t\t\tif (op->op1_type < op->op2_type) { \n" );
2894
+ out ($ f , "\t\t\tif (swap_operands && op->op1_type < op->op2_type) { \n" );
2894
2895
out ($ f , "\t\t\t\tzend_swap_operands(op); \n" );
2895
2896
out ($ f , "\t\t\t} \n" );
2896
2897
}
@@ -2911,7 +2912,7 @@ function gen_vm($def, $skel) {
2911
2912
}
2912
2913
out ($ f , "\t\t\t\tspec = {$ spec_dsc ['spec_code ' ]}; \n" );
2913
2914
if (isset ($ spec_dsc ["spec " ]["COMMUTATIVE " ]) && !isset ($ dsc ["spec " ]["COMMUTATIVE " ])) {
2914
- out ($ f , "\t\t\t\tif (op->op1_type < op->op2_type) { \n" );
2915
+ out ($ f , "\t\t\t\tif (swap_operands && op->op1_type < op->op2_type) { \n" );
2915
2916
out ($ f , "\t\t\t\t\tzend_swap_operands(op); \n" );
2916
2917
out ($ f , "\t\t\t\t} \n" );
2917
2918
}
@@ -2933,13 +2934,13 @@ function gen_vm($def, $skel) {
2933
2934
}
2934
2935
}
2935
2936
if ($ has_commutative ) {
2936
- out ($ f , "\t\t\tif (op->op1_type < op->op2_type) { \n" );
2937
+ out ($ f , "\t\t\tif (swap_operands && op->op1_type < op->op2_type) { \n" );
2937
2938
out ($ f , "\t\t\t\tzend_swap_operands(op); \n" );
2938
2939
out ($ f , "\t\t\t} \n" );
2939
2940
out ($ f , "\t\t\tbreak; \n" );
2940
2941
out ($ f , "\t\tcase ZEND_USER_OPCODE: \n" );
2941
2942
out ($ f , "\t\t\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) { \n" );
2942
- out ($ f , "\t\t\t\tif (op->op1_type < op->op2_type) { \n" );
2943
+ out ($ f , "\t\t\t\tif (swap_operands && op->op1_type < op->op2_type) { \n" );
2943
2944
out ($ f , "\t\t\t\t\tzend_swap_operands(op); \n" );
2944
2945
out ($ f , "\t\t\t\t} \n" );
2945
2946
out ($ f , "\t\t\t} \n" );
@@ -2949,7 +2950,7 @@ function gen_vm($def, $skel) {
2949
2950
out ($ f , "\t\t\tbreak; \n" );
2950
2951
out ($ f , "\t} \n" );
2951
2952
}
2952
- out ($ f , "\t op->handler = zend_opcode_handlers[ zend_vm_get_opcode_handler_idx(spec, op)] ; \n" );
2953
+ out ($ f , "\t return zend_vm_get_opcode_handler_idx(spec, op); \n" );
2953
2954
}
2954
2955
out ($ f , "} \n\n" );
2955
2956
0 commit comments