OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import "dart:collection" show HashMap; | 5 import "dart:collection" show HashMap; |
6 import "dart:_internal" hide Symbol; | 6 import "dart:_internal" hide Symbol; |
7 | 7 |
8 @patch class ReceivePort { | 8 @patch |
9 @patch factory ReceivePort() = _ReceivePortImpl; | 9 class ReceivePort { |
| 10 @patch |
| 11 factory ReceivePort() = _ReceivePortImpl; |
10 | 12 |
11 @patch factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) = | 13 @patch |
| 14 factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) = |
12 _ReceivePortImpl.fromRawReceivePort; | 15 _ReceivePortImpl.fromRawReceivePort; |
13 } | 16 } |
14 | 17 |
15 @patch class Capability { | 18 @patch |
16 @patch factory Capability() = _CapabilityImpl; | 19 class Capability { |
| 20 @patch |
| 21 factory Capability() = _CapabilityImpl; |
17 } | 22 } |
18 | 23 |
19 class _CapabilityImpl implements Capability { | 24 class _CapabilityImpl implements Capability { |
20 factory _CapabilityImpl() native "CapabilityImpl_factory"; | 25 factory _CapabilityImpl() native "CapabilityImpl_factory"; |
21 | 26 |
22 bool operator==(var other) { | 27 bool operator ==(var other) { |
23 return (other is _CapabilityImpl) && _equals(other); | 28 return (other is _CapabilityImpl) && _equals(other); |
24 } | 29 } |
25 | 30 |
26 int get hashCode { | 31 int get hashCode { |
27 return _get_hashcode(); | 32 return _get_hashcode(); |
28 } | 33 } |
29 | 34 |
30 _equals(other) native "CapabilityImpl_equals"; | 35 _equals(other) native "CapabilityImpl_equals"; |
31 _get_hashcode() native "CapabilityImpl_get_hashcode"; | 36 _get_hashcode() native "CapabilityImpl_get_hashcode"; |
32 } | 37 } |
33 | 38 |
34 @patch class RawReceivePort { | 39 @patch |
| 40 class RawReceivePort { |
35 /** | 41 /** |
36 * Opens a long-lived port for receiving messages. | 42 * Opens a long-lived port for receiving messages. |
37 * | 43 * |
38 * A [RawReceivePort] is low level and does not work with [Zone]s. It | 44 * A [RawReceivePort] is low level and does not work with [Zone]s. It |
39 * can not be paused. The data-handler must be set before the first | 45 * can not be paused. The data-handler must be set before the first |
40 * event is received. | 46 * event is received. |
41 */ | 47 */ |
42 @patch factory RawReceivePort([void handler(event)]) { | 48 @patch |
| 49 factory RawReceivePort([void handler(event)]) { |
43 _RawReceivePortImpl result = new _RawReceivePortImpl(); | 50 _RawReceivePortImpl result = new _RawReceivePortImpl(); |
44 result.handler = handler; | 51 result.handler = handler; |
45 return result; | 52 return result; |
46 } | 53 } |
47 } | 54 } |
48 | 55 |
49 class _ReceivePortImpl extends Stream implements ReceivePort { | 56 class _ReceivePortImpl extends Stream implements ReceivePort { |
50 _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort()); | 57 _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort()); |
51 | 58 |
52 _ReceivePortImpl.fromRawReceivePort(this._rawPort) { | 59 _ReceivePortImpl.fromRawReceivePort(this._rawPort) { |
53 _controller = new StreamController(onCancel: close, sync: true); | 60 _controller = new StreamController(onCancel: close, sync: true); |
54 _rawPort.handler = _controller.add; | 61 _rawPort.handler = _controller.add; |
55 } | 62 } |
56 | 63 |
57 SendPort get sendPort { | 64 SendPort get sendPort { |
58 return _rawPort.sendPort; | 65 return _rawPort.sendPort; |
59 } | 66 } |
60 | 67 |
61 StreamSubscription listen(void onData(var message), | 68 StreamSubscription listen(void onData(var message), |
62 { Function onError, | 69 {Function onError, void onDone(), bool cancelOnError}) { |
63 void onDone(), | |
64 bool cancelOnError }) { | |
65 return _controller.stream.listen(onData, | 70 return _controller.stream.listen(onData, |
66 onError: onError, | 71 onError: onError, onDone: onDone, cancelOnError: cancelOnError); |
67 onDone: onDone, | |
68 cancelOnError: cancelOnError); | |
69 } | 72 } |
70 | 73 |
71 close() { | 74 close() { |
72 _rawPort.close(); | 75 _rawPort.close(); |
73 _controller.close(); | 76 _controller.close(); |
74 } | 77 } |
75 | 78 |
76 final RawReceivePort _rawPort; | 79 final RawReceivePort _rawPort; |
77 StreamController _controller; | 80 StreamController _controller; |
78 } | 81 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 | 117 |
115 close() { | 118 close() { |
116 // Close the port and remove it from the handler map. | 119 // Close the port and remove it from the handler map. |
117 _handlerMap.remove(this._closeInternal()); | 120 _handlerMap.remove(this._closeInternal()); |
118 } | 121 } |
119 | 122 |
120 SendPort get sendPort { | 123 SendPort get sendPort { |
121 return _get_sendport(); | 124 return _get_sendport(); |
122 } | 125 } |
123 | 126 |
124 bool operator==(var other) { | 127 bool operator ==(var other) { |
125 return (other is _RawReceivePortImpl) && | 128 return (other is _RawReceivePortImpl) && |
126 (this._get_id() == other._get_id()); | 129 (this._get_id() == other._get_id()); |
127 } | 130 } |
128 | 131 |
129 int get hashCode { | 132 int get hashCode { |
130 return sendPort.hashCode; | 133 return sendPort.hashCode; |
131 } | 134 } |
132 | 135 |
133 /**** Internal implementation details ****/ | 136 /**** Internal implementation details ****/ |
134 _get_id() native "RawReceivePortImpl_get_id"; | 137 _get_id() native "RawReceivePortImpl_get_id"; |
(...skipping 25 matching lines...) Expand all Loading... |
160 // id to handler mapping. | 163 // id to handler mapping. |
161 static _initHandlerMap() { | 164 static _initHandlerMap() { |
162 // TODO(18511): Workaround bad CheckSmi hoisting. | 165 // TODO(18511): Workaround bad CheckSmi hoisting. |
163 var tempMap = new HashMap(); | 166 var tempMap = new HashMap(); |
164 // Collect feedback that not all keys are Smis. | 167 // Collect feedback that not all keys are Smis. |
165 tempMap["."] = 1; | 168 tempMap["."] = 1; |
166 tempMap["."] = 2; | 169 tempMap["."] = 2; |
167 | 170 |
168 return new HashMap(); | 171 return new HashMap(); |
169 } | 172 } |
| 173 |
170 static final Map _handlerMap = _initHandlerMap(); | 174 static final Map _handlerMap = _initHandlerMap(); |
171 } | 175 } |
172 | 176 |
173 | |
174 class _SendPortImpl implements SendPort { | 177 class _SendPortImpl implements SendPort { |
175 /*--- public interface ---*/ | 178 /*--- public interface ---*/ |
176 void send(var message) { | 179 void send(var message) { |
177 _sendInternal(message); | 180 _sendInternal(message); |
178 } | 181 } |
179 | 182 |
180 bool operator==(var other) { | 183 bool operator ==(var other) { |
181 return (other is _SendPortImpl) && (this._get_id() == other._get_id()); | 184 return (other is _SendPortImpl) && (this._get_id() == other._get_id()); |
182 } | 185 } |
183 | 186 |
184 int get hashCode { | 187 int get hashCode { |
185 return _get_hashcode(); | 188 return _get_hashcode(); |
186 } | 189 } |
187 | 190 |
188 /*--- private implementation ---*/ | 191 /*--- private implementation ---*/ |
189 _get_id() native "SendPortImpl_get_id"; | 192 _get_id() native "SendPortImpl_get_id"; |
190 _get_hashcode() native "SendPortImpl_get_hashcode"; | 193 _get_hashcode() native "SendPortImpl_get_hashcode"; |
191 | 194 |
192 // Forward the implementation of sending messages to the VM. | 195 // Forward the implementation of sending messages to the VM. |
193 void _sendInternal(var message) native "SendPortImpl_sendInternal_"; | 196 void _sendInternal(var message) native "SendPortImpl_sendInternal_"; |
194 } | 197 } |
195 | 198 |
196 typedef _NullaryFunction(); | 199 typedef _NullaryFunction(); |
197 typedef _UnaryFunction(args); | 200 typedef _UnaryFunction(args); |
198 typedef _BinaryFunction(args, message); | 201 typedef _BinaryFunction(args, message); |
199 | 202 |
200 /** | 203 /** |
201 * Takes the real entry point as argument and invokes it with the | 204 * Takes the real entry point as argument and invokes it with the |
202 * initial message. Defers execution of the entry point until the | 205 * initial message. Defers execution of the entry point until the |
203 * isolate is in the message loop. | 206 * isolate is in the message loop. |
204 */ | 207 */ |
205 void _startMainIsolate(Function entryPoint, | 208 void _startMainIsolate(Function entryPoint, List<String> args) { |
206 List<String> args) { | 209 _startIsolate( |
207 _startIsolate(null, // no parent port | 210 null, // no parent port |
208 entryPoint, | 211 entryPoint, |
209 args, | 212 args, |
210 null, // no message | 213 null, // no message |
211 true, // isSpawnUri | 214 true, // isSpawnUri |
212 null, // no control port | 215 null, // no control port |
213 null); // no capabilities | 216 null); // no capabilities |
214 } | 217 } |
215 | 218 |
216 /** | 219 /** |
217 * Takes the real entry point as argument and invokes it with the initial | 220 * Takes the real entry point as argument and invokes it with the initial |
218 * message. | 221 * message. |
219 */ | 222 */ |
220 void _startIsolate(SendPort parentPort, | 223 void _startIsolate( |
221 Function entryPoint, | 224 SendPort parentPort, |
222 List<String> args, | 225 Function entryPoint, |
223 var message, | 226 List<String> args, |
224 bool isSpawnUri, | 227 var message, |
225 RawReceivePort controlPort, | 228 bool isSpawnUri, |
226 List capabilities) { | 229 RawReceivePort controlPort, |
| 230 List capabilities) { |
227 // The control port (aka the main isolate port) does not handle any messages. | 231 // The control port (aka the main isolate port) does not handle any messages. |
228 if (controlPort != null) { | 232 if (controlPort != null) { |
229 controlPort.handler = (_) {}; // Nobody home on the control port. | 233 controlPort.handler = (_) {}; // Nobody home on the control port. |
230 } | 234 } |
231 | 235 |
232 if (parentPort != null) { | 236 if (parentPort != null) { |
233 // Build a message to our parent isolate providing access to the | 237 // Build a message to our parent isolate providing access to the |
234 // current isolate's control port and capabilities. | 238 // current isolate's control port and capabilities. |
235 // | 239 // |
236 // TODO(floitsch): Send an error message if we can't find the entry point. | 240 // TODO(floitsch): Send an error message if we can't find the entry point. |
237 var readyMessage = new List(2); | 241 var readyMessage = new List(2); |
238 readyMessage[0] = controlPort.sendPort; | 242 readyMessage[0] = controlPort.sendPort; |
239 readyMessage[1] = capabilities; | 243 readyMessage[1] = capabilities; |
(...skipping 21 matching lines...) Expand all Loading... |
261 entryPoint(); | 265 entryPoint(); |
262 } | 266 } |
263 } else { | 267 } else { |
264 entryPoint(message); | 268 entryPoint(message); |
265 } | 269 } |
266 }; | 270 }; |
267 // Make sure the message handler is triggered. | 271 // Make sure the message handler is triggered. |
268 port.sendPort.send(null); | 272 port.sendPort.send(null); |
269 } | 273 } |
270 | 274 |
271 @patch class Isolate { | 275 @patch |
| 276 class Isolate { |
272 static final _currentIsolate = _getCurrentIsolate(); | 277 static final _currentIsolate = _getCurrentIsolate(); |
273 static final _rootUri = _getCurrentRootUri(); | 278 static final _rootUri = _getCurrentRootUri(); |
274 | 279 |
275 @patch static Isolate get current => _currentIsolate; | 280 @patch |
| 281 static Isolate get current => _currentIsolate; |
276 | 282 |
277 @patch static Future<Uri> get packageRoot { | 283 @patch |
| 284 static Future<Uri> get packageRoot { |
278 var hook = VMLibraryHooks.packageRootUriFuture; | 285 var hook = VMLibraryHooks.packageRootUriFuture; |
279 if (hook == null) { | 286 if (hook == null) { |
280 throw new UnsupportedError("Isolate.packageRoot"); | 287 throw new UnsupportedError("Isolate.packageRoot"); |
281 } | 288 } |
282 return hook(); | 289 return hook(); |
283 } | 290 } |
284 | 291 |
285 @patch static Future<Uri> get packageConfig { | 292 @patch |
| 293 static Future<Uri> get packageConfig { |
286 var hook = VMLibraryHooks.packageConfigUriFuture; | 294 var hook = VMLibraryHooks.packageConfigUriFuture; |
287 if (hook == null) { | 295 if (hook == null) { |
288 throw new UnsupportedError("Isolate.packageConfig"); | 296 throw new UnsupportedError("Isolate.packageConfig"); |
289 } | 297 } |
290 return hook(); | 298 return hook(); |
291 } | 299 } |
292 | 300 |
293 @patch static Future<Uri> resolvePackageUri(Uri packageUri) { | 301 @patch |
| 302 static Future<Uri> resolvePackageUri(Uri packageUri) { |
294 var hook = VMLibraryHooks.resolvePackageUriFuture; | 303 var hook = VMLibraryHooks.resolvePackageUriFuture; |
295 if (hook == null) { | 304 if (hook == null) { |
296 throw new UnsupportedError("Isolate.resolvePackageUri"); | 305 throw new UnsupportedError("Isolate.resolvePackageUri"); |
297 } | 306 } |
298 return hook(packageUri); | 307 return hook(packageUri); |
299 } | 308 } |
300 | 309 |
301 static bool _packageSupported() => | 310 static bool _packageSupported() => |
302 (VMLibraryHooks.packageRootUriFuture != null) && | 311 (VMLibraryHooks.packageRootUriFuture != null) && |
303 (VMLibraryHooks.packageConfigUriFuture != null) && | 312 (VMLibraryHooks.packageConfigUriFuture != null) && |
304 (VMLibraryHooks.resolvePackageUriFuture != null); | 313 (VMLibraryHooks.resolvePackageUriFuture != null); |
305 | 314 |
306 @patch static Future<Isolate> spawn( | 315 @patch |
307 void entryPoint(message), var message, | 316 static Future<Isolate> spawn(void entryPoint(message), var message, |
308 {bool paused: false, bool errorsAreFatal, | 317 {bool paused: false, |
309 SendPort onExit, SendPort onError}) async { | 318 bool errorsAreFatal, |
| 319 SendPort onExit, |
| 320 SendPort onError}) async { |
310 // `paused` isn't handled yet. | 321 // `paused` isn't handled yet. |
311 RawReceivePort readyPort; | 322 RawReceivePort readyPort; |
312 try { | 323 try { |
313 // Check for the type of `entryPoint` on the spawning isolate to make | 324 // Check for the type of `entryPoint` on the spawning isolate to make |
314 // error-handling easier. | 325 // error-handling easier. |
315 if (entryPoint is! _UnaryFunction) { | 326 if (entryPoint is! _UnaryFunction) { |
316 throw new ArgumentError(entryPoint); | 327 throw new ArgumentError(entryPoint); |
317 } | 328 } |
318 // The VM will invoke [_startIsolate] with entryPoint as argument. | 329 // The VM will invoke [_startIsolate] with entryPoint as argument. |
319 readyPort = new RawReceivePort(); | 330 readyPort = new RawReceivePort(); |
320 | 331 |
321 // We do not inherit the package root or package config settings | 332 // We do not inherit the package root or package config settings |
322 // from the parent isolate, instead we use the values that were | 333 // from the parent isolate, instead we use the values that were |
323 // set on the command line. | 334 // set on the command line. |
324 var packageRoot = VMLibraryHooks.packageRootString; | 335 var packageRoot = VMLibraryHooks.packageRootString; |
325 var packageConfig = VMLibraryHooks.packageConfigString; | 336 var packageConfig = VMLibraryHooks.packageConfigString; |
326 var script = VMLibraryHooks.platformScript; | 337 var script = VMLibraryHooks.platformScript; |
327 if (script == null) { | 338 if (script == null) { |
328 // We do not have enough information to support spawning the new | 339 // We do not have enough information to support spawning the new |
329 // isolate. | 340 // isolate. |
330 throw new UnsupportedError("Isolate.spawn"); | 341 throw new UnsupportedError("Isolate.spawn"); |
331 } | 342 } |
332 if (script.scheme == "package") { | 343 if (script.scheme == "package") { |
333 script = await Isolate.resolvePackageUri(script); | 344 script = await Isolate.resolvePackageUri(script); |
334 } | 345 } |
335 | 346 |
336 _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message, | 347 _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message, |
337 paused, errorsAreFatal, onExit, onError, | 348 paused, errorsAreFatal, onExit, onError, packageRoot, packageConfig); |
338 packageRoot, packageConfig); | |
339 return await _spawnCommon(readyPort); | 349 return await _spawnCommon(readyPort); |
340 } catch (e, st) { | 350 } catch (e, st) { |
341 if (readyPort != null) { | 351 if (readyPort != null) { |
342 readyPort.close(); | 352 readyPort.close(); |
343 } | 353 } |
344 return await new Future<Isolate>.error(e, st); | 354 return await new Future<Isolate>.error(e, st); |
345 } | 355 } |
346 } | 356 } |
347 | 357 |
348 @patch static Future<Isolate> spawnUri( | 358 @patch |
349 Uri uri, List<String> args, var message, | 359 static Future<Isolate> spawnUri(Uri uri, List<String> args, var message, |
350 {bool paused: false, | 360 {bool paused: false, |
351 SendPort onExit, | 361 SendPort onExit, |
352 SendPort onError, | 362 SendPort onError, |
353 bool errorsAreFatal, | 363 bool errorsAreFatal, |
354 bool checked, | 364 bool checked, |
355 Map<String, String> environment, | 365 Map<String, String> environment, |
356 Uri packageRoot, | 366 Uri packageRoot, |
357 Uri packageConfig, | 367 Uri packageConfig, |
358 bool automaticPackageResolution: false}) async { | 368 bool automaticPackageResolution: false}) async { |
359 RawReceivePort readyPort; | 369 RawReceivePort readyPort; |
360 if (environment != null) { | 370 if (environment != null) { |
361 throw new UnimplementedError("environment"); | 371 throw new UnimplementedError("environment"); |
362 } | 372 } |
363 | 373 |
364 // Verify that no mutually exclusive arguments have been passed. | 374 // Verify that no mutually exclusive arguments have been passed. |
365 if (automaticPackageResolution) { | 375 if (automaticPackageResolution) { |
366 if (packageRoot != null) { | 376 if (packageRoot != null) { |
367 throw new ArgumentError("Cannot simultaneously request " | 377 throw new ArgumentError("Cannot simultaneously request " |
368 "automaticPackageResolution and specify a" | 378 "automaticPackageResolution and specify a" |
369 "packageRoot."); | 379 "packageRoot."); |
370 } | 380 } |
371 if (packageConfig != null) { | 381 if (packageConfig != null) { |
372 throw new ArgumentError("Cannot simultaneously request " | 382 throw new ArgumentError("Cannot simultaneously request " |
373 "automaticPackageResolution and specify a" | 383 "automaticPackageResolution and specify a" |
374 "packageConfig."); | 384 "packageConfig."); |
375 } | 385 } |
376 } else { | 386 } else { |
377 if ((packageRoot != null) && (packageConfig != null)) { | 387 if ((packageRoot != null) && (packageConfig != null)) { |
378 throw new ArgumentError("Cannot simultaneously specify a " | 388 throw new ArgumentError("Cannot simultaneously specify a " |
379 "packageRoot and a packageConfig."); | 389 "packageRoot and a packageConfig."); |
380 } | 390 } |
381 } | 391 } |
382 try { | 392 try { |
383 // Resolve the uri against the current isolate's root Uri first. | 393 // Resolve the uri against the current isolate's root Uri first. |
384 var spawnedUri = _rootUri.resolveUri(uri); | 394 var spawnedUri = _rootUri.resolveUri(uri); |
385 | 395 |
386 // Inherit this isolate's package resolution setup if not overridden. | 396 // Inherit this isolate's package resolution setup if not overridden. |
387 if (!automaticPackageResolution && | 397 if (!automaticPackageResolution && |
388 (packageRoot == null) && | 398 (packageRoot == null) && |
389 (packageConfig == null)) { | 399 (packageConfig == null)) { |
(...skipping 16 matching lines...) Expand all Loading... |
406 if (packageConfig.scheme == "package") { | 416 if (packageConfig.scheme == "package") { |
407 packageConfig = await Isolate.resolvePackageUri(packageConfig); | 417 packageConfig = await Isolate.resolvePackageUri(packageConfig); |
408 } | 418 } |
409 } | 419 } |
410 | 420 |
411 // The VM will invoke [_startIsolate] and not `main`. | 421 // The VM will invoke [_startIsolate] and not `main`. |
412 readyPort = new RawReceivePort(); | 422 readyPort = new RawReceivePort(); |
413 var packageRootString = packageRoot?.toString(); | 423 var packageRootString = packageRoot?.toString(); |
414 var packageConfigString = packageConfig?.toString(); | 424 var packageConfigString = packageConfig?.toString(); |
415 | 425 |
416 _spawnUri(readyPort.sendPort, spawnedUri.toString(), | 426 _spawnUri( |
417 args, message, | 427 readyPort.sendPort, |
418 paused, onExit, onError, | 428 spawnedUri.toString(), |
419 errorsAreFatal, checked, | 429 args, |
420 null, /* environment */ | 430 message, |
421 packageRootString, packageConfigString); | 431 paused, |
| 432 onExit, |
| 433 onError, |
| 434 errorsAreFatal, |
| 435 checked, |
| 436 null, |
| 437 /* environment */ |
| 438 packageRootString, |
| 439 packageConfigString); |
422 return await _spawnCommon(readyPort); | 440 return await _spawnCommon(readyPort); |
423 } catch (e, st) { | 441 } catch (e, st) { |
424 if (readyPort != null) { | 442 if (readyPort != null) { |
425 readyPort.close(); | 443 readyPort.close(); |
426 } | 444 } |
427 rethrow; | 445 rethrow; |
428 } | 446 } |
429 } | 447 } |
430 | 448 |
431 static Future<Isolate> _spawnCommon(RawReceivePort readyPort) { | 449 static Future<Isolate> _spawnCommon(RawReceivePort readyPort) { |
432 Completer completer = new Completer<Isolate>.sync(); | 450 Completer completer = new Completer<Isolate>.sync(); |
433 readyPort.handler = (readyMessage) { | 451 readyPort.handler = (readyMessage) { |
434 readyPort.close(); | 452 readyPort.close(); |
435 if (readyMessage is List && readyMessage.length == 2) { | 453 if (readyMessage is List && readyMessage.length == 2) { |
436 SendPort controlPort = readyMessage[0]; | 454 SendPort controlPort = readyMessage[0]; |
437 List capabilities = readyMessage[1]; | 455 List capabilities = readyMessage[1]; |
438 completer.complete(new Isolate(controlPort, | 456 completer.complete(new Isolate(controlPort, |
439 pauseCapability: capabilities[0], | 457 pauseCapability: capabilities[0], |
440 terminateCapability: capabilities[1])); | 458 terminateCapability: capabilities[1])); |
441 } else if (readyMessage is String) { | 459 } else if (readyMessage is String) { |
442 // We encountered an error while starting the new isolate. | 460 // We encountered an error while starting the new isolate. |
443 completer.completeError(new IsolateSpawnException( | 461 completer.completeError(new IsolateSpawnException( |
444 'Unable to spawn isolate: ${readyMessage}')); | 462 'Unable to spawn isolate: ${readyMessage}')); |
445 } else { | 463 } else { |
446 // This shouldn't happen. | 464 // This shouldn't happen. |
447 completer.completeError(new IsolateSpawnException( | 465 completer.completeError(new IsolateSpawnException( |
448 "Internal error: unexpected format for ready message: " | 466 "Internal error: unexpected format for ready message: " |
449 "'${readyMessage}'")); | 467 "'${readyMessage}'")); |
450 } | 468 } |
451 }; | 469 }; |
452 return completer.future; | 470 return completer.future; |
453 } | 471 } |
454 | 472 |
455 // TODO(iposva): Cleanup to have only one definition. | 473 // TODO(iposva): Cleanup to have only one definition. |
456 // These values need to be kept in sync with the class IsolateMessageHandler | 474 // These values need to be kept in sync with the class IsolateMessageHandler |
457 // in vm/isolate.cc. | 475 // in vm/isolate.cc. |
458 static const _PAUSE = 1; | 476 static const _PAUSE = 1; |
459 static const _RESUME = 2; | 477 static const _RESUME = 2; |
460 static const _PING = 3; | 478 static const _PING = 3; |
461 static const _KILL = 4; | 479 static const _KILL = 4; |
462 static const _ADD_EXIT = 5; | 480 static const _ADD_EXIT = 5; |
463 static const _DEL_EXIT = 6; | 481 static const _DEL_EXIT = 6; |
464 static const _ADD_ERROR = 7; | 482 static const _ADD_ERROR = 7; |
465 static const _DEL_ERROR = 8; | 483 static const _DEL_ERROR = 8; |
466 static const _ERROR_FATAL = 9; | 484 static const _ERROR_FATAL = 9; |
467 | 485 |
| 486 static void _spawnFunction( |
| 487 SendPort readyPort, |
| 488 String uri, |
| 489 Function topLevelFunction, |
| 490 var message, |
| 491 bool paused, |
| 492 bool errorsAreFatal, |
| 493 SendPort onExit, |
| 494 SendPort onError, |
| 495 String packageRoot, |
| 496 String packageConfig) native "Isolate_spawnFunction"; |
468 | 497 |
469 static void _spawnFunction(SendPort readyPort, String uri, | 498 static void _spawnUri( |
470 Function topLevelFunction, | 499 SendPort readyPort, |
471 var message, bool paused, bool errorsAreFatal, | 500 String uri, |
472 SendPort onExit, SendPort onError, | 501 List<String> args, |
473 String packageRoot, String packageConfig) | 502 var message, |
474 native "Isolate_spawnFunction"; | 503 bool paused, |
475 | 504 SendPort onExit, |
476 static void _spawnUri(SendPort readyPort, String uri, | 505 SendPort onError, |
477 List<String> args, var message, | 506 bool errorsAreFatal, |
478 bool paused, SendPort onExit, SendPort onError, | 507 bool checked, |
479 bool errorsAreFatal, bool checked, | 508 List environment, |
480 List environment, | 509 String packageRoot, |
481 String packageRoot, String packageConfig) | 510 String packageConfig) native "Isolate_spawnUri"; |
482 native "Isolate_spawnUri"; | |
483 | 511 |
484 static void _sendOOB(port, msg) native "Isolate_sendOOB"; | 512 static void _sendOOB(port, msg) native "Isolate_sendOOB"; |
485 | 513 |
486 @patch void _pause(Capability resumeCapability) { | 514 @patch |
| 515 void _pause(Capability resumeCapability) { |
487 var msg = new List(4) | 516 var msg = new List(4) |
488 ..[0] = 0 // Make room for OOB message type. | 517 ..[0] = 0 // Make room for OOB message type. |
489 ..[1] = _PAUSE | 518 ..[1] = _PAUSE |
490 ..[2] = pauseCapability | 519 ..[2] = pauseCapability |
491 ..[3] = resumeCapability; | 520 ..[3] = resumeCapability; |
492 _sendOOB(controlPort, msg); | 521 _sendOOB(controlPort, msg); |
493 } | 522 } |
494 | 523 |
495 @patch void resume(Capability resumeCapability) { | 524 @patch |
| 525 void resume(Capability resumeCapability) { |
496 var msg = new List(4) | 526 var msg = new List(4) |
497 ..[0] = 0 // Make room for OOB message type. | 527 ..[0] = 0 // Make room for OOB message type. |
498 ..[1] = _RESUME | 528 ..[1] = _RESUME |
499 ..[2] = pauseCapability | 529 ..[2] = pauseCapability |
500 ..[3] = resumeCapability; | 530 ..[3] = resumeCapability; |
501 _sendOOB(controlPort, msg); | 531 _sendOOB(controlPort, msg); |
502 } | 532 } |
503 | 533 |
504 @patch void addOnExitListener(SendPort responsePort, | 534 @patch |
505 {Object response}) { | 535 void addOnExitListener(SendPort responsePort, {Object response}) { |
506 var msg = new List(4) | 536 var msg = new List(4) |
507 ..[0] = 0 // Make room for OOB message type. | 537 ..[0] = 0 // Make room for OOB message type. |
508 ..[1] = _ADD_EXIT | 538 ..[1] = _ADD_EXIT |
509 ..[2] = responsePort | 539 ..[2] = responsePort |
510 ..[3] = response; | 540 ..[3] = response; |
511 _sendOOB(controlPort, msg); | 541 _sendOOB(controlPort, msg); |
512 } | 542 } |
513 | 543 |
514 @patch void removeOnExitListener(SendPort responsePort) { | 544 @patch |
| 545 void removeOnExitListener(SendPort responsePort) { |
515 var msg = new List(3) | 546 var msg = new List(3) |
516 ..[0] = 0 // Make room for OOB message type. | 547 ..[0] = 0 // Make room for OOB message type. |
517 ..[1] = _DEL_EXIT | 548 ..[1] = _DEL_EXIT |
518 ..[2] = responsePort; | 549 ..[2] = responsePort; |
519 _sendOOB(controlPort, msg); | 550 _sendOOB(controlPort, msg); |
520 } | 551 } |
521 | 552 |
522 @patch void setErrorsFatal(bool errorsAreFatal) { | 553 @patch |
| 554 void setErrorsFatal(bool errorsAreFatal) { |
523 var msg = new List(4) | 555 var msg = new List(4) |
524 ..[0] = 0 // Make room for OOB message type. | 556 ..[0] = 0 // Make room for OOB message type. |
525 ..[1] = _ERROR_FATAL | 557 ..[1] = _ERROR_FATAL |
526 ..[2] = terminateCapability | 558 ..[2] = terminateCapability |
527 ..[3] = errorsAreFatal; | 559 ..[3] = errorsAreFatal; |
528 _sendOOB(controlPort, msg); | 560 _sendOOB(controlPort, msg); |
529 } | 561 } |
530 | 562 |
531 @patch void kill({int priority: BEFORE_NEXT_EVENT}) { | 563 @patch |
| 564 void kill({int priority: BEFORE_NEXT_EVENT}) { |
532 var msg = new List(4) | 565 var msg = new List(4) |
533 ..[0] = 0 // Make room for OOB message type. | 566 ..[0] = 0 // Make room for OOB message type. |
534 ..[1] = _KILL | 567 ..[1] = _KILL |
535 ..[2] = terminateCapability | 568 ..[2] = terminateCapability |
536 ..[3] = priority; | 569 ..[3] = priority; |
537 _sendOOB(controlPort, msg); | 570 _sendOOB(controlPort, msg); |
538 } | 571 } |
539 | 572 |
540 @patch void ping(SendPort responsePort, {Object response, | 573 @patch |
541 int priority: IMMEDIATE}) { | 574 void ping(SendPort responsePort, {Object response, int priority: IMMEDIATE}) { |
542 var msg = new List(5) | 575 var msg = new List(5) |
543 ..[0] = 0 // Make room for OOM message type. | 576 ..[0] = 0 // Make room for OOM message type. |
544 ..[1] = _PING | 577 ..[1] = _PING |
545 ..[2] = responsePort | 578 ..[2] = responsePort |
546 ..[3] = priority | 579 ..[3] = priority |
547 ..[4] = response; | 580 ..[4] = response; |
548 _sendOOB(controlPort, msg); | 581 _sendOOB(controlPort, msg); |
549 } | 582 } |
550 | 583 |
551 @patch void addErrorListener(SendPort port) { | 584 @patch |
| 585 void addErrorListener(SendPort port) { |
552 var msg = new List(3) | 586 var msg = new List(3) |
553 ..[0] = 0 // Make room for OOB message type. | 587 ..[0] = 0 // Make room for OOB message type. |
554 ..[1] = _ADD_ERROR | 588 ..[1] = _ADD_ERROR |
555 ..[2] = port; | 589 ..[2] = port; |
556 _sendOOB(controlPort, msg); | 590 _sendOOB(controlPort, msg); |
557 } | 591 } |
558 | 592 |
559 @patch void removeErrorListener(SendPort port) { | 593 @patch |
| 594 void removeErrorListener(SendPort port) { |
560 var msg = new List(3) | 595 var msg = new List(3) |
561 ..[0] = 0 // Make room for OOB message type. | 596 ..[0] = 0 // Make room for OOB message type. |
562 ..[1] = _DEL_ERROR | 597 ..[1] = _DEL_ERROR |
563 ..[2] = port; | 598 ..[2] = port; |
564 _sendOOB(controlPort, msg); | 599 _sendOOB(controlPort, msg); |
565 } | 600 } |
566 | 601 |
567 static Isolate _getCurrentIsolate() { | 602 static Isolate _getCurrentIsolate() { |
568 List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate(); | 603 List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate(); |
569 return new Isolate(portAndCapabilities[0], | 604 return new Isolate(portAndCapabilities[0], |
570 pauseCapability: portAndCapabilities[1], | 605 pauseCapability: portAndCapabilities[1], |
571 terminateCapability: portAndCapabilities[2]); | 606 terminateCapability: portAndCapabilities[2]); |
572 } | 607 } |
573 | 608 |
574 static List _getPortAndCapabilitiesOfCurrentIsolate() | 609 static List _getPortAndCapabilitiesOfCurrentIsolate() |
575 native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; | 610 native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; |
576 | 611 |
577 static Uri _getCurrentRootUri() { | 612 static Uri _getCurrentRootUri() { |
578 try { | 613 try { |
579 return Uri.parse(_getCurrentRootUriStr()); | 614 return Uri.parse(_getCurrentRootUriStr()); |
580 } catch (e, s) { | 615 } catch (e, s) { |
581 return null; | 616 return null; |
582 } | 617 } |
583 } | 618 } |
584 | 619 |
585 static String _getCurrentRootUriStr() | 620 static String _getCurrentRootUriStr() native "Isolate_getCurrentRootUriStr"; |
586 native "Isolate_getCurrentRootUriStr"; | |
587 } | 621 } |
OLD | NEW |