mirror of
https://github.com/esphome/esphome.git
synced 2026-09-22 20:48:43 +00:00
Merge branch 'inline-varint-parse-fast-path' into integration
This commit is contained in:
@@ -461,7 +461,7 @@ class FloatType(TypeInfo):
|
||||
class Int64Type(TypeInfo):
|
||||
cpp_type = "int64_t"
|
||||
default_value = "0"
|
||||
decode_varint = "value.as_int64()"
|
||||
decode_varint = "static_cast<int64_t>(value)"
|
||||
encode_func = "encode_int64"
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
|
||||
@@ -481,7 +481,7 @@ class Int64Type(TypeInfo):
|
||||
class UInt64Type(TypeInfo):
|
||||
cpp_type = "uint64_t"
|
||||
default_value = "0"
|
||||
decode_varint = "value.as_uint64()"
|
||||
decode_varint = "value"
|
||||
encode_func = "encode_uint64"
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
|
||||
@@ -501,7 +501,7 @@ class UInt64Type(TypeInfo):
|
||||
class Int32Type(TypeInfo):
|
||||
cpp_type = "int32_t"
|
||||
default_value = "0"
|
||||
decode_varint = "value.as_int32()"
|
||||
decode_varint = "static_cast<int32_t>(value)"
|
||||
encode_func = "encode_int32"
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
|
||||
@@ -573,7 +573,7 @@ class Fixed32Type(TypeInfo):
|
||||
class BoolType(TypeInfo):
|
||||
cpp_type = "bool"
|
||||
default_value = "false"
|
||||
decode_varint = "value.as_bool()"
|
||||
decode_varint = "value != 0"
|
||||
encode_func = "encode_bool"
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
|
||||
@@ -1151,7 +1151,7 @@ class FixedArrayBytesType(TypeInfo):
|
||||
class UInt32Type(TypeInfo):
|
||||
cpp_type = "uint32_t"
|
||||
default_value = "0"
|
||||
decode_varint = "value.as_uint32()"
|
||||
decode_varint = "value"
|
||||
encode_func = "encode_uint32"
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
|
||||
@@ -1175,7 +1175,7 @@ class EnumType(TypeInfo):
|
||||
|
||||
@property
|
||||
def decode_varint(self) -> str:
|
||||
return f"static_cast<{self.cpp_type}>(value.as_uint32())"
|
||||
return f"static_cast<{self.cpp_type}>(value)"
|
||||
|
||||
default_value = ""
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
@@ -1262,7 +1262,7 @@ class SFixed64Type(TypeInfo):
|
||||
class SInt32Type(TypeInfo):
|
||||
cpp_type = "int32_t"
|
||||
default_value = "0"
|
||||
decode_varint = "value.as_sint32()"
|
||||
decode_varint = "decode_zigzag32(value)"
|
||||
encode_func = "encode_sint32"
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
|
||||
@@ -1282,7 +1282,7 @@ class SInt32Type(TypeInfo):
|
||||
class SInt64Type(TypeInfo):
|
||||
cpp_type = "int64_t"
|
||||
default_value = "0"
|
||||
decode_varint = "value.as_sint64()"
|
||||
decode_varint = "decode_zigzag64(value)"
|
||||
encode_func = "encode_sint64"
|
||||
wire_type = WireType.VARINT # Uses wire type 0
|
||||
|
||||
@@ -2205,7 +2205,7 @@ def build_message_type(
|
||||
|
||||
cpp = ""
|
||||
if decode_varint:
|
||||
o = f"bool {desc.name}::decode_varint(uint32_t field_id, ProtoVarInt value) {{\n"
|
||||
o = f"bool {desc.name}::decode_varint(uint32_t field_id, proto_varint_value_t value) {{\n"
|
||||
o += " switch (field_id) {\n"
|
||||
o += indent("\n".join(decode_varint), " ") + "\n"
|
||||
o += " default: return false;\n"
|
||||
@@ -2213,7 +2213,7 @@ def build_message_type(
|
||||
o += " return true;\n"
|
||||
o += "}\n"
|
||||
cpp += o
|
||||
prot = "bool decode_varint(uint32_t field_id, ProtoVarInt value) override;"
|
||||
prot = "bool decode_varint(uint32_t field_id, proto_varint_value_t value) override;"
|
||||
protected_content.insert(0, prot)
|
||||
if decode_length:
|
||||
o = f"bool {desc.name}::decode_length(uint32_t field_id, ProtoLengthDelimited value) {{\n"
|
||||
|
||||
+1
-1
@@ -519,7 +519,7 @@ def lint_constants_usage():
|
||||
continue
|
||||
errs.append(
|
||||
f"Constant {highlight(constant)} is defined in {len(uses)} files. Please move all definitions of the "
|
||||
f"constant to const.py (Uses: {', '.join(str(u) for u in uses)}) in a separate PR. "
|
||||
f"constant to esphome/components/const/__init__.py (Uses: {', '.join(str(u) for u in uses)}) in a separate PR. "
|
||||
"See https://developers.esphome.io/contributing/code/#python"
|
||||
)
|
||||
return errs
|
||||
|
||||
@@ -160,6 +160,76 @@ def format_change(before: int, after: int, threshold: float | None = None) -> st
|
||||
return f"{emoji} {delta_str} ({pct_str})"
|
||||
|
||||
|
||||
def _sig_base(sym: str) -> str:
|
||||
"""Strip argument types from a symbol name for fuzzy matching.
|
||||
|
||||
Removes the entire outermost parenthesized argument list (including
|
||||
the parentheses) from the symbol string.
|
||||
|
||||
This makes, for example, "foo(int)::nested" and "foo(float)::nested"
|
||||
share the same key "foo::nested", while "foo(int)" maps to "foo" and
|
||||
therefore does NOT collide with "foo(int)::nested".
|
||||
"""
|
||||
start = sym.find("(")
|
||||
if start == -1:
|
||||
return sym
|
||||
end = sym.rfind(")")
|
||||
if end == -1:
|
||||
return sym
|
||||
return sym[:start] + sym[end + 1 :]
|
||||
|
||||
|
||||
_AMBIGUOUS = object()
|
||||
|
||||
|
||||
def _match_signature_changes(
|
||||
changed_symbols: list[tuple[str, int, int, int]],
|
||||
new_symbols: list[tuple[str, int]],
|
||||
removed_symbols: list[tuple[str, int]],
|
||||
) -> tuple[
|
||||
list[tuple[str, int, int, int]],
|
||||
list[tuple[str, int]],
|
||||
list[tuple[str, int]],
|
||||
]:
|
||||
"""Match new/removed symbol pairs that only differ in argument types.
|
||||
|
||||
When a function's argument types change (e.g. foo(vector<>&) -> foo(Buffer&)),
|
||||
it appears as a new + removed symbol. This matches them by base name and moves
|
||||
them to changed_symbols. Only matches unambiguous 1:1 pairs.
|
||||
"""
|
||||
if not new_symbols or not removed_symbols:
|
||||
return changed_symbols, new_symbols, removed_symbols
|
||||
|
||||
# Build base -> entry maps; mark ambiguous bases with sentinel
|
||||
new_by_base: dict[str, tuple[str, int] | object] = {}
|
||||
for entry in new_symbols:
|
||||
base = _sig_base(entry[0])
|
||||
new_by_base[base] = _AMBIGUOUS if base in new_by_base else entry
|
||||
removed_by_base: dict[str, tuple[str, int] | object] = {}
|
||||
for entry in removed_symbols:
|
||||
base = _sig_base(entry[0])
|
||||
removed_by_base[base] = _AMBIGUOUS if base in removed_by_base else entry
|
||||
|
||||
matched: set[str] = set() # matched base keys
|
||||
for base, new_entry in new_by_base.items():
|
||||
if new_entry is _AMBIGUOUS:
|
||||
continue
|
||||
rem_entry = removed_by_base.get(base)
|
||||
if rem_entry is None or rem_entry is _AMBIGUOUS:
|
||||
continue
|
||||
pr_sym, pr_size = new_entry
|
||||
_rm_sym, target_size = rem_entry
|
||||
delta = pr_size - target_size
|
||||
if delta != 0:
|
||||
changed_symbols.append((pr_sym, target_size, pr_size, delta))
|
||||
matched.add(base)
|
||||
|
||||
if matched:
|
||||
new_symbols = [e for e in new_symbols if _sig_base(e[0]) not in matched]
|
||||
removed_symbols = [e for e in removed_symbols if _sig_base(e[0]) not in matched]
|
||||
return changed_symbols, new_symbols, removed_symbols
|
||||
|
||||
|
||||
def prepare_symbol_changes_data(
|
||||
target_symbols: dict | None, pr_symbols: dict | None
|
||||
) -> dict | None:
|
||||
@@ -200,6 +270,11 @@ def prepare_symbol_changes_data(
|
||||
delta = pr_size - target_size
|
||||
changed_symbols.append((symbol, target_size, pr_size, delta))
|
||||
|
||||
# Match new/removed symbols that only differ in argument types
|
||||
changed_symbols, new_symbols, removed_symbols = _match_signature_changes(
|
||||
changed_symbols, new_symbols, removed_symbols
|
||||
)
|
||||
|
||||
if not changed_symbols and not new_symbols and not removed_symbols:
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user