/* maxo shouldn't differ from MAXO but leave room anyway (see BOOT:) */
#define OP_MASK_BUF_SIZE (MAXO + 100)
+/* XXX op_named_bits and opset_all are never freed */
static HV *op_named_bits; /* cache shared for whole process */
static SV *opset_all; /* mask with all bits set */
static IV opset_len; /* length of opmasks in bytes */
* It is first loaded with the name and number of each perl operator.
* Then the builtin tags :none and :all are added.
* Opcode.pm loads the standard optags from __DATA__
+ * XXX leak-alert: data allocated here is never freed, call this
+ * at most once
*/
static void
char * Package
SV * mask
SV * codesv
- PPCODE:
+PPCODE:
char op_mask_buf[OP_MASK_BUF_SIZE];
GV *gv;
void
invert_opset(opset)
SV *opset
- CODE:
+CODE:
{
char *bitmap;
STRLEN len = opset_len;
- opset = new_opset(opset); /* verify and clone opset */
+ opset = sv_2mortal(new_opset(opset)); /* verify and clone opset */
bitmap = SvPVX(opset);
while(len-- > 0)
bitmap[len] = ~bitmap[len];
opset_to_ops(opset, desc = 0)
SV *opset
int desc
- PPCODE:
+PPCODE:
{
STRLEN len;
int i, j, myopcode;
void
opset(...)
- CODE:
+CODE:
int i, j;
SV *bitspec, *opset;
char *bitmap;
STRLEN len, on;
- opset = new_opset(Nullsv);
+ opset = sv_2mortal(new_opset(Nullsv));
bitmap = SvPVX(opset);
for (i = 0; i < items; i++) {
char *opname;
void
permit_only(safe, ...)
SV *safe
- ALIAS:
+ALIAS:
permit = 1
deny_only = 2
deny = 3
- CODE:
+CODE:
int i, on;
SV *bitspec, *mask;
char *bitmap, *opname;
croak("Not a Safe object");
mask = *hv_fetch((HV*)SvRV(safe), "Mask",4, 1);
if (ONLY_THESE) /* *_only = new mask, else edit current */
- sv_setsv(mask, new_opset(PERMITING ? opset_all : Nullsv));
- else verify_opset(mask,1); /* croaks */
+ sv_setsv(mask, sv_2mortal(new_opset(PERMITING ? opset_all : Nullsv)));
+ else
+ verify_opset(mask,1); /* croaks */
bitmap = SvPVX(mask);
for (i = 1; i < items; i++) {
on = PERMITING ? 0 : 1; /* deny = mask bit on */
void
opdesc(...)
- PPCODE:
+PPCODE:
int i, myopcode;
STRLEN len;
SV **args;
define_optag(optagsv, mask)
SV *optagsv
SV *mask
- CODE:
+CODE:
STRLEN len;
char *optag = SvPV(optagsv, len);
put_op_bitspec(optag, len, mask); /* croaks */
void
empty_opset()
- CODE:
+CODE:
ST(0) = sv_2mortal(new_opset(Nullsv));
void
full_opset()
- CODE:
+CODE:
ST(0) = sv_2mortal(new_opset(opset_all));
void
opmask_add(opset)
SV *opset
- PREINIT:
+PREINIT:
if (!op_mask)
Newz(0, op_mask, maxo, char);
void
opcodes()
- PPCODE:
+PPCODE:
if (GIMME == G_ARRAY) {
croak("opcodes in list context not yet implemented"); /* XXX */
}
void
opmask()
- CODE:
+CODE:
ST(0) = sv_2mortal(new_opset(Nullsv));
if (op_mask) {
char *bitmap = SvPVX(ST(0));
sub DESTROY {
my $obj = shift;
- $obj->erase if $obj->{Erase};
+ $obj->erase('DESTROY') if $obj->{Erase};
}
sub erase {
- my $obj= shift;
+ my ($obj, $action) = @_;
my $pkg = $obj->root();
my ($stem, $leaf);
#warn " stem_symtab hash ".scalar(%$stem_symtab)."\n";
# ", join(', ', %$stem_symtab),"\n";
- delete $stem_symtab->{$leaf};
+# delete $stem_symtab->{$leaf};
-# my $leaf_glob = $stem_symtab->{$leaf};
-# my $leaf_symtab = *{$leaf_glob}{HASH};
+ my $leaf_glob = $stem_symtab->{$leaf};
+ my $leaf_symtab = *{$leaf_glob}{HASH};
# warn " leaf_symtab ", join(', ', %$leaf_symtab),"\n";
-# %$leaf_symtab = ();
+ %$leaf_symtab = ();
#delete $leaf_symtab->{'__ANON__'};
#delete $leaf_symtab->{'foo'};
#delete $leaf_symtab->{'main::'};
# my $foo = undef ${"$stem\::"}{"$leaf\::"};
- $obj->share_from('main', $default_share);
+ if ($action and $action eq 'DESTROY') {
+ delete $stem_symtab->{$leaf};
+ } else {
+ $obj->share_from('main', $default_share);
+ }
1;
}