/* Selected functions borrowed from perl's ext/Opcode/Opcode.xs */ /* PL_maxo shouldn't differ from MAXO but leave room anyway (see BOOT:) */ #define OP_MASK_BUF_SIZE (MAXO + 100) #define opset_len ((PL_maxo + 7) / 8) static void opmask_add(pTHX_ char *bitmask, STRLEN len) { int i,j; int myopcode = 0; if (len != opset_len) croak("Invalid opset: wrong size"); if (!PL_op_mask) /* caller must ensure PL_op_mask exists */ croak("Can't add to uninitialised PL_op_mask"); /* OPCODES ALREADY MASKED ARE NEVER UNMASKED. See opmask_addlocal() */ for (i=0; i < opset_len; i++) { U16 bits = bitmask[i]; if (!bits) { /* optimise for sparse masks */ myopcode += 8; continue; } for (j=0; j < 8 && myopcode < PL_maxo; ) PL_op_mask[myopcode++] |= bits & (1 << j++); } } static void opmask_addlocal(pTHX_ char *bitmask, STRLEN len, char *op_mask_buf) { char *orig_op_mask = PL_op_mask; SAVEVPTR(PL_op_mask); PL_op_mask = &op_mask_buf[0]; if (orig_op_mask) Copy(orig_op_mask, PL_op_mask, PL_maxo, char); else Zero(PL_op_mask, PL_maxo, char); opmask_add(aTHX_ bitmask, len); }