From 369cd9055c6c6fb2f72832ec9e1a9633d8243caf Mon Sep 17 00:00:00 2001 From: Steven Schveighoffer Date: Tue, 23 Aug 2016 16:05:15 -0400 Subject: [PATCH 1/2] Fix issue 16291. Make sure internal shared ctor is called from std.encoding and std.process. --- std/encoding.d | 20 ++++++++++++++++++++ std/internal/phobosinit.d | 12 +++--------- std/process.d | 1 + 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/std/encoding.d b/std/encoding.d index efc033933c9..2b50eb0afb9 100644 --- a/std/encoding.d +++ b/std/encoding.d @@ -55,6 +55,7 @@ module std.encoding; import std.traits; import std.typecons; import std.range.primitives; +import std.internal.phobosinit; @system unittest { @@ -3297,6 +3298,25 @@ class EncodingSchemeUtf32Native : EncodingScheme assert(ub.length == 8); } +// this hack allows us to register all the classes without having dependencies +// on other modules. The function is eterned, and then called from phobosinit. +// Note that EncodingScheme.register uses the default constructor of each of +// these classes via the Object.factory method, and then calls the names() +// function. None of these functions above depend on external modules, so we +// are safe to call this from an external module without risk of creating +// cycles. +extern(C) void std_encoding_shared_static_this() +{ + EncodingScheme.register("std.encoding.EncodingSchemeASCII"); + EncodingScheme.register("std.encoding.EncodingSchemeLatin1"); + EncodingScheme.register("std.encoding.EncodingSchemeLatin2"); + EncodingScheme.register("std.encoding.EncodingSchemeWindows1250"); + EncodingScheme.register("std.encoding.EncodingSchemeWindows1252"); + EncodingScheme.register("std.encoding.EncodingSchemeUtf8"); + EncodingScheme.register("std.encoding.EncodingSchemeUtf16Native"); + EncodingScheme.register("std.encoding.EncodingSchemeUtf32Native"); +} + //============================================================================= diff --git a/std/internal/phobosinit.d b/std/internal/phobosinit.d index 961da9d0c96..ab557e5188e 100644 --- a/std/internal/phobosinit.d +++ b/std/internal/phobosinit.d @@ -21,15 +21,9 @@ version(OSX) } } +extern(C) void std_encoding_shared_static_this(); + shared static this() { - import std.encoding : EncodingScheme; - EncodingScheme.register("std.encoding.EncodingSchemeASCII"); - EncodingScheme.register("std.encoding.EncodingSchemeLatin1"); - EncodingScheme.register("std.encoding.EncodingSchemeLatin2"); - EncodingScheme.register("std.encoding.EncodingSchemeWindows1250"); - EncodingScheme.register("std.encoding.EncodingSchemeWindows1252"); - EncodingScheme.register("std.encoding.EncodingSchemeUtf8"); - EncodingScheme.register("std.encoding.EncodingSchemeUtf16Native"); - EncodingScheme.register("std.encoding.EncodingSchemeUtf32Native"); + std_encoding_shared_static_this(); } diff --git a/std/process.d b/std/process.d index eedd587a33f..8b04f4f662c 100644 --- a/std/process.d +++ b/std/process.d @@ -132,6 +132,7 @@ version (Posix) { version (OSX) { + import std.internal.phobosinit; // needed to make sure the function gets called extern(C) char*** _NSGetEnviron() nothrow; private __gshared const(char**)* environPtr; extern(C) void std_process_shared_static_this() { environPtr = _NSGetEnviron(); } From 78d7c3bfecd369acf0c13b4c0464e039dbb4b203 Mon Sep 17 00:00:00 2001 From: Steven Schveighoffer Date: Tue, 23 Aug 2016 17:09:05 -0400 Subject: [PATCH 2/2] Make sure the classinfo of all the encoding schemes gets included! --- std/encoding.d | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/std/encoding.d b/std/encoding.d index 2b50eb0afb9..9231e79c3e4 100644 --- a/std/encoding.d +++ b/std/encoding.d @@ -2374,7 +2374,10 @@ abstract class EncodingScheme */ static void register(string className) { - auto scheme = cast(EncodingScheme)ClassInfo.find(className).create(); + auto info = ClassInfo.find(className); + if (info is null) + throw new EncodingException("Unable to find class info for class "~className); + auto scheme = cast(EncodingScheme)info.create(); if (scheme is null) throw new EncodingException("Unable to create class "~className); foreach (encodingName;scheme.names()) @@ -3307,6 +3310,9 @@ class EncodingSchemeUtf32Native : EncodingScheme // cycles. extern(C) void std_encoding_shared_static_this() { + // BUG: this is needed or all the classinfo from this file will not be + // included in phobos! + scope ascii = new EncodingSchemeASCII; EncodingScheme.register("std.encoding.EncodingSchemeASCII"); EncodingScheme.register("std.encoding.EncodingSchemeLatin1"); EncodingScheme.register("std.encoding.EncodingSchemeLatin2");