// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_ #define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_ #include "vm/compiler/frontend/kernel_translation_helper.h" #include "vm/constants_kbc.h" #include "vm/object.h" #if !defined(DART_PRECOMPILED_RUNTIME) namespace dart { namespace kernel { // Helper class which provides access to bytecode metadata. class BytecodeMetadataHelper : public MetadataHelper { public: static const char* tag() { return "vm.bytecode"; } explicit BytecodeMetadataHelper(KernelReaderHelper* helper, TypeTranslator* type_translator, ActiveClass* active_class); bool HasBytecode(intptr_t node_offset); void ReadMetadata(const Function& function); private: // Returns the index of the last read pool entry. intptr_t ReadPoolEntries(const Function& function, const Function& inner_function, const ObjectPool& pool, intptr_t from_index); RawBytecode* ReadBytecode(const ObjectPool& pool); void ReadExceptionsTable(const Bytecode& bytecode, bool has_exceptions_table); void ReadSourcePositions(const Bytecode& bytecode, bool has_source_positions); RawTypedData* NativeEntry(const Function& function, const String& external_name); TypeTranslator& type_translator_; ActiveClass* const active_class_; DISALLOW_COPY_AND_ASSIGN(BytecodeMetadataHelper); }; class BytecodeReader : public AllStatic { public: // Reads bytecode for the given function and sets its bytecode field. // Returns error (if any), or null. static RawError* ReadFunctionBytecode(Thread* thread, const Function& function); }; class BytecodeSourcePositionsIterator : ValueObject { public: BytecodeSourcePositionsIterator(Zone* zone, const Bytecode& bytecode) : reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))), pairs_remaining_(0), cur_bci_(0), cur_token_pos_(TokenPosition::kNoSource.value()) { if (bytecode.HasSourcePositions()) { reader_.set_offset(bytecode.source_positions_binary_offset()); pairs_remaining_ = reader_.ReadUInt(); } } bool MoveNext() { if (pairs_remaining_ == 0) { return false; } ASSERT(pairs_remaining_ > 0); --pairs_remaining_; cur_bci_ += reader_.ReadUInt(); cur_token_pos_ += reader_.ReadSLEB128(); return true; } intptr_t BytecodeInstructionIndex() const { return cur_bci_; } uword PcOffset() const { return KernelBytecode::BytecodePcToOffset(BytecodeInstructionIndex(), /* is_return_address = */ true); } TokenPosition TokenPos() const { return TokenPosition(cur_token_pos_); } private: Reader reader_; intptr_t pairs_remaining_; intptr_t cur_bci_; intptr_t cur_token_pos_; }; } // namespace kernel } // namespace dart #endif // !defined(DART_PRECOMPILED_RUNTIME) #endif // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_