OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// This library defines runtime operations on objects used by the code | 5 /// This library defines runtime operations on objects used by the code |
6 /// generator. | 6 /// generator. |
7 part of dart._runtime; | 7 part of dart._runtime; |
8 | 8 |
9 class InvocationImpl extends Invocation { | 9 class InvocationImpl extends Invocation { |
10 final Symbol memberName; | 10 final Symbol memberName; |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 return map; | 610 return map; |
611 })()'''); | 611 })()'''); |
612 | 612 |
613 @JSExportName('assert') | 613 @JSExportName('assert') |
614 assert_(condition, [message]) => JS( | 614 assert_(condition, [message]) => JS( |
615 '', | 615 '', |
616 '''(() => { | 616 '''(() => { |
617 if (!$condition) $throwAssertionError(message); | 617 if (!$condition) $throwAssertionError(message); |
618 })()'''); | 618 })()'''); |
619 | 619 |
620 var _stack = null; | 620 /// Store a JS error for an exception. For non-primitives, we store as an |
| 621 /// expando. For primitive, we use a side cache. To limit memory leakage, we |
| 622 /// only keep the last [_maxTraceCache] entries. |
| 623 final _error = JS('', 'Symbol("_error")'); |
| 624 Map _primitiveErrorCache; |
| 625 const _maxErrorCache = 10; |
| 626 |
| 627 bool _isJsError(exception) { |
| 628 return JS('bool', '#.Error != null && # instanceof #.Error', global_, |
| 629 exception, global_); |
| 630 } |
| 631 |
| 632 // Record/return the JS error for an exception. If an error was already |
| 633 // recorded, prefer that to [newError]. |
| 634 recordJsError(exception, [newError]) { |
| 635 if (_isJsError(exception)) return exception; |
| 636 |
| 637 var useExpando = |
| 638 exception != null && JS('bool', 'typeof # == "object"', exception); |
| 639 var error; |
| 640 if (useExpando) { |
| 641 error = JS('', '#[#]', exception, _error); |
| 642 } else { |
| 643 if (_primitiveErrorCache == null) _primitiveErrorCache = {}; |
| 644 error = _primitiveErrorCache[exception]; |
| 645 } |
| 646 if (error != null) return error; |
| 647 if (newError != null) { |
| 648 error = newError; |
| 649 } else { |
| 650 // We should only hit this path when a non-Error was thrown from JS. In |
| 651 // case, there is no stack trace on the exception, so we create one: |
| 652 error = JS('', 'new Error()'); |
| 653 } |
| 654 if (useExpando) { |
| 655 JS('', '#[#] = #', exception, _error, error); |
| 656 } else { |
| 657 _primitiveErrorCache[exception] = error; |
| 658 if (_primitiveErrorCache.length > _maxErrorCache) { |
| 659 _primitiveErrorCache.remove(_primitiveErrorCache.keys.first); |
| 660 } |
| 661 } |
| 662 return error; |
| 663 } |
| 664 |
621 @JSExportName('throw') | 665 @JSExportName('throw') |
622 throw_(obj) => JS( | 666 throw_(obj) { |
623 '', | 667 // Note, we create the error here to avoid the extra frame. |
624 '''(() => { | 668 // package:stack_trace and tests appear to assume this. We could fix use |
625 $_stack = new Error(); | 669 // cases instead, but we're already on the exceptional path here. |
626 throw $obj; | 670 recordJsError(obj, JS('', 'new Error()')); |
627 })()'''); | 671 JS('', 'throw #', obj); |
628 | 672 } |
629 getError(exception) => JS( | |
630 '', | |
631 '''(() => { | |
632 var stack = $_stack; | |
633 return stack !== null ? stack : $exception; | |
634 })()'''); | |
635 | 673 |
636 // This is a utility function: it is only intended to be called from dev | 674 // This is a utility function: it is only intended to be called from dev |
637 // tools. | 675 // tools. |
638 stackPrint(exception) => JS( | 676 stackPrint(exception) { |
639 '', | 677 var error = recordJsError(exception); |
640 '''(() => { | 678 JS('', 'console.log(#.stack ? #.stack : "No stack trace for: " + #)', error, |
641 var error = $getError($exception); | 679 error, error); |
642 console.log(error.stack ? error.stack : 'No stack trace for: ' + error); | 680 } |
643 })()'''); | |
644 | 681 |
645 stackTrace(exception) => JS( | 682 // Forward to dart:_js_helper to create a _StackTrace object. |
646 '', | 683 stackTrace(exception) => getTraceFromException(exception); |
647 '''(() => { | |
648 var error = $getError($exception); | |
649 return $getTraceFromException(error); | |
650 })()'''); | |
651 | 684 |
652 /// | 685 /// |
653 /// Implements a sequence of .? operations. | 686 /// Implements a sequence of .? operations. |
654 /// | 687 /// |
655 /// Will call each successive callback, unless one returns null, which stops | 688 /// Will call each successive callback, unless one returns null, which stops |
656 /// the sequence. | 689 /// the sequence. |
657 /// | 690 /// |
658 nullSafe(obj, @rest callbacks) => JS( | 691 nullSafe(obj, @rest callbacks) => JS( |
659 '', | 692 '', |
660 '''(() => { | 693 '''(() => { |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 name = '+' + name; | 944 name = '+' + name; |
912 } | 945 } |
913 return name; | 946 return name; |
914 } | 947 } |
915 | 948 |
916 /// Emulates the implicit "loadLibrary" function provided by a deferred library. | 949 /// Emulates the implicit "loadLibrary" function provided by a deferred library. |
917 /// | 950 /// |
918 /// Libraries are not actually deferred in DDC, so this just returns a future | 951 /// Libraries are not actually deferred in DDC, so this just returns a future |
919 /// that completes immediately. | 952 /// that completes immediately. |
920 Future loadLibrary() => new Future.value(); | 953 Future loadLibrary() => new Future.value(); |
OLD | NEW |