mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:51:29 +00:00
[VM/runtime] - detect null safety before isolate initialization
- Detect null safety when not specified before isolate initialization - for source files by having CFE parse the source file for @dart annotations - for kernel files by sniffing the kernel file for compilation mode - for appJIT files by sniffing the feature string - for AOT snapshots by sniffing the feature string - Remove workaround of returning null safety to false during bootstrapping - Add a new Dart C API call for detecting null safety Bug: 41766 Change-Id: Ia8cf264323a2d0d58c2855ce6491456aa6f1da07 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150089 Commit-Queue: Siva Annamalai <asiva@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
parent
c0c66ab10f
commit
a782dd82db
|
@ -28,7 +28,6 @@ import 'dart:isolate';
|
|||
import 'dart:typed_data' show Uint8List;
|
||||
|
||||
import 'package:build_integration/file_system/multi_root.dart';
|
||||
import 'package:front_end/src/api_prototype/experimental_flags.dart';
|
||||
import 'package:front_end/src/api_prototype/front_end.dart' as fe
|
||||
show CompilerResult;
|
||||
import 'package:front_end/src/api_prototype/memory_file_system.dart';
|
||||
|
@ -78,6 +77,7 @@ const int kTrainTag = 3;
|
|||
const int kCompileExpressionTag = 4;
|
||||
const int kListDependenciesTag = 5;
|
||||
const int kNotifyIsolateShutdownTag = 6;
|
||||
const int kDetectNullabilityTag = 7;
|
||||
|
||||
bool allowDartInternalImport = false;
|
||||
|
||||
|
@ -92,6 +92,62 @@ const int kNullSafetyOptionUnspecified = 0;
|
|||
const int kNullSafetyOptionWeak = 1;
|
||||
const int kNullSafetyOptionStrong = 2;
|
||||
|
||||
CompilerOptions setupCompilerOptions(
|
||||
FileSystem fileSystem,
|
||||
Uri platformKernelPath,
|
||||
bool suppressWarnings,
|
||||
bool enableAsserts,
|
||||
int nullSafety,
|
||||
List<String> experimentalFlags,
|
||||
bool bytecode,
|
||||
Uri packagesUri,
|
||||
List<String> errors) {
|
||||
final expFlags = <String>[];
|
||||
if (experimentalFlags != null) {
|
||||
for (String flag in experimentalFlags) {
|
||||
expFlags.addAll(flag.split(","));
|
||||
}
|
||||
}
|
||||
|
||||
return new CompilerOptions()
|
||||
..fileSystem = fileSystem
|
||||
..target = new VmTarget(new TargetFlags(
|
||||
enableNullSafety: nullSafety == kNullSafetyOptionStrong))
|
||||
..packagesFileUri = packagesUri
|
||||
..sdkSummary = platformKernelPath
|
||||
..verbose = verbose
|
||||
..omitPlatform = true
|
||||
..bytecode = bytecode
|
||||
..experimentalFlags = parseExperimentalFlags(
|
||||
parseExperimentalArguments(expFlags),
|
||||
onError: (msg) => errors.add(msg))
|
||||
..environmentDefines = new EnvironmentMap()
|
||||
..nnbdMode = (nullSafety == kNullSafetyOptionStrong)
|
||||
? NnbdMode.Strong
|
||||
: NnbdMode.Weak
|
||||
..onDiagnostic = (DiagnosticMessage message) {
|
||||
bool printMessage;
|
||||
switch (message.severity) {
|
||||
case Severity.error:
|
||||
case Severity.internalProblem:
|
||||
// TODO(sigmund): support emitting code with errors as long as they
|
||||
// are handled in the generated code.
|
||||
printMessage = false; // errors are printed by VM
|
||||
errors.addAll(message.plainTextFormatted);
|
||||
break;
|
||||
case Severity.warning:
|
||||
printMessage = !suppressWarnings;
|
||||
break;
|
||||
case Severity.context:
|
||||
case Severity.ignored:
|
||||
throw "Unexpected severity: ${message.severity}";
|
||||
}
|
||||
if (printMessage) {
|
||||
printDiagnosticMessage(message, stderr.writeln);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
abstract class Compiler {
|
||||
final int isolateId;
|
||||
final FileSystem fileSystem;
|
||||
|
@ -135,50 +191,16 @@ abstract class Compiler {
|
|||
print("DFE: platformKernelPath: ${platformKernelPath}");
|
||||
}
|
||||
|
||||
var expFlags = List<String>();
|
||||
if (experimentalFlags != null) {
|
||||
for (String flag in experimentalFlags) {
|
||||
expFlags.addAll(flag.split(","));
|
||||
}
|
||||
}
|
||||
|
||||
options = new CompilerOptions()
|
||||
..fileSystem = fileSystem
|
||||
..target = new VmTarget(new TargetFlags(
|
||||
enableNullSafety: nullSafety == kNullSafetyOptionStrong))
|
||||
..packagesFileUri = packagesUri
|
||||
..sdkSummary = platformKernelPath
|
||||
..verbose = verbose
|
||||
..omitPlatform = true
|
||||
..bytecode = bytecode
|
||||
..experimentalFlags = parseExperimentalFlags(
|
||||
parseExperimentalArguments(expFlags),
|
||||
onError: (msg) => errors.add(msg))
|
||||
..environmentDefines = new EnvironmentMap()
|
||||
..nnbdMode = (nullSafety == kNullSafetyOptionStrong)
|
||||
? NnbdMode.Strong
|
||||
: NnbdMode.Weak
|
||||
..onDiagnostic = (DiagnosticMessage message) {
|
||||
bool printMessage;
|
||||
switch (message.severity) {
|
||||
case Severity.error:
|
||||
case Severity.internalProblem:
|
||||
// TODO(sigmund): support emitting code with errors as long as they
|
||||
// are handled in the generated code.
|
||||
printMessage = false; // errors are printed by VM
|
||||
errors.addAll(message.plainTextFormatted);
|
||||
break;
|
||||
case Severity.warning:
|
||||
printMessage = !suppressWarnings;
|
||||
break;
|
||||
case Severity.context:
|
||||
case Severity.ignored:
|
||||
throw "Unexpected severity: ${message.severity}";
|
||||
}
|
||||
if (printMessage) {
|
||||
printDiagnosticMessage(message, stderr.writeln);
|
||||
}
|
||||
};
|
||||
options = setupCompilerOptions(
|
||||
fileSystem,
|
||||
platformKernelPath,
|
||||
suppressWarnings,
|
||||
enableAsserts,
|
||||
nullSafety,
|
||||
experimentalFlags,
|
||||
bytecode,
|
||||
packagesUri,
|
||||
errors);
|
||||
}
|
||||
|
||||
Future<CompilerResult> compile(Uri script) {
|
||||
|
@ -352,13 +374,6 @@ class IncrementalCompilerWrapper extends Compiler {
|
|||
@override
|
||||
Future<CompilerResult> compileInternal(Uri script) async {
|
||||
if (generator == null) {
|
||||
if ((nullSafety == kNullSafetyOptionUnspecified) &&
|
||||
options.experimentalFlags[ExperimentalFlag.nonNullable]) {
|
||||
await autoDetectNullSafetyMode(script, options);
|
||||
// Reinitialize target to set correct null safety mode.
|
||||
options.target = new VmTarget(new TargetFlags(
|
||||
enableNullSafety: options.nnbdMode == NnbdMode.Strong));
|
||||
}
|
||||
generator = new IncrementalCompiler(options, script);
|
||||
}
|
||||
errors.clear();
|
||||
|
@ -420,13 +435,6 @@ class SingleShotCompilerWrapper extends Compiler {
|
|||
|
||||
@override
|
||||
Future<CompilerResult> compileInternal(Uri script) async {
|
||||
if ((nullSafety == kNullSafetyOptionUnspecified) &&
|
||||
options.experimentalFlags[ExperimentalFlag.nonNullable]) {
|
||||
await autoDetectNullSafetyMode(script, options);
|
||||
// Reinitialize target to set correct null safety mode.
|
||||
options.target = new VmTarget(new TargetFlags(
|
||||
enableNullSafety: options.nnbdMode == NnbdMode.Strong));
|
||||
}
|
||||
fe.CompilerResult compilerResult = requireMain
|
||||
? await kernelForProgram(script, options)
|
||||
: await kernelForModule([script], options);
|
||||
|
@ -768,6 +776,7 @@ Future _processLoadRequest(request) async {
|
|||
final String packageConfig = request[12];
|
||||
final String multirootFilepaths = request[13];
|
||||
final String multirootScheme = request[14];
|
||||
final String workingDirectory = request[15];
|
||||
|
||||
Uri platformKernelPath = null;
|
||||
List<int> platformKernel = null;
|
||||
|
@ -810,6 +819,30 @@ Future _processLoadRequest(request) async {
|
|||
}
|
||||
port.send(new CompilationResult.ok(null).toResponse());
|
||||
return;
|
||||
} 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<String> errors = <String>[];
|
||||
var options = setupCompilerOptions(fileSystem, platformKernelPath, false,
|
||||
false, nullSafety, experimentalFlags, false, packagesUri, errors);
|
||||
|
||||
// script should only be null for kUpdateSourcesTag.
|
||||
assert(script != null);
|
||||
await autoDetectNullSafetyMode(script, options);
|
||||
bool value = options.nnbdMode == NnbdMode.Strong;
|
||||
port.send(new CompilationResult.nullSafety(value).toResponse());
|
||||
return;
|
||||
}
|
||||
|
||||
// script should only be null for kUpdateSourcesTag.
|
||||
|
@ -997,6 +1030,7 @@ Future trainInternal(
|
|||
null /* package_config */,
|
||||
null /* multirootFilepaths */,
|
||||
null /* multirootScheme */,
|
||||
null /* original working directory */,
|
||||
];
|
||||
await _processLoadRequest(request);
|
||||
}
|
||||
|
@ -1044,6 +1078,8 @@ abstract class CompilationResult {
|
|||
|
||||
factory CompilationResult.ok(Uint8List bytes) = _CompilationOk;
|
||||
|
||||
factory CompilationResult.nullSafety(bool val) = _CompilationNullSafety;
|
||||
|
||||
factory CompilationResult.errors(List<String> errors, Uint8List bytes) =
|
||||
_CompilationError;
|
||||
|
||||
|
@ -1075,6 +1111,20 @@ class _CompilationOk extends CompilationResult {
|
|||
String toString() => "_CompilationOk(${bytes.length} bytes)";
|
||||
}
|
||||
|
||||
class _CompilationNullSafety extends CompilationResult {
|
||||
final bool _null_safety;
|
||||
|
||||
_CompilationNullSafety(this._null_safety) : super._() {}
|
||||
|
||||
@override
|
||||
Status get status => Status.ok;
|
||||
|
||||
@override
|
||||
get payload => _null_safety;
|
||||
|
||||
String toString() => "_CompilationNullSafety($_null_safety)";
|
||||
}
|
||||
|
||||
abstract class _CompilationFail extends CompilationResult {
|
||||
_CompilationFail() : super._();
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
#include "bin/dfe.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "bin/abi_version.h"
|
||||
#include "bin/dartutils.h"
|
||||
#include "bin/directory.h"
|
||||
|
@ -191,53 +189,54 @@ bool DFE::CanUseDartFrontend() const {
|
|||
(KernelServiceDillAvailable() || (frontend_filename() != nullptr));
|
||||
}
|
||||
|
||||
class WindowsPathSanitizer {
|
||||
public:
|
||||
explicit WindowsPathSanitizer(const char* path) {
|
||||
// For Windows we need to massage the paths a bit according to
|
||||
// http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
|
||||
//
|
||||
// Convert
|
||||
// C:\one\two\three
|
||||
// to
|
||||
// /C:/one/two/three
|
||||
//
|
||||
// (see builtin.dart#_sanitizeWindowsPath)
|
||||
intptr_t len = strlen(path);
|
||||
sanitized_uri_ = reinterpret_cast<char*>(malloc(len + 1 + 1));
|
||||
if (sanitized_uri_ == nullptr) {
|
||||
OUT_OF_MEMORY();
|
||||
}
|
||||
char* s = sanitized_uri_;
|
||||
if (len > 2 && path[1] == ':') {
|
||||
*s++ = '/';
|
||||
}
|
||||
for (const char* p = path; *p != '\0'; ++p, ++s) {
|
||||
*s = *p == '\\' ? '/' : *p;
|
||||
}
|
||||
*s = '\0';
|
||||
PathSanitizer::PathSanitizer(const char* path) {
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
// For Windows we need to massage the paths a bit according to
|
||||
// http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
|
||||
//
|
||||
// Convert
|
||||
// C:\one\two\three
|
||||
// to
|
||||
// /C:/one/two/three
|
||||
//
|
||||
// (see builtin.dart#_sanitizeWindowsPath)
|
||||
if (path == nullptr) {
|
||||
return;
|
||||
}
|
||||
~WindowsPathSanitizer() { free(sanitized_uri_); }
|
||||
intptr_t len = strlen(path);
|
||||
char* uri = reinterpret_cast<char*>(new char[len + 1 + 1]);
|
||||
if (uri == nullptr) {
|
||||
OUT_OF_MEMORY();
|
||||
}
|
||||
char* s = uri;
|
||||
if (len > 2 && path[1] == ':') {
|
||||
*s++ = '/';
|
||||
}
|
||||
for (const char* p = path; *p != '\0'; ++p, ++s) {
|
||||
*s = *p == '\\' ? '/' : *p;
|
||||
}
|
||||
*s = '\0';
|
||||
sanitized_uri_ = std::unique_ptr<char[]>(uri);
|
||||
#else
|
||||
sanitized_uri_ = path;
|
||||
#endif // defined(HOST_OS_WINDOWS)
|
||||
}
|
||||
|
||||
const char* sanitized_uri() { return sanitized_uri_; }
|
||||
|
||||
private:
|
||||
char* sanitized_uri_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WindowsPathSanitizer);
|
||||
};
|
||||
const char* PathSanitizer::sanitized_uri() const {
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
return sanitized_uri_.get();
|
||||
#else
|
||||
return sanitized_uri_;
|
||||
#endif // defined(HOST_OS_WINDOWS)
|
||||
}
|
||||
|
||||
Dart_KernelCompilationResult DFE::CompileScript(const char* script_uri,
|
||||
bool incremental,
|
||||
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.
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
WindowsPathSanitizer path_sanitizer(script_uri);
|
||||
PathSanitizer path_sanitizer(script_uri);
|
||||
const char* sanitized_uri = path_sanitizer.sanitized_uri();
|
||||
#else
|
||||
const char* sanitized_uri = script_uri;
|
||||
#endif
|
||||
|
||||
return Dart_CompileToKernel(
|
||||
sanitized_uri, platform_strong_dill_for_compilation_,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef RUNTIME_BIN_DFE_H_
|
||||
#define RUNTIME_BIN_DFE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "include/dart_api.h"
|
||||
#include "include/dart_native_api.h"
|
||||
#include "platform/assert.h"
|
||||
|
@ -121,6 +123,21 @@ class DFE {
|
|||
DISALLOW_COPY_AND_ASSIGN(DFE);
|
||||
};
|
||||
|
||||
class PathSanitizer {
|
||||
public:
|
||||
explicit PathSanitizer(const char* path);
|
||||
const char* sanitized_uri() const;
|
||||
|
||||
private:
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
std::unique_ptr<char[]> sanitized_uri_;
|
||||
#else
|
||||
const char* sanitized_uri_;
|
||||
#endif // defined(HOST_OS_WINDOWS)
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PathSanitizer);
|
||||
};
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
extern DFE dfe;
|
||||
#endif
|
||||
|
|
|
@ -664,6 +664,9 @@ static int CreateIsolateAndSnapshot(const CommandLineOptions& inputs) {
|
|||
|
||||
Dart_IsolateFlags isolate_flags;
|
||||
Dart_IsolateFlagsInitialize(&isolate_flags);
|
||||
isolate_flags.null_safety =
|
||||
Dart_DetectNullSafety(nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
kernel_buffer, kernel_buffer_size);
|
||||
if (IsSnapshottingForPrecompilation()) {
|
||||
isolate_flags.obfuscate = obfuscate;
|
||||
isolate_flags.entry_points = no_entry_points;
|
||||
|
|
|
@ -599,6 +599,9 @@ static Dart_Isolate CreateIsolateGroupAndSetupHelper(
|
|||
const uint8_t* isolate_snapshot_data = app_isolate_snapshot_data;
|
||||
const uint8_t* isolate_snapshot_instructions =
|
||||
app_isolate_snapshot_instructions;
|
||||
flags->null_safety =
|
||||
Dart_DetectNullSafety(nullptr, nullptr, nullptr, isolate_snapshot_data,
|
||||
isolate_snapshot_instructions, nullptr, -1);
|
||||
#else
|
||||
// JIT: Main isolate starts from the app snapshot, if any. Other isolates
|
||||
// use the core libraries snapshot.
|
||||
|
@ -635,6 +638,13 @@ static Dart_Isolate CreateIsolateGroupAndSetupHelper(
|
|||
if (kernel_buffer == NULL && !isolate_run_app_snapshot) {
|
||||
dfe.ReadScript(script_uri, &kernel_buffer, &kernel_buffer_size);
|
||||
}
|
||||
PathSanitizer script_uri_sanitizer(script_uri);
|
||||
PathSanitizer packages_config_sanitizer(packages_config);
|
||||
flags->null_safety = Dart_DetectNullSafety(
|
||||
script_uri_sanitizer.sanitized_uri(),
|
||||
packages_config_sanitizer.sanitized_uri(),
|
||||
DartUtils::original_working_directory, isolate_snapshot_data,
|
||||
isolate_snapshot_instructions, kernel_buffer, kernel_buffer_size);
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
auto isolate_group_data = new IsolateGroupData(
|
||||
|
|
|
@ -532,6 +532,7 @@ typedef struct {
|
|||
Dart_QualifiedFunctionName* entry_points;
|
||||
bool load_vmservice_library;
|
||||
bool copy_parent_code;
|
||||
bool null_safety;
|
||||
} Dart_IsolateFlags;
|
||||
|
||||
/**
|
||||
|
@ -3313,8 +3314,8 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
Dart_KernelCompilationStatus status;
|
||||
bool null_safety;
|
||||
char* error;
|
||||
|
||||
uint8_t* kernel;
|
||||
intptr_t kernel_size;
|
||||
} Dart_KernelCompilationResult;
|
||||
|
@ -3370,6 +3371,49 @@ DART_EXPORT void Dart_SetDartLibrarySourcesKernel(
|
|||
const uint8_t* platform_kernel,
|
||||
const intptr_t platform_kernel_size);
|
||||
|
||||
/**
|
||||
* Detect the null safety opt-in status.
|
||||
*
|
||||
* When running from source, it is based on the opt-in status of `script_uri`.
|
||||
* When running from a kernel buffer, it is based on the mode used when
|
||||
* generating `kernel_buffer`.
|
||||
* When running from an appJIT or AOT snapshot, it is based on the mode used
|
||||
* when generating `snapshot_data`.
|
||||
*
|
||||
* \param script_uri Uri of the script that contains the source code
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* \param snapshot_data
|
||||
*
|
||||
* \param snapshot_instructions Buffers containing a snapshot of the
|
||||
* isolate or NULL if no snapshot is provided. If provided, the buffers must
|
||||
* remain valid until the isolate shuts down.
|
||||
*
|
||||
* \param kernel_buffer
|
||||
*
|
||||
* \param kernel_buffer_size A buffer which contains a kernel/DIL program. Must
|
||||
* remain valid until isolate shutdown.
|
||||
*
|
||||
* \return Returns true if the null safety is opted in by the input being
|
||||
* run `script_uri`, `snapshot_data` or `kernel_buffer`.
|
||||
*
|
||||
*/
|
||||
DART_EXPORT bool Dart_DetectNullSafety(const char* script_uri,
|
||||
const char* package_config,
|
||||
const char* original_working_directory,
|
||||
const uint8_t* snapshot_data,
|
||||
const uint8_t* snapshot_instructions,
|
||||
const uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size);
|
||||
|
||||
#define DART_KERNEL_ISOLATE_NAME "kernel-service"
|
||||
|
||||
/*
|
||||
|
|
|
@ -109,7 +109,6 @@ static ErrorPtr BootstrapFromKernel(Thread* thread,
|
|||
|
||||
LongJumpScope jump;
|
||||
if (setjmp(*jump.Set()) == 0) {
|
||||
program->AutoDetectNullSafety(thread->isolate());
|
||||
kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
|
||||
|
||||
Isolate* isolate = thread->isolate();
|
||||
|
|
|
@ -6662,23 +6662,50 @@ char* SnapshotHeaderReader::InitializeGlobalVMFlagsFromSnapshot(
|
|||
#undef CHECK_FLAG
|
||||
#undef SET_FLAG
|
||||
|
||||
if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
|
||||
if (strncmp(cursor, "null-safety", end - cursor) == 0) {
|
||||
FLAG_null_safety = kNullSafetyOptionStrong;
|
||||
cursor = end;
|
||||
continue;
|
||||
}
|
||||
if (strncmp(cursor, "no-null-safety", end - cursor) == 0) {
|
||||
FLAG_null_safety = kNullSafetyOptionWeak;
|
||||
cursor = end;
|
||||
continue;
|
||||
}
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SnapshotHeaderReader::NullSafetyFromSnapshot(const Snapshot* snapshot) {
|
||||
bool null_safety = false;
|
||||
SnapshotHeaderReader header_reader(snapshot);
|
||||
const char* features = nullptr;
|
||||
intptr_t features_length = 0;
|
||||
|
||||
char* error = header_reader.ReadFeatures(&features, &features_length);
|
||||
if (error != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERT(features[features_length] == '\0');
|
||||
const char* cursor = features;
|
||||
while (*cursor != '\0') {
|
||||
while (*cursor == ' ') {
|
||||
cursor++;
|
||||
}
|
||||
|
||||
const char* end = strstr(cursor, " ");
|
||||
if (end == nullptr) {
|
||||
end = features + features_length;
|
||||
}
|
||||
|
||||
if (strncmp(cursor, "null-safety", end - cursor) == 0) {
|
||||
cursor = end;
|
||||
null_safety = true;
|
||||
continue;
|
||||
}
|
||||
if (strncmp(cursor, "no-null-safety", end - cursor) == 0) {
|
||||
cursor = end;
|
||||
null_safety = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
cursor = end;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return null_safety;
|
||||
}
|
||||
|
||||
ApiErrorPtr FullSnapshotReader::ReadVMSnapshot() {
|
||||
|
|
|
@ -514,6 +514,7 @@ struct SerializerWritingObjectScope {
|
|||
class SnapshotHeaderReader {
|
||||
public:
|
||||
static char* InitializeGlobalVMFlagsFromSnapshot(const Snapshot* snapshot);
|
||||
static bool NullSafetyFromSnapshot(const Snapshot* snapshot);
|
||||
|
||||
explicit SnapshotHeaderReader(const Snapshot* snapshot)
|
||||
: SnapshotHeaderReader(snapshot->kind(),
|
||||
|
|
|
@ -746,6 +746,55 @@ ErrorPtr Dart::InitIsolateFromSnapshot(Thread* T,
|
|||
return Error::null();
|
||||
}
|
||||
|
||||
bool Dart::DetectNullSafety(const char* script_uri,
|
||||
const uint8_t* snapshot_data,
|
||||
const uint8_t* snapshot_instructions,
|
||||
const uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size,
|
||||
const char* package_config,
|
||||
const char* original_working_directory) {
|
||||
// Before creating the isolate we first determine the null safety mode
|
||||
// in which the isolate needs to run based on one of these factors :
|
||||
// - if loading from source, based on opt-in status of the source
|
||||
// - if loading from a kernel file, based on the mode used when
|
||||
// generating the kernel file
|
||||
// - if loading from an appJIT or AOT snapshot, based on the mode used
|
||||
// when generating the snapshot.
|
||||
ASSERT(FLAG_null_safety == kNullSafetyOptionUnspecified);
|
||||
|
||||
// If snapshot is an appJIT/AOT snapshot we will figure out the mode by
|
||||
// sniffing the feature string in the snapshot.
|
||||
if (snapshot_data != nullptr) {
|
||||
// Read the snapshot and check for null safety option.
|
||||
const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
|
||||
if (Snapshot::IncludesCode(snapshot->kind())) {
|
||||
return SnapshotHeaderReader::NullSafetyFromSnapshot(snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
// If kernel_buffer is specified, it could be a self contained
|
||||
// kernel file or the kernel file of the application,
|
||||
// figure out the null safety mode by sniffing the kernel file.
|
||||
if (kernel_buffer != nullptr) {
|
||||
const char* error = nullptr;
|
||||
std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
|
||||
kernel_buffer, kernel_buffer_size, &error);
|
||||
if (program != nullptr) {
|
||||
return program->compilation_mode() == NNBDCompiledMode::kStrong;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are loading from source, figure out the mode from the source.
|
||||
if (KernelIsolate::GetExperimentalFlag("non-nullable")) {
|
||||
return KernelIsolate::DetectNullSafety(script_uri, package_config,
|
||||
original_working_directory);
|
||||
}
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
static void PrintLLVMConstantPool(Thread* T, Isolate* I) {
|
||||
StackZone printing_zone(T);
|
||||
|
|
|
@ -66,6 +66,15 @@ class Dart : public AllStatic {
|
|||
const uint8_t* snapshot_instructions,
|
||||
const uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size);
|
||||
|
||||
static bool DetectNullSafety(const char* script_uri,
|
||||
const uint8_t* snapshot_data,
|
||||
const uint8_t* snapshot_instructions,
|
||||
const uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size,
|
||||
const char* package_config,
|
||||
const char* original_working_directory);
|
||||
|
||||
static void RunShutdownCallback();
|
||||
static void ShutdownIsolate(Isolate* isolate);
|
||||
static void ShutdownIsolate();
|
||||
|
|
|
@ -5449,7 +5449,6 @@ DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t* buffer,
|
|||
if (program == nullptr) {
|
||||
return Api::NewError("Can't load Kernel binary: %s.", error);
|
||||
}
|
||||
program->AutoDetectNullSafety(I);
|
||||
const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
|
||||
program.reset();
|
||||
|
||||
|
@ -5755,7 +5754,6 @@ DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t* buffer,
|
|||
DARTSCOPE(Thread::Current());
|
||||
API_TIMELINE_DURATION(T);
|
||||
StackZone zone(T);
|
||||
Isolate* I = T->isolate();
|
||||
|
||||
CHECK_CALLBACK_STATE(T);
|
||||
|
||||
|
@ -5772,7 +5770,6 @@ DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t* buffer,
|
|||
if (program == nullptr) {
|
||||
return Api::NewError("Can't load Kernel binary: %s.", error);
|
||||
}
|
||||
program->AutoDetectNullSafety(I);
|
||||
const Object& result =
|
||||
kernel::KernelLoader::LoadEntireProgram(program.get(), false);
|
||||
program.reset();
|
||||
|
@ -6028,6 +6025,24 @@ DART_EXPORT void Dart_SetDartLibrarySourcesKernel(
|
|||
#endif
|
||||
}
|
||||
|
||||
DART_EXPORT bool Dart_DetectNullSafety(const char* script_uri,
|
||||
const char* package_config,
|
||||
const char* original_working_directory,
|
||||
const uint8_t* snapshot_data,
|
||||
const uint8_t* snapshot_instructions,
|
||||
const uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size) {
|
||||
bool null_safety;
|
||||
if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
|
||||
null_safety = Dart::DetectNullSafety(
|
||||
script_uri, snapshot_data, snapshot_instructions, kernel_buffer,
|
||||
kernel_buffer_size, package_config, original_working_directory);
|
||||
} else {
|
||||
null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
|
||||
}
|
||||
return null_safety;
|
||||
}
|
||||
|
||||
// --- Service support ---
|
||||
|
||||
DART_EXPORT bool Dart_IsServiceIsolate(Dart_Isolate isolate) {
|
||||
|
|
|
@ -1455,6 +1455,7 @@ void Isolate::FlagsInitialize(Dart_IsolateFlags* api_flags) {
|
|||
api_flags->entry_points = NULL;
|
||||
api_flags->load_vmservice_library = false;
|
||||
api_flags->copy_parent_code = false;
|
||||
api_flags->null_safety = false;
|
||||
}
|
||||
|
||||
void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const {
|
||||
|
@ -1466,6 +1467,7 @@ void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const {
|
|||
api_flags->entry_points = NULL;
|
||||
api_flags->load_vmservice_library = should_load_vmservice();
|
||||
api_flags->copy_parent_code = false;
|
||||
api_flags->null_safety = null_safety();
|
||||
}
|
||||
|
||||
void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) {
|
||||
|
@ -1495,6 +1497,7 @@ void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) {
|
|||
#undef SET_FROM_FLAG
|
||||
|
||||
set_should_load_vmservice(api_flags.load_vmservice_library);
|
||||
set_null_safety(api_flags.null_safety);
|
||||
|
||||
// Copy entry points list.
|
||||
ASSERT(embedder_entry_points_ == NULL);
|
||||
|
@ -1757,26 +1760,12 @@ Isolate* Isolate::InitIsolate(const char* name_prefix,
|
|||
isolate_group->RegisterIsolate(result);
|
||||
|
||||
if (ServiceIsolate::NameEquals(name_prefix)) {
|
||||
// For now the service isolate always runs in weak mode.
|
||||
result->set_null_safety(false);
|
||||
ASSERT(!ServiceIsolate::Exists());
|
||||
ServiceIsolate::SetServiceIsolate(result);
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
} else if (KernelIsolate::NameEquals(name_prefix)) {
|
||||
// For now the kernel isolate always runs in weak mode.
|
||||
result->set_null_safety(false);
|
||||
ASSERT(!KernelIsolate::Exists());
|
||||
KernelIsolate::SetKernelIsolate(result);
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
} else if (FLAG_null_safety != kNullSafetyOptionUnspecified) {
|
||||
// If the null-safety option is specified on the command line then
|
||||
// use the value specified on the command line, if the dill file being
|
||||
// loaded is in a different mode than that specified on the command line
|
||||
// we will get an error during kernel file loading.
|
||||
result->set_null_safety(FLAG_null_safety == kNullSafetyOptionStrong);
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
} else if (!KernelIsolate::GetExperimentalFlag("non-nullable")) {
|
||||
result->set_null_safety(false);
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
|
|
|
@ -1235,11 +1235,6 @@ class Isolate : public BaseIsolate, public IntrusiveDListEntry<Isolate> {
|
|||
}
|
||||
|
||||
bool null_safety() const {
|
||||
// TODO(asiva) : We return false when the null safety mode is not yet set
|
||||
// instead of just asserting as some code runs during bootstrapping that
|
||||
// requires the mode to be set. Once all of that is resolved this could
|
||||
// turn into just an assert.
|
||||
if (null_safety_not_set()) return false;
|
||||
ASSERT(!null_safety_not_set());
|
||||
return NullSafetyBit::decode(isolate_flags_);
|
||||
}
|
||||
|
|
|
@ -95,9 +95,6 @@ class Program {
|
|||
intptr_t library_count() { return library_count_; }
|
||||
NNBDCompiledMode compilation_mode() const { return compilation_mode_; }
|
||||
|
||||
// Detect null-safety mode from this program if it was not set yet.
|
||||
void AutoDetectNullSafety(Isolate* isolate);
|
||||
|
||||
private:
|
||||
Program() : typed_data_(NULL), kernel_data_(NULL), kernel_data_size_(-1) {}
|
||||
|
||||
|
|
|
@ -226,20 +226,6 @@ std::unique_ptr<Program> Program::ReadFromTypedData(
|
|||
return kernel::Program::ReadFrom(&reader, error);
|
||||
}
|
||||
|
||||
void Program::AutoDetectNullSafety(Isolate* isolate) {
|
||||
if (isolate->is_service_isolate() || isolate->is_kernel_isolate()) {
|
||||
// For now the service isolate and kernel isolate will be running in
|
||||
// weak mode and we assert for that here.
|
||||
ASSERT(!isolate->null_safety());
|
||||
} else {
|
||||
// If null safety is not specified on the command line we use the value
|
||||
// from the dill file that the CFE has computed based on how it was invoked.
|
||||
if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
|
||||
isolate->set_null_safety(compilation_mode() == NNBDCompiledMode::kStrong);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
} // namespace dart
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "vm/message_handler.h"
|
||||
#include "vm/native_arguments.h"
|
||||
#include "vm/native_entry.h"
|
||||
#include "vm/native_message_handler.h"
|
||||
#include "vm/object.h"
|
||||
#include "vm/object_store.h"
|
||||
#include "vm/port.h"
|
||||
|
@ -52,6 +53,10 @@ DEFINE_FLAG(charp,
|
|||
// 1 - Update in-memory file system with in-memory sources (used by tests).
|
||||
// 2 - Accept last compilation result.
|
||||
// 3 - APP JIT snapshot training run for kernel_service.
|
||||
// 4 - Compile expressions in context (used by expression evaluation).
|
||||
// 5 - Generate dependencies used to create a dependencies file.
|
||||
// 6 - Triggers shutdown of the kernel isolate.
|
||||
// 7 - Detects the nullability of a script based on it's opt-in status.
|
||||
const int KernelIsolate::kCompileTag = 0;
|
||||
const int KernelIsolate::kUpdateSourcesTag = 1;
|
||||
const int KernelIsolate::kAcceptTag = 2;
|
||||
|
@ -59,6 +64,7 @@ const int KernelIsolate::kTrainTag = 3;
|
|||
const int KernelIsolate::kCompileExpressionTag = 4;
|
||||
const int KernelIsolate::kListDependenciesTag = 5;
|
||||
const int KernelIsolate::kNotifyIsolateShutdown = 6;
|
||||
const int KernelIsolate::kDetectNullabilityTag = 7;
|
||||
|
||||
const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME;
|
||||
Dart_IsolateGroupCreateCallback KernelIsolate::create_group_callback_ = NULL;
|
||||
|
@ -695,7 +701,8 @@ class KernelCompilationRequest : public ValueObject {
|
|||
const char* package_config,
|
||||
const char* multiroot_filepaths,
|
||||
const char* multiroot_scheme,
|
||||
const MallocGrowableArray<char*>* experimental_flags) {
|
||||
const MallocGrowableArray<char*>* experimental_flags,
|
||||
const char* original_working_directory) {
|
||||
// Build the message for the Kernel isolate.
|
||||
// tag is used to specify which operation the frontend should perform.
|
||||
Dart_CObject tag;
|
||||
|
@ -767,7 +774,10 @@ class KernelCompilationRequest : public ValueObject {
|
|||
|
||||
Dart_CObject null_safety;
|
||||
null_safety.type = Dart_CObject_kInt32;
|
||||
null_safety.value.as_int32 = FLAG_null_safety;
|
||||
null_safety.value.as_int32 =
|
||||
(isolate != NULL) ? (isolate->null_safety() ? kNullSafetyOptionStrong
|
||||
: kNullSafetyOptionWeak)
|
||||
: FLAG_null_safety;
|
||||
|
||||
intptr_t num_experimental_flags = experimental_flags->length();
|
||||
Dart_CObject** experimental_flags_array =
|
||||
|
@ -822,6 +832,17 @@ class KernelCompilationRequest : public ValueObject {
|
|||
}
|
||||
}
|
||||
|
||||
Dart_CObject original_working_directory_object;
|
||||
{
|
||||
if (original_working_directory != NULL) {
|
||||
original_working_directory_object.type = Dart_CObject_kString;
|
||||
original_working_directory_object.value.as_string =
|
||||
const_cast<char*>(original_working_directory);
|
||||
} else {
|
||||
original_working_directory_object.type = Dart_CObject_kNull;
|
||||
}
|
||||
}
|
||||
|
||||
Dart_CObject* message_arr[] = {&tag,
|
||||
&send_port,
|
||||
&uri,
|
||||
|
@ -836,7 +857,8 @@ class KernelCompilationRequest : public ValueObject {
|
|||
&bytecode,
|
||||
&package_config_uri,
|
||||
&multiroot_filepaths_object,
|
||||
&multiroot_scheme_object};
|
||||
&multiroot_scheme_object,
|
||||
&original_working_directory_object};
|
||||
message.value.as_array.values = message_arr;
|
||||
message.value.as_array.length = ARRAY_SIZE(message_arr);
|
||||
// Send the message.
|
||||
|
@ -862,11 +884,16 @@ class KernelCompilationRequest : public ValueObject {
|
|||
private:
|
||||
void LoadKernelFromResponse(Dart_CObject* response) {
|
||||
ASSERT((response->type == Dart_CObject_kTypedData) ||
|
||||
(response->type == Dart_CObject_kBool) ||
|
||||
(response->type == Dart_CObject_kNull));
|
||||
|
||||
if (response->type == Dart_CObject_kNull) {
|
||||
return;
|
||||
}
|
||||
if (response->type == Dart_CObject_kBool) {
|
||||
result_.null_safety = response->value.as_bool;
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(response->value.as_typed_data.type == Dart_TypedData_kUint8);
|
||||
result_.kernel_size = response->value.as_typed_data.length;
|
||||
|
@ -999,7 +1026,33 @@ 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_);
|
||||
multiroot_scheme, experimental_flags_, NULL);
|
||||
}
|
||||
|
||||
bool KernelIsolate::DetectNullSafety(const char* script_uri,
|
||||
const char* package_config,
|
||||
const char* original_working_directory) {
|
||||
// Start the kernel Isolate if it is not already running.
|
||||
if (!Start()) {
|
||||
Dart_KernelCompilationResult result = {};
|
||||
result.status = Dart_KernelCompilationStatus_Unknown;
|
||||
result.error = strdup("Error while starting Kernel isolate task");
|
||||
return false;
|
||||
}
|
||||
// Wait for Kernel isolate to finish initialization.
|
||||
Dart_Port kernel_port = WaitForKernelPort();
|
||||
if (kernel_port == ILLEGAL_PORT) {
|
||||
Dart_KernelCompilationResult result = {};
|
||||
result.status = Dart_KernelCompilationStatus_Unknown;
|
||||
result.error = strdup("Error while initializing Kernel isolate");
|
||||
return false;
|
||||
}
|
||||
KernelCompilationRequest request;
|
||||
Dart_KernelCompilationResult result = request.SendAndWaitForResponse(
|
||||
kDetectNullabilityTag, kernel_port, script_uri, nullptr, -1, 0, nullptr,
|
||||
false, package_config, nullptr, nullptr, experimental_flags_,
|
||||
original_working_directory);
|
||||
return result.null_safety;
|
||||
}
|
||||
|
||||
Dart_KernelCompilationResult KernelIsolate::ListDependencies() {
|
||||
|
@ -1014,7 +1067,7 @@ Dart_KernelCompilationResult KernelIsolate::ListDependencies() {
|
|||
KernelCompilationRequest request;
|
||||
return request.SendAndWaitForResponse(kListDependenciesTag, kernel_port, NULL,
|
||||
NULL, 0, 0, NULL, false, NULL, NULL,
|
||||
NULL, experimental_flags_);
|
||||
NULL, experimental_flags_, NULL);
|
||||
}
|
||||
|
||||
Dart_KernelCompilationResult KernelIsolate::AcceptCompilation() {
|
||||
|
@ -1031,7 +1084,7 @@ Dart_KernelCompilationResult KernelIsolate::AcceptCompilation() {
|
|||
KernelCompilationRequest request;
|
||||
return request.SendAndWaitForResponse(kAcceptTag, kernel_port, NULL, NULL, 0,
|
||||
0, NULL, true, NULL, NULL, NULL,
|
||||
experimental_flags_);
|
||||
experimental_flags_, NULL);
|
||||
}
|
||||
|
||||
Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
|
||||
|
@ -1073,7 +1126,7 @@ Dart_KernelCompilationResult KernelIsolate::UpdateInMemorySources(
|
|||
KernelCompilationRequest request;
|
||||
return request.SendAndWaitForResponse(
|
||||
kUpdateSourcesTag, kernel_port, NULL, NULL, 0, source_files_count,
|
||||
source_files, true, NULL, NULL, NULL, experimental_flags_);
|
||||
source_files, true, NULL, NULL, NULL, experimental_flags_, NULL);
|
||||
}
|
||||
|
||||
void KernelIsolate::NotifyAboutIsolateShutdown(const Isolate* isolate) {
|
||||
|
|
|
@ -30,6 +30,7 @@ class KernelIsolate : public AllStatic {
|
|||
static const int kCompileExpressionTag;
|
||||
static const int kListDependenciesTag;
|
||||
static const int kNotifyIsolateShutdown;
|
||||
static const int kDetectNullabilityTag;
|
||||
|
||||
static void InitializeState();
|
||||
static bool Start();
|
||||
|
@ -53,6 +54,10 @@ class KernelIsolate : public AllStatic {
|
|||
const char* multiroot_filepaths = NULL,
|
||||
const char* multiroot_scheme = NULL);
|
||||
|
||||
static bool DetectNullSafety(const char* script_uri,
|
||||
const char* package_config,
|
||||
const char* original_working_directory);
|
||||
|
||||
static Dart_KernelCompilationResult AcceptCompilation();
|
||||
static Dart_KernelCompilationResult UpdateInMemorySources(
|
||||
int source_files_count,
|
||||
|
|
|
@ -78,16 +78,20 @@ VMTag::TagEntry VMTag::entries_[] = {
|
|||
|
||||
VMTagScope::VMTagScope(Thread* thread, uword tag, bool conditional_set)
|
||||
: ThreadStackResource(thread) {
|
||||
ASSERT(isolate_group() != NULL);
|
||||
previous_tag_ = thread->vm_tag();
|
||||
if (conditional_set) {
|
||||
thread->set_vm_tag(tag);
|
||||
if (thread != NULL) {
|
||||
ASSERT(isolate_group() != NULL);
|
||||
previous_tag_ = thread->vm_tag();
|
||||
if (conditional_set) {
|
||||
thread->set_vm_tag(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VMTagScope::~VMTagScope() {
|
||||
ASSERT(isolate_group() != NULL);
|
||||
thread()->set_vm_tag(previous_tag_);
|
||||
if (thread() != NULL) {
|
||||
ASSERT(isolate_group() != NULL);
|
||||
thread()->set_vm_tag(previous_tag_);
|
||||
}
|
||||
}
|
||||
|
||||
VMTagCounters::VMTagCounters() {
|
||||
|
|
39
tests/lib/isolate/detect_nullsafety_1_test.dart
Normal file
39
tests/lib/isolate/detect_nullsafety_1_test.dart
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "detect_nullsafety_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/strong.dart";
|
||||
String dillPath = "$tmpDirPath/strong.dill";
|
||||
String jitPath = "$tmpDirPath/strong.appjit";
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
generateIsolateSource(sourcePath, "");
|
||||
generateKernel(sourcePath, dillPath);
|
||||
generateAppJIT(sourcePath, jitPath);
|
||||
|
||||
try {
|
||||
// Running from Source.
|
||||
testNullSafetyMode(sourcePath, 'Strong Mode');
|
||||
// Without the enable experiment option it will be in weak mode.
|
||||
testNullSafetyMode1(sourcePath, 'Weak Mode');
|
||||
|
||||
// Running from Kernel File.
|
||||
testNullSafetyMode(dillPath, 'Strong Mode');
|
||||
// Without the enable experiment option it will be inferred to strong.
|
||||
testNullSafetyMode1(dillPath, 'Strong Mode');
|
||||
|
||||
// Running from app JIT File.
|
||||
testNullSafetyMode(jitPath, 'Strong Mode');
|
||||
// Without the enable experiment option it will be inferred to strong.
|
||||
testNullSafetyMode1(jitPath, 'Strong Mode');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
38
tests/lib/isolate/detect_nullsafety_2_test.dart
Normal file
38
tests/lib/isolate/detect_nullsafety_2_test.dart
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "detect_nullsafety_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/weak.dart";
|
||||
String dillPath = "$tmpDirPath/weak.dill";
|
||||
String jitPath = "$tmpDirPath/weak.appjit";
|
||||
|
||||
// Generate code for an isolate to run in weak mode.
|
||||
generateIsolateSource(sourcePath, "2.6");
|
||||
generateKernel(sourcePath, dillPath);
|
||||
generateAppJIT(sourcePath, jitPath);
|
||||
|
||||
try {
|
||||
testNullSafetyMode(sourcePath, 'Weak Mode');
|
||||
// Without the enable experiment option it will be in weak mode.
|
||||
testNullSafetyMode1(sourcePath, 'Weak Mode');
|
||||
|
||||
// Running from Kernel File.
|
||||
testNullSafetyMode(dillPath, 'Weak Mode');
|
||||
// Without the enable experiment option it will be inferred to weak.
|
||||
testNullSafetyMode1(dillPath, 'Weak Mode');
|
||||
|
||||
// Running from app JIT File.
|
||||
testNullSafetyMode(jitPath, 'Weak Mode');
|
||||
// Without the enable experiment option it will be inferred to weak.
|
||||
testNullSafetyMode1(jitPath, 'Weak Mode');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
56
tests/lib/isolate/detect_nullsafety_helper.dart
Normal file
56
tests/lib/isolate/detect_nullsafety_helper.dart
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "package:async_helper/async_minitest.dart";
|
||||
|
||||
void generateIsolateSource(String filePath, String version) {
|
||||
File mainIsolate = new File(filePath);
|
||||
mainIsolate.writeAsStringSync('''
|
||||
// @dart=$version
|
||||
void main() {
|
||||
try {
|
||||
int x = null as int;
|
||||
print("Weak Mode");
|
||||
} catch (ex) {
|
||||
print("Strong Mode");
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
void generateOutput(String sourcePath, String outPath, String type) {
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--snapshot-kind=$type");
|
||||
args.add("--snapshot=$outPath");
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(sourcePath);
|
||||
var result = Process.runSync(exec, args);
|
||||
}
|
||||
|
||||
void generateKernel(String sourcePath, String outPath) {
|
||||
generateOutput(sourcePath, outPath, "kernel");
|
||||
}
|
||||
|
||||
void generateAppJIT(String sourcePath, String outPath) {
|
||||
generateOutput(sourcePath, outPath, "app-jit");
|
||||
}
|
||||
|
||||
void testNullSafetyMode(String filePath, String expected) {
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(filePath);
|
||||
var result = Process.runSync(exec, args);
|
||||
expect(result.stdout.contains('$expected'), true);
|
||||
}
|
||||
|
||||
void testNullSafetyMode1(String filePath, String expected) {
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add(filePath);
|
||||
var result = Process.runSync(exec, args);
|
||||
expect(result.stdout.contains('$expected'), true);
|
||||
}
|
29
tests/lib/isolate/nnbd_spawn_autodetect_1_test.dart
Normal file
29
tests/lib/isolate/nnbd_spawn_autodetect_1_test.dart
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "nnbd_spawn_autodetect_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/strong.dart";
|
||||
String dillPath = "$tmpDirPath/strong.dill";
|
||||
String jitPath = "$tmpDirPath/strong.appjit";
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
generateIsolateSource(sourcePath, "");
|
||||
generateKernel(sourcePath, dillPath);
|
||||
generateAppJIT(sourcePath, jitPath);
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another Strong Isolate using spawn.
|
||||
testNullSafetyMode(sourcePath, 're: strong');
|
||||
testNullSafetyMode(dillPath, 're: strong');
|
||||
testNullSafetyMode(jitPath, 're: strong');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
29
tests/lib/isolate/nnbd_spawn_autodetect_2_test.dart
Normal file
29
tests/lib/isolate/nnbd_spawn_autodetect_2_test.dart
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "nnbd_spawn_autodetect_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/strong.dart";
|
||||
String dillPath = "$tmpDirPath/strong.dill";
|
||||
String jitPath = "$tmpDirPath/strong.appjit";
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
generateIsolateSource(sourcePath, "2.6");
|
||||
generateKernel(sourcePath, dillPath);
|
||||
generateAppJIT(sourcePath, jitPath);
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another Strong Isolate using spawn.
|
||||
testNullSafetyMode(sourcePath, 're: weak');
|
||||
testNullSafetyMode(dillPath, 're: weak');
|
||||
testNullSafetyMode(jitPath, 're: weak');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
74
tests/lib/isolate/nnbd_spawn_autodetect_helper.dart
Normal file
74
tests/lib/isolate/nnbd_spawn_autodetect_helper.dart
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "package:async_helper/async_minitest.dart";
|
||||
|
||||
void generateIsolateSource(String filePath, String version) {
|
||||
File isolateSource = new File(filePath);
|
||||
isolateSource.writeAsStringSync('''
|
||||
// @dart=$version
|
||||
import \'dart:isolate\';
|
||||
|
||||
spawnFunc(List args) {
|
||||
var data = args[0];
|
||||
var replyTo = args[1];
|
||||
try {
|
||||
int x = null as int;
|
||||
replyTo.send(\'re: weak\');
|
||||
} catch (ex) {
|
||||
replyTo.send(\'re: strong\');
|
||||
}
|
||||
}
|
||||
|
||||
void main() async {
|
||||
const String debugName = \'spawnedIsolate\';
|
||||
final exitPort = ReceivePort();
|
||||
final port = new ReceivePort();
|
||||
port.listen((msg) {
|
||||
print(msg);
|
||||
port.close();
|
||||
});
|
||||
|
||||
final isolate = await Isolate.spawn(
|
||||
spawnFunc,
|
||||
[\'re: hi\', port.sendPort],
|
||||
paused: false,
|
||||
debugName: debugName,
|
||||
onExit: exitPort.sendPort);
|
||||
|
||||
// Explicitly await spawned isolate exit to enforce main isolate not
|
||||
// completing (and the stand-alone runtime exiting) before the spawned
|
||||
// isolate is done.
|
||||
await exitPort.first;
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
void generateOutput(String sourcePath, String outPath, String type) {
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--snapshot-kind=$type");
|
||||
args.add("--snapshot=$outPath");
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(sourcePath);
|
||||
var result = Process.runSync(exec, args);
|
||||
}
|
||||
|
||||
void generateKernel(String sourcePath, String outPath) {
|
||||
generateOutput(sourcePath, outPath, "kernel");
|
||||
}
|
||||
|
||||
void generateAppJIT(String sourcePath, String outPath) {
|
||||
generateOutput(sourcePath, outPath, "app-jit");
|
||||
}
|
||||
|
||||
void testNullSafetyMode(String filePath, String expected) {
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(filePath);
|
||||
var result = Process.runSync(exec, args);
|
||||
expect(result.stdout.contains('$expected'), true);
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "package:async_helper/async_minitest.dart";
|
||||
|
||||
void testNullSafetyMode(String filePath, String version, String expected) {
|
||||
File mainIsolate = new File(filePath);
|
||||
mainIsolate.writeAsStringSync('''
|
||||
// $version
|
||||
import \'dart:isolate\';
|
||||
|
||||
spawnFunc(List args) {
|
||||
var data = args[0];
|
||||
var replyTo = args[1];
|
||||
try {
|
||||
int x = null as int;
|
||||
replyTo.send(\'re: weak\');
|
||||
} catch (ex) {
|
||||
replyTo.send(\'re: strong\');
|
||||
}
|
||||
}
|
||||
|
||||
void main() async {
|
||||
const String debugName = \'spawnedIsolate\';
|
||||
final exitPort = ReceivePort();
|
||||
final port = new ReceivePort();
|
||||
port.listen((msg) {
|
||||
print(msg);
|
||||
port.close();
|
||||
});
|
||||
|
||||
final isolate = await Isolate.spawn(
|
||||
spawnFunc,
|
||||
[\'re: hi\', port.sendPort],
|
||||
paused: false,
|
||||
debugName: debugName,
|
||||
onExit: exitPort.sendPort);
|
||||
|
||||
// Explicitly await spawned isolate exit to enforce main isolate not
|
||||
// completing (and the stand-alone runtime exiting) before the spawned
|
||||
// isolate is done.
|
||||
await exitPort.first;
|
||||
}
|
||||
''');
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(mainIsolate.path);
|
||||
var result = Process.runSync(exec, args);
|
||||
expect(result.stdout.contains('$expected'), true);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another Strong Isolate using spawn.
|
||||
testNullSafetyMode("$tmpDirPath/strong.dart", '', 're: strong');
|
||||
|
||||
// Weak Isolate Spawning a Weak Isolate using spawn.
|
||||
testNullSafetyMode("$tmpDirPath/weak.dart", '@dart=2.6', 're: weak');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
28
tests/lib/isolate/nnbd_spawnuri_autodetect_1_test.dart
Normal file
28
tests/lib/isolate/nnbd_spawnuri_autodetect_1_test.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "nnbd_spawnuri_autodetect_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/strong_isolate.dart";
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
generateIsolateSource(sourcePath, "");
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another Strong Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/strong_strong.dart", "", sourcePath, 're: strong');
|
||||
|
||||
// Weak Isolate Spawning a Strong Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/weak_strong.dart", "2.6", sourcePath, 're: strong');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
28
tests/lib/isolate/nnbd_spawnuri_autodetect_2_test.dart
Normal file
28
tests/lib/isolate/nnbd_spawnuri_autodetect_2_test.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "nnbd_spawnuri_autodetect_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/weak_isolate.dart";
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
generateIsolateSource(sourcePath, "2.6");
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another weak Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/strong_weak.dart", "", sourcePath, 're: weak');
|
||||
|
||||
// Weak Isolate Spawning another Weak Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/weak_weak.dart", "2.6", sourcePath, 're: weak');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
30
tests/lib/isolate/nnbd_spawnuri_autodetect_3_test.dart
Normal file
30
tests/lib/isolate/nnbd_spawnuri_autodetect_3_test.dart
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "nnbd_spawnuri_autodetect_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/strong_isolate.dart";
|
||||
String outPath = "$tmpDirPath/strong_isolate.dill";
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
generateIsolateSource(sourcePath, "");
|
||||
generateKernel(sourcePath, outPath);
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another Strong Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/strong_strong.dart", "", outPath, 're: strong');
|
||||
|
||||
// Weak Isolate Spawning a Strong Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/weak_strong.dart", "2.6", outPath, 're: strong');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
29
tests/lib/isolate/nnbd_spawnuri_autodetect_4_test.dart
Normal file
29
tests/lib/isolate/nnbd_spawnuri_autodetect_4_test.dart
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "nnbd_spawnuri_autodetect_helper.dart";
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
String sourcePath = "$tmpDirPath/weak_isolate.dart";
|
||||
String outPath = "$tmpDirPath/weak_isolate.dill";
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
generateIsolateSource(sourcePath, "2.6");
|
||||
generateKernel(sourcePath, outPath);
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another weak Isolate using spawnUri.
|
||||
testNullSafetyMode("$tmpDirPath/strong_weak.dart", "", outPath, 're: weak');
|
||||
|
||||
// Weak Isolate Spawning another Weak Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/weak_weak.dart", "2.6", outPath, 're: weak');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
81
tests/lib/isolate/nnbd_spawnuri_autodetect_helper.dart
Normal file
81
tests/lib/isolate/nnbd_spawnuri_autodetect_helper.dart
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "package:async_helper/async_minitest.dart";
|
||||
|
||||
void generateIsolateSource(String filePath, String version) {
|
||||
File isolateSource = new File("$filePath");
|
||||
isolateSource.writeAsStringSync('''
|
||||
// @dart=$version
|
||||
library SpawnUriIsolate;
|
||||
main(List<String> args, replyTo) {
|
||||
var data = args[0];
|
||||
try {
|
||||
int x = null as int;
|
||||
replyTo.send(\'re: weak\');
|
||||
} catch (ex) {
|
||||
replyTo.send(\'re: strong\');
|
||||
}
|
||||
}
|
||||
''');
|
||||
}
|
||||
|
||||
void generateOutput(String sourcePath, String outPath, String type) {
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--snapshot-kind=$type");
|
||||
args.add("--snapshot=$outPath");
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(sourcePath);
|
||||
var result = Process.runSync(exec, args);
|
||||
}
|
||||
|
||||
void generateKernel(String sourcePath, String outPath) {
|
||||
generateOutput(sourcePath, outPath, "kernel");
|
||||
}
|
||||
|
||||
void generateAppJIT(String sourcePath, String outPath) {
|
||||
generateOutput(sourcePath, outPath, "app-jit");
|
||||
}
|
||||
|
||||
void testNullSafetyMode(
|
||||
String filePath, String version, String uri, String expected) {
|
||||
File mainIsolate = new File(filePath);
|
||||
mainIsolate.writeAsStringSync('''
|
||||
// @dart=$version
|
||||
library spawn_tests;
|
||||
|
||||
import \'dart:isolate\';
|
||||
|
||||
void main() async {
|
||||
const String debugName = \'spawnedIsolate\';
|
||||
final exitPort = ReceivePort();
|
||||
final port = new ReceivePort();
|
||||
port.listen((msg) {
|
||||
print(msg);
|
||||
port.close();
|
||||
});
|
||||
|
||||
final isolate = await Isolate.spawnUri(
|
||||
Uri.parse(\'$uri\'),
|
||||
[\'re: hi\'],
|
||||
port.sendPort,
|
||||
paused: false,
|
||||
debugName: debugName,
|
||||
onExit: exitPort.sendPort);
|
||||
|
||||
// Explicitly await spawned isolate exit to enforce main isolate not
|
||||
// completing (and the stand-alone runtime exiting) before the spawned
|
||||
// isolate is done.
|
||||
await exitPort.first;
|
||||
}
|
||||
''');
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(mainIsolate.path);
|
||||
var result = Process.runSync(exec, args);
|
||||
expect(result.stdout.contains('$expected'), true);
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "dart:io";
|
||||
import "package:async_helper/async_minitest.dart";
|
||||
|
||||
void testNullSafetyMode(String filePath, String uri, String expected) {
|
||||
File mainIsolate = new File(filePath);
|
||||
mainIsolate.writeAsStringSync('''
|
||||
library spawn_tests;
|
||||
|
||||
import \'dart:isolate\';
|
||||
|
||||
void main() async {
|
||||
const String debugName = \'spawnedIsolate\';
|
||||
final exitPort = ReceivePort();
|
||||
final port = new ReceivePort();
|
||||
port.listen((msg) {
|
||||
print(msg);
|
||||
port.close();
|
||||
});
|
||||
|
||||
final isolate = await Isolate.spawnUri(
|
||||
Uri.parse(\'$uri\'),
|
||||
[\'re: hi\'],
|
||||
port.sendPort,
|
||||
paused: false,
|
||||
debugName: debugName,
|
||||
onExit: exitPort.sendPort);
|
||||
|
||||
// Explicitly await spawned isolate exit to enforce main isolate not
|
||||
// completing (and the stand-alone runtime exiting) before the spawned
|
||||
// isolate is done.
|
||||
await exitPort.first;
|
||||
}
|
||||
''');
|
||||
var exec = Platform.resolvedExecutable;
|
||||
var args = <String>[];
|
||||
args.add("--enable-experiment=non-nullable");
|
||||
args.add(mainIsolate.path);
|
||||
var result = Process.runSync(exec, args);
|
||||
expect(result.stdout.contains('$expected'), true);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Create temporary directory.
|
||||
var tmpDir = Directory.systemTemp.createTempSync();
|
||||
var tmpDirPath = tmpDir.path;
|
||||
|
||||
// Generate code for an isolate to run in strong mode.
|
||||
File strongIsolate = new File("$tmpDirPath/strong_isolate.dart");
|
||||
strongIsolate.writeAsStringSync('''
|
||||
library SpawnUriStrongIsolate;
|
||||
main(List<String> args, replyTo) {
|
||||
var data = args[0];
|
||||
try {
|
||||
int x = null as int;
|
||||
replyTo.send(\'re: weak\');
|
||||
} catch (ex) {
|
||||
replyTo.send(\'re: strong\');
|
||||
}
|
||||
}
|
||||
''');
|
||||
|
||||
// Generate code for an isolate to run in weak mode.
|
||||
File weakIsolate = new File("$tmpDirPath/weak_isolate.dart");
|
||||
weakIsolate.writeAsStringSync('''
|
||||
// @dart=2.7
|
||||
library SpawnUriStrongIsolate;
|
||||
main(List<String> args, replyTo) {
|
||||
var data = args[0];
|
||||
try {
|
||||
int x = null as int;
|
||||
replyTo.send(\'re: weak\');
|
||||
} catch (ex) {
|
||||
replyTo.send(\'re: strong\');
|
||||
}
|
||||
}
|
||||
''');
|
||||
|
||||
try {
|
||||
// Strong Isolate Spawning another Strong Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/strong_strong.dart", strongIsolate.path, 're: strong');
|
||||
|
||||
// Strong Isolate Spawning a Weak Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/strong_weak.dart", weakIsolate.path, 're: weak');
|
||||
|
||||
// Weak Isolate Spawning a Strong Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/weak_strong.dart", strongIsolate.path, 're: strong');
|
||||
|
||||
// Weak Isolate Spawning a Weak Isolate using spawnUri.
|
||||
testNullSafetyMode(
|
||||
"$tmpDirPath/weak_weak.dart", weakIsolate.path, 're: weak');
|
||||
} finally {
|
||||
tmpDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
|
@ -79,6 +79,8 @@ isolate/count_test: Skip # Isolate.spawnUri
|
|||
isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
|
||||
isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
|
||||
isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
|
||||
isolate/detect_nullsafety_1_test: Skip # Tests Source, Kernel, appJIT modes
|
||||
isolate/detect_nullsafety_2_test: Skip # Tests Source, Kernel, appJIT modes
|
||||
isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
|
||||
isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
|
||||
isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
|
||||
|
@ -95,8 +97,12 @@ isolate/message_test: Skip # Isolate.spawnUri
|
|||
isolate/mint_maker_test: Skip # Isolate.spawnUri
|
||||
isolate/nested_spawn2_test: Skip # Isolate.spawnUri
|
||||
isolate/nested_spawn_test: Skip # Isolate.spawnUri
|
||||
isolate/nnbd_spawn_autodetect_test: Skip # Auto detect not for precompiled.
|
||||
isolate/nnbd_spawnuri_autodetect_test: Skip # Auto detect not for precompiled.
|
||||
isolate/nnbd_spawn_autodetect_1_test: Skip # Tests Source, Kernel, appJIT modes
|
||||
isolate/nnbd_spawn_autodetect_2_test: Skip # Tests Source, Kernel, appJIT modes
|
||||
isolate/nnbd_spawnuri_autodetect_1_test: Skip # Uses Isolate.spawnUri
|
||||
isolate/nnbd_spawnuri_autodetect_2_test: Skip # Uses Isolate.spawnUri
|
||||
isolate/nnbd_spawnuri_autodetect_3_test: Skip # Uses Isolate.spawnUri
|
||||
isolate/nnbd_spawnuri_autodetect_4_test: Skip # Uses Isolate.spawnUri
|
||||
isolate/no_package_test: Skip # Isolate.spawnUri
|
||||
isolate/package_config_test: Skip # Isolate.spawnUri
|
||||
isolate/raw_port_test: Skip # Isolate.spawnUri
|
||||
|
|
Loading…
Reference in a new issue