mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
More cleanup of the loader code.
Change-Id: I8ee048f2a06f8aa54cb5efb832740a53b2bd042d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/127444 Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Ben Konyi <bkonyi@google.com> Commit-Queue: Siva Annamalai <asiva@google.com>
This commit is contained in:
parent
a3953b607d
commit
b99599bae1
7 changed files with 6 additions and 322 deletions
|
@ -524,21 +524,10 @@ Dart_Handle DartUtils::SetupServiceLoadPort() {
|
|||
return Builtin::SetLoadPort(load_port);
|
||||
}
|
||||
|
||||
Dart_Handle DartUtils::SetupPackageRoot(const char* package_root,
|
||||
const char* packages_config) {
|
||||
Dart_Handle DartUtils::SetupPackageConfig(const char* packages_config) {
|
||||
Dart_Handle result = Dart_Null();
|
||||
|
||||
// Set up package root if specified.
|
||||
if (package_root != NULL) {
|
||||
ASSERT(packages_config == NULL);
|
||||
result = NewString(package_root);
|
||||
RETURN_IF_ERROR(result);
|
||||
const int kNumArgs = 1;
|
||||
Dart_Handle dart_args[kNumArgs];
|
||||
dart_args[0] = result;
|
||||
result = Dart_Invoke(DartUtils::LookupBuiltinLib(),
|
||||
NewString("_setPackageRoot"), kNumArgs, dart_args);
|
||||
} else if (packages_config != NULL) {
|
||||
if (packages_config != NULL) {
|
||||
result = NewString(packages_config);
|
||||
RETURN_IF_ERROR(result);
|
||||
const int kNumArgs = 1;
|
||||
|
|
|
@ -152,8 +152,8 @@ class DartUtils {
|
|||
static Dart_Handle PrepareForScriptLoading(bool is_service_isolate,
|
||||
bool trace_loading);
|
||||
static Dart_Handle SetupServiceLoadPort();
|
||||
static Dart_Handle SetupPackageRoot(const char* package_root,
|
||||
const char* packages_file);
|
||||
static Dart_Handle SetupPackageConfig(const char* packages_file);
|
||||
|
||||
static Dart_Handle SetupIOLibrary(const char* namespc_path,
|
||||
const char* script_uri,
|
||||
bool disable_exit);
|
||||
|
|
|
@ -199,14 +199,13 @@ static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate,
|
|||
if (Dart_IsError(result)) return result;
|
||||
}
|
||||
|
||||
// Setup package root if specified.
|
||||
result = DartUtils::SetupPackageRoot(nullptr, packages_file);
|
||||
// Setup packages config if specified.
|
||||
result = DartUtils::SetupPackageConfig(packages_file);
|
||||
if (Dart_IsError(result)) return result;
|
||||
if (!Dart_IsNull(result) && resolved_packages_config != nullptr) {
|
||||
result = Dart_StringToCString(result, resolved_packages_config);
|
||||
if (Dart_IsError(result)) return result;
|
||||
ASSERT(*resolved_packages_config != nullptr);
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
if (is_isolate_group_start) {
|
||||
isolate_group_data->set_resolved_packages_config(
|
||||
|
|
|
@ -30,44 +30,8 @@ _sanitizeWindowsPath(path) {
|
|||
return fixedPath;
|
||||
}
|
||||
|
||||
_trimWindowsPath(path) {
|
||||
// Convert /X:/ to X:/.
|
||||
if (_isWindows == false) {
|
||||
// Do nothing when not running Windows.
|
||||
return path;
|
||||
}
|
||||
if (!path.startsWith('/') || (path.length < 3)) {
|
||||
return path;
|
||||
}
|
||||
// Match '/?:'.
|
||||
if ((path[0] == '/') && (path[2] == ':')) {
|
||||
// Remove leading '/'.
|
||||
return path.substring(1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
// Ensure we have a trailing slash character.
|
||||
_enforceTrailingSlash(uri) {
|
||||
if (!uri.endsWith('/')) {
|
||||
return '$uri/';
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
class FileRequest {
|
||||
final SendPort sp;
|
||||
final int tag;
|
||||
final Uri uri;
|
||||
final Uri resolvedUri;
|
||||
final String libraryUrl;
|
||||
FileRequest(this.sp, this.tag, this.uri, this.resolvedUri, this.libraryUrl);
|
||||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
bool _traceLoading = false;
|
||||
@pragma("vm:entry-point")
|
||||
bool _deterministic = false;
|
||||
|
||||
// State associated with the isolate that is used for loading.
|
||||
class IsolateLoaderState extends IsolateEmbedderData {
|
||||
|
@ -87,10 +51,6 @@ class IsolateLoaderState extends IsolateEmbedderData {
|
|||
if (rootScript != null) {
|
||||
_rootScript = Uri.parse(rootScript);
|
||||
}
|
||||
// If the --package-root flag was passed.
|
||||
if (packageRootFlag != null) {
|
||||
_setPackageRoot(packageRootFlag);
|
||||
}
|
||||
// If the --packages flag was passed.
|
||||
if (packagesConfigFlag != null) {
|
||||
_setPackagesConfig(packagesConfigFlag);
|
||||
|
@ -139,40 +99,6 @@ class IsolateLoaderState extends IsolateEmbedderData {
|
|||
Uri _packageConfig = null;
|
||||
Map<String, Uri> _packageMap = null;
|
||||
|
||||
// We issue only 16 concurrent calls to File.readAsBytes() to stay within
|
||||
// platform-specific resource limits (e.g. max open files). The rest go on
|
||||
// _fileRequestQueue and are processed when we can safely issue them.
|
||||
static final int _maxFileRequests = _deterministic ? 1 : 16;
|
||||
int currentFileRequests = 0;
|
||||
final List<FileRequest> _fileRequestQueue = new List<FileRequest>();
|
||||
|
||||
bool get shouldIssueFileRequest => currentFileRequests < _maxFileRequests;
|
||||
void enqueueFileRequest(FileRequest fr) {
|
||||
_fileRequestQueue.add(fr);
|
||||
}
|
||||
|
||||
FileRequest dequeueFileRequest() {
|
||||
if (_fileRequestQueue.length == 0) {
|
||||
return null;
|
||||
}
|
||||
return _fileRequestQueue.removeAt(0);
|
||||
}
|
||||
|
||||
_setPackageRoot(String packageRoot) {
|
||||
packageRoot = _sanitizeWindowsPath(packageRoot);
|
||||
if (packageRoot.startsWith('file:') ||
|
||||
packageRoot.startsWith('http:') ||
|
||||
packageRoot.startsWith('https:')) {
|
||||
packageRoot = _enforceTrailingSlash(packageRoot);
|
||||
_packageRoot = _workingDirectory.resolve(packageRoot);
|
||||
} else {
|
||||
packageRoot = _sanitizeWindowsPath(packageRoot);
|
||||
packageRoot = _trimWindowsPath(packageRoot);
|
||||
_packageRoot =
|
||||
_workingDirectory.resolveUri(new Uri.directory(packageRoot));
|
||||
}
|
||||
}
|
||||
|
||||
_setPackagesConfig(String packagesParam) {
|
||||
var packagesName = _sanitizeWindowsPath(packagesParam);
|
||||
var packagesUri = Uri.parse(packagesName);
|
||||
|
@ -396,150 +322,6 @@ void _sendExtensionImportResponse(
|
|||
sp.send(msg);
|
||||
}
|
||||
|
||||
void _loadHttp(
|
||||
SendPort sp, int tag, Uri uri, Uri resolvedUri, String libraryUrl) {
|
||||
if (_httpClient == null) {
|
||||
_httpClient = new HttpClient()..maxConnectionsPerHost = 6;
|
||||
}
|
||||
_httpClient
|
||||
.getUrl(resolvedUri)
|
||||
.then((HttpClientRequest request) => request.close())
|
||||
.then((HttpClientResponse response) {
|
||||
var builder = new BytesBuilder(copy: false);
|
||||
response.listen(builder.add, onDone: () {
|
||||
if (response.statusCode != 200) {
|
||||
var msg = "Failure getting $resolvedUri:\n"
|
||||
" ${response.statusCode} ${response.reasonPhrase}";
|
||||
_sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, msg);
|
||||
} else {
|
||||
_sendResourceResponse(
|
||||
sp, tag, uri, resolvedUri, libraryUrl, builder.takeBytes());
|
||||
}
|
||||
}, onError: (e) {
|
||||
_sendResourceResponse(
|
||||
sp, tag, uri, resolvedUri, libraryUrl, e.toString());
|
||||
});
|
||||
}).catchError((e) {
|
||||
_sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, e.toString());
|
||||
});
|
||||
// It's just here to push an event on the event loop so that we invoke the
|
||||
// scheduled microtasks.
|
||||
Timer.run(() {});
|
||||
}
|
||||
|
||||
void _loadFile(IsolateLoaderState loaderState, SendPort sp, int tag, Uri uri,
|
||||
Uri resolvedUri, String libraryUrl) {
|
||||
var path = resolvedUri.toFilePath();
|
||||
var sourceFile = new File(path);
|
||||
sourceFile.readAsBytes().then((data) {
|
||||
_sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, data);
|
||||
}, onError: (e) {
|
||||
_sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl, e.toString());
|
||||
}).whenComplete(() {
|
||||
loaderState.currentFileRequests--;
|
||||
while (loaderState.shouldIssueFileRequest) {
|
||||
FileRequest fr = loaderState.dequeueFileRequest();
|
||||
if (fr == null) {
|
||||
break;
|
||||
}
|
||||
_loadFile(
|
||||
loaderState, fr.sp, fr.tag, fr.uri, fr.resolvedUri, fr.libraryUrl);
|
||||
loaderState.currentFileRequests++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _loadDataUri(
|
||||
SendPort sp, int tag, Uri uri, Uri resolvedUri, String libraryUrl) {
|
||||
try {
|
||||
var mime = uri.data.mimeType;
|
||||
if ((mime != "application/dart") && (mime != "text/plain")) {
|
||||
throw "MIME-type must be application/dart or text/plain: $mime given.";
|
||||
}
|
||||
var charset = uri.data.charset;
|
||||
if ((charset != "utf-8") && (charset != "US-ASCII")) {
|
||||
// The C++ portion of the embedder assumes UTF-8.
|
||||
throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
|
||||
}
|
||||
_sendResourceResponse(
|
||||
sp, tag, uri, resolvedUri, libraryUrl, uri.data.contentAsBytes());
|
||||
} catch (e) {
|
||||
_sendResourceResponse(sp, tag, uri, resolvedUri, libraryUrl,
|
||||
"Invalid data uri ($uri):\n $e");
|
||||
}
|
||||
}
|
||||
|
||||
// Loading a package URI needs to first map the package name to a loadable
|
||||
// URI.
|
||||
_loadPackage(IsolateLoaderState loaderState, SendPort sp, bool traceLoading,
|
||||
int tag, Uri uri, Uri resolvedUri, String libraryUrl) {
|
||||
if (loaderState._packagesReady) {
|
||||
var resolvedUri;
|
||||
try {
|
||||
resolvedUri = loaderState._resolvePackageUri(uri);
|
||||
} catch (e, s) {
|
||||
if (traceLoading) {
|
||||
_log("Exception ($e) when resolving package URI: $uri");
|
||||
}
|
||||
// Report error.
|
||||
_sendResourceResponse(
|
||||
sp, tag, uri, resolvedUri, libraryUrl, e.toString());
|
||||
return;
|
||||
}
|
||||
// Recursively call with the new resolved uri.
|
||||
_handleResourceRequest(
|
||||
loaderState, sp, traceLoading, tag, uri, resolvedUri, libraryUrl);
|
||||
} else {
|
||||
if (loaderState._pendingPackageLoads.isEmpty) {
|
||||
// Package resolution has not been setup yet, and this is the first
|
||||
// request for package resolution & loading.
|
||||
loaderState._requestPackagesMap();
|
||||
}
|
||||
// Register the action of loading this package once the package resolution
|
||||
// is ready.
|
||||
loaderState._pendingPackageLoads.add(() {
|
||||
_handleResourceRequest(
|
||||
loaderState, sp, traceLoading, tag, uri, uri, libraryUrl);
|
||||
});
|
||||
if (traceLoading) {
|
||||
_log("Pending package load of '$uri': "
|
||||
"${loaderState._pendingPackageLoads.length} pending");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(johnmccutchan): This and most other top level functions in this file
|
||||
// should be turned into methods on the IsolateLoaderState class.
|
||||
_handleResourceRequest(IsolateLoaderState loaderState, SendPort sp,
|
||||
bool traceLoading, int tag, Uri uri, Uri resolvedUri, String libraryUrl) {
|
||||
if (resolvedUri.scheme == '' || resolvedUri.scheme == 'file') {
|
||||
if (loaderState.shouldIssueFileRequest) {
|
||||
_loadFile(loaderState, sp, tag, uri, resolvedUri, libraryUrl);
|
||||
loaderState.currentFileRequests++;
|
||||
} else {
|
||||
FileRequest fr = new FileRequest(sp, tag, uri, resolvedUri, libraryUrl);
|
||||
loaderState.enqueueFileRequest(fr);
|
||||
}
|
||||
} else if ((resolvedUri.scheme == 'http') ||
|
||||
(resolvedUri.scheme == 'https')) {
|
||||
_loadHttp(sp, tag, uri, resolvedUri, libraryUrl);
|
||||
} else if ((resolvedUri.scheme == 'data')) {
|
||||
_loadDataUri(sp, tag, uri, resolvedUri, libraryUrl);
|
||||
} else if ((resolvedUri.scheme == 'package')) {
|
||||
_loadPackage(
|
||||
loaderState, sp, traceLoading, tag, uri, resolvedUri, libraryUrl);
|
||||
} else {
|
||||
_sendResourceResponse(
|
||||
sp,
|
||||
tag,
|
||||
uri,
|
||||
resolvedUri,
|
||||
libraryUrl,
|
||||
'Unknown scheme (${resolvedUri.scheme}) for '
|
||||
'$resolvedUri');
|
||||
}
|
||||
}
|
||||
|
||||
// Handling of packages requests. Finding and parsing of .packages file or
|
||||
// packages/ directories.
|
||||
const _LF = 0x0A;
|
||||
|
|
|
@ -202,12 +202,6 @@ bool VmService::Setup(const char* server_ip,
|
|||
Dart_SetField(library, DartUtils::NewString("_isFuchsia"), is_fuchsia);
|
||||
SHUTDOWN_ON_ERROR(result);
|
||||
|
||||
if (deterministic) {
|
||||
result = Dart_SetField(library, DartUtils::NewString("_deterministic"),
|
||||
Dart_True());
|
||||
SHUTDOWN_ON_ERROR(result);
|
||||
}
|
||||
|
||||
// Get _getWatchSignalInternal from dart:io.
|
||||
Dart_Handle dart_io_str = Dart_NewStringFromCString(DartUtils::kIOLibURL);
|
||||
SHUTDOWN_ON_ERROR(dart_io_str);
|
||||
|
|
|
@ -74,8 +74,6 @@ Uri _workingDirectory;
|
|||
// package imports can be resolved relative to it. The root script is the basis
|
||||
// for the root library in the VM.
|
||||
Uri _rootScript;
|
||||
// The package root set on the command line.
|
||||
Uri _packageRoot;
|
||||
|
||||
// Special handling for Windows paths so that they are compatible with URI
|
||||
// handling.
|
||||
|
@ -154,38 +152,6 @@ void _setWorkingDirectory(String cwd) {
|
|||
}
|
||||
}
|
||||
|
||||
// Embedder Entrypoint:
|
||||
// The embedder calls this method with a custom package root.
|
||||
@pragma("vm:entry-point")
|
||||
String _setPackageRoot(String packageRoot) {
|
||||
if (!_setupCompleted) {
|
||||
_setupHooks();
|
||||
}
|
||||
if (_traceLoading) {
|
||||
_log('Setting package root: $packageRoot');
|
||||
}
|
||||
if (packageRoot.startsWith('file:') ||
|
||||
packageRoot.startsWith('http:') ||
|
||||
packageRoot.startsWith('https:')) {
|
||||
packageRoot = _enforceTrailingSlash(packageRoot);
|
||||
_packageRoot = _workingDirectory.resolve(packageRoot);
|
||||
} else {
|
||||
packageRoot = _sanitizeWindowsPath(packageRoot);
|
||||
packageRoot = _trimWindowsPath(packageRoot);
|
||||
_packageRoot = _workingDirectory.resolveUri(new Uri.directory(packageRoot));
|
||||
}
|
||||
// Now that we have determined the packageRoot value being used, set it
|
||||
// up for use in Platform.packageRoot. This is only set when the embedder
|
||||
// sets up the package root. Automatically discovered package root will
|
||||
// not update the VMLibraryHooks value.
|
||||
var packageRootStr = _packageRoot.toString();
|
||||
VMLibraryHooks.packageRootString = packageRootStr;
|
||||
if (_traceLoading) {
|
||||
_log('Package root URI: $_packageRoot');
|
||||
}
|
||||
return packageRootStr;
|
||||
}
|
||||
|
||||
// Embedder Entrypoint:
|
||||
@pragma("vm:entry-point")
|
||||
String _setPackagesMap(String packagesParam) {
|
||||
|
@ -246,12 +212,6 @@ String _resolveScriptUri(String scriptName) {
|
|||
return scriptUri.toString();
|
||||
}
|
||||
|
||||
// Only used by vm/cc unit tests.
|
||||
Uri _resolvePackageUri(Uri uri) {
|
||||
assert(_packageRoot != null);
|
||||
return _packageRoot.resolve(uri.path);
|
||||
}
|
||||
|
||||
// Register callbacks and hooks with the rest of the core libraries.
|
||||
@pragma("vm:entry-point")
|
||||
_setupHooks() {
|
||||
|
|
|
@ -74,8 +74,6 @@ Uri _workingDirectory;
|
|||
// package imports can be resolved relative to it. The root script is the basis
|
||||
// for the root library in the VM.
|
||||
Uri _rootScript;
|
||||
// The package root set on the command line.
|
||||
Uri _packageRoot;
|
||||
|
||||
// Special handling for Windows paths so that they are compatible with URI
|
||||
// handling.
|
||||
|
@ -154,38 +152,6 @@ void _setWorkingDirectory(String cwd) {
|
|||
}
|
||||
}
|
||||
|
||||
// Embedder Entrypoint:
|
||||
// The embedder calls this method with a custom package root.
|
||||
@pragma("vm:entry-point")
|
||||
String _setPackageRoot(String packageRoot) {
|
||||
if (!_setupCompleted) {
|
||||
_setupHooks();
|
||||
}
|
||||
if (_traceLoading) {
|
||||
_log('Setting package root: $packageRoot');
|
||||
}
|
||||
if (packageRoot.startsWith('file:') ||
|
||||
packageRoot.startsWith('http:') ||
|
||||
packageRoot.startsWith('https:')) {
|
||||
packageRoot = _enforceTrailingSlash(packageRoot);
|
||||
_packageRoot = _workingDirectory.resolve(packageRoot);
|
||||
} else {
|
||||
packageRoot = _sanitizeWindowsPath(packageRoot);
|
||||
packageRoot = _trimWindowsPath(packageRoot);
|
||||
_packageRoot = _workingDirectory.resolveUri(new Uri.directory(packageRoot));
|
||||
}
|
||||
// Now that we have determined the packageRoot value being used, set it
|
||||
// up for use in Platform.packageRoot. This is only set when the embedder
|
||||
// sets up the package root. Automatically discovered package root will
|
||||
// not update the VMLibraryHooks value.
|
||||
var packageRootStr = _packageRoot.toString();
|
||||
VMLibraryHooks.packageRootString = packageRootStr;
|
||||
if (_traceLoading) {
|
||||
_log('Package root URI: $_packageRoot');
|
||||
}
|
||||
return packageRootStr;
|
||||
}
|
||||
|
||||
// Embedder Entrypoint:
|
||||
@pragma("vm:entry-point")
|
||||
String _setPackagesMap(String packagesParam) {
|
||||
|
@ -246,12 +212,6 @@ String _resolveScriptUri(String scriptName) {
|
|||
return scriptUri.toString();
|
||||
}
|
||||
|
||||
// Only used by vm/cc unit tests.
|
||||
Uri _resolvePackageUri(Uri uri) {
|
||||
assert(_packageRoot != null);
|
||||
return _packageRoot.resolve(uri.path);
|
||||
}
|
||||
|
||||
// Register callbacks and hooks with the rest of the core libraries.
|
||||
@pragma("vm:entry-point")
|
||||
_setupHooks() {
|
||||
|
|
Loading…
Reference in a new issue