Wolfgang Thallergcc 15.1.0ada185d1 year agoHistory
1099 lines · 35.5 KB · D
RawDownload
/** * The runtime module exposes information specific to the D runtime code. * * Copyright: Copyright Sean Kelly 2005 - 2009. * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Authors:   Sean Kelly * Source:    $(DRUNTIMESRC core/_runtime.d) * Documentation: https://dlang.org/phobos/core_runtime.html */ /* NOTE: This file has been patched from the original DMD distribution to * work with the GDC compiler. */module core.runtime; version (OSX)    version = Darwin;else version (iOS)    version = Darwin;else version (TVOS)    version = Darwin;else version (WatchOS)    version = Darwin; version (GNU){    import gcc.backtrace;    // This shouldn't be necessary but ensure that code doesn't get mixed    // It does however prevent the unittest SEGV handler to be installed,    // which is desireable as it uses backtrace directly.    private enum hasExecinfo = false;    version = LibBacktrace_TraceHandler;}else version (DRuntime_Use_Libunwind){    version = DefineBacktrace_using_UnwindBacktrace;     // This shouldn't be necessary but ensure that code doesn't get mixed    // It does however prevent the unittest SEGV handler to be installed,    // which is desireable as it uses backtrace directly.    private enum hasExecinfo = false;}else    import core.internal.execinfo; /// C interface for Runtime.loadLibraryextern (C) void* rt_loadLibrary(const char* name);/// dittoversion (Windows) extern (C) void* rt_loadLibraryW(const wchar* name); /// C interface for Runtime.unloadLibrary, returns 1/0 instead of boolextern (C) int rt_unloadLibrary(void* ptr); /// C interface for Runtime.initialize, returns 1/0 instead of boolextern(C) int rt_init();/// C interface for Runtime.terminate, returns 1/0 instead of boolextern(C) int rt_term(); /** * This type is returned by the module unit test handler to indicate testing * results. */struct UnitTestResult{    /**     * Number of modules which were tested     */    size_t executed;     /**     * Number of modules passed the unittests     */    size_t passed;     /**     * Should the main function be run or not? This is ignored if any tests     * failed.     */    bool runMain;     /**     * Should we print a summary of the results?     */    bool summarize;     /**     * Simple check for whether execution should continue after unit tests     * have been run. Works with legacy code that expected a bool return.     *     * Returns:     *    true if execution should continue after testing is complete, false if     *    not.     */    bool opCast(T : bool)() const    {        return runMain && (executed == passed);    }     /// Simple return code that says unit tests pass, and main should be run    enum UnitTestResult pass = UnitTestResult(0, 0, true, false);    /// Simple return code that says unit tests failed.    enum UnitTestResult fail = UnitTestResult(1, 0, false, false);} /// Legacy module unit test handleralias ModuleUnitTester = bool function();/// Module unit test handleralias ExtendedModuleUnitTester = UnitTestResult function();private{    alias CollectHandler = bool function(Object);    alias TraceHandler = Throwable.TraceInfo function(void* ptr);     alias ExceptionHandler = void delegate(Throwable);    extern (C) void _d_print_throwable(Throwable t);     extern (C) void* thread_stackBottom() nothrow @nogc;}  shared static this(){    // NOTE: Some module ctors will run before this handler is set, so it's    //       still possible the app could exit without a stack trace.  If    //       this becomes an issue, the handler could be set in C main    //       before the module ctors are run.    Runtime.traceHandler(&defaultTraceHandler, &defaultTraceDeallocator);}  ///////////////////////////////////////////////////////////////////////////////// Runtime/////////////////////////////////////////////////////////////////////////////// /** * Stores the unprocessed arguments supplied when the * process was started. */struct CArgs{    int argc; /// The argument count.    char** argv; /// The arguments as a C array of strings.} /** * This struct encapsulates all functionality related to the underlying runtime * module for the calling context. */struct Runtime{    /**     * Initializes the runtime.  This call is to be used in instances where the     * standard program initialization process is not executed.  This is most     * often in shared libraries or in libraries linked to a C program.     * If the runtime was already successfully initialized this returns true.     * Each call to initialize must be paired by a call to $(LREF terminate).     *     * Returns:     *  true if initialization succeeded or false if initialization failed.     */    static bool initialize()    {        return !!rt_init();    }     /**     * Terminates the runtime.  This call is to be used in instances where the     * standard program termination process will not be not executed.  This is     * most often in shared libraries or in libraries linked to a C program.     * If the runtime was not successfully initialized the function returns false.     *     * Returns:     *  true if termination succeeded or false if termination failed.     */    static bool terminate()    {        return !!rt_term();    }     /**     * Returns the arguments supplied when the process was started.     *     * Returns:     *  The arguments supplied when this process was started.     */    extern(C) pragma(mangle, "rt_args") static @property string[] args();     /**     * Returns the unprocessed C arguments supplied when the process was started.     * Use this when you need to supply argc and argv to C libraries.     *     * Returns:     *  A $(LREF CArgs) struct with the arguments supplied when this process was started.     *     * Example:     * ---     * import core.runtime;     *     * // A C library function requiring char** arguments     * extern(C) void initLibFoo(int argc, char** argv);     *     * void main()     * {     *     auto args = Runtime.cArgs;     *     initLibFoo(args.argc, args.argv);     * }     * ---     */    extern(C) pragma(mangle, "rt_cArgs") static @property CArgs cArgs() @nogc;     /**     * Locates a dynamic library with the supplied library name and dynamically     * loads it into the caller's address space.  If the library contains a D     * runtime it will be integrated with the current runtime.     *     * Params:     *  name = The name of the dynamic library to load.     *     * Returns:     *  A reference to the library or null on error.     */    static void* loadLibrary()(const scope char[] name)    {        import core.stdc.stdlib : free, malloc;        version (Windows)        {            import core.sys.windows.winnls : CP_UTF8, MultiByteToWideChar;            import core.sys.windows.winnt : WCHAR;             if (name.length == 0) return null;            // Load a DLL at runtime            auto len = MultiByteToWideChar(                CP_UTF8, 0, name.ptr, cast(int)name.length, null, 0);            if (len == 0)                return null;             auto buf = cast(WCHAR*)malloc((len+1) * WCHAR.sizeof);            if (buf is null) return null;            scope (exit) free(buf);             len = MultiByteToWideChar(                CP_UTF8, 0, name.ptr, cast(int)name.length, buf, len);            if (len == 0)                return null;             buf[len] = '\0';             return rt_loadLibraryW(buf);        }        else version (Posix)        {            /* Need a 0-terminated C string for the dll name             */            immutable len = name.length;            auto buf = cast(char*)malloc(len + 1);            if (!buf) return null;            scope (exit) free(buf);             buf[0 .. len] = name[];            buf[len] = 0;             return rt_loadLibrary(buf);        }    }      /**     * Unloads the dynamic library referenced by p.  If this library contains a     * D runtime then any necessary finalization or cleanup of that runtime     * will be performed.     *     * Params:     *  p = A reference to the library to unload.     */    static bool unloadLibrary()(void* p)    {        return !!rt_unloadLibrary(p);    }      /**     * Overrides the default trace mechanism with a user-supplied version.  A     * trace represents the context from which an exception was thrown, and the     * trace handler will be called when this occurs.  The pointer supplied to     * this routine indicates the base address from which tracing should occur.     * If the supplied pointer is null then the trace routine should determine     * an appropriate calling context from which to begin the trace.     *     * If the deallocator is set, then it is called with the traceinfo when the     * exception is finalized. The deallocator is only set in the exception if     * the default handler is used to generate the trace info.     *     * Params:     *  h = The new trace handler.  Set to null to disable exception backtracing.     *  d = The new trace deallocator. If non-null, this will be called on     *      exception destruction with the trace info, only when the trace     *      handler is used to generate TraceInfo.     */    extern(C) pragma(mangle, "rt_setTraceHandler") static @property void traceHandler(TraceHandler h,                    Throwable.TraceDeallocator d = null);     /**     * Gets the current trace handler.     *     * Returns:     *  The current trace handler or null if none has been set.     */    extern(C) pragma(mangle, "rt_getTraceHandler") static @property TraceHandler traceHandler();     /**     * Gets the current trace deallocator.     *     * Returns:     *  The current trace deallocator or null if none has been set.     */    extern(C) pragma(mangle, "rt_getTraceDeallocator") static @property Throwable.TraceDeallocator traceDeallocator();     /**     * Overrides the default collect hander with a user-supplied version.  This     * routine will be called for each resource object that is finalized in a     * non-deterministic manner--typically during a garbage collection cycle.     * If the supplied routine returns true then the object's dtor will called     * as normal, but if the routine returns false than the dtor will not be     * called.  The default behavior is for all object dtors to be called.     *     * Params:     *  h = The new collect handler.  Set to null to use the default handler.     */    extern(C) pragma(mangle, "rt_setCollectHandler") static @property void collectHandler( CollectHandler h );      /**     * Gets the current collect handler.     *     * Returns:     *  The current collect handler or null if none has been set.     */    extern(C) pragma(mangle, "rt_getCollectHandler") static @property CollectHandler collectHandler();      /**     * Overrides the default module unit tester with a user-supplied version.     * This routine will be called once on program initialization.  The return     * value of this routine indicates to the runtime whether the tests ran     * without error.     *     * There are two options for handlers. The `bool` version is deprecated but     * will be kept for legacy support. Returning `true` from the handler is     * equivalent to returning `UnitTestResult.pass` from the extended version.     * Returning `false` from the handler is equivalent to returning     * `UnitTestResult.fail` from the extended version.     *     * See the documentation for `UnitTestResult` to see how you should set up     * the return structure.     *     * See the documentation for `runModuleUnitTests` for how the default     * algorithm works, or read the example below.     *     * Params:     *  h = The new unit tester.  Set both to null to use the default unit     *  tester.     *     * Example:     * ---------     * shared static this()     * {     *     import core.runtime;     *     *     Runtime.extendedModuleUnitTester = &customModuleUnitTester;     * }     *     * UnitTestResult customModuleUnitTester()     * {     *     import std.stdio;     *     *     writeln("Using customModuleUnitTester");     *     *     // Do the same thing as the default moduleUnitTester:     *     UnitTestResult result;     *     foreach (m; ModuleInfo)     *     {     *         if (m)     *         {     *             auto fp = m.unitTest;     *     *             if (fp)     *             {     *                 ++result.executed;     *                 try     *                 {     *                     fp();     *                     ++result.passed;     *                 }     *                 catch (Throwable e)     *                 {     *                     writeln(e);     *                 }     *             }     *         }     *     }     *     if (result.executed != result.passed)     *     {     *         result.runMain = false;  // don't run main     *         result.summarize = true; // print failure     *     }     *     else     *     {     *         result.runMain = true;    // all UT passed     *         result.summarize = false; // be quiet about it.     *     }     *     return result;     * }     * ---------     */    static @property void extendedModuleUnitTester( ExtendedModuleUnitTester h )    {        sm_extModuleUnitTester = h;    }     /// Ditto    static @property void moduleUnitTester( ModuleUnitTester h )    {        sm_moduleUnitTester = h;    }     /**     * Gets the current legacy module unit tester.     *     * This property should not be used, but is supported for legacy purposes.     *     * Note that if the extended unit test handler is set, this handler will     * be ignored.     *     * Returns:     *  The current legacy module unit tester handler or null if none has been     *  set.     */    static @property ModuleUnitTester moduleUnitTester()    {        return sm_moduleUnitTester;    }     /**     * Gets the current module unit tester.     *     * This handler overrides any legacy module unit tester set by the     * moduleUnitTester property.     *     * Returns:     *  The current  module unit tester handler or null if none has been     *  set.     */    static @property ExtendedModuleUnitTester extendedModuleUnitTester()    {        return sm_extModuleUnitTester;    } private:     // NOTE: This field will only ever be set in a static ctor and should    //       never occur within any but the main thread, so it is safe to    //       make it __gshared.    __gshared ExtendedModuleUnitTester sm_extModuleUnitTester = null;    __gshared ModuleUnitTester sm_moduleUnitTester = null;} /** * Set source file path for coverage reports. * * Params: *  path = The new path name. * Note: *  This is a dmd specific setting. */extern (C) void dmd_coverSourcePath(string path); /** * Set output path for coverage reports. * * Params: *  path = The new path name. * Note: *  This is a dmd specific setting. */extern (C) void dmd_coverDestPath(string path); /** * Enable merging of coverage reports with existing data. * * Params: *  flag = enable/disable coverage merge mode * Note: *  This is a dmd specific setting. */extern (C) void dmd_coverSetMerge(bool flag); /** * Set the output file name for profile reports (-profile switch). * An empty name will set the output to stdout. *

Lines 1–500 of 1099.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t