[kernel/vm] Fix native extensions.

Tested with imports through current directory, VM binary directory,
and LD_LIBRARY_PATH. This also restores the Dart 1 behavior of not supporting
relative extension paths.

Change-Id: I090bf8592fef74d4ccde40e6f550baa84c98e3bc
Reviewed-on: https://dart-review.googlesource.com/69162
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Samir Jindel <sjindel@google.com>
This commit is contained in:
Samir Jindel 2018-08-10 11:06:56 +00:00 committed by commit-bot@chromium.org
parent f99b9b80ff
commit 5c7d257978
12 changed files with 64 additions and 49 deletions

View file

@ -39,7 +39,7 @@ class Import {
// The LibraryBuilder for the imported library ('imported') may be null when // The LibraryBuilder for the imported library ('imported') may be null when
// this field is set. // this field is set.
final Uri nativeImportUri; final String nativeImportPath;
Import( Import(
this.importer, this.importer,
@ -51,14 +51,14 @@ class Import {
this.charOffset, this.charOffset,
this.prefixCharOffset, this.prefixCharOffset,
int importIndex, int importIndex,
{this.nativeImportUri}) {this.nativeImportPath})
: prefixBuilder = createPrefixBuilder(prefix, importer, imported, : prefixBuilder = createPrefixBuilder(prefix, importer, imported,
combinators, deferred, charOffset, prefixCharOffset, importIndex); combinators, deferred, charOffset, prefixCharOffset, importIndex);
Uri get fileUri => importer.fileUri; Uri get fileUri => importer.fileUri;
void finalizeImports(LibraryBuilder importer) { void finalizeImports(LibraryBuilder importer) {
if (nativeImportUri != null) return; if (nativeImportPath != null) return;
void Function(String, Declaration) add; void Function(String, Declaration) add;
if (prefixBuilder == null) { if (prefixBuilder == null) {
add = (String name, Declaration member) { add = (String name, Declaration member) {

View file

@ -828,10 +828,10 @@ class KernelLibraryBuilder
} }
} }
void addNativeDependency(Uri nativeImportUri) { void addNativeDependency(String nativeImportPath) {
Declaration constructor = loader.getNativeAnnotation(); Declaration constructor = loader.getNativeAnnotation();
Arguments arguments = Arguments arguments =
new Arguments(<Expression>[new StringLiteral("$nativeImportUri")]); new Arguments(<Expression>[new StringLiteral(nativeImportPath)]);
Expression annotation; Expression annotation;
if (constructor.isConstructor) { if (constructor.isConstructor) {
annotation = new ConstructorInvocation(constructor.target, arguments) annotation = new ConstructorInvocation(constructor.target, arguments)
@ -862,8 +862,8 @@ class KernelLibraryBuilder
Import import = imports[importIndex++]; Import import = imports[importIndex++];
// Rather than add a LibraryDependency, we attach an annotation. // Rather than add a LibraryDependency, we attach an annotation.
if (import.nativeImportUri != null) { if (import.nativeImportPath != null) {
addNativeDependency(import.nativeImportUri); addNativeDependency(import.nativeImportPath);
continue; continue;
} }

View file

@ -290,27 +290,30 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
} }
} }
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; 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); resolvedUri = loader.target.translateUri(resolvedUri);
nativePath = resolvedUri.toString();
} else {
resolvedUri = new Uri(scheme: "dart-ext", pathSegments: [uri]);
nativePath = uri;
} }
} else { } else {
resolvedUri = resolve(this.uri, uri, uriOffset);
builder = loader.read(resolvedUri, charOffset, accessor: this); builder = loader.read(resolvedUri, charOffset, accessor: this);
} }
imports.add(new Import(this, builder, deferred, prefix, combinators, imports.add(new Import(this, builder, deferred, prefix, combinators,
configurations, charOffset, prefixCharOffset, importIndex, configurations, charOffset, prefixCharOffset, importIndex,
nativeImportUri: builder == null ? resolvedUri : null)); nativeImportPath: nativePath));
} }
void addPart(List<MetadataBuilder> metadata, String uri, int charOffset) { void addPart(List<MetadataBuilder> metadata, String uri, int charOffset) {

View file

@ -1,6 +1,6 @@
@dart._internal::ExternalName::•("org-dartlang-testcase:///here") @dart._internal::ExternalName::•("dart-ext:here")
@dart._internal::ExternalName::•("org-dartlang-testcase:///there") @dart._internal::ExternalName::•("dart-ext:foo/../there")
@dart._internal::ExternalName::•("file:///usr/local/somewhere") @dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere")
library; library;
import self as self; import self as self;
import "dart:_internal" as _in; import "dart:_internal" as _in;

View file

@ -1,6 +1,6 @@
@dart._internal::ExternalName::•("org-dartlang-testcase:///here") @dart._internal::ExternalName::•("dart-ext:here")
@dart._internal::ExternalName::•("org-dartlang-testcase:///there") @dart._internal::ExternalName::•("dart-ext:foo/../there")
@dart._internal::ExternalName::•("file:///usr/local/somewhere") @dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere")
library; library;
import self as self; import self as self;
import "dart:_internal" as _in; import "dart:_internal" as _in;

View file

@ -1,6 +1,6 @@
@dart._internal::ExternalName::•("org-dartlang-testcase:///here") @dart._internal::ExternalName::•("dart-ext:here")
@dart._internal::ExternalName::•("org-dartlang-testcase:///there") @dart._internal::ExternalName::•("dart-ext:foo/../there")
@dart._internal::ExternalName::•("file:///usr/local/somewhere") @dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere")
library; library;
import self as self; import self as self;
import "dart:_internal" as _in; import "dart:_internal" as _in;

View file

@ -1,6 +1,6 @@
@dart._internal::ExternalName::•("org-dartlang-testcase:///here") @dart._internal::ExternalName::•("dart-ext:here")
@dart._internal::ExternalName::•("org-dartlang-testcase:///there") @dart._internal::ExternalName::•("dart-ext:foo/../there")
@dart._internal::ExternalName::•("file:///usr/local/somewhere") @dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere")
library; library;
import self as self; import self as self;
import "dart:_internal" as _in; import "dart:_internal" as _in;

View file

@ -1,6 +1,6 @@
@dart._internal::ExternalName::•("org-dartlang-testcase:///here") @dart._internal::ExternalName::•("dart-ext:here")
@dart._internal::ExternalName::•("org-dartlang-testcase:///there") @dart._internal::ExternalName::•("dart-ext:foo/../there")
@dart._internal::ExternalName::•("file:///usr/local/somewhere") @dart._internal::ExternalName::•("dart-ext:/usr/local/somewhere")
library; library;
import self as self; import self as self;
import "dart:_internal" as _in; import "dart:_internal" as _in;

View file

@ -674,18 +674,32 @@ Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
MallocFinalizer); MallocFinalizer);
return result; return result;
} }
if (tag == Dart_kImportResolvedExtensionTag) { if (tag == Dart_kImportExtensionTag) {
if (strncmp(url_string, "file://", 7)) { if (strncmp(url_string, "dart-ext:", 9)) {
return DartUtils::NewError( 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)) { const char* lib_uri = NULL;
return DartUtils::NewError("Native extension path must be absolute."); 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) { if (tag != Dart_kScriptTag) {
// Special case for handling dart: imports and parts. // Special case for handling dart: imports and parts.

View file

@ -2846,7 +2846,7 @@ typedef enum {
Dart_kSourceTag, Dart_kSourceTag,
Dart_kImportTag, Dart_kImportTag,
Dart_kKernelTag, Dart_kKernelTag,
Dart_kImportResolvedExtensionTag, Dart_kImportExtensionTag,
} Dart_LibraryTag; } Dart_LibraryTag;
/** /**
@ -2896,12 +2896,10 @@ typedef enum {
* files into one intermediate file hence we don't use the source/import or * files into one intermediate file hence we don't use the source/import or
* script tags. * script tags.
* *
* Dart_kImportResolvedExtensionTag * Dart_kImportExtensionTag
* *
* This tag is used to load an external import (shared object file) without * This tag is used to load an external import (shared object file). The
* performing path resolution first. The 'url' provided should be an absolute * extension path must have the scheme 'dart-ext:'.
* path with the 'file://' schema. It doesn't require the service isolate to be
* available and will not initialize a Loader for the isolate.
*/ */
typedef Dart_Handle (*Dart_LibraryTagHandler)( typedef Dart_Handle (*Dart_LibraryTagHandler)(
Dart_LibraryTag tag, Dart_LibraryTag tag,

View file

@ -547,7 +547,7 @@ void KernelLoader::LoadNativeExtensionLibraries(
{ {
TransitionVMToNative transition(thread_); TransitionVMToNative transition(thread_);
Api::Scope api_scope(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_, library.raw()),
Api::NewHandle(thread_, uri_path.raw())); Api::NewHandle(thread_, uri_path.raw()));
result = Api::UnwrapHandle(retval); result = Api::UnwrapHandle(retval);

View file

@ -36,7 +36,7 @@ String getExtensionPath(String buildDirectory) {
} }
bool checkExitCode(int code) { bool checkExitCode(int code) {
return ((code == 255) || (code == 253)); return ((code == 255) || (code == 254) || (code == 253));
} }
bool checkStdError(String err) { bool checkStdError(String err) {