php内核分析(八)-zend_compile

这里阅读的php版本为PHP-7.1.0 RC3,阅读代码的平台为linux

回到之前看的zend_eval_stringl

ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name) /* {{{ */
{
    ...
    new_op_array = zend_compile_string(&pv, string_name);  // 这个是把php代码编译成为opcode的过程
    ...
    zend_execute(new_op_array, &local_retval); // 这个是具体的执行过程,执行opcode,把结果存储到local_retval中
    ...
    retval = SUCCESS;
    return retval;
}

这里的zend_execute执行了两步,第一步是把php编译解析成为opcode的过程,我们就先看这个。

zend_compile_string

zend_compile_string函数追下去可以追到compile_string

// 将一个字符串解析成为op_array
zend_op_array *compile_string(zval *source_string, char *filename)
{
     zend_lex_state original_lex_state;
     zend_op_array *op_array = NULL;
     zval tmp;

    // 如果传进来要解析的字符为空,则返回null
     if (Z_STRLEN_P(source_string)==0) {
          return NULL;
     }

     ZVAL_DUP(&tmp, source_string); // 复制source_string到zval中
     convert_to_string(&tmp); // 如果不是字符类型就转换为字符类型
     source_string = &tmp;

     zend_save_lexical_state(&original_lex_state); // 保存lex上下文
     if (zend_prepare_string_for_scanning(source_string, filename) == SUCCESS) {  // 做编译前的准备
          BEGIN(ST_IN_SCRIPTING); // 设置状态为正在编译
          op_array = zend_compile(ZEND_EVAL_CODE); // 进行编译,并把生成结果放在op_array中
     }

     zend_restore_lexical_state(&original_lex_state); // 恢复lex上下文
     zval_dtor(&tmp); // 释放tmp

     return op_array;
}

里面最核心的就是zend_compile了。这里的几个点可以看看:

1 这么做类型转换,参考convert_to_string。这个函数就是把任意类型的值转换为zval的string类型。
2 zval_dtor,这个函数是能把任意的zval变量做回收。非常好用。
3 ZVAL_DUP,是进行复制,它和ZVAL_COPY的区别在于是否增加gc的引用计数。

下面又找到关键点:zend_compile

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值