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

Add rtInfo (or equivalent) to ModuleInfo #18576

Open
dlangBugzillaToGithub opened this issue May 3, 2013 · 7 comments
Open

Add rtInfo (or equivalent) to ModuleInfo #18576

dlangBugzillaToGithub opened this issue May 3, 2013 · 7 comments

Comments

@dlangBugzillaToGithub
Copy link

Steven Schveighoffer (@schveiguy) reported this on 2013-05-03T14:42:52Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=10023

CC List

Description

Currently, we have rtInfo for TypeInfo instances, which is a compile time-generated member based on the library template RTInfo.

It would be nice to have this same mechanism for ModuleInfo instances.  This would be very helpful for many different nifty runtime features, such as precise garbage collection, or fixing cyclic import dependencies.
@dlangBugzillaToGithub
Copy link
Author

bearophile_hugs commented on 2013-06-15T04:29:04Z

I think this is a significant feature, so I think it's better to explain better its advantages and usages (like for a unittest system).

@dlangBugzillaToGithub
Copy link
Author

doob (@jacob-carlborg) commented on 2013-06-28T11:30:23Z

Pull requests:

https://github.com/D-Programming-Language/dmd/pull/2271
https://github.com/D-Programming-Language/druntime/pull/534

@dlangBugzillaToGithub
Copy link
Author

doob (@jacob-carlborg) commented on 2013-06-29T06:04:39Z

I have an idea how to make RTInfo and my proposed RMInfo, in the pull request, work outside object.di.

1. We add a new struct (rtIfno/rmInfo) to object.di as an UDA recognized by the compiler

2. If a template that have the correct signature and the object.rtInfo UDA attached, instantiated that as RTInfo/RMInfo

3. Collect the result of the RTInfo/RMInfo template in an associative array. The keys will be the fully qualified name of the module the template is defined in, the values will be what the same as now

@dlangBugzillaToGithub
Copy link
Author

doob (@jacob-carlborg) commented on 2013-06-29T06:11:31Z

I had an idea how to use this for unit tests. We add a new traits that will return all the unit test functions of the given module. RMInfo can then be used to collect all these unit tests functions at compile time. The advantage of doing it at compile time is because then it's possible to access UDA's attached to the unit tests. This would basically make it possible to implement named unit tests in library code:

// UDA
struct name { string name; }

@name("foo") unittest
{
    assert(1 +2 == 3);
}

This is also more flexible then named unit tests implemented in the language. One could use UDA's to do a more RSpec version of unit tests:

struct describe { string desc; }
struct it { string desc; }

@desctibe("Address.validate")
{
    @it("should validate the address")
    {
        assert(true);
    }
}

@dlangBugzillaToGithub
Copy link
Author

code (@MartinNowak) commented on 2014-10-18T16:42:06Z

We are still lacking a workable idea how to make RTInfo/RMInfo customizable.
https://github.com/D-Programming-Language/dmd/pull/2271#issuecomment-20553000

@dlangBugzillaToGithub
Copy link
Author

johannespfau (@jpf91) commented on 2016-12-24T18:45:55Z

> We are still lacking a workable idea how to make RTInfo/RMInfo customizable.

Just some thoughts:

As there are currently discussions of dropping ModuleInfo completely what we really need is some way to aggregate information from different modules where the modules are not necessarily known during compilation. And the kind of information that is aggregated is user defined.

So issue 1: Aggregating information from different modules (with full support for separate compilation, shared libraries, dlopened libraries)

1)
The most portable way to implement this is using small C constructor stubs. There's not much backend magic required to enable this:

@clikeCtor void registerData()
{
    import baseModule;
    baseModule.register(...);
}

Such functions are implemented as __attribute__((constructor)) functions. There is some runtime overhead involved, but the code can be adapted to any usecase. Things get a little more complicated if you want to aggregate data per library, e.g. you might want to have a list of all Webpage subclasses in a dlopened shared library. In that case the aggregation code could use per-library hidden fields and access the data using library-exported accessor functions.


2)
Without runtime overhead, but needs some kind of linker support: Aggregate symbols into a custom section. Use per library start/end markers to guard the section and provide per library accessor functions to access the data.


Issue 2: Making sure every module A can add information related to module B.

My proposal is to introduce a special kind of mixin templates. Every module keeps a list of these special templates in the module and as soon as the module is imported all special 'auto mixin' templates are mixed into the importing module. A full reimplementation of the unittest system without ModuleInfo could then look like this:

------------------------------------------------------------------
module myunittest;

struct MyUnittest{}

@auto template mixin(Module)
{
    // 2 above
    @section("myunittest") TestModuleInfo info = getTests!Module;
    // alternatively 1 above
    @clikeCtor unittestConstructor()
    {
        registerTests(getTests!Module);
    }
}

void runTests()
{
    // approach 2
    TestModuleInfo[] tests = myunittest_start[0 .. myunittest_end - start];
    foreach(test; tests) ...
}
------------------------------------------------------------------

------------------------------------------------------------------
module user;
import myunittest;

@MyUnittest void testFunc1()
{
}
------------------------------------------------------------------

------------------------------------------------------------------
module main;
import myUnittest;

void main() {runTests()};
------------------------------------------------------------------

@dlangBugzillaToGithub
Copy link
Author

destructionator commented on 2016-12-24T21:29:04Z

> We are still lacking a workable idea how to make RTInfo/RMInfo customizable.

Why does it have to be customizable? I think it gives enough benefit just to the runtime author (which btw may include custom runtimes) to be brought in, and then it also simplifies the compiler/runtime interface by letting us move more and more right out.

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

No branches or pull requests

1 participant