2020#include " absl/types/span.h"
2121#include " eval/eval/attribute_trail.h"
2222#include " eval/eval/attribute_utility.h"
23+ #include " eval/eval/evaluator_stack.h"
2324#include " eval/public/activation.h"
2425#include " eval/public/cel_attribute.h"
2526#include " eval/public/cel_expression.h"
@@ -42,7 +43,7 @@ class ExpressionStep {
4243 virtual ~ExpressionStep () {}
4344
4445 // Performs actual evaluation.
45- // Values are passed between Expression objects via ValueStack , which is
46+ // Values are passed between Expression objects via EvaluatorStack , which is
4647 // supplied with context.
4748 // Also, Expression gets values supplied by caller though Activation
4849 // interface.
@@ -64,122 +65,6 @@ class ExpressionStep {
6465
6566using ExecutionPath = std::vector<std::unique_ptr<const ExpressionStep>>;
6667
67- // CelValue stack.
68- // Implementation is based on vector to allow passing parameters from
69- // stack as Span<>.
70- class ValueStack {
71- public:
72- explicit ValueStack (size_t max_size) : current_size_(0 ) {
73- stack_.resize (max_size);
74- attribute_stack_.resize (max_size);
75- }
76-
77- // Return the current stack size.
78- size_t size () const { return current_size_; }
79-
80- // Return the maximum size of the stack.
81- size_t max_size () const { return stack_.size (); }
82-
83- // Returns true if stack is empty.
84- bool empty () const { return current_size_ == 0 ; }
85-
86- // Attributes stack size.
87- size_t attribute_size () const { return current_size_; }
88-
89- // Check that stack has enough elements.
90- bool HasEnough (size_t size) const { return current_size_ >= size; }
91-
92- // Dumps the entire stack state as is.
93- void Clear ();
94-
95- // Gets the last size elements of the stack.
96- // Checking that stack has enough elements is caller's responsibility.
97- // Please note that calls to Push may invalidate returned Span object.
98- absl::Span<const CelValue> GetSpan (size_t size) const {
99- if (!HasEnough (size)) {
100- GOOGLE_LOG (ERROR) << " Requested span size (" << size
101- << " ) exceeds current stack size: " << current_size_;
102- }
103- return absl::Span<const CelValue>(stack_.data () + current_size_ - size,
104- size);
105- }
106-
107- // Gets the last size attribute trails of the stack.
108- // Checking that stack has enough elements is caller's responsibility.
109- // Please note that calls to Push may invalidate returned Span object.
110- absl::Span<const AttributeTrail> GetAttributeSpan (size_t size) const {
111- return absl::Span<const AttributeTrail>(
112- attribute_stack_.data () + current_size_ - size, size);
113- }
114-
115- // Peeks the last element of the stack.
116- // Checking that stack is not empty is caller's responsibility.
117- const CelValue& Peek () const {
118- if (empty ()) {
119- GOOGLE_LOG (ERROR) << " Peeking on empty ValueStack" ;
120- }
121- return stack_[current_size_ - 1 ];
122- }
123-
124- // Peeks the last element of the attribute stack.
125- // Checking that stack is not empty is caller's responsibility.
126- const AttributeTrail& PeekAttribute () const {
127- if (empty ()) {
128- GOOGLE_LOG (ERROR) << " Peeking on empty ValueStack" ;
129- }
130- return attribute_stack_[current_size_ - 1 ];
131- }
132-
133- // Clears the last size elements of the stack.
134- // Checking that stack has enough elements is caller's responsibility.
135- void Pop (size_t size) {
136- if (!HasEnough (size)) {
137- GOOGLE_LOG (ERROR) << " Trying to pop more elements (" << size
138- << " ) than the current stack size: " << current_size_;
139- }
140- current_size_ -= size;
141- }
142-
143- // Put element on the top of the stack.
144- void Push (const CelValue& value) { Push (value, AttributeTrail ()); }
145-
146- void Push (const CelValue& value, AttributeTrail attribute) {
147- if (current_size_ >= stack_.size ()) {
148- GOOGLE_LOG (ERROR) << " No room to push more elements on to ValueStack" ;
149- }
150- stack_[current_size_] = value;
151- attribute_stack_[current_size_] = attribute;
152- current_size_++;
153- }
154-
155- // Replace element on the top of the stack.
156- // Checking that stack is not empty is caller's responsibility.
157- void PopAndPush (const CelValue& value) {
158- PopAndPush (value, AttributeTrail ());
159- }
160-
161- // Replace element on the top of the stack.
162- // Checking that stack is not empty is caller's responsibility.
163- void PopAndPush (const CelValue& value, AttributeTrail attribute) {
164- if (empty ()) {
165- GOOGLE_LOG (ERROR) << " Cannot PopAndPush on empty stack." ;
166- }
167- stack_[current_size_ - 1 ] = value;
168- attribute_stack_[current_size_ - 1 ] = attribute;
169- }
170-
171- // Preallocate stack.
172- void Reserve (size_t size) {
173- stack_.reserve (size);
174- attribute_stack_.reserve (size);
175- }
176-
177- private:
178- std::vector<CelValue> stack_;
179- std::vector<AttributeTrail> attribute_stack_;
180- size_t current_size_;
181- };
182-
18368class CelExpressionFlatEvaluationState : public CelEvaluationState {
18469 public:
18570 CelExpressionFlatEvaluationState (
@@ -196,7 +81,7 @@ class CelExpressionFlatEvaluationState : public CelEvaluationState {
19681
19782 void Reset ();
19883
199- ValueStack & value_stack () { return value_stack_; }
84+ EvaluatorStack & value_stack () { return value_stack_; }
20085
20186 std::vector<IterVarFrame>& iter_stack () { return iter_stack_; }
20287
@@ -207,7 +92,7 @@ class CelExpressionFlatEvaluationState : public CelEvaluationState {
20792 google::protobuf::Arena* arena () { return arena_; }
20893
20994 private:
210- ValueStack value_stack_;
95+ EvaluatorStack value_stack_;
21196 std::set<std::string> iter_variable_names_;
21297 std::vector<IterVarFrame> iter_stack_;
21398 google::protobuf::Arena* arena_;
@@ -254,7 +139,7 @@ class ExecutionFrame {
254139 return absl::OkStatus ();
255140 }
256141
257- ValueStack & value_stack () { return state_->value_stack (); }
142+ EvaluatorStack & value_stack () { return state_->value_stack (); }
258143 bool enable_unknowns () const { return enable_unknowns_; }
259144 bool enable_unknown_function_results () const {
260145 return enable_unknown_function_results_;
0 commit comments