@@ -339,25 +339,9 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
339339#define EX_Ts() EX(Ts)
340340
341341
342- ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
343- {
344- DCL_OPLINE
345-
342+ static zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) {
346343 zend_execute_data *execute_data;
347- size_t execute_data_size;
348-
349- zend_bool nested = 0;
350- zend_bool original_in_execution = EG(in_execution);
351-
352-
353-
354- if (EG(exception)) {
355- return;
356- }
357-
358- EG(in_execution) = 1;
359344
360- zend_vm_enter:
361345 /*
362346 * When allocating the execute_data, memory for compiled variables and
363347 * temporary variables is also allocated after the actual zend_execute_data
@@ -367,11 +351,10 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
367351 * In that case the first half contains zval**s and the second half the
368352 * actual zval*s (which would otherwise be in the symbol table).
369353 */
370- execute_data_size =
371- ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
372- ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
373- ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T
374- ;
354+ size_t execute_data_size = ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data));
355+ size_t CVs_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
356+ size_t Ts_size = ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T;
357+ size_t total_size = execute_data_size + CVs_size + Ts_size;
375358
376359 /*
377360 * Normally the execute_data is allocated on the VM stack (because it does
@@ -383,14 +366,16 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
383366 * by replacing a pointer.
384367 */
385368 if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
386- execute_data = emalloc(execute_data_size );
369+ execute_data = emalloc(total_size );
387370 } else {
388- execute_data = zend_vm_stack_alloc(execute_data_size TSRMLS_CC);
371+ execute_data = zend_vm_stack_alloc(total_size TSRMLS_CC);
389372 }
390373
391- EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
392- memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
393- EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
374+ EX(CVs) = (zval ***) ((char *) execute_data + execute_data_size);
375+ memset(EX(CVs), 0, sizeof(zval **) * op_array->last_var);
376+
377+ EX(Ts) = (temp_variable *) ((char *) EX(CVs) + CVs_size);
378+
394379 EX(fbc) = NULL;
395380 EX(called_scope) = NULL;
396381 EX(object) = NULL;
@@ -400,9 +385,6 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
400385 EX(prev_execute_data) = EG(current_execute_data);
401386 EG(current_execute_data) = execute_data;
402387 EX(nested) = nested;
403- nested = 1;
404-
405- LOAD_REGS();
406388
407389 if (!op_array->run_time_cache && op_array->last_cache_slot) {
408390 op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
@@ -422,11 +404,31 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
422404
423405 EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
424406 EG(opline_ptr) = &EX(opline);
425- LOAD_OPLINE();
426407
427408 EX(function_state).function = (zend_function *) op_array;
428409 EX(function_state).arguments = NULL;
429410
411+ return execute_data;
412+ }
413+
414+ ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
415+ {
416+ DCL_OPLINE
417+
418+ zend_bool original_in_execution = EG(in_execution);
419+
420+
421+
422+ if (EG(exception)) {
423+ return;
424+ }
425+
426+ EG(in_execution) = 1;
427+
428+ zend_vm_enter:
429+ LOAD_REGS();
430+ LOAD_OPLINE();
431+
430432 while (1) {
431433 int ret;
432434#ifdef ZEND_WIN32
@@ -441,8 +443,7 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
441443 EG(in_execution) = original_in_execution;
442444 return;
443445 case 2:
444- op_array = EG(active_op_array);
445- goto zend_vm_enter;
446+ execute_data = zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
446447 case 3:
447448 execute_data = EG(current_execute_data);
448449 default:
@@ -454,6 +455,13 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
454455 zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
455456}
456457
458+ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
459+ {
460+ zend_execute_data *execute_data = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC);
461+
462+ execute_ex(execute_data TSRMLS_CC);
463+ }
464+
457465static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
458466{
459467 USE_OPLINE
0 commit comments