[Docs, Chore] (docs, tools, MobileGL, scripts, CONTRIBUTING.md, .gitignore): translate the documentation and use US spelling

This commit is contained in:
BZLZHH
2026-10-31 19:58:19 +08:00
parent 47892afddc
commit 4f50bedde0
512 changed files with 2955 additions and 2945 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ A gate whose baker is a different program from the gate has the same failure one
day the CLI's defaults and the library's diverge, the gate reds on a header nobody can
regenerate, and the fix is to edit the words by hand.
FORMATTING IS PRESERVED PER HEADER, not normalised: the headers in the tree disagree about
FORMATTING IS PRESERVED PER HEADER, not normalized: the headers in the tree disagree about
words per line and about the `u` suffix, and reformatting one of them would bury a one-word
change in a whole-file diff. The style is read back out of the array being replaced.
+5 -5
View File
@@ -224,7 +224,7 @@ def repo_relative(path, cwd):
"""normpath the -H spelling, then express it repo-relative with forward slashes.
Today's transcripts contain e.g. TextureState/../SamplerState/SamplerObject.h, which
only matches a forbidden prefix after normalisation. Anything outside the repo (the
only matches a forbidden prefix after normalization. Anything outside the repo (the
toolchain's own headers, /usr/include) is not our business and returns None.
"""
absolute = os.path.normpath(os.path.join(cwd, path))
@@ -498,7 +498,7 @@ Multiple include guards may be useful for:
def self_test_parser():
"""Check 4: the trailer paragraph is discarded and a `../` spelling normalises."""
"""Check 4: the trailer paragraph is discarded and a `../` spelling normalizes."""
problems = []
entries = parse_h_output(PARSER_CANNED_GXX, REPO_ROOT)
if len(entries) != 3:
@@ -508,14 +508,14 @@ def self_test_parser():
problems.append("depths misparsed: {}".format(depths))
normalised = entries[-1][1] if entries else None
if normalised != "MobileGL/MG_State/GLState/SamplerState/SamplerObject.h":
problems.append("`../` spelling did not normalise: {}".format(normalised))
problems.append("`../` spelling did not normalize: {}".format(normalised))
elif not find_violations(entries, PROBES[0]["Forbidden"], []):
problems.append("normalised path did not match the value-header forbidden list")
problems.append("normalized path did not match the value-header forbidden list")
if problems:
for problem in problems:
say(" self-test parser: " + problem)
return False
say(" self-test parser: trailer discarded, `../` normalised and matched")
say(" self-test parser: trailer discarded, `../` normalized and matched")
return True
+2 -2
View File
@@ -20,7 +20,7 @@ exemptions; the first is gone from the tree, and the second is compiled into the
embeds (the push monolith without MG_Remote), so it is shipped code and gets the same rule.
The rule is now "no frontend-pointer KEY in any named memo family, in any build", and nothing
else; the one allow-list entry below is a named, dated carve-out.
It does not evaluate the preprocessor - it recognises the conditional spellings the
It does not evaluate the preprocessor - it recognizes the conditional spellings the
tree actually uses - and it does not look at DirectVulkan, whose own key inventory is
P7 wave 2's.
@@ -107,7 +107,7 @@ def legacy_lines(code: str) -> set[int]:
def _retired_legacy_lines(code: str) -> set[int]:
"""The pre-W3b exemption, kept only for the self-test's record of what changed.
NOT a preprocessor. It recognises `#if MOBILEGL_PIPE_LEGACY_MEMOS`,
NOT a preprocessor. It recognizes `#if MOBILEGL_PIPE_LEGACY_MEMOS`,
`#if !MOBILEGL_BUILD_DISAGGREGATED`, and the `#else` of
`#if MOBILEGL_BUILD_DISAGGREGATED` - which is every spelling these two files use -
and treats every other conditional as transparent."""
+1 -1
View File
@@ -41,7 +41,7 @@ and integration harnesses drive the library rather than being it.
THE SITES OF THE WIDENED PERIMETER, TRIAGED. The widening found 83; the same package routed
five of them through Session::Fail and added one funnel of its own, so the floor the baseline
records is 79 over 20 files. The triage is the argument for why the gate can be green with
seventy-nine deaths inside it. The ENFORCEABLE artefact is the baseline's per-file map - this
seventy-nine deaths inside it. The ENFORCEABLE artifact is the baseline's per-file map - this
prose is why that map reads the way it does.
(i) INSIDE A SANCTIONED FUNNEL - 5 sites, and the only ones allowed to carry no marker. The
+2 -2
View File
@@ -73,7 +73,7 @@ def _list_property(test, name):
def tcp_lock_violations(document):
"""Entries of a ctest --show-only=json-v1 document that reach the loopback TCP supervisor -
FIXTURES_REQUIRED names mobilegl-tcp, or the entry is labelled exactly integration-tcp - and do
FIXTURES_REQUIRED names mobilegl-tcp, or the entry is labeled exactly integration-tcp - and do
not hold RESOURCE_LOCK mobilegl-tcp. Sorted names; empty when the registration is sound."""
bad = []
for test in document.get('tests', []):
@@ -121,7 +121,7 @@ def require_entries_passed(path, names):
`TcpLane.SupervisorProtocolControls` is registered with SKIP_RETURN_CODE 77 because the
script it runs needs flatc, which is deliberately not in the build graph. That is the right
behaviour for a developer who has not built one; it is the wrong behaviour for CI, where the
behavior for a developer who has not built one; it is the wrong behavior for CI, where the
lane's whole job is to run the supervisor's protocol controls and "skipped" is
indistinguishable from the three commits the entry did not exist. The workflow builds flatc
and then names the entry here, so a CI run in which the tool went missing reds by name
+1 -1
View File
@@ -53,7 +53,7 @@ FILES = {
}
# (file, a substring of the site's line) -> why no peer byte reaches it. The site is converted
# anyway - it is on the decode path and returns like its neighbours - and the reason names the
# anyway - it is on the decode path and returns like its neighbors - and the reason names the
# earlier check that refuses the same bytes first.
UNREACHABLE = [
("PipeWireCodec.cpp", '"segment-resolve"',
+1 -1
View File
@@ -18,7 +18,7 @@ surface as a silently absent field - the exact failure the revision was added to
This script pins the two together. protocol_revision_pins.json beside it is a table
{revision: sha256(protocol.fbs)} of the schema each revision was minted for. The check reads the
header's current revision, hashes protocol.fbs (line endings normalised, so a CRLF checkout hashes
header's current revision, hashes protocol.fbs (line endings normalized, so a CRLF checkout hashes
the same bytes as an LF one) and refuses when the current revision has no row or its row is not
the file's digest. Both directions are covered: a schema edit that forgot the bump is red (stale
row), and a bump that forgot the table is red (no row), so the table cannot fall behind the header.
+1 -1
View File
@@ -25,7 +25,7 @@ runs", not "runs inproc"), and that arm's scenario is monolith-only by construct
have a spawn counterpart, so it is named as an exception rather than allowed to widen the
tolerance for everything else.
P7 PACKAGE L ADDS THE SAME QUESTION FOR MAGMA, IN TWO TIERS, AND THE NORMALISATION IS
P7 PACKAGE L ADDS THE SAME QUESTION FOR MAGMA, IN TWO TIERS, AND THE NORMALIZATION IS
DIFFERENT ON PURPOSE. The Espryt half above strips the sub-lane tails `F1.` and `Ct.` because
they name neither the case nor the arm. The Magma half must NOT: `RunAhead.Credit1.` and
`RunAhead.Credit3.` are two entries of the same case, differing in the credit the lane pins, and
+3 -3
View File
@@ -19,7 +19,7 @@ asked about - and nothing about a green split lane says so. This asserts, per ba
after the arm and tail segments come off both sides: an entry name is `<Backend>.[<Arm>.][<tail>.]
<Suite>.<Case>`, and only the last two segments (the gtest name) are compared. `Split.F1.`,
`Spawn.ForcedDs.`, `Tcp.MultiDrawTierBaseVertex.` and the monolith's
`ForcedDepthStencilEmulation.` all normalise away.
`ForcedDepthStencilEmulation.` all normalize away.
WHAT COUNTS AS A SPLIT CASE differs by backend, on purpose:
* DirectGLES - an entry with an arm segment (Split/Spawn/Tcp/TcpDevice) that carries a GATED
@@ -33,7 +33,7 @@ WHAT COUNTS AS A SPLIT CASE differs by backend, on purpose:
WHAT COUNTS AS A MONOLITH CASE: an entry with no arm segment carrying `integration-gpu` - the label
the monolith registrations and the monolith-control mechanism entries share. That puts
`DirectGLES.PushMonolithArm.<case>` (labelled integration-split, but no arm) on the monolith side,
`DirectGLES.PushMonolithArm.<case>` (labeled integration-split, but no arm) on the monolith side,
where it belongs, and leaves build-verify's `DirectGLES.VerifySplit.<case>` (no integration-gpu)
out of both sides.
@@ -254,7 +254,7 @@ def self_test():
if got != rc or any(n not in text for n in needles) or any(n in text for n in absent):
failures.append(f"{label}: rc {got} (want {rc}); output:\n{text}")
expect("tails normalise on both sides", _doc(*BASE), "", 0,
expect("tails normalize on both sides", _doc(*BASE), "", 0,
"DirectGLES: monolith 3, on a gated split arm 3", "missing 0")
expect("a monolith case on no arm reds BY NAME",
_doc(*BASE, _entry("DirectGLES.CScenario.Five", "integration-gpu")), "", 1,
+1 -1
View File
@@ -189,7 +189,7 @@ class Accounting(unittest.TestCase):
`ctest -L integration-gpu -j 4` that entry and another Tcp case killed each other.
The stub mirrors the real json-v1 shapes: the fixture's own setup entry, a sound Tcp
case, the violator as it was registered, a Magma tcp entry that reaches the fixture
under another label, a labelled control with no fixture, and the device lane, whose
under another label, a labeled control with no fixture, and the device lane, whose
lock is its own."""
tally = module('junit_tally')
parity = module('spawn_lane_parity')
+19 -19
View File
@@ -10,7 +10,7 @@
Reads the four hand-maintained sources of truth
MobileGL/MG_Pipe/PipeCalls.def the call catalogue
MobileGL/MG_Pipe/PipeCalls.def the call catalog
MobileGL/MG_Pipe/PipeFields.def per-payload field lists for the verify comparator
MobileGL/MG_Pipe/Coverage.def accessor -> call mapping for the read inventory,
and the sticky-field list
@@ -23,13 +23,13 @@ plus the vendored copy of the backend read inventory
and writes MobileGL/MG_Pipe/generated/*.inc. The outputs are COMMITTED; CI regenerates
them and fails on a diff, which is what keeps the seven generators from drifting apart
from the catalogue (they all consume the same .def).
from the catalog (they all consume the same .def).
python3 scripts/gen_pipe.py # write the generated files, print the summary
python3 scripts/gen_pipe.py --check # fail if regenerating would change anything
python3 scripts/gen_pipe.py --self-test # the negative controls: each gate below must trip
Both modes refuse a catalogue whose call payload has no field list in PipeFields.def: a
Both modes refuse a catalog whose call payload has no field list in PipeFields.def: a
payload the G4 comparator cannot see is a payload MOBILEGL_PIPE_VERIFY is blind to. Both
also refuse a field list that does not name every data member of its struct (or names one
that is not a member), and a backend accessor read through gPipeInputs-> / pGLContext-> that
@@ -573,7 +573,7 @@ def parse_wait_classes():
this list is what the generated kMGPipeWaitClasses[] table spells into C++, and a copy
here would go stale in exactly the case that matters. kWaitClassCount is the terminator and
is NOT a class a row may carry - a row that named it would generate a table entry the
lookup uses to mean 'this opcode never came from the catalogue'."""
lookup uses to mean 'this opcode never came from the catalog'."""
text = read(os.path.join(PIPE_DIR, "MGPipe.h"))
body = WAIT_ENUM_RE.search(text)
if not body:
@@ -597,7 +597,7 @@ def check_wait_classes_are_known(calls):
compile error in one consumer.
1. The token must be an MGPipeWaitClass enumerator, and never the kWaitClassCount
terminator, which the generated lookup uses for "not from this catalogue".
terminator, which the generated lookup uses for "not from this catalog".
2. kReplySlot and kWaitReply must agree, BOTH WAYS. A reply-slot row that did not wait
would be a waiter that hangs - the client would run on and read a slot nobody had
posted into yet; a waiting row with no slot would block on an answer nobody posts.
@@ -690,7 +690,7 @@ def banner(name, title, sources):
def gen_wire_layout(calls, payloads):
"""Compiler-evaluated wire layout, including same-width member reorders."""
out = [banner("PipeWireLayout.inc", "P6.5: wire layout and ordered catalogue.",
out = [banner("PipeWireLayout.inc", "P6.5: wire layout and ordered catalog.",
"PipeFields.def and PipeCalls.def")]
out += ["struct WireLayoutMember { const char* Name; Uint64 Offset; Uint64 Size; };",
"inline constexpr WireLayoutMember kMGPipeWireLayoutMembers[] = {"]
@@ -735,12 +735,12 @@ def gen_tables(calls):
out.append("// A table that is not exactly its call count of function pointers has grown a")
out.append("// member that no generator knows about.")
out.append("static_assert(sizeof(MGPipeScreen) == kMGPipeScreenCallCount * sizeof(void (*)()),")
out.append(" \"MGPipeScreen is not exactly its catalogue's function pointers\");")
out.append(" \"MGPipeScreen is not exactly its catalog's function pointers\");")
out.append("static_assert(sizeof(MGPipeContext) == kMGPipeContextCallCount * sizeof(void (*)()),")
out.append(" \"MGPipeContext is not exactly its catalogue's function pointers\");")
out.append(" \"MGPipeContext is not exactly its catalog's function pointers\");")
out.append("static_assert(kMGPipeScreenCallCount + kMGPipeContextCallCount == kMGPipeCallCount);")
out.append("static_assert(kMGPipeCallCount == MGP_CALL_LIST_DOCUMENTED_COUNT,")
out.append(" \"the catalogue and its documented count disagree\");")
out.append(" \"the catalog and its documented count disagree\");")
return "\n".join(out) + "\n"
@@ -833,8 +833,8 @@ enum class MGPWireOp : Uint16 {
// GetCaps and CreateSamplerState came to carry an MGPBlobRef member with no kHasBlob on
// their line at all - nothing compared the two, because nothing had both in one place.
//
// Index 0 is MGPWireOp::kInvalid and is kNone: the catalogue is 1-based, and an encoder
// that reads flags for an opcode it never got from the catalogue must see the empty set
// Index 0 is MGPWireOp::kInvalid and is kNone: the catalog is 1-based, and an encoder
// that reads flags for an opcode it never got from the catalog must see the empty set
// rather than another call's flags.
//
// kHasBlob here means EXACTLY "the payload owns an MGPBlobRef member". Three calls carry
@@ -853,7 +853,7 @@ enum class MGPWireOp : Uint16 {
out.append(" \"the flags table and the opcode space disagree\");")
out.append("""
// The only supported read of the table. Out-of-range is kNone rather than undefined
// behaviour, because the one caller that can pass a bad opcode is a decoder holding bytes
// behavior, because the one caller that can pass a bad opcode is a decoder holding bytes
// off a stream, and it must reach its own Fatal{ProtocolCorruption} rather than read past
// the array on the way there.
inline constexpr Uint32 MGPipeCallFlagsFor(MGPWireOp op) {
@@ -862,7 +862,7 @@ inline constexpr Uint32 MGPipeCallFlagsFor(MGPWireOp op) {
: static_cast<Uint32>(kNone);
}
// The catalogue class of every opcode, indexed the same way; index 0 is kCallClassCount,
// The catalog class of every opcode, indexed the same way; index 0 is kCallClassCount,
// never a real class, for the flags table's reason.
inline constexpr Uint8 kMGPipeCallClasses[static_cast<SizeT>(MGPWireOp::kOpCount)] = {
/* 0 */ static_cast<Uint8>(kCallClassCount),
@@ -883,7 +883,7 @@ inline constexpr MGPipeCallClass MGPipeCallClassFor(MGPWireOp op) {
// P5e (2.2): THE WAIT CLASS OF EVERY OPCODE, indexed the same way.
// Index 0 is kWaitClassCount - never a real class - for the flags table's reason: the one
// caller that can pass an opcode this catalogue never produced is a decoder holding bytes off
// caller that can pass an opcode this catalog never produced is a decoder holding bytes off
// a stream, and it must reach its own Fatal{ProtocolCorruption} rather than a wait decision.
//
// This is the STATIC HALF of MGPipeBarriered(op, payload, applierState), the predicate the emit
@@ -908,7 +908,7 @@ inline constexpr MGPipeWaitClass MGPipeWaitClassFor(MGPWireOp op) {
}
// THE COLUMN'S OWN INVARIANT, stated in C++ as well as in the generator: a reply-slot row
// waits for its reply and a waiting row owns a slot. gen_pipe.py refuses a catalogue where the
// waits for its reply and a waiting row owns a slot. gen_pipe.py refuses a catalog where the
// two disagree, and this is the same statement where a reader of the generated table will look
// for it - a kReplySlot row that did not wait would run on and read a slot nobody had posted
// into, and a kWaitReply row with no slot would block on an answer nobody posts.
@@ -923,7 +923,7 @@ static_assert(MGPipeWaitClassFor(MGPWireOp::ApplierReset) == kWaitApplied,
static_assert(MGPipeWaitClassFor(MGPWireOp::ReadPixels) == kWaitReply,
"a readback's answer is not derivable (R-5)");
// Spot checks the generator states about its own output, so that a catalogue edit that
// Spot checks the generator states about its own output, so that a catalog edit that
// silently drops a flag is a build break here and not a wrong decode six packages away.
static_assert(MGPipeCallFlagsFor(MGPWireOp::kInvalid) == static_cast<Uint32>(kNone),
"opcode 0 is not a call and carries no flags");
@@ -1011,9 +1011,9 @@ inline MGPipeWireRecordApplyFn gMGPipeWireRecordApply = nullptr;
// record's own count fields and require it to EQUAL MGPWireRecHeader::Size - belongs to the
// decoder, which has the payload (MG_Remote/Wire's MGPipeWireRecordLayout, P5 w1).
//
// The switch and the opcode enum come from the same list, so a call added to the catalogue
// The switch and the opcode enum come from the same list, so a call added to the catalog
// cannot be forgotten here; the default arm is for the opcode that never came from this
// catalogue at all - a byte off a corrupt stream - and it is fatal for the same reason the
// catalog at all - a byte off a corrupt stream - and it is fatal for the same reason the
// bounds check is.
//
// With no decoder installed - every monolith build, and a split build before
@@ -1661,7 +1661,7 @@ def self_test(accessors):
# The positive control: the canned struct's exact list passes, and the parser sees the
# padding member as padding and the function as not a member.
check_field_lists_cover_struct_members({"Canned": ["A", "B", "C"]}, ["Canned"], [canned_struct])
# ... and the real catalogue's real flags and wait classes pass the same gates.
# ... and the real catalog's real flags and wait classes pass the same gates.
check_call_flags_are_known(calls_for_control)
check_wait_classes_are_known(calls_for_control)
if trips == 0:
+14 -14
View File
@@ -343,7 +343,7 @@ def render_state_publishers():
# not read. What it models is written down here, and what it does not model taints the
# function it is in, which turns every answer depending on that function into UNDECIDED:
#
# modelled ++m_x / m_x = / m_x op= (a whole-member write: MEM:m_x, FIELD:m_x.*); a write
# modeled ++m_x / m_x = / m_x op= (a whole-member write: MEM:m_x, FIELD:m_x.*); a write
# through a member-rooted lvalue (m_x.f, m_x[i].f, m_x->f, nested), which records
# MEM:m_x and FIELD:m_x.f - the first field below the member, deeper paths
# collapse to it, because that is the granularity the shutter reads at; a
@@ -356,7 +356,7 @@ def render_state_publishers():
# memcpy/memset/memmove/swap whose destination is one, all credited as a whole
# write of that lvalue - a read-only call is over-credited, which only WIDENS the
# writer side; a write to a value local, a by-value parameter or an aggregate
# initialiser's `.f = v`, which touch no member; a write through a const alias
# initializer's `.f = v`, which touch no member; a write through a const alias
# with `.` or through a const raw pointer, which the language forbids - but `->`
# through a const REFERENCE may be a smart pointer's and is NOT taken as
# read-only; MGP_NOTE_AGGREGATE; a call to any function whose body is under the
@@ -417,7 +417,7 @@ AGGREGATE_CASE_RE = re.compile(r"case\s+MGPipeAggregate::(\w+)\s*:\s*([^;]*);")
# is then `!`, `<` or `>` and no alternative here begins with one except <<= / >>=.
ASSIGN = r"(?:\+\+|--|\+=|-=|\*=|/=|%=|&=|\|=|\^=|<<=|>>=|=(?!=))"
# A write to the member itself: ++m_x, m_x = v, m_x += v. Used by the OUTSIDE scan only; the
# analysed bodies go through extract_writes below.
# analyzed bodies go through extract_writes below.
MEMBER_WRITE_RE = re.compile(r"\+\+\s*(m_\w+)|\b(m_\w+)\s*%s" % ASSIGN)
# A write THROUGH a member: m_x.f = v, m_x[i].f = v, m_x->f = v, and nested. Outside scan only.
MEMBER_ROOTED_WRITE_RE = re.compile(
@@ -451,8 +451,8 @@ READ_ONLY_METHODS = frozenset(("size", "empty", "begin", "end", "cbegin", "cend"
# memcpy(&dst, ...), memset(&dst, ...), memmove(&dst, ...), swap(a, b): whole writes.
BULK_RE = re.compile(r"\b(?:std\s*::\s*)?(memcpy|memmove|memset|swap)\s*\(")
# A local declaration: [qualifiers] Type[<...>][::More] [const] [& | && | *] name, then the
# initialiser's opener. A `&`/`*` mark (or an initialiser that takes an address) makes the
# local an ALIAS whose initialiser must resolve to a member-rooted lvalue; anything else is
# initializer's opener. A `&`/`*` mark (or an initializer that takes an address) makes the
# local an ALIAS whose initializer must resolve to a member-rooted lvalue; anything else is
# a value local, which cannot alias a member - unless the body later writes through it with
# `->` or `*`, in which case it is a pointer or an iterator and is treated as an alias. A
# pointer alias is REBOUND by `p = expr;` (every binding counts); a reference alias is
@@ -494,7 +494,7 @@ ASSIGN_OP_RE = re.compile(r"(\+\+|--|<<=|>>=|[-+*/%&|^]=|(?<![=!<>\[\-+*/%&|^])=
# answered.
MACRO_DIRECTIVE_RE = re.compile(
r"^[ \t]*#[ \t]*(define|undef)[ \t]+(\w+)(\([^()\n]*\))?((?:\\\n|[^\n])*)", re.M)
# MGP_NOTE_AGGREGATE is modelled directly (its hop is read out of MGPipeNoteAggregate's own
# MGP_NOTE_AGGREGATE is modeled directly (its hop is read out of MGPipeNoteAggregate's own
# switch), so expanding it would delete the very token AGGREGATE_RE looks for.
NEVER_EXPAND = frozenset(("MGP_NOTE_AGGREGATE", "MGP_NOTE_MUTATION"))
MACRO_BODY_LIMIT = 4000
@@ -856,7 +856,7 @@ def extract_writes(body, params_text, site):
% (site, what, root))
def designated(text, root_at):
"""`{.f = v, .g = w}`: an aggregate initialiser, not a write to a field named f."""
"""`{.f = v, .g = w}`: an aggregate initializer, not a write to a field named f."""
before = text[:root_at].rstrip()
if not before.endswith("."):
return False
@@ -934,7 +934,7 @@ def extract_writes(body, params_text, site):
def state_bodies():
"""({function name: [body text]}, {function name: [parameter text]},
{function name: {taint reason}}, [analysed paths]) over MG_State/GLState and
{function name: {taint reason}}, [analyzed paths]) over MG_State/GLState and
MG_Impl/Pipe, macros expanded first."""
paths = []
for root in STATE_ROOTS:
@@ -962,15 +962,15 @@ def state_bodies():
def writers_outside(analysed):
"""{MEM token: a file OUTSIDE the analysed roots that writes it}.
"""{MEM token: a file OUTSIDE the analyzed roots that writes it}.
The absence claim is only as good as the set of writers the analysis reads. Every .h/.cpp
under MobileGL/ that is not one of the analysed files is scanned with the direct write
under MobileGL/ that is not one of the analyzed files is scanned with the direct write
patterns, and a shutter member that turns up here is undecided rather than answered.
A file that DECLARES a member of that name is writing its own, not the frontend's - the
backend's PipeInputs mirrors half of GLState's member names - so its writes do not count.
That is the one judgement here, and it is the conservative way round only for names the
That is the one judgment here, and it is the conservative way round only for names the
two sides share; a genuine outside writer of a frontend member does not declare it.
This scan is textual and file-wide: it sees a direct member write and a member-rooted
@@ -1375,7 +1375,7 @@ def derive_bit_answers(mapping, bits, movers, moved, outside=None):
unread = sorted(set(outside[token] for token in shutter if token in outside))
if unread:
out[(mutator, bit)] = (UNDECIDED, "that shutter's members are written outside "
"the analysed roots too, e.g. %s, so 'it writes "
"the analyzed roots too, e.g. %s, so 'it writes "
"nothing that shutter reads' is not a fact this "
"script has" % unread[0])
continue
@@ -1702,8 +1702,8 @@ def self_test(scanned, bits, publishers, movers, moved, outside=None, undecided_
hidden[token] = "MobileGL/MG_Backend/a-file-this-analysis-never-reads.cpp"
verdicts = derive_bit_answers(with_wrong_bit, bits, movers, moved, hidden)
verdict, detail = verdicts.get(("SetCurrentVertexAttributeInt", "NEW_PIXEL_PACK"), ("", ""))
tripped(verdict == UNDECIDED and "outside the analysed roots" in detail,
"10 (a shutter member written outside the analysed roots)")
tripped(verdict == UNDECIDED and "outside the analyzed roots" in detail,
"10 (a shutter member written outside the analyzed roots)")
# 11-14. THE WRITE ANALYSIS ITSELF, on synthetic bodies through the real extractor. The
# review's false verdict was "SetBlendEquation writes nothing NEW_PATCH_STATE's
+5 -5
View File
@@ -197,7 +197,7 @@ def parse_ownership(text=None):
def parse_ops_and_verbs(calls_text=None, fill_points_text=None):
"""The two name spaces the stamp map joins, read from the files that define them: the
catalogue's calls (PipeCalls.def, which IS the MGPWireOp enum, with each call's KIND) and
catalog's calls (PipeCalls.def, which IS the MGPWireOp enum, with each call's KIND) and
the verb set (FillPoints.def, which IS MG_Backend::GLFunctionsTable's member list)."""
calls_text = read(PIPE_CALLS) if calls_text is None else calls_text
fill_points_text = read(FILL_POINTS) if fill_points_text is None else fill_points_text
@@ -213,7 +213,7 @@ def parse_ops_and_verbs(calls_text=None, fill_points_text=None):
def array_block(text, declaration):
"""The braced initialiser of a generated `... <declaration> = {` table, comments KEPT.
"""The braced initializer of a generated `... <declaration> = {` table, comments KEPT.
The generated tables carry the row's name in a trailing comment (`// DrawArrays`) and in a
leading one (`/* 58 ReadPixels */`), and those comments are the only place the row's NAME
@@ -236,7 +236,7 @@ def array_block(text, declaration):
if depth == 0:
return text[open_at + 1:i]
i += 1
sys.exit("gen_pipe_field_ownership: %r never closes its initialiser" % declaration)
sys.exit("gen_pipe_field_ownership: %r never closes its initializer" % declaration)
WAIT_ROW_RE = re.compile(r"/\*\s*\d+\s+(\w+)\s*\*/\s*static_cast<Uint8>\(\s*(k\w+)\s*\)")
@@ -386,7 +386,7 @@ def build_admitted(accessors, ownership, phase, verbs, verb_ops, waits, verb_cla
def verb_shaped_calls(calls, verbs):
"""The calls that MUST have a stamp row or an exemption, by two derived tests: the
catalogue's own kind (kCtxVerb) and a name that is also a verb's. Neither can see a call
catalog's own kind (kCtxVerb) and a name that is also a verb's. Neither can see a call
that is a verb boundary, is not kCtxVerb and is renamed - FieldOwnership.def names the one
such call in the tree and says the phase that emits it writes its row."""
verbSet = set(verbs)
@@ -946,7 +946,7 @@ def self_test():
# alone and control 12 would pass for the wrong reason. Renaming the kind is the cheapest
# way to prove the kind is actually being read.
kindless = read(PIPE_CALLS).replace("kCtxVerb", "kCtxVerbb")
controls.append(("the catalogue's kCtxVerb kind renamed away",
controls.append(("the catalog's kCtxVerb kind renamed away",
"is exempted from the stamp map but is not verb-shaped",
lambda: run(calls_text=kindless)))
+1 -1
View File
@@ -7,7 +7,7 @@
# SPDX-License-Identifier: LGPL-3.0-only
# End of Source File Header
# G5's gate: "pool 与延迟释放原样搬" is LITERAL - ELEVEN functions in
# G5's gate: "the pool and the deferred release are moved as they are" is LITERAL - ELEVEN functions in
# MobileGL/MG_Backend/DirectGLES/Managers.cpp are byte-identical after P3a.
#
# WHAT G5 CLAIMS, and why a diff of the file cannot say it. ARCHITECTURE.md §9.1 puts the three
+2 -2
View File
@@ -26,7 +26,7 @@
# four static_asserts in MGPipeValueTypes.h's trip-wire block still hold, the field list in
# PipeFields.def still names it and the generated comparator still compares it. What breaks is the
# VALUE - the wire record now says "not BGRA" for a GL_BGRA attribute, which is the shape that made
# a swizzled colour array read back with its channels in driver order. It is also the field with
# a swizzled color array read back with its channels in driver order. It is also the field with
# the least other coverage: `Size` keeps 4 for GL_BGRA (D-G2), so a dropped IsBgra does not even
# change the attribute's size.
#
@@ -265,7 +265,7 @@ fi
case "$VERDICT" in
did-not-trip)
say "NEGATIVE CONTROL DID NOT TRIP: $TEST_NAME was still green with ${FIELD} no longer copied"
say "into MGPVertexAttribWire. A GL_BGRA attribute travelled as a non-BGRA one and the emission"
say "into MGPVertexAttribWire. A GL_BGRA attribute traveled as a non-BGRA one and the emission"
say "comparison did not notice, so G6 is not checking what it claims to check."
say "The failing run's output is kept at $LOG_DIR/ctest-after.log"
exit 1
+3 -3
View File
@@ -40,11 +40,11 @@
# rather than in the code because excluding the hash copy would mean hard-coding another
# package's helper name into a regex that deliberately does not know one.
# 2. SamplerParameters::borderColorForm stops being copied in MG_Impl/Pipe/SamplerEmit.h. All
# four border-colour VALUES still cross; what is lost is which of the three forms
# four border-color VALUES still cross; what is lost is which of the three forms
# (float / int / uint) they are to be read as, and D-F4 is explicit that the form crosses and
# that all four values are compared. The failure it models is IntegerBorderColorScenario's:
# an integer border colour read as floats is not an error anywhere, it is just the wrong
# colour at the clamped edge of every sampled texture.
# an integer border color read as floats is not an error anywhere, it is just the wrong
# color at the clamped edge of every sampled texture.
#
# Each patch is applied by REGEX rather than by an exact line, because both headers belong to OTHER
# PACKAGES (C.7: FramebufferEmit.h is package B's, SamplerEmit.h is package C's) and their spelling
+2 -2
View File
@@ -42,7 +42,7 @@
# StageBlocksIntoUnpackRing Managers.cpp: the unpack-PBO staging repack. It is what makes the
# ring path issue NO glPixelStorei, and the +6 ms/frame Mali cliff
# lives on the other side of it
# UnpackRingAvailable Managers.cpp: honours Features.EsprytDisableUnpackRing and
# UnpackRingAvailable Managers.cpp: honors Features.EsprytDisableUnpackRing and
# self-heals a stale context generation
# UnpackRingAllocate Managers.cpp: on the hot upload route
# RecomputeBackendColorSlots Managers.cpp: the attachment permutation - three passes plus the
@@ -503,7 +503,7 @@ write_spec() {
done
}
# Materialise every region source at a git ref into "$2".
# Materialize every region source at a git ref into "$2".
checkout_ref() {
local ref=$1 dir=$2 source
mkdir -p "$dir" || return 2
+6 -6
View File
@@ -12,7 +12,7 @@ P0.5's acceptance gate says every `nm --defined-only -S` delta has to be explain
symbol. The awkward part is that de-nesting a type renames every mangled
name that mentions it - `ProgramObject::LinkArtifacts` -> `LinkArtifacts` shows up inside
every `std::vector<...>` instantiation too - so a raw nm diff of a pure move looks
catastrophic. `--strip-scope` folds those into a "renamed-only" bucket: same normalised
catastrophic. `--strip-scope` folds those into a "renamed-only" bucket: same normalized
demangled name, byte-identical size. What is left over is the report's real content.
python3 scripts/symbol_report.py --before old.so --after new.so
@@ -195,7 +195,7 @@ def bucket(before, after, only_names, threshold):
"before": b["size"], "after": a["size"]})
continue
if a["mangled"] != b["mangled"]:
# same normalised name, byte-identical size: the pure-move signature
# same normalized name, byte-identical size: the pure-move signature
if wanted(name):
renamed.append({"name": name, "delta": 0,
"before": b["mangled"][0], "after": a["mangled"][0]})
@@ -302,7 +302,7 @@ def self_test():
if [(r["name"], r["delta"]) for r in resized] != [("MobileGL::Grew()", 0x10)]:
problems.append("resized bucket: {}".format([(r["name"], r["delta"]) for r in resized]))
# `ProgramObject::LinkArtifacts::Reset` -> `LinkArtifacts::Reset` folds to the same
# normalised name at the same size: renamed-only, not added+removed.
# normalized name at the same size: renamed-only, not added+removed.
if [r["name"] for r in renamed] != ["MobileGL::MG_State::GLState::LinkArtifacts::Reset()"]:
problems.append("renamed bucket: {}".format([r["name"] for r in renamed]))
if unchanged != 2: # ProgramObject::Link() and NoSize()
@@ -432,8 +432,8 @@ def main():
say("{} -> {} defined symbols: {} added, {} removed, {} resized, {} renamed".format(
before_count, after_count, len(added), len(removed), len(resized), len(renamed)))
# The two counts differ by the folding: several mangled symbols can share one
# normalised demangled name (local aliases, `.cold` parts, identical-COMDAT clones).
say("{} -> {} normalised names, {} unchanged (name, size and mangling all identical)".format(
# normalized demangled name (local aliases, `.cold` parts, identical-COMDAT clones).
say("{} -> {} normalized names, {} unchanged (name, size and mangling all identical)".format(
len(before), len(after), unchanged))
if only_names:
say("listing restricted to names containing: " + ", ".join(only_names))
@@ -468,7 +468,7 @@ def main():
["symbol", "before", "after", "delta"])
lines += markdown_table("Renamed only (same size)",
[(r["name"], r["before"], r["after"]) for r in renamed],
["normalised symbol", "before mangling", "after mangling"])
["normalized symbol", "before mangling", "after mangling"])
report = "\n".join(lines) + "\n"
if args.markdown: