72 lines
2.3 KiB
C++
72 lines
2.3 KiB
C++
#include "CustomAttributeCreator.h"
|
|
#include "gc/WriteBarrier.h"
|
|
#include "vm/Class.h"
|
|
#include "vm/Exception.h"
|
|
#include "vm/Field.h"
|
|
#include "vm/Method.h"
|
|
#include "vm/Object.h"
|
|
#include "vm/Property.h"
|
|
#include "vm/Runtime.h"
|
|
|
|
namespace il2cpp
|
|
{
|
|
namespace metadata
|
|
{
|
|
static void* ConvertArgumentValue(const Il2CppType* targetType, const CustomAttributeArgument* arg)
|
|
{
|
|
// If the argument target target is a value type, then just pass a pointer to the data
|
|
if (targetType->valuetype)
|
|
return (void*)&arg->data;
|
|
|
|
// Our target isn't value type, but our data is, we need to box
|
|
if (il2cpp::vm::Class::IsValuetype(arg->klass))
|
|
return il2cpp::vm::Object::Box(arg->klass, (void*)&arg->data);
|
|
|
|
// Storing reference type data in a reference type field, just get the pointer to the object
|
|
return arg->data.obj;
|
|
}
|
|
|
|
void CustomAttributeCreator::VisitCtor(const MethodInfo* ctor, CustomAttributeArgument args[], uint32_t argumentCount)
|
|
{
|
|
attr = il2cpp::vm::Object::New(ctor->klass);
|
|
|
|
void** ctorArgs = (void**)alloca(argumentCount * sizeof(void*));
|
|
for (uint32_t i = 0; i < argumentCount; i++)
|
|
ctorArgs[i] = ConvertArgumentValue(ctor->parameters[i], args + i);
|
|
il2cpp::vm::Runtime::Invoke(ctor, attr, ctorArgs, &exc);
|
|
|
|
if (exc != NULL)
|
|
attr = NULL;
|
|
}
|
|
|
|
void CustomAttributeCreator::VisitField(const CustomAttributeFieldArgument& field, uint32_t index)
|
|
{
|
|
if (exc != NULL)
|
|
return;
|
|
|
|
IL2CPP_ASSERT(attr);
|
|
il2cpp::vm::Field::SetValue(attr, field.field, ConvertArgumentValue(field.field->type, &field.arg));
|
|
}
|
|
|
|
void CustomAttributeCreator::VisitProperty(const CustomAttributePropertyArgument& prop, uint32_t index)
|
|
{
|
|
if (exc != NULL)
|
|
return;
|
|
|
|
IL2CPP_ASSERT(attr);
|
|
|
|
const MethodInfo* setMethod = il2cpp::vm::Property::GetSetMethod(prop.prop);
|
|
IL2CPP_ASSERT(setMethod->parameters_count == 1);
|
|
void* param = ConvertArgumentValue(setMethod->parameters[0], &prop.arg);
|
|
|
|
il2cpp::vm::Runtime::Invoke(setMethod, attr, ¶m, &exc);
|
|
}
|
|
|
|
Il2CppObject* CustomAttributeCreator::GetAttribute(Il2CppException** exc)
|
|
{
|
|
*exc = this->exc;
|
|
return attr;
|
|
}
|
|
} /* namespace vm */
|
|
} /* namespace il2cpp */
|