// ignore_for_file: always_specify_types
// ignore_for_file: camel_case_types
// ignore_for_file: non_constant_identifier_names

// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint
import 'dart:ffi' as ffi;

/// Bindings for `src/pocketpy.h`.
///
/// Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
///
class PocketpyBindings {
  /// Holds the symbol lookup function.
  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
      _lookup;

  /// The symbols are looked up in [dynamicLibrary].
  PocketpyBindings(ffi.DynamicLibrary dynamicLibrary)
      : _lookup = dynamicLibrary.lookup;

  /// The symbols are looked up with [lookup].
  PocketpyBindings.fromLookup(
      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
          lookup)
      : _lookup = lookup;

  /// Initialize pocketpy and the default VM.
  void py_initialize() {
    return _py_initialize();
  }

  late final _py_initializePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_initialize');
  late final _py_initialize = _py_initializePtr.asFunction<void Function()>();

  /// Finalize pocketpy and free all VMs. This opearation is irreversible.
  /// After this call, you cannot use any function from this header anymore.
  void py_finalize() {
    return _py_finalize();
  }

  late final _py_finalizePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_finalize');
  late final _py_finalize = _py_finalizePtr.asFunction<void Function()>();

  /// Get the current VM index.
  int py_currentvm() {
    return _py_currentvm();
  }

  late final _py_currentvmPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function()>>('py_currentvm');
  late final _py_currentvm = _py_currentvmPtr.asFunction<int Function()>();

  /// Switch to a VM.
  /// @param index index of the VM ranging from 0 to 16 (exclusive). `0` is the default VM.
  void py_switchvm(
    int index,
  ) {
    return _py_switchvm(
      index,
    );
  }

  late final _py_switchvmPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>('py_switchvm');
  late final _py_switchvm = _py_switchvmPtr.asFunction<void Function(int)>();

  /// Reset the current VM.
  void py_resetvm() {
    return _py_resetvm();
  }

  late final _py_resetvmPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_resetvm');
  late final _py_resetvm = _py_resetvmPtr.asFunction<void Function()>();

  /// Reset All VMs.
  void py_resetallvm() {
    return _py_resetallvm();
  }

  late final _py_resetallvmPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_resetallvm');
  late final _py_resetallvm = _py_resetallvmPtr.asFunction<void Function()>();

  /// Get the current VM context. This is used for user-defined data.
  ffi.Pointer<ffi.Void> py_getvmctx() {
    return _py_getvmctx();
  }

