@@ -25,8 +25,10 @@ namespace executorch {
25
25
namespace extension {
26
26
namespace pytree {
27
27
28
- inline void pytree_assert (bool must_be_true) {
29
- assert (must_be_true);
28
+ inline void pytree_check (bool must_be_true) {
29
+ if (!must_be_true) {
30
+ throw std::runtime_error (" pytree assertion failed" );
31
+ }
30
32
}
31
33
32
34
#ifdef _MSC_VER
@@ -37,18 +39,6 @@ inline void pytree_assert(bool must_be_true) {
37
39
#define EXECUTORCH_ALWAYS_INLINE inline
38
40
#endif
39
41
40
- [[noreturn]] EXECUTORCH_ALWAYS_INLINE void pytree_unreachable () {
41
- assert (false );
42
- #if defined(__GNUC__)
43
- __builtin_unreachable ();
44
- #elif defined(_MSC_VER)
45
- __assume (0 );
46
- #else
47
- while (!0 )
48
- ;
49
- #endif
50
- }
51
-
52
42
enum class Kind : uint8_t { List, Tuple, NamedTuple, Dict, Leaf, Custom, None };
53
43
54
44
using KeyStr = std::string;
@@ -144,45 +134,45 @@ struct ContainerHandle {
144
134
: handle(std::move(c)) {}
145
135
146
136
void set_leaf (leaf_type* leaf) {
147
- pytree_assert (handle->kind == Kind::Leaf);
137
+ pytree_check (handle->kind == Kind::Leaf);
148
138
handle->leaf = leaf;
149
139
}
150
140
151
141
operator leaf_type () const {
152
- pytree_assert (handle->kind == Kind::Leaf);
142
+ pytree_check (handle->kind == Kind::Leaf);
153
143
return *handle->leaf ;
154
144
}
155
145
156
146
const leaf_type& leaf () const {
157
- pytree_assert (handle->kind == Kind::Leaf);
147
+ pytree_check (handle->kind == Kind::Leaf);
158
148
return *handle->leaf ;
159
149
}
160
150
leaf_type& leaf () {
161
- pytree_assert (handle->kind == Kind::Leaf);
151
+ pytree_check (handle->kind == Kind::Leaf);
162
152
return *handle->leaf ;
163
153
}
164
154
165
155
const leaf_type* leaf_ptr () const {
166
- pytree_assert (handle->kind == Kind::Leaf);
156
+ pytree_check (handle->kind == Kind::Leaf);
167
157
return handle->leaf ;
168
158
}
169
159
leaf_type* leaf_ptr () {
170
- pytree_assert (handle->kind == Kind::Leaf);
160
+ pytree_check (handle->kind == Kind::Leaf);
171
161
return handle->leaf ;
172
162
}
173
163
174
164
const ContainerHandle& operator [](size_t idx) const {
175
- pytree_assert (idx < handle->size );
165
+ pytree_check (idx < handle->size );
176
166
return handle->items [idx];
177
167
}
178
168
179
169
ContainerHandle& operator [](size_t idx) {
180
- pytree_assert (idx < handle->size );
170
+ pytree_check (idx < handle->size );
181
171
return handle->items [idx];
182
172
}
183
173
184
174
bool contains (const KeyStr& lookup_key) const {
185
- pytree_assert (isDict ());
175
+ pytree_check (isDict ());
186
176
for (size_t i = 0 ; i < handle->size ; ++i) {
187
177
if (handle->keys [i] == lookup_key) {
188
178
return true ;
@@ -192,13 +182,13 @@ struct ContainerHandle {
192
182
}
193
183
194
184
const ContainerHandle& at (const Key& lookup_key) const {
195
- pytree_assert (isDict ());
185
+ pytree_check (isDict ());
196
186
for (size_t i = 0 ; i < handle->size ; ++i) {
197
187
if (handle->keys [i] == lookup_key) {
198
188
return handle->items [i];
199
189
}
200
190
}
201
- pytree_unreachable ( );
191
+ throw std::runtime_error ( " Dict::at lookup failed " );
202
192
}
203
193
204
194
const ContainerHandle& at (const KeyInt& lookup_key) const {
@@ -210,11 +200,11 @@ struct ContainerHandle {
210
200
}
211
201
212
202
const Key& key (size_t idx) const {
213
- pytree_assert (isDict ());
203
+ pytree_check (isDict ());
214
204
return handle->keys [idx];
215
205
}
216
206
Key& key (size_t idx) {
217
- pytree_assert (isDict ());
207
+ pytree_check (isDict ());
218
208
return handle->keys [idx];
219
209
}
220
210
@@ -399,7 +389,8 @@ StrTreeSpec to_str_internal(const TreeSpec<Aux>& spec) {
399
389
s.append (key.as_str ());
400
390
s.push_back (Config::kDictStrKeyQuote );
401
391
} else {
402
- pytree_unreachable ();
392
+ throw std::runtime_error (
393
+ " invalid key in pytree dict; must be int or string" );
403
394
}
404
395
s.push_back (Config::kDictKeyValueSep );
405
396
s.append (to_str_internal (spec[i]));
@@ -475,6 +466,11 @@ struct arr {
475
466
476
467
inline size_t read_number (const StrTreeSpec& spec, size_t & read_idx) {
477
468
size_t num = 0 ;
469
+ if (!isdigit (spec.at (read_idx))) {
470
+ throw std::runtime_error (
471
+ std::string (" expected a digit while decoding pytree, not " ) +
472
+ spec[read_idx]);
473
+ }
478
474
while (isdigit (spec.at (read_idx))) {
479
475
num = 10 * num + (spec[read_idx] - ' 0' );
480
476
read_idx++;
@@ -583,7 +579,6 @@ TreeSpec<Aux> from_str_internal(
583
579
c->keys [child_idx] = spec.substr (read_idx, key_len);
584
580
read_idx = key_delim_idx + 2 ;
585
581
} else {
586
- pytree_assert (isdigit (spec[read_idx]));
587
582
size_t key = read_number (spec, read_idx);
588
583
c->keys [child_idx] = KeyInt (key);
589
584
read_idx += 1 ;
@@ -604,7 +599,6 @@ TreeSpec<Aux> from_str_internal(
604
599
case Config::kLeaf :
605
600
return new TreeSpecContainer<Aux>(nullptr );
606
601
}
607
- pytree_unreachable ();
608
602
return new TreeSpecContainer<Aux>(Kind::None);
609
603
}
610
604
@@ -616,17 +610,17 @@ struct stack final {
616
610
T data[SIZE];
617
611
618
612
void push (T&& item) {
619
- pytree_assert (size_ < SIZE);
613
+ pytree_check (size_ < SIZE);
620
614
data[size_++] = std::move (item);
621
615
}
622
616
623
617
T pop () {
624
- pytree_assert (size_ > 0 );
618
+ pytree_check (size_ > 0 );
625
619
return data[--size_];
626
620
}
627
621
628
622
T& top () {
629
- pytree_assert (size_ > 0 );
623
+ pytree_check (size_ > 0 );
630
624
return data[size_ - 1 ];
631
625
}
632
626
0 commit comments