static amf0_data_t* _amf0_data(SV* sv) { amf0_data_t* d; if (NULL == sv || !SvOK(sv)) { d = (amf0_data_t*)amf0_null_init(); } else if (SvPOKp(sv)) { STRLEN len; char* c = SvPV(sv, len); d = (amf0_data_t*)amf0_string_init_len(c, len); } else if (SvNOKp(sv)) { d = (amf0_data_t*)amf0_number_init((double)SvNVX(sv)); } else if (SvIOK_UV(sv)) { d = (amf0_data_t*)amf0_number_init((double)SvUV(sv)); } else if (SvIOKp(sv)) { d = (amf0_data_t*)amf0_number_init((double)SvIV(sv)); } else if (SvROK(sv)) { d = _amf0_data_rv(SvRV(sv)); } else { Perl_croak(aTHX_ "Data::AMF::XS doesn't support SvTYPE: %d\n", SvTYPE(sv)); } return d; }
static void modify_timer_perl(plcb_IOPROCS *async, plcb_EVENT *cevent, uint32_t usecs, int action) { SvNVX(async->usec_sv) = (double) usecs / 1000000; SvIVX(async->action_sv) = action; cb_args_noret(async->cv_timermod, 0, 4, async->userdata, cevent->rv_event, async->action_sv, async->usec_sv); }
NV Perl_sv_nv(pTHX_ SV *sv) { PERL_ARGS_ASSERT_SV_NV; if (SvNOK(sv)) return SvNVX(sv); return sv_2nv(sv); }
/* Entry point for serialization. Dumps generic SVs and delegates * to more specialized functions for RVs, etc. */ void ddl_dump_sv(pTHX_ ddl_encoder_t *enc, SV *src) { SvGETMAGIC(src); /* dump strings */ if (SvPOKp(src)) { STRLEN len; char *str = SvPV(src, len); BUF_SIZE_ASSERT(enc, 2 + len); ddl_dump_pv(aTHX_ enc, str, len, SvUTF8(src)); } /* dump floats */ else if (SvNOKp(src)) { BUF_SIZE_ASSERT(enc, NV_DIG + 32); Gconvert(SvNVX(src), NV_DIG, 0, enc->pos); enc->pos += strlen(enc->pos); } /* dump ints */ else if (SvIOKp(src)) { /* we assume we can always read an IV as a UV and vice versa * we assume two's complement * we assume no aliasing issues in the union */ if (SvIsUV(src) ? SvUVX(src) <= 59000 : SvIVX(src) <= 59000 && SvIVX(src) >= -59000) { /* optimise the "small number case" * code will likely be branchless and use only a single multiplication * works for numbers up to 59074 */ I32 i = SvIVX(src); U32 u; char digit, nz = 0; BUF_SIZE_ASSERT(enc, 6); *enc->pos = '-'; enc->pos += i < 0 ? 1 : 0; u = i < 0 ? -i : i; /* convert to 4.28 fixed-point representation */ u *= ((0xfffffff + 10000) / 10000); /* 10**5, 5 fractional digits */ /* now output digit by digit, each time masking out the integer part * and multiplying by 5 while moving the decimal point one to the right, * resulting in a net multiplication by 10. * we always write the digit to memory but conditionally increment * the pointer, to enable the use of conditional move instructions. */ digit = u >> 28; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0xfffffffUL) * 5; digit = u >> 27; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x7ffffffUL) * 5; digit = u >> 26; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x3ffffffUL) * 5; digit = u >> 25; *enc->pos = digit + '0'; enc->pos += (nz = nz || digit); u = (u & 0x1ffffffUL) * 5; digit = u >> 24; *enc->pos = digit + '0'; enc->pos += 1; /* correctly generate '0' */ } else {
void Perl_set_version(pTHX_ const char *name, STRLEN nlen, const char *strval, STRLEN plen, NV nvval) { SV* ver = GvSV(gv_add_by_type(gv_fetchpvn(name, nlen, GV_ADD, SVt_PVNV), SVt_PVNV)); PERL_ARGS_ASSERT_SET_VERSION; SvREADONLY_off(ver); SvUPGRADE(ver, SVt_PVNV); SvPVX(ver) = SvGROW(ver, plen+1); Move(strval, SvPVX(ver), plen, char); SvCUR_set(ver, plen); SvNVX(ver) = nvval; /* not the PROTECT bit */ SvFLAGS(ver) |= (SVf_NOK|SVp_NOK|SVf_POK|SVp_POK|SVf_READONLY); }