Support for IsolateMirror.loadUri/kImportTag.
Make file loading errors non-fatal.
Remove dependency tracking left over from the days of sky_snapshot.
Change-Id: I6852c84c44dd7074cc8a515a30468f0ba7430447
diff --git a/file_loader/file_loader.cc b/file_loader/file_loader.cc
index 4d0a23a..0acae19 100644
--- a/file_loader/file_loader.cc
+++ b/file_loader/file_loader.cc
@@ -50,6 +50,9 @@
FileLoader::FileLoader(int dirfd) : dirfd_(dirfd) {}
FileLoader::~FileLoader() {
+ for (auto kernel_buffer : kernel_buffers_)
+ free(kernel_buffer);
+
if (dirfd_ >= 0)
close(dirfd_);
}
@@ -76,7 +79,6 @@
bool FileLoader::LoadPackagesMap(const std::string& packages) {
packages_ = packages;
- dependencies_.insert(packages_);
std::string packages_source;
if (!ReadFileToString(packages_, &packages_source)) {
tonic::Log("error: Unable to load .packages file '%s'.", packages_.c_str());
@@ -124,6 +126,8 @@
return CanonicalizeURL(library, url);
if (tag == Dart_kKernelTag)
return Kernel(url);
+ if (tag == Dart_kImportTag)
+ return Import(url);
return Dart_NewApiError("Unknown library tag.");
}
@@ -153,25 +157,42 @@
return url;
}
-std::pair<uint8_t*, intptr_t> FileLoader::FetchBytes(const std::string& url) {
+Dart_Handle FileLoader::FetchBytes(const std::string& url,
+ uint8_t*& buffer,
+ intptr_t& buffer_size) {
+ buffer = nullptr;
+ buffer_size = -1;
+
std::string path = filesystem::SimplifyPath(GetFilePathForURL(url));
if (path.empty()) {
- tonic::Log("error: Unable to read Dart source '%s'.", url.c_str());
- PlatformExit(1);
+ std::string error_message = "error: Unable to read '" + url + "'.";
+ return Dart_NewUnhandledExceptionError(
+ Dart_NewStringFromCString(error_message.c_str()));
}
- auto result =
- filesystem::ReadFileToBytes(filesystem::GetAbsoluteFilePath(path));
+ std::string absolute_path = filesystem::GetAbsoluteFilePath(path);
+ auto result = filesystem::ReadFileToBytes(absolute_path);
if (result.first == nullptr) {
- // TODO(aam): Same as above the file loader should not explicitly log the
- // error or exit the process. Instead these errors should be reported to the
- // caller of the FileLoader who can implement the application-specific error
- // handling policy.
- tonic::Log("error: Unable to read Dart source '%s'.", url.c_str());
- PlatformExit(1);
+ std::string error_message =
+ "error: Unable to read '" + absolute_path + "'.";
+ return Dart_NewUnhandledExceptionError(
+ Dart_NewStringFromCString(error_message.c_str()));
}
- url_dependencies_.insert(url);
- dependencies_.insert(path);
- return result;
+ buffer = result.first;
+ buffer_size = result.second;
+ return Dart_True();
+}
+
+Dart_Handle FileLoader::Import(Dart_Handle url) {
+ std::string url_string = StdStringFromDart(url);
+ uint8_t* buffer = nullptr;
+ intptr_t buffer_size = -1;
+ Dart_Handle result = FetchBytes(url_string, buffer, buffer_size);
+ if (Dart_IsError(result)) {
+ return result;
+ }
+ // The embedder must keep the buffer alive until isolate shutdown.
+ kernel_buffers_.push_back(buffer);
+ return Dart_LoadLibraryFromKernel(buffer, buffer_size);
}
namespace {
@@ -184,11 +205,15 @@
Dart_Handle FileLoader::Kernel(Dart_Handle url) {
std::string url_string = StdStringFromDart(url);
- std::pair<uint8_t*, intptr_t> fetched_result = FetchBytes(url_string);
- Dart_Handle result = Dart_NewExternalTypedData(
- Dart_TypedData_kUint8, fetched_result.first, fetched_result.second);
- Dart_NewWeakPersistentHandle(result, fetched_result.first,
- fetched_result.second, MallocFinalizer);
+ uint8_t* buffer = nullptr;
+ intptr_t buffer_size = -1;
+ Dart_Handle result = FetchBytes(url_string, buffer, buffer_size);
+ if (Dart_IsError(result)) {
+ return result;
+ }
+ result =
+ Dart_NewExternalTypedData(Dart_TypedData_kUint8, buffer, buffer_size);
+ Dart_NewWeakPersistentHandle(result, buffer, buffer_size, MallocFinalizer);
return result;
}
diff --git a/file_loader/file_loader.h b/file_loader/file_loader.h
index 41a576b..5a25058 100644
--- a/file_loader/file_loader.h
+++ b/file_loader/file_loader.h
@@ -8,6 +8,7 @@
#include <memory>
#include <set>
#include <string>
+#include <vector>
#include "third_party/dart/runtime/include/dart_api.h"
#include "tonic/common/macros.h"
@@ -25,25 +26,18 @@
// The path to the `.packages` file the packages map was loaded from.
const std::string& packages() const { return packages_; }
- // Fully resolved file paths to dependencies. For example,
- // "package:foo/bar.dart" will be resolved to
- // "/path/to/package/foo/lib/bar.dart".
- const std::set<std::string>& dependencies() const { return dependencies_; }
- // Canonicalized urls to dependencies. No package resolution is done,
- // For example, "package:foo/bar.dart" will be "package:foo/bar.dart".
- const std::set<std::string>& url_dependencies() const {
- return url_dependencies_;
- }
-
Dart_Handle HandleLibraryTag(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url);
Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url);
+ Dart_Handle Import(Dart_Handle url);
Dart_Handle Kernel(Dart_Handle url);
void SetPackagesUrl(Dart_Handle url);
- std::pair<uint8_t*, intptr_t> FetchBytes(const std::string& url);
+ Dart_Handle FetchBytes(const std::string& url,
+ uint8_t*& buffer,
+ intptr_t& buffer_size);
static const char kFileURLPrefix[];
static const size_t kFileURLPrefixLength;
@@ -64,10 +58,9 @@
std::pair<uint8_t*, intptr_t> ReadFileToBytes(const std::string& path);
int dirfd_;
- std::set<std::string> dependencies_;
- std::set<std::string> url_dependencies_;
std::string packages_;
std::unique_ptr<PackagesMap> packages_map_;
+ std::vector<uint8_t*> kernel_buffers_;
TONIC_DISALLOW_COPY_AND_ASSIGN(FileLoader);
};