1// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_KERNEL_H_
6#define RUNTIME_VM_KERNEL_H_
7
8#include <memory>
9
10#include "platform/assert.h"
11#include "vm/allocation.h"
12#include "vm/globals.h"
13#include "vm/growable_array.h"
14#include "vm/object.h"
15#include "vm/token_position.h"
16
17namespace dart {
18namespace kernel {
19class NameIndex {
20 public:
21 static const int kInvalidName = -1;
22
23 NameIndex() : value_(kInvalidName) {}
24 explicit NameIndex(int value) : value_(value) {}
25
26 operator int() const { return value_; }
27
28 private:
29 int value_;
30};
31} // namespace kernel
32} // namespace dart
33
34#if !defined(DART_PRECOMPILED_RUNTIME)
35namespace dart {
36
37class BitVector;
38class Field;
39class ParsedFunction;
40class Zone;
41
42namespace kernel {
43
44class Reader;
45struct ProcedureAttributesMetadata;
46class TableSelectorMetadata;
47
48class StringIndex {
49 public:
50 StringIndex() : value_(-1) {}
51 explicit StringIndex(int value) : value_(value) {}
52
53 operator int() const { return value_; }
54
55 private:
56 int value_;
57};
58
59const uint8_t kNativeYieldFlags = 0x2;
60
61enum LogicalOperator { kAnd, kOr };
62
63class Program {
64 public:
65 // Read a kernel Program from the given Reader. Note the returned Program
66 // can potentially contain several "sub programs", though the library count
67 // etc will reference the last "sub program" only.
68 static std::unique_ptr<Program> ReadFrom(Reader* reader,
69 const char** error = nullptr);
70
71 static std::unique_ptr<Program> ReadFromFile(const char* script_uri,
72 const char** error = nullptr);
73 static std::unique_ptr<Program> ReadFromBuffer(const uint8_t* buffer,
74 intptr_t buffer_length,
75 const char** error = nullptr);
76 static std::unique_ptr<Program> ReadFromTypedData(
77 const ExternalTypedData& typed_data, const char** error = nullptr);
78
79 bool is_single_program() { return single_program_; }
80 uint32_t binary_version() { return binary_version_; }
81 NameIndex main_method() { return main_method_reference_; }
82 intptr_t source_table_offset() const { return source_table_offset_; }
83 intptr_t string_table_offset() const { return string_table_offset_; }
84 intptr_t name_table_offset() const { return name_table_offset_; }
85 intptr_t metadata_payloads_offset() const {
86 return metadata_payloads_offset_;
87 }
88 intptr_t metadata_mappings_offset() const {
89 return metadata_mappings_offset_;
90 }
91 intptr_t constant_table_offset() { return constant_table_offset_; }
92 const ExternalTypedData* typed_data() { return typed_data_; }
93 const uint8_t* kernel_data() { return kernel_data_; }
94 intptr_t kernel_data_size() { return kernel_data_size_; }
95 intptr_t library_count() { return library_count_; }
96 NNBDCompiledMode compilation_mode() const { return compilation_mode_; }
97
98 private:
99 Program() : typed_data_(NULL), kernel_data_(NULL), kernel_data_size_(-1) {}
100
101 bool single_program_;
102 uint32_t binary_version_;
103 NameIndex main_method_reference_; // Procedure.
104 NNBDCompiledMode compilation_mode_;
105 intptr_t library_count_;
106
107 // The offset from the start of the binary to the start of the source table.
108 intptr_t source_table_offset_;
109
110 // The offset from the start of the binary to the start of the constant table.
111 intptr_t constant_table_offset_;
112
113 // The offset from the start of the binary to the canonical name table.
114 intptr_t name_table_offset_;
115
116 // The offset from the start of the binary to the metadata payloads.
117 intptr_t metadata_payloads_offset_;
118
119 // The offset from the start of the binary to the metadata mappings.
120 intptr_t metadata_mappings_offset_;
121
122 // The offset from the start of the binary to the start of the string table.
123 intptr_t string_table_offset_;
124
125 const ExternalTypedData* typed_data_;
126 const uint8_t* kernel_data_;
127 intptr_t kernel_data_size_;
128
129 DISALLOW_COPY_AND_ASSIGN(Program);
130};
131
132class KernelLineStartsReader {
133 public:
134 KernelLineStartsReader(const dart::TypedData& line_starts_data,
135 dart::Zone* zone);
136
137 ~KernelLineStartsReader() { delete helper_; }
138
139 int32_t DeltaAt(intptr_t index) const {
140 return helper_->At(line_starts_data_, index);
141 }
142
143 void LocationForPosition(intptr_t position,
144 intptr_t* line,
145 intptr_t* col) const;
146
147 void TokenRangeAtLine(intptr_t source_length,
148 intptr_t line_number,
149 dart::TokenPosition* first_token_index,
150 dart::TokenPosition* last_token_index) const;
151
152 private:
153 class KernelLineStartsHelper {
154 public:
155 KernelLineStartsHelper() {}
156 virtual ~KernelLineStartsHelper() {}
157 virtual int32_t At(const dart::TypedData& data, intptr_t index) const = 0;
158
159 private:
160 DISALLOW_COPY_AND_ASSIGN(KernelLineStartsHelper);
161 };
162
163 class KernelInt8LineStartsHelper : public KernelLineStartsHelper {
164 public:
165 KernelInt8LineStartsHelper() {}
166 virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
167
168 private:
169 DISALLOW_COPY_AND_ASSIGN(KernelInt8LineStartsHelper);
170 };
171
172 class KernelInt16LineStartsHelper : public KernelLineStartsHelper {
173 public:
174 KernelInt16LineStartsHelper() {}
175 virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
176
177 private:
178 DISALLOW_COPY_AND_ASSIGN(KernelInt16LineStartsHelper);
179 };
180
181 class KernelInt32LineStartsHelper : public KernelLineStartsHelper {
182 public:
183 KernelInt32LineStartsHelper() {}
184 virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
185
186 private:
187 DISALLOW_COPY_AND_ASSIGN(KernelInt32LineStartsHelper);
188 };
189
190 const dart::TypedData& line_starts_data_;
191 KernelLineStartsHelper* helper_;
192
193 DISALLOW_COPY_AND_ASSIGN(KernelLineStartsReader);
194};
195
196void CollectTokenPositionsFor(const Script& script);
197
198ObjectPtr EvaluateMetadata(const Field& metadata_field,
199 bool is_annotations_offset);
200ObjectPtr BuildParameterDescriptor(const Function& function);
201
202// Fills in [is_covariant] and [is_generic_covariant_impl] vectors
203// according to covariance attributes of [function] parameters.
204//
205// [is_covariant] and [is_generic_covariant_impl] should contain bitvectors
206// of function.NumParameters() length.
207void ReadParameterCovariance(const Function& function,
208 BitVector* is_covariant,
209 BitVector* is_generic_covariant_impl);
210
211// Returns true if the given function needs dynamic invocation forwarder:
212// that is if any of the arguments require checking on the dynamic
213// call-site: if function has no parameters or has only covariant parameters
214// as such function already checks all of its parameters.
215bool NeedsDynamicInvocationForwarder(const Function& function);
216
217// Returns a list of ParameterTypeChecks needed by a dynamic invocation
218// forwarder that targets [function]. Indices in these checks correspond to
219// bytecode frame indices.
220ArrayPtr CollectDynamicInvocationChecks(const Function& function);
221
222ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function,
223 Zone* zone);
224
225ProcedureAttributesMetadata ProcedureAttributesOf(const Field& field,
226 Zone* zone);
227
228TableSelectorMetadata* TableSelectorMetadataForProgram(
229 const KernelProgramInfo& info,
230 Zone* zone);
231
232} // namespace kernel
233} // namespace dart
234
235#endif // !defined(DART_PRECOMPILED_RUNTIME)
236#endif // RUNTIME_VM_KERNEL_H_
237