mono_tasklets_init ()
{
  InitializeCriticalSection (&tasklets_mutex);
  mono_add_internal_call ("Mono.Tasklets.Continuation::alloc", continuation_alloc);
  mono_add_internal_call ("Mono.Tasklets.Continuation::free", continuation_free);
  mono_add_internal_call ("Mono.Tasklets.Continuation::mark", continuation_mark_frame);
  mono_add_internal_call ("Mono.Tasklets.Continuation::store", continuation_store);
  mono_add_internal_call ("Mono.Tasklets.Continuation::restore", continuation_restore);
}


continuation_restore (struct MonoContinuation * cont, int state)
{
  struct MonoDomain * D.22595;
  void * D.22597;
  struct MonoException * D.22598;
  struct MonoDomain * D.22601;
  long unsigned int D.22603;
  long unsigned int D.22604;
  struct MonoLMF * D.22605;
  struct MonoLMF * * lmf_addr;
  void (*MonoContinuationRestore) (struct MonoContinuation *, int, struct MonoLMF * *) restore_state;

  lmf_addr = mono_get_lmf_addr ();
  restore_state = mono_tasklets_arch_restore ();
  D.22595 = cont->domain;
  if (D.22595 == 0B) goto <D.22593>; else goto <D.22596>;
  <D.22596>:
  D.22597 = cont->return_sp;
  if (D.22597 == 0B) goto <D.22593>; else goto <D.22594>;
  <D.22593>:
  D.22598 = mono_get_exception_argument ("cont", "Continuation not initialized");
  return D.22598;
  <D.22594>:
  D.22595 = cont->domain;
  D.22601 = mono_domain_get ();
  if (D.22595 != D.22601) goto <D.22599>; else goto <D.22602>;
  <D.22602>:
  D.22603 = cont->thread_id;
  D.22604 = GetCurrentThreadId ();
  if (D.22603 != D.22604) goto <D.22599>; else goto <D.22600>;
  <D.22599>:
  D.22598 = mono_get_exception_argument ("cont", "Continuation from another thread or domain");
  return D.22598;
  <D.22600>:
  D.22605 = cont->lmf;
  *lmf_addr = D.22605;
  restore_state (cont, state, lmf_addr);
  monoeg_assertion_message ("* Assertion: should not be reached at %s:%d\n", "tasklets.c", 143);
}


continuation_store (struct MonoContinuation * cont, int state, struct MonoException * * e)
{
  struct MonoDomain * D.22607;
  struct MonoException * D.22610;
  int D.22611;
  struct MonoDomain * D.22614;
  long unsigned int D.22616;
  long unsigned int D.22617;
  struct MonoException * D.22618;
  void * D.22619;
  void * D.22620;
  void * D.22621;
  void * D.22622;
  long int D.22623;
  void * D.22624;
  long int D.22625;
  long int D.22626;
  void * D.22629;
  int D.22631;
  long unsigned int D.22632;
  int D.22634;
  long unsigned int D.22635;
  long unsigned int D.22638;
  void * D.22639;
  int D.22640;
  _Bool D.22643;
  long int D.22644;
  long int D.22645;
  struct MonoGHashTable * keepalive_stacks.0;
  double D.22651;
  double D.22652;
  int D.22653;
  long unsigned int D.22654;
  void * D.22655;
  _Bool D.22658;
  long int D.22659;
  long int D.22660;
  struct MonoLMF * lmf;
  gsize num_bytes;

  lmf = mono_get_lmf ();
  D.22607 = cont->domain;
  if (D.22607 == 0B) goto <D.22608>; else goto <D.22609>;
  <D.22608>:
  D.22610 = mono_get_exception_argument ("cont", "Continuation not initialized");
  *e = D.22610;
  D.22611 = 0;
  return D.22611;
  <D.22609>:
  D.22607 = cont->domain;
  D.22614 = mono_domain_get ();
  if (D.22607 != D.22614) goto <D.22612>; else goto <D.22615>;
  <D.22615>:
  D.22616 = cont->thread_id;
  D.22617 = GetCurrentThreadId ();
  if (D.22616 != D.22617) goto <D.22612>; else goto <D.22613>;
  <D.22612>:
  D.22618 = mono_get_exception_argument ("cont", "Continuation from another thread or domain");
  *e = D.22618;
  D.22611 = 0;
  return D.22611;
  <D.22613>:
  cont->lmf = lmf;
  D.22619 = __builtin_return_address (0);
  D.22620 = __builtin_extract_return_addr (D.22619);
  cont->return_ip = D.22620;
  D.22621 = __builtin_frame_address (0);
  cont->return_sp = D.22621;
  D.22622 = cont->top_sp;
  D.22623 = (long int) D.22622;
  D.22624 = cont->return_sp;
  D.22625 = (long int) D.22624;
  D.22626 = D.22623 - D.22625;
  num_bytes = (gsize) D.22626;
  D.22629 = cont->saved_stack;
  if (D.22629 != 0B) goto <D.22630>; else goto <D.22627>;
  <D.22630>:
  D.22631 = cont->stack_alloc_size;
  D.22632 = (long unsigned int) D.22631;
  if (D.22632 >= num_bytes) goto <D.22633>; else goto <D.22627>;
  <D.22633>:
  D.22634 = cont->stack_used_size;
  D.22635 = (long unsigned int) D.22634;
  if (D.22635 > num_bytes) goto <D.22636>; else goto <D.22637>;
  <D.22636>:
  D.22634 = cont->stack_used_size;
  D.22635 = (long unsigned int) D.22634;
  D.22638 = D.22635 - num_bytes;
  D.22629 = cont->saved_stack;
  D.22639 = D.22629 + num_bytes;
  memset (D.22639, 0, D.22638);
  <D.22637>:
  D.22640 = (int) num_bytes;
  cont->stack_used_size = D.22640;
  goto <D.22628>;
  <D.22627>:
  {
    int ret;

    ret = pthread_mutex_lock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22641>; else goto <D.22642>;
    <D.22641>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22642>:
    D.22643 = ret != 0;
    D.22644 = (long int) D.22643;
    D.22645 = __builtin_expect (D.22644, 0);
    if (D.22645 != 0) goto <D.22646>; else goto <D.22647>;
    <D.22646>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 112, "ret == 0");
    <D.22647>:
  }
  internal_init ();
  D.22629 = cont->saved_stack;
  if (D.22629 != 0B) goto <D.22648>; else goto <D.22649>;
  <D.22648>:
  D.22629 = cont->saved_stack;
  keepalive_stacks.0 = keepalive_stacks;
  mono_g_hash_table_remove (keepalive_stacks.0, D.22629);
  D.22629 = cont->saved_stack;
  mono_gc_free_fixed (D.22629);
  <D.22649>:
  D.22640 = (int) num_bytes;
  cont->stack_used_size = D.22640;
  D.22651 = (double) num_bytes;
  D.22652 = D.22651 * 1.100000000000000088817841970012523233890533447265625e+0;
  D.22653 = (int) D.22652;
  cont->stack_alloc_size = D.22653;
  D.22631 = cont->stack_alloc_size;
  D.22654 = (long unsigned int) D.22631;
  D.22655 = mono_gc_alloc_fixed (D.22654, 0B);
  cont->saved_stack = D.22655;
  D.22629 = cont->saved_stack;
  D.22629 = cont->saved_stack;
  keepalive_stacks.0 = keepalive_stacks;
  mono_g_hash_table_insert (keepalive_stacks.0, D.22629, D.22629);
  {
    int ret;

    ret = pthread_mutex_unlock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22656>; else goto <D.22657>;
    <D.22656>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22657>:
    D.22658 = ret != 0;
    D.22659 = (long int) D.22658;
    D.22660 = __builtin_expect (D.22659, 0);
    if (D.22660 != 0) goto <D.22661>; else goto <D.22662>;
    <D.22661>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 122, "ret == 0");
    <D.22662>:
  }
  <D.22628>:
  D.22624 = cont->return_sp;
  D.22629 = cont->saved_stack;
  memcpy (D.22629, D.22624, num_bytes);
  D.22611 = state;
  return D.22611;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.22666;
  int D.22671;
  void * D.22673;
  long unsigned int D.22674;

  D.22666 = __builtin_constant_p (__len);
  if (D.22666 != 0) goto <D.22667>; else goto <D.22668>;
  <D.22667>:
  if (__len == 0) goto <D.22669>; else goto <D.22670>;
  <D.22669>:
  D.22671 = __builtin_constant_p (__ch);
  if (D.22671 == 0) goto <D.22664>; else goto <D.22672>;
  <D.22672>:
  if (__ch != 0) goto <D.22664>; else goto <D.22665>;
  <D.22664>:
  __warn_memset_zero_len ();
  D.22673 = __dest;
  return D.22673;
  <D.22665>:
  <D.22670>:
  <D.22668>:
  D.22674 = __builtin_object_size (__dest, 0);
  D.22673 = __builtin___memset_chk (__dest, __ch, __len, D.22674);
  return D.22673;
}


internal_init ()
{
  struct MonoGHashTable * keepalive_stacks.1;
  struct MonoGHashTable * keepalive_stacks.2;

  keepalive_stacks.1 = keepalive_stacks;
  if (keepalive_stacks.1 != 0B) goto <D.22677>; else goto <D.22678>;
  <D.22677>:
  return;
  <D.22678>:
  mono_gc_register_root (&keepalive_stacks, 8, 0B);
  keepalive_stacks.2 = mono_g_hash_table_new (0B, 0B);
  keepalive_stacks = keepalive_stacks.2;
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.22681;
  long unsigned int D.22682;

  D.22682 = __builtin_object_size (__dest, 0);
  D.22681 = __builtin___memcpy_chk (__dest, __src, __len, D.22682);
  return D.22681;
}


continuation_mark_frame (struct MonoContinuation * cont)
{
  struct MonoDomain * D.22684;
  struct MonoException * D.22687;
  unsigned int mono_jit_tls_id.3;
  struct MonoLMF * lmf.4;
  struct MonoDomain * D.22690;
  long unsigned int D.22691;
  struct MonoJitInfo * D.22692;
  int D.22569;
  int iftmp.5;
  int D.22568;
  struct MonoMethod * D.22699;
  const char[5] * D.22700;
  unsigned char D.22701;
  int D.22702;
  unsigned char D.22703;
  int D.22704;
  _Bool D.22705;
  _Bool D.22706;
  _Bool D.22707;
  const unsigned char * D.22710;
  unsigned char D.22711;
  int D.22712;
  const unsigned char * D.22713;
  unsigned char D.22714;
  int D.22715;
  _Bool D.22716;
  _Bool D.22717;
  const unsigned char * D.22720;
  unsigned char D.22721;
  int D.22722;
  const unsigned char * D.22723;
  unsigned char D.22724;
  int D.22725;
  _Bool D.22726;
  _Bool D.22727;
  const unsigned char * D.22730;
  unsigned char D.22731;
  int D.22732;
  const unsigned char * D.22733;
  unsigned char D.22734;
  int D.22735;
  struct MonoMethod * D.22737;
  const char * D.22738;
  long int D.22741;
  void * D.22742;
  struct MonoJitTlsData * jit_tls;
  struct MonoLMF * lmf;
  struct MonoContext ctx;
  struct MonoContext new_ctx;
  struct MonoJitInfo * ji;
  struct MonoJitInfo rji;
  int endloop;

  try
    {
      endloop = 0;
      D.22684 = cont->domain;
      if (D.22684 != 0B) goto <D.22685>; else goto <D.22686>;
      <D.22685>:
      D.22687 = mono_get_exception_argument ("cont", "Already marked");
      return D.22687;
      <D.22686>:
      mono_jit_tls_id.3 = mono_jit_tls_id;
      jit_tls = pthread_getspecific (mono_jit_tls_id.3);
      lmf.4 = mono_get_lmf ();
      lmf = lmf.4;
      D.22690 = mono_domain_get ();
      cont->domain = D.22690;
      D.22691 = GetCurrentThreadId ();
      cont->thread_id = D.22691;
      memset (&rji, 0, 48);
      <D.22570>:
      D.22684 = cont->domain;
      ji = mono_find_jit_info (D.22684, jit_tls, &rji, 0B, &ctx, &new_ctx, 0B, &lmf, 0B, 0B);
      D.22692 = ji + 18446744073709551615;
      if (D.22692 > -3B) goto <D.22693>; else goto <D.22694>;
      <D.22693>:
      D.22687 = mono_get_exception_not_supported ("Invalid stack frame");
      return D.22687;
      <D.22694>:
      ctx = new_ctx;
      if (endloop != 0) goto <D.22560>; else goto <D.22695>;
      <D.22695>:
      {
        size_t __s1_len;
        size_t __s2_len;

        __s2_len = 4;
        if (__s2_len <= 3) goto <D.22697>; else goto <D.22698>;
        <D.22697>:
        {
          const unsigned char * __s2;
          int __result;

          D.22699 = jinfo_get_method (ji);
          __s2 = D.22699->name;
          D.22700 = "Mark";
          D.22701 = MEM[(const unsigned char *)D.22700];
          D.22702 = (int) D.22701;
          D.22703 = *__s2;
          D.22704 = (int) D.22703;
          __result = D.22702 - D.22704;
          {
            D.22705 = __s2_len != 0;
            D.22706 = __result == 0;
            D.22707 = D.22705 & D.22706;
            if (D.22707 != 0) goto <D.22708>; else goto <D.22709>;
            <D.22708>:
            D.22710 = &MEM[(void *)"Mark" + 1B];
            D.22711 = *D.22710;
            D.22712 = (int) D.22711;
            D.22713 = __s2 + 1;
            D.22714 = *D.22713;
            D.22715 = (int) D.22714;
            __result = D.22712 - D.22715;
            D.22716 = __s2_len > 1;
            D.22706 = __result == 0;
            D.22717 = D.22716 & D.22706;
            if (D.22717 != 0) goto <D.22718>; else goto <D.22719>;
            <D.22718>:
            D.22720 = &MEM[(void *)"Mark" + 2B];
            D.22721 = *D.22720;
            D.22722 = (int) D.22721;
            D.22723 = __s2 + 2;
            D.22724 = *D.22723;
            D.22725 = (int) D.22724;
            __result = D.22722 - D.22725;
            D.22726 = __s2_len > 2;
            D.22706 = __result == 0;
            D.22727 = D.22726 & D.22706;
            if (D.22727 != 0) goto <D.22728>; else goto <D.22729>;
            <D.22728>:
            D.22730 = &MEM[(void *)"Mark" + 3B];
            D.22731 = *D.22730;
            D.22732 = (int) D.22731;
            D.22733 = __s2 + 3;
            D.22734 = *D.22733;
            D.22735 = (int) D.22734;
            __result = D.22732 - D.22735;
            <D.22729>:
            <D.22719>:
            <D.22709>:
          }
          D.22568 = __result;
        }
        iftmp.5 = -D.22568;
        goto <D.22736>;
        <D.22698>:
        D.22737 = jinfo_get_method (ji);
        D.22738 = D.22737->name;
        iftmp.5 = __builtin_strcmp (D.22738, "Mark");
        <D.22736>:
        D.22569 = iftmp.5;
      }
      if (D.22569 == 0) goto <D.22739>; else goto <D.22740>;
      <D.22739>:
      endloop = 1;
      <D.22740>:
      goto <D.22570>;
      <D.22560>:
      D.22741 = ctx.rsp;
      D.22742 = (void *) D.22741;
      cont->top_sp = D.22742;
      D.22687 = 0B;
      return D.22687;
    }
  finally
    {
      lmf = {CLOBBER};
      ctx = {CLOBBER};
      new_ctx = {CLOBBER};
      rji = {CLOBBER};
    }
}


jinfo_get_method (struct MonoJitInfo * ji)
{
  struct MonoMethod * D.22745;

  D.22745 = mono_jit_info_get_method (ji);
  return D.22745;
}


continuation_free (struct MonoContinuation * cont)
{
  void * D.22747;
  _Bool D.22752;
  long int D.22753;
  long int D.22754;
  struct MonoGHashTable * keepalive_stacks.6;
  _Bool D.22760;
  long int D.22761;
  long int D.22762;

  D.22747 = cont->saved_stack;
  if (D.22747 != 0B) goto <D.22748>; else goto <D.22749>;
  <D.22748>:
  {
    int ret;

    ret = pthread_mutex_lock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22750>; else goto <D.22751>;
    <D.22750>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22751>:
    D.22752 = ret != 0;
    D.22753 = (long int) D.22752;
    D.22754 = __builtin_expect (D.22753, 0);
    if (D.22754 != 0) goto <D.22755>; else goto <D.22756>;
    <D.22755>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 37, "ret == 0");
    <D.22756>:
  }
  D.22747 = cont->saved_stack;
  keepalive_stacks.6 = keepalive_stacks;
  mono_g_hash_table_remove (keepalive_stacks.6, D.22747);
  {
    int ret;

    ret = pthread_mutex_unlock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22758>; else goto <D.22759>;
    <D.22758>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22759>:
    D.22760 = ret != 0;
    D.22761 = (long int) D.22760;
    D.22762 = __builtin_expect (D.22761, 0);
    if (D.22762 != 0) goto <D.22763>; else goto <D.22764>;
    <D.22763>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 39, "ret == 0");
    <D.22764>:
  }
  D.22747 = cont->saved_stack;
  mono_gc_free_fixed (D.22747);
  <D.22749>:
  monoeg_g_free (cont);
}


continuation_alloc ()
{
  void * D.22765;
  struct MonoContinuation * cont;

  cont = monoeg_malloc0 (64);
  D.22765 = cont;
  return D.22765;
}


mono_tasklets_cleanup ()
{

}


