/* * 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/binary-reader-interp.h" #include #include #include #include #include #include "src/binary-reader-nop.h" #include "src/cast.h" #include "src/error-handler.h" #include "src/interp.h" #include "src/stream.h" #include "src/type-checker.h" namespace wabt { using namespace interp; namespace { typedef std::vector IndexVector; typedef std::vector IstreamOffsetVector; typedef std::vector IstreamOffsetVectorVector; struct Label { Label(IstreamOffset offset, IstreamOffset fixup_offset); IstreamOffset offset; IstreamOffset fixup_offset; }; Label::Label(IstreamOffset offset, IstreamOffset fixup_offset) : offset(offset), fixup_offset(fixup_offset) {} struct ElemSegmentInfo { ElemSegmentInfo(Index* dst, Index func_index) : dst(dst), func_index(func_index) {} Index* dst; Index func_index; }; struct DataSegmentInfo { DataSegmentInfo(void* dst_data, const void* src_data, IstreamOffset size) : dst_data(dst_data), src_data(src_data), size(size) {} void* dst_data; // Not owned. const void* src_data; // Not owned. IstreamOffset size; }; class BinaryReaderInterp : public BinaryReaderNop { public: BinaryReaderInterp(Environment* env, DefinedModule* module, std::unique_ptr istream, ErrorHandler* error_handler); wabt::Result ReadBinary(DefinedModule* out_module); std::unique_ptr ReleaseOutputBuffer(); // Implement BinaryReader. bool OnError(const char* message) 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 OnTable(Index index, Type elem_type, const Limits* elem_limits) 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) override; wabt::Result OnLocalDeclCount(Index count) override; wabt::Result OnLocalDecl(Index decl_index, Index count, Type type) 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 OnAtomicWakeExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnBinaryExpr(wabt::Opcode opcode) override; wabt::Result OnBlockExpr(Index num_types, Type* sig_types) 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) override; wabt::Result OnCompareExpr(wabt::Opcode opcode) override; wabt::Result OnConvertExpr(wabt::Opcode opcode) override; wabt::Result OnCurrentMemoryExpr() 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 OnGetGlobalExpr(Index global_index) override; wabt::Result OnGetLocalExpr(Index local_index) override; wabt::Result OnGrowMemoryExpr() override; wabt::Result OnI32ConstExpr(uint32_t value) override; wabt::Result OnI64ConstExpr(uint64_t value) override; wabt::Result OnIfExpr(Index num_types, Type* sig_types) override; wabt::Result OnLoadExpr(wabt::Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnLoopExpr(Index num_types, Type* sig_types) override; wabt::Result OnNopExpr() override; wabt::Result OnReturnExpr() override; wabt::Result OnSelectExpr() override; wabt::Result OnSetGlobalExpr(Index global_index) override; wabt::Result OnSetLocalExpr(Index local_index) override; wabt::Result OnStoreExpr(wabt::Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnTeeLocalExpr(Index local_index) override; wabt::Result OnUnaryExpr(wabt::Opcode opcode) override; wabt::Result OnUnreachableExpr() override; wabt::Result EndFunctionBody(Index index) override; wabt::Result EndElemSegmentInitExpr(Index index) override; wabt::Result OnElemSegmentFunctionIndex(Index index, Index func_index) 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 OnInitExprGetGlobalExpr(Index index, Index global_index) override; wabt::Result OnInitExprI32ConstExpr(Index index, uint32_t value) override; wabt::Result OnInitExprI64ConstExpr(Index index, uint64_t value) override; private: Label* GetLabel(Index depth); Label* TopLabel(); void PushLabel(IstreamOffset offset, IstreamOffset fixup_offset); void PopLabel(); bool HandleError(Offset offset, const char* message); void PrintError(const char* format, ...); Index TranslateSigIndexToEnv(Index sig_index); FuncSignature* GetSignatureByModuleIndex(Index sig_index); Index TranslateFuncIndexToEnv(Index func_index); Index TranslateModuleFuncIndexToDefined(Index func_index); Func* GetFuncByModuleIndex(Index func_index); Index TranslateGlobalIndexToEnv(Index global_index); Global* GetGlobalByModuleIndex(Index global_index); Type GetGlobalTypeByModuleIndex(Index global_index); Index TranslateLocalIndex(Index local_index); Type GetLocalTypeByIndex(Func* func, Index local_index); IstreamOffset GetIstreamOffset(); wabt::Result EmitDataAt(IstreamOffset offset, const void* data, IstreamOffset size); wabt::Result EmitData(const void* data, IstreamOffset size); wabt::Result EmitOpcode(Opcode opcode); wabt::Result EmitI8(uint8_t value); wabt::Result EmitI32(uint32_t value); wabt::Result EmitI64(uint64_t value); wabt::Result EmitV128(v128 value); wabt::Result EmitI32At(IstreamOffset offset, uint32_t value); wabt::Result EmitDropKeep(uint32_t drop, uint8_t keep); wabt::Result AppendFixup(IstreamOffsetVectorVector* fixups_vector, Index index); wabt::Result EmitBrOffset(Index depth, IstreamOffset offset); 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 EmitBr(Index depth, Index drop_count, Index keep_count); wabt::Result EmitBrTableOffset(Index depth); wabt::Result FixupTopLabel(); wabt::Result EmitFuncOffset(DefinedFunc* func, Index func_index); wabt::Result CheckLocal(Index local_index); wabt::Result CheckGlobal(Index global_index); wabt::Result CheckImportKind(Import* import, ExternalKind expected_kind); wabt::Result CheckImportLimits(const Limits* declared_limits, const Limits* actual_limits); wabt::Result CheckHasMemory(wabt::Opcode opcode); wabt::Result CheckAlign(uint32_t alignment_log2, Address natural_alignment); wabt::Result CheckAtomicAlign(uint32_t alignment_log2, Address natural_alignment); wabt::Result AppendExport(Module* module, ExternalKind kind, Index item_index, string_view name); wabt::Result FindRegisteredModule(string_view module_name, Module** out_module); wabt::Result GetModuleExport(Module* module, string_view field_name, Export** out_export); HostImportDelegate::ErrorCallback MakePrintErrorCallback(); ErrorHandler* error_handler_ = nullptr; Environment* env_ = nullptr; DefinedModule* module_ = nullptr; DefinedFunc* current_func_ = nullptr; TypeChecker typechecker_; std::vector