Skip to content

Commit

Permalink
Extend the Unix hosting API
Browse files Browse the repository at this point in the history
This change modifies the Unix hosting API so that the hosting app can create
as many managed delegates as it needs and execute them as many times it wants.
The new API contains separate functions to initialize and shutdown CoreCLR
and a function to create a delegate.
The current ExecuteAssembly function behavior stays unmodified for now to
ensure that dnx that uses that API and that pulls the binary libcoreclr
is not broken.
After the dnx is updated to use the new coreclr_create_delegate API, I'll remove
the ExecuteAssembly.

Also done:
1) Added support for comments and skipping empty lines in the mscorwks_unixexports.src.
2) Restructured the mscorwks_unixexports.src
3) Added coreclr_execute_assembly to the unixinterface.cpp / exports
4) Modified coreruncommon.cpp to use the new hosting API
  • Loading branch information
janvorli committed Jul 16, 2015
1 parent bff51f7 commit 441a977
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 95 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function(generate_exports_file inputFilename outputFilename)
add_custom_command(
OUTPUT ${outputFilename}
COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${inputFilename} >${outputFilename}
DEPENDS ${inputFilename}
DEPENDS ${inputFilename} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT}
COMMENT "Generating exports file ${outputFilename}"
)
set_source_files_properties(${outputFilename}
Expand Down
7 changes: 6 additions & 1 deletion generateexportedsymbols.awk
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
# Remove the CR character in case the sources are mapped from
# a Windows share and contain CRLF line endings
gsub(/\r/,"", $0);
print "_" $0;

# Skip empty lines and comment lines starting with semicolon
if (NF && !match($0, /^[:space:]*;/))
{
print "_" $0;
}
}
7 changes: 6 additions & 1 deletion generateversionscript.awk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ BEGIN {
# Remove the CR character in case the sources are mapped from
# a Windows share and contain CRLF line endings
gsub(/\r/,"", $0);
print " " $0 ";";

# Skip empty lines and comment lines starting with semicolon
if (NF && !match($0, /^[:space:]*;/))
{
print " " $0 ";";
}
}
END {
print " local: *;"
Expand Down
121 changes: 77 additions & 44 deletions src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,31 @@ static const char * const coreClrDll = "libcoreclr.dylib";
static const char * const coreClrDll = "libcoreclr.so";
#endif

// Windows types used by the ExecuteAssembly function
typedef unsigned int DWORD;
typedef const char16_t* LPCWSTR;
typedef const char* LPCSTR;
typedef int32_t HRESULT;

#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)

// Prototype of the ExecuteAssembly function from the libcoreclr.do
typedef HRESULT (*ExecuteAssemblyFunction)(
LPCSTR exePath,
LPCSTR coreClrPath,
LPCSTR appDomainFriendlyName,
int propertyCount,
LPCSTR* propertyKeys,
LPCSTR* propertyValues,
int argc,
LPCSTR* argv,
LPCSTR managedAssemblyPath,
LPCSTR entryPointAssemblyName,
LPCSTR entryPointTypeName,
LPCSTR entryPointMethodsName,
DWORD* exitCode);
#define SUCCEEDED(Status) ((Status) >= 0)

// Prototype of the coreclr_initialize function from the libcoreclr.so
typedef int (*InitializeCoreCLRFunction)(
const char* exePath,
const char* appDomainFriendlyName,
int propertyCount,
const char** propertyKeys,
const char** propertyValues,
void** hostHandle,
unsigned int* domainId);

// Prototype of the coreclr_shutdown function from the libcoreclr.so
typedef int (*ShutdownCoreCLRFunction)(
void* hostHandle,
unsigned int domainId);

// Prototype of the coreclr_execute_assembly function from the libcoreclr.so
typedef int (*ExecuteAssemblyFunction)(
void* hostHandle,
unsigned int domainId,
int argc,
const char** argv,
const char* managedAssemblyPath,
unsigned int* exitCode);

bool GetAbsolutePath(const char* path, std::string& absolutePath)
{
Expand Down Expand Up @@ -233,8 +235,23 @@ int ExecuteManagedAssembly(
void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
if (coreclrLib != nullptr)
{
ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
if (executeAssembly != nullptr)
InitializeCoreCLRFunction initializeCoreCLR = (InitializeCoreCLRFunction)dlsym(coreclrLib, "coreclr_initialize");
ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "coreclr_execute_assembly");
ShutdownCoreCLRFunction shutdownCoreCLR = (ShutdownCoreCLRFunction)dlsym(coreclrLib, "coreclr_shutdown");

if (initializeCoreCLR == nullptr)
{
fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n");
}
else if (executeAssembly == nullptr)
{
fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n");
}
else if (shutdownCoreCLR == nullptr)
{
fprintf(stderr, "Function coreclr_shutdown not found in the libcoreclr.so\n");
}
else
{
// Allowed property names:
// APPBASE
Expand Down Expand Up @@ -272,30 +289,46 @@ int ExecuteManagedAssembly(
"UseLatestBehaviorWhenTFMNotSpecified"
};

HRESULT st = executeAssembly(
currentExeAbsolutePath,
coreClrDllPath.c_str(),
"unixcorerun",
sizeof(propertyKeys) / sizeof(propertyKeys[0]),
propertyKeys,
propertyValues,
managedAssemblyArgc,
managedAssemblyArgv,
managedAssemblyAbsolutePath,
NULL,
NULL,
NULL,
(DWORD*)&exitCode);
void* hostHandle;
unsigned int domainId;

int st = initializeCoreCLR(
currentExeAbsolutePath,
"unixcorerun",
sizeof(propertyKeys) / sizeof(propertyKeys[0]),
propertyKeys,
propertyValues,
&hostHandle,
&domainId);

if (!SUCCEEDED(st))
{
fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st);
fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st);
exitCode = -1;
}
}
else
{
fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n");
else
{
st = executeAssembly(
hostHandle,
domainId,
managedAssemblyArgc,
managedAssemblyArgv,
managedAssemblyAbsolutePath,
(unsigned int*)&exitCode);

if (!SUCCEEDED(st))
{
fprintf(stderr, "coreclr_execute_assembly failed - status: 0x%08x\n", st);
exitCode = -1;
}

st = shutdownCoreCLR(hostHandle, domainId);
if (!SUCCEEDED(st))
{
fprintf(stderr, "coreclr_shutdown failed - status: 0x%08x\n", st);
exitCode = -1;
}
}
}

if (dlclose(coreclrLib) != 0)
Expand Down
33 changes: 24 additions & 9 deletions src/dlls/mscoree/mscorwks_unixexports.src
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
; Unix hosting API
coreclr_create_delegate
coreclr_execute_assembly
coreclr_initialize
coreclr_shutdown

; Obsolete Unix hosting API, to be removed
ExecuteAssembly

; PAL initialization and module registration
PAL_InitializeCoreCLR
PAL_RegisterModule
PAL_UnregisterModule

; Functions exported by the coreclr
CoreDllMain
DllMain
GetCLRRuntimeHost

; Functions used by CoreFX
EnsureOpenSslInitialized
ForkAndExecProcess

; Win32 API and other PAL functions used by the mscorlib
CloseHandle
CoCreateGuid
CopyFileW
CoreDllMain
CoTaskMemAlloc
CoTaskMemFree
CreateDirectoryW
Expand All @@ -10,19 +33,14 @@ CreateFileW
CreateMutexW
CreateSemaphoreW
DeleteFileW
DllMain
DuplicateHandle
EnsureOpenSslInitialized
ExecuteAssembly
FindClose
FindFirstFileW
FindNextFileW
FlushFileBuffers
ForkAndExecProcess
FormatMessageW
FreeEnvironmentStringsW
GetACP
GetCLRRuntimeHost
GetConsoleCP
GetConsoleOutputCP
GetCurrentDirectoryW
Expand Down Expand Up @@ -53,10 +71,7 @@ MultiByteToWideChar
OpenEventW
OpenMutexW
OpenSemaphoreW
PAL_InitializeCoreCLR
PAL_Random
PAL_RegisterModule
PAL_UnregisterModule
QueryPerformanceCounter
QueryPerformanceFrequency
RaiseException
Expand Down
Loading

0 comments on commit 441a977

Please sign in to comment.