diff --git a/crates/compiler-core/src/bytecode/instruction.rs b/crates/compiler-core/src/bytecode/instruction.rs index aab176de62a..079d7963259 100644 --- a/crates/compiler-core/src/bytecode/instruction.rs +++ b/crates/compiler-core/src/bytecode/instruction.rs @@ -614,23 +614,15 @@ impl Instruction { /// Map a specialized opcode back to its adaptive (base) variant. /// `_PyOpcode_Deopt` pub const fn deopt(self) -> Option { - Some(match self { - // RESUME specializations - Self::ResumeCheck => Self::Resume { - context: Arg::marker(), - }, - // LOAD_CONST specializations - Self::LoadConstMortal | Self::LoadConstImmortal => Self::LoadConst { - consti: Arg::marker(), - }, - // TO_BOOL specializations + let opcode = match self { + Self::ResumeCheck => Opcode::Resume, + Self::LoadConstMortal | Self::LoadConstImmortal => Opcode::LoadConst, Self::ToBoolAlwaysTrue | Self::ToBoolBool | Self::ToBoolInt | Self::ToBoolList | Self::ToBoolNone - | Self::ToBoolStr => Self::ToBool, - // BINARY_OP specializations + | Self::ToBoolStr => Opcode::ToBool, Self::BinaryOpMultiplyInt | Self::BinaryOpAddInt | Self::BinaryOpSubtractInt @@ -645,34 +637,18 @@ impl Instruction { | Self::BinaryOpSubscrDict | Self::BinaryOpSubscrGetitem | Self::BinaryOpExtend - | Self::BinaryOpInplaceAddUnicode => Self::BinaryOp { op: Arg::marker() }, - // STORE_SUBSCR specializations - Self::StoreSubscrDict | Self::StoreSubscrListInt => Self::StoreSubscr, - // SEND specializations - Self::SendGen => Self::Send { - delta: Arg::marker(), - }, - // UNPACK_SEQUENCE specializations + | Self::BinaryOpInplaceAddUnicode => Opcode::BinaryOp, + Self::StoreSubscrDict | Self::StoreSubscrListInt => Opcode::StoreSubscr, + Self::SendGen => Opcode::Send, Self::UnpackSequenceTwoTuple | Self::UnpackSequenceTuple | Self::UnpackSequenceList => { - Self::UnpackSequence { - count: Arg::marker(), - } + Opcode::UnpackSequence } - // STORE_ATTR specializations + Self::StoreAttrInstanceValue | Self::StoreAttrSlot | Self::StoreAttrWithHint => { - Self::StoreAttr { - namei: Arg::marker(), - } + Opcode::StoreAttr } - // LOAD_GLOBAL specializations - Self::LoadGlobalModule | Self::LoadGlobalBuiltin => Self::LoadGlobal { - namei: Arg::marker(), - }, - // LOAD_SUPER_ATTR specializations - Self::LoadSuperAttrAttr | Self::LoadSuperAttrMethod => Self::LoadSuperAttr { - namei: Arg::marker(), - }, - // LOAD_ATTR specializations + Self::LoadGlobalModule | Self::LoadGlobalBuiltin => Opcode::LoadGlobal, + Self::LoadSuperAttrAttr | Self::LoadSuperAttrMethod => Opcode::LoadSuperAttr, Self::LoadAttrInstanceValue | Self::LoadAttrModule | Self::LoadAttrWithHint @@ -685,28 +661,13 @@ impl Instruction { | Self::LoadAttrMethodNoDict | Self::LoadAttrMethodLazyDict | Self::LoadAttrNondescriptorWithValues - | Self::LoadAttrNondescriptorNoDict => Self::LoadAttr { - namei: Arg::marker(), - }, - // COMPARE_OP specializations - Self::CompareOpFloat | Self::CompareOpInt | Self::CompareOpStr => Self::CompareOp { - opname: Arg::marker(), - }, - // CONTAINS_OP specializations - Self::ContainsOpSet | Self::ContainsOpDict => Self::ContainsOp { - invert: Arg::marker(), - }, - // JUMP_BACKWARD specializations - Self::JumpBackwardNoJit | Self::JumpBackwardJit => Self::JumpBackward { - delta: Arg::marker(), - }, - // FOR_ITER specializations + | Self::LoadAttrNondescriptorNoDict => Opcode::LoadAttr, + Self::CompareOpFloat | Self::CompareOpInt | Self::CompareOpStr => Opcode::CompareOp, + Self::ContainsOpSet | Self::ContainsOpDict => Opcode::ContainsOp, + Self::JumpBackwardNoJit | Self::JumpBackwardJit => Opcode::JumpBackward, Self::ForIterList | Self::ForIterTuple | Self::ForIterRange | Self::ForIterGen => { - Self::ForIter { - delta: Arg::marker(), - } + Opcode::ForIter } - // CALL specializations Self::CallBoundMethodExactArgs | Self::CallPyExactArgs | Self::CallType1 @@ -726,15 +687,12 @@ impl Instruction { | Self::CallAllocAndEnterInit | Self::CallPyGeneral | Self::CallBoundMethodGeneral - | Self::CallNonPyGeneral => Self::Call { - argc: Arg::marker(), - }, - // CALL_KW specializations - Self::CallKwBoundMethod | Self::CallKwPy | Self::CallKwNonPy => Self::CallKw { - argc: Arg::marker(), - }, + | Self::CallNonPyGeneral => Opcode::Call, + Self::CallKwBoundMethod | Self::CallKwPy | Self::CallKwNonPy => Opcode::CallKw, _ => return None, - }) + }; + + Some(opcode.as_instruction()) } /// Map a specialized or instrumented opcode back to its adaptive (base) variant. diff --git a/scripts/generate_opcode_metadata.py b/scripts/generate_opcode_metadata.py index f16759ec87a..2758f0b982a 100644 --- a/scripts/generate_opcode_metadata.py +++ b/scripts/generate_opcode_metadata.py @@ -85,48 +85,44 @@ def extract_enum_body(text: str, name: str) -> str: return text[start + 1 : i] -def build_deopts(contents: str) -> dict[str, list[str]]: - raw_body = re.search( - r"fn deopt\(self\) -> Option(.*)", contents, re.DOTALL - ).group(1) - body = "\n".join( - itertools.takewhile( - lambda l: not l.startswith("_ =>"), # Take until reaching fallback - filter( - lambda l: ( - not l.startswith( - ("//", "Some(match") - ) # Skip comments or start of match - ), - map(str.strip, raw_body.splitlines()), - ), - ) - ).removeprefix("{") +def build_deopts(text: str) -> dict[str, list[str]]: + raw_body = re.search(r"fn deopt\(self\)(.*)", text, re.DOTALL).group(1) + match_start = raw_body.find("match self") + if match_start == -1: + raise ValueError("Could not detect a match statement in deopt method") - depth = 0 - arms = [] - buf = [] - for char in body: - if char == "{": - depth += 1 - elif char == "}": - depth -= 1 + brace_depth = 0 + block_start = None + block_end = None - if depth == 0 and (char in ("}", ",")): - arm = "".join(buf).strip() - arms.append(arm) - buf = [] - else: - buf.append(char) + for i, ch in enumerate(raw_body[match_start:], match_start): + if ch == "{": + brace_depth += 1 + if block_start is None: + block_start = i + 1 + elif ch == "}": + brace_depth -= 1 + if brace_depth == 0: + block_end = i + break + + match_body = raw_body[block_start:block_end] - # last arm - arms.append("".join(buf)) - arms = [arm for arm in arms if arm] + arm_pattern = re.compile( + r"((?:Self::\w+\s*\|\s*)*Self::\w+)\s*=>\s*(?:\{\s*)?Opcode::(\w+)", re.DOTALL + ) + variants_pattern = re.compile(r"Self::(\w+)") deopts = {} - for arm in arms: - *specialized, deopt = map(to_snake_case, re.findall(r"Self::(\w*)\b", arm)) - deopts[deopt] = specialized + for hit in arm_pattern.finditer(match_body): + raw_variants = hit.group(1) + opcode = hit.group(2) + + variants = variants_pattern.findall(raw_variants) + + key = to_snake_case(opcode) + value = [to_snake_case(variant) for variant in variants] + deopts[key] = value return deopts