// 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.

library _js_helper;

import 'dart:_js_embedded_names'
    show
        CURRENT_SCRIPT,
        DEFERRED_LIBRARY_PARTS,
        DEFERRED_PART_URIS,
        DEFERRED_PART_HASHES,
        GET_ISOLATE_TAG,
        INITIALIZATION_EVENT_LOG,
        INITIALIZE_LOADED_HUNK,
        INTERCEPTORS_BY_TAG,
        IS_HUNK_LOADED,
        IS_HUNK_INITIALIZED,
        LEAF_TAGS,
        NATIVE_SUPERCLASS_TAG_NAME,
        RECORD_TYPE_TEST_COMBINATORS_PROPERTY,
        RUNTIME_METRICS,
        STARTUP_METRICS,
        STATIC_FUNCTION_NAME_PROPERTY_NAME,
        TearOffParametersPropertyNames;

import 'dart:_js_shared_embedded_names' show JsBuiltin, JsGetName;

import 'dart:collection';

import 'dart:convert' show jsonDecode;

import 'dart:async' show Completer, DeferredLoadException, Future, Zone;

import 'dart:_foreign_helper'
    show
        DART_CLOSURE_TO_JS,
        getInterceptor,
        JS,
        JS_BUILTIN,
        JS_CONST,
        JS_EFFECT,
        JS_EMBEDDED_GLOBAL,
        JS_GET_FLAG,
        JS_GET_NAME,
        JS_INTERCEPTOR_CONSTANT,
        JS_STRING_CONCAT,
        RAW_DART_FUNCTION_REF;

import 'dart:_interceptors';
import 'dart:_internal' as _symbol_dev;
import 'dart:_internal'
    show
        checkNotNullable,
        EfficientLengthIterable,
        HideEfficientLengthIterable,
        MappedIterable,
        IterableElementError,
        SubListIterable;

import 'dart:_native_typed_data';

import 'dart:_js_names' show unmangleGlobalNameIfPreservedAnyways;

import 'dart:_rti' as newRti
    show
        createRuntimeType,
        evalInInstance,
        evaluateRtiForRecord,
        getRuntimeType,
        getRuntimeTypeOfClosure,
        getRuntimeTypeOfRecord,
        getTypeFromTypesTable,
        instanceTypeName,
        instantiatedGenericFunctionType,
        pairwiseIsTest,
        throwTypeError,
        Rti;

import 'dart:_load_library_priority';

import 'dart:_invocation_mirror_constants' as mirrors;

part 'annotations.dart';
part 'constant_map.dart';
part 'instantiation.dart';
part 'native_helper.dart';
part 'regexp_helper.dart';
part 'string_helper.dart';
part 'linked_hash_map.dart';
part 'records.dart';

const JS_FUNCTION_PROPERTY_NAME = r'$dart_jsFunction';
const JS_FUNCTION_PROPERTY_NAME_CAPTURE_THIS = r'_$dart_jsFunctionCaptureThis';

/// Marks the internal map in dart2js, so that internal libraries can is-check
/// them.
abstract class InternalMap {}

/// Given a raw constructor name, return the unminified name, if available,
/// otherwise tag the name with `minified:`.
String unminifyOrTag(String rawClassName) {
  String? preserved = unmangleGlobalNameIfPreservedAnyways(rawClassName);
  if (preserved != null) return preserved;
  if (JS_GET_FLAG('MINIFIED')) return 'minified:${rawClassName}';
  return rawClassName;
}

/// Returns the metadata of the given [index].
// TODO(floitsch): move this to foreign_helper.dart or similar.
@pragma('dart2js:tryInline')
getMetadata(int index) {
  return JS_BUILTIN(
      'returns:var;effects:none;depends:none', JsBuiltin.getMetadata, index);
}

/// Returns the type of the given [index].
// TODO(floitsch): move this to foreign_helper.dart or similar.
@pragma('dart2js:tryInline')
getType(int index) {
  return JS_BUILTIN(
      'returns:var;effects:none;depends:none', JsBuiltin.getType, index);
}

/// No-op method that is called to inform the compiler that preambles might
/// be needed when executing the resulting JS file in a command-line
/// JS engine.
requiresPreamble() {}

bool isJsIndexable(var object, var record) {
  if (record != null) {
    var result = dispatchRecordIndexability(record);
    if (result != null) return result;
  }
  return object is JavaScriptIndexingBehavior;
}

String S(value) {
  if (value is String) return value;
  if (value is num) {
    if (value != 0) {
      // ""+x is faster than String(x) for integers on most browsers.
      return JS('String', r'"" + (#)', value);
    }
  } else if (true == value) {
    return 'true';
  } else if (false == value) {
    return 'false';
  } else if (value == null) {
    return 'null';
  }
  var result = value.toString();
  if (result is! String) {
    throw ArgumentError.value(
        value, 'object', "toString method returned 'null'");
  }
  return result;
}

// Called from generated code.
createInvocationMirror(
    String name, internalName, kind, arguments, argumentNames, types) {
  // TODO(sra): [types] (the number of type arguments) could be omitted in the
  // generated stub code to save an argument. Then we would use `types ?? 0`.
  return JSInvocationMirror(
      name, internalName, kind, arguments, argumentNames, types);
}

createUnmangledInvocationMirror(
    Symbol symbol, internalName, kind, arguments, argumentNames, types) {
  return JSInvocationMirror(
      symbol, internalName, kind, arguments, argumentNames, types);
}

void throwInvalidReflectionError(String memberName) {
  throw UnsupportedError("Can't use '$memberName' in reflection.");
}

/// Helper used to instrument calls when the compiler is invoked with
/// `--experiment-call-instrumentation`.
///
/// By default, whenever a method is invoked for the first time, it prints an id
/// and the method name to the console. This can be overridden by adding a top
/// level `dartCallInstrumentation` hook in JavaScript.
@pragma('dart2js:noInline')
void traceHelper(dynamic /*int*/ id, dynamic /*String*/ qualifiedName) {
  // Note: this method is written mostly in JavaScript to prevent a stack
  // overflow. In particular, we use dynamic argument types because with with
  // types, traceHelper would include type checks for the parameter types, those
  // checks (intTypeCheck, stringTypeCheck) are themselves calls that end up
  // invoking this traceHelper and produce a stack overflow.  Similarly if we
  // had Dart code below using, for example, string interpolation, we would
  // include extra calls to the Dart runtime that could also trigger a stack
  // overflow. This approach here is simpler than making the compiler smart
  // about how to generate traceHelper calls more carefully.
  JS(
      '',
      r'''
      (function (id, name) {
        var hook = self.dartCallInstrumentation;
        if (typeof hook === "function") {
          hook(id, name);
          return;
        }
        if (!this.callInstrumentationCache) {
          this.callInstrumentationCache = Object.create(null);
        }
        if (!this.callInstrumentationCache[id]) {
          console.log(id, name);
          this.callInstrumentationCache[id] = true;
        }
      })(#, #)''',
      id,
      qualifiedName);
}

class JSInvocationMirror implements Invocation {
  /// When [_memberName] is a String, it holds the mangled name of this
  /// invocation.  When it is a Symbol, it holds the unmangled name.
  var /* String or Symbol */ _memberName;
  final String _internalName;
  final int _kind;
  final List _arguments;
  final List _namedArgumentNames;
  final int _typeArgumentCount;

  JSInvocationMirror(this._memberName, this._internalName, this._kind,
      this._arguments, this._namedArgumentNames, this._typeArgumentCount);

  Symbol get memberName {
    if (_memberName is Symbol) return _memberName;
    return _memberName = _symbol_dev.Symbol.unvalidated(_memberName);
  }

  bool get isMethod => _kind == mirrors.method;
  bool get isGetter => _kind == mirrors.getter;
  bool get isSetter => _kind == mirrors.setter;
  bool get isAccessor => _kind != mirrors.method;

  List<Type> get typeArguments {
    if (_typeArgumentCount == 0) return const <Type>[];
    int start = _arguments.length - _typeArgumentCount;
    var list = <Type>[];
    for (int index = 0; index < _typeArgumentCount; index++) {
      list.add(newRti.createRuntimeType(_arguments[start + index]));
    }
    return JSArray.markUnmodifiableList(list);
  }

  List get positionalArguments {
    if (isGetter) return const [];
    var argumentCount =
        _arguments.length - _namedArgumentNames.length - _typeArgumentCount;
    if (argumentCount == 0) return const [];
    var list = [];
    for (var index = 0; index < argumentCount; index++) {
      list.add(_arguments[index]);
    }
    return JSArray.markUnmodifiableList(list);
  }

  Map<Symbol, dynamic> get namedArguments {
    if (isAccessor) return const <Symbol, dynamic>{};
    int namedArgumentCount = _namedArgumentNames.length;
    int namedArgumentsStartIndex =
        _arguments.length - namedArgumentCount - _typeArgumentCount;
    if (namedArgumentCount == 0) return const <Symbol, dynamic>{};
    var map = Map<Symbol, dynamic>();
    for (int i = 0; i < namedArgumentCount; i++) {
      map[_symbol_dev.Symbol.unvalidated(_namedArgumentNames[i])] =
          _arguments[namedArgumentsStartIndex + i];
    }
    return ConstantMapView<Symbol, dynamic>(map);
  }
}

class Primitives {
  static Object? _identityHashCodeProperty;

  /// Identity hash code for a JavaScript object or function.
  static int objectHashCode(Object? object) {
    Object property =
        _identityHashCodeProperty ??= _computeIdentityHashCodeProperty();
    int? hash = JS('int|Null', r'#[#]', object, property);
    if (hash == null) {
      hash = JS('int', '(Math.random() * 0x3fffffff) | 0');
      JS('void', r'#[#] = #', object, property, hash);
    }
    return JS('int', '#', hash);
  }

  static Object _computeIdentityHashCodeProperty() =>
      JS('', 'Symbol("identityHashCode")');

  static int? parseInt(String source, int? radix) {
    checkString(source);
    var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
    List? match = JS('JSExtendableArray|Null', '#.exec(#)', re, source);
    int digitsIndex = 1;
    int hexIndex = 2;
    int decimalIndex = 3;
    if (match == null) {
      // TODO(sra): It might be that the match failed due to unrecognized U+0085
      // spaces.  We could replace them with U+0020 spaces and try matching
      // again.
      return null;
    }
    Object? decimalMatch = match[decimalIndex];
    if (radix == null) {
      if (decimalMatch != null) {
        // Cannot fail because we know that the digits are all decimal.
        return JS('int', r'parseInt(#, 10)', source);
      }
      if (match[hexIndex] != null) {
        // Cannot fail because we know that the digits are all hex.
        return JS('int', r'parseInt(#, 16)', source);
      }
      return null;
    }

    if (radix is! int) {
      throw ArgumentError.value(radix, 'radix', 'is not an integer');
    }
    if (radix < 2 || radix > 36) {
      throw RangeError.range(radix, 2, 36, 'radix');
    }
    if (radix == 10 && decimalMatch != null) {
      // Cannot fail because we know that the digits are all decimal.
      return JS('int', r'parseInt(#, 10)', source);
    }
    // If radix >= 10 and we have only decimal digits the string is safe.
    // Otherwise we need to check the digits.
    if (radix < 10 || decimalMatch == null) {
      // We know that the characters must be ASCII as otherwise the
      // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
      // guaranteed to be a safe operation, since it preserves digits
      // and lower-cases ASCII letters.
      int maxCharCode;
      if (radix <= 10) {
        // Allow all digits less than the radix. For example 0, 1, 2 for
        // radix 3.
        // "0".codeUnitAt(0) + radix - 1;
        maxCharCode = (0x30 - 1) + radix;
      } else {
        // Letters are located after the digits in ASCII. Therefore we
        // only check for the character code. The regexp above made already
        // sure that the string does not contain anything but digits or
        // letters.
        // "a".codeUnitAt(0) + (radix - 10) - 1;
        maxCharCode = (0x61 - 10 - 1) + radix;
      }
      assert(match[digitsIndex] is String);
      String digitsPart = JS('String', '#[#]', match, digitsIndex);
      for (int i = 0; i < digitsPart.length; i++) {
        int characterCode = digitsPart.codeUnitAt(i) | 0x20;
        if (characterCode > maxCharCode) {
          return null;
        }
      }
    }
    // The above matching and checks ensures the source has at least one digits
    // and all digits are suitable for the radix, so parseInt cannot return NaN.
    return JS('int', r'parseInt(#, #)', source, radix);
  }

