Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(843)

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/isolate_helper.dart

Issue 742873002: Isolates: allow sending of arbitrary objects in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove unnecessary comment. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 library _isolate_helper; 5 library _isolate_helper;
6 6
7 import 'shared/embedded_names.dart' show 7 import 'shared/embedded_names.dart' show
8 CLASS_ID_EXTRACTOR,
9 CLASS_FIELDS_EXTRACTOR,
8 CURRENT_SCRIPT, 10 CURRENT_SCRIPT,
9 GLOBAL_FUNCTIONS; 11 GLOBAL_FUNCTIONS,
12 INITIALIZE_EMPTY_INSTANCE,
13 INSTANCE_FROM_CLASS_ID;
10 14
11 import 'dart:async'; 15 import 'dart:async';
12 import 'dart:collection' show Queue, HashMap; 16 import 'dart:collection' show Queue, HashMap;
13 import 'dart:isolate'; 17 import 'dart:isolate';
18 import 'dart:typed_data' show TypedData;
19
14 import 'dart:_js_helper' show 20 import 'dart:_js_helper' show
15 Closure, 21 Closure,
16 Null, 22 Null,
17 Primitives, 23 Primitives,
18 convertDartClosureToJS, 24 convertDartClosureToJS,
19 random64, 25 random64,
20 requiresPreamble; 26 requiresPreamble;
21 import 'dart:_foreign_helper' show DART_CLOSURE_TO_JS, 27 import 'dart:_foreign_helper' show DART_CLOSURE_TO_JS,
22 JS, 28 JS,
23 JS_CREATE_ISOLATE, 29 JS_CREATE_ISOLATE,
24 JS_CURRENT_ISOLATE_CONTEXT, 30 JS_CURRENT_ISOLATE_CONTEXT,
25 JS_CURRENT_ISOLATE, 31 JS_CURRENT_ISOLATE,
26 JS_EMBEDDED_GLOBAL, 32 JS_EMBEDDED_GLOBAL,
27 JS_SET_CURRENT_ISOLATE, 33 JS_SET_CURRENT_ISOLATE,
28 IsolateContext; 34 IsolateContext;
29 import 'dart:_interceptors' show JSExtendableArray; 35 import 'dart:_interceptors' show Interceptor,
36 JSArray,
37 JSExtendableArray,
38 JSFixedArray,
39 JSIndexable,
40 JSMutableArray,
41 JSObject;
42 import 'dart:_internal' show InternalMap;
43
44
45 part 'isolate_serialization.dart';
30 46
31 /** 47 /**
32 * Called by the compiler to support switching 48 * Called by the compiler to support switching
33 * between isolates when we get a callback from the DOM. 49 * between isolates when we get a callback from the DOM.
34 */ 50 */
35 _callInIsolate(_IsolateContext isolate, Function function) { 51 _callInIsolate(_IsolateContext isolate, Function function) {
36 var result = isolate.eval(function); 52 var result = isolate.eval(function);
37 _globalState.topEventLoop.run(); 53 _globalState.topEventLoop.run();
38 return result; 54 return result;
39 } 55 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 /** Whether we support spawning web workers. */ 195 /** Whether we support spawning web workers. */
180 bool supportsWorkers; 196 bool supportsWorkers;
181 197
182 /** 198 /**
183 * Whether to use web workers when implementing isolates. Set to false for 199 * Whether to use web workers when implementing isolates. Set to false for
184 * debugging/testing. 200 * debugging/testing.
185 */ 201 */
186 bool get useWorkers => supportsWorkers; 202 bool get useWorkers => supportsWorkers;
187 203
188 /** 204 /**
189 * Whether to use the web-worker JSON-based message serialization protocol. By
190 * default this is only used with web workers. For debugging, you can force
191 * using this protocol by changing this field value to [:true:].
192 */
193 bool get needSerialization => useWorkers;
194
195 /**
196 * Registry of isolates. Isolates must be registered if, and only if, receive 205 * Registry of isolates. Isolates must be registered if, and only if, receive
197 * ports are alive. Normally no open receive-ports means that the isolate is 206 * ports are alive. Normally no open receive-ports means that the isolate is
198 * dead, but DOM callbacks could resurrect it. 207 * dead, but DOM callbacks could resurrect it.
199 */ 208 */
200 Map<int, _IsolateContext> isolates; 209 Map<int, _IsolateContext> isolates;
201 210
202 /** Reference to the main [_Manager]. Null in the main [_Manager] itself. */ 211 /** Reference to the main [_Manager]. Null in the main [_Manager] itself. */
203 _MainManagerStub mainManager; 212 _MainManagerStub mainManager;
204 213
205 /// Registry of active Web Workers. Only used in the main [_Manager]. 214 /// Registry of active Web Workers. Only used in the main [_Manager].
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 return completer.future; 982 return completer.future;
974 } 983 }
975 984
976 static void _startWorker( 985 static void _startWorker(
977 String functionName, String uri, 986 String functionName, String uri,
978 List<String> args, message, 987 List<String> args, message,
979 bool isSpawnUri, 988 bool isSpawnUri,
980 bool startPaused, 989 bool startPaused,
981 SendPort replyPort, 990 SendPort replyPort,
982 void onError(String message)) { 991 void onError(String message)) {
992 // Make sure that the args list is a generic list.
sigurdm 2014/11/24 09:06:09 What happens if it is not?
Lasse Reichstein Nielsen 2014/11/24 12:55:41 Also ensures that it is a fresh list.
floitsch 2014/11/24 15:06:56 added "fresh" to the comment.
floitsch 2014/11/24 15:06:56 Added more info to comment. It's mostly to make it
993 if (args != null) args = new List<String>.from(args);
983 if (_globalState.isWorker) { 994 if (_globalState.isWorker) {
984 _globalState.mainManager.postMessage(_serializeMessage({ 995 _globalState.mainManager.postMessage(_serializeMessage({
985 'command': 'spawn-worker', 996 'command': 'spawn-worker',
986 'functionName': functionName, 997 'functionName': functionName,
987 'args': args, 998 'args': args,
988 'msg': message, 999 'msg': message,
989 'uri': uri, 1000 'uri': uri,
990 'isSpawnUri': isSpawnUri, 1001 'isSpawnUri': isSpawnUri,
991 'startPaused': startPaused, 1002 'startPaused': startPaused,
992 'replyPort': replyPort})); 1003 'replyPort': replyPort}));
993 } else { 1004 } else {
994 _spawnWorker(functionName, uri, args, message, 1005 _spawnWorker(functionName, uri, args, message,
995 isSpawnUri, startPaused, replyPort, onError); 1006 isSpawnUri, startPaused, replyPort, onError);
996 } 1007 }
997 } 1008 }
998 1009
999 static void _startNonWorker( 1010 static void _startNonWorker(
1000 String functionName, String uri, 1011 String functionName, String uri,
1001 List<String> args, var message, 1012 List<String> args, var message,
1002 bool isSpawnUri, 1013 bool isSpawnUri,
1003 bool startPaused, 1014 bool startPaused,
1004 SendPort replyPort) { 1015 SendPort replyPort) {
1005 // TODO(eub): support IE9 using an iframe -- Dart issue 1702. 1016 // TODO(eub): support IE9 using an iframe -- Dart issue 1702.
1006 if (uri != null) { 1017 if (uri != null) {
1007 throw new UnsupportedError( 1018 throw new UnsupportedError(
1008 "Currently spawnUri is not supported without web workers."); 1019 "Currently spawnUri is not supported without web workers.");
1009 } 1020 }
1010 message = _serializeMessage(message); 1021 // Clone the message to enforce the restrictions we have on isolate
1011 args = _serializeMessage(args); // Or just args.toList() ? 1022 // messages.
1023 message = _clone(message);
1024 // Make sure that the args list is a generic list.
1025 if (args != null) args = new List<String>.from(args);
1012 _globalState.topEventLoop.enqueue(new _IsolateContext(), () { 1026 _globalState.topEventLoop.enqueue(new _IsolateContext(), () {
1013 final func = _getJSFunctionFromName(functionName); 1027 final func = _getJSFunctionFromName(functionName);
1014 _startIsolate(func, args, message, isSpawnUri, startPaused, replyPort); 1028 _startIsolate(func, args, message, isSpawnUri, startPaused, replyPort);
1015 }, 'nonworker start'); 1029 }, 'nonworker start');
1016 } 1030 }
1017 1031
1018 static void _startIsolate(Function topLevel, 1032 static void _startIsolate(Function topLevel,
1019 List<String> args, message, 1033 List<String> args, message,
1020 bool isSpawnUri, 1034 bool isSpawnUri,
1021 bool startPaused, 1035 bool startPaused,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 class _NativeJsSendPort extends _BaseSendPort implements SendPort { 1172 class _NativeJsSendPort extends _BaseSendPort implements SendPort {
1159 final RawReceivePortImpl _receivePort; 1173 final RawReceivePortImpl _receivePort;
1160 1174
1161 const _NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId); 1175 const _NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId);
1162 1176
1163 void send(var message) { 1177 void send(var message) {
1164 // Check that the isolate still runs and the port is still open 1178 // Check that the isolate still runs and the port is still open
1165 final isolate = _globalState.isolates[_isolateId]; 1179 final isolate = _globalState.isolates[_isolateId];
1166 if (isolate == null) return; 1180 if (isolate == null) return;
1167 if (_receivePort._isClosed) return; 1181 if (_receivePort._isClosed) return;
1168 // We force serialization/deserialization as a simple way to ensure 1182 // Clone the message to enforce the restrictions we have on isolate
1169 // isolate communication restrictions are respected between isolates that 1183 // messages.
1170 // live in the same worker. [_NativeJsSendPort] delivers both messages 1184 var msg = _clone(message);
1171 // from the same worker and messages from other workers. In particular,
1172 // messages sent from a worker via a [_WorkerSendPort] are received at
1173 // [_processWorkerMessage] and forwarded to a native port. In such cases,
1174 // here we'll see [_globalState.currentContext == null].
1175 final shouldSerialize = _globalState.currentContext != null
1176 && _globalState.currentContext.id != _isolateId;
1177 var msg = message;
1178 if (shouldSerialize) {
1179 msg = _serializeMessage(msg);
1180 }
1181 if (isolate.controlPort == _receivePort) { 1185 if (isolate.controlPort == _receivePort) {
1182 isolate.handleControlMessage(msg); 1186 isolate.handleControlMessage(msg);
1183 return; 1187 return;
1184 } 1188 }
1185 _globalState.topEventLoop.enqueue(isolate, () { 1189 _globalState.topEventLoop.enqueue(isolate, () {
1186 if (!_receivePort._isClosed) { 1190 if (!_receivePort._isClosed) {
1187 if (shouldSerialize) {
1188 msg = _deserializeMessage(msg);
1189 }
1190 _receivePort._add(msg); 1191 _receivePort._add(msg);
1191 } 1192 }
1192 }, 'receive $message'); 1193 }, 'receive $message');
1193 } 1194 }
1194 1195
1195 bool operator ==(var other) => (other is _NativeJsSendPort) && 1196 bool operator ==(var other) => (other is _NativeJsSendPort) &&
1196 (_receivePort == other._receivePort); 1197 (_receivePort == other._receivePort);
1197 1198
1198 int get hashCode => _receivePort._id; 1199 int get hashCode => _receivePort._id;
1199 } 1200 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 } 1311 }
1311 1312
1312 void close() { 1313 void close() {
1313 _rawPort.close(); 1314 _rawPort.close();
1314 _controller.close(); 1315 _controller.close();
1315 } 1316 }
1316 1317
1317 SendPort get sendPort => _rawPort.sendPort; 1318 SendPort get sendPort => _rawPort.sendPort;
1318 } 1319 }
1319 1320
1320
1321 /********************************************************
1322 Inserted from lib/isolate/dart2js/messages.dart
1323 ********************************************************/
1324
1325 // Defines message visitors, serialization, and deserialization.
1326
1327 /** Serialize [message] (or simulate serialization). */
1328 _serializeMessage(message) {
1329 if (_globalState.needSerialization) {
1330 return new _JsSerializer().traverse(message);
1331 } else {
1332 return new _JsCopier().traverse(message);
1333 }
1334 }
1335
1336 /** Deserialize [message] (or simulate deserialization). */
1337 _deserializeMessage(message) {
1338 if (_globalState.needSerialization) {
1339 return new _JsDeserializer().deserialize(message);
1340 } else {
1341 // Nothing more to do.
1342 return message;
1343 }
1344 }
1345
1346 class _JsSerializer extends _Serializer {
1347
1348 _JsSerializer() : super() { _visited = new _JsVisitedMap(); }
1349
1350 visitSendPort(SendPort x) {
1351 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x);
1352 if (x is _WorkerSendPort) return visitWorkerSendPort(x);
1353 throw "Illegal underlying port $x";
1354 }
1355
1356 visitCapability(Capability x) {
1357 if (x is CapabilityImpl) {
1358 return ['capability', x._id];
1359 }
1360 throw "Capability not serializable: $x";
1361 }
1362
1363 visitNativeJsSendPort(_NativeJsSendPort port) {
1364 return ['sendport', _globalState.currentManagerId,
1365 port._isolateId, port._receivePort._id];
1366 }
1367
1368 visitWorkerSendPort(_WorkerSendPort port) {
1369 return ['sendport', port._workerId, port._isolateId, port._receivePortId];
1370 }
1371
1372 visitFunction(Function topLevelFunction) {
1373 final name = IsolateNatives._getJSFunctionName(topLevelFunction);
1374 if (name == null) {
1375 throw new UnsupportedError(
1376 "only top-level functions can be sent.");
1377 }
1378 return ['function', name];
1379 }
1380 }
1381
1382
1383 class _JsCopier extends _Copier {
1384
1385 _JsCopier() : super() { _visited = new _JsVisitedMap(); }
1386
1387 visitSendPort(SendPort x) {
1388 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x);
1389 if (x is _WorkerSendPort) return visitWorkerSendPort(x);
1390 throw "Illegal underlying port $x";
1391 }
1392
1393 visitCapability(Capability x) {
1394 if (x is CapabilityImpl) {
1395 return new CapabilityImpl._internal(x._id);
1396 }
1397 throw "Capability not serializable: $x";
1398 }
1399
1400 SendPort visitNativeJsSendPort(_NativeJsSendPort port) {
1401 return new _NativeJsSendPort(port._receivePort, port._isolateId);
1402 }
1403
1404 SendPort visitWorkerSendPort(_WorkerSendPort port) {
1405 return new _WorkerSendPort(
1406 port._workerId, port._isolateId, port._receivePortId);
1407 }
1408
1409 Function visitFunction(Function topLevelFunction) {
1410 final name = IsolateNatives._getJSFunctionName(topLevelFunction);
1411 if (name == null) {
1412 throw new UnsupportedError(
1413 "only top-level functions can be sent.");
1414 }
1415 // Is this getting it from the correct isolate? Is it just topLevelFunction?
1416 return IsolateNatives._getJSFunctionFromName(name);
1417 }
1418 }
1419
1420 class _JsDeserializer extends _Deserializer {
1421
1422 SendPort deserializeSendPort(List list) {
1423 int managerId = list[1];
1424 int isolateId = list[2];
1425 int receivePortId = list[3];
1426 // If two isolates are in the same manager, we use NativeJsSendPorts to
1427 // deliver messages directly without using postMessage.
1428 if (managerId == _globalState.currentManagerId) {
1429 var isolate = _globalState.isolates[isolateId];
1430 if (isolate == null) return null; // Isolate has been closed.
1431 var receivePort = isolate.lookup(receivePortId);
1432 if (receivePort == null) return null; // Port has been closed.
1433 return new _NativeJsSendPort(receivePort, isolateId);
1434 } else {
1435 return new _WorkerSendPort(managerId, isolateId, receivePortId);
1436 }
1437 }
1438
1439 Capability deserializeCapability(List list) {
1440 return new CapabilityImpl._internal(list[1]);
1441 }
1442
1443 Function deserializeFunction(List list) {
1444 return IsolateNatives._getJSFunctionFromName(list[1]);
1445 }
1446 }
1447
1448 class _JsVisitedMap implements _MessageTraverserVisitedMap {
1449 List tagged;
1450
1451 /** Retrieves any information stored in the native object [object]. */
1452 operator[](var object) {
1453 return _getAttachedInfo(object);
1454 }
1455
1456 /** Injects some information into the native [object]. */
1457 void operator[]=(var object, var info) {
1458 tagged.add(object);
1459 _setAttachedInfo(object, info);
1460 }
1461
1462 /** Get ready to rumble. */
1463 void reset() {
1464 assert(tagged == null);
1465 tagged = new List();
1466 }
1467
1468 /** Remove all information injected in the native objects. */
1469 void cleanup() {
1470 for (int i = 0, length = tagged.length; i < length; i++) {
1471 _clearAttachedInfo(tagged[i]);
1472 }
1473 tagged = null;
1474 }
1475
1476 void _clearAttachedInfo(var o) {
1477 JS("void", "#['__MessageTraverser__attached_info__'] = #", o, null);
1478 }
1479
1480 void _setAttachedInfo(var o, var info) {
1481 JS("void", "#['__MessageTraverser__attached_info__'] = #", o, info);
1482 }
1483
1484 _getAttachedInfo(var o) {
1485 return JS("", "#['__MessageTraverser__attached_info__']", o);
1486 }
1487 }
1488
1489 // only visible for testing purposes
1490 // TODO(sigmund): remove once we can disable privacy for testing (bug #1882)
1491 class TestingOnly {
1492 static copy(x) {
1493 return new _JsCopier().traverse(x);
1494 }
1495
1496 // only visible for testing purposes
1497 static serialize(x) {
1498 _Serializer serializer = new _JsSerializer();
1499 _Deserializer deserializer = new _JsDeserializer();
1500 return deserializer.deserialize(serializer.traverse(x));
1501 }
1502 }
1503
1504 /********************************************************
1505 Inserted from lib/isolate/serialization.dart
1506 ********************************************************/
1507
1508 class _MessageTraverserVisitedMap {
1509
1510 operator[](var object) => null;
1511 void operator[]=(var object, var info) { }
1512
1513 void reset() { }
1514 void cleanup() { }
1515
1516 }
1517
1518 /** Abstract visitor for dart objects that can be sent as isolate messages. */
1519 abstract class _MessageTraverser {
1520
1521 _MessageTraverserVisitedMap _visited;
1522 _MessageTraverser() : _visited = new _MessageTraverserVisitedMap();
1523
1524 /** Visitor's entry point. */
1525 traverse(var x) {
1526 if (isPrimitive(x)) return visitPrimitive(x);
1527 _visited.reset();
1528 var result;
1529 try {
1530 result = _dispatch(x);
1531 } finally {
1532 _visited.cleanup();
1533 }
1534 return result;
1535 }
1536
1537 _dispatch(var x) {
1538 // This code likely fails for user classes implementing
1539 // SendPort and Capability because it assumes the internal classes.
1540 if (isPrimitive(x)) return visitPrimitive(x);
1541 if (x is List) return visitList(x);
1542 if (x is Map) return visitMap(x);
1543 if (x is SendPort) return visitSendPort(x);
1544 if (x is Capability) return visitCapability(x);
1545 if (x is Function) return visitFunction(x);
1546
1547 // Overridable fallback.
1548 return visitObject(x);
1549 }
1550
1551 visitPrimitive(x);
1552 visitList(List x);
1553 visitMap(Map x);
1554 visitSendPort(SendPort x);
1555 visitCapability(Capability x);
1556 visitFunction(Function f);
1557
1558 visitObject(Object x) {
1559 // TODO(floitsch): make this a real exception. (which one)?
1560 throw "Message serialization: Illegal value $x passed";
1561 }
1562
1563 static bool isPrimitive(x) {
1564 return (x == null) || (x is String) || (x is num) || (x is bool);
1565 }
1566 }
1567
1568
1569 /** A visitor that recursively copies a message. */
1570 class _Copier extends _MessageTraverser {
1571
1572 visitPrimitive(x) => x;
1573
1574 List visitList(List list) {
1575 List copy = _visited[list];
1576 if (copy != null) return copy;
1577
1578 int len = list.length;
1579
1580 // TODO(floitsch): we loose the generic type of the List.
1581 copy = new List(len);
1582 _visited[list] = copy;
1583 for (int i = 0; i < len; i++) {
1584 copy[i] = _dispatch(list[i]);
1585 }
1586 return copy;
1587 }
1588
1589 Map visitMap(Map map) {
1590 Map copy = _visited[map];
1591 if (copy != null) return copy;
1592
1593 // TODO(floitsch): we loose the generic type of the map.
1594 copy = new Map();
1595 _visited[map] = copy;
1596 map.forEach((key, val) {
1597 copy[_dispatch(key)] = _dispatch(val);
1598 });
1599 return copy;
1600 }
1601
1602 visitFunction(Function f) => throw new UnimplementedError();
1603
1604 visitSendPort(SendPort x) => throw new UnimplementedError();
1605
1606 visitCapability(Capability x) => throw new UnimplementedError();
1607 }
1608
1609 /** Visitor that serializes a message as a JSON array. */
1610 class _Serializer extends _MessageTraverser {
1611 int _nextFreeRefId = 0;
1612
1613 visitPrimitive(x) => x;
1614
1615 visitList(List list) {
1616 int copyId = _visited[list];
1617 if (copyId != null) return ['ref', copyId];
1618
1619 int id = _nextFreeRefId++;
1620 _visited[list] = id;
1621 var jsArray = _serializeList(list);
1622 // TODO(floitsch): we are losing the generic type.
1623 return ['list', id, jsArray];
1624 }
1625
1626 visitMap(Map map) {
1627 int copyId = _visited[map];
1628 if (copyId != null) return ['ref', copyId];
1629
1630 int id = _nextFreeRefId++;
1631 _visited[map] = id;
1632 var keys = _serializeList(map.keys.toList());
1633 var values = _serializeList(map.values.toList());
1634 // TODO(floitsch): we are losing the generic type.
1635 return ['map', id, keys, values];
1636 }
1637
1638 _serializeList(List list) {
1639 int len = list.length;
1640 // Use a growable list because we do not add extra properties on
1641 // them.
1642 var result = new List()..length = len;
1643 for (int i = 0; i < len; i++) {
1644 result[i] = _dispatch(list[i]);
1645 }
1646 return result;
1647 }
1648
1649 visitSendPort(SendPort x) => throw new UnimplementedError();
1650
1651 visitCapability(Capability x) => throw new UnimplementedError();
1652
1653 visitFunction(Function f) => throw new UnimplementedError();
1654 }
1655
1656 /** Deserializes arrays created with [_Serializer]. */
1657 abstract class _Deserializer {
1658 Map<int, dynamic> _deserialized;
1659
1660 _Deserializer();
1661
1662 static bool isPrimitive(x) {
1663 return (x == null) || (x is String) || (x is num) || (x is bool);
1664 }
1665
1666 deserialize(x) {
1667 if (isPrimitive(x)) return x;
1668 // TODO(floitsch): this should be new HashMap<int, dynamic>()
1669 _deserialized = new HashMap();
1670 return _deserializeHelper(x);
1671 }
1672
1673 _deserializeHelper(x) {
1674 if (isPrimitive(x)) return x;
1675 assert(x is List);
1676 switch (x[0]) {
1677 case 'ref': return _deserializeRef(x);
1678 case 'list': return _deserializeList(x);
1679 case 'map': return _deserializeMap(x);
1680 case 'sendport': return deserializeSendPort(x);
1681 case 'capability': return deserializeCapability(x);
1682 case 'function' : return deserializeFunction(x);
1683 default: return deserializeObject(x);
1684 }
1685 }
1686
1687 _deserializeRef(List x) {
1688 int id = x[1];
1689 var result = _deserialized[id];
1690 assert(result != null);
1691 return result;
1692 }
1693
1694 List _deserializeList(List x) {
1695 int id = x[1];
1696 // We rely on the fact that Dart-lists are directly mapped to Js-arrays.
1697 List dartList = x[2];
1698 _deserialized[id] = dartList;
1699 int len = dartList.length;
1700 for (int i = 0; i < len; i++) {
1701 dartList[i] = _deserializeHelper(dartList[i]);
1702 }
1703 return dartList;
1704 }
1705
1706 Map _deserializeMap(List x) {
1707 Map result = new Map();
1708 int id = x[1];
1709 _deserialized[id] = result;
1710 List keys = x[2];
1711 List values = x[3];
1712 int len = keys.length;
1713 assert(len == values.length);
1714 for (int i = 0; i < len; i++) {
1715 var key = _deserializeHelper(keys[i]);
1716 var value = _deserializeHelper(values[i]);
1717 result[key] = value;
1718 }
1719 return result;
1720 }
1721
1722 deserializeFunction(List x);
1723
1724 deserializeSendPort(List x);
1725
1726 deserializeCapability(List x);
1727
1728 deserializeObject(List x) {
1729 // TODO(floitsch): Use real exception (which one?).
1730 throw "Unexpected serialized object";
1731 }
1732 }
1733
1734 class TimerImpl implements Timer { 1321 class TimerImpl implements Timer {
1735 final bool _once; 1322 final bool _once;
1736 bool _inEventLoop = false; 1323 bool _inEventLoop = false;
1737 int _handle; 1324 int _handle;
1738 1325
1739 TimerImpl(int milliseconds, void callback()) 1326 TimerImpl(int milliseconds, void callback())
1740 : _once = true { 1327 : _once = true {
1741 if (milliseconds == 0 && (!hasTimer() || _globalState.isWorker)) { 1328 if (milliseconds == 0 && (!hasTimer() || _globalState.isWorker)) {
1742 1329
1743 void internalCallback() { 1330 void internalCallback() {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1845 } 1432 }
1846 1433
1847 bool operator==(Object other) { 1434 bool operator==(Object other) {
1848 if (identical(other, this)) return true; 1435 if (identical(other, this)) return true;
1849 if (other is CapabilityImpl) { 1436 if (other is CapabilityImpl) {
1850 return identical(_id, other._id); 1437 return identical(_id, other._id);
1851 } 1438 }
1852 return false; 1439 return false;
1853 } 1440 }
1854 } 1441 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698