sdk icon indicating copy to clipboard operation
sdk copied to clipboard

Bug with dart2js

Open antonbashir opened this issue 5 days ago • 0 comments

Hello team ! Not sure that it is still actual, but I found this bug on Dart 3.8.0 and Dart 3.10.3.

Consider the following Dart Code:

import 'dart:async';
void main() {
  final processor = TestProcessor();
  processor.test();
  Timer(Duration(milliseconds: 100), () {
    print('Expected: scheduleMicrotask called 1 time');
    print('Actual: scheduleMicrotask called ${processor.microtaskCount} times');
    if (processor.microtaskCount > 1) {
      print('BUG!: Code after for+break is duplicated!');
    }
  });
}
class TestProcessor {
  int microtaskCount = 0;
  void test() {
    print('test() called');
    final items = <String>[];
    for (final item in items) {
      print('Processing item: $item');
      break;
    }
    scheduleMicrotask(() {
      microtaskCount++;
      print('scheduleMicrotask callback executed');
    });
    print('test() completed');
  }
}

Now the output from VM version:

dart run bug.dart 
test() called
test() completed
scheduleMicrotask callback executed
Expected: scheduleMicrotask called 1 time
Actual: scheduleMicrotask called 1 times

Now the output from JS version (D8 environment):

./dart-sdk/bin/dart compile js -O0 bug.dart -o bug.js 
./d8 --snapshot_blob=snapshot_blob.bin preamble.js bug.js
test() called
test() completed
test() completed
scheduleMicrotask callback executed
scheduleMicrotask callback executed
Expected: scheduleMicrotask called 1 time
Actual: scheduleMicrotask called 2 times
BUG!: Code after for+break is duplicated!

In browser (vscode internal):

<!DOCTYPE html>
<html>
<head><title>Test</title></head>
<body>
<script>
</script>
<script src="bug.js"></script>
</body>
</html>

___vscode_livepreview_injected_script:141 test() called
___vscode_livepreview_injected_script:141 test() completed
___vscode_livepreview_injected_script:141 test() completed
___vscode_livepreview_injected_script:141 scheduleMicrotask callback executed
___vscode_livepreview_injected_script:141 scheduleMicrotask callback executed
___vscode_livepreview_injected_script:141 Expected: scheduleMicrotask called 1 time
___vscode_livepreview_injected_script:141 Actual: scheduleMicrotask called 2 times
___vscode_livepreview_injected_script:141 BUG!: Code after for+break is duplicated!

And consider the generated JS code:

  A.TestProcessor.prototype = {
    test$0() {
      A.print("test() called");
      var t1 = B.JSArray_methods.get$iterator(A._setArrayType([], type$.JSArray_String));
      $loop$0: {
        if (t1.moveNext$0()) {
          A.print("Processing item: " + t1.get$current());
          break $loop$0;
        }
        A.scheduleMicrotask(new A.TestProcessor_test_closure(this));
        A.print("test() completed");
      }
      A.scheduleMicrotask(new A.TestProcessor_test_closure(this));
      A.print("test() completed");
    }
  };

The generated instructions are inside the $loop$0.

        A.scheduleMicrotask(new A.TestProcessor_test_closure(this));
        A.print("test() completed");

antonbashir avatar Dec 06 '25 22:12 antonbashir