Skip to content
This repository has been archived by the owner on Dec 18, 2017. It is now read-only.

Commit

Permalink
Passing context from native bootstrapper CLR
Browse files Browse the repository at this point in the history
Bonus
  - renaming KatanaMager to ClrBoostrapper
  - removing Helios entry point
  • Loading branch information
moozzyk committed Sep 18, 2015
1 parent 85f82f9 commit a8f5cd4
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 149 deletions.
15 changes: 13 additions & 2 deletions src/Microsoft.Dnx.Host.Clr/DomainManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private int Main(int argc, string[] argv)
},
null);

return RuntimeBootstrapper.Execute(argv, _dnxTfm);
return RuntimeBootstrapper.Execute(argv, _dnxTfm, _info);
}

private Version SelectHighestSupportedDnxVersion(string applicationBase)
Expand Down Expand Up @@ -163,17 +163,28 @@ private Version SelectHighestSupportedDnxVersion(string applicationBase)
[DllImport(Constants.BootstrapperClrName + ".dll")]
private extern static void BindApplicationMain(ref ApplicationMainInfo info);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ApplicationMainInfo
{
[MarshalAs(UnmanagedType.FunctionPtr)]
public MainDelegate Main;

[MarshalAs(UnmanagedType.BStr)]
public string OperatingSystem;

[MarshalAs(UnmanagedType.BStr)]
public string OsVersion;

[MarshalAs(UnmanagedType.BStr)]
public string Architecture;

[MarshalAs(UnmanagedType.BStr)]
public string RuntimeDirectory;

[MarshalAs(UnmanagedType.BStr)]
public string ApplicationBase;

public bool HandleExceptions;
}

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
Expand Down
101 changes: 0 additions & 101 deletions src/Microsoft.Dnx.Host.Clr/EntryPoint.cs

This file was deleted.

38 changes: 16 additions & 22 deletions src/Microsoft.Dnx.Host.Clr/RuntimeBootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,30 @@ namespace Microsoft.Dnx.Host.Clr
{
internal class RuntimeBootstrapper
{
public static int Execute(string[] argv, FrameworkName targetFramework)
public static int Execute(string[] argv, FrameworkName targetFramework, DomainManager.ApplicationMainInfo info)
{
var bootstrapperContext = GetBootstrapperContext();
var bootstrapperContext = GetBootstrapperContext(targetFramework, info);
var bootstrapperType = bootstrapperContext.GetType().Assembly.GetType("Microsoft.Dnx.Host.RuntimeBootstrapper");

var executeMethodInfo = GetBootstrapperType(bootstrapperContext.GetType().Assembly)
.GetMethod("Execute", BindingFlags.Static | BindingFlags.Public, null,
var executeMethodInfo = bootstrapperType.GetMethod("Execute", BindingFlags.Static | BindingFlags.Public, null,
new[] { typeof(string[]), typeof(FrameworkName), bootstrapperContext.GetType() }, null);
return (int)executeMethodInfo.Invoke(null, new object[] { argv, targetFramework, null });
}

// This method is only called by Helios
public static Task<int> ExecuteAsync(string[] argv, FrameworkName targetFramework)
{
var bootstrapperContext = GetBootstrapperContext();

var executeMethodInfo = GetBootstrapperType(bootstrapperContext.GetType().Assembly)
.GetMethod("ExecuteAsync", BindingFlags.Static | BindingFlags.Public, null,
new[] { typeof(string[]), typeof(FrameworkName), bootstrapperContext.GetType() }, null);
return (Task<int>)executeMethodInfo.Invoke(null, new object[] { argv, targetFramework, null });
}

private static Type GetBootstrapperType(Assembly dnxHost)
{
return dnxHost.GetType("Microsoft.Dnx.Host.RuntimeBootstrapper");
return (int)executeMethodInfo.Invoke(null, new object[] { argv, targetFramework, null });
}

private static object GetBootstrapperContext()
private static object GetBootstrapperContext(FrameworkName targetFramework, DomainManager.ApplicationMainInfo info)
{
var dnxHost = Assembly.Load("Microsoft.Dnx.Host");
var bootstrapperContext = Activator.CreateInstance(dnxHost.GetType("Microsoft.Dnx.Host.BootstrapperContext"));
var contextType = dnxHost.GetType("Microsoft.Dnx.Host.BootstrapperContext");
var bootstrapperContext = Activator.CreateInstance(contextType);
contextType.GetProperty("OperatingSystem").SetValue(bootstrapperContext, info.OperatingSystem);
contextType.GetProperty("OsVersion").SetValue(bootstrapperContext, info.OsVersion);
contextType.GetProperty("Architecture").SetValue(bootstrapperContext, info.Architecture);
contextType.GetProperty("RuntimeDirectory").SetValue(bootstrapperContext, info.RuntimeDirectory);
contextType.GetProperty("ApplicationBase").SetValue(bootstrapperContext, info.ApplicationBase);
contextType.GetProperty("TargetFramework").SetValue(bootstrapperContext, targetFramework);
contextType.GetProperty("HandleExceptions").SetValue(bootstrapperContext, info.HandleExceptions);

return bootstrapperContext;
}
}
Expand Down
46 changes: 35 additions & 11 deletions src/dnx.clr/KatanaManager.h → src/dnx.clr/ClrBootstrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ComObject.h"
#include "FileStream.h"
#include "HostAssemblyManager.h"
#include "utils.h"

extern const wchar_t* AppDomainManagerAssemblyName;

Expand All @@ -18,25 +19,33 @@ struct ApplicationMainInfo

/* in */ ApplicationMainDelegate ApplicationMain;

/* out */ BSTR OperatingSystem;

/* out */ BSTR OsVersion;

/* out */ BSTR Architecture;

/* out */ BSTR RuntimeDirectory;

/* out */ BSTR ApplicationBase;

/* out */ bool HandleExceptions;
};

class __declspec(uuid("7E9C5238-60DC-49D3-94AA-53C91FA79F7C")) IKatanaManager : public IUnknown
class __declspec(uuid("7E9C5238-60DC-49D3-94AA-53C91FA79F7C")) IClrBootstrapper : public IUnknown
{
public:
virtual HRESULT InitializeRuntime(LPCWSTR runtimeDirectory, LPCWSTR applicationBase) = 0;
virtual HRESULT InitializeRuntime(LPCWSTR runtimeDirectory, LPCWSTR applicationBase, bool handleExceptions) = 0;

virtual HRESULT BindApplicationMain(ApplicationMainInfo* pInfo) = 0;

virtual HRESULT CallApplicationMain(int argc, PCWSTR* argv) = 0;
};

_COM_SMARTPTR_TYPEDEF(IKatanaManager, __uuidof(IKatanaManager));
_COM_SMARTPTR_TYPEDEF(IClrBootstrapper, __uuidof(IClrBootstrapper));

class KatanaManager :
public IKatanaManager,
class ClrBootstrapper :
public IClrBootstrapper,
public IHostControl
{
CriticalSection _crit;
Expand All @@ -55,19 +64,20 @@ class KatanaManager :

_bstr_t _applicationBase;
_bstr_t _runtimeDirectory;
bool _handleExceptions;

ApplicationMainInfo _applicationMainInfo;

public:

KatanaManager()
ClrBootstrapper()
: m_pHostAssemblyManager{nullptr}
{
_calledInitializeRuntime = false;
_hrInitializeRuntime = E_PENDING;
}

~KatanaManager()
~ClrBootstrapper()
{
if (m_pHostAssemblyManager)
{
Expand All @@ -77,8 +87,8 @@ class KatanaManager :

IUnknown* CastInterface(REFIID riid)
{
if (riid == __uuidof(IKatanaManager))
return static_cast<IKatanaManager*>(this);
if (riid == __uuidof(IClrBootstrapper))
return static_cast<IClrBootstrapper*>(this);
if (riid == __uuidof(IHostControl))
return static_cast<IHostControl*>(this);
if (riid == __uuidof(IHostAssemblyManager))
Expand All @@ -87,16 +97,19 @@ class KatanaManager :
return NULL;
}

HRESULT InitializeRuntime(LPCWSTR runtimeDirectory, LPCWSTR applicationBase)
HRESULT InitializeRuntime(LPCWSTR runtimeDirectory, LPCWSTR applicationBase, bool handleExceptions)
{
Lock lock(&_crit);
if (_calledInitializeRuntime)
{
return _hrInitializeRuntime;
}

HRESULT hr = S_OK;

_applicationBase = applicationBase;
_runtimeDirectory = runtimeDirectory;
_handleExceptions = handleExceptions;

m_pHostAssemblyManager = new HostAssemblyManager(runtimeDirectory);
m_pHostAssemblyManager->AddRef();
Expand Down Expand Up @@ -146,6 +159,17 @@ class KatanaManager :
_applicationMainInfo = *pInfo;
pInfo->RuntimeDirectory = _runtimeDirectory.copy();
pInfo->ApplicationBase = _applicationBase.copy();
pInfo->OperatingSystem = _bstr_t(L"Windows").copy();
pInfo->OsVersion = _bstr_t(dnx::utils::get_windows_version()).copy();
pInfo->Architecture =
#if defined(AMD64)
_bstr_t(L"x64")
#else
_bstr_t(L"x86")
#endif
.copy();
pInfo->HandleExceptions = _handleExceptions;

return S_OK;
}

Expand All @@ -162,7 +186,7 @@ class KatanaManager :
/* [out] */ void **ppObject)
{
HRESULT hr = S_OK;
_HR(static_cast<IKatanaManager*>(this)->QueryInterface(riid, ppObject));
_HR(static_cast<IClrBootstrapper*>(this)->QueryInterface(riid, ppObject));
return hr;
}

Expand Down
18 changes: 9 additions & 9 deletions src/dnx.clr/dnx.clr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@

#include "stdafx.h"

#include "KatanaManager.h"
#include "ClrBootstrapper.h"
#include "app_main.h"

IKatanaManagerPtr g_katanaManager;
IClrBootstrapperPtr g_clrBootstrapper;

extern "C" __declspec(dllexport) HRESULT __stdcall CallApplicationMain(PCALL_APPLICATION_MAIN_DATA data)
{
HRESULT hr = S_OK;

IKatanaManagerPtr manager = new ComObject<KatanaManager, IKatanaManager>();
IClrBootstrapperPtr bootstrapper = new ComObject<ClrBootstrapper, IClrBootstrapper>();

g_katanaManager = manager;
g_clrBootstrapper = bootstrapper;

hr = manager->InitializeRuntime(data->runtimeDirectory, data->applicationBase);
hr = bootstrapper->InitializeRuntime(data->runtimeDirectory, data->applicationBase, data->handleExceptions);
if (SUCCEEDED(hr))
{
g_katanaManager = NULL;
data->exitcode = manager->CallApplicationMain(data->argc, data->argv);
g_clrBootstrapper = NULL;
data->exitcode = bootstrapper->CallApplicationMain(data->argc, data->argv);
}
else
{
Expand All @@ -38,8 +38,8 @@ extern "C" __declspec(dllexport) HRESULT __stdcall BindApplicationMain(Applicati
HRESULT hr = S_OK;

// LOCK g_
IKatanaManagerPtr katanaManager = g_katanaManager;
IClrBootstrapperPtr bootstrapper = g_clrBootstrapper;

_HR(katanaManager->BindApplicationMain(pInfo));
_HR(bootstrapper->BindApplicationMain(pInfo));
return hr;
}
2 changes: 1 addition & 1 deletion src/dnx.clr/dnx.clr.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
<ClInclude Include="FileStream.h" />
<ClInclude Include="HostAssemblyManager.h" />
<ClInclude Include="HostAssemblyStore.h" />
<ClInclude Include="KatanaManager.h" />
<ClInclude Include="ClrBootstrapper.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="version.h" />
Expand Down
6 changes: 3 additions & 3 deletions src/dnx.clr/dnx.clr.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
<ClInclude Include="FileStream.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KatanaManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="version.h">
<Filter>Header Files</Filter>
</ClInclude>
Expand All @@ -42,6 +39,9 @@
<ClInclude Include="HostAssemblyStore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClrBootstrapper.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
Expand Down
Loading

1 comment on commit a8f5cd4

@davidfowl
Copy link
Member

Choose a reason for hiding this comment

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

Add the announcement 😄

Please sign in to comment.