Repository navigation
Order a class's functions independently of the compilation unit order - #1425
Merged
Merged
Conversation
A class's function joined its class's list the first time anything asked for it. Packages are translated depth first from each compilation unit in turn, so imports of a package which do not import each other, and the packages of an import cycle, ask in the order of the units: two interfaces in unrelated packages asking for the overloads implementing them swapped Base_Base_m and Base_Base_m1 in the Lua, and a superclass and an interface in unrelated packages swapped the order in which a class's functions are emitted. A class's function now waits until the elements of its class's package are translated. The class then takes its functions in the order they get when that package is translated first: those asked for by the packages it imports and which do not import it back, in the order of their translation from it, then those asked for by the package itself, in the order of its definitions. Requests from other packages do not count. A superclass translated first by a subclass in another package counts for its own package. Where the unit order made no difference this is the old order. Castle fight and zombie defense (-lua -inline -localOptimizations) change only in the function order of 6 and 17 classes, each in or below an import cycle; putting those lists back in the old order gives the old Lua byte for byte.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A class's function joined its class's function list the first time anything asked for it (
ImTranslator.getFuncFor, the constructor and destroy functions). Packages are translated depth first from each compilation unit, imports first, so the imports of a package which do not import each other, and the packages of an import cycle, ask in the order of the units. The backends emit a class's functions in list order and Lua numbers same-named overloads in it, so the Lua depended on the unit order:Base implements IntM, StrMwithm(int)andm(string), the interfaces in two unrelated packages:Base_Base_mandBase_Base_m1swapped bodies and slot bindings.sortEverythingdoes not sort class function lists, and sorting them would change the output of programs which are already deterministic.Fix
A class's function now waits until the elements of its class's package are translated. The class then takes its functions in the order they get when that package is translated first:
Requests are attributed to the top-level definition being translated (
TLDTranslation), including a superclass translated first by a subclass in another package.getMethodForanddestroyMethodnow ask for their function on every lookup so a cached hit still counts. The class init function goes through the same path. Where the unit order made no difference, this is exactly the old order.Tests
New
DeterministicCheckscases, each compiled for all backends and run in two unit orders, each failing on master:overloadsImplementingInterfacesOfOtherPackagesEmitTheSameLuaInAnyUnitOrder(the overload repro)functionsAskedForByUnrelatedPackagesEmitTheSameLuaInAnyUnitOrder(superclass and interface in unrelated packages)functionsAskedForAcrossAnImportCycleEmitTheSameLuaInAnyUnitOrder(call across a cycle plus a cross-package subclass in it; also fails if only the pull-in attribution is removed)DeterministicChecks,InterfaceTests,ClassesTests,LuaBackendAuditTestsandLuaTranslationTestspass on the merged tree.Real maps
Castle fight and zombie defense built with
-lua -inline -localOptimizations, Lua compared withcmp(zombie defense's build date masked; two baseline builds are byte-identical):CampaignBotswith the campaign chapters,CustomAI/DraftOrchestratorin a 42-package cycle; zombie defense: a 58-package cycle) or extends classes from one (JungleBoss,PlagueBoss,PlainsBossbelowBoss/Zombie). So their order depended on where translation entered the cycle.