Skip to content

Commit 0650ae7

Browse files
committed
[WIP] Remove android_coreclr_initialize and modify the existing one
Signature is altered on Android, by adding a pointer to the host contract structure. The host contract structure also gains a new pointer, `external_assembly_probe` (proposed in dotnet#112706) which is used, if present, when `bundle_probe` is `nullptr` or if it returns `false` when called. Either `bundle_probe` or `external_assembly_probe` must be set in the contract
1 parent cc4e734 commit 0650ae7

File tree

8 files changed

+42
-166
lines changed

8 files changed

+42
-166
lines changed

src/coreclr/dlls/mscoree/exports.cpp

+7-130
Original file line numberDiff line numberDiff line change
@@ -147,31 +147,6 @@ static void InitializeStartupFlags(STARTUP_FLAGS* startupFlagsRef)
147147
*startupFlagsRef = startupFlags;
148148
}
149149

150-
#if defined(TARGET_ANDROID)
151-
static void ConvertConfigPropertiesToUnicode(
152-
const host_configuration_properties* properties,
153-
LPCWSTR** propertyKeysWRef,
154-
LPCWSTR** propertyValuesWRef)
155-
{
156-
LPCWSTR* propertyKeysW = new (nothrow) LPCWSTR[properties->nitems];
157-
ASSERTE_ALL_BUILDS(propertyKeysW != nullptr);
158-
159-
LPCWSTR* propertyValuesW = new (nothrow) LPCWSTR[properties->nitems];
160-
ASSERTE_ALL_BUILDS(propertyValuesW != nullptr);
161-
162-
for (size_t propertyIndex = 0; propertyIndex < properties->nitems; ++propertyIndex)
163-
{
164-
host_configuration_property const& prop = properties->data[propertyIndex];
165-
propertyKeysW[propertyIndex] = prop.name;
166-
propertyValuesW[propertyIndex] = prop.value;
167-
}
168-
169-
*propertyKeysWRef = propertyKeysW;
170-
*propertyValuesWRef = propertyValuesW;
171-
}
172-
173-
#else // TARGET_ANDROID
174-
175150
static void ConvertConfigPropertiesToUnicode(
176151
const char** propertyKeys,
177152
const char** propertyValues,
@@ -230,7 +205,6 @@ static void ConvertConfigPropertiesToUnicode(
230205
*propertyKeysWRef = propertyKeysW;
231206
*propertyValuesWRef = propertyValuesW;
232207
}
233-
#endif // !TARGET_ANDROID
234208
coreclr_error_writer_callback_fn g_errorWriter = nullptr;
235209

236210
//
@@ -256,103 +230,6 @@ GetInfoForMethodDelegate getInfoForMethodDelegate = NULL;
256230
extern "C" int coreclr_create_delegate(void*, unsigned int, const char*, const char*, const char*, void**);
257231
#endif //FEATURE_GDBJIT
258232

259-
#if defined(TARGET_ANDROID)
260-
extern "C"
261-
NOINLINE
262-
DLLEXPORT
263-
int android_coreclr_initialize(
264-
const char* appName,
265-
const char16_t* appDomainFriendlyName,
266-
host_runtime_contract* hostContract,
267-
const host_configuration_properties* properties,
268-
void **hostHandle,
269-
unsigned int* domainId)
270-
{
271-
HostingApiFrameHolder apiFrameHolder(_ReturnAddress());
272-
273-
if (properties == nullptr) { [[unlikely]]
274-
LogErrorToLogcat(ANDROID_LOG_FATAL, "Initialization routine was not passed the required configuration properties pointer.");
275-
return HOST_E_INVALIDOPERATION;
276-
}
277-
278-
if (properties->data == nullptr) { [[unlikely]]
279-
LogErrorToLogcat(ANDROID_LOG_FATAL, "Initialization routine was not passed valid configuration properties data.");
280-
return HOST_E_INVALIDOPERATION;
281-
}
282-
283-
if (hostContract == nullptr) { [[unlikely]]
284-
LogErrorToLogcat(ANDROID_LOG_FATAL, "Initialization routine was not passed the required host contract pointer.");
285-
return HOST_E_INVALIDOPERATION;
286-
}
287-
288-
if (hostContract->pinvoke_override == nullptr) { [[unlikely]]
289-
LogErrorToLogcat(ANDROID_LOG_FATAL, "Host contract isn't initialized properly: missing p/invoke override handler.");
290-
return HOST_E_INVALIDOPERATION;
291-
}
292-
293-
if (hostContract->android_bundle_probe == nullptr) { [[unlikely]]
294-
LogErrorToLogcat(ANDROID_LOG_FATAL, "Host contract isn't initialized properly: missing bundle probe handler.");
295-
return HOST_E_INVALIDOPERATION;
296-
}
297-
298-
LPCWSTR* propertyKeysW = nullptr;
299-
LPCWSTR* propertyValuesW = nullptr;
300-
ConvertConfigPropertiesToUnicode (properties, &propertyKeysW, &propertyValuesW);
301-
302-
// Android doesn't have executables as such (at least as far as Android applications are concerned),
303-
// so we will use application name (package name) as the "executable path" here.
304-
DWORD error = PAL_InitializeCoreCLR(appName, g_coreclr_embedded);
305-
HRESULT hr = HRESULT_FROM_WIN32(error);
306-
307-
// If PAL initialization failed, then we should return right away and avoid
308-
// calling any other APIs because they can end up calling into the PAL layer again.
309-
if (FAILED(hr))
310-
{
311-
return hr;
312-
}
313-
314-
HostInformation::SetContract(hostContract);
315-
PInvokeOverride::SetPInvokeOverride(hostContract->pinvoke_override, PInvokeOverride::Source::RuntimeConfiguration);
316-
317-
ReleaseHolder<ICLRRuntimeHost4> host;
318-
hr = CorHost2::CreateObject(IID_ICLRRuntimeHost4, (void**)&host);
319-
IfFailRet(hr);
320-
321-
static Bundle bundle(appName, hostContract->android_bundle_probe);
322-
Bundle::AppBundle = &bundle;
323-
324-
// This will take ownership of propertyKeysWTemp and propertyValuesWTemp
325-
Configuration::InitializeConfigurationKnobs(static_cast<int>(properties->nitems), propertyKeysW, propertyValuesW);
326-
327-
STARTUP_FLAGS startupFlags;
328-
InitializeStartupFlags(&startupFlags);
329-
330-
hr = host->SetStartupFlags(startupFlags);
331-
IfFailRet(hr);
332-
333-
hr = host->Start();
334-
IfFailRet(hr);
335-
336-
hr = host->CreateAppDomainWithManager(
337-
appDomainFriendlyName,
338-
APPDOMAIN_SECURITY_DEFAULT,
339-
nullptr, // Name of the assembly that contains the AppDomainManager implementation
340-
nullptr, // The AppDomainManager implementation type name
341-
static_cast<int>(properties->nitems),
342-
propertyKeysW,
343-
propertyValuesW,
344-
(DWORD *)domainId);
345-
346-
if (SUCCEEDED(hr))
347-
{
348-
host.SuppressRelease();
349-
*hostHandle = host;
350-
}
351-
return hr;
352-
}
353-
354-
#endif // TARGET_ANDROID
355-
356233
//
357234
// Initialize the CoreCLR. Creates and starts CoreCLR host and creates an app domain
358235
//
@@ -372,6 +249,9 @@ extern "C"
372249
NOINLINE
373250
DLLEXPORT
374251
int coreclr_initialize(
252+
#if defined(TARGET_ANDROID)
253+
host_runtime_contract* contract,
254+
#endif
375255
const char* exePath,
376256
const char* appDomainFriendlyName,
377257
int propertyCount,
@@ -380,14 +260,13 @@ int coreclr_initialize(
380260
void** hostHandle,
381261
unsigned int* domainId)
382262
{
383-
#if !defined(TARGET_ANDROID)
384263
HRESULT hr;
385264

386265
LPCWSTR* propertyKeysW;
387266
LPCWSTR* propertyValuesW;
388267
BundleProbeFn* bundleProbe = nullptr;
389268
PInvokeOverrideFn* pinvokeOverride = nullptr;
390-
host_runtime_contract* hostContract = nullptr;
269+
host_runtime_contract* hostContract = contract;
391270

392271
#ifdef TARGET_UNIX
393272
HostingApiFrameHolder apiFrameHolder(_ReturnAddress());
@@ -432,9 +311,10 @@ int coreclr_initialize(
432311

433312
ConstWStringHolder appDomainFriendlyNameW = StringToUnicode(appDomainFriendlyName);
434313

435-
if (bundleProbe != nullptr)
314+
ExternalAssemblyProbeFn* externalAssemblyProbe = contract != nullptr ? contract->external_assembly_probe : nullptr;
315+
if (bundleProbe != nullptr || externalAssemblyProbe != nullptr)
436316
{
437-
static Bundle bundle(exePath, bundleProbe);
317+
static Bundle bundle(exePath, bundleProbe, externalAssemblyProbe);
438318
Bundle::AppBundle = &bundle;
439319
}
440320

@@ -485,9 +365,6 @@ int coreclr_initialize(
485365
#endif
486366
}
487367
return hr;
488-
#else // TARGET_ANDROID
489-
return HOST_E_INVALIDOPERATION;
490-
#endif
491368
}
492369

493370
//

src/coreclr/dlls/mscoree/mscorwks_unixexports.src

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
; Android hosting API
2-
android_coreclr_initialize
3-
41
; Unix hosting API
52
coreclr_create_delegate
63
coreclr_execute_assembly

src/coreclr/hosts/corerun/corerun.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ static int run(const configuration& config)
404404

405405
int result;
406406
result = coreclr_init_func(
407+
#if defined(TARGET_ANDROID)
408+
nullptr, // contract
409+
#endif
407410
exe_path_utf8.c_str(),
408411
"corerun",
409412
propertyCount,

src/coreclr/hosts/inc/coreclrhost.h

+5-13
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,11 @@
3333
CORECLR_HOSTING_API_LINKAGE int CORECLR_CALLING_CONVENTION function(__VA_ARGS__); \
3434
typedef int (CORECLR_CALLING_CONVENTION *function##_ptr)(__VA_ARGS__)
3535

36-
#if defined(TARGET_ANDROID)
37-
CORECLR_HOSTING_API(android_coreclr_initialize,
38-
const char* appName,
39-
const char16_t* appDomainFriendlyName,
40-
host_runtime_contract* hostContract,
41-
const host_configuration_properties* properties,
42-
void **hostHandle,
43-
unsigned int* domainId);
44-
#endif
4536
//
4637
// Initialize the CoreCLR. Creates and starts CoreCLR host and creates an app domain
4738
//
4839
// Parameters:
40+
// hostContract - (Android only) pointer to the host contract structure
4941
// exePath - Absolute path of the executable that invoked the ExecuteAssembly (the native host application)
5042
// appDomainFriendlyName - Friendly name of the app domain that will be created to execute the assembly
5143
// propertyCount - Number of properties (elements of the following two arguments)
@@ -58,6 +50,9 @@ CORECLR_HOSTING_API(android_coreclr_initialize,
5850
// HRESULT indicating status of the operation. S_OK if the assembly was successfully executed
5951
//
6052
CORECLR_HOSTING_API(coreclr_initialize,
53+
#if defined(TARGET_ANDROID)
54+
host_runtime_contract* contract,
55+
#endif
6156
const char* exePath,
6257
const char* appDomainFriendlyName,
6358
int propertyCount,
@@ -163,11 +158,8 @@ CORECLR_HOSTING_API(coreclr_execute_assembly,
163158
//
164159
// Callback types used by the hosts
165160
//
166-
#if defined(TARGET_ANDROID)
167-
using BundleProbeFn = bool(const char* path, void** data_start, int64_t* size);
168-
#else
161+
using ExternalAssemblyProbeFn = bool(const char* path, void** data_start, int64_t* size);
169162
typedef bool(CORECLR_CALLING_CONVENTION BundleProbeFn)(const char* path, int64_t* offset, int64_t* size, int64_t* compressedSize);
170-
#endif
171163
typedef const void* (CORECLR_CALLING_CONVENTION PInvokeOverrideFn)(const char* libraryName, const char* entrypointName);
172164

173165

src/coreclr/inc/bundle.h

+2-9
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,18 @@ class Bundle;
1818
struct BundleFileLocation
1919
{
2020
INT64 Size;
21-
#if defined(TARGET_ANDROID)
2221
void* DataStart;
23-
constexpr static INT64 Offset = 0;
24-
constexpr static INT64 UncompresedSize = 0;
25-
#else
2622
INT64 Offset;
2723
INT64 UncompresedSize;
28-
#endif
2924

3025
BundleFileLocation()
3126
{
3227
LIMITED_METHOD_CONTRACT;
3328

3429
Size = 0;
35-
#if defined(TARGET_ANDROID)
3630
DataStart = INVALID_HANDLE_VALUE;
37-
#else
3831
Offset = 0;
3932
UncompresedSize = 0;
40-
#endif
4133
}
4234

4335
static BundleFileLocation Invalid() { LIMITED_METHOD_CONTRACT; return BundleFileLocation(); }
@@ -54,7 +46,7 @@ struct BundleFileLocation
5446
class Bundle
5547
{
5648
public:
57-
Bundle(LPCSTR bundlePath, BundleProbeFn *probe);
49+
Bundle(LPCSTR bundlePath, BundleProbeFn *probe, ExternalAssemblyProbeFn* externalAssemblyProbe = nullptr);
5850
BundleFileLocation Probe(const SString& path, bool pathIsBundleRelative = false) const;
5951

6052
const SString &Path() const { LIMITED_METHOD_CONTRACT; return m_path; }
@@ -70,6 +62,7 @@ class Bundle
7062
#endif
7163
SString m_path; // The path to single-file executable
7264
BundleProbeFn *m_probe;
65+
ExternalAssemblyProbeFn *m_externalAssemblyProbe;
7366

7467
SString m_basePath; // The prefix to denote a path within the bundle
7568
COUNT_T m_basePathLength = 0;

src/coreclr/vm/bundle.cpp

+21-7
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ const SString &BundleFileLocation::AppName() const
4242
}
4343
#endif
4444

45-
Bundle::Bundle(LPCSTR bundlePath, BundleProbeFn *probe)
45+
Bundle::Bundle(LPCSTR bundlePath, BundleProbeFn *probe, ExternalAssemblyProbeFn* externalAssemblyProbe)
4646
{
4747
STANDARD_VM_CONTRACT;
4848

49-
_ASSERTE(probe != nullptr);
49+
_ASSERTE(probe != nullptr || externalAssemblyProbe != nullptr);
5050
m_probe = probe;
51+
m_externalAssemblyProbe = externalAssemblyProbe;
5152
#if defined(TARGET_ANDROID)
5253
m_appName.SetUTF8(bundlePath);
5354
#else
@@ -105,11 +106,24 @@ BundleFileLocation Bundle::Probe(const SString& path, bool pathIsBundleRelative)
105106
#endif // !TARGET_ANDROID
106107
INT64 fileSize = 0;
107108
INT64 compressedSize = 0;
109+
bool assemblyFound = false;
108110

109-
#if defined(TARGET_ANDROID)
110-
m_probe(utf8Path, &loc.DataStart, &loc.Size);
111-
#else
112-
m_probe(utf8Path, &loc.Offset, &fileSize, &compressedSize);
111+
if (m_probe != nullptr)
112+
{
113+
assemblyFound = m_probe(utf8Path, &loc.Offset, &fileSize, &compressedSize);
114+
loc.DataStart = nullptr; // Location is based on the bundle file start
115+
}
116+
117+
if (!assemblyFound && m_externalAssemblyProbe != nullptr)
118+
{
119+
m_externalAssemblyProbe (utf8Path, &loc.DataStart, &fileSize);
120+
121+
// Host takes care of decompression, if any
122+
compressedSize = 0;
123+
124+
// Must always be 0 in this mode, since loc.DataStart points to the beginning of data
125+
loc.Offset = 0;
126+
}
113127

114128
if (compressedSize)
115129
{
@@ -121,7 +135,7 @@ BundleFileLocation Bundle::Probe(const SString& path, bool pathIsBundleRelative)
121135
loc.Size = fileSize;
122136
loc.UncompresedSize = 0;
123137
}
124-
#endif
138+
125139
return loc;
126140
}
127141

src/coreclr/vm/peimagelayout.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ FlatImageLayout::FlatImageLayout(PEImage* pOwner)
638638
#else // !TARGET_ANDROID
639639
INT64 size = pOwner->GetSize();
640640
HANDLE mapBegin = pOwner->AndroidGetDataStart();
641-
if (size == 0) {
641+
if (size == 0 || mapBegin == nullptr) {
642642
// TODO: throw something
643643
}
644644
#endif // TARGET_ANDROID

src/native/corehost/host_runtime_contract.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ struct host_runtime_contract
3838
size_t value_buffer_size,
3939
void* contract_context);
4040

41-
#if defined(TARGET_ANDROID)
42-
bool(HOST_CONTRACT_CALLTYPE* android_bundle_probe)(
41+
// Probe the host for `path`. Sets pointer to data start and its size, if found.
42+
bool(HOST_CONTRACT_CALLTYPE* external_assembly_probe)(
4343
const char* path,
4444
void **data_start,
4545
int64_t* size);
46-
#endif
46+
4747
// Probe an app bundle for `path`. Sets its location (`offset`, `size`) in the bundle if found.
4848
// Returns true if found, false otherwise.
4949
bool(HOST_CONTRACT_CALLTYPE* bundle_probe)(

0 commit comments

Comments
 (0)