/* * 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 #include #include #include "src/binary-reader-nop.h" #include "src/cast.h" #include "src/feature.h" #include "src/interp/interp.h" #include "src/interp/interp-internal.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(Table* table, Index dst) : table(table), dst(dst) {} Table* table; Index dst; std::vector src; }; struct DataSegmentInfo { DataSegmentInfo(Memory* memory, Address dst, const void* src, IstreamOffset size) : memory(memory), dst(dst), src(src), size(size) {} Memory* memory; Address dst; const void* src; // Not owned. IstreamOffset size; }; class BinaryReaderInterp : public BinaryReaderNop { public: BinaryReaderInterp(Environment* env, DefinedModule* module, std::unique_ptr istream, Errors* errors, const Features& features); wabt::Result ReadBinary(DefinedModule* out_module); std::unique_ptr ReleaseOutputBuffer(); wabt::Result InitializeSegments(); // Implement BinaryReader. bool OnError(const Error&) 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, 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() override; wabt::Result OnStoreExpr(wabt::Opcode opcode, uint32_t alignment_log2, Address offset) override; wabt::Result OnUnaryExpr(wabt::Opcode opcode) override; wabt::Result OnTableCopyExpr() override; wabt::Result OnTableGetExpr(Index table_index) override; wabt::Result OnTableSetExpr(Index table_index) override; wabt::Result OnElemDropExpr(Index segment_index) override; wabt::Result OnTableInitExpr(Index segment_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, bool passive, Type elem_type) override; wabt::Result BeginElemSegmentInitExpr(Index index) override; wabt::Result EndElemSegmentInitExpr(Index index) 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 BeginDataSegment(Index index, Index memory_index, bool passive) override; wabt::Result BeginDataSegmentInitExpr(Index 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 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; private: Label* GetLabel(Index depth); Label* TopLabel(); void PushLabel(IstreamOffset offset, IstreamOffset fixup_offset); void PopLabel(); void PrintError(const char* format, ...); Index TranslateSigIndexToEnv(Index sig_index); void GetBlockSignature(Type sig_type, TypeVector* out_param_types, TypeVector* out_result_types); 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); Index TranslateDataSegmentIndexToEnv(Index data_segment_index); Index TranslateElemSegmentIndexToEnv(Index elem_segment_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, uint32_t keep); wabt::Result AppendFixup(IstreamOffsetVectorVector* fixups_vector, Index index); wabt::Result EmitBrOffset(Index depth, IstreamOffset offset); 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(FuncSignature* sig, Index keep_extra, 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 CheckDataSegment(Index data_segment_index); wabt::Result CheckElemSegment(Index elem_segment_index); wabt::Result CheckImportKind(string_view module, string_view field, ExternalKind kind, ExternalKind actual_kind); wabt::Result CheckImportLimits(const Limits* declared_limits, const Limits* actual_limits); wabt::Result CheckHasMemory(wabt::Opcode opcode); wabt::Result CheckHasTable(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 CheckInFunction(); 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); Features features_; Errors* errors_ = nullptr; Environment* env_ = nullptr; DefinedModule* module_ = nullptr; DefinedFunc* current_func_ = nullptr; TypeChecker typechecker_; std::vector