/* * 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 "binary-reader-interpreter.h" #include #include #include #include #include #include "binary-error-handler.h" #include "binary-reader-nop.h" #include "interpreter.h" #include "type-checker.h" #include "writer.h" #define CHECK_RESULT(expr) \ do { \ if (WABT_FAILED(expr)) \ return Result::Error; \ } while (0) namespace wabt { 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 BinaryReaderInterpreter : public BinaryReaderNop { public: BinaryReaderInterpreter(InterpreterEnvironment* env, DefinedInterpreterModule* module, IstreamOffset istream_offset, BinaryErrorHandler* error_handler); std::unique_ptr ReleaseOutputBuffer(); IstreamOffset get_istream_offset() { return istream_offset; } // Implement BinaryReader. bool OnError(const char* message) override; Result EndModule() override; Result OnTypeCount(Index count) override; Result OnType(Index index, Index param_count, Type* param_types, Index result_count, Type* result_types) override; Result OnImportCount(Index count) override; Result OnImport(Index index, StringSlice module_name, StringSlice field_name) override; Result OnImportFunc(Index import_index, StringSlice module_name, StringSlice field_name, Index func_index, Index sig_index) override; Result OnImportTable(Index import_index, StringSlice module_name, StringSlice field_name, Index table_index, Type elem_type, const Limits* elem_limits) override; Result OnImportMemory(Index import_index, StringSlice module_name, StringSlice field_name, Index memory_index, const Limits* page_limits) override; Result OnImportGlobal(Index import_index, StringSlice module_name, StringSlice field_name, Index global_index, Type type, bool mutable_) override; Result OnFunctionCount(Index count) override; Result OnFunction(Index index, Index sig_index) override; Result OnTable(Index index, Type elem_type, const Limits* elem_limits) override; Result OnMemory(Index index, const Limits* limits) override; Result OnGlobalCount(Index count) override; Result BeginGlobal(Index index, Type type, bool mutable_) override; Result EndGlobalInitExpr(Index index) override; Result OnExport(Index index, ExternalKind kind, Index item_index, StringSlice name) override; Result OnStartFunction(Index func_index) override; Result BeginFunctionBody(Index index) override; Result OnLocalDeclCount(Index count) override; Result OnLocalDecl(Index decl_index, Index count, Type type) override; Result OnBinaryExpr(Opcode opcode) override; Result OnBlockExpr(Index num_types, Type* sig_types) override; Result OnBrExpr(Index depth) override; Result OnBrIfExpr(Index depth) override; Result OnBrTableExpr(Index num_targets, Index* target_depths, Index default_target_depth) override; Result OnCallExpr(Index func_index) override; Result OnCallIndirectExpr(Index sig_index) override; Result OnCompareExpr(Opcode opcode) override; Result OnConvertExpr(Opcode opcode) override; Result OnCurrentMemoryExpr() override; Result OnDropExpr() override; Result OnElseExpr() override; Result OnEndExpr() override; Result OnF32ConstExpr(uint32_t value_bits) override; Result OnF64ConstExpr(uint64_t value_bits) override; Result OnGetGlobalExpr(Index global_index) override; Result OnGetLocalExpr(Index local_index) override; Result OnGrowMemoryExpr() override; Result OnI32ConstExpr(uint32_t value) override; Result OnI64ConstExpr(uint64_t value) override; Result OnIfExpr(Index num_types, Type* sig_types) override; Result OnLoadExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; Result OnLoopExpr(Index num_types, Type* sig_types) override; Result OnNopExpr() override; Result OnReturnExpr() override; Result OnSelectExpr() override; Result OnSetGlobalExpr(Index global_index) override; Result OnSetLocalExpr(Index local_index) override; Result OnStoreExpr(Opcode opcode, uint32_t alignment_log2, Address offset) override; Result OnTeeLocalExpr(Index local_index) override; Result OnUnaryExpr(Opcode opcode) override; Result OnUnreachableExpr() override; Result EndFunctionBody(Index index) override; Result EndElemSegmentInitExpr(Index index) override; Result OnElemSegmentFunctionIndex(Index index, Index func_index) override; Result OnDataSegmentData(Index index, const void* data, Address size) override; Result OnInitExprF32ConstExpr(Index index, uint32_t value) override; Result OnInitExprF64ConstExpr(Index index, uint64_t value) override; Result OnInitExprGetGlobalExpr(Index index, Index global_index) override; Result OnInitExprI32ConstExpr(Index index, uint32_t value) override; 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, ...); static void OnTypecheckerError(const char* msg, void* user_data); Index TranslateSigIndexToEnv(Index sig_index); InterpreterFuncSignature* GetSignatureByEnvIndex(Index sig_index); InterpreterFuncSignature* GetSignatureByModuleIndex(Index sig_index); Index TranslateFuncIndexToEnv(Index func_index); Index TranslateModuleFuncIndexToDefined(Index func_index); InterpreterFunc* GetFuncByEnvIndex(Index func_index); InterpreterFunc* GetFuncByModuleIndex(Index func_index); Index TranslateGlobalIndexToEnv(Index global_index); InterpreterGlobal* GetGlobalByEnvIndex(Index global_index); InterpreterGlobal* GetGlobalByModuleIndex(Index global_index); Type GetGlobalTypeByModuleIndex(Index global_index); Index TranslateLocalIndex(Index local_index); Type GetLocalTypeByIndex(InterpreterFunc* func, Index local_index); IstreamOffset GetIstreamOffset(); Result EmitDataAt(IstreamOffset offset, const void* data, IstreamOffset size); Result EmitData(const void* data, IstreamOffset size); Result EmitOpcode(Opcode opcode); Result EmitOpcode(InterpreterOpcode opcode); Result EmitI8(uint8_t value); Result EmitI32(uint32_t value); Result EmitI64(uint64_t value); Result EmitI32At(IstreamOffset offset, uint32_t value); Result EmitDropKeep(uint32_t drop, uint8_t keep); Result AppendFixup(IstreamOffsetVectorVector* fixups_vector, Index index); Result EmitBrOffset(Index depth, IstreamOffset offset); Result GetBrDropKeepCount(Index depth, Index* out_drop_count, Index* out_keep_count); Result GetReturnDropKeepCount(Index* out_drop_count, Index* out_keep_count); Result EmitBr(Index depth, Index drop_count, Index keep_count); Result EmitBrTableOffset(Index depth); Result FixupTopLabel(); Result EmitFuncOffset(DefinedInterpreterFunc* func, Index func_index); Result CheckLocal(Index local_index); Result CheckGlobal(Index global_index); Result CheckImportKind(InterpreterImport* import, ExternalKind expected_kind); Result CheckImportLimits(const Limits* declared_limits, const Limits* actual_limits); Result CheckHasMemory(Opcode opcode); Result CheckAlign(uint32_t alignment_log2, Address natural_alignment); Result AppendExport(InterpreterModule* module, ExternalKind kind, Index item_index, StringSlice name); PrintErrorCallback MakePrintErrorCallback(); static void OnHostImportPrintError(const char* msg, void* user_data); BinaryErrorHandler* error_handler = nullptr; InterpreterEnvironment* env = nullptr; DefinedInterpreterModule* module = nullptr; DefinedInterpreterFunc* current_func = nullptr; TypeCheckerErrorHandler tc_error_handler; TypeChecker typechecker; std::vector