Browse Source

- Commit new VM

- Old one is tagged as PRE_NEW_VM_GEN_PATCH
- Still doing work so more commits to come. Don't complain (yet) :)
PHP-5.1
Andi Gutmans 21 years ago
parent
commit
e50a6fde11
  1. 2
      Zend/Makefile.frag
  2. 309
      Zend/zend_execute.c
  3. 366
      Zend/zend_vm.h
  4. 3423
      Zend/zend_vm_def.h
  5. 72
      Zend/zend_vm_execute.skl
  6. 1001
      Zend/zend_vm_gen.php

2
Zend/Makefile.frag

@ -1 +1 @@
Zend/zend_execute.lo: $(srcdir)/zend_vm_spec.h $(srcdir)/zend_vm_handlers.h
Zend/zend_execute.lo: $(srcdir)/zend_vm_execute.h

309
Zend/zend_execute.c

@ -36,6 +36,21 @@
#include "zend_exceptions.h"
#include "zend_vm.h"
#define _CONST_CODE 0
#define _TMP_CODE 1
#define _VAR_CODE 2
#define _UNUSED_CODE 3
#define _CV_CODE 4
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(ZEND_VM_OLD_EXECUTOR)
# define ZEND_VM_ALWAYS_INLINE __attribute__ ((always_inline))
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
/*extern void zend_error_noreturn(int type, const char *format, ...) __asm__("zend_error") __attribute__ ((noreturn));*/
#else
# define ZEND_VM_ALWAYS_INLINE
# define zend_error_noreturn zend_error
#endif
typedef int (*incdec_t)(zval *);
#define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free, type TSRMLS_CC)
@ -260,8 +275,6 @@ static inline zval **_get_zval_ptr_ptr(znode *node, temp_variable *Ts, zend_free
}
}
#ifdef ZEND_VM_SPEC
static inline zval *_get_zval_ptr_const(znode *node, temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
{
return &node->u.constant;
@ -453,7 +466,6 @@ static inline zval **_get_obj_zval_ptr_ptr_unused(znode *op, temp_variable *Ts,
return NULL;
}
}
#endif
static inline void zend_switch_free(zend_op *opline, temp_variable *Ts TSRMLS_DC)
{
@ -1427,265 +1439,38 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v
((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr, execute_data_ptr->object, return_value_used TSRMLS_CC);
}
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
{
zend_execute_data execute_data;
ZEND_VM_HELPER_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
ZEND_VM_HELPER_VAR(incdec_t incdec_op)
ZEND_VM_HELPER_VAR(int prop_dim)
ZEND_VM_HELPER_VAR(int type)
#if ZEND_VM_KIND == ZEND_VM_KIND_GOTO
if (op_array == NULL) {
goto init_labels;
}
#endif
/* Initialize execute_data */
EX(fbc) = NULL;
EX(object) = NULL;
if (op_array->T < TEMP_VAR_STACK_LIMIT) {
EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);
} else {
EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);
}
EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var);
memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
EX(op_array) = op_array;
EX(original_in_execution) = EG(in_execution);
EX(symbol_table) = EG(active_symbol_table);
EX(prev_execute_data) = EG(current_execute_data);
EG(current_execute_data) = &execute_data;
EG(in_execution) = 1;
if (op_array->start_op) {
ZEND_VM_SET_OPCODE(op_array->start_op);
} else {
ZEND_VM_SET_OPCODE(op_array->opcodes);
}
if (op_array->uses_this && EG(This)) {
EG(This)->refcount++; /* For $this pointer */
if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
EG(This)->refcount--;
}
}
EG(opline_ptr) = &EX(opline);
EX(function_state).function = (zend_function *) op_array;
EG(function_state_ptr) = &EX(function_state);
#if ZEND_DEBUG
/* function_state.function_symbol_table is saved as-is to a stack,
* which is an intentional UMR. Shut it up if we're in DEBUG.
*/
EX(function_state).function_symbol_table = NULL;
#endif
while (1) {
ZEND_VM_CONTINUE_LABEL
#ifdef ZEND_WIN32
if (EG(timed_out)) {
zend_timeout(0);
}
#endif
ZEND_VM_DISPATCH() {
#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
return;
#else
# include "zend_vm_spec.h"
#endif
}
}
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
#if ZEND_VM_KIND == ZEND_VM_KIND_GOTO
{
static const opcode_handler_t labels[] = {ZEND_VM_LABELS};
init_labels:
zend_opcode_handlers = (opcode_handler_t*)labels;
return;
}
#endif
}
#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
# undef EX
# define EX(element) execute_data->element
# include"zend_vm_spec.h"
#endif
void zend_init_opcodes_handlers()
{
#if ZEND_VM_KIND == ZEND_VM_KIND_GOTO
TSRMLS_FETCH();
zend_execute(NULL TSRMLS_CC);
#else
static const opcode_handler_t labels[] = {ZEND_VM_LABELS};
zend_opcode_handlers = (opcode_handler_t*)labels;
#endif
}
#ifdef ZEND_VM_HAVE_OLD_EXECUTOR
/* Old Style Executor */
/* TODO: remove it */
# undef EX
# define EX(element) execute_data.element
/* Hack */
# define ZEND_VM_OLD_EXECUTOR
# undef ZEND_VM_H
# undef ZEND_VM_KIND
# define ZEND_VM_KIND ZEND_VM_KIND_CALL
# undef ZEND_VM_SPEC
# undef ZEND_VM_ALWAYS_INLINE
# undef zend_error_noreturn
# undef ZEND_VM_CODE
# undef ZEND_VM_SPEC_OPCODE
# undef ZEND_VM_SET_OPCODE_HANDLER
# undef EXECUTE_DATA
# undef ZEND_VM_HELPER_VAR
# undef ZEND_VM_DISPATCH
# undef ZEND_VM_HANDLER
# undef ZEND_VM_HANDLER_EX
# undef ZEND_VM_HELPER
# undef ZEND_VM_HELPER_EX
# undef ZEND_VM_SPEC_HANDLER
# undef ZEND_VM_SPEC_HANDLER_EX
# undef ZEND_VM_SPEC_HELPER
# undef ZEND_VM_SPEC_HELPER_EX
# undef ZEND_VM_NULL_HANDLER
# undef ZEND_VM_DISPATCH_TO_HANDLER
# undef ZEND_VM_DISPATCH_TO_HELPER
# undef ZEND_VM_DISPATCH_TO_HELPER_EX
# undef ZEND_VM_SPEC_DISPATCH_TO_HANDLER
# undef ZEND_VM_SPEC_DISPATCH_TO_HELPER
# undef ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX
# undef ZEND_VM_CONTINUE
# undef ZEND_VM_NEXT_OPCODE
# undef ZEND_VM_RETURN_FROM_EXECUTE_LOOP
# undef ZEND_VM_LABEL
# undef ZEND_VM_NULL_LABEL
# undef ZEND_VM_SPEC_LABEL
# undef ZEND_VM_SPEC_NULL_LABEL
# undef ZEND_VM_CONTINUE_LABEL
# include "zend_vm.h"
static void old_execute(zend_op_array *op_array TSRMLS_DC)
{
zend_execute_data execute_data;
/* Initialize execute_data */
EX(fbc) = NULL;
EX(object) = NULL;
if (op_array->T < TEMP_VAR_STACK_LIMIT) {
EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);
} else {
EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);
}
EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var);
memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
EX(op_array) = op_array;
EX(original_in_execution) = EG(in_execution);
EX(symbol_table) = EG(active_symbol_table);
EX(prev_execute_data) = EG(current_execute_data);
EG(current_execute_data) = &execute_data;
EG(in_execution) = 1;
if (op_array->start_op) {
ZEND_VM_SET_OPCODE(op_array->start_op);
} else {
ZEND_VM_SET_OPCODE(op_array->opcodes);
}
if (op_array->uses_this && EG(This)) {
EG(This)->refcount++; /* For $this pointer */
if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
EG(This)->refcount--;
}
}
EG(opline_ptr) = &EX(opline);
EX(function_state).function = (zend_function *) op_array;
EG(function_state_ptr) = &EX(function_state);
#if ZEND_DEBUG
/* function_state.function_symbol_table is saved as-is to a stack,
* which is an intentional UMR. Shut it up if we're in DEBUG.
*/
EX(function_state).function_symbol_table = NULL;
#endif
while (1) {
#ifdef ZEND_WIN32
if (EG(timed_out)) {
zend_timeout(0);
}
#endif
ZEND_VM_DISPATCH() {
return;
}
}
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
}
# undef EX
# define EX(element) execute_data->element
/* Hack */
# undef OP1_OP2_MASK
# undef HAVE_OP
# undef ZEND_VM_C_GOTO
# undef ZEND_VM_C_LABEL
# include"zend_vm_spec.h"
ZEND_API int zend_vm_old_executor = 0;
void zend_vm_set_opcode_handler(zend_op* op)
{
if (zend_vm_old_executor) {
op->handler = zend_opcode_handlers[op->opcode];
} else {
static const int zend_vm_decode[] = {
_UNUSED_CODE, /* 0 */
_CONST_CODE, /* 1 = IS_CONST */
_TMP_CODE, /* 2 = IS_TMP_VAR */
_UNUSED_CODE, /* 3 */
_VAR_CODE, /* 4 = IS_VAR */
_UNUSED_CODE, /* 5 */
_UNUSED_CODE, /* 6 */
_UNUSED_CODE, /* 7 */
_UNUSED_CODE, /* 8 = IS_UNUSED */
_UNUSED_CODE, /* 9 */
_UNUSED_CODE, /* 10 */
_UNUSED_CODE, /* 11 */
_UNUSED_CODE, /* 12 */
_UNUSED_CODE, /* 13 */
_UNUSED_CODE, /* 14 */
_UNUSED_CODE, /* 15 */
_CV_CODE /* 16 = IS_CV */
};
op->handler = zend_opcode_handlers[op->opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type]];
}
}
ZEND_API void zend_vm_use_old_executor()
{
static opcode_handler_t labels[512] = {ZEND_VM_LABELS};
zend_vm_old_executor = 1;
zend_opcode_handlers = (opcode_handler_t*)labels;
zend_execute = old_execute;
}
#endif
#define ZEND_VM_NEXT_OPCODE() \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
ZEND_VM_CONTINUE()
#define ZEND_VM_SET_OPCODE(new_op) \
CHECK_SYMBOL_TABLES() \
EX(opline) = new_op
#define ZEND_VM_INC_OPCODE() \
if (!EG(exception)) { \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
}
#define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
free_alloca(EX(CVs)); \
if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
free_alloca(EX(Ts)); \
} else { \
efree(EX(Ts)); \
} \
EG(in_execution) = EX(original_in_execution); \
EG(current_execute_data) = EX(prev_execute_data); \
ZEND_VM_RETURN()
#define ZEND_VM_CONTINUE_JMP() \
ZEND_VM_CONTINUE()
static int zend_vm_old_executor = 0;
#include "zend_vm_execute.h"
/*
* Local variables:

366
Zend/zend_vm.h

@ -21,373 +21,9 @@
#ifndef ZEND_VM_H
#define ZEND_VM_H
#define ZEND_VM_HAVE_OLD_EXECUTOR
#define ZEND_VM_KIND_CALL 1
#define ZEND_VM_KIND_SWITCH 2
#define ZEND_VM_KIND_GOTO 3
#ifndef ZEND_VM_OLD_EXECUTOR
/*# define ZEND_VM_KIND ZEND_VM_KIND_CALL */
# define ZEND_VM_SPEC
#endif
/* don't edit the rest of the file */
#ifdef ZEND_VM_HAVE_OLD_EXECUTOR
ZEND_API void zend_vm_use_old_executor();
void zend_vm_set_opcode_handler(zend_op* opcode);
#endif
#define _CONST_CODE 0
#define _TMP_CODE 1
#define _VAR_CODE 2
#define _UNUSED_CODE 3
#define _CV_CODE 4
#ifndef ZEND_VM_KIND
# ifdef __GNUC__
# define ZEND_VM_KIND ZEND_VM_KIND_GOTO
# else
# define ZEND_VM_KIND ZEND_VM_KIND_CALL
# endif
#endif
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(ZEND_VM_OLD_EXECUTOR)
# define ZEND_VM_ALWAYS_INLINE __attribute__ ((always_inline))
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
/*extern void zend_error_noreturn(int type, const char *format, ...) __asm__("zend_error") __attribute__ ((noreturn));*/
#else
# define ZEND_VM_ALWAYS_INLINE
# define zend_error_noreturn zend_error
#endif
#ifndef ZEND_VM_SPEC
# define ZEND_VM_CODE(opcode, op1, op2) opcode
# define ZEND_VM_SPEC_OPCODE(opcode, op1, op2) opcode
# ifdef ZEND_VM_HAVE_OLD_EXECUTOR
# define ZEND_VM_SET_OPCODE_HANDLER(opline) \
zend_vm_set_opcode_handler(opline)
# else
# define ZEND_VM_SET_OPCODE_HANDLER(opline) \
opline->handler = zend_opcode_handlers[opline->opcode]
# endif
#else
static const int zend_vm_decode[] = {
_UNUSED_CODE, /* 0 */
_CONST_CODE, /* 1 = IS_CONST */
_TMP_CODE, /* 2 = IS_TMP_VAR */
_UNUSED_CODE, /* 3 */
_VAR_CODE, /* 4 = IS_VAR */
_UNUSED_CODE, /* 5 */
_UNUSED_CODE, /* 6 */
_UNUSED_CODE, /* 7 */
_UNUSED_CODE, /* 8 = IS_UNUSED */
_UNUSED_CODE, /* 9 */
_UNUSED_CODE, /* 10 */
_UNUSED_CODE, /* 11 */
_UNUSED_CODE, /* 12 */
_UNUSED_CODE, /* 13 */
_UNUSED_CODE, /* 14 */
_UNUSED_CODE, /* 15 */
_CV_CODE /* 16 = IS_CV */
};
# define ZEND_VM_CODE(opcode, op1, op2) \
opcode * 25 + op1 * 5 + op2
# define ZEND_VM_SPEC_OPCODE(opcode, op1, op2) \
ZEND_VM_CODE(opcode, zend_vm_decode[op1], zend_vm_decode[op2])
# ifdef ZEND_VM_HAVE_OLD_EXECUTOR
# define ZEND_VM_SET_OPCODE_HANDLER(opline) \
zend_vm_set_opcode_handler(opline)
# else
# define ZEND_VM_SET_OPCODE_HANDLER(opline) \
opline->handler = zend_opcode_handlers[ZEND_VM_SPEC_OPCODE(opline->opcode, opline->op1.op_type, opline->op2.op_type)]
# endif
#endif
#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
# define EXECUTE_DATA execute_data
# define ZEND_VM_HELPER_VAR(X)
# define ZEND_VM_DISPATCH() \
if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0)
# define ZEND_VM_CONTINUE_LABEL
# define ZEND_VM_HANDLER(OP) \
static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_HANDLER_EX(OP) \
static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_HELPER(NAME) \
static int NAME(ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_HELPER_EX(NAME,PARAM) \
static int NAME(PARAM, ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_SPEC_HANDLER(OP, CODE) \
static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_SPEC_HANDLER_EX(OP, CODE) \
static int OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_SPEC_HELPER(NAME) \
static int NAME(ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_SPEC_HELPER_EX(NAME,PARAM) \
static int NAME(PARAM, ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_NULL_HANDLER() \
int ZEND_VM_NULL(ZEND_OPCODE_HANDLER_ARGS)
# define ZEND_VM_DISPATCH_TO_HANDLER(OP) \
return OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
# define ZEND_VM_DISPATCH_TO_HELPER(NAME) \
return NAME(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
# define ZEND_VM_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
return NAME(VAL, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER(OP) \
return OP##_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
# define ZEND_VM_SPEC_DISPATCH_TO_HELPER(NAME) \
return NAME(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
return NAME(VAL, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)
# define ZEND_VM_CONTINUE() \
return 0
# define ZEND_VM_NEXT_OPCODE() \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
return 0
# define ZEND_VM_SET_OPCODE(new_op) \
CHECK_SYMBOL_TABLES() \
EX(opline) = new_op
# define ZEND_VM_INC_OPCODE() \
if (!EG(exception)) { \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
}
# define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
free_alloca(EX(CVs)); \
if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
free_alloca(EX(Ts)); \
} else { \
efree(EX(Ts)); \
} \
EG(in_execution) = EX(original_in_execution); \
EG(current_execute_data) = EX(prev_execute_data); \
return 1;
# define ZEND_VM_LABEL(OP) OP##_HANDLER
# define ZEND_VM_NULL_LABEL ZEND_VM_NULL
# define ZEND_VM_SPEC_LABEL(OP,CODE) OP##_HANDLER
# define ZEND_VM_SPEC_NULL_LABEL ZEND_VM_NULL
#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
# define EXECUTE_DATA &execute_data
# define ZEND_VM_HELPER_VAR(X) X;
# define ZEND_VM_DISPATCH() \
switch ((int)EX(opline)->handler)
# define ZEND_VM_CONTINUE_LABEL \
zend_vm_continue:
# define ZEND_VM_HANDLER(OP) \
case OP:
# define ZEND_VM_HANDLER_EX(OP) \
case OP: \
OP##_LABEL:
# define ZEND_VM_HELPER(NAME) \
NAME:
# define ZEND_VM_HELPER_EX(NAME,PARAM) \
NAME:
# define ZEND_VM_SPEC_HANDLER(OP, CODE) \
case CODE:
# define ZEND_VM_SPEC_HANDLER_EX(OP, CODE) \
case CODE: \
OP##_LABEL:
# define ZEND_VM_SPEC_HELPER(NAME) \
NAME:
# define ZEND_VM_SPEC_HELPER_EX(NAME,PARAM) \
NAME:
# define ZEND_VM_NULL_HANDLER() \
default:
# define ZEND_VM_DISPATCH_TO_HANDLER(OP) \
goto OP##_LABEL
# define ZEND_VM_DISPATCH_TO_HELPER(NAME) \
goto NAME
# define ZEND_VM_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
VAR = VAL; \
goto NAME
# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER(OP) \
goto OP##_LABEL
# define ZEND_VM_SPEC_DISPATCH_TO_HELPER(NAME) \
goto NAME
# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
VAR = VAL; \
goto NAME
# define ZEND_VM_CONTINUE() \
goto zend_vm_continue
# define ZEND_VM_NEXT_OPCODE() \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
ZEND_VM_CONTINUE()
# define ZEND_VM_SET_OPCODE(new_op) \
CHECK_SYMBOL_TABLES() \
EX(opline) = new_op
# define ZEND_VM_INC_OPCODE() \
if (!EG(exception)) { \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
}
# define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
free_alloca(EX(CVs)); \
if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
free_alloca(EX(Ts)); \
} else { \
efree(EX(Ts)); \
} \
EG(in_execution) = EX(original_in_execution); \
EG(current_execute_data) = EX(prev_execute_data); \
return;
# define ZEND_VM_LABEL(OP) (opcode_handler_t)OP
# define ZEND_VM_NULL_LABEL (opcode_handler_t)-1
# define ZEND_VM_SPEC_LABEL(OP,CODE) (opcode_handler_t)(CODE)
# define ZEND_VM_SPEC_NULL_LABEL (opcode_handler_t)-1
#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO
# define EXECUTE_DATA &execute_data
# define ZEND_VM_HELPER_VAR(X) X;
# define ZEND_VM_DISPATCH() \
goto *(void**)(EX(opline)->handler);
# define ZEND_VM_CONTINUE_LABEL
# define ZEND_VM_HANDLER(OP) \
OP##_HANDLER:
# define ZEND_VM_HANDLER_EX(OP) \
OP##_HANDLER:
# define ZEND_VM_HELPER(NAME) \
NAME:
# define ZEND_VM_HELPER_EX(NAME,PARAM) \
NAME:
# define ZEND_VM_SPEC_HANDLER(OP, CODE) \
OP##_HANDLER:
# define ZEND_VM_SPEC_HANDLER_EX(OP, CODE) \
OP##_HANDLER:
# define ZEND_VM_SPEC_HELPER(NAME) \
NAME:
# define ZEND_VM_SPEC_HELPER_EX(NAME,PARAM) \
NAME:
# define ZEND_VM_NULL_HANDLER() \
ZEND_VM_NULL:
# define ZEND_VM_DISPATCH_TO_HANDLER(OP) \
goto OP##_HANDLER
# define ZEND_VM_DISPATCH_TO_HELPER(NAME) \
goto NAME
# define ZEND_VM_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
VAR = VAL; \
goto NAME
# define ZEND_VM_SPEC_DISPATCH_TO_HANDLER(OP) \
goto OP##_HANDLER
# define ZEND_VM_SPEC_DISPATCH_TO_HELPER(NAME) \
goto NAME
# define ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX(NAME,VAR,VAL) \
VAR = VAL; \
goto NAME
# define ZEND_VM_CONTINUE() \
goto *(void**)(EX(opline)->handler)
# define ZEND_VM_NEXT_OPCODE() \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
ZEND_VM_CONTINUE()
# define ZEND_VM_SET_OPCODE(new_op) \
CHECK_SYMBOL_TABLES() \
EX(opline) = new_op
# define ZEND_VM_INC_OPCODE() \
if (!EG(exception)) { \
CHECK_SYMBOL_TABLES() \
EX(opline)++; \
}
# define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
free_alloca(EX(CVs)); \
if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
free_alloca(EX(Ts)); \
} else { \
efree(EX(Ts)); \
} \
EG(in_execution) = EX(original_in_execution); \
EG(current_execute_data) = EX(prev_execute_data); \
return;
# define ZEND_VM_LABEL(OP) (opcode_handler_t)&&OP##_HANDLER
# define ZEND_VM_NULL_LABEL &&ZEND_VM_NULL
# define ZEND_VM_SPEC_LABEL(OP,CODE) (opcode_handler_t)&&OP##_HANDLER
# define ZEND_VM_SPEC_NULL_LABEL &&ZEND_VM_NULL
#else
# error "Unknown ZEND_VM_KIND"
#endif
#define ZEND_VM_CONTINUE_JMP() ZEND_VM_CONTINUE()
#define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline)
#endif

3423
Zend/zend_vm_def.h
File diff suppressed because it is too large
View File

72
Zend/zend_vm_execute.skl

@ -0,0 +1,72 @@
{%DEFINES%}
ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
{
zend_execute_data execute_data;
{%HELPER_VARS%}
{%INTERANL_LABELS%}
/* Initialize execute_data */
EX(fbc) = NULL;
EX(object) = NULL;
if (op_array->T < TEMP_VAR_STACK_LIMIT) {
EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);
} else {
EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);
}
EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var);
memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
EX(op_array) = op_array;
EX(original_in_execution) = EG(in_execution);
EX(symbol_table) = EG(active_symbol_table);
EX(prev_execute_data) = EG(current_execute_data);
EG(current_execute_data) = &execute_data;
EG(in_execution) = 1;
if (op_array->start_op) {
ZEND_VM_SET_OPCODE(op_array->start_op);
} else {
ZEND_VM_SET_OPCODE(op_array->opcodes);
}
if (op_array->uses_this && EG(This)) {
EG(This)->refcount++; /* For $this pointer */
if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
EG(This)->refcount--;
}
}
EG(opline_ptr) = &EX(opline);
EX(function_state).function = (zend_function *) op_array;
EG(function_state_ptr) = &EX(function_state);
#if ZEND_DEBUG
/* function_state.function_symbol_table is saved as-is to a stack,
* which is an intentional UMR. Shut it up if we're in DEBUG.
*/
EX(function_state).function_symbol_table = NULL;
#endif
while (1) {
{%ZEND_VM_CONTINUE_LABEL%}
#ifdef ZEND_WIN32
if (EG(timed_out)) {
zend_timeout(0);
}
#endif
{%ZEND_VM_DISPATCH%} {
{%INTERNAL_EXECUTOR%}
}
}
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
}
{%EXTERNAL_EXECUTOR%}
void {%INITIALIZER_NAME%}()
{
{%EXTERNAL_LABELS%}
}

1001
Zend/zend_vm_gen.php
File diff suppressed because it is too large
View File

Loading…
Cancel
Save