summaryrefslogtreecommitdiff
path: root/src/ToolBox/superpmi/superpmi/jithost.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ToolBox/superpmi/superpmi/jithost.cpp')
-rw-r--r--src/ToolBox/superpmi/superpmi/jithost.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/ToolBox/superpmi/superpmi/jithost.cpp b/src/ToolBox/superpmi/superpmi/jithost.cpp
new file mode 100644
index 0000000000..cb61e48de2
--- /dev/null
+++ b/src/ToolBox/superpmi/superpmi/jithost.cpp
@@ -0,0 +1,120 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+#include "standardpch.h"
+#include "superpmi.h"
+#include "jitinstance.h"
+#include "icorjitinfo.h"
+#include "jithost.h"
+
+// Look for 'key' as an environment variable named COMPlus_<key>. The returned value
+// is nullptr if it is not found, or a string if found. If not nullptr, the returned
+// value must be freed with jitInstance.freeLongLivedArray(value).
+wchar_t* GetCOMPlusVariable(const wchar_t* key, JitInstance& jitInstance)
+{
+ static const wchar_t Prefix[] = W("COMPlus_");
+ static const size_t PrefixLen = (sizeof(Prefix) / sizeof(Prefix[0])) - 1;
+
+ // Prepend "COMPlus_" to the provided key
+ size_t keyLen = wcslen(key);
+ size_t keyBufferLen = keyLen + PrefixLen + 1;
+ wchar_t* keyBuffer = reinterpret_cast<wchar_t*>(jitInstance.allocateArray(static_cast<ULONG>(sizeof(wchar_t) * keyBufferLen)));
+ wcscpy_s(keyBuffer, keyBufferLen, Prefix);
+ wcscpy_s(&keyBuffer[PrefixLen], keyLen + 1, key);
+
+ // Look up the environment variable
+ DWORD valueLen = GetEnvironmentVariableW(keyBuffer, nullptr, 0);
+ if (valueLen == 0)
+ {
+ jitInstance.freeArray(keyBuffer);
+ return nullptr;
+ }
+
+ // Note this value must live as long as the jit instance does.
+ wchar_t* value = reinterpret_cast<wchar_t*>(jitInstance.allocateLongLivedArray(sizeof(wchar_t) * valueLen));
+ DWORD newValueLen = GetEnvironmentVariableW(keyBuffer, value, valueLen);
+
+ jitInstance.freeArray(keyBuffer);
+ if (valueLen < newValueLen)
+ {
+ jitInstance.freeLongLivedArray(value);
+ return nullptr;
+ }
+
+ return value;
+}
+
+JitHost::JitHost(JitInstance& jitInstance) : jitInstance(jitInstance)
+{
+}
+
+void* JitHost::allocateMemory(size_t size, bool usePageAllocator)
+{
+ return InitIEEMemoryManager(&jitInstance)->ClrVirtualAlloc(nullptr, size, 0, 0);
+}
+
+void JitHost::freeMemory(void* block, bool usePageAllocator)
+{
+ InitIEEMemoryManager(&jitInstance)->ClrVirtualFree(block, 0, 0);
+}
+
+int JitHost::getIntConfigValue(const wchar_t* key, int defaultValue)
+{
+ jitInstance.mc->cr->AddCall("getIntConfigValue");
+ int result = jitInstance.mc->repGetIntConfigValue(key, defaultValue);
+
+ if (result != defaultValue)
+ {
+ return result;
+ }
+
+ // Look for special case keys.
+ if (wcscmp(key, W("SuperPMIMethodContextNumber")) == 0)
+ {
+ return jitInstance.mc->index;
+ }
+
+ // If the result is the default value, probe the environment for
+ // a COMPlus variable with the same name.
+ wchar_t* complus = GetCOMPlusVariable(key, jitInstance);
+ if (complus == nullptr)
+ {
+ return defaultValue;
+ }
+
+ // Parse the value as a hex integer.
+ wchar_t* endPtr;
+ result = static_cast<int>(wcstoul(complus, &endPtr, 16));
+ bool succeeded = (errno != ERANGE) && (endPtr != complus);
+ jitInstance.freeLongLivedArray(complus);
+
+ return succeeded ? result : defaultValue;
+}
+
+const wchar_t* JitHost::getStringConfigValue(const wchar_t* key)
+{
+ jitInstance.mc->cr->AddCall("getStringConfigValue");
+ const wchar_t *result = jitInstance.mc->repGetStringConfigValue(key);
+
+ if (result != nullptr)
+ {
+ // Now we need to dup it, so you can call freeStringConfigValue() on what we return.
+ size_t resultLenInChars = wcslen(result) + 1;
+ wchar_t *dupResult = (wchar_t*)jitInstance.allocateLongLivedArray((ULONG)(sizeof(wchar_t) * resultLenInChars));
+ wcscpy_s(dupResult, resultLenInChars, result);
+
+ return dupResult;
+ }
+
+ // If the result is the default value, probe the environment for
+ // a COMPlus variable with the same name.
+ return GetCOMPlusVariable(key, jitInstance);
+}
+
+void JitHost::freeStringConfigValue(const wchar_t* value)
+{
+ jitInstance.mc->cr->AddCall("freeStringConfigValue");
+ jitInstance.freeLongLivedArray((void*)value);
+}