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// See the LICENSE file in the project root for more information.
4
5
6
7#include "common.h"
8#include "appdomain.hpp"
9#include "appdomainnative.hpp"
10#include "vars.hpp"
11#include "eeconfig.h"
12#include "appdomain.inl"
13#include "eventtrace.h"
14#if defined(FEATURE_APPX)
15#include "appxutil.h"
16#endif // FEATURE_APPX
17#include "../binder/inc/clrprivbindercoreclr.h"
18
19#include "clr/fs/path.h"
20using namespace clr::fs;
21
22FCIMPL3(Object*, AppDomainNative::CreateDynamicAssembly, AssemblyNameBaseObject* assemblyNameUNSAFE, StackCrawlMark* stackMark, INT32 access)
23{
24 FCALL_CONTRACT;
25
26 ASSEMBLYREF refRetVal = NULL;
27
28 //<TODO>
29 // @TODO: there MUST be a better way to do this...
30 //</TODO>
31 CreateDynamicAssemblyArgs args;
32
33 args.assemblyName = (ASSEMBLYNAMEREF) assemblyNameUNSAFE;
34 args.loaderAllocator = NULL;
35
36 args.access = access;
37 args.stackMark = stackMark;
38
39 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT((CreateDynamicAssemblyArgsGC&)args);
40
41 Assembly *pAssembly = Assembly::CreateDynamic(GetAppDomain(), &args);
42
43 refRetVal = (ASSEMBLYREF) pAssembly->GetExposedObject();
44
45 HELPER_METHOD_FRAME_END();
46 return OBJECTREFToObject(refRetVal);
47}
48FCIMPLEND
49
50#ifdef FEATURE_APPX
51// static
52BOOL QCALLTYPE AppDomainNative::IsAppXProcess()
53{
54 QCALL_CONTRACT;
55
56 BOOL result;
57
58 BEGIN_QCALL;
59
60 result = AppX::IsAppXProcess();
61
62 END_QCALL;
63
64 return result;
65}
66#endif // FEATURE_APPX
67
68FCIMPL0(Object*, AppDomainNative::GetLoadedAssemblies)
69{
70 FCALL_CONTRACT;
71
72 struct _gc
73 {
74 PTRARRAYREF AsmArray;
75 } gc;
76
77 gc.AsmArray = NULL;
78
79 HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
80
81 MethodTable * pAssemblyClass = MscorlibBinder::GetClass(CLASS__ASSEMBLY);
82
83 AppDomain * pApp = GetAppDomain();
84
85 // Allocate an array with as many elements as there are assemblies in this
86 // appdomain. This will usually be correct, but there may be assemblies
87 // that are still loading, and those won't be included in the array of
88 // loaded assemblies. When that happens, the array will have some trailing
89 // NULL entries; those entries will need to be trimmed.
90 size_t nArrayElems = pApp->m_Assemblies.GetCount(pApp);
91 gc.AsmArray = (PTRARRAYREF) AllocateObjectArray(
92 (DWORD)nArrayElems,
93 pAssemblyClass);
94
95 size_t numAssemblies = 0;
96 {
97 // Iterate over the loaded assemblies in the appdomain, and add each one to
98 // to the array. Quit when the array is full, in case assemblies have been
99 // loaded into this appdomain, on another thread.
100 AppDomain::AssemblyIterator i = pApp->IterateAssembliesEx((AssemblyIterationFlags)(
101 kIncludeLoaded | kIncludeExecution));
102 CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
103
104 while (i.Next(pDomainAssembly.This()) && (numAssemblies < nArrayElems))
105 {
106 // Do not change this code. This is done this way to
107 // prevent a GC hole in the SetObjectReference() call. The compiler
108 // is free to pick the order of evaluation.
109 OBJECTREF o = (OBJECTREF)pDomainAssembly->GetExposedAssemblyObject();
110 if (o == NULL)
111 { // The assembly was collected and is not reachable from managed code anymore
112 continue;
113 }
114 gc.AsmArray->SetAt(numAssemblies++, o);
115 // If it is a collectible assembly, it is now referenced from the managed world, so we can
116 // release the native reference in the holder
117 }
118 }
119
120 // If we didn't fill the array, allocate a new array that is exactly the
121 // right size, and copy the data to it.
122 if (numAssemblies < nArrayElems)
123 {
124 PTRARRAYREF AsmArray2;
125 AsmArray2 = (PTRARRAYREF) AllocateObjectArray(
126 (DWORD)numAssemblies,
127 pAssemblyClass);
128
129 for (size_t ix = 0; ix < numAssemblies; ++ix)
130 {
131 AsmArray2->SetAt(ix, gc.AsmArray->GetAt(ix));
132 }
133
134 gc.AsmArray = AsmArray2;
135 }
136
137 HELPER_METHOD_FRAME_END();
138 return OBJECTREFToObject(gc.AsmArray);
139} // AppDomainNative::GetAssemblies
140FCIMPLEND
141
142FCIMPL1(Object*, AppDomainNative::IsStringInterned, StringObject* pStringUNSAFE)
143{
144 FCALL_CONTRACT;
145
146 STRINGREF refString = ObjectToSTRINGREF(pStringUNSAFE);
147 STRINGREF* prefRetVal = NULL;
148
149 HELPER_METHOD_FRAME_BEGIN_RET_1(refString);
150
151 if (refString == NULL)
152 COMPlusThrow(kArgumentNullException, W("ArgumentNull_String"));
153
154 prefRetVal = GetAppDomain()->IsStringInterned(&refString);
155
156 HELPER_METHOD_FRAME_END();
157
158 if (prefRetVal == NULL)
159 return NULL;
160
161 return OBJECTREFToObject(*prefRetVal);
162}
163FCIMPLEND
164
165FCIMPL1(Object*, AppDomainNative::GetOrInternString, StringObject* pStringUNSAFE)
166{
167 FCALL_CONTRACT;
168
169 STRINGREF refRetVal = NULL;
170 STRINGREF pString = (STRINGREF) pStringUNSAFE;
171
172 HELPER_METHOD_FRAME_BEGIN_RET_1(pString);
173
174 if (pString == NULL)
175 COMPlusThrow(kArgumentNullException, W("ArgumentNull_String"));
176
177 STRINGREF* stringVal = GetAppDomain()->GetOrInternString(&pString);
178 if (stringVal != NULL)
179 {
180 refRetVal = *stringVal;
181 }
182
183 HELPER_METHOD_FRAME_END();
184 return OBJECTREFToObject(refRetVal);
185}
186FCIMPLEND
187