了解 zend_execute 个 API

Understanding zend_execute APIs

我四处看了很多,但从来没有找到一本关于 zend_extensions 的好书或任何在线文档 [在 PHP 扩展上找到了很多,但在 zend_extensions] 上找到了很多。我正在编写扩展程序并希望执行以下操作:

1. 捕获当前正在执行的函数的状态(主要是函数调用的参数)。 [我找到了一个包含一些函数数据的结构,并查看它以找到函数参数名称,但无法找到它们的值。如果 zend_execute_data *execd 是结构指针。

execd->function_state.function->common.(arg_info+i)->name)给出当前函数的第i个参数的变量名]。如何获取第 i 个参数的 value。我知道我需要从堆栈中读取。如何获取对堆栈中参数的引用?有哈希 table 什么的吗?

2.其次,如何在php脚本中跳过当前执行的函数跳转到下一个function/statement或者替换当前函数的代码来自该函数的更清洁或安全版本的代码?来自 zend_execute 函数。

大图:我正在尝试获取函数状态并根据函数状态对解释器的执行流程做出一些决定。我正在尝试从 zend_extension 中的 zend_execute( ) 执行所有这些操作,因此我只有 zend_execute( ) API 来完成上述 2 个任务。下面是我已经检查过并检查过的结构列表,以便能够找到当前函数的参数值。

struct _zend_execute_data {
    struct _zend_op *opline;
    zend_function_state function_state;
    zend_function *fbc; /* Function Being Called */
    zend_class_entry *called_scope;
    zend_op_array *op_array;
    zval *object;
    union _temp_variable *Ts;
    zval ***CVs;
    HashTable *symbol_table;
    struct _zend_execute_data *prev_execute_data;
    zval *old_error_reporting;
    zend_bool nested;
    zval **original_return_value;
    zend_class_entry *current_scope;
    zend_class_entry *current_called_scope;
    zval *current_this;
    zval *current_object;
};

参考资料

typedef struct _zend_function_state {
    zend_function *function;
    void **arguments;
} zend_function_state;

参考文献

typedef union _zend_function {
    zend_uchar type;  /* MUST be the first element of this struct! */

    struct {
        zend_uchar type;  /* never used */
        const char *function_name;
        zend_class_entry *scope;
        zend_uint fn_flags;
        union _zend_function *prototype;
        zend_uint num_args;
        zend_uint required_num_args;
        zend_arg_info *arg_info;
    } common;

    zend_op_array op_array;
    zend_internal_function internal_function;
} zend_function;

关于内部的文档不多,我没能加入内部邮件列表。它说我正在等待批准。我参考了有关 PHP 扩展编写的文章和 "Advanced PHP programming" 等书籍,但对这些方面及其周围的 API 仍然很模糊。

直接回答或任何关于我如何从这里取得进展的一般建议将不胜感激。这是我在 Stack Overflow 上的第一个 post,如果有任何我没有遵守的准则,我深表歉意。我试图在尽可能多的方面做到合规。

我在检查 Zend 文件夹中的一些源代码时发现了这一点。 如果将其转换为 (zval **) 并分配给 (zval *) 然后分配给 zval,则下面的结构具有 void ** 的元素,[ 的每个元素=14=]可以访问。事实证明这是一个非常微不足道的问题。

typedef struct _zend_function_state {
    zend_function *function;
    void **arguments;
} zend_function_state;

用法示例:

ptr = (zval**)execd_init->function_state.arguments;
ptr1 = *(ptr-2);
ptr3 = *(ptr-1);
ptr2.value.str.val // gives the string value if type is string
ptr4.value.str.val // gives the second argument of type string
(*(curr_func->common.arg_info + i)).name

给名字。

void **args = ex->function_state.arguments;
int argc = (int) (zend_uintptr_t) *args;

*(args - (argc - i))

给出值。