mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
d354a28cb2
The introduced "constants" transformation can evaluate constant expressions. The original use-sites of constant expressions are replaced by a new [ConstantExpression] node, which points to a subclass of a new [Constant] class hierarchy. Constant [Field]s and [VariableDeclarations]s will be removed, since all use-sites are re-written. The [Constant] class hierarchy is, similarly to the [DartType] class hierarchy, not part of the AST tree (also has no parent pointer). The constants form a DAG (directed acyclic graph). There is no canonicalization requirement of the [Constant] objects referenced by the AST (via [ConstantExpression]). Although it is beneficial to canonicalize them during construction, since it reduces time spent in operator==/hashCode. This CL furthermore adds support for a constant table in the binary format. Similarly to [String]s, we canonicalize the constants before writing the table to the binary. The constant table entries in the binary are written in a post-order way, to ensure easy construction on the backend side. The text format will be augmented with a "constants { ... }" section at the end, which lists the constants in the same order as in the binary format. The transformation can be used by those backends who choose to do so. It is not enabled by default atm. It should therefore not affect analyzer, fasta or other components. Change-Id: I57cd9624fedcf537ab6870db76246149647bed21 Reviewed-on: https://dart-review.googlesource.com/14382 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Kevin Millikin <kmillikin@google.com>
75 lines
2.6 KiB
C++
75 lines
2.6 KiB
C++
// Copyright (c) 2016, 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.
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
#include "vm/kernel_binary.h"
|
|
#include "platform/globals.h"
|
|
#include "vm/compiler/frontend/kernel_to_il.h"
|
|
#include "vm/flags.h"
|
|
#include "vm/growable_array.h"
|
|
#include "vm/kernel.h"
|
|
#include "vm/os.h"
|
|
|
|
namespace dart {
|
|
|
|
namespace kernel {
|
|
|
|
Program* Program::ReadFrom(Reader* reader, bool take_buffer_ownership) {
|
|
uint32_t magic = reader->ReadUInt32();
|
|
if (magic != kMagicProgramFile) FATAL("Invalid magic identifier");
|
|
|
|
uint32_t formatVersion = reader->ReadUInt32();
|
|
if (formatVersion != kBinaryFormatVersion) {
|
|
FATAL2("Invalid kernel binary format version (found %u, expected %u)",
|
|
formatVersion, kBinaryFormatVersion);
|
|
}
|
|
|
|
Program* program = new Program();
|
|
program->kernel_data_ = reader->buffer();
|
|
program->kernel_data_size_ = reader->size();
|
|
program->buffer_ownership_ = take_buffer_ownership;
|
|
|
|
// Dill files can be concatenated (e.g. cat a.dill b.dill > c.dill). Find out
|
|
// if this dill contains more than one program.
|
|
int subprogram_count = 0;
|
|
reader->set_offset(reader->size() - 4);
|
|
while (reader->offset() > 0) {
|
|
intptr_t size = reader->ReadUInt32();
|
|
intptr_t start = reader->offset() - size;
|
|
if (start < 0) {
|
|
FATAL("Invalid kernel binary: Indicated size is invalid.");
|
|
}
|
|
++subprogram_count;
|
|
if (subprogram_count > 1) break;
|
|
reader->set_offset(start - 4);
|
|
}
|
|
program->single_program_ = subprogram_count == 1;
|
|
|
|
// Read backwards at the end.
|
|
program->library_count_ = reader->ReadFromIndexNoReset(
|
|
reader->size_, LibraryCountFieldCountFromEnd, 1, 0);
|
|
program->source_table_offset_ = reader->ReadFromIndexNoReset(
|
|
reader->size_,
|
|
LibraryCountFieldCountFromEnd + 1 + program->library_count_ + 1 +
|
|
SourceTableFieldCountFromFirstLibraryOffset,
|
|
1, 0);
|
|
program->name_table_offset_ = reader->ReadUInt32();
|
|
program->string_table_offset_ = reader->ReadUInt32();
|
|
program->constant_table_offset_ = reader->ReadUInt32();
|
|
|
|
program->main_method_reference_ = NameIndex(reader->ReadUInt32() - 1);
|
|
|
|
return program;
|
|
}
|
|
|
|
} // namespace kernel
|
|
|
|
kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer,
|
|
intptr_t buffer_length) {
|
|
kernel::Reader reader(buffer, buffer_length);
|
|
return kernel::Program::ReadFrom(&reader);
|
|
}
|
|
|
|
} // namespace dart
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|