Add "checked" parameter to Isolate.spawnUri.

R=iposva@google.com

Review URL: https://codereview.chromium.org//1154673004
This commit is contained in:
Lasse R.H. Nielsen 2015-06-03 12:32:52 +02:00
parent 683743c9c5
commit 5a843ebbf3
9 changed files with 112 additions and 27 deletions

View file

@ -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();
}

View file

@ -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";

View file

@ -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) \

View file

@ -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);

View file

@ -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

View file

@ -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 {

View file

@ -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});
/**

View 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]);
}

View file

@ -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.