| // 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 { |
| |
| class BytecodeComponentData; |
| |
| // Helper class which provides access to bytecode metadata. |
| class BytecodeMetadataHelper : public MetadataHelper { |
| public: |
| static const char* tag() { return "vm.bytecode"; } |
| |
| explicit BytecodeMetadataHelper(KernelReaderHelper* helper, |
| ActiveClass* active_class); |
| |
| bool HasBytecode(intptr_t node_offset); |
| |
| void ReadMetadata(const Function& function); |
| |
| RawArray* ReadBytecodeComponent(); |
| |
| private: |
| ActiveClass* const active_class_; |
| |
| DISALLOW_COPY_AND_ASSIGN(BytecodeMetadataHelper); |
| }; |
| |
| // Helper class for reading bytecode. |
| class BytecodeReaderHelper : public ValueObject { |
| public: |
| explicit BytecodeReaderHelper(KernelReaderHelper* helper, |
| ActiveClass* active_class, |
| BytecodeComponentData* bytecode_component); |
| |
| void ReadMemberBytecode(const Function& function, intptr_t md_offset); |
| |
| RawArray* ReadBytecodeComponent(intptr_t md_offset); |
| |
| private: |
| // These constants should match corresponding constants in class ObjectHandle |
| // (pkg/vm/lib/bytecode/object_table.dart). |
| static const int kReferenceBit = 1 << 0; |
| static const int kIndexShift = 1; |
| static const int kKindShift = 1; |
| static const int kKindMask = 0x0f; |
| static const int kFlagBit0 = 1 << 5; |
| static const int kFlagBit1 = 1 << 6; |
| static const int kFlagBit2 = 1 << 7; |
| static const int kFlagBit3 = 1 << 8; |
| static const int kFlagsMask = (kFlagBit0 | kFlagBit1 | kFlagBit2 | kFlagBit3); |
| |
| class FunctionTypeScope : public ValueObject { |
| public: |
| explicit FunctionTypeScope(BytecodeReaderHelper* bytecode_reader) |
| : bytecode_reader_(bytecode_reader), |
| saved_type_parameters_( |
| bytecode_reader->function_type_type_parameters_) {} |
| |
| ~FunctionTypeScope() { |
| bytecode_reader_->function_type_type_parameters_ = saved_type_parameters_; |
| } |
| |
| private: |
| BytecodeReaderHelper* bytecode_reader_; |
| TypeArguments* const saved_type_parameters_; |
| }; |
| |
| void ReadClosureDeclaration(const Function& function, intptr_t closureIndex); |
| RawType* ReadFunctionSignature(const Function& func, |
| bool has_optional_positional_params, |
| bool has_optional_named_params, |
| bool has_type_params, |
| bool has_positional_param_names); |
| void ReadTypeParametersDeclaration(const Class& parameterized_class, |
| const Function& parameterized_function, |
| intptr_t num_type_params); |
| |
| void ReadConstantPool(const Function& function, const ObjectPool& pool); |
| 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); |
| |
| RawObject* ReadObject(); |
| RawObject* ReadObjectContents(uint32_t header); |
| RawObject* ReadConstObject(intptr_t tag); |
| RawString* ReadString(bool is_canonical = true); |
| RawTypeArguments* ReadTypeArguments(const Class& instantiator); |
| |
| KernelReaderHelper* const helper_; |
| TranslationHelper& translation_helper_; |
| ActiveClass* const active_class_; |
| Zone* const zone_; |
| BytecodeComponentData* const bytecode_component_; |
| Array* closures_; |
| TypeArguments* function_type_type_parameters_; |
| |
| DISALLOW_COPY_AND_ASSIGN(BytecodeReaderHelper); |
| }; |
| |
| class BytecodeComponentData : ValueObject { |
| public: |
| enum { |
| kVersion, |
| kStringsHeaderOffset, |
| kStringsContentsOffset, |
| kObjectsContentsOffset, |
| kNumFields |
| }; |
| |
| explicit BytecodeComponentData(const Array& data) : data_(data) {} |
| |
| intptr_t GetVersion() const; |
| intptr_t GetStringsHeaderOffset() const; |
| intptr_t GetStringsContentsOffset() const; |
| intptr_t GetObjectsContentsOffset() const; |
| void SetObject(intptr_t index, const Object& obj) const; |
| RawObject* GetObject(intptr_t index) const; |
| |
| bool IsNull() const { return data_.IsNull(); } |
| |
| static RawArray* New(Zone* zone, |
| intptr_t version, |
| intptr_t num_objects, |
| intptr_t strings_header_offset, |
| intptr_t strings_contents_offset, |
| intptr_t objects_contents_offset, |
| Heap::Space space); |
| |
| private: |
| const Array& data_; |
| }; |
| |
| 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_ |