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

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

Issue 945783002: Dart2js async-await. Propagate stacktraces from futures. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix status file Created 5 years, 10 months 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 _js_helper; 5 library _js_helper;
6 6
7 import 'dart:_async_await_error_codes' as async_error_codes; 7 import 'dart:_async_await_error_codes' as async_error_codes;
8 8
9 import 'dart:_js_embedded_names' show 9 import 'dart:_js_embedded_names' show
10 JsGetName, 10 JsGetName,
(...skipping 1766 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 if (thrownStackTrace == null) { 1777 if (thrownStackTrace == null) {
1778 JS('void', r'#.$thrownJsError = #', error, ex); 1778 JS('void', r'#.$thrownJsError = #', error, ex);
1779 } 1779 }
1780 } 1780 }
1781 return error; 1781 return error;
1782 } 1782 }
1783 1783
1784 // Note that we are checking if the object has the property. If it 1784 // Note that we are checking if the object has the property. If it
1785 // has, it could be set to null if the thrown value is null. 1785 // has, it could be set to null if the thrown value is null.
1786 if (ex == null) return null; 1786 if (ex == null) return null;
1787 if (ex is ExceptionAndStackTrace) {
1788 return saveStackTrace(ex.dartException);
1789 }
1787 if (JS('bool', 'typeof # !== "object"', ex)) return ex; 1790 if (JS('bool', 'typeof # !== "object"', ex)) return ex;
1788 1791
1789 if (JS('bool', r'"dartException" in #', ex)) { 1792 if (JS('bool', r'"dartException" in #', ex)) {
1790 return saveStackTrace(JS('', r'#.dartException', ex)); 1793 return saveStackTrace(JS('', r'#.dartException', ex));
1791 } else if (!JS('bool', r'"message" in #', ex)) { 1794 } else if (!JS('bool', r'"message" in #', ex)) {
1792 return ex; 1795 return ex;
1793 } 1796 }
1794 1797
1795 // Grab hold of the exception message. This field is available on 1798 // Grab hold of the exception message. This field is available on
1796 // all supported browsers. 1799 // all supported browsers.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 // Just return the exception. We should not wrap it because in case 1903 // Just return the exception. We should not wrap it because in case
1901 // the exception comes from the DOM, it is a JavaScript 1904 // the exception comes from the DOM, it is a JavaScript
1902 // object backed by a native Dart class. 1905 // object backed by a native Dart class.
1903 return ex; 1906 return ex;
1904 } 1907 }
1905 1908
1906 /** 1909 /**
1907 * Called by generated code to fetch the stack trace from an 1910 * Called by generated code to fetch the stack trace from an
1908 * exception. Should never return null. 1911 * exception. Should never return null.
1909 */ 1912 */
1910 StackTrace getTraceFromException(exception) => new _StackTrace(exception); 1913 StackTrace getTraceFromException(exception) {
1914 if (exception is ExceptionAndStackTrace) {
1915 return exception.stackTrace;
1916 }
1917 return new _StackTrace(exception);
1918 }
1911 1919
1912 class _StackTrace implements StackTrace { 1920 class _StackTrace implements StackTrace {
1913 var _exception; 1921 var _exception;
1914 String _trace; 1922 String _trace;
1915 _StackTrace(this._exception); 1923 _StackTrace(this._exception);
1916 1924
1917 String toString() { 1925 String toString() {
1918 if (_trace != null) return JS('String', '#', _trace); 1926 if (_trace != null) return JS('String', '#', _trace);
1919 1927
1920 String trace; 1928 String trace;
(...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after
3549 } 3557 }
3550 3558
3551 void badMain() { 3559 void badMain() {
3552 throw new MainError("'main' is not a function."); 3560 throw new MainError("'main' is not a function.");
3553 } 3561 }
3554 3562
3555 void mainHasTooManyParameters() { 3563 void mainHasTooManyParameters() {
3556 throw new MainError("'main' expects too many parameters."); 3564 throw new MainError("'main' expects too many parameters.");
3557 } 3565 }
3558 3566
3567 /// A wrapper around an exception, much like the one created by [wrapException]
3568 /// but with a pre-given stack-trace.
3569 class ExceptionAndStackTrace {
3570 dynamic dartException;
3571 StackTrace stackTrace;
3572
3573 ExceptionAndStackTrace(this.dartException, this.stackTrace);
3574 }
3575
3559 /// Runtime support for async-await transformation. 3576 /// Runtime support for async-await transformation.
3560 /// 3577 ///
3561 /// This function is called by a transformed function on each await and return 3578 /// This function is called by a transformed function on each await and return
3562 /// in the untransformed function, and before starting. 3579 /// in the untransformed function, and before starting.
3563 /// 3580 ///
3564 /// If [object] is not a future it will be wrapped in a `new Future.value`. 3581 /// If [object] is not a future it will be wrapped in a `new Future.value`.
3565 /// 3582 ///
3566 /// If [asyncBody] is [async_error_codes.SUCCESS]/[async_error_codes.ERROR] it 3583 /// If [asyncBody] is [async_error_codes.SUCCESS]/[async_error_codes.ERROR] it
3567 /// indicates a return or throw from the async function, and 3584 /// indicates a return or throw from the async function, and
3568 /// complete/completeError is called on [completer] with [object]. 3585 /// complete/completeError is called on [completer] with [object].
(...skipping 11 matching lines...) Expand all
3580 return; 3597 return;
3581 } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) { 3598 } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) {
3582 // The error is a js-error. 3599 // The error is a js-error.
3583 completer.completeError(unwrapException(object), 3600 completer.completeError(unwrapException(object),
3584 getTraceFromException(object)); 3601 getTraceFromException(object));
3585 return; 3602 return;
3586 } 3603 }
3587 Future future = object is Future ? object : new Future.value(object); 3604 Future future = object is Future ? object : new Future.value(object);
3588 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3605 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3589 async_error_codes.SUCCESS), 3606 async_error_codes.SUCCESS),
3590 onError: _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3607 onError: (dynamic error, StackTrace stackTrace) {
3591 async_error_codes.ERROR)); 3608 ExceptionAndStackTrace wrapped =
3609 new ExceptionAndStackTrace(error, stackTrace);
3610 return _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3611 async_error_codes.ERROR)(wrapped);
3612 });
3592 return completer.future; 3613 return completer.future;
3593 } 3614 }
3594 3615
3595 Function _wrapJsFunctionForAsync(dynamic /* js function */ function, 3616 Function _wrapJsFunctionForAsync(dynamic /* js function */ function,
3596 int errorCode) { 3617 int errorCode) {
3597 var protected = JS('', """ 3618 var protected = JS('', """
3598 // Invokes [function] with [errorCode] and [result]. 3619 // Invokes [function] with [errorCode] and [result].
3599 // 3620 //
3600 // If (and as long as) the invocation throws, calls [function] again, 3621 // If (and as long as) the invocation throws, calls [function] again,
3601 // with an error-code. 3622 // with an error-code.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
3696 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3717 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3697 async_error_codes.SUCCESS)(null); 3718 async_error_codes.SUCCESS)(null);
3698 }); 3719 });
3699 return; 3720 return;
3700 } 3721 }
3701 } 3722 }
3702 3723
3703 Future future = object is Future ? object : new Future.value(object); 3724 Future future = object is Future ? object : new Future.value(object);
3704 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3725 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3705 async_error_codes.SUCCESS), 3726 async_error_codes.SUCCESS),
3706 onError: _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, 3727 onError: (error, StackTrace stackTrace) {
3707 async_error_codes.ERROR)); 3728 ExceptionAndStackTrace wrapped =
3729 new ExceptionAndStackTrace(error, stackTrace);
3730 return _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
3731 async_error_codes.ERROR)
3732 (wrapped);
3733 });
3708 } 3734 }
3709 3735
3710 Stream streamOfController(AsyncStarStreamController controller) { 3736 Stream streamOfController(AsyncStarStreamController controller) {
3711 return controller.stream; 3737 return controller.stream;
3712 } 3738 }
3713 3739
3714 /// A wrapper around a [StreamController] that remembers if that controller 3740 /// A wrapper around a [StreamController] that remembers if that controller
3715 /// got a cancel. 3741 /// got a cancel.
3716 /// 3742 ///
3717 /// Also has a subSubscription that when not null will provide events for the 3743 /// Also has a subSubscription that when not null will provide events for the
3718 /// stream, and will be paused and resumed along with this controller. 3744 /// stream, and will be paused and resumed along with this controller.
3719 class AsyncStarStreamController { 3745 class AsyncStarStreamController {
3720 StreamController controller; 3746 StreamController controller;
3721 Stream get stream => controller.stream; 3747 Stream get stream => controller.stream;
3722 bool stopRunning = false; 3748 bool stopRunning = false;
3723 bool isAdding = false; 3749 bool isAdding = false;
3724 bool get isPaused => controller.isPaused; 3750 bool get isPaused => controller.isPaused;
3725 add(event) => controller.add(event); 3751 add(event) => controller.add(event);
3726 addStream(Stream stream) { 3752 addStream(Stream stream) {
3727 return controller.addStream(stream, cancelOnError: false); 3753 return controller.addStream(stream, cancelOnError: false);
3728 } 3754 }
3729 addError(error, stackTrace) => controller.addError(error, stackTrace); 3755 addError(error, stackTrace) => controller.addError(error, stackTrace);
3730 close() => controller.close(); 3756 close() => controller.close();
3731 3757
3732 AsyncStarStreamController(helperCallback) { 3758 AsyncStarStreamController(body) {
3733 controller = new StreamController( 3759 controller = new StreamController(
3734 onListen: () { 3760 onListen: () {
3735 scheduleMicrotask(() { 3761 scheduleMicrotask(() {
3736 JS('', '#(#, null)', helperCallback, async_error_codes.SUCCESS); 3762 _wrapJsFunctionForAsync(body,
3763 async_error_codes.SUCCESS)(null);
3737 }); 3764 });
3738 }, 3765 },
3739 onResume: () { 3766 onResume: () {
3740 if (!isAdding) { 3767 if (!isAdding) {
3741 asyncStarHelper(null, helperCallback, this); 3768 asyncStarHelper(null, body, this);
3742 } 3769 }
3743 }, onCancel: () { 3770 }, onCancel: () {
3744 stopRunning = true; 3771 stopRunning = true;
3745 }); 3772 });
3746 } 3773 }
3747 } 3774 }
3748 3775
3749 makeAsyncStarController(helperCallback) { 3776 makeAsyncStarController(body) {
3750 return new AsyncStarStreamController(helperCallback); 3777 return new AsyncStarStreamController(body);
3751 } 3778 }
3752 3779
3753 class IterationMarker { 3780 class IterationMarker {
3754 static const YIELD_SINGLE = 0; 3781 static const YIELD_SINGLE = 0;
3755 static const YIELD_STAR = 1; 3782 static const YIELD_STAR = 1;
3756 static const ITERATION_ENDED = 2; 3783 static const ITERATION_ENDED = 2;
3757 static const UNCAUGHT_ERROR = 3; 3784 static const UNCAUGHT_ERROR = 3;
3758 3785
3759 final value; 3786 final value;
3760 final int state; 3787 final int state;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
3848 // This is a function that will return a helper function that does the 3875 // This is a function that will return a helper function that does the
3849 // iteration of the sync*. 3876 // iteration of the sync*.
3850 // 3877 //
3851 // Each invocation should give a body with fresh state. 3878 // Each invocation should give a body with fresh state.
3852 final dynamic /* js function */ _outerHelper; 3879 final dynamic /* js function */ _outerHelper;
3853 3880
3854 SyncStarIterable(this._outerHelper); 3881 SyncStarIterable(this._outerHelper);
3855 3882
3856 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); 3883 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper));
3857 } 3884 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698