  static double? parseDouble(String source) {
    checkString(source);
    // Notice that JS parseFloat accepts garbage at the end of the string.
    // Accept only:
    // - [+/-]NaN
    // - [+/-]Infinity
    // - a Dart double literal
    // We do allow leading or trailing whitespace.
    if (!JS(
        'bool',
        r'/^\s*[+-]?(?:Infinity|NaN|'
            r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
        source)) {
      return null;
    }
    double result = JS('double', r'parseFloat(#)', source);
    if (result.isNaN) {
      var trimmed = source.trim();
      if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
        return result;
      }
      return null;
    }
    return result;
  }

  static bool? parseBool(String source, bool caseSensitive) {
    checkNotNullable(source, "source");
    checkNotNullable(caseSensitive, "caseSensitive");
    if (caseSensitive) {
      return source == "true"
          ? true
          : source == "false"
              ? false
              : null;
    }
    return _compareIgnoreCase(source, "true")
        ? true
        : _compareIgnoreCase(source, "false")
            ? false
            : null;
  }

  static bool _compareIgnoreCase(String input, String lowerCaseTarget) {
    if (input.length != lowerCaseTarget.length) return false;
    for (var i = 0; i < input.length; i++) {
      if (input.codeUnitAt(i) | 0x20 != lowerCaseTarget.codeUnitAt(i)) {
        return false;
      }
    }
    return true;
  }

  /// [: r"$".codeUnitAt(0) :]
  static const int DOLLAR_CHAR_VALUE = 36;

  /// Returns the type of [object] as a string (including type arguments).
  /// Tries to return a sensible name for non-Dart objects.
  ///
  /// In minified mode, uses the unminified names if available, otherwise tags
  /// them with 'minified:'.
  @pragma('dart2js:noInline')
  static String objectTypeName(Object? object) {
    return _objectTypeNameNewRti(object);
  }

  /// Returns the type of [object] as a string (including type arguments).
  /// Tries to return a sensible name for non-Dart objects.
  ///
  /// In minified mode, uses the unminified names if available, otherwise tags
  /// them with 'minified:'.
  static String _objectTypeNameNewRti(Object? object) {
    var dartObjectConstructor = JS_BUILTIN(
        'depends:none;effects:none;', JsBuiltin.dartObjectConstructor);
    if (JS('bool', '# instanceof #', object, dartObjectConstructor)) {
      return newRti.instanceTypeName(object);
    }

    var interceptor = getInterceptor(object);
    if (identical(interceptor, JS_INTERCEPTOR_CONSTANT(Interceptor)) ||
        identical(interceptor, JS_INTERCEPTOR_CONSTANT(JavaScriptObject)) ||
        object is UnknownJavaScriptObject) {
      // Try to do better.  If we do not find something better, fallthrough to
      // Dart-type based name that leave the name as 'UnknownJavaScriptObject',
      // 'Interceptor', or 'JavaScriptObject' (or their minified versions).
      //
      // When we get here via the UnknownJavaScriptObject test (for JavaScript
      // objects from outside the program), the object's constructor has a
      // better name that 'UnknownJavaScriptObject'.
      //
      // When we get here via either the Interceptor or JavaScriptObject test
      // (for Native classes that are declared in the Dart program but have been
      // 'folded' into one of those interceptors), the native class's
      // constructor name is better than the generic 'Interceptor' or
      // 'JavaScriptObject'.

      // Try the [constructorNameFallback]. This gets the constructor name for
      // any browser (used by [getNativeInterceptor]).
      String dispatchName = constructorNameFallback(object);
      if (_saneNativeClassName(dispatchName)) return dispatchName;
      var constructor = JS('', '#.constructor', object);
      if (JS('bool', 'typeof # == "function"', constructor)) {
        var constructorName = JS('', '#.name', constructor);
        if (constructorName is String &&
            _saneNativeClassName(constructorName)) {
          return constructorName;
        }
      }
    }

    return newRti.instanceTypeName(object);
  }

  static bool _saneNativeClassName(name) =>
      name != null && name != 'Object' && name != '';

  /// In minified mode, uses the unminified names if available.
  static String objectToHumanReadableString(Object? object) {
    String name = objectTypeName(object);
    return "Instance of '$name'";
  }

  static String stringSafeToString(String string) {
    return jsonEncodeNative(string);
  }

  static String safeToString(Object? object) {
    if (object == null || object is num || object is bool) {
      return object.toString();
    }
    if (object is String) {
      return stringSafeToString(object);
    }
    // Closures all have useful and safe toString methods.
    if (object is Closure) {
      return object.toString();
    }
    if (object is _Record) {
      return object._toString(true);
    }

    return Primitives.objectToHumanReadableString(object);
  }

  static int dateNow() => JS('int', r'Date.now()');

  static void initTicker() {
    if (timerFrequency != 0) return;
    // Start with low-resolution. We overwrite the fields if we find better.
    timerFrequency = 1000;
    if (JS('bool', 'typeof window == "undefined"')) return;
    var window = JS('var', 'window');
    if (window == null) return;

    // This property is set in the preambles that fake `Date.now()` to simulate
    // the passage of time by advancing the clock rather than waiting. The
    // simulated passage of time is not implemented for the browser
    // `Performance` APIs, so we must use `Date.now()` to measure time.
    if (JS('bool', '!!#.dartUseDateNowForTicks', window)) return;

    var performance = JS('var', '#.performance', window);
    if (performance == null) return;
    if (JS('bool', 'typeof #.now != "function"', performance)) return;
    timerFrequency = 1000000;
    timerTicks = () => (1000 * JS('num', '#.now()', performance)).floor();
  }

  static int timerFrequency = 0;
  static int Function() timerTicks = dateNow; // Low-resolution version.

  static String? currentUri() {
    requiresPreamble();
    // In a browser return self.location.href.
    if (JS('bool', '!!self.location')) {
      return JS('String', 'self.location.href');
    }

    return null;
  }

  /// Version of `String.fromCharCode.apply` that chunks the conversion to avoid
  /// stack overflows due to very large argument arrays.
  ///
  /// [array] is pre-validated as a JSArray of int values but is not typed as
  /// <int> so it can be called with any JSArray.
  static String _fromCharCodeApply(List array) {
    const kMaxApply = 500;
    int end = array.length;
    if (end <= kMaxApply) {
      return JS('String', r'String.fromCharCode.apply(null, #)', array);
    }
    String result = '';
    for (int i = 0; i < end; i += kMaxApply) {
      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
      result = JS(
          'String',
          r'# + String.fromCharCode.apply(null, #.slice(#, #))',
          result,
          array,
          i,
          chunkEnd);
    }
    return result;
  }

  static String stringFromCodePoints(codePoints) {
    List<int> a = <int>[];
    for (var i in codePoints) {
      if (i is! int) throw argumentErrorValue(i);
      if (i <= 0xffff) {
        a.add(i);
      } else if (i <= 0x10ffff) {
        a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)));
        a.add(0xdc00 + (i & 0x3ff));
      } else {
        throw argumentErrorValue(i);
      }
    }
    return _fromCharCodeApply(a);
  }

  static String stringFromCharCodes(charCodes) {
    for (var i in charCodes) {
      if (i is! int) throw argumentErrorValue(i);
      if (i < 0) throw argumentErrorValue(i);
      if (i > 0xffff) return stringFromCodePoints(charCodes);
    }
    return _fromCharCodeApply(charCodes);
  }

  // [start] and [end] are validated.
  static String stringFromNativeUint8List(
      NativeUint8List charCodes, int start, int end) {
    const kMaxApply = 500;
    if (end <= kMaxApply && start == 0 && end == charCodes.length) {
      return JS('String', r'String.fromCharCode.apply(null, #)', charCodes);
    }
    String result = '';
    for (int i = start; i < end; i += kMaxApply) {
      int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
      result = JS(
          'String',
          r'# + String.fromCharCode.apply(null, #.subarray(#, #))',
          result,
          charCodes,
          i,
          chunkEnd);
    }
    return result;
  }

  static String stringFromCharCode(int charCode) {
    if (0 <= charCode) {
      if (charCode <= 0xffff) {
        return JS('returns:String;effects:none;depends:none',
            'String.fromCharCode(#)', charCode);
      }
      if (charCode <= 0x10ffff) {
        var bits = charCode - 0x10000;
        var low = 0xDC00 | (bits & 0x3ff);
        var high = 0xD800 | (bits >> 10);
        return JS('returns:String;effects:none;depends:none',
            'String.fromCharCode(#, #)', high, low);
      }
    }
    throw RangeError.range(charCode, 0, 0x10ffff);
  }

  static String stringConcatUnchecked(String string1, String string2) {
    return JS_STRING_CONCAT(string1, string2);
  }

  static String flattenString(String str) {
    return JS('returns:String;depends:none;effects:none;throws:never;gvn:true',
        '#.charCodeAt(0) == 0 ? # : #', str, str, str);
  }

  static String getTimeZoneName(DateTime receiver) {
    // Firefox and Chrome emit the timezone in parenthesis.
    // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
    // We extract this name using a regexp.
    var d = lazyAsJsDate(receiver);
    List? match = JS('JSArray|Null', r'/\((.*)\)/.exec(#.toString())', d);
    if (match != null) return match[1];

    // Internet Explorer 10+ emits the zone name without parenthesis:
    // Example: Thu Oct 31 14:07:44 PDT 2013
    match = JS(
        'JSArray|Null',
        // Thu followed by a space.
        r'/^[A-Z,a-z]{3}\s'
            // Oct 31 followed by space.
            r'[A-Z,a-z]{3}\s\d+\s'
            // Time followed by a space.
            r'\d{2}:\d{2}:\d{2}\s'
            // The time zone name followed by a space.
            r'([A-Z]{3,5})\s'
            // The year.
            r'\d{4}$/'
            '.exec(#.toString())',
        d);
    if (match != null) return match[1];

    // IE 9 and Opera don't provide the zone name. We fall back to emitting the
    // UTC/GMT offset.
    // Example (IE9): Wed Nov 20 09:51:00 UTC+0100 2013
    //       (Opera): Wed Nov 20 2013 11:03:38 GMT+0100
    match = JS('JSArray|Null', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d);
    if (match != null) return match[0];
    return '';
  }

  static int getTimeZoneOffsetInMinutes(DateTime receiver) {
    // Note that JS and Dart disagree on the sign of the offset.
    // Subtract to avoid -0.0
    return 0 - JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver))
        as int;
  }

  static int? valueFromDecomposedDate(int years, int month, int day, int hours,
      int minutes, int seconds, int milliseconds, bool isUtc) {
    final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
    checkInt(years);
    checkInt(month);
    checkInt(day);
    checkInt(hours);
    checkInt(minutes);
    checkInt(seconds);
    checkInt(milliseconds);
    checkBool(isUtc);
    var jsMonth = month - 1;
    // The JavaScript Date constructor 'corrects' year NN to 19NN. Sidestep that
    // correction by adjusting years out of that range and compensating with an
    // adjustment of months. This hack should not be sensitive to leap years but
    // use 400 just in case.
    if (0 <= years && years < 100) {
      years += 400;
      jsMonth -= 400 * 12;
    }
    num value;
    if (isUtc) {
      value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
          hours, minutes, seconds, milliseconds);
    } else {
      value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
          jsMonth, day, hours, minutes, seconds, milliseconds);
    }
    if (value.isNaN ||
        value < -MAX_MILLISECONDS_SINCE_EPOCH ||
        value > MAX_MILLISECONDS_SINCE_EPOCH) {
      return null;
    }
    return JS('int', '#', value);
  }

  // Lazily keep a JS Date stored in the JS object.
  static lazyAsJsDate(DateTime receiver) {
    if (JS('bool', r'#.date === (void 0)', receiver)) {
      JS('void', r'#.date = new Date(#)', receiver,
          receiver.millisecondsSinceEpoch);
    }
    return JS('var', r'#.date', receiver);
  }

  // The getters for date and time parts below add a positive integer to ensure
  // that the result is really an integer, because the JavaScript implementation
  // may return -0.0 instead of 0.
  //
  // They are marked as @pragma('dart2js:noThrows') because `receiver` comes from a receiver of
  // a method on DateTime (i.e. is not `null`).

  // TODO(sra): These methods are GVN-able. dart2js should implement an
  // annotation for that.

  // TODO(sra): These methods often occur in groups (e.g. day, month and
  // year). Is it possible to factor them so that the `Date` is visible and can
  // be GVN-ed without a lot of code bloat?

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getYear(DateTime receiver) {
    return (receiver.isUtc)
        ? JS('int', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
        : JS('int', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
  }

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getMonth(DateTime receiver) {
    return (receiver.isUtc)
        ? JS('JSUInt31', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
        : JS('JSUInt31', r'#.getMonth() + 1', lazyAsJsDate(receiver));
  }

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getDay(DateTime receiver) {
    return (receiver.isUtc)
        ? JS('JSUInt31', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
        : JS('JSUInt31', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
  }

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getHours(DateTime receiver) {
    return (receiver.isUtc)
        ? JS('JSUInt31', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
        : JS('JSUInt31', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
  }

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getMinutes(DateTime receiver) {
    return (receiver.isUtc)
        ? JS('JSUInt31', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
        : JS('JSUInt31', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
  }

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getSeconds(DateTime receiver) {
    return (receiver.isUtc)
        ? JS('JSUInt31', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
        : JS('JSUInt31', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
  }

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getMilliseconds(DateTime receiver) {
    return (receiver.isUtc)
        ? JS(
            'JSUInt31', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
        : JS('JSUInt31', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
  }

  @pragma('dart2js:noSideEffects')
  @pragma('dart2js:noThrows')
  @pragma('dart2js:noInline')
  static getWeekday(DateTime receiver) {
    int weekday = (receiver.isUtc)
        ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
        : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver));
    // Adjust by one because JS weeks start on Sunday.
    return (weekday + 6) % 7 + 1;
  }

  static num valueFromDateString(str) {
    if (str is! String) throw argumentErrorValue(str);
    num value = JS('num', r'Date.parse(#)', str);
    if (value.isNaN) throw argumentErrorValue(str);
    return value;
  }

  static getProperty(object, key) {
    if (object == null || object is bool || object is num || object is String) {
      throw argumentErrorValue(object);
    }
    return JS('var', '#[#]', object, key);
  }

  static void setProperty(object, key, value) {
    if (object == null || object is bool || object is num || object is String) {
      throw argumentErrorValue(object);
    }
    JS('void', '#[#] = #', object, key, value);
  }

  static functionNoSuchMethod(function, List? positionalArguments,
      Map<String, dynamic>? namedArguments) {
    int argumentCount = 0;
    List arguments = [];
    List namedArgumentList = [];

    if (positionalArguments != null) {
      argumentCount += positionalArguments.length;
      arguments.addAll(positionalArguments);
    }

    String names = '';
    if (namedArguments != null && !namedArguments.isEmpty) {
      namedArguments.forEach((String name, argument) {
        names = '$names\$$name';
        namedArgumentList.add(name);
        arguments.add(argument);
        argumentCount++;
      });
    }

    String selectorName =
        '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount$names';

    return function.noSuchMethod(createUnmangledInvocationMirror(
        #call, selectorName, mirrors.method, arguments, namedArgumentList, 0));
  }

  /// Implements [Function.apply] for the lazy and startup emitters.
  ///
  /// There are two types of closures that can reach this function:
  ///
  /// 1. tear-offs (including tear-offs of static functions).
  /// 2. anonymous closures.
  ///
  /// They are treated differently (although there are lots of similarities).
  /// Both have in common that they have
  /// a [JsGetName.CALL_CATCH_ALL] and
  /// a [JsGetName.REQUIRED_PARAMETER_PROPERTY] property.
  ///
  /// If the closure supports optional parameters, then they also feature
  /// a [JsGetName.DEFAULT_VALUES_PROPERTY] property.
  ///
  /// The catch-all property is a method that takes all arguments (including
  /// all optional positional or named arguments). If the function accepts
  /// optional arguments, then the default-values property stores (potentially
  /// wrapped in a function) the default values for the optional arguments. If
  /// the function accepts optional positional arguments, then the value is a
  /// JavaScript array with the default values. Otherwise, when the function
  /// accepts optional named arguments, it is a JavaScript object.
  ///
  /// The default-values property may either contain the value directly, or
  /// it can be a function that returns the default-values when invoked.
  ///
  /// If the function is an anonymous closure, then the catch-all property
  /// only contains a string pointing to the property that should be used
  /// instead. For example, if the catch-all property contains the string
  /// "call$4", then the object's "call$4" property should be used as if it was
  /// the value of the catch-all property.
  static applyFunction(Function function, List? positionalArguments,
      Map<String, dynamic>? namedArguments) {
    // Fast path for common cases.
    if (positionalArguments is JSArray &&
        (namedArguments == null || namedArguments.isEmpty)) {
      JSArray arguments = positionalArguments;
      int argumentCount = arguments.length;
      if (argumentCount == 0) {
        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX0);
        if (JS('bool', '!!#[#]', function, selectorName)) {
          return JS('', '#[#]()', function, selectorName);
        }
      } else if (argumentCount == 1) {
        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX1);
        if (JS('bool', '!!#[#]', function, selectorName)) {
          return JS('', '#[#](#[0])', function, selectorName, arguments);
        }
      } else if (argumentCount == 2) {
        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX2);
        if (JS('bool', '!!#[#]', function, selectorName)) {
          return JS('', '#[#](#[0],#[1])', function, selectorName, arguments,
              arguments);
        }
      } else if (argumentCount == 3) {
        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX3);
        if (JS('bool', '!!#[#]', function, selectorName)) {
          return JS('', '#[#](#[0],#[1],#[2])', function, selectorName,
              arguments, arguments, arguments);
        }
      } else if (argumentCount == 4) {
        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX4);
        if (JS('bool', '!!#[#]', function, selectorName)) {
          return JS('', '#[#](#[0],#[1],#[2],#[3])', function, selectorName,
              arguments, arguments, arguments, arguments);
        }
      } else if (argumentCount == 5) {
        String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX5);
        if (JS('bool', '!!#[#]', function, selectorName)) {
          return JS(
              '',
              '#[#](#[0],#[1],#[2],#[3],#[4])',
              function,
              selectorName,
              arguments,
              arguments,
              arguments,
              arguments,
              arguments);
        }
      }
      String selectorName =
          '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount';
      var jsStub = JS('var', r'#[#]', function, selectorName);
      if (jsStub != null) {
        return JS('var', '#.apply(#, #)', jsStub, function, arguments);
      }
    }

    return _generalApplyFunction(function, positionalArguments, namedArguments);
  }

  static _generalApplyFunction(Function function, List? positionalArguments,
      Map<String, dynamic>? namedArguments) {
    List arguments;
    if (positionalArguments != null) {
      if (positionalArguments is JSArray) {
        arguments = positionalArguments;
      } else {
        arguments = List.of(positionalArguments);
      }
    } else {
      arguments = [];
    }

    int argumentCount = arguments.length;

    int requiredParameterCount = JS('int', r'#[#]', function,
        JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY));

    if (argumentCount < requiredParameterCount) {
      return functionNoSuchMethod(function, arguments, namedArguments);
    }

    var defaultValuesClosure = JS('var', r'#[#]', function,
        JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY));

    bool acceptsOptionalArguments = defaultValuesClosure != null;

    // Default values are stored inside a JavaScript closure to avoid
    // accessing them too early.
    var defaultValues =
        acceptsOptionalArguments ? JS('', '#()', defaultValuesClosure) : null;

    var interceptor = getInterceptor(function);
    var jsFunction =
        JS('', '#[#]', interceptor, JS_GET_NAME(JsGetName.CALL_CATCH_ALL));
    if (jsFunction is String) {
      // Anonymous closures redirect to the catch-all property instead of
      // storing the catch-all method directly in the catch-all property.
      jsFunction = JS('', '#[#]', interceptor, jsFunction);
    }

    if (!acceptsOptionalArguments) {
      if (namedArguments != null && namedArguments.isNotEmpty) {
        // Tried to invoke a function that takes a fixed number of arguments
        // with named (optional) arguments.
        return functionNoSuchMethod(function, arguments, namedArguments);
      }
      if (argumentCount == requiredParameterCount) {
        return JS('var', r'#.apply(#, #)', jsFunction, function, arguments);
      }
      return functionNoSuchMethod(function, arguments, namedArguments);
    }

    bool acceptsPositionalArguments = defaultValues is JSArray;

    if (acceptsPositionalArguments) {
      if (namedArguments != null && namedArguments.isNotEmpty) {
        // Tried to invoke a function that takes optional positional arguments
        // with named arguments.
        return functionNoSuchMethod(function, arguments, namedArguments);
      }

      int defaultsLength = JS('int', '#.length', defaultValues);
      int maxArguments = requiredParameterCount + defaultsLength;
      if (argumentCount > maxArguments) {
        // The function expects fewer arguments.
        return functionNoSuchMethod(function, arguments, null);
      }
      if (argumentCount < maxArguments) {
        List missingDefaults = JS('JSArray', '#.slice(#)', defaultValues,
            argumentCount - requiredParameterCount);
        if (identical(arguments, positionalArguments)) {
          // Defensive copy to avoid modifying passed-in List.
          arguments = List.of(arguments);
        }
        arguments.addAll(missingDefaults);
      }
      return JS('var', '#.apply(#, #)', jsFunction, function, arguments);
    } else {
      // Handle named arguments.

      if (argumentCount > requiredParameterCount) {
        // Tried to invoke a function that takes named parameters with
        // too many positional arguments.
        return functionNoSuchMethod(function, arguments, namedArguments);
      }

      if (identical(arguments, positionalArguments)) {
        // Defensive copy to avoid modifying passed-in List.
        arguments = List.of(arguments);
      }

      List keys = JS('JSArray', r'Object.keys(#)', defaultValues);
      if (namedArguments == null) {
        for (String key in keys) {
          var defaultValue = JS('var', '#[#]', defaultValues, key);
          if (isRequired(defaultValue)) {
            return functionNoSuchMethod(function, arguments, namedArguments);
          }
          arguments.add(defaultValue);
        }
      } else {
        int used = 0;
        for (String key in keys) {
          if (namedArguments.containsKey(key)) {
            used++;
            arguments.add(namedArguments[key]);
          } else {
            var defaultValue = JS('var', '#[#]', defaultValues, key);
            if (isRequired(defaultValue)) {
              return functionNoSuchMethod(function, arguments, namedArguments);
            }
            arguments.add(defaultValue);
          }
        }
        if (used != namedArguments.length) {
          // Named argument with name not accepted by function.
          return functionNoSuchMethod(function, arguments, namedArguments);
        }
      }
      return JS('var', r'#.apply(#, #)', jsFunction, function, arguments);
    }
  }

  static StackTrace? extractStackTrace(Error error) {
    var jsError = JS('', r'#.$thrownJsError', error);
    if (jsError == null) return null;
    return getTraceFromException(jsError);
  }
}

/// Called by generated code to throw an illegal-argument exception,
/// for example, if a non-integer index is given to an optimized
/// indexed access.
@pragma('dart2js:noInline')
iae(argument) {
  throw argumentErrorValue(argument);
}

/// Called by generated code to throw an index-out-of-range exception, for
/// example, if a bounds check fails in an optimized indexed access.  This may
/// also be called when the index is not an integer, in which case it throws an
/// illegal-argument exception instead, like [iae], or when the receiver is
/// null.
@pragma('dart2js:noInline')
ioore(receiver, index) {
  if (receiver == null) receiver.length; // Force a NoSuchMethodError.
  throw diagnoseIndexError(receiver, index);
}

/// Diagnoses an indexing error. Returns the ArgumentError or RangeError that
/// describes the problem.
@pragma('dart2js:noInline')
Error diagnoseIndexError(indexable, index) {
  if (index is! int) return ArgumentError.value(index, 'index');
  int length = indexable.length;
  // The following returns the same error that would be thrown by calling
  // [IndexError.check] with no optional parameters
  // provided.
  if (index < 0 || index >= length) {
    return IndexError.withLength(index, length,
        indexable: indexable, name: 'index');
  }
  // The above should always match, but if it does not, use the following.
  return RangeError.value(index, 'index');
}

/// Diagnoses a range error. Returns the ArgumentError or RangeError that
/// describes the problem.
@pragma('dart2js:noInline')
Error diagnoseRangeError(start, end, length) {
  if (start is! int) {
    return ArgumentError.value(start, 'start');
  }
  if (start < 0 || start > length) {
    return RangeError.range(start, 0, length, 'start');
  }
  if (end != null) {
    if (end is! int) {
      return ArgumentError.value(end, 'end');
    }
    if (end < start || end > length) {
      return RangeError.range(end, start, length, 'end');
    }
  }
  // The above should always match, but if it does not, use the following.
  return ArgumentError.value(end, 'end');
}

stringLastIndexOfUnchecked(receiver, element, start) =>
    JS('int', r'#.lastIndexOf(#, #)', receiver, element, start);

/// 'factory' for constructing ArgumentError.value to keep the call sites small.
@pragma('dart2js:noInline')
ArgumentError argumentErrorValue(object) {
  return ArgumentError.value(object);
}

checkNull(object) {
  if (object == null) throw argumentErrorValue(object);
  return object;
}

@pragma('dart2js:noInline')
num checkNum(value) {
  if (value is! num) throw argumentErrorValue(value);
  return value;
}

int checkInt(value) {
  if (value is! int) throw argumentErrorValue(value);
  return value;
}

bool checkBool(value) {
  if (value is! bool) throw argumentErrorValue(value);
  return value;
}

String checkString(value) {
  if (value is! String) throw argumentErrorValue(value);
  return value;
}

/// Wrap the given Dart object and record a stack trace.
///
/// The code in [unwrapException] deals with getting the original Dart
/// object out of the wrapper again.
@pragma('dart2js:never-inline')
wrapException(ex) {
  final wrapper = JS('', 'new Error()');
  return initializeExceptionWrapper(wrapper, ex);
}

@pragma('dart2js:never-inline')
initializeExceptionWrapper(wrapper, ex) {
  if (ex == null) ex = TypeError();
  // [unwrapException] looks for the property 'dartException'.
  JS('void', '#.dartException = #', wrapper, ex);

  if (JS('bool', '"defineProperty" in Object')) {
    // Define a JavaScript getter for 'message'. This is to work around V8 bug
    // (https://code.google.com/p/v8/issues/detail?id=2519).  The default
    // toString on Error returns the value of 'message' if 'name' is
    // empty. Setting toString directly doesn't work, see the bug.
    JS('void', 'Object.defineProperty(#, "message", { get: # })', wrapper,
        DART_CLOSURE_TO_JS(toStringWrapper));
    JS('void', '#.name = ""', wrapper);
  } else {
    // In the unlikely event the browser doesn't support Object.defineProperty,
    // hope that it just calls toString.
    JS('void', '#.toString = #', wrapper, DART_CLOSURE_TO_JS(toStringWrapper));
  }

  return wrapper;
}

/// Do not call directly.
toStringWrapper() {
  // This method gets installed as toString on a JavaScript object. Due to the
  // weird scope rules of JavaScript, JS 'this' will refer to that object.
  return JS('', r'this.dartException').toString();
}

/// This wraps the exception and does the throw.  It is possible to call this in
/// a JS expression context, where the throw statement is not allowed.  Helpers
/// are never inlined, so we don't risk inlining the throw statement into an
/// expression context.
@pragma('dart2js:never-inline')
Never throwExpression(ex) {
  // TODO(sra): Manually inline `wrapException` to remove one stack frame.
  JS<Never>('', 'throw #', wrapException(ex));
}

Never throwExpressionWithWrapper(ex, wrapper) {
  JS<Never>('', 'throw #', initializeExceptionWrapper(wrapper, ex));
}

throwUnsupportedError(message) {
  throw UnsupportedError(message);
}

// This is used in open coded for-in loops on arrays.
//
//     checkConcurrentModificationError(a.length == startLength, a)
//
// is replaced in codegen by:
//
//     a.length == startLength || throwConcurrentModificationError(a)
//
// TODO(sra): We would like to annotate this as @pragma('dart2js:noSideEffects') so that loops
// with no other effects can recognize that the array length does not
// change. However, in the usual case where the loop does have other effects,
// that causes the length in the loop condition to be phi(startLength,a.length),
// which causes confusion in range analysis and the insertion of a bounds check.
@pragma('dart2js:noInline')
checkConcurrentModificationError(sameLength, collection) {
  if (true != sameLength) {
    throwConcurrentModificationError(collection);
  }
}

@pragma('dart2js:noInline')
throwConcurrentModificationError(collection) {
  throw ConcurrentModificationError(collection);
}

/// Helper class for building patterns recognizing native type errors.
class TypeErrorDecoder {
  // Field names are private to help tree-shaking.

  /// A regular expression which matches is matched against an error message.
  final String _pattern;

  /// The group index of "arguments" in [_pattern], or -1 if _pattern has no
  /// match for "arguments".
  final int _arguments;

  /// The group index of "argumentsExpr" in [_pattern], or -1 if _pattern has
  /// no match for "argumentsExpr".
  final int _argumentsExpr;

  /// The group index of "expr" in [_pattern], or -1 if _pattern has no match
  /// for "expr".
  final int _expr;

  /// The group index of "method" in [_pattern], or -1 if _pattern has no match
  /// for "method".
  final int _method;

  /// The group index of "receiver" in [_pattern], or -1 if _pattern has no
  /// match for "receiver".
  final int _receiver;

  /// Pattern used to recognize a NoSuchMethodError error (and
  /// possibly extract the method name).
  static final TypeErrorDecoder noSuchMethodPattern =
      extractPattern(provokeCallErrorOn(buildJavaScriptObject()));

  /// Pattern used to recognize an "object not a closure" error (and
  /// possibly extract the method name).
  static final TypeErrorDecoder notClosurePattern =
      extractPattern(provokeCallErrorOn(buildJavaScriptObjectWithNonClosure()));

  /// Pattern used to recognize a NoSuchMethodError on JavaScript null
  /// call.
  static final TypeErrorDecoder nullCallPattern =
      extractPattern(provokeCallErrorOn(JS('', 'null')));

  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal null
  /// call.
  static final TypeErrorDecoder nullLiteralCallPattern =
      extractPattern(provokeCallErrorOnNull());

  /// Pattern used to recognize a NoSuchMethodError on JavaScript
  /// undefined call.
  static final TypeErrorDecoder undefinedCallPattern =
      extractPattern(provokeCallErrorOn(JS('', 'void 0')));

  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal
  /// undefined call.
  static final TypeErrorDecoder undefinedLiteralCallPattern =
      extractPattern(provokeCallErrorOnUndefined());

  /// Pattern used to recognize a NoSuchMethodError on JavaScript null
  /// property access.
  static final TypeErrorDecoder nullPropertyPattern =
      extractPattern(provokePropertyErrorOn(JS('', 'null')));

  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal null
  /// property access.
  static final TypeErrorDecoder nullLiteralPropertyPattern =
      extractPattern(provokePropertyErrorOnNull());

  /// Pattern used to recognize a NoSuchMethodError on JavaScript
  /// undefined property access.
  static final TypeErrorDecoder undefinedPropertyPattern =
      extractPattern(provokePropertyErrorOn(JS('', 'void 0')));

  /// Pattern used to recognize a NoSuchMethodError on JavaScript literal
  /// undefined property access.
  static final TypeErrorDecoder undefinedLiteralPropertyPattern =
      extractPattern(provokePropertyErrorOnUndefined());

  TypeErrorDecoder(this._arguments, this._argumentsExpr, this._expr,
      this._method, this._receiver, this._pattern);

  /// Returns a JavaScript object literal (map) with at most the
  /// following keys:
  ///
  /// * arguments: The arguments as formatted by the JavaScript
  ///   engine. No browsers are known to provide this information.
  ///
  /// * argumentsExpr: The syntax of the arguments (JavaScript source
  ///   code). No browsers are known to provide this information.
  ///
  /// * expr: The syntax of the receiver expression (JavaScript source
  ///   code). Firefox provides this information, for example: "$expr$.$method$
  ///   is not a function".
  ///
  /// * method: The name of the called method (mangled name). At least Firefox
  ///   and Chrome/V8 provides this information, for example, "Object [object
  ///   Object] has no method '$method$'".
  ///
  /// * receiver: The string representation of the receiver. Chrome/V8
  ///   used to provide this information (by calling user-defined
  ///   JavaScript toString on receiver), but it has degenerated into
  ///   "[object Object]" in recent versions.
  matchTypeError(message) {
    var match = JS(
        'JSExtendableArray|Null', 'new RegExp(#).exec(#)', _pattern, message);
    if (match == null) return null;
    var result = JS('', 'Object.create(null)');
    if (_arguments != -1) {
      JS('', '#.arguments = #[# + 1]', result, match, _arguments);
    }
    if (_argumentsExpr != -1) {
      JS('', '#.argumentsExpr = #[# + 1]', result, match, _argumentsExpr);
    }
    if (_expr != -1) {
      JS('', '#.expr = #[# + 1]', result, match, _expr);
    }
    if (_method != -1) {
      JS('', '#.method = #[# + 1]', result, match, _method);
    }
    if (_receiver != -1) {
      JS('', '#.receiver = #[# + 1]', result, match, _receiver);
    }

    return result;
  }

  /// Builds a JavaScript Object with a toString method saying
  /// r"$receiver$".
  static buildJavaScriptObject() {
    return JS('', r'{ toString: function() { return "$receiver$"; } }');
  }

  /// Builds a JavaScript Object with a toString method saying
  /// r"$receiver$". The property "$method" is defined, but is not a function.
  static buildJavaScriptObjectWithNonClosure() {
    return JS(
        '',
        r'{ $method$: null, '
            r'toString: function() { return "$receiver$"; } }');
  }

  /// Extract a pattern from a JavaScript TypeError message.
  ///
  /// The patterns are extracted by forcing TypeErrors on known
  /// objects thus forcing known strings into the error message. The
  /// known strings are then replaced with wildcards which in theory
  /// makes it possible to recognize the desired information even if
  /// the error messages are reworded or translated.
  static extractPattern(String message) {
    // Some JavaScript implementations (V8 at least) include a
    // representation of the receiver in the error message, however,
    // this representation is not always [: receiver.toString() :],
    // sometimes it is [: Object.prototype.toString(receiver) :], and
    // sometimes it is an implementation specific method (but that
    // doesn't seem to happen for object literals). So sometimes we
    // get the text "[object Object]". The shortest way to get that
    // string is using "String({})".
    // See: http://code.google.com/p/v8/issues/detail?id=2519.
    message = JS('String', r'#.replace(String({}), "$receiver$")', message);

    // Since we want to create a new regular expression from an unknown string,
    // we must escape all regular expression syntax.
    message = quoteStringForRegExp(message);

    // Look for the special pattern \$camelCase\$ (all the $ symbols
    // have been escaped already), as we will soon be inserting
    // regular expression syntax that we want interpreted by RegExp.
    List<String>? match =
        JS('JSExtendableArray|Null', r'#.match(/\\\$[a-zA-Z]+\\\$/g)', message);
    if (match == null) match = [];

    // Find the positions within the substring matches of the error message
    // components.  This will help us extract information later, such as the
    // method name.
    int arguments = JS('int', '#.indexOf(#)', match, r'\$arguments\$');
    int argumentsExpr = JS('int', '#.indexOf(#)', match, r'\$argumentsExpr\$');
    int expr = JS('int', '#.indexOf(#)', match, r'\$expr\$');
    int method = JS('int', '#.indexOf(#)', match, r'\$method\$');
    int receiver = JS('int', '#.indexOf(#)', match, r'\$receiver\$');

    // Replace the patterns with a regular expression wildcard.
    // Note: in a perfect world, one would use "(.*)", but not in
    // JavaScript, "." does not match newlines.
    String pattern = JS(
        'String',
        r'#.replace(new RegExp("\\\\\\$arguments\\\\\\$", "g"), '
            r'"((?:x|[^x])*)")'
            r'.replace(new RegExp("\\\\\\$argumentsExpr\\\\\\$", "g"),  '
            r'"((?:x|[^x])*)")'
            r'.replace(new RegExp("\\\\\\$expr\\\\\\$", "g"),  "((?:x|[^x])*)")'
            r'.replace(new RegExp("\\\\\\$method\\\\\\$", "g"),  "((?:x|[^x])*)")'
            r'.replace(new RegExp("\\\\\\$receiver\\\\\\$", "g"),  '
            r'"((?:x|[^x])*)")',
        message);

    return TypeErrorDecoder(
        arguments, argumentsExpr, expr, method, receiver, pattern);
  }

  /// Provokes a TypeError and returns its message.
  ///
  /// The error is provoked so all known variable content can be recognized and
  /// a pattern can be inferred.
  static String provokeCallErrorOn(expression) {
    // This function is carefully created to maximize the possibility
    // of decoding the TypeError message and turning it into a general
    // pattern.
    //
    // The idea is to inject something known into something unknown.  The
    // unknown entity is the error message that the browser provides with a
    // TypeError.  It is a human readable message, possibly localized in a
    // language no dart2js engineer understand.  We assume that $name$ would
    // never naturally occur in a human readable error message, yet it is easy
    // to decode.
    //
    // For example, evaluate this in V8 version 3.13.7.6:
    //
    // var $expr$ = null; $expr$.$method$()
    //
    // The VM throws an instance of TypeError whose message property contains
    // "Cannot call method '$method$' of null".  We can then reasonably assume
    // that if the string contains $method$, that's where the method name will
    // be in general.  Call this automatically reverse engineering the error
    // format string in V8.
    //
    // So the error message from V8 is turned into this regular expression:
    //
    // "Cannot call method '(.*)' of null"
    //
    // Similarly, if we evaluate:
    //
    // var $expr$ = {toString: function() { return '$receiver$'; }};
    // $expr$.$method$()
    //
    // We get this message: "Object $receiver$ has no method '$method$'"
    //
    // Which is turned into this regular expression:
    //
    // "Object (.*) has no method '(.*)'"
    //
    // Firefox/jsshell is slightly different, it tries to include the source
    // code that caused the exception, so we get this message: "$expr$.$method$
    // is not a function" which is turned into this regular expression:
    //
    // "(.*)\\.(.*) is not a function"

    var function = JS('', r"""function($expr$) {
  var $argumentsExpr$ = "$arguments$";
  try {
    $expr$.$method$($argumentsExpr$);
  } catch (e) {
    return e.message;
  }
}""");
    return JS('String', '(#)(#)', function, expression);
  }

  /// Similar to [provokeCallErrorOn], but provokes an error directly on
  /// literal "null" expression.
  static String provokeCallErrorOnNull() {
    // See [provokeCallErrorOn] for a detailed explanation.
    var function = JS('', r"""function() {
  var $argumentsExpr$ = "$arguments$";
  try {
    null.$method$($argumentsExpr$);
  } catch (e) {
    return e.message;
  }
}""");
    return JS('String', '(#)()', function);
  }

  /// Similar to [provokeCallErrorOnNull], but provokes an error directly on
  /// (void 0), that is, "undefined".
  static String provokeCallErrorOnUndefined() {
    // See [provokeCallErrorOn] for a detailed explanation.
    var function = JS('', r"""function() {
  var $argumentsExpr$ = "$arguments$";
  try {
    (void 0).$method$($argumentsExpr$);
  } catch (e) {
    return e.message;
  }
}""");
    return JS('String', '(#)()', function);
  }

  /// Similar to [provokeCallErrorOn], but provokes a property access
  /// error.
  static String provokePropertyErrorOn(expression) {
    // See [provokeCallErrorOn] for a detailed explanation.
    var function = JS('', r"""function($expr$) {
  try {
    $expr$.$method$;
  } catch (e) {
    return e.message;
  }
}""");
    return JS('String', '(#)(#)', function, expression);
  }

  /// Similar to [provokePropertyErrorOn], but provokes an property access
  /// error directly on literal "null" expression.
  static String provokePropertyErrorOnNull() {
    // See [provokeCallErrorOn] for a detailed explanation.
    var function = JS('', r"""function() {
  try {
    null.$method$;
  } catch (e) {
    return e.message;
  }
}""");
    return JS('String', '(#)()', function);
  }

  /// Similar to [provokePropertyErrorOnNull], but provokes an property access
  /// error directly on (void 0), that is, "undefined".
  static String provokePropertyErrorOnUndefined() {
    // See [provokeCallErrorOn] for a detailed explanation.
    var function = JS('', r"""function() {
  try {
    (void 0).$method$;
  } catch (e) {
    return e.message;
  }
}""");
    return JS('String', '(#)()', function);
  }
}

class NullError extends TypeError implements NoSuchMethodError {
  final String _message;

  NullError(this._message);

  String toString() {
    return 'Null check operator used on a null value';
  }
}

class JsNoSuchMethodError extends Error implements NoSuchMethodError {
  final String _message;
  final String? _method;
  final String? _receiver;

  JsNoSuchMethodError(this._message, match)
      : _method = match == null ? null : JS('String|Null', '#.method', match),
        _receiver =
            match == null ? null : JS('String|Null', '#.receiver', match);

  String toString() {
    if (_method == null) return 'NoSuchMethodError: $_message';
    if (_receiver == null) {
      return "NoSuchMethodError: method not found: '$_method' ($_message)";
    }
    return "NoSuchMethodError: "
        "method not found: '$_method' on '$_receiver' ($_message)";
  }
}

class UnknownJsTypeError extends Error {
  final String _message;

  UnknownJsTypeError(this._message);

  String toString() => _message.isEmpty ? 'Error' : 'Error: $_message';
}

class NullThrownFromJavaScriptException implements Exception {
  final dynamic _irritant;
  NullThrownFromJavaScriptException(this._irritant);

  @override
  String toString() {
    String description =
        JS('bool', '# === null', _irritant) ? 'null' : 'undefined';
    return "Throw of null ('$description' from JavaScript)";
  }
}

/// A wrapper around an exception, much like the one created by [wrapException]
/// but with a pre-given stack-trace.
class ExceptionAndStackTrace {
  dynamic dartException;
  StackTrace stackTrace;

  ExceptionAndStackTrace(this.dartException, this.stackTrace);
}

/// Called from catch blocks in generated code to extract the Dart exception
/// from the thrown value. The thrown value may have been created by
/// [wrapException] or it may be a 'native' JavaScript exception.
///
/// Some native exceptions are mapped to new Dart instances, others are
/// returned unmodified.
Object unwrapException(Object? ex) {
  // Null safe Dart can't throw null, and it is now a `TypeError` in unsound
  // code. JavaScript can still throw a nullish value.
  if (ex == null) {
    return NullThrownFromJavaScriptException(ex);
  }

  if (ex is ExceptionAndStackTrace) {
    return saveStackTrace(ex, ex.dartException);
  }

  // e.g. a primitive value thrown by JavaScript.
  if (JS('bool', 'typeof # !== "object"', ex)) return ex;

  if (JS('bool', r'"dartException" in #', ex)) {
    return saveStackTrace(ex, JS('', r'#.dartException', ex));
  }
  return _unwrapNonDartException(ex);
}

/// If error implements Dart [Error], save [ex] in [error.$thrownJsError].
/// Otherwise, do nothing. Later, the stack trace can then be extracted from
/// [ex].
Object saveStackTrace(Object ex, Object error) {
  if (error is Error) {
    var thrownStackTrace = JS('', r'#.$thrownJsError', error);
    if (thrownStackTrace == null) {
      JS('void', r'#.$thrownJsError = #', error, ex);
    }
  }
  return error;
}

Object _unwrapNonDartException(Object ex) {
  if (!JS('bool', r'"message" in #', ex)) {
    return ex;
  }
  // Grab hold of the exception message. This field is available on
  // all supported browsers.
  var message = JS('var', r'#.message', ex);

  // Internet Explorer has an error number.  This is the most reliable way to
  // detect specific errors, so check for this first.
  if (JS('bool', '"number" in #', ex) &&
      JS('bool', 'typeof #.number == "number"', ex)) {
    int number = JS('int', '#.number', ex);

    // From http://msdn.microsoft.com/en-us/library/ie/hc53e755(v=vs.94).aspx
    // "number" is a 32-bit word. The error code is the low 16 bits, and the
    // facility code is the upper 16 bits.
    var ieErrorCode = number & 0xffff;
    var ieFacilityNumber = (number >> 16) & 0x1fff;

    // http://msdn.microsoft.com/en-us/library/aa264975(v=vs.60).aspx
    // http://msdn.microsoft.com/en-us/library/ie/1dk3k160(v=vs.94).aspx
    if (ieFacilityNumber == 10) {
      switch (ieErrorCode) {
        case 438:
          return saveStackTrace(
              ex, JsNoSuchMethodError('$message (Error $ieErrorCode)', null));
        case 445:
        case 5007:
          return saveStackTrace(ex, NullError('$message (Error $ieErrorCode)'));
      }
    }
  }

  if (JS('bool', r'# instanceof TypeError', ex)) {
    var match;
    var nsme = TypeErrorDecoder.noSuchMethodPattern;
    var notClosure = TypeErrorDecoder.notClosurePattern;
    var nullCall = TypeErrorDecoder.nullCallPattern;
    var nullLiteralCall = TypeErrorDecoder.nullLiteralCallPattern;
    var undefCall = TypeErrorDecoder.undefinedCallPattern;
    var undefLiteralCall = TypeErrorDecoder.undefinedLiteralCallPattern;
    var nullProperty = TypeErrorDecoder.nullPropertyPattern;
    var nullLiteralProperty = TypeErrorDecoder.nullLiteralPropertyPattern;
    var undefProperty = TypeErrorDecoder.undefinedPropertyPattern;
    var undefLiteralProperty = TypeErrorDecoder.undefinedLiteralPropertyPattern;
    if ((match = nsme.matchTypeError(message)) != null) {
      return saveStackTrace(ex, JsNoSuchMethodError(message, match));
    } else if ((match = notClosure.matchTypeError(message)) != null) {
      // notClosure may match "({c:null}).c()" or "({c:1}).c()", so we
      // cannot tell if this an attempt to invoke call on null or a
      // non-function object.
      // But we do know the method name is "call".
      JS('', '#.method = "call"', match);
      return saveStackTrace(ex, JsNoSuchMethodError(message, match));
    } else if ((match = nullCall.matchTypeError(message)) != null ||
        (match = nullLiteralCall.matchTypeError(message)) != null ||
        (match = undefCall.matchTypeError(message)) != null ||
        (match = undefLiteralCall.matchTypeError(message)) != null ||
        (match = nullProperty.matchTypeError(message)) != null ||
        (match = nullLiteralCall.matchTypeError(message)) != null ||
        (match = undefProperty.matchTypeError(message)) != null ||
        (match = undefLiteralProperty.matchTypeError(message)) != null) {
      return saveStackTrace(ex, NullError(message));
    }

    // If we cannot determine what kind of error this is, we fall back
    // to reporting this as a generic error. It's probably better than
    // nothing.
    return saveStackTrace(
        ex, UnknownJsTypeError(message is String ? message : ''));
  }

  if (JS('bool', r'# instanceof RangeError', ex)) {
    if (message is String && contains(message, 'call stack')) {
      return StackOverflowError();
    }

    // In general, a RangeError is thrown when trying to pass a number as an
    // argument to a function that does not allow a range that includes that
    // number. Translate to a Dart ArgumentError with the same message.
    // TODO(sra): Translate to RangeError.
    message = tryStringifyException(ex);
    if (message is String) {
      message = JS('String', r'#.replace(/^RangeError:\s*/, "")', message);
    }
    return saveStackTrace(ex, ArgumentError(message));
  }

  // Check for the Firefox specific stack overflow signal.
  if (JS(
      'bool',
      r'typeof InternalError == "function" && # instanceof InternalError',
      ex)) {
    if (message is String && message == 'too much recursion') {
      return StackOverflowError();
    }
  }

  // Just return the exception. We should not wrap it because in case the
  // exception comes from the DOM, it is a JavaScript object that has a Dart
  // interceptor.
  return ex;
}

String? tryStringifyException(ex) {
  // Since this function is called from [unwrapException] which is called from
  // code injected into a catch-clause, use JavaScript try-catch to avoid a
  // potential loop if stringifying crashes.
  return JS(
      'String|Null',
      r'''
    (function(ex) {
      try {
        return String(ex);
      } catch (e) {}
      return null;
    })(#)
    ''',
      ex);
}

/// Called by generated code to fetch the stack trace from an
/// exception. Should never return null.
StackTrace getTraceFromException(exception) {
  if (exception is ExceptionAndStackTrace) {
    return exception.stackTrace;
  }
  if (exception == null) return _StackTrace(exception);
  _StackTrace? trace = JS('_StackTrace|Null', r'#.$cachedTrace', exception);
  if (trace != null) return trace;
  trace = _StackTrace(exception);

  // When storing a property on a primitive value `v`, JavaScript converts the
  // primitive value to an ephemeral wrapper object via `Object(v)`, and then
  // stores the property on the wrapper object. This is either (1) a useless
  // operation or (2) an error in "use strict" mode. So only store the cached
  // stack trace on an exception value that is actually an object.
  if (JS('bool', 'typeof # === "object"', exception)) {
    JS('', r'#.$cachedTrace = #', exception, trace);
  }

  return trace;
}

class _StackTrace implements StackTrace {
  var _exception;
  String? _trace;
  _StackTrace(this._exception);

  String toString() {
    if (_trace != null) return JS('String', '#', _trace);

    String? trace;
    if (JS('bool', '# !== null', _exception) &&
        JS('bool', 'typeof # === "object"', _exception)) {
      trace = JS('String|Null', r'#.stack', _exception);
    }
    return _trace = (trace == null) ? '' : trace;
  }
}

/// Implementation of `identityHashCode`.
///
/// This hash code is compatible with identical, which means that it's
/// guaranteed to give the same result every time it's passed the same argument,
/// throughout a single program execution, for any non-record object.
int objectHashCode(Object? object) {
  // `typeof null == "object"` so test `null` first.
  if (object == null) return object.hashCode;
  if (JS('bool', 'typeof # == "object"', object)) {
    return Primitives.objectHashCode(object);
  }
  // Other values are primitives so use the override of `Object.hashCode`.
  return object.hashCode;
}

/// Hash code for constant Maps and Sets. Unlike `identityHashCode`, this is
/// defined for Records.
int constantHashCode(Object? key) {
  // Types are tested here one-by-one so that each call to get:hashCode can be
  // resolved differently.

  // Some common primitives used as keys in a GeneralConstantMap.
  if (key is num) return key.hashCode; // One method on JSNumber.

  // Specially handled known types.
  if (key is Type) return key.hashCode;
  if (key is Record) return key.hashCode;
  if (key is Symbol) return key.hashCode;

  // Everything else, including less common primitives.
  return identityHashCode(key);
}

/// Called by generated code to build a map literal. [keyValuePairs] is
/// a list of key, value, key, value, ..., etc.
fillLiteralMap(keyValuePairs, Map result) {
  // TODO(johnniwinther): Use JSArray to optimize this code instead of calling
  // [getLength] and [getIndex].
  int index = 0;
  int length = getLength(keyValuePairs);
  while (index < length) {
    var key = getIndex(keyValuePairs, index++);
    var value = getIndex(keyValuePairs, index++);
    result[key] = value;
  }
  return result;
}

/// Called by generated code to build a set literal.
fillLiteralSet(values, Set result) {
  // TODO(johnniwinther): Use JSArray to optimize this code instead of calling
  // [getLength] and [getIndex].
  int length = getLength(values);
  for (int index = 0; index < length; index++) {
    result.add(getIndex(values, index));
  }
  return result;
}

/// Called by generated code to move and JSON-ify properties from an object
/// to a map literal.
copyAndJsonifyProperties(from, Map to) {
  if (JS('bool', '!#', from)) return to;
  List keys = JS('JSArray', r'Object.keys(#)', from);
  int index = 0;
  int length = getLength(keys);
  while (index < length) {
    var key = getIndex(keys, index++);
    var value = JS('String', r'JSON.stringify(#[#])', from, key);
    Map jsonValue = jsonDecode(value);
    to[key] = jsonValue;
  }
  return to;
}

/// Returns the property [index] of the JavaScript array [array].
getIndex(var array, int index) {
  return JS('var', r'#[#]', array, index);
}

/// Returns the length of the JavaScript array [array].
int getLength(var array) {
  return JS('int', r'#.length', array);
}

_invokeClosure(Function closure, int numberOfArguments, var arg1, var arg2,
    var arg3, var arg4) {
  switch (numberOfArguments) {
    case 0:
      return closure();
    case 1:
      return closure(arg1);
    case 2:
      return closure(arg1, arg2);
    case 3:
      return closure(arg1, arg2, arg3);
    case 4:
      return closure(arg1, arg2, arg3, arg4);
  }
  throw Exception('Unsupported number of arguments for wrapped closure');
}

/// Called by generated code to convert a Dart closure to a JS
/// closure when the Dart closure is passed to the DOM.
convertDartClosureToJS(Object? closure, int arity) {
  if (closure == null) return null;
  var function = JS('var', r'#.$identity', closure);
  if (JS('bool', r'!!#', function)) return function;
  function = convertDartClosureToJSUncached(closure, arity);
  JS('void', r'#.$identity = #', closure, function);
  return function;
}

convertDartClosureToJSUncached(Object closure, int arity) {
  // dart2js closures are objects with a separate JavaScript method 'entry
  // point' per arity, `call$1`, `call$2` etc. The entry points have no optional
  // parameters so additional arguments at the call site will be ignored. This
  // lets us simply use `Function.prototype.bind` to pass the closed values that
  // are stored in the closure class object.

  Object? entry;
  switch (arity) {
    case 0:
      entry = JS('', '#[#]', closure, JS_GET_NAME(JsGetName.CALL_PREFIX0));
    case 1:
      entry = JS('', '#[#]', closure, JS_GET_NAME(JsGetName.CALL_PREFIX1));
    case 2:
      entry = JS('', '#[#]', closure, JS_GET_NAME(JsGetName.CALL_PREFIX2));
    case 3:
      entry = JS('', '#[#]', closure, JS_GET_NAME(JsGetName.CALL_PREFIX3));
    case 4:
      entry = JS('', '#[#]', closure, JS_GET_NAME(JsGetName.CALL_PREFIX4));
  }
  if (entry != null) {
    return JS('', '#.bind(#)', entry, closure);
  }

  // The above is an optimization for the following technique.
  //
  // If the entry is missing (or the above fast path is removed) the wrapped
  // closure is a JavaScript function that uses `_invokeClosure` to call the
  // Dart closure. In addition to providing a default wrapping implementation,
  // the following code causes both `closure` and `_invokeClosure` to
  // escape. Escaping both ensures the compiler should connect the escaping
  // `closure` with the call sites in `_invokeClosure`, preventing the entry
  // points of `closure` from being tree-shaken. (dart2js's current analysis is
  // the code enqueuer which is less precise, using only the presence of the
  // call sites in `_invokeClosure` to retain the entry points).

  return JS(
      'var',
      r'''
        (function(closure, arity, invoke) {
          return function(a1, a2, a3, a4) {
            return invoke(closure, arity, a1, a2, a3, a4);
          };
        })(#,#,#)''',
      closure,
      arity,
      DART_CLOSURE_TO_JS(_invokeClosure));
}

/// Superclass for Dart closures.
///
/// All static, tear-off, function declaration and function expression closures
/// extend this class.
abstract final class Closure implements Function {
  /// Global counter to prevent reusing function code objects.
  ///
  /// V8 will share the underlying function code objects when the same string is
  /// passed to "new Function".  Shared function code objects can lead to
  /// sub-optimal performance due to polymorphism, and can be prevented by
  /// ensuring the strings are different, for example, by generating a local
  /// variable with a name dependent on [functionCounter].
  static int functionCounter = 0;

  Closure();

  /// Creates a new closure class for use by implicit getters associated with a
  /// method.
  ///
  /// Called from [closureFromTearOff], which is called from code generated by
  /// the emitter.
  ///
  /// Caution: This function is used to create static tearoffs which, being
  /// constants, may be referred to by other constants. This means that this
  /// code cannot refer to the constant pool since it does not exist.
  /// TODO(ahe): Don't call this function when building constants.
  static fromTearOff(Object? parameters) {
    JS_EFFECT(() {
      // The functions are called here to model the calls from JS forms below.
      // The types in the JS forms in the arguments are propagated in type
      // inference.
      var aBoundClosure = JS('BoundClosure', '0');
      var aString = JS('String', '0');
      BoundClosure.receiverOf(aBoundClosure);
      BoundClosure.interceptorOf(aBoundClosure);
      BoundClosure.evalRecipe(aBoundClosure, aString);
      getType(JS('int', '0'));
    });

    Object? container =
        JS('', '#.#', parameters, TearOffParametersPropertyNames.container);

    bool isStatic =
        JS('', '#.#', parameters, TearOffParametersPropertyNames.isStatic);
    bool isIntercepted =
        JS('', '#.#', parameters, TearOffParametersPropertyNames.isIntercepted);
    bool needsDirectAccess = JS('', '#.#', parameters,
        TearOffParametersPropertyNames.needsDirectAccess);
    int applyTrampolineIndex =
        JS('', '#.#', parameters, TearOffParametersPropertyNames.applyIndex);

    JSArray funsOrNames =
        JS('', '#.#', parameters, TearOffParametersPropertyNames.funsOrNames);
    JSArray callNames =
        JS('', '#.#', parameters, TearOffParametersPropertyNames.callNames);

    // The first function is the primary entry point. It is always a string, the
    // property name of the first function within the container.
    assert(JS('', '#[#]', funsOrNames, 0) is String);
    String name = JS('', '#[#]', funsOrNames, 0);
    String? callName = JS('', '#[#]', callNames, 0);
    Object? function = JS('', '#[#]', container, name);

    // [functionType] is either an index into the types-table, a String type
    // recipe (for types that are dependent on the tear-off class type
    // variables), or a function that can compute an Rti. (The latter is
    // necessary if the type is dependent on generic arguments).
    Object? functionType =
        JS('', '#.#', parameters, TearOffParametersPropertyNames.funType)!;

    // function tmp() {};
    // tmp.prototype = BC.prototype;
    // var proto = new tmp;
    // for each computed prototype property:
    //   proto[property] = ...;
    // proto._init = BC;
    // var dynClosureConstructor =
    //     new Function('self', 'target', 'receiver', 'name',
    //                  'this._init(self, target, receiver, name)');
    // proto.constructor = dynClosureConstructor;
    // dynClosureConstructor.prototype = proto;
    // return dynClosureConstructor;

    // We need to create a new subclass of TearOffClosure, one of StaticClosure
    // or BoundClosure.  For this, we need to create an object whose prototype
    // is the prototype is either StaticClosure.prototype or
    // BoundClosure.prototype, respectively in pseudo JavaScript code. The
    // simplest way to access the JavaScript construction function of a Dart
    // class is to create an instance and access its constructor property.
    // Creating an instance ensures that any lazy class initialization has taken
    // place. The newly created instance could in theory be used directly as the
    // prototype, but it might include additional fields that we don't need.  So
    // we only use the new instance to access the constructor property and use
    // Object.create to create the desired prototype.
    //
    // TODO(sra): Cache the prototype to avoid the allocation.
    var prototype = isStatic
        ? JS('StaticClosure', 'Object.create(#.constructor.prototype)',
            StaticClosure())
        : JS('BoundClosure', 'Object.create(#.constructor.prototype)',
            BoundClosure(null, null));

    JS('', '#.\$initialize = #', prototype, JS('', '#.constructor', prototype));

    // The constructor functions have names to prevent the JavaScript
    // implementation from inventing a name that might have special meaning
    // (e.g. clashing with minified 'Object' or 'Interceptor').
    var constructor = isStatic
        ? JS('', 'function static_tear_off(){this.\$initialize()}')
        : isCsp
            ? JS('', 'function tear_off(a,b) {this.\$initialize(a,b)}')
            : JS(
                '',
                'new Function("a,b" + #,'
                    ' "this.\$initialize(a,b" + # + ")")',
                functionCounter,
                functionCounter++);

    // It is necessary to set the constructor property, otherwise it will be
    // "Object".
    JS('', '#.constructor = #', prototype, constructor);

    JS('', '#.prototype = #', constructor, prototype);

    JS('', '#.# = #', prototype, BoundClosure.nameProperty, name);
    JS('', '#.# = #', prototype, BoundClosure.targetProperty, function);

    // Create a closure and "monkey" patch it with call stubs.
    var trampoline = function;
    if (!isStatic) {
      trampoline =
          forwardCallTo(name, function, isIntercepted, needsDirectAccess);
    } else {
      // TODO(sra): Can this be removed?
      JS('', '#[#] = #', prototype, STATIC_FUNCTION_NAME_PROPERTY_NAME, name);
    }

    var signatureFunction =
        _computeSignatureFunctionNewRti(functionType, isStatic, isIntercepted);

    JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.SIGNATURE_NAME),
        signatureFunction);
    var applyTrampoline = trampoline;
    JS('', '#[#] = #', prototype, callName, trampoline);

    for (int i = 1; i < funsOrNames.length; i++) {
      Object? stub = JS('', '#[#]', funsOrNames, i);

      String stubName = '';
      if (stub is String) {
        stubName = stub;
        stub = JS('', '#[#]', container, stubName);
      }

      Object? stubCallName = JS('', '#[#]', callNames, i);
      // stubCallName can be null if the applyTrampoline has a selector that is
      // otherwise unused, e.g. `foo<T>({bool strange = true})...`
      if (stubCallName != null) {
        if (!isStatic) {
          stub =
              forwardCallTo(stubName, stub, isIntercepted, needsDirectAccess);
        }
        JS('', '#[#] = #', prototype, stubCallName, stub);
      }
      if (i == applyTrampolineIndex) {
        applyTrampoline = stub;
      }
    }

    JS('', '#[#] = #', prototype, JS_GET_NAME(JsGetName.CALL_CATCH_ALL),
        applyTrampoline);

    String reqArgProperty = JS_GET_NAME(JsGetName.REQUIRED_PARAMETER_PROPERTY);
    Object? requiredParameterCount = JS('', '#.#', parameters,
        TearOffParametersPropertyNames.requiredParameterCount);
    JS('', '#.# = #', prototype, reqArgProperty, requiredParameterCount);

    String defValProperty = JS_GET_NAME(JsGetName.DEFAULT_VALUES_PROPERTY);
    Object? optionalParameterDefaultValues = JS('', '#.#', parameters,
        TearOffParametersPropertyNames.optionalParameterDefaultValues);
    JS('', '#.# = #', prototype, defValProperty,
        optionalParameterDefaultValues);

    return constructor;
  }

  static _computeSignatureFunctionNewRti(
      Object functionType, bool isStatic, bool isIntercepted) {
    if (JS('bool', 'typeof # == "number"', functionType)) {
      // Index into types table. Handled in rti.dart.
      return functionType;
    }
    if (JS('bool', 'typeof # == "string"', functionType)) {
      // A recipe to evaluate against the instance type.
      if (isStatic) {
        // TODO(sra): Recipe for static tearoff.
        throw 'Cannot compute signature for static tearoff.';
      }
      final typeEvalMethod = RAW_DART_FUNCTION_REF(BoundClosure.evalRecipe);
      return JS(
          '',
          '    function(recipe, evalOnReceiver) {'
              '  return function() {'
              '    return evalOnReceiver(this, recipe);'
              '  };'
              '}(#,#)',
          functionType,
          typeEvalMethod);
    }
    throw 'Error in functionType of tearoff';
  }

  static cspForwardCall(
      int arity, bool needsDirectAccess, String? stubName, function) {
    var getReceiver = RAW_DART_FUNCTION_REF(BoundClosure.receiverOf);

    // We have the target method (or an arity stub for the method) in
    // [function]. These fixed-arity forwarding stubs could use
    // `Function.prototype.call` on the target directly, but on some browsers it
    // is quite a bit faster to do a property access again to get the
    // function. Accessing the property again will fail (retrieve the wrong
    // function) if the desired property is shadowed. This can happen, e.g.,
    // when the tear-off was created by a super-getter call `super.method` and
    // `method` has an override on some subclass.
    //
    // To handle the shadowing-of-a-method-that-has-a-super-tearoff case, we use
    // the default slow case that uses `Function.prototype.apply`.
    if (needsDirectAccess) arity = -1;

    switch (arity) {
      case 0:
        return JS(
            '',
            'function(entry, receiverOf){'
                'return function(){'
                'return receiverOf(this)[entry]()'
                '}'
                '}(#,#)',
            stubName,
            getReceiver);
      case 1:
        return JS(
            '',
            'function(entry, receiverOf){'
                'return function(a){'
                'return receiverOf(this)[entry](a)'
                '}'
                '}(#,#)',
            stubName,
            getReceiver);
      case 2:
        return JS(
            '',
            'function(entry, receiverOf){'
                'return function(a, b){'
                'return receiverOf(this)[entry](a, b)'
                '}'
                '}(#,#)',
            stubName,
            getReceiver);
      case 3:
        return JS(
            '',
            'function(entry, receiverOf){'
                'return function(a, b, c){'
                'return receiverOf(this)[entry](a, b, c)'
                '}'
                '}(#,#)',
            stubName,
            getReceiver);
      case 4:
        return JS(
            '',
            'function(entry, receiverOf){'
                'return function(a, b, c, d){'
                'return receiverOf(this)[entry](a, b, c, d)'
                '}'
                '}(#,#)',
            stubName,
            getReceiver);
      case 5:
        return JS(
            '',
            'function(entry, receiverOf){'
                'return function(a, b, c, d, e){'
                'return receiverOf(this)[entry](a, b, c, d, e)'
                '}'
                '}(#,#)',
            stubName,
            getReceiver);
      default:
        // Here we use `Function.prototype.apply`.
        return JS(
            '',
            'function(f, receiverOf){'
                'return function(){'
                'return f.apply(receiverOf(this), arguments)'
                '}'
                '}(#,#)',
            function,
            getReceiver);
    }
  }

  static bool get isCsp => JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');

  static forwardCallTo(
      String stubName, function, bool isIntercepted, bool needsDirectAccess) {
    if (isIntercepted)
      return forwardInterceptedCallTo(stubName, function, needsDirectAccess);
    int arity = JS('int', '#.length', function);

    if (isCsp || needsDirectAccess || arity >= 27) {
      return cspForwardCall(arity, needsDirectAccess, stubName, function);
    }

    if (arity == 0) {
      // Incorporate functionCounter into a local.
      String selfName = 'self${functionCounter++}';
      return JS(
          '',
          '(new Function(#))()',
          'return function(){'
              'var $selfName = this.${BoundClosure.receiverFieldName()};'
              'return $selfName.$stubName();'
              '}');
    }
    assert(1 <= arity && arity < 27);
    String arguments = JS('String',
        '"abcdefghijklmnopqrstuvwxyz".split("").splice(0,#).join(",")', arity);
    arguments += '${functionCounter++}';
    return JS(
        '',
        '(new Function(#))()',
        'return function($arguments){'
            'return this.${BoundClosure.receiverFieldName()}.$stubName($arguments);'
            '}');
  }

  static cspForwardInterceptedCall(
      int arity, bool needsDirectAccess, String? stubName, function) {
    var getReceiver = RAW_DART_FUNCTION_REF(BoundClosure.receiverOf);
    var getInterceptor = RAW_DART_FUNCTION_REF(BoundClosure.interceptorOf);
    // Handle intercepted stub-names with the default slow case.
    if (needsDirectAccess) arity = -1;
    switch (arity) {
      case 0:
        // Intercepted functions always takes at least one argument (the
        // receiver).
        throw RuntimeError('Intercepted function with no arguments.');
      case 1:
        return JS(
            '',
            'function(entry, interceptorOf, receiverOf){'
                'return function(){'
                'return interceptorOf(this)[entry](receiverOf(this))'
                '}'
                '}(#,#,#)',
            stubName,
            getInterceptor,
            getReceiver);
      case 2:
        return JS(
            '',
            'function(entry, interceptorOf, receiverOf){'
                'return function(a){'
                'return interceptorOf(this)[entry](receiverOf(this), a)'
                '}'
                '}(#,#,#)',
            stubName,
            getInterceptor,
            getReceiver);
      case 3:
        return JS(
            '',
            'function(entry, interceptorOf, receiverOf){'
                'return function(a, b){'
                'return interceptorOf(this)[entry](receiverOf(this), a, b)'
                '}'
                '}(#,#,#)',
            stubName,
            getInterceptor,
            getReceiver);
      case 4:
        return JS(
            '',
            'function(entry, interceptorOf, receiverOf){'
                'return function(a, b, c){'
                'return interceptorOf(this)[entry](receiverOf(this), a, b, c)'
                '}'
                '}(#,#,#)',
            stubName,
            getInterceptor,
            getReceiver);
      case 5:
        return JS(
            '',
            'function(entry, interceptorOf, receiverOf){'
                'return function(a, b, c, d){'
                'return interceptorOf(this)[entry](receiverOf(this), a, b, c, d)'
                '}'
                '}(#,#,#)',
            stubName,
            getInterceptor,
            getReceiver);
      case 6:
        return JS(
            '',
            'function(entry, interceptorOf, receiverOf){'
                'return function(a, b, c, d, e){'
                'return interceptorOf(this)[entry](receiverOf(this), a, b, c, d, e)'
                '}'
                '}(#,#,#)',
            stubName,
            getInterceptor,
            getReceiver);
      default:
        return JS(
            '',
            'function(f, interceptorOf, receiverOf){'
                'return function(){'
                'var a = [receiverOf(this)];'
                'Array.prototype.push.apply(a, arguments);'
                'return f.apply(interceptorOf(this), a)'
                '}'
                '}(#,#,#)',
            function,
            getInterceptor,
            getReceiver);
    }
  }

  static forwardInterceptedCallTo(
      String stubName, function, bool needsDirectAccess) {
    String interceptorField = BoundClosure.interceptorFieldName();
    String receiverField = BoundClosure.receiverFieldName();
    int arity = JS('int', '#.length', function);
    bool isCsp = JS_GET_FLAG('USE_CONTENT_SECURITY_POLICY');

    if (isCsp || needsDirectAccess || arity >= 28) {
      return cspForwardInterceptedCall(
          arity, needsDirectAccess, stubName, function);
    }
    if (arity == 1) {
      return JS(
          '',
          '(new Function(#))()',
          'return function(){'
              'return this.$interceptorField.$stubName(this.$receiverField);'
              '${functionCounter++}'
              '}');
    }
    assert(1 < arity && arity < 28);
    String arguments = JS(
        'String',
        '"abcdefghijklmnopqrstuvwxyz".split("").splice(0,#).join(",")',
        arity - 1);
    return JS(
        '',
        '(new Function(#))()',
        'return function($arguments){'
            'return this.$interceptorField.$stubName(this.$receiverField, $arguments);'
            '${functionCounter++}'
            '}');
  }

  // The backend adds a special getter of the form
  //
  // Closure get call => this;
  //
  // to allow tearing off a closure from itself. We do this magically in the
  // backend rather than simply adding it here, as we do not want this getter
  // to be visible to resolution and the generation of extra stubs.

  String toString() {
    String? name;
    var constructor = JS('', '#.constructor', this);
    name =
        constructor == null ? null : JS('String|Null', '#.name', constructor);
    if (name == null) name = 'unknown';
    return "Closure '${unminifyOrTag(name)}'";
  }

  Type get runtimeType => newRti.getRuntimeTypeOfClosure(this);
}

/// This is called by the fragment emitter.
// TODO(sra): The fragment emitter could call `Closure.fromTearOff` directly.
closureFromTearOff(parameters) {
  return Closure.fromTearOff(parameters);
}

/// Base class for closures with no arguments.
abstract final class Closure0Args extends Closure {}

/// Base class for closures with two positional arguments.
abstract final class Closure2Args extends Closure {}

/// Represents an implicit closure of a function.
abstract final class TearOffClosure extends Closure {}

final class StaticClosure extends TearOffClosure {
  String toString() {
    String? name =
        JS('String|Null', '#[#]', this, STATIC_FUNCTION_NAME_PROPERTY_NAME);
    if (name == null) return 'Closure of unknown static method';
    return "Closure '${unminifyOrTag(name)}'";
  }
}

/// Represents a 'tear-off' or property extraction closure of an instance
/// method, that is an instance method bound to a specific receiver (instance).
///
/// This is a base class that is extended to create a separate closure class for
/// each instance method. The subclass is created at run time.
final class BoundClosure extends TearOffClosure {
  /// The Dart receiver.
  final _receiver;

  /// The JavaScript receiver when using the interceptor calling convention.
  final _interceptor;

  /// The [_name] and [_target] of the bound closure are stored in the prototype
  /// of the closure class (i.e. the subclass of BoundClosure).
  static const nameProperty = r'$_name';
  static const targetProperty = r'$_target';

  /// The name of the function. Only used by `toString()`.
  String get _name => JS('', '#.#', this, nameProperty);

  /// The primary entry point for the instance method, used by `==`/`hashCode`.
  Object get _target => JS('', '#.#', this, targetProperty);

  BoundClosure(this._receiver, this._interceptor);

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (other is! BoundClosure) return false;
    return JS('bool', '# === #', _target, other._target) &&
        JS('bool', '# === #', _receiver, other._receiver);
  }

  @override
  int get hashCode {
    int receiverHashCode = objectHashCode(_receiver);
    return receiverHashCode ^ Primitives.objectHashCode(_target);
  }

  @override
  String toString() {
    // TODO(sra): When minified, mark [_name] with a tag,
    // e.g. 'minified-property:' so that it can be unminified.
    return "Closure '$_name' of "
        "${Primitives.objectToHumanReadableString(_receiver)}";
  }

  @pragma('dart2js:parameter:trust')
  static evalRecipe(BoundClosure closure, String recipe) {
    return newRti.evalInInstance(closure._receiver, recipe);
  }

  @pragma('dart2js:noInline')
  @pragma('dart2js:parameter:trust')
  static receiverOf(BoundClosure closure) => closure._receiver;

  @pragma('dart2js:noInline')
  @pragma('dart2js:parameter:trust')
  static interceptorOf(BoundClosure closure) => closure._interceptor;

  static String? _receiverFieldNameCache;
  static String receiverFieldName() =>
      _receiverFieldNameCache ??= _computeFieldNamed('receiver');

  static String? _interceptorFieldNameCache;
  static String interceptorFieldName() =>
      _interceptorFieldNameCache ??= _computeFieldNamed('interceptor');

  @pragma('dart2js:noInline')
  @pragma('dart2js:noSideEffects')
  static String _computeFieldNamed(String fieldName) {
    var template = BoundClosure('receiver', 'interceptor');
    var names = JSArray.markFixedList(
        JS('', 'Object.getOwnPropertyNames(#)', template));
    for (int i = 0; i < names.length; i++) {
      var name = names[i];
      if (JS('bool', '#[#] === #', template, name, fieldName)) {
        return JS('String', '#', name);
      }
    }
    throw ArgumentError("Field name $fieldName not found.");
  }
}

bool jsHasOwnProperty(var jsObject, String property) {
  return JS('bool', r'#.hasOwnProperty(#)', jsObject, property);
}

jsPropertyAccess(var jsObject, String property) {
  return JS('var', r'#[#]', jsObject, property);
}

/// A metadata annotation describing the types instantiated by a native element.
///
/// The annotation is valid on a native method and a field of a native class.
///
/// By default, a field of a native class is seen as an instantiation point for
/// all native classes that are a subtype of the field's type, and a native
/// method is seen as an instantiation point fo all native classes that are a
/// subtype of the method's return type, or the argument types of the declared
/// type of the method's callback parameter.
///
/// An @[Creates] annotation overrides the default set of instantiated types.
/// If one or more @[Creates] annotations are present, the type of the native
/// element is ignored, and the union of @[Creates] annotations is used instead.
/// The names in the strings are resolved and the program will fail to compile
/// with dart2js if they do not name types.
///
/// The argument to [Creates] is a string.  The string is parsed as the names of
/// one or more types, separated by vertical bars `|`.  There are some special
/// names:
///
/// * `=Object`. This means 'exactly Object', which is a plain JavaScript object
///   with properties and none of the subtypes of Object.
///
/// Example: we may know that a method always returns a specific implementation:
///
///     @Creates('_NodeList')
///     List<Node> getElementsByTagName(String tag) native;
///
/// Useful trick: A method can be marked as not instantiating any native classes
/// with the annotation `@Creates('Null')`.  This is useful for fields on native
/// classes that are used only in Dart code.
///
///     @Creates('Null')
///     var _cachedFoo;
class Creates {
  final String types;
  const Creates(this.types);
}

/// A metadata annotation describing the types returned or yielded by a native
/// element.
///
/// The annotation is valid on a native method and a field of a native class.
///
/// By default, a native method or field is seen as returning or yielding all
/// subtypes if the method return type or field type.  This annotation allows a
/// more precise set of types to be specified.
///
/// See [Creates] for the syntax of the argument.
///
/// Example: IndexedDB keys are numbers, strings and JavaScript Arrays of keys.
///
///     @Returns('String|num|JSExtendableArray')
///     dynamic key;
///
///     // Equivalent:
///     @Returns('String') @Returns('num') @Returns('JSExtendableArray')
///     dynamic key;
class Returns {
  final String types;
  const Returns(this.types);
}

/// A metadata annotation placed on native methods and fields of native classes
/// to specify the JavaScript name.
///
/// This example declares a Dart field + getter + setter called `$dom_title`
/// that corresponds to the JavaScript property `title`.
///
///     class Document native "*Foo" {
///       @JSName('title')
///       String $dom_title;
///     }
class JSName {
  final String name;
  const JSName(this.name);
}

/// The following methods are called by the runtime to implement checked mode
/// and casts. We specialize each primitive type (eg int, bool), and use the
/// compiler's convention to do is-checks on regular objects.
bool boolConversionCheck(value) {
  // The value from kernel should always be true, false, or null.
  if (value == null) assertThrow('boolean expression must not be null');
  return JS('bool', '#', value);
}

@pragma('dart2js:noInline')
void checkDeferredIsLoaded(String loadId) {
  if (!_loadedLibraries.contains(loadId)) {
    throw DeferredNotLoadedError(loadId);
  }
}

/// Special interface recognized by the compiler and implemented by DOM
/// objects that support integer indexing. This interface is not
/// visible to anyone, and is only injected into special libraries.
abstract class JavaScriptIndexingBehavior<E> extends JSMutableIndexable<E> {}

/// Helper function for implementing asserts. The compiler treats this
/// specially.
///
/// Returns the negation of the condition. That is: `true` if the assert should
/// fail.
bool assertTest(condition) {
  if (true == condition) return false;
  if (false == condition) return true;
  bool checked = condition as bool;
  if (null == condition) {
    newRti.throwTypeError('assert condition must not be null');
  }
  return !checked;
}

/// Helper function for implementing asserts with messages.
/// The compiler treats this specially.
void assertThrow(Object message) {
  throw _AssertionError(message);
}

/// Helper function for implementing asserts without messages.
/// The compiler treats this specially.
@pragma('dart2js:noInline')
void assertHelper(condition) {
  if (assertTest(condition)) throw AssertionError();
}

/// Called by generated code when a static field's initializer references the
/// field that is currently being initialized.
void throwCyclicInit(String staticName) {
  throw _CyclicInitializationError(staticName);
}

/// Error thrown when a lazily initialized variable cannot be initialized.
///
/// Cyclic dependencies are no longer detected at runtime in null safe code.
/// Such code will fail in other ways instead,
/// possibly with a [StackOverflowError].
///
/// Will be removed when support for non-null-safe code is discontinued.
@Deprecated("Remove when no longer supporting non-null-safe code.")
class _CyclicInitializationError extends Error {
  final String? variableName;
  _CyclicInitializationError([this.variableName]);
  String toString() {
    var variableName = this.variableName;
    return variableName == null
        ? "Reading static variable during its initialization"
        : "Reading static variable '$variableName' during its initialization";
  }
}

/// Error thrown when a runtime error occurs.
class RuntimeError extends Error {
  final message;
  RuntimeError(this.message);
  String toString() => 'RuntimeError: $message';
}

class DeferredNotLoadedError extends Error implements NoSuchMethodError {
  String libraryName;

  DeferredNotLoadedError(this.libraryName);

  String toString() {
    return 'Deferred library $libraryName was not loaded.';
  }
}

// TODO(ahe): Remove this class and call noSuchMethod instead.
class UnimplementedNoSuchMethodError extends Error
    implements NoSuchMethodError {
  final String _message;

  UnimplementedNoSuchMethodError(this._message);

  String toString() => 'Unsupported operation: $_message';
}

/// Creates a random number with 64 bits of randomness.
///
/// This will be truncated to the 53 bits available in a double.
int random64() {
  // TODO(lrn): Use a secure random source.
  int int32a = JS('int', '(Math.random() * 0x100000000) >>> 0');
  int int32b = JS('int', '(Math.random() * 0x100000000) >>> 0');
  return int32a + int32b * 0x100000000;
}

String jsonEncodeNative(String string) {
  return JS('String', 'JSON.stringify(#)', string);
}

/// Returns a property name for placing data on JavaScript objects shared
/// between DOM isolates.  This happens when multiple programs are loaded in the
/// same JavaScript context (i.e. page).  The name is based on [name] but with
/// an additional part that is unique for each isolate.
///
/// The form of the name is '___dart_$name_$id'.
String getIsolateAffinityTag(String name) {
  var isolateTagGetter = JS_EMBEDDED_GLOBAL('', GET_ISOLATE_TAG);
  return JS('String', '#(#)', isolateTagGetter, name);
}

final Map<String, Completer<Null>?> _loadingLibraries = {};
final Set<String> _loadedLibraries = {};

typedef DeferredLoadCallback = void Function();

// Function that will be called every time a new deferred import is loaded.
DeferredLoadCallback? deferredLoadHook;

/// Add events to global initialization event log.
void _addEvent(
    {required String part,
    required String event,
    String? loadId,
    String? hash}) {
  var initializationEventLog = JS_EMBEDDED_GLOBAL('', INITIALIZATION_EVENT_LOG);
  var dataObj = JS('=Object', '{p: #, e: #}', part, event);
  if (hash != null) JS('', '#.h = #', dataObj, hash);
  if (loadId != null) JS('', '#.l = #', dataObj, loadId);
  JS('', '#.s = #', dataObj, thisScript);
  JS('', '#.push(#)', initializationEventLog, dataObj);
}

/// Returns the event log as a string where each line is a JSON format event.
///
/// The events are printed in reverse chronological order in case the tail gets
/// truncated, the newest events are retained.
String _getEventLog() {
  var initializationEventLog = JS_EMBEDDED_GLOBAL('', INITIALIZATION_EVENT_LOG);
  final o = JS('', 'Array.from(#).reverse()', initializationEventLog);
  JS(
      '',
      '#.reduce((p, e, i, a) => {e.i = a.length - i; '
          'if (p == null) return e.s; '
          'if (e.s == null) return p; '
          'if (e.s === p) { delete e.s; return p; }'
          'return e.s;}'
          ', null)',
      o);
  return JS('String', '#.map((e) => JSON.stringify(e)).join("\\n")', o);
}

/// Loads a deferred library. The compiler generates a call to this method to
/// implement `import.loadLibrary()`. The [priority] argument is the index of
/// one of the [LoadLibraryPriority] enum's members.
///
///   - `0` for `LoadLibraryPriority.normal`
///   - `1` for `LoadLibraryPriority.high`
@pragma('dart2js:resource-identifier')
Future<Null> loadDeferredLibrary(String loadId, int priority) {
  // Validate the priority using the index to allow the actual enum to get
  // tree-shaken.
  if (priority < 0 || priority >= LoadLibraryPriority.values.length) {
    throw DeferredLoadException('Invalid library priority: $priority');
  }

  // For each loadId there is a list of parts to load. The parts are represented
  // by an index. There are two arrays, one that maps the index into a Uri and
  // another that maps the index to a hash.
  var partsMap = JS_EMBEDDED_GLOBAL('', DEFERRED_LIBRARY_PARTS);
  List? indexes = JS('JSExtendableArray|Null', '#[#]', partsMap, loadId);
  if (indexes == null) return Future.value(null);
  List<String> uris = <String>[];
  List<String> hashes = <String>[];
  List index2uri = JS_EMBEDDED_GLOBAL('JSArray', DEFERRED_PART_URIS);
  List index2hash = JS_EMBEDDED_GLOBAL('JSArray', DEFERRED_PART_HASHES);
  for (int i = 0; i < indexes.length; i++) {
    int index = JS('int', '#[#]', indexes, i);
    uris.add(JS('String', '#[#]', index2uri, index));
    hashes.add(JS('String', '#[#]', index2hash, index));
  }

  int total = hashes.length;
  assert(total == uris.length);
  List<bool> waitingForLoad = List.filled(total, true);
  int nextHunkToInitialize = 0;
  var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED);
  var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED);
  var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK);

  void initializeSomeLoadedHunks() {
    for (int i = nextHunkToInitialize; i < total; ++i) {
      // A hunk is initialized only if all the preceding hunks have been
      // initialized.
      if (waitingForLoad[i]) return;
      nextHunkToInitialize++;

      // It is possible for a hash to be repeated. This happens when two
      // different parts both end up empty. Checking in the loop rather than
      // pre-filtering prevents duplicate hashes leading to duplicated
      // initializations.
      // TODO(29572): Merge small parts.
      // TODO(29635): Remove duplicate parts from tables and output files.
      var uri = uris[i];
      var hash = hashes[i];
      if (JS('bool', '#(#)', isHunkInitialized, hash)) {
        _addEvent(
            part: uri, hash: hash, event: 'alreadyInitialized', loadId: loadId);
        continue;
      }
      // This check is just an extra precaution, `isHunkLoaded(hash)` should
      // always be true at this point. `_loadHunk` does this check and throws
      // for any part that failed to load.
      if (JS('bool', '#(#)', isHunkLoaded, hash)) {
        _addEvent(part: uri, hash: hash, event: 'initialize', loadId: loadId);
        JS('void', '#(#)', initializer, hash);
      } else {
        _addEvent(part: uri, hash: hash, event: 'missing', loadId: loadId);

        throw DeferredLoadException("Loading ${uris[i]} failed: "
            "the code with hash '${hash}' was not loaded.\n"
            "event log:\n${_getEventLog()}\n");
      }
    }
  }

  void finalizeLoad() {
    initializeSomeLoadedHunks();
    // At this point all hunks have been loaded, so there should be no pending
    // initializations to do.
    assert(nextHunkToInitialize == total);
    bool updated = _loadedLibraries.add(loadId);
    if (updated && deferredLoadHook != null) {
      deferredLoadHook!();
    }
  }

  var deferredLibraryMultiLoader =
      JS('', 'self.dartDeferredLibraryMultiLoader');

  if (JS('bool', 'typeof # === "function"', deferredLibraryMultiLoader)) {
    return _loadAllHunks(
            deferredLibraryMultiLoader, uris, hashes, loadId, priority, 0)
        .then((_) {
      waitingForLoad = List.filled(total, false);
      finalizeLoad();
    });
  }

  Future loadAndInitialize(int i) {
    final hash = hashes[i];
    if (JS('bool', '#(#)', isHunkLoaded, hash)) {
      waitingForLoad[i] = false;
      return Future.value();
    }
    return _loadHunk(uris[i], loadId, priority, hash, 0).then((Null _) {
      waitingForLoad[i] = false;
      initializeSomeLoadedHunks();
    });
  }

  return Future.wait(List.generate(total, loadAndInitialize)).then((_) {
    finalizeLoad();
  });
}

/// The `nonce` value on the current script used for strict-CSP, if any.
String? _cspNonce = _computeCspNonce();

String? _computeCspNonce() {
  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
  if (currentScript == null) return null;
  String? nonce = JS('String|Null', '#.nonce', currentScript);
  return (nonce != null && nonce != '')
      ? nonce
      : JS('String|Null', '#.getAttribute("nonce")', currentScript);
}

/// The 'crossOrigin' value on the current script used for CORS, if any.
String? _crossOrigin = _computeCrossOrigin();

String? _computeCrossOrigin() {
  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
  if (currentScript == null) return null;
  return JS('String|Null', '#.crossOrigin', currentScript);
}

/// Returns true if we are currently in a worker context.
bool _isWorker() {
  requiresPreamble();
  return JS('', '!self.window && !!self.postMessage');
}

/// The src URL for the script tag that loaded this code.
final String? thisScript = _computeThisScript();

/// Base URL of `thisScript`.
final String _thisScriptBaseUrl = _computeBaseUrl();

String _computeBaseUrl() {
  String script = thisScript!;
  return JS('', '#.substring(0, #.lastIndexOf("/") + 1)', script, script);
}

/// Trusted Type policy [1] for generating validated URLs for scripts for
/// deferred loading. Only the `createScriptURL` member of this policy is used.
///
/// [1]: https://w3c.github.io/webappsec-trusted-types/dist/spec/#trusted-type-policy
final Object _deferredLoadingTrustedTypesPolicy = _computePolicy();

const _deferredLoadingTrustedTypesPolicyName = 'dart:deferred-loading';

Object _computePolicy() {
  // There is no actual validation, since the URLs for deferred loading are safe
  // by construction (see [_getBasedScriptUrl].  If the URL was validated, the
  // validation would ensure it is based off the main script.
  final Object policyOptions = JS('=Object', '{createScriptURL: (url) => url}');

  // For our purposes, the policyOptions duck-types to an object with a single
  // method of the policy, so we use the options as a policy polyfill.
  final fallbackPolicy = policyOptions;

  final Object? policyFactory = JS('', 'self.trustedTypes');
  if (policyFactory == null) return fallbackPolicy;
  final Object? newPolicy = JS('', '#.createPolicy(#, #)', policyFactory,
      _deferredLoadingTrustedTypesPolicyName, policyOptions);
  return newPolicy ?? fallbackPolicy;
}

/// A TrustedScriptURL for the component that is alongside the main script of
/// this program. On browsers or environments that do not support
/// TrustedScriptURL, a String is returned instead.
///
/// Changes to this method require a careful review to ensure that the URLs
/// remain safe by construction.
///
/// The component is encoded to prevent any directory 'navigation'. If deferred
/// loading is changed to use a more structured layout with subdirectories, this
/// method will need to be updated to make the URL still clearly safe by
/// construction.
Object _getBasedScriptUrl(String component, String suffix) {
  final base = _thisScriptBaseUrl;
  final encodedComponent = _encodeURIComponent(component);
  final url = '$base$encodedComponent$suffix';
  final policy = _deferredLoadingTrustedTypesPolicy;
  return JS('', '#.createScriptURL(#)', policy, url);
}

