Ancient

 view release on metacpan or  search on metacpan

t/1018-trim-maybe.t  view on Meta::CPAN


# maybe as safe accessor pattern
my $config = { timeout => 30 };
is(maybe($config->{timeout}, $config->{timeout} * 2), 60, 'maybe for safe math');
is(maybe($config->{missing}, 100), undef, 'maybe with missing key');

# trim + maybe combo use case
my $input = "  user input  ";
my $cleaned = trim($input);
is($cleaned, "user input", 'trim user input');
is(maybe($cleaned, uc($cleaned)), "USER INPUT", 'maybe transform cleaned input');

done_testing;

xs/const/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/const/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/doubly/doubly.c  view on Meta::CPAN


            current_node_id = node->node_id;
            node_data = node->data ? newSVsv(node->data) : &PL_sv_undef;

            DOUBLY_UNLOCK();

            {
                dSP;
                PUSHMARK(SP);
                XPUSHs(sv_2mortal(node_data));
                PUTBACK;
                call_sv(cb, G_SCALAR);
                SPAGAIN;
                if (SvTRUE(*PL_stack_sp)) {
                    found = 1;
                    found_node_id = current_node_id;
                }
                POPs;
            }

            DOUBLY_LOCK();

xs/doubly/doubly.c  view on Meta::CPAN


            current_node_id = node->node_id;
            node_data = node->data ? newSVsv(node->data) : &PL_sv_undef;

            DOUBLY_UNLOCK();

            {
                dSP;
                PUSHMARK(SP);
                XPUSHs(sv_2mortal(node_data));
                PUTBACK;
                call_sv(cb, G_SCALAR);
                SPAGAIN;
                if (SvTRUE(*PL_stack_sp)) {
                    found = 1;
                }
                POPs;
            }

            DOUBLY_LOCK();
            list = get_list(list_idx);

xs/doubly/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/doubly/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/file/file.c  view on Meta::CPAN

        } else if (entry->perl_callback) {
            /* Call Perl callback */
            dSP;
            int count;

            ENTER;
            SAVETMPS;
            PUSHMARK(SP);
            mXPUSHs(newSVpv(path, 0));
            mXPUSHs(SvREFCNT_inc(result));
            PUTBACK;

            count = call_sv(entry->perl_callback, G_SCALAR);

            SPAGAIN;
            if (count > 0) {
                SV *ret = POPs;
                if (SvOK(ret)) {
                    result = newSVsv(ret);
                } else {
                    ctx.cancel = 1;
                }
            }
            PUTBACK;
            FREETMPS;
            LEAVE;
        }

        if (!result || ctx.cancel) return NULL;
    }

    return result;
}

xs/file/file.c  view on Meta::CPAN

   Custom OP implementations - fastest path
   ============================================ */

/* pp_file_slurp: single path arg on stack */
static OP* pp_file_slurp(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    SV *result = file_slurp_internal(aTHX_ path);
    PUSHs(sv_2mortal(result));
    PUTBACK;
    return NORMAL;
}

/* pp_file_spew: path and data on stack */
static OP* pp_file_spew(pTHX) {
    dSP;
    SV *data = POPs;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    if (file_spew_internal(aTHX_ path, data)) {
        PUSHs(&PL_sv_yes);
    } else {
        PUSHs(&PL_sv_no);
    }
    PUTBACK;
    return NORMAL;
}

/* pp_file_exists: single path arg on stack */
static OP* pp_file_exists(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_exists_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_size: single path arg on stack */
static OP* pp_file_size(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(newSViv(file_size_internal(path))));
    PUTBACK;
    return NORMAL;
}

/* pp_file_is_file: single path arg on stack */
static OP* pp_file_is_file(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_is_file_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_is_dir: single path arg on stack */
static OP* pp_file_is_dir(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_is_dir_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_lines: single path arg on stack */
static OP* pp_file_lines(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    SV *content = file_slurp_internal(aTHX_ path);
    AV *lines;

    if (content == &PL_sv_undef) {
        lines = newAV();
    } else {
        lines = file_split_lines(aTHX_ content);
        SvREFCNT_dec(content);
    }

    PUSHs(sv_2mortal(newRV_noinc((SV*)lines)));
    PUTBACK;
    return NORMAL;
}

/* pp_file_unlink: single path arg on stack */
static OP* pp_file_unlink(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_unlink_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_mkdir: single path arg on stack (mode defaults to 0755) */
static OP* pp_file_mkdir(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_mkdir_internal(path, 0755) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_rmdir: single path arg on stack */
static OP* pp_file_rmdir(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_rmdir_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_touch: single path arg on stack */
static OP* pp_file_touch(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_touch_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_basename: single path arg on stack */
static OP* pp_file_basename(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(file_basename_internal(aTHX_ path)));
    PUTBACK;
    return NORMAL;
}

/* pp_file_dirname: single path arg on stack */
static OP* pp_file_dirname(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(file_dirname_internal(aTHX_ path)));
    PUTBACK;
    return NORMAL;
}

/* pp_file_extname: single path arg on stack */
static OP* pp_file_extname(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(file_extname_internal(aTHX_ path)));
    PUTBACK;
    return NORMAL;
}

/* pp_file_mtime: single path arg on stack */
static OP* pp_file_mtime(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(newSViv(file_mtime_internal(path))));
    PUTBACK;
    return NORMAL;
}

/* pp_file_atime: single path arg on stack */
static OP* pp_file_atime(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(newSViv(file_atime_internal(path))));
    PUTBACK;
    return NORMAL;
}

/* pp_file_ctime: single path arg on stack */
static OP* pp_file_ctime(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(newSViv(file_ctime_internal(path))));
    PUTBACK;
    return NORMAL;
}