  late final _py_getvmctxPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
          'py_getvmctx');
  late final _py_getvmctx =
      _py_getvmctxPtr.asFunction<ffi.Pointer<ffi.Void> Function()>();

  /// Set the current VM context. This is used for user-defined data.
  void py_setvmctx(
    ffi.Pointer<ffi.Void> ctx,
  ) {
    return _py_setvmctx(
      ctx,
    );
  }

  late final _py_setvmctxPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
          'py_setvmctx');
  late final _py_setvmctx =
      _py_setvmctxPtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();

  /// Setup the callbacks for the current VM.
  ffi.Pointer<py_Callbacks> py_callbacks() {
    return _py_callbacks();
  }

  late final _py_callbacksPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<py_Callbacks> Function()>>(
          'py_callbacks');
  late final _py_callbacks =
      _py_callbacksPtr.asFunction<ffi.Pointer<py_Callbacks> Function()>();

  /// Setup the application callbacks
  ffi.Pointer<py_AppCallbacks> py_appcallbacks() {
    return _py_appcallbacks();
  }

  late final _py_appcallbacksPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<py_AppCallbacks> Function()>>(
          'py_appcallbacks');
  late final _py_appcallbacks =
      _py_appcallbacksPtr.asFunction<ffi.Pointer<py_AppCallbacks> Function()>();

  /// Set `sys.argv`. Used for storing command-line arguments.
  void py_sys_setargv(
    int argc,
    ffi.Pointer<ffi.Pointer<ffi.Char>> argv,
  ) {
    return _py_sys_setargv(
      argc,
      argv,
    );
  }

  late final _py_sys_setargvPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Int, ffi.Pointer<ffi.Pointer<ffi.Char>>)>>('py_sys_setargv');
  late final _py_sys_setargv = _py_sys_setargvPtr
      .asFunction<void Function(int, ffi.Pointer<ffi.Pointer<ffi.Char>>)>();

  /// Set the trace function for the current VM.
  void py_sys_settrace(
    py_TraceFunc func,
    bool reset,
  ) {
    return _py_sys_settrace(
      func,
      reset,
    );
  }

  late final _py_sys_settracePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_TraceFunc, ffi.Bool)>>(
          'py_sys_settrace');
  late final _py_sys_settrace =
      _py_sys_settracePtr.asFunction<void Function(py_TraceFunc, bool)>();

  /// Invoke the garbage collector.
  int py_gc_collect() {
    return _py_gc_collect();
  }

  late final _py_gc_collectPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function()>>('py_gc_collect');
  late final _py_gc_collect = _py_gc_collectPtr.asFunction<int Function()>();

  /// Wrapper for `PK_MALLOC(size)`.
  ffi.Pointer<ffi.Void> py_malloc(
    int size,
  ) {
    return _py_malloc(
      size,
    );
  }

  late final _py_mallocPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size)>>(
          'py_malloc');
  late final _py_malloc =
      _py_mallocPtr.asFunction<ffi.Pointer<ffi.Void> Function(int)>();

  /// Wrapper for `PK_REALLOC(ptr, size)`.
  ffi.Pointer<ffi.Void> py_realloc(
    ffi.Pointer<ffi.Void> ptr,
    int size,
  ) {
    return _py_realloc(
      ptr,
      size,
    );
  }

  late final _py_reallocPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(
              ffi.Pointer<ffi.Void>, ffi.Size)>>('py_realloc');
  late final _py_realloc = _py_reallocPtr
      .asFunction<ffi.Pointer<ffi.Void> Function(ffi.Pointer<ffi.Void>, int)>();

  /// Wrapper for `PK_FREE(ptr)`.
  void py_free(
    ffi.Pointer<ffi.Void> ptr,
  ) {
    return _py_free(
      ptr,
    );
  }

  late final _py_freePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
          'py_free');
  late final _py_free =
      _py_freePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();

  /// A shorthand for `True`.
  py_GlobalRef py_True() {
    return _py_True();
  }

  late final _py_TruePtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function()>>('py_True');
  late final _py_True = _py_TruePtr.asFunction<py_GlobalRef Function()>();

  /// A shorthand for `False`.
  py_GlobalRef py_False() {
    return _py_False();
  }

  late final _py_FalsePtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function()>>('py_False');
  late final _py_False = _py_FalsePtr.asFunction<py_GlobalRef Function()>();

  /// A shorthand for `None`.
  py_GlobalRef py_None() {
    return _py_None();
  }

  late final _py_NonePtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function()>>('py_None');
  late final _py_None = _py_NonePtr.asFunction<py_GlobalRef Function()>();

  /// A shorthand for `nil`. `nil` is not a valid python object.
  py_GlobalRef py_NIL() {
    return _py_NIL();
  }

  late final _py_NILPtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function()>>('py_NIL');
  late final _py_NIL = _py_NILPtr.asFunction<py_GlobalRef Function()>();

  /// Get the current source location of the frame.
  ffi.Pointer<ffi.Char> py_Frame_sourceloc(
    ffi.Pointer<py_Frame> frame,
    ffi.Pointer<ffi.Int> lineno,
  ) {
    return _py_Frame_sourceloc(
      frame,
      lineno,
    );
  }

  late final _py_Frame_sourcelocPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(ffi.Pointer<py_Frame>,
              ffi.Pointer<ffi.Int>)>>('py_Frame_sourceloc');
  late final _py_Frame_sourceloc = _py_Frame_sourcelocPtr.asFunction<
      ffi.Pointer<ffi.Char> Function(
          ffi.Pointer<py_Frame>, ffi.Pointer<ffi.Int>)>();

  /// Python equivalent to `globals()` with respect to the given frame.
  void py_Frame_newglobals(
    ffi.Pointer<py_Frame> frame,
    py_OutRef out,
  ) {
    return _py_Frame_newglobals(
      frame,
      out,
    );
  }

  late final _py_Frame_newglobalsPtr = _lookup<
          ffi
          .NativeFunction<ffi.Void Function(ffi.Pointer<py_Frame>, py_OutRef)>>(
      'py_Frame_newglobals');
  late final _py_Frame_newglobals = _py_Frame_newglobalsPtr
      .asFunction<void Function(ffi.Pointer<py_Frame>, py_OutRef)>();

  /// Python equivalent to `locals()` with respect to the given frame.
  void py_Frame_newlocals(
    ffi.Pointer<py_Frame> frame,
    py_OutRef out,
  ) {
    return _py_Frame_newlocals(
      frame,
      out,
    );
  }

  late final _py_Frame_newlocalsPtr = _lookup<
          ffi
          .NativeFunction<ffi.Void Function(ffi.Pointer<py_Frame>, py_OutRef)>>(
      'py_Frame_newlocals');
  late final _py_Frame_newlocals = _py_Frame_newlocalsPtr
      .asFunction<void Function(ffi.Pointer<py_Frame>, py_OutRef)>();

  /// Get the function object of the frame.
  /// Returns `NULL` if not available.
  py_StackRef py_Frame_function(
    ffi.Pointer<py_Frame> frame,
  ) {
    return _py_Frame_function(
      frame,
    );
  }

  late final _py_Frame_functionPtr =
      _lookup<ffi.NativeFunction<py_StackRef Function(ffi.Pointer<py_Frame>)>>(
          'py_Frame_function');
  late final _py_Frame_function = _py_Frame_functionPtr
      .asFunction<py_StackRef Function(ffi.Pointer<py_Frame>)>();

  /// Compile a source string into a code object.
  /// Use python's `exec()` or `eval()` to execute it.
  bool py_compile(
    ffi.Pointer<ffi.Char> source,
    ffi.Pointer<ffi.Char> filename,
    int mode,
    bool is_dynamic,
  ) {
    return _py_compile(
      source,
      filename,
      mode,
      is_dynamic,
    );
  }

  late final _py_compilePtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
              ffi.Int32, ffi.Bool)>>('py_compile');
  late final _py_compile = _py_compilePtr.asFunction<
      bool Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int, bool)>();

  /// Compile a `.py` file into a `.pyc` file.
  bool py_compilefile(
    ffi.Pointer<ffi.Char> src_path,
    ffi.Pointer<ffi.Char> dst_path,
  ) {
    return _py_compilefile(
      src_path,
      dst_path,
    );
  }

  late final _py_compilefilePtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>>('py_compilefile');
  late final _py_compilefile = _py_compilefilePtr.asFunction<
      bool Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();

  /// Run a compiled code object.
  bool py_execo(
    ffi.Pointer<ffi.Void> data,
    int size,
    ffi.Pointer<ffi.Char> filename,
    py_Ref module,
  ) {
    return _py_execo(
      data,
      size,
      filename,
      module,
    );
  }

  late final _py_execoPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int,
              ffi.Pointer<ffi.Char>, py_Ref)>>('py_execo');
  late final _py_execo = _py_execoPtr.asFunction<
      bool Function(
          ffi.Pointer<ffi.Void>, int, ffi.Pointer<ffi.Char>, py_Ref)>();

  /// Run a source string.
  /// @param source source string.
  /// @param filename filename (for error messages).
  /// @param mode compile mode. Use `EXEC_MODE` for statements `EVAL_MODE` for expressions.
  /// @param module target module. Use NULL for the main module.
  /// @return `true` if the execution is successful or `false` if an exception is raised.
  bool py_exec(
    ffi.Pointer<ffi.Char> source,
    ffi.Pointer<ffi.Char> filename,
    int mode,
    py_Ref module,
  ) {
    return _py_exec(
      source,
      filename,
      mode,
      module,
    );
  }

  late final _py_execPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>,
              ffi.Int32, py_Ref)>>('py_exec');
  late final _py_exec = _py_execPtr.asFunction<
      bool Function(
          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int, py_Ref)>();

  /// Evaluate a source string. Equivalent to `py_exec(source, "<string>", EVAL_MODE, module)`.
  bool py_eval(
    ffi.Pointer<ffi.Char> source,
    py_Ref module,
  ) {
    return _py_eval(
      source,
      module,
    );
  }

  late final _py_evalPtr = _lookup<
          ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Char>, py_Ref)>>(
      'py_eval');
  late final _py_eval =
      _py_evalPtr.asFunction<bool Function(ffi.Pointer<ffi.Char>, py_Ref)>();

  /// Run a source string with smart interpretation.
  /// Example:
  /// `py_newstr(py_r0(), "abc");`
  /// `py_newint(py_r1(), 123);`
  /// `py_smartexec("print(_0, _1)", NULL, py_r0(), py_r1());`
  /// `// "abc 123" will be printed`.
  bool py_smartexec(
    ffi.Pointer<ffi.Char> source,
    py_Ref module,
  ) {
    return _py_smartexec(
      source,
      module,
    );
  }

  late final _py_smartexecPtr = _lookup<
          ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Char>, py_Ref)>>(
      'py_smartexec');
  late final _py_smartexec = _py_smartexecPtr
      .asFunction<bool Function(ffi.Pointer<ffi.Char>, py_Ref)>();

  /// Evaluate a source string with smart interpretation.
  /// Example:
  /// `py_newstr(py_r0(), "abc");`
  /// `py_smarteval("len(_)", NULL, py_r0());`
  /// `int res = py_toint(py_retval());`
  /// `// res will be 3`.
  bool py_smarteval(
    ffi.Pointer<ffi.Char> source,
    py_Ref module,
  ) {
    return _py_smarteval(
      source,
      module,
    );
  }

  late final _py_smartevalPtr = _lookup<
          ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Char>, py_Ref)>>(
      'py_smarteval');
  late final _py_smarteval = _py_smartevalPtr
      .asFunction<bool Function(ffi.Pointer<ffi.Char>, py_Ref)>();

  /// Create an `int` object.
  void py_newint(
    py_OutRef arg0,
    int arg1,
  ) {
    return _py_newint(
      arg0,
      arg1,
    );
  }

  late final _py_newintPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, py_i64)>>(
          'py_newint');
  late final _py_newint =
      _py_newintPtr.asFunction<void Function(py_OutRef, int)>();

  /// Create a trivial value object.
  void py_newtrivial(
    py_OutRef out,
    int type,
    ffi.Pointer<ffi.Void> data,
    int size,
  ) {
    return _py_newtrivial(
      out,
      type,
      data,
      size,
    );
  }

  late final _py_newtrivialPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(py_OutRef, py_Type, ffi.Pointer<ffi.Void>,
              ffi.Int)>>('py_newtrivial');
  late final _py_newtrivial = _py_newtrivialPtr
      .asFunction<void Function(py_OutRef, int, ffi.Pointer<ffi.Void>, int)>();

  /// Create a `float` object.
  void py_newfloat(
    py_OutRef arg0,
    double arg1,
  ) {
    return _py_newfloat(
      arg0,
      arg1,
    );
  }

  late final _py_newfloatPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, py_f64)>>(
          'py_newfloat');
  late final _py_newfloat =
      _py_newfloatPtr.asFunction<void Function(py_OutRef, double)>();

  /// Create a `bool` object.
  void py_newbool(
    py_OutRef arg0,
    bool arg1,
  ) {
    return _py_newbool(
      arg0,
      arg1,
    );
  }

  late final _py_newboolPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, ffi.Bool)>>(
          'py_newbool');
  late final _py_newbool =
      _py_newboolPtr.asFunction<void Function(py_OutRef, bool)>();

  /// Create a `str` object from a null-terminated string (utf-8).
  void py_newstr(
    py_OutRef arg0,
    ffi.Pointer<ffi.Char> arg1,
  ) {
    return _py_newstr(
      arg0,
      arg1,
    );
  }

  late final _py_newstrPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(py_OutRef, ffi.Pointer<ffi.Char>)>>('py_newstr');
  late final _py_newstr = _py_newstrPtr
      .asFunction<void Function(py_OutRef, ffi.Pointer<ffi.Char>)>();

  /// Create a `str` object with `n` UNINITIALIZED bytes plus `'\0'`.
  ffi.Pointer<ffi.Char> py_newstrn(
    py_OutRef arg0,
    int arg1,
  ) {
    return _py_newstrn(
      arg0,
      arg1,
    );
  }

  late final _py_newstrnPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(py_OutRef, ffi.Int)>>('py_newstrn');
  late final _py_newstrn = _py_newstrnPtr
      .asFunction<ffi.Pointer<ffi.Char> Function(py_OutRef, int)>();

  /// Create a `str` object from a `c11_sv`.
  void py_newstrv(
    py_OutRef arg0,
    c11_sv arg1,
  ) {
    return _py_newstrv(
      arg0,
      arg1,
    );
  }

  late final _py_newstrvPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, c11_sv)>>(
          'py_newstrv');
  late final _py_newstrv =
      _py_newstrvPtr.asFunction<void Function(py_OutRef, c11_sv)>();

  /// Create a formatted `str` object.
  void py_newfstr(
    py_OutRef arg0,
    ffi.Pointer<ffi.Char> arg1,
  ) {
    return _py_newfstr(
      arg0,
      arg1,
    );
  }

  late final _py_newfstrPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(py_OutRef, ffi.Pointer<ffi.Char>)>>('py_newfstr');
  late final _py_newfstr = _py_newfstrPtr
      .asFunction<void Function(py_OutRef, ffi.Pointer<ffi.Char>)>();

  /// Create a `bytes` object with `n` UNINITIALIZED bytes.
  ffi.Pointer<ffi.UnsignedChar> py_newbytes(
    py_OutRef arg0,
    int n,
  ) {
    return _py_newbytes(
      arg0,
      n,
    );
  }

  late final _py_newbytesPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.UnsignedChar> Function(
              py_OutRef, ffi.Int)>>('py_newbytes');
  late final _py_newbytes = _py_newbytesPtr
      .asFunction<ffi.Pointer<ffi.UnsignedChar> Function(py_OutRef, int)>();

  /// Create a `None` object.
  void py_newnone(
    py_OutRef arg0,
  ) {
    return _py_newnone(
      arg0,
    );
  }

  late final _py_newnonePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>('py_newnone');
  late final _py_newnone =
      _py_newnonePtr.asFunction<void Function(py_OutRef)>();

  /// Create a `NotImplemented` object.
  void py_newnotimplemented(
    py_OutRef arg0,
  ) {
    return _py_newnotimplemented(
      arg0,
    );
  }

  late final _py_newnotimplementedPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>(
          'py_newnotimplemented');
  late final _py_newnotimplemented =
      _py_newnotimplementedPtr.asFunction<void Function(py_OutRef)>();

  /// Create a `...` object.
  void py_newellipsis(
    py_OutRef arg0,
  ) {
    return _py_newellipsis(
      arg0,
    );
  }

  late final _py_newellipsisPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>(
          'py_newellipsis');
  late final _py_newellipsis =
      _py_newellipsisPtr.asFunction<void Function(py_OutRef)>();

  /// Create a `nil` object. `nil` is an invalid representation of an object.
  /// Don't use it unless you know what you are doing.
  void py_newnil(
    py_OutRef arg0,
  ) {
    return _py_newnil(
      arg0,
    );
  }

  late final _py_newnilPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>('py_newnil');
  late final _py_newnil = _py_newnilPtr.asFunction<void Function(py_OutRef)>();

  /// Create a `nativefunc` object.
  void py_newnativefunc(
    py_OutRef arg0,
    py_CFunction arg1,
  ) {
    return _py_newnativefunc(
      arg0,
      arg1,
    );
  }

  late final _py_newnativefuncPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, py_CFunction)>>(
          'py_newnativefunc');
  late final _py_newnativefunc =
      _py_newnativefuncPtr.asFunction<void Function(py_OutRef, py_CFunction)>();

  /// Create a `function` object.
  py_Name py_newfunction(
    py_OutRef out,
    ffi.Pointer<ffi.Char> sig,
    py_CFunction f,
    ffi.Pointer<ffi.Char> docstring,
    int slots,
  ) {
    return _py_newfunction(
      out,
      sig,
      f,
      docstring,
      slots,
    );
  }

  late final _py_newfunctionPtr = _lookup<
      ffi.NativeFunction<
          py_Name Function(py_OutRef, ffi.Pointer<ffi.Char>, py_CFunction,
              ffi.Pointer<ffi.Char>, ffi.Int)>>('py_newfunction');
  late final _py_newfunction = _py_newfunctionPtr.asFunction<
      py_Name Function(py_OutRef, ffi.Pointer<ffi.Char>, py_CFunction,
          ffi.Pointer<ffi.Char>, int)>();

  /// Create a `boundmethod` object.
  void py_newboundmethod(
    py_OutRef out,
    py_Ref self,
    py_Ref func,
  ) {
    return _py_newboundmethod(
      out,
      self,
      func,
    );
  }

  late final _py_newboundmethodPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, py_Ref, py_Ref)>>(
          'py_newboundmethod');
  late final _py_newboundmethod = _py_newboundmethodPtr
      .asFunction<void Function(py_OutRef, py_Ref, py_Ref)>();

  /// Create a new object.
  /// @param out output reference.
  /// @param type type of the object.
  /// @param slots number of slots. Use `-1` to create a `__dict__`.
  /// @param udsize size of your userdata.
  /// @return pointer to the userdata.
  ffi.Pointer<ffi.Void> py_newobject(
    py_OutRef out,
    int type,
    int slots,
    int udsize,
  ) {
    return _py_newobject(
      out,
      type,
      slots,
      udsize,
    );
  }

  late final _py_newobjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Void> Function(
              py_OutRef, py_Type, ffi.Int, ffi.Int)>>('py_newobject');
  late final _py_newobject = _py_newobjectPtr
      .asFunction<ffi.Pointer<ffi.Void> Function(py_OutRef, int, int, int)>();

  /// Convert a null-terminated string to a name.
  py_Name py_name(
    ffi.Pointer<ffi.Char> arg0,
  ) {
    return _py_name(
      arg0,
    );
  }

  late final _py_namePtr =
      _lookup<ffi.NativeFunction<py_Name Function(ffi.Pointer<ffi.Char>)>>(
          'py_name');
  late final _py_name =
      _py_namePtr.asFunction<py_Name Function(ffi.Pointer<ffi.Char>)>();

  /// Convert a name to a null-terminated string.
  ffi.Pointer<ffi.Char> py_name2str(
    py_Name arg0,
  ) {
    return _py_name2str(
      arg0,
    );
  }

  late final _py_name2strPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(py_Name)>>(
          'py_name2str');
  late final _py_name2str =
      _py_name2strPtr.asFunction<ffi.Pointer<ffi.Char> Function(py_Name)>();

  /// Convert a name to a python `str` object with cache.
  py_GlobalRef py_name2ref(
    py_Name arg0,
  ) {
    return _py_name2ref(
      arg0,
    );
  }

  late final _py_name2refPtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function(py_Name)>>(
          'py_name2ref');
  late final _py_name2ref =
      _py_name2refPtr.asFunction<py_GlobalRef Function(py_Name)>();

  /// Convert a `c11_sv` to a name.
  py_Name py_namev(
    c11_sv arg0,
  ) {
    return _py_namev(
      arg0,
    );
  }

  late final _py_namevPtr =
      _lookup<ffi.NativeFunction<py_Name Function(c11_sv)>>('py_namev');
  late final _py_namev = _py_namevPtr.asFunction<py_Name Function(c11_sv)>();

  /// Convert a name to a `c11_sv`.
  c11_sv py_name2sv(
    py_Name arg0,
  ) {
    return _py_name2sv(
      arg0,
    );
  }

  late final _py_name2svPtr =
      _lookup<ffi.NativeFunction<c11_sv Function(py_Name)>>('py_name2sv');
  late final _py_name2sv =
      _py_name2svPtr.asFunction<c11_sv Function(py_Name)>();

  /// Bind a function to the object via "decl-based" style.
  /// @param obj the target object.
  /// @param sig signature of the function. e.g. `add(x, y)`.
  /// @param f function to bind.
  void py_bind(
    py_Ref obj,
    ffi.Pointer<ffi.Char> sig,
    py_CFunction f,
  ) {
    return _py_bind(
      obj,
      sig,
      f,
    );
  }

  late final _py_bindPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              py_Ref, ffi.Pointer<ffi.Char>, py_CFunction)>>('py_bind');
  late final _py_bind = _py_bindPtr
      .asFunction<void Function(py_Ref, ffi.Pointer<ffi.Char>, py_CFunction)>();

  /// Bind a method to type via "argc-based" style.
  /// @param type the target type.
  /// @param name name of the method.
  /// @param f function to bind.
  void py_bindmethod(
    int type,
    ffi.Pointer<ffi.Char> name,
    py_CFunction f,
  ) {
    return _py_bindmethod(
      type,
      name,
      f,
    );
  }

  late final _py_bindmethodPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              py_Type, ffi.Pointer<ffi.Char>, py_CFunction)>>('py_bindmethod');
  late final _py_bindmethod = _py_bindmethodPtr
      .asFunction<void Function(int, ffi.Pointer<ffi.Char>, py_CFunction)>();

  /// Bind a static method to type via "argc-based" style.
  /// @param type the target type.
  /// @param name name of the method.
  /// @param f function to bind.
  void py_bindstaticmethod(
    int type,
    ffi.Pointer<ffi.Char> name,
    py_CFunction f,
  ) {
    return _py_bindstaticmethod(
      type,
      name,
      f,
    );
  }

  late final _py_bindstaticmethodPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(py_Type, ffi.Pointer<ffi.Char>,
              py_CFunction)>>('py_bindstaticmethod');
  late final _py_bindstaticmethod = _py_bindstaticmethodPtr
      .asFunction<void Function(int, ffi.Pointer<ffi.Char>, py_CFunction)>();

  /// Bind a function to the object via "argc-based" style.
  /// @param obj the target object.
  /// @param name name of the function.
  /// @param f function to bind.
  void py_bindfunc(
    py_Ref obj,
    ffi.Pointer<ffi.Char> name,
    py_CFunction f,
  ) {
    return _py_bindfunc(
      obj,
      name,
      f,
    );
  }

  late final _py_bindfuncPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              py_Ref, ffi.Pointer<ffi.Char>, py_CFunction)>>('py_bindfunc');
  late final _py_bindfunc = _py_bindfuncPtr
      .asFunction<void Function(py_Ref, ffi.Pointer<ffi.Char>, py_CFunction)>();

  /// Bind a property to type.
  /// @param type the target type.
  /// @param name name of the property.
  /// @param getter getter function.
  /// @param setter setter function. Use `NULL` if not needed.
  void py_bindproperty(
    int type,
    ffi.Pointer<ffi.Char> name,
    py_CFunction getter,
    py_CFunction setter,
  ) {
    return _py_bindproperty(
      type,
      name,
      getter,
      setter,
    );
  }

  late final _py_bindpropertyPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(py_Type, ffi.Pointer<ffi.Char>, py_CFunction,
              py_CFunction)>>('py_bindproperty');
  late final _py_bindproperty = _py_bindpropertyPtr.asFunction<
      void Function(int, ffi.Pointer<ffi.Char>, py_CFunction, py_CFunction)>();

  /// Bind a magic method to type.
  void py_bindmagic(
    int type,
    py_Name name,
    py_CFunction f,
  ) {
    return _py_bindmagic(
      type,
      name,
      f,
    );
  }

  late final _py_bindmagicPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(py_Type, py_Name, py_CFunction)>>('py_bindmagic');
  late final _py_bindmagic =
      _py_bindmagicPtr.asFunction<void Function(int, py_Name, py_CFunction)>();

  /// Convert an `int` object in python to `int64_t`.
  int py_toint(
    py_Ref arg0,
  ) {
    return _py_toint(
      arg0,
    );
  }

  late final _py_tointPtr =
      _lookup<ffi.NativeFunction<py_i64 Function(py_Ref)>>('py_toint');
  late final _py_toint = _py_tointPtr.asFunction<int Function(py_Ref)>();

  /// Get the address of the trivial value object (16 bytes).
  ffi.Pointer<ffi.Void> py_totrivial(
    py_Ref arg0,
  ) {
    return _py_totrivial(
      arg0,
    );
  }

  late final _py_totrivialPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(py_Ref)>>(
          'py_totrivial');
  late final _py_totrivial =
      _py_totrivialPtr.asFunction<ffi.Pointer<ffi.Void> Function(py_Ref)>();

  /// Convert a `float` object in python to `double`.
  double py_tofloat(
    py_Ref arg0,
  ) {
    return _py_tofloat(
      arg0,
    );
  }

  late final _py_tofloatPtr =
      _lookup<ffi.NativeFunction<py_f64 Function(py_Ref)>>('py_tofloat');
  late final _py_tofloat = _py_tofloatPtr.asFunction<double Function(py_Ref)>();

  /// Cast a `int` or `float` object in python to `double`.
  /// If successful, return true and set the value to `out`.
  /// Otherwise, return false and raise `TypeError`.
  bool py_castfloat(
    py_Ref arg0,
    ffi.Pointer<py_f64> out,
  ) {
    return _py_castfloat(
      arg0,
      out,
    );
  }

  late final _py_castfloatPtr = _lookup<
          ffi.NativeFunction<ffi.Bool Function(py_Ref, ffi.Pointer<py_f64>)>>(
      'py_castfloat');
  late final _py_castfloat =
      _py_castfloatPtr.asFunction<bool Function(py_Ref, ffi.Pointer<py_f64>)>();

  /// 32-bit version of `py_castfloat`.
  bool py_castfloat32(
    py_Ref arg0,
    ffi.Pointer<ffi.Float> out,
  ) {
    return _py_castfloat32(
      arg0,
      out,
    );
  }

  late final _py_castfloat32Ptr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(py_Ref, ffi.Pointer<ffi.Float>)>>('py_castfloat32');
  late final _py_castfloat32 = _py_castfloat32Ptr
      .asFunction<bool Function(py_Ref, ffi.Pointer<ffi.Float>)>();

  /// Cast a `int` object in python to `int64_t`.
  bool py_castint(
    py_Ref arg0,
    ffi.Pointer<py_i64> out,
  ) {
    return _py_castint(
      arg0,
      out,
    );
  }

  late final _py_castintPtr = _lookup<
          ffi.NativeFunction<ffi.Bool Function(py_Ref, ffi.Pointer<py_i64>)>>(
      'py_castint');
  late final _py_castint =
      _py_castintPtr.asFunction<bool Function(py_Ref, ffi.Pointer<py_i64>)>();

  /// Convert a `bool` object in python to `bool`.
  bool py_tobool(
    py_Ref arg0,
  ) {
    return _py_tobool(
      arg0,
    );
  }

  late final _py_toboolPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_tobool');
  late final _py_tobool = _py_toboolPtr.asFunction<bool Function(py_Ref)>();

  /// Convert a `type` object in python to `py_Type`.
  int py_totype(
    py_Ref arg0,
  ) {
    return _py_totype(
      arg0,
    );
  }

  late final _py_totypePtr =
      _lookup<ffi.NativeFunction<py_Type Function(py_Ref)>>('py_totype');
  late final _py_totype = _py_totypePtr.asFunction<int Function(py_Ref)>();

  /// Convert a user-defined object to its userdata.
  ffi.Pointer<ffi.Void> py_touserdata(
    py_Ref arg0,
  ) {
    return _py_touserdata(
      arg0,
    );
  }

  late final _py_touserdataPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(py_Ref)>>(
          'py_touserdata');
  late final _py_touserdata =
      _py_touserdataPtr.asFunction<ffi.Pointer<ffi.Void> Function(py_Ref)>();

  /// Convert a `str` object in python to null-terminated string.
  ffi.Pointer<ffi.Char> py_tostr(
    py_Ref arg0,
  ) {
    return _py_tostr(
      arg0,
    );
  }

  late final _py_tostrPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(py_Ref)>>(
          'py_tostr');
  late final _py_tostr =
      _py_tostrPtr.asFunction<ffi.Pointer<ffi.Char> Function(py_Ref)>();

  /// Convert a `str` object in python to char array.
  ffi.Pointer<ffi.Char> py_tostrn(
    py_Ref arg0,
    ffi.Pointer<ffi.Int> size,
  ) {
    return _py_tostrn(
      arg0,
      size,
    );
  }

  late final _py_tostrnPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(
              py_Ref, ffi.Pointer<ffi.Int>)>>('py_tostrn');
  late final _py_tostrn = _py_tostrnPtr.asFunction<
      ffi.Pointer<ffi.Char> Function(py_Ref, ffi.Pointer<ffi.Int>)>();

  /// Convert a `str` object in python to `c11_sv`.
  c11_sv py_tosv(
    py_Ref arg0,
  ) {
    return _py_tosv(
      arg0,
    );
  }

  late final _py_tosvPtr =
      _lookup<ffi.NativeFunction<c11_sv Function(py_Ref)>>('py_tosv');
  late final _py_tosv = _py_tosvPtr.asFunction<c11_sv Function(py_Ref)>();

  /// Convert a `bytes` object in python to char array.
  ffi.Pointer<ffi.UnsignedChar> py_tobytes(
    py_Ref arg0,
    ffi.Pointer<ffi.Int> size,
  ) {
    return _py_tobytes(
      arg0,
      size,
    );
  }

  late final _py_tobytesPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.UnsignedChar> Function(
              py_Ref, ffi.Pointer<ffi.Int>)>>('py_tobytes');
  late final _py_tobytes = _py_tobytesPtr.asFunction<
      ffi.Pointer<ffi.UnsignedChar> Function(py_Ref, ffi.Pointer<ffi.Int>)>();

  /// Resize a `bytes` object. It can only be resized down.
  void py_bytes_resize(
    py_Ref arg0,
    int size,
  ) {
    return _py_bytes_resize(
      arg0,
      size,
    );
  }

  late final _py_bytes_resizePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, ffi.Int)>>(
          'py_bytes_resize');
  late final _py_bytes_resize =
      _py_bytes_resizePtr.asFunction<void Function(py_Ref, int)>();

  /// Create a new type.
  /// @param name name of the type.
  /// @param base base type.
  /// @param module module where the type is defined. Use `NULL` for built-in types.
  /// @param dtor destructor function. Use `NULL` if not needed.
  int py_newtype(
    ffi.Pointer<ffi.Char> name,
    int base,
    py_GlobalRef module,
    py_Dtor dtor,
  ) {
    return _py_newtype(
      name,
      base,
      module,
      dtor,
    );
  }

  late final _py_newtypePtr = _lookup<
      ffi.NativeFunction<
          py_Type Function(ffi.Pointer<ffi.Char>, py_Type, py_GlobalRef,
              py_Dtor)>>('py_newtype');
  late final _py_newtype = _py_newtypePtr.asFunction<
      int Function(ffi.Pointer<ffi.Char>, int, py_GlobalRef, py_Dtor)>();

  /// Check if the object is exactly the given type.
  bool py_istype(
    py_Ref arg0,
    int arg1,
  ) {
    return _py_istype(
      arg0,
      arg1,
    );
  }

  late final _py_istypePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Type)>>(
          'py_istype');
  late final _py_istype =
      _py_istypePtr.asFunction<bool Function(py_Ref, int)>();

  /// Get the type of the object.
  int py_typeof(
    py_Ref self,
  ) {
    return _py_typeof(
      self,
    );
  }

  late final _py_typeofPtr =
      _lookup<ffi.NativeFunction<py_Type Function(py_Ref)>>('py_typeof');
  late final _py_typeof = _py_typeofPtr.asFunction<int Function(py_Ref)>();

  /// Check if the object is an instance of the given type.
  bool py_isinstance(
    py_Ref obj,
    int type,
  ) {
    return _py_isinstance(
      obj,
      type,
    );
  }

  late final _py_isinstancePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Type)>>(
          'py_isinstance');
  late final _py_isinstance =
      _py_isinstancePtr.asFunction<bool Function(py_Ref, int)>();

  /// Check if the derived type is a subclass of the base type.
  bool py_issubclass(
    int derived,
    int base,
  ) {
    return _py_issubclass(
      derived,
      base,
    );
  }

  late final _py_issubclassPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Type, py_Type)>>(
          'py_issubclass');
  late final _py_issubclass =
      _py_issubclassPtr.asFunction<bool Function(int, int)>();

  /// Get type by module and name. e.g. `py_gettype("time", py_name("struct_time"))`.
  /// Return `0` if not found.
  int py_gettype(
    ffi.Pointer<ffi.Char> module,
    py_Name name,
  ) {
    return _py_gettype(
      module,
      name,
    );
  }

  late final _py_gettypePtr = _lookup<
          ffi.NativeFunction<py_Type Function(ffi.Pointer<ffi.Char>, py_Name)>>(
      'py_gettype');
  late final _py_gettype =
      _py_gettypePtr.asFunction<int Function(ffi.Pointer<ffi.Char>, py_Name)>();

  /// Check if the object is an instance of the given type exactly.
  /// Raise `TypeError` if the check fails.
  bool py_checktype(
    py_Ref self,
    int type,
  ) {
    return _py_checktype(
      self,
      type,
    );
  }

  late final _py_checktypePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Type)>>(
          'py_checktype');
  late final _py_checktype =
      _py_checktypePtr.asFunction<bool Function(py_Ref, int)>();

  /// Check if the object is an instance of the given type or its subclass.
  /// Raise `TypeError` if the check fails.
  bool py_checkinstance(
    py_Ref self,
    int type,
  ) {
    return _py_checkinstance(
      self,
      type,
    );
  }

  late final _py_checkinstancePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Type)>>(
          'py_checkinstance');
  late final _py_checkinstance =
      _py_checkinstancePtr.asFunction<bool Function(py_Ref, int)>();

  /// Get the magic method from the given type only.
  /// Return `nil` if not found.
  py_GlobalRef py_tpgetmagic(
    int type,
    py_Name name,
  ) {
    return _py_tpgetmagic(
      type,
      name,
    );
  }

  late final _py_tpgetmagicPtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function(py_Type, py_Name)>>(
          'py_tpgetmagic');
  late final _py_tpgetmagic =
      _py_tpgetmagicPtr.asFunction<py_GlobalRef Function(int, py_Name)>();

  /// Search the magic method from the given type to the base type.
  /// Return `NULL` if not found.
  py_GlobalRef py_tpfindmagic(
    int arg0,
    py_Name name,
  ) {
    return _py_tpfindmagic(
      arg0,
      name,
    );
  }

  late final _py_tpfindmagicPtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function(py_Type, py_Name)>>(
          'py_tpfindmagic');
  late final _py_tpfindmagic =
      _py_tpfindmagicPtr.asFunction<py_GlobalRef Function(int, py_Name)>();

  /// Search the name from the given type to the base type.
  /// Return `NULL` if not found.
  py_ItemRef py_tpfindname(
    int arg0,
    py_Name name,
  ) {
    return _py_tpfindname(
      arg0,
      name,
    );
  }

  late final _py_tpfindnamePtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Type, py_Name)>>(
          'py_tpfindname');
  late final _py_tpfindname =
      _py_tpfindnamePtr.asFunction<py_ItemRef Function(int, py_Name)>();

  /// Get the base type of the given type.
  int py_tpbase(
    int type,
  ) {
    return _py_tpbase(
      type,
    );
  }

  late final _py_tpbasePtr =
      _lookup<ffi.NativeFunction<py_Type Function(py_Type)>>('py_tpbase');
  late final _py_tpbase = _py_tpbasePtr.asFunction<int Function(int)>();

  /// Get the type object of the given type.
  py_GlobalRef py_tpobject(
    int type,
  ) {
    return _py_tpobject(
      type,
    );
  }

  late final _py_tpobjectPtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function(py_Type)>>(
          'py_tpobject');
  late final _py_tpobject =
      _py_tpobjectPtr.asFunction<py_GlobalRef Function(int)>();

  /// Get the type name.
  ffi.Pointer<ffi.Char> py_tpname(
    int type,
  ) {
    return _py_tpname(
      type,
    );
  }

  late final _py_tpnamePtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(py_Type)>>(
          'py_tpname');
  late final _py_tpname =
      _py_tpnamePtr.asFunction<ffi.Pointer<ffi.Char> Function(int)>();

  /// Disable the type for subclassing.
  void py_tpsetfinal(
    int type,
  ) {
    return _py_tpsetfinal(
      type,
    );
  }

  late final _py_tpsetfinalPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Type)>>('py_tpsetfinal');
  late final _py_tpsetfinal =
      _py_tpsetfinalPtr.asFunction<void Function(int)>();

  /// Set attribute hooks for the given type.
  void py_tphookattributes(
    int type,
    ffi.Pointer<
            ffi.NativeFunction<ffi.Bool Function(py_Ref self, py_Name name)>>
        getattribute,
    ffi.Pointer<
            ffi.NativeFunction<
                ffi.Bool Function(py_Ref self, py_Name name, py_Ref val)>>
        setattribute,
    ffi.Pointer<
            ffi.NativeFunction<ffi.Bool Function(py_Ref self, py_Name name)>>
        delattribute,
    ffi.Pointer<
            ffi.NativeFunction<ffi.Bool Function(py_Ref self, py_Name name)>>
        getunboundmethod,
  ) {
    return _py_tphookattributes(
      type,
      getattribute,
      setattribute,
      delattribute,
      getunboundmethod,
    );
  }

  late final _py_tphookattributesPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              py_Type,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Bool Function(py_Ref self, py_Name name)>>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Bool Function(
                          py_Ref self, py_Name name, py_Ref val)>>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Bool Function(py_Ref self, py_Name name)>>,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Bool Function(py_Ref self,
                          py_Name name)>>)>>('py_tphookattributes');
  late final _py_tphookattributes = _py_tphookattributesPtr.asFunction<
      void Function(
          int,
          ffi.Pointer<
              ffi.NativeFunction<ffi.Bool Function(py_Ref self, py_Name name)>>,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(py_Ref self, py_Name name, py_Ref val)>>,
          ffi.Pointer<
              ffi.NativeFunction<ffi.Bool Function(py_Ref self, py_Name name)>>,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(py_Ref self, py_Name name)>>)>();

  /// Get the current `Callable` object on the stack of the most recent vectorcall.
  /// Return `NULL` if not available.
  /// NOTE: This function should be placed at the beginning of your bindings or you will get wrong result.
  py_StackRef py_inspect_currentfunction() {
    return _py_inspect_currentfunction();
  }

  late final _py_inspect_currentfunctionPtr =
      _lookup<ffi.NativeFunction<py_StackRef Function()>>(
          'py_inspect_currentfunction');
  late final _py_inspect_currentfunction =
      _py_inspect_currentfunctionPtr.asFunction<py_StackRef Function()>();

  /// Get the current `module` object where the code is executed.
  /// Return `NULL` if not available.
  py_GlobalRef py_inspect_currentmodule() {
    return _py_inspect_currentmodule();
  }

  late final _py_inspect_currentmodulePtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function()>>(
          'py_inspect_currentmodule');
  late final _py_inspect_currentmodule =
      _py_inspect_currentmodulePtr.asFunction<py_GlobalRef Function()>();

  /// Get the current frame object.
  /// Return `NULL` if not available.
  ffi.Pointer<py_Frame> py_inspect_currentframe() {
    return _py_inspect_currentframe();
  }

  late final _py_inspect_currentframePtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<py_Frame> Function()>>(
          'py_inspect_currentframe');
  late final _py_inspect_currentframe = _py_inspect_currentframePtr
      .asFunction<ffi.Pointer<py_Frame> Function()>();

  /// Python equivalent to `globals()`.
  void py_newglobals(
    py_OutRef arg0,
  ) {
    return _py_newglobals(
      arg0,
    );
  }

  late final _py_newglobalsPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>(
          'py_newglobals');
  late final _py_newglobals =
      _py_newglobalsPtr.asFunction<void Function(py_OutRef)>();

  /// Python equivalent to `locals()`.
  void py_newlocals(
    py_OutRef arg0,
  ) {
    return _py_newlocals(
      arg0,
    );
  }

  late final _py_newlocalsPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>('py_newlocals');
  late final _py_newlocals =
      _py_newlocalsPtr.asFunction<void Function(py_OutRef)>();

  /// Get the i-th register.
  /// All registers are located in a contiguous memory.
  py_GlobalRef py_getreg(
    int i,
  ) {
    return _py_getreg(
      i,
    );
  }

  late final _py_getregPtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function(ffi.Int)>>('py_getreg');
  late final _py_getreg =
      _py_getregPtr.asFunction<py_GlobalRef Function(int)>();

  /// Set the i-th register.
  void py_setreg(
    int i,
    py_Ref val,
  ) {
    return _py_setreg(
      i,
      val,
    );
  }

  late final _py_setregPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int, py_Ref)>>(
          'py_setreg');
  late final _py_setreg =
      _py_setregPtr.asFunction<void Function(int, py_Ref)>();

  /// Get the last return value.
  /// Please note that `py_retval()` cannot be used as input argument.
  py_GlobalRef py_retval() {
    return _py_retval();
  }

  late final _py_retvalPtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function()>>('py_retval');
  late final _py_retval = _py_retvalPtr.asFunction<py_GlobalRef Function()>();

  /// Get an item from the object's `__dict__`.
  /// Return `NULL` if not found.
  py_ItemRef py_getdict(
    py_Ref self,
    py_Name name,
  ) {
    return _py_getdict(
      self,
      name,
    );
  }

  late final _py_getdictPtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Ref, py_Name)>>(
          'py_getdict');
  late final _py_getdict =
      _py_getdictPtr.asFunction<py_ItemRef Function(py_Ref, py_Name)>();

  /// Set an item to the object's `__dict__`.
  void py_setdict(
    py_Ref self,
    py_Name name,
    py_Ref val,
  ) {
    return _py_setdict(
      self,
      name,
      val,
    );
  }

  late final _py_setdictPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, py_Name, py_Ref)>>(
          'py_setdict');
  late final _py_setdict =
      _py_setdictPtr.asFunction<void Function(py_Ref, py_Name, py_Ref)>();

  /// Delete an item from the object's `__dict__`.
  /// Return `true` if the deletion is successful.
  bool py_deldict(
    py_Ref self,
    py_Name name,
  ) {
    return _py_deldict(
      self,
      name,
    );
  }

  late final _py_deldictPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Name)>>(
          'py_deldict');
  late final _py_deldict =
      _py_deldictPtr.asFunction<bool Function(py_Ref, py_Name)>();

  /// Prepare an insertion to the object's `__dict__`.
  py_ItemRef py_emplacedict(
    py_Ref self,
    py_Name name,
  ) {
    return _py_emplacedict(
      self,
      name,
    );
  }

  late final _py_emplacedictPtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Ref, py_Name)>>(
          'py_emplacedict');
  late final _py_emplacedict =
      _py_emplacedictPtr.asFunction<py_ItemRef Function(py_Ref, py_Name)>();

  /// Apply a function to all items in the object's `__dict__`.
  /// Return `true` if the function is successful for all items.
  /// NOTE: Be careful if `f` modifies the object's `__dict__`.
  bool py_applydict(
    py_Ref self,
    ffi.Pointer<
            ffi.NativeFunction<
                ffi.Bool Function(
                    py_Name name, py_Ref val, ffi.Pointer<ffi.Void> ctx)>>
        f,
    ffi.Pointer<ffi.Void> ctx,
  ) {
    return _py_applydict(
      self,
      f,
      ctx,
    );
  }

  late final _py_applydictPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              py_Ref,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Bool Function(py_Name name, py_Ref val,
                          ffi.Pointer<ffi.Void> ctx)>>,
              ffi.Pointer<ffi.Void>)>>('py_applydict');
  late final _py_applydict = _py_applydictPtr.asFunction<
      bool Function(
          py_Ref,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(
                      py_Name name, py_Ref val, ffi.Pointer<ffi.Void> ctx)>>,
          ffi.Pointer<ffi.Void>)>();

  /// Clear the object's `__dict__`. This function is dangerous.
  void py_cleardict(
    py_Ref self,
  ) {
    return _py_cleardict(
      self,
    );
  }

  late final _py_cleardictPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref)>>('py_cleardict');
  late final _py_cleardict =
      _py_cleardictPtr.asFunction<void Function(py_Ref)>();

  /// Get the i-th slot of the object.
  /// The object must have slots and `i` must be in valid range.
  py_ObjectRef py_getslot(
    py_Ref self,
    int i,
  ) {
    return _py_getslot(
      self,
      i,
    );
  }

  late final _py_getslotPtr =
      _lookup<ffi.NativeFunction<py_ObjectRef Function(py_Ref, ffi.Int)>>(
          'py_getslot');
  late final _py_getslot =
      _py_getslotPtr.asFunction<py_ObjectRef Function(py_Ref, int)>();

  /// Set the i-th slot of the object.
  void py_setslot(
    py_Ref self,
    int i,
    py_Ref val,
  ) {
    return _py_setslot(
      self,
      i,
      val,
    );
  }

  late final _py_setslotPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, ffi.Int, py_Ref)>>(
          'py_setslot');
  late final _py_setslot =
      _py_setslotPtr.asFunction<void Function(py_Ref, int, py_Ref)>();

  /// Get variable in the `builtins` module.
  py_ItemRef py_getbuiltin(
    py_Name name,
  ) {
    return _py_getbuiltin(
      name,
    );
  }

  late final _py_getbuiltinPtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Name)>>(
          'py_getbuiltin');
  late final _py_getbuiltin =
      _py_getbuiltinPtr.asFunction<py_ItemRef Function(py_Name)>();

  /// Get variable in the `__main__` module.
  py_ItemRef py_getglobal(
    py_Name name,
  ) {
    return _py_getglobal(
      name,
    );
  }

  late final _py_getglobalPtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Name)>>('py_getglobal');
  late final _py_getglobal =
      _py_getglobalPtr.asFunction<py_ItemRef Function(py_Name)>();

  /// Set variable in the `__main__` module.
  void py_setglobal(
    py_Name name,
    py_Ref val,
  ) {
    return _py_setglobal(
      name,
      val,
    );
  }

  late final _py_setglobalPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Name, py_Ref)>>(
          'py_setglobal');
  late final _py_setglobal =
      _py_setglobalPtr.asFunction<void Function(py_Name, py_Ref)>();

  /// Get the i-th object from the top of the stack.
  /// `i` should be negative, e.g. (-1) means TOS.
  py_StackRef py_peek(
    int i,
  ) {
    return _py_peek(
      i,
    );
  }

  late final _py_peekPtr =
      _lookup<ffi.NativeFunction<py_StackRef Function(ffi.Int)>>('py_peek');
  late final _py_peek = _py_peekPtr.asFunction<py_StackRef Function(int)>();

  /// Push the object to the stack.
  void py_push(
    py_Ref src,
  ) {
    return _py_push(
      src,
    );
  }

  late final _py_pushPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref)>>('py_push');
  late final _py_push = _py_pushPtr.asFunction<void Function(py_Ref)>();

  /// Push a `nil` object to the stack.
  void py_pushnil() {
    return _py_pushnil();
  }

  late final _py_pushnilPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_pushnil');
  late final _py_pushnil = _py_pushnilPtr.asFunction<void Function()>();

  /// Push a `None` object to the stack.
  void py_pushnone() {
    return _py_pushnone();
  }

  late final _py_pushnonePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_pushnone');
  late final _py_pushnone = _py_pushnonePtr.asFunction<void Function()>();

  /// Push a `py_Name` to the stack. This is used for keyword arguments.
  void py_pushname(
    py_Name name,
  ) {
    return _py_pushname(
      name,
    );
  }

  late final _py_pushnamePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Name)>>('py_pushname');
  late final _py_pushname =
      _py_pushnamePtr.asFunction<void Function(py_Name)>();

  /// Pop an object from the stack.
  void py_pop() {
    return _py_pop();
  }

  late final _py_popPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_pop');
  late final _py_pop = _py_popPtr.asFunction<void Function()>();

  /// Shrink the stack by n.
  void py_shrink(
    int n,
  ) {
    return _py_shrink(
      n,
    );
  }

  late final _py_shrinkPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>('py_shrink');
  late final _py_shrink = _py_shrinkPtr.asFunction<void Function(int)>();

  /// Get a temporary variable from the stack.
  py_StackRef py_pushtmp() {
    return _py_pushtmp();
  }

  late final _py_pushtmpPtr =
      _lookup<ffi.NativeFunction<py_StackRef Function()>>('py_pushtmp');
  late final _py_pushtmp = _py_pushtmpPtr.asFunction<py_StackRef Function()>();

  /// Get the unbound method of the object.
  /// Assume the object is located at the top of the stack.
  /// If return true:  `[self] -> [unbound, self]`.
  /// If return false: `[self] -> [self]` (no change).
  bool py_pushmethod(
    py_Name name,
  ) {
    return _py_pushmethod(
      name,
    );
  }

  late final _py_pushmethodPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Name)>>('py_pushmethod');
  late final _py_pushmethod =
      _py_pushmethodPtr.asFunction<bool Function(py_Name)>();

  /// Evaluate an expression and push the result to the stack.
  /// This function is used for testing.
  bool py_pusheval(
    ffi.Pointer<ffi.Char> expr,
    py_GlobalRef module,
  ) {
    return _py_pusheval(
      expr,
      module,
    );
  }

  late final _py_pushevalPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ffi.Char>, py_GlobalRef)>>('py_pusheval');
  late final _py_pusheval = _py_pushevalPtr
      .asFunction<bool Function(ffi.Pointer<ffi.Char>, py_GlobalRef)>();

  /// Call a callable object via pocketpy's calling convention.
  /// You need to prepare the stack using the following format:
  /// `callable, self/nil, arg1, arg2, ..., k1, v1, k2, v2, ...`.
  /// `argc` is the number of positional arguments excluding `self`.
  /// `kwargc` is the number of keyword arguments.
  /// The result will be set to `py_retval()`.
  /// The stack size will be reduced by `2 + argc + kwargc * 2`.
  bool py_vectorcall(
    int argc,
    int kwargc,
  ) {
    return _py_vectorcall(
      argc,
      kwargc,
    );
  }

  late final _py_vectorcallPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Uint16, ffi.Uint16)>>(
          'py_vectorcall');
  late final _py_vectorcall =
      _py_vectorcallPtr.asFunction<bool Function(int, int)>();

  /// Call a function.
  /// It prepares the stack and then performs a `vectorcall(argc, 0, false)`.
  /// The result will be set to `py_retval()`.
  /// The stack remains unchanged if successful.
  bool py_call(
    py_Ref f,
    int argc,
    py_Ref argv,
  ) {
    return _py_call(
      f,
      argc,
      argv,
    );
  }

  late final _py_callPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, ffi.Int, py_Ref)>>(
          'py_call');
  late final _py_call =
      _py_callPtr.asFunction<bool Function(py_Ref, int, py_Ref)>();

  /// Call a type to create a new instance.
  bool py_tpcall(
    int type,
    int argc,
    py_Ref argv,
  ) {
    return _py_tpcall(
      type,
      argc,
      argv,
    );
  }

  late final _py_tpcallPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Type, ffi.Int, py_Ref)>>(
          'py_tpcall');
  late final _py_tpcall =
      _py_tpcallPtr.asFunction<bool Function(int, int, py_Ref)>();

  /// Call a `py_CFunction` in a safe way.
  /// This function does extra checks to help you debug `py_CFunction`.
  bool py_callcfunc(
    py_CFunction f,
    int argc,
    py_Ref argv,
  ) {
    return _py_callcfunc(
      f,
      argc,
      argv,
    );
  }

  late final _py_callcfuncPtr = _lookup<
          ffi.NativeFunction<ffi.Bool Function(py_CFunction, ffi.Int, py_Ref)>>(
      'py_callcfunc');
  late final _py_callcfunc =
      _py_callcfuncPtr.asFunction<bool Function(py_CFunction, int, py_Ref)>();

  /// Perform a binary operation.
  /// The result will be set to `py_retval()`.
  /// The stack remains unchanged after the operation.
  bool py_binaryop(
    py_Ref lhs,
    py_Ref rhs,
    py_Name op,
    py_Name rop,
  ) {
    return _py_binaryop(
      lhs,
      rhs,
      op,
      rop,
    );
  }

  late final _py_binaryopPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(py_Ref, py_Ref, py_Name, py_Name)>>('py_binaryop');
  late final _py_binaryop = _py_binaryopPtr
      .asFunction<bool Function(py_Ref, py_Ref, py_Name, py_Name)>();

  /// lhs + rhs
  bool py_binaryadd(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binaryadd(
      lhs,
      rhs,
    );
  }

  late final _py_binaryaddPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binaryadd');
  late final _py_binaryadd =
      _py_binaryaddPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs - rhs
  bool py_binarysub(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binarysub(
      lhs,
      rhs,
    );
  }

  late final _py_binarysubPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binarysub');
  late final _py_binarysub =
      _py_binarysubPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs * rhs
  bool py_binarymul(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binarymul(
      lhs,
      rhs,
    );
  }

  late final _py_binarymulPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binarymul');
  late final _py_binarymul =
      _py_binarymulPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs / rhs
  bool py_binarytruediv(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binarytruediv(
      lhs,
      rhs,
    );
  }

  late final _py_binarytruedivPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binarytruediv');
  late final _py_binarytruediv =
      _py_binarytruedivPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs // rhs
  bool py_binaryfloordiv(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binaryfloordiv(
      lhs,
      rhs,
    );
  }

  late final _py_binaryfloordivPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binaryfloordiv');
  late final _py_binaryfloordiv =
      _py_binaryfloordivPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs % rhs
  bool py_binarymod(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binarymod(
      lhs,
      rhs,
    );
  }

  late final _py_binarymodPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binarymod');
  late final _py_binarymod =
      _py_binarymodPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs ** rhs
  bool py_binarypow(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binarypow(
      lhs,
      rhs,
    );
  }

  late final _py_binarypowPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binarypow');
  late final _py_binarypow =
      _py_binarypowPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs << rhs
  bool py_binarylshift(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binarylshift(
      lhs,
      rhs,
    );
  }

  late final _py_binarylshiftPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binarylshift');
  late final _py_binarylshift =
      _py_binarylshiftPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs >> rhs
  bool py_binaryrshift(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binaryrshift(
      lhs,
      rhs,
    );
  }

  late final _py_binaryrshiftPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binaryrshift');
  late final _py_binaryrshift =
      _py_binaryrshiftPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs & rhs
  bool py_binaryand(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binaryand(
      lhs,
      rhs,
    );
  }

  late final _py_binaryandPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binaryand');
  late final _py_binaryand =
      _py_binaryandPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs | rhs
  bool py_binaryor(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binaryor(
      lhs,
      rhs,
    );
  }

  late final _py_binaryorPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binaryor');
  late final _py_binaryor =
      _py_binaryorPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs ^ rhs
  bool py_binaryxor(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binaryxor(
      lhs,
      rhs,
    );
  }

  late final _py_binaryxorPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binaryxor');
  late final _py_binaryxor =
      _py_binaryxorPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs @ rhs
  bool py_binarymatmul(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_binarymatmul(
      lhs,
      rhs,
    );
  }

  late final _py_binarymatmulPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_binarymatmul');
  late final _py_binarymatmul =
      _py_binarymatmulPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs == rhs
  bool py_eq(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_eq(
      lhs,
      rhs,
    );
  }

  late final _py_eqPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>('py_eq');
  late final _py_eq = _py_eqPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs != rhs
  bool py_ne(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_ne(
      lhs,
      rhs,
    );
  }

  late final _py_nePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>('py_ne');
  late final _py_ne = _py_nePtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs < rhs
  bool py_lt(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_lt(
      lhs,
      rhs,
    );
  }

  late final _py_ltPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>('py_lt');
  late final _py_lt = _py_ltPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs <= rhs
  bool py_le(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_le(
      lhs,
      rhs,
    );
  }

  late final _py_lePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>('py_le');
  late final _py_le = _py_lePtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs > rhs
  bool py_gt(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_gt(
      lhs,
      rhs,
    );
  }

  late final _py_gtPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>('py_gt');
  late final _py_gt = _py_gtPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// lhs >= rhs
  bool py_ge(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_ge(
      lhs,
      rhs,
    );
  }

  late final _py_gePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>('py_ge');
  late final _py_ge = _py_gePtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// Python equivalent to `lhs is rhs`.
  bool py_isidentical(
    py_Ref arg0,
    py_Ref arg1,
  ) {
    return _py_isidentical(
      arg0,
      arg1,
    );
  }

  late final _py_isidenticalPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_isidentical');
  late final _py_isidentical =
      _py_isidenticalPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// Python equivalent to `bool(val)`.
  /// 1: true, 0: false, -1: error
  int py_bool(
    py_Ref val,
  ) {
    return _py_bool(
      val,
    );
  }

  late final _py_boolPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref)>>('py_bool');
  late final _py_bool = _py_boolPtr.asFunction<int Function(py_Ref)>();

  /// Compare two objects.
  /// 1: lhs == rhs, 0: lhs != rhs, -1: error
  int py_equal(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_equal(
      lhs,
      rhs,
    );
  }

  late final _py_equalPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref, py_Ref)>>('py_equal');
  late final _py_equal =
      _py_equalPtr.asFunction<int Function(py_Ref, py_Ref)>();

  /// Compare two objects.
  /// 1: lhs < rhs, 0: lhs >= rhs, -1: error
  int py_less(
    py_Ref lhs,
    py_Ref rhs,
  ) {
    return _py_less(
      lhs,
      rhs,
    );
  }

  late final _py_lessPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref, py_Ref)>>('py_less');
  late final _py_less = _py_lessPtr.asFunction<int Function(py_Ref, py_Ref)>();

  /// Python equivalent to `callable(val)`.
  bool py_callable(
    py_Ref val,
  ) {
    return _py_callable(
      val,
    );
  }

  late final _py_callablePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_callable');
  late final _py_callable = _py_callablePtr.asFunction<bool Function(py_Ref)>();

  /// Get the hash value of the object.
  bool py_hash(
    py_Ref arg0,
    ffi.Pointer<py_i64> out,
  ) {
    return _py_hash(
      arg0,
      out,
    );
  }

  late final _py_hashPtr = _lookup<
          ffi.NativeFunction<ffi.Bool Function(py_Ref, ffi.Pointer<py_i64>)>>(
      'py_hash');
  late final _py_hash =
      _py_hashPtr.asFunction<bool Function(py_Ref, ffi.Pointer<py_i64>)>();

  /// Get the iterator of the object.
  bool py_iter(
    py_Ref arg0,
  ) {
    return _py_iter(
      arg0,
    );
  }

  late final _py_iterPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_iter');
  late final _py_iter = _py_iterPtr.asFunction<bool Function(py_Ref)>();

  /// Get the next element from the iterator.
  /// 1: success, 0: StopIteration, -1: error
  int py_next(
    py_Ref arg0,
  ) {
    return _py_next(
      arg0,
    );
  }

  late final _py_nextPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref)>>('py_next');
  late final _py_next = _py_nextPtr.asFunction<int Function(py_Ref)>();

  /// Python equivalent to `str(val)`.
  bool py_str(
    py_Ref val,
  ) {
    return _py_str(
      val,
    );
  }

  late final _py_strPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_str');
  late final _py_str = _py_strPtr.asFunction<bool Function(py_Ref)>();

  /// Python equivalent to `repr(val)`.
  bool py_repr(
    py_Ref val,
  ) {
    return _py_repr(
      val,
    );
  }

  late final _py_reprPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_repr');
  late final _py_repr = _py_reprPtr.asFunction<bool Function(py_Ref)>();

  /// Python equivalent to `len(val)`.
  bool py_len(
    py_Ref val,
  ) {
    return _py_len(
      val,
    );
  }

  late final _py_lenPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_len');
  late final _py_len = _py_lenPtr.asFunction<bool Function(py_Ref)>();

  /// Python equivalent to `getattr(self, name)`.
  bool py_getattr(
    py_Ref self,
    py_Name name,
  ) {
    return _py_getattr(
      self,
      name,
    );
  }

  late final _py_getattrPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Name)>>(
          'py_getattr');
  late final _py_getattr =
      _py_getattrPtr.asFunction<bool Function(py_Ref, py_Name)>();

  /// Python equivalent to `setattr(self, name, val)`.
  bool py_setattr(
    py_Ref self,
    py_Name name,
    py_Ref val,
  ) {
    return _py_setattr(
      self,
      name,
      val,
    );
  }

  late final _py_setattrPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Name, py_Ref)>>(
          'py_setattr');
  late final _py_setattr =
      _py_setattrPtr.asFunction<bool Function(py_Ref, py_Name, py_Ref)>();

  /// Python equivalent to `delattr(self, name)`.
  bool py_delattr(
    py_Ref self,
    py_Name name,
  ) {
    return _py_delattr(
      self,
      name,
    );
  }

  late final _py_delattrPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Name)>>(
          'py_delattr');
  late final _py_delattr =
      _py_delattrPtr.asFunction<bool Function(py_Ref, py_Name)>();

  /// Python equivalent to `self[key]`.
  bool py_getitem(
    py_Ref self,
    py_Ref key,
  ) {
    return _py_getitem(
      self,
      key,
    );
  }

  late final _py_getitemPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_getitem');
  late final _py_getitem =
      _py_getitemPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// Python equivalent to `self[key] = val`.
  bool py_setitem(
    py_Ref self,
    py_Ref key,
    py_Ref val,
  ) {
    return _py_setitem(
      self,
      key,
      val,
    );
  }

  late final _py_setitemPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref, py_Ref)>>(
          'py_setitem');
  late final _py_setitem =
      _py_setitemPtr.asFunction<bool Function(py_Ref, py_Ref, py_Ref)>();

  /// Python equivalent to `del self[key]`.
  bool py_delitem(
    py_Ref self,
    py_Ref key,
  ) {
    return _py_delitem(
      self,
      key,
    );
  }

  late final _py_delitemPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref)>>(
          'py_delitem');
  late final _py_delitem =
      _py_delitemPtr.asFunction<bool Function(py_Ref, py_Ref)>();

  /// Get a module by path.
  py_GlobalRef py_getmodule(
    ffi.Pointer<ffi.Char> path,
  ) {
    return _py_getmodule(
      path,
    );
  }

  late final _py_getmodulePtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function(ffi.Pointer<ffi.Char>)>>(
          'py_getmodule');
  late final _py_getmodule = _py_getmodulePtr
      .asFunction<py_GlobalRef Function(ffi.Pointer<ffi.Char>)>();

  /// Create a new module.
  py_GlobalRef py_newmodule(
    ffi.Pointer<ffi.Char> path,
  ) {
    return _py_newmodule(
      path,
    );
  }

  late final _py_newmodulePtr =
      _lookup<ffi.NativeFunction<py_GlobalRef Function(ffi.Pointer<ffi.Char>)>>(
          'py_newmodule');
  late final _py_newmodule = _py_newmodulePtr
      .asFunction<py_GlobalRef Function(ffi.Pointer<ffi.Char>)>();

  /// Reload an existing module.
  bool py_importlib_reload(
    py_Ref module,
  ) {
    return _py_importlib_reload(
      module,
    );
  }

  late final _py_importlib_reloadPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>(
          'py_importlib_reload');
  late final _py_importlib_reload =
      _py_importlib_reloadPtr.asFunction<bool Function(py_Ref)>();

  /// Import a module.
  /// The result will be set to `py_retval()`.
  /// -1: error, 0: not found, 1: success
  int py_import(
    ffi.Pointer<ffi.Char> path,
  ) {
    return _py_import(
      path,
    );
  }

  late final _py_importPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>)>>(
          'py_import');
  late final _py_import =
      _py_importPtr.asFunction<int Function(ffi.Pointer<ffi.Char>)>();

  /// Check if there is an unhandled exception.
  bool py_checkexc() {
    return _py_checkexc();
  }

  late final _py_checkexcPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function()>>('py_checkexc');
  late final _py_checkexc = _py_checkexcPtr.asFunction<bool Function()>();

  /// Check if the unhandled exception is an instance of the given type.
  /// If match, the exception will be stored in `py_retval()`.
  bool py_matchexc(
    int type,
  ) {
    return _py_matchexc(
      type,
    );
  }

  late final _py_matchexcPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Type)>>('py_matchexc');
  late final _py_matchexc = _py_matchexcPtr.asFunction<bool Function(int)>();

  /// Clear the unhandled exception.
  /// @param p0 the unwinding point. Use `NULL` if not needed.
  void py_clearexc(
    py_StackRef p0,
  ) {
    return _py_clearexc(
      p0,
    );
  }

  late final _py_clearexcPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_StackRef)>>(
          'py_clearexc');
  late final _py_clearexc =
      _py_clearexcPtr.asFunction<void Function(py_StackRef)>();

  /// Print the unhandled exception.
  void py_printexc() {
    return _py_printexc();
  }

  late final _py_printexcPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_printexc');
  late final _py_printexc = _py_printexcPtr.asFunction<void Function()>();

  /// Format the unhandled exception and return a null-terminated string.
  /// The returned string should be freed by the caller.
  ffi.Pointer<ffi.Char> py_formatexc() {
    return _py_formatexc();
  }

  late final _py_formatexcPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
          'py_formatexc');
  late final _py_formatexc =
      _py_formatexcPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();

  /// Raise an exception by type and message. Always return false.
  bool py_exception(
    int type,
    ffi.Pointer<ffi.Char> fmt,
  ) {
    return _py_exception(
      type,
      fmt,
    );
  }

  late final _py_exceptionPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(py_Type, ffi.Pointer<ffi.Char>)>>('py_exception');
  late final _py_exception =
      _py_exceptionPtr.asFunction<bool Function(int, ffi.Pointer<ffi.Char>)>();

  /// Raise an exception object. Always return false.
  bool py_raise(
    py_Ref arg0,
  ) {
    return _py_raise(
      arg0,
    );
  }

  late final _py_raisePtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_raise');
  late final _py_raise = _py_raisePtr.asFunction<bool Function(py_Ref)>();

  bool KeyError(
    py_Ref key,
  ) {
    return _KeyError(
      key,
    );
  }

  late final _KeyErrorPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('KeyError');
  late final _KeyError = _KeyErrorPtr.asFunction<bool Function(py_Ref)>();

  bool StopIteration() {
    return _StopIteration();
  }

  late final _StopIterationPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function()>>('StopIteration');
  late final _StopIteration = _StopIterationPtr.asFunction<bool Function()>();

  void py_debugger_waitforattach(
    ffi.Pointer<ffi.Char> hostname,
    int port,
  ) {
    return _py_debugger_waitforattach(
      hostname,
      port,
    );
  }

  late final _py_debugger_waitforattachPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<ffi.Char>,
              ffi.UnsignedShort)>>('py_debugger_waitforattach');
  late final _py_debugger_waitforattach = _py_debugger_waitforattachPtr
      .asFunction<void Function(ffi.Pointer<ffi.Char>, int)>();

  int py_debugger_status() {
    return _py_debugger_status();
  }

  late final _py_debugger_statusPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function()>>('py_debugger_status');
  late final _py_debugger_status =
      _py_debugger_statusPtr.asFunction<int Function()>();

  void py_debugger_exceptionbreakpoint(
    py_Ref exc,
  ) {
    return _py_debugger_exceptionbreakpoint(
      exc,
    );
  }

  late final _py_debugger_exceptionbreakpointPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref)>>(
          'py_debugger_exceptionbreakpoint');
  late final _py_debugger_exceptionbreakpoint =
      _py_debugger_exceptionbreakpointPtr.asFunction<void Function(py_Ref)>();

  void py_debugger_exit(
    int code,
  ) {
    return _py_debugger_exit(
      code,
    );
  }

  late final _py_debugger_exitPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int)>>(
          'py_debugger_exit');
  late final _py_debugger_exit =
      _py_debugger_exitPtr.asFunction<void Function(int)>();

  /// Create a `tuple` with `n` UNINITIALIZED elements.
  /// You should initialize all elements before using it.
  py_ObjectRef py_newtuple(
    py_OutRef arg0,
    int n,
  ) {
    return _py_newtuple(
      arg0,
      n,
    );
  }

  late final _py_newtuplePtr =
      _lookup<ffi.NativeFunction<py_ObjectRef Function(py_OutRef, ffi.Int)>>(
          'py_newtuple');
  late final _py_newtuple =
      _py_newtuplePtr.asFunction<py_ObjectRef Function(py_OutRef, int)>();

  py_ObjectRef py_tuple_data(
    py_Ref self,
  ) {
    return _py_tuple_data(
      self,
    );
  }

  late final _py_tuple_dataPtr =
      _lookup<ffi.NativeFunction<py_ObjectRef Function(py_Ref)>>(
          'py_tuple_data');
  late final _py_tuple_data =
      _py_tuple_dataPtr.asFunction<py_ObjectRef Function(py_Ref)>();

  py_ObjectRef py_tuple_getitem(
    py_Ref self,
    int i,
  ) {
    return _py_tuple_getitem(
      self,
      i,
    );
  }

  late final _py_tuple_getitemPtr =
      _lookup<ffi.NativeFunction<py_ObjectRef Function(py_Ref, ffi.Int)>>(
          'py_tuple_getitem');
  late final _py_tuple_getitem =
      _py_tuple_getitemPtr.asFunction<py_ObjectRef Function(py_Ref, int)>();

  void py_tuple_setitem(
    py_Ref self,
    int i,
    py_Ref val,
  ) {
    return _py_tuple_setitem(
      self,
      i,
      val,
    );
  }

  late final _py_tuple_setitemPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, ffi.Int, py_Ref)>>(
          'py_tuple_setitem');
  late final _py_tuple_setitem =
      _py_tuple_setitemPtr.asFunction<void Function(py_Ref, int, py_Ref)>();

  int py_tuple_len(
    py_Ref self,
  ) {
    return _py_tuple_len(
      self,
    );
  }

  late final _py_tuple_lenPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref)>>('py_tuple_len');
  late final _py_tuple_len =
      _py_tuple_lenPtr.asFunction<int Function(py_Ref)>();

  /// Create an empty `list`.
  void py_newlist(
    py_OutRef arg0,
  ) {
    return _py_newlist(
      arg0,
    );
  }

  late final _py_newlistPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>('py_newlist');
  late final _py_newlist =
      _py_newlistPtr.asFunction<void Function(py_OutRef)>();

  /// Create a `list` with `n` UNINITIALIZED elements.
  /// You should initialize all elements before using it.
  void py_newlistn(
    py_OutRef arg0,
    int n,
  ) {
    return _py_newlistn(
      arg0,
      n,
    );
  }

  late final _py_newlistnPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, ffi.Int)>>(
          'py_newlistn');
  late final _py_newlistn =
      _py_newlistnPtr.asFunction<void Function(py_OutRef, int)>();

  py_ItemRef py_list_data(
    py_Ref self,
  ) {
    return _py_list_data(
      self,
    );
  }

  late final _py_list_dataPtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Ref)>>('py_list_data');
  late final _py_list_data =
      _py_list_dataPtr.asFunction<py_ItemRef Function(py_Ref)>();

  py_ItemRef py_list_getitem(
    py_Ref self,
    int i,
  ) {
    return _py_list_getitem(
      self,
      i,
    );
  }

  late final _py_list_getitemPtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Ref, ffi.Int)>>(
          'py_list_getitem');
  late final _py_list_getitem =
      _py_list_getitemPtr.asFunction<py_ItemRef Function(py_Ref, int)>();

  void py_list_setitem(
    py_Ref self,
    int i,
    py_Ref val,
  ) {
    return _py_list_setitem(
      self,
      i,
      val,
    );
  }

  late final _py_list_setitemPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, ffi.Int, py_Ref)>>(
          'py_list_setitem');
  late final _py_list_setitem =
      _py_list_setitemPtr.asFunction<void Function(py_Ref, int, py_Ref)>();

  void py_list_delitem(
    py_Ref self,
    int i,
  ) {
    return _py_list_delitem(
      self,
      i,
    );
  }

  late final _py_list_delitemPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, ffi.Int)>>(
          'py_list_delitem');
  late final _py_list_delitem =
      _py_list_delitemPtr.asFunction<void Function(py_Ref, int)>();

  int py_list_len(
    py_Ref self,
  ) {
    return _py_list_len(
      self,
    );
  }

  late final _py_list_lenPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref)>>('py_list_len');
  late final _py_list_len = _py_list_lenPtr.asFunction<int Function(py_Ref)>();

  void py_list_swap(
    py_Ref self,
    int i,
    int j,
  ) {
    return _py_list_swap(
      self,
      i,
      j,
    );
  }

  late final _py_list_swapPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, ffi.Int, ffi.Int)>>(
          'py_list_swap');
  late final _py_list_swap =
      _py_list_swapPtr.asFunction<void Function(py_Ref, int, int)>();

  void py_list_append(
    py_Ref self,
    py_Ref val,
  ) {
    return _py_list_append(
      self,
      val,
    );
  }

  late final _py_list_appendPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, py_Ref)>>(
          'py_list_append');
  late final _py_list_append =
      _py_list_appendPtr.asFunction<void Function(py_Ref, py_Ref)>();

  py_ItemRef py_list_emplace(
    py_Ref self,
  ) {
    return _py_list_emplace(
      self,
    );
  }

  late final _py_list_emplacePtr =
      _lookup<ffi.NativeFunction<py_ItemRef Function(py_Ref)>>(
          'py_list_emplace');
  late final _py_list_emplace =
      _py_list_emplacePtr.asFunction<py_ItemRef Function(py_Ref)>();

  void py_list_clear(
    py_Ref self,
  ) {
    return _py_list_clear(
      self,
    );
  }

  late final _py_list_clearPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref)>>('py_list_clear');
  late final _py_list_clear =
      _py_list_clearPtr.asFunction<void Function(py_Ref)>();

  void py_list_insert(
    py_Ref self,
    int i,
    py_Ref val,
  ) {
    return _py_list_insert(
      self,
      i,
      val,
    );
  }

  late final _py_list_insertPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, ffi.Int, py_Ref)>>(
          'py_list_insert');
  late final _py_list_insert =
      _py_list_insertPtr.asFunction<void Function(py_Ref, int, py_Ref)>();

  /// Create an empty `dict`.
  void py_newdict(
    py_OutRef arg0,
  ) {
    return _py_newdict(
      arg0,
    );
  }

  late final _py_newdictPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>('py_newdict');
  late final _py_newdict =
      _py_newdictPtr.asFunction<void Function(py_OutRef)>();

  /// -1: error, 0: not found, 1: found
  int py_dict_getitem(
    py_Ref self,
    py_Ref key,
  ) {
    return _py_dict_getitem(
      self,
      key,
    );
  }

  late final _py_dict_getitemPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref, py_Ref)>>(
          'py_dict_getitem');
  late final _py_dict_getitem =
      _py_dict_getitemPtr.asFunction<int Function(py_Ref, py_Ref)>();

  /// true: success, false: error
  bool py_dict_setitem(
    py_Ref self,
    py_Ref key,
    py_Ref val,
  ) {
    return _py_dict_setitem(
      self,
      key,
      val,
    );
  }

  late final _py_dict_setitemPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_Ref, py_Ref)>>(
          'py_dict_setitem');
  late final _py_dict_setitem =
      _py_dict_setitemPtr.asFunction<bool Function(py_Ref, py_Ref, py_Ref)>();

  /// -1: error, 0: not found, 1: found (and deleted)
  int py_dict_delitem(
    py_Ref self,
    py_Ref key,
  ) {
    return _py_dict_delitem(
      self,
      key,
    );
  }

  late final _py_dict_delitemPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref, py_Ref)>>(
          'py_dict_delitem');
  late final _py_dict_delitem =
      _py_dict_delitemPtr.asFunction<int Function(py_Ref, py_Ref)>();

  /// -1: error, 0: not found, 1: found
  int py_dict_getitem_by_str(
    py_Ref self,
    ffi.Pointer<ffi.Char> key,
  ) {
    return _py_dict_getitem_by_str(
      self,
      key,
    );
  }

  late final _py_dict_getitem_by_strPtr = _lookup<
          ffi.NativeFunction<ffi.Int Function(py_Ref, ffi.Pointer<ffi.Char>)>>(
      'py_dict_getitem_by_str');
  late final _py_dict_getitem_by_str = _py_dict_getitem_by_strPtr
      .asFunction<int Function(py_Ref, ffi.Pointer<ffi.Char>)>();

  /// -1: error, 0: not found, 1: found
  int py_dict_getitem_by_int(
    py_Ref self,
    int key,
  ) {
    return _py_dict_getitem_by_int(
      self,
      key,
    );
  }

  late final _py_dict_getitem_by_intPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref, py_i64)>>(
          'py_dict_getitem_by_int');
  late final _py_dict_getitem_by_int =
      _py_dict_getitem_by_intPtr.asFunction<int Function(py_Ref, int)>();

  /// true: success, false: error
  bool py_dict_setitem_by_str(
    py_Ref self,
    ffi.Pointer<ffi.Char> key,
    py_Ref val,
  ) {
    return _py_dict_setitem_by_str(
      self,
      key,
      val,
    );
  }

  late final _py_dict_setitem_by_strPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(py_Ref, ffi.Pointer<ffi.Char>,
              py_Ref)>>('py_dict_setitem_by_str');
  late final _py_dict_setitem_by_str = _py_dict_setitem_by_strPtr
      .asFunction<bool Function(py_Ref, ffi.Pointer<ffi.Char>, py_Ref)>();

  /// true: success, false: error
  bool py_dict_setitem_by_int(
    py_Ref self,
    int key,
    py_Ref val,
  ) {
    return _py_dict_setitem_by_int(
      self,
      key,
      val,
    );
  }

  late final _py_dict_setitem_by_intPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, py_i64, py_Ref)>>(
          'py_dict_setitem_by_int');
  late final _py_dict_setitem_by_int = _py_dict_setitem_by_intPtr
      .asFunction<bool Function(py_Ref, int, py_Ref)>();

  /// -1: error, 0: not found, 1: found (and deleted)
  int py_dict_delitem_by_str(
    py_Ref self,
    ffi.Pointer<ffi.Char> key,
  ) {
    return _py_dict_delitem_by_str(
      self,
      key,
    );
  }

  late final _py_dict_delitem_by_strPtr = _lookup<
          ffi.NativeFunction<ffi.Int Function(py_Ref, ffi.Pointer<ffi.Char>)>>(
      'py_dict_delitem_by_str');
  late final _py_dict_delitem_by_str = _py_dict_delitem_by_strPtr
      .asFunction<int Function(py_Ref, ffi.Pointer<ffi.Char>)>();

  /// -1: error, 0: not found, 1: found (and deleted)
  int py_dict_delitem_by_int(
    py_Ref self,
    int key,
  ) {
    return _py_dict_delitem_by_int(
      self,
      key,
    );
  }

  late final _py_dict_delitem_by_intPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref, py_i64)>>(
          'py_dict_delitem_by_int');
  late final _py_dict_delitem_by_int =
      _py_dict_delitem_by_intPtr.asFunction<int Function(py_Ref, int)>();

  /// true: success, false: error
  bool py_dict_apply(
    py_Ref self,
    ffi.Pointer<
            ffi.NativeFunction<
                ffi.Bool Function(
                    py_Ref key, py_Ref val, ffi.Pointer<ffi.Void> ctx)>>
        f,
    ffi.Pointer<ffi.Void> ctx,
  ) {
    return _py_dict_apply(
      self,
      f,
      ctx,
    );
  }

  late final _py_dict_applyPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              py_Ref,
              ffi.Pointer<
                  ffi.NativeFunction<
                      ffi.Bool Function(
                          py_Ref key, py_Ref val, ffi.Pointer<ffi.Void> ctx)>>,
              ffi.Pointer<ffi.Void>)>>('py_dict_apply');
  late final _py_dict_apply = _py_dict_applyPtr.asFunction<
      bool Function(
          py_Ref,
          ffi.Pointer<
              ffi.NativeFunction<
                  ffi.Bool Function(
                      py_Ref key, py_Ref val, ffi.Pointer<ffi.Void> ctx)>>,
          ffi.Pointer<ffi.Void>)>();

  /// noexcept
  int py_dict_len(
    py_Ref self,
  ) {
    return _py_dict_len(
      self,
    );
  }

  late final _py_dict_lenPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref)>>('py_dict_len');
  late final _py_dict_len = _py_dict_lenPtr.asFunction<int Function(py_Ref)>();

  /// Create an UNINITIALIZED `slice` object.
  /// You should use `py_setslot()` to set `start`, `stop`, and `step`.
  py_ObjectRef py_newslice(
    py_OutRef arg0,
  ) {
    return _py_newslice(
      arg0,
    );
  }

  late final _py_newslicePtr =
      _lookup<ffi.NativeFunction<py_ObjectRef Function(py_OutRef)>>(
          'py_newslice');
  late final _py_newslice =
      _py_newslicePtr.asFunction<py_ObjectRef Function(py_OutRef)>();

  /// Create a `slice` object from 3 integers.
  void py_newsliceint(
    py_OutRef out,
    int start,
    int stop,
    int step,
  ) {
    return _py_newsliceint(
      out,
      start,
      stop,
      step,
    );
  }

  late final _py_newsliceintPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              py_OutRef, py_i64, py_i64, py_i64)>>('py_newsliceint');
  late final _py_newsliceint =
      _py_newsliceintPtr.asFunction<void Function(py_OutRef, int, int, int)>();

  /// random module
  void py_newRandom(
    py_OutRef out,
  ) {
    return _py_newRandom(
      out,
    );
  }

  late final _py_newRandomPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef)>>('py_newRandom');
  late final _py_newRandom =
      _py_newRandomPtr.asFunction<void Function(py_OutRef)>();

  void py_Random_seed(
    py_Ref self,
    int seed,
  ) {
    return _py_Random_seed(
      self,
      seed,
    );
  }

  late final _py_Random_seedPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_Ref, py_i64)>>(
          'py_Random_seed');
  late final _py_Random_seed =
      _py_Random_seedPtr.asFunction<void Function(py_Ref, int)>();

  double py_Random_random(
    py_Ref self,
  ) {
    return _py_Random_random(
      self,
    );
  }

  late final _py_Random_randomPtr =
      _lookup<ffi.NativeFunction<py_f64 Function(py_Ref)>>('py_Random_random');
  late final _py_Random_random =
      _py_Random_randomPtr.asFunction<double Function(py_Ref)>();

  double py_Random_uniform(
    py_Ref self,
    double a,
    double b,
  ) {
    return _py_Random_uniform(
      self,
      a,
      b,
    );
  }

  late final _py_Random_uniformPtr =
      _lookup<ffi.NativeFunction<py_f64 Function(py_Ref, py_f64, py_f64)>>(
          'py_Random_uniform');
  late final _py_Random_uniform = _py_Random_uniformPtr
      .asFunction<double Function(py_Ref, double, double)>();

  int py_Random_randint(
    py_Ref self,
    int a,
    int b,
  ) {
    return _py_Random_randint(
      self,
      a,
      b,
    );
  }

  late final _py_Random_randintPtr =
      _lookup<ffi.NativeFunction<py_i64 Function(py_Ref, py_i64, py_i64)>>(
          'py_Random_randint');
  late final _py_Random_randint =
      _py_Random_randintPtr.asFunction<int Function(py_Ref, int, int)>();

  /// array2d module
  void py_newarray2d(
    py_OutRef out,
    int width,
    int height,
  ) {
    return _py_newarray2d(
      out,
      width,
      height,
    );
  }

  late final _py_newarray2dPtr = _lookup<
          ffi.NativeFunction<ffi.Void Function(py_OutRef, ffi.Int, ffi.Int)>>(
      'py_newarray2d');
  late final _py_newarray2d =
      _py_newarray2dPtr.asFunction<void Function(py_OutRef, int, int)>();

  int py_array2d_getwidth(
    py_Ref self,
  ) {
    return _py_array2d_getwidth(
      self,
    );
  }

  late final _py_array2d_getwidthPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref)>>(
          'py_array2d_getwidth');
  late final _py_array2d_getwidth =
      _py_array2d_getwidthPtr.asFunction<int Function(py_Ref)>();

  int py_array2d_getheight(
    py_Ref self,
  ) {
    return _py_array2d_getheight(
      self,
    );
  }

  late final _py_array2d_getheightPtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(py_Ref)>>(
          'py_array2d_getheight');
  late final _py_array2d_getheight =
      _py_array2d_getheightPtr.asFunction<int Function(py_Ref)>();

  py_ObjectRef py_array2d_getitem(
    py_Ref self,
    int x,
    int y,
  ) {
    return _py_array2d_getitem(
      self,
      x,
      y,
    );
  }

  late final _py_array2d_getitemPtr = _lookup<
          ffi.NativeFunction<py_ObjectRef Function(py_Ref, ffi.Int, ffi.Int)>>(
      'py_array2d_getitem');
  late final _py_array2d_getitem = _py_array2d_getitemPtr
      .asFunction<py_ObjectRef Function(py_Ref, int, int)>();

  void py_array2d_setitem(
    py_Ref self,
    int x,
    int y,
    py_Ref val,
  ) {
    return _py_array2d_setitem(
      self,
      x,
      y,
      val,
    );
  }

  late final _py_array2d_setitemPtr = _lookup<
          ffi
          .NativeFunction<ffi.Void Function(py_Ref, ffi.Int, ffi.Int, py_Ref)>>(
      'py_array2d_setitem');
  late final _py_array2d_setitem = _py_array2d_setitemPtr
      .asFunction<void Function(py_Ref, int, int, py_Ref)>();

  /// vmath module
  void py_newvec2(
    py_OutRef out,
    c11_vec2 arg1,
  ) {
    return _py_newvec2(
      out,
      arg1,
    );
  }

  late final _py_newvec2Ptr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, c11_vec2)>>(
          'py_newvec2');
  late final _py_newvec2 =
      _py_newvec2Ptr.asFunction<void Function(py_OutRef, c11_vec2)>();

  void py_newvec3(
    py_OutRef out,
    c11_vec3 arg1,
  ) {
    return _py_newvec3(
      out,
      arg1,
    );
  }

  late final _py_newvec3Ptr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, c11_vec3)>>(
          'py_newvec3');
  late final _py_newvec3 =
      _py_newvec3Ptr.asFunction<void Function(py_OutRef, c11_vec3)>();

  void py_newvec2i(
    py_OutRef out,
    c11_vec2i arg1,
  ) {
    return _py_newvec2i(
      out,
      arg1,
    );
  }

  late final _py_newvec2iPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, c11_vec2i)>>(
          'py_newvec2i');
  late final _py_newvec2i =
      _py_newvec2iPtr.asFunction<void Function(py_OutRef, c11_vec2i)>();

  void py_newvec3i(
    py_OutRef out,
    c11_vec3i arg1,
  ) {
    return _py_newvec3i(
      out,
      arg1,
    );
  }

  late final _py_newvec3iPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, c11_vec3i)>>(
          'py_newvec3i');
  late final _py_newvec3i =
      _py_newvec3iPtr.asFunction<void Function(py_OutRef, c11_vec3i)>();

  void py_newvec4i(
    py_OutRef out,
    c11_vec4i arg1,
  ) {
    return _py_newvec4i(
      out,
      arg1,
    );
  }

  late final _py_newvec4iPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, c11_vec4i)>>(
          'py_newvec4i');
  late final _py_newvec4i =
      _py_newvec4iPtr.asFunction<void Function(py_OutRef, c11_vec4i)>();

  void py_newcolor32(
    py_OutRef out,
    c11_color32 arg1,
  ) {
    return _py_newcolor32(
      out,
      arg1,
    );
  }

  late final _py_newcolor32Ptr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_OutRef, c11_color32)>>(
          'py_newcolor32');
  late final _py_newcolor32 =
      _py_newcolor32Ptr.asFunction<void Function(py_OutRef, c11_color32)>();

  ffi.Pointer<c11_mat3x3> py_newmat3x3(
    py_OutRef out,
  ) {
    return _py_newmat3x3(
      out,
    );
  }

  late final _py_newmat3x3Ptr =
      _lookup<ffi.NativeFunction<ffi.Pointer<c11_mat3x3> Function(py_OutRef)>>(
          'py_newmat3x3');
  late final _py_newmat3x3 = _py_newmat3x3Ptr
      .asFunction<ffi.Pointer<c11_mat3x3> Function(py_OutRef)>();

  c11_vec2 py_tovec2(
    py_Ref self,
  ) {
    return _py_tovec2(
      self,
    );
  }

  late final _py_tovec2Ptr =
      _lookup<ffi.NativeFunction<c11_vec2 Function(py_Ref)>>('py_tovec2');
  late final _py_tovec2 = _py_tovec2Ptr.asFunction<c11_vec2 Function(py_Ref)>();

  c11_vec3 py_tovec3(
    py_Ref self,
  ) {
    return _py_tovec3(
      self,
    );
  }

  late final _py_tovec3Ptr =
      _lookup<ffi.NativeFunction<c11_vec3 Function(py_Ref)>>('py_tovec3');
  late final _py_tovec3 = _py_tovec3Ptr.asFunction<c11_vec3 Function(py_Ref)>();

  c11_vec2i py_tovec2i(
    py_Ref self,
  ) {
    return _py_tovec2i(
      self,
    );
  }

  late final _py_tovec2iPtr =
      _lookup<ffi.NativeFunction<c11_vec2i Function(py_Ref)>>('py_tovec2i');
  late final _py_tovec2i =
      _py_tovec2iPtr.asFunction<c11_vec2i Function(py_Ref)>();

  c11_vec3i py_tovec3i(
    py_Ref self,
  ) {
    return _py_tovec3i(
      self,
    );
  }

  late final _py_tovec3iPtr =
      _lookup<ffi.NativeFunction<c11_vec3i Function(py_Ref)>>('py_tovec3i');
  late final _py_tovec3i =
      _py_tovec3iPtr.asFunction<c11_vec3i Function(py_Ref)>();

  c11_vec4i py_tovec4i(
    py_Ref self,
  ) {
    return _py_tovec4i(
      self,
    );
  }

  late final _py_tovec4iPtr =
      _lookup<ffi.NativeFunction<c11_vec4i Function(py_Ref)>>('py_tovec4i');
  late final _py_tovec4i =
      _py_tovec4iPtr.asFunction<c11_vec4i Function(py_Ref)>();

  ffi.Pointer<c11_mat3x3> py_tomat3x3(
    py_Ref self,
  ) {
    return _py_tomat3x3(
      self,
    );
  }

  late final _py_tomat3x3Ptr =
      _lookup<ffi.NativeFunction<ffi.Pointer<c11_mat3x3> Function(py_Ref)>>(
          'py_tomat3x3');
  late final _py_tomat3x3 =
      _py_tomat3x3Ptr.asFunction<ffi.Pointer<c11_mat3x3> Function(py_Ref)>();

  c11_color32 py_tocolor32(
    py_Ref self,
  ) {
    return _py_tocolor32(
      self,
    );
  }

  late final _py_tocolor32Ptr =
      _lookup<ffi.NativeFunction<c11_color32 Function(py_Ref)>>('py_tocolor32');
  late final _py_tocolor32 =
      _py_tocolor32Ptr.asFunction<c11_color32 Function(py_Ref)>();

  /// json module *************/
  /// /// Python equivalent to `json.dumps(val)`.
  bool py_json_dumps(
    py_Ref val,
    int indent,
  ) {
    return _py_json_dumps(
      val,
      indent,
    );
  }

  late final _py_json_dumpsPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref, ffi.Int)>>(
          'py_json_dumps');
  late final _py_json_dumps =
      _py_json_dumpsPtr.asFunction<bool Function(py_Ref, int)>();

  /// Python equivalent to `json.loads(val)`.
  bool py_json_loads(
    ffi.Pointer<ffi.Char> source,
  ) {
    return _py_json_loads(
      source,
    );
  }

  late final _py_json_loadsPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Char>)>>(
          'py_json_loads');
  late final _py_json_loads =
      _py_json_loadsPtr.asFunction<bool Function(ffi.Pointer<ffi.Char>)>();

  /// pickle module *************/
  /// /// Python equivalent to `pickle.dumps(val)`.
  bool py_pickle_dumps(
    py_Ref val,
  ) {
    return _py_pickle_dumps(
      val,
    );
  }

  late final _py_pickle_dumpsPtr =
      _lookup<ffi.NativeFunction<ffi.Bool Function(py_Ref)>>('py_pickle_dumps');
  late final _py_pickle_dumps =
      _py_pickle_dumpsPtr.asFunction<bool Function(py_Ref)>();

  /// Python equivalent to `pickle.loads(val)`.
  bool py_pickle_loads(
    ffi.Pointer<ffi.UnsignedChar> data,
    int size,
  ) {
    return _py_pickle_loads(
      data,
      size,
    );
  }

  late final _py_pickle_loadsPtr = _lookup<
      ffi.NativeFunction<
          ffi.Bool Function(
              ffi.Pointer<ffi.UnsignedChar>, ffi.Int)>>('py_pickle_loads');
  late final _py_pickle_loads = _py_pickle_loadsPtr
      .asFunction<bool Function(ffi.Pointer<ffi.UnsignedChar>, int)>();

  /// pkpy module *************/
  /// /// Begin the watchdog with `timeout` in milliseconds.
  /// /// `PK_ENABLE_WATCHDOG` must be defined to `1` to use this feature.
  /// /// You need to call `py_watchdog_end()` later.
  /// /// If `timeout` is reached, `TimeoutError` will be raised.
  void py_watchdog_begin(
    int timeout,
  ) {
    return _py_watchdog_begin(
      timeout,
    );
  }

  late final _py_watchdog_beginPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(py_i64)>>(
          'py_watchdog_begin');
  late final _py_watchdog_begin =
      _py_watchdog_beginPtr.asFunction<void Function(int)>();

  /// Reset the watchdog.
  void py_watchdog_end() {
    return _py_watchdog_end();
  }

  late final _py_watchdog_endPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_watchdog_end');
  late final _py_watchdog_end =
      _py_watchdog_endPtr.asFunction<void Function()>();

  void py_profiler_begin() {
    return _py_profiler_begin();
  }

  late final _py_profiler_beginPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_profiler_begin');
  late final _py_profiler_begin =
      _py_profiler_beginPtr.asFunction<void Function()>();

  void py_profiler_end() {
    return _py_profiler_end();
  }

  late final _py_profiler_endPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_profiler_end');
  late final _py_profiler_end =
      _py_profiler_endPtr.asFunction<void Function()>();

  void py_profiler_reset() {
    return _py_profiler_reset();
  }

  late final _py_profiler_resetPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function()>>('py_profiler_reset');
  late final _py_profiler_reset =
      _py_profiler_resetPtr.asFunction<void Function()>();

  ffi.Pointer<ffi.Char> py_profiler_report() {
    return _py_profiler_report();
  }

  late final _py_profiler_reportPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
          'py_profiler_report');
  late final _py_profiler_report =
      _py_profiler_reportPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();

  /// Others
  int time_ns() {
    return _time_ns();
  }

  late final _time_nsPtr =
      _lookup<ffi.NativeFunction<ffi.Int64 Function()>>('time_ns');
  late final _time_ns = _time_nsPtr.asFunction<int Function()>();

  int time_monotonic_ns() {
    return _time_monotonic_ns();
  }

  late final _time_monotonic_nsPtr =
      _lookup<ffi.NativeFunction<ffi.Int64 Function()>>('time_monotonic_ns');
  late final _time_monotonic_ns =
      _time_monotonic_nsPtr.asFunction<int Function()>();

  /// An utility function to read a line from stdin for REPL.
  int py_replinput(
    ffi.Pointer<ffi.Char> buf,
    int max_size,
  ) {
    return _py_replinput(
      buf,
      max_size,
    );
  }

  late final _py_replinputPtr = _lookup<
          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>, ffi.Int)>>(
      'py_replinput');
  late final _py_replinput =
      _py_replinputPtr.asFunction<int Function(ffi.Pointer<ffi.Char>, int)>();
}

