| 2016 | } |
| 2017 | |
| 2018 | FlatExprVisitor::CallHandlerResult FlatExprVisitor::HandleBlock( |
| 2019 | const cel::Expr& expr, const cel::CallExpr& call_expr) { |
| 2020 | ABSL_DCHECK(call_expr.function() == kBlock); |
| 2021 | if (!block_.has_value() || block_->expr != &expr || |
| 2022 | call_expr.args().size() != 2 || call_expr.has_target()) { |
| 2023 | SetProgressStatusError( |
| 2024 | absl::InvalidArgumentError("unexpected call to internal cel.@block")); |
| 2025 | return CallHandlerResult::kIntercepted; |
| 2026 | } |
| 2027 | |
| 2028 | BlockInfo& block = *block_; |
| 2029 | block.in = false; |
| 2030 | index_manager().ReleaseSlots(block.slot_count); |
| 2031 | |
| 2032 | // Check if eligible for recursion and update the plan if so. |
| 2033 | // |
| 2034 | // The first argument to @block is the list of initializers. These don't |
| 2035 | // generate a plan in the main program (they are tracked separately to support |
| 2036 | // lazy evaluation) so we only need to extract the second argument -- the body |
| 2037 | // of the block that uses the initializers. |
| 2038 | ProgramBuilder::Subexpression* body_subexpression = |
| 2039 | program_builder_.GetSubexpression(&call_expr.args()[1]); |
| 2040 | |
| 2041 | if (options_.max_recursion_depth != 0 && body_subexpression != nullptr && |
| 2042 | body_subexpression->IsRecursive() && |
| 2043 | (options_.max_recursion_depth < 0 || |
| 2044 | body_subexpression->recursive_program().depth < |
| 2045 | options_.max_recursion_depth)) { |
| 2046 | auto recursive_program = body_subexpression->ExtractRecursiveProgram(); |
| 2047 | SetRecursiveStep( |
| 2048 | CreateDirectBlockStep(block.index, block.slot_count, |
| 2049 | std::move(recursive_program.step), expr.id()), |
| 2050 | recursive_program.depth + 1); |
| 2051 | return CallHandlerResult::kIntercepted; |
| 2052 | } |
| 2053 | |
| 2054 | // Otherwise, iterative plan. |
| 2055 | AddStep(CreateClearSlotsStep(block.index, block.slot_count, expr.id())); |
| 2056 | |
| 2057 | return CallHandlerResult::kIntercepted; |
| 2058 | } |
| 2059 | |
| 2060 | FlatExprVisitor::CallHandlerResult FlatExprVisitor::HandleListAppend( |
| 2061 | const cel::Expr& expr, const cel::CallExpr& call_expr) { |
nothing calls this directly
no test coverage detected