Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/wabt/type-checker.h
1 /* 2 * Copyright 2017 WebAssembly Community Group participants 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef WABT_TYPE_CHECKER_H_ 18 #define WABT_TYPE_CHECKER_H_ 19 20 #include <functional> 21 #include <type_traits> 22 #include <vector> 23 24 #include "wabt/common.h" 25 #include "wabt/feature.h" 26 #include "wabt/opcode.h" 27 28 namespace wabt { 29 30 class TypeChecker { 31 public: 32 using ErrorCallback = std::function<void(const char* msg)>; 33 34 struct Label { 35 Label(LabelType, 36 const TypeVector& param_types, 37 const TypeVector& result_types, 38 size_t limit); 39 40 TypeVector& br_types() { 41 return label_type == LabelType::Loop ? param_types : result_types; 42 } 43 44 LabelType label_type; 45 TypeVector param_types; 46 TypeVector result_types; 47 size_t type_stack_limit; 48 bool unreachable; 49 }; 50 51 explicit TypeChecker(const Features& features) : features_(features) {} 52 53 void set_error_callback(const ErrorCallback& error_callback) { 54 error_callback_ = error_callback; 55 } 56 57 size_t type_stack_size() const { return type_stack_.size(); } 58 59 bool IsUnreachable(); 60 Result GetLabel(Index depth, Label** out_label); 61 Result GetRethrowLabel(Index depth, Label** out_label); 62 Result GetCatchCount(Index depth, Index* out_depth); 63 64 Result BeginFunction(const TypeVector& sig); 65 Result OnAtomicFence(uint32_t consistency_model); 66 Result OnAtomicLoad(Opcode, const Limits& limits); 67 Result OnAtomicNotify(Opcode, const Limits& limits); 68 Result OnAtomicStore(Opcode, const Limits& limits); 69 Result OnAtomicRmw(Opcode, const Limits& limits); 70 Result OnAtomicRmwCmpxchg(Opcode, const Limits& limits); 71 Result OnAtomicWait(Opcode, const Limits& limits); 72 Result OnBinary(Opcode); 73 Result OnBlock(const TypeVector& param_types, const TypeVector& result_types); 74 Result OnBr(Index depth); 75 Result OnBrIf(Index depth); 76 Result BeginBrTable(); 77 Result OnBrTableTarget(Index depth); 78 Result EndBrTable(); 79 Result OnCall(const TypeVector& param_types, const TypeVector& result_types); 80 Result OnCallIndirect(const TypeVector& param_types, 81 const TypeVector& result_types, 82 const Limits& table_limits); 83 Result OnIndexedFuncRef(Index* out_index); 84 Result OnReturnCall(const TypeVector& param_types, 85 const TypeVector& result_types); 86 Result OnReturnCallIndirect(const TypeVector& param_types, 87 const TypeVector& result_types); 88 Result OnCatch(const TypeVector& sig); 89 Result OnCompare(Opcode); 90 Result OnConst(Type); 91 Result OnConvert(Opcode); 92 Result OnDelegate(Index depth); 93 Result OnDrop(); 94 Result OnElse(); 95 Result OnEnd(); 96 Result OnGlobalGet(Type); 97 Result OnGlobalSet(Type); 98 Result OnIf(const TypeVector& param_types, const TypeVector& result_types); 99 Result OnLoad(Opcode, const Limits& limits); 100 Result OnLocalGet(Type); 101 Result OnLocalSet(Type); 102 Result OnLocalTee(Type); 103 Result OnLoop(const TypeVector& param_types, const TypeVector& result_types); 104 Result OnMemoryCopy(const Limits& dst_limits, const Limits& src_limits); 105 Result OnDataDrop(Index); 106 Result OnMemoryFill(const Limits& limits); 107 Result OnMemoryGrow(const Limits& limits); 108 Result OnMemoryInit(Index, const Limits& limits); 109 Result OnMemorySize(const Limits& limits); 110 Result OnTableCopy(const Limits& dst_limits, const Limits& src_limits); 111 Result OnElemDrop(Index); 112 Result OnTableInit(Index, const Limits& limits); 113 Result OnTableGet(Type elem_type, const Limits& limits); 114 Result OnTableSet(Type elem_type, const Limits& limits); 115 Result OnTableGrow(Type elem_type, const Limits& limits); 116 Result OnTableSize(const Limits& limits); 117 Result OnTableFill(Type elem_type, const Limits& limits); 118 Result OnRefFuncExpr(Index func_type, bool force_generic_funcref); 119 Result OnRefNullExpr(Type type); 120 Result OnRefIsNullExpr(); 121 Result OnRethrow(Index depth); 122 Result OnReturn(); 123 Result OnSelect(const TypeVector& result_types); 124 Result OnSimdLaneOp(Opcode, uint64_t); 125 Result OnSimdLoadLane(Opcode, const Limits& limits, uint64_t); 126 Result OnSimdStoreLane(Opcode, const Limits& limits, uint64_t); 127 Result OnSimdShuffleOp(Opcode, v128); 128 Result OnStore(Opcode, const Limits& limits); 129 Result OnTernary(Opcode); 130 Result OnThrow(const TypeVector& sig); 131 Result OnTry(const TypeVector& param_types, const TypeVector& result_types); 132 Result OnUnary(Opcode); 133 Result OnUnreachable(); 134 Result EndFunction(); 135 136 Result BeginInitExpr(Type type); 137 Result EndInitExpr(); 138 139 static Result CheckType(Type actual, Type expected); 140 141 private: 142 void WABT_PRINTF_FORMAT(2, 3) PrintError(const char* fmt, ...); 143 Result TopLabel(Label** out_label); 144 void ResetTypeStackToLabel(Label* label); 145 Result SetUnreachable(); 146 void PushLabel(LabelType label_type, 147 const TypeVector& param_types, 148 const TypeVector& result_types); 149 Result PopLabel(); 150 Result CheckLabelType(Label* label, LabelType label_type); 151 Result Check2LabelTypes(Label* label, 152 LabelType label_type1, 153 LabelType label_type2); 154 Result GetThisFunctionLabel(Label** label); 155 Result PeekType(Index depth, Type* out_type); 156 Result PeekAndCheckType(Index depth, Type expected); 157 Result DropTypes(size_t drop_count); 158 void PushType(Type type); 159 void PushTypes(const TypeVector& types); 160 Result CheckTypeStackEnd(const char* desc); 161 Result CheckTypes(const TypeVector& actual, const TypeVector& expected); 162 Result CheckSignature(const TypeVector& sig, const char* desc); 163 Result CheckReturnSignature(const TypeVector& sig, 164 const TypeVector& expected, 165 const char* desc); 166 Result PopAndCheckSignature(const TypeVector& sig, const char* desc); 167 Result PopAndCheckCall(const TypeVector& param_types, 168 const TypeVector& result_types, 169 const char* desc); 170 Result PopAndCheck1Type(Type expected, const char* desc); 171 Result PopAndCheck2Types(Type expected1, Type expected2, const char* desc); 172 Result PopAndCheck3Types(Type expected1, 173 Type expected2, 174 Type expected3, 175 const char* desc); 176 Result CheckOpcode1(Opcode opcode, const Limits* limits = nullptr); 177 Result CheckOpcode2(Opcode opcode, const Limits* limits = nullptr); 178 Result CheckOpcode3(Opcode opcode, 179 const Limits* limits1 = nullptr, 180 const Limits* limits2 = nullptr, 181 const Limits* limits3 = nullptr); 182 Result OnEnd(Label* label, const char* sig_desc, const char* end_desc); 183 184 template <typename... Args> 185 void PrintStackIfFailed(Result result, const char* desc, Args... args) { 186 // Assert all args are Type or Type::Enum. If it's a TypeVector then 187 // PrintStackIfFailedV() should be used instead. 188 static_assert((std::is_constructible_v<Type, Args> && ...)); 189 // Minor optimization, check result before constructing the vector to pass 190 // to the other overload of PrintStackIfFailed. 191 if (Failed(result)) { 192 PrintStackIfFailedV(result, desc, {args...}, /*is_end=*/false); 193 } 194 } 195 196 void PrintStackIfFailedV(Result, 197 const char* desc, 198 const TypeVector&, 199 bool is_end); 200 201 ErrorCallback error_callback_; 202 TypeVector type_stack_; 203 std::vector<Label> label_stack_; 204 // Cache the expected br_table signature. It will be initialized to `nullptr` 205 // to represent "any". 206 TypeVector* br_table_sig_ = nullptr; 207 Features features_; 208 }; 209 210 } // namespace wabt 211 212 #endif /* WABT_TYPE_CHECKER_H_ */