Object getBasedScriptUrlForTesting(String component) =>
    _getBasedScriptUrl(component, '');

String _encodeURIComponent(String component) {
  return JS('', 'self.encodeURIComponent(#)', component);
}

/// The src url for the script tag that loaded this function.
///
/// Used to create JavaScript workers and load deferred libraries.
String? _computeThisScript() {
  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
  if (currentScript != null) {
    return JS('String', 'String(#.src)', currentScript);
  }
  // A worker has no script tag - so get an url from a stack-trace.
  if (_isWorker()) return _computeThisScriptFromTrace();
  // An isolate that doesn't support workers, but doesn't have a
  // currentScript either. This is most likely a Chrome extension.
  return null;
}

String _computeThisScriptFromTrace() {
  var stack = JS('String|Null', 'new Error().stack');
  if (stack == null) {
    // According to Internet Explorer documentation, the stack
    // property is not set until the exception is thrown. The stack
    // property was not provided until IE10.
    stack = JS(
        'String|Null',
        '(function() {'
            'try { throw new Error() } catch(e) { return e.stack }'
            '})()');
    if (stack == null) throw UnsupportedError('No stack trace');
  }
  var pattern, matches;

  // This pattern matches V8, Chrome, and Internet Explorer stack
  // traces that look like this:
  // Error
  //     at methodName (URI:LINE:COLUMN)
  pattern = JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');

  matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
  if (matches != null) return JS('String', '#[1]', matches);

  // This pattern matches Firefox stack traces that look like this:
  // methodName@URI:LINE
  pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")');

  matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
  if (matches != null) return JS('String', '#[1]', matches);

  throw UnsupportedError('Cannot extract URI from "$stack"');
}

Future _loadAllHunks(Object loader, List<String> hunkNames, List<String> hashes,
    String loadId, int priority, int retryCount) {
  const int maxRetries = 3;
  var initializationEventLog = JS_EMBEDDED_GLOBAL('', INITIALIZATION_EVENT_LOG);
  var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED);

  _addEvent(part: hunkNames.join(';'), event: 'startLoad', loadId: loadId);

  List<String> hunksToLoad = [];
  List<String> urisToLoad = [];
  List<String> hashesToLoad = [];
  List<Future> pendingLoads = [];
  for (int i = 0; i < hunkNames.length; ++i) {
    final hunkName = hunkNames[i];
    final hash = hashes[i];
    if (JS('bool', '!#(#)', isHunkLoaded, hash)) {
      final completerForHunk = _loadingLibraries[hunkName];
      if (completerForHunk != null) {
        pendingLoads.add(completerForHunk.future);
        _addEvent(part: hunkName, event: 'reuse', loadId: loadId);
      } else {
        hunksToLoad.add(hunkName);
        hashesToLoad.add(hash);
        Object trustedScriptUri = _getBasedScriptUrl(hunkName, '');
        // [trustedScriptUri] is either a String, in which case `toString()` is
        // an identity function, or it is a TrustedScriptURL and `toString()`
        // returns the sanitized URL.
        urisToLoad.add(JS('', '#.toString()', trustedScriptUri));
      }
    }
  }

  if (hunksToLoad.isEmpty) {
    return Future.wait(pendingLoads);
  }

  final loadedHunksString = hunksToLoad.join(';');

  Completer<Null> completer = Completer();

  hunksToLoad.forEach((hunkName) => _loadingLibraries[hunkName] = completer);
  _addEvent(part: loadedHunksString, event: 'downloadMulti', loadId: loadId);

  void failure(error, String context, StackTrace? stackTrace,
      List<String>? hunksToRetry, List<String>? hashesToRetry) {
    if (retryCount < maxRetries && hunksToRetry != null) {
      _addEvent(
          part: hunksToRetry.join(';'),
          event: 'retry$retryCount',
          loadId: loadId);
      for (var i = 0; i < hunksToRetry.length; i++) {
        _loadingLibraries[hunksToRetry[i]] = null;
      }
      _loadAllHunks(loader, hunksToRetry!, hashesToRetry!, loadId, priority,
              retryCount + 1)
          .then((_) => completer.complete(null),
              onError: completer.completeError);
    } else {
      _addEvent(
          part: loadedHunksString, event: 'downloadFailure', loadId: loadId);
      hunksToLoad.forEach((hunkName) => _loadingLibraries[hunkName] = null);
      stackTrace ??= StackTrace.current;
      completer.completeError(
          DeferredLoadException('Loading $loadedHunksString failed: $error\n'
              'Context: $context\n'
              'event log:\n${_getEventLog()}\n'),
          stackTrace);
    }
  }

  void success() {
    List<String> hunksToRetry = [];
    List<String> hashesToRetry = [];
    for (int i = 0; i < hashesToLoad.length; i++) {
      bool isLoaded = JS('bool', '#(#)', isHunkLoaded, hashesToLoad[i]);
      if (!isLoaded) {
        hunksToRetry.add(hunksToLoad[i]);
        hashesToRetry.add(hashesToLoad[i]);
      }
    }
    if (hunksToRetry.isEmpty) {
      _addEvent(
          part: loadedHunksString, event: 'downloadSuccess', loadId: loadId);
      completer.complete(null);
    } else {
      failure(
        'Success callback invoked but parts ${hunksToRetry.join(';')} not '
            'loaded.',
        '',
        null,
        hunksToRetry,
        hashesToRetry,
      );
    }
  }

  var jsSuccess = convertDartClosureToJS(success, 0);
  var jsFailure = convertDartClosureToJS((error) {
    failure(
      unwrapException(error),
      'js-failure-wrapper',
      getTraceFromException(error),
      hunksToLoad,
      hashesToLoad,
    );
  }, 1);

  try {
    JS('void', '#(#, #, #, #, #)', loader, urisToLoad, jsSuccess, jsFailure,
        loadId, priority);
  } catch (error, stackTrace) {
    failure(error, "invoking dartDeferredLibraryMultiLoader hook", stackTrace,
        hunksToLoad, hashesToLoad);
  }

  return Future.wait([...pendingLoads, completer.future]);
}

Future<Null> _loadHunk(
    String hunkName, String loadId, int priority, String hash, int retryCount) {
  const int maxRetries = 3;
  var initializationEventLog = JS_EMBEDDED_GLOBAL('', INITIALIZATION_EVENT_LOG);

  var completer = _loadingLibraries[hunkName];
  _addEvent(part: hunkName, event: 'startLoad', loadId: loadId);
  if (completer != null && retryCount == 0) {
    _addEvent(part: hunkName, event: 'reuse', loadId: loadId);
    return completer.future;
  }
  completer ??= _loadingLibraries[hunkName] = Completer();

  Object trustedScriptUri = _getBasedScriptUrl(
      hunkName, retryCount > 0 ? '?dart2jsRetry=$retryCount' : '');
  // [trustedScriptUri] is either a String, in which case `toString()` is an
  // identity function, or it is a TrustedScriptURL and `toString()` returns the
  // sanitized URL.
  String uriAsString = JS('', '#.toString()', trustedScriptUri);

  _addEvent(part: hunkName, event: 'download', loadId: loadId);

  var deferredLibraryLoader = JS('', 'self.dartDeferredLibraryLoader');

  void failure(error, String context, StackTrace? stackTrace) {
    if (retryCount < maxRetries) {
      _addEvent(part: hunkName, event: 'retry$retryCount', loadId: loadId);
      _loadHunk(hunkName, loadId, priority, hash, retryCount + 1);
    } else {
      _addEvent(part: hunkName, event: 'downloadFailure', loadId: loadId);
      _loadingLibraries[hunkName] = null;
      stackTrace ??= StackTrace.current;
      completer!.completeError(
          DeferredLoadException('Loading $uriAsString failed: $error\n'
              'Context: $context\n'
              'event log:\n${_getEventLog()}\n'),
          stackTrace);
    }
  }

  void success() {
    var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED);

    if (JS('bool', '#(#)', isHunkLoaded, hash)) {
      _addEvent(part: hunkName, event: 'downloadSuccess', loadId: loadId);
      completer!.complete(null);
    } else {
      failure(
          'Success callback invoked but part $hunkName not loaded.', '', null);
    }
  }

  var jsSuccess = convertDartClosureToJS(success, 0);
  var jsFailure = convertDartClosureToJS((error) {
    failure(unwrapException(error), 'js-failure-wrapper',
        getTraceFromException(error));
  }, 1);

  if (JS('bool', 'typeof # === "function"', deferredLibraryLoader)) {
    try {
      // Share the loadId that hunk belongs to, this will allow for any
      // additional loadId based bundling optimizations.
      JS('void', '#(#, #, #, #, #)', deferredLibraryLoader, uriAsString,
          jsSuccess, jsFailure, loadId, priority);
    } catch (error, stackTrace) {
      failure(error, "invoking dartDeferredLibraryLoader hook", stackTrace);
    }
  } else if (_isWorker()) {
    // We are in a web worker. Load the code with an XMLHttpRequest.
    var xhr = JS('var', 'new XMLHttpRequest()');
    JS('void', '#.open("GET", #)', xhr, uriAsString);
    JS(
        'void',
        '#.addEventListener("load", #, false)',
        xhr,
        convertDartClosureToJS((event) {
          int status = JS('int', '#.status', xhr);
          if (status != 200) {
            failure('Request status: $status', 'worker xhr', null);
          }
          String code = JS('String', '#.responseText', xhr);
          try {
            // Create a new function to avoid getting access to current function
            // context.
            JS('void', '(new Function(#))()', code);
            success();
          } catch (error, stackTrace) {
            failure(error, 'evaluating the code in worker xhr', stackTrace);
          }
        }, 1));

    JS('void', '#.addEventListener("error", #, false)', xhr, (e) {
      failure(e, 'xhr error handler', null);
    });
    JS('void', '#.addEventListener("abort", #, false)', xhr, (e) {
      failure(e, 'xhr abort handler', null);
    });
    JS('void', '#.send()', xhr);
  } else {
    // We are in a dom-context.
    // Inject a script tag.
    var script = JS('', 'document.createElement("script")');
    JS('', '#.type = "text/javascript"', script);
    JS('', '#.src = #', script, trustedScriptUri);
    if (_cspNonce != null && _cspNonce != '') {
      JS('', '#.nonce = #', script, _cspNonce);
      JS('', '#.setAttribute("nonce", #)', script, _cspNonce);
    }
    if (_crossOrigin != null && _crossOrigin != '') {
      JS('', '#.crossOrigin = #', script, _crossOrigin);
    }
    if (priority == LoadLibraryPriority.high.index) {
      JS('', '#.fetchPriority = "high"', script);
    }
    JS('', '#.addEventListener("load", #, false)', script, jsSuccess);
    JS('', '#.addEventListener("error", #, false)', script, jsFailure);
    JS('', 'document.body.appendChild(#)', script);
  }
  return completer.future;
}

/// Converts a raw JavaScript array into a `List<String>`.
/// Called from generated code.
List<String> convertMainArgumentList(Object? args) {
  List<String> result = [];
  if (args == null) return result;
  if (args is JSArray) {
    for (int i = 0; i < args.length; i++) {
      JS('', '#.push(String(#[#]))', result, args, i);
    }
    return result;
  }
  // Single non-Array element. Convert to a String.
  JS('', '#.push(String(#))', result, args);
  return result;
}

class _AssertionError extends AssertionError {
  _AssertionError(Object message) : super(message);

  String toString() => "Assertion failed: " + Error.safeToString(message);
}

// [_UnreachableError] is a separate class because we always resolve
// [assertUnreachable] and want to reduce the impact of resolving possibly
// unneeded code.
class _UnreachableError extends AssertionError {
  _UnreachableError();
  String toString() => 'Assertion failed: Reached dead code';
}

@pragma('dart2js:noInline')
Never assertUnreachable() {
  throw _UnreachableError();
}

// Hook to register new global object if necessary.
// This is currently a no-op in dart2js.
void registerGlobalObject(object) {}

// Hook to register new browser classes in dartdevc.
// This is currently a no-op in dart2js.
void applyExtension(name, nativeObject) {}

// Hook to upgrade user native-type classes in dartdevc.
// This is currently a no-op in dart2js, but used for native tests.
void applyTestExtensions(List<String> names) {}

// See tests/web/platform_environment_variable1_test.dart
const String testPlatformEnvironmentVariableValue = String.fromEnvironment(
    'dart2js.test.platform.environment.variable',
    defaultValue: 'not-specified');

String testingGetPlatformEnvironmentVariable() {
  return testPlatformEnvironmentVariableValue;
}

// These are used to indicate that a named parameter is required when lazily
// retrieving default values via [JsGetName.DEFAULT_VALUES_PROPERTY].
class _Required {
  const _Required();
}

const kRequiredSentinel = _Required();
bool isRequired(Object? value) => identical(kRequiredSentinel, value);

/// Checks that [f] is a function that supports interop.
@pragma('dart2js:tryInline')
bool isJSFunction(Function f) => JS('bool', 'typeof(#) == "function"', f);

/// Asserts that if [value] is a function, it is a JavaScript function or has
/// been wrapped by [allowInterop].
///
/// This function does not recurse if [value] is a collection.
void assertInterop(Object? value) {
  assert(value is! Function || isJSFunction(value),
      'Dart function requires `allowInterop` to be passed to JavaScript.');
}

/// Like [assertInterop], except iterates over a list of arguments
/// non-recursively.
///
/// This function intentionally avoids using [assertInterop] so that this
/// function can become a no-op if assertions are disabled.
void assertInteropArgs(List<Object?> args) {
  assert(args.every((arg) => arg is! Function || isJSFunction(arg)),
      'Dart function requires `allowInterop` to be passed to JavaScript.');
}

Object? rawStartupMetrics() {
  return JS('JSArray', '#.a', JS_EMBEDDED_GLOBAL('', STARTUP_METRICS));
}

Object? rawRuntimeMetrics() {
  return JS('', '#', JS_EMBEDDED_GLOBAL('', RUNTIME_METRICS));
}

/// Wraps the given [callback] within the current Zone.
void Function(T)? wrapZoneUnaryCallback<T>(void Function(T)? callback) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.root) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallbackGuarded(callback);
}

/// A marker interface for classes with 'trustworthy' implementations of `get
/// runtimeType`.
///
/// Generally, overrides of `get runtimeType` are not used in displaying the
/// types of irritants in TypeErrors or computing the structural `runtimeType`
/// of records. Instead the Rti (aka 'true') type is used.
///
/// The 'true' type is sometimes confusing because it shows implementation
/// details, e.g. the true type of `42` is `JSInt` and `2.1` is `JSNumNotInt`.
///
/// For a limited number of implementation classes we tell a 'white lie' that
/// the value is of another type, e.g. that `42` is an `int` and `2.1` is
/// `double`. This is achieved by overriding `get runtimeType` to return the
/// desired type, and marking the implementation class type with `implements
/// [TrustedGetRuntimeType]`.
///
/// [TrustedGetRuntimeType] is not exposed outside the `dart:` libraries so
/// users cannot tell lies.
///
/// The `Type` returned by a trusted `get runtimeType` must be an instance of
/// the system `Type`, which is guaranteed by using a type literal. Type
/// literals can be generic and dependent on type variables, e.g. `List<E>`.
///
/// Care needs to taken to ensure that the runtime does not get caught telling
/// lies. Generally, a class's `runtimeType` lies by returning an abstract
/// supertype of the class.  Since both the the marker interface and `get
/// runtimeType` are inherited, there should be no way in which a user can
/// extend the class or implement interface of the class.
// TODO(48585): Move this class back to the dart:_rti library when old DDC
// runtime type system has been removed.
abstract class TrustedGetRuntimeType {}

/// The global context that "static interop" members use for namespaces.
///
/// For example, an interop library with no library-level `@JS` annotation and a
/// top-level external member named or renamed to 'foo' will lower a call to
/// that member as `<staticInteropGlobalContext>.foo`. The same applies for any
/// external constructors or class/extension type static members.
///
/// If the library does have a `@JS` annotation with a value, the call then gets
/// lowered to `<staticInteropGlobalContext>.<libraryJSAnnotationValue>.foo`.
///
/// To see which members get lowered with this, see the transformation in
/// `pkg/_js_interop_checks/lib/src/js_util_optimizer.dart`.
///
/// This should match the global context that non-static interop members use.
Object get staticInteropGlobalContext =>
    JS('creates:;returns:Object;depends:none;effects:none;gvn:true', 'self');

/// Return a fresh object literal.
T createObjectLiteral<T>() => JS('PlainJavaScriptObject', '{}');
