Python内核源码解析:深入研究抽象语法树实现

除了常量折叠优化外,Python还有其它的语法树优化手段。

fold_binop

如果表达式的左值和右值都是常量,那么可以对表达式进行折叠优化。如 1 + 2,可以直接折叠为 3。这个操作是通过调用 PyNumber_Add 函数来实现数值的相加,那么最终的结果就是一个常量。除了加法外,还有减法、乘法、除法、位运算等操作。由于上一篇文章已经介绍了这种折叠优化,这里就不再赘述。

make_const

新的 val 是被计算出来的一个常量,如果 val 为 NULL,则跳过。如果 val 不为空,则需要给 val 分配新的内存,将 val 赋值给 node 的 Constant.value,并将 node 的 kind(类型)设置为 Constant_kind。

make_const 在很多地方都会被调用,如 fold_binop、fold_unaryop、fold_iter、fold_compare、fold_subscr、fold_tuple 等函数中。

static int
make_const(expr_ty node, PyObject *val, PyArena *arena)
{
    // Even if no new value was calculated, make_const may still
    // need to clear an error (e.g. for division by zero)
    if (val == NULL) {
        if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
            return 0;
        }
        PyErr_Clear();
        return 1;
    }
    if (_PyArena_AddPyObject(arena, val) < 0) {
        Py_DECREF(val);
        return 0;
    }
    node->kind = Constant_kind;
    node->v.Constant.kind = NULL;
    node->v.Constant.value = val;
    return 1;
}

fold_unaryop

一元运算操作符的折叠优化,如 not、-、+、~ 等操作符。如果操作数不是常量,那么直接返回。否则,根据操作符的类型,调用对应的函数进行计算。如 not 操作符,调用 unary_not 函数,- 操作符,调用 PyNumber_Negative 函数,+ 操作符,调用 PyNumber_Positive 函数,~ 操作符,调用 PyNumber_Invert 函数。

static int
fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
{
    expr_ty arg = node->v.UnaryOp.operand;

    if (arg->kind != Constant_kind) {
        /* Fold not into comparison */
        if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind &&
                asdl_seq_LEN(arg->v.Compare.ops) == 1) {
            /* Eq and NotEq are often implemented in terms of one another, so
               folding not (self == other) into self != other breaks implementation
               of !=. Detecting such cases doesn't seem worthwhile.
               Python uses </> for 'is subset'/'is superset' operations on sets.
               They don't satisfy not folding laws. */
            cmpop_ty op = asdl_seq_GET(arg->v.Compare.ops, 0);
            switch (op) {
            case Is:
                op = IsNot;
                break;
            case IsNot:
                op = Is;
                break;
            case In:
                op = NotIn;
             
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值