diff --git a/pkg/front_end/lib/src/fasta/import.dart b/pkg/front_end/lib/src/fasta/import.dart index 91165d315c2..b484601d884 100644 --- a/pkg/front_end/lib/src/fasta/import.dart +++ b/pkg/front_end/lib/src/fasta/import.dart @@ -39,7 +39,7 @@ class Import { // The LibraryBuilder for the imported library ('imported') may be null when // this field is set. - final Uri nativeImportUri; + final String nativeImportPath; Import( this.importer, @@ -51,14 +51,14 @@ class Import { this.charOffset, this.prefixCharOffset, int importIndex, - {this.nativeImportUri}) + {this.nativeImportPath}) : prefixBuilder = createPrefixBuilder(prefix, importer, imported, combinators, deferred, charOffset, prefixCharOffset, importIndex); Uri get fileUri => importer.fileUri; void finalizeImports(LibraryBuilder importer) { - if (nativeImportUri != null) return; + if (nativeImportPath != null) return; void Function(String, Declaration) add; if (prefixBuilder == null) { add = (String name, Declaration member) { diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart index adcad5ba579..b52d03d1cf0 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart @@ -828,10 +828,10 @@ class KernelLibraryBuilder } } - void addNativeDependency(Uri nativeImportUri) { + void addNativeDependency(String nativeImportPath) { Declaration constructor = loader.getNativeAnnotation(); Arguments arguments = - new Arguments([new StringLiteral("$nativeImportUri")]); + new Arguments([new StringLiteral(nativeImportPath)]); Expression annotation; if (constructor.isConstructor) { annotation = new ConstructorInvocation(constructor.target, arguments) @@ -862,8 +862,8 @@ class KernelLibraryBuilder Import import = imports[importIndex++]; // Rather than add a LibraryDependency, we attach an annotation. - if (import.nativeImportUri != null) { - addNativeDependency(import.nativeImportUri); + if (import.nativeImportPath != null) { + addNativeDependency(import.nativeImportPath); continue; } diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart index 1529ed0ed10..9f15391b480 100644 --- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart @@ -290,27 +290,30 @@ abstract class SourceLibraryBuilder } } - const String nativeExtensionScheme = "dart-ext:"; - bool isExternal = uri.startsWith(nativeExtensionScheme); - if (isExternal) { - uri = uri.substring(nativeExtensionScheme.length); - uriOffset += nativeExtensionScheme.length; - } - - Uri resolvedUri = resolve(this.uri, uri, uriOffset); - LibraryBuilder builder = null; - if (isExternal) { - if (resolvedUri.scheme == "package") { + + Uri resolvedUri; + String nativePath; + const String nativeExtensionScheme = "dart-ext:"; + if (uri.startsWith(nativeExtensionScheme)) { + String strippedUri = uri.substring(nativeExtensionScheme.length); + if (strippedUri.startsWith("package")) { + resolvedUri = resolve( + this.uri, strippedUri, uriOffset + nativeExtensionScheme.length); resolvedUri = loader.target.translateUri(resolvedUri); + nativePath = resolvedUri.toString(); + } else { + resolvedUri = new Uri(scheme: "dart-ext", pathSegments: [uri]); + nativePath = uri; } } else { + resolvedUri = resolve(this.uri, uri, uriOffset); builder = loader.read(resolvedUri, charOffset, accessor: this); } imports.add(new Import(this, builder, deferred, prefix, combinators, configurations, charOffset, prefixCharOffset, importIndex, - nativeImportUri: builder == null ? resolvedUri : null)); + nativeImportPath: nativePath)); } void addPart(List metadata, String uri, int charOffset) { diff --git a/pkg/front_end/testcases/external_import.dart.direct.expect b/pkg/front_end/testcases/external_import.dart.direct.expect index b262abf3ff9..27762240a7c 100644 --- a/pkg/front_end/testcases/external_import.dart.direct.expect +++ b/pkg/front_end/testcases/external_import.dart.direct.expect @@ -1,6 +1,6 @@ -@dart._internal::ExternalName::•("org-dartlang-testcase:///here") -@dart._internal::ExternalName::•("org-dartlang-testcase:///there") -@dart._internal::ExternalName::•("file:///usr/local/somewhere") +@dart._internal::ExternalName::•("dart-ext:here") +@dart._internal::ExternalName::•("dart-ext:foo/../there") +@dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere") library; import self as self; import "dart:_internal" as _in; diff --git a/pkg/front_end/testcases/external_import.dart.direct.transformed.expect b/pkg/front_end/testcases/external_import.dart.direct.transformed.expect index b262abf3ff9..27762240a7c 100644 --- a/pkg/front_end/testcases/external_import.dart.direct.transformed.expect +++ b/pkg/front_end/testcases/external_import.dart.direct.transformed.expect @@ -1,6 +1,6 @@ -@dart._internal::ExternalName::•("org-dartlang-testcase:///here") -@dart._internal::ExternalName::•("org-dartlang-testcase:///there") -@dart._internal::ExternalName::•("file:///usr/local/somewhere") +@dart._internal::ExternalName::•("dart-ext:here") +@dart._internal::ExternalName::•("dart-ext:foo/../there") +@dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere") library; import self as self; import "dart:_internal" as _in; diff --git a/pkg/front_end/testcases/external_import.dart.outline.expect b/pkg/front_end/testcases/external_import.dart.outline.expect index b4467206e9a..b0af5d4b3ed 100644 --- a/pkg/front_end/testcases/external_import.dart.outline.expect +++ b/pkg/front_end/testcases/external_import.dart.outline.expect @@ -1,6 +1,6 @@ -@dart._internal::ExternalName::•("org-dartlang-testcase:///here") -@dart._internal::ExternalName::•("org-dartlang-testcase:///there") -@dart._internal::ExternalName::•("file:///usr/local/somewhere") +@dart._internal::ExternalName::•("dart-ext:here") +@dart._internal::ExternalName::•("dart-ext:foo/../there") +@dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere") library; import self as self; import "dart:_internal" as _in; diff --git a/pkg/front_end/testcases/external_import.dart.strong.expect b/pkg/front_end/testcases/external_import.dart.strong.expect index b262abf3ff9..27762240a7c 100644 --- a/pkg/front_end/testcases/external_import.dart.strong.expect +++ b/pkg/front_end/testcases/external_import.dart.strong.expect @@ -1,6 +1,6 @@ -@dart._internal::ExternalName::•("org-dartlang-testcase:///here") -@dart._internal::ExternalName::•("org-dartlang-testcase:///there") -@dart._internal::ExternalName::•("file:///usr/local/somewhere") +@dart._internal::ExternalName::•("dart-ext:here") +@dart._internal::ExternalName::•("dart-ext:foo/../there") +@dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere") library; import self as self; import "dart:_internal" as _in; diff --git a/pkg/front_end/testcases/external_import.dart.strong.transformed.expect b/pkg/front_end/testcases/external_import.dart.strong.transformed.expect index b262abf3ff9..27762240a7c 100644 --- a/pkg/front_end/testcases/external_import.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/external_import.dart.strong.transformed.expect @@ -1,6 +1,6 @@ -@dart._internal::ExternalName::•("org-dartlang-testcase:///here") -@dart._internal::ExternalName::•("org-dartlang-testcase:///there") -@dart._internal::ExternalName::•("file:///usr/local/somewhere") +@dart._internal::ExternalName::•("dart-ext:here") +@dart._internal::ExternalName::•("dart-ext:foo/../there") +@dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere") library; import self as self; import "dart:_internal" as _in; diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc index 0096fa6108e..4e4bf651972 100644 --- a/runtime/bin/loader.cc +++ b/runtime/bin/loader.cc @@ -674,18 +674,32 @@ Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag, MallocFinalizer); return result; } - if (tag == Dart_kImportResolvedExtensionTag) { - if (strncmp(url_string, "file://", 7)) { + if (tag == Dart_kImportExtensionTag) { + if (strncmp(url_string, "dart-ext:", 9)) { return DartUtils::NewError( - "Resolved native extensions must use the file:// scheme."); + "Native extensions must use the dart-ext: scheme."); } - const char* absolute_path = DartUtils::RemoveScheme(url_string); + const char* path = DartUtils::RemoveScheme(url_string); - if (!File::IsAbsolutePath(absolute_path)) { - return DartUtils::NewError("Native extension path must be absolute."); + const char* lib_uri = NULL; + result = Dart_StringToCString(Dart_LibraryUrl(library), &lib_uri); + RETURN_ERROR(result); + + char* lib_path = NULL; + if (strncmp(lib_uri, "file://", 7) == 0) { + lib_path = DartUtils::DirName(DartUtils::RemoveScheme(lib_uri)); + } else { + lib_path = strdup(lib_uri); } - return Extensions::LoadExtension("/", absolute_path, library); + if (!File::IsAbsolutePath(path) && PathContainsSeparator(path)) { + return DartUtils::NewError( + "Native extension path must be absolute, or simply the file name: " + "%s: ", + path); + } + + return Extensions::LoadExtension(lib_path, path, library); } if (tag != Dart_kScriptTag) { // Special case for handling dart: imports and parts. diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h index abde8b1a09b..195439492ba 100644 --- a/runtime/include/dart_api.h +++ b/runtime/include/dart_api.h @@ -2846,7 +2846,7 @@ typedef enum { Dart_kSourceTag, Dart_kImportTag, Dart_kKernelTag, - Dart_kImportResolvedExtensionTag, + Dart_kImportExtensionTag, } Dart_LibraryTag; /** @@ -2896,12 +2896,10 @@ typedef enum { * files into one intermediate file hence we don't use the source/import or * script tags. * - * Dart_kImportResolvedExtensionTag + * Dart_kImportExtensionTag * - * This tag is used to load an external import (shared object file) without - * performing path resolution first. The 'url' provided should be an absolute - * path with the 'file://' schema. It doesn't require the service isolate to be - * available and will not initialize a Loader for the isolate. + * This tag is used to load an external import (shared object file). The + * extension path must have the scheme 'dart-ext:'. */ typedef Dart_Handle (*Dart_LibraryTagHandler)( Dart_LibraryTag tag, diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index df6ceafce78..61947f586cb 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc @@ -547,7 +547,7 @@ void KernelLoader::LoadNativeExtensionLibraries( { TransitionVMToNative transition(thread_); Api::Scope api_scope(thread_); - Dart_Handle retval = handler(Dart_kImportResolvedExtensionTag, + Dart_Handle retval = handler(Dart_kImportExtensionTag, Api::NewHandle(thread_, library.raw()), Api::NewHandle(thread_, uri_path.raw())); result = Api::UnwrapHandle(retval); diff --git a/tests/standalone_2/io/test_extension_fail_test.dart b/tests/standalone_2/io/test_extension_fail_test.dart index 262d1db3825..dae44118645 100644 --- a/tests/standalone_2/io/test_extension_fail_test.dart +++ b/tests/standalone_2/io/test_extension_fail_test.dart @@ -36,7 +36,7 @@ String getExtensionPath(String buildDirectory) { } bool checkExitCode(int code) { - return ((code == 255) || (code == 253)); + return ((code == 255) || (code == 254) || (code == 253)); } bool checkStdError(String err) {