mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:27:43 +00:00
Add "checked" parameter to Isolate.spawnUri.
R=iposva@google.com Review URL: https://codereview.chromium.org//1154673004
This commit is contained in:
parent
683743c9c5
commit
5a843ebbf3
|
@ -181,8 +181,13 @@ static bool CreateIsolate(Isolate* parent_isolate,
|
|||
if (child_isolate == NULL) {
|
||||
return false;
|
||||
}
|
||||
// TODO(iposva): Evaluate whether it's ok to override the embedder's setup.
|
||||
// Currently the strict_compilation flag is ignored if it's false and
|
||||
// checked-mode was enabled using a command-line flag. The command-line flag
|
||||
// overrides the user code's request.
|
||||
child_isolate->set_strict_compilation(state->checked_mode());
|
||||
if (!state->is_spawn_uri()) {
|
||||
// For isolates spawned using the spawnFunction semantics we set
|
||||
// For isolates spawned using the spawn semantics we set
|
||||
// the origin_id to the origin_id of the parent isolate.
|
||||
child_isolate->set_origin_id(parent_isolate->origin_id());
|
||||
}
|
||||
|
@ -229,10 +234,12 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 4) {
|
|||
#endif
|
||||
// Get the parent function so that we get the right function name.
|
||||
func = func.parent_function();
|
||||
bool checkedFlag = isolate->strict_compilation();
|
||||
Spawn(isolate, new IsolateSpawnState(port.Id(),
|
||||
func,
|
||||
message,
|
||||
paused.value()));
|
||||
paused.value(),
|
||||
checkedFlag));
|
||||
return Object::null();
|
||||
}
|
||||
}
|
||||
|
@ -243,13 +250,14 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 4) {
|
|||
}
|
||||
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 6) {
|
||||
DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 7) {
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
|
||||
GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(5));
|
||||
GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(5));
|
||||
GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(6));
|
||||
|
||||
// Canonicalize the uri with respect to the current isolate.
|
||||
char* error = NULL;
|
||||
|
@ -270,12 +278,20 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 6) {
|
|||
utf8_package_root[len] = '\0';
|
||||
}
|
||||
|
||||
bool checkedFlag;
|
||||
if (checked.IsNull()) {
|
||||
checkedFlag = isolate->strict_compilation();
|
||||
} else {
|
||||
checkedFlag = checked.value();
|
||||
}
|
||||
|
||||
Spawn(isolate, new IsolateSpawnState(port.Id(),
|
||||
canonical_uri,
|
||||
utf8_package_root,
|
||||
args,
|
||||
message,
|
||||
paused.value()));
|
||||
paused.value(),
|
||||
checkedFlag));
|
||||
return Object::null();
|
||||
}
|
||||
|
||||
|
|
|
@ -303,8 +303,7 @@ patch class Isolate {
|
|||
|
||||
/* patch */ static Future<Isolate> spawnUri(
|
||||
Uri uri, List<String> args, var message,
|
||||
{ bool paused: false, Uri packageRoot }) {
|
||||
// `paused` isn't handled yet.
|
||||
{ bool paused: false, bool checked, Uri packageRoot }) {
|
||||
RawReceivePort readyPort;
|
||||
try {
|
||||
// The VM will invoke [_startIsolate] and not `main`.
|
||||
|
@ -312,7 +311,7 @@ patch class Isolate {
|
|||
var packageRootString =
|
||||
(packageRoot == null) ? null : packageRoot.toString();
|
||||
_spawnUri(readyPort.sendPort, uri.toString(), args, message,
|
||||
paused, packageRootString);
|
||||
paused, checked, packageRootString);
|
||||
Completer completer = new Completer<Isolate>.sync();
|
||||
readyPort.handler = (readyMessage) {
|
||||
readyPort.close();
|
||||
|
@ -354,7 +353,7 @@ patch class Isolate {
|
|||
|
||||
static void _spawnUri(SendPort readyPort, String uri,
|
||||
List<String> args, var message,
|
||||
bool paused, String packageRoot)
|
||||
bool paused, bool checked, String packageRoot)
|
||||
native "Isolate_spawnUri";
|
||||
|
||||
static void _sendOOB(port, msg) native "Isolate_sendOOB";
|
||||
|
|
|
@ -293,7 +293,7 @@ namespace dart {
|
|||
V(Int32x4_setFlagW, 2) \
|
||||
V(Int32x4_select, 3) \
|
||||
V(Isolate_spawnFunction, 4) \
|
||||
V(Isolate_spawnUri, 6) \
|
||||
V(Isolate_spawnUri, 7) \
|
||||
V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) \
|
||||
V(Isolate_sendOOB, 2) \
|
||||
V(Mirrors_evalInLibraryWithPrivateKey, 2) \
|
||||
|
|
|
@ -1799,7 +1799,8 @@ static RawInstance* DeserializeObject(Isolate* isolate,
|
|||
IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
||||
const Function& func,
|
||||
const Instance& message,
|
||||
bool paused)
|
||||
bool paused,
|
||||
bool checkedFlag)
|
||||
: isolate_(NULL),
|
||||
parent_port_(parent_port),
|
||||
script_url_(NULL),
|
||||
|
@ -1811,7 +1812,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
|||
serialized_args_len_(0),
|
||||
serialized_message_(NULL),
|
||||
serialized_message_len_(0),
|
||||
paused_(paused) {
|
||||
paused_(paused),
|
||||
checked_(checkedFlag) {
|
||||
script_url_ = NULL;
|
||||
const Class& cls = Class::Handle(func.Owner());
|
||||
const Library& lib = Library::Handle(cls.library());
|
||||
|
@ -1837,7 +1839,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
|||
const char* package_root,
|
||||
const Instance& args,
|
||||
const Instance& message,
|
||||
bool paused)
|
||||
bool paused,
|
||||
bool checkedFlag)
|
||||
: isolate_(NULL),
|
||||
parent_port_(parent_port),
|
||||
package_root_(NULL),
|
||||
|
@ -1848,7 +1851,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
|
|||
serialized_args_len_(0),
|
||||
serialized_message_(NULL),
|
||||
serialized_message_len_(0),
|
||||
paused_(paused) {
|
||||
paused_(paused),
|
||||
checked_(checkedFlag) {
|
||||
script_url_ = strdup(script_url);
|
||||
if (package_root != NULL) {
|
||||
package_root_ = strdup(package_root);
|
||||
|
|
|
@ -926,13 +926,15 @@ class IsolateSpawnState {
|
|||
IsolateSpawnState(Dart_Port parent_port,
|
||||
const Function& func,
|
||||
const Instance& message,
|
||||
bool paused);
|
||||
bool paused,
|
||||
bool checked);
|
||||
IsolateSpawnState(Dart_Port parent_port,
|
||||
const char* script_url,
|
||||
const char* package_root,
|
||||
const Instance& args,
|
||||
const Instance& message,
|
||||
bool paused);
|
||||
bool paused,
|
||||
bool checked);
|
||||
~IsolateSpawnState();
|
||||
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
|
@ -946,6 +948,7 @@ class IsolateSpawnState {
|
|||
char* function_name() const { return function_name_; }
|
||||
bool is_spawn_uri() const { return library_url_ == NULL; }
|
||||
bool paused() const { return paused_; }
|
||||
bool checked_mode() const { return checked_; }
|
||||
|
||||
RawObject* ResolveFunction();
|
||||
RawInstance* BuildArgs(Zone* zone);
|
||||
|
@ -965,6 +968,7 @@ class IsolateSpawnState {
|
|||
uint8_t* serialized_message_;
|
||||
intptr_t serialized_message_len_;
|
||||
bool paused_;
|
||||
bool checked_;
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -37,6 +37,7 @@ class Isolate {
|
|||
@patch
|
||||
static Future<Isolate> spawnUri(
|
||||
Uri uri, List<String> args, var message, { bool paused: false,
|
||||
bool checked,
|
||||
Uri packageRoot }) {
|
||||
if (packageRoot != null) throw new UnimplementedError("packageRoot");
|
||||
try {
|
||||
|
|
|
@ -148,8 +148,6 @@ class Isolate {
|
|||
* before it starts running.
|
||||
* To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
|
||||
*
|
||||
* WARNING: The `pause` parameter is not implemented on all platforms yet.
|
||||
*
|
||||
* Returns a future that will complete with an [Isolate] instance if the
|
||||
* spawning succeeded. It will complete with an error otherwise.
|
||||
*/
|
||||
|
@ -172,6 +170,26 @@ class Isolate {
|
|||
* When present, the parameter `args` is set to the provided [args] list.
|
||||
* When present, the parameter `message` is set to the initial [message].
|
||||
*
|
||||
* If the [paused] parameter is set to `true`,
|
||||
* the isolate will start up in a paused state,
|
||||
* as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
|
||||
* This allows setting up error or exit listeners on the isolate
|
||||
* before it starts running.
|
||||
* To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
|
||||
*
|
||||
* If the [checked] parameter is set to `true` or `false`,
|
||||
* the new isolate will run code in checked mode,
|
||||
* respectively in production mode, if possible.
|
||||
* If the parameter is omitted, the new isolate will inherit the
|
||||
* value from the current isolate.
|
||||
*
|
||||
* It may not always be possible to honor the `checked` parameter.
|
||||
* If the isolate code was pre-compiled, it may not be possible to change
|
||||
* the checked mode setting dynamically.
|
||||
* In that case, the `checked` parameter is ignored.
|
||||
*
|
||||
* WARNING: The [checked] parameter is not implemented on all platforms yet.
|
||||
*
|
||||
* If the [packageRoot] parameter is provided, it is used to find the location
|
||||
* of packages imports in the spawned isolate.
|
||||
* The `packageRoot` URI must be a "file" or "http"/"https" URI that specifies
|
||||
|
@ -187,15 +205,6 @@ class Isolate {
|
|||
* WARNING: The [packageRoot] parameter is not implemented on all
|
||||
* platforms yet.
|
||||
*
|
||||
* If the [paused] parameter is set to `true`,
|
||||
* the isolate will start up in a paused state,
|
||||
* as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
|
||||
* This allows setting up error or exit listeners on the isolate
|
||||
* before it starts running.
|
||||
* To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
|
||||
*
|
||||
* WARNING: The `pause` parameter is not implemented on all platforms yet.
|
||||
*
|
||||
* Returns a future that will complete with an [Isolate] instance if the
|
||||
* spawning succeeded. It will complete with an error otherwise.
|
||||
*/
|
||||
|
@ -204,6 +213,7 @@ class Isolate {
|
|||
List<String> args,
|
||||
var message,
|
||||
{bool paused: false,
|
||||
bool checked,
|
||||
Uri packageRoot});
|
||||
|
||||
/**
|
||||
|
|
48
tests/isolate/checked_test.dart
Normal file
48
tests/isolate/checked_test.dart
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) 2014, 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:isolate";
|
||||
import "dart:async";
|
||||
import "package:expect/expect.dart";
|
||||
import "package:async_helper/async_helper.dart";
|
||||
|
||||
void main([args, message]) {
|
||||
if (message != null) return isolateMain(message);
|
||||
|
||||
bool isChecked = false;
|
||||
assert((isChecked = true));
|
||||
if (isChecked) return; // Skip this test in checked mode.
|
||||
|
||||
var responses = {};
|
||||
var port = new RawReceivePort();
|
||||
port.handler = (pair) {
|
||||
responses[pair[0]] = pair[1];
|
||||
if (responses.length == 3) {
|
||||
port.close();
|
||||
Expect.isTrue(responses[true], "true @ $isChecked");
|
||||
Expect.isTrue(responses[false], "false @ $isChecked");
|
||||
Expect.isTrue(responses[null], "null @ $isChecked");
|
||||
}
|
||||
};
|
||||
test(checked) {
|
||||
Isolate.spawnUri(Uri.parse("checked_test.dart"), [],
|
||||
[checked, isChecked, port.sendPort],
|
||||
checked: checked);
|
||||
}
|
||||
test(true);
|
||||
test(false);
|
||||
test(null);
|
||||
}
|
||||
|
||||
|
||||
void isolateMain(args) {
|
||||
var checkedFlag = args[0];
|
||||
var parentIsChecked = args[1];
|
||||
var responsePort = args[2];
|
||||
bool isChecked = false;
|
||||
assert((isChecked = true));
|
||||
bool expected = checkedFlag;
|
||||
if (checkedFlag == null) expected = parentIsChecked;
|
||||
responsePort.send([checkedFlag, expected == isChecked]);
|
||||
}
|
|
@ -6,6 +6,9 @@
|
|||
browser/*: SkipByDesign # Browser specific tests
|
||||
isolate_stress_test: Fail # Issue 12588: This should be able to pass when we have wrapper-less tests.
|
||||
|
||||
[ $runtime != vm ]
|
||||
checked_test: Skip # Unsupported.
|
||||
|
||||
[ $runtime == vm && $arch == mips && $mode == debug ]
|
||||
mandel_isolate_test: Skip # Uses 600 MB Ram on our 1 GB test device.
|
||||
|
||||
|
|
Loading…
Reference in a new issue