final class py_OpaqueName extends ffi.Opaque {}

final class py_TValue extends ffi.Struct {
  @py_Type()
  external int type;

  @ffi.Bool()
  external bool is_ptr;

  @ffi.Int()
  external int extra;

  external UnnamedUnion1 unnamed;
}

/// An integer that represents a python type. `0` is invalid.
typedef py_Type = ffi.Int16;

final class UnnamedUnion1 extends ffi.Union {
  @ffi.Int64()
  external int _i64;

  @ffi.Double()
  external double _f64;

  @ffi.Bool()
  external bool _bool;

  external py_CFunction _cfunc;

  external ffi.Pointer<ffi.Void> _obj;

  external ffi.Pointer<ffi.Void> _ptr;

  @ffi.Array.multi([16])
  external ffi.Array<ffi.Char> _chars;
}

/// Native function signature.
/// @param argc number of arguments.
/// @param argv array of arguments. Use `py_arg(i)` macro to get the i-th argument.
/// @return `true` if the function is successful or `false` if an exception is raised.
typedef py_CFunction = ffi.Pointer<
    ffi.NativeFunction<ffi.Bool Function(ffi.Int argc, py_StackRef argv)>>;

/// A specific location in the value stack of the VM.
typedef py_StackRef = ffi.Pointer<py_TValue>;

