ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Faster/Faster.xs
Revision: 1.4
Committed: Thu Mar 9 22:55:56 2006 UTC (18 years, 2 months ago) by root
Branch: MAIN
Changes since 1.3: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 root 1.3 typedef CV *B__CV;
6    
7 root 1.1 static OP *(*old_entersub)(pTHX);
8    
9 root 1.3 int count = 1;
10    
11 root 1.1 // this is, of course, a slower entersub
12     static OP *
13     faster_entersub (pTHX)
14     {
15     dSP;
16     dTOPss;
17    
18     if (SvTYPE (sv) == SVt_PVGV)
19 root 1.2 sv = (SV *)GvCV (sv);
20 root 1.1
21     if (sv)
22     {
23     // only once for now
24     PL_op->op_ppaddr = old_entersub;
25    
26     // only simple cv calls for now
27 root 1.2 if (!PL_perldb && !PL_tainting
28 root 1.3 && SvTYPE (sv) == SVt_PVCV && !CvXSUB (sv)
29 root 1.4 && CvSTART (sv) // must exist
30 root 1.3 && CvSTART (sv)->op_type != OP_NULL) // shield against compiling an already-compiled op
31 root 1.1 {
32 root 1.3 SV *bsv = newSViv (PTR2IV (sv));
33 root 1.2
34 root 1.1 ENTER;
35     SAVETMPS;
36     PUSHMARK (SP);
37     // emulate B::CV typemap entry we don't have
38 root 1.3 XPUSHs (sv_2mortal (sv_bless (newRV_noinc (bsv), gv_stashpv ("B::CV", 1))));
39 root 1.1 PUTBACK;
40 root 1.3 call_pv ("Faster::entersub", G_VOID|G_DISCARD|G_EVAL);
41 root 1.1 SPAGAIN;
42     FREETMPS;
43     LEAVE;
44     }
45     }
46    
47     return old_entersub (aTHX);
48     }
49    
50     MODULE = Faster PACKAGE = Faster
51    
52 root 1.2 PROTOTYPES: ENABLE
53    
54     IV
55     ppaddr (int optype)
56     CODE:
57     RETVAL = optype == OP_ENTERSUB
58     ? old_entersub
59     : PL_ppaddr [optype];
60     OUTPUT:
61     RETVAL
62    
63 root 1.1 void
64     hook_entersub ()
65     CODE:
66     old_entersub = PL_ppaddr [OP_ENTERSUB];
67     PL_ppaddr [OP_ENTERSUB] = faster_entersub;
68    
69 root 1.3 void
70     patch_cv (B::CV cv, void *ptr)
71     CODE:
72     {
73     OP *op;
74    
75     NewOp (0, op, 1, OP);
76    
77     op->op_sibling = CvSTART (cv);
78     op->op_type = OP_NULL;
79     op->op_ppaddr = ptr;
80    
81     CvSTART (cv) = op;
82     }
83    
84 root 1.1