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 library _isolate_helper; | 5 library _isolate_helper; |
6 | 6 |
7 import 'shared/embedded_names.dart' show | 7 import 'shared/embedded_names.dart' show |
8 CURRENT_SCRIPT, | 8 CURRENT_SCRIPT, |
9 GLOBAL_FUNCTIONS; | 9 GLOBAL_FUNCTIONS; |
10 | 10 |
(...skipping 1350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 } | 1361 } |
1362 | 1362 |
1363 visitNativeJsSendPort(_NativeJsSendPort port) { | 1363 visitNativeJsSendPort(_NativeJsSendPort port) { |
1364 return ['sendport', _globalState.currentManagerId, | 1364 return ['sendport', _globalState.currentManagerId, |
1365 port._isolateId, port._receivePort._id]; | 1365 port._isolateId, port._receivePort._id]; |
1366 } | 1366 } |
1367 | 1367 |
1368 visitWorkerSendPort(_WorkerSendPort port) { | 1368 visitWorkerSendPort(_WorkerSendPort port) { |
1369 return ['sendport', port._workerId, port._isolateId, port._receivePortId]; | 1369 return ['sendport', port._workerId, port._isolateId, port._receivePortId]; |
1370 } | 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 } |
1371 } | 1380 } |
1372 | 1381 |
1373 | 1382 |
1374 class _JsCopier extends _Copier { | 1383 class _JsCopier extends _Copier { |
1375 | 1384 |
1376 _JsCopier() : super() { _visited = new _JsVisitedMap(); } | 1385 _JsCopier() : super() { _visited = new _JsVisitedMap(); } |
1377 | 1386 |
1378 visitSendPort(SendPort x) { | 1387 visitSendPort(SendPort x) { |
1379 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x); | 1388 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x); |
1380 if (x is _WorkerSendPort) return visitWorkerSendPort(x); | 1389 if (x is _WorkerSendPort) return visitWorkerSendPort(x); |
1381 throw "Illegal underlying port $x"; | 1390 throw "Illegal underlying port $x"; |
1382 } | 1391 } |
1383 | 1392 |
1384 visitCapability(Capability x) { | 1393 visitCapability(Capability x) { |
1385 if (x is CapabilityImpl) { | 1394 if (x is CapabilityImpl) { |
1386 return new CapabilityImpl._internal(x._id); | 1395 return new CapabilityImpl._internal(x._id); |
1387 } | 1396 } |
1388 throw "Capability not serializable: $x"; | 1397 throw "Capability not serializable: $x"; |
1389 } | 1398 } |
1390 | 1399 |
1391 SendPort visitNativeJsSendPort(_NativeJsSendPort port) { | 1400 SendPort visitNativeJsSendPort(_NativeJsSendPort port) { |
1392 return new _NativeJsSendPort(port._receivePort, port._isolateId); | 1401 return new _NativeJsSendPort(port._receivePort, port._isolateId); |
1393 } | 1402 } |
1394 | 1403 |
1395 SendPort visitWorkerSendPort(_WorkerSendPort port) { | 1404 SendPort visitWorkerSendPort(_WorkerSendPort port) { |
1396 return new _WorkerSendPort( | 1405 return new _WorkerSendPort( |
1397 port._workerId, port._isolateId, port._receivePortId); | 1406 port._workerId, port._isolateId, port._receivePortId); |
1398 } | 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 } |
1399 } | 1418 } |
1400 | 1419 |
1401 class _JsDeserializer extends _Deserializer { | 1420 class _JsDeserializer extends _Deserializer { |
1402 | 1421 |
1403 SendPort deserializeSendPort(List list) { | 1422 SendPort deserializeSendPort(List list) { |
1404 int managerId = list[1]; | 1423 int managerId = list[1]; |
1405 int isolateId = list[2]; | 1424 int isolateId = list[2]; |
1406 int receivePortId = list[3]; | 1425 int receivePortId = list[3]; |
1407 // If two isolates are in the same manager, we use NativeJsSendPorts to | 1426 // If two isolates are in the same manager, we use NativeJsSendPorts to |
1408 // deliver messages directly without using postMessage. | 1427 // deliver messages directly without using postMessage. |
1409 if (managerId == _globalState.currentManagerId) { | 1428 if (managerId == _globalState.currentManagerId) { |
1410 var isolate = _globalState.isolates[isolateId]; | 1429 var isolate = _globalState.isolates[isolateId]; |
1411 if (isolate == null) return null; // Isolate has been closed. | 1430 if (isolate == null) return null; // Isolate has been closed. |
1412 var receivePort = isolate.lookup(receivePortId); | 1431 var receivePort = isolate.lookup(receivePortId); |
1413 if (receivePort == null) return null; // Port has been closed. | 1432 if (receivePort == null) return null; // Port has been closed. |
1414 return new _NativeJsSendPort(receivePort, isolateId); | 1433 return new _NativeJsSendPort(receivePort, isolateId); |
1415 } else { | 1434 } else { |
1416 return new _WorkerSendPort(managerId, isolateId, receivePortId); | 1435 return new _WorkerSendPort(managerId, isolateId, receivePortId); |
1417 } | 1436 } |
1418 } | 1437 } |
1419 | 1438 |
1420 Capability deserializeCapability(List list) { | 1439 Capability deserializeCapability(List list) { |
1421 return new CapabilityImpl._internal(list[1]); | 1440 return new CapabilityImpl._internal(list[1]); |
1422 } | 1441 } |
| 1442 |
| 1443 Function deserializeFunction(List list) { |
| 1444 return IsolateNatives._getJSFunctionFromName(list[1]); |
| 1445 } |
1423 } | 1446 } |
1424 | 1447 |
1425 class _JsVisitedMap implements _MessageTraverserVisitedMap { | 1448 class _JsVisitedMap implements _MessageTraverserVisitedMap { |
1426 List tagged; | 1449 List tagged; |
1427 | 1450 |
1428 /** Retrieves any information stored in the native object [object]. */ | 1451 /** Retrieves any information stored in the native object [object]. */ |
1429 operator[](var object) { | 1452 operator[](var object) { |
1430 return _getAttachedInfo(object); | 1453 return _getAttachedInfo(object); |
1431 } | 1454 } |
1432 | 1455 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 } | 1535 } |
1513 | 1536 |
1514 _dispatch(var x) { | 1537 _dispatch(var x) { |
1515 // This code likely fails for user classes implementing | 1538 // This code likely fails for user classes implementing |
1516 // SendPort and Capability because it assumes the internal classes. | 1539 // SendPort and Capability because it assumes the internal classes. |
1517 if (isPrimitive(x)) return visitPrimitive(x); | 1540 if (isPrimitive(x)) return visitPrimitive(x); |
1518 if (x is List) return visitList(x); | 1541 if (x is List) return visitList(x); |
1519 if (x is Map) return visitMap(x); | 1542 if (x is Map) return visitMap(x); |
1520 if (x is SendPort) return visitSendPort(x); | 1543 if (x is SendPort) return visitSendPort(x); |
1521 if (x is Capability) return visitCapability(x); | 1544 if (x is Capability) return visitCapability(x); |
| 1545 if (x is Function) return visitFunction(x); |
1522 | 1546 |
1523 // Overridable fallback. | 1547 // Overridable fallback. |
1524 return visitObject(x); | 1548 return visitObject(x); |
1525 } | 1549 } |
1526 | 1550 |
1527 visitPrimitive(x); | 1551 visitPrimitive(x); |
1528 visitList(List x); | 1552 visitList(List x); |
1529 visitMap(Map x); | 1553 visitMap(Map x); |
1530 visitSendPort(SendPort x); | 1554 visitSendPort(SendPort x); |
1531 visitCapability(Capability x); | 1555 visitCapability(Capability x); |
| 1556 visitFunction(Function f); |
1532 | 1557 |
1533 visitObject(Object x) { | 1558 visitObject(Object x) { |
1534 // TODO(floitsch): make this a real exception. (which one)? | 1559 // TODO(floitsch): make this a real exception. (which one)? |
1535 throw "Message serialization: Illegal value $x passed"; | 1560 throw "Message serialization: Illegal value $x passed"; |
1536 } | 1561 } |
1537 | 1562 |
1538 static bool isPrimitive(x) { | 1563 static bool isPrimitive(x) { |
1539 return (x == null) || (x is String) || (x is num) || (x is bool); | 1564 return (x == null) || (x is String) || (x is num) || (x is bool); |
1540 } | 1565 } |
1541 } | 1566 } |
(...skipping 25 matching lines...) Expand all Loading... |
1567 | 1592 |
1568 // TODO(floitsch): we loose the generic type of the map. | 1593 // TODO(floitsch): we loose the generic type of the map. |
1569 copy = new Map(); | 1594 copy = new Map(); |
1570 _visited[map] = copy; | 1595 _visited[map] = copy; |
1571 map.forEach((key, val) { | 1596 map.forEach((key, val) { |
1572 copy[_dispatch(key)] = _dispatch(val); | 1597 copy[_dispatch(key)] = _dispatch(val); |
1573 }); | 1598 }); |
1574 return copy; | 1599 return copy; |
1575 } | 1600 } |
1576 | 1601 |
| 1602 visitFunction(Function f) => throw new UnimplementedError(); |
| 1603 |
1577 visitSendPort(SendPort x) => throw new UnimplementedError(); | 1604 visitSendPort(SendPort x) => throw new UnimplementedError(); |
1578 | 1605 |
1579 visitCapability(Capability x) => throw new UnimplementedError(); | 1606 visitCapability(Capability x) => throw new UnimplementedError(); |
1580 } | 1607 } |
1581 | 1608 |
1582 /** Visitor that serializes a message as a JSON array. */ | 1609 /** Visitor that serializes a message as a JSON array. */ |
1583 class _Serializer extends _MessageTraverser { | 1610 class _Serializer extends _MessageTraverser { |
1584 int _nextFreeRefId = 0; | 1611 int _nextFreeRefId = 0; |
1585 | 1612 |
1586 visitPrimitive(x) => x; | 1613 visitPrimitive(x) => x; |
(...skipping 28 matching lines...) Expand all Loading... |
1615 var result = new List()..length = len; | 1642 var result = new List()..length = len; |
1616 for (int i = 0; i < len; i++) { | 1643 for (int i = 0; i < len; i++) { |
1617 result[i] = _dispatch(list[i]); | 1644 result[i] = _dispatch(list[i]); |
1618 } | 1645 } |
1619 return result; | 1646 return result; |
1620 } | 1647 } |
1621 | 1648 |
1622 visitSendPort(SendPort x) => throw new UnimplementedError(); | 1649 visitSendPort(SendPort x) => throw new UnimplementedError(); |
1623 | 1650 |
1624 visitCapability(Capability x) => throw new UnimplementedError(); | 1651 visitCapability(Capability x) => throw new UnimplementedError(); |
| 1652 |
| 1653 visitFunction(Function f) => throw new UnimplementedError(); |
1625 } | 1654 } |
1626 | 1655 |
1627 /** Deserializes arrays created with [_Serializer]. */ | 1656 /** Deserializes arrays created with [_Serializer]. */ |
1628 abstract class _Deserializer { | 1657 abstract class _Deserializer { |
1629 Map<int, dynamic> _deserialized; | 1658 Map<int, dynamic> _deserialized; |
1630 | 1659 |
1631 _Deserializer(); | 1660 _Deserializer(); |
1632 | 1661 |
1633 static bool isPrimitive(x) { | 1662 static bool isPrimitive(x) { |
1634 return (x == null) || (x is String) || (x is num) || (x is bool); | 1663 return (x == null) || (x is String) || (x is num) || (x is bool); |
1635 } | 1664 } |
1636 | 1665 |
1637 deserialize(x) { | 1666 deserialize(x) { |
1638 if (isPrimitive(x)) return x; | 1667 if (isPrimitive(x)) return x; |
1639 // TODO(floitsch): this should be new HashMap<int, dynamic>() | 1668 // TODO(floitsch): this should be new HashMap<int, dynamic>() |
1640 _deserialized = new HashMap(); | 1669 _deserialized = new HashMap(); |
1641 return _deserializeHelper(x); | 1670 return _deserializeHelper(x); |
1642 } | 1671 } |
1643 | 1672 |
1644 _deserializeHelper(x) { | 1673 _deserializeHelper(x) { |
1645 if (isPrimitive(x)) return x; | 1674 if (isPrimitive(x)) return x; |
1646 assert(x is List); | 1675 assert(x is List); |
1647 switch (x[0]) { | 1676 switch (x[0]) { |
1648 case 'ref': return _deserializeRef(x); | 1677 case 'ref': return _deserializeRef(x); |
1649 case 'list': return _deserializeList(x); | 1678 case 'list': return _deserializeList(x); |
1650 case 'map': return _deserializeMap(x); | 1679 case 'map': return _deserializeMap(x); |
1651 case 'sendport': return deserializeSendPort(x); | 1680 case 'sendport': return deserializeSendPort(x); |
1652 case 'capability': return deserializeCapability(x); | 1681 case 'capability': return deserializeCapability(x); |
| 1682 case 'function' : return deserializeFunction(x); |
1653 default: return deserializeObject(x); | 1683 default: return deserializeObject(x); |
1654 } | 1684 } |
1655 } | 1685 } |
1656 | 1686 |
1657 _deserializeRef(List x) { | 1687 _deserializeRef(List x) { |
1658 int id = x[1]; | 1688 int id = x[1]; |
1659 var result = _deserialized[id]; | 1689 var result = _deserialized[id]; |
1660 assert(result != null); | 1690 assert(result != null); |
1661 return result; | 1691 return result; |
1662 } | 1692 } |
(...skipping 19 matching lines...) Expand all Loading... |
1682 int len = keys.length; | 1712 int len = keys.length; |
1683 assert(len == values.length); | 1713 assert(len == values.length); |
1684 for (int i = 0; i < len; i++) { | 1714 for (int i = 0; i < len; i++) { |
1685 var key = _deserializeHelper(keys[i]); | 1715 var key = _deserializeHelper(keys[i]); |
1686 var value = _deserializeHelper(values[i]); | 1716 var value = _deserializeHelper(values[i]); |
1687 result[key] = value; | 1717 result[key] = value; |
1688 } | 1718 } |
1689 return result; | 1719 return result; |
1690 } | 1720 } |
1691 | 1721 |
| 1722 deserializeFunction(List x); |
| 1723 |
1692 deserializeSendPort(List x); | 1724 deserializeSendPort(List x); |
1693 | 1725 |
1694 deserializeCapability(List x); | 1726 deserializeCapability(List x); |
1695 | 1727 |
1696 deserializeObject(List x) { | 1728 deserializeObject(List x) { |
1697 // TODO(floitsch): Use real exception (which one?). | 1729 // TODO(floitsch): Use real exception (which one?). |
1698 throw "Unexpected serialized object"; | 1730 throw "Unexpected serialized object"; |
1699 } | 1731 } |
1700 } | 1732 } |
1701 | 1733 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1813 } | 1845 } |
1814 | 1846 |
1815 bool operator==(Object other) { | 1847 bool operator==(Object other) { |
1816 if (identical(other, this)) return true; | 1848 if (identical(other, this)) return true; |
1817 if (other is CapabilityImpl) { | 1849 if (other is CapabilityImpl) { |
1818 return identical(_id, other._id); | 1850 return identical(_id, other._id); |
1819 } | 1851 } |
1820 return false; | 1852 return false; |
1821 } | 1853 } |
1822 } | 1854 } |
OLD | NEW |