1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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);
}
|