/* pp_file_mode: single path arg on stack */
static OP* pp_file_mode(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(sv_2mortal(newSViv(file_mode_internal(path))));
    PUTBACK;
    return NORMAL;
}

/* pp_file_is_link: single path arg on stack */
static OP* pp_file_is_link(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_is_link_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_is_readable: single path arg on stack */
static OP* pp_file_is_readable(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_is_readable_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_is_writable: single path arg on stack */
static OP* pp_file_is_writable(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_is_writable_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_is_executable: single path arg on stack */
static OP* pp_file_is_executable(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_is_executable_internal(path) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_readdir: single path arg on stack */
static OP* pp_file_readdir(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    AV *result = file_readdir_internal(aTHX_ path);
    PUSHs(sv_2mortal(newRV_noinc((SV*)result)));
    PUTBACK;
    return NORMAL;
}

/* pp_file_slurp_raw: single path arg on stack (bypasses hooks) */
static OP* pp_file_slurp_raw(pTHX) {
    dSP;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    SV *result = file_slurp_raw_internal(aTHX_ path);
    PUSHs(sv_2mortal(result));
    PUTBACK;
    return NORMAL;
}

/* pp_file_copy: src and dst on stack */
static OP* pp_file_copy(pTHX) {
    dSP;
    SV *dst_sv = POPs;
    SV *src_sv = POPs;
    const char *src = SvPV_nolen(src_sv);
    const char *dst = SvPV_nolen(dst_sv);
    PUSHs(file_copy_internal(aTHX_ src, dst) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_move: src and dst on stack */
static OP* pp_file_move(pTHX) {
    dSP;
    SV *dst_sv = POPs;
    SV *src_sv = POPs;
    const char *src = SvPV_nolen(src_sv);
    const char *dst = SvPV_nolen(dst_sv);
    PUSHs(file_move_internal(aTHX_ src, dst) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_chmod: path and mode on stack */
static OP* pp_file_chmod(pTHX) {
    dSP;
    SV *mode_sv = POPs;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    int mode = SvIV(mode_sv);
    PUSHs(file_chmod_internal(path, mode) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_append: path and data on stack */
static OP* pp_file_append(pTHX) {
    dSP;
    SV *data = POPs;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_append_internal(aTHX_ path, data) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* pp_file_atomic_spew: path and data on stack */
static OP* pp_file_atomic_spew(pTHX) {
    dSP;
    SV *data = POPs;
    SV *path_sv = POPs;
    const char *path = SvPV_nolen(path_sv);
    PUSHs(file_atomic_spew_internal(aTHX_ path, data) ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/* ============================================
   Call checkers for compile-time optimization
   ============================================ */

/* 1-arg call checker (slurp, exists, size, is_file, is_dir, lines) */
static OP* file_call_checker_1arg(pTHX_ OP *entersubop, GV *namegv, SV *ckobj) {
    file_ppfunc ppfunc = (file_ppfunc)SvIVX(ckobj);

xs/file/file.c  view on Meta::CPAN

        SV *old_defsv = DEFSV;
        SAVESPTR(DEFSV);  /* Automatically restore $_ on scope exit */

        while ((line = file_lines_next(aTHX_ idx)) != &PL_sv_undef) {
            dSP;
            ENTER;
            SAVETMPS;
            DEFSV_set(line);  /* Set $_ */
            PUSHMARK(SP);
            XPUSHs(line);  /* Don't mortalise - line is freed by file_lines_close or DEFSV restore */
            PUTBACK;
            call_sv(callback, G_DISCARD);
            FREETMPS;
            LEAVE;
            SvREFCNT_dec(line);  /* Release our reference after callback completes */
        }
    }

    file_lines_close(idx);
    XSRETURN_EMPTY;
}

xs/file/file.c  view on Meta::CPAN

        SV *cb_sv = fcb ? fcb->perl_callback : (SV*)block_cv;
        SV *old_defsv = DEFSV;
        while ((line = file_lines_next(aTHX_ idx)) != &PL_sv_undef) {
            dSP;
            IV count;
            SV *result_sv;
            bool matches = FALSE;
            DEFSV_set(line);  /* Set $_ */
            PUSHMARK(SP);
            XPUSHs(line);
            PUTBACK;
            count = call_sv(cb_sv, G_SCALAR);
            SPAGAIN;
            if (count > 0) {
                result_sv = POPs;
                matches = SvTRUE(result_sv);
            }
            PUTBACK;
            if (matches) {
                av_push(result, line);
            } else {
                SvREFCNT_dec(line);
            }
        }
        DEFSV_set(old_defsv);
    }

    file_lines_close(idx);

xs/file/file.c  view on Meta::CPAN

        SV *cb_sv = fcb ? fcb->perl_callback : (SV*)block_cv;
        SV *old_defsv = DEFSV;
        while ((line = file_lines_next(aTHX_ idx)) != &PL_sv_undef) {
            dSP;
            IV n;
            SV *result_sv;
            bool matches = FALSE;
            DEFSV_set(line);  /* Set $_ */
            PUSHMARK(SP);
            XPUSHs(line);
            PUTBACK;
            n = call_sv(cb_sv, G_SCALAR);
            SPAGAIN;
            if (n > 0) {
                result_sv = POPs;
                matches = SvTRUE(result_sv);
            }
            PUTBACK;
            if (matches) {
                count++;
            }
            SvREFCNT_dec(line);
        }
        DEFSV_set(old_defsv);
    }

    file_lines_close(idx);
    ST(0) = sv_2mortal(newSViv(count));

xs/file/file.c  view on Meta::CPAN

        SV *cb_sv = fcb ? fcb->perl_callback : (SV*)block_cv;
        SV *old_defsv = DEFSV;
        while ((line = file_lines_next(aTHX_ idx)) != &PL_sv_undef) {
            dSP;
            IV n;
            SV *result_sv;
            bool matches = FALSE;
            DEFSV_set(line);  /* Set $_ */
            PUSHMARK(SP);
            XPUSHs(line);
            PUTBACK;
            n = call_sv(cb_sv, G_SCALAR);
            SPAGAIN;
            if (n > 0) {
                result_sv = POPs;
                matches = SvTRUE(result_sv);
            }
            PUTBACK;
            if (matches) {
                DEFSV_set(old_defsv);
                file_lines_close(idx);
                ST(0) = sv_2mortal(line);
                XSRETURN(1);
            }
            SvREFCNT_dec(line);
        }
        DEFSV_set(old_defsv);
    }

xs/file/file.c  view on Meta::CPAN

    /* Call Perl callback - set both $_ and pass as argument */
    {
        SV *old_defsv = DEFSV;
        while ((line = file_lines_next(aTHX_ idx)) != &PL_sv_undef) {
            dSP;
            IV count;
            SV *result_sv;
            DEFSV_set(line);  /* Set $_ */
            PUSHMARK(SP);
            XPUSHs(sv_2mortal(line));
            PUTBACK;
            count = call_sv(callback, G_SCALAR);
            SPAGAIN;
            if (count > 0) {
                result_sv = POPs;
                av_push(result, SvREFCNT_inc(result_sv));
            }
            PUTBACK;
        }
        DEFSV_set(old_defsv);
    }

    file_lines_close(idx);
    ST(0) = sv_2mortal(newRV_noinc((SV*)result));
    XSRETURN(1);
}

/* Register a Perl callback */

xs/file/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/file/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/heap/heap.c  view on Meta::CPAN

/* Custom comparator sift operations */
static bool heap_compare_custom(pTHX_ Heap *h, SV *a, SV *b) {
    dSP;
    IV result;
    int count;

    ENTER; SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(a);
    XPUSHs(b);
    PUTBACK;

    count = call_sv(h->comparator, G_SCALAR);

    SPAGAIN;
    if (count != 1) croak("Comparator must return exactly one value");
    result = POPi;
    PUTBACK;
    FREETMPS; LEAVE;

    return h->type == HEAP_MIN ? result < 0 : result > 0;
}

static void heap_sift_up_custom(pTHX_ Heap *h, IV idx) {
    while (idx > 0) {
        IV parent = (idx - 1) >> 1;
        if (heap_compare_custom(aTHX_ h, h->data[idx], h->data[parent])) {
            SV *tmp = h->data[idx];

xs/heap/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/heap/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/lru/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/lru/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/noop/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/noop/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/nvec/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/nvec/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/object/object.c  view on Meta::CPAN

    /* Fall back to Perl callback (~100 cycles) */
    if (spec->registered->perl_check) {
        dSP;
        int count;
        bool result = false;
        SV *result_sv;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(val);
        PUTBACK;
        count = call_sv(spec->registered->perl_check, G_SCALAR);
        SPAGAIN;
        if (count > 0) {
            result_sv = POPs;
            result = SvTRUE(result_sv);
        }
        PUTBACK;
        FREETMPS;
        LEAVE;
        return result;
    }
    
    return true;
}

/* ============================================
   Slot spec parser: "name:Type:default(val)"

xs/object/object.c  view on Meta::CPAN

    }

    /* Create blessed reference */
    obj_sv = newRV_noinc((SV*)obj_av);
    sv_bless(obj_sv, meta->stash);

    /* Magic for lock/freeze is added lazily when first needed */

    SP = MARK;
    XPUSHs(obj_sv);
    PUTBACK;
    return NORMAL;
}

/* ============================================
   Prototype chain resolution
   ============================================ */

#define MAX_PROTOTYPE_DEPTH 100

/* Resolve a property through the full prototype chain.

xs/object/object.c  view on Meta::CPAN

    /* Readonly check */
    if (spec->is_readonly) {
        croak("Cannot modify readonly slot '%s'", spec->name);
    }

    /* Coercion (if callback exists) */
    if (spec->has_coerce && spec->coerce_cb) {
        dSP;
        PUSHMARK(SP);
        XPUSHs(val);
        PUTBACK;
        call_sv(spec->coerce_cb, G_SCALAR);
        SPAGAIN;
        val = POPs;
        PUTBACK;
    }

    /* External XS type coercion (C function - fast path) */
    if (spec->type_id == TYPE_CUSTOM && spec->registered && spec->registered->coerce) {
        val = spec->registered->coerce(aTHX_ val);
    }

    /* Type check using helper (handles both C and Perl callbacks) */
    if (spec->has_type) {
        if (!check_slot_type(aTHX_ val, spec)) {

xs/object/object.c  view on Meta::CPAN

    }

    /* Trigger callback (old, new) */
    if (spec->has_trigger && spec->trigger_cb) {
        SV *oldval = *av_fetch(av, idx, 0);
        dSP;
        PUSHMARK(SP);
        XPUSHs(obj);
        XPUSHs(oldval);
        XPUSHs(val);
        PUTBACK;
        call_sv(spec->trigger_cb, G_DISCARD);
    }

    av_store(av, idx, newSVsv(val));
    SETs(val);
    RETURN;
}

/* ============================================
   Call checker for accessor

xs/object/object.c  view on Meta::CPAN

            if (spec->has_builder && spec->builder_name) {
                /* Call builder method */
                dSP;
                const char *builder = SvPV_nolen(spec->builder_name);
                int count;
                
                ENTER;
                SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(self);
                PUTBACK;
                
                count = call_method(builder, G_SCALAR);
                
                SPAGAIN;
                if (count > 0) {
                    /* Copy the value BEFORE FREETMPS to avoid freed scalar issue */
                    built_val = newSVsv(POPs);
                } else {
                    built_val = newSV(0);  /* undef */
                }
                PUTBACK;
                FREETMPS;
                LEAVE;
            } else if (spec->has_default && spec->default_sv) {
                /* Use default value for lazy default */
                if (SvROK(spec->default_sv)) {
                    /* Clone reference types (arrays, hashes) */
                    SV *inner = SvRV(spec->default_sv);
                    if (SvTYPE(inner) == SVt_PVAV) {
                        built_val = newRV_noinc((SV*)newAV());
                    } else if (SvTYPE(inner) == SVt_PVHV) {

xs/object/object.c  view on Meta::CPAN

    SV *self = ST(0);
    
    PERL_UNUSED_VAR(items);
    
    if (meta && meta->demolish_cv) {
        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(self);
        PUTBACK;
        call_sv((SV*)meta->demolish_cv, G_DISCARD | G_EVAL);
        SPAGAIN;
        /* Ignore errors in DEMOLISH - don't die during destruction */
        if (SvTRUE(ERRSV)) {
            warn("Error in DEMOLISH: %s", SvPV_nolen(ERRSV));
        }
        FREETMPS;
        LEAVE;
    }
    

xs/object/object.c  view on Meta::CPAN

    /* Call before chain (in stack order - most recent first) */
    for (m = mod->before_chain; m; m = m->next) {
        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        for (i = 0; i <= av_len(saved_args); i++) {
            SV **svp = av_fetch(saved_args, i, 0);
            XPUSHs(svp ? *svp : &PL_sv_undef);
        }
        PUTBACK;
        call_sv(m->callback, G_DISCARD);
        FREETMPS;
        LEAVE;
    }
    
    /* Save results from original/around call */
    saved_results = newAV();
    sv_2mortal((SV*)saved_results);
    
    /* Call around chain (or original if no around) */

xs/object/object.c  view on Meta::CPAN

        {
            dSP;
            ENTER;
            SAVETMPS;
            PUSHMARK(SP);
            XPUSHs(sv_2mortal(newRV_inc((SV*)mod->original_cv)));
            for (i = 0; i <= av_len(saved_args); i++) {
                SV **svp = av_fetch(saved_args, i, 0);
                XPUSHs(svp ? *svp : &PL_sv_undef);
            }
            PUTBACK;
            count = call_sv(m->callback, gimme == G_ARRAY ? G_LIST : G_SCALAR);
            SPAGAIN;
            /* Save results before LEAVE destroys them - they're on stack in reverse */
            for (i = 0; i < count; i++) {
                av_push(saved_results, newSVsv(POPs));
            }
            FREETMPS;
            LEAVE;
        }
    } else if (mod->original_cv) {
        /* Call original method */
        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        for (i = 0; i <= av_len(saved_args); i++) {
            SV **svp = av_fetch(saved_args, i, 0);
            XPUSHs(svp ? *svp : &PL_sv_undef);
        }
        PUTBACK;
        count = call_sv((SV*)mod->original_cv, gimme == G_ARRAY ? G_LIST : G_SCALAR);
        SPAGAIN;
        /* Save results before LEAVE destroys them */
        for (i = 0; i < count; i++) {
            av_push(saved_results, newSVsv(POPs));
        }
        FREETMPS;
        LEAVE;
    }
    
    /* Call after chain (in order of registration) */
    for (m = mod->after_chain; m; m = m->next) {
        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        for (i = 0; i <= av_len(saved_args); i++) {
            SV **svp = av_fetch(saved_args, i, 0);
            XPUSHs(svp ? *svp : &PL_sv_undef);
        }
        PUTBACK;
        call_sv(m->callback, G_DISCARD);
        FREETMPS;
        LEAVE;
    }
    
    /* Put saved results back on stack (they were saved in reverse order) */
    {
        count = av_len(saved_results) + 1;
        for (i = count - 1; i >= 0; i--) {
            SV **svp = av_fetch(saved_results, i, 0);

xs/object/object.c  view on Meta::CPAN

        SV *obj;
        GV *build_gv;
        char full_build[256];

        ENTER;
        SAVETMPS;

        /* Call ClassName->new() */
        PUSHMARK(SP);
        XPUSHs(sv_2mortal(newSVpv(meta->class_name, 0)));
        PUTBACK;

        count = call_method("new", G_SCALAR);

        SPAGAIN;

        if (count != 1) {
            croak("Singleton new() did not return object");
        }

        obj = POPs;
        SvREFCNT_inc(obj);  /* Keep the object alive */

        PUTBACK;

        /* Check for BUILD method and call it */
        snprintf(full_build, sizeof(full_build), "%s::BUILD", meta->class_name);
        build_gv = gv_fetchpv(full_build, 0, SVt_PVCV);
        if (build_gv && GvCV(build_gv)) {
            PUSHMARK(SP);
            XPUSHs(obj);
            PUTBACK;
            call_method("BUILD", G_VOID | G_DISCARD);
        }

        /* Cache the instance */
        meta->singleton_instance = obj;

        FREETMPS;
        LEAVE;

        ST(0) = obj;

xs/object/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/object/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/slot/ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

xs/slot/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)

xs/slot/slot.c  view on Meta::CPAN

        AV *callbacks = (AV*)SvRV(*svp);
        SSize_t i, len = av_len(callbacks);
        for (i = 0; i <= len; i++) {
            SV **cb = av_fetch(callbacks, i, 0);
            if (cb && SvROK(*cb)) {
                dSP;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                mXPUSHs(newSVpvn(name, name_len));
                XPUSHs(new_val);
                PUTBACK;
                call_sv(*cb, G_DISCARD);
                FREETMPS; LEAVE;
            }
        }
    }
}

/* ============================================
   Slot management
   ============================================ */

xs/slot/slot.c  view on Meta::CPAN


static XS(xs_slots) {
    dXSARGS;
    HE *entry;
    PERL_UNUSED_VAR(items);
    SP -= items;
    hv_iterinit(g_slot_index);
    while ((entry = hv_iternext(g_slot_index))) {
        XPUSHs(hv_iterkeysv(entry));
    }
    PUTBACK;
    return;
}

/* slot::exists - check if slot is defined */
static XS(xs_exists) {
    dXSARGS;
    STRLEN name_len;
    const char *name;
    if (items != 1) croak("Usage: slot::exists($name)");
    name = SvPV(ST(0), name_len);

xs/util/ppport.h  view on Meta::CPAN

PTR2ul|5.007001||p
PTRV|5.006000||p
PUSHMARK|||
PUSH_MULTICALL||5.011000|
PUSHi|||
PUSHmortal|5.009002||p
PUSHn|||
PUSHp|||
PUSHs|||
PUSHu|5.004000||p
PUTBACK|||
PerlIO_clearerr||5.007003|
PerlIO_close||5.007003|
PerlIO_context_layers||5.009004|
PerlIO_eof||5.007003|
PerlIO_error||5.007003|
PerlIO_fileno||5.007003|
PerlIO_fill||5.007003|
PerlIO_flush||5.007003|
PerlIO_get_base||5.007003|
PerlIO_get_bufsiz||5.007003|

xs/util/ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    if (croak_on_error && SvTRUE(GvSV(errgv)))
	croak(SvPVx(GvSV(errgv), na));

    return sv;
}

#endif
#endif

xs/util/util.c  view on Meta::CPAN

/* clamp: 3 values on stack, return clamped */
static OP* pp_clamp(pTHX) {
    dSP; dMARK; dORIGMARK;
    SV *val_sv, *min_sv, *max_sv;
    NV value, min, max, result;
    
    /* We get 3 args on stack after the mark */
    if (SP - MARK != 3) {
        /* Fallback: just use direct POPs if no mark context */
        SP = ORIGMARK;
        PUTBACK;
        /* Pop without mark - shouldn't happen in list context */
        dSP;
        max_sv = POPs;
        min_sv = POPs;
        val_sv = POPs;
    } else {
        val_sv = MARK[1];
        min_sv = MARK[2];
        max_sv = MARK[3];
        SP = ORIGMARK;  /* reset stack to before args */

xs/util/util.c  view on Meta::CPAN


    ENTER;
    SAVETMPS;
    PUSHMARK(SP);

    IV i;
    EXTEND(SP, items);
    for (i = 0; i < items; i++) {
        PUSHs(ST(i));
    }
    PUTBACK;

    IV count = call_sv(mf->func, G_ARRAY);

    SPAGAIN;

    if (count == 1) {
        SV *result = SvREFCNT_inc(POPs);
        hv_store(mf->cache, key_pv, key_len, result, 0);
        PUTBACK;
        FREETMPS;
        LEAVE;
        SvREFCNT_dec_NN(key);
        ST(0) = result;
        XSRETURN(1);
    } else if (count > 0) {
        AV *av = newAV();
        av_extend(av, count - 1);
        for (i = count - 1; i >= 0; i--) {
            av_store(av, i, SvREFCNT_inc(POPs));
        }
        SV *result = newRV_noinc((SV*)av);
        hv_store(mf->cache, key_pv, key_len, result, 0);
        PUTBACK;
        FREETMPS;
        LEAVE;
        SvREFCNT_dec_NN(key);
        for (i = 0; i < count; i++) {
            SV **elem = av_fetch(av, i, 0);
            ST(i) = elem ? *elem : &PL_sv_undef;
        }
        XSRETURN(count);
    } else {
        hv_store(mf->cache, key_pv, key_len, &PL_sv_undef, 0);
        PUTBACK;
        FREETMPS;
        LEAVE;
        SvREFCNT_dec_NN(key);
        XSRETURN_EMPTY;
    }
}

/* ============================================
   Pipe/Compose implementation
   ============================================ */

xs/util/util.c  view on Meta::CPAN

        SV *func = ST(i);
        if (!SvROK(func) || SvTYPE(SvRV(func)) != SVt_PVCV) {
            SvREFCNT_dec(value);
            croak("util::pipeline: argument %d is not a coderef", (int)i);
        }

        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(value);
        PUTBACK;

        call_sv(func, G_SCALAR);

        SPAGAIN;
        SV *new_value = POPs;
        SvREFCNT_inc(new_value);
        PUTBACK;
        FREETMPS;
        LEAVE;

        SvREFCNT_dec(value);
        value = new_value;
    }

    ST(0) = sv_2mortal(value);
    XSRETURN(1);
}

xs/util/util.c  view on Meta::CPAN


        if (i == func_count - 1) {
            IV j;
            EXTEND(SP, items);
            for (j = 0; j < items; j++) {
                PUSHs(ST(j));
            }
        } else {
            XPUSHs(value);
        }
        PUTBACK;

        call_sv(*func_ptr, G_SCALAR);

        SPAGAIN;
        SV *new_value = POPs;
        SvREFCNT_inc(new_value);
        PUTBACK;
        FREETMPS;
        LEAVE;

        if (value) SvREFCNT_dec(value);
        value = new_value;
    }

    ST(0) = value ? sv_2mortal(value) : &PL_sv_undef;
    XSRETURN(1);
}

xs/util/util.c  view on Meta::CPAN

    LazyValue *lv = &g_lazies[idx];

    if (lv->forced) {
        ST(0) = lv->value;
        XSRETURN(1);
    }

    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    PUTBACK;

    call_sv(lv->thunk, G_SCALAR);

    SPAGAIN;
    lv->value = SvREFCNT_inc(POPs);
    lv->forced = TRUE;
    PUTBACK;
    FREETMPS;
    LEAVE;

    SvREFCNT_dec(lv->thunk);
    lv->thunk = NULL;

    ST(0) = lv->value;
    XSRETURN(1);
}

xs/util/util.c  view on Meta::CPAN

        croak("util::tap: first argument must be a coderef");
    }

    ENTER;
    SAVETMPS;
    SAVE_DEFSV;
    DEFSV_set(value);

    PUSHMARK(SP);
    XPUSHs(value);
    PUTBACK;

    call_sv(func, G_DISCARD | G_VOID);

    SPAGAIN;
    FREETMPS;
    LEAVE;

    ST(0) = value;
    XSRETURN(1);
}

xs/util/util.c  view on Meta::CPAN


    ENTER;
    SAVETMPS;
    PUSHMARK(SP);

    IV i;
    EXTEND(SP, items);
    for (i = 0; i < items; i++) {
        PUSHs(ST(i));
    }
    PUTBACK;

    call_sv(pred, G_SCALAR);

    SPAGAIN;
    SV *result = POPs;
    bool val = SvTRUE(result);
    PUTBACK;
    FREETMPS;
    LEAVE;

    ST(0) = val ? &PL_sv_no : &PL_sv_yes;
    XSRETURN(1);
}

/* once(\&f) - execute once, cache forever */
static XS(xs_once) {
    dXSARGS;

xs/util/util.c  view on Meta::CPAN

    OnceFunc *of = &g_onces[idx];

    if (of->called) {
        ST(0) = of->result ? of->result : &PL_sv_undef;
        XSRETURN(1);
    }

    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    PUTBACK;

    call_sv(of->func, G_SCALAR);

    SPAGAIN;
    of->result = SvREFCNT_inc(POPs);
    of->called = TRUE;
    PUTBACK;
    FREETMPS;
    LEAVE;

    /* Free the original function, no longer needed */
    SvREFCNT_dec(of->func);
    of->func = NULL;

    ST(0) = of->result;
    XSRETURN(1);
}

xs/util/util.c  view on Meta::CPAN

    IV i;
    for (i = 0; i < bound_count; i++) {
        SV **elem = av_fetch(pf->bound_args, i, 0);
        PUSHs(elem ? *elem : &PL_sv_undef);
    }

    /* Push call-time args */
    for (i = 0; i < items; i++) {
        PUSHs(ST(i));
    }
    PUTBACK;

    IV count = call_sv(pf->func, G_SCALAR);

    SPAGAIN;
    SV *result = count > 0 ? POPs : &PL_sv_undef;
    SvREFCNT_inc(result);
    PUTBACK;
    FREETMPS;
    LEAVE;

    ST(0) = sv_2mortal(result);
    XSRETURN(1);
}

/* ============================================
   Data extraction functions
   ============================================ */

xs/util/util.c  view on Meta::CPAN


        hv_iterinit(dest);
        HE *he;
        while ((he = hv_iternext(dest)) != NULL) {
            STRLEN klen;
            const char *key = HePV(he, klen);
            mPUSHp(key, klen);
            mPUSHs(SvREFCNT_inc(HeVAL(he)));
        }
        SvREFCNT_dec((SV*)dest);  /* Free the temp hash */
        PUTBACK;
        return;
    }

    /* Scalar context - return hashref */
    ST(0) = sv_2mortal(newRV_noinc((SV*)dest));
    XSRETURN(1);
}

