• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef DAWNNATIVE_ERROR_H_
16 #define DAWNNATIVE_ERROR_H_
17 
18 #include "common/Result.h"
19 
20 #include <string>
21 
22 namespace dawn_native {
23 
24     // This is the content of an error value for MaybeError or ResultOrError, split off to its own
25     // file to avoid having all files including headers like <string> and <vector>
26     class ErrorData;
27 
28     enum class ErrorType : uint32_t { Validation, ContextLost, Unimplemented };
29 
30     // MaybeError and ResultOrError are meant to be used as return value for function that are not
31     // expected to, but might fail. The handling of error is potentially much slower than successes.
32     using MaybeError = Result<void, ErrorData*>;
33 
34     template <typename T>
35     using ResultOrError = Result<T, ErrorData*>;
36 
37     // Returning a success is done like so:
38     //   return {}; // for Error
39     //   return SomethingOfTypeT; // for ResultOrError<T>
40     //
41     // Returning an error is done via:
42     //   return DAWN_MAKE_ERROR(errorType, "My error message");
43     //
44     // but shorthand version for specific error types are preferred:
45     //   return DAWN_VALIDATION_ERROR("My error message");
46 #define DAWN_MAKE_ERROR(TYPE, MESSAGE) \
47     ::dawn_native::MakeError(TYPE, MESSAGE, __FILE__, __func__, __LINE__)
48 #define DAWN_VALIDATION_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::Validation, MESSAGE)
49 #define DAWN_CONTEXT_LOST_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::ContextLost, MESSAGE)
50 #define DAWN_UNIMPLEMENTED_ERROR(MESSAGE) DAWN_MAKE_ERROR(ErrorType::Unimplemented, MESSAGE)
51 
52 #define DAWN_CONCAT1(x, y) x##y
53 #define DAWN_CONCAT2(x, y) DAWN_CONCAT1(x, y)
54 #define DAWN_LOCAL_VAR DAWN_CONCAT2(_localVar, __LINE__)
55 
56     // When Errors aren't handled explicitly, calls to functions returning errors should be
57     // wrapped in an DAWN_TRY. It will return the error if any, otherwise keep executing
58     // the current function.
59 #define DAWN_TRY(EXPR)                                                           \
60     {                                                                            \
61         auto DAWN_LOCAL_VAR = EXPR;                                              \
62         if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) {                           \
63             ErrorData* error = DAWN_LOCAL_VAR.AcquireError();                    \
64             ::dawn_native::AppendBacktrace(error, __FILE__, __func__, __LINE__); \
65             return {std::move(error)};                                           \
66         }                                                                        \
67     }                                                                            \
68     for (;;)                                                                     \
69     break
70 
71     // DAWN_TRY_ASSIGN is the same as DAWN_TRY for ResultOrError and assigns the success value, if
72     // any, to VAR.
73 #define DAWN_TRY_ASSIGN(VAR, EXPR)                                               \
74     {                                                                            \
75         auto DAWN_LOCAL_VAR = EXPR;                                              \
76         if (DAWN_UNLIKELY(DAWN_LOCAL_VAR.IsError())) {                           \
77             ErrorData* error = DAWN_LOCAL_VAR.AcquireError();                    \
78             ::dawn_native::AppendBacktrace(error, __FILE__, __func__, __LINE__); \
79             return {std::move(error)};                                           \
80         }                                                                        \
81         VAR = DAWN_LOCAL_VAR.AcquireSuccess();                                   \
82     }                                                                            \
83     for (;;)                                                                     \
84     break
85 
86     // Implementation detail of DAWN_TRY and DAWN_TRY_ASSIGN's adding to the Error's backtrace.
87     void AppendBacktrace(ErrorData* error, const char* file, const char* function, int line);
88 
89     // Implementation detail of DAWN_MAKE_ERROR
90     ErrorData* MakeError(ErrorType type,
91                          std::string message,
92                          const char* file,
93                          const char* function,
94                          int line);
95 
96 }  // namespace dawn_native
97 
98 #endif  // DAWNNATIVE_ERROR_H_
99