Chromium Code Reviews| 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 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection' show Queue, HashMap; | 8 import 'dart:collection' show Queue, HashMap; |
| 9 import 'dart:isolate'; | 9 import 'dart:isolate'; |
| 10 import 'dart:_js_helper' show convertDartClosureToJS, | 10 import 'dart:_js_helper' show convertDartClosureToJS, |
| 11 Null; | 11 Null; |
| 12 import 'dart:_foreign_helper' show DART_CLOSURE_TO_JS, | 12 import 'dart:_foreign_helper' show DART_CLOSURE_TO_JS, |
| 13 JS, | 13 JS, |
| 14 JS_CREATE_ISOLATE, | 14 JS_CREATE_ISOLATE, |
| 15 JS_CURRENT_ISOLATE, | 15 JS_CURRENT_ISOLATE, |
| 16 JS_SET_CURRENT_ISOLATE, | 16 JS_SET_CURRENT_ISOLATE, |
| 17 IsolateContext; | 17 IsolateContext; |
| 18 | 18 |
| 19 ReceivePort lazyPort; | 19 ReceivePort lazyPort; |
| 20 | 20 |
| 21 class CloseToken { | |
| 22 /// This token is sent from [IsolateSink]s to [IsolateStream]s to ask them to | |
| 23 /// close themselves. | |
| 24 const CloseToken(); | |
| 25 } | |
| 26 | |
| 27 class JsIsolateSink extends StreamSink<dynamic> implements IsolateSink { | |
| 28 bool _isClosed = false; | |
| 29 final SendPort _port; | |
| 30 JsIsolateSink.fromPort(this._port); | |
| 31 | |
| 32 void add(dynamic message) { | |
| 33 _port.send(message); | |
| 34 } | |
| 35 | |
| 36 void addError(AsyncError errorEvent) { | |
| 37 throw new UnimplementedError("signalError on isolate streams"); | |
| 38 } | |
| 39 | |
| 40 void close() { | |
| 41 if (_isClosed) return; | |
| 42 add(const CloseToken()); | |
| 43 _isClosed = true; | |
| 44 } | |
| 45 | |
| 46 bool operator==(var other) { | |
| 47 return other is IsolateSink && _port == other._port; | |
| 48 } | |
| 49 | |
| 50 int get hashCode => _port.hashCode + 499; | |
| 51 } | |
| 52 | |
| 21 /** | 53 /** |
| 22 * Called by the compiler to support switching | 54 * Called by the compiler to support switching |
| 23 * between isolates when we get a callback from the DOM. | 55 * between isolates when we get a callback from the DOM. |
| 24 */ | 56 */ |
| 25 void _callInIsolate(_IsolateContext isolate, Function function) { | 57 void _callInIsolate(_IsolateContext isolate, Function function) { |
| 26 isolate.eval(function); | 58 isolate.eval(function); |
| 27 _globalState.topEventLoop.run(); | 59 _globalState.topEventLoop.run(); |
| 28 } | 60 } |
| 29 | 61 |
| 30 /** | 62 /** |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 899 // TODO(sigmund): replace with the following: (bug #1660) | 931 // TODO(sigmund): replace with the following: (bug #1660) |
| 900 // map.values.forEach(_dispatch); | 932 // map.values.forEach(_dispatch); |
| 901 map.values.forEach((e) => _dispatch(e)); | 933 map.values.forEach((e) => _dispatch(e)); |
| 902 } | 934 } |
| 903 | 935 |
| 904 visitSendPort(SendPort port) { | 936 visitSendPort(SendPort port) { |
| 905 if (port is _BufferingSendPort && port._port == null) { | 937 if (port is _BufferingSendPort && port._port == null) { |
| 906 ports.add(port._futurePort); | 938 ports.add(port._futurePort); |
| 907 } | 939 } |
| 908 } | 940 } |
| 941 | |
| 942 visitIsolateSink(IsolateSink sink) { | |
| 943 visitSendPort(sink._port); | |
| 944 } | |
| 945 | |
| 946 visitCloseToken(CloseToken token) { | |
| 947 // Do nothing. | |
| 948 } | |
| 909 } | 949 } |
| 910 | 950 |
| 911 /******************************************************** | 951 /******************************************************** |
| 912 Inserted from lib/isolate/dart2js/messages.dart | 952 Inserted from lib/isolate/dart2js/messages.dart |
| 913 ********************************************************/ | 953 ********************************************************/ |
| 914 | 954 |
| 915 // Defines message visitors, serialization, and deserialization. | 955 // Defines message visitors, serialization, and deserialization. |
| 916 | 956 |
| 917 /** Serialize [message] (or simulate serialization). */ | 957 /** Serialize [message] (or simulate serialization). */ |
| 918 _serializeMessage(message) { | 958 _serializeMessage(message) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 957 if (port._port != null) { | 997 if (port._port != null) { |
| 958 return visitSendPort(port._port); | 998 return visitSendPort(port._port); |
| 959 } else { | 999 } else { |
| 960 // TODO(floitsch): Use real exception (which one?). | 1000 // TODO(floitsch): Use real exception (which one?). |
| 961 throw | 1001 throw |
| 962 "internal error: must call _waitForPendingPorts to ensure all" | 1002 "internal error: must call _waitForPendingPorts to ensure all" |
| 963 " ports are resolved at this point."; | 1003 " ports are resolved at this point."; |
| 964 } | 1004 } |
| 965 } | 1005 } |
| 966 | 1006 |
| 1007 visitIsolateSink(IsolateSink sink) { | |
| 1008 SendPort port = sink._port; | |
| 1009 bool isClosed = sink._isClosed; | |
| 1010 return ['isolateSink', visitSendPort(port), isClosed]; | |
| 1011 } | |
| 1012 | |
| 1013 visitCloseToken(CloseToken token) { | |
| 1014 return ['closeToken']; | |
| 1015 } | |
| 967 } | 1016 } |
| 968 | 1017 |
| 969 | 1018 |
| 970 class _JsCopier extends _Copier { | 1019 class _JsCopier extends _Copier { |
| 971 | 1020 |
| 972 _JsCopier() : super() { _visited = new _JsVisitedMap(); } | 1021 _JsCopier() : super() { _visited = new _JsVisitedMap(); } |
| 973 | 1022 |
| 974 visitSendPort(SendPort x) { | 1023 visitSendPort(SendPort x) { |
| 975 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x); | 1024 if (x is _NativeJsSendPort) return visitNativeJsSendPort(x); |
| 976 if (x is _WorkerSendPort) return visitWorkerSendPort(x); | 1025 if (x is _WorkerSendPort) return visitWorkerSendPort(x); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 991 if (port._port != null) { | 1040 if (port._port != null) { |
| 992 return visitSendPort(port._port); | 1041 return visitSendPort(port._port); |
| 993 } else { | 1042 } else { |
| 994 // TODO(floitsch): Use real exception (which one?). | 1043 // TODO(floitsch): Use real exception (which one?). |
| 995 throw | 1044 throw |
| 996 "internal error: must call _waitForPendingPorts to ensure all" | 1045 "internal error: must call _waitForPendingPorts to ensure all" |
| 997 " ports are resolved at this point."; | 1046 " ports are resolved at this point."; |
| 998 } | 1047 } |
| 999 } | 1048 } |
| 1000 | 1049 |
| 1050 IsolateSink visitIsolateSink(IsolateSink sink) { | |
| 1051 SendPort port = sink._port; | |
| 1052 bool isClosed = sink._isClosed; | |
| 1053 IsolateSink result = new JsIsolateSink.fromPort(visitSendPort(port)); | |
| 1054 result._isClosed = isClosed; | |
| 1055 return result; | |
| 1056 } | |
| 1057 | |
| 1058 CloseToken visitCloseToken(CloseToken token) { | |
| 1059 return token; // Can be shared. | |
| 1060 } | |
| 1001 } | 1061 } |
| 1002 | 1062 |
| 1003 class _JsDeserializer extends _Deserializer { | 1063 class _JsDeserializer extends _Deserializer { |
| 1004 | 1064 |
| 1005 SendPort deserializeSendPort(List x) { | 1065 SendPort deserializeSendPort(List x) { |
| 1006 int managerId = x[1]; | 1066 int managerId = x[1]; |
| 1007 int isolateId = x[2]; | 1067 int isolateId = x[2]; |
| 1008 int receivePortId = x[3]; | 1068 int receivePortId = x[3]; |
| 1009 // If two isolates are in the same manager, we use NativeJsSendPorts to | 1069 // If two isolates are in the same manager, we use NativeJsSendPorts to |
| 1010 // deliver messages directly without using postMessage. | 1070 // deliver messages directly without using postMessage. |
| 1011 if (managerId == _globalState.currentManagerId) { | 1071 if (managerId == _globalState.currentManagerId) { |
| 1012 var isolate = _globalState.isolates[isolateId]; | 1072 var isolate = _globalState.isolates[isolateId]; |
| 1013 if (isolate == null) return null; // Isolate has been closed. | 1073 if (isolate == null) return null; // Isolate has been closed. |
| 1014 var receivePort = isolate.lookup(receivePortId); | 1074 var receivePort = isolate.lookup(receivePortId); |
| 1015 if (receivePort == null) return null; // Port has been closed. | 1075 if (receivePort == null) return null; // Port has been closed. |
| 1016 return new _NativeJsSendPort(receivePort, isolateId); | 1076 return new _NativeJsSendPort(receivePort, isolateId); |
| 1017 } else { | 1077 } else { |
| 1018 return new _WorkerSendPort(managerId, isolateId, receivePortId); | 1078 return new _WorkerSendPort(managerId, isolateId, receivePortId); |
| 1019 } | 1079 } |
| 1020 } | 1080 } |
| 1021 | 1081 |
| 1082 IsolateSink deserializeIsolateSink(List x) { | |
|
Lasse Reichstein Nielsen
2013/03/19 12:01:55
Better name than 'x', please.
floitsch
2013/03/19 13:18:59
Done.
| |
| 1083 SendPort port = deserializeSendPort(x[1]); | |
| 1084 bool isClosed = x[2]; | |
| 1085 IsolateSink result = new JsIsolateSink.fromPort(port); | |
| 1086 result._isClosed = isClosed; | |
| 1087 return result; | |
| 1088 } | |
| 1089 | |
| 1090 CloseToken deserializeCloseToken(List x) { | |
| 1091 return const CloseToken(); | |
| 1092 } | |
| 1022 } | 1093 } |
| 1023 | 1094 |
| 1024 class _JsVisitedMap implements _MessageTraverserVisitedMap { | 1095 class _JsVisitedMap implements _MessageTraverserVisitedMap { |
| 1025 List tagged; | 1096 List tagged; |
| 1026 | 1097 |
| 1027 /** Retrieves any information stored in the native object [object]. */ | 1098 /** Retrieves any information stored in the native object [object]. */ |
| 1028 operator[](var object) { | 1099 operator[](var object) { |
| 1029 return _getAttachedInfo(object); | 1100 return _getAttachedInfo(object); |
| 1030 } | 1101 } |
| 1031 | 1102 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1109 } | 1180 } |
| 1110 return result; | 1181 return result; |
| 1111 } | 1182 } |
| 1112 | 1183 |
| 1113 _dispatch(var x) { | 1184 _dispatch(var x) { |
| 1114 if (isPrimitive(x)) return visitPrimitive(x); | 1185 if (isPrimitive(x)) return visitPrimitive(x); |
| 1115 if (x is List) return visitList(x); | 1186 if (x is List) return visitList(x); |
| 1116 if (x is Map) return visitMap(x); | 1187 if (x is Map) return visitMap(x); |
| 1117 if (x is SendPort) return visitSendPort(x); | 1188 if (x is SendPort) return visitSendPort(x); |
| 1118 if (x is SendPortSync) return visitSendPortSync(x); | 1189 if (x is SendPortSync) return visitSendPortSync(x); |
| 1190 if (x is JsIsolateSink) return visitIsolateSink(x); | |
| 1191 if (x is CloseToken) return visitCloseToken(x); | |
| 1119 | 1192 |
| 1120 // Overridable fallback. | 1193 // Overridable fallback. |
| 1121 return visitObject(x); | 1194 return visitObject(x); |
| 1122 } | 1195 } |
| 1123 | 1196 |
| 1124 visitPrimitive(x); | 1197 visitPrimitive(x); |
| 1125 visitList(List x); | 1198 visitList(List x); |
| 1126 visitMap(Map x); | 1199 visitMap(Map x); |
| 1127 visitSendPort(SendPort x); | 1200 visitSendPort(SendPort x); |
| 1128 visitSendPortSync(SendPortSync x); | 1201 visitSendPortSync(SendPortSync x); |
| 1202 visitIsolateSink(IsolateSink x); | |
| 1203 visitCloseToken(CloseToken x); | |
| 1129 | 1204 |
| 1130 visitObject(Object x) { | 1205 visitObject(Object x) { |
| 1131 // TODO(floitsch): make this a real exception. (which one)? | 1206 // TODO(floitsch): make this a real exception. (which one)? |
| 1132 throw "Message serialization: Illegal value $x passed"; | 1207 throw "Message serialization: Illegal value $x passed"; |
| 1133 } | 1208 } |
| 1134 | 1209 |
| 1135 static bool isPrimitive(x) { | 1210 static bool isPrimitive(x) { |
| 1136 return (x == null) || (x is String) || (x is num) || (x is bool); | 1211 return (x == null) || (x is String) || (x is num) || (x is bool); |
| 1137 } | 1212 } |
| 1138 } | 1213 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1230 } | 1305 } |
| 1231 | 1306 |
| 1232 _deserializeHelper(x) { | 1307 _deserializeHelper(x) { |
| 1233 if (isPrimitive(x)) return x; | 1308 if (isPrimitive(x)) return x; |
| 1234 assert(x is List); | 1309 assert(x is List); |
| 1235 switch (x[0]) { | 1310 switch (x[0]) { |
| 1236 case 'ref': return _deserializeRef(x); | 1311 case 'ref': return _deserializeRef(x); |
| 1237 case 'list': return _deserializeList(x); | 1312 case 'list': return _deserializeList(x); |
| 1238 case 'map': return _deserializeMap(x); | 1313 case 'map': return _deserializeMap(x); |
| 1239 case 'sendport': return deserializeSendPort(x); | 1314 case 'sendport': return deserializeSendPort(x); |
| 1315 case 'isolateSink': return deserializeIsolateSink(x); | |
| 1316 case 'closeToken': return deserializeCloseToken(x); | |
| 1240 default: return deserializeObject(x); | 1317 default: return deserializeObject(x); |
| 1241 } | 1318 } |
| 1242 } | 1319 } |
| 1243 | 1320 |
| 1244 _deserializeRef(List x) { | 1321 _deserializeRef(List x) { |
| 1245 int id = x[1]; | 1322 int id = x[1]; |
| 1246 var result = _deserialized[id]; | 1323 var result = _deserialized[id]; |
| 1247 assert(result != null); | 1324 assert(result != null); |
| 1248 return result; | 1325 return result; |
| 1249 } | 1326 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1271 for (int i = 0; i < len; i++) { | 1348 for (int i = 0; i < len; i++) { |
| 1272 var key = _deserializeHelper(keys[i]); | 1349 var key = _deserializeHelper(keys[i]); |
| 1273 var value = _deserializeHelper(values[i]); | 1350 var value = _deserializeHelper(values[i]); |
| 1274 result[key] = value; | 1351 result[key] = value; |
| 1275 } | 1352 } |
| 1276 return result; | 1353 return result; |
| 1277 } | 1354 } |
| 1278 | 1355 |
| 1279 deserializeSendPort(List x); | 1356 deserializeSendPort(List x); |
| 1280 | 1357 |
| 1358 deserializeIsolateSink(List x); | |
| 1359 | |
| 1360 deserializeCloseToken(List x); | |
| 1361 | |
| 1281 deserializeObject(List x) { | 1362 deserializeObject(List x) { |
| 1282 // TODO(floitsch): Use real exception (which one?). | 1363 // TODO(floitsch): Use real exception (which one?). |
| 1283 throw "Unexpected serialized object"; | 1364 throw "Unexpected serialized object"; |
| 1284 } | 1365 } |
| 1285 } | 1366 } |
| 1286 | 1367 |
| 1287 class TimerImpl implements Timer { | 1368 class TimerImpl implements Timer { |
| 1288 final bool _once; | 1369 final bool _once; |
| 1289 bool _inEventLoop = false; | 1370 bool _inEventLoop = false; |
| 1290 int _handle; | 1371 int _handle; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1344 JS('void', '#.clearInterval(#)', globalThis, _handle); | 1425 JS('void', '#.clearInterval(#)', globalThis, _handle); |
| 1345 } | 1426 } |
| 1346 _handle = null; | 1427 _handle = null; |
| 1347 } else { | 1428 } else { |
| 1348 throw new UnsupportedError("Canceling a timer."); | 1429 throw new UnsupportedError("Canceling a timer."); |
| 1349 } | 1430 } |
| 1350 } | 1431 } |
| 1351 } | 1432 } |
| 1352 | 1433 |
| 1353 bool hasTimer() => JS('', '#.setTimeout', globalThis) != null; | 1434 bool hasTimer() => JS('', '#.setTimeout', globalThis) != null; |
| OLD | NEW |