Skip to content

Commit 5a843eb

Browse files
committed
Add "checked" parameter to Isolate.spawnUri.
R=iposva@google.com Review URL: https://codereview.chromium.org//1154673004
1 parent 683743c commit 5a843eb

File tree

9 files changed

+112
-27
lines changed

9 files changed

+112
-27
lines changed

runtime/lib/isolate.cc

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,13 @@ static bool CreateIsolate(Isolate* parent_isolate,
181181
if (child_isolate == NULL) {
182182
return false;
183183
}
184+
// TODO(iposva): Evaluate whether it's ok to override the embedder's setup.
185+
// Currently the strict_compilation flag is ignored if it's false and
186+
// checked-mode was enabled using a command-line flag. The command-line flag
187+
// overrides the user code's request.
188+
child_isolate->set_strict_compilation(state->checked_mode());
184189
if (!state->is_spawn_uri()) {
185-
// For isolates spawned using the spawnFunction semantics we set
190+
// For isolates spawned using the spawn semantics we set
186191
// the origin_id to the origin_id of the parent isolate.
187192
child_isolate->set_origin_id(parent_isolate->origin_id());
188193
}
@@ -229,10 +234,12 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 4) {
229234
#endif
230235
// Get the parent function so that we get the right function name.
231236
func = func.parent_function();
237+
bool checkedFlag = isolate->strict_compilation();
232238
Spawn(isolate, new IsolateSpawnState(port.Id(),
233239
func,
234240
message,
235-
paused.value()));
241+
paused.value(),
242+
checkedFlag));
236243
return Object::null();
237244
}
238245
}
@@ -243,13 +250,14 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 4) {
243250
}
244251

245252

246-
DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 6) {
253+
DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 7) {
247254
GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
248255
GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(1));
249256
GET_NON_NULL_NATIVE_ARGUMENT(Instance, args, arguments->NativeArgAt(2));
250257
GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(3));
251258
GET_NON_NULL_NATIVE_ARGUMENT(Bool, paused, arguments->NativeArgAt(4));
252-
GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(5));
259+
GET_NATIVE_ARGUMENT(Bool, checked, arguments->NativeArgAt(5));
260+
GET_NATIVE_ARGUMENT(String, package_root, arguments->NativeArgAt(6));
253261

254262
// Canonicalize the uri with respect to the current isolate.
255263
char* error = NULL;
@@ -270,12 +278,20 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 6) {
270278
utf8_package_root[len] = '\0';
271279
}
272280

281+
bool checkedFlag;
282+
if (checked.IsNull()) {
283+
checkedFlag = isolate->strict_compilation();
284+
} else {
285+
checkedFlag = checked.value();
286+
}
287+
273288
Spawn(isolate, new IsolateSpawnState(port.Id(),
274289
canonical_uri,
275290
utf8_package_root,
276291
args,
277292
message,
278-
paused.value()));
293+
paused.value(),
294+
checkedFlag));
279295
return Object::null();
280296
}
281297

runtime/lib/isolate_patch.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,16 +303,15 @@ patch class Isolate {
303303

304304
/* patch */ static Future<Isolate> spawnUri(
305305
Uri uri, List<String> args, var message,
306-
{ bool paused: false, Uri packageRoot }) {
307-
// `paused` isn't handled yet.
306+
{ bool paused: false, bool checked, Uri packageRoot }) {
308307
RawReceivePort readyPort;
309308
try {
310309
// The VM will invoke [_startIsolate] and not `main`.
311310
readyPort = new RawReceivePort();
312311
var packageRootString =
313312
(packageRoot == null) ? null : packageRoot.toString();
314313
_spawnUri(readyPort.sendPort, uri.toString(), args, message,
315-
paused, packageRootString);
314+
paused, checked, packageRootString);
316315
Completer completer = new Completer<Isolate>.sync();
317316
readyPort.handler = (readyMessage) {
318317
readyPort.close();
@@ -354,7 +353,7 @@ patch class Isolate {
354353

355354
static void _spawnUri(SendPort readyPort, String uri,
356355
List<String> args, var message,
357-
bool paused, String packageRoot)
356+
bool paused, bool checked, String packageRoot)
358357
native "Isolate_spawnUri";
359358

360359
static void _sendOOB(port, msg) native "Isolate_sendOOB";

runtime/vm/bootstrap_natives.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ namespace dart {
293293
V(Int32x4_setFlagW, 2) \
294294
V(Int32x4_select, 3) \
295295
V(Isolate_spawnFunction, 4) \
296-
V(Isolate_spawnUri, 6) \
296+
V(Isolate_spawnUri, 7) \
297297
V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) \
298298
V(Isolate_sendOOB, 2) \
299299
V(Mirrors_evalInLibraryWithPrivateKey, 2) \

runtime/vm/isolate.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,7 +1799,8 @@ static RawInstance* DeserializeObject(Isolate* isolate,
17991799
IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
18001800
const Function& func,
18011801
const Instance& message,
1802-
bool paused)
1802+
bool paused,
1803+
bool checkedFlag)
18031804
: isolate_(NULL),
18041805
parent_port_(parent_port),
18051806
script_url_(NULL),
@@ -1811,7 +1812,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
18111812
serialized_args_len_(0),
18121813
serialized_message_(NULL),
18131814
serialized_message_len_(0),
1814-
paused_(paused) {
1815+
paused_(paused),
1816+
checked_(checkedFlag) {
18151817
script_url_ = NULL;
18161818
const Class& cls = Class::Handle(func.Owner());
18171819
const Library& lib = Library::Handle(cls.library());
@@ -1837,7 +1839,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
18371839
const char* package_root,
18381840
const Instance& args,
18391841
const Instance& message,
1840-
bool paused)
1842+
bool paused,
1843+
bool checkedFlag)
18411844
: isolate_(NULL),
18421845
parent_port_(parent_port),
18431846
package_root_(NULL),
@@ -1848,7 +1851,8 @@ IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
18481851
serialized_args_len_(0),
18491852
serialized_message_(NULL),
18501853
serialized_message_len_(0),
1851-
paused_(paused) {
1854+
paused_(paused),
1855+
checked_(checkedFlag) {
18521856
script_url_ = strdup(script_url);
18531857
if (package_root != NULL) {
18541858
package_root_ = strdup(package_root);

runtime/vm/isolate.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -926,13 +926,15 @@ class IsolateSpawnState {
926926
IsolateSpawnState(Dart_Port parent_port,
927927
const Function& func,
928928
const Instance& message,
929-
bool paused);
929+
bool paused,
930+
bool checked);
930931
IsolateSpawnState(Dart_Port parent_port,
931932
const char* script_url,
932933
const char* package_root,
933934
const Instance& args,
934935
const Instance& message,
935-
bool paused);
936+
bool paused,
937+
bool checked);
936938
~IsolateSpawnState();
937939

938940
Isolate* isolate() const { return isolate_; }
@@ -946,6 +948,7 @@ class IsolateSpawnState {
946948
char* function_name() const { return function_name_; }
947949
bool is_spawn_uri() const { return library_url_ == NULL; }
948950
bool paused() const { return paused_; }
951+
bool checked_mode() const { return checked_; }
949952

950953
RawObject* ResolveFunction();
951954
RawInstance* BuildArgs(Zone* zone);
@@ -965,6 +968,7 @@ class IsolateSpawnState {
965968
uint8_t* serialized_message_;
966969
intptr_t serialized_message_len_;
967970
bool paused_;
971+
bool checked_;
968972
};
969973

970974
} // namespace dart

sdk/lib/_internal/compiler/js_lib/isolate_patch.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Isolate {
3737
@patch
3838
static Future<Isolate> spawnUri(
3939
Uri uri, List<String> args, var message, { bool paused: false,
40+
bool checked,
4041
Uri packageRoot }) {
4142
if (packageRoot != null) throw new UnimplementedError("packageRoot");
4243
try {

sdk/lib/isolate/isolate.dart

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,6 @@ class Isolate {
148148
* before it starts running.
149149
* To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
150150
*
151-
* WARNING: The `pause` parameter is not implemented on all platforms yet.
152-
*
153151
* Returns a future that will complete with an [Isolate] instance if the
154152
* spawning succeeded. It will complete with an error otherwise.
155153
*/
@@ -172,6 +170,26 @@ class Isolate {
172170
* When present, the parameter `args` is set to the provided [args] list.
173171
* When present, the parameter `message` is set to the initial [message].
174172
*
173+
* If the [paused] parameter is set to `true`,
174+
* the isolate will start up in a paused state,
175+
* as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
176+
* This allows setting up error or exit listeners on the isolate
177+
* before it starts running.
178+
* To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
179+
*
180+
* If the [checked] parameter is set to `true` or `false`,
181+
* the new isolate will run code in checked mode,
182+
* respectively in production mode, if possible.
183+
* If the parameter is omitted, the new isolate will inherit the
184+
* value from the current isolate.
185+
*
186+
* It may not always be possible to honor the `checked` parameter.
187+
* If the isolate code was pre-compiled, it may not be possible to change
188+
* the checked mode setting dynamically.
189+
* In that case, the `checked` parameter is ignored.
190+
*
191+
* WARNING: The [checked] parameter is not implemented on all platforms yet.
192+
*
175193
* If the [packageRoot] parameter is provided, it is used to find the location
176194
* of packages imports in the spawned isolate.
177195
* The `packageRoot` URI must be a "file" or "http"/"https" URI that specifies
@@ -187,15 +205,6 @@ class Isolate {
187205
* WARNING: The [packageRoot] parameter is not implemented on all
188206
* platforms yet.
189207
*
190-
* If the [paused] parameter is set to `true`,
191-
* the isolate will start up in a paused state,
192-
* as if by an initial call of `isolate.pause(isolate.pauseCapability)`.
193-
* This allows setting up error or exit listeners on the isolate
194-
* before it starts running.
195-
* To resume the isolate, call `isolate.resume(isolate.pauseCapability)`.
196-
*
197-
* WARNING: The `pause` parameter is not implemented on all platforms yet.
198-
*
199208
* Returns a future that will complete with an [Isolate] instance if the
200209
* spawning succeeded. It will complete with an error otherwise.
201210
*/
@@ -204,6 +213,7 @@ class Isolate {
204213
List<String> args,
205214
var message,
206215
{bool paused: false,
216+
bool checked,
207217
Uri packageRoot});
208218

209219
/**

tests/isolate/checked_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import "dart:isolate";
6+
import "dart:async";
7+
import "package:expect/expect.dart";
8+
import "package:async_helper/async_helper.dart";
9+
10+
void main([args, message]) {
11+
if (message != null) return isolateMain(message);
12+
13+
bool isChecked = false;
14+
assert((isChecked = true));
15+
if (isChecked) return; // Skip this test in checked mode.
16+
17+
var responses = {};
18+
var port = new RawReceivePort();
19+
port.handler = (pair) {
20+
responses[pair[0]] = pair[1];
21+
if (responses.length == 3) {
22+
port.close();
23+
Expect.isTrue(responses[true], "true @ $isChecked");
24+
Expect.isTrue(responses[false], "false @ $isChecked");
25+
Expect.isTrue(responses[null], "null @ $isChecked");
26+
}
27+
};
28+
test(checked) {
29+
Isolate.spawnUri(Uri.parse("checked_test.dart"), [],
30+
[checked, isChecked, port.sendPort],
31+
checked: checked);
32+
}
33+
test(true);
34+
test(false);
35+
test(null);
36+
}
37+
38+
39+
void isolateMain(args) {
40+
var checkedFlag = args[0];
41+
var parentIsChecked = args[1];
42+
var responsePort = args[2];
43+
bool isChecked = false;
44+
assert((isChecked = true));
45+
bool expected = checkedFlag;
46+
if (checkedFlag == null) expected = parentIsChecked;
47+
responsePort.send([checkedFlag, expected == isChecked]);
48+
}

tests/isolate/isolate.status

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
browser/*: SkipByDesign # Browser specific tests
77
isolate_stress_test: Fail # Issue 12588: This should be able to pass when we have wrapper-less tests.
88

9+
[ $runtime != vm ]
10+
checked_test: Skip # Unsupported.
11+
912
[ $runtime == vm && $arch == mips && $mode == debug ]
1013
mandel_isolate_test: Skip # Uses 600 MB Ram on our 1 GB test device.
1114

0 commit comments

Comments
 (0)