summaryrefslogtreecommitdiffstats
path: root/third_party/wasm2c/include/wabt/shared-validator.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/wasm2c/include/wabt/shared-validator.h330
1 files changed, 330 insertions, 0 deletions
diff --git a/third_party/wasm2c/include/wabt/shared-validator.h b/third_party/wasm2c/include/wabt/shared-validator.h
new file mode 100644
index 0000000000..8c1f3988b1
--- /dev/null
+++ b/third_party/wasm2c/include/wabt/shared-validator.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2020 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_SHARED_VALIDATOR_H_
+#define WABT_SHARED_VALIDATOR_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "wabt/common.h"
+#include "wabt/error.h"
+#include "wabt/feature.h"
+#include "wabt/ir.h"
+#include "wabt/opcode.h"
+#include "wabt/type-checker.h"
+
+#include "wabt/binary-reader.h" // For TypeMut.
+
+namespace wabt {
+
+struct ValidateOptions {
+ ValidateOptions() = default;
+ ValidateOptions(const Features& features) : features(features) {}
+
+ Features features;
+};
+
+class SharedValidator {
+ public:
+ WABT_DISALLOW_COPY_AND_ASSIGN(SharedValidator);
+ SharedValidator(Errors*, const ValidateOptions& options);
+
+ // TODO: Move into SharedValidator?
+ using Label = TypeChecker::Label;
+ size_t type_stack_size() const { return typechecker_.type_stack_size(); }
+ Result GetLabel(Index depth, Label** out_label) {
+ return typechecker_.GetLabel(depth, out_label);
+ }
+ Result GetCatchCount(Index depth, Index* out_count) {
+ return typechecker_.GetCatchCount(depth, out_count);
+ }
+
+ Result WABT_PRINTF_FORMAT(3, 4)
+ PrintError(const Location& loc, const char* fmt, ...);
+
+ void OnTypecheckerError(const char* msg);
+
+ Index GetLocalCount() const;
+
+ Result EndModule();
+
+ Result OnFuncType(const Location&,
+ Index param_count,
+ const Type* param_types,
+ Index result_count,
+ const Type* result_types,
+ Index type_index);
+ Result OnStructType(const Location&, Index field_count, TypeMut* fields);
+ Result OnArrayType(const Location&, TypeMut field);
+
+ Result OnFunction(const Location&, Var sig_var);
+ Result OnTable(const Location&, Type elem_type, const Limits&);
+ Result OnMemory(const Location&, const Limits&);
+ Result OnGlobalImport(const Location&, Type type, bool mutable_);
+ Result OnGlobal(const Location&, Type type, bool mutable_);
+ Result OnTag(const Location&, Var sig_var);
+
+ Result OnExport(const Location&,
+ ExternalKind,
+ Var item_var,
+ std::string_view name);
+
+ Result OnStart(const Location&, Var func_var);
+
+ Result OnElemSegment(const Location&, Var table_var, SegmentKind);
+ Result OnElemSegmentElemType(const Location&, Type elem_type);
+ Result OnElemSegmentElemExpr_RefNull(const Location&, Type type);
+ Result OnElemSegmentElemExpr_RefFunc(const Location&, Var func_var);
+ Result OnElemSegmentElemExpr_Other(const Location&);
+
+ void OnDataCount(Index count);
+ Result OnDataSegment(const Location&, Var memory_var, SegmentKind);
+
+ Result BeginInitExpr(const Location&, Type type);
+ Result EndInitExpr();
+
+ Result BeginFunctionBody(const Location&, Index func_index);
+ Result EndFunctionBody(const Location&);
+ Result OnLocalDecl(const Location&, Index count, Type type);
+
+ Result OnAtomicFence(const Location&, uint32_t consistency_model);
+ Result OnAtomicLoad(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicNotify(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicRmwCmpxchg(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicRmw(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicStore(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicWait(const Location&, Opcode, Var memidx, Address align);
+ Result OnBinary(const Location&, Opcode);
+ Result OnBlock(const Location&, Type sig_type);
+ Result OnBr(const Location&, Var depth);
+ Result OnBrIf(const Location&, Var depth);
+ Result BeginBrTable(const Location&);
+ Result OnBrTableTarget(const Location&, Var depth);
+ Result EndBrTable(const Location&);
+ Result OnCall(const Location&, Var func_var);
+ Result OnCallIndirect(const Location&, Var sig_var, Var table_var);
+ Result OnCallRef(const Location&, Index* function_type_index);
+ Result OnCatch(const Location&, Var tag_var, bool is_catch_all);
+ Result OnCompare(const Location&, Opcode);
+ Result OnConst(const Location&, Type);
+ Result OnConvert(const Location&, Opcode);
+ Result OnDataDrop(const Location&, Var segment_var);
+ Result OnDelegate(const Location&, Var depth);
+ Result OnDrop(const Location&);
+ Result OnElemDrop(const Location&, Var segment_var);
+ Result OnElse(const Location&);
+ Result OnEnd(const Location&);
+ Result OnGlobalGet(const Location&, Var);
+ Result OnGlobalSet(const Location&, Var);
+ Result OnIf(const Location&, Type sig_type);
+ Result OnLoad(const Location&, Opcode, Var memidx, Address align);
+ Result OnLoadSplat(const Location&, Opcode, Var memidx, Address align);
+ Result OnLoadZero(const Location&, Opcode, Var memidx, Address align);
+ Result OnLocalGet(const Location&, Var);
+ Result OnLocalSet(const Location&, Var);
+ Result OnLocalTee(const Location&, Var);
+ Result OnLoop(const Location&, Type sig_type);
+ Result OnMemoryCopy(const Location&, Var srcmemidx, Var destmemidx);
+ Result OnMemoryFill(const Location&, Var memidx);
+ Result OnMemoryGrow(const Location&, Var memidx);
+ Result OnMemoryInit(const Location&, Var segment_var, Var memidx);
+ Result OnMemorySize(const Location&, Var memidx);
+ Result OnNop(const Location&);
+ Result OnRefFunc(const Location&, Var func_var);
+ Result OnRefIsNull(const Location&);
+ Result OnRefNull(const Location&, Type type);
+ Result OnRethrow(const Location&, Var depth);
+ Result OnReturnCall(const Location&, Var func_var);
+ Result OnReturnCallIndirect(const Location&, Var sig_var, Var table_var);
+ Result OnReturn(const Location&);
+ Result OnSelect(const Location&, Index result_count, Type* result_types);
+ Result OnSimdLaneOp(const Location&, Opcode, uint64_t lane_idx);
+ Result OnSimdLoadLane(const Location&,
+ Opcode,
+ Var memidx,
+ Address align,
+ uint64_t lane_idx);
+ Result OnSimdStoreLane(const Location&,
+ Opcode,
+ Var memidx,
+ Address align,
+ uint64_t lane_idx);
+ Result OnSimdShuffleOp(const Location&, Opcode, v128 lane_idx);
+ Result OnStore(const Location&, Opcode, Var memidx, Address align);
+ Result OnTableCopy(const Location&, Var dst_var, Var src_var);
+ Result OnTableFill(const Location&, Var table_var);
+ Result OnTableGet(const Location&, Var table_var);
+ Result OnTableGrow(const Location&, Var table_var);
+ Result OnTableInit(const Location&, Var segment_var, Var table_var);
+ Result OnTableSet(const Location&, Var table_var);
+ Result OnTableSize(const Location&, Var table_var);
+ Result OnTernary(const Location&, Opcode);
+ Result OnThrow(const Location&, Var tag_var);
+ Result OnTry(const Location&, Type sig_type);
+ Result OnUnary(const Location&, Opcode);
+ Result OnUnreachable(const Location&);
+
+ private:
+ struct FuncType {
+ FuncType() = default;
+ FuncType(const TypeVector& params,
+ const TypeVector& results,
+ Index type_index)
+ : params(params), results(results), type_index(type_index) {}
+
+ TypeVector params;
+ TypeVector results;
+ Index type_index;
+ };
+
+ struct StructType {
+ StructType() = default;
+ StructType(const TypeMutVector& fields) : fields(fields) {}
+
+ TypeMutVector fields;
+ };
+
+ struct ArrayType {
+ ArrayType() = default;
+ ArrayType(TypeMut field) : field(field) {}
+
+ TypeMut field;
+ };
+
+ struct TableType {
+ TableType() = default;
+ TableType(Type element, Limits limits) : element(element), limits(limits) {}
+
+ Type element = Type::Any;
+ Limits limits;
+ };
+
+ struct MemoryType {
+ MemoryType() = default;
+ MemoryType(Limits limits) : limits(limits) {}
+
+ Limits limits;
+ };
+
+ struct GlobalType {
+ GlobalType() = default;
+ GlobalType(Type type, bool mutable_) : type(type), mutable_(mutable_) {}
+
+ Type type = Type::Any;
+ bool mutable_ = true;
+ };
+
+ struct TagType {
+ TypeVector params;
+ };
+
+ struct ElemType {
+ ElemType() = default;
+ ElemType(Type element, bool is_active, Type table_type)
+ : element(element), is_active(is_active), table_type(table_type) {}
+
+ Type element;
+ bool is_active;
+ Type table_type;
+ };
+
+ struct LocalDecl {
+ Type type;
+ Index end;
+ };
+
+ bool ValidInitOpcode(Opcode opcode) const;
+ Result CheckInstr(Opcode opcode, const Location& loc);
+ Result CheckType(const Location&,
+ Type actual,
+ Type expected,
+ const char* desc);
+ Result CheckLimits(const Location&,
+ const Limits&,
+ uint64_t absolute_max,
+ const char* desc);
+
+ Result CheckLocalIndex(Var local_var, Type* out_type);
+
+ Result CheckDeclaredFunc(Var func_var);
+
+ Result CheckIndex(Var var, Index max_index, const char* desc);
+ template <typename T>
+ Result CheckIndexWithValue(Var var,
+ const std::vector<T>& values,
+ T* out,
+ const char* desc);
+ Result CheckFuncTypeIndex(Var sig_var, FuncType* out = nullptr);
+ Result CheckFuncIndex(Var func_var, FuncType* out = nullptr);
+ Result CheckTableIndex(Var table_var, TableType* out = nullptr);
+ Result CheckMemoryIndex(Var memory_var, MemoryType* out = nullptr);
+ Result CheckGlobalIndex(Var global_var, GlobalType* out = nullptr);
+ Result CheckTagIndex(Var tag_var, TagType* out = nullptr);
+ Result CheckElemSegmentIndex(Var elem_segment_var, ElemType* out = nullptr);
+ Result CheckDataSegmentIndex(Var data_segment_var);
+
+ Result CheckAlign(const Location&, Address align, Address natural_align);
+ Result CheckAtomicAlign(const Location&,
+ Address align,
+ Address natural_align);
+
+ Result CheckBlockSignature(const Location&,
+ Opcode,
+ Type sig_type,
+ TypeVector* out_param_types,
+ TypeVector* out_result_types);
+
+ Index GetFunctionTypeIndex(Index func_index) const;
+
+ TypeVector ToTypeVector(Index count, const Type* types);
+
+ ValidateOptions options_;
+ Errors* errors_;
+ TypeChecker typechecker_; // TODO: Move into SharedValidator.
+ // Cached for access by OnTypecheckerError.
+ Location expr_loc_ = Location(kInvalidOffset);
+ bool in_init_expr_ = false;
+
+ Index num_types_ = 0;
+ std::map<Index, FuncType> func_types_;
+ std::map<Index, StructType> struct_types_;
+ std::map<Index, ArrayType> array_types_;
+
+ std::vector<FuncType> funcs_; // Includes imported and defined.
+ std::vector<TableType> tables_; // Includes imported and defined.
+ std::vector<MemoryType> memories_; // Includes imported and defined.
+ std::vector<GlobalType> globals_; // Includes imported and defined.
+ std::vector<TagType> tags_; // Includes imported and defined.
+ std::vector<ElemType> elems_;
+ Index starts_ = 0;
+ Index num_imported_globals_ = 0;
+ Index data_segments_ = 0;
+
+ // Includes parameters, since this is only used for validating
+ // local.{get,set,tee} instructions.
+ std::vector<LocalDecl> locals_;
+
+ std::set<std::string> export_names_; // Used to check for duplicates.
+ std::set<Index> declared_funcs_; // TODO: optimize?
+ std::vector<Var> check_declared_funcs_;
+};
+
+} // namespace wabt
+
+#endif // WABT_SHARED_VALIDATOR_H_