/// A string view type. It is helpful for passing strings which are not null-terminated.
final class c11_sv extends ffi.Struct {
  external ffi.Pointer<ffi.Char> data;

  @ffi.Int()
  external int size;
}

final class py_Frame extends ffi.Opaque {}

/// An enum for tracing events.
abstract class py_TraceEvent {
  static const int TRACE_EVENT_LINE = 0;
  static const int TRACE_EVENT_PUSH = 1;
  static const int TRACE_EVENT_POP = 2;
}

/// A struct contains the callbacks of the VM.
final class py_Callbacks extends ffi.Struct {
  /// Used by `__import__` to load a source or compiled module.
  external ffi.Pointer<
          ffi.NativeFunction<
              ffi.Pointer<ffi.Char> Function(
                  ffi.Pointer<ffi.Char> path, ffi.Pointer<ffi.Int> data_size)>>
      importfile;

  /// Called before `importfile` to lazy-import a C module.
  external ffi
      .Pointer<ffi.NativeFunction<py_GlobalRef Function(ffi.Pointer<ffi.Char>)>>
      lazyimport;

  /// Used by `print` to output a string.
  external ffi
      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>
      print;

  /// Flush the output buffer of `print`.
  external ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> flush;

  /// Used by `input` to get a character.
  external ffi.Pointer<ffi.NativeFunction<ffi.Int Function()>> getchr;

  /// Used by `gc.collect()` to mark extra objects for garbage collection.
  external ffi.Pointer<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<
                      ffi.NativeFunction<
                          ffi.Void Function(
                              py_Ref val, ffi.Pointer<ffi.Void> ctx)>>
                  f,
              ffi.Pointer<ffi.Void> ctx)>> gc_mark;

  /// Used by `PRINT_EXPR` bytecode.
  external ffi.Pointer<ffi.NativeFunction<ffi.Bool Function(py_Ref val)>>
      displayhook;
}

/// A global reference which has the same lifespan as the VM.
typedef py_GlobalRef = ffi.Pointer<py_TValue>;

/// A generic reference to a python object.
typedef py_Ref = ffi.Pointer<py_TValue>;

/// A struct contains the application-level callbacks.
final class py_AppCallbacks extends ffi.Struct {
  external ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Int index)>>
      on_vm_ctor;

  external ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Int index)>>
      on_vm_dtor;
}

/// Python compiler modes.
/// + `EXEC_MODE`: for statements.
/// + `EVAL_MODE`: for expressions.
/// + `SINGLE_MODE`: for REPL or jupyter notebook execution.
/// + `RELOAD_MODE`: for reloading a module without allocating new types if possible.
abstract class py_CompileMode {
  static const int EXEC_MODE = 0;
  static const int EVAL_MODE = 1;
  static const int SINGLE_MODE = 2;
  static const int RELOAD_MODE = 3;
}

typedef py_TraceFunc = ffi.Pointer<
    ffi.NativeFunction<ffi.Void Function(ffi.Pointer<py_Frame>, ffi.Int32)>>;

/// An output reference for returning a value. Only use this for function arguments.
typedef py_OutRef = ffi.Pointer<py_TValue>;

/// A 64-bit integer type. Corresponds to `int` in python.
typedef py_i64 = ffi.Int64;

/// A 64-bit floating-point type. Corresponds to `float` in python.
typedef py_f64 = ffi.Double;

/// A pointer that represents a python identifier. For fast name resolution.
typedef py_Name = ffi.Pointer<py_OpaqueName>;

/// A generic destructor function.
typedef py_Dtor
    = ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>;

/// An item reference to a container object. It invalidates when the container is modified.
typedef py_ItemRef = ffi.Pointer<py_TValue>;

/// A reference which has the same lifespan as the python object.
typedef py_ObjectRef = ffi.Pointer<py_TValue>;

final class c11_vec2 extends ffi.Union {
  external UnnamedStruct1 unnamed;

  @ffi.Array.multi([2])
  external ffi.Array<ffi.Float> data;
}

final class UnnamedStruct1 extends ffi.Struct {
  @ffi.Float()
  external double x;

  @ffi.Float()
  external double y;
}

final class c11_vec3 extends ffi.Union {
  external UnnamedStruct2 unnamed;

  @ffi.Array.multi([3])
  external ffi.Array<ffi.Float> data;
}

final class UnnamedStruct2 extends ffi.Struct {
  @ffi.Float()
  external double x;

  @ffi.Float()
  external double y;

  @ffi.Float()
  external double z;
}

final class c11_vec2i extends ffi.Union {
  external UnnamedStruct3 unnamed;

  @ffi.Array.multi([2])
  external ffi.Array<ffi.Int> data;

  @ffi.Int64()
  external int _i64;
}

final class UnnamedStruct3 extends ffi.Struct {
  @ffi.Int()
  external int x;

  @ffi.Int()
  external int y;
}

final class c11_vec3i extends ffi.Union {
  external UnnamedStruct4 unnamed;

  @ffi.Array.multi([3])
  external ffi.Array<ffi.Int> data;
}

final class UnnamedStruct4 extends ffi.Struct {
  @ffi.Int()
  external int x;

  @ffi.Int()
  external int y;

  @ffi.Int()
  external int z;
}

final class c11_vec4i extends ffi.Union {
  external UnnamedStruct5 unnamed;

  @ffi.Array.multi([4])
  external ffi.Array<ffi.Int> data;
}

final class UnnamedStruct5 extends ffi.Struct {
  @ffi.Int()
  external int x;

  @ffi.Int()
  external int y;

  @ffi.Int()
  external int z;

  @ffi.Int()
  external int w;
}

final class c11_color32 extends ffi.Union {
  external UnnamedStruct6 unnamed;

  @ffi.Array.multi([4])
  external ffi.Array<ffi.UnsignedChar> data;

  @ffi.Uint32()
  external int u32;
}

final class UnnamedStruct6 extends ffi.Struct {
  @ffi.UnsignedChar()
  external int r;

  @ffi.UnsignedChar()
  external int g;

  @ffi.UnsignedChar()
  external int b;

  @ffi.UnsignedChar()
  external int a;
}

final class c11_mat3x3 extends ffi.Union {
  external UnnamedStruct7 unnamed;

  @ffi.Array.multi([3, 3])
  external ffi.Array<ffi.Array<ffi.Float>> m;

  @ffi.Array.multi([9])
  external ffi.Array<ffi.Float> data;
}

final class UnnamedStruct7 extends ffi.Struct {
  @ffi.Float()
  external double _11;

  @ffi.Float()
  external double _12;

  @ffi.Float()
  external double _13;

  @ffi.Float()
  external double _21;

  @ffi.Float()
  external double _22;

  @ffi.Float()
  external double _23;

  @ffi.Float()
  external double _31;

  @ffi.Float()
  external double _32;

  @ffi.Float()
  external double _33;
}

/// Python favored string formatting.
/// %d: int
/// %i: py_i64 (int64_t)
/// %f: py_f64 (double)
/// %s: const char*
/// %q: c11_sv
/// %v: c11_sv
/// %c: char
/// %p: void*
/// %t: py_Type
/// %n: py_Name
abstract class py_PredefinedType {
  static const int tp_nil = 0;
  static const int tp_object = 1;

  /// py_Type
  static const int tp_type = 2;
  static const int tp_int = 3;
  static const int tp_float = 4;
  static const int tp_bool = 5;
  static const int tp_str = 6;
  static const int tp_str_iterator = 7;

  /// c11_vector
  static const int tp_list = 8;

  /// N slots
  static const int tp_tuple = 9;

  /// 1 slot
  static const int tp_list_iterator = 10;

  /// 1 slot
  static const int tp_tuple_iterator = 11;

  /// 3 slots (start, stop, step)
  static const int tp_slice = 12;
  static const int tp_range = 13;
  static const int tp_range_iterator = 14;
  static const int tp_module = 15;
  static const int tp_function = 16;
  static const int tp_nativefunc = 17;

  /// 2 slots (self, func)
  static const int tp_boundmethod = 18;

  /// 1 slot + py_Type
  static const int tp_super = 19;
  static const int tp_BaseException = 20;
  static const int tp_Exception = 21;
  static const int tp_bytes = 22;
  static const int tp_namedict = 23;
  static const int tp_locals = 24;
  static const int tp_code = 25;
  static const int tp_dict = 26;

  /// 1 slot
  static const int tp_dict_iterator = 27;

  /// 2 slots (getter + setter)
  static const int tp_property = 28;

  /// 1 slot + int level
  static const int tp_star_wrapper = 29;

  /// 1 slot
  static const int tp_staticmethod = 30;

  /// 1 slot
  static const int tp_classmethod = 31;
  static const int tp_NoneType = 32;
  static const int tp_NotImplementedType = 33;
  static const int tp_ellipsis = 34;
  static const int tp_generator = 35;

  /// builtin exceptions
  static const int tp_SystemExit = 36;
  static const int tp_KeyboardInterrupt = 37;
  static const int tp_StopIteration = 38;
  static const int tp_SyntaxError = 39;
  static const int tp_RecursionError = 40;
  static const int tp_OSError = 41;
  static const int tp_NotImplementedError = 42;
  static const int tp_TypeError = 43;
  static const int tp_IndexError = 44;
  static const int tp_ValueError = 45;
  static const int tp_RuntimeError = 46;
  static const int tp_TimeoutError = 47;
  static const int tp_ZeroDivisionError = 48;
  static const int tp_NameError = 49;
  static const int tp_UnboundLocalError = 50;
  static const int tp_AttributeError = 51;
  static const int tp_ImportError = 52;
  static const int tp_AssertionError = 53;
  static const int tp_KeyError = 54;

  /// stdc
  static const int tp_stdc_Memory = 55;
  static const int tp_stdc_Char = 56;
  static const int tp_stdc_UChar = 57;
  static const int tp_stdc_Short = 58;
  static const int tp_stdc_UShort = 59;
  static const int tp_stdc_Int = 60;
  static const int tp_stdc_UInt = 61;
  static const int tp_stdc_Long = 62;
  static const int tp_stdc_ULong = 63;
  static const int tp_stdc_LongLong = 64;
  static const int tp_stdc_ULongLong = 65;
  static const int tp_stdc_Float = 66;
  static const int tp_stdc_Double = 67;
  static const int tp_stdc_Pointer = 68;
  static const int tp_stdc_Bool = 69;

  /// vmath
  static const int tp_vec2 = 70;
  static const int tp_vec3 = 71;
  static const int tp_vec2i = 72;
  static const int tp_vec3i = 73;
  static const int tp_vec4i = 74;
  static const int tp_mat3x3 = 75;
  static const int tp_color32 = 76;

  /// array2d
  static const int tp_array2d_like = 77;
  static const int tp_array2d_like_iterator = 78;
  static const int tp_array2d = 79;
  static const int tp_array2d_view = 80;
  static const int tp_chunked_array2d = 81;
}
