bytecode

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package bytecode holds CPython 3.14 opcode constants, the inline cache size table, the CodeObject builder, and the line/exception table encoders.

Opcode numbers and the cache size table are sourced from github.com/tamnd/goipy/op (the canonical opcode source in this ecosystem), which itself is generated from python3.14 dis.opname/opcode.

Index

Constants

View Source
const (
	CO_OPTIMIZED          uint32 = 0x0001 // function uses fast locals
	CO_NEWLOCALS          uint32 = 0x0002 // creates a new local namespace at call time
	CO_VARARGS            uint32 = 0x0004 // *args parameter present
	CO_VARKEYWORDS        uint32 = 0x0008 // **kwargs parameter present
	CO_NESTED             uint32 = 0x0010 // closure (refers to free variables)
	CO_GENERATOR          uint32 = 0x0020 // is a generator
	CO_NOFREE             uint32 = 0x0040 // no free or cell vars
	CO_COROUTINE          uint32 = 0x0080 // async def
	CO_ITERABLE_COROUTINE uint32 = 0x0100 // @types.coroutine wrapped
	CO_ASYNC_GENERATOR    uint32 = 0x0200 // async generator

	CO_FUTURE_BARRY_AS_BDFL  uint32 = 0x00400000
	CO_FUTURE_GENERATOR_STOP uint32 = 0x00800000
	CO_FUTURE_ANNOTATIONS    uint32 = 0x01000000
	CO_NO_MONITORING_EVENTS  uint32 = 0x02000000
	CO_HAS_DOCSTRING         uint32 = 0x04000000
)

CodeObject co_flags bits. Mirror CPython's Include/cpython/code.h.

SOURCE: https://github.com/python/cpython/blob/3.14/Include/cpython/code.h

View Source
const (
	FastHidden byte = 0x10
	FastLocal  byte = 0x20
	FastCell   byte = 0x40
	FastFree   byte = 0x80

	FastArgPos byte = 0x02
	FastArgKw  byte = 0x04
	FastArgVar byte = 0x08

	// FastArg is the common shorthand for a positional-or-keyword argument.
	FastArg = FastArgPos | FastArgKw // 0x06
)

co_localspluskinds entry bytes. Mirror CPython's Include/internal/pycore_code.h CO_FAST_* macros.

Each entry in co_localspluskinds is a byte describing one slot in co_localsplusnames. The bits are OR-combined.

View Source
const (
	// LocalsKindLocal: a plain local (variable assigned in body).
	LocalsKindLocal byte = FastLocal
	// LocalsKindArg: a positional/kw argument that stays a plain
	// local (CO_FAST_LOCAL | CO_FAST_ARG).
	LocalsKindArg byte = FastLocal | FastArg
	// LocalsKindArgCell: a cell holding a positional/kw argument
	// captured by a nested closure (CO_FAST_LOCAL | CO_FAST_ARG |
	// CO_FAST_CELL).
	LocalsKindArgCell byte = FastLocal | FastArg | FastCell
	// LocalsKindFree: a free variable referenced from an outer
	// scope.
	LocalsKindFree byte = FastFree
	// LocalsKindCell: a cell that backs a closure-bound name.
	LocalsKindCell byte = FastCell
)

Predefined co_localspluskinds bytes for the slot shapes the compiler emits today. Each is an OR-combination of the FastX bits in flags.go.

View Source
const (
	CmpLt    = 2   // <
	CmpLtE   = 42  // <=
	CmpEq    = 72  // ==
	CmpNotEq = 103 // !=
	CmpGt    = 132 // >
	CmpGtE   = 172 // >=
)

COMPARE_OP oparg values for non-conditional (value) context. In conditional-jump context, add 16 to these values. SOURCE: empirically verified against CPython 3.14 `python3.14 -m py_compile`.

View Source
const (
	NbAdd            = 0
	NbAnd            = 1
	NbFloorDivide    = 2
	NbLshift         = 3
	NbMatrixMultiply = 4
	NbMultiply       = 5
	NbRemainder      = 6
	NbOr             = 7
	NbPower          = 8
	NbRshift         = 9
	NbSubtract       = 10
	NbTrueDivide     = 11
	NbXor            = 12
)

BINARY_OP opargs for non-inplace binary operators (NB_* enum). SOURCE: github.com/tamnd/goipy/op/opcodes.go (NB_* constants).

View Source
const (
	NbInplaceAdd         = 13
	NbInplaceAnd         = 14
	NbInplaceFloorDivide = 15
	NbInplaceLshift      = 16
	NbInplaceMultiply    = 18
	NbInplaceRemainder   = 19
	NbInplaceOr          = 20
	NbInplacePower       = 21
	NbInplaceRshift      = 22
	NbInplaceSubtract    = 23
	NbInplaceTrueDivide  = 24
	NbInplaceXor         = 25
)

BINARY_OP opargs for augmented assignment operators (NB_INPLACE_* enum). SOURCE: github.com/tamnd/goipy/op/opcodes.go (NB_INPLACE_* constants).

View Source
const NbGetItem = 26

NbGetItem is the BINARY_OP oparg for subscript reads `a[b]`. It is the NB_GET_ITEM slot in CPython's binary-operation dispatch table.

View Source
const NoCol uint16 = 0xFFFF

NoCol is the sentinel column meaning "unknown column". Matches CPython's behaviour when source-position tracking has lost the column for a particular instruction.

Variables

View Source
var CacheSize = [256]uint8{
	38:  1,
	39:  3,
	52:  3,
	44:  5,
	92:  4,
	56:  1,
	57:  1,
	80:  9,
	70:  1,
	75:  1,
	100: 1,
	101: 1,
	102: 1,
	103: 1,
	110: 4,
}

CacheSize maps each opcode to the number of inline cache entries that follow it in the bytecode stream. Each entry is two bytes (one instruction word). Values are zero-initialized for opcodes we do not list; v0.0.1 does not emit any cached opcode, so the empty defaults are correct.

SOURCE: github.com/tamnd/goipy/op/opcodes.go::Cache (CPython 3.14 _PyOpcode_Caches).

View Source
var Ellipsis = EllipsisType{}

Ellipsis is the singleton EllipsisType value used in CodeObject.Consts to represent Python's `...` literal.

