Skip to content

Modernisation #1015

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

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Drop InitializePlatformData
  • Loading branch information
filmor committed Dec 18, 2019
commit 5753d38f32b7e900ab44e239a343ff0095a0d41c
9 changes: 2 additions & 7 deletions Python.Runtime/platform/InternalLoadContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,8 @@ class InternalLoadContext : AssemblyLoadContext

protected override IntPtr LoadUnmanagedDll(string name)
{
if (name == "__Internal")
{
var loader = LibraryLoader.Get(OperatingSystemType.Linux);
return loader.Load(null);
}

return IntPtr.Zero;
var filtered = name == "__Internal" ? null : name;
return LibraryLoader.Instance.Load(filtered);
}

public static AssemblyLoadContext Instance { get; } = new InternalLoadContext();
Expand Down
29 changes: 19 additions & 10 deletions Python.Runtime/platform/LibraryLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,27 @@ interface ILibraryLoader

static class LibraryLoader
{
public static ILibraryLoader Get(OperatingSystemType os)
static ILibraryLoader _instance = null;

public static ILibraryLoader Instance
{
switch (os)
get
{
case OperatingSystemType.Windows:
return new WindowsLoader();
case OperatingSystemType.Darwin:
return new DarwinLoader();
case OperatingSystemType.Linux:
return new LinuxLoader();
default:
throw new PlatformNotSupportedException($"This operating system ({os}) is not supported");
if (_instance == null)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
_instance = new WindowsLoader();
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
_instance = new DarwinLoader();
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
_instance = new LinuxLoader();
else
throw new PlatformNotSupportedException(
$"This operating system is not supported"
);
}

return _instance;
}
}
}
Expand Down
105 changes: 2 additions & 103 deletions Python.Runtime/runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,56 +26,7 @@ public static partial class Runtime

internal static bool Is32Bit = IntPtr.Size == 4;

// .NET core: System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
internal static bool IsWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;

static readonly Dictionary<string, OperatingSystemType> OperatingSystemTypeMapping = new Dictionary<string, OperatingSystemType>()
{
{ "Windows", OperatingSystemType.Windows },
{ "Darwin", OperatingSystemType.Darwin },
{ "Linux", OperatingSystemType.Linux },
};

/// <summary>
/// Gets the operating system as reported by python's platform.system().
/// </summary>
public static OperatingSystemType OperatingSystem { get; private set; }

/// <summary>
/// Gets the operating system as reported by python's platform.system().
/// </summary>
public static string OperatingSystemName { get; private set; }


/// <summary>
/// Map lower-case version of the python machine name to the processor
/// type. There are aliases, e.g. x86_64 and amd64 are two names for
/// the same thing. Make sure to lower-case the search string, because
/// capitalization can differ.
/// </summary>
static readonly Dictionary<string, MachineType> MachineTypeMapping = new Dictionary<string, MachineType>()
{
["i386"] = MachineType.i386,
["i686"] = MachineType.i386,
["x86"] = MachineType.i386,
["x86_64"] = MachineType.x86_64,
["amd64"] = MachineType.x86_64,
["x64"] = MachineType.x86_64,
["em64t"] = MachineType.x86_64,
["armv7l"] = MachineType.armv7l,
["armv8"] = MachineType.armv8,
["aarch64"] = MachineType.aarch64,
};

/// <summary>
/// Gets the machine architecture as reported by python's platform.machine().
/// </summary>
public static MachineType Machine { get; private set; }/* set in Initialize using python's platform.machine */

/// <summary>
/// Gets the machine architecture as reported by python's platform.machine().
/// </summary>
public static string MachineName { get; private set; }
internal static bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

#if PYTHON2
internal static bool IsPython2 = true;
Expand Down Expand Up @@ -221,13 +172,8 @@ internal static void Initialize(bool initSigs = false)

Error = new IntPtr(-1);

// Initialize data about the platform we're running on. We need
// this for the type manager and potentially other details. Must
// happen after caching the python types, above.
InitializePlatformData();

IntPtr dllLocal = IntPtr.Zero;
var loader = LibraryLoader.Get(OperatingSystem);
var loader = LibraryLoader.Instance;

_PyObject_NextNotImplemented = loader.GetFunction(dllLocal, "_PyObject_NextNotImplemented");
PyModuleType = loader.GetFunction(dllLocal, "PyModule_Type");
Expand All @@ -248,53 +194,6 @@ internal static void Initialize(bool initSigs = false)
AssemblyManager.UpdatePath();
}

/// <summary>
/// Initializes the data about platforms.
///
/// This must be the last step when initializing the runtime:
/// GetManagedString needs to have the cached values for types.
/// But it must run before initializing anything outside the runtime
/// because those rely on the platform data.
/// </summary>
private static void InitializePlatformData()
{
IntPtr op;
IntPtr fn;
IntPtr platformModule = PyImport_ImportModule("platform");
IntPtr emptyTuple = PyTuple_New(0);

fn = PyObject_GetAttrString(platformModule, "system");
op = PyObject_Call(fn, emptyTuple, IntPtr.Zero);
OperatingSystemName = GetManagedString(op);
XDecref(op);
XDecref(fn);

fn = PyObject_GetAttrString(platformModule, "machine");
op = PyObject_Call(fn, emptyTuple, IntPtr.Zero);
MachineName = GetManagedString(op);
XDecref(op);
XDecref(fn);

XDecref(emptyTuple);
XDecref(platformModule);

// Now convert the strings into enum values so we can do switch
// statements rather than constant parsing.
OperatingSystemType OSType;
if (!OperatingSystemTypeMapping.TryGetValue(OperatingSystemName, out OSType))
{
OSType = OperatingSystemType.Other;
}
OperatingSystem = OSType;

MachineType MType;
if (!MachineTypeMapping.TryGetValue(MachineName.ToLower(), out MType))
{
MType = MachineType.Other;
}
Machine = MType;
}

internal static void Shutdown()
{
AssemblyManager.Shutdown();
Expand Down
35 changes: 13 additions & 22 deletions Python.Runtime/typemanager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -503,11 +503,11 @@ public static NativeCode Active
{
get
{
switch (Runtime.Machine)
switch (RuntimeInformation.ProcessArchitecture)
{
case MachineType.i386:
case Architecture.X86:
return I386;
case MachineType.x86_64:
case Architecture.X64:
return X86_64;
default:
return null;
Expand Down Expand Up @@ -600,15 +600,12 @@ int MAP_ANONYMOUS
{
get
{
switch (Runtime.OperatingSystem)
{
case OperatingSystemType.Darwin:
return 0x1000;
case OperatingSystemType.Linux:
return 0x20;
default:
throw new NotImplementedException($"mmap is not supported on {Runtime.OperatingSystemName}");
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
return 0x1000;
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
return 0x20;
else
throw new NotImplementedException($"mmap is not supported on this operating system");
}
}

Expand All @@ -633,16 +630,10 @@ public void SetReadExec(IntPtr mappedMemory, int numBytes)

internal static IMemoryMapper CreateMemoryMapper()
{
switch (Runtime.OperatingSystem)
{
case OperatingSystemType.Darwin:
case OperatingSystemType.Linux:
return new UnixMemoryMapper();
case OperatingSystemType.Windows:
return new WindowsMemoryMapper();
default:
throw new NotImplementedException($"No support for {Runtime.OperatingSystemName}");
}
if (Runtime.IsWindows)
return new WindowsMemoryMapper();
else
return new UnixMemoryMapper();
}

/// <summary>
Expand Down