@@ -257,11 +257,19 @@ bool parse_cond_value(const EValue& cond_value) {
257
257
258
258
} // namespace
259
259
260
- Error Method::parse_values (
261
- const flatbuffers::Vector<
262
- flatbuffers::Offset<executorch_flatbuffer::EValue>>* flatbuffer_values,
263
- size_t * num_parsed) {
264
- for (size_t i = 0 ; i < n_value_; ++i) {
260
+ Error Method::parse_values () {
261
+ auto flatbuffer_values = serialization_plan_->values ();
262
+ ET_CHECK (flatbuffer_values != nullptr );
263
+ size_t n_value = flatbuffer_values->size ();
264
+ values_ = ET_ALLOCATE_LIST_OR_RETURN_ERROR (
265
+ memory_manager_->get_runtime_allocator (), EValue, n_value);
266
+
267
+ // n_value_ counts the number of successfully-initialized values for ~Method()
268
+ // to clean up, and is incremented at the bottom of the loop. This makes it
269
+ // safe for errors to return without updating any state.
270
+ n_value_ = 0 ;
271
+
272
+ for (size_t i = 0 ; i < n_value; ++i) {
265
273
auto serialization_value = flatbuffer_values->Get (i);
266
274
switch (serialization_value->val_type ()) {
267
275
case executorch_flatbuffer::KernelTypes::Null: {
@@ -329,7 +337,6 @@ Error Method::parse_values(
329
337
" Failed parsing tensor at index %zu: %" PRIu32,
330
338
i,
331
339
t.error ());
332
- *num_parsed = i;
333
340
return t.error ();
334
341
}
335
342
new (&values_[i]) EValue (t.get ());
@@ -347,7 +354,6 @@ Error Method::parse_values(
347
354
" Failed parsing tensor list at index %zu: %" PRIu32,
348
355
i,
349
356
tensors.error ());
350
- *num_parsed = i;
351
357
return tensors.error ();
352
358
}
353
359
new (&values_[i]) EValue (tensors.get ());
@@ -365,7 +371,6 @@ Error Method::parse_values(
365
371
" Failed parsing optional tensor list at index %zu: %" PRIu32,
366
372
i,
367
373
tensors.error ());
368
- *num_parsed = i;
369
374
return tensors.error ();
370
375
}
371
376
new (&values_[i]) EValue (tensors.get ());
@@ -383,8 +388,12 @@ Error Method::parse_values(
383
388
" to see which type this is." ,
384
389
static_cast <uint32_t >(serialization_value->val_type ()) - 1 );
385
390
}
391
+
392
+ // ~Method() will try to clean up n_value_ entries in the values_ array.
393
+ // Only increment this once we know the entry is valid, so that we don't try
394
+ // to clean up an uninitialized entry.
395
+ n_value_ = i + 1 ;
386
396
}
387
- *num_parsed = n_value_;
388
397
return Error::Ok;
389
398
}
390
399
@@ -502,18 +511,9 @@ Error Method::init(executorch_flatbuffer::ExecutionPlan* s_plan) {
502
511
auto runtime_allocator = memory_manager_->get_runtime_allocator ();
503
512
504
513
{
505
- // Load values
506
- auto plan_values = serialization_plan_->values ();
507
- ET_CHECK (plan_values != nullptr );
508
- n_value_ = plan_values->size ();
509
- values_ =
510
- ET_ALLOCATE_LIST_OR_RETURN_ERROR (runtime_allocator, EValue, n_value_);
511
- size_t num_parsed;
512
- Error err = parse_values (plan_values, &num_parsed);
514
+ // Parse the elements of the values_ array.
515
+ Error err = parse_values ();
513
516
if (err != Error::Ok) {
514
- // ~Method() will try to clean up entries in this list. Ensure that it
515
- // doesn't look at any uninitialized entries.
516
- n_value_ = num_parsed;
517
517
return err;
518
518
}
519
519
}
0 commit comments