/* * Copyright 2016 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. */ #include "src/interp/binary-reader-interp.h" #include #include #include "src/binary-reader-nop.h" #include "src/feature.h" #include "src/interp/interp.h" #include "src/shared-validator.h" #include "src/stream.h" // TODO: Remove wabt:: namespace everywhere. namespace wabt { namespace interp { namespace { ValueTypes ToInterp(Index count, Type* types) { return ValueTypes(&types[0], &types[count]); } Mutability ToMutability(bool mut) { return mut ? Mutability::Var : Mutability::Const; } SegmentMode ToSegmentMode(uint8_t flags) { if ((flags & SegDeclared) == SegDeclared) { return SegmentMode::Declared; } else if ((flags & SegPassive) == SegPassive) { return SegmentMode::Passive; } else { return SegmentMode::Active; } } struct Label { Istream::Offset offset; Istream::Offset fixup_offset; }; struct FixupMap { using Offset = Istream::Offset; using Fixups = std::vector; void Clear(); void Append(Index, Offset); void Resolve(Istream&, Index); std::map map; }; class BinaryReaderInterp : public BinaryReaderNop { public: BinaryReaderInterp(ModuleDesc* module, Errors* errors, const Features& features); ValueType GetType(InitExpr); // Implement BinaryReader. bool OnError(const Error&) override; wabt::Result EndModule() override; wabt::Result OnTypeCount(Index count) override; wabt::Result OnType(Index index, Index param_count, Type* param_types, Index result_count, Type* result_types) override; wabt::Result OnImportFunc(Index import_index, string_view module_name, string_view field_name, Index func_index, Index sig_index) override; wabt::Result OnImportTable(Index import_index, string_view module_name, string_view field_name, Index table_index, Type elem_type, const Limits* elem_limits) override; wabt::Result OnImportMemory(Index import_index, string_view module_name, string_view field_name, Index memory_index, const Limits* page_limits) override; wabt::Result OnImportGlobal(Index import_index, string_view module_name, string_view field_name, Index global_index, Type type, bool mutable_) override; wabt::Result OnFunctionCount(Index count) override; wabt::Result OnFunction(Index index, Index sig_index) override; wabt::Result OnTableCount(Index count) override; wabt::Result OnTable(Index index, Type elem_type, const Limits* elem_limits) override; wabt::Result OnMemoryCount(Index count) override; wabt::Result OnMemory(Index index, const Limits* limits) override; wabt::Result OnGlobalCount(Index count) override; wabt::Result BeginGlobal(Index index, Type type, bool mutable_) override; wabt::Result EndGlobalInitExpr(Index index) override; wabt::Result OnExport(Index index, ExternalKind kind, Index item_index, string_view name) override; wabt::Result OnStartFunction(Index func_index) override; wabt::Result BeginFunctionBody(Index index, Offset size) override; wabt::Result OnLocalDeclCount(Index count) override; wabt::Result OnLocalDecl(Index decl_index, Index count, Type type) override; wabt::Result OnOpcode(Opcode Opcode) override; wabt::Result OnAtomicLoadExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnAtomicStoreExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnAtomicRmwExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnAtomicRmwCmpxchgExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnAtomicWaitExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnAtomicNotifyExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnBinaryExpr(wabt::Opcode opcode) override; wabt::Result OnBlockExpr(Type sig_type) override; wabt::Result OnBrExpr(Index depth) override; wabt::Result OnBrIfExpr(Index depth) override; wabt::Result OnBrTableExpr(Index num_targets, Index* target_depths, Index default_target_depth) override; wabt::Result OnCallExpr(Index func_index) override; wabt::Result OnCallIndirectExpr(Index sig_index, Index table_index) override; wabt::Result OnReturnCallExpr(Index func_index) override; wabt::Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override; wabt::Result OnCompareExpr(wabt::Opcode opcode) override; wabt::Result OnConvertExpr(wabt::Opcode opcode) override; wabt::Result OnDropExpr() override; wabt::Result OnElseExpr() override; wabt::Result OnEndExpr() override; wabt::Result OnF32ConstExpr(uint32_t value_bits) override; wabt::Result OnF64ConstExpr(uint64_t value_bits) override; wabt::Result OnV128ConstExpr(v128 value_bits) override; wabt::Result OnGlobalGetExpr(Index global_index) override; wabt::Result OnGlobalSetExpr(Index global_index) override; wabt::Result OnI32ConstExpr(uint32_t value) override; wabt::Result OnI64ConstExpr(uint64_t value) override; wabt::Result OnIfExpr(Type sig_type) override; wabt::Result OnLoadExpr(wabt::Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnLocalGetExpr(Index local_index) override; wabt::Result OnLocalSetExpr(Index local_index) override; wabt::Result OnLocalTeeExpr(Index local_index) override; wabt::Result OnLoopExpr(Type sig_type) override; wabt::Result OnMemoryCopyExpr() override; wabt::Result OnDataDropExpr(Index segment_index) override; wabt::Result OnMemoryGrowExpr() override; wabt::Result OnMemoryFillExpr() override; wabt::Result OnMemoryInitExpr(Index segment_index) override; wabt::Result OnMemorySizeExpr() override; wabt::Result OnRefFuncExpr(Index func_index) override; wabt::Result OnRefNullExpr() override; wabt::Result OnRefIsNullExpr() override; wabt::Result OnNopExpr() override; wabt::Result OnReturnExpr() override; wabt::Result OnSelectExpr(Type result_type) override; wabt::Result OnStoreExpr(wabt::Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnUnaryExpr(wabt::Opcode opcode) override; wabt::Result OnTableCopyExpr(Index dst_index, Index src_index) override; wabt::Result OnTableGetExpr(Index table_index) override; wabt::Result OnTableSetExpr(Index table_index) override; wabt::Result OnTableGrowExpr(Index table_index) override; wabt::Result OnTableSizeExpr(Index table_index) override; wabt::Result OnTableFillExpr(Index table_index) override; wabt::Result OnElemDropExpr(Index segment_index) override; wabt::Result OnTableInitExpr(Index segment_index, Index table_index) override; wabt::Result OnTernaryExpr(wabt::Opcode opcode) override; wabt::Result OnUnreachableExpr() override; wabt::Result EndFunctionBody(Index index) override; wabt::Result OnSimdLaneOpExpr(wabt::Opcode opcode, uint64_t value) override; wabt::Result OnSimdShuffleOpExpr(wabt::Opcode opcode, v128 value) override; wabt::Result OnLoadSplatExpr(wabt::Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnElemSegmentCount(Index count) override; wabt::Result BeginElemSegment(Index index, Index table_index, uint8_t flags) override; wabt::Result EndElemSegmentInitExpr(Index index) override; wabt::Result OnElemSegmentElemType(Index index, Type elem_type) override; wabt::Result OnElemSegmentElemExprCount(Index index, Index count) override; wabt::Result OnElemSegmentElemExpr_RefNull(Index segment_index) override; wabt::Result OnElemSegmentElemExpr_RefFunc(Index segment_index, Index func_index) override; wabt::Result OnDataCount(Index count) override; wabt::Result EndDataSegmentInitExpr(Index index) override; wabt::Result BeginDataSegment(Index index, Index memory_index, uint8_t flags) override; wabt::Result OnDataSegmentData(Index index, const void* data, Address size) override; wabt::Result OnInitExprF32ConstExpr(Index index, uint32_t value) override; wabt::Result OnInitExprF64ConstExpr(Index index, uint64_t value) override; wabt::Result OnInitExprV128ConstExpr(Index index, v128 value) override; wabt::Result OnInitExprGlobalGetExpr(Index index, Index global_index) override; wabt::Result OnInitExprI32ConstExpr(Index index, uint32_t value) override; wabt::Result OnInitExprI64ConstExpr(Index index, uint64_t value) override; wabt::Result OnInitExprRefNull(Index index) override; wabt::Result OnInitExprRefFunc(Index index, Index func_index) override; private: Label* GetLabel(Index depth); Label* TopLabel(); void PushLabel(Istream::Offset offset = Istream::kInvalidOffset, Istream::Offset fixup_offset = Istream::kInvalidOffset); void PopLabel(); void PrintError(const char* format, ...); wabt::Result GetDropCount(Index keep_count, size_t type_stack_limit, Index* out_drop_count); wabt::Result GetBrDropKeepCount(Index depth, Index* out_drop_count, Index* out_keep_count); wabt::Result GetReturnDropKeepCount(Index* out_drop_count, Index* out_keep_count); wabt::Result GetReturnCallDropKeepCount(const FuncType&, Index keep_extra, Index* out_drop_count, Index* out_keep_count); void EmitBr(Index depth, Index drop_count, Index keep_count); void FixupTopLabel(); u32 GetFuncOffset(Index func_index); Index TranslateLocalIndex(Index local_index); Index num_func_imports() const; Errors* errors_ = nullptr; ModuleDesc& module_; Istream& istream_; SharedValidator validator_; FuncDesc* func_; std::vector