Devel-RunBlock

 view release on metacpan or  search on metacpan

RunBlock.xs  view on Meta::CPAN

      PL_op, OP_NAME(PL_op), cxstack_ix, PL_op->op_next, PL_op->op_sibling);
  }
  fprintf(stderr, "(my_trace_runopts:leave#%d)\n", depth);
  --depth;
  TAINT_NOT;
  return 0;
}
#endif

/* ----------------------------------------------------------------------------
 * dopoptosub_at (pp_ctl.c).
 * ------------------------------------------------------------------------- */
STATIC I32
S_dopoptosub_at(pTHX_ const PERL_CONTEXT *cxstk, I32 startingblock)
{
  I32 i;
  for (i = startingblock; i >= 0; i--)
  {
    switch( CxTYPE(&cxstk[i]) )
    {
      default:
        continue;
      case CXt_EVAL:
      case CXt_SUB:
      case CXt_FORMAT:
        DEBUG_l( Perl_deb(aTHX_ "(Found sub #%ld)\n", (long)i));
        return i;
    }
  }
  return i;
}

/* ----------------------------------------------------------------------------
 * XS codes.
 * ------------------------------------------------------------------------- */

MODULE = Devel::RunBlock    PACKAGE = Devel::RunBlock    

int
_runblock(coderef)
    SV* coderef;
  CODE:
    {
      run_info->prev_op_is_return = 0;
      run_info->old_runops = PL_runops;
      PL_runops = &my_runops;
      call_sv(coderef, G_DISCARD);
      if( run_info->old_runops )
      {
        PL_runops = run_info->old_runops;
        run_info->old_runops = NULL;
      }
      RETVAL = run_info->prev_op_is_return;
    }
  OUTPUT:
    RETVAL

void
_long_wantarray(up)
    int up;
  PPCODE:
    {
      I32 cxix;
      for( cxix = cxstack_ix; up>=0; --up, --cxix )
      {
        cxix = S_dopoptosub_at(aTHX_ cxstack, cxix);
      }
      if (cxix < 0)
        XSRETURN_UNDEF;
      switch (cxstack[cxix].blk_gimme)
      {
      case G_ARRAY:  XSRETURN_YES;
      case G_SCALAR: XSRETURN_NO;
      default:       XSRETURN_UNDEF;
      }
    }

void
_long_return(up)
    int up;
  PPCODE:
    {
      I32 cxix;
      CV* cv_retops;
#if DEBUG_MESSAGES
      fprintf(stderr, "_long_return:enter(up=%d)\n", up)
      for( cxix=cxstack_ix; cxix>=0; --cxix )
      {
        switch( CxTYPE(&cxstack[cxix]) )
        {
        case CXt_NULL:   fprintf(stderr, "  #%d %s\n", cxix, "null"); break;
        case CXt_SUB:    fprintf(stderr, "  #%d %s\n", cxix, "sub"); break;
        case CXt_EVAL:   fprintf(stderr, "  #%d %s\n", cxix, "eval"); break;
        case CXt_LOOP:   fprintf(stderr, "  #%d %s\n", cxix, "loop"); break;
        case CXt_SUBST:  fprintf(stderr, "  #%d %s\n", cxix, "subst"); break;
        case CXt_BLOCK:  fprintf(stderr, "  #%d %s\n", cxix, "block"); break;
        case CXt_FORMAT: fprintf(stderr, "  #%d %s\n", cxix, "format"); break;
        default:         fprintf(stderr, "  #%d %d\n", cxix, CxTYPE(&cxstack[cxix])); break;
        }
      }
#endif
      cxix = cxstack_ix;
      for( ; up>1; --up )
      {
        const PERL_CONTEXT* cx;
        CV* cv;
#if DEBUG_MESSAGES
        fprintf(stderr, "_long_return: up = %d cx <= %d\n", up, cxix);
#endif
        cxix = S_dopoptosub_at(aTHX_ cxstack, cxix);
#if DEBUG_MESSAGES
        fprintf(stderr, "_long_return: up = %d cx => %d\n", up, cxix);
#endif
        if( cxix < 0 )
        {
          croak("_long_return run out callstack");
        }
        cx = &cxstack[cxix];
        if( 0 && CxTYPE(cx)==CXt_EVAL )
        {
          ++up;
          --cxix;
          continue;
        }
        cv = cx->blk_sub.cv;
#if DEBUG_MESSAGES
        fprintf(stderr, "_long_return: up = %d type=%d, cv => %p\n", up, CxTYPE(cx), cv);
#endif
        if( CxTYPE(cx)==CXt_SUB && CvXSUB(cv) )
        {
          croak("_long_return could not through xsub");
        }
        if( up>0 )
        {
          --cxix;
        }
      }
#if DEBUG_MESSAGES
      fprintf(stderr, "_long_return:rewrite ix(%d..%d)..\n", cxix, cxstack_ix);
      fprintf(stderr, "_long_return:rewrite sp(%d..%d/%d)..\n", cxstack[cxix].blk_oldretsp, cxstack[cxstack_ix].blk_oldretsp,PL_retstack_ix);
#endif



( run in 1.243 second using v1.01-cache-2.11-cpan-5511b514fd6 )