/* pluck(\@hashes, $field) - extract field from each hash */
static XS(xs_pluck) {

xs/util/util.c  view on Meta::CPAN


        hv_iterinit(dest);
        HE *he;
        while ((he = hv_iternext(dest)) != NULL) {
            STRLEN klen;
            const char *key = HePV(he, klen);
            mPUSHp(key, klen);
            mPUSHs(SvREFCNT_inc(HeVAL(he)));
        }
        SvREFCNT_dec((SV*)dest);  /* Free the temp hash */
        PUTBACK;
        return;
    }

    /* Scalar context - return hashref */
    ST(0) = sv_2mortal(newRV_noinc((SV*)dest));
    XSRETURN(1);
}

/* uniq(@list) - return unique elements (preserves order) */
static XS(xs_uniq) {

xs/util/util.c  view on Meta::CPAN

    IV i;
    for (i = 1; i < items; i++) {
        SV *elem = ST(i);

        DEFSV_set(elem);

        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(elem);
        PUTBACK;

        call_sv(block, G_SCALAR);

        SPAGAIN;
        SV *result = POPs;
        bool matched = SvTRUE(result);
        PUTBACK;
        FREETMPS;
        LEAVE;

        if (matched) {
            av_push(pass, SvREFCNT_inc_simple_NN(elem));
        } else {
            av_push(fail, SvREFCNT_inc_simple_NN(elem));
        }
    }

xs/util/util.c  view on Meta::CPAN


        hv_iterinit(dest);
        HE *he;
        while ((he = hv_iternext(dest)) != NULL) {
            STRLEN klen;
            const char *key = HePV(he, klen);
            mPUSHp(key, klen);
            mPUSHs(SvREFCNT_inc(HeVAL(he)));
        }
        SvREFCNT_dec((SV*)dest);  /* Free the temp hash */
        PUTBACK;
        return;
    }

    /* Scalar context - return hashref */
    ST(0) = sv_2mortal(newRV_noinc((SV*)dest));
    XSRETURN(1);
}

/* ============================================
   Null coalescing functions

xs/util/util.c  view on Meta::CPAN

            {
                dSP;
                int count;
                SV *result;

                ENTER;
                SAVETMPS;

                PUSHMARK(SP);
                XPUSHs(*svp);
                PUTBACK;

                count = call_sv(cb->perl_callback, G_SCALAR);

                SPAGAIN;
                if (count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;

                FREETMPS;
                LEAVE;
            }

            if (matches) {
                XSRETURN_YES;
            }
        }
    }

xs/util/util.c  view on Meta::CPAN

            SV **svp = av_fetch(list, i, 0);
            if (!svp) { XSRETURN_NO; }
            bool matches = FALSE;
            {
                dSP;
                int count;
                SV *result;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(*svp);
                PUTBACK;
                count = call_sv(cb->perl_callback, G_SCALAR);
                SPAGAIN;
                if (count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;
                FREETMPS; LEAVE;
            }
            if (!matches) {
                XSRETURN_NO;
            }
        }
    }

    XSRETURN_YES;
}

xs/util/util.c  view on Meta::CPAN

            SV **svp = av_fetch(list, i, 0);
            if (!svp) continue;
            bool matches = FALSE;
            {
                dSP;
                int count;
                SV *result;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(*svp);
                PUTBACK;
                count = call_sv(cb->perl_callback, G_SCALAR);
                SPAGAIN;
                if (count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;
                FREETMPS; LEAVE;
            }
            if (matches) {
                XSRETURN_NO;
            }
        }
    }

    XSRETURN_YES;
}

xs/util/util.c  view on Meta::CPAN

            SV **svp = av_fetch(list, i, 0);
            if (!svp) continue;
            bool matches = FALSE;
            {
                dSP;
                int count;
                SV *result;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(*svp);
                PUTBACK;
                count = call_sv(cb->perl_callback, G_SCALAR);
                SPAGAIN;
                if (count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;
                FREETMPS; LEAVE;
            }
            if (matches) {
                ST(0) = *svp;
                XSRETURN(1);
            }
        }
    }

    XSRETURN_UNDEF;

xs/util/util.c  view on Meta::CPAN

            if (!svp) continue;
            SV *elem = *svp;
            bool matches = FALSE;
            {
                dSP;
                int call_count;
                SV *result;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(elem);
                PUTBACK;
                call_count = call_sv(cb->perl_callback, G_SCALAR);
                SPAGAIN;
                if (call_count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;
                FREETMPS; LEAVE;
            }
            if (matches) {
                av_push(results, SvREFCNT_inc(elem));
                count++;
            }
        }
    }

    /* Now push all results to the stack */
    SP -= items;
    for (i = 0; i < count; i++) {
        SV **svp = av_fetch(results, i, 0);
        if (svp) {
            XPUSHs(sv_2mortal(SvREFCNT_inc(*svp)));
        }
    }

    PUTBACK;
    XSRETURN(count);
}

/* count_cb(\@list, ':predicate') - count matching elements */
static XS(xs_count_cb) {
    dXSARGS;
    if (items != 2) croak("Usage: util::count_cb(\\@list, $callback_name)");

    SV *list_sv = ST(0);
    if (!SvROK(list_sv) || SvTYPE(SvRV(list_sv)) != SVt_PVAV) {

xs/util/util.c  view on Meta::CPAN

            SV **svp = av_fetch(list, i, 0);
            if (!svp) continue;
            bool matches = FALSE;
            {
                dSP;
                int call_count;
                SV *result;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(*svp);
                PUTBACK;
                call_count = call_sv(cb->perl_callback, G_SCALAR);
                SPAGAIN;
                if (call_count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;
                FREETMPS; LEAVE;
            }
            if (matches) {
                count++;
            }
        }
    }

    XSRETURN_IV(count);
}

xs/util/util.c  view on Meta::CPAN

            {
                dSP;
                int call_count;
                SV *result;

                ENTER;
                SAVETMPS;

                PUSHMARK(SP);
                XPUSHs(*svp);
                PUTBACK;

                call_count = call_sv(cb->perl_callback, G_SCALAR);

                SPAGAIN;
                if (call_count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;

                FREETMPS;
                LEAVE;
            }
            if (matches) {
                av_push(pass, SvREFCNT_inc_simple_NN(*svp));
            } else {
                av_push(fail, SvREFCNT_inc_simple_NN(*svp));
            }
        }

xs/util/util.c  view on Meta::CPAN

            SV **svp = av_fetch(list, i, 0);
            if (!svp) continue;
            bool matches = FALSE;
            {
                dSP;
                int count;
                SV *result;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(*svp);
                PUTBACK;
                count = call_sv(cb->perl_callback, G_SCALAR);
                SPAGAIN;
                if (count > 0) {
                    result = POPs;
                    matches = SvTRUE(result);
                }
                PUTBACK;
                FREETMPS; LEAVE;
            }
            if (matches) {
                ST(0) = *svp;
                XSRETURN(1);
            }
        }
    }

    XSRETURN_UNDEF;



( run in 0.819 second using v1.01-cache-2.11-cpan-13bb782fe5a )