diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart index abd87c32e25..021c8583011 100644 --- a/pkg/vm/bin/kernel_service.dart +++ b/pkg/vm/bin/kernel_service.dart @@ -100,8 +100,7 @@ CompilerOptions setupCompilerOptions( int nullSafety, List experimentalFlags, bool bytecode, - String packageConfig, - String workingDirectory, + Uri packagesUri, List errors) { final expFlags = []; if (experimentalFlags != null) { @@ -109,17 +108,7 @@ CompilerOptions setupCompilerOptions( expFlags.addAll(flag.split(",")); } } - Uri packagesUri = null; - if (packageConfig != null) { - packagesUri = Uri.parse(packageConfig); - if (packagesUri.scheme == '') { - // Script does not have a scheme, assume that it is a path, - // resolve it against the working directory. - packagesUri = Uri.directory(workingDirectory).resolveUri(packagesUri); - } - } else if (Platform.packageConfig != null) { - packagesUri = Uri.parse(Platform.packageConfig); - } + return new CompilerOptions() ..fileSystem = fileSystem ..target = new VmTarget(new TargetFlags( @@ -169,7 +158,7 @@ abstract class Compiler { final List experimentalFlags; final bool bytecode; final String packageConfig; - final String workingDirectory; + // Code coverage and hot reload are only supported by incremental compiler, // which is used if vm-service is enabled. final bool supportCodeCoverage; @@ -187,8 +176,21 @@ abstract class Compiler { this.bytecode: false, this.supportCodeCoverage: false, this.supportHotReload: false, - this.packageConfig: null, - this.workingDirectory: null}) { + this.packageConfig: null}) { + Uri packagesUri = null; + if (packageConfig != null) { + packagesUri = Uri.parse(packageConfig); + } else if (Platform.packageConfig != null) { + packagesUri = Uri.parse(Platform.packageConfig); + } + + if (verbose) { + print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); + print("DFE: packagesUri: ${packagesUri}"); + print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); + print("DFE: platformKernelPath: ${platformKernelPath}"); + } + options = setupCompilerOptions( fileSystem, platformKernelPath, @@ -197,16 +199,8 @@ abstract class Compiler { nullSafety, experimentalFlags, bytecode, - packageConfig, - workingDirectory, + packagesUri, errors); - - if (verbose) { - print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); - print("DFE: packagesUri: ${options.packagesFileUri}"); - print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); - print("DFE: platformKernelPath: ${platformKernelPath}"); - } } Future compile(Uri script) { @@ -343,8 +337,7 @@ class IncrementalCompilerWrapper extends Compiler { int nullSafety: kNullSafetyOptionUnspecified, List experimentalFlags: null, bool bytecode: false, - String packageConfig: null, - String workingDirectory: null}) + String packageConfig: null}) : super(isolateId, fileSystem, platformKernelPath, suppressWarnings: suppressWarnings, enableAsserts: enableAsserts, @@ -353,8 +346,7 @@ class IncrementalCompilerWrapper extends Compiler { bytecode: bytecode, supportHotReload: true, supportCodeCoverage: true, - packageConfig: packageConfig, - workingDirectory: workingDirectory); + packageConfig: packageConfig); factory IncrementalCompilerWrapper.forExpressionCompilationOnly( Component component, @@ -365,8 +357,7 @@ class IncrementalCompilerWrapper extends Compiler { bool enableAsserts: false, List experimentalFlags: null, bool bytecode: false, - String packageConfig: null, - String workingDirectory: null}) { + String packageConfig: null}) { IncrementalCompilerWrapper result = IncrementalCompilerWrapper( isolateId, fileSystem, platformKernelPath, suppressWarnings: suppressWarnings, @@ -402,8 +393,7 @@ class IncrementalCompilerWrapper extends Compiler { nullSafety: nullSafety, experimentalFlags: experimentalFlags, bytecode: bytecode, - packageConfig: packageConfig, - workingDirectory: workingDirectory); + packageConfig: packageConfig); generator.resetDeltaState(); Component fullComponent = await generator.compile(); @@ -434,16 +424,14 @@ class SingleShotCompilerWrapper extends Compiler { int nullSafety: kNullSafetyOptionUnspecified, List experimentalFlags: null, bool bytecode: false, - String packageConfig: null, - String workingDirectory: null}) + String packageConfig: null}) : super(isolateId, fileSystem, platformKernelPath, suppressWarnings: suppressWarnings, enableAsserts: enableAsserts, nullSafety: nullSafety, experimentalFlags: experimentalFlags, bytecode: bytecode, - packageConfig: packageConfig, - workingDirectory: workingDirectory); + packageConfig: packageConfig); @override Future compileInternal(Uri script) async { @@ -479,7 +467,6 @@ Future lookupOrBuildNewIncrementalCompiler(int isolateId, List experimentalFlags: null, bool bytecode: false, String packageConfig: null, - String workingDirectory: null, String multirootFilepaths, String multirootScheme}) async { IncrementalCompilerWrapper compiler = lookupIncrementalCompiler(isolateId); @@ -493,8 +480,7 @@ Future lookupOrBuildNewIncrementalCompiler(int isolateId, if (sourceFiles != null && sourceFiles.length > 0 && sourceFiles[1] == null) { - // Just use first compiler that should represent main isolate as a source - // for cloning. + // Just use first compiler that should represent main isolate as a source for cloning. var source = isolateCompilers.entries.first; compiler = await source.value.clone(isolateId); } else { @@ -512,8 +498,7 @@ Future lookupOrBuildNewIncrementalCompiler(int isolateId, nullSafety: nullSafety, experimentalFlags: experimentalFlags, bytecode: bytecode, - packageConfig: packageConfig, - workingDirectory: workingDirectory); + packageConfig: packageConfig); } isolateCompilers[isolateId] = compiler; } @@ -837,18 +822,20 @@ Future _processLoadRequest(request) async { } else if (tag == kDetectNullabilityTag) { FileSystem fileSystem = _buildFileSystem( sourceFiles, platformKernel, multirootFilepaths, multirootScheme); + Uri packagesUri = null; + if (packageConfig != null) { + packagesUri = Uri.parse(packageConfig); + } else if (Platform.packageConfig != null) { + packagesUri = Uri.parse(Platform.packageConfig); + } + if (packagesUri != null && packagesUri.scheme == '') { + // Script does not have a scheme, assume that it is a path, + // resolve it against the working directory. + packagesUri = Uri.directory(workingDirectory).resolveUri(packagesUri); + } final List errors = []; - var options = setupCompilerOptions( - fileSystem, - platformKernelPath, - false, - false, - nullSafety, - experimentalFlags, - false, - packageConfig, - workingDirectory, - errors); + var options = setupCompilerOptions(fileSystem, platformKernelPath, false, + false, nullSafety, experimentalFlags, false, packagesUri, errors); // script should only be null for kUpdateSourcesTag. assert(script != null); @@ -874,7 +861,6 @@ Future _processLoadRequest(request) async { experimentalFlags: experimentalFlags, bytecode: bytecode, packageConfig: packageConfig, - workingDirectory: workingDirectory, multirootFilepaths: multirootFilepaths, multirootScheme: multirootScheme); } else { @@ -888,8 +874,7 @@ Future _processLoadRequest(request) async { nullSafety: nullSafety, experimentalFlags: experimentalFlags, bytecode: bytecode, - packageConfig: packageConfig, - workingDirectory: workingDirectory); + packageConfig: packageConfig); } CompilationResult result; diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc index f8f374d2b03..f1eeeb2a946 100644 --- a/runtime/bin/dartutils.cc +++ b/runtime/bin/dartutils.cc @@ -302,6 +302,15 @@ bool DartUtils::EntropySource(uint8_t* buffer, intptr_t length) { return Crypto::GetRandomBytes(length, buffer); } +static Dart_Handle SingleArgDart_Invoke(Dart_Handle lib, + const char* method, + Dart_Handle arg) { + const int kNumArgs = 1; + Dart_Handle dart_args[kNumArgs]; + dart_args[0] = arg; + return Dart_Invoke(lib, DartUtils::NewString(method), kNumArgs, dart_args); +} + // TODO(iposva): Allocate from the zone instead of leaking error string // here. On the other hand the binary is about to exit anyway. #define SET_ERROR_MSG(error_msg, format, ...) \ @@ -361,6 +370,20 @@ Dart_Handle DartUtils::MakeUint8Array(const uint8_t* buffer, intptr_t len) { return array; } +Dart_Handle DartUtils::SetWorkingDirectory() { + Dart_Handle directory = NewString(original_working_directory); + return SingleArgDart_Invoke(LookupBuiltinLib(), "_setWorkingDirectory", + directory); +} + +Dart_Handle DartUtils::ResolveScript(Dart_Handle url) { + const int kNumArgs = 1; + Dart_Handle dart_args[kNumArgs]; + dart_args[0] = url; + return Dart_Invoke(DartUtils::LookupBuiltinLib(), + NewString("_resolveScriptUri"), kNumArgs, dart_args); +} + static bool CheckMagicNumber(const uint8_t* buffer, intptr_t buffer_length, const MagicNumberData& magic_number) { @@ -442,6 +465,9 @@ Dart_Handle DartUtils::PrepareBuiltinLibrary(Dart_Handle builtin_lib, Dart_SetField(builtin_lib, NewString("_traceLoading"), Dart_True()); RETURN_IF_ERROR(result); } + // Set current working directory. + result = SetWorkingDirectory(); + RETURN_IF_ERROR(result); } return Dart_True(); } @@ -488,6 +514,21 @@ Dart_Handle DartUtils::PrepareCLILibrary(Dart_Handle cli_lib) { wait_for_event_handle); } +Dart_Handle DartUtils::SetupPackageConfig(const char* packages_config) { + Dart_Handle result = Dart_Null(); + + if (packages_config != NULL) { + result = NewString(packages_config); + RETURN_IF_ERROR(result); + const int kNumArgs = 1; + Dart_Handle dart_args[kNumArgs]; + dart_args[0] = result; + result = Dart_Invoke(DartUtils::LookupBuiltinLib(), + NewString("_setPackagesMap"), kNumArgs, dart_args); + } + return result; +} + Dart_Handle DartUtils::PrepareForScriptLoading(bool is_service_isolate, bool trace_loading) { // First ensure all required libraries are available. diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h index c2fa094d783..23122adf2cb 100644 --- a/runtime/bin/dartutils.h +++ b/runtime/bin/dartutils.h @@ -161,6 +161,8 @@ class DartUtils { static Dart_Handle MakeUint8Array(const uint8_t* buffer, intptr_t length); static Dart_Handle PrepareForScriptLoading(bool is_service_isolate, bool trace_loading); + static Dart_Handle SetupPackageConfig(const char* packages_file); + static Dart_Handle SetupIOLibrary(const char* namespc_path, const char* script_uri, bool disable_exit); @@ -223,6 +225,8 @@ class DartUtils { static bool SetOriginalWorkingDirectory(); + static Dart_Handle ResolveScript(Dart_Handle url); + enum MagicNumber { kAppJITMagicNumber, kKernelMagicNumber, @@ -261,6 +265,7 @@ class DartUtils { static Dart_Handle EnvironmentCallback(Dart_Handle name); private: + static Dart_Handle SetWorkingDirectory(); static Dart_Handle PrepareBuiltinLibrary(Dart_Handle builtin_lib, Dart_Handle internal_lib, bool is_service_isolate, diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc index 6543dfeadfc..45b625d9ac6 100644 --- a/runtime/bin/dfe.cc +++ b/runtime/bin/dfe.cc @@ -235,15 +235,12 @@ Dart_KernelCompilationResult DFE::CompileScript(const char* script_uri, const char* package_config) { // TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill // instead of vm_platform.dill to Frontend for compilation. - PathSanitizer script_uri_sanitizer(script_uri); - PathSanitizer packages_config_sanitizer(package_config); + PathSanitizer path_sanitizer(script_uri); + const char* sanitized_uri = path_sanitizer.sanitized_uri(); - return Dart_CompileToKernel(script_uri_sanitizer.sanitized_uri(), - platform_strong_dill_for_compilation_, - platform_strong_dill_for_compilation_size_, - incremental, - packages_config_sanitizer.sanitized_uri(), - DartUtils::original_working_directory); + return Dart_CompileToKernel( + sanitized_uri, platform_strong_dill_for_compilation_, + platform_strong_dill_for_compilation_size_, incremental, package_config); } void DFE::CompileAndReadScript(const char* script_uri, diff --git a/runtime/bin/isolate_data.cc b/runtime/bin/isolate_data.cc index 4fca8c41315..154797507aa 100644 --- a/runtime/bin/isolate_data.cc +++ b/runtime/bin/isolate_data.cc @@ -15,6 +15,7 @@ IsolateGroupData::IsolateGroupData(const char* url, bool isolate_run_app_snapshot) : script_url((url != NULL) ? strdup(url) : NULL), app_snapshot_(app_snapshot), + resolved_packages_config_(NULL), kernel_buffer_(NULL), kernel_buffer_size_(0), isolate_run_app_snapshot_(isolate_run_app_snapshot) { @@ -28,6 +29,8 @@ IsolateGroupData::~IsolateGroupData() { script_url = NULL; free(packages_file_); packages_file_ = NULL; + free(resolved_packages_config_); + resolved_packages_config_ = NULL; kernel_buffer_ = NULL; kernel_buffer_size_ = 0; } diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h index f21828571e5..6dae87a3842 100644 --- a/runtime/bin/isolate_data.h +++ b/runtime/bin/isolate_data.h @@ -74,6 +74,18 @@ class IsolateGroupData { kernel_buffer_size_ = size; } + const char* resolved_packages_config() const { + return resolved_packages_config_; + } + + void set_resolved_packages_config(const char* packages_config) { + if (resolved_packages_config_ != NULL) { + free(resolved_packages_config_); + resolved_packages_config_ = NULL; + } + resolved_packages_config_ = strdup(packages_config); + } + bool RunFromAppSnapshot() const { // If the main isolate is using an app snapshot the [app_snapshot_] pointer // will be still nullptr (see main.cc:CreateIsolateGroupAndSetupHelper) @@ -87,6 +99,7 @@ class IsolateGroupData { friend class IsolateData; // For packages_file_ std::unique_ptr app_snapshot_; + char* resolved_packages_config_; std::shared_ptr kernel_buffer_; intptr_t kernel_buffer_size_; char* packages_file_ = nullptr; diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc index 5c8c302ee9f..6868012ca87 100644 --- a/runtime/bin/loader.cc +++ b/runtime/bin/loader.cc @@ -23,22 +23,27 @@ namespace bin { extern DFE dfe; #endif -// Initialize package resolution state. -// Returns the resolved script URI after it resolves 'script_uri' in the -// current working directory iff the given uri did not specify a scheme -// (e.g. a path to a script file on the command line). -Dart_Handle Loader::Init(const char* script_uri, IsolateData* isolate_data) { +Dart_Handle Loader::InitForSnapshot(const char* snapshot_uri, + IsolateData* isolate_data) { ASSERT(isolate_data != NULL); - const char* packages_file = isolate_data->packages_file(); + + return Loader::Init(isolate_data->packages_file(), + DartUtils::original_working_directory, snapshot_uri); +} + +// Initialize package resolution state. +Dart_Handle Loader::Init(const char* packages_file, + const char* working_directory, + const char* root_script_uri) { const int kNumArgs = 3; Dart_Handle dart_args[kNumArgs]; dart_args[0] = (packages_file == NULL) ? Dart_Null() : Dart_NewStringFromCString(packages_file); - dart_args[1] = - Dart_NewStringFromCString(DartUtils::original_working_directory); - dart_args[2] = (script_uri == NULL) ? Dart_Null() - : Dart_NewStringFromCString(script_uri); + dart_args[1] = Dart_NewStringFromCString(working_directory); + dart_args[2] = (root_script_uri == NULL) + ? Dart_Null() + : Dart_NewStringFromCString(root_script_uri); return Dart_Invoke(DartUtils::LookupBuiltinLib(), DartUtils::NewString("_Init"), kNumArgs, dart_args); } diff --git a/runtime/bin/loader.h b/runtime/bin/loader.h index a3460253a3a..f4715e91dac 100644 --- a/runtime/bin/loader.h +++ b/runtime/bin/loader.h @@ -17,7 +17,8 @@ namespace bin { class Loader { public: - static Dart_Handle Init(const char* script_uri, IsolateData* isolate_data); + static Dart_Handle InitForSnapshot(const char* snapshot_uri, + IsolateData* isolate_data); static Dart_Handle ReloadNativeExtensions(); @@ -29,6 +30,10 @@ class Loader { static void InitOnce(); private: + static Dart_Handle Init(const char* packages_file, + const char* working_directory, + const char* root_script_uri); + static Dart_Handle LoadImportExtension(const char* url_string, Dart_Handle library); diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc index 4d76a734c5c..e99d675fe98 100644 --- a/runtime/bin/main.cc +++ b/runtime/bin/main.cc @@ -174,8 +174,10 @@ static void OnExitHook(int64_t exit_code) { static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate, IsolateData* isolate_data, - bool is_isolate_group_start) { + bool is_isolate_group_start, + const char** resolved_packages_config) { auto isolate_group_data = isolate_data->isolate_group_data(); + const auto packages_file = isolate_data->packages_file(); const auto script_uri = isolate_group_data->script_url; Dart_Handle result; @@ -186,6 +188,24 @@ static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate, result = DartUtils::PrepareForScriptLoading(false, Options::trace_loading()); if (Dart_IsError(result)) return result; + // 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( + *resolved_packages_config); + } else { + ASSERT(strcmp(isolate_group_data->resolved_packages_config(), + *resolved_packages_config) == 0); + } +#endif + } + result = Dart_SetEnvironmentCallback(DartUtils::EnvironmentCallback); if (Dart_IsError(result)) return result; @@ -215,17 +235,35 @@ static bool OnIsolateInitialize(void** child_callback_data, char** error) { *child_callback_data = isolate_data; Dart_EnterScope(); - Dart_Handle resolved_script_uri; const auto script_uri = isolate_group_data->script_url; const bool isolate_run_app_snapshot = isolate_group_data->RunFromAppSnapshot(); Dart_Handle result = SetupCoreLibraries(isolate, isolate_data, - /*group_start=*/false); + /*group_start=*/false, + /*resolved_packages_config=*/nullptr); if (Dart_IsError(result)) goto failed; - // Resolve script URI and Initialize package resolution state. - resolved_script_uri = Loader::Init(script_uri, isolate_data); - if (Dart_IsError(resolved_script_uri)) goto failed; + if (isolate_run_app_snapshot) { + if (Dart_IsVMFlagSet("support_service") || !Dart_IsPrecompiledRuntime()) { + result = Loader::InitForSnapshot(script_uri, isolate_data); + if (Dart_IsError(result)) goto failed; + } + } else { + result = DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri)); + if (Dart_IsError(result)) return result != nullptr; + + if (isolate_group_data->kernel_buffer().get() != nullptr) { + // Various core-library parts will send requests to the Loader to resolve + // relative URIs and perform other related tasks. We need Loader to be + // initialized for this to work because loading from Kernel binary + // bypasses normal source code loading paths that initialize it. + const char* resolved_script_uri = NULL; + result = Dart_StringToCString(result, &resolved_script_uri); + if (Dart_IsError(result)) goto failed; + result = Loader::InitForSnapshot(resolved_script_uri, isolate_data); + if (Dart_IsError(result)) goto failed; + } + } if (isolate_run_app_snapshot) { result = Loader::ReloadNativeExtensions(); @@ -262,8 +300,10 @@ static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate, auto isolate_data = reinterpret_cast(Dart_IsolateData(isolate)); + const char* resolved_packages_config = nullptr; result = SetupCoreLibraries(isolate, isolate_data, - /*is_isolate_group_start=*/true); + /*is_isolate_group_start=*/true, + &resolved_packages_config); CHECK_RESULT(result); #if !defined(DART_PRECOMPILED_RUNTIME) @@ -287,7 +327,7 @@ static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate, intptr_t application_kernel_buffer_size = 0; dfe.CompileAndReadScript(script_uri, &application_kernel_buffer, &application_kernel_buffer_size, error, exit_code, - packages_config); + resolved_packages_config); if (application_kernel_buffer == NULL) { Dart_ExitScope(); Dart_ShutdownIsolate(); @@ -298,8 +338,11 @@ static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate, kernel_buffer = application_kernel_buffer; kernel_buffer_size = application_kernel_buffer_size; } - // Load the specified application script into the newly created isolate. if (kernel_buffer != NULL) { + Dart_Handle uri = Dart_NewStringFromCString(script_uri); + CHECK_RESULT(uri); + Dart_Handle resolved_script_uri = DartUtils::ResolveScript(uri); + CHECK_RESULT(resolved_script_uri); result = Dart_LoadScriptFromKernel(kernel_buffer, kernel_buffer_size); CHECK_RESULT(result); } @@ -310,29 +353,47 @@ static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate, CHECK_RESULT(result); } - // Resolve script URI and Initialize package resolution state. - Dart_Handle resolved_script_uri = Loader::Init(script_uri, isolate_data); - CHECK_RESULT(resolved_script_uri); -#if !defined(DART_PRECOMPILED_RUNTIME) if (isolate_run_app_snapshot) { + if (Dart_IsVMFlagSet("support_service") || !Dart_IsPrecompiledRuntime()) { + Dart_Handle result = Loader::InitForSnapshot(script_uri, isolate_data); + CHECK_RESULT(result); + } +#if !defined(DART_PRECOMPILED_RUNTIME) if (is_main_isolate) { // Find the canonical uri of the app snapshot. We'll use this to decide if // other isolates should use the app snapshot or the core snapshot. - const char* resolved_script = NULL; - result = Dart_StringToCString(resolved_script_uri, &resolved_script); + const char* resolved_script_uri = NULL; + result = Dart_StringToCString( + DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri)), + &resolved_script_uri); CHECK_RESULT(result); ASSERT(app_script_uri == NULL); - app_script_uri = strdup(resolved_script); + app_script_uri = strdup(resolved_script_uri); } - } - Dart_TimelineEvent("LoadScript", Dart_TimelineGetMicros(), - Dart_GetMainPortId(), Dart_Timeline_Event_Async_End, 0, - NULL, NULL); -#else - if (!isolate_run_app_snapshot) { - UNREACHABLE(); - } #endif // !defined(DART_PRECOMPILED_RUNTIME) + } else { +#if !defined(DART_PRECOMPILED_RUNTIME) + // Load the specified application script into the newly created isolate. + Dart_Handle uri = + DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri)); + CHECK_RESULT(uri); + if (kernel_buffer != NULL) { + // relative URIs and perform other related tasks. We need Loader to be + // initialized for this to work because loading from Kernel binary + // bypasses normal source code loading paths that initialize it. + const char* resolved_script_uri = NULL; + result = Dart_StringToCString(uri, &resolved_script_uri); + CHECK_RESULT(result); + result = Loader::InitForSnapshot(resolved_script_uri, isolate_data); + CHECK_RESULT(result); + } + Dart_TimelineEvent("LoadScript", Dart_TimelineGetMicros(), + Dart_GetMainPortId(), Dart_Timeline_Event_Async_End, 0, + NULL, NULL); +#else + UNREACHABLE(); +#endif // !defined(DART_PRECOMPILED_RUNTIME) + } if (Options::gen_snapshot_kind() == kAppJIT) { // If we sort, we must do it for all isolates, not just the main isolate, @@ -793,9 +854,8 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) { Options::package_root()); } - const char* packages_config = Options::packages_file(); Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper( - is_main_isolate, script_name, "main", packages_config, &flags, + is_main_isolate, script_name, "main", Options::packages_file(), &flags, NULL /* callback_data */, &error, &exit_code); if (isolate == NULL) { @@ -820,6 +880,8 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) { Dart_EnterScope(); + auto isolate_group_data = + reinterpret_cast(Dart_IsolateGroupData(isolate)); if (Options::gen_snapshot_kind() == kKernel) { if (vm_run_app_snapshot) { Syslog::PrintErr( @@ -829,7 +891,7 @@ bool RunMainIsolate(const char* script_name, CommandLineOptions* dart_options) { Platform::Exit(kErrorExitCode); } Snapshot::GenerateKernel(Options::snapshot_filename(), script_name, - packages_config); + isolate_group_data->resolved_packages_config()); } else { // Lookup the library of the root script. Dart_Handle root_lib = Dart_RootLibrary(); diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h index 1ee9ee75e06..a58095cf306 100644 --- a/runtime/include/dart_api.h +++ b/runtime/include/dart_api.h @@ -3334,17 +3334,6 @@ DART_EXPORT Dart_Port Dart_KernelPort(); * * \param platform_kernel_size The length of the platform_kernel buffer. * - * \param incremental_compile Specifies if incremental compilation is needed. - * - * \param package_config Uri of the package configuration file (either in format - * of .packages or .dart_tool/package_config.json) for the null safety - * detection to resolve package imports against. If this parameter is not - * passed the package resolution of the parent isolate should be used. - * - * \param original_working_directory current working directory when the VM - * process was launched, this is used to correctly resolve the path specified - * for package_config. - * * \return Returns the result of the compilation. * * On a successful compilation the returned [Dart_KernelCompilationResult] has @@ -3362,8 +3351,7 @@ Dart_CompileToKernel(const char* script_uri, const uint8_t* platform_kernel, const intptr_t platform_kernel_size, bool incremental_compile, - const char* package_config, - const char* original_working_directory); + const char* package_config); typedef struct { const char* uri; diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 79e2e29236b..78930305403 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -5980,8 +5980,7 @@ Dart_CompileToKernel(const char* script_uri, const uint8_t* platform_kernel, intptr_t platform_kernel_size, bool incremental_compile, - const char* package_config, - const char* original_working_directory) { + const char* package_config) { API_TIMELINE_DURATION(Thread::Current()); Dart_KernelCompilationResult result = {}; @@ -5989,9 +5988,9 @@ Dart_CompileToKernel(const char* script_uri, result.status = Dart_KernelCompilationStatus_Unknown; result.error = strdup("Dart_CompileToKernel is unsupported."); #else - result = KernelIsolate::CompileToKernel( - script_uri, platform_kernel, platform_kernel_size, 0, NULL, - incremental_compile, package_config, original_working_directory); + result = KernelIsolate::CompileToKernel(script_uri, platform_kernel, + platform_kernel_size, 0, NULL, + incremental_compile, package_config); if (result.status == Dart_KernelCompilationStatus_Ok) { Dart_KernelCompilationResult accept_result = KernelIsolate::AcceptCompilation(); diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc index 3fcf4374266..6c83404d48a 100644 --- a/runtime/vm/isolate_reload.cc +++ b/runtime/vm/isolate_reload.cc @@ -1107,7 +1107,7 @@ char* IsolateGroupReloadContext::CompileToKernel(bool force_reload, TransitionVMToNative transition(Thread::Current()); retval = KernelIsolate::CompileToKernel(root_lib_url, nullptr, 0, modified_scripts_count, - modified_scripts, true); + modified_scripts, true, nullptr); } if (retval.status != Dart_KernelCompilationStatus_Ok) { if (retval.kernel != nullptr) { diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc index 96dd335533f..947d4688d0d 100644 --- a/runtime/vm/kernel_isolate.cc +++ b/runtime/vm/kernel_isolate.cc @@ -1001,7 +1001,6 @@ Dart_KernelCompilationResult KernelIsolate::CompileToKernel( Dart_SourceFile source_files[], bool incremental_compile, const char* package_config, - const char* original_working_directory, const char* multiroot_filepaths, const char* multiroot_scheme) { // Start the kernel Isolate if it is not already running. @@ -1027,7 +1026,7 @@ Dart_KernelCompilationResult KernelIsolate::CompileToKernel( kCompileTag, kernel_port, script_uri, platform_kernel, platform_kernel_size, source_file_count, source_files, incremental_compile, package_config, multiroot_filepaths, - multiroot_scheme, experimental_flags_, original_working_directory); + multiroot_scheme, experimental_flags_, NULL); } bool KernelIsolate::DetectNullSafety(const char* script_uri, diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h index 132c18cf550..fbf31e237da 100644 --- a/runtime/vm/kernel_isolate.h +++ b/runtime/vm/kernel_isolate.h @@ -51,7 +51,6 @@ class KernelIsolate : public AllStatic { Dart_SourceFile source_files[] = NULL, bool incremental_compile = true, const char* package_config = NULL, - const char* original_working_directory = NULL, const char* multiroot_filepaths = NULL, const char* multiroot_scheme = NULL); diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc index fcff39904ec..bcc7d99bd96 100644 --- a/runtime/vm/unit_test.cc +++ b/runtime/vm/unit_test.cc @@ -326,8 +326,7 @@ char* TestCase::CompileTestScriptWithDFE(const char* url, Zone* zone = Thread::Current()->zone(); Dart_KernelCompilationResult result = KernelIsolate::CompileToKernel( url, platform_strong_dill, platform_strong_dill_size, sourcefiles_count, - sourcefiles, incrementally, nullptr, nullptr, multiroot_filepaths, - multiroot_scheme); + sourcefiles, incrementally, NULL, multiroot_filepaths, multiroot_scheme); if (result.status == Dart_KernelCompilationStatus_Ok) { if (KernelIsolate::AcceptCompilation().status != Dart_KernelCompilationStatus_Ok) { diff --git a/sdk/lib/_internal/vm/bin/builtin.dart b/sdk/lib/_internal/vm/bin/builtin.dart index af74bbe4a53..5abcbfb80aa 100644 --- a/sdk/lib/_internal/vm/bin/builtin.dart +++ b/sdk/lib/_internal/vm/bin/builtin.dart @@ -17,6 +17,10 @@ import 'dart:typed_data'; // command line. bool _traceLoading = false; +// Before handling an embedder entrypoint we finalize the setup of the +// dart:_builtin library. +bool _setupCompleted = false; + // 'print' implementation. // The standalone embedder registers the closurized _print function with the // dart:core library. @@ -89,6 +93,17 @@ _sanitizeWindowsPath(path) { return fixedPath; } +_setPackagesConfig(String packagesParam) { + var packagesName = _sanitizeWindowsPath(packagesParam); + var packagesUri = Uri.parse(packagesName); + if (packagesUri.scheme == '') { + // Script does not have a scheme, assume that it is a path, + // resolve it against the working directory. + packagesUri = _workingDirectory.resolveUri(packagesUri); + } + _packagesConfigUri = packagesUri; +} + // Given a uri with a 'package' scheme, return a Uri that is prefixed with // the package root or resolved relative to the package configuration. Uri _resolvePackageUri(Uri uri) { @@ -470,53 +485,60 @@ _handlePackagesRequest(bool traceLoading, int tag, Uri resource) { // Embedder Entrypoint: // The embedder calls this method to initial the package resolution state. -// Returns the resolved script URI after it resolves the script uri in the -// current working directory iff the given uri did not specify a scheme -// (e.g. a path to a script file on the command line). @pragma("vm:entry-point") -String _Init( - String packagesConfig, String workingDirectory, String rootScript) { - if (_traceLoading) { - _log("_Init: $packagesConfig $workingDirectory $rootScript"); - } - +void _Init(String packagesConfig, String workingDirectory, String rootScript) { // Register callbacks and hooks with the rest of core libraries. _setupHooks(); // _workingDirectory must be set first. _workingDirectory = new Uri.directory(workingDirectory); - if (_traceLoading) { - _log('_Init (working directory): $_workingDirectory'); - } // setup _rootScript. if (rootScript != null) { - _rootScript = _resolveScriptUri(rootScript); - assert(rootScript != null); + _rootScript = Uri.parse(rootScript); } // If the --packages flag was passed, setup _packagesConfig. if (packagesConfig != null) { _packageMap = null; - VMLibraryHooks.packageConfigString = _setPackagesConfig(packagesConfig); + _setPackagesConfig(packagesConfig); } - - if (_traceLoading) { - _log("_Init returns: ${rootScript.toString()}"); - } - return _rootScript.toString(); } -// packagesParam is the value of the --packages command line option. -// It can point to a ".packages" or a ".dart_tool/package_config.json" +// Embedder Entrypoint: +// The embedder calls this method with the current working directory. +@pragma("vm:entry-point") +void _setWorkingDirectory(String cwd) { + if (!_setupCompleted) { + _setupHooks(); + } + if (_traceLoading) { + _log('Setting working directory: $cwd'); + } + _workingDirectory = new Uri.directory(cwd); + if (_traceLoading) { + _log('Working directory URI: $_workingDirectory'); + } +} + +// Embedder Entrypoint: +// The embedder calls this method with the value of the --packages command line +// option. It can point to a ".packages" or a ".dart_tool/package_config.json" // file. -String _setPackagesConfig(String packagesParam) { +@pragma("vm:entry-point") +String _setPackagesMap(String packagesParam) { + if (!_setupCompleted) { + _setupHooks(); + } // First convert the packages parameter from the command line to a URI which // can be handled by the loader code. // TODO(iposva): Consider refactoring the common code below which is almost // shared with resolution of the root script. if (_traceLoading) { - _log("Resolving packages config: $packagesParam"); + _log("Resolving packages map: $packagesParam"); + } + if (_workingDirectory == null) { + throw 'No current working directory set.'; } var packagesName = _sanitizeWindowsPath(packagesParam); var packagesUri = Uri.parse(packagesName); @@ -525,19 +547,24 @@ String _setPackagesConfig(String packagesParam) { // resolve it against the working directory. packagesUri = _workingDirectory.resolveUri(packagesUri); } - _packagesConfigUri = packagesUri; + var packagesUriStr = packagesUri.toString(); + VMLibraryHooks.packageConfigString = packagesUriStr; if (_traceLoading) { - _log('Resolved packages config to: $packagesUri'); + _log('Resolved packages map to: $packagesUri'); } - return packagesUri.toString(); + return packagesUriStr; } // Resolves the script uri in the current working directory iff the given uri // did not specify a scheme (e.g. a path to a script file on the command line). -Uri _resolveScriptUri(String scriptName) { +@pragma("vm:entry-point") +String _resolveScriptUri(String scriptName) { if (_traceLoading) { _log("Resolving script: $scriptName"); } + if (_workingDirectory == null) { + throw 'No current working directory set.'; + } scriptName = _sanitizeWindowsPath(scriptName); var scriptUri = Uri.parse(scriptName); @@ -547,15 +574,20 @@ Uri _resolveScriptUri(String scriptName) { scriptUri = _workingDirectory.resolveUri(scriptUri); } + // Remember the root script URI so that we can resolve packages based on + // this location. + _rootScript = scriptUri; + if (_traceLoading) { - _log('Resolved entry point to: ${scriptUri.toString()}'); + _log('Resolved entry point to: $_rootScript'); } - return scriptUri; + return scriptUri.toString(); } // Register callbacks and hooks with the rest of the core libraries. @pragma("vm:entry-point") _setupHooks() { + _setupCompleted = true; VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture; VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture; }