This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
put signature ops in their own subtree.
[perl5.git] / ext / PerlIO-encoding / encoding.xs
... / ...
CommitLineData
1#define PERL_NO_GET_CONTEXT
2#include "EXTERN.h"
3#include "perl.h"
4#include "XSUB.h"
5#define U8 U8
6
7#define OUR_DEFAULT_FB "Encode::PERLQQ"
8
9#if defined(USE_PERLIO)
10
11/* Define an encoding "layer" in the perliol.h sense.
12
13 The layer defined here "inherits" in an object-oriented sense from
14 the "perlio" layer with its PerlIOBuf_* "methods". The
15 implementation is particularly efficient as until Encode settles
16 down there is no point in tryint to tune it.
17
18 The layer works by overloading the "fill" and "flush" methods.
19
20 "fill" calls "SUPER::fill" in perl terms, then calls the encode OO
21 perl API to convert the encoded data to UTF-8 form, then copies it
22 back to the buffer. The "base class's" read methods then see the
23 UTF-8 data.
24
25 "flush" transforms the UTF-8 data deposited by the "base class's
26 write method in the buffer back into the encoded form using the
27 encode OO perl API, then copies data back into the buffer and calls
28 "SUPER::flush.
29
30 Note that "flush" is _also_ called for read mode - we still do the
31 (back)-translate so that the base class's "flush" sees the
32 correct number of encoded chars for positioning the seek
33 pointer. (This double translation is the worst performance issue -
34 particularly with all-perl encode engine.)
35
36*/
37
38#include "perliol.h"
39
40typedef struct {
41 PerlIOBuf base; /* PerlIOBuf stuff */
42 SV *bufsv; /* buffer seen by layers above */
43 SV *dataSV; /* data we have read from layer below */
44 SV *enc; /* the encoding object */
45 SV *chk; /* CHECK in Encode methods */
46 int flags; /* Flags currently just needs lines */
47 int inEncodeCall; /* trap recursive encode calls */
48} PerlIOEncode;
49
50#define NEEDS_LINES 1
51
52static const MGVTBL PerlIOEncode_tag = { 0, 0, 0, 0, 0, 0, 0, 0 };
53
54static SV *
55PerlIOEncode_getarg(pTHX_ PerlIO * f, CLONE_PARAMS * param, int flags)
56{
57 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
58 SV *sv;
59 PERL_UNUSED_ARG(flags);
60 /* During cloning, return an undef token object so that _pushed() knows
61 * that it should not call methods and wait for _dup() to actually dup the
62 * encoding object. */
63 if (param) {
64 sv = newSV(0);
65 sv_magicext(sv, NULL, PERL_MAGIC_ext, &PerlIOEncode_tag, 0, 0);
66 return sv;
67 }
68 sv = &PL_sv_undef;
69 if (e->enc) {
70 dSP;
71 /* Not 100% sure stack swap is right thing to do during dup ... */
72 PUSHSTACKi(PERLSI_MAGIC);
73 ENTER;
74 SAVETMPS;
75 PUSHMARK(sp);
76 XPUSHs(e->enc);
77 PUTBACK;
78 if (call_method("name", G_SCALAR) == 1) {
79 SPAGAIN;
80 sv = newSVsv(POPs);
81 PUTBACK;
82 }
83 FREETMPS;
84 LEAVE;
85 POPSTACK;
86 }
87 return sv;
88}
89
90static IV
91PerlIOEncode_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg, PerlIO_funcs *tab)
92{
93 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
94 dSP;
95 IV code = PerlIOBuf_pushed(aTHX_ f, mode, Nullsv,tab);
96 SV *result = Nullsv;
97
98 if (SvTYPE(arg) >= SVt_PVMG
99 && mg_findext(arg, PERL_MAGIC_ext, &PerlIOEncode_tag)) {
100 e->enc = NULL;
101 e->chk = NULL;
102 e->inEncodeCall = 0;
103 return code;
104 }
105
106 PUSHSTACKi(PERLSI_MAGIC);
107 ENTER;
108 SAVETMPS;
109
110 PUSHMARK(sp);
111 XPUSHs(arg);
112 PUTBACK;
113 if (call_pv("Encode::find_encoding", G_SCALAR) != 1) {
114 /* should never happen */
115 Perl_die(aTHX_ "Encode::find_encoding did not return a value");
116 return -1;
117 }
118 SPAGAIN;
119 result = POPs;
120 PUTBACK;
121
122 if (!SvROK(result) || !SvOBJECT(SvRV(result))) {
123 e->enc = Nullsv;
124 if (ckWARN_d(WARN_IO))
125 Perl_warner(aTHX_ packWARN(WARN_IO), "Cannot find encoding \"%" SVf "\"",
126 arg);
127 errno = EINVAL;
128 code = -1;
129 }
130 else {
131
132 /* $enc->renew */
133 PUSHMARK(sp);
134 XPUSHs(result);
135 PUTBACK;
136 if (call_method("renew",G_SCALAR|G_EVAL) != 1 || SvTRUE(ERRSV)) {
137 if (ckWARN_d(WARN_IO))
138 Perl_warner(aTHX_ packWARN(WARN_IO), "\"%" SVf "\" does not support renew method",
139 arg);
140 }
141 else {
142 SPAGAIN;
143 result = POPs;
144 PUTBACK;
145 }
146 e->enc = newSVsv(result);
147 PUSHMARK(sp);
148 XPUSHs(e->enc);
149 PUTBACK;
150 if (call_method("needs_lines",G_SCALAR|G_EVAL) != 1 || SvTRUE(ERRSV)) {
151 if (ckWARN_d(WARN_IO))
152 Perl_warner(aTHX_ packWARN(WARN_IO), "\"%" SVf "\" does not support needs_lines",
153 arg);
154 }
155 else {
156 SPAGAIN;
157 result = POPs;
158 PUTBACK;
159 if (SvTRUE(result)) {
160 e->flags |= NEEDS_LINES;
161 }
162 }
163 PerlIOBase(f)->flags |= PERLIO_F_UTF8;
164 }
165
166 e->chk = newSVsv(get_sv("PerlIO::encoding::fallback", 0));
167 e->inEncodeCall = 0;
168
169 FREETMPS;
170 LEAVE;
171 POPSTACK;
172 return code;
173}
174
175static IV
176PerlIOEncode_popped(pTHX_ PerlIO * f)
177{
178 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
179 if (e->enc) {
180 SvREFCNT_dec(e->enc);
181 e->enc = Nullsv;
182 }
183 if (e->bufsv) {
184 SvREFCNT_dec(e->bufsv);
185 e->bufsv = Nullsv;
186 }
187 if (e->dataSV) {
188 SvREFCNT_dec(e->dataSV);
189 e->dataSV = Nullsv;
190 }
191 if (e->chk) {
192 SvREFCNT_dec(e->chk);
193 e->chk = Nullsv;
194 }
195 return 0;
196}
197
198static STDCHAR *
199PerlIOEncode_get_base(pTHX_ PerlIO * f)
200{
201 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
202 if (!e->base.bufsiz)
203 e->base.bufsiz = 1024;
204 if (!e->bufsv) {
205 e->bufsv = newSV(e->base.bufsiz);
206 SvPVCLEAR(e->bufsv);
207 }
208 e->base.buf = (STDCHAR *) SvPVX(e->bufsv);
209 if (!e->base.ptr)
210 e->base.ptr = e->base.buf;
211 if (!e->base.end)
212 e->base.end = e->base.buf;
213 if (e->base.ptr < e->base.buf
214 || e->base.ptr > e->base.buf + SvLEN(e->bufsv)) {
215 Perl_warn(aTHX_ " ptr %p(%p)%p", e->base.buf, e->base.ptr,
216 e->base.buf + SvLEN(e->bufsv));
217 abort();
218 }
219 if (SvLEN(e->bufsv) < e->base.bufsiz) {
220 SSize_t poff = e->base.ptr - e->base.buf;
221 SSize_t eoff = e->base.end - e->base.buf;
222 e->base.buf = (STDCHAR *) SvGROW(e->bufsv, e->base.bufsiz);
223 e->base.ptr = e->base.buf + poff;
224 e->base.end = e->base.buf + eoff;
225 }
226 if (e->base.ptr < e->base.buf
227 || e->base.ptr > e->base.buf + SvLEN(e->bufsv)) {
228 Perl_warn(aTHX_ " ptr %p(%p)%p", e->base.buf, e->base.ptr,
229 e->base.buf + SvLEN(e->bufsv));
230 abort();
231 }
232 return e->base.buf;
233}
234
235static IV
236PerlIOEncode_fill(pTHX_ PerlIO * f)
237{
238 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
239 dSP;
240 IV code = 0;
241 PerlIO *n;
242 SSize_t avail;
243
244 if (PerlIO_flush(f) != 0)
245 return -1;
246 n = PerlIONext(f);
247 if (!PerlIO_fast_gets(n)) {
248 /* Things get too messy if we don't have a buffer layer
249 push a :perlio to do the job */
250 char mode[8];
251 n = PerlIO_push(aTHX_ n, &PerlIO_perlio, PerlIO_modestr(f,mode), Nullsv);
252 if (!n) {
253 Perl_die(aTHX_ "panic: cannot push :perlio for %p",f);
254 }
255 }
256 PUSHSTACKi(PERLSI_MAGIC);
257 ENTER;
258 SAVETMPS;
259 retry:
260 avail = PerlIO_get_cnt(n);
261 if (avail <= 0) {
262 avail = PerlIO_fill(n);
263 if (avail == 0) {
264 avail = PerlIO_get_cnt(n);
265 }
266 else {
267 if (!PerlIO_error(n) && PerlIO_eof(n))
268 avail = 0;
269 }
270 }
271 if (avail > 0 || (e->flags & NEEDS_LINES)) {
272 STDCHAR *ptr = PerlIO_get_ptr(n);
273 SSize_t use = (avail >= 0) ? avail : 0;
274 SV *uni;
275 char *s = NULL;
276 STRLEN len = 0;
277 e->base.ptr = e->base.end = (STDCHAR *) NULL;
278 (void) PerlIOEncode_get_base(aTHX_ f);
279 if (!e->dataSV)
280 e->dataSV = newSV(0);
281 if (SvTYPE(e->dataSV) < SVt_PV) {
282 sv_upgrade(e->dataSV,SVt_PV);
283 }
284 if (e->flags & NEEDS_LINES) {
285 /* Encoding needs whole lines (e.g. iso-2022-*)
286 search back from end of available data for
287 and line marker
288 */
289 STDCHAR *nl = ptr+use-1;
290 while (nl >= ptr) {
291 if (*nl == '\n') {
292 break;
293 }
294 nl--;
295 }
296 if (nl >= ptr && *nl == '\n') {
297 /* found a line - take up to and including that */
298 use = (nl+1)-ptr;
299 }
300 else if (avail > 0) {
301 /* No line, but not EOF - append avail to the pending data */
302 sv_catpvn(e->dataSV, (char*)ptr, use);
303 PerlIO_set_ptrcnt(n, ptr+use, 0);
304 goto retry;
305 }
306 else if (!SvCUR(e->dataSV)) {
307 goto end_of_file;
308 }
309 }
310 if (!SvCUR(e->dataSV))
311 SvPVCLEAR(e->dataSV);
312 if (use + SvCUR(e->dataSV) > e->base.bufsiz) {
313 if (e->flags & NEEDS_LINES) {
314 /* Have to grow buffer */
315 e->base.bufsiz = use + SvCUR(e->dataSV);
316 PerlIOEncode_get_base(aTHX_ f);
317 }
318 else {
319 use = e->base.bufsiz - SvCUR(e->dataSV);
320 }
321 }
322 sv_catpvn(e->dataSV,(char*)ptr,use);
323 SvUTF8_off(e->dataSV);
324 PUSHMARK(sp);
325 XPUSHs(e->enc);
326 XPUSHs(e->dataSV);
327 XPUSHs(e->chk);
328 PUTBACK;
329 if (call_method("decode", G_SCALAR) != 1) {
330 Perl_die(aTHX_ "panic: decode did not return a value");
331 }
332 SPAGAIN;
333 uni = POPs;
334 PUTBACK;
335 /* No cows allowed. */
336 if (SvTHINKFIRST(e->dataSV)) SvPV_force_nolen(e->dataSV);
337 /* Now get translated string (forced to UTF-8) and use as buffer */
338 if (SvPOK(uni)) {
339 s = SvPVutf8(uni, len);
340#ifdef PARANOID_ENCODE_CHECKS
341 if (len && !is_utf8_string((U8*)s,len)) {
342 Perl_warn(aTHX_ "panic: decode did not return UTF-8 '%.*s'",(int) len,s);
343 }
344#endif
345 }
346 if (len > 0) {
347 /* Got _something */
348 /* if decode gave us back dataSV then data may vanish when
349 we do ptrcnt adjust - so take our copy now.
350 (The copy is a pain - need a put-it-here option for decode.)
351 */
352 sv_setpvn(e->bufsv,s,len);
353 e->base.ptr = e->base.buf = (STDCHAR*)SvPVX(e->bufsv);
354 e->base.end = e->base.ptr + SvCUR(e->bufsv);
355 PerlIOBase(f)->flags |= PERLIO_F_RDBUF;
356 SvUTF8_on(e->bufsv);
357
358 /* Adjust ptr/cnt not taking anything which
359 did not translate - not clear this is a win */
360 /* compute amount we took */
361 if (!SvPOKp(e->dataSV)) (void)SvPV_force_nolen(e->dataSV);
362 use -= SvCUR(e->dataSV);
363 PerlIO_set_ptrcnt(n, ptr+use, (avail-use));
364 /* and as we did not take it, it isn't pending */
365 SvCUR_set(e->dataSV,0);
366 } else {
367 /* Got nothing - assume partial character so we need some more */
368 /* Make sure e->dataSV is a normal SV before re-filling as
369 buffer alias will change under us
370 */
371 s = SvPV(e->dataSV,len);
372 sv_setpvn(e->dataSV,s,len);
373 PerlIO_set_ptrcnt(n, ptr+use, (avail-use));
374 goto retry;
375 }
376 }
377 else {
378 end_of_file:
379 code = -1;
380 if (avail == 0)
381 PerlIOBase(f)->flags |= PERLIO_F_EOF;
382 else
383 {
384 PerlIOBase(f)->flags |= PERLIO_F_ERROR;
385 Perl_PerlIO_save_errno(aTHX_ f);
386 }
387 }
388 FREETMPS;
389 LEAVE;
390 POPSTACK;
391 return code;
392}
393
394static IV
395PerlIOEncode_flush(pTHX_ PerlIO * f)
396{
397 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
398 IV code = 0;
399
400 if (e->bufsv) {
401 dSP;
402 SV *str;
403 char *s;
404 STRLEN len;
405 SSize_t count = 0;
406 if ((PerlIOBase(f)->flags & PERLIO_F_WRBUF) && (e->base.ptr > e->base.buf)) {
407 if (e->inEncodeCall) return 0;
408 /* Write case - encode the buffer and write() to layer below */
409 PUSHSTACKi(PERLSI_MAGIC);
410 ENTER;
411 SAVETMPS;
412 PUSHMARK(sp);
413 XPUSHs(e->enc);
414 SvCUR_set(e->bufsv, e->base.ptr - e->base.buf);
415 SvUTF8_on(e->bufsv);
416 XPUSHs(e->bufsv);
417 XPUSHs(e->chk);
418 PUTBACK;
419 e->inEncodeCall = 1;
420 if (call_method("encode", G_SCALAR) != 1) {
421 e->inEncodeCall = 0;
422 Perl_die(aTHX_ "panic: encode did not return a value");
423 }
424 e->inEncodeCall = 0;
425 SPAGAIN;
426 str = POPs;
427 PUTBACK;
428 s = SvPV(str, len);
429 count = PerlIO_write(PerlIONext(f),s,len);
430 if ((STRLEN)count != len) {
431 code = -1;
432 }
433 FREETMPS;
434 LEAVE;
435 POPSTACK;
436 if (PerlIO_flush(PerlIONext(f)) != 0) {
437 code = -1;
438 }
439 if (!SvPOKp(e->bufsv) || SvTHINKFIRST(e->bufsv))
440 (void)SvPV_force_nolen(e->bufsv);
441 if ((STDCHAR *)SvPVX(e->bufsv) != e->base.buf) {
442 e->base.ptr = (STDCHAR *)SvEND(e->bufsv);
443 e->base.end = (STDCHAR *)SvPVX(e->bufsv) + (e->base.end-e->base.buf);
444 e->base.buf = (STDCHAR *)SvPVX(e->bufsv);
445 }
446 (void)PerlIOEncode_get_base(aTHX_ f);
447 if (SvCUR(e->bufsv)) {
448 /* Did not all translate */
449 e->base.ptr = e->base.buf+SvCUR(e->bufsv);
450 return code;
451 }
452 }
453 else if ((PerlIOBase(f)->flags & PERLIO_F_RDBUF)) {
454 /* read case */
455 /* if we have any untranslated stuff then unread that first */
456 /* FIXME - unread is fragile is there a better way ? */
457 if (e->dataSV && SvCUR(e->dataSV)) {
458 s = SvPV(e->dataSV, len);
459 count = PerlIO_unread(PerlIONext(f),s,len);
460 if ((STRLEN)count != len) {
461 code = -1;
462 }
463 SvCUR_set(e->dataSV,0);
464 }
465 /* See if there is anything left in the buffer */
466 if (e->base.ptr < e->base.end) {
467 if (e->inEncodeCall) return 0;
468 /* Bother - have unread data.
469 re-encode and unread() to layer below
470 */
471 PUSHSTACKi(PERLSI_MAGIC);
472 ENTER;
473 SAVETMPS;
474 str = sv_newmortal();
475 sv_upgrade(str, SVt_PV);
476 SvPV_set(str, (char*)e->base.ptr);
477 SvLEN_set(str, 0);
478 SvCUR_set(str, e->base.end - e->base.ptr);
479 SvPOK_only(str);
480 SvUTF8_on(str);
481 PUSHMARK(sp);
482 XPUSHs(e->enc);
483 XPUSHs(str);
484 XPUSHs(e->chk);
485 PUTBACK;
486 e->inEncodeCall = 1;
487 if (call_method("encode", G_SCALAR) != 1) {
488 e->inEncodeCall = 0;
489 Perl_die(aTHX_ "panic: encode did not return a value");
490 }
491 e->inEncodeCall = 0;
492 SPAGAIN;
493 str = POPs;
494 PUTBACK;
495 s = SvPV(str, len);
496 count = PerlIO_unread(PerlIONext(f),s,len);
497 if ((STRLEN)count != len) {
498 code = -1;
499 }
500 FREETMPS;
501 LEAVE;
502 POPSTACK;
503 }
504 }
505 e->base.ptr = e->base.end = e->base.buf;
506 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
507 }
508 return code;
509}
510
511static IV
512PerlIOEncode_close(pTHX_ PerlIO * f)
513{
514 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
515 IV code;
516 if (PerlIOBase(f)->flags & PERLIO_F_RDBUF) {
517 /* Discard partial character */
518 if (e->dataSV) {
519 SvCUR_set(e->dataSV,0);
520 }
521 /* Don't back decode and unread any pending data */
522 e->base.ptr = e->base.end = e->base.buf;
523 }
524 code = PerlIOBase_close(aTHX_ f);
525 if (e->bufsv) {
526 /* This should only fire for write case */
527 if (e->base.buf && e->base.ptr > e->base.buf) {
528 Perl_croak(aTHX_ "Close with partial character");
529 }
530 SvREFCNT_dec(e->bufsv);
531 e->bufsv = Nullsv;
532 }
533 e->base.buf = NULL;
534 e->base.ptr = NULL;
535 e->base.end = NULL;
536 PerlIOBase(f)->flags &= ~(PERLIO_F_RDBUF | PERLIO_F_WRBUF);
537 return code;
538}
539
540static Off_t
541PerlIOEncode_tell(pTHX_ PerlIO * f)
542{
543 PerlIOBuf *b = PerlIOSelf(f, PerlIOBuf);
544 /* Unfortunately the only way to get a position is to (re-)translate,
545 the UTF8 we have in buffer and then ask layer below
546 */
547 PerlIO_flush(f);
548 if (b->buf && b->ptr > b->buf) {
549 Perl_croak(aTHX_ "Cannot tell at partial character");
550 }
551 return PerlIO_tell(PerlIONext(f));
552}
553
554static PerlIO *
555PerlIOEncode_dup(pTHX_ PerlIO * f, PerlIO * o,
556 CLONE_PARAMS * params, int flags)
557{
558 if ((f = PerlIOBase_dup(aTHX_ f, o, params, flags))) {
559 PerlIOEncode *fe = PerlIOSelf(f, PerlIOEncode);
560 PerlIOEncode *oe = PerlIOSelf(o, PerlIOEncode);
561 if (oe->enc) {
562 fe->enc = PerlIO_sv_dup(aTHX_ oe->enc, params);
563 }
564 if (oe->chk) {
565 fe->chk = PerlIO_sv_dup(aTHX_ oe->chk, params);
566 }
567 }
568 return f;
569}
570
571static SSize_t
572PerlIOEncode_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
573{
574 PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode);
575 if (e->flags & NEEDS_LINES) {
576 SSize_t done = 0;
577 const char *ptr = (const char *) vbuf;
578 const char *end = ptr+count;
579 while (ptr < end) {
580 const char *nl = ptr;
581 while (nl < end && *nl++ != '\n') /* empty body */;
582 done = PerlIOBuf_write(aTHX_ f, ptr, nl-ptr);
583 if (done != nl-ptr) {
584 if (done > 0) {
585 ptr += done;
586 }
587 break;
588 }
589 ptr += done;
590 if (ptr[-1] == '\n') {
591 if (PerlIOEncode_flush(aTHX_ f) != 0) {
592 break;
593 }
594 }
595 }
596 return (SSize_t) (ptr - (const char *) vbuf);
597 }
598 else {
599 return PerlIOBuf_write(aTHX_ f, vbuf, count);
600 }
601}
602
603static PERLIO_FUNCS_DECL(PerlIO_encode) = {
604 sizeof(PerlIO_funcs),
605 "encoding",
606 sizeof(PerlIOEncode),
607 PERLIO_K_BUFFERED|PERLIO_K_DESTRUCT,
608 PerlIOEncode_pushed,
609 PerlIOEncode_popped,
610 PerlIOBuf_open,
611 NULL, /* binmode - always pop */
612 PerlIOEncode_getarg,
613 PerlIOBase_fileno,
614 PerlIOEncode_dup,
615 PerlIOBuf_read,
616 PerlIOBuf_unread,
617 PerlIOEncode_write,
618 PerlIOBuf_seek,
619 PerlIOEncode_tell,
620 PerlIOEncode_close,
621 PerlIOEncode_flush,
622 PerlIOEncode_fill,
623 PerlIOBase_eof,
624 PerlIOBase_error,
625 PerlIOBase_clearerr,
626 PerlIOBase_setlinebuf,
627 PerlIOEncode_get_base,
628 PerlIOBuf_bufsiz,
629 PerlIOBuf_get_ptr,
630 PerlIOBuf_get_cnt,
631 PerlIOBuf_set_ptrcnt,
632};
633#endif /* encode layer */
634
635MODULE = PerlIO::encoding PACKAGE = PerlIO::encoding
636
637PROTOTYPES: ENABLE
638
639BOOT:
640{
641 SV *chk = get_sv("PerlIO::encoding::fallback", GV_ADD|GV_ADDMULTI);
642 /*
643 * we now "use Encode ()" here instead of
644 * PerlIO/encoding.pm. This avoids SEGV when ":encoding()"
645 * is invoked without prior "use Encode". -- dankogai
646 */
647 PUSHSTACKi(PERLSI_MAGIC);
648 if (!get_cvs(OUR_DEFAULT_FB, 0)) {
649#if 0
650 /* This would just be an irritant now loading works */
651 Perl_warner(aTHX_ packWARN(WARN_IO), ":encoding without 'use Encode'");
652#endif
653 /* The SV is magically freed by load_module */
654 load_module(PERL_LOADMOD_NOIMPORT, newSVpvs("Encode"), Nullsv, Nullsv);
655 assert(sp == PL_stack_sp);
656 }
657 PUSHMARK(sp);
658 PUTBACK;
659 if (call_pv(OUR_DEFAULT_FB, G_SCALAR) != 1) {
660 /* should never happen */
661 Perl_die(aTHX_ "%s did not return a value",OUR_DEFAULT_FB);
662 }
663 SPAGAIN;
664 sv_setsv(chk, POPs);
665 PUTBACK;
666#ifdef PERLIO_LAYERS
667 PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_encode));
668#endif
669 POPSTACK;
670}