自定义优化器

    要创建优化器,您必须在“优化器”目录中创建一个类(您可以在中配置该目录的名称; 见下文)。 必须使用以下命名约定:

    请注意, 优化器是用 PHP 编写的, 而不是 Zephir编写的。 在编译过程中, 它用于以编程方式为您的扩展调用生成适当的 c 代码。 它负责检查参数和返回类型是否与 c 函数实际需要的内容相匹配, 从而防止 Zephir 生成无效的 c 代码。

    这是 “优化器” 的基本结构:

    优化器的实现在很大程度上取决于要生成的代码类型。 在我们的示例中, 我们将用对 c 函数的调用来替换对此函数的调用。 在 Zephir 中, 用于调用此函数的代码是:

    1. let pi = calculate_pi(1000);

    因此, 优化器只需要一个参数, 我们必须验证这一点, 以避免以后出现问题:

    1. <?php
    2. public function optimize(array $expression, Call $call, CompilationContext $context)
    3. {
    4. if (!isset($expression['parameters'])) {
    5. throw new CompilerException("'calculate_pi' requires one parameter", $expression);
    6. }
    7. }
    8. //...
    9. }

    我们正在检查返回的值是否将存储在 double 类型的变量中; 否则, 将引发编译器异常。

    接下来我们需要做的是处理传递给函数的参数:

    1. <?php
    2. $resolvedParams = $call->getReadOnlyResolvedParams($expression['parameters'], $context, $expression);

    Zephir 的一个好做法是创建不修改其参数的函数。 如果要更改传递的参数, Zephir 将需要为其分配内存, 并且必须使用 getResolvedParams 而不是 getReadOnlyResolvedParams

    这些方法返回的代码是有效的 c 代码, 可在代码打印机中用于生成 c 函数调用:

    1. <?php
    2. // Generate the C-code

    所有优化器都必须返回一个编译表达式实例。 这将告诉编译器代码返回的类型及其相关的c代码。

    实现函数my_calculate_pi的代码是用C编写的,必须与扩展一起编译。

    这段代码必须放在ext/目录中任何您认为合适的位置; 检查这些文件是否与Zephir生成的文件冲突。

    这个文件必须包含Zend Engine标头,以及函数的C实现:

    1. #include "config.h"
    2. #endif
    3. #include "php.h"
    4. #include "php_ext.h"
    5. double my_calculate_pi(zval *accuracy) {
    6. return 0.0;
    7. }

    This file must be added at a special section in the config.json file:

    1. "extra-sources": [
    2. "utils/pi.c"

    最后, 您必须使用 optimizer-dirs 配置选项指定 Zephir 在何处可以找到优化器。