File Coverage

lib/XS/JIT/Builder.xs
Criterion Covered Total %
statement 865 888 97.4
branch 266 398 66.8
condition n/a
subroutine n/a
pod n/a
total 1131 1286 87.9


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include "xs_jit_builder.h"
7              
8             /* Store the builder pointer in the object's hash */
9             #define BUILDER_KEY "_builder_ptr"
10             #define BUILDER_KEY_LEN 12
11              
12 2937           static XS_JIT_Builder* get_builder(pTHX_ SV* self) {
13             HV* hv;
14             SV** svp;
15            
16 2937 50         if (!SvROK(self) || SvTYPE(SvRV(self)) != SVt_PVHV) {
    50          
17 0           croak("Not a valid XS::JIT::Builder object");
18             }
19            
20 2937           hv = (HV*)SvRV(self);
21 2937           svp = hv_fetch(hv, BUILDER_KEY, BUILDER_KEY_LEN, 0);
22            
23 2937 50         if (!svp || !SvOK(*svp)) {
    50          
24 0           croak("Builder object not initialized");
25             }
26            
27 2937           return INT2PTR(XS_JIT_Builder*, SvIV(*svp));
28             }
29              
30 369           static void set_builder(pTHX_ SV* self, XS_JIT_Builder* b) {
31 369           HV* hv = (HV*)SvRV(self);
32 369           hv_store(hv, BUILDER_KEY, BUILDER_KEY_LEN, newSViv(PTR2IV(b)), 0);
33 369           }
34              
35             MODULE = XS::JIT::Builder PACKAGE = XS::JIT::Builder
36              
37             PROTOTYPES: DISABLE
38              
39             BOOT:
40             {
41 46           HV* stash = gv_stashpv("XS::JIT::Builder", GV_ADD);
42            
43             /* Inline op type constants */
44 46           newCONSTSUB(stash, "INLINE_NONE", newSViv(XS_JIT_INLINE_NONE));
45 46           newCONSTSUB(stash, "INLINE_GETTER", newSViv(XS_JIT_INLINE_GETTER));
46 46           newCONSTSUB(stash, "INLINE_SETTER", newSViv(XS_JIT_INLINE_SETTER));
47 46           newCONSTSUB(stash, "INLINE_HV_GETTER", newSViv(XS_JIT_INLINE_HV_GETTER));
48 46           newCONSTSUB(stash, "INLINE_HV_SETTER", newSViv(XS_JIT_INLINE_HV_SETTER));
49            
50             /* Type check constants */
51 46           newCONSTSUB(stash, "TYPE_ANY", newSViv(XS_JIT_TYPE_ANY));
52 46           newCONSTSUB(stash, "TYPE_DEFINED", newSViv(XS_JIT_TYPE_DEFINED));
53 46           newCONSTSUB(stash, "TYPE_INT", newSViv(XS_JIT_TYPE_INT));
54 46           newCONSTSUB(stash, "TYPE_NUM", newSViv(XS_JIT_TYPE_NUM));
55 46           newCONSTSUB(stash, "TYPE_STR", newSViv(XS_JIT_TYPE_STR));
56 46           newCONSTSUB(stash, "TYPE_REF", newSViv(XS_JIT_TYPE_REF));
57 46           newCONSTSUB(stash, "TYPE_ARRAYREF", newSViv(XS_JIT_TYPE_ARRAYREF));
58 46           newCONSTSUB(stash, "TYPE_HASHREF", newSViv(XS_JIT_TYPE_HASHREF));
59 46           newCONSTSUB(stash, "TYPE_CODEREF", newSViv(XS_JIT_TYPE_CODEREF));
60 46           newCONSTSUB(stash, "TYPE_OBJECT", newSViv(XS_JIT_TYPE_OBJECT));
61 46           newCONSTSUB(stash, "TYPE_BLESSED", newSViv(XS_JIT_TYPE_BLESSED));
62             }
63              
64             SV*
65             new(class, ...)
66             const char* class
67             PREINIT:
68             HV* hv;
69             SV* self;
70             XS_JIT_Builder* b;
71 369           int indent_width = 4;
72 369           int use_tabs = 0;
73             int i;
74             CODE:
75             /* Parse options */
76 375 100         for (i = 1; i < items; i += 2) {
77 6 50         if (i + 1 < items) {
78 6           const char* key = SvPV_nolen(ST(i));
79 6 100         if (strEQ(key, "indent_width")) {
80 4           indent_width = SvIV(ST(i + 1));
81 2 50         } else if (strEQ(key, "use_tabs")) {
82 2           use_tabs = SvTRUE(ST(i + 1)) ? 1 : 0;
83             }
84             }
85             }
86            
87             /* Create the builder */
88 369           b = xs_jit_builder_new(aTHX);
89 369           xs_jit_set_indent_width(b, indent_width);
90 369           xs_jit_set_use_tabs(b, use_tabs);
91            
92             /* Create blessed hashref */
93 369           hv = newHV();
94 369           self = newRV_noinc((SV*)hv);
95 369           sv_bless(self, gv_stashpv(class, GV_ADD));
96            
97             /* Store the pointer */
98 369           set_builder(aTHX_ self, b);
99            
100 369           RETVAL = self;
101             OUTPUT:
102             RETVAL
103              
104             void
105             DESTROY(self)
106             SV* self
107             PREINIT:
108             XS_JIT_Builder* b;
109             CODE:
110 369           b = get_builder(aTHX_ self);
111 369           xs_jit_builder_free(aTHX_ b);
112              
113             SV*
114             code(self)
115             SV* self
116             PREINIT:
117             XS_JIT_Builder* b;
118             CODE:
119 416           b = get_builder(aTHX_ self);
120 416           RETVAL = xs_jit_builder_code(aTHX_ b);
121             OUTPUT:
122             RETVAL
123              
124             SV*
125             reset(self)
126             SV* self
127             PREINIT:
128             XS_JIT_Builder* b;
129             CODE:
130 74           b = get_builder(aTHX_ self);
131 74           xs_jit_builder_reset(aTHX_ b);
132 74           RETVAL = SvREFCNT_inc(self);
133             OUTPUT:
134             RETVAL
135              
136             SV*
137             line(self, fmt, ...)
138             SV* self
139             const char* fmt
140             PREINIT:
141             XS_JIT_Builder* b;
142             CODE:
143 143           b = get_builder(aTHX_ self);
144 143           xs_jit_line(aTHX_ b, "%s", fmt);
145 143           RETVAL = SvREFCNT_inc(self);
146             OUTPUT:
147             RETVAL
148              
149             SV*
150             raw(self, text)
151             SV* self
152             const char* text
153             PREINIT:
154             XS_JIT_Builder* b;
155             CODE:
156 93           b = get_builder(aTHX_ self);
157 93           xs_jit_raw(aTHX_ b, "%s", text);
158 93           RETVAL = SvREFCNT_inc(self);
159             OUTPUT:
160             RETVAL
161              
162             SV*
163             comment(self, text)
164             SV* self
165             const char* text
166             PREINIT:
167             XS_JIT_Builder* b;
168             CODE:
169 4           b = get_builder(aTHX_ self);
170 4           xs_jit_comment(aTHX_ b, text);
171 4           RETVAL = SvREFCNT_inc(self);
172             OUTPUT:
173             RETVAL
174              
175             SV*
176             blank(self)
177             SV* self
178             PREINIT:
179             XS_JIT_Builder* b;
180             CODE:
181 27           b = get_builder(aTHX_ self);
182 27           xs_jit_blank(aTHX_ b);
183 27           RETVAL = SvREFCNT_inc(self);
184             OUTPUT:
185             RETVAL
186              
187             SV*
188             indent(self)
189             SV* self
190             PREINIT:
191             XS_JIT_Builder* b;
192             CODE:
193 7           b = get_builder(aTHX_ self);
194 7           xs_jit_indent(b);
195 7           RETVAL = SvREFCNT_inc(self);
196             OUTPUT:
197             RETVAL
198              
199             SV*
200             dedent(self)
201             SV* self
202             PREINIT:
203             XS_JIT_Builder* b;
204             CODE:
205 4           b = get_builder(aTHX_ self);
206 4           xs_jit_dedent(b);
207 4           RETVAL = SvREFCNT_inc(self);
208             OUTPUT:
209             RETVAL
210              
211             SV*
212             block_start(self)
213             SV* self
214             PREINIT:
215             XS_JIT_Builder* b;
216             CODE:
217 2           b = get_builder(aTHX_ self);
218 2           xs_jit_block_start(aTHX_ b);
219 2           RETVAL = SvREFCNT_inc(self);
220             OUTPUT:
221             RETVAL
222              
223             SV*
224             block_end(self)
225             SV* self
226             PREINIT:
227             XS_JIT_Builder* b;
228             CODE:
229 2           b = get_builder(aTHX_ self);
230 2           xs_jit_block_end(aTHX_ b);
231 2           RETVAL = SvREFCNT_inc(self);
232             OUTPUT:
233             RETVAL
234              
235             SV*
236             xs_function(self, name)
237             SV* self
238             const char* name
239             PREINIT:
240             XS_JIT_Builder* b;
241             CODE:
242 183           b = get_builder(aTHX_ self);
243 183           xs_jit_xs_function(aTHX_ b, name);
244 183           RETVAL = SvREFCNT_inc(self);
245             OUTPUT:
246             RETVAL
247              
248             SV*
249             xs_preamble(self)
250             SV* self
251             PREINIT:
252             XS_JIT_Builder* b;
253             CODE:
254 180           b = get_builder(aTHX_ self);
255 180           xs_jit_xs_preamble(aTHX_ b);
256 180           RETVAL = SvREFCNT_inc(self);
257             OUTPUT:
258             RETVAL
259              
260             SV*
261             xs_end(self)
262             SV* self
263             PREINIT:
264             XS_JIT_Builder* b;
265             CODE:
266 182           b = get_builder(aTHX_ self);
267 182           xs_jit_xs_end(aTHX_ b);
268 182           RETVAL = SvREFCNT_inc(self);
269             OUTPUT:
270             RETVAL
271              
272             SV*
273             xs_return(self, count)
274             SV* self
275             int count
276             PREINIT:
277             XS_JIT_Builder* b;
278             CODE:
279 25           b = get_builder(aTHX_ self);
280 25           xs_jit_xs_return(aTHX_ b, count);
281 25           RETVAL = SvREFCNT_inc(self);
282             OUTPUT:
283             RETVAL
284              
285             SV*
286             xs_return_undef(self)
287             SV* self
288             PREINIT:
289             XS_JIT_Builder* b;
290             CODE:
291 13           b = get_builder(aTHX_ self);
292 13           xs_jit_xs_return_undef(aTHX_ b);
293 13           RETVAL = SvREFCNT_inc(self);
294             OUTPUT:
295             RETVAL
296              
297             SV*
298             return_undef(self)
299             SV* self
300             PREINIT:
301             XS_JIT_Builder* b;
302             CODE:
303 10           b = get_builder(aTHX_ self);
304 10           xs_jit_xs_return_undef(aTHX_ b);
305 10           RETVAL = SvREFCNT_inc(self);
306             OUTPUT:
307             RETVAL
308              
309             SV*
310             croak_usage(self, usage)
311             SV* self
312             const char* usage
313             PREINIT:
314             XS_JIT_Builder* b;
315             CODE:
316 5           b = get_builder(aTHX_ self);
317 5           xs_jit_croak_usage(aTHX_ b, usage);
318 5           RETVAL = SvREFCNT_inc(self);
319             OUTPUT:
320             RETVAL
321              
322             SV*
323             if(self, cond)
324             SV* self
325             const char* cond
326             PREINIT:
327             XS_JIT_Builder* b;
328             CODE:
329 74           b = get_builder(aTHX_ self);
330 74           xs_jit_if(aTHX_ b, cond);
331 74           RETVAL = SvREFCNT_inc(self);
332             OUTPUT:
333             RETVAL
334              
335             SV*
336             elsif(self, cond)
337             SV* self
338             const char* cond
339             PREINIT:
340             XS_JIT_Builder* b;
341             CODE:
342 7           b = get_builder(aTHX_ self);
343 7           xs_jit_elsif(aTHX_ b, cond);
344 7           RETVAL = SvREFCNT_inc(self);
345             OUTPUT:
346             RETVAL
347              
348             SV*
349             else(self)
350             SV* self
351             PREINIT:
352             XS_JIT_Builder* b;
353             CODE:
354 20           b = get_builder(aTHX_ self);
355 20           xs_jit_else(aTHX_ b);
356 20           RETVAL = SvREFCNT_inc(self);
357             OUTPUT:
358             RETVAL
359              
360             SV*
361             endif(self)
362             SV* self
363             PREINIT:
364             XS_JIT_Builder* b;
365             CODE:
366 76           b = get_builder(aTHX_ self);
367 76           xs_jit_endif(aTHX_ b);
368 76           RETVAL = SvREFCNT_inc(self);
369             OUTPUT:
370             RETVAL
371              
372             SV*
373             for(self, init, cond, incr)
374             SV* self
375             const char* init
376             const char* cond
377             const char* incr
378             PREINIT:
379             XS_JIT_Builder* b;
380             CODE:
381 13           b = get_builder(aTHX_ self);
382 13           xs_jit_for(aTHX_ b, init, cond, incr);
383 13           RETVAL = SvREFCNT_inc(self);
384             OUTPUT:
385             RETVAL
386              
387             SV*
388             while(self, cond)
389             SV* self
390             const char* cond
391             PREINIT:
392             XS_JIT_Builder* b;
393             CODE:
394 4           b = get_builder(aTHX_ self);
395 4           xs_jit_while(aTHX_ b, cond);
396 4           RETVAL = SvREFCNT_inc(self);
397             OUTPUT:
398             RETVAL
399              
400             SV*
401             endloop(self)
402             SV* self
403             PREINIT:
404             XS_JIT_Builder* b;
405             CODE:
406 5           b = get_builder(aTHX_ self);
407 5           xs_jit_endloop(aTHX_ b);
408 5           RETVAL = SvREFCNT_inc(self);
409             OUTPUT:
410             RETVAL
411              
412             SV*
413             endfor(self)
414             SV* self
415             PREINIT:
416             XS_JIT_Builder* b;
417             CODE:
418 9           b = get_builder(aTHX_ self);
419 9           xs_jit_endloop(aTHX_ b);
420 9           RETVAL = SvREFCNT_inc(self);
421             OUTPUT:
422             RETVAL
423              
424             SV*
425             endwhile(self)
426             SV* self
427             PREINIT:
428             XS_JIT_Builder* b;
429             CODE:
430 2           b = get_builder(aTHX_ self);
431 2           xs_jit_endloop(aTHX_ b);
432 2           RETVAL = SvREFCNT_inc(self);
433             OUTPUT:
434             RETVAL
435              
436             SV*
437             block(self)
438             SV* self
439             PREINIT:
440             XS_JIT_Builder* b;
441             CODE:
442 1           b = get_builder(aTHX_ self);
443 1           xs_jit_block_start(aTHX_ b);
444 1           RETVAL = SvREFCNT_inc(self);
445             OUTPUT:
446             RETVAL
447              
448             SV*
449             endblock(self)
450             SV* self
451             PREINIT:
452             XS_JIT_Builder* b;
453             CODE:
454 1           b = get_builder(aTHX_ self);
455 1           xs_jit_block_end(aTHX_ b);
456 1           RETVAL = SvREFCNT_inc(self);
457             OUTPUT:
458             RETVAL
459              
460             SV*
461             declare(self, type, name, ...)
462             SV* self
463             const char* type
464             const char* name
465             PREINIT:
466             XS_JIT_Builder* b;
467 24           const char* value = NULL;
468             CODE:
469 24 50         if (items > 3 && SvOK(ST(3))) {
    100          
470 19           value = SvPV_nolen(ST(3));
471             }
472 24           b = get_builder(aTHX_ self);
473 24           xs_jit_declare(aTHX_ b, type, name, value);
474 24           RETVAL = SvREFCNT_inc(self);
475             OUTPUT:
476             RETVAL
477              
478             SV*
479             declare_sv(self, name, value)
480             SV* self
481             const char* name
482             const char* value
483             PREINIT:
484             XS_JIT_Builder* b;
485             CODE:
486 62           b = get_builder(aTHX_ self);
487 62           xs_jit_declare_sv(aTHX_ b, name, value);
488 62           RETVAL = SvREFCNT_inc(self);
489             OUTPUT:
490             RETVAL
491              
492             SV*
493             declare_hv(self, name, value)
494             SV* self
495             const char* name
496             const char* value
497             PREINIT:
498             XS_JIT_Builder* b;
499             CODE:
500 10           b = get_builder(aTHX_ self);
501 10           xs_jit_declare_hv(aTHX_ b, name, value);
502 10           RETVAL = SvREFCNT_inc(self);
503             OUTPUT:
504             RETVAL
505              
506             SV*
507             declare_av(self, name, value)
508             SV* self
509             const char* name
510             const char* value
511             PREINIT:
512             XS_JIT_Builder* b;
513             CODE:
514 12           b = get_builder(aTHX_ self);
515 12           xs_jit_declare_av(aTHX_ b, name, value);
516 12           RETVAL = SvREFCNT_inc(self);
517             OUTPUT:
518             RETVAL
519              
520             SV*
521             new_hv(self, name)
522             SV* self
523             const char* name
524             PREINIT:
525             XS_JIT_Builder* b;
526             CODE:
527 10           b = get_builder(aTHX_ self);
528 10           xs_jit_declare_hv(aTHX_ b, name, "newHV()");
529 10           RETVAL = SvREFCNT_inc(self);
530             OUTPUT:
531             RETVAL
532              
533             SV*
534             new_av(self, name)
535             SV* self
536             const char* name
537             PREINIT:
538             XS_JIT_Builder* b;
539             CODE:
540 2           b = get_builder(aTHX_ self);
541 2           xs_jit_declare_av(aTHX_ b, name, "newAV()");
542 2           RETVAL = SvREFCNT_inc(self);
543             OUTPUT:
544             RETVAL
545              
546             SV*
547             declare_int(self, name, value)
548             SV* self
549             const char* name
550             const char* value
551             PREINIT:
552             XS_JIT_Builder* b;
553             CODE:
554 3           b = get_builder(aTHX_ self);
555 3           xs_jit_declare_int(aTHX_ b, name, value);
556 3           RETVAL = SvREFCNT_inc(self);
557             OUTPUT:
558             RETVAL
559              
560             SV*
561             declare_iv(self, name, value)
562             SV* self
563             const char* name
564             const char* value
565             PREINIT:
566             XS_JIT_Builder* b;
567             CODE:
568 42           b = get_builder(aTHX_ self);
569 42           xs_jit_declare_iv(aTHX_ b, name, value);
570 42           RETVAL = SvREFCNT_inc(self);
571             OUTPUT:
572             RETVAL
573              
574             SV*
575             declare_nv(self, name, value)
576             SV* self
577             const char* name
578             const char* value
579             PREINIT:
580             XS_JIT_Builder* b;
581             CODE:
582 16           b = get_builder(aTHX_ self);
583 16           xs_jit_declare_nv(aTHX_ b, name, value);
584 16           RETVAL = SvREFCNT_inc(self);
585             OUTPUT:
586             RETVAL
587              
588             SV*
589             declare_pv(self, name, value)
590             SV* self
591             const char* name
592             const char* value
593             PREINIT:
594             XS_JIT_Builder* b;
595             CODE:
596 5           b = get_builder(aTHX_ self);
597 5           xs_jit_declare_pv(aTHX_ b, name, value);
598 5           RETVAL = SvREFCNT_inc(self);
599             OUTPUT:
600             RETVAL
601              
602             SV*
603             assign(self, var, value)
604             SV* self
605             const char* var
606             const char* value
607             PREINIT:
608             XS_JIT_Builder* b;
609             CODE:
610 1           b = get_builder(aTHX_ self);
611 1           xs_jit_assign(aTHX_ b, var, value);
612 1           RETVAL = SvREFCNT_inc(self);
613             OUTPUT:
614             RETVAL
615              
616             SV*
617             get_self(self)
618             SV* self
619             PREINIT:
620             XS_JIT_Builder* b;
621             CODE:
622 8           b = get_builder(aTHX_ self);
623 8           xs_jit_get_self(aTHX_ b);
624 8           RETVAL = SvREFCNT_inc(self);
625             OUTPUT:
626             RETVAL
627              
628             SV*
629             get_self_hv(self)
630             SV* self
631             PREINIT:
632             XS_JIT_Builder* b;
633             CODE:
634 29           b = get_builder(aTHX_ self);
635 29           xs_jit_get_self_hv(aTHX_ b);
636 29           RETVAL = SvREFCNT_inc(self);
637             OUTPUT:
638             RETVAL
639              
640             SV*
641             get_self_av(self)
642             SV* self
643             PREINIT:
644             XS_JIT_Builder* b;
645             CODE:
646 2           b = get_builder(aTHX_ self);
647 2           xs_jit_get_self_av(aTHX_ b);
648 2           RETVAL = SvREFCNT_inc(self);
649             OUTPUT:
650             RETVAL
651              
652             SV*
653             hv_fetch(self, hv, key, len, result_var)
654             SV* self
655             const char* hv
656             const char* key
657             STRLEN len
658             const char* result_var
659             PREINIT:
660             XS_JIT_Builder* b;
661             CODE:
662 28           b = get_builder(aTHX_ self);
663 28           xs_jit_hv_fetch(aTHX_ b, hv, key, len, result_var);
664 28           RETVAL = SvREFCNT_inc(self);
665             OUTPUT:
666             RETVAL
667              
668             SV*
669             hv_fetch_sv(self, hv, key_expr, len_expr, result_var)
670             SV* self
671             const char* hv
672             const char* key_expr
673             const char* len_expr
674             const char* result_var
675             PREINIT:
676             XS_JIT_Builder* b;
677             CODE:
678 2           b = get_builder(aTHX_ self);
679 2           xs_jit_hv_fetch_sv(aTHX_ b, hv, key_expr, len_expr, result_var);
680 2           RETVAL = SvREFCNT_inc(self);
681             OUTPUT:
682             RETVAL
683              
684             SV*
685             hv_store(self, hv, key, len, value)
686             SV* self
687             const char* hv
688             const char* key
689             STRLEN len
690             const char* value
691             PREINIT:
692             XS_JIT_Builder* b;
693             CODE:
694 26           b = get_builder(aTHX_ self);
695 26           xs_jit_hv_store(aTHX_ b, hv, key, len, value);
696 26           RETVAL = SvREFCNT_inc(self);
697             OUTPUT:
698             RETVAL
699              
700             SV*
701             hv_store_sv(self, hv, key_expr, len_expr, value)
702             SV* self
703             const char* hv
704             const char* key_expr
705             const char* len_expr
706             const char* value
707             PREINIT:
708             XS_JIT_Builder* b;
709             CODE:
710 2           b = get_builder(aTHX_ self);
711 2           xs_jit_hv_store_sv(aTHX_ b, hv, key_expr, len_expr, value);
712 2           RETVAL = SvREFCNT_inc(self);
713             OUTPUT:
714             RETVAL
715              
716             SV*
717             hv_fetch_return(self, hv, key, len)
718             SV* self
719             const char* hv
720             const char* key
721             STRLEN len
722             PREINIT:
723             XS_JIT_Builder* b;
724             CODE:
725 3           b = get_builder(aTHX_ self);
726 3           xs_jit_hv_fetch_return(aTHX_ b, hv, key, len);
727 3           RETVAL = SvREFCNT_inc(self);
728             OUTPUT:
729             RETVAL
730              
731             SV*
732             av_fetch(self, av, index, result_var)
733             SV* self
734             const char* av
735             const char* index
736             const char* result_var
737             PREINIT:
738             XS_JIT_Builder* b;
739             CODE:
740 6           b = get_builder(aTHX_ self);
741 6           xs_jit_av_fetch(aTHX_ b, av, index, result_var);
742 6           RETVAL = SvREFCNT_inc(self);
743             OUTPUT:
744             RETVAL
745              
746             SV*
747             av_store(self, av, index, value)
748             SV* self
749             const char* av
750             const char* index
751             const char* value
752             PREINIT:
753             XS_JIT_Builder* b;
754             CODE:
755 3           b = get_builder(aTHX_ self);
756 3           xs_jit_av_store(aTHX_ b, av, index, value);
757 3           RETVAL = SvREFCNT_inc(self);
758             OUTPUT:
759             RETVAL
760              
761             SV*
762             av_push(self, av, value)
763             SV* self
764             const char* av
765             const char* value
766             PREINIT:
767             XS_JIT_Builder* b;
768             CODE:
769 7           b = get_builder(aTHX_ self);
770 7           xs_jit_av_push(aTHX_ b, av, value);
771 7           RETVAL = SvREFCNT_inc(self);
772             OUTPUT:
773             RETVAL
774              
775             SV*
776             av_len(self, av, result_var)
777             SV* self
778             const char* av
779             const char* result_var
780             PREINIT:
781             XS_JIT_Builder* b;
782             CODE:
783 4           b = get_builder(aTHX_ self);
784 4           xs_jit_av_len(aTHX_ b, av, result_var);
785 4           RETVAL = SvREFCNT_inc(self);
786             OUTPUT:
787             RETVAL
788              
789             SV*
790             new_sv_iv(self, result_var, value)
791             SV* self
792             const char* result_var
793             const char* value
794             PREINIT:
795             XS_JIT_Builder* b;
796             CODE:
797 3           b = get_builder(aTHX_ self);
798 3           xs_jit_new_sv_iv(aTHX_ b, result_var, value);
799 3           RETVAL = SvREFCNT_inc(self);
800             OUTPUT:
801             RETVAL
802              
803             SV*
804             new_sv_nv(self, result_var, value)
805             SV* self
806             const char* result_var
807             const char* value
808             PREINIT:
809             XS_JIT_Builder* b;
810             CODE:
811 3           b = get_builder(aTHX_ self);
812 3           xs_jit_new_sv_nv(aTHX_ b, result_var, value);
813 3           RETVAL = SvREFCNT_inc(self);
814             OUTPUT:
815             RETVAL
816              
817             SV*
818             new_sv_pv(self, result_var, str, len)
819             SV* self
820             const char* result_var
821             const char* str
822             STRLEN len
823             PREINIT:
824             XS_JIT_Builder* b;
825             CODE:
826 3           b = get_builder(aTHX_ self);
827 3           xs_jit_new_sv_pv(aTHX_ b, result_var, str, len);
828 3           RETVAL = SvREFCNT_inc(self);
829             OUTPUT:
830             RETVAL
831              
832             SV*
833             mortal(self, sv)
834             SV* self
835             const char* sv
836             PREINIT:
837             XS_JIT_Builder* b;
838             CODE:
839 6           b = get_builder(aTHX_ self);
840 6           xs_jit_mortal(aTHX_ b, sv);
841 6           RETVAL = SvREFCNT_inc(self);
842             OUTPUT:
843             RETVAL
844              
845             SV*
846             croak(self, message)
847             SV* self
848             const char* message
849             PREINIT:
850             XS_JIT_Builder* b;
851             CODE:
852 7           b = get_builder(aTHX_ self);
853 7           xs_jit_croak(aTHX_ b, message);
854 7           RETVAL = SvREFCNT_inc(self);
855             OUTPUT:
856             RETVAL
857              
858             SV*
859             warn(self, message)
860             SV* self
861             const char* message
862             PREINIT:
863             XS_JIT_Builder* b;
864             CODE:
865 3           b = get_builder(aTHX_ self);
866 3           xs_jit_warn(aTHX_ b, message);
867 3           RETVAL = SvREFCNT_inc(self);
868             OUTPUT:
869             RETVAL
870              
871             SV*
872             check_items(self, min, max, usage)
873             SV* self
874             int min
875             int max
876             const char* usage
877             PREINIT:
878             XS_JIT_Builder* b;
879             CODE:
880 19           b = get_builder(aTHX_ self);
881 19           xs_jit_check_items(aTHX_ b, min, max, usage);
882 19           RETVAL = SvREFCNT_inc(self);
883             OUTPUT:
884             RETVAL
885              
886             SV*
887             check_defined(self, sv, error_msg)
888             SV* self
889             const char* sv
890             const char* error_msg
891             PREINIT:
892             XS_JIT_Builder* b;
893             CODE:
894 3           b = get_builder(aTHX_ self);
895 3           xs_jit_check_defined(aTHX_ b, sv, error_msg);
896 3           RETVAL = SvREFCNT_inc(self);
897             OUTPUT:
898             RETVAL
899              
900             SV*
901             check_hashref(self, sv, error_msg)
902             SV* self
903             const char* sv
904             const char* error_msg
905             PREINIT:
906             XS_JIT_Builder* b;
907             CODE:
908 3           b = get_builder(aTHX_ self);
909 3           xs_jit_check_hashref(aTHX_ b, sv, error_msg);
910 3           RETVAL = SvREFCNT_inc(self);
911             OUTPUT:
912             RETVAL
913              
914             SV*
915             check_arrayref(self, sv, error_msg)
916             SV* self
917             const char* sv
918             const char* error_msg
919             PREINIT:
920             XS_JIT_Builder* b;
921             CODE:
922 3           b = get_builder(aTHX_ self);
923 3           xs_jit_check_arrayref(aTHX_ b, sv, error_msg);
924 3           RETVAL = SvREFCNT_inc(self);
925             OUTPUT:
926             RETVAL
927              
928             SV*
929             sv_to_iv(self, result_var, sv)
930             SV* self
931             const char* result_var
932             const char* sv
933             PREINIT:
934             XS_JIT_Builder* b;
935             CODE:
936 3           b = get_builder(aTHX_ self);
937 3           xs_jit_sv_to_iv(aTHX_ b, result_var, sv);
938 3           RETVAL = SvREFCNT_inc(self);
939             OUTPUT:
940             RETVAL
941              
942             SV*
943             sv_to_nv(self, result_var, sv)
944             SV* self
945             const char* result_var
946             const char* sv
947             PREINIT:
948             XS_JIT_Builder* b;
949             CODE:
950 3           b = get_builder(aTHX_ self);
951 3           xs_jit_sv_to_nv(aTHX_ b, result_var, sv);
952 3           RETVAL = SvREFCNT_inc(self);
953             OUTPUT:
954             RETVAL
955              
956             SV*
957             sv_to_pv(self, result_var, len_var, sv)
958             SV* self
959             const char* result_var
960             SV* len_var
961             const char* sv
962             PREINIT:
963             XS_JIT_Builder* b;
964 5           const char* len_var_str = NULL;
965             CODE:
966 5 100         if (SvOK(len_var)) {
967 3           len_var_str = SvPV_nolen(len_var);
968             }
969 5           b = get_builder(aTHX_ self);
970 5           xs_jit_sv_to_pv(aTHX_ b, result_var, len_var_str, sv);
971 5           RETVAL = SvREFCNT_inc(self);
972             OUTPUT:
973             RETVAL
974              
975             SV*
976             sv_to_bool(self, result_var, sv)
977             SV* self
978             const char* result_var
979             const char* sv
980             PREINIT:
981             XS_JIT_Builder* b;
982             CODE:
983 3           b = get_builder(aTHX_ self);
984 3           xs_jit_sv_to_bool(aTHX_ b, result_var, sv);
985 3           RETVAL = SvREFCNT_inc(self);
986             OUTPUT:
987             RETVAL
988              
989             SV*
990             return_iv(self, value)
991             SV* self
992             const char* value
993             PREINIT:
994             XS_JIT_Builder* b;
995             CODE:
996 54           b = get_builder(aTHX_ self);
997 54           xs_jit_return_iv(aTHX_ b, value);
998 54           RETVAL = SvREFCNT_inc(self);
999             OUTPUT:
1000             RETVAL
1001              
1002             SV*
1003             return_nv(self, value)
1004             SV* self
1005             const char* value
1006             PREINIT:
1007             XS_JIT_Builder* b;
1008             CODE:
1009 13           b = get_builder(aTHX_ self);
1010 13           xs_jit_return_nv(aTHX_ b, value);
1011 13           RETVAL = SvREFCNT_inc(self);
1012             OUTPUT:
1013             RETVAL
1014              
1015             SV*
1016             return_pv(self, str, ...)
1017             SV* self
1018             const char* str
1019             PREINIT:
1020             XS_JIT_Builder* b;
1021 22           const char* len_str = NULL;
1022             CODE:
1023 22 100         if (items > 2 && SvOK(ST(2))) {
    100          
1024 3           len_str = SvPV_nolen(ST(2));
1025             }
1026 22           b = get_builder(aTHX_ self);
1027 22           xs_jit_return_pv(aTHX_ b, str, len_str);
1028 22           RETVAL = SvREFCNT_inc(self);
1029             OUTPUT:
1030             RETVAL
1031              
1032             SV*
1033             return_sv(self, sv)
1034             SV* self
1035             const char* sv
1036             PREINIT:
1037             XS_JIT_Builder* b;
1038             CODE:
1039 36           b = get_builder(aTHX_ self);
1040 36           xs_jit_return_sv(aTHX_ b, sv);
1041 36           RETVAL = SvREFCNT_inc(self);
1042             OUTPUT:
1043             RETVAL
1044              
1045             SV*
1046             return_yes(self)
1047             SV* self
1048             PREINIT:
1049             XS_JIT_Builder* b;
1050             CODE:
1051 7           b = get_builder(aTHX_ self);
1052 7           xs_jit_return_yes(aTHX_ b);
1053 7           RETVAL = SvREFCNT_inc(self);
1054             OUTPUT:
1055             RETVAL
1056              
1057             SV*
1058             return_no(self)
1059             SV* self
1060             PREINIT:
1061             XS_JIT_Builder* b;
1062             CODE:
1063 3           b = get_builder(aTHX_ self);
1064 3           xs_jit_return_no(aTHX_ b);
1065 3           RETVAL = SvREFCNT_inc(self);
1066             OUTPUT:
1067             RETVAL
1068              
1069             SV*
1070             return_self(self)
1071             SV* self
1072             PREINIT:
1073             XS_JIT_Builder* b;
1074             CODE:
1075 9           b = get_builder(aTHX_ self);
1076 9           xs_jit_return_self(aTHX_ b);
1077 9           RETVAL = SvREFCNT_inc(self);
1078             OUTPUT:
1079             RETVAL
1080              
1081             SV*
1082             method_start(self, func_name, min_args, max_args, usage)
1083             SV* self
1084             const char* func_name
1085             int min_args
1086             int max_args
1087             const char* usage
1088             PREINIT:
1089             XS_JIT_Builder* b;
1090             CODE:
1091 2           b = get_builder(aTHX_ self);
1092 2           xs_jit_method_start(aTHX_ b, func_name, min_args, max_args, usage);
1093 2           RETVAL = SvREFCNT_inc(self);
1094             OUTPUT:
1095             RETVAL
1096              
1097             SV*
1098             ro_accessor(self, func_name, attr_name, attr_len)
1099             SV* self
1100             const char* func_name
1101             const char* attr_name
1102             STRLEN attr_len
1103             PREINIT:
1104             XS_JIT_Builder* b;
1105             CODE:
1106 4           b = get_builder(aTHX_ self);
1107 4           xs_jit_ro_accessor(aTHX_ b, func_name, attr_name, attr_len);
1108 4           RETVAL = SvREFCNT_inc(self);
1109             OUTPUT:
1110             RETVAL
1111              
1112             SV*
1113             rw_accessor(self, func_name, attr_name, attr_len)
1114             SV* self
1115             const char* func_name
1116             const char* attr_name
1117             STRLEN attr_len
1118             PREINIT:
1119             XS_JIT_Builder* b;
1120             CODE:
1121 33           b = get_builder(aTHX_ self);
1122 33           xs_jit_rw_accessor(aTHX_ b, func_name, attr_name, attr_len);
1123 33           RETVAL = SvREFCNT_inc(self);
1124             OUTPUT:
1125             RETVAL
1126              
1127             SV*
1128             accessor(self, attr_name, ...)
1129             SV* self
1130             const char* attr_name
1131             PREINIT:
1132             XS_JIT_Builder* b;
1133 10           int readonly = 0;
1134             STRLEN attr_len;
1135             CODE:
1136 10           b = get_builder(aTHX_ self);
1137 10           attr_len = strlen(attr_name);
1138             /* Check for readonly option in hash-style args */
1139 10 50         if (items > 2) {
1140 10           SV* opts = ST(2);
1141 10 50         if (SvROK(opts) && SvTYPE(SvRV(opts)) == SVt_PVHV) {
    50          
1142 10           HV* hv = (HV*)SvRV(opts);
1143 10           SV** val = hv_fetchs(hv, "readonly", 0);
1144 10 50         if (val && *val && SvTRUE(*val)) {
    50          
    100          
1145 1           readonly = 1;
1146             }
1147             }
1148             }
1149 10 100         if (readonly) {
1150 1           xs_jit_ro_accessor(aTHX_ b, attr_name, attr_name, attr_len);
1151             } else {
1152 9           xs_jit_rw_accessor(aTHX_ b, attr_name, attr_name, attr_len);
1153             }
1154 10           RETVAL = SvREFCNT_inc(self);
1155             OUTPUT:
1156             RETVAL
1157              
1158             SV*
1159             predicate(self, attr_name)
1160             SV* self
1161             const char* attr_name
1162             PREINIT:
1163             XS_JIT_Builder* b;
1164             char func_name[256];
1165             STRLEN attr_len;
1166             CODE:
1167 4           b = get_builder(aTHX_ self);
1168 4           attr_len = strlen(attr_name);
1169 4           snprintf(func_name, sizeof(func_name), "has_%s", attr_name);
1170 4           xs_jit_predicate(aTHX_ b, func_name, attr_name, attr_len);
1171 4           RETVAL = SvREFCNT_inc(self);
1172             OUTPUT:
1173             RETVAL
1174              
1175             SV*
1176             clearer(self, attr_name)
1177             SV* self
1178             const char* attr_name
1179             PREINIT:
1180             XS_JIT_Builder* b;
1181             char func_name[256];
1182             STRLEN attr_len;
1183             CODE:
1184 4           b = get_builder(aTHX_ self);
1185 4           attr_len = strlen(attr_name);
1186 4           snprintf(func_name, sizeof(func_name), "clear_%s", attr_name);
1187 4           xs_jit_clearer(aTHX_ b, func_name, attr_name, attr_len);
1188 4           RETVAL = SvREFCNT_inc(self);
1189             OUTPUT:
1190             RETVAL
1191              
1192             SV*
1193             constructor(self, func_name, attrs)
1194             SV* self
1195             const char* func_name
1196             AV* attrs
1197             PREINIT:
1198             XS_JIT_Builder* b;
1199             XS_JIT_Attr* attr_array;
1200             int num_attrs;
1201             int i;
1202             CODE:
1203 6           b = get_builder(aTHX_ self);
1204 6           num_attrs = av_len(attrs) + 1;
1205            
1206 6 100         if (num_attrs > 0) {
1207 3           Newx(attr_array, num_attrs, XS_JIT_Attr);
1208            
1209 11 100         for (i = 0; i < num_attrs; i++) {
1210 8           SV** elem = av_fetch(attrs, i, 0);
1211 16 50         if (elem && SvROK(*elem) && SvTYPE(SvRV(*elem)) == SVt_PVAV) {
    50          
    50          
1212 8           AV* pair = (AV*)SvRV(*elem);
1213 8           SV** name_sv = av_fetch(pair, 0, 0);
1214 8           SV** len_sv = av_fetch(pair, 1, 0);
1215            
1216 8 50         if (name_sv && len_sv) {
    50          
1217 8           attr_array[i].name = SvPV_nolen(*name_sv);
1218 8           attr_array[i].len = SvIV(*len_sv);
1219             }
1220 0 0         } else if (elem && SvPOK(*elem)) {
    0          
1221             /* Simple string attribute name */
1222 0           attr_array[i].name = SvPV_nolen(*elem);
1223 0           attr_array[i].len = SvCUR(*elem);
1224             }
1225             }
1226            
1227 3           xs_jit_constructor(aTHX_ b, func_name, NULL, attr_array, num_attrs);
1228 3           Safefree(attr_array);
1229             } else {
1230 3           xs_jit_constructor(aTHX_ b, func_name, NULL, NULL, 0);
1231             }
1232            
1233 6           RETVAL = SvREFCNT_inc(self);
1234             OUTPUT:
1235             RETVAL
1236              
1237             SV*
1238             new_simple(self, func_name)
1239             SV* self
1240             const char* func_name
1241             PREINIT:
1242             XS_JIT_Builder* b;
1243             CODE:
1244 3           b = get_builder(aTHX_ self);
1245 3           xs_jit_new_simple(aTHX_ b, func_name);
1246 3           RETVAL = SvREFCNT_inc(self);
1247             OUTPUT:
1248             RETVAL
1249              
1250             SV*
1251             new_hash(self, func_name)
1252             SV* self
1253             const char* func_name
1254             PREINIT:
1255             XS_JIT_Builder* b;
1256             CODE:
1257 28           b = get_builder(aTHX_ self);
1258 28           xs_jit_new_hash(aTHX_ b, func_name);
1259 28           RETVAL = SvREFCNT_inc(self);
1260             OUTPUT:
1261             RETVAL
1262              
1263             SV*
1264             new_array(self, func_name, num_slots)
1265             SV* self
1266             const char* func_name
1267             int num_slots
1268             PREINIT:
1269             XS_JIT_Builder* b;
1270             CODE:
1271 1           b = get_builder(aTHX_ self);
1272 1           xs_jit_new_array(aTHX_ b, func_name, num_slots);
1273 1           RETVAL = SvREFCNT_inc(self);
1274             OUTPUT:
1275             RETVAL
1276              
1277             SV*
1278             new_with_build(self, func_name)
1279             SV* self
1280             const char* func_name
1281             PREINIT:
1282             XS_JIT_Builder* b;
1283             CODE:
1284 2           b = get_builder(aTHX_ self);
1285 2           xs_jit_new_with_build(aTHX_ b, func_name);
1286 2           RETVAL = SvREFCNT_inc(self);
1287             OUTPUT:
1288             RETVAL
1289              
1290             SV*
1291             clone_hash(self, func_name)
1292             SV* self
1293             const char* func_name
1294             PREINIT:
1295             XS_JIT_Builder* b;
1296             CODE:
1297 4           b = get_builder(aTHX_ self);
1298 4           xs_jit_clone_hash(aTHX_ b, func_name);
1299 4           RETVAL = SvREFCNT_inc(self);
1300             OUTPUT:
1301             RETVAL
1302              
1303             SV*
1304             clone_array(self, func_name)
1305             SV* self
1306             const char* func_name
1307             PREINIT:
1308             XS_JIT_Builder* b;
1309             CODE:
1310 4           b = get_builder(aTHX_ self);
1311 4           xs_jit_clone_array(aTHX_ b, func_name);
1312 4           RETVAL = SvREFCNT_inc(self);
1313             OUTPUT:
1314             RETVAL
1315              
1316             SV*
1317             new_with_required(self, func_name, required_av)
1318             SV* self
1319             const char* func_name
1320             AV* required_av
1321             PREINIT:
1322             XS_JIT_Builder* b;
1323             const char** required_attrs;
1324             STRLEN* required_lens;
1325             int num_required;
1326             int i;
1327             CODE:
1328 6           b = get_builder(aTHX_ self);
1329 6           num_required = av_len(required_av) + 1;
1330 6 50         if (num_required > 0) {
1331 6           Newx(required_attrs, num_required, const char*);
1332 6           Newx(required_lens, num_required, STRLEN);
1333 15 100         for (i = 0; i < num_required; i++) {
1334 9           SV** elem = av_fetch(required_av, i, 0);
1335 9 50         if (elem && *elem) {
    50          
1336 9           required_attrs[i] = SvPV(*elem, required_lens[i]);
1337             } else {
1338 0           required_attrs[i] = "";
1339 0           required_lens[i] = 0;
1340             }
1341             }
1342 6           xs_jit_new_with_required(aTHX_ b, func_name, required_attrs, required_lens, num_required);
1343 6           Safefree(required_attrs);
1344 6           Safefree(required_lens);
1345             } else {
1346 0           xs_jit_new_with_required(aTHX_ b, func_name, NULL, NULL, 0);
1347             }
1348 6           RETVAL = SvREFCNT_inc(self);
1349             OUTPUT:
1350             RETVAL
1351              
1352             SV*
1353             rw_accessor_typed(self, func_name, attr_name, attr_len, type, error_msg)
1354             SV* self
1355             const char* func_name
1356             const char* attr_name
1357             STRLEN attr_len
1358             int type
1359             const char* error_msg
1360             PREINIT:
1361             XS_JIT_Builder* b;
1362             CODE:
1363 10           b = get_builder(aTHX_ self);
1364 10           xs_jit_rw_accessor_typed(aTHX_ b, func_name, attr_name, attr_len, type, error_msg);
1365 10           RETVAL = SvREFCNT_inc(self);
1366             OUTPUT:
1367             RETVAL
1368              
1369             SV*
1370             rw_accessor_weak(self, func_name, attr_name, attr_len)
1371             SV* self
1372             const char* func_name
1373             const char* attr_name
1374             STRLEN attr_len
1375             PREINIT:
1376             XS_JIT_Builder* b;
1377             CODE:
1378 4           b = get_builder(aTHX_ self);
1379 4           xs_jit_rw_accessor_weak(aTHX_ b, func_name, attr_name, attr_len);
1380 4           RETVAL = SvREFCNT_inc(self);
1381             OUTPUT:
1382             RETVAL
1383              
1384             SV*
1385             hv_store_weak(self, hv_name, key, key_len, value_expr)
1386             SV* self
1387             const char* hv_name
1388             const char* key
1389             int key_len
1390             const char* value_expr
1391             PREINIT:
1392             XS_JIT_Builder* b;
1393             CODE:
1394 2           b = get_builder(aTHX_ self);
1395 2           xs_jit_hv_store_weak(aTHX_ b, hv_name, key, key_len, value_expr);
1396 2           RETVAL = SvREFCNT_inc(self);
1397             OUTPUT:
1398             RETVAL
1399              
1400             SV*
1401             new_complete(self, func_name, attrs_av, call_build)
1402             SV* self
1403             const char* func_name
1404             AV* attrs_av
1405             int call_build
1406             PREINIT:
1407             XS_JIT_Builder* b;
1408             XS_JIT_AttrSpec* attrs;
1409             int num_attrs;
1410             int i;
1411             CODE:
1412 14           b = get_builder(aTHX_ self);
1413 14           num_attrs = av_len(attrs_av) + 1;
1414            
1415 14 100         if (num_attrs > 0) {
1416 13           Newxz(attrs, num_attrs, XS_JIT_AttrSpec);
1417            
1418 30 100         for (i = 0; i < num_attrs; i++) {
1419 17           SV** elem = av_fetch(attrs_av, i, 0);
1420 17 50         if (elem && SvROK(*elem) && SvTYPE(SvRV(*elem)) == SVt_PVHV) {
    50          
    50          
1421 17           HV* spec = (HV*)SvRV(*elem);
1422             SV** val;
1423            
1424             /* Required: name */
1425 17           val = hv_fetchs(spec, "name", 0);
1426 17 50         if (val && SvOK(*val)) {
    50          
1427 17           attrs[i].name = SvPV(*val, attrs[i].len);
1428             }
1429            
1430             /* Optional: required */
1431 17           val = hv_fetchs(spec, "required", 0);
1432 17 100         if (val && SvTRUE(*val)) {
    50          
1433 3           attrs[i].required = 1;
1434             }
1435            
1436             /* Optional: type */
1437 17           val = hv_fetchs(spec, "type", 0);
1438 17 100         if (val && SvIOK(*val)) {
    50          
1439 3           attrs[i].type = SvIV(*val);
1440             }
1441            
1442             /* Optional: type_msg */
1443 17           val = hv_fetchs(spec, "type_msg", 0);
1444 17 100         if (val && SvOK(*val)) {
    50          
1445 3           attrs[i].type_msg = SvPV_nolen(*val);
1446             }
1447            
1448             /* Optional: weak */
1449 17           val = hv_fetchs(spec, "weak", 0);
1450 17 100         if (val && SvTRUE(*val)) {
    50          
1451 1           attrs[i].weak = 1;
1452             }
1453            
1454             /* Optional: coerce */
1455 17           val = hv_fetchs(spec, "coerce", 0);
1456 17 100         if (val && SvOK(*val)) {
    50          
1457 1           attrs[i].coerce = SvPV(*val, attrs[i].coerce_len);
1458             }
1459            
1460             /* Optional: default_iv */
1461 17           val = hv_fetchs(spec, "default_iv", 0);
1462 17 100         if (val && SvOK(*val)) {
    50          
1463 3           attrs[i].has_default = XS_JIT_DEFAULT_IV;
1464 3           attrs[i].default_iv = SvIV(*val);
1465             }
1466            
1467             /* Optional: default_nv */
1468 17           val = hv_fetchs(spec, "default_nv", 0);
1469 17 50         if (val && SvOK(*val)) {
    0          
1470 0           attrs[i].has_default = XS_JIT_DEFAULT_NV;
1471 0           attrs[i].default_nv = SvNV(*val);
1472             }
1473            
1474             /* Optional: default_pv */
1475 17           val = hv_fetchs(spec, "default_pv", 0);
1476 17 100         if (val && SvOK(*val)) {
    50          
1477 2           attrs[i].has_default = XS_JIT_DEFAULT_PV;
1478 2           attrs[i].default_pv = SvPV(*val, attrs[i].default_pv_len);
1479             }
1480            
1481             /* Optional: default_av (creates empty []) */
1482 17           val = hv_fetchs(spec, "default_av", 0);
1483 17 100         if (val && SvTRUE(*val)) {
    50          
1484 2           attrs[i].has_default = XS_JIT_DEFAULT_AV;
1485             }
1486            
1487             /* Optional: default_hv (creates empty {}) */
1488 17           val = hv_fetchs(spec, "default_hv", 0);
1489 17 100         if (val && SvTRUE(*val)) {
    50          
1490 1           attrs[i].has_default = XS_JIT_DEFAULT_HV;
1491             }
1492             }
1493             }
1494            
1495 13           xs_jit_new_complete(aTHX_ b, func_name, attrs, num_attrs, call_build);
1496 13           Safefree(attrs);
1497             } else {
1498 1           xs_jit_new_complete(aTHX_ b, func_name, NULL, 0, call_build);
1499             }
1500            
1501 14           RETVAL = SvREFCNT_inc(self);
1502             OUTPUT:
1503             RETVAL
1504              
1505             SV*
1506             call_sv(self, cv_expr, args_av)
1507             SV* self
1508             const char* cv_expr
1509             AV* args_av
1510             PREINIT:
1511             XS_JIT_Builder* b;
1512             const char** args;
1513             int num_args;
1514             int i;
1515             CODE:
1516 1           b = get_builder(aTHX_ self);
1517 1           num_args = av_len(args_av) + 1;
1518            
1519 1 50         if (num_args > 0) {
1520 1           Newxz(args, num_args, const char*);
1521 3 100         for (i = 0; i < num_args; i++) {
1522 2           SV** elem = av_fetch(args_av, i, 0);
1523 2 50         if (elem && SvOK(*elem)) {
    50          
1524 2           args[i] = SvPV_nolen(*elem);
1525             } else {
1526 0           args[i] = "NULL";
1527             }
1528             }
1529 1           xs_jit_call_sv(aTHX_ b, cv_expr, args, num_args);
1530 1           Safefree(args);
1531             } else {
1532 0           xs_jit_call_sv(aTHX_ b, cv_expr, NULL, 0);
1533             }
1534            
1535 1           RETVAL = SvREFCNT_inc(self);
1536             OUTPUT:
1537             RETVAL
1538              
1539             SV*
1540             call_method(self, method_name, invocant, args_av)
1541             SV* self
1542             const char* method_name
1543             const char* invocant
1544             AV* args_av
1545             PREINIT:
1546             XS_JIT_Builder* b;
1547             const char** args;
1548             int num_args;
1549             int i;
1550             CODE:
1551 1           b = get_builder(aTHX_ self);
1552 1           num_args = av_len(args_av) + 1;
1553            
1554 1 50         if (num_args > 0) {
1555 1           Newxz(args, num_args, const char*);
1556 3 100         for (i = 0; i < num_args; i++) {
1557 2           SV** elem = av_fetch(args_av, i, 0);
1558 2 50         if (elem && SvOK(*elem)) {
    50          
1559 2           args[i] = SvPV_nolen(*elem);
1560             } else {
1561 0           args[i] = "NULL";
1562             }
1563             }
1564 1           xs_jit_call_method(aTHX_ b, method_name, invocant, args, num_args);
1565 1           Safefree(args);
1566             } else {
1567 0           xs_jit_call_method(aTHX_ b, method_name, invocant, NULL, 0);
1568             }
1569            
1570 1           RETVAL = SvREFCNT_inc(self);
1571             OUTPUT:
1572             RETVAL
1573              
1574             SV*
1575             rw_accessor_trigger(self, func_name, attr_name, attr_len, trigger_method)
1576             SV* self
1577             const char* func_name
1578             const char* attr_name
1579             STRLEN attr_len
1580             const char* trigger_method
1581             PREINIT:
1582             XS_JIT_Builder* b;
1583             CODE:
1584 2           b = get_builder(aTHX_ self);
1585 2           xs_jit_rw_accessor_trigger(aTHX_ b, func_name, attr_name, attr_len, trigger_method);
1586 2           RETVAL = SvREFCNT_inc(self);
1587             OUTPUT:
1588             RETVAL
1589              
1590             SV*
1591             accessor_lazy_builder(self, func_name, attr_name, attr_len, builder_method)
1592             SV* self
1593             const char* func_name
1594             const char* attr_name
1595             STRLEN attr_len
1596             const char* builder_method
1597             PREINIT:
1598             XS_JIT_Builder* b;
1599             CODE:
1600 1           b = get_builder(aTHX_ self);
1601 1           xs_jit_accessor_lazy_builder(aTHX_ b, func_name, attr_name, attr_len, builder_method);
1602 1           RETVAL = SvREFCNT_inc(self);
1603             OUTPUT:
1604             RETVAL
1605              
1606             SV*
1607             destroy_with_demolish(self, func_name)
1608             SV* self
1609             const char* func_name
1610             PREINIT:
1611             XS_JIT_Builder* b;
1612             CODE:
1613 1           b = get_builder(aTHX_ self);
1614 1           xs_jit_destroy_with_demolish(aTHX_ b, func_name);
1615 1           RETVAL = SvREFCNT_inc(self);
1616             OUTPUT:
1617             RETVAL
1618              
1619             SV*
1620             do_loop(self)
1621             SV* self
1622             PREINIT:
1623             XS_JIT_Builder* b;
1624             CODE:
1625 1           b = get_builder(aTHX_ self);
1626 1           xs_jit_do(aTHX_ b);
1627 1           RETVAL = SvREFCNT_inc(self);
1628             OUTPUT:
1629             RETVAL
1630              
1631             SV*
1632             end_do_while(self, condition)
1633             SV* self
1634             const char* condition
1635             PREINIT:
1636             XS_JIT_Builder* b;
1637             CODE:
1638 1           b = get_builder(aTHX_ self);
1639 1           xs_jit_end_do_while(aTHX_ b, condition);
1640 1           RETVAL = SvREFCNT_inc(self);
1641             OUTPUT:
1642             RETVAL
1643              
1644             SV*
1645             if_list_context(self)
1646             SV* self
1647             PREINIT:
1648             XS_JIT_Builder* b;
1649             CODE:
1650 1           b = get_builder(aTHX_ self);
1651 1           xs_jit_if_list_context(aTHX_ b);
1652 1           RETVAL = SvREFCNT_inc(self);
1653             OUTPUT:
1654             RETVAL
1655              
1656             SV*
1657             if_scalar_context(self)
1658             SV* self
1659             PREINIT:
1660             XS_JIT_Builder* b;
1661             CODE:
1662 1           b = get_builder(aTHX_ self);
1663 1           xs_jit_if_scalar_context(aTHX_ b);
1664 1           RETVAL = SvREFCNT_inc(self);
1665             OUTPUT:
1666             RETVAL
1667              
1668             SV*
1669             extend_stack(self, count_expr)
1670             SV* self
1671             const char* count_expr
1672             PREINIT:
1673             XS_JIT_Builder* b;
1674             CODE:
1675 1           b = get_builder(aTHX_ self);
1676 1           xs_jit_extend_stack(aTHX_ b, count_expr);
1677 1           RETVAL = SvREFCNT_inc(self);
1678             OUTPUT:
1679             RETVAL
1680              
1681             SV*
1682             return_list(self, values_av)
1683             SV* self
1684             AV* values_av
1685             PREINIT:
1686             XS_JIT_Builder* b;
1687             const char** values;
1688             int num_values;
1689             int i;
1690             CODE:
1691 1           b = get_builder(aTHX_ self);
1692 1           num_values = av_len(values_av) + 1;
1693            
1694 1 50         if (num_values > 0) {
1695 1           Newxz(values, num_values, const char*);
1696 4 100         for (i = 0; i < num_values; i++) {
1697 3           SV** elem = av_fetch(values_av, i, 0);
1698 3 50         if (elem && SvOK(*elem)) {
    50          
1699 3           values[i] = SvPV_nolen(*elem);
1700             } else {
1701 0           values[i] = "&PL_sv_undef";
1702             }
1703             }
1704 1           xs_jit_return_list(aTHX_ b, values, num_values);
1705 1           Safefree(values);
1706             } else {
1707 0           xs_jit_return_list(aTHX_ b, NULL, 0);
1708             }
1709            
1710 1           RETVAL = SvREFCNT_inc(self);
1711             OUTPUT:
1712             RETVAL
1713              
1714             SV*
1715             declare_ternary(self, type, name, cond, true_expr, false_expr)
1716             SV* self
1717             const char* type
1718             const char* name
1719             const char* cond
1720             const char* true_expr
1721             const char* false_expr
1722             PREINIT:
1723             XS_JIT_Builder* b;
1724             CODE:
1725 1           b = get_builder(aTHX_ self);
1726 1           xs_jit_declare_ternary(aTHX_ b, type, name, cond, true_expr, false_expr);
1727 1           RETVAL = SvREFCNT_inc(self);
1728             OUTPUT:
1729             RETVAL
1730              
1731             SV*
1732             assign_ternary(self, var, cond, true_expr, false_expr)
1733             SV* self
1734             const char* var
1735             const char* cond
1736             const char* true_expr
1737             const char* false_expr
1738             PREINIT:
1739             XS_JIT_Builder* b;
1740             CODE:
1741 1           b = get_builder(aTHX_ self);
1742 1           xs_jit_assign_ternary(aTHX_ b, var, cond, true_expr, false_expr);
1743 1           RETVAL = SvREFCNT_inc(self);
1744             OUTPUT:
1745             RETVAL
1746              
1747             SV*
1748             delegate_method(self, func_name, attr_name, attr_len, target_method)
1749             SV* self
1750             const char* func_name
1751             const char* attr_name
1752             STRLEN attr_len
1753             const char* target_method
1754             PREINIT:
1755             XS_JIT_Builder* b;
1756             CODE:
1757 3           b = get_builder(aTHX_ self);
1758 3           xs_jit_delegate_method(aTHX_ b, func_name, attr_name, attr_len, target_method);
1759 3           RETVAL = SvREFCNT_inc(self);
1760             OUTPUT:
1761             RETVAL
1762              
1763             SV*
1764             singleton_accessor(self, func_name, class_name)
1765             SV* self
1766             const char* func_name
1767             const char* class_name
1768             PREINIT:
1769             XS_JIT_Builder* b;
1770             CODE:
1771 4           b = get_builder(aTHX_ self);
1772 4           xs_jit_singleton_accessor(aTHX_ b, func_name, class_name);
1773 4           RETVAL = SvREFCNT_inc(self);
1774             OUTPUT:
1775             RETVAL
1776              
1777             SV*
1778             singleton_reset(self, func_name, class_name)
1779             SV* self
1780             const char* func_name
1781             const char* class_name
1782             PREINIT:
1783             XS_JIT_Builder* b;
1784             CODE:
1785 2           b = get_builder(aTHX_ self);
1786 2           xs_jit_singleton_reset(aTHX_ b, func_name, class_name);
1787 2           RETVAL = SvREFCNT_inc(self);
1788             OUTPUT:
1789             RETVAL
1790              
1791             SV*
1792             registry_add(self, func_name, registry_attr)
1793             SV* self
1794             const char* func_name
1795             SV* registry_attr
1796             PREINIT:
1797             XS_JIT_Builder* b;
1798             const char* attr_str;
1799             STRLEN attr_len;
1800             CODE:
1801 13           b = get_builder(aTHX_ self);
1802 13           attr_str = SvPV(registry_attr, attr_len);
1803 13           xs_jit_registry_add(aTHX_ b, func_name, attr_str, attr_len);
1804 13           RETVAL = SvREFCNT_inc(self);
1805             OUTPUT:
1806             RETVAL
1807              
1808             SV*
1809             registry_get(self, func_name, registry_attr)
1810             SV* self
1811             const char* func_name
1812             SV* registry_attr
1813             PREINIT:
1814             XS_JIT_Builder* b;
1815             const char* attr_str;
1816             STRLEN attr_len;
1817             CODE:
1818 11           b = get_builder(aTHX_ self);
1819 11           attr_str = SvPV(registry_attr, attr_len);
1820 11           xs_jit_registry_get(aTHX_ b, func_name, attr_str, attr_len);
1821 11           RETVAL = SvREFCNT_inc(self);
1822             OUTPUT:
1823             RETVAL
1824              
1825             SV*
1826             registry_remove(self, func_name, registry_attr)
1827             SV* self
1828             const char* func_name
1829             SV* registry_attr
1830             PREINIT:
1831             XS_JIT_Builder* b;
1832             const char* attr_str;
1833             STRLEN attr_len;
1834             CODE:
1835 3           b = get_builder(aTHX_ self);
1836 3           attr_str = SvPV(registry_attr, attr_len);
1837 3           xs_jit_registry_remove(aTHX_ b, func_name, attr_str, attr_len);
1838 3           RETVAL = SvREFCNT_inc(self);
1839             OUTPUT:
1840             RETVAL
1841              
1842             SV*
1843             registry_all(self, func_name, registry_attr)
1844             SV* self
1845             const char* func_name
1846             SV* registry_attr
1847             PREINIT:
1848             XS_JIT_Builder* b;
1849             const char* attr_str;
1850             STRLEN attr_len;
1851             CODE:
1852 5           b = get_builder(aTHX_ self);
1853 5           attr_str = SvPV(registry_attr, attr_len);
1854 5           xs_jit_registry_all(aTHX_ b, func_name, attr_str, attr_len);
1855 5           RETVAL = SvREFCNT_inc(self);
1856             OUTPUT:
1857             RETVAL
1858              
1859             SV*
1860             wrap_before(self, func_name, orig_name, before_cv_name)
1861             SV* self
1862             const char* func_name
1863             const char* orig_name
1864             const char* before_cv_name
1865             PREINIT:
1866             XS_JIT_Builder* b;
1867             CODE:
1868 6           b = get_builder(aTHX_ self);
1869 6           xs_jit_wrap_before(aTHX_ b, func_name, orig_name, before_cv_name);
1870 6           RETVAL = SvREFCNT_inc(self);
1871             OUTPUT:
1872             RETVAL
1873              
1874             SV*
1875             wrap_after(self, func_name, orig_name, after_cv_name)
1876             SV* self
1877             const char* func_name
1878             const char* orig_name
1879             const char* after_cv_name
1880             PREINIT:
1881             XS_JIT_Builder* b;
1882             CODE:
1883 5           b = get_builder(aTHX_ self);
1884 5           xs_jit_wrap_after(aTHX_ b, func_name, orig_name, after_cv_name);
1885 5           RETVAL = SvREFCNT_inc(self);
1886             OUTPUT:
1887             RETVAL
1888              
1889             SV*
1890             wrap_around(self, func_name, orig_name, around_cv_name)
1891             SV* self
1892             const char* func_name
1893             const char* orig_name
1894             const char* around_cv_name
1895             PREINIT:
1896             XS_JIT_Builder* b;
1897             CODE:
1898 6           b = get_builder(aTHX_ self);
1899 6           xs_jit_wrap_around(aTHX_ b, func_name, orig_name, around_cv_name);
1900 6           RETVAL = SvREFCNT_inc(self);
1901             OUTPUT:
1902             RETVAL
1903              
1904             SV*
1905             op_ro_accessor(self, func_name, slot)
1906             SV* self
1907             const char* func_name
1908             IV slot
1909             PREINIT:
1910             XS_JIT_Builder* b;
1911             CODE:
1912 3           b = get_builder(aTHX_ self);
1913 3           xs_jit_op_ro_accessor(aTHX_ b, func_name, slot);
1914 3           RETVAL = SvREFCNT_inc(self);
1915             OUTPUT:
1916             RETVAL
1917              
1918             SV*
1919             op_rw_accessor(self, func_name, slot)
1920             SV* self
1921             const char* func_name
1922             IV slot
1923             PREINIT:
1924             XS_JIT_Builder* b;
1925             CODE:
1926 4           b = get_builder(aTHX_ self);
1927 4           xs_jit_op_rw_accessor(aTHX_ b, func_name, slot);
1928 4           RETVAL = SvREFCNT_inc(self);
1929             OUTPUT:
1930             RETVAL
1931              
1932             void
1933             inline_init()
1934             CODE:
1935 1           xs_jit_inline_init(aTHX);
1936              
1937             int
1938             inline_register(cv, type, slot, ...)
1939             CV* cv
1940             int type
1941             IV slot
1942             PREINIT:
1943 2           const char* key = NULL;
1944 2 50         STRLEN key_len = 0;
1945             CODE:
1946             /* Optional key for hash-based accessors */
1947 2 50         if (items > 3) {
1948 0           key = SvPV(ST(3), key_len);
1949             }
1950 2           RETVAL = xs_jit_inline_register(aTHX_ cv, (XS_JIT_InlineType)type, slot, key, key_len);
1951             OUTPUT:
1952             RETVAL
1953              
1954             int
1955             inline_get_type(cv)
1956             CV* cv
1957             CODE:
1958 2 50         RETVAL = (int)xs_jit_inline_get_type(aTHX_ cv);
1959             OUTPUT:
1960             RETVAL
1961              
1962             # ============================================
1963             # Custom op builder methods
1964             # ============================================
1965              
1966             SV*
1967             pp_start(self, name)
1968             SV* self
1969             const char* name
1970             PREINIT:
1971             XS_JIT_Builder* b;
1972             CODE:
1973 20           b = get_builder(aTHX_ self);
1974 20           xs_jit_pp_start(aTHX_ b, name);
1975 20           RETVAL = SvREFCNT_inc(self);
1976             OUTPUT:
1977             RETVAL
1978              
1979             SV*
1980             pp_end(self)
1981             SV* self
1982             PREINIT:
1983             XS_JIT_Builder* b;
1984             CODE:
1985 6           b = get_builder(aTHX_ self);
1986 6           xs_jit_pp_end(aTHX_ b);
1987 6           RETVAL = SvREFCNT_inc(self);
1988             OUTPUT:
1989             RETVAL
1990              
1991             SV*
1992             pp_dsp(self)
1993             SV* self
1994             PREINIT:
1995             XS_JIT_Builder* b;
1996             CODE:
1997 18           b = get_builder(aTHX_ self);
1998 18           xs_jit_pp_dsp(aTHX_ b);
1999 18           RETVAL = SvREFCNT_inc(self);
2000             OUTPUT:
2001             RETVAL
2002              
2003             SV*
2004             pp_get_self(self)
2005             SV* self
2006             PREINIT:
2007             XS_JIT_Builder* b;
2008             CODE:
2009 7           b = get_builder(aTHX_ self);
2010 7           xs_jit_pp_get_self(aTHX_ b);
2011 7           RETVAL = SvREFCNT_inc(self);
2012             OUTPUT:
2013             RETVAL
2014              
2015             SV*
2016             pp_pop_self(self)
2017             SV* self
2018             PREINIT:
2019             XS_JIT_Builder* b;
2020             CODE:
2021 2           b = get_builder(aTHX_ self);
2022 2           xs_jit_pp_pop_self(aTHX_ b);
2023 2           RETVAL = SvREFCNT_inc(self);
2024             OUTPUT:
2025             RETVAL
2026              
2027             SV*
2028             pp_pop_sv(self, name)
2029             SV* self
2030             const char* name
2031             PREINIT:
2032             XS_JIT_Builder* b;
2033             CODE:
2034 2           b = get_builder(aTHX_ self);
2035 2           xs_jit_pp_pop_sv(aTHX_ b, name);
2036 2           RETVAL = SvREFCNT_inc(self);
2037             OUTPUT:
2038             RETVAL
2039              
2040             SV*
2041             pp_pop_nv(self, name)
2042             SV* self
2043             const char* name
2044             PREINIT:
2045             XS_JIT_Builder* b;
2046             CODE:
2047 1           b = get_builder(aTHX_ self);
2048 1           xs_jit_pp_pop_nv(aTHX_ b, name);
2049 1           RETVAL = SvREFCNT_inc(self);
2050             OUTPUT:
2051             RETVAL
2052              
2053             SV*
2054             pp_pop_iv(self, name)
2055             SV* self
2056             const char* name
2057             PREINIT:
2058             XS_JIT_Builder* b;
2059             CODE:
2060 1           b = get_builder(aTHX_ self);
2061 1           xs_jit_pp_pop_iv(aTHX_ b, name);
2062 1           RETVAL = SvREFCNT_inc(self);
2063             OUTPUT:
2064             RETVAL
2065              
2066             SV*
2067             pp_get_slots(self)
2068             SV* self
2069             PREINIT:
2070             XS_JIT_Builder* b;
2071             CODE:
2072 7           b = get_builder(aTHX_ self);
2073 7           xs_jit_pp_get_slots(aTHX_ b);
2074 7           RETVAL = SvREFCNT_inc(self);
2075             OUTPUT:
2076             RETVAL
2077              
2078             SV*
2079             pp_slot(self, name, slot)
2080             SV* self
2081             const char* name
2082             IV slot
2083             PREINIT:
2084             XS_JIT_Builder* b;
2085             CODE:
2086 2           b = get_builder(aTHX_ self);
2087 2           xs_jit_pp_slot(aTHX_ b, name, slot);
2088 2           RETVAL = SvREFCNT_inc(self);
2089             OUTPUT:
2090             RETVAL
2091              
2092             SV*
2093             pp_return_sv(self, sv_expr)
2094             SV* self
2095             const char* sv_expr
2096             PREINIT:
2097             XS_JIT_Builder* b;
2098             CODE:
2099 4           b = get_builder(aTHX_ self);
2100 4           xs_jit_pp_return_sv(aTHX_ b, sv_expr);
2101 4           RETVAL = SvREFCNT_inc(self);
2102             OUTPUT:
2103             RETVAL
2104              
2105             SV*
2106             pp_return_nv(self, nv_expr)
2107             SV* self
2108             const char* nv_expr
2109             PREINIT:
2110             XS_JIT_Builder* b;
2111             CODE:
2112 1           b = get_builder(aTHX_ self);
2113 1           xs_jit_pp_return_nv(aTHX_ b, nv_expr);
2114 1           RETVAL = SvREFCNT_inc(self);
2115             OUTPUT:
2116             RETVAL
2117              
2118             SV*
2119             pp_return_iv(self, iv_expr)
2120             SV* self
2121             const char* iv_expr
2122             PREINIT:
2123             XS_JIT_Builder* b;
2124             CODE:
2125 2           b = get_builder(aTHX_ self);
2126 2           xs_jit_pp_return_iv(aTHX_ b, iv_expr);
2127 2           RETVAL = SvREFCNT_inc(self);
2128             OUTPUT:
2129             RETVAL
2130              
2131             SV*
2132             pp_return_pv(self, pv_expr)
2133             SV* self
2134             const char* pv_expr
2135             PREINIT:
2136             XS_JIT_Builder* b;
2137             CODE:
2138 1           b = get_builder(aTHX_ self);
2139 1           xs_jit_pp_return_pv(aTHX_ b, pv_expr);
2140 1           RETVAL = SvREFCNT_inc(self);
2141             OUTPUT:
2142             RETVAL
2143              
2144             SV*
2145             pp_return(self)
2146             SV* self
2147             PREINIT:
2148             XS_JIT_Builder* b;
2149             CODE:
2150 3           b = get_builder(aTHX_ self);
2151 3           xs_jit_pp_return(aTHX_ b);
2152 3           RETVAL = SvREFCNT_inc(self);
2153             OUTPUT:
2154             RETVAL
2155              
2156             # ============================================
2157             # Call checker builder methods
2158             # ============================================
2159              
2160             SV*
2161             ck_start(self, name)
2162             SV* self
2163             const char* name
2164             PREINIT:
2165             XS_JIT_Builder* b;
2166             CODE:
2167 9           b = get_builder(aTHX_ self);
2168 9           xs_jit_ck_start(aTHX_ b, name);
2169 9           RETVAL = SvREFCNT_inc(self);
2170             OUTPUT:
2171             RETVAL
2172              
2173             SV*
2174             ck_end(self)
2175             SV* self
2176             PREINIT:
2177             XS_JIT_Builder* b;
2178             CODE:
2179 4           b = get_builder(aTHX_ self);
2180 4           xs_jit_ck_end(aTHX_ b);
2181 4           RETVAL = SvREFCNT_inc(self);
2182             OUTPUT:
2183             RETVAL
2184              
2185             SV*
2186             ck_preamble(self)
2187             SV* self
2188             PREINIT:
2189             XS_JIT_Builder* b;
2190             CODE:
2191 7           b = get_builder(aTHX_ self);
2192 7           xs_jit_ck_preamble(aTHX_ b);
2193 7           RETVAL = SvREFCNT_inc(self);
2194             OUTPUT:
2195             RETVAL
2196              
2197             SV*
2198             ck_build_unop(self, pp_func, targ_expr)
2199             SV* self
2200             const char* pp_func
2201             const char* targ_expr
2202             PREINIT:
2203             XS_JIT_Builder* b;
2204             CODE:
2205 3           b = get_builder(aTHX_ self);
2206 3           xs_jit_ck_build_unop(aTHX_ b, pp_func, targ_expr);
2207 3           RETVAL = SvREFCNT_inc(self);
2208             OUTPUT:
2209             RETVAL
2210              
2211             SV*
2212             ck_build_binop(self, pp_func, targ_expr)
2213             SV* self
2214             const char* pp_func
2215             const char* targ_expr
2216             PREINIT:
2217             XS_JIT_Builder* b;
2218             CODE:
2219 1           b = get_builder(aTHX_ self);
2220 1           xs_jit_ck_build_binop(aTHX_ b, pp_func, targ_expr);
2221 1           RETVAL = SvREFCNT_inc(self);
2222             OUTPUT:
2223             RETVAL
2224              
2225             SV*
2226             ck_fallback(self)
2227             SV* self
2228             PREINIT:
2229             XS_JIT_Builder* b;
2230             CODE:
2231 2           b = get_builder(aTHX_ self);
2232 2           xs_jit_ck_fallback(aTHX_ b);
2233 2           RETVAL = SvREFCNT_inc(self);
2234             OUTPUT:
2235             RETVAL
2236              
2237             # ============================================
2238             # XOP helpers
2239             # ============================================
2240              
2241             SV*
2242             xop_declare(self, name, pp_func, desc)
2243             SV* self
2244             const char* name
2245             const char* pp_func
2246             const char* desc
2247             PREINIT:
2248             XS_JIT_Builder* b;
2249             CODE:
2250 5           b = get_builder(aTHX_ self);
2251 5           xs_jit_xop_declare(aTHX_ b, name, pp_func, desc);
2252 5           RETVAL = SvREFCNT_inc(self);
2253             OUTPUT:
2254             RETVAL
2255              
2256             SV*
2257             register_checker(self, cv_expr, ck_func, ckobj_expr)
2258             SV* self
2259             const char* cv_expr
2260             const char* ck_func
2261             const char* ckobj_expr
2262             PREINIT:
2263             XS_JIT_Builder* b;
2264             CODE:
2265 2           b = get_builder(aTHX_ self);
2266 2           xs_jit_register_checker(aTHX_ b, cv_expr, ck_func, ckobj_expr);
2267 2           RETVAL = SvREFCNT_inc(self);
2268             OUTPUT:
2269             RETVAL
2270              
2271             # ============================================
2272             # Direct AvARRAY access (Meow-style)
2273             # ============================================
2274              
2275             SV*
2276             av_direct(self, result_var, av_expr)
2277             SV* self
2278             const char* result_var
2279             const char* av_expr
2280             PREINIT:
2281             XS_JIT_Builder* b;
2282             CODE:
2283 1           b = get_builder(aTHX_ self);
2284 1           xs_jit_av_direct(aTHX_ b, result_var, av_expr);
2285 1           RETVAL = SvREFCNT_inc(self);
2286             OUTPUT:
2287             RETVAL
2288              
2289             SV*
2290             av_slot_read(self, result_var, slots_var, slot)
2291             SV* self
2292             const char* result_var
2293             const char* slots_var
2294             IV slot
2295             PREINIT:
2296             XS_JIT_Builder* b;
2297             CODE:
2298 1           b = get_builder(aTHX_ self);
2299 1           xs_jit_av_slot_read(aTHX_ b, result_var, slots_var, slot);
2300 1           RETVAL = SvREFCNT_inc(self);
2301             OUTPUT:
2302             RETVAL
2303              
2304             SV*
2305             av_slot_write(self, slots_var, slot, value)
2306             SV* self
2307             const char* slots_var
2308             IV slot
2309             const char* value
2310             PREINIT:
2311             XS_JIT_Builder* b;
2312             CODE:
2313 1           b = get_builder(aTHX_ self);
2314 1           xs_jit_av_slot_write(aTHX_ b, slots_var, slot, value);
2315 1           RETVAL = SvREFCNT_inc(self);
2316             OUTPUT:
2317             RETVAL
2318              
2319             # ============================================
2320             # Type checking
2321             # ============================================
2322              
2323             SV*
2324             check_value_type(self, sv, type, ...)
2325             SV* self
2326             const char* sv
2327             IV type
2328             PREINIT:
2329             XS_JIT_Builder* b;
2330 1           const char* classname = NULL;
2331 1           const char* error_msg = "Type check failed";
2332             CODE:
2333 1           b = get_builder(aTHX_ self);
2334 1 50         if (items > 3) {
2335 1           classname = SvPV_nolen(ST(3));
2336             }
2337 1 50         if (items > 4) {
2338 1           error_msg = SvPV_nolen(ST(4));
2339             }
2340 1           xs_jit_check_value_type(aTHX_ b, sv, (XS_JIT_TypeCheck)type, classname, error_msg);
2341 1           RETVAL = SvREFCNT_inc(self);
2342             OUTPUT:
2343             RETVAL
2344              
2345             # ============================================
2346             # Lazy initialization
2347             # ============================================
2348              
2349             SV*
2350             lazy_init_dor(self, func_name, attr_name, attr_len, default_expr, is_mortal)
2351             SV* self
2352             const char* func_name
2353             const char* attr_name
2354             STRLEN attr_len
2355             const char* default_expr
2356             int is_mortal
2357             PREINIT:
2358             XS_JIT_Builder* b;
2359             CODE:
2360 2           b = get_builder(aTHX_ self);
2361 2           xs_jit_lazy_init_dor(aTHX_ b, func_name, attr_name, attr_len, default_expr, is_mortal);
2362 2           RETVAL = SvREFCNT_inc(self);
2363             OUTPUT:
2364             RETVAL
2365              
2366             SV*
2367             lazy_init_or(self, func_name, attr_name, attr_len, default_expr, is_mortal)
2368             SV* self
2369             const char* func_name
2370             const char* attr_name
2371             STRLEN attr_len
2372             const char* default_expr
2373             int is_mortal
2374             PREINIT:
2375             XS_JIT_Builder* b;
2376             CODE:
2377 1           b = get_builder(aTHX_ self);
2378 1           xs_jit_lazy_init_or(aTHX_ b, func_name, attr_name, attr_len, default_expr, is_mortal);
2379 1           RETVAL = SvREFCNT_inc(self);
2380             OUTPUT:
2381             RETVAL
2382              
2383             SV*
2384             slot_lazy_init_dor(self, func_name, slot, default_expr, is_mortal)
2385             SV* self
2386             const char* func_name
2387             IV slot
2388             const char* default_expr
2389             int is_mortal
2390             PREINIT:
2391             XS_JIT_Builder* b;
2392             CODE:
2393 1           b = get_builder(aTHX_ self);
2394 1           xs_jit_slot_lazy_init_dor(aTHX_ b, func_name, slot, default_expr, is_mortal);
2395 1           RETVAL = SvREFCNT_inc(self);
2396             OUTPUT:
2397             RETVAL
2398              
2399             SV*
2400             slot_lazy_init_or(self, func_name, slot, default_expr, is_mortal)
2401             SV* self
2402             const char* func_name
2403             IV slot
2404             const char* default_expr
2405             int is_mortal
2406             PREINIT:
2407             XS_JIT_Builder* b;
2408             CODE:
2409 0           b = get_builder(aTHX_ self);
2410 0           xs_jit_slot_lazy_init_or(aTHX_ b, func_name, slot, default_expr, is_mortal);
2411 0           RETVAL = SvREFCNT_inc(self);
2412             OUTPUT:
2413             RETVAL
2414              
2415             # ============================================
2416             # Setter patterns
2417             # ============================================
2418              
2419             SV*
2420             setter_chain(self, func_name, attr_name, attr_len)
2421             SV* self
2422             const char* func_name
2423             const char* attr_name
2424             STRLEN attr_len
2425             PREINIT:
2426             XS_JIT_Builder* b;
2427             CODE:
2428 3           b = get_builder(aTHX_ self);
2429 3           xs_jit_setter_chain(aTHX_ b, func_name, attr_name, attr_len);
2430 3           RETVAL = SvREFCNT_inc(self);
2431             OUTPUT:
2432             RETVAL
2433              
2434             SV*
2435             slot_setter_chain(self, func_name, slot)
2436             SV* self
2437             const char* func_name
2438             IV slot
2439             PREINIT:
2440             XS_JIT_Builder* b;
2441             CODE:
2442 0           b = get_builder(aTHX_ self);
2443 0           xs_jit_slot_setter_chain(aTHX_ b, func_name, slot);
2444 0           RETVAL = SvREFCNT_inc(self);
2445             OUTPUT:
2446             RETVAL
2447              
2448             SV*
2449             setter_return_value(self, func_name, attr_name, attr_len)
2450             SV* self
2451             const char* func_name
2452             const char* attr_name
2453             STRLEN attr_len
2454             PREINIT:
2455             XS_JIT_Builder* b;
2456             CODE:
2457 2           b = get_builder(aTHX_ self);
2458 2           xs_jit_setter_return_value(aTHX_ b, func_name, attr_name, attr_len);
2459 2           RETVAL = SvREFCNT_inc(self);
2460             OUTPUT:
2461             RETVAL
2462              
2463             # ============================================
2464             # Array attribute operations
2465             # ============================================
2466              
2467             SV*
2468             attr_push(self, func_name, attr_name, attr_len)
2469             SV* self
2470             const char* func_name
2471             const char* attr_name
2472             STRLEN attr_len
2473             PREINIT:
2474             XS_JIT_Builder* b;
2475             CODE:
2476 2           b = get_builder(aTHX_ self);
2477 2           xs_jit_attr_push(aTHX_ b, func_name, attr_name, attr_len);
2478 2           RETVAL = SvREFCNT_inc(self);
2479             OUTPUT:
2480             RETVAL
2481              
2482             SV*
2483             attr_pop(self, func_name, attr_name, attr_len)
2484             SV* self
2485             const char* func_name
2486             const char* attr_name
2487             STRLEN attr_len
2488             PREINIT:
2489             XS_JIT_Builder* b;
2490             CODE:
2491 2           b = get_builder(aTHX_ self);
2492 2           xs_jit_attr_pop(aTHX_ b, func_name, attr_name, attr_len);
2493 2           RETVAL = SvREFCNT_inc(self);
2494             OUTPUT:
2495             RETVAL
2496              
2497             SV*
2498             attr_shift(self, func_name, attr_name, attr_len)
2499             SV* self
2500             const char* func_name
2501             const char* attr_name
2502             STRLEN attr_len
2503             PREINIT:
2504             XS_JIT_Builder* b;
2505             CODE:
2506 1           b = get_builder(aTHX_ self);
2507 1           xs_jit_attr_shift(aTHX_ b, func_name, attr_name, attr_len);
2508 1           RETVAL = SvREFCNT_inc(self);
2509             OUTPUT:
2510             RETVAL
2511              
2512             SV*
2513             attr_unshift(self, func_name, attr_name, attr_len)
2514             SV* self
2515             const char* func_name
2516             const char* attr_name
2517             STRLEN attr_len
2518             PREINIT:
2519             XS_JIT_Builder* b;
2520             CODE:
2521 1           b = get_builder(aTHX_ self);
2522 1           xs_jit_attr_unshift(aTHX_ b, func_name, attr_name, attr_len);
2523 1           RETVAL = SvREFCNT_inc(self);
2524             OUTPUT:
2525             RETVAL
2526              
2527             SV*
2528             attr_count(self, func_name, attr_name, attr_len)
2529             SV* self
2530             const char* func_name
2531             const char* attr_name
2532             STRLEN attr_len
2533             PREINIT:
2534             XS_JIT_Builder* b;
2535             CODE:
2536 2           b = get_builder(aTHX_ self);
2537 2           xs_jit_attr_count(aTHX_ b, func_name, attr_name, attr_len);
2538 2           RETVAL = SvREFCNT_inc(self);
2539             OUTPUT:
2540             RETVAL
2541              
2542             SV*
2543             attr_clear(self, func_name, attr_name, attr_len)
2544             SV* self
2545             const char* func_name
2546             const char* attr_name
2547             STRLEN attr_len
2548             PREINIT:
2549             XS_JIT_Builder* b;
2550             CODE:
2551 1           b = get_builder(aTHX_ self);
2552 1           xs_jit_attr_clear(aTHX_ b, func_name, attr_name, attr_len);
2553 1           RETVAL = SvREFCNT_inc(self);
2554             OUTPUT:
2555             RETVAL
2556              
2557             # ============================================
2558             # Hash attribute operations
2559             # ============================================
2560              
2561             SV*
2562             attr_keys(self, func_name, attr_name, attr_len)
2563             SV* self
2564             const char* func_name
2565             const char* attr_name
2566             STRLEN attr_len
2567             PREINIT:
2568             XS_JIT_Builder* b;
2569             CODE:
2570 2           b = get_builder(aTHX_ self);
2571 2           xs_jit_attr_keys(aTHX_ b, func_name, attr_name, attr_len);
2572 2           RETVAL = SvREFCNT_inc(self);
2573             OUTPUT:
2574             RETVAL
2575              
2576             SV*
2577             attr_values(self, func_name, attr_name, attr_len)
2578             SV* self
2579             const char* func_name
2580             const char* attr_name
2581             STRLEN attr_len
2582             PREINIT:
2583             XS_JIT_Builder* b;
2584             CODE:
2585 1           b = get_builder(aTHX_ self);
2586 1           xs_jit_attr_values(aTHX_ b, func_name, attr_name, attr_len);
2587 1           RETVAL = SvREFCNT_inc(self);
2588             OUTPUT:
2589             RETVAL
2590              
2591             SV*
2592             attr_delete(self, func_name, attr_name, attr_len)
2593             SV* self
2594             const char* func_name
2595             const char* attr_name
2596             STRLEN attr_len
2597             PREINIT:
2598             XS_JIT_Builder* b;
2599             CODE:
2600 2           b = get_builder(aTHX_ self);
2601 2           xs_jit_attr_delete(aTHX_ b, func_name, attr_name, attr_len);
2602 2           RETVAL = SvREFCNT_inc(self);
2603             OUTPUT:
2604             RETVAL
2605              
2606             SV*
2607             attr_hash_clear(self, func_name, attr_name, attr_len)
2608             SV* self
2609             const char* func_name
2610             const char* attr_name
2611             STRLEN attr_len
2612             PREINIT:
2613             XS_JIT_Builder* b;
2614             CODE:
2615 2           b = get_builder(aTHX_ self);
2616 2           xs_jit_attr_hash_clear(aTHX_ b, func_name, attr_name, attr_len);
2617 2           RETVAL = SvREFCNT_inc(self);
2618             OUTPUT:
2619             RETVAL
2620              
2621             SV*
2622             conditional(self, struct_hv)
2623             SV* self
2624             HV* struct_hv
2625             PREINIT:
2626             XS_JIT_Builder* b;
2627             XS_JIT_Conditional cond;
2628             XS_JIT_Given given_struct;
2629             SV** val;
2630 29           int is_given = 0;
2631             CODE:
2632 29           b = get_builder(aTHX_ self);
2633 29           memset(&cond, 0, sizeof(cond));
2634 29           memset(&given_struct, 0, sizeof(given_struct));
2635              
2636             /* Check if this is a 'given' structure */
2637 29           val = hv_fetchs(struct_hv, "given", 0);
2638 32 100         if (val && SvOK(*val) && SvROK(*val) && SvTYPE(SvRV(*val)) == SVt_PVHV) {
    50          
    50          
    50          
2639 3           is_given = 1;
2640 3           HV* given_hv = (HV*)SvRV(*val);
2641             SV** key_val;
2642             SV** when_val;
2643             SV** default_val;
2644              
2645             /* Get key */
2646 3           key_val = hv_fetchs(given_hv, "key", 0);
2647 3 50         if (key_val && SvOK(*key_val)) {
    50          
2648 3           given_struct.key = SvPV_nolen(*key_val);
2649             }
2650              
2651             /* Parse 'when' - can be hash or array */
2652 3           when_val = hv_fetchs(given_hv, "when", 0);
2653 3 50         if (when_val && SvOK(*when_val) && SvROK(*when_val)) {
    50          
    50          
2654 3 100         if (SvTYPE(SvRV(*when_val)) == SVt_PVHV) {
2655             /* Hash-style when: { val1 => {...}, val2 => {...}, default => {...} } */
2656 2           HV* when_hv = (HV*)SvRV(*when_val);
2657 2           I32 num_keys = hv_iterinit(when_hv);
2658             HE* entry;
2659 2           int i = 0;
2660              
2661             /* Count non-default keys */
2662 2           given_struct.num_when = 0;
2663 2           hv_iterinit(when_hv);
2664 10 100         while ((entry = hv_iternext(when_hv))) {
2665             STRLEN klen;
2666 8 50         const char* key = HePV(entry, klen);
2667 8 100         if (!strEQ(key, "default")) {
2668 6           given_struct.num_when++;
2669             }
2670             }
2671              
2672 2 50         if (given_struct.num_when > 0) {
2673 2           Newxz(given_struct.when_clauses, given_struct.num_when, XS_JIT_Clause*);
2674              
2675 2           hv_iterinit(when_hv);
2676 10 100         while ((entry = hv_iternext(when_hv))) {
2677             STRLEN klen;
2678 8 50         const char* key = HePV(entry, klen);
2679 8           SV* val = HeVAL(entry);
2680              
2681 8 100         if (strEQ(key, "default")) {
2682             /* Handle default separately */
2683 2 50         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVHV) {
    50          
2684 2           given_struct.default_actions = xs_jit_parse_actions(aTHX_ val, &given_struct.num_default_actions);
2685             }
2686             } else {
2687             /* Create a clause for this when value */
2688             XS_JIT_Clause* clause;
2689 6           Newxz(clause, 1, XS_JIT_Clause);
2690 6           clause->key = given_struct.key;
2691 6           clause->expr_type = XS_JIT_EXPR_EQ;
2692 6           clause->expr_value = key;
2693 6           clause->expr_value_len = klen;
2694              
2695             /* Parse actions from value */
2696 6 50         if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVHV) {
    50          
2697 6           clause->actions = xs_jit_parse_actions(aTHX_ val, &clause->num_actions);
2698             }
2699              
2700 6           given_struct.when_clauses[i++] = clause;
2701             }
2702             }
2703             }
2704             }
2705 1 50         else if (SvTYPE(SvRV(*when_val)) == SVt_PVAV) {
2706             /* Array-style when: [ { m => 'foo', then => {...} }, ... ] */
2707 1           AV* when_av = (AV*)SvRV(*when_val);
2708 1           I32 len = av_len(when_av) + 1;
2709             int i;
2710              
2711 1 50         if (len > 0) {
2712 1           Newxz(given_struct.when_clauses, len, XS_JIT_Clause*);
2713              
2714 3 100         for (i = 0; i < len; i++) {
2715 2           SV** elem = av_fetch(when_av, i, 0);
2716 2 50         if (elem && SvOK(*elem) && SvROK(*elem) && SvTYPE(SvRV(*elem)) == SVt_PVHV) {
    50          
    50          
    50          
2717 4           given_struct.when_clauses[given_struct.num_when] =
2718 2           xs_jit_parse_clause(aTHX_ (HV*)SvRV(*elem));
2719 2           given_struct.num_when++;
2720             }
2721             }
2722             }
2723             }
2724             }
2725              
2726             /* Parse default if not already done */
2727 3           default_val = hv_fetchs(given_hv, "default", 0);
2728 3 100         if (default_val && SvOK(*default_val) && given_struct.num_default_actions == 0) {
    50          
    50          
2729 1           given_struct.default_actions = xs_jit_parse_actions(aTHX_ *default_val, &given_struct.num_default_actions);
2730             }
2731              
2732 3           xs_jit_given(aTHX_ b, &given_struct);
2733 3           xs_jit_free_given(aTHX_ &given_struct);
2734             }
2735             else {
2736             /* Standard if/elsif/else structure */
2737              
2738             /* Parse 'if' clause */
2739 26           val = hv_fetchs(struct_hv, "if", 0);
2740 26 50         if (val && SvOK(*val) && SvROK(*val) && SvTYPE(SvRV(*val)) == SVt_PVHV) {
    50          
    50          
    50          
2741 26           cond.if_clause = xs_jit_parse_clause(aTHX_ (HV*)SvRV(*val));
2742             }
2743              
2744             /* Parse 'elsif' - can be single hash or array */
2745 26           val = hv_fetchs(struct_hv, "elsif", 0);
2746 26 100         if (val && SvOK(*val) && SvROK(*val)) {
    50          
    50          
2747 4 100         if (SvTYPE(SvRV(*val)) == SVt_PVHV) {
2748             /* Single elsif */
2749 2           Newxz(cond.elsif_clauses, 1, XS_JIT_Clause*);
2750 2           cond.elsif_clauses[0] = xs_jit_parse_clause(aTHX_ (HV*)SvRV(*val));
2751 2           cond.num_elsif = 1;
2752             }
2753 2 50         else if (SvTYPE(SvRV(*val)) == SVt_PVAV) {
2754             /* Array of elsif */
2755 2           AV* elsif_av = (AV*)SvRV(*val);
2756 2           I32 len = av_len(elsif_av) + 1;
2757             int i;
2758              
2759 2 50         if (len > 0) {
2760 2           Newxz(cond.elsif_clauses, len, XS_JIT_Clause*);
2761              
2762 8 100         for (i = 0; i < len; i++) {
2763 6           SV** elem = av_fetch(elsif_av, i, 0);
2764 6 50         if (elem && SvOK(*elem) && SvROK(*elem) && SvTYPE(SvRV(*elem)) == SVt_PVHV) {
    50          
    50          
    50          
2765 12           cond.elsif_clauses[cond.num_elsif] =
2766 6           xs_jit_parse_clause(aTHX_ (HV*)SvRV(*elem));
2767 6           cond.num_elsif++;
2768             }
2769             }
2770             }
2771             }
2772             }
2773              
2774             /* Parse 'else' */
2775 26           val = hv_fetchs(struct_hv, "else", 0);
2776 26 100         if (val && SvOK(*val) && SvROK(*val) && SvTYPE(SvRV(*val)) == SVt_PVHV) {
    50          
    50          
    50          
2777 9           HV* else_hv = (HV*)SvRV(*val);
2778 9           SV** then_val = hv_fetchs(else_hv, "then", 0);
2779 9 50         if (then_val && SvOK(*then_val)) {
    50          
2780 9           cond.else_actions = xs_jit_parse_actions(aTHX_ *then_val, &cond.num_else_actions);
2781             }
2782             }
2783              
2784 26           xs_jit_conditional(aTHX_ b, &cond);
2785 26           xs_jit_free_conditional(aTHX_ &cond);
2786             }
2787              
2788 29           RETVAL = SvREFCNT_inc(self);
2789             OUTPUT:
2790             RETVAL
2791              
2792             SV*
2793             switch(self, key, cases_av, ...)
2794             SV* self
2795             const char* key
2796             AV* cases_av
2797             PREINIT:
2798             XS_JIT_Builder* b;
2799             XS_JIT_Switch sw;
2800             I32 cases_len;
2801             I32 i;
2802 19           SV* default_sv = NULL;
2803             CODE:
2804 19           b = get_builder(aTHX_ self);
2805 19           memset(&sw, 0, sizeof(sw));
2806              
2807 19           sw.key = key;
2808              
2809             /* Check for optional default argument */
2810 19 100         if (items > 3 && SvOK(ST(3))) {
    50          
2811 18           default_sv = ST(3);
2812             }
2813              
2814             /* Parse cases array */
2815 19           cases_len = av_len(cases_av) + 1;
2816 19 100         if (cases_len > 0) {
2817 18           Newxz(sw.cases, cases_len, XS_JIT_Clause*);
2818              
2819 92 100         for (i = 0; i < cases_len; i++) {
2820 74           SV** elem = av_fetch(cases_av, i, 0);
2821 74 50         if (elem && SvOK(*elem) && SvROK(*elem) && SvTYPE(SvRV(*elem)) == SVt_PVHV) {
    50          
    50          
    50          
2822 74           HV* case_hv = (HV*)SvRV(*elem);
2823             XS_JIT_Clause* clause;
2824              
2825             /* Parse the clause and set the key */
2826 74           clause = xs_jit_parse_clause(aTHX_ case_hv);
2827 74           clause->key = key;
2828 74           sw.cases[sw.num_cases] = clause;
2829 74           sw.num_cases++;
2830             }
2831             }
2832             }
2833              
2834             /* Parse default actions if provided */
2835 19 100         if (default_sv && SvROK(default_sv) && SvTYPE(SvRV(default_sv)) == SVt_PVHV) {
    50          
    50          
2836 18           sw.default_actions = xs_jit_parse_actions(aTHX_ default_sv, &sw.num_default_actions);
2837             }
2838              
2839 19           xs_jit_switch(aTHX_ b, &sw);
2840 19           xs_jit_free_switch(aTHX_ &sw);
2841              
2842 19           RETVAL = SvREFCNT_inc(self);
2843             OUTPUT:
2844             RETVAL
2845              
2846             SV*
2847             enum(self, name_sv, values_av, ...)
2848             SV* self
2849             SV* name_sv
2850             AV* values_av
2851             PREINIT:
2852             XS_JIT_Builder* b;
2853 17           XS_JIT_EnumValue* values = NULL;
2854             XS_JIT_EnumOpts opts;
2855 17           XS_JIT_EnumOpts* opts_ptr = NULL;
2856             I32 num_values;
2857             I32 i;
2858             const char* name;
2859             CODE:
2860 15 100         if (!SvOK(name_sv) || !SvPOK(name_sv) || SvCUR(name_sv) == 0) {
    50          
    50          
2861 1           croak("enum requires a name");
2862             }
2863 14           name = SvPV_nolen(name_sv);
2864              
2865 14           b = get_builder(aTHX_ self);
2866              
2867 14           memset(&opts, 0, sizeof(opts));
2868              
2869             /* Parse values array */
2870 14           num_values = av_len(values_av) + 1;
2871 14 100         if (num_values <= 0) {
2872 1           croak("enum requires a non-empty values array");
2873             }
2874              
2875 13           Newxz(values, num_values, XS_JIT_EnumValue);
2876 72 100         for (i = 0; i < num_values; i++) {
2877 59           SV** elem = av_fetch(values_av, i, 0);
2878 59 50         if (elem && SvOK(*elem)) {
    50          
2879             STRLEN len;
2880 59           const char* pv = SvPV(*elem, len);
2881 59           values[i].name = pv;
2882 59           values[i].name_len = len;
2883             }
2884             }
2885              
2886             /* Check for optional opts hash */
2887 13 100         if (items > 3 && SvOK(ST(3)) && SvROK(ST(3)) && SvTYPE(SvRV(ST(3))) == SVt_PVHV) {
    50          
    50          
    50          
2888 5           HV* opts_hv = (HV*)SvRV(ST(3));
2889 5           SV** start_sv = hv_fetchs(opts_hv, "start", 0);
2890 5           SV** prefix_sv = hv_fetchs(opts_hv, "prefix", 0);
2891              
2892 5 100         if (start_sv && SvOK(*start_sv)) {
    50          
2893 4           opts.start = SvIV(*start_sv);
2894             }
2895 5 100         if (prefix_sv && SvOK(*prefix_sv)) {
    50          
2896 2           opts.prefix = SvPV(*prefix_sv, opts.prefix_len);
2897             }
2898 5           opts_ptr = &opts;
2899             }
2900              
2901 13           xs_jit_enum(aTHX_ b, name, values, num_values, opts_ptr);
2902              
2903 13           Safefree(values);
2904              
2905 13           RETVAL = SvREFCNT_inc(self);
2906             OUTPUT:
2907             RETVAL
2908              
2909             SV*
2910             memoize(self, func_name_sv, ...)
2911             SV* self
2912             SV* func_name_sv
2913             PREINIT:
2914             XS_JIT_Builder* b;
2915             XS_JIT_MemoizeOpts opts;
2916 11           XS_JIT_MemoizeOpts* opts_ptr = NULL;
2917             const char* func_name;
2918             CODE:
2919 11 100         if (!SvOK(func_name_sv) || !SvPOK(func_name_sv) || SvCUR(func_name_sv) == 0) {
    50          
    100          
2920 2           croak("memoize requires a function name");
2921             }
2922 9           func_name = SvPV_nolen(func_name_sv);
2923 9           b = get_builder(aTHX_ self);
2924              
2925 9           memset(&opts, 0, sizeof(opts));
2926              
2927             /* Check for optional opts hash */
2928 9 100         if (items > 2 && SvOK(ST(2)) && SvROK(ST(2)) && SvTYPE(SvRV(ST(2))) == SVt_PVHV) {
    50          
    50          
    50          
2929 2           HV* opts_hv = (HV*)SvRV(ST(2));
2930 2           SV** cache_sv = hv_fetchs(opts_hv, "cache", 0);
2931 2           SV** ttl_sv = hv_fetchs(opts_hv, "ttl", 0);
2932              
2933 2 100         if (cache_sv && SvOK(*cache_sv)) {
    50          
2934 1           opts.cache_attr = SvPV(*cache_sv, opts.cache_attr_len);
2935             }
2936 2 100         if (ttl_sv && SvOK(*ttl_sv)) {
    50          
2937 1           opts.ttl = SvIV(*ttl_sv);
2938             }
2939 2           opts_ptr = &opts;
2940             }
2941              
2942 9           xs_jit_memoize(aTHX_ b, func_name, opts_ptr);
2943              
2944 9           RETVAL = SvREFCNT_inc(self);
2945             OUTPUT:
2946             RETVAL
2947              
2948             SV*
2949             enum_functions(self, name, package)
2950             SV* self
2951             const char* name
2952             const char* package
2953             PREINIT:
2954             XS_JIT_Builder* b;
2955             HV* result;
2956             CODE:
2957 13           b = get_builder(aTHX_ self);
2958 13           result = xs_jit_enum_functions(aTHX_ b, name, package);
2959 12           RETVAL = newRV_noinc((SV*)result);
2960             OUTPUT:
2961             RETVAL
2962              
2963             SV*
2964             memoize_functions(self, func_name, package)
2965             SV* self
2966             const char* func_name
2967             const char* package
2968             PREINIT:
2969             XS_JIT_Builder* b;
2970             HV* result;
2971             CODE:
2972 10           b = get_builder(aTHX_ self);
2973 10           result = xs_jit_memoize_functions(aTHX_ b, func_name, package);
2974 9           RETVAL = newRV_noinc((SV*)result);
2975             OUTPUT:
2976             RETVAL
2977              
2978             SV*
2979             role(self, role_name_sv, ...)
2980             SV* self
2981             SV* role_name_sv
2982             PREINIT:
2983             XS_JIT_Builder* b;
2984             XS_JIT_RoleType role_type;
2985             XS_JIT_RoleOpts opts;
2986 12           XS_JIT_RoleOpts* opts_ptr = NULL;
2987             const char* role_name;
2988             CODE:
2989 12 100         if (!SvOK(role_name_sv) || !SvPOK(role_name_sv) || SvCUR(role_name_sv) == 0) {
    50          
    100          
2990 2           croak("role requires a role name");
2991             }
2992 10           role_name = SvPV_nolen(role_name_sv);
2993 10           b = get_builder(aTHX_ self);
2994              
2995             /* Map role name to type */
2996 10 100         if (strEQ(role_name, "Comparable")) {
2997 3           role_type = XS_JIT_ROLE_COMPARABLE;
2998 7 100         } else if (strEQ(role_name, "Cloneable")) {
2999 2           role_type = XS_JIT_ROLE_CLONEABLE;
3000 5 100         } else if (strEQ(role_name, "Serializable")) {
3001 1           role_type = XS_JIT_ROLE_SERIALIZABLE;
3002 4 100         } else if (strEQ(role_name, "Observable")) {
3003 3           role_type = XS_JIT_ROLE_OBSERVABLE;
3004             } else {
3005 1           croak("Unknown role: '%s'. Valid roles: Comparable, Cloneable, Serializable, Observable", role_name);
3006             }
3007              
3008 9           memset(&opts, 0, sizeof(opts));
3009              
3010             /* Check for optional opts hash */
3011 9 100         if (items > 2 && SvOK(ST(2)) && SvROK(ST(2)) && SvTYPE(SvRV(ST(2))) == SVt_PVHV) {
    50          
    50          
    50          
3012 2           HV* opts_hv = (HV*)SvRV(ST(2));
3013 2           SV** compare_key_sv = hv_fetchs(opts_hv, "compare_key", 0);
3014 2           SV** observers_attr_sv = hv_fetchs(opts_hv, "observers_attr", 0);
3015              
3016 2 100         if (compare_key_sv && SvOK(*compare_key_sv)) {
    50          
3017 1           opts.compare_key = SvPV(*compare_key_sv, opts.compare_key_len);
3018             }
3019 2 100         if (observers_attr_sv && SvOK(*observers_attr_sv)) {
    50          
3020 1           opts.observers_attr = SvPV(*observers_attr_sv, opts.observers_attr_len);
3021             }
3022 2           opts_ptr = &opts;
3023             }
3024              
3025 9           xs_jit_role(aTHX_ b, role_type, opts_ptr);
3026 9           RETVAL = SvREFCNT_inc(self);
3027             OUTPUT:
3028             RETVAL
3029              
3030             SV*
3031             with_roles(self, roles_av, ...)
3032             SV* self
3033             SV* roles_av
3034             PREINIT:
3035             XS_JIT_Builder* b;
3036             AV* roles;
3037             SSize_t i, len;
3038 7           HV* opts_hv = NULL;
3039             CODE:
3040 7 100         if (!SvROK(roles_av) || SvTYPE(SvRV(roles_av)) != SVt_PVAV) {
    100          
3041 2           croak("with_roles requires an arrayref of role names");
3042             }
3043 5           b = get_builder(aTHX_ self);
3044 5           roles = (AV*)SvRV(roles_av);
3045 5           len = av_len(roles) + 1;
3046              
3047             /* Check for optional opts hash */
3048 5 100         if (items > 2 && SvOK(ST(2)) && SvROK(ST(2)) && SvTYPE(SvRV(ST(2))) == SVt_PVHV) {
    50          
    50          
    50          
3049 1           opts_hv = (HV*)SvRV(ST(2));
3050             }
3051              
3052 13 100         for (i = 0; i < len; i++) {
3053 9           SV** role_svp = av_fetch(roles, i, 0);
3054 9 50         if (role_svp && SvOK(*role_svp)) {
    50          
3055 9           const char* role_name = SvPV_nolen(*role_svp);
3056             XS_JIT_RoleType role_type;
3057             XS_JIT_RoleOpts opts;
3058 9           XS_JIT_RoleOpts* opts_ptr = NULL;
3059              
3060             /* Map role name to type */
3061 9 100         if (strEQ(role_name, "Comparable")) {
3062 4           role_type = XS_JIT_ROLE_COMPARABLE;
3063 5 100         } else if (strEQ(role_name, "Cloneable")) {
3064 2           role_type = XS_JIT_ROLE_CLONEABLE;
3065 3 100         } else if (strEQ(role_name, "Serializable")) {
3066 1           role_type = XS_JIT_ROLE_SERIALIZABLE;
3067 2 100         } else if (strEQ(role_name, "Observable")) {
3068 1           role_type = XS_JIT_ROLE_OBSERVABLE;
3069             } else {
3070 1           croak("Unknown role: '%s'. Valid roles: Comparable, Cloneable, Serializable, Observable", role_name);
3071             }
3072              
3073 8           memset(&opts, 0, sizeof(opts));
3074              
3075             /* Apply opts if provided */
3076 8 100         if (opts_hv) {
3077 2           SV** compare_key_sv = hv_fetchs(opts_hv, "compare_key", 0);
3078 2           SV** observers_attr_sv = hv_fetchs(opts_hv, "observers_attr", 0);
3079              
3080 2 50         if (compare_key_sv && SvOK(*compare_key_sv)) {
    50          
3081 2           opts.compare_key = SvPV(*compare_key_sv, opts.compare_key_len);
3082             }
3083 2 50         if (observers_attr_sv && SvOK(*observers_attr_sv)) {
    50          
3084 2           opts.observers_attr = SvPV(*observers_attr_sv, opts.observers_attr_len);
3085             }
3086 2           opts_ptr = &opts;
3087             }
3088              
3089 8           xs_jit_role(aTHX_ b, role_type, opts_ptr);
3090             }
3091             }
3092 4           RETVAL = SvREFCNT_inc(self);
3093             OUTPUT:
3094             RETVAL