res = Py_IsFalse(value) ? Py_True : Py_False;
}
- family(to_bool, INLINE_CACHE_ENTRIES_TO_BOOL) = {
- TO_BOOL,
+ family(TO_BOOL, INLINE_CACHE_ENTRIES_TO_BOOL) = {
TO_BOOL_ALWAYS_TRUE,
TO_BOOL_BOOL,
TO_BOOL_INT,
ERROR_IF(res == NULL, error);
}
- family(binary_op, INLINE_CACHE_ENTRIES_BINARY_OP) = {
- BINARY_OP,
+ family(BINARY_OP, INLINE_CACHE_ENTRIES_BINARY_OP) = {
BINARY_OP_MULTIPLY_INT,
BINARY_OP_ADD_INT,
BINARY_OP_SUBTRACT_INT,
macro(BINARY_OP_INPLACE_ADD_UNICODE) =
_GUARD_BOTH_UNICODE + _BINARY_OP_INPLACE_ADD_UNICODE;
- family(binary_subscr, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
- BINARY_SUBSCR,
+ family(BINARY_SUBSCR, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = {
BINARY_SUBSCR_DICT,
BINARY_SUBSCR_GETITEM,
BINARY_SUBSCR_LIST_INT,
ERROR_IF(err, error);
}
- family(store_subscr, INLINE_CACHE_ENTRIES_STORE_SUBSCR) = {
- STORE_SUBSCR,
+ family(STORE_SUBSCR, INLINE_CACHE_ENTRIES_STORE_SUBSCR) = {
STORE_SUBSCR_DICT,
STORE_SUBSCR_LIST_INT,
};
ERROR_IF(iter == NULL, error);
}
- family(send, INLINE_CACHE_ENTRIES_SEND) = {
- SEND,
+ family(SEND, INLINE_CACHE_ENTRIES_SEND) = {
SEND_GEN,
};
}
}
- family(unpack_sequence, INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE) = {
- UNPACK_SEQUENCE,
+ family(UNPACK_SEQUENCE, INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE) = {
UNPACK_SEQUENCE_TWO_TUPLE,
UNPACK_SEQUENCE_TUPLE,
UNPACK_SEQUENCE_LIST,
ERROR_IF(res == 0, error);
}
- family(store_attr, INLINE_CACHE_ENTRIES_STORE_ATTR) = {
- STORE_ATTR,
+ family(STORE_ATTR, INLINE_CACHE_ENTRIES_STORE_ATTR) = {
STORE_ATTR_INSTANCE_VALUE,
STORE_ATTR_SLOT,
STORE_ATTR_WITH_HINT,
macro(LOAD_FROM_DICT_OR_GLOBALS) = _LOAD_FROM_DICT_OR_GLOBALS;
- family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = {
- LOAD_GLOBAL,
+ family(LOAD_GLOBAL, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = {
LOAD_GLOBAL_MODULE,
LOAD_GLOBAL_BUILTIN,
};
GO_TO_INSTRUCTION(LOAD_SUPER_ATTR);
}
- family(load_super_attr, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
- LOAD_SUPER_ATTR,
+ family(LOAD_SUPER_ATTR, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = {
LOAD_SUPER_ATTR_ATTR,
LOAD_SUPER_ATTR_METHOD,
};
}
}
- family(load_attr, INLINE_CACHE_ENTRIES_LOAD_ATTR) = {
- LOAD_ATTR,
+ family(LOAD_ATTR, INLINE_CACHE_ENTRIES_LOAD_ATTR) = {
LOAD_ATTR_INSTANCE_VALUE,
LOAD_ATTR_MODULE,
LOAD_ATTR_WITH_HINT,
Py_DECREF(owner);
}
- family(compare_op, INLINE_CACHE_ENTRIES_COMPARE_OP) = {
- COMPARE_OP,
+ family(COMPARE_OP, INLINE_CACHE_ENTRIES_COMPARE_OP) = {
COMPARE_OP_FLOAT,
COMPARE_OP_INT,
COMPARE_OP_STR,
// This is optimized by skipping that instruction and combining
// its effect (popping 'iter' instead of pushing 'next'.)
- family(for_iter, INLINE_CACHE_ENTRIES_FOR_ITER) = {
- FOR_ITER,
+ family(FOR_ITER, INLINE_CACHE_ENTRIES_FOR_ITER) = {
FOR_ITER_LIST,
FOR_ITER_TUPLE,
FOR_ITER_RANGE,
// Cache layout: counter/1, func_version/2
// Neither CALL_INTRINSIC_1/2 nor CALL_FUNCTION_EX are members!
- family(call, INLINE_CACHE_ENTRIES_CALL) = {
- CALL,
+ family(CALL, INLINE_CACHE_ENTRIES_CALL) = {
CALL_BOUND_METHOD_EXACT_ARGS,
CALL_PY_EXACT_ARGS,
CALL_PY_WITH_DEFAULTS,
"""Write one instruction, sans prologue and epilogue."""
# Write a static assertion that a family's cache size is correct
if family := self.family:
- if self.name == family.members[0]:
+ if self.name == family.name:
if cache_size := family.size:
out.emit(
f"static_assert({cache_size} == "
def map_families(self) -> None:
"""Link instruction names back to their family, if they have one."""
for family in self.families.values():
- for member in family.members:
+ for member in [family.name] + family.members:
if member_instr := self.instrs.get(member):
if member_instr.family not in (family, None):
self.error(
- All members must have the same cache, input and output effects
"""
for family in self.families.values():
- if len(family.members) < 2:
- self.error(f"Family {family.name!r} has insufficient members", family)
+ if family.name not in self.macro_instrs and family.name not in self.instrs:
+ self.error(
+ f"Family {family.name!r} has unknown instruction {family.name!r}",
+ family,
+ )
members = [
member
for member in family.members
self.error(
f"Family {family.name!r} has unknown members: {unknown}", family
)
- if len(members) < 2:
- continue
- expected_effects = self.effect_counts(members[0])
- for member in members[1:]:
+ expected_effects = self.effect_counts(family.name)
+ for member in members:
member_effects = self.effect_counts(member)
if member_effects != expected_effects:
self.error(
self.out.emit("")
self.out.emit("_specializations = {")
for name, family in self.families.items():
- assert len(family.members) > 1
with self.out.indent():
- self.out.emit(f"\"{family.members[0]}\": [")
+ self.out.emit(f"\"{family.name}\": [")
with self.out.indent():
- for m in family.members[1:]:
+ for m in family.members:
self.out.emit(f"\"{m}\",")
self.out.emit(f"],")
self.out.emit("}")
self.out.emit(f"next_instr += {cache_adjust};")
if (
- last_instr
- and (family := last_instr.family)
- and mac.name == family.members[0]
+ (family := self.families.get(mac.name))
+ and mac.name == family.name
and (cache_size := family.size)
):
self.out.emit(