Skip to content

Commit e50a6fd

Browse files
author
Andi Gutmans
committed
- 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) :)
1 parent b20d2ba commit e50a6fd

File tree

6 files changed

+4545
-628
lines changed

6 files changed

+4545
-628
lines changed

Zend/Makefile.frag

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Zend/zend_execute.lo: $(srcdir)/zend_vm_spec.h $(srcdir)/zend_vm_handlers.h
1+
Zend/zend_execute.lo: $(srcdir)/zend_vm_execute.h

Zend/zend_execute.c

+47-262
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,21 @@
3636
#include "zend_exceptions.h"
3737
#include "zend_vm.h"
3838

39+
#define _CONST_CODE 0
40+
#define _TMP_CODE 1
41+
#define _VAR_CODE 2
42+
#define _UNUSED_CODE 3
43+
#define _CV_CODE 4
44+
45+
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(ZEND_VM_OLD_EXECUTOR)
46+
# define ZEND_VM_ALWAYS_INLINE __attribute__ ((always_inline))
47+
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn));
48+
/*extern void zend_error_noreturn(int type, const char *format, ...) __asm__("zend_error") __attribute__ ((noreturn));*/
49+
#else
50+
# define ZEND_VM_ALWAYS_INLINE
51+
# define zend_error_noreturn zend_error
52+
#endif
53+
3954
typedef int (*incdec_t)(zval *);
4055

4156
#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
260275
}
261276
}
262277

263-
#ifdef ZEND_VM_SPEC
264-
265278
static inline zval *_get_zval_ptr_const(znode *node, temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
266279
{
267280
return &node->u.constant;
@@ -453,7 +466,6 @@ static inline zval **_get_obj_zval_ptr_ptr_unused(znode *op, temp_variable *Ts,
453466
return NULL;
454467
}
455468
}
456-
#endif
457469

458470
static inline void zend_switch_free(zend_op *opline, temp_variable *Ts TSRMLS_DC)
459471
{
@@ -1427,265 +1439,38 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v
14271439
((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);
14281440
}
14291441

1430-
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
1431-
{
1432-
zend_execute_data execute_data;
1433-
ZEND_VM_HELPER_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
1434-
ZEND_VM_HELPER_VAR(incdec_t incdec_op)
1435-
ZEND_VM_HELPER_VAR(int prop_dim)
1436-
ZEND_VM_HELPER_VAR(int type)
1437-
1438-
#if ZEND_VM_KIND == ZEND_VM_KIND_GOTO
1439-
if (op_array == NULL) {
1440-
goto init_labels;
1441-
}
1442-
#endif
1443-
1444-
/* Initialize execute_data */
1445-
EX(fbc) = NULL;
1446-
EX(object) = NULL;
1447-
if (op_array->T < TEMP_VAR_STACK_LIMIT) {
1448-
EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);
1449-
} else {
1450-
EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);
1451-
}
1452-
EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var);
1453-
memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
1454-
EX(op_array) = op_array;
1455-
EX(original_in_execution) = EG(in_execution);
1456-
EX(symbol_table) = EG(active_symbol_table);
1457-
EX(prev_execute_data) = EG(current_execute_data);
1458-
EG(current_execute_data) = &execute_data;
1459-
1460-
EG(in_execution) = 1;
1461-
if (op_array->start_op) {
1462-
ZEND_VM_SET_OPCODE(op_array->start_op);
1463-
} else {
1464-
ZEND_VM_SET_OPCODE(op_array->opcodes);
1465-
}
1466-
1467-
if (op_array->uses_this && EG(This)) {
1468-
EG(This)->refcount++; /* For $this pointer */
1469-
if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
1470-
EG(This)->refcount--;
1471-
}
1472-
}
1473-
1474-
EG(opline_ptr) = &EX(opline);
1475-
1476-
EX(function_state).function = (zend_function *) op_array;
1477-
EG(function_state_ptr) = &EX(function_state);
1478-
#if ZEND_DEBUG
1479-
/* function_state.function_symbol_table is saved as-is to a stack,
1480-
* which is an intentional UMR. Shut it up if we're in DEBUG.
1481-
*/
1482-
EX(function_state).function_symbol_table = NULL;
1483-
#endif
1484-
1485-
while (1) {
1486-
ZEND_VM_CONTINUE_LABEL
1487-
#ifdef ZEND_WIN32
1488-
if (EG(timed_out)) {
1489-
zend_timeout(0);
1490-
}
1491-
#endif
1492-
1493-
ZEND_VM_DISPATCH() {
1494-
#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
1495-
return;
1496-
#else
1497-
# include "zend_vm_spec.h"
1498-
#endif
1499-
}
1500-
1501-
}
1502-
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
1503-
#if ZEND_VM_KIND == ZEND_VM_KIND_GOTO
1504-
{
1505-
static const opcode_handler_t labels[] = {ZEND_VM_LABELS};
1506-
1507-
init_labels:
1508-
zend_opcode_handlers = (opcode_handler_t*)labels;
1509-
return;
1510-
}
1511-
#endif
1512-
}
1513-
1514-
#if ZEND_VM_KIND == ZEND_VM_KIND_CALL
1515-
# undef EX
1516-
# define EX(element) execute_data->element
1517-
# include"zend_vm_spec.h"
1518-
#endif
1519-
1520-
void zend_init_opcodes_handlers()
1521-
{
1522-
#if ZEND_VM_KIND == ZEND_VM_KIND_GOTO
1523-
TSRMLS_FETCH();
1524-
zend_execute(NULL TSRMLS_CC);
1525-
#else
1526-
static const opcode_handler_t labels[] = {ZEND_VM_LABELS};
1527-
1528-
zend_opcode_handlers = (opcode_handler_t*)labels;
1529-
#endif
1530-
}
1531-
1532-
#ifdef ZEND_VM_HAVE_OLD_EXECUTOR
1533-
/* Old Style Executor */
1534-
/* TODO: remove it */
1535-
1536-
# undef EX
1537-
# define EX(element) execute_data.element
1538-
1539-
/* Hack */
1540-
# define ZEND_VM_OLD_EXECUTOR
1541-
# undef ZEND_VM_H
1542-
# undef ZEND_VM_KIND
1543-
# define ZEND_VM_KIND ZEND_VM_KIND_CALL
1544-
# undef ZEND_VM_SPEC
1545-
# undef ZEND_VM_ALWAYS_INLINE
1546-
# undef zend_error_noreturn
1547-
# undef ZEND_VM_CODE
1548-
# undef ZEND_VM_SPEC_OPCODE
1549-
# undef ZEND_VM_SET_OPCODE_HANDLER
1550-
# undef EXECUTE_DATA
1551-
# undef ZEND_VM_HELPER_VAR
1552-
# undef ZEND_VM_DISPATCH
1553-
# undef ZEND_VM_HANDLER
1554-
# undef ZEND_VM_HANDLER_EX
1555-
# undef ZEND_VM_HELPER
1556-
# undef ZEND_VM_HELPER_EX
1557-
# undef ZEND_VM_SPEC_HANDLER
1558-
# undef ZEND_VM_SPEC_HANDLER_EX
1559-
# undef ZEND_VM_SPEC_HELPER
1560-
# undef ZEND_VM_SPEC_HELPER_EX
1561-
# undef ZEND_VM_NULL_HANDLER
1562-
# undef ZEND_VM_DISPATCH_TO_HANDLER
1563-
# undef ZEND_VM_DISPATCH_TO_HELPER
1564-
# undef ZEND_VM_DISPATCH_TO_HELPER_EX
1565-
# undef ZEND_VM_SPEC_DISPATCH_TO_HANDLER
1566-
# undef ZEND_VM_SPEC_DISPATCH_TO_HELPER
1567-
# undef ZEND_VM_SPEC_DISPATCH_TO_HELPER_EX
1568-
# undef ZEND_VM_CONTINUE
1569-
# undef ZEND_VM_NEXT_OPCODE
1570-
# undef ZEND_VM_RETURN_FROM_EXECUTE_LOOP
1571-
# undef ZEND_VM_LABEL
1572-
# undef ZEND_VM_NULL_LABEL
1573-
# undef ZEND_VM_SPEC_LABEL
1574-
# undef ZEND_VM_SPEC_NULL_LABEL
1575-
# undef ZEND_VM_CONTINUE_LABEL
1576-
1577-
# include "zend_vm.h"
1578-
1579-
static void old_execute(zend_op_array *op_array TSRMLS_DC)
1580-
{
1581-
zend_execute_data execute_data;
1582-
1583-
/* Initialize execute_data */
1584-
EX(fbc) = NULL;
1585-
EX(object) = NULL;
1586-
if (op_array->T < TEMP_VAR_STACK_LIMIT) {
1587-
EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);
1588-
} else {
1589-
EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);
1590-
}
1591-
EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var);
1592-
memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
1593-
EX(op_array) = op_array;
1594-
EX(original_in_execution) = EG(in_execution);
1595-
EX(symbol_table) = EG(active_symbol_table);
1596-
EX(prev_execute_data) = EG(current_execute_data);
1597-
EG(current_execute_data) = &execute_data;
1598-
1599-
EG(in_execution) = 1;
1600-
if (op_array->start_op) {
1601-
ZEND_VM_SET_OPCODE(op_array->start_op);
1602-
} else {
1603-
ZEND_VM_SET_OPCODE(op_array->opcodes);
1604-
}
1605-
1606-
if (op_array->uses_this && EG(This)) {
1607-
EG(This)->refcount++; /* For $this pointer */
1608-
if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
1609-
EG(This)->refcount--;
1610-
}
1611-
}
1612-
1613-
EG(opline_ptr) = &EX(opline);
1614-
1615-
EX(function_state).function = (zend_function *) op_array;
1616-
EG(function_state_ptr) = &EX(function_state);
1617-
#if ZEND_DEBUG
1618-
/* function_state.function_symbol_table is saved as-is to a stack,
1619-
* which is an intentional UMR. Shut it up if we're in DEBUG.
1620-
*/
1621-
EX(function_state).function_symbol_table = NULL;
1622-
#endif
1623-
1624-
while (1) {
1625-
#ifdef ZEND_WIN32
1626-
if (EG(timed_out)) {
1627-
zend_timeout(0);
1628-
}
1629-
#endif
1630-
1631-
ZEND_VM_DISPATCH() {
1632-
return;
1633-
}
1634-
1635-
}
1636-
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
1637-
}
1638-
# undef EX
1639-
# define EX(element) execute_data->element
1640-
1641-
/* Hack */
1642-
# undef OP1_OP2_MASK
1643-
# undef HAVE_OP
1644-
# undef ZEND_VM_C_GOTO
1645-
# undef ZEND_VM_C_LABEL
1646-
1647-
# include"zend_vm_spec.h"
1648-
1649-
ZEND_API int zend_vm_old_executor = 0;
1650-
1651-
void zend_vm_set_opcode_handler(zend_op* op)
1652-
{
1653-
if (zend_vm_old_executor) {
1654-
op->handler = zend_opcode_handlers[op->opcode];
1655-
} else {
1656-
static const int zend_vm_decode[] = {
1657-
_UNUSED_CODE, /* 0 */
1658-
_CONST_CODE, /* 1 = IS_CONST */
1659-
_TMP_CODE, /* 2 = IS_TMP_VAR */
1660-
_UNUSED_CODE, /* 3 */
1661-
_VAR_CODE, /* 4 = IS_VAR */
1662-
_UNUSED_CODE, /* 5 */
1663-
_UNUSED_CODE, /* 6 */
1664-
_UNUSED_CODE, /* 7 */
1665-
_UNUSED_CODE, /* 8 = IS_UNUSED */
1666-
_UNUSED_CODE, /* 9 */
1667-
_UNUSED_CODE, /* 10 */
1668-
_UNUSED_CODE, /* 11 */
1669-
_UNUSED_CODE, /* 12 */
1670-
_UNUSED_CODE, /* 13 */
1671-
_UNUSED_CODE, /* 14 */
1672-
_UNUSED_CODE, /* 15 */
1673-
_CV_CODE /* 16 = IS_CV */
1674-
};
1675-
op->handler = zend_opcode_handlers[op->opcode * 25 + zend_vm_decode[op->op1.op_type] * 5 + zend_vm_decode[op->op2.op_type]];
1676-
}
1677-
}
1678-
1679-
1680-
ZEND_API void zend_vm_use_old_executor()
1681-
{
1682-
static opcode_handler_t labels[512] = {ZEND_VM_LABELS};
1683-
1684-
zend_vm_old_executor = 1;
1685-
zend_opcode_handlers = (opcode_handler_t*)labels;
1686-
zend_execute = old_execute;
1687-
}
1688-
#endif
1442+
#define ZEND_VM_NEXT_OPCODE() \
1443+
CHECK_SYMBOL_TABLES() \
1444+
EX(opline)++; \
1445+
ZEND_VM_CONTINUE()
1446+
1447+
#define ZEND_VM_SET_OPCODE(new_op) \
1448+
CHECK_SYMBOL_TABLES() \
1449+
EX(opline) = new_op
1450+
1451+
#define ZEND_VM_INC_OPCODE() \
1452+
if (!EG(exception)) { \
1453+
CHECK_SYMBOL_TABLES() \
1454+
EX(opline)++; \
1455+
}
1456+
1457+
#define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
1458+
free_alloca(EX(CVs)); \
1459+
if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \
1460+
free_alloca(EX(Ts)); \
1461+
} else { \
1462+
efree(EX(Ts)); \
1463+
} \
1464+
EG(in_execution) = EX(original_in_execution); \
1465+
EG(current_execute_data) = EX(prev_execute_data); \
1466+
ZEND_VM_RETURN()
1467+
1468+
#define ZEND_VM_CONTINUE_JMP() \
1469+
ZEND_VM_CONTINUE()
1470+
1471+
static int zend_vm_old_executor = 0;
1472+
1473+
#include "zend_vm_execute.h"
16891474

16901475
/*
16911476
* Local variables:

0 commit comments

Comments
 (0)