1{%DEFINES%} 2 3#if (ZEND_VM_KIND != ZEND_VM_KIND_CALL) && (ZEND_GCC_VERSION >= 4000) && !defined(__clang__) 4# pragma GCC push_options 5# pragma GCC optimize("no-gcse") 6# pragma GCC optimize("no-ivopts") 7#endif 8ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *ex) 9{ 10 DCL_OPLINE 11 12 {%HELPER_VARS%} 13 14 {%INTERNAL_LABELS%} 15 16 LOAD_OPLINE(); 17 ZEND_VM_LOOP_INTERRUPT_CHECK(); 18 19 while (1) { 20 {%ZEND_VM_CONTINUE_LABEL%} 21 {%ZEND_VM_DISPATCH%} { 22 {%INTERNAL_EXECUTOR%} 23 } 24 25 } 26 zend_error_noreturn(E_CORE_ERROR, "Arrived at end of main loop which shouldn't happen"); 27} 28#if (ZEND_VM_KIND != ZEND_VM_KIND_CALL) && (ZEND_GCC_VERSION >= 4000) && !defined(__clang__) 29# pragma GCC pop_options 30#endif 31 32ZEND_API void zend_{%EXECUTOR_NAME%}(zend_op_array *op_array, zval *return_value) 33{ 34 zend_execute_data *execute_data; 35 void *object_or_called_scope; 36 uint32_t call_info; 37 38 if (EG(exception) != NULL) { 39 return; 40 } 41 42 object_or_called_scope = zend_get_this_object(EG(current_execute_data)); 43 if (EXPECTED(!object_or_called_scope)) { 44 object_or_called_scope = zend_get_called_scope(EG(current_execute_data)); 45 call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE; 46 } else { 47 call_info = ZEND_CALL_TOP_CODE | ZEND_CALL_HAS_SYMBOL_TABLE | ZEND_CALL_HAS_THIS; 48 } 49 execute_data = zend_vm_stack_push_call_frame(call_info, 50 (zend_function*)op_array, 0, object_or_called_scope); 51 if (EG(current_execute_data)) { 52 execute_data->symbol_table = zend_rebuild_symbol_table(); 53 } else { 54 execute_data->symbol_table = &EG(symbol_table); 55 } 56 EX(prev_execute_data) = EG(current_execute_data); 57 i_init_code_execute_data(execute_data, op_array, return_value); 58 ZEND_OBSERVER_FCALL_BEGIN(execute_data); 59 zend_{%EXECUTOR_NAME%}_ex(execute_data); 60 /* Observer end handlers are called from ZEND_RETURN */ 61 zend_vm_stack_free_call_frame(execute_data); 62} 63 64{%EXTERNAL_EXECUTOR%} 65 66void {%INITIALIZER_NAME%}(void) 67{ 68 {%EXTERNAL_LABELS%} 69 VM_TRACE_START(); 70} 71 72static HashTable *zend_handlers_table = NULL; 73 74void zend_vm_dtor(void) 75{ 76 VM_TRACE_END(); 77 if (zend_handlers_table) { 78 zend_hash_destroy(zend_handlers_table); 79 free(zend_handlers_table); 80 zend_handlers_table = NULL; 81 } 82} 83 84static void init_opcode_serialiser(void) 85{ 86 int i; 87 zval tmp; 88 89 zend_handlers_table = malloc(sizeof(HashTable)); 90 zend_hash_init(zend_handlers_table, zend_handlers_count, NULL, NULL, 1); 91 zend_hash_real_init(zend_handlers_table, 0); 92 Z_TYPE_INFO(tmp) = IS_LONG; 93 for (i = 0; i < zend_handlers_count; i++) { 94 Z_LVAL(tmp) = i; 95 zend_hash_index_add(zend_handlers_table, (zend_long)(zend_uintptr_t)zend_opcode_handlers[i], &tmp); 96 } 97} 98 99ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op) 100{ 101 zval *zv; 102 103 if (!zend_handlers_table) { 104 init_opcode_serialiser(); 105 } 106 zv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)op->handler); 107 ZEND_ASSERT(zv != NULL); 108 op->handler = (const void *)(zend_uintptr_t)Z_LVAL_P(zv); 109} 110 111ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op) 112{ 113 op->handler = zend_opcode_handlers[(zend_uintptr_t)op->handler]; 114} 115 116ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *op) 117{ 118#if ZEND_VM_KIND == ZEND_VM_KIND_CALL 119 return op->handler; 120#elif ZEND_VM_KIND == ZEND_VM_KIND_HYBRID 121 zval *zv; 122 123 if (!zend_handlers_table) { 124 init_opcode_serialiser(); 125 } 126 zv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)op->handler); 127 ZEND_ASSERT(zv != NULL); 128 return zend_opcode_handler_funcs[Z_LVAL_P(zv)]; 129#else 130 return NULL; 131#endif 132} 133 134ZEND_API const zend_op *zend_get_halt_op(void) 135{ 136#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID 137 return &hybrid_halt_op; 138#else 139 return NULL; 140#endif 141} 142 143ZEND_API int zend_vm_kind(void) 144{ 145 return ZEND_VM_KIND; 146} 147