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.22157;
  void * D.22159;
  struct MonoException * D.22160;
  struct MonoDomain * D.22163;
  unsigned int D.22165;
  unsigned int D.22166;
  struct MonoLMF * D.22167;
  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.22157 = cont->domain;
  if (D.22157 == 0B) goto <D.22155>; else goto <D.22158>;
  <D.22158>:
  D.22159 = cont->return_sp;
  if (D.22159 == 0B) goto <D.22155>; else goto <D.22156>;
  <D.22155>:
  D.22160 = mono_get_exception_argument ("cont", "Continuation not initialized");
  return D.22160;
  <D.22156>:
  D.22157 = cont->domain;
  D.22163 = mono_domain_get ();
  if (D.22157 != D.22163) goto <D.22161>; else goto <D.22164>;
  <D.22164>:
  D.22165 = cont->thread_id;
  D.22166 = GetCurrentThreadId ();
  if (D.22165 != D.22166) goto <D.22161>; else goto <D.22162>;
  <D.22161>:
  D.22160 = mono_get_exception_argument ("cont", "Continuation from another thread or domain");
  return D.22160;
  <D.22162>:
  D.22167 = cont->lmf;
  *lmf_addr = D.22167;
  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.22169;
  struct MonoException * D.22172;
  int D.22173;
  struct MonoDomain * D.22176;
  unsigned int D.22178;
  unsigned int D.22179;
  struct MonoException * D.22180;
  void * D.22181;
  void * D.22182;
  void * D.22183;
  void * D.22184;
  int D.22185;
  void * D.22186;
  int D.22187;
  int D.22188;
  void * D.22191;
  int D.22193;
  unsigned int D.22194;
  int D.22196;
  unsigned int D.22197;
  unsigned int D.22200;
  void * D.22201;
  int num_bytes.0;
  _Bool D.22205;
  long int D.22206;
  long int D.22207;
  struct MonoGHashTable * keepalive_stacks.1;
  double D.22213;
  double D.22214;
  int D.22215;
  unsigned int D.22216;
  void * D.22217;
  _Bool D.22220;
  long int D.22221;
  long int D.22222;
  struct MonoLMF * lmf;
  gsize num_bytes;

  lmf = mono_get_lmf ();
  D.22169 = cont->domain;
  if (D.22169 == 0B) goto <D.22170>; else goto <D.22171>;
  <D.22170>:
  D.22172 = mono_get_exception_argument ("cont", "Continuation not initialized");
  *e = D.22172;
  D.22173 = 0;
  return D.22173;
  <D.22171>:
  D.22169 = cont->domain;
  D.22176 = mono_domain_get ();
  if (D.22169 != D.22176) goto <D.22174>; else goto <D.22177>;
  <D.22177>:
  D.22178 = cont->thread_id;
  D.22179 = GetCurrentThreadId ();
  if (D.22178 != D.22179) goto <D.22174>; else goto <D.22175>;
  <D.22174>:
  D.22180 = mono_get_exception_argument ("cont", "Continuation from another thread or domain");
  *e = D.22180;
  D.22173 = 0;
  return D.22173;
  <D.22175>:
  cont->lmf = lmf;
  D.22181 = __builtin_return_address (0);
  D.22182 = __builtin_extract_return_addr (D.22181);
  cont->return_ip = D.22182;
  D.22183 = __builtin_frame_address (0);
  cont->return_sp = D.22183;
  D.22184 = cont->top_sp;
  D.22185 = (int) D.22184;
  D.22186 = cont->return_sp;
  D.22187 = (int) D.22186;
  D.22188 = D.22185 - D.22187;
  num_bytes = (gsize) D.22188;
  D.22191 = cont->saved_stack;
  if (D.22191 != 0B) goto <D.22192>; else goto <D.22189>;
  <D.22192>:
  D.22193 = cont->stack_alloc_size;
  D.22194 = (unsigned int) D.22193;
  if (D.22194 >= num_bytes) goto <D.22195>; else goto <D.22189>;
  <D.22195>:
  D.22196 = cont->stack_used_size;
  D.22197 = (unsigned int) D.22196;
  if (D.22197 > num_bytes) goto <D.22198>; else goto <D.22199>;
  <D.22198>:
  D.22196 = cont->stack_used_size;
  D.22197 = (unsigned int) D.22196;
  D.22200 = D.22197 - num_bytes;
  D.22191 = cont->saved_stack;
  D.22201 = D.22191 + num_bytes;
  memset (D.22201, 0, D.22200);
  <D.22199>:
  num_bytes.0 = (int) num_bytes;
  cont->stack_used_size = num_bytes.0;
  goto <D.22190>;
  <D.22189>:
  {
    int ret;

    ret = pthread_mutex_lock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22203>; else goto <D.22204>;
    <D.22203>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22204>:
    D.22205 = ret != 0;
    D.22206 = (long int) D.22205;
    D.22207 = __builtin_expect (D.22206, 0);
    if (D.22207 != 0) goto <D.22208>; else goto <D.22209>;
    <D.22208>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 112, "ret == 0");
    <D.22209>:
  }
  internal_init ();
  D.22191 = cont->saved_stack;
  if (D.22191 != 0B) goto <D.22210>; else goto <D.22211>;
  <D.22210>:
  D.22191 = cont->saved_stack;
  keepalive_stacks.1 = keepalive_stacks;
  mono_g_hash_table_remove (keepalive_stacks.1, D.22191);
  D.22191 = cont->saved_stack;
  mono_gc_free_fixed (D.22191);
  <D.22211>:
  num_bytes.0 = (int) num_bytes;
  cont->stack_used_size = num_bytes.0;
  D.22213 = (double) num_bytes;
  D.22214 = D.22213 * 1.100000000000000088817841970012523233890533447265625e+0;
  D.22215 = (int) D.22214;
  cont->stack_alloc_size = D.22215;
  D.22193 = cont->stack_alloc_size;
  D.22216 = (unsigned int) D.22193;
  D.22217 = mono_gc_alloc_fixed (D.22216, 0B);
  cont->saved_stack = D.22217;
  D.22191 = cont->saved_stack;
  D.22191 = cont->saved_stack;
  keepalive_stacks.1 = keepalive_stacks;
  mono_g_hash_table_insert (keepalive_stacks.1, D.22191, D.22191);
  {
    int ret;

    ret = pthread_mutex_unlock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22218>; else goto <D.22219>;
    <D.22218>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22219>:
    D.22220 = ret != 0;
    D.22221 = (long int) D.22220;
    D.22222 = __builtin_expect (D.22221, 0);
    if (D.22222 != 0) goto <D.22223>; else goto <D.22224>;
    <D.22223>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 122, "ret == 0");
    <D.22224>:
  }
  <D.22190>:
  D.22186 = cont->return_sp;
  D.22191 = cont->saved_stack;
  memcpy (D.22191, D.22186, num_bytes);
  D.22173 = state;
  return D.22173;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.22228;
  int D.22233;
  void * D.22235;
  unsigned int D.22236;

  D.22228 = __builtin_constant_p (__len);
  if (D.22228 != 0) goto <D.22229>; else goto <D.22230>;
  <D.22229>:
  if (__len == 0) goto <D.22231>; else goto <D.22232>;
  <D.22231>:
  D.22233 = __builtin_constant_p (__ch);
  if (D.22233 == 0) goto <D.22226>; else goto <D.22234>;
  <D.22234>:
  if (__ch != 0) goto <D.22226>; else goto <D.22227>;
  <D.22226>:
  __warn_memset_zero_len ();
  D.22235 = __dest;
  return D.22235;
  <D.22227>:
  <D.22232>:
  <D.22230>:
  D.22236 = __builtin_object_size (__dest, 0);
  D.22235 = __builtin___memset_chk (__dest, __ch, __len, D.22236);
  return D.22235;
}


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

  keepalive_stacks.2 = keepalive_stacks;
  if (keepalive_stacks.2 != 0B) goto <D.22239>; else goto <D.22240>;
  <D.22239>:
  return;
  <D.22240>:
  mono_gc_register_root (&keepalive_stacks, 4, 0B);
  keepalive_stacks.3 = mono_g_hash_table_new (0B, 0B);
  keepalive_stacks = keepalive_stacks.3;
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.22243;
  unsigned int D.22244;

  D.22244 = __builtin_object_size (__dest, 0);
  D.22243 = __builtin___memcpy_chk (__dest, __src, __len, D.22244);
  return D.22243;
}


continuation_mark_frame (struct MonoContinuation * cont)
{
  struct MonoDomain * D.22246;
  struct MonoException * D.22249;
  unsigned int mono_jit_tls_id.4;
  struct MonoLMF * lmf.5;
  struct MonoDomain * D.22252;
  unsigned int D.22253;
  struct MonoJitInfo * D.22254;
  int D.22131;
  int iftmp.6;
  int D.22130;
  struct MonoMethod * D.22261;
  const char[5] * D.22262;
  unsigned char D.22263;
  int D.22264;
  unsigned char D.22265;
  int D.22266;
  _Bool D.22267;
  _Bool D.22268;
  _Bool D.22269;
  const unsigned char * D.22272;
  unsigned char D.22273;
  int D.22274;
  const unsigned char * D.22275;
  unsigned char D.22276;
  int D.22277;
  _Bool D.22278;
  _Bool D.22279;
  const unsigned char * D.22282;
  unsigned char D.22283;
  int D.22284;
  const unsigned char * D.22285;
  unsigned char D.22286;
  int D.22287;
  _Bool D.22288;
  _Bool D.22289;
  const unsigned char * D.22292;
  unsigned char D.22293;
  int D.22294;
  const unsigned char * D.22295;
  unsigned char D.22296;
  int D.22297;
  struct MonoMethod * D.22299;
  const char * D.22300;
  int D.22303;
  void * D.22304;
  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.22246 = cont->domain;
      if (D.22246 != 0B) goto <D.22247>; else goto <D.22248>;
      <D.22247>:
      D.22249 = mono_get_exception_argument ("cont", "Already marked");
      return D.22249;
      <D.22248>:
      mono_jit_tls_id.4 = mono_jit_tls_id;
      jit_tls = pthread_getspecific (mono_jit_tls_id.4);
      lmf.5 = mono_get_lmf ();
      lmf = lmf.5;
      D.22252 = mono_domain_get ();
      cont->domain = D.22252;
      D.22253 = GetCurrentThreadId ();
      cont->thread_id = D.22253;
      memset (&rji, 0, 28);
      <D.22132>:
      D.22246 = cont->domain;
      ji = mono_find_jit_info (D.22246, jit_tls, &rji, 0B, &ctx, &new_ctx, 0B, &lmf, 0B, 0B);
      D.22254 = ji + 4294967295;
      if (D.22254 > 4294967293B) goto <D.22255>; else goto <D.22256>;
      <D.22255>:
      D.22249 = mono_get_exception_not_supported ("Invalid stack frame");
      return D.22249;
      <D.22256>:
      ctx = new_ctx;
      if (endloop != 0) goto <D.22122>; else goto <D.22257>;
      <D.22257>:
      {
        size_t __s1_len;
        size_t __s2_len;

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

          D.22261 = jinfo_get_method (ji);
          __s2 = D.22261->name;
          D.22262 = "Mark";
          D.22263 = MEM[(const unsigned char *)D.22262];
          D.22264 = (int) D.22263;
          D.22265 = *__s2;
          D.22266 = (int) D.22265;
          __result = D.22264 - D.22266;
          {
            D.22267 = __s2_len != 0;
            D.22268 = __result == 0;
            D.22269 = D.22267 & D.22268;
            if (D.22269 != 0) goto <D.22270>; else goto <D.22271>;
            <D.22270>:
            D.22272 = &MEM[(void *)"Mark" + 1B];
            D.22273 = *D.22272;
            D.22274 = (int) D.22273;
            D.22275 = __s2 + 1;
            D.22276 = *D.22275;
            D.22277 = (int) D.22276;
            __result = D.22274 - D.22277;
            D.22278 = __s2_len > 1;
            D.22268 = __result == 0;
            D.22279 = D.22278 & D.22268;
            if (D.22279 != 0) goto <D.22280>; else goto <D.22281>;
            <D.22280>:
            D.22282 = &MEM[(void *)"Mark" + 2B];
            D.22283 = *D.22282;
            D.22284 = (int) D.22283;
            D.22285 = __s2 + 2;
            D.22286 = *D.22285;
            D.22287 = (int) D.22286;
            __result = D.22284 - D.22287;
            D.22288 = __s2_len > 2;
            D.22268 = __result == 0;
            D.22289 = D.22288 & D.22268;
            if (D.22289 != 0) goto <D.22290>; else goto <D.22291>;
            <D.22290>:
            D.22292 = &MEM[(void *)"Mark" + 3B];
            D.22293 = *D.22292;
            D.22294 = (int) D.22293;
            D.22295 = __s2 + 3;
            D.22296 = *D.22295;
            D.22297 = (int) D.22296;
            __result = D.22294 - D.22297;
            <D.22291>:
            <D.22281>:
            <D.22271>:
          }
          D.22130 = __result;
        }
        iftmp.6 = -D.22130;
        goto <D.22298>;
        <D.22260>:
        D.22299 = jinfo_get_method (ji);
        D.22300 = D.22299->name;
        iftmp.6 = __builtin_strcmp (D.22300, "Mark");
        <D.22298>:
        D.22131 = iftmp.6;
      }
      if (D.22131 == 0) goto <D.22301>; else goto <D.22302>;
      <D.22301>:
      endloop = 1;
      <D.22302>:
      goto <D.22132>;
      <D.22122>:
      D.22303 = ctx.esp;
      D.22304 = (void *) D.22303;
      cont->top_sp = D.22304;
      D.22249 = 0B;
      return D.22249;
    }
  finally
    {
      lmf = {CLOBBER};
      ctx = {CLOBBER};
      new_ctx = {CLOBBER};
      rji = {CLOBBER};
    }
}


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

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


continuation_free (struct MonoContinuation * cont)
{
  void * D.22309;
  _Bool D.22314;
  long int D.22315;
  long int D.22316;
  struct MonoGHashTable * keepalive_stacks.7;
  _Bool D.22322;
  long int D.22323;
  long int D.22324;

  D.22309 = cont->saved_stack;
  if (D.22309 != 0B) goto <D.22310>; else goto <D.22311>;
  <D.22310>:
  {
    int ret;

    ret = pthread_mutex_lock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22312>; else goto <D.22313>;
    <D.22312>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_lock result %d", ret);
    <D.22313>:
    D.22314 = ret != 0;
    D.22315 = (long int) D.22314;
    D.22316 = __builtin_expect (D.22315, 0);
    if (D.22316 != 0) goto <D.22317>; else goto <D.22318>;
    <D.22317>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 37, "ret == 0");
    <D.22318>:
  }
  D.22309 = cont->saved_stack;
  keepalive_stacks.7 = keepalive_stacks;
  mono_g_hash_table_remove (keepalive_stacks.7, D.22309);
  {
    int ret;

    ret = pthread_mutex_unlock (&tasklets_mutex.mutex);
    if (ret != 0) goto <D.22320>; else goto <D.22321>;
    <D.22320>:
    monoeg_g_log (0B, 16, "Bad call to mono_mutex_unlock result %d", ret);
    <D.22321>:
    D.22322 = ret != 0;
    D.22323 = (long int) D.22322;
    D.22324 = __builtin_expect (D.22323, 0);
    if (D.22324 != 0) goto <D.22325>; else goto <D.22326>;
    <D.22325>:
    monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "tasklets.c", 39, "ret == 0");
    <D.22326>:
  }
  D.22309 = cont->saved_stack;
  mono_gc_free_fixed (D.22309);
  <D.22311>:
  monoeg_g_free (cont);
}


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

  cont = monoeg_malloc0 (36);
  D.22327 = cont;
  return D.22327;
}


mono_tasklets_cleanup ()
{

}


