Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bugzilla issue 24882 - COM class is allocated using GC not malloc #17095

Open
wants to merge 1 commit into
base: stable
Choose a base branch
from

Conversation

rikkimax
Copy link
Contributor

Has spec PR: dlang/dlang.org#3928

Fixes it by introducing the trait isCOMClass

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @rikkimax! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Auto-close Bugzilla Severity Description
24882 regression COM class is allocated using GC not malloc

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "stable + dmd#17095"


A COM class inherits from a possibly user defined interface called ``IUnknown``.
To detect this during compilation use the trait ``__traits(isCOMClass, Type)``.
Or using the ``TypeInfo_Class`` flag.
Copy link
Contributor

Choose a reason for hiding this comment

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

How do you check that flag? If this works as an alternative, why is __traits(isCOMClass) introduced?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is the original code from the hook:

extern (C) Object _d_newclass(const ClassInfo ci) @weak
{
    import core.stdc.stdlib;
    import core.exception : onOutOfMemoryError;
    void* p;
    auto init = ci.initializer;

    debug(PRINTF) printf("_d_newclass(ci = %p, %s)\n", ci, cast(char *)ci.name);
    if (ci.m_flags & TypeInfo_Class.ClassFlags.isCOMclass)

The templated hook that has been fixed to use the new trait:

T _d_newclassT(T)() @trusted
if (is(T == class))
{
   import core.internal.traits : hasIndirections;
   import core.exception : onOutOfMemoryError;
   import core.memory : pureMalloc;
   import core.memory : GC;

   alias BlkAttr = GC.BlkAttr;

   auto init = __traits(initSymbol, T);
   void* p;

   static if (__traits(isCOMClass, T))

While both do the same thing new a class, one uses purely CT available information, the other RT only information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Either we revert back to TypeInfo for this hook, or we go in the direction of some sort of CT available information.

Of course we could derive it by looking for a IUnknown interface, but that isn't an easy thing to do, let alone perform on every single class new instantiation when there is a flag in the compiler easily readable with the information we need.

Copy link
Contributor

Choose a reason for hiding this comment

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

The new trait is good, I just think the last line of the changelog should be removed or clarified. The current wording implies TypeInfo_Class can be used during compilation to check the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

@dkorpel dkorpel Nov 26, 2024

Choose a reason for hiding this comment

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

Something like "The trait is equivalent to the runtime check ClassInfo.m_flags & TypeInfo_Class.ClassFlags.isCOMclass ".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't want to encourage people to use anything TypeInfo-related, it's stated so that people know what existing code they can replace with the trait.

@adamdruppe
Copy link
Contributor

What's the problem with static if(is(T : IUnknown)) again?

@rikkimax
Copy link
Contributor Author

What's the problem with static if(is(T : IUnknown)) again?

A COM class is any class derived from an interface called IUnknown.

That would only work with a specific IUnknown interface in druntime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants