Skip to content
This repository has been archived by the owner on Aug 10, 2021. It is now read-only.

[objc][codegen] Fixed bug with calling fake override interface methods #4588

Merged
merged 1 commit into from
Dec 15, 2020

Conversation

homuroll
Copy link
Contributor

@homuroll homuroll commented Dec 9, 2020

No description provided.

@@ -943,8 +945,21 @@ static void throwIfCantBeOverridden(Class clazz, const KotlinToObjCMethodAdapter
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
RuntimeAssert(adapter->vtableIndex == -1, "");

if (adapter->itableIndex != -1 && superITable != nullptr)
if (adapter->itableIndex != -1 && superITable != nullptr) {
// Because of fake overrides [adapter->interfaceId] might not be equal to [typeInfo->classId_].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not entirely correct. Yes, the particular bug we've encountered features a fake override. But

  • It is probably triggered by a bug in ObjCExportCodeGenerator: the latter doesn't "resolve fake overrides" when computing functionName, so the machinery doesn't find the adapter among the inherited ones and generates an adapter for super interface's method.
  • Generally that machinery doesn't guarantee that it would only emit adapters matching the type. Avoiding emitting adapters that are inherited from super types is only an optimization. We are free to remove or rework it. And even if we don't, there might be cases when it doesn't guarantee that adapters match type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bug in ObjCExportCodeGenerator: the latter doesn't "resolve fake overrides" when computing functionName, so the machinery doesn't find the adapter among the inherited ones and generates an adapter for super interface's method.

JFTR: I've rechecked the ObjCExportCodeGenerator and am not sure anymore that it has such a bug.

Apparently our virtual call machinery calls interface fake override methods using .functionName of a fake override, not of its "real" super method. This means that ObjCExportCodeGenerator generally has to generate additional "reverse adapter" for the fake override, using its own functionName. While itablePlace is reused from super interface.
It can use itablePlace = null though, but this would be just an optimization (see also above).

} else {
auto const& interfaceVTable = interfaceVTablesIt->second;
RuntimeAssert(interfaceVTable.size() == static_cast<size_t>(interfaceVTableSize), "");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty much like a copy-paste from the code above. It should be possible to extract a (lambda) function for this code.

if (adapter->itableIndex != -1 && superITable != nullptr)
if (adapter->itableIndex != -1 && superITable != nullptr) {
// In general, [adapter->interfaceId] might not be equal to [typeInfo->classId_].
auto interfaceId = adapter->interfaceId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can also be used in addToITable below.

@homuroll homuroll force-pushed the objc_fake_override_interface_call_fix branch from 62cccc5 to 03ad015 Compare December 15, 2020 19:23
@homuroll homuroll merged commit c18ae92 into master Dec 15, 2020
@homuroll homuroll deleted the objc_fake_override_interface_call_fix branch December 15, 2020 19:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants