public override bool VisitManagedArrayType(ManagedArrayType array, TypeQualifiers quals) { var support = Context.SupportBefore; var contextId = CGenerator.GenId("mono_context"); var arrayId = CGenerator.GenId($"{Context.ArgName}_array"); var elementClassId = CGenerator.GenId($"{Context.ArgName}_element_class"); var managedArray = array.Array; var elementType = managedArray.Type; support.WriteLine("MonoClass* {0} = mono_class_get_element_class({1});", elementClassId, GenerateArrayTypeLookup(elementType, support)); support.WriteLine("MonoArray* {0} = mono_array_new({1}.domain, {2}, {3}.array->len);", arrayId, contextId, elementClassId, Context.ArgName); var iteratorId = CGenerator.GenId("i"); support.WriteLine("for (int {0} = 0; {0} < {1}.array->len; {0}++)", iteratorId, Context.ArgName); support.WriteStartBraceIndent(); var typePrinter = CTypePrinter; string elementTypeName = elementType.Visit(typePrinter); var elementId = CGenerator.GenId($"{Context.ArgName}_array_element"); support.WriteLine("{0} {1} = g_array_index({2}.array, {0}, {3});", elementTypeName, elementId, Context.ArgName, iteratorId); var ctx = new MarshalContext(Context.Context) { ArgName = elementId, }; var marshal = new CMarshalNativeToManaged (Options, ctx) { PrimitiveValuesByValue = true }; elementType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) support.Write(marshal.Context.SupportBefore.ToString()); var isValueType = IsValueType(elementType); if (isValueType) { support.WriteLine("mono_array_set({0}, {1}, {2}, {3});", arrayId, elementTypeName, iteratorId, marshal.Context.Return.ToString()); } else { support.WriteLine("mono_array_setref({0}, {1}, {2});", arrayId, iteratorId, marshal.Context.Return.ToString()); } support.WriteCloseBraceIndent(); Context.Return.Write("{0}", arrayId); return true; }
void GenerateFieldSetter(Property property) { var setter = property.SetMethod; var @class = property.Namespace as Class; GenerateMethodSpecifier(setter, setter.Namespace as Class); NewLine(); WriteStartBraceIndent(); var field = property.Field; var fieldId = GeneratedIdentifier("field"); GenerateFieldLookup(field); var ctx = new MarshalContext(Context) { ArgName = "value" }; var marshal = new CMarshalNativeToManaged(EmbedOptions, ctx); property.QualifiedType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } var valueId = GeneratedIdentifier("value"); WriteLine($"void* {valueId} = {marshal.Context.Return.ToString()};"); if (field.IsStatic) { var vtableId = GeneratedIdentifier("vtable"); var domainId = $"{GeneratedIdentifier("mono_context")}.domain"; var classId = $"class_{@class.QualifiedName}"; WriteLine($"MonoVTable* {vtableId} = mono_class_vtable({domainId}, {classId});"); WriteLine($"mono_field_static_set_value({vtableId}, {fieldId}, {valueId});"); } else { var instanceId = GeneratedIdentifier("instance"); var handle = GetMonoObjectField(Options, MonoObjectFieldUsage.Instance, FixMethodParametersPass.ObjectParameterId, "_handle"); WriteLine($"MonoObject* {instanceId} = mono_gchandle_get_target({handle});"); WriteLine($"mono_field_set_value({instanceId}, {fieldId}, {valueId});"); } WriteCloseBraceIndent(); }
public void GenerateMethodInvocation(Method method) { GenerateMethodInitialization(method); NewLine(); var paramsToMarshal = method.Parameters.Where(p => !p.IsImplicit); var numParamsToMarshal = paramsToMarshal.Count(); var argsId = "0"; if (numParamsToMarshal > 0) { argsId = GeneratedIdentifier("args"); WriteLine($"void* {argsId}[{numParamsToMarshal}];"); } var contexts = new List <MarshalContext>(); int paramIndex = 0; foreach (var param in paramsToMarshal) { var ctx = new MarshalContext(Context) { ArgName = param.Name, Parameter = param, ParameterIndex = paramIndex }; contexts.Add(ctx); var marshal = new CMarshalNativeToManaged(EmbedOptions, ctx); param.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine($"{argsId}[{paramIndex++}] = {marshal.Context.Return};"); } var exceptionId = GeneratedIdentifier("exception"); WriteLine($"MonoObject* {exceptionId} = 0;"); var resultId = GeneratedIdentifier("result"); WriteLine($"MonoObject* {resultId};"); var methodId = GeneratedIdentifier("method"); var instanceId = method.IsStatic ? "0" : GeneratedIdentifier("instance"); if (method.IsVirtual) { var virtualMethodId = GeneratedIdentifier("virtual_method"); WriteLine($"MonoMethod* {virtualMethodId} = mono_object_get_virtual_method({instanceId}, {methodId});"); methodId = virtualMethodId; } var @class = method.Namespace as Class; if (@class.IsValueType && !method.IsStatic) { var unboxedId = CGenerator.GenId("unboxed"); WriteLine($"void* {unboxedId} = mono_object_unbox({instanceId});"); instanceId = unboxedId; } WriteLine("{0} = mono_runtime_invoke({1}, {2}, {3}, &{4});", resultId, methodId, instanceId, argsId, exceptionId); NewLine(); WriteLine($"if ({exceptionId})"); WriteStartBraceIndent(); if (method.IsConstructor) { WriteLine("free(object);"); } WriteLine($"mono_embeddinator_throw_exception({exceptionId});"); if (method.IsConstructor) { WriteLine("return 0;"); } WriteCloseBraceIndent(); foreach (var marshalContext in contexts) { if (!string.IsNullOrWhiteSpace(marshalContext.SupportAfter)) { Write(marshalContext.SupportAfter); } } }
public override bool VisitManagedArrayType(ManagedArrayType array, TypeQualifiers quals) { var support = Context.SupportBefore; var arrayId = CGenerator.GenId($"{Context.ArgName}_array"); support.WriteLine("MonoArray* {0} = (MonoArray*) {1};", arrayId, Context.ArgName); var arraySizeId = CGenerator.GenId($"{Context.ArgName}_array_size"); support.WriteLine("uintptr_t {0} = mono_array_length({1});", arraySizeId, arrayId); var typePrinter = CTypePrinter; typePrinter.PrintScopeKind = TypePrintScopeKind.Local; var arrayTypedefName = array.Typedef.Visit(typePrinter); typePrinter.PrintScopeKind = TypePrintScopeKind.Qualified; var arrayElementName = array.Array.Type.Visit(typePrinter); var elementSize = $"sizeof({arrayElementName})"; var nativeArrayId = CGenerator.GenId($"{Context.ArgName}_native_array"); support.WriteLine("{0} {1};", arrayTypedefName, nativeArrayId); support.WriteLine("{0}.array = g_array_sized_new(/*zero_terminated=*/FALSE," + " /*clear_=*/TRUE, {1}, {2});", nativeArrayId, elementSize, arraySizeId); var elementClassId = CGenerator.GenId($"{Context.ArgName}_element_class"); support.WriteLine("MonoClass* {0} = mono_class_get_element_class({1});", elementClassId, CMarshalNativeToManaged.GenerateArrayTypeLookup(array.Array.Type, support)); var elementSizeId = CGenerator.GenId($"{Context.ArgName}_array_element_size"); support.WriteLine("gint32 {0} = mono_class_array_element_size({1});", elementSizeId, elementClassId); var iteratorId = CGenerator.GenId("i"); support.WriteLine("for (int {0} = 0; {0} < {1}; {0}++)", iteratorId, arraySizeId); support.WriteStartBraceIndent(); var elementId = CGenerator.GenId($"{Context.ArgName}_array_element"); var isValueType = CMarshalNativeToManaged.IsValueType(array.Array.Type); support.WriteLine("{5} {0} = {4}mono_array_addr_with_size({1}, {2}, {3});", elementId, arrayId, elementSizeId, iteratorId, isValueType ? string.Empty : "*(MonoObject**)", isValueType ? "char*" : "MonoObject*"); var ctx = new MarshalContext(Context.Context) { ArgName = elementId, ReturnVarName = elementId, ReturnType = array.Array.QualifiedType }; var marshal = new CMarshalManagedToNative(Options, ctx) { UnboxPrimitiveValues = false }; array.Array.QualifiedType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { support.Write(marshal.Context.SupportBefore.ToString()); } support.WriteLine("g_array_append_val({0}.array, {1});", nativeArrayId, marshal.Context.Return.ToString()); support.WriteCloseBraceIndent(); Context.Return.Write("{0}", nativeArrayId); return(false); }
public void GenerateMethodInvocation(Method method) { GenerateMethodGCHandleLookup(method); var paramsToMarshal = method.Parameters.Where(p => !p.IsImplicit); var numParamsToMarshal = paramsToMarshal.Count(); var argsId = "0"; if (numParamsToMarshal > 0) { argsId = GeneratedIdentifier("args"); WriteLine("void* {0}[{1}];", argsId, numParamsToMarshal); } var contexts = new List <MarshalContext>(); int paramIndex = 0; foreach (var param in paramsToMarshal) { var ctx = new MarshalContext(Context) { ArgName = param.Name, Parameter = param, ParameterIndex = paramIndex }; contexts.Add(ctx); var marshal = new CMarshalNativeToManaged(EmbedOptions, ctx); param.QualifiedType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("{0}[{1}] = {2};", argsId, paramIndex++, marshal.Context.Return.ToString()); } var exceptionId = GeneratedIdentifier("exception"); WriteLine("MonoObject* {0} = 0;", exceptionId); var resultId = GeneratedIdentifier("result"); WriteLine("MonoObject* {0};", resultId); var methodId = GeneratedIdentifier("method"); var instanceId = method.IsStatic ? "0" : GeneratedIdentifier("instance"); WriteLine("{0} = mono_runtime_invoke({1}, {2}, {3}, &{4});", resultId, methodId, instanceId, argsId, exceptionId); WriteLine("if ({0} != 0)", exceptionId); WriteStartBraceIndent(); var errorId = GeneratedIdentifier("error"); WriteLine("mono_m2n_error_t {0};", errorId); WriteLine("{0}.type = MONO_M2N_EXCEPTION_THROWN;", errorId); WriteLine("{0}.exception = (MonoException*) {1};", errorId, exceptionId); WriteLine("mono_m2n_error({0});", errorId); WriteCloseBraceIndent(); foreach (var marshalContext in contexts) { if (!string.IsNullOrWhiteSpace(marshalContext.SupportAfter)) { Write(marshalContext.SupportAfter); } } }
public void GenerateMethodInvocation(Method method) { GenerateMethodInitialization(method); NewLine(); var paramsToMarshal = method.Parameters.Where(p => !p.IsImplicit); var numParamsToMarshal = paramsToMarshal.Count(); var argsId = "0"; if (numParamsToMarshal > 0) { argsId = GeneratedIdentifier("args"); WriteLine($"void* {argsId}[{numParamsToMarshal}];"); } var contexts = new List <MarshalContext>(); int paramIndex = 0; foreach (var param in paramsToMarshal) { var ctx = new MarshalContext(Context) { ArgName = param.Name, Parameter = param, ParameterIndex = paramIndex }; contexts.Add(ctx); var marshal = new CMarshalNativeToManaged(EmbedOptions, ctx); param.QualifiedType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine($"{argsId}[{paramIndex++}] = {marshal.Context.Return};"); } var exceptionId = GeneratedIdentifier("exception"); WriteLine($"MonoObject* {exceptionId} = 0;"); var resultId = GeneratedIdentifier("result"); WriteLine($"MonoObject* {resultId};"); var methodId = GeneratedIdentifier("method"); var instanceId = method.IsStatic ? "0" : GeneratedIdentifier("instance"); WriteLine("{0} = mono_runtime_invoke({1}, {2}, {3}, &{4});", resultId, methodId, instanceId, argsId, exceptionId); NewLine(); WriteLine($"if (!{exceptionId})"); WriteLineIndent($"mono_embeddinator_throw_exception({exceptionId});"); foreach (var marshalContext in contexts) { if (!string.IsNullOrWhiteSpace(marshalContext.SupportAfter)) { Write(marshalContext.SupportAfter); } } }