Skip to content

Commit 077feaf

Browse files
authored
Fix error handling macros to work well with MSVC. (#13214)
Differential Revision: D79865456
1 parent c8c6628 commit 077feaf

File tree

2 files changed

+38
-68
lines changed

2 files changed

+38
-68
lines changed

runtime/core/error.h

Lines changed: 25 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -205,42 +205,37 @@ using ::executorch::runtime::error_code_t;
205205
* @param[in] ... Optional format string for the log error message and its
206206
* arguments.
207207
*/
208-
#define ET_CHECK_OK_OR_RETURN_ERROR(error__, ...) \
209-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR(error__, ##__VA_ARGS__)
210-
211-
// Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead.
212-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR(...) \
213-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_SELECT( \
214-
__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) \
215-
(__VA_ARGS__)
208+
#define ET_CHECK_OK_OR_RETURN_ERROR(...) \
209+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR(__VA_ARGS__)
216210

217211
/**
218212
* Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead.
219213
* This macro selects the correct version of
220214
* ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR based on the number of arguments passed.
221-
* It uses a trick with the preprocessor to count the number of arguments and
222-
* then selects the appropriate macro.
223-
*
224-
* The macro expansion uses __VA_ARGS__ to accept any number of arguments and
225-
* then appends them to ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_, followed by the
226-
* count of arguments. The count is determined by the macro
227-
* ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_SELECT which takes the arguments and
228-
* passes them along with a sequence of numbers (2, 1). The preprocessor then
229-
* matches this sequence to the correct number of arguments provided.
230-
*
231-
* If two arguments are passed, ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2 is
232-
* selected, suitable for cases where an error code and a custom message are
233-
* provided. If only one argument is passed,
234-
* ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_1 is selected, which is used for cases
235-
* with just an error code.
236-
*
237-
* Usage:
238-
* ET_CHECK_OK_OR_RETURN_ERROR(error_code); // Calls v1
239-
* ET_CHECK_OK_OR_RETURN_ERROR(error_code, "Error message", ...); // Calls v2
215+
* It uses a helper that reliably picks the 1-arg or 2+-arg form on
216+
* MSVC/Clang/GCC.
240217
*/
241-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_SELECT( \
242-
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) \
243-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_##N
218+
#define ET_INTERNAL_EXPAND(x) x
219+
#define ET_INTERNAL_GET_MACRO( \
220+
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) \
221+
NAME
222+
223+
// Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead.
224+
// Picks _2 for 2..10 args, _1 for exactly 1 arg.
225+
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR(...) \
226+
ET_INTERNAL_EXPAND(ET_INTERNAL_GET_MACRO( \
227+
__VA_ARGS__, \
228+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 10 */ \
229+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 9 */ \
230+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 8 */ \
231+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 7 */ \
232+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 6 */ \
233+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 5 */ \
234+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 4 */ \
235+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 3 */ \
236+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2, /* 2 */ \
237+
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_1 /* 1 */ \
238+
)(__VA_ARGS__))
244239

245240
// Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead.
246241
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_1(error__) \
@@ -260,21 +255,3 @@ using ::executorch::runtime::error_code_t;
260255
return et_error__; \
261256
} \
262257
} while (0)
263-
264-
// Internal only: Use ET_CHECK_OK_OR_RETURN_ERROR() instead.
265-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_3 \
266-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2
267-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_4 \
268-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2
269-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_5 \
270-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2
271-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_6 \
272-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2
273-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_7 \
274-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2
275-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_8 \
276-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2
277-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_9 \
278-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2
279-
#define ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_10 \
280-
ET_INTERNAL_CHECK_OK_OR_RETURN_ERROR_2

runtime/executor/method.cpp

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,26 +1076,22 @@ Method::set_input(const EValue& input_evalue, size_t input_idx) {
10761076
executorch::runtime::toString(t_src.scalar_type()));
10771077
// Reset the shape for the Method's input as the size of forwarded input
10781078
// tensor for shape dynamism. Also is a safety check if need memcpy.
1079-
Error err = resize_tensor(t_dst, t_src.sizes());
1080-
ET_CHECK_OR_RETURN_ERROR(
1081-
err == Error::Ok,
1082-
InvalidArgument,
1083-
"Error setting input %" ET_PRIsize_t ": 0x%" PRIx32,
1084-
input_idx,
1085-
static_cast<uint32_t>(err));
1086-
Error error;
1079+
ET_CHECK_OK_OR_RETURN_ERROR(
1080+
resize_tensor(t_dst, t_src.sizes()),
1081+
"Error resizing tensor at input %" ET_PRIsize_t,
1082+
input_idx);
10871083
auto tensor_meta = this->method_meta().input_tensor_meta(input_idx);
10881084
if (tensor_meta->is_memory_planned()) {
1089-
error = internal::copy_tensor_data(t_dst, t_src);
1085+
ET_CHECK_OK_OR_RETURN_ERROR(
1086+
internal::copy_tensor_data(t_dst, t_src),
1087+
"Error copying tensor data at input %" ET_PRIsize_t,
1088+
input_idx);
10901089
} else {
1091-
error = internal::share_tensor_data(t_dst, t_src);
1090+
ET_CHECK_OK_OR_RETURN_ERROR(
1091+
internal::share_tensor_data(t_dst, t_src),
1092+
"Error sharing tensor data at input %" ET_PRIsize_t,
1093+
input_idx);
10921094
}
1093-
ET_CHECK_OR_RETURN_ERROR(
1094-
error == Error::Ok,
1095-
InvalidArgument,
1096-
"Error setting data_ptr %" ET_PRIsize_t ": 0x%" PRIx32,
1097-
input_idx,
1098-
static_cast<uint32_t>(error));
10991095
// Prims have to be the same as what was traced
11001096
} else if (e.isInt()) {
11011097
ET_CHECK_OR_RETURN_ERROR(
@@ -1188,10 +1184,7 @@ Method::set_inputs(const executorch::aten::ArrayRef<EValue>& input_evalues) {
11881184
input_size);
11891185

11901186
for (size_t i = 0; i < input_size; i++) {
1191-
Error status = set_input(input_evalues[i], i);
1192-
if (status != Error::Ok) {
1193-
return status;
1194-
}
1187+
ET_CHECK_OK_OR_RETURN_ERROR(set_input(input_evalues[i], i));
11951188
}
11961189
return Error::Ok;
11971190
}

0 commit comments

Comments
 (0)