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