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 | 10 import 'dart:_js_helper' show |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 supportsWorkers = isWorker | 221 supportsWorkers = isWorker |
222 || (isWorkerDefined && IsolateNatives.thisScript != null); | 222 || (isWorkerDefined && IsolateNatives.thisScript != null); |
223 fromCommandLine = !isWindowDefined && !isWorker; | 223 fromCommandLine = !isWindowDefined && !isWorker; |
224 } | 224 } |
225 | 225 |
226 void _nativeInitWorkerMessageHandler() { | 226 void _nativeInitWorkerMessageHandler() { |
227 var function = JS('', | 227 var function = JS('', |
228 "(function (f, a) { return function (e) { f(a, e); }})(#, #)", | 228 "(function (f, a) { return function (e) { f(a, e); }})(#, #)", |
229 DART_CLOSURE_TO_JS(IsolateNatives._processWorkerMessage), | 229 DART_CLOSURE_TO_JS(IsolateNatives._processWorkerMessage), |
230 mainManager); | 230 mainManager); |
231 JS("void", r"#.onmessage = #", globalThis, function); | 231 JS("void", r"self.onmessage = #", function); |
232 // We define dartPrint so that the implementation of the Dart | 232 // We define dartPrint so that the implementation of the Dart |
233 // print method knows what to call. | 233 // print method knows what to call. |
234 // TODO(ngeoffray): Should we forward to the main isolate? What if | 234 // TODO(ngeoffray): Should we forward to the main isolate? What if |
235 // it exited? | 235 // it exited? |
236 JS('void', r'#.dartPrint = function (object) {}', globalThis); | 236 JS('void', r'self.dartPrint = function (object) {}'); |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 /** | 240 /** |
241 * Close the worker running this code if all isolates are done and | 241 * Close the worker running this code if all isolates are done and |
242 * there are no active async JavaScript tasks still running. | 242 * there are no active async JavaScript tasks still running. |
243 */ | 243 */ |
244 void maybeCloseWorker() { | 244 void maybeCloseWorker() { |
245 if (isWorker | 245 if (isWorker |
246 && isolates.isEmpty | 246 && isolates.isEmpty |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 /** Function called with an uncaught error. */ | 396 /** Function called with an uncaught error. */ |
397 void handleUncaughtError(error, StackTrace stackTrace) { | 397 void handleUncaughtError(error, StackTrace stackTrace) { |
398 // Just print the error if there is no error listener registered. | 398 // Just print the error if there is no error listener registered. |
399 if (errorPorts.isEmpty) { | 399 if (errorPorts.isEmpty) { |
400 // An uncaught error in the root isolate will terminate the program? | 400 // An uncaught error in the root isolate will terminate the program? |
401 if (errorsAreFatal && identical(this, _globalState.rootContext)) { | 401 if (errorsAreFatal && identical(this, _globalState.rootContext)) { |
402 // The error will be rethrown to reach the global scope, so | 402 // The error will be rethrown to reach the global scope, so |
403 // don't print it. | 403 // don't print it. |
404 return; | 404 return; |
405 } | 405 } |
406 if (JS('bool', '#.console != null && ' | 406 if (JS('bool', '!!self.console && !!self.console.error')) { |
407 'typeof #.console.error == "function"', | 407 JS('void', 'self.console.error(#, #)', error, stackTrace); |
408 globalThis, globalThis)) { | |
409 JS('void', '#.console.error(#, #)', globalThis, error, stackTrace); | |
410 } else { | 408 } else { |
411 print(error); | 409 print(error); |
412 if (stackTrace != null) print(stackTrace); | 410 if (stackTrace != null) print(stackTrace); |
413 } | 411 } |
414 return; | 412 return; |
415 } | 413 } |
416 List message = new List(2) | 414 List message = new List(2) |
417 ..[0] = error.toString() | 415 ..[0] = error.toString() |
418 ..[1] = (stackTrace == null) ? null : stackTrace.toString(); | 416 ..[1] = (stackTrace == null) ? null : stackTrace.toString(); |
419 for (SendPort port in errorPorts) port.send(message); | 417 for (SendPort port in errorPorts) port.send(message); |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 // | 676 // |
679 // See: http://www.w3.org/TR/workers/#the-global-scope | 677 // See: http://www.w3.org/TR/workers/#the-global-scope |
680 // and: http://www.w3.org/TR/Window/#dfn-self-attribute | 678 // and: http://www.w3.org/TR/Window/#dfn-self-attribute |
681 JS("void", r"self.postMessage(#)", msg); | 679 JS("void", r"self.postMessage(#)", msg); |
682 } | 680 } |
683 } | 681 } |
684 | 682 |
685 const String _SPAWNED_SIGNAL = "spawned"; | 683 const String _SPAWNED_SIGNAL = "spawned"; |
686 const String _SPAWN_FAILED_SIGNAL = "spawn failed"; | 684 const String _SPAWN_FAILED_SIGNAL = "spawn failed"; |
687 | 685 |
688 var globalThis = Primitives.computeGlobalThis(); | 686 get globalWindow => JS('', "self.window"); |
689 var globalWindow = JS('', "#.window", globalThis); | 687 get globalWorker => JS('', "self.Worker"); |
690 var globalWorker = JS('', "#.Worker", globalThis); | 688 bool get globalPostMessageDefined => JS('bool', "!!self.postMessage"); |
691 bool globalPostMessageDefined = | |
692 JS('', "#.postMessage !== (void 0)", globalThis); | |
693 | 689 |
694 typedef _MainFunction(); | 690 typedef _MainFunction(); |
695 typedef _MainFunctionArgs(args); | 691 typedef _MainFunctionArgs(args); |
696 typedef _MainFunctionArgsMessage(args, message); | 692 typedef _MainFunctionArgsMessage(args, message); |
697 | 693 |
698 /// Note: IsolateNatives depends on _globalState which is only set up correctly | 694 /// Note: IsolateNatives depends on _globalState which is only set up correctly |
699 /// when 'dart:isolate' has been imported. | 695 /// when 'dart:isolate' has been imported. |
700 class IsolateNatives { | 696 class IsolateNatives { |
701 | 697 |
702 // We set [enableSpawnWorker] to true (not null) when calling isolate | 698 // We set [enableSpawnWorker] to true (not null) when calling isolate |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 } else { | 858 } else { |
863 try { | 859 try { |
864 _consoleLog(msg); | 860 _consoleLog(msg); |
865 } catch (e, trace) { | 861 } catch (e, trace) { |
866 throw new Exception(trace); | 862 throw new Exception(trace); |
867 } | 863 } |
868 } | 864 } |
869 } | 865 } |
870 | 866 |
871 static void _consoleLog(msg) { | 867 static void _consoleLog(msg) { |
872 JS("void", r"#.console.log(#)", globalThis, msg); | 868 JS("void", r"self.console.log(#)", msg); |
873 } | 869 } |
874 | 870 |
875 static _getJSFunctionFromName(String functionName) { | 871 static _getJSFunctionFromName(String functionName) { |
876 return JS("", "init.globalFunctions[#]()", functionName); | 872 return JS("", "init.globalFunctions[#]()", functionName); |
877 } | 873 } |
878 | 874 |
879 /** | 875 /** |
880 * Get a string name for the function, if possible. The result for | 876 * Get a string name for the function, if possible. The result for |
881 * anonymous functions is browser-dependent -- it may be "" or "anonymous" | 877 * anonymous functions is browser-dependent -- it may be "" or "anonymous" |
882 * but you should probably not count on this. | 878 * but you should probably not count on this. |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1705 } else if (hasTimer()) { | 1701 } else if (hasTimer()) { |
1706 | 1702 |
1707 void internalCallback() { | 1703 void internalCallback() { |
1708 _handle = null; | 1704 _handle = null; |
1709 leaveJsAsync(); | 1705 leaveJsAsync(); |
1710 callback(); | 1706 callback(); |
1711 } | 1707 } |
1712 | 1708 |
1713 enterJsAsync(); | 1709 enterJsAsync(); |
1714 | 1710 |
1715 _handle = JS('int', '#.setTimeout(#, #)', | 1711 _handle = JS('int', 'self.setTimeout(#, #)', |
1716 globalThis, | |
1717 convertDartClosureToJS(internalCallback, 0), | 1712 convertDartClosureToJS(internalCallback, 0), |
1718 milliseconds); | 1713 milliseconds); |
1719 } else { | 1714 } else { |
1720 assert(milliseconds > 0); | 1715 assert(milliseconds > 0); |
1721 throw new UnsupportedError("Timer greater than 0."); | 1716 throw new UnsupportedError("Timer greater than 0."); |
1722 } | 1717 } |
1723 } | 1718 } |
1724 | 1719 |
1725 TimerImpl.periodic(int milliseconds, void callback(Timer timer)) | 1720 TimerImpl.periodic(int milliseconds, void callback(Timer timer)) |
1726 : _once = false { | 1721 : _once = false { |
1727 if (hasTimer()) { | 1722 if (hasTimer()) { |
1728 enterJsAsync(); | 1723 enterJsAsync(); |
1729 _handle = JS('int', '#.setInterval(#, #)', | 1724 _handle = JS('int', 'self.setInterval(#, #)', |
1730 globalThis, | |
1731 convertDartClosureToJS(() { callback(this); }, 0), | 1725 convertDartClosureToJS(() { callback(this); }, 0), |
1732 milliseconds); | 1726 milliseconds); |
1733 } else { | 1727 } else { |
1734 throw new UnsupportedError("Periodic timer."); | 1728 throw new UnsupportedError("Periodic timer."); |
1735 } | 1729 } |
1736 } | 1730 } |
1737 | 1731 |
1738 void cancel() { | 1732 void cancel() { |
1739 if (hasTimer()) { | 1733 if (hasTimer()) { |
1740 if (_inEventLoop) { | 1734 if (_inEventLoop) { |
1741 throw new UnsupportedError("Timer in event loop cannot be canceled."); | 1735 throw new UnsupportedError("Timer in event loop cannot be canceled."); |
1742 } | 1736 } |
1743 if (_handle == null) return; | 1737 if (_handle == null) return; |
1744 leaveJsAsync(); | 1738 leaveJsAsync(); |
1745 if (_once) { | 1739 if (_once) { |
1746 JS('void', '#.clearTimeout(#)', globalThis, _handle); | 1740 JS('void', 'self.clearTimeout(#)', _handle); |
1747 } else { | 1741 } else { |
1748 JS('void', '#.clearInterval(#)', globalThis, _handle); | 1742 JS('void', 'self.clearInterval(#)', _handle); |
1749 } | 1743 } |
1750 _handle = null; | 1744 _handle = null; |
1751 } else { | 1745 } else { |
1752 throw new UnsupportedError("Canceling a timer."); | 1746 throw new UnsupportedError("Canceling a timer."); |
1753 } | 1747 } |
1754 } | 1748 } |
1755 | 1749 |
1756 bool get isActive => _handle != null; | 1750 bool get isActive => _handle != null; |
1757 } | 1751 } |
1758 | 1752 |
1759 bool hasTimer() => JS('', '#.setTimeout', globalThis) != null; | 1753 bool hasTimer() => JS('', 'self.setTimeout') != null; |
1760 | 1754 |
1761 | 1755 |
1762 /** | 1756 /** |
1763 * Implementation class for [Capability]. | 1757 * Implementation class for [Capability]. |
1764 * | 1758 * |
1765 * It has the same name to make it harder for users to distinguish. | 1759 * It has the same name to make it harder for users to distinguish. |
1766 */ | 1760 */ |
1767 class CapabilityImpl implements Capability { | 1761 class CapabilityImpl implements Capability { |
1768 /** Internal random secret identifying the capability. */ | 1762 /** Internal random secret identifying the capability. */ |
1769 final int _id; | 1763 final int _id; |
(...skipping 18 matching lines...) Expand all Loading... |
1788 } | 1782 } |
1789 | 1783 |
1790 bool operator==(Object other) { | 1784 bool operator==(Object other) { |
1791 if (identical(other, this)) return true; | 1785 if (identical(other, this)) return true; |
1792 if (other is CapabilityImpl) { | 1786 if (other is CapabilityImpl) { |
1793 return identical(_id, other._id); | 1787 return identical(_id, other._id); |
1794 } | 1788 } |
1795 return false; | 1789 return false; |
1796 } | 1790 } |
1797 } | 1791 } |
OLD | NEW |