256 {
258
260
261 if (program->is_single_program()) {
263 return Object::Handle(loader.LoadProgram(process_pending_classes));
264 }
265
266 GrowableArray<intptr_t> subprogram_file_starts;
267 {
268 kernel::Reader reader(program->binary());
270 }
271
272 Zone* zone = thread->zone();
274 intptr_t subprogram_count = subprogram_file_starts.length() - 1;
275
276
278 UriToSourceTableEntry wrapper;
280 Zone* zone_ = thread_->zone();
281 for (intptr_t
i = subprogram_count - 1;
i >= 0; --
i) {
282 intptr_t subprogram_start = subprogram_file_starts.At(
i);
283 intptr_t subprogram_end = subprogram_file_starts.At(
i + 1);
285 program->binary().ViewFromTo(subprogram_start, subprogram_end));
286 TranslationHelper translation_helper(thread);
287 KernelReaderHelper helper_(zone_, &translation_helper, component, 0);
289 for (intptr_t index = 0; index < source_table_size; ++index) {
291 wrapper.uri = &uri_string;
292 TypedData& line_starts =
294 if (line_starts.Length() == 0) continue;
295 const String& script_source = helper_.
GetSourceFor(index);
296 wrapper.uri = &uri_string;
297 UriToSourceTableEntry* pair = uri_to_source_table.LookupValue(&wrapper);
298 if (pair != nullptr) {
299
300
301 const bool src_differ = pair->sources->
CompareTo(script_source) != 0;
302 const bool line_starts_differ =
303 !pair->line_starts->CanonicalizeEquals(line_starts);
304 if (src_differ || line_starts_differ) {
306 "Invalid kernel binary: Contains at least two source entries "
307 "that do not agree. URI '%s', difference: %s. Subprogram count: "
309 uri_string.ToCString(),
310 src_differ && line_starts_differ
311 ? "src and line starts"
312 : (src_differ ? "src" : "line starts"),
313 subprogram_count);
314 }
315 } else {
316 UriToSourceTableEntry* tmp = new UriToSourceTableEntry();
317 tmp->uri = &uri_string;
318 tmp->sources = &script_source;
319 tmp->line_starts = &line_starts;
320 uri_to_source_table.Insert(tmp);
321 }
322 }
323 }
324
325
326 for (intptr_t
i = subprogram_count - 1;
i >= 0; --
i) {
327 intptr_t subprogram_start = subprogram_file_starts.At(
i);
328 intptr_t subprogram_end = subprogram_file_starts.At(
i + 1);
330 program->binary().ViewFromTo(subprogram_start, subprogram_end));
331 Reader reader(component);
332 const char*
error =
nullptr;
334 if (subprogram == nullptr) {
335 FATAL(
"Failed to load kernel file: %s",
error);
336 }
337 ASSERT(subprogram->is_single_program());
338 KernelLoader loader(subprogram.get(), &uri_to_source_table);
340 if (load_result.IsError()) return load_result;
341
342 if (load_result.IsLibrary()) {
343 library ^= load_result.ptr();
344 }
345 }
346
348
350 }
351
352 return library;
353}
static bool ProcessPendingClasses()
intptr_t CompareTo(const String &other) const
const String & GetSourceFor(intptr_t index)
String & SourceTableUriFor(intptr_t index)
intptr_t SourceTableSize()
TypedDataPtr GetLineStartsFor(intptr_t index)
DirectChainedHashMap< UriToSourceTableTrait > UriToSourceTable
#define TIMELINE_DURATION(thread, stream, name)