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_{%EXECUTOR_NAME%}_ex(execute_data); 59 zend_vm_stack_free_call_frame(execute_data); 60} 61 62{%EXTERNAL_EXECUTOR%} 63 64void {%INITIALIZER_NAME%}(void) 65{ 66 {%EXTERNAL_LABELS%} 67 VM_TRACE_START(); 68} 69 70static HashTable *zend_handlers_table = NULL; 71 72void zend_vm_dtor(void) 73{ 74 VM_TRACE_END(); 75 if (zend_handlers_table) { 76 zend_hash_destroy(zend_handlers_table); 77 free(zend_handlers_table); 78 zend_handlers_table = NULL; 79 } 80} 81 82static void init_opcode_serialiser(void) 83{ 84 int i; 85 zval tmp; 86 87 zend_handlers_table = malloc(sizeof(HashTable)); 88 zend_hash_init_ex(zend_handlers_table, zend_handlers_count, NULL, NULL, 1, 0); 89 zend_hash_real_init(zend_handlers_table, 0); 90 Z_TYPE_INFO(tmp) = IS_LONG; 91 for (i = 0; i < zend_handlers_count; i++) { 92 Z_LVAL(tmp) = i; 93 zend_hash_index_add(zend_handlers_table, (zend_long)(zend_uintptr_t)zend_opcode_handlers[i], &tmp); 94 } 95} 96 97ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op) 98{ 99 zval *zv; 100 101 if (!zend_handlers_table) { 102 init_opcode_serialiser(); 103 } 104 zv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)op->handler); 105 ZEND_ASSERT(zv != NULL); 106 op->handler = (const void *)(zend_uintptr_t)Z_LVAL_P(zv); 107} 108 109ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op) 110{ 111 op->handler = zend_opcode_handlers[(zend_uintptr_t)op->handler]; 112} 113 114ZEND_API const void* ZEND_FASTCALL zend_get_opcode_handler_func(const zend_op *op) 115{ 116#if ZEND_VM_KIND == ZEND_VM_KIND_CALL 117 return op->handler; 118#elif ZEND_VM_KIND == ZEND_VM_KIND_HYBRID 119 zval *zv; 120 121 if (!zend_handlers_table) { 122 init_opcode_serialiser(); 123 } 124 zv = zend_hash_index_find(zend_handlers_table, (zend_long)(zend_uintptr_t)op->handler); 125 ZEND_ASSERT(zv != NULL); 126 return zend_opcode_handler_funcs[Z_LVAL_P(zv)]; 127#else 128 return NULL; 129#endif 130} 131 132ZEND_API const zend_op *zend_get_halt_op(void) 133{ 134#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID 135 return &hybrid_halt_op; 136#else 137 return NULL; 138#endif 139} 140 141ZEND_API int zend_vm_kind(void) 142{ 143 return ZEND_VM_KIND; 144} 145