| // 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_ |