Opcode#

📦 min

Name, group and mask the interpreter’s opcodes - the machinery Safe compartments are built from.

An opset is a bit string with one bit per opcode, (MAXO + 7) / 8 bytes wide. Operators are named individually ("print", "backtick") or by tag (":base_core", ":subprocess"); Opcode converts between names, tags and opsets, and installs an opset into PL_op_mask, which the compiler consults to refuse masked ops.

This is the XS half only. Opcode.pm still loads from disk (xs_only: true) and supplies the exported wrappers (opset_to_hex, opdump, ops_to_opset) plus the standard tag definitions it builds from its own __DATA__ section via define_optag.

Functions#

Other Functions#

safe_pkg_prep#

Opcode.xs _safe_pkg_prep($Package): make the compartment stash believe it is main, and wire its _ to the global *_ so $_ still works.

safe_call_sv#

Opcode.xs _safe_call_sv($Package, $mask, $codesv): run $codesv with PL_op_mask localised to $mask and the compartment stash installed as PL_defstash/PL_curstash, so compiled code inside it sees the compartment as main.

verify_opset#

verify_opset($opset, $fatal = 0) - Opcode.xs line 337.

invert_opset#

invert_opset($opset) - Opcode.xs line 347. Clears the bits past MAXO in the last byte so the result never names a nonexistent opcode.

opset_to_ops#

opset_to_ops($opset, $desc = 0) - Opcode.xs line 367.

opset#

opset(@names_or_opsets) - Opcode.xs line 391. A leading ! on a name turns the bit off instead of on.

opdesc#

opdesc(@names) - Opcode.xs line 461.

define_optag#

define_optag($tag, $mask) - Opcode.xs line 504.

empty_opset#

empty_opset() - Opcode.xs line 517.

full_opset#

full_opset() - Opcode.xs line 524.

opmask_add#

opmask_add($opset) - Opcode.xs line 532. The PREINIT allocates PL_op_mask on first use; opmask_add itself refuses a null mask.

opcodes#

opcodes() - Opcode.xs line 541. List context is unimplemented upstream too, and croaks.

opmask#

opmask() - Opcode.xs line 552: the current PL_op_mask as an opset.