// Copyright (c) 2013, 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.

/// Note: the VM concatenates all patch files into a single patch file. This
/// file is the first patch in "dart:_internal" which contains all the imports
/// used by patches of that library. We plan to change this when we have a
/// shared front end and simply use parts.

import "dart:async" show Timer;
import "dart:core" hide Symbol;

import "dart:isolate" show SendPort;
import "dart:typed_data" show Int32List, Uint8List;

/// These are the additional parts of this patch library:
// part "class_id_fasta.dart";
// part "print_patch.dart";
// part "symbol_patch.dart";

// On the VM, we don't make the entire legacy weak mode check
// const to avoid having a constant in the platform libraries
// which evaluates differently in weak vs strong mode.
@patch
bool typeAcceptsNull<T>() => (const <Null>[]) is List<int> || null is T;

@patch
@pragma("vm:external-name", "Internal_makeListFixedLength")
external List<T> makeListFixedLength<T>(List<T> growableList);

@patch
@pragma("vm:external-name", "Internal_makeFixedListUnmodifiable")
external List<T> makeFixedListUnmodifiable<T>(List<T> fixedLengthList);

@patch
@pragma("vm:external-name", "Internal_extractTypeArguments")
external Object? extractTypeArguments<T>(T instance, Function extract);

/// The returned string is a [_OneByteString] with uninitialized content.
@pragma("vm:recognized", "asm-intrinsic")
@pragma("vm:external-name", "Internal_allocateOneByteString")
external String allocateOneByteString(int length);

/// The [string] must be a [_OneByteString]. The [index] must be valid.
@pragma("vm:recognized", "asm-intrinsic")
@pragma("vm:external-name", "Internal_writeIntoOneByteString")
external void writeIntoOneByteString(String string, int index, int codePoint);

/// It is assumed that [from] is a native [Uint8List] class and [to] is a
/// [_OneByteString]. The [fromStart] and [toStart] indices together with the
/// [length] must specify ranges within the bounds of the list / string.
@pragma("vm:recognized", "other")
@pragma("vm:prefer-inline")
void copyRangeFromUint8ListToOneByteString(
    Uint8List from, String to, int fromStart, int toStart, int length) {
  for (int i = 0; i < length; i++) {
    writeIntoOneByteString(to, toStart + i, from[fromStart + i]);
  }
}

/// The returned string is a [_TwoByteString] with uninitialized content.
@pragma("vm:recognized", "asm-intrinsic")
@pragma("vm:external-name", "Internal_allocateTwoByteString")
external String allocateTwoByteString(int length);

/// The [string] must be a [_TwoByteString]. The [index] must be valid.
@pragma("vm:recognized", "asm-intrinsic")
@pragma("vm:external-name", "Internal_writeIntoTwoByteString")
external void writeIntoTwoByteString(String string, int index, int codePoint);

class VMLibraryHooks {
  // Example: "dart:isolate _Timer._factory"
  static Timer Function(int, void Function(Timer), bool)? timerFactory;

  // Example: "dart:io _EventHandler._sendData"
  static late void Function(Object?, SendPort, int) eventHandlerSendData;

  // A nullary closure that answers the current clock value in milliseconds.
  // Example: "dart:io _EventHandler._timerMillisecondClock"
  static late int Function() timerMillisecondClock;

  // Implementation of package root/map provision.
  static String? packageRootString;
  static String? packageConfigString;
  static Future<Uri?> Function()? packageConfigUriFuture;
  static Future<Uri?> Function(Uri)? resolvePackageUriFuture;

  static Uri Function()? _computeScriptUri;
  static Uri? _cachedScript;
  static set platformScript(Object? f) {
    _computeScriptUri = f as Uri Function()?;
    _cachedScript = null;
  }

  static Uri? get platformScript {
    return _cachedScript ??= _computeScriptUri?.call();
  }
}

@pragma("vm:recognized", "other")
@pragma('vm:prefer-inline')
external bool get has63BitSmis;

@pragma("vm:recognized", "other")
@pragma("vm:entry-point", "call")
@pragma("vm:exact-result-type", bool)
@pragma("vm:prefer-inline")
bool _classRangeCheck(int cid, int lowerLimit, int upperLimit) {
  return cid >= lowerLimit && cid <= upperLimit;
}

// Utility class now only used by the VM.
class Lists {
  @pragma("vm:prefer-inline")
  static void copy(List src, int srcStart, List dst, int dstStart, int count) {
    if (srcStart < dstStart) {
      for (int i = srcStart + count - 1, j = dstStart + count - 1;
          i >= srcStart;
          i--, j--) {
        dst[j] = src[i];
      }
    } else {
      for (int i = srcStart, j = dstStart; i < srcStart + count; i++, j++) {
        dst[j] = src[i];
      }
    }
  }
}

// Prepend the parent type arguments (maybe null) of length 'parentLen' to the
// function type arguments (may be null). The result is null if both input
// vectors are null or is a newly allocated and canonicalized vector of length
// 'totalLen'.
@pragma("vm:entry-point", "call")
@pragma("vm:external-name", "Internal_prependTypeArguments")
external _prependTypeArguments(
    functionTypeArguments, parentTypeArguments, parentLen, totalLen);

// Check that a set of type arguments satisfy the type parameter bounds on a
// closure.
@pragma("vm:entry-point", "call")
@pragma("vm:external-name", "Internal_boundsCheckForPartialInstantiation")
external _boundsCheckForPartialInstantiation(closure, typeArgs);

// Called by IRRegExpMacroAssembler::GrowStack.
Int32List _growRegExpStack(Int32List stack) {
  final newStack = new Int32List(stack.length * 2);
  for (int i = 0; i < stack.length; i++) {
    newStack[i] = stack[i];
  }
  return newStack;
}

@patch
@pragma("vm:external-name", "Internal_unsafeCast")
external T unsafeCast<T>(dynamic v);

// This function can be used to keep an object alive till that point.
@pragma("vm:recognized", "other")
@pragma('vm:prefer-inline')
external void reachabilityFence(Object? object);

// This function can be used to encode native side effects.
//
// The function call and it's argument are removed in flow graph construction.
@pragma("vm:recognized", "other")
@pragma("vm:external-name", "Internal_nativeEffect")
external void _nativeEffect(Object object);

// Collection of functions which should only be used for testing purposes.
abstract class VMInternalsForTesting {
  // This function can be used by tests to enforce garbage collection.
  @pragma("vm:external-name", "Internal_collectAllGarbage")
  external static void collectAllGarbage();

  @pragma("vm:external-name", "Internal_deoptimizeFunctionsOnStack")
  external static void deoptimizeFunctionsOnStack();
}

@patch
T createSentinel<T>() => throw UnsupportedError('createSentinel');

@patch
bool isSentinel(dynamic value) => throw UnsupportedError('isSentinel');

@patch
class LateError {
  @pragma("vm:entry-point")
  static _throwFieldAlreadyInitialized(String fieldName) {
    throw new LateError.fieldAI(fieldName);
  }

  @pragma("vm:entry-point")
  static _throwLocalNotInitialized(String localName) {
    throw new LateError.localNI(localName);
  }

  @pragma("vm:entry-point")
  static _throwLocalAlreadyInitialized(String localName) {
    throw new LateError.localAI(localName);
  }

  @pragma("vm:entry-point")
  static _throwLocalAssignedDuringInitialization(String localName) {
    throw new LateError.localADI(localName);
  }
}
