This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
POSIX: MSVC defines all of these
[perl5.git] / feature.h
1 /* -*- mode: C; buffer-read-only: t -*-
2    !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
3    This file is built by regen/feature.pl.
4    Any changes made here will be lost!
5  */
6
7
8 #ifndef PERL_FEATURE_H_
9 #define PERL_FEATURE_H_
10
11 #if defined(PERL_CORE) || defined (PERL_EXT)
12
13 #define HINT_FEATURE_SHIFT      26
14
15 #define FEATURE_BAREWORD_FILEHANDLES_BIT    0x0001
16 #define FEATURE_BITWISE_BIT                 0x0002
17 #define FEATURE_CLASS_BIT                   0x0004
18 #define FEATURE___SUB___BIT                 0x0008
19 #define FEATURE_MYREF_BIT                   0x0010
20 #define FEATURE_DEFER_BIT                   0x0020
21 #define FEATURE_EVALBYTES_BIT               0x0040
22 #define FEATURE_MORE_DELIMS_BIT             0x0080
23 #define FEATURE_FC_BIT                      0x0100
24 #define FEATURE_INDIRECT_BIT                0x0200
25 #define FEATURE_ISA_BIT                     0x0400
26 #define FEATURE_MODULE_TRUE_BIT             0x0800
27 #define FEATURE_MULTIDIMENSIONAL_BIT        0x1000
28 #define FEATURE_POSTDEREF_QQ_BIT            0x2000
29 #define FEATURE_REFALIASING_BIT             0x4000
30 #define FEATURE_SAY_BIT                     0x8000
31 #define FEATURE_SIGNATURES_BIT              0x10000
32 #define FEATURE_STATE_BIT                   0x20000
33 #define FEATURE_SWITCH_BIT                  0x40000
34 #define FEATURE_TRY_BIT                     0x80000
35 #define FEATURE_UNIEVAL_BIT                 0x100000
36 #define FEATURE_UNICODE_BIT                 0x200000
37
38 #define FEATURE_BUNDLE_DEFAULT  0
39 #define FEATURE_BUNDLE_510      1
40 #define FEATURE_BUNDLE_511      2
41 #define FEATURE_BUNDLE_515      3
42 #define FEATURE_BUNDLE_523      4
43 #define FEATURE_BUNDLE_527      5
44 #define FEATURE_BUNDLE_535      6
45 #define FEATURE_BUNDLE_537      7
46 #define FEATURE_BUNDLE_CUSTOM   (HINT_FEATURE_MASK >> HINT_FEATURE_SHIFT)
47
48 /* this is preserved for testing and asserts */
49 #define OLD_CURRENT_HINTS \
50     (PL_curcop == &PL_compiling ? PL_hints : PL_curcop->cop_hints)
51 /* this is the same thing, but simpler (no if) as PL_hints expands
52    to PL_compiling.cop_hints */
53 #define CURRENT_HINTS \
54     PL_curcop->cop_hints
55 #define CURRENT_FEATURE_BUNDLE \
56     ((CURRENT_HINTS & HINT_FEATURE_MASK) >> HINT_FEATURE_SHIFT)
57
58 #define FEATURE_IS_ENABLED_MASK(mask)                   \
59   ((CURRENT_HINTS & HINT_LOCALIZE_HH)                \
60     ? (PL_curcop->cop_features & (mask)) : FALSE)
61
62 /* The longest string we pass in.  */
63 #define MAX_FEATURE_LEN (sizeof("bareword_filehandles")-1)
64
65 #define FEATURE_FC_IS_ENABLED \
66     ( \
67         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
68          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
69      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
70          FEATURE_IS_ENABLED_MASK(FEATURE_FC_BIT)) \
71     )
72
73 #define FEATURE_ISA_IS_ENABLED \
74     ( \
75         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_535 && \
76          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
77      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
78          FEATURE_IS_ENABLED_MASK(FEATURE_ISA_BIT)) \
79     )
80
81 #define FEATURE_SAY_IS_ENABLED \
82     ( \
83         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \
84          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
85      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
86          FEATURE_IS_ENABLED_MASK(FEATURE_SAY_BIT)) \
87     )
88
89 #define FEATURE_TRY_IS_ENABLED \
90     ( \
91         CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
92          FEATURE_IS_ENABLED_MASK(FEATURE_TRY_BIT) \
93     )
94
95 #define FEATURE_CLASS_IS_ENABLED \
96     ( \
97         CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
98          FEATURE_IS_ENABLED_MASK(FEATURE_CLASS_BIT) \
99     )
100
101 #define FEATURE_DEFER_IS_ENABLED \
102     ( \
103         CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
104          FEATURE_IS_ENABLED_MASK(FEATURE_DEFER_BIT) \
105     )
106
107 #define FEATURE_STATE_IS_ENABLED \
108     ( \
109         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \
110          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
111      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
112          FEATURE_IS_ENABLED_MASK(FEATURE_STATE_BIT)) \
113     )
114
115 #define FEATURE_SWITCH_IS_ENABLED \
116     ( \
117         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_510 && \
118          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_527) \
119      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
120          FEATURE_IS_ENABLED_MASK(FEATURE_SWITCH_BIT)) \
121     )
122
123 #define FEATURE_BITWISE_IS_ENABLED \
124     ( \
125         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_527 && \
126          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
127      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
128          FEATURE_IS_ENABLED_MASK(FEATURE_BITWISE_BIT)) \
129     )
130
131 #define FEATURE_INDIRECT_IS_ENABLED \
132     ( \
133         CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_527 \
134      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
135          FEATURE_IS_ENABLED_MASK(FEATURE_INDIRECT_BIT)) \
136     )
137
138 #define FEATURE_EVALBYTES_IS_ENABLED \
139     ( \
140         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
141          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
142      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
143          FEATURE_IS_ENABLED_MASK(FEATURE_EVALBYTES_BIT)) \
144     )
145
146 #define FEATURE_SIGNATURES_IS_ENABLED \
147     ( \
148         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_535 && \
149          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
150      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
151          FEATURE_IS_ENABLED_MASK(FEATURE_SIGNATURES_BIT)) \
152     )
153
154 #define FEATURE___SUB___IS_ENABLED \
155     ( \
156         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
157          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
158      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
159          FEATURE_IS_ENABLED_MASK(FEATURE___SUB___BIT)) \
160     )
161
162 #define FEATURE_MODULE_TRUE_IS_ENABLED \
163     ( \
164         CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_537 \
165      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
166          FEATURE_IS_ENABLED_MASK(FEATURE_MODULE_TRUE_BIT)) \
167     )
168
169 #define FEATURE_REFALIASING_IS_ENABLED \
170     ( \
171         CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
172          FEATURE_IS_ENABLED_MASK(FEATURE_REFALIASING_BIT) \
173     )
174
175 #define FEATURE_POSTDEREF_QQ_IS_ENABLED \
176     ( \
177         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_523 && \
178          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
179      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
180          FEATURE_IS_ENABLED_MASK(FEATURE_POSTDEREF_QQ_BIT)) \
181     )
182
183 #define FEATURE_UNIEVAL_IS_ENABLED \
184     ( \
185         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_515 && \
186          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
187      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
188          FEATURE_IS_ENABLED_MASK(FEATURE_UNIEVAL_BIT)) \
189     )
190
191 #define FEATURE_MYREF_IS_ENABLED \
192     ( \
193         CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
194          FEATURE_IS_ENABLED_MASK(FEATURE_MYREF_BIT) \
195     )
196
197 #define FEATURE_UNICODE_IS_ENABLED \
198     ( \
199         (CURRENT_FEATURE_BUNDLE >= FEATURE_BUNDLE_511 && \
200          CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_537) \
201      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
202          FEATURE_IS_ENABLED_MASK(FEATURE_UNICODE_BIT)) \
203     )
204
205 #define FEATURE_MULTIDIMENSIONAL_IS_ENABLED \
206     ( \
207         CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_527 \
208      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
209          FEATURE_IS_ENABLED_MASK(FEATURE_MULTIDIMENSIONAL_BIT)) \
210     )
211
212 #define FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED \
213     ( \
214         CURRENT_FEATURE_BUNDLE <= FEATURE_BUNDLE_535 \
215      || (CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
216          FEATURE_IS_ENABLED_MASK(FEATURE_BAREWORD_FILEHANDLES_BIT)) \
217     )
218
219 #define FEATURE_MORE_DELIMS_IS_ENABLED \
220     ( \
221         CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM && \
222          FEATURE_IS_ENABLED_MASK(FEATURE_MORE_DELIMS_BIT) \
223     )
224
225
226 #define SAVEFEATUREBITS() SAVEI32(PL_compiling.cop_features)
227
228 #define CLEARFEATUREBITS() (PL_compiling.cop_features = 0)
229
230 #define FETCHFEATUREBITSHH(hh) S_fetch_feature_bits_hh(aTHX_ (hh))
231
232 #endif /* PERL_CORE or PERL_EXT */
233
234 #ifdef PERL_IN_OP_C
235 PERL_STATIC_INLINE void
236 S_enable_feature_bundle(pTHX_ SV *ver)
237 {
238     SV *comp_ver = sv_newmortal();
239     PL_hints = (PL_hints &~ HINT_FEATURE_MASK)
240              | (
241                   (sv_setnv(comp_ver, 5.037),
242                    vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
243                         ? FEATURE_BUNDLE_537 :
244                   (sv_setnv(comp_ver, 5.035),
245                    vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
246                         ? FEATURE_BUNDLE_535 :
247                   (sv_setnv(comp_ver, 5.027),
248                    vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
249                         ? FEATURE_BUNDLE_527 :
250                   (sv_setnv(comp_ver, 5.023),
251                    vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
252                         ? FEATURE_BUNDLE_523 :
253                   (sv_setnv(comp_ver, 5.015),
254                    vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
255                         ? FEATURE_BUNDLE_515 :
256                   (sv_setnv(comp_ver, 5.011),
257                    vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
258                         ? FEATURE_BUNDLE_511 :
259                   (sv_setnv(comp_ver, 5.009005),
260                    vcmp(ver, upg_version(comp_ver, FALSE)) >= 0)
261                         ? FEATURE_BUNDLE_510 :
262                           FEATURE_BUNDLE_DEFAULT
263                ) << HINT_FEATURE_SHIFT;
264     /* special case */
265     assert(PL_curcop == &PL_compiling);
266     if (FEATURE_UNICODE_IS_ENABLED) PL_hints |=  HINT_UNI_8_BIT;
267     else                            PL_hints &= ~HINT_UNI_8_BIT;
268 }
269 #endif /* PERL_IN_OP_C */
270
271 #if defined(PERL_IN_MG_C) || defined(PERL_IN_PP_CTL_C)
272
273 #define magic_sethint_feature(keysv, keypv, keylen, valsv, valbool) \
274     S_magic_sethint_feature(aTHX_ (keysv), (keypv), (keylen), (valsv), (valbool))
275 PERL_STATIC_INLINE void
276 S_magic_sethint_feature(pTHX_ SV *keysv, const char *keypv, STRLEN keylen,
277                         SV *valsv, bool valbool) {
278     if (keysv)
279       keypv = SvPV_const(keysv, keylen);
280
281     if (memBEGINs(keypv, keylen, "feature_")) {
282         const char *subf = keypv + (sizeof("feature_")-1);
283         U32 mask = 0;
284         switch (*subf) {
285         case '_':
286             if (keylen == sizeof("feature___SUB__")-1
287                  && memcmp(subf+1, "_SUB__", keylen - sizeof("feature_")) == 0) {
288                 mask = FEATURE___SUB___BIT;
289                 break;
290             }
291             return;
292
293         case 'b':
294             if (keylen == sizeof("feature_bareword_filehandles")-1
295                  && memcmp(subf+1, "areword_filehandles", keylen - sizeof("feature_")) == 0) {
296                 mask = FEATURE_BAREWORD_FILEHANDLES_BIT;
297                 break;
298             }
299             else if (keylen == sizeof("feature_bitwise")-1
300                  && memcmp(subf+1, "itwise", keylen - sizeof("feature_")) == 0) {
301                 mask = FEATURE_BITWISE_BIT;
302                 break;
303             }
304             return;
305
306         case 'c':
307             if (keylen == sizeof("feature_class")-1
308                  && memcmp(subf+1, "lass", keylen - sizeof("feature_")) == 0) {
309                 mask = FEATURE_CLASS_BIT;
310                 break;
311             }
312             return;
313
314         case 'd':
315             if (keylen == sizeof("feature_defer")-1
316                  && memcmp(subf+1, "efer", keylen - sizeof("feature_")) == 0) {
317                 mask = FEATURE_DEFER_BIT;
318                 break;
319             }
320             return;
321
322         case 'e':
323             if (keylen == sizeof("feature_evalbytes")-1
324                  && memcmp(subf+1, "valbytes", keylen - sizeof("feature_")) == 0) {
325                 mask = FEATURE_EVALBYTES_BIT;
326                 break;
327             }
328             return;
329
330         case 'f':
331             if (keylen == sizeof("feature_fc")-1
332                  && memcmp(subf+1, "c", keylen - sizeof("feature_")) == 0) {
333                 mask = FEATURE_FC_BIT;
334                 break;
335             }
336             return;
337
338         case 'i':
339             if (keylen == sizeof("feature_indirect")-1
340                  && memcmp(subf+1, "ndirect", keylen - sizeof("feature_")) == 0) {
341                 mask = FEATURE_INDIRECT_BIT;
342                 break;
343             }
344             else if (keylen == sizeof("feature_isa")-1
345                  && memcmp(subf+1, "sa", keylen - sizeof("feature_")) == 0) {
346                 mask = FEATURE_ISA_BIT;
347                 break;
348             }
349             return;
350
351         case 'm':
352             if (keylen == sizeof("feature_module_true")-1
353                  && memcmp(subf+1, "odule_true", keylen - sizeof("feature_")) == 0) {
354                 mask = FEATURE_MODULE_TRUE_BIT;
355                 break;
356             }
357             else if (keylen == sizeof("feature_more_delims")-1
358                  && memcmp(subf+1, "ore_delims", keylen - sizeof("feature_")) == 0) {
359                 mask = FEATURE_MORE_DELIMS_BIT;
360                 break;
361             }
362             else if (keylen == sizeof("feature_multidimensional")-1
363                  && memcmp(subf+1, "ultidimensional", keylen - sizeof("feature_")) == 0) {
364                 mask = FEATURE_MULTIDIMENSIONAL_BIT;
365                 break;
366             }
367             else if (keylen == sizeof("feature_myref")-1
368                  && memcmp(subf+1, "yref", keylen - sizeof("feature_")) == 0) {
369                 mask = FEATURE_MYREF_BIT;
370                 break;
371             }
372             return;
373
374         case 'p':
375             if (keylen == sizeof("feature_postderef_qq")-1
376                  && memcmp(subf+1, "ostderef_qq", keylen - sizeof("feature_")) == 0) {
377                 mask = FEATURE_POSTDEREF_QQ_BIT;
378                 break;
379             }
380             return;
381
382         case 'r':
383             if (keylen == sizeof("feature_refaliasing")-1
384                  && memcmp(subf+1, "efaliasing", keylen - sizeof("feature_")) == 0) {
385                 mask = FEATURE_REFALIASING_BIT;
386                 break;
387             }
388             return;
389
390         case 's':
391             if (keylen == sizeof("feature_say")-1
392                  && memcmp(subf+1, "ay", keylen - sizeof("feature_")) == 0) {
393                 mask = FEATURE_SAY_BIT;
394                 break;
395             }
396             else if (keylen == sizeof("feature_signatures")-1
397                  && memcmp(subf+1, "ignatures", keylen - sizeof("feature_")) == 0) {
398                 mask = FEATURE_SIGNATURES_BIT;
399                 break;
400             }
401             else if (keylen == sizeof("feature_state")-1
402                  && memcmp(subf+1, "tate", keylen - sizeof("feature_")) == 0) {
403                 mask = FEATURE_STATE_BIT;
404                 break;
405             }
406             else if (keylen == sizeof("feature_switch")-1
407                  && memcmp(subf+1, "witch", keylen - sizeof("feature_")) == 0) {
408                 mask = FEATURE_SWITCH_BIT;
409                 break;
410             }
411             return;
412
413         case 't':
414             if (keylen == sizeof("feature_try")-1
415                  && memcmp(subf+1, "ry", keylen - sizeof("feature_")) == 0) {
416                 mask = FEATURE_TRY_BIT;
417                 break;
418             }
419             return;
420
421         case 'u':
422             if (keylen == sizeof("feature_unicode")-1
423                  && memcmp(subf+1, "nicode", keylen - sizeof("feature_")) == 0) {
424                 mask = FEATURE_UNICODE_BIT;
425                 break;
426             }
427             else if (keylen == sizeof("feature_unieval")-1
428                  && memcmp(subf+1, "nieval", keylen - sizeof("feature_")) == 0) {
429                 mask = FEATURE_UNIEVAL_BIT;
430                 break;
431             }
432             return;
433
434         default:
435             return;
436         }
437         if (valsv ? SvTRUE(valsv) : valbool)
438             PL_compiling.cop_features |= mask;
439         else
440             PL_compiling.cop_features &= ~mask;
441     }
442 }
443 #endif /* PERL_IN_MG_C */
444
445 /* subject to change */
446 struct perl_feature_bit {
447   const char *name;
448   STRLEN namelen;
449   U32 mask;
450 };
451
452 #ifdef PERL_IN_PP_CTL_C
453
454 static const struct perl_feature_bit
455 PL_feature_bits[] = {
456     {
457         /* feature bareword_filehandles */
458         "feature_bareword_filehandles",
459         STRLENs("feature_bareword_filehandles"),
460         FEATURE_BAREWORD_FILEHANDLES_BIT
461     },
462     {
463         /* feature bitwise */
464         "feature_bitwise",
465         STRLENs("feature_bitwise"),
466         FEATURE_BITWISE_BIT
467     },
468     {
469         /* feature class */
470         "feature_class",
471         STRLENs("feature_class"),
472         FEATURE_CLASS_BIT
473     },
474     {
475         /* feature current_sub */
476         "feature___SUB__",
477         STRLENs("feature___SUB__"),
478         FEATURE___SUB___BIT
479     },
480     {
481         /* feature declared_refs */
482         "feature_myref",
483         STRLENs("feature_myref"),
484         FEATURE_MYREF_BIT
485     },
486     {
487         /* feature defer */
488         "feature_defer",
489         STRLENs("feature_defer"),
490         FEATURE_DEFER_BIT
491     },
492     {
493         /* feature evalbytes */
494         "feature_evalbytes",
495         STRLENs("feature_evalbytes"),
496         FEATURE_EVALBYTES_BIT
497     },
498     {
499         /* feature extra_paired_delimiters */
500         "feature_more_delims",
501         STRLENs("feature_more_delims"),
502         FEATURE_MORE_DELIMS_BIT
503     },
504     {
505         /* feature fc */
506         "feature_fc",
507         STRLENs("feature_fc"),
508         FEATURE_FC_BIT
509     },
510     {
511         /* feature indirect */
512         "feature_indirect",
513         STRLENs("feature_indirect"),
514         FEATURE_INDIRECT_BIT
515     },
516     {
517         /* feature isa */
518         "feature_isa",
519         STRLENs("feature_isa"),
520         FEATURE_ISA_BIT
521     },
522     {
523         /* feature module_true */
524         "feature_module_true",
525         STRLENs("feature_module_true"),
526         FEATURE_MODULE_TRUE_BIT
527     },
528     {
529         /* feature multidimensional */
530         "feature_multidimensional",
531         STRLENs("feature_multidimensional"),
532         FEATURE_MULTIDIMENSIONAL_BIT
533     },
534     {
535         /* feature postderef_qq */
536         "feature_postderef_qq",
537         STRLENs("feature_postderef_qq"),
538         FEATURE_POSTDEREF_QQ_BIT
539     },
540     {
541         /* feature refaliasing */
542         "feature_refaliasing",
543         STRLENs("feature_refaliasing"),
544         FEATURE_REFALIASING_BIT
545     },
546     {
547         /* feature say */
548         "feature_say",
549         STRLENs("feature_say"),
550         FEATURE_SAY_BIT
551     },
552     {
553         /* feature signatures */
554         "feature_signatures",
555         STRLENs("feature_signatures"),
556         FEATURE_SIGNATURES_BIT
557     },
558     {
559         /* feature state */
560         "feature_state",
561         STRLENs("feature_state"),
562         FEATURE_STATE_BIT
563     },
564     {
565         /* feature switch */
566         "feature_switch",
567         STRLENs("feature_switch"),
568         FEATURE_SWITCH_BIT
569     },
570     {
571         /* feature try */
572         "feature_try",
573         STRLENs("feature_try"),
574         FEATURE_TRY_BIT
575     },
576     {
577         /* feature unicode_eval */
578         "feature_unieval",
579         STRLENs("feature_unieval"),
580         FEATURE_UNIEVAL_BIT
581     },
582     {
583         /* feature unicode_strings */
584         "feature_unicode",
585         STRLENs("feature_unicode"),
586         FEATURE_UNICODE_BIT
587     },
588     { NULL, 0, 0U }
589 };
590
591 PERL_STATIC_INLINE void
592 S_fetch_feature_bits_hh(pTHX_ HV *hh) {
593     PL_compiling.cop_features = 0;
594
595     const struct perl_feature_bit *fb = PL_feature_bits;
596     while (fb->name) {
597         SV **svp = hv_fetch(hh, fb->name, (I32)fb->namelen, 0);
598         if (svp && SvTRUE(*svp))
599                PL_compiling.cop_features |= fb->mask;
600         ++fb;
601     }
602 }
603
604 #endif
605
606 #endif /* PERL_FEATURE_H_ */
607
608 /* ex: set ro ft=c: */