| 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 |