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

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

Issue 839323003: Implementation of async-await transformation on js ast. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Implement new ssa-nodes in ssa-tracer. 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:_js_embedded_names' show 7 import 'dart:_js_embedded_names' show
8 GET_TYPE_FROM_NAME, 8 GET_TYPE_FROM_NAME,
9 GET_ISOLATE_TAG, 9 GET_ISOLATE_TAG,
10 INTERCEPTED_NAMES, 10 INTERCEPTED_NAMES,
11 INTERCEPTORS_BY_TAG, 11 INTERCEPTORS_BY_TAG,
12 LEAF_TAGS, 12 LEAF_TAGS,
13 METADATA, 13 METADATA,
14 DEFERRED_LIBRARY_URIS, 14 DEFERRED_LIBRARY_URIS,
15 DEFERRED_LIBRARY_HASHES, 15 DEFERRED_LIBRARY_HASHES,
16 INITIALIZE_LOADED_HUNK, 16 INITIALIZE_LOADED_HUNK,
17 IS_HUNK_LOADED, 17 IS_HUNK_LOADED,
18 IS_HUNK_INITIALIZED, 18 IS_HUNK_INITIALIZED,
19 NATIVE_SUPERCLASS_TAG_NAME; 19 NATIVE_SUPERCLASS_TAG_NAME;
20 20
21 import 'dart:collection'; 21 import 'dart:collection';
22 import 'dart:_isolate_helper' show 22 import 'dart:_isolate_helper' show
23 IsolateNatives, 23 IsolateNatives,
24 leaveJsAsync, 24 leaveJsAsync,
25 enterJsAsync, 25 enterJsAsync,
26 isWorker; 26 isWorker;
27 27
28 import 'dart:async' show Future, DeferredLoadException, Completer; 28 import 'dart:async'
29 show Future, DeferredLoadException, Completer, StreamController;
29 30
30 import 'dart:_foreign_helper' show 31 import 'dart:_foreign_helper' show
31 DART_CLOSURE_TO_JS, 32 DART_CLOSURE_TO_JS,
32 JS, 33 JS,
33 JS_CALL_IN_ISOLATE, 34 JS_CALL_IN_ISOLATE,
34 JS_CONST, 35 JS_CONST,
35 JS_CURRENT_ISOLATE, 36 JS_CURRENT_ISOLATE,
36 JS_CURRENT_ISOLATE_CONTEXT, 37 JS_CURRENT_ISOLATE_CONTEXT,
37 JS_DART_OBJECT_CONSTRUCTOR, 38 JS_DART_OBJECT_CONSTRUCTOR,
38 JS_EFFECT, 39 JS_EFFECT,
(...skipping 3410 matching lines...) Expand 10 before | Expand all | Expand 10 after
3449 throw new MainError("No top-level function named 'main'."); 3450 throw new MainError("No top-level function named 'main'.");
3450 } 3451 }
3451 3452
3452 void badMain() { 3453 void badMain() {
3453 throw new MainError("'main' is not a function."); 3454 throw new MainError("'main' is not a function.");
3454 } 3455 }
3455 3456
3456 void mainHasTooManyParameters() { 3457 void mainHasTooManyParameters() {
3457 throw new MainError("'main' expects too many parameters."); 3458 throw new MainError("'main' expects too many parameters.");
3458 } 3459 }
3460
3461 /// Runtime support for async-await transformation.
3462 // If helperCallback is null we complete the completer with object.
floitsch 2015/02/02 22:00:12 Explain more. Is errorCallback necessary?...
sigurdm 2015/02/03 16:59:32 The error callback will redirect the control flow
floitsch 2015/02/04 12:31:27 Yes. I was talking about another implementation. F
3463 // If helperCallback or errorCallback throws we complete the completer with
3464 // the error.
3465 thenHelper(object,
floitsch 2015/02/02 22:00:11 Types.
sigurdm 2015/02/03 16:59:32 Done.
3466 helperCallback,
3467 Completer completer,
3468 errorCallback) {
3469 if (helperCallback == null) {
3470 completer.complete(object);
3471 return;
3472 }
3473 Future future = object is Future ? object : new Future.value(object);
3474 future.then(new WrappedJsFunction(helperCallback, completer),
3475 onError: new WrappedJsFunction(errorCallback, completer));
3476 return completer.future;
3477 }
3478
3479 // Used to avoid creating two identical closure classes in [thenHelper].
3480 class WrappedJsFunction {
floitsch 2015/02/02 22:00:11 I don't understand this. Why not: Function _wrapJ
sigurdm 2015/02/03 16:59:32 That is better, thanks
3481 final function;
3482 final Completer completer;
3483
3484 WrappedJsFunction(this.function, this.completer);
3485
3486 call(result) {
3487 try {
3488 JS('', '#(#)', function, result);
3489 } catch (e, st) {
3490 completer.completeError(e, st);
3491 }
3492 }
3493 }
3494
3495 // If helperCallback is null we close the stream.
3496 // If helperCallback or errorCallback throws we add the error to the stream
floitsch 2015/02/02 22:00:11 Add more documentation what exactly is expected an
sigurdm 2015/02/03 16:59:32 Done.
3497 // If the object is a YIELD_SINGLE we add the object to the stream.
3498 streamHelper(object,
floitsch 2015/02/02 22:00:12 add real dartdoc. types.
sigurdm 2015/02/03 16:59:32 Done.
3499 helperCallback,
3500 StreamController controller,
3501 errorCallback) {
3502 print("Called with $controller");
floitsch 2015/02/02 22:00:11 debug line.
sigurdm 2015/02/03 16:59:32 Done.
3503 if (helperCallback == null) {
3504 // This happens on return from the async* function.
3505 controller.close();
3506 return;
3507 }
3508
3509 if (object is IterationMarker) {
3510 if (object.state == IterationMarker.YIELD_SINGLE) {
3511 controller.add(object.value);
3512 } else if (object.state == IterationMarker.YIELD_STAR) {
3513 // TODO(sigurdm): Handle yield star from async*.
floitsch 2015/02/02 22:00:11 Don't silently ignore the value.
sigurdm 2015/02/03 16:59:32 Done.
3514 }
3515 if (controller.isPaused) {
3516 return;
3517 } else if (controller.isCanceled) {
3518 // TODO(sigurdm): Handle cancelled streams.
3519 }
3520 object = null;
3521 }
3522
3523 Future future = object is Future ? object : new Future.value(object);
3524 future.then(new WrappedJsFunctionForStream(helperCallback, controller),
3525 onError: errorCallback = null
3526 ? null
3527 : new WrappedJsFunctionForStream(errorCallback,
3528 controller));
3529 return controller.stream;
3530 }
3531
3532
3533 makeAsyncStarController(helperCallBack) {
3534 StreamControllor c;
3535 c = new StreamController(
3536 onResume: () {
3537 // TODO(sigurdm): The errorCallback should not be null.
3538 streamHelper(null, helperCallBack, c, null);
3539 });
3540 return c;
3541 }
3542
3543 // Used to avoid creating two identical closure classes in [streamHelper].
floitsch 2015/02/02 22:00:12 Ditto: I don't like "call" classes. Never sure if
sigurdm 2015/02/03 16:59:32 Done.
3544 class WrappedJsFunctionForStream {
3545 final function;
3546 final StreamController controller;
3547
3548 WrappedJsFunctionForStream(this.function, this.controller);
3549
3550 call(result) {
3551 print(controller);
floitsch 2015/02/02 22:00:11 debugprint.
sigurdm 2015/02/03 16:59:32 Done.
3552 try {
3553 JS('', "#(#)", function, result);
3554 } catch (e, st) {
3555 controller.addError(e, st);
3556 }
3557 }
3558 }
3559
3560 class IterationMarker {
3561 static const YIELD_SINGLE = 0;
3562 static const YIELD_STAR = 1;
3563 static const ITERATION_ENDED = 2;
3564
3565 final value;
3566 final int state;
3567
3568 IterationMarker._(this.state, this.value);
3569
3570 static yieldStar(Iterable iterable) {
3571 return new IterationMarker._(YIELD_STAR, iterable);
3572 }
3573
3574 static endOfIteration() {
3575 return new IterationMarker._(ITERATION_ENDED, null);
3576 }
3577
3578 static yieldSingle(value) {
3579 return new IterationMarker._(YIELD_SINGLE, value);
3580 }
3581
3582 toString() => "IterationMarker($state, $value)";
3583 }
3584
3585 class SyncStarIterator implements Iterator {
3586 final helper;
floitsch 2015/02/02 22:00:11 should not be public.
sigurdm 2015/02/03 16:59:32 Done.
3587
3588 var _current = null;
3589 bool stillRunning = true;
floitsch 2015/02/02 22:00:11 Should not be public.
floitsch 2015/02/02 22:00:12 I don't think we use "stillRunning" in other itera
sigurdm 2015/02/03 16:59:32 Done.
sigurdm 2015/02/03 16:59:32 None of the other Iterators I could find maintains
3590 bool runningNested = false;
floitsch 2015/02/02 22:00:12 should not be public.
sigurdm 2015/02/03 16:59:33 Done.
3591
3592 get current => runningNested ? _current.current : _current;
3593
3594 SyncStarIterator(helper)
3595 : helper = ((arg) => JS('', '#(#)', helper, arg));
floitsch 2015/02/02 22:00:11 don't call them the same. Call the argument jsHel
sigurdm 2015/02/03 16:59:33 Done.
3596
3597 bool moveNext() {
3598 if (!stillRunning) return false;
3599 if (runningNested) {
3600 if (_current.moveNext()) {
3601 return true;
3602 } else {
3603 runningNested = false;
3604 }
3605 }
3606 _current = helper(null);
3607 if (_current is IterationMarker) {
3608 if (_current.state == IterationMarker.ITERATION_ENDED) {
3609 _current = null;
3610 stillRunning = false;
3611 } else {
3612 assert(_current.state == IterationMarker.YIELD_STAR);
3613 _current = _current.value.iterator;
3614 runningNested = true;
3615 return moveNext();
3616 }
3617 }
3618 return stillRunning;
3619 }
3620 }
3621
3622 class SyncStarIterable extends IterableBase {
3623 final outerHelper;
floitsch 2015/02/02 22:00:11 should not be public.
sigurdm 2015/02/03 16:59:33 Done.
3624
3625 SyncStarIterable(this.outerHelper);
floitsch 2015/02/02 22:00:12 Document what this is.
sigurdm 2015/02/03 16:59:32 Done.
3626
3627 Iterator get iterator => new SyncStarIterator(JS('', '#()', outerHelper));
3628 }
3629
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698