|
| 1 | +// Licensed to the .NET Foundation under one or more agreements. |
| 2 | +// The .NET Foundation licenses this file to you under the MIT license. |
| 3 | +// |
| 4 | + |
| 5 | +#include <cstdio> |
| 6 | +#include <vector> |
| 7 | +#include <emscripten.h> |
| 8 | + |
| 9 | +#include <pal.h> |
| 10 | +#include <minipal/utils.h> |
| 11 | +#include <host_runtime_contract.h> |
| 12 | + |
| 13 | +static void log_error_info(const char* line) |
| 14 | +{ |
| 15 | + std::fprintf(stderr, "log error: %s\n", line); |
| 16 | +} |
| 17 | + |
| 18 | +// The current CoreCLR instance details. |
| 19 | +static void* CurrentClrInstance; |
| 20 | +static unsigned int CurrentAppDomainId; |
| 21 | + |
| 22 | +typedef void (*coreclr_error_writer_callback_fn)(const char* line); |
| 23 | +extern "C" |
| 24 | +{ |
| 25 | + pal::hresult_t coreclr_initialize( |
| 26 | + const char* exePath, |
| 27 | + const char* appDomainFriendlyName, |
| 28 | + int propertyCount, |
| 29 | + const char** propertyKeys, |
| 30 | + const char** propertyValues, |
| 31 | + void** hostHandle, |
| 32 | + unsigned int* domainId); |
| 33 | + |
| 34 | + pal::hresult_t coreclr_shutdown_2( |
| 35 | + void* hostHandle, |
| 36 | + unsigned int domainId, |
| 37 | + int* latchedExitCode); |
| 38 | + |
| 39 | + pal::hresult_t coreclr_execute_assembly( |
| 40 | + void* hostHandle, |
| 41 | + unsigned int domainId, |
| 42 | + int argc, |
| 43 | + const char** argv, |
| 44 | + const char* managedAssemblyPath, |
| 45 | + unsigned int* exitCode); |
| 46 | + |
| 47 | + pal::hresult_t coreclr_create_delegate( |
| 48 | + void* hostHandle, |
| 49 | + unsigned int domainId, |
| 50 | + const char* entryPointAssemblyName, |
| 51 | + const char* entryPointTypeName, |
| 52 | + const char* entryPointMethodName, |
| 53 | + void** delegate); |
| 54 | + |
| 55 | + pal::hresult_t coreclr_set_error_writer( |
| 56 | + coreclr_error_writer_callback_fn error_writer); |
| 57 | + |
| 58 | + const void* SystemResolveDllImport(const char* name); |
| 59 | + const void* SystemJSResolveDllImport(const char* name); |
| 60 | + const void* SystemJSInteropResolveDllImport(const char* name); |
| 61 | + const void* GlobalizationResolveDllImport(const char* name); |
| 62 | + const void* CompressionResolveDllImport(const char* name); |
| 63 | +} |
| 64 | + |
| 65 | +bool bundle_probe(const char* path, int64_t* offset, int64_t* size, int64_t* compressedSize) |
| 66 | +{ |
| 67 | + // WASMTODO: Not implemented |
| 68 | + return false; |
| 69 | +} |
| 70 | + |
| 71 | +bool external_assembly_probe(const char* path, /*out*/ void **data_start, /*out*/ int64_t* size) |
| 72 | +{ |
| 73 | + // WASMTODO: Not implemented |
| 74 | + return false; |
| 75 | +} |
| 76 | + |
| 77 | +size_t get_runtime_property(const char* key, char* value_buffer, size_t value_buffer_size, void* contract_context) |
| 78 | +{ |
| 79 | + // WASMTODO: Not implemented |
| 80 | + return -1; |
| 81 | +} |
| 82 | + |
| 83 | +const void* pinvoke_override(const char* library_name, const char* entry_point_name) |
| 84 | +{ |
| 85 | + if (strcmp(library_name, "libSystem.Native") == 0) |
| 86 | + { |
| 87 | + return SystemResolveDllImport(entry_point_name); |
| 88 | + } |
| 89 | + if (strcmp(library_name, "libSystem.JavaScript") == 0) |
| 90 | + { |
| 91 | + return SystemJSResolveDllImport(entry_point_name); |
| 92 | + } |
| 93 | + if (strcmp(library_name, "libSystem.Runtime.InteropServices.JavaScript") == 0) |
| 94 | + { |
| 95 | + return SystemJSInteropResolveDllImport(entry_point_name); |
| 96 | + } |
| 97 | + if (strcmp(library_name, "libSystem.Globalization.Native") == 0) |
| 98 | + { |
| 99 | + return GlobalizationResolveDllImport(entry_point_name); |
| 100 | + } |
| 101 | + if (strcmp(library_name, "libSystem.IO.Compression.Native") == 0) |
| 102 | + { |
| 103 | + return CompressionResolveDllImport(entry_point_name); |
| 104 | + } |
| 105 | + |
| 106 | + return nullptr; |
| 107 | +} |
| 108 | + |
| 109 | +static int run() |
| 110 | +{ |
| 111 | + pal::string_t exe_path; |
| 112 | + pal::string_t tpa; |
| 113 | + pal::string_t app; |
| 114 | + pal::getenv("CWD", &exe_path); |
| 115 | + pal::getenv("TRUSTED_PLATFORM_ASSEMBLIES", &tpa); |
| 116 | + pal::getenv("APP", &app); |
| 117 | + const pal::string_t app_domain_name = "corehost"; |
| 118 | + |
| 119 | + // Set base initialization properties. |
| 120 | + std::vector<const char*> propertyKeys; |
| 121 | + std::vector<const char*> propertyValues; |
| 122 | + |
| 123 | + propertyKeys.push_back(HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES); |
| 124 | + propertyValues.push_back(tpa.c_str()); |
| 125 | + propertyKeys.push_back(HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES); |
| 126 | + propertyValues.push_back(exe_path.c_str()); |
| 127 | + |
| 128 | + host_runtime_contract host_contract = { sizeof(host_runtime_contract), nullptr }; |
| 129 | + host_contract.get_runtime_property = &get_runtime_property; |
| 130 | + host_contract.bundle_probe = &bundle_probe; |
| 131 | + host_contract.pinvoke_override = &pinvoke_override; |
| 132 | + host_contract.external_assembly_probe = &external_assembly_probe; |
| 133 | + |
| 134 | + pal::char_t buffer[STRING_LENGTH("0xffffffffffffffff")]; |
| 135 | + pal::snwprintf(buffer, ARRAY_SIZE(buffer), _X("0x%zx"), (size_t)(&host_contract)); |
| 136 | + |
| 137 | + propertyKeys.push_back(HOST_PROPERTY_RUNTIME_CONTRACT); |
| 138 | + propertyValues.push_back(buffer); |
| 139 | + |
| 140 | + coreclr_set_error_writer(log_error_info); |
| 141 | + |
| 142 | + // printf("BEGIN: call coreclr_initialize\n"); |
| 143 | + int retval = coreclr_initialize(exe_path.c_str(), app_domain_name.c_str(), (int)propertyKeys.size(), propertyKeys.data(), propertyValues.data(), &CurrentClrInstance, &CurrentAppDomainId); |
| 144 | + // printf("END: call coreclr_initialize\n"); |
| 145 | + |
| 146 | + if (retval < 0) |
| 147 | + { |
| 148 | + std::fprintf(stderr, "coreclr_initialize failed - Error: 0x%08x\n", retval); |
| 149 | + return -1; |
| 150 | + } |
| 151 | + else |
| 152 | + { |
| 153 | + // printf("coreclr_initialize succeeded - retval: 0x%08x\n", retval); |
| 154 | + } |
| 155 | + |
| 156 | + int exit_code; |
| 157 | + // printf("BEGIN: call coreclr_execute_assembly\n"); |
| 158 | + retval = coreclr_execute_assembly(CurrentClrInstance, CurrentAppDomainId, 0, nullptr, app.c_str(), (uint32_t*)&exit_code); |
| 159 | + // printf("END: call coreclr_execute_assembly\n"); |
| 160 | + |
| 161 | + if (retval < 0) |
| 162 | + { |
| 163 | + std::fprintf(stderr, "coreclr_execute_assembly failed - Error: 0x%08x\n", retval); |
| 164 | + return -1; |
| 165 | + } |
| 166 | + |
| 167 | + int latched_exit_code = 0; |
| 168 | + // printf("BEGIN: call coreclr_shutdown_2\n"); |
| 169 | + retval = coreclr_shutdown_2(CurrentClrInstance, CurrentAppDomainId, &latched_exit_code); |
| 170 | + // printf("END: call coreclr_shutdown_2\n"); |
| 171 | + if (retval < 0) |
| 172 | + { |
| 173 | + std::fprintf(stderr, "coreclr_shutdown_2 failed - Error: 0x%08x\n", retval); |
| 174 | + exit_code = -1; |
| 175 | + } |
| 176 | + |
| 177 | + return retval; |
| 178 | +} |
| 179 | + |
| 180 | +int main() |
| 181 | +{ |
| 182 | + int retval = run(); |
| 183 | + |
| 184 | + return retval; |
| 185 | +} |
0 commit comments