// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Machinery for async and await.
//
// The implementation is based on two mechanisms in the JS Promise integration:
//
// The export wrapper: Allocates a new stack and calls the wrapped export on the
// new stack, passing a suspender object as an extra first argument that
// represents the new stack.
//
// The import wrapper: Takes a suspender object as an extra first argument and
// calls the wrapped import. If the wrapped import returns a `Promise`, the
// current stack is suspended, and the `Promise` is forwarded to the
// corresponding call of the export wrapper, where execution resumes on the
// original stack. When the `Promise` is resolved, execution resumes on the
// suspended stack, with the call to the import wrapper returning the value the
// `Promise` was resolved with.
//
// The call sequence when calling an async function is:
//
// Caller
//  -> Outer (function specific, generated by `generateAsyncWrapper`)
//  -> `_asyncHelper`
//  -> `_callAsyncBridge` (imported JS function)
//  -> `_asyncBridge` (via the Promise integration export wrapper)
//  -> `_asyncBridge2` (intrinsic function)
//  -> Stub (function specific, generated by `generateAsyncWrapper`)
//  -> Inner (contains implementation, generated from async inner reference)
//
// The call sequence on await is:
//
// Function containing await
//  -> `_awaitHelper`
//  -> `_futurePromise` (via the Promise integration import wrapper)
//  -> `new Promise`
//  -> `Promise` constructor callback
//  -> `_awaitCallback`
//  -> `Future.then`
// `futurePromise` returns the newly created `Promise`, suspending the
// current execution.
//
// When the `Future` completes:
//
// `Future.then` callback
//  -> `_callResolve` (imported JS function)
//  -> `Promise` resolve function
// Resolving the `Promise` causes the suspended execution to resume.

import 'dart:_internal' show patch, scheduleCallback, unsafeCastOpaque;

import 'dart:wasm';

@pragma("wasm:entry-point")
Future<T> _asyncHelper<T>(WasmEqRef args) {
  Completer<T> completer = Completer();
  _callAsyncBridge(args, completer);
  return completer.future;
}

@pragma("wasm:import", "dart2wasm.callAsyncBridge")
external void _callAsyncBridge(WasmEqRef args, Completer<Object?> completer);

@pragma("wasm:export", "\$asyncBridge")
WasmAnyRef? _asyncBridge(
    WasmExternRef? stack, WasmDataRef args, Completer<Object?> completer) {
  try {
    Object? result = _asyncBridge2(args, stack);
    completer.complete(result);
  } catch (e, s) {
    completer.completeError(e, s);
  }
}

external Object? _asyncBridge2(WasmDataRef args, WasmExternRef? stack);

class _FutureError {
  final Object exception;
  final StackTrace stackTrace;

  _FutureError(this.exception, this.stackTrace);
}

@pragma("wasm:entry-point")
Object? _awaitHelper(Object? operand, WasmExternRef? stack) {
  if (operand is! Future) return operand;
  WasmExternRef futureRef = WasmAnyRef.fromObject(operand).externalize();
  Object? result =
      unsafeCastOpaque(_futurePromise(stack, futureRef).internalize());
  if (result is _FutureError) {
    // TODO(askesc): Combine stack traces
    throw result.exception;
  }
  return result;
}

@pragma("wasm:import", "dart2wasm.futurePromise")
external WasmExternRef? _futurePromise(
    WasmExternRef? stack, WasmExternRef? future);

@pragma("wasm:export", "\$awaitCallback")
void _awaitCallback(Future<Object?> future, WasmAnyRef resolve) {
  future.then((value) {
    _callResolve(resolve, value);
  }, onError: (exception, stackTrace) {
    _callResolve(resolve, _FutureError(exception, stackTrace));
  });
}

@pragma("wasm:import", "dart2wasm.callResolve")
external void _callResolve(WasmAnyRef resolve, Object? result);