View Source
var OpMetaTable = func() [256]OpMeta {
	var t [256]OpMeta

	set := func(op Opcode, m OpMeta) {
		m.CacheSize = CacheSize[op]
		t[op] = m
	}

	set(NOP, OpMeta{Name: "NOP", HasArg: false, ArgKind: ArgNone})
	set(NOT_TAKEN, OpMeta{Name: "NOT_TAKEN", HasArg: false, ArgKind: ArgNone})
	set(POP_TOP, OpMeta{Name: "POP_TOP", HasArg: false, ArgKind: ArgNone, StackEff: -1})
	set(PUSH_NULL, OpMeta{Name: "PUSH_NULL", HasArg: false, ArgKind: ArgNone, StackEff: 1})
	set(END_FOR, OpMeta{Name: "END_FOR", HasArg: false, ArgKind: ArgNone, StackEff: -1})
	set(POP_ITER, OpMeta{Name: "POP_ITER", HasArg: false, ArgKind: ArgNone, StackEff: -1})
	set(GET_ITER, OpMeta{Name: "GET_ITER", HasArg: false, ArgKind: ArgNone, StackEff: 0})
	set(TO_BOOL, OpMeta{Name: "TO_BOOL", HasArg: false, ArgKind: ArgNone, StackEff: 0})
	set(UNARY_INVERT, OpMeta{Name: "UNARY_INVERT", HasArg: false, ArgKind: ArgNone, StackEff: 0})
	set(UNARY_NEGATIVE, OpMeta{Name: "UNARY_NEGATIVE", HasArg: false, ArgKind: ArgNone, StackEff: 0})
	set(UNARY_NOT, OpMeta{Name: "UNARY_NOT", HasArg: false, ArgKind: ArgNone, StackEff: 0})
	set(STORE_SUBSCR, OpMeta{Name: "STORE_SUBSCR", HasArg: false, ArgKind: ArgNone, StackEff: -3})

	set(RETURN_VALUE, OpMeta{Name: "RETURN_VALUE", HasArg: false, ArgKind: ArgNone, Flags: OpTerminator, StackEff: 0})

	set(RAISE_VARARGS, OpMeta{Name: "RAISE_VARARGS", HasArg: true, ArgKind: ArgRaw, Flags: OpTerminator, StackVar: true})
	set(COPY_FREE_VARS, OpMeta{Name: "COPY_FREE_VARS", HasArg: true, ArgKind: ArgRaw, StackEff: 0})
	set(MAKE_FUNCTION, OpMeta{Name: "MAKE_FUNCTION", HasArg: false, ArgKind: ArgNone, StackEff: 0})

	set(LOAD_CONST, OpMeta{Name: "LOAD_CONST", HasArg: true, ArgKind: ArgConst, StackEff: 1})
	set(LOAD_COMMON_CONSTANT, OpMeta{Name: "LOAD_COMMON_CONSTANT", HasArg: true, ArgKind: ArgRaw, StackEff: 1})
	set(LOAD_SMALL_INT, OpMeta{Name: "LOAD_SMALL_INT", HasArg: true, ArgKind: ArgRaw, StackEff: 1})
	set(LOAD_NAME, OpMeta{Name: "LOAD_NAME", HasArg: true, ArgKind: ArgName, StackEff: 1})
	set(STORE_NAME, OpMeta{Name: "STORE_NAME", HasArg: true, ArgKind: ArgName, StackEff: -1})
	set(IMPORT_NAME, OpMeta{Name: "IMPORT_NAME", HasArg: true, ArgKind: ArgName, StackEff: -1})
	set(IMPORT_FROM, OpMeta{Name: "IMPORT_FROM", HasArg: true, ArgKind: ArgName, StackEff: 1})
	set(STORE_ATTR, OpMeta{Name: "STORE_ATTR", HasArg: true, ArgKind: ArgName, StackEff: -2})
	set(LOAD_ATTR, OpMeta{Name: "LOAD_ATTR", HasArg: true, ArgKind: ArgRaw, StackVar: true})
	set(LOAD_GLOBAL, OpMeta{Name: "LOAD_GLOBAL", HasArg: true, ArgKind: ArgRaw, StackVar: true})

	set(LOAD_FAST, OpMeta{Name: "LOAD_FAST", HasArg: true, ArgKind: ArgLocal, StackEff: 1})
	set(LOAD_FAST_BORROW, OpMeta{Name: "LOAD_FAST_BORROW", HasArg: true, ArgKind: ArgLocal, StackEff: 1})
	set(LOAD_FAST_BORROW_LOAD_FAST_BORROW, OpMeta{Name: "LOAD_FAST_BORROW_LOAD_FAST_BORROW", HasArg: true, ArgKind: ArgRaw, StackEff: 2})
	set(LOAD_FAST_LOAD_FAST, OpMeta{Name: "LOAD_FAST_LOAD_FAST", HasArg: true, ArgKind: ArgRaw, StackEff: 2})
	set(STORE_FAST, OpMeta{Name: "STORE_FAST", HasArg: true, ArgKind: ArgLocal, StackEff: -1})
	set(STORE_FAST_LOAD_FAST, OpMeta{Name: "STORE_FAST_LOAD_FAST", HasArg: true, ArgKind: ArgRaw, StackEff: 0})
	set(STORE_FAST_STORE_FAST, OpMeta{Name: "STORE_FAST_STORE_FAST", HasArg: true, ArgKind: ArgRaw, StackEff: -2})
	set(LOAD_DEREF, OpMeta{Name: "LOAD_DEREF", HasArg: true, ArgKind: ArgFree, StackEff: 1})
	set(STORE_DEREF, OpMeta{Name: "STORE_DEREF", HasArg: true, ArgKind: ArgFree, StackEff: -1})
	set(STORE_GLOBAL, OpMeta{Name: "STORE_GLOBAL", HasArg: true, ArgKind: ArgName, StackEff: -1})
	set(MAKE_CELL, OpMeta{Name: "MAKE_CELL", HasArg: true, ArgKind: ArgLocal, StackEff: 0})

	set(BUILD_LIST, OpMeta{Name: "BUILD_LIST", HasArg: true, ArgKind: ArgRaw, StackVar: true})
	set(BUILD_MAP, OpMeta{Name: "BUILD_MAP", HasArg: true, ArgKind: ArgRaw, StackVar: true})
	set(BUILD_SET, OpMeta{Name: "BUILD_SET", HasArg: true, ArgKind: ArgRaw, StackVar: true})
	set(BUILD_TUPLE, OpMeta{Name: "BUILD_TUPLE", HasArg: true, ArgKind: ArgRaw, StackVar: true})
	set(LIST_APPEND, OpMeta{Name: "LIST_APPEND", HasArg: true, ArgKind: ArgRaw, StackEff: -1})
	set(LIST_EXTEND, OpMeta{Name: "LIST_EXTEND", HasArg: true, ArgKind: ArgRaw, StackEff: -1})

	set(CALL, OpMeta{Name: "CALL", HasArg: true, ArgKind: ArgRaw, StackVar: true})
	set(CALL_INTRINSIC_1, OpMeta{Name: "CALL_INTRINSIC_1", HasArg: true, ArgKind: ArgRaw, StackEff: 0})
	set(SET_FUNCTION_ATTRIBUTE, OpMeta{Name: "SET_FUNCTION_ATTRIBUTE", HasArg: true, ArgKind: ArgRaw, StackEff: -1})

	set(COMPARE_OP, OpMeta{Name: "COMPARE_OP", HasArg: true, ArgKind: ArgRaw, StackEff: -1})
	set(CONTAINS_OP, OpMeta{Name: "CONTAINS_OP", HasArg: true, ArgKind: ArgRaw, StackEff: -1})
	set(IS_OP, OpMeta{Name: "IS_OP", HasArg: true, ArgKind: ArgRaw, StackEff: -1})
	set(BINARY_OP, OpMeta{Name: "BINARY_OP", HasArg: true, ArgKind: ArgRaw, StackEff: -1})

	set(COPY, OpMeta{Name: "COPY", HasArg: true, ArgKind: ArgRaw, StackEff: 1})

	set(JUMP_FORWARD, OpMeta{Name: "JUMP_FORWARD", HasArg: true, ArgKind: ArgJumpRel, Flags: OpJump | OpTerminator, StackEff: 0})
	set(JUMP_BACKWARD, OpMeta{Name: "JUMP_BACKWARD", HasArg: true, ArgKind: ArgJumpRel, Flags: OpJump | OpTerminator, StackEff: 0})
	set(FOR_ITER, OpMeta{Name: "FOR_ITER", HasArg: true, ArgKind: ArgJumpRel, Flags: OpJump, StackEff: 1})
	set(POP_JUMP_IF_FALSE, OpMeta{Name: "POP_JUMP_IF_FALSE", HasArg: true, ArgKind: ArgJumpRel, Flags: OpJump, StackEff: -1})
	set(POP_JUMP_IF_TRUE, OpMeta{Name: "POP_JUMP_IF_TRUE", HasArg: true, ArgKind: ArgJumpRel, Flags: OpJump, StackEff: -1})
	set(POP_JUMP_IF_NONE, OpMeta{Name: "POP_JUMP_IF_NONE", HasArg: true, ArgKind: ArgJumpRel, Flags: OpJump, StackEff: -1})
	set(POP_JUMP_IF_NOT_NONE, OpMeta{Name: "POP_JUMP_IF_NOT_NONE", HasArg: true, ArgKind: ArgJumpRel, Flags: OpJump, StackEff: -1})

	set(RESUME, OpMeta{Name: "RESUME", HasArg: true, ArgKind: ArgRaw, StackEff: 0})

	return t
}()

OpMetaTable is the canonical lookup. Entries default to the zero OpMeta, meaning "unknown opcode" (Name == ""). Future releases of gocopy add entries as they emit more of the CPython 3.14 opcode space.

SOURCE: cross-checked against python3.14 in cpython_parity_test.go for every named opcode in opcode.go.

Functions

func AssignBytecode

func AssignBytecode(noneIdx byte, tailStmts int) []byte

AssignBytecode returns the instruction stream for `name = value` followed by `tailStmts` no-op statements. `noneIdx` is the const index for the implicit `LOAD_CONST None` at the end: 0 when the assigned value itself is None (consts collapses to `(None,)`), 1 otherwise. The value is always at const index 0.

func AssignBytecodeAt

func AssignBytecodeAt(valueIdx, noneIdx byte, tailStmts int) []byte

AssignBytecodeAt is the general form of AssignBytecode. valueIdx is the const index for the value (0 in the common case; 2 when CPython's constant folder places the folded result after the original literal and None, as in `x = -1` where consts = (1, None, -1)).

func AssignLineTable

func AssignLineTable(line int, nameLen, valStartCol, valEndCol byte, tail []NoOpStmt) []byte

AssignLineTable returns the PEP 626 line table for a single `name = value` assignment on `line`, where the value occupies columns `valStartCol`..`valEndCol` and the name occupies columns 0..`nameLen` (so `nameLen` is the number of bytes in the name). `tail` is the trailing no-op statements after the assignment.

Layout:

prologue: LONG length 1 covering RESUME
LOAD_CONST entry: ONE_LINE1 length 1, cols (valStartCol, valEndCol)
STORE_NAME entry: SHORT0 length (3 if no tail else 1), cols (0, nameLen)
tail: same v0.0.4 rule as no-op bodies, prev_line starts at `line`

func AssignSmallIntBytecode

func AssignSmallIntBytecode(val byte, tailStmts int) []byte

AssignSmallIntBytecode returns the instruction stream for `name = <int>` where the integer value fits in 0..255. CPython uses LOAD_SMALL_INT with the value embedded in the oparg instead of LOAD_CONST; None is always at const index 1 (the consts tuple is `(int_val, None)`).

func AssignsThenFuncDefLineTable

func AssignsThenFuncDefLineTable(asgns []AssignInfo, defLine, bodyEndLine int, bodyEndCol byte) []byte

AssignsThenFuncDefLineTable returns the PEP 626 line table for a module body consisting of N ≥ 1 constant-folded assignments followed by a function definition. Each assign contributes 2 CUs (LOAD_CONST + STORE_NAME); the funcdef contributes 5.

func AttrLoadBytecode

func AttrLoadBytecode() []byte

AttrLoadBytecode returns the instruction stream for `x = a.b` (module-level attribute read, object is a name).

Bytecode pattern:

RESUME 0
LOAD_NAME 0 (a)
LOAD_ATTR 2 (b)  -- oparg = attrIdx<<1 = 1<<1 = 2
  + 9 cache words (18 bytes)
STORE_NAME 2 (x)
LOAD_CONST 0 (None)
RETURN_VALUE 0

co_names: [a, b, x] co_consts: [None] co_stacksize: 1

func AttrLoadLineTable

func AttrLoadLineTable(line int, objCol, objEnd, attrEnd, targetLen byte) []byte

AttrLoadLineTable returns the PEP 626 line table for `x = a.b`.

LOAD_ATTR spans 10 code units (opcode + 9 cache words), which exceeds the 8-code-unit per-entry limit, so it is split into two consecutive entries covering 8 + 2 code units at the same column range.

objCol/objEnd: column range of the object name (a). attrEnd: exclusive end column of the attribute (= objCol+objLen+1+attrLen). targetLen: length of the target name x.

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME a: 1 code unit
  3. LOAD_ATTR + 7 caches: 8 code units at (objCol, attrEnd)
  4. Remaining 2 caches: 2 code units at (objCol, attrEnd)
  5. STORE_NAME + LOAD_CONST + RETURN_VALUE: 3 code units at (0, targetLen)

func AttrStoreBytecode

func AttrStoreBytecode() []byte

AttrStoreBytecode returns the instruction stream for `a.b = x` (module-level attribute store, object and value are names).

Bytecode pattern:

RESUME 0
LOAD_NAME 0 (x)   -- value to store
LOAD_NAME 1 (a)   -- object
STORE_ATTR 2 (b)  -- oparg = 2 (index of 'b' in names=[x,a,b])
  + 4 cache words (8 bytes)
LOAD_CONST 0 (None)
RETURN_VALUE 0

co_names: [x, a, b] co_consts: [None] co_stacksize: 2

func AttrStoreLineTable

func AttrStoreLineTable(line int, valCol, valEnd, objCol, objEnd, attrEnd byte) []byte

AttrStoreLineTable returns the PEP 626 line table for `a.b = x`.

STORE_ATTR + 4 caches + LOAD_CONST + RETURN_VALUE = 7 code units; they all share the column range of the assignment target `a.b`.

valCol/valEnd: column range of the value name (x). objCol/objEnd: column range of the object name (a). attrEnd: exclusive end column of the attribute (= objCol+objLen+1+attrLen).

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME x: 1 code unit
  3. LOAD_NAME a: 1 code unit
  4. STORE_ATTR + 4 caches + LOAD_CONST + RETURN_VALUE: 7 code units at (objCol, attrEnd)

func AugAssignBytecode

func AugAssignBytecode(initVal, augVal int64, oparg byte, tailStmts int) []byte

AugAssignBytecode returns the instruction stream for a module-level augmented assignment of the form `name = initVal\nname op= augVal\n`, where both values are non-negative integers and oparg is the NB_INPLACE_* enum value for the operator (e.g. NbInplaceAdd for +=).

Bytecode pattern:

RESUME 0
LOAD initVal                 (LOAD_SMALL_INT if 0..255, else LOAD_CONST 0)
STORE_NAME 0
LOAD_NAME 0
LOAD augVal                  (LOAD_SMALL_INT if 0..255, else LOAD_CONST augConstIdx)
BINARY_OP oparg
<5 cache words>
STORE_NAME 0
<nops>
LOAD_CONST noneIdx
RETURN_VALUE

consts layout:

  • consts[0] = initVal (phantom slot when small int, real slot when large)
  • consts[1] = augVal (only present when augVal > 255)
  • consts[?] = None (last slot)

func AugAssignLineTable

func AugAssignLineTable(
	initLine int, nameLen, initValStart, initValEnd byte,
	augLine int, augValStart, augValEnd byte,
	tail []NoOpStmt,
) []byte

AugAssignLineTable returns the PEP 626 line table for:

`name = initVal` on initLine, value at columns initValStart..initValEnd
`name += augVal` on augLine, value at columns augValStart..augValEnd

augValEnd is also the end column of the full augmented-assignment statement (no trailing text after the value). nameLen is the byte length of the variable name (1..15). Optional tail no-op statements follow.

func BinOpAssignBytecode

func BinOpAssignBytecode(oparg byte) []byte

BinOpAssignBytecode returns the instruction stream for a module-level assignment of the form `target = left op right` where both operands are names. oparg is the NB_* enum value for the operator (e.g. NbAdd for +).

Bytecode pattern:

RESUME 0
LOAD_NAME leftIdx
LOAD_NAME rightIdx
BINARY_OP oparg
<5 cache words (10 zero bytes)>
STORE_NAME targetIdx
LOAD_CONST 0 (None)
RETURN_VALUE

co_names order: [left, right, target] (insertion order during compilation). co_consts: [None] co_stacksize: 2

func BinOpAssignLineTable

func BinOpAssignLineTable(line int, leftCol, leftLen, rightCol, rightLen, targetLen byte) []byte

BinOpAssignLineTable returns the PEP 626 line table for:

`target = left op right` on the given source line

leftCol/leftLen: column and byte length of the left-operand name. rightCol/rightLen: column and byte length of the right-operand name. targetLen: byte length of the target name (at column 0).

func BoolAndBytecode

func BoolAndBytecode() []byte

BoolAndBytecode returns the instruction stream for `x = a and b` (module-level boolean-and assignment, both operands are names).

Bytecode pattern:

RESUME 0
LOAD_NAME 0 (a)
COPY 1
TO_BOOL 0 + 3 cache words
POP_JUMP_IF_FALSE 3 + 1 cache word
NOT_TAKEN 0
POP_TOP 0
LOAD_NAME 1 (b)
STORE_NAME 2 (x)
LOAD_CONST 0 (None)
RETURN_VALUE 0

Jump offset 3: when a is falsy, STORE_NAME x (keeping a on stack from COPY). co_names: [a, b, x] co_consts: [None] co_stacksize: 2

func BoolAndOrLineTable

func BoolAndOrLineTable(line int, leftCol, leftLen, rightCol, rightLen, targetLen byte) []byte

BoolAndOrLineTable returns the PEP 626 line table for:

x = a and b  or  x = a or b  (both operands are names)

leftCol/leftLen: column and length of the left name (a). rightCol/rightLen: column and length of the right name (b). targetLen: length of the target name (x, always at column 0).

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME a: 1 code unit
  3. COPY + TO_BOOL+3cache + POP_JUMP_IF_FALSE+1cache + NOT_TAKEN: 8 code units
  4. POP_TOP: 1 code unit
  5. LOAD_NAME b: 1 code unit
  6. STORE_NAME + LOAD_CONST + RETURN_VALUE: 3 code units

func BoolOrBytecode

func BoolOrBytecode() []byte

BoolOrBytecode returns the instruction stream for `x = a or b` (module-level boolean-or assignment, both operands are names).

Identical to BoolAndBytecode except POP_JUMP_IF_TRUE replaces POP_JUMP_IF_FALSE: when a is truthy, keep a; when falsy, use b.

co_names: [a, b, x] co_consts: [None] co_stacksize: 2

func CallAssignBytecode

func CallAssignBytecode(n int) []byte

CallAssignBytecode returns the instruction stream for `x = f(args...)` where f and all args are names and there are no keyword arguments.

Bytecode pattern (N args):

RESUME 0
LOAD_NAME 0 (f)
PUSH_NULL 0
LOAD_NAME 1 (arg0)   // repeated N times
  ...
CALL N + 3 cache words
STORE_NAME N+1 (x)
LOAD_CONST 0 (None)
RETURN_VALUE 0

co_names: [f, arg0, ..., argN-1, x] co_consts: [None] co_stacksize: 2+N (LOAD_NAME f + PUSH_NULL = 2 stack slots, each arg adds 1)

func CallAssignLineTable

func CallAssignLineTable(line int, funcCol, funcEnd byte, args []CallArg, closeEnd, targetLen byte) []byte

CallAssignLineTable returns the PEP 626 line table for `x = f(args...)`.

funcCol/funcEnd: column range of the function name (f). args: positions of each argument name. closeEnd: exclusive end column of the closing `)` (= lineEndCol for a simple call). targetLen: length of the target name x.

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME f + PUSH_NULL: 2 code units at (funcCol, funcEnd)
  3. LOAD_NAME arg0..argN-1: 1 code unit each
  4. CALL N + 3 caches: 4 code units at (funcCol, closeEnd)
  5. STORE_NAME + LOAD_CONST + RETURN_VALUE: 3 code units at (0, targetLen)

func ChainedAssignLineTable

func ChainedAssignLineTable(line int, targets []ChainedTarget, valStart, valEnd byte, tail []NoOpStmt) []byte

ChainedAssignLineTable returns the PEP 626 line table for a chained assignment `t0 = t1 = ... = tN-1 = value` on `line`, where the value occupies [valStart, valEnd) and each target occupies [t[i].NameStart, t[i].NameStart+t[i].NameLen), optionally followed by tail no-ops.

CPython emits LOAD value, then for each target except the last a COPY (covering 0..valEnd) + STORE pair, and a final STORE.

func ClcThenImportsLineTable

func ClcThenImportsLineTable(
	clcLine, clcCloseLine int, clcOpenCol, clcCloseEnd, clcTargetLen byte,
	entries []ClcImportEntry,
) []byte

ClcThenImportsLineTable returns the PEP 626 line table for a module whose body is one constant-literal list assignment (3..30 elements, possibly multi-line) followed by one or more import/from-import statements.

clcLine/clcCloseLine are the 1-indexed source lines of '[' and ']'. If clcCloseLine > clcLine the list spans multiple source lines and a LONG entry is emitted; otherwise ONE_LINE1 is used. clcOpenCol/clcCloseEnd are the column positions of '[' and ']'+1. clcTargetLen is the byte length of the assignment target name (for the SHORT0 STORE_NAME entry that follows the 3-CU build group). entries holds per-import metadata in source order.

func ClosureInnerBytecode

func ClosureInnerBytecode() []byte

ClosureInnerBytecode returns the bytecode for the inner function in a closure of the form `def g(): return x` where x is a free variable.

localsplusnames[0] = x (free variable, kind 0x80)

Instruction sequence:

COPY_FREE_VARS 1   copy x from closure cell
RESUME 0
LOAD_DEREF 0       load free variable x
RETURN_VALUE 0

func ClosureInnerLineTable

func ClosureInnerLineTable(innerDefLine, innerRetLine int,
	innerFreeArgCol, innerFreeArgEnd, innerRetKwCol byte) []byte

ClosureInnerLineTable returns the PEP 626 line table for the inner function.

  • innerDefLine: line of `def g():` (= g.firstlineno)
  • innerRetLine: line of `return x`
  • innerFreeArgCol: column of x in `return x`
  • innerFreeArgEnd: exclusive end column of x in `return x`
  • innerRetKwCol: column of the `return` keyword in `return x`

Entries:

  1. NO_INFO 1 CU — COPY_FREE_VARS (synthetic)
  2. SHORT0 1 CU — RESUME at innerDefLine
  3. ONE_LINE* 1 CU — LOAD_DEREF x at innerRetLine, cols=[innerFreeArgCol, innerFreeArgEnd)
  4. SHORT* 1 CU — RETURN_VALUE at innerRetLine, cols=[innerRetKwCol, innerFreeArgEnd)

func ClosureOuterBytecode

func ClosureOuterBytecode() []byte

ClosureOuterBytecode returns the bytecode for the outer function in a closure of the form `def f(x): def g(): return x; return g`.

localsplusnames[0] = x (arg, promoted to cell, kind 0x66) localsplusnames[1] = g (local, kind 0x20) co_consts[0] = g code object (no None)

Instruction sequence:

MAKE_CELL 0               promote x to cell (before RESUME)
RESUME 0
LOAD_FAST_BORROW 0        load x cell to build closure tuple
BUILD_TUPLE 1             closure = (x,)
LOAD_CONST 0              g code object
MAKE_FUNCTION 0
SET_FUNCTION_ATTRIBUTE 8  set __closure__
STORE_FAST 1              g = <function>
LOAD_FAST_BORROW 1        load g
RETURN_VALUE 0

func ClosureOuterLineTable

func ClosureOuterLineTable(outerDefLine, innerDefLine, innerRetLine, outerRetLine int,
	innerDefCol, innerBodyEndCol, outerRetArgCol, outerRetArgEnd, outerRetKwCol byte) []byte

ClosureOuterLineTable returns the PEP 626 line table for the outer function.

  • outerDefLine: line of `def f(x):`
  • innerDefLine: line of `def g():` (start of inner def, used as LONG entry start line)
  • innerRetLine: line of `return x` in g (innerBodyEnd, used as LONG entry end line)
  • outerRetLine: line of `return g` in f
  • innerDefCol: column of the `def` keyword in `def g():`
  • innerBodyEndCol: exclusive end column of the last token in g's body
  • outerRetArgCol: column of `g` in `return g`
  • outerRetArgEnd: exclusive end column of `g` in `return g`
  • outerRetKwCol: column of the `return` keyword in `return g`

Entries:

  1. NO_INFO 1 CU — MAKE_CELL (synthetic, no source location)
  2. SHORT0 1 CU — RESUME at outerDefLine
  3. LONG 6 CU — LOAD_FAST_BORROW+BUILD_TUPLE+LOAD_CONST+MAKE_FUNCTION+SET_FUNCTION_ATTRIBUTE+STORE_FAST start=innerDefLine, end=innerRetLine, cols=[innerDefCol, innerBodyEndCol)
  4. ONE_LINE* 1 CU — LOAD_FAST_BORROW g at outerRetLine, cols=[outerRetArgCol, outerRetArgEnd)
  5. SHORT* 1 CU — RETURN_VALUE at outerRetLine, cols=[outerRetKwCol, outerRetArgEnd)

func CmpAssignBytecode

func CmpAssignBytecode(op Opcode, oparg byte) []byte

CmpAssignBytecode returns the instruction stream for a module-level assignment of the form `target = left op right` where both operands are names and op is a comparison, identity, or containment operator.

op must be one of COMPARE_OP, IS_OP, or CONTAINS_OP. oparg is the NB_/CMP_/IS_/CONTAINS_ oparg for the operator.

Bytecode pattern:

RESUME 0
LOAD_NAME leftIdx   (names[0])
LOAD_NAME rightIdx  (names[1])
op oparg
[cache word if op has cache]
STORE_NAME targetIdx (names[2])
LOAD_CONST 0 (None)
RETURN_VALUE

co_names: [left, right, target] co_consts: [None] co_stacksize: 2

func CmpAssignLineTable

func CmpAssignLineTable(op Opcode, line int, leftCol, leftLen, rightCol, rightLen, targetLen byte) []byte

CmpAssignLineTable returns the PEP 626 line table for:

`target = left op right` on the given source line

op must be COMPARE_OP, IS_OP, or CONTAINS_OP. leftCol/leftLen: column and byte length of the left-operand name. rightCol/rightLen: column and byte length of the right-operand name. targetLen: byte length of the target name (at column 0).

func CollectionEmptyBytecode

func CollectionEmptyBytecode(kind CollKind) []byte

CollectionEmptyBytecode returns the instruction stream for an empty collection literal assignment `x = []`, `x = ()`, or `x = {}`.

For list and dict the pattern is BUILD_LIST/BUILD_MAP 0; for tuple CPython constant-folds `()` and emits LOAD_CONST 1 (the () sentinel).

co_names: [x] co_consts: [None] for list/dict; [None, ()] for tuple co_stacksize: 1

func CollectionEmptyLineTable

func CollectionEmptyLineTable(line int, openCol, closeEnd, targetLen byte) []byte

CollectionEmptyLineTable returns the PEP 626 line table for an empty collection literal `x = []`, `x = ()`, or `x = {}` on the given source line.

openCol: column of the opening bracket/paren/brace. closeEnd: exclusive end column of the closing bracket (= lineEndCol for

a single-line statement).

targetLen: byte length of the target name x (always at column 0).

Line table entries:

  1. Prologue (RESUME)
  2. BUILD_*/LOAD_CONST: 1 code unit at (openCol, closeEnd)
  3. STORE_NAME + LOAD_CONST None + RETURN_VALUE: 3 code units at (0, targetLen)

func CollectionNamesBytecode

func CollectionNamesBytecode(kind CollKind, n int) []byte

CollectionNamesBytecode returns the instruction stream for a collection literal assignment `x = [e0, e1, ...]` (list), `x = (e0, e1, ...)` (tuple), `x = {e0, e1, ...}` (set), or `x = {k0: v0, k1: v1, ...}` (dict) where all elements are names.

elts holds one entry per LOAD_NAME instruction. For dicts, elts alternates key/value so len(elts) must be even; BUILD_MAP oparg = len(elts)/2.

co_names: [elts[0].Name, ..., elts[N-1].Name, target] (insertion order) co_consts: [None] co_stacksize: len(elts) (or 1 if len=1, since BUILD_* collapses to 1 stack slot)

func CollectionNamesLineTable

func CollectionNamesLineTable(line int, elts []CollElt, openCol, closeEnd, targetLen byte) []byte

CollectionNamesLineTable returns the PEP 626 line table for a non-empty collection literal assignment where all elements are names, on the given source line.

elts: positions of each name element (same order as in CollectionNamesBytecode). openCol: column of the opening bracket. closeEnd: exclusive end column of the closing bracket. targetLen: length of the target name.

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME elts[0]: 1 code unit at (elts[0].Col, elts[0].Col+elts[0].NameLen)
  3. LOAD_NAME elts[1..N-1]: 1 code unit each at their respective columns
  4. BUILD_* N: 1 code unit at (openCol, closeEnd)
  5. STORE_NAME + LOAD_CONST + RETURN_VALUE: 3 code units at (0, targetLen)

func CompareCondArg added in v0.6.0

func CompareCondArg(base byte) byte

CompareCondArg adds 16 to a value-context COMPARE_OP oparg to produce the conditional-context oparg. CPython's compiler embeds the comparison into the following jump by setting bit 4 of the oparg.

SOURCE: CPython 3.14 Python/compile.c, compiler_compare and the COMPARISON_BITS layout in Lib/dis.py.

func ConstLitLargeListBytecode

func ConstLitLargeListBytecode(n int) []byte

ConstLitLargeListBytecode returns the instruction stream for a large (n≥31) all-string-constant list: RESUME + BUILD_LIST 0 + N×(LOAD_CONST i + LIST_APPEND 1) + STORE_NAME 0 + LOAD_CONST N (None at index N) + RETURN_VALUE.

func ConstLitLargeListLineTable

func ConstLitLargeListLineTable(openLine, closeLine int, nameLen, openCol, closeEndCol byte, elts []LargeListElt) []byte

ConstLitLargeListLineTable returns the PEP 626 line table for a large list assignment where elements are each on their own line. openLine/closeLine are the 1-indexed lines of '[' and ']'; openCol is the column of '['; closeEndCol is the exclusive end column of ']' (1 for ']' at col 0).

func ConstLitList1Bytecode

func ConstLitList1Bytecode() []byte

ConstLitList1Bytecode returns the instruction stream for a 1-element constant list: RESUME + LOAD_CONST 0 + BUILD_LIST 1 + STORE_NAME 0 + LOAD_CONST 1 (None) + RETURN_VALUE.

func ConstLitList1LineTable

func ConstLitList1LineTable(line int, nameLen, openCol, closeEnd, elemCol, elemEnd byte) []byte

ConstLitList1LineTable returns the PEP 626 line table for a 1-element constant-literal list assignment. elemCol/elemEnd are the column range of the single element literal (including quotes). openCol/closeEnd span the entire [...] expression.

func ConstLitList2Bytecode

func ConstLitList2Bytecode() []byte

ConstLitList2Bytecode returns the instruction stream for a 2-element constant list: RESUME + LOAD_CONST 0 + LOAD_CONST 1 + BUILD_LIST 2 + STORE_NAME 0 + LOAD_CONST 2 (None) + RETURN_VALUE.

func ConstLitList2LineTable

func ConstLitList2LineTable(line int, nameLen, openCol, closeEnd, col0, end0, col1, end1 byte) []byte

ConstLitList2LineTable returns the PEP 626 line table for a 2-element constant-literal list assignment. col0/end0 and col1/end1 are the column ranges of the two element literals (including quotes). openCol/closeEnd span the entire [...] expression.

func ConstLitListExtendBytecode

func ConstLitListExtendBytecode() []byte

ConstLitListExtendBytecode returns the instruction stream for a 3+ element constant list: RESUME + BUILD_LIST 0 + LOAD_CONST 2 (full tuple) + LIST_EXTEND 1 + STORE_NAME 0 + LOAD_CONST 1 (None) + RETURN_VALUE.

func ConstLitListExtendLineTable

func ConstLitListExtendLineTable(line int, nameLen, openCol, closeEnd byte) []byte

ConstLitListExtendLineTable returns the PEP 626 line table for a 3+ element constant-literal list assignment. BUILD_LIST 0 + LOAD_CONST + LIST_EXTEND together cover 3 code units and get one linetable entry spanning [openCol, closeEnd). STORE_NAME + LOAD_CONST None + RETURN_VALUE are 3 more code units, covered by a SHORT0 entry at column [0, nameLen).

func ConstLitSeqLineTable

func ConstLitSeqLineTable(
	hasDoc bool, docLine, docEndLine int, docEndCol byte,
	stmts []ConstLitSeqStmt,
	frozenSetStmts []FrozenSetSeqStmt,
) []byte

ConstLitSeqLineTable returns the PEP 626 line table for a multi-statement module body consisting of an optional docstring, zero or more constant-literal collection assignments, and zero or more frozenset(arg).__contains__ assignments. hasDoc, docLine, docEndLine, and docEndCol describe the docstring (ignored when hasDoc is false). Multi-line docstrings (docEndLine > docLine) emit a LONG entry automatically.

func ConstLitTupleBytecode

func ConstLitTupleBytecode() []byte

ConstLitTupleBytecode returns the instruction stream for a tuple of N≥1 constant elements: RESUME + LOAD_CONST 2 (full tuple at index 2) + STORE_NAME 0 + LOAD_CONST 1 (None) + RETURN_VALUE.

func ConstLitTupleLineTable

func ConstLitTupleLineTable(line int, nameLen, openCol, closeEnd byte) []byte

ConstLitTupleLineTable returns the PEP 626 line table for a constant-literal tuple assignment on `line`. openCol is the column of '(' and closeEnd is the lineEndCol (exclusive). This is identical to AssignLineTable(line, nameLen, openCol, closeEnd, nil) since LOAD_CONST <tuple> is one code unit.

func DocstringBytecode

func DocstringBytecode(tailStmts int) []byte

DocstringBytecode returns the instruction stream for a module whose body is a leading docstring followed by `tailStmts` no-op statements. The result is always the docstring's RESUME + LOAD_CONST + STORE_NAME + max(0, tailStmts-1) NOPs + LOAD_CONST None + RETURN_VALUE; each instruction is two bytes.

func DocstringLineTable

func DocstringLineTable(docLine, docEndLine int, docEndCol byte, tail []NoOpStmt) []byte

DocstringLineTable returns the PEP 626 line table for a module whose first statement is a docstring on `docLine` ending on `docEndLine` at column `docEndCol`, followed by `tail` no-op statements.

The docstring entry covers two code units (LOAD_CONST + STORE_NAME) when the tail is non-empty, four when not. Single-line docstrings (docEndLine == docLine) use the compact ONE_LINE_* dispatch in appendNoOpEntry. Multi-line docstrings always use a LONG entry because the ONE_LINE codes implicitly mean end_line == start_line; `appendDocstringLong` handles that path.

Tail line deltas are computed from the docstring's *start* line (the v0.0.4 entry-to-entry rule), not its end line.

func ForAssignBytecode

func ForAssignBytecode(iterIdx, loopVarIdx, bodyVal, bodyVarIdx, noneIdx byte) []byte

ForAssignBytecode returns the instruction stream for a simple `for loopVar in iter: bodyVar = bodyVal` loop with no break/continue/else.

Bytecode pattern:

RESUME 0
LOAD_NAME iterIdx
GET_ITER
[loop top L1:]
  FOR_ITER 5 + 1 cache word
  STORE_NAME loopVarIdx
  LOAD_SMALL_INT bodyVal
  STORE_NAME bodyVarIdx
  JUMP_BACKWARD 7 + 1 cache word
[loop exit L2:]
  END_FOR
  POP_ITER
  LOAD_CONST noneIdx (None)
  RETURN_VALUE 0

Jump offsets (in code units):

  • FOR_ITER oparg = 5: STORE_NAME+LOAD_SMALL_INT+STORE_NAME+JUMP_BACKWARD+cache
  • JUMP_BACKWARD oparg = 7: L2_cu - L1_cu (from END_FOR back to FOR_ITER)

func ForAssignLineTable

func ForAssignLineTable(forLine, bodyLine int, iterCol, iterEnd, loopVarCol, loopVarEnd, valCol, valEnd, bodyVarCol, bodyVarEnd byte) []byte

ForAssignLineTable returns the PEP 626 line table for a simple `for loopVar in iter: bodyVar = bodyVal` loop on two lines.

Line table entries:

  1. Setup block (4 code units): LOAD_NAME iter+GET_ITER+FOR_ITER+cache
  2. STORE_NAME loopVar (1 code unit): same line as for
  3. LOAD_SMALL_INT bodyVal (1 code unit): body line
  4. STORE_NAME bodyVar + JUMP_BACKWARD + cache (3 code units): same as body
  5. END_FOR+POP_ITER+LOAD_CONST+RETURN_VALUE (4 code units): LONG entry attributed back to the for line at the iterator's column range.

func FrozenSetContainsBytecode

func FrozenSetContainsBytecode() []byte

FrozenSetContainsBytecode returns the fixed 42-byte instruction stream for `target = frozenset(arg).__contains__`.

func FrozenSetContainsLineTable

func FrozenSetContainsLineTable(line int, targetLen, frozensetCol, argCol, argLen byte) []byte

FrozenSetContainsLineTable returns the PEP 626 line table for `target = frozenset(arg).__contains__` on source line `line`.

Column arguments (all 0-indexed, exclusive end):

targetLen    – byte length of the assignment target name
frozensetCol – column of the 'f' in 'frozenset'
argCol       – column of the first character of arg
argLen       – byte length of arg

func FuncDefModuleBytecode

func FuncDefModuleBytecode(funcNameIdx byte) []byte

FuncDefModuleBytecode returns the module-level instruction stream for a `def funcName(...): ...` where funcNameIdx is the index of the function name in co_names, the function code object is co_consts[0], and None is co_consts[1].

Pattern:

RESUME 0
LOAD_CONST 0        (function code object)
MAKE_FUNCTION 0
STORE_NAME funcNameIdx
LOAD_CONST 1        (None)
RETURN_VALUE 0

func FuncDefModuleLineTable

func FuncDefModuleLineTable(defLine, bodyEndLine int, bodyEndCol byte) []byte

FuncDefModuleLineTable returns the PEP 626 line table for a module-level def spanning defLine through bodyEndLine, with the last body statement ending at bodyEndCol (0-indexed exclusive).

Table entries:

  1. Prologue: RESUME at synthetic line (1 CU)
  2. LONG: 5 CUs (LOAD_CONST+MAKE_FUNCTION+STORE_NAME+LOAD_CONST+RETURN_VALUE) attributed to defLine..bodyEndLine at columns [0, bodyEndCol)

func FuncReturnArgBytecode

func FuncReturnArgBytecode(argIdx byte) []byte

FuncReturnArgBytecode returns the instruction stream for a function whose single body statement is `return arg` where arg is at argIdx in co_localsplusnames.

Pattern:

RESUME 0
LOAD_FAST_BORROW argIdx
RETURN_VALUE 0

func FuncReturnArgLineTable

func FuncReturnArgLineTable(firstlineno, bodyLine int, argCol, argEnd, retKwCol byte) []byte

FuncReturnArgLineTable returns the PEP 626 line table for a function body `return arg` where the return keyword is at retKwCol and the argument expression spans [argCol, argEnd).

Table entries:

  1. SHORT0: RESUME at line firstlineno (1 CU, columns [0,0))
  2. ONE_LINE1/2/LONG: LOAD_FAST_BORROW at bodyLine (1 CU, [argCol, argEnd))
  3. SHORT0: RETURN_VALUE at same line (1 CU, [retKwCol, argEnd))

func GenExprFirstEntry

func GenExprFirstEntry(out []byte, lineDelta, cuCount int, sc, ec byte) []byte

GenExprFirstEntry appends a ONE_LINE0/1/2 or LONG entry for the first real instruction after RESUME (lineDelta is relative to the synthetic line 0, so for line 1 pass lineDelta=1).

func GenExprProlog

func GenExprProlog() []byte

GenExprProlog returns the 5-byte LONG(1) prologue linetable entry that covers the RESUME instruction in a module-level code object:

f0 03 01 01 01  (code=LONG, length=1, delta=-1, end_delta=1, cols=[0,0))

func GenExprSameLine

func GenExprSameLine(out []byte, cuCount int, sc, ec byte) []byte

GenExprSameLine appends a SHORTn or ONE_LINE0 entry for an instruction on the same source line as the previous entry.

func IfElseBytecode

func IfElseBytecode(branches []IfBranch, hasElse bool, elseVal, elseVarIdx, noneIdx byte) []byte

IfElseBytecode returns the instruction stream for an if/elif/else chain where each branch body is a single `name = small_int` assignment.

All branch bodies use LOAD_SMALL_INT (values 0-255). noneIdx is the co_consts index of None (always 1 for our pattern). If hasElse is false the last code unit group is just LOAD_CONST noneIdx / RETURN_VALUE.

Bytecode pattern for N conditions with else:

RESUME 0
[for each branch (if/elif):]
  LOAD_NAME condIdx
  TO_BOOL 0 + 3 cache words
  POP_JUMP_IF_FALSE 5 + 1 cache word
  NOT_TAKEN 0
  LOAD_SMALL_INT bodyVal
  STORE_NAME varIdx
  LOAD_CONST noneIdx (None)
  RETURN_VALUE 0
[else body (if hasElse):]
  LOAD_SMALL_INT elseVal
  STORE_NAME elseVarIdx
  LOAD_CONST noneIdx
  RETURN_VALUE 0
[no-else implicit return:]
  LOAD_CONST noneIdx
  RETURN_VALUE 0

Jump offset 5: after the cache word, skip NOT_TAKEN + LOAD_SMALL_INT + STORE_NAME + LOAD_CONST + RETURN_VALUE (5 code units) to reach the next condition or else body.

func IfElseLineTable

func IfElseLineTable(branches []IfBranchLT, hasElse bool, elseLine int, elseValCol, elseValEnd, elseVarCol, elseVarEnd byte) []byte

IfElseLineTable returns the PEP 626 line table for an if/elif/else chain.

branches: condition+body positions for each if/elif arm. hasElse: whether there is an else body. elseLine/elseValCol/elseValEnd/elseVarCol/elseVarEnd: positions in the else body.

Line table entries per branch:

  1. Condition block (8 code units): LOAD_NAME + TO_BOOL+3cache + POP_JUMP+cache + NOT_TAKEN
  2. LOAD_SMALL_INT (1 code unit): value position in body
  3. STORE_NAME + LOAD_CONST + RETURN_VALUE (3 code units): variable position in body

For no-else: appends a LONG entry (2 code units) at the first condition's column going back to the condition line (implicit "return None" when false). For else: appends the else body entries (same structure as a true body).

func ImportBytecode

func ImportBytecode(entries []ImportEntry, constIdxs []byte, nameRefs []ImportNameRef) []byte

ImportBytecode builds the bytecode for a sequence of import entries. noneIdx is the co_consts index for None. The final LOAD_CONST None + RETURN_VALUE are appended after all entries. Each entry's constIdx is the co_consts index for its fromlist constant.

func ImportLineTable

func ImportLineTable(entries []ImportEntry, isLast []bool) []byte

ImportLineTable builds the linetable for a sequence of import entries. All imports are at absolute level; prevLine is the line before the first import (use 0 since the RESUME prologue is at the synthetic line 0).

func LflblflbArg added in v0.6.0

func LflblflbArg(slotL, slotR byte) byte

LflblflbArg encodes the oparg for the LOAD_FAST_BORROW_LOAD_FAST_BORROW super-instruction: high nibble is the left slot, low nibble is the right slot. Both slots must fit in 4 bits.

func LineTableEmpty

func LineTableEmpty() []byte

LineTableEmpty returns the line table CPython emits for an empty module body (no real statements; the synthetic RESUME / LOAD_CONST None / RETURN_VALUE prologue covers all three instructions in a single LONG entry). Verified against `python3.14 -m py_compile` on an empty source file.

f2 03 01 01 01
|  |  |  |  |
|  |  |  |  end_col+1 = 1 (col 0)
|  |  |  start_col+1 = 1 (col 0)
|  |  end_line_delta = 0
|  line_delta = -1 (synthetic line is firstlineno-1)
header: code 14 (LONG), length-1 = 2 (covers 3 code units)

func LineTableNoOps

func LineTableNoOps(stmts []NoOpStmt) []byte

LineTableNoOps returns the line table for a module body of N >= 1 no-op statements at the given source positions. Bytecode for the body is `RESUME, (N-1) NOPs, LOAD_CONST 0, RETURN_VALUE`. Each statement contributes one entry: length 1 for non-last (covers one NOP) or length 2 for the last (covers LOAD_CONST + RETURN_VALUE).

Statements must be in source order (Line strictly increasing for the v0.0.4 grammar; equal lines would also encode but we never emit them today). Verified against `python3.14 -m py_compile` for every gap configuration up through ten blank lines between statements.

func LineTableSingleNoOp

func LineTableSingleNoOp(endCol byte) []byte

LineTableSingleNoOp is the N=1 case of LineTableNoOps with the statement on line 1. Kept as a named alias for readability.

func LoadAttrArg added in v0.6.0

func LoadAttrArg(nameIdx byte, asMethod bool) byte

LoadAttrArg encodes the LOAD_ATTR oparg. The high seven bits are the index into co_names; the low bit signals method-load form (LOAD_METHOD-style: pushes NULL+method instead of the bare attribute).

SOURCE: CPython 3.14 Python/compile.c, codegen_load_attr.

func LoadGlobalArg added in v0.6.0

func LoadGlobalArg(nameIdx byte, pushNull bool) byte

LoadGlobalArg encodes the LOAD_GLOBAL oparg as CPython does: the high seven bits are the index into co_names, the low bit signals whether to push NULL ahead of the loaded value (used by CPython's calling convention for `LOAD_GLOBAL` immediately followed by `CALL`).

SOURCE: CPython 3.14 Python/compile.c, codegen_load_global.

func MixedModuleLineTable added in v0.5.7

func MixedModuleLineTable(info MixedModuleInfo) []byte

MixedModuleLineTable generates the PEP 626 module-level line table for a mixed module with the structure:

[docstring?] [constLitColl?] [foldedBinOp assigns*] [funcBodyExprs+]

func MultiAssignLineTable

func MultiAssignLineTable(asgns []AssignInfo, tail []NoOpStmt) []byte

MultiAssignLineTable returns the PEP 626 line table for a sequence of N >= 1 `name = value` assignments followed by optional tail no-ops. It generalises AssignLineTable to the multi-assignment case.

func MultiFuncDefLineTable added in v0.5.1

func MultiFuncDefLineTable(entries []MultiFuncDefEntry) []byte

MultiFuncDefLineTable returns the PEP 626 line table for a module body of N >= 2 function definitions with no other top-level statements.

Layout:

  • Prologue: 1 CU (RESUME, no-source)
  • For each funcdef except the last: 3 CUs (LOAD_CONST + MAKE_FUNCTION + STORE_NAME)
  • For the last funcdef: 5 CUs (LOAD_CONST + MAKE_FUNCTION + STORE_NAME + LOAD_CONST None + RETURN_VALUE)

func NoOpBytecode

func NoOpBytecode(n int) []byte

NoOpBytecode returns the raw instruction stream for a module body of exactly N >= 1 no-op statements:

RESUME 0  +  (N-1) x NOP 0  +  LOAD_CONST 0  +  RETURN_VALUE 0

Each instruction is two bytes (opcode + oparg), so the result is 6 + 2*(N-1) bytes long. Verified against `python3.14 -m py_compile`.

func SubscriptLoadBytecode

func SubscriptLoadBytecode() []byte

SubscriptLoadBytecode returns the instruction stream for `x = a[b]` (module-level subscript read, object and key are names).

Bytecode pattern:

RESUME 0
LOAD_NAME 0 (a)
LOAD_NAME 1 (b)
BINARY_OP 26 ([]) + 5 cache words
STORE_NAME 2 (x)
LOAD_CONST 0 (None)
RETURN_VALUE 0

co_names: [a, b, x] co_consts: [None] co_stacksize: 2

func SubscriptLoadLineTable

func SubscriptLoadLineTable(line int, objCol, objEnd, keyCol, keyEnd, closeEnd, targetLen byte) []byte

SubscriptLoadLineTable returns the PEP 626 line table for `x = a[b]`.

objCol/objEnd: column range of the object name (a). keyCol/keyEnd: column range of the key name (b). closeEnd: column after the closing `]` (= keyEnd + 1 for simple `a[b]`). targetLen: length of the target name x.

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME a: 1 code unit
  3. LOAD_NAME b: 1 code unit
  4. BINARY_OP + 5 caches: 6 code units at (objCol, closeEnd)
  5. STORE_NAME + LOAD_CONST + RETURN_VALUE: 3 code units at (0, targetLen)

func SubscriptStoreBytecode

func SubscriptStoreBytecode() []byte

SubscriptStoreBytecode returns the instruction stream for `a[b] = x` (module-level subscript store, object, key and value are names).

Bytecode pattern:

RESUME 0
LOAD_NAME 0 (x)  -- value to store
LOAD_NAME 1 (a)  -- object
LOAD_NAME 2 (b)  -- key
STORE_SUBSCR 0 + 1 cache word
LOAD_CONST 0 (None)
RETURN_VALUE 0

co_names: [x, a, b] co_consts: [None] co_stacksize: 3

func SubscriptStoreLineTable

func SubscriptStoreLineTable(line int, valCol, valEnd, objCol, objEnd, keyCol, keyEnd, closeEnd byte) []byte

SubscriptStoreLineTable returns the PEP 626 line table for `a[b] = x`.

valCol/valEnd: column range of the value name (x). objCol/objEnd: column range of the object name (a). keyCol/keyEnd: column range of the key name (b). closeEnd: column after the closing `]` (= keyEnd + 1).

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME x: 1 code unit
  3. LOAD_NAME a: 1 code unit
  4. LOAD_NAME b: 1 code unit
  5. STORE_SUBSCR + 1 cache + LOAD_CONST + RETURN_VALUE: 4 code units at (objCol, closeEnd)

func TernaryBytecode

func TernaryBytecode() []byte

TernaryBytecode returns the instruction stream for `x = a if c else b` (module-level conditional expression, all operands are names).

Bytecode pattern:

RESUME 0
LOAD_NAME 0 (c)           -- condition
TO_BOOL 0 + 3 cache words
POP_JUMP_IF_FALSE 5 + 1 cache word
NOT_TAKEN 0
LOAD_NAME 1 (a)           -- true branch
STORE_NAME 3 (x)
LOAD_CONST 0 (None)
RETURN_VALUE 0
LOAD_NAME 2 (b)           -- false branch (jump target)
STORE_NAME 3 (x)
LOAD_CONST 0 (None)
RETURN_VALUE 0

Jump offset 5: false branch is 5 words after the POP_JUMP_IF_FALSE cache. co_names: [c, a, b, x] co_consts: [None] co_stacksize: 1

func TernaryLineTable

func TernaryLineTable(line int, condCol, condLen, trueCol, trueLen, falseCol, falseLen, targetLen byte) []byte

TernaryLineTable returns the PEP 626 line table for:

x = a if c else b  (all operands are names, on the given source line)

condCol/condLen: column and length of the condition name (c). trueCol/trueLen: column and length of the true-branch name (a). falseCol/falseLen: column and length of the false-branch name (b). targetLen: length of the target name (x, always at column 0).

Line table entries:

  1. Prologue (RESUME)
  2. LOAD_NAME c + TO_BOOL+3cache + POP_JUMP_IF_FALSE+1cache + NOT_TAKEN: 8 code units
  3. LOAD_NAME a: 1 code unit
  4. STORE_NAME + LOAD_CONST + RETURN_VALUE: 3 code units
  5. LOAD_NAME b: 1 code unit
  6. STORE_NAME + LOAD_CONST + RETURN_VALUE: 3 code units

func UnaryNegInvertBytecode

func UnaryNegInvertBytecode(opcode Opcode) []byte

UnaryNegInvertBytecode returns the instruction stream for:

target = -operand  (UNARY_NEGATIVE)
target = ~operand  (UNARY_INVERT)

opcode must be UNARY_NEGATIVE or UNARY_INVERT. co_names order: [operand, target] co_consts: [None] co_stacksize: 1

func UnaryNegInvertLineTable

func UnaryNegInvertLineTable(line int, opCol, operandCol, operandLen, targetLen byte) []byte

UnaryNegInvertLineTable returns the PEP 626 line table for:

`target = -operand` or `target = ~operand` on the given source line

opCol: column of the unary operator (- or ~). operandCol/operandLen: column and byte length of the operand name. targetLen: byte length of the target name (at column 0).

func UnaryNotBytecode

func UnaryNotBytecode() []byte

UnaryNotBytecode returns the instruction stream for `target = not operand`.

Bytecode pattern:

RESUME 0
LOAD_NAME 0 (operand)
TO_BOOL
<3 cache words (6 zero bytes)>
UNARY_NOT
STORE_NAME 1 (target)
LOAD_CONST 0 (None)
RETURN_VALUE

co_names order: [operand, target] co_consts: [None] co_stacksize: 1

func UnaryNotLineTable

func UnaryNotLineTable(line int, notCol, operandCol, operandLen, targetLen byte) []byte

UnaryNotLineTable returns the PEP 626 line table for:

`target = not operand` on the given source line

notCol: column of 'n' in 'not'. operandCol/operandLen: column and byte length of the operand name. targetLen: byte length of the target name (at column 0).

func WhileAssignBytecode

func WhileAssignBytecode(condIdx, bodyVal, varIdx, noneIdx byte) []byte

WhileAssignBytecode returns the instruction stream for a simple `while cond: name = val` loop with no break/continue/else.

Bytecode pattern:

RESUME 0
[loop top L1:]
  LOAD_NAME condIdx
  TO_BOOL 0 + 3 cache words
  POP_JUMP_IF_FALSE 5 + 1 cache word
  NOT_TAKEN 0
  LOAD_SMALL_INT bodyVal
  STORE_NAME varIdx
  JUMP_BACKWARD 12 + 1 cache word
[loop exit L2:]
  LOAD_CONST noneIdx (None)
  RETURN_VALUE 0

Jump offsets (in code units):

  • POP_JUMP_IF_FALSE oparg = 5: NOT_TAKEN+LOAD_SMALL_INT+STORE_NAME+JUMP_BACKWARD+cache
  • JUMP_BACKWARD oparg = 12: L2_cu - L1_cu (back from LOAD_CONST to LOAD_NAME)

func WhileAssignLineTable

func WhileAssignLineTable(condLine, bodyLine int, condCol, condEnd, valCol, valEnd, varCol, varEnd byte) []byte

WhileAssignLineTable returns the PEP 626 line table for a simple `while cond: name = val` loop on two lines.

Line table entries:

  1. Condition block (8 code units): LOAD_NAME+TO_BOOL+3cache+POP_JUMP+cache+NOT_TAKEN
  2. LOAD_SMALL_INT (1 code unit): integer literal in body
  3. STORE_NAME + JUMP_BACKWARD + cache (3 code units): variable name in body
  4. LOAD_CONST + RETURN_VALUE (2 code units): LONG entry attributed back to the condition line (loop exits when condition is false).

Types

type AliasNameRef

type AliasNameRef struct {
	NameIdx  byte // IMPORT_FROM oparg (original attribute name)
	StoreIdx byte // STORE_NAME oparg (local binding)
}

AliasNameRef holds co_names indices for one alias in a from-import.

type ArgKind added in v0.6.0

type ArgKind uint8

ArgKind classifies what an opcode's oparg means.

Distinct from CacheSize: a cache size says how many bytes follow the opcode for inline-caching. ArgKind says what the one oparg byte itself is *for*.

const (
	ArgNone    ArgKind = iota // oparg unused (still occupies one byte)
	ArgConst                  // index into co_consts
	ArgName                   // index into co_names
	ArgLocal                  // index into co_localsplusnames (fast)
	ArgFree                   // index into freevars region of locals
	ArgJumpRel                // relative jump in instruction words
	ArgJumpAbs                // absolute jump target
	ArgRaw                    // opcode-specific encoding (CALL n, COMPARE_OP cmp, etc.)
)

type AssignInfo

type AssignInfo struct {
	Line     int  // 1-indexed source line
	NameLen  byte // number of bytes in the name (1..15)
	ValStart byte // 0-indexed start column of the value text
	ValEnd   byte // 0-indexed exclusive end column of the value text
}

AssignInfo describes one `name = value` assignment for multi-assign line-table generation.

type Atom added in v0.6.0

type Atom uint32

Atom is an interned identifier. It indexes into an AtomTable. Atom IDs are dense and start at 0, so they can directly drive arrays such as co_names indexing.

type AtomTable added in v0.6.0

type AtomTable struct {
	// contains filtered or unexported fields
}

AtomTable interns strings. Insertion order is preserved: the first string passed to Intern gets atom 0, the next unique string gets 1, and so on. Re-interning a known string returns its original ID.

Determinism matters: gocopy needs byte-identical output, and co_names ordering follows source order. The slice + map combo keeps interning O(1) amortized while preserving that ordering.

func NewAtomTable added in v0.6.0

func NewAtomTable() *AtomTable

NewAtomTable returns an empty AtomTable.

func (*AtomTable) Intern added in v0.6.0

func (t *AtomTable) Intern(s string) Atom

Intern returns the Atom for s, allocating a new one if it has not been seen before.

func (*AtomTable) Len added in v0.6.0

func (t *AtomTable) Len() int

Len returns the number of distinct atoms.

func (*AtomTable) Slice added in v0.6.0

func (t *AtomTable) Slice() []string

Slice returns a defensive copy of all interned strings in atom order, suitable for emitting as a tuple constant.

func (*AtomTable) String added in v0.6.0

func (t *AtomTable) String(a Atom) string

String returns the string for the given Atom. It panics if the Atom is out of range; that is always a programmer error.

type CallArg

type CallArg struct {
	Name    string
	Col     byte
	NameLen byte
}

CallArg describes one positional argument in a function call assignment.

type ChainedTarget

type ChainedTarget struct {
	NameStart byte // 0-indexed column of the name's first byte
	NameLen   byte // number of bytes in the name
}

ChainedTarget describes one assignment target in a chained assignment for line-table generation.

type ClcImportEntry

type ClcImportEntry struct {
	Line    int
	EndCol  byte
	CUCount int // precomputed (e.cuCount())
	IsLast  bool
}

ClcImportEntry carries linetable metadata for one import in a CLC-then-imports module body.

type CodeObject

type CodeObject struct {
	ArgCount        int32
	PosOnlyArgCount int32
	KwOnlyArgCount  int32
	StackSize       int32
	Flags           uint32

	Bytecode []byte // raw instruction bytes (opcode, oparg, cache words)

	// Consts holds the value table. Each entry is one of: nil (None),
	// bool, int64, float64, complex128, string, []byte, *CodeObject, or
	// a tuple represented as []any. v0.0.1 only emits a single nil for
	// the implicit `return None`.
	Consts []any

	Names           []string // attribute / global names referenced by LOAD_GLOBAL etc.
	LocalsPlusNames []string // varnames + cellvars + freevars in one ordered slice
	LocalsPlusKinds []byte   // kind flag per name (FastLocal/FastCell/FastFree/FastArg/FastHidden)

	Filename    string
	Name        string
	QualName    string
	FirstLineNo int32
	LineTable   []byte
	ExcTable    []byte
}

CodeObject is gocopy's mutable representation of a CPython code object. The marshal package walks this struct in field order matching Python/marshal.c::w_object's code-object branch and emits the wire format.

Field order is the canonical CPython 3.14 code-object marshal order:

argcount, posonlyargcount, kwonlyargcount, stacksize, flags,
bytecode, consts, names, localsplusnames, localspluskinds,
filename, name, qualname, firstlineno, linetable, exceptiontable.

type CollElt

type CollElt struct {
	Name    string
	Col     byte
	NameLen byte
}

CollElt describes one element (or key+value pair for dicts) in a collection-literal assignment. For dicts, elts alternate key/value.

type CollKind

type CollKind uint8

CollKind identifies the collection type for collection-literal assignments.

const (
	CollList  CollKind = iota // x = [...]
	CollTuple                 // x = (...)
	CollSet                   // x = {...}  (set, not dict)
	CollDict                  // x = {k: v, ...}
)

type Const added in v0.6.0

type Const struct {
	Kind    ConstKind
	Int     int64
	Float   float64
	Complex complex128
	Str     string
	Bytes   []byte
	Tuple   []ConstRef
	Code    *CodeObject
}

Const is a tagged union covering every kind of value gocopy emits into co_consts. The struct stays small: tagged-int / tagged-float / pointer-into-pool layouts match what the marshal writer needs.

type ConstKind added in v0.6.0

type ConstKind uint8

ConstKind tags one variant of Const. The discrete set mirrors the Python types CPython's marshal format encodes for code-object constants: None, True, False, Ellipsis, int, float, complex, str, bytes, tuple, code.

const (
	KindNone ConstKind = iota
	KindFalse
	KindTrue
	KindEllipsis
	KindInt
	KindFloat
	KindComplex
	KindStr
	KindBytes
	KindTuple
	KindCode
)

type ConstLitSeqStmt

type ConstLitSeqStmt struct {
	Line      int            // 1-indexed source line of '[', '(', or value
	CloseLine int            // 1-indexed source line of ']' (large lists only)
	TargetLen byte           // byte length of the assignment target name
	OpenCol   byte           // column of '[' or '('
	CloseEnd  byte           // exclusive end column of ']' or ')'
	IsList    bool           // true for list, false for tuple
	N         int            // number of elements
	Elts      []LargeListElt // non-nil only for n≥31 lists
}

ConstLitSeqStmt describes one constLitColl statement in a multi-statement sequence for linetable generation.

type ConstPool added in v0.6.0

type ConstPool struct {
	// contains filtered or unexported fields
}

ConstPool stores Const values with type-specific interning matching CPython's marshal-time identity rules:

  • None / True / False / Ellipsis are singletons.
  • Strings intern by content.
  • Ints intern by value.
  • Floats intern by bit pattern (so -0.0 and 0.0 stay distinct, and NaN bit patterns preserve identity).
  • Complex numbers intern by the bit pattern of (real, imag).
  • Bytes intern by content.
  • Tuples intern by the sequence of ConstRefs they contain.
  • Code objects are always distinct: each compiled function gets its own entry.

func NewConstPool added in v0.6.0

func NewConstPool() *ConstPool

NewConstPool returns an empty pool.

func (*ConstPool) AddBool added in v0.6.0

func (p *ConstPool) AddBool(b bool) ConstRef

AddBool returns the ConstRef for True or False.

func (*ConstPool) AddBytes added in v0.6.0

func (p *ConstPool) AddBytes(b []byte) ConstRef

AddBytes interns a bytes constant by content.

func (*ConstPool) AddCode added in v0.6.0

func (p *ConstPool) AddCode(c *CodeObject) ConstRef

AddCode adds a code-object constant. Code objects are never interned; each compiled function gets its own entry.

func (*ConstPool) AddComplex added in v0.6.0

func (p *ConstPool) AddComplex(v complex128) ConstRef

AddComplex interns a complex constant by the bit pattern of its real and imaginary parts.

func (*ConstPool) AddEllipsis added in v0.6.0

func (p *ConstPool) AddEllipsis() ConstRef

AddEllipsis returns the ConstRef for the Ellipsis singleton.

func (*ConstPool) AddFloat added in v0.6.0

func (p *ConstPool) AddFloat(v float64) ConstRef

AddFloat interns a float constant by bit pattern.

func (*ConstPool) AddInt added in v0.6.0

func (p *ConstPool) AddInt(v int64) ConstRef

AddInt interns an int constant.

func (*ConstPool) AddNone added in v0.6.0

func (p *ConstPool) AddNone() ConstRef

AddNone returns the ConstRef for None, allocating it on first use.

func (*ConstPool) AddStr added in v0.6.0

func (p *ConstPool) AddStr(s string) ConstRef

AddStr interns a string constant by content.

func (*ConstPool) AddTuple added in v0.6.0

func (p *ConstPool) AddTuple(elems []ConstRef) ConstRef

AddTuple interns a tuple constant by the sequence of ConstRefs.

func (*ConstPool) Get added in v0.6.0

func (p *ConstPool) Get(r ConstRef) Const

Get returns the Const at r.

func (*ConstPool) Len added in v0.6.0

func (p *ConstPool) Len() int

Len returns the number of entries in the pool.

func (*ConstPool) Slice added in v0.6.0

func (p *ConstPool) Slice() []Const

Slice returns a defensive copy of the pool in insertion order.

type ConstRef added in v0.6.0

type ConstRef uint32

ConstRef indexes into a ConstPool.

type ConstTuple

type ConstTuple []any

ConstTuple represents a Python tuple constant stored inside a code object's co_consts. Distinct from []any (which the marshal package uses for the co_consts slice itself) so the marshal writer can tell the two apart and emit a nested TYPE_SMALL_TUPLE correctly.

Example: `x = ()` puts ConstTuple{} at consts[1] and None at consts[0].

type DefaultInfo added in v0.5.8

type DefaultInfo struct {
	Line     int  // source line of the default value expression
	ColStart byte // start column
	ColEnd   byte // end column (exclusive)
}

DefaultInfo describes one Name-default-parameter load in a funcdef.

type EllipsisType

type EllipsisType struct{}

Ellipsis is the gocopy sentinel for Python's `Ellipsis` singleton (the value of the `...` literal). Go has no built-in equivalent and `nil` is already taken by `None`, so we use a private named type with a single exported value. Equality (`v == bytecode.Ellipsis`) works because `EllipsisType` is comparable.

The marshal layer emits this sentinel as the single byte `TYPE_ELLIPSIS` (0x2e) with no FLAG_REF (CPython treats Ellipsis as a built-in singleton).

type FrozenSetSeqStmt

type FrozenSetSeqStmt struct {
	Line         int  // 1-indexed source line
	TargetLen    byte // byte length of the assignment target name
	FrozensetCol byte // column of 'f' in 'frozenset'
	ArgCol       byte // column of first char of the arg name
	ArgLen       byte // byte length of the arg name
}

FrozenSetSeqStmt describes one frozenset(arg).__contains__ statement in a multi-statement sequence for linetable generation.

type IfBranch

type IfBranch struct {
	CondIdx byte // index of condition name in co_names
	BodyVal byte // small-int value for LOAD_SMALL_INT in the true body
	VarIdx  byte // index of variable name in co_names
}

IfBranch describes one condition+body pair in an if/elif/else chain. Used by IfElseBytecode.

type IfBranchLT

type IfBranchLT struct {
	CondLine int
	CondCol  byte
	CondEnd  byte
	BodyLine int
	ValCol   byte // column of the integer literal in the body
	ValEnd   byte // column after the integer literal
	VarCol   byte // column of the variable name in the body
	VarEnd   byte // column after the variable name
}

IfBranchLT describes one condition+body pair's source positions for line-table generation.

type ImportAlias

type ImportAlias struct {
	Name   string
	Asname string // empty = same as Name; local binding name
}

ImportAlias is one (name, asname) pair in an import statement.

type ImportEntry

type ImportEntry struct {
	Line   int
	EndCol byte
	IsFrom bool
	// IsFrom=false: simple import
	Module string // full module name (e.g., "os", "os.path")
	Asname string // local alias; empty = top-level component of Module
	// IsFrom=true: from-import
	FromMod string
	Level   int           // 0=absolute
	Aliases []ImportAlias // imported names, in order
}

ImportEntry is one import or from-import statement.

func (*ImportEntry) LocalName

func (e *ImportEntry) LocalName() string

LocalName returns the local binding name for a simple import entry.

type ImportNameRef

type ImportNameRef struct {
	ModuleIdx byte
	StoreIdx  byte // for simple import
	AliasIdxs []AliasNameRef
}

ImportNameRef holds pre-computed co_names indices for one import entry.

type LargeListElt

type LargeListElt struct {
	Line     int  // 1-indexed source line of the element
	StartCol byte // column of the opening quote
	EndCol   byte // exclusive end column (after closing quote)
}

LargeListElt describes one element of a large (n≥31) all-string-constant list.

type Loc added in v0.6.0

type Loc struct {
	Line    uint32
	EndLine uint32
	Col     uint16
	EndCol  uint16
}

Loc is a source-code location range. It mirrors the 4-tuple shape CPython exposes via PyCode_Addr2Location and code.co_positions(): (start_line, end_line, start_col, end_col).

Lines are 1-based when valid; line 0 means "no source position". Columns are 0-based byte offsets, or 0xFFFF for "no column".

Line numbers use uint32 to match CPython's PyCodeObject layout in 3.14, where line numbers are stored as 32-bit ints. Columns use uint16 so the struct stays 16 bytes; CPython's line-table format caps the encodable column at 2047 anyway.

func (Loc) IsZero added in v0.6.0

func (l Loc) IsZero() bool

IsZero reports whether all fields are zero.

func (Loc) OneLine added in v0.6.0

func (l Loc) OneLine() bool

OneLine reports whether the start and end line are the same and the location is valid.

func (Loc) Valid added in v0.6.0

func (l Loc) Valid() bool

Valid reports whether the location has a real source line. CPython treats line 0 as "no source information".

type MixedModuleInfo added in v0.5.7

type MixedModuleInfo struct {
	HasDocstring bool
	DocLine      int
	DocEndLine   int
	DocEndCol    byte

	HasStarImport    bool
	StarImportLine   int
	StarImportEndCol byte

	HasCLC       bool
	CLCLine      int
	CLCCloseLine int
	CLCOpenCol   byte
	CLCCloseEnd  byte
	CLCTargetLen byte

	Assigns []AssignInfo
	Funcs   []MultiFuncDefEntry
}

MixedModuleInfo describes a mixed module: optional docstring, optional star import, optional constLitColl (__all__), folded BinOp assignments, and function definitions.

type MultiFuncDefEntry added in v0.5.1

type MultiFuncDefEntry struct {
	DefLine     int
	BodyEndLine int
	BodyEndCol  byte
	Defaults    []DefaultInfo // Name defaults; nil/empty = no defaults
}

MultiFuncDefEntry describes one function definition within a modMultiFuncDef module.

type NoOpStmt

type NoOpStmt struct {
	Line   int
	EndCol byte
}

NoOpStmt describes one no-op statement's source position. Line is 1-indexed; EndCol is the 0-indexed exclusive end column (i.e. the length of the statement text on its line).

type OpFlags added in v0.6.0

type OpFlags uint8

OpFlags is a bitset of opcode-level booleans.

const (
	// OpJump is set on any opcode that can transfer control to a
	// non-fallthrough target (forward, backward, conditional, or
	// absolute).
	OpJump OpFlags = 1 << iota
	// OpTerminator ends a basic block: control does not fall through
	// to the next instruction (RETURN_VALUE, JUMP_FORWARD,
	// JUMP_BACKWARD).
	OpTerminator
	// OpPseudo is set on placeholder opcodes that codegen uses but
	// the assembler resolves before emission.
	OpPseudo
)

type OpMeta added in v0.6.0

type OpMeta struct {
	Name      string
	HasArg    bool
	CacheSize uint8
	ArgKind   ArgKind
	Flags     OpFlags
	StackEff  int8
	StackVar  bool
}

OpMeta describes one opcode's contract.

  • Name matches CPython's opcode.opname[op].
  • HasArg matches dis._inst_has_arg(op).
  • CacheSize matches CPython's _PyOpcode_Caches[op].
  • ArgKind groups opcodes by what their oparg means.
  • Flags carries jump/terminator/pseudo bits.
  • StackEff is the net stack delta for fixed-effect opcodes.
  • StackVar is true when the effect depends on the oparg (CALL n, BUILD_TUPLE n, etc.).

func MetaOf added in v0.6.0

func MetaOf(op Opcode) OpMeta

MetaOf returns the OpMeta for op. The zero OpMeta means the entry is not yet populated; callers should treat that as "unknown opcode" and back off.

type Opcode

type Opcode uint8

Opcode is a single CPython 3.14 opcode byte.

const (
	END_FOR                           Opcode = 9
	MAKE_FUNCTION                     Opcode = 23
	NOP                               Opcode = 27
	NOT_TAKEN                         Opcode = 28
	POP_ITER                          Opcode = 30
	POP_TOP                           Opcode = 31
	PUSH_NULL                         Opcode = 33
	RETURN_VALUE                      Opcode = 35
	STORE_SUBSCR                      Opcode = 38
	TO_BOOL                           Opcode = 39
	UNARY_INVERT                      Opcode = 40
	UNARY_NEGATIVE                    Opcode = 41
	UNARY_NOT                         Opcode = 42
	GET_ITER                          Opcode = 16
	BINARY_OP                         Opcode = 44
	BUILD_LIST                        Opcode = 46
	BUILD_MAP                         Opcode = 47
	BUILD_SET                         Opcode = 48
	BUILD_TUPLE                       Opcode = 51
	CALL                              Opcode = 52
	CALL_INTRINSIC_1                  Opcode = 53
	COMPARE_OP                        Opcode = 56
	CONTAINS_OP                       Opcode = 57
	COPY_FREE_VARS                    Opcode = 60
	COPY                              Opcode = 59
	FOR_ITER                          Opcode = 70
	IMPORT_FROM                       Opcode = 72
	IMPORT_NAME                       Opcode = 73
	IS_OP                             Opcode = 74
	JUMP_BACKWARD                     Opcode = 75
	JUMP_FORWARD                      Opcode = 77
	LIST_APPEND                       Opcode = 78
	LIST_EXTEND                       Opcode = 79
	LOAD_ATTR                         Opcode = 80
	LOAD_COMMON_CONSTANT              Opcode = 81
	LOAD_CONST                        Opcode = 82
	LOAD_DEREF                        Opcode = 83
	LOAD_FAST                         Opcode = 84
	LOAD_FAST_BORROW                  Opcode = 86
	LOAD_FAST_BORROW_LOAD_FAST_BORROW Opcode = 87
	LOAD_FAST_LOAD_FAST               Opcode = 89
	LOAD_GLOBAL                       Opcode = 92
	LOAD_NAME                         Opcode = 93
	MAKE_CELL                         Opcode = 97
	LOAD_SMALL_INT                    Opcode = 94
	POP_JUMP_IF_FALSE                 Opcode = 100
	POP_JUMP_IF_NONE                  Opcode = 101
	POP_JUMP_IF_NOT_NONE              Opcode = 102
	POP_JUMP_IF_TRUE                  Opcode = 103
	RAISE_VARARGS                     Opcode = 104
	SET_FUNCTION_ATTRIBUTE            Opcode = 108
	STORE_NAME                        Opcode = 116
	STORE_ATTR                        Opcode = 110
	STORE_FAST                        Opcode = 112
	STORE_FAST_LOAD_FAST              Opcode = 113
	STORE_FAST_STORE_FAST             Opcode = 114
	STORE_DEREF                       Opcode = 111
	STORE_GLOBAL                      Opcode = 115
	RESUME                            Opcode = 128
)

CPython 3.14 opcode numbers. Only the opcodes the current gocopy version actually emits are listed here; subsequent versions add the rest as needed.

SOURCE: github.com/tamnd/goipy/op/opcodes.go (run `go generate ./op` in goipy to regenerate from upstream).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL