blob: 21700db6127d93e15d8517c2f4669e78d18fe8b9 [file] [log] [blame]
// Copyright (c) 2017, 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_BIN_DFE_H_
#define RUNTIME_BIN_DFE_H_
#include <memory>
#include "bin/thread.h"
#include "include/dart_api.h"
#include "include/dart_native_api.h"
#include "platform/assert.h"
#include "platform/globals.h"
#include "platform/hashmap.h"
#include "platform/utils.h"
namespace dart {
namespace bin {
class DFE {
public:
DFE();
~DFE();
// Call Init before Dart_Initialize to prevent races between the
// different isolates.
void Init();
char* frontend_filename() const { return frontend_filename_; }
void set_frontend_filename(const char* name) {
if (frontend_filename_ != nullptr) {
free(frontend_filename_);
}
frontend_filename_ = Utils::StrDup(name);
set_use_dfe();
}
void set_use_dfe(bool value = true) { use_dfe_ = value; }
bool UseDartFrontend() const { return use_dfe_; }
void set_use_incremental_compiler(bool value) {
use_incremental_compiler_ = value;
}
bool use_incremental_compiler() const { return use_incremental_compiler_; }
void set_verbosity(Dart_KernelCompilationVerbosityLevel verbosity) {
verbosity_ = verbosity;
}
Dart_KernelCompilationVerbosityLevel verbosity() const { return verbosity_; }
// Returns the platform binary file name if the path to
// kernel binaries was set using SetKernelBinaries.
const char* GetPlatformBinaryFilename();
// Set the kernel program for the main application if it was specified
// as a dill file.
void set_application_kernel_buffer(uint8_t* buffer, intptr_t size) {
application_kernel_buffer_ = buffer;
application_kernel_buffer_size_ = size;
}
void application_kernel_buffer(const uint8_t** buffer, intptr_t* size) const {
*buffer = application_kernel_buffer_;
*size = application_kernel_buffer_size_;
}
// Compiles specified script.
// Returns result from compiling the script.
//
// `snapshot` is used by the frontend to determine if compilation
// related information should be printed to console (e.g., null safety mode).
Dart_KernelCompilationResult CompileScript(const char* script_uri,
bool incremental,
const char* package_config,
bool snapshot);
// Compiles specified script.
// Returns result from compiling the script.
//
// `snapshot` is used by the frontend to determine if compilation
// related information should be printed to console (e.g., null safety mode).
// `null_safety` specifies compilation mode, which is normally
// retrieved either from vm flags or from vm isolate group.
Dart_KernelCompilationResult CompileScriptWithGivenNullsafety(
const char* script_uri,
const char* package_config,
bool snapshot,
bool null_safety);
// Compiles specified script and reads the resulting kernel file.
// If the compilation is successful, returns a valid in memory kernel
// representation of the script, NULL otherwise
// 'error' and 'exit_code' have the error values in case of errors.
//
// `snapshot` is used by the frontend to determine if compilation
// related information should be printed to console (e.g., null safety mode).
void CompileAndReadScript(const char* script_uri,
uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size,
char** error,
int* exit_code,
const char* package_config,
bool snapshot);
// Reads the script kernel file if specified 'script_uri' is a kernel file.
// Returns an in memory kernel representation of the specified script is a
// valid kernel file, sets 'kernel_buffer' to nullptr otherwise.
//
// If 'kernel_blob_ptr' is not nullptr, then this function can also
// read kernel blobs. In such case it sets 'kernel_blob_ptr'
// to a shared pointer which owns the kernel buffer.
// Othwerise, the caller is responsible for free()ing 'kernel_buffer'.
void ReadScript(const char* script_uri,
uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size,
bool decode_uri = true,
std::shared_ptr<uint8_t>* kernel_blob_ptr = nullptr);
bool KernelServiceDillAvailable() const;
// Tries to read 'script_uri' as a Kernel IR file.
// Returns `true` if successful and sets 'kernel_buffer' and 'kernel_length'
// to be the kernel IR contents.
//
// If 'kernel_blob_ptr' is not nullptr, then this function can also
// read kernel blobs. In such case it sets 'kernel_blob_ptr'
// to a shared pointer which owns the kernel buffer.
// Othwerise, the caller is responsible for free()ing 'kernel_buffer'
// if `true` was returned.
bool TryReadKernelFile(const char* script_uri,
uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size,
bool decode_uri = true,
std::shared_ptr<uint8_t>* kernel_blob_ptr = nullptr);
// We distinguish between "intent to use Dart frontend" vs "can actually
// use Dart frontend". The method UseDartFrontend tells us about the
// intent to use DFE. This method tells us if Dart frontend can actually
// be used.
bool CanUseDartFrontend() const;
void LoadPlatform(const uint8_t** kernel_buffer,
intptr_t* kernel_buffer_size);
void LoadKernelService(const uint8_t** kernel_service_buffer,
intptr_t* kernel_service_buffer_size);
// Registers given kernel blob and returns blob URI which
// can be used in TryReadKernelFile later to load the given kernel.
// Data from [kernel_buffer] is copied, it doesn't need to stay alive.
// Returns NULL if failed to allocate memory.
const char* RegisterKernelBlob(const uint8_t* kernel_buffer,
intptr_t kernel_buffer_size);
// Looks for kernel blob using the given [uri].
// Returns non-null pointer to the kernel blob if successful and
// sets [kernel_length].
std::shared_ptr<uint8_t> TryFindKernelBlob(const char* uri,
intptr_t* kernel_length);
// Unregisters kernel blob with given URI.
void UnregisterKernelBlob(const char* uri);
private:
bool use_dfe_;
bool use_incremental_compiler_;
char* frontend_filename_;
Dart_KernelCompilationVerbosityLevel verbosity_ =
Dart_KernelCompilationVerbosityLevel_All;
// Kernel binary specified on the cmd line.
uint8_t* application_kernel_buffer_;
intptr_t application_kernel_buffer_size_;
// Registry of kernel blobs. Maps URI (char *) to KernelBlob.
SimpleHashMap kernel_blobs_;
intptr_t kernel_blob_counter_ = 0;
Mutex kernel_blobs_lock_;
void InitKernelServiceAndPlatformDills();
DISALLOW_COPY_AND_ASSIGN(DFE);
};
class KernelBlob {
public:
// Takes ownership over [uri] and [buffer].
KernelBlob(char* uri, uint8_t* buffer, intptr_t size)
: uri_(uri, std::free), buffer_(buffer, std::free), size_(size) {}
std::shared_ptr<uint8_t> buffer() { return buffer_; }
intptr_t size() const { return size_; }
private:
Utils::CStringUniquePtr uri_;
std::shared_ptr<uint8_t> buffer_;
const intptr_t size_;
DISALLOW_COPY_AND_ASSIGN(KernelBlob);
};
class PathSanitizer {
public:
explicit PathSanitizer(const char* path);
const char* sanitized_uri() const;
private:
#if defined(DART_HOST_OS_WINDOWS)
std::unique_ptr<char[]> sanitized_uri_;
#else
const char* sanitized_uri_;
#endif // defined(DART_HOST_OS_WINDOWS)
DISALLOW_COPY_AND_ASSIGN(PathSanitizer);
};
#if !defined(DART_PRECOMPILED_RUNTIME)
extern DFE dfe;
#endif
} // namespace bin
} // namespace dart
#endif // RUNTIME_BIN_DFE_H_