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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
#include "UnityPrefix.h"
#include "../ScriptingTypes.h"
#include "Runtime/Mono/MonoIncludes.h"
#include "ScriptingBackendApi_Mono.h"
#include "../ScriptingMethodRegistry.h"
#include "../ScriptingTypeRegistry.h"
#include "Runtime/Scripting/ScriptingUtility.h" //required for ExtractMonoobjectData, todo: see if we can remove that.
std::string scripting_cpp_string_for(ScriptingStringPtr str)
{
return MonoStringToCpp(str);
}
bool scripting_method_is_instance(ScriptingMethodPtr method)
{
return method->isInstance;
}
const char* scripting_method_get_name(ScriptingMethodPtr method)
{
return mono_method_get_name(method->monoMethod);
}
int scripting_method_get_argument_count(ScriptingMethodPtr method, ScriptingTypeRegistry& typeRegistry)
{
MonoMethodSignature* sig = mono_method_signature(method->monoMethod);
Assert(sig);
return mono_signature_get_param_count(sig);
}
ScriptingTypePtr scripting_method_get_returntype(ScriptingMethodPtr method, ScriptingTypeRegistry& registry)
{
MonoMethodSignature* sig = mono_method_signature (method->monoMethod);
MonoType* returnType = mono_signature_get_return_type (sig);
if (returnType == NULL)
return NULL;
return mono_class_from_mono_type (returnType);
}
ScriptingTypePtr scripting_method_get_nth_argumenttype(ScriptingMethodPtr method, int index, ScriptingTypeRegistry& typeRegistry)
{
MonoMethodSignature* sig = mono_method_signature (method->monoMethod);
void* iterator = NULL;
MonoType* type = mono_signature_get_params (sig, &iterator);
if (type == NULL)
return NULL;
MonoClass* methodClass = mono_class_from_mono_type (type);
return typeRegistry.GetType(methodClass);
}
bool scripting_method_has_attribute(ScriptingMethodPtr method, ScriptingClassPtr attribute)
{
bool hasAttribute = false;
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method (method->monoMethod);
if (attrInfo != NULL && mono_custom_attrs_has_attr (attrInfo, attribute))
hasAttribute = true;
if (attrInfo)
mono_custom_attrs_free(attrInfo);
return hasAttribute;
}
ScriptingTypePtr scripting_class_get_parent(ScriptingTypePtr t, ScriptingTypeRegistry& registry)
{
return mono_class_get_parent(t);
}
void scripting_class_get_methods(ScriptingTypePtr t, ScriptingMethodRegistry& registry, std::vector<ScriptingMethodPtr>& result)
{
void* iterator = NULL;
ScriptingMethodPtr scriptingMethod = NULL;
while (MonoMethod* method = mono_class_get_methods(t, &iterator))
if ((scriptingMethod = registry.GetMethod (method)))
result.push_back(scriptingMethod);
}
ScriptingTypePtr scripting_class_from_systemtypeinstance(ScriptingObjectPtr systemTypeInstance, ScriptingTypeRegistry& typeRegistry)
{
if (!systemTypeInstance)
return NULL;
MonoClass* klass = mono_class_from_mono_type(ExtractMonoObjectData<MonoType*>(systemTypeInstance));
return typeRegistry.GetType(klass);
}
const char* scripting_class_get_name(ScriptingClassPtr klass)
{
return mono_class_get_name(klass);
}
const char* scripting_class_get_namespace(ScriptingClassPtr klass)
{
return mono_class_get_namespace(klass);
}
bool scripting_class_is_subclass_of(ScriptingClassPtr c1, ScriptingClassPtr c2)
{
return mono_class_is_subclass_of(c1,c2,true);
}
bool scripting_class_is_enum(ScriptingClassPtr klass)
{
return mono_class_is_enum (klass);
}
ScriptingTypePtr scripting_object_get_class(ScriptingObjectPtr t, ScriptingTypeRegistry& registry)
{
return mono_object_get_class(t);
}
void scripting_object_invoke_default_constructor(ScriptingObjectPtr t, ScriptingExceptionPtr* exc)
{
mono_runtime_object_init_exception(t,exc);
}
ScriptingMethodPtr scripting_object_get_virtual_method(ScriptingObjectPtr o, ScriptingMethodPtr method, ScriptingMethodRegistry& methodRegistry)
{
return methodRegistry.GetMethod(mono_object_get_virtual_method(o,method->monoMethod));
}
ScriptingObjectPtr scripting_object_new(ScriptingTypePtr t)
{
#if UNITY_EDITOR
if (mono_unity_class_is_abstract (t)) {
// Cannot instantiate abstract class
return SCRIPTING_NULL;
}
#endif
return mono_object_new(mono_domain_get(), t);
}
int scripting_gchandle_new(ScriptingObjectPtr o)
{
return mono_gchandle_new(o,1);
}
int scripting_gchandle_weak_new(ScriptingObjectPtr o)
{
return mono_gchandle_new_weakref(o, 1);
}
void scripting_gchandle_free(int handle)
{
mono_gchandle_free(handle);
}
ScriptingObjectPtr scripting_gchandle_get_target(int handle)
{
return mono_gchandle_get_target(handle);
}
int scripting_gc_maxgeneration()
{
return mono_gc_max_generation();
}
void scripting_gc_collect(int maxGeneration)
{
mono_gc_collect(maxGeneration);
}
ScriptingObjectPtr scripting_method_invoke(ScriptingMethodPtr method, ScriptingObjectPtr object, ScriptingArguments& arguments, ScriptingExceptionPtr* exception)
{
#if UNITY_EDITOR
bool IsStackLargeEnough ();
if (!IsStackLargeEnough ())
{
*exception = mono_exception_from_name_msg (mono_get_corlib (), "System", "StackOverflowException", "");
return NULL;
}
#endif
if (method->fastMonoMethod)
{
Assert(arguments.GetCount()==0);
Assert(object);
return method->fastMonoMethod(object,exception);
}
return mono_runtime_invoke(method->monoMethod, object, arguments.InMonoFormat(), exception);
}
ScriptingObjectPtr scripting_class_get_object(ScriptingClassPtr klass)
{
return mono_class_get_object(klass);
}
ScriptingArrayPtr scripting_cast_object_to_array(ScriptingObjectPtr o)
{
return (ScriptingArrayPtr)o;
}
ScriptingStringPtr scripting_string_new(const std::string& str)
{
return scripting_string_new(str.c_str());
}
ScriptingStringPtr scripting_string_new(const UnityStr& str)
{
return scripting_string_new(str.c_str());
}
ScriptingStringPtr scripting_string_new(const char* str)
{
return MonoStringNew(str);
}
ScriptingStringPtr scripting_string_new(const wchar_t* str)
{
return MonoStringNewUTF16(str);
}
ScriptingStringPtr scripting_string_new(const char* str, unsigned int length)
{
return MonoStringNewLength(str, length);
}
void scripting_stack_trace_info_for(ScriptingExceptionPtr exception, StackTraceInfo& info)
{
AssertIf (exception == NULL);
MonoException* tempException = NULL;
MonoString* monoStringMessage = NULL;
MonoString* monoStringTrace = NULL;
void* args[] = { exception, &monoStringMessage, &monoStringTrace };
if (GetMonoManagerPtr () && GetMonoManager ().GetCommonClasses ().extractStringFromException)
{
// Call mono_runtime_invoke directly to avoid our stack size check in mono_runtime_invoke_profiled.
// We *should* have enough stack here to make this call, and a stack trace would be useful for the user.
mono_runtime_invoke (GetMonoManager ().GetCommonClasses ().extractStringFromException->monoMethod, (MonoObject*)exception, args, &tempException);
}
if (tempException)
{
char const* exceptionClassName = mono_class_get_name(mono_object_get_class((MonoObject*)tempException));
ErrorString ("Couldn't extract exception string from exception (another exception of class '"
+ std::string (exceptionClassName) + "' was thrown while processing the stack trace)");
return;
}
// Log returned string
string message;
char* extractedMessage = NULL;
if (monoStringMessage)
message = extractedMessage = mono_string_to_utf8 (monoStringMessage);
char* extractedTrace = NULL;
if (monoStringTrace)
extractedTrace = mono_string_to_utf8 (monoStringTrace);
string processedStackTrace;
int line = -1;
string path;
if (extractedTrace && *extractedTrace != 0)
{
PostprocessStacktrace(extractedTrace, processedStackTrace);
ExceptionToLineAndPath (processedStackTrace, line, path);
}
info.condition = message;
info.strippedStacktrace = processedStackTrace;
info.stacktrace = extractedTrace;
info.errorNum = 0;
info.file = path;
info.line = line;
g_free (extractedMessage);
g_free (extractedTrace);
}
void* scripting_array_element_ptr(ScriptingArrayPtr array, int i, size_t element_size)
{
return kMonoArrayOffset + i * element_size + (char*)array;
}
|