dart-lang/core

Fast sink doesn't work when using Wasm

Closed this issue · 5 comments

Sample code:

import 'dart:convert';

import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Testing fast sink on Wasm',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const BenchmarkPage(),
    );
  }
}

class BenchmarkPage extends StatefulWidget {
  const BenchmarkPage({super.key});

  @override
  State<BenchmarkPage> createState() => _BenchmarkPageState();
}

class _BenchmarkPageState extends State<BenchmarkPage> {
  String benchmarkResult = '';

  void _runBenchmark() {
    final stopwatch = Stopwatch()..start();
    for (int i = 0; i < 100000; i++) {
      // Create deterministic strings
      String data = "Deterministic string $i";
      var bytes = utf8.encode(data);
      // Compute SHA-512
      sha512.convert(bytes);
    }
    stopwatch.stop();
    setState(() {
      benchmarkResult = 'Time taken: ${stopwatch.elapsedMilliseconds} ms';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _runBenchmark,
              child: const Text('Run Benchmark'),
            ),
            Text(
              benchmarkResult,
              style: Theme.of(context).textTheme.bodyMedium,
            ),
          ],
        ),
      ),
    );
  }
}

This code works when using slow sinks, but gives errors now (on master) using fast sinks

flutter build web --wasm

cd build/web

dhttpd '--headers=Cross-Origin-Embedder-Policy=credentialless;Cross-Origin-Opener-Policy=same-origin'

The integer literal 0x8c3d37c819544da2 can't be represented exactly in JavaScript.
0x8c3d37c819544da2,

Points for submitting this as a (failing) test w/ the fix!

Fix:

Changing values in lib/src/sha512_fastsinks.dart (for example: 0x6a09e667f3bcc908) to:
BigInt.parse('0x6a09e667f3bcc908').toInt() and using another additional conditional import

The issue now only appears when forcing to use fast sinks on Wasm build.

import 'sha512_fastsinks.dart' if (dart.library.html) 'sha512_slowsinks.dart';
->
import 'sha512_fastsinks.dart';
This fails on Wasm builds.

import 'sha512_fastsinks.dart' if (dart.library.html) 'sha512_slowsinks.dart';
->
import 'sha512_slowsinks.dart';
This doesn't fail on Wasm builds.

Conditional imports change and adding a fast sinks only for Wasm build:

import 'sha512_fastsinks.dart'
    if (dart.library.html) 'sha512_slowsinks.dart'
    if (dart.library.js_interop) 'sha512_fastsinks_wasm.dart';

I still can't really understand the root of the problem

Even with the --wasm flag, flutter build web will still compile the application to JavaScript. If WasmGC support is not detected at runtime, the JavaScript output is used so the application will continue to work across browsers.

This was the root of the problems with my tests.

Current changes should work fine, this issue could be closed and by publishing the changes and using fast sinks on Wasm when possible, everything should be a lot faster. (4 seconds -> 1 seconds)

I apologize for the incorrect bug report.

@h1376h – so we can close this bug?

@kevmoo Yeah, I closed it. Couldn't find any bug/problems with the current conditional imports after clearing cache and some tests.