|
36 | 36 | #include "zend_exceptions.h"
|
37 | 37 | #include "zend_vm.h"
|
38 | 38 |
|
| 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 | + |
39 | 54 | typedef int (*incdec_t)(zval *);
|
40 | 55 |
|
41 | 56 | #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
|
260 | 275 | }
|
261 | 276 | }
|
262 | 277 |
|
263 |
| -#ifdef ZEND_VM_SPEC |
264 |
| - |
265 | 278 | static inline zval *_get_zval_ptr_const(znode *node, temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
|
266 | 279 | {
|
267 | 280 | return &node->u.constant;
|
@@ -453,7 +466,6 @@ static inline zval **_get_obj_zval_ptr_ptr_unused(znode *op, temp_variable *Ts,
|
453 | 466 | return NULL;
|
454 | 467 | }
|
455 | 468 | }
|
456 |
| -#endif |
457 | 469 |
|
458 | 470 | static inline void zend_switch_free(zend_op *opline, temp_variable *Ts TSRMLS_DC)
|
459 | 471 | {
|
@@ -1427,265 +1439,38 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v
|
1427 | 1439 | ((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);
|
1428 | 1440 | }
|
1429 | 1441 |
|
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" |
1689 | 1474 |
|
1690 | 1475 | /*
|
1691 | 1476 | * Local variables:
|
|
0 commit comments