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