Version 1.11.0-dev.5.3
Cherry-pick 19bb19d to dev
Cherry-pick d5a34bd to dev
Cherry-pick bbdc57e to dev
Cherry-pick bd25e64 to dev
Cherry-pick 5cc8fca to dev
Cherry-pick ed72caa to dev
Cherry-pick 82535a6 to dev
Cherry-pick c05c8c6 to dev
Cherry-pick f9e8852 to dev
Cherry-pick 9a01a22 to dev
Cherry-pick 3c85970 to dev
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index cbe0c83..8bbd2cd 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -40,6 +40,7 @@
V(Platform_PathSeparator, 0) \
V(Platform_LocalHostname, 0) \
V(Platform_ExecutableName, 0) \
+ V(Platform_ResolvedExecutableName, 0) \
V(Platform_Environment, 0) \
V(Platform_ExecutableArguments, 0) \
V(Platform_PackageRoot, 0) \
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 2f55f9d..0ed2bd3 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -13,7 +13,7 @@
namespace bin {
const char* Platform::executable_name_ = NULL;
-bool Platform::executable_name_resolved_ = false;
+const char* Platform::resolved_executable_name_ = NULL;
const char* Platform::package_root_ = NULL;
int Platform::script_index_ = 1;
char** Platform::argv_ = NULL;
@@ -51,6 +51,16 @@
}
+void FUNCTION_NAME(Platform_ResolvedExecutableName)(Dart_NativeArguments args) {
+ if (Platform::GetResolvedExecutableName() != NULL) {
+ Dart_SetReturnValue(
+ args, Dart_NewStringFromCString(Platform::GetResolvedExecutableName()));
+ } else {
+ Dart_SetReturnValue(args, Dart_Null());
+ }
+}
+
+
void FUNCTION_NAME(Platform_ExecutableArguments)(Dart_NativeArguments args) {
int end = Platform::GetScriptIndex();
char** argv = Platform::GetArgv();
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 6b81539..3d3c0f3 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -46,16 +46,15 @@
executable_name_ = executable_name;
}
static const char* GetExecutableName() {
- if (!executable_name_resolved_) {
- // Try to resolve the executable path using platform specific APIs.
- char* path = Platform::ResolveExecutablePath();
- if (path != NULL) {
- executable_name_ = path;
- }
- executable_name_resolved_ = true;
- }
return executable_name_;
}
+ static const char* GetResolvedExecutableName() {
+ if (resolved_executable_name_ == NULL) {
+ // Try to resolve the executable path using platform specific APIs.
+ resolved_executable_name_ = Platform::ResolveExecutablePath();
+ }
+ return resolved_executable_name_;
+ }
// Stores and gets the package root.
static void SetPackageRoot(const char* package_root) {
@@ -80,8 +79,8 @@
private:
// The path to the executable.
static const char* executable_name_;
- // State to indicate whether the executable name has been resolved.
- static bool executable_name_resolved_;
+ // The path to the resolved executable.
+ static const char* resolved_executable_name_;
static const char* package_root_;
static int script_index_;
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 702bf01..351a829 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -7,6 +7,7 @@
#include <mach-o/dyld.h>
+#include "bin/file.h"
#include "bin/platform.h"
#include <crt_externs.h> // NOLINT
@@ -91,7 +92,10 @@
free(path);
return NULL;
}
- return path;
+ // Return the canonical path as the returned path might contain symlinks.
+ char* canon_path = File::GetCanonicalPath(path);
+ free(path);
+ return canon_path;
}
} // namespace bin
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index fe1e90c..c917b54 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -10,6 +10,8 @@
native "Platform_OperatingSystem";
/* patch */ static _localHostname() native "Platform_LocalHostname";
/* patch */ static _executable() native "Platform_ExecutableName";
+ /* patch */ static _resolvedExecutable()
+ native "Platform_ResolvedExecutableName";
/* patch */ static _environment() native "Platform_Environment";
/* patch */ static List<String> _executableArguments()
native "Platform_ExecutableArguments";
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index afa924b..d109c82 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -5,6 +5,7 @@
#include "platform/globals.h"
#if defined(TARGET_OS_WINDOWS)
+#include "bin/file.h"
#include "bin/platform.h"
#include "bin/log.h"
#include "bin/socket.h"
@@ -97,7 +98,10 @@
}
char* path = StringUtils::WideToUtf8(tmp_buffer);
free(tmp_buffer);
- return path;
+ // Return the canonical path as the returned path might contain symlinks.
+ char* canon_path = File::GetCanonicalPath(path);
+ free(path);
+ return canon_path;
}
} // namespace bin
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index bc36704..15ef1ad 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -3182,10 +3182,20 @@
Dart_Handle object) {
TRACE_API_CALL(CURRENT_FUNC);
intptr_t class_id = Api::ClassId(object);
- if (RawObject::IsExternalTypedDataClassId(class_id) ||
- RawObject::IsTypedDataViewClassId(class_id)) {
+ if (RawObject::IsExternalTypedDataClassId(class_id)) {
return GetType(class_id);
}
+ if (RawObject::IsTypedDataViewClassId(class_id)) {
+ // Check if data object of the view is external.
+ Isolate* isolate = Isolate::Current();
+ const Instance& view_obj = Api::UnwrapInstanceHandle(isolate, object);
+ ASSERT(!view_obj.IsNull());
+ const Instance& data_obj =
+ Instance::Handle(isolate, TypedDataView::Data(view_obj));
+ if (ExternalTypedData::IsExternalTypedData(data_obj)) {
+ return GetType(class_id);
+ }
+ }
return Dart_TypedData_kInvalid;
}
diff --git a/sdk/lib/_internal/compiler/js_lib/io_patch.dart b/sdk/lib/_internal/compiler/js_lib/io_patch.dart
index 8fbc6a7..792b74d 100644
--- a/sdk/lib/_internal/compiler/js_lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/js_lib/io_patch.dart
@@ -221,6 +221,10 @@
throw new UnsupportedError("Platform._executable");
}
@patch
+ static _resolvedExecutable() {
+ throw new UnsupportedError("Platform._resolvedExecutable");
+ }
+ @patch
static List<String> _executableArguments() {
throw new UnsupportedError("Platform._executableArguments");
}
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 6b86095..9ad7b56 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -131,14 +131,25 @@
* Returns the path of the executable used to run the script in this
* isolate.
*
- * If supported by the platform the returned path will be absolute.
+ * The path returned is the literal path used to run the script. This
+ * path might be relative or just be a name from which the executable
+ * was found by searching the `PATH`.
*
- * If the execution environment does not support [executable] an empty
- * string is returned.
+ * To get the absolute path to the resolved executable use
+ * [resolvedExecutable].
*/
static String get executable => _Platform.executable;
/**
+ * Returns the path of the executable used to run the script in this
+ * isolate after it has been resolved by the OS.
+ *
+ * This is the absolute path, with all symlinks resolved, to the
+ * executable used to run the script.
+ */
+ static String get resolvedExecutable => _Platform.resolvedExecutable;
+
+ /**
* Returns the absolute URI of the script being run in this
* isolate.
*
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index 3883957..6380e0d 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -10,6 +10,7 @@
external static String _operatingSystem();
external static _localHostname();
external static _executable();
+ external static _resolvedExecutable();
/**
* Retrieve the entries of the process environment.
*
@@ -31,6 +32,7 @@
external static String _version();
static String executable = _executable();
+ static String resolvedExecutable = _resolvedExecutable();
static String packageRoot = _packageRoot();
// Cache the OS environemnt. This can be an OSError instance if
diff --git a/tests/standalone/io/platform_executable_test.dart b/tests/standalone/io/platform_resolved_executable_test.dart
similarity index 77%
rename from tests/standalone/io/platform_executable_test.dart
rename to tests/standalone/io/platform_resolved_executable_test.dart
index 1b6bce3..b5ae47c 100644
--- a/tests/standalone/io/platform_executable_test.dart
+++ b/tests/standalone/io/platform_resolved_executable_test.dart
@@ -35,7 +35,7 @@
}
var result = processResult.stdout.trim();
- expectEquals(Platform.executable, result);
+ expectEquals(Platform.resolvedExecutable, result);
}
void testDartExecShouldNotBeInCurrentDir() {
@@ -60,23 +60,20 @@
}
void testShouldSucceedWithSourcePlatformExecutable() {
- //print('*** Running normally');
- verify(Platform.executable);
+ verify(Platform.resolvedExecutable);
}
void testExeSymLinked(Directory dir) {
var dirUri = new Uri.directory(dir.path);
var link = new Link.fromUri(dirUri.resolve('dart_exe_link'));
- link.createSync(Platform.executable);
- //print('*** Creating a sym-link to the executable');
+ link.createSync(Platform.resolvedExecutable);
verify(link.path);
}
void testPathToDirWithExeSymLinked(Directory dir) {
var dirUri = new Uri.directory(dir.path);
var link = new Link.fromUri(dirUri.resolve('dart_exe_link'));
- link.createSync(Platform.executable);
- //print('*** Path to a directory that contains a sym-link to dart bin');
+ link.createSync(Platform.resolvedExecutable);
verify('dart_exe_link', altPath: dir.path);
}
@@ -87,14 +84,13 @@
var linkDirUri = dirUri.resolve('dart_bin_dir_link');
var link = new Link.fromUri(linkDirUri);
- var exeFile = new File(Platform.executable);
+ var exeFile = new File(Platform.resolvedExecutable);
link.createSync(exeFile.parent.path);
var linkedBin =
new Uri.directory(linkDirUri.toFilePath()).resolve(platformExeName);
- //print('*** Running in a sym-linked directory');
verify(linkedBin.toFilePath());
}
@@ -104,19 +100,17 @@
var linkDirUri = dirUri.resolve('dart_bin_dir_link');
var link = new Link.fromUri(linkDirUri);
- var exeFile = new File(Platform.executable);
+ var exeFile = new File(Platform.resolvedExecutable);
link.createSync(exeFile.parent.path);
- //print('*** Path points to a sym-linked SDK dir');
verify(platformExeName, altPath: link.path);
}
void testPathToSDKDir() {
- var exeFile = new File(Platform.executable);
+ var exeFile = new File(Platform.resolvedExecutable);
var binDirPath = exeFile.parent.path;
- //print('*** Running with PATH env set to environment - fixed in 16994 - thanks!');
verify(platformExeName, altPath: binDirPath);
}
@@ -130,24 +124,34 @@
}
String get platformExeName {
- var raw = new Uri.file(Platform.executable);
+ var raw = new Uri.file(Platform.resolvedExecutable);
return raw.pathSegments.last;
}
String get scriptPath => Platform.script.toFilePath();
void main() {
+ // The same script is used for both running the tests and as for starting
+ // child verifying the value of Platform.resolvedExecutable. If the
+ // environment variable _SCRIPT_KEY is set this is a child process which
+ // should print the value of Platform.resolvedExecutable.
if (Platform.environment.containsKey(_SCRIPT_KEY)) {
- print(Platform.executable);
+ print(Platform.resolvedExecutable);
return;
}
testDartExecShouldNotBeInCurrentDir();
testShouldSucceedWithSourcePlatformExecutable(); /// 00: ok
- withTempDir(testExeSymLinked); /// 01: ok
+ // dart:io does not support linking to files in Windows.
+ if (!Platform.isWindows) {
+ withTempDir(testExeSymLinked); /// 01: ok
+ }
withTempDir(testExeDirSymLinked); /// 02: ok
testPathToSDKDir(); /// 03: ok
withTempDir(testPathPointsToSymLinkedSDKPath); /// 04: ok
- withTempDir(testPathToDirWithExeSymLinked); /// 05: ok
+ // dart:io does not support linking to files in Windows.
+ if (!Platform.isWindows) {
+ withTempDir(testPathToDirWithExeSymLinked); /// 05: ok
+ }
testShouldFailOutsidePath(); /// 06: ok
}
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index 269a487..f074750 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_test.dart
@@ -24,15 +24,21 @@
Expect.isTrue(hostname is String && hostname != "");
var environment = Platform.environment;
Expect.isTrue(environment is Map<String, String>);
- Expect.isTrue(Platform.executable.contains('dart'));
if (!Platform.isWindows) {
- Expect.isTrue(Platform.executable.startsWith('/'));
+ Expect.isTrue(Platform.executable.endsWith('dart'));
+ Expect.isTrue(Platform.resolvedExecutable.endsWith('dart'));
+ } else {
+ Expect.isTrue(Platform.executable.endsWith('dart.exe'));
+ Expect.isTrue(Platform.resolvedExecutable.endsWith('dart.exe'));
+ }
+ if (!Platform.isWindows) {
+ Expect.isTrue(Platform.resolvedExecutable.startsWith('/'));
} else {
// This assumes that tests (both locally and on the bots) are
// running off a location referred to by a drive letter. If a UNC
// location is used or long names ("\\?\" prefix) is used this
// needs to be fixed.
- Expect.equals(Platform.executable.substring(1, 3), ':\\');
+ Expect.equals(Platform.resolvedExecutable.substring(1, 3), ':\\');
}
// Move directory to be sure script is correct.
var oldDir = Directory.current;
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index f3868b7..68f560a 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -17,15 +17,6 @@
package/package_isolate_test: Fail # Issue 12474
io/observatory_test: Fail
-[ $runtime == vm && ($system == macos || $system == windows) ]
-io/platform_executable_test/01: RuntimeError # Issue 16994
-io/platform_executable_test/02: RuntimeError # Issue 16994
-io/platform_executable_test/04: RuntimeError # Issue 16994
-io/platform_executable_test/05: RuntimeError # Issue 16994
-
-[ $runtime == vm && $system == windows ]
-io/platform_executable_test/06: RuntimeError # NEEDS TRIAGE (kevmoo)
-
[ $runtime == vm && $checked ]
# These tests have type errors on purpose.
io/process_invalid_arguments_test: Fail, OK
@@ -167,6 +158,7 @@
[ $system == windows ]
io/skipping_dart2js_compilations_test: Fail # Issue 19551.
verbose_gc_to_bmu_test: Skip
+io/platform_resolved_executable_test/06: RuntimeError # Issue 23641
[ $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te && $mode == debug ]
verified_mem_test: Skip # Not yet implemented.
@@ -219,10 +211,10 @@
io/link_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
io/link_uri_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
io/observatory_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
-io/platform_executable_test/01: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
-io/platform_executable_test/02: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
-io/platform_executable_test/04: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
-io/platform_executable_test/05: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
+io/platform_resolved_executable_test/01: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
+io/platform_resolved_executable_test/02: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
+io/platform_resolved_executable_test/04: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
+io/platform_resolved_executable_test/05: Crash # (try {test(tempDir);}finally {tempDir.deleteSync(recursive:true);}): try/finally
io/platform_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
io/process_invalid_arguments_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
io/raw_datagram_socket_test: Crash # Unhandled node
diff --git a/tools/VERSION b/tools/VERSION
index 983e8a9..09befe8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 11
PATCH 0
PRERELEASE 5
-PRERELEASE_PATCH 2
+PRERELEASE_PATCH 3