1 /* 2 +----------------------------------------------------------------------+ 3 | Zend Engine | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 2.00 of the Zend license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.zend.com/license/2_00.txt. | 11 | If you did not receive a copy of the Zend license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@zend.com so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 */ 16 17 #ifndef ZEND_FRAMELESS_FUNCTION_H 18 #define ZEND_FRAMELESS_FUNCTION_H 19 20 #include <stdint.h> 21 #include <stddef.h> 22 23 #ifdef PHP_WIN32 24 # include <config.w32.h> 25 #else 26 # include <php_config.h> 27 #endif 28 29 #include "zend_portability.h" 30 31 #define ZEND_FRAMELESS_FUNCTION_PARAMETERS_0 zval *return_value 32 #define ZEND_FRAMELESS_FUNCTION_PARAMETERS_1 zval *return_value, zval *arg1 33 #define ZEND_FRAMELESS_FUNCTION_PARAMETERS_2 zval *return_value, zval *arg1, zval *arg2 34 #define ZEND_FRAMELESS_FUNCTION_PARAMETERS_3 zval *return_value, zval *arg1, zval *arg2, zval *arg3 35 36 #define ZEND_FRAMELESS_FUNCTION_NAME(name, arity) zflf_##name##_##arity 37 #define ZEND_OP_IS_FRAMELESS_ICALL(opcode) ((opcode) >= ZEND_FRAMELESS_ICALL_0 && (opcode) <= ZEND_FRAMELESS_ICALL_3) 38 #define ZEND_FLF_NUM_ARGS(opcode) ((opcode) - ZEND_FRAMELESS_ICALL_0) 39 #define ZEND_FLF_FUNC(opline) (zend_flf_functions[(opline)->extended_value]) 40 #define ZEND_FLF_HANDLER(opline) (zend_flf_handlers[(opline)->extended_value]) 41 42 #define ZEND_FRAMELESS_FUNCTION(name, arity) \ 43 void ZEND_FRAMELESS_FUNCTION_NAME(name, arity)(ZEND_FRAMELESS_FUNCTION_PARAMETERS_##arity) 44 45 #define Z_FLF_PARAM_ZVAL(arg_num, dest) \ 46 dest = arg ## arg_num; 47 #define Z_FLF_PARAM_ARRAY(arg_num, dest) \ 48 if (!zend_parse_arg_array(arg ## arg_num, &dest, /* null_check */ false, /* or_object */ false)) { \ 49 zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY, arg ## arg_num); \ 50 goto flf_clean; \ 51 } 52 #define Z_FLF_PARAM_ARRAY_OR_NULL(arg_num, dest) \ 53 if (!zend_parse_arg_array(arg ## arg_num, &dest, /* null_check */ true, /* or_object */ false)) { \ 54 zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY_OR_NULL, arg ## arg_num); \ 55 goto flf_clean; \ 56 } 57 #define Z_FLF_PARAM_ARRAY_HT_OR_STR(arg_num, dest_ht, dest_str, str_tmp) \ 58 if (Z_TYPE_P(arg ## arg_num) == IS_STRING) { \ 59 dest_ht = NULL; \ 60 dest_str = Z_STR_P(arg ## arg_num); \ 61 } else if (EXPECTED(Z_TYPE_P(arg ## arg_num) == IS_ARRAY)) { \ 62 dest_ht = Z_ARRVAL_P(arg ## arg_num); \ 63 dest_str = NULL; \ 64 } else { \ 65 dest_ht = NULL; \ 66 ZVAL_COPY(&str_tmp, arg ## arg_num); \ 67 arg ## arg_num = &str_tmp; \ 68 if (!zend_flf_parse_arg_str_slow(arg ## arg_num, &dest_str, arg_num)) { \ 69 zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY_OR_STRING, arg ## arg_num); \ 70 goto flf_clean; \ 71 } \ 72 } 73 #define Z_FLF_PARAM_BOOL(arg_num, dest) \ 74 if (!zend_parse_arg_bool_ex(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num, /* frameless */ true)) { \ 75 zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_BOOL, arg ## arg_num); \ 76 goto flf_clean; \ 77 } 78 #define Z_FLF_PARAM_LONG(arg_num, dest) \ 79 if (!zend_parse_arg_long_ex(arg ## arg_num, &dest, /* is_null */ NULL, /* null_check */ false, arg_num, /* frameless */ true)) { \ 80 zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_LONG, arg ## arg_num); \ 81 goto flf_clean; \ 82 } 83 #define Z_FLF_PARAM_LONG_OR_NULL(arg_num, is_null, dest) \ 84 if (!zend_parse_arg_long_ex(arg ## arg_num, &dest, &is_null, /* null_check */ true, arg_num, /* frameless */ true)) { \ 85 zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_LONG_OR_NULL, arg ## arg_num); \ 86 goto flf_clean; \ 87 } 88 #define Z_FLF_PARAM_STR(arg_num, dest, tmp) \ 89 if (Z_TYPE_P(arg ## arg_num) == IS_STRING) { \ 90 dest = Z_STR_P(arg ## arg_num); \ 91 } else { \ 92 ZVAL_COPY(&tmp, arg ## arg_num); \ 93 arg ## arg_num = &tmp; \ 94 if (!zend_parse_arg_str_ex(arg ## arg_num, &dest, /* null_check */ false, arg_num, /* frameless */ true)) { \ 95 zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_STRING, arg ## arg_num); \ 96 goto flf_clean; \ 97 } \ 98 } 99 #define Z_FLF_PARAM_FREE_STR(arg_num, tmp) \ 100 if (UNEXPECTED(arg ## arg_num == &tmp)) { \ 101 zval_ptr_dtor(arg ## arg_num); \ 102 } 103 104 BEGIN_EXTERN_C() 105 106 typedef struct _zval_struct zval; 107 typedef struct _zend_op zend_op; 108 typedef union _zend_function zend_function; 109 110 typedef void (*zend_frameless_function_0)(zval *return_value); 111 typedef void (*zend_frameless_function_1)(zval *return_value, zval *op1); 112 typedef void (*zend_frameless_function_2)(zval *return_value, zval *op1, zval *op2); 113 typedef void (*zend_frameless_function_3)(zval *return_value, zval *op1, zval *op2, zval *op3); 114 115 extern size_t zend_flf_count; 116 extern size_t zend_flf_capacity; 117 ZEND_API extern void **zend_flf_handlers; 118 ZEND_API extern zend_function **zend_flf_functions; 119 120 typedef struct { 121 void *handler; 122 uint32_t num_args; 123 } zend_frameless_function_info; 124 125 typedef enum { 126 ZEND_JMP_FL_UNPRIMED = 0, 127 ZEND_JMP_FL_MISS = 1, 128 ZEND_JMP_FL_HIT = 2, 129 } zend_jmp_fl_result; 130 131 END_EXTERN_C() 132 133 #endif 134