diff options
Diffstat (limited to 'third_party/wasm2c/include/wabt/type-checker.h')
-rw-r--r-- | third_party/wasm2c/include/wabt/type-checker.h | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/third_party/wasm2c/include/wabt/type-checker.h b/third_party/wasm2c/include/wabt/type-checker.h new file mode 100644 index 0000000000..2b0ec092fe --- /dev/null +++ b/third_party/wasm2c/include/wabt/type-checker.h @@ -0,0 +1,207 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_TYPE_CHECKER_H_ +#define WABT_TYPE_CHECKER_H_ + +#include <functional> +#include <vector> + +#include "wabt/common.h" +#include "wabt/feature.h" +#include "wabt/opcode.h" + +namespace wabt { + +class TypeChecker { + public: + using ErrorCallback = std::function<void(const char* msg)>; + + struct Label { + Label(LabelType, + const TypeVector& param_types, + const TypeVector& result_types, + size_t limit); + + TypeVector& br_types() { + return label_type == LabelType::Loop ? param_types : result_types; + } + + LabelType label_type; + TypeVector param_types; + TypeVector result_types; + size_t type_stack_limit; + bool unreachable; + }; + + explicit TypeChecker(const Features& features) : features_(features) {} + + void set_error_callback(const ErrorCallback& error_callback) { + error_callback_ = error_callback; + } + + size_t type_stack_size() const { return type_stack_.size(); } + + bool IsUnreachable(); + Result GetLabel(Index depth, Label** out_label); + Result GetRethrowLabel(Index depth, Label** out_label); + Result GetCatchCount(Index depth, Index* out_depth); + + Result BeginFunction(const TypeVector& sig); + Result OnAtomicFence(uint32_t consistency_model); + Result OnAtomicLoad(Opcode, const Limits& limits); + Result OnAtomicNotify(Opcode, const Limits& limits); + Result OnAtomicStore(Opcode, const Limits& limits); + Result OnAtomicRmw(Opcode, const Limits& limits); + Result OnAtomicRmwCmpxchg(Opcode, const Limits& limits); + Result OnAtomicWait(Opcode, const Limits& limits); + Result OnBinary(Opcode); + Result OnBlock(const TypeVector& param_types, const TypeVector& result_types); + Result OnBr(Index depth); + Result OnBrIf(Index depth); + Result BeginBrTable(); + Result OnBrTableTarget(Index depth); + Result EndBrTable(); + Result OnCall(const TypeVector& param_types, const TypeVector& result_types); + Result OnCallIndirect(const TypeVector& param_types, + const TypeVector& result_types); + Result OnIndexedFuncRef(Index* out_index); + Result OnReturnCall(const TypeVector& param_types, + const TypeVector& result_types); + Result OnReturnCallIndirect(const TypeVector& param_types, + const TypeVector& result_types); + Result OnCatch(const TypeVector& sig); + Result OnCompare(Opcode); + Result OnConst(Type); + Result OnConvert(Opcode); + Result OnDelegate(Index depth); + Result OnDrop(); + Result OnElse(); + Result OnEnd(); + Result OnGlobalGet(Type); + Result OnGlobalSet(Type); + Result OnIf(const TypeVector& param_types, const TypeVector& result_types); + Result OnLoad(Opcode, const Limits& limits); + Result OnLocalGet(Type); + Result OnLocalSet(Type); + Result OnLocalTee(Type); + Result OnLoop(const TypeVector& param_types, const TypeVector& result_types); + Result OnMemoryCopy(const Limits& srclimits, const Limits& dstlimits); + Result OnDataDrop(Index); + Result OnMemoryFill(const Limits& limits); + Result OnMemoryGrow(const Limits& limits); + Result OnMemoryInit(Index, const Limits& limits); + Result OnMemorySize(const Limits& limits); + Result OnTableCopy(); + Result OnElemDrop(Index); + Result OnTableInit(Index, Index); + Result OnTableGet(Type elem_type); + Result OnTableSet(Type elem_type); + Result OnTableGrow(Type elem_type); + Result OnTableSize(); + Result OnTableFill(Type elem_type); + Result OnRefFuncExpr(Index func_type); + Result OnRefNullExpr(Type type); + Result OnRefIsNullExpr(); + Result OnRethrow(Index depth); + Result OnReturn(); + Result OnSelect(const TypeVector& result_types); + Result OnSimdLaneOp(Opcode, uint64_t); + Result OnSimdLoadLane(Opcode, const Limits& limits, uint64_t); + Result OnSimdStoreLane(Opcode, const Limits& limits, uint64_t); + Result OnSimdShuffleOp(Opcode, v128); + Result OnStore(Opcode, const Limits& limits); + Result OnTernary(Opcode); + Result OnThrow(const TypeVector& sig); + Result OnTry(const TypeVector& param_types, const TypeVector& result_types); + Result OnUnary(Opcode); + Result OnUnreachable(); + Result EndFunction(); + + Result BeginInitExpr(Type type); + Result EndInitExpr(); + + static Result CheckType(Type actual, Type expected); + + private: + void WABT_PRINTF_FORMAT(2, 3) PrintError(const char* fmt, ...); + Result TopLabel(Label** out_label); + void ResetTypeStackToLabel(Label* label); + Result SetUnreachable(); + void PushLabel(LabelType label_type, + const TypeVector& param_types, + const TypeVector& result_types); + Result PopLabel(); + Result CheckLabelType(Label* label, LabelType label_type); + Result Check2LabelTypes(Label* label, + LabelType label_type1, + LabelType label_type2); + Result GetThisFunctionLabel(Label** label); + Result PeekType(Index depth, Type* out_type); + Result PeekAndCheckType(Index depth, Type expected); + Result DropTypes(size_t drop_count); + void PushType(Type type); + void PushTypes(const TypeVector& types); + Result CheckTypeStackEnd(const char* desc); + Result CheckTypes(const TypeVector& actual, const TypeVector& expected); + Result CheckSignature(const TypeVector& sig, const char* desc); + Result CheckReturnSignature(const TypeVector& sig, + const TypeVector& expected, + const char* desc); + Result PopAndCheckSignature(const TypeVector& sig, const char* desc); + Result PopAndCheckCall(const TypeVector& param_types, + const TypeVector& result_types, + const char* desc); + Result PopAndCheck1Type(Type expected, const char* desc); + Result PopAndCheck2Types(Type expected1, Type expected2, const char* desc); + Result PopAndCheck3Types(Type expected1, + Type expected2, + Type expected3, + const char* desc); + Result CheckOpcode1(Opcode opcode, const Limits* limits = nullptr); + Result CheckOpcode2(Opcode opcode, const Limits* limits = nullptr); + Result CheckOpcode3(Opcode opcode, + const Limits* limits1 = nullptr, + const Limits* limits2 = nullptr, + const Limits* limits3 = nullptr); + Result OnEnd(Label* label, const char* sig_desc, const char* end_desc); + + template <typename... Args> + void PrintStackIfFailed(Result result, const char* desc, Args... args) { + // Minor optimization, check result before constructing the vector to pass + // to the other overload of PrintStackIfFailed. + if (Failed(result)) { + PrintStackIfFailedV(result, desc, {args...}, /*is_end=*/false); + } + } + + void PrintStackIfFailedV(Result, + const char* desc, + const TypeVector&, + bool is_end); + + ErrorCallback error_callback_; + TypeVector type_stack_; + std::vector<Label> label_stack_; + // Cache the expected br_table signature. It will be initialized to `nullptr` + // to represent "any". + TypeVector* br_table_sig_ = nullptr; + Features features_; +}; + +} // namespace wabt + +#endif /* WABT_TYPE_CHECKER_H_ */ |