Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

Commit bb0327a

Browse files
Merge pull request #823 from xamarin/non-blittable
fix issues marshaling booleans
2 parents 9ec280d + 279ba67 commit bb0327a

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

SwiftReflector/MarshalEngineCSafeSwiftToCSharp.cs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSFunc (CSType thisType, st
4949
bool returnIsProtocol = needsReturn && ((entity != null && entity.EntityType == EntityType.Protocol) || entityType == EntityType.ProtocolList);
5050
bool returnIsTuple = needsReturn && entityType == EntityType.Tuple;
5151
bool returnIsClosure = needsReturn && entityType == EntityType.Closure;
52+
bool returnIsBool = needsReturn && entityType == EntityType.Scalar && funcDecl.ReturnTypeName == "Swift.Bool";
5253

5354
var callParams = new List<CSBaseExpression> ();
5455
var preMarshalCode = new List<CSLine> ();
@@ -65,6 +66,7 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSFunc (CSType thisType, st
6566
entity = !newValueIsGeneric ? typeMapper.GetEntityForTypeSpec (swiftNewValue.TypeSpec) : null;
6667
entityType = !newValueIsGeneric ? typeMapper.GetEntityTypeForTypeSpec (swiftNewValue.TypeSpec) : EntityType.None;
6768
var isUnusualNewValue = IsUnusualParameter (entity, delegateParams [1]);
69+
var newValueIsBool = entityType == EntityType.Scalar && swiftNewValue.TypeName == "Swift.Bool";
6870

6971
if (entityType == EntityType.Class || entity != null && entity.IsObjCProtocol) {
7072
var csParmType = new CSSimpleType (entity.SharpNamespace + "." + entity.SharpTypeName);
@@ -120,6 +122,8 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSFunc (CSType thisType, st
120122
valueID, genRef.Typeof ())));
121123
preMarshalCode.Add (valDecl);
122124
valueExpr = valMarshalId;
125+
} else if (newValueIsBool) {
126+
valueExpr = NIntToBool (valueExpr);
123127
}
124128
}
125129

@@ -132,6 +136,7 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSFunc (CSType thisType, st
132136
entityType = !parmIsGeneric ? typeMapper.GetEntityTypeForTypeSpec (swiftParm.TypeSpec) : EntityType.None;
133137
var isUnusualParameter = IsUnusualParameter (entity, delegateParams [i]);
134138
var csParm = methodParams [j];
139+
var parmIsBool = entityType == EntityType.Scalar && swiftParm.TypeName == "Swift.Bool";
135140

136141
if (entityType == EntityType.DynamicSelf) {
137142
var retrieveCallSite = isObjC ? $"Runtime.GetNSObject<{csProxyName}> " : $"SwiftObjectRegistry.Registry.CSObjectForSwiftObject<{csProxyName}> ";
@@ -260,7 +265,11 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSFunc (CSType thisType, st
260265
callParams.Add (new CSIdentifier (String.Format ("{0} {1}",
261266
csParm.ParameterKind == CSParameterKind.Out ? "out" : "ref", delegateParams [i].Name.Name)));
262267
} else {
263-
callParams.Add (delegateParams [i].Name);
268+
CSBaseExpression parmExpr = delegateParams [i].Name;
269+
if (parmIsBool) {
270+
parmExpr = NIntToBool (parmExpr);
271+
}
272+
callParams.Add (parmExpr);
264273
}
265274
}
266275
}
@@ -405,6 +414,8 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSFunc (CSType thisType, st
405414
} else {
406415
if (returnIsClosure) {
407416
invoker = MarshalEngine.BuildBlindClosureCall (invoker, methodType as CSSimpleType, use);
417+
} else if (returnIsBool) {
418+
invoker = BoolToNint (invoker);
408419
}
409420
if (postMarshalCode.Count > 0) {
410421
string retvalName = MarshalEngine.Uniqueify ("retval", identifiersUsed);
@@ -448,6 +459,7 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSProp (CSProperty prop, CS
448459
bool returnIsTuple = needsReturn && entityType == EntityType.Tuple;
449460
bool returnIsClosure = needsReturn && entityType == EntityType.Closure;
450461
bool returnIsDynamicSelf = needsReturn && forProtocol && methodType.ToString () == NewClassCompiler.kGenericSelfName;
462+
var returnIsBool = needsReturn && entityType == EntityType.Scalar && funcDecl.ReturnTypeName == "Swift.Bool";
451463

452464
string returnCsProxyName = returnIsProtocol ?
453465
NewClassCompiler.CSProxyNameForProtocol (entity.Type.ToFullyQualifiedName (true), typeMapper) : null;
@@ -544,14 +556,21 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSProp (CSProperty prop, CS
544556
if (returnIsClosure) {
545557
body.Add (CSReturn.ReturnLine (MarshalEngine.BuildBlindClosureCall (csharpCall, methodType as CSSimpleType, use)));
546558
} else {
547-
body.Add (CSReturn.ReturnLine (csharpCall));
559+
if (returnIsBool) {
560+
body.Add (CSReturn.ReturnLine (BoolToNint (csharpCall)));
561+
} else {
562+
body.Add (CSReturn.ReturnLine (csharpCall));
563+
}
548564
}
549565
}
550566
} else {
551567
CSBaseExpression valueExpr = null;
552-
bool valueIsGeneric = funcDecl.IsTypeSpecGeneric (funcDecl.ParameterLists [1] [0].TypeSpec) ;
553-
entity = !valueIsGeneric ? typeMapper.GetEntityForTypeSpec (funcDecl.ParameterLists [1] [0].TypeSpec) : null;
568+
var valueTypeSpec = funcDecl.ParameterLists [1] [0].TypeSpec;
569+
var valueTypeName = funcDecl.ParameterLists [1] [0].TypeName;
570+
bool valueIsGeneric = funcDecl.IsTypeSpecGeneric (valueTypeSpec) ;
571+
entity = !valueIsGeneric ? typeMapper.GetEntityForTypeSpec (valueTypeSpec) : null;
554572
entityType = !valueIsGeneric ? typeMapper.GetEntityTypeForTypeSpec (funcDecl.ParameterLists [1] [0].TypeSpec) : EntityType.None;
573+
var isBoolNewValue = entityType == EntityType.Scalar && valueTypeName == "Swift.Bool";
555574
var isUnusualNewValue = IsUnusualParameter (entity, delegateParams [1]);
556575

557576
if (entityType == EntityType.Class || (entity != null && entity.IsObjCProtocol)) {
@@ -615,6 +634,9 @@ public List<ICodeElement> MarshalFromLambdaReceiverToCSProp (CSProperty prop, CS
615634
valueExpr = MarshalEngine.BuildWrappedClosureCall (delegateParams [1].Name, methodType as CSSimpleType, flags);
616635
} else {
617636
valueExpr = delegateParams [1].Name;
637+
if (isBoolNewValue) {
638+
valueExpr = NIntToBool (valueExpr);
639+
}
618640
}
619641
}
620642
body.Add (CSAssignment.Assign (csharpCall, valueExpr));
@@ -627,6 +649,18 @@ static bool IsUnusualParameter (Entity entity, CSParameter parameter)
627649
// check to see if an entity is either an objc struct or enum
628650
return entity != null && (entity.IsObjCStruct || entity.IsObjCEnum) && parameter.ParameterKind == CSParameterKind.Ref;
629651
}
652+
653+
static CSBaseExpression NIntToBool (CSBaseExpression expr)
654+
{
655+
// converts expr to
656+
// (expr & 1) != 0;
657+
return new CSParenthesisExpression (new CSBinaryExpression (CSBinaryOperator.BitAnd, expr, CSConstant.Val (1))) != CSConstant.Val (0);
658+
}
659+
660+
static CSBaseExpression BoolToNint (CSBaseExpression expr)
661+
{
662+
return new CSTernary (expr, CSConstant.Val (1), CSConstant.Val (0), false);
663+
}
630664
}
631665
}
632666

SwiftReflector/TopLevelFunctionCompiler.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ public CSDelegateTypeDecl CompileToDelegateDeclaration (FunctionDeclaration func
156156
AddUsingBlock (packs, returnType);
157157

158158
CSType csReturnType = returnType == null || returnType.IsVoid ? CSSimpleType.Void : returnType.ToCSType (packs);
159+
csReturnType = RecastBoolAsNint (csReturnType);
160+
159161
var csParams = new CSParameterList ();
160162
for (int i = 0; i < args.Count; i++) {
161163
var arg = args [i];
@@ -165,9 +167,9 @@ public CSDelegateTypeDecl CompileToDelegateDeclaration (FunctionDeclaration func
165167
if (arg.Type.Entity == EntityType.Tuple || (!argIsGeneric && IsObjCStruct (parmType))) {
166168
csParam = new CSParameter (CSSimpleType.IntPtr, new CSIdentifier (arg.Name), CSParameterKind.None, null);
167169
} else {
168-
var argType = arg.Type.ToCSType (packs);
170+
var argType = RecastBoolAsNint (arg.Type.ToCSType (packs));
169171
if (argType is CSSimpleType csType && arg.Type.IsReference)
170-
argType = csType.Star;
172+
argType = csType.Star;
171173
csParam = new CSParameter (argType, new CSIdentifier (arg.Name), CSParameterKind.None, null);
172174
}
173175
csParams.Add (csParam);
@@ -212,6 +214,15 @@ public CSDelegateTypeDecl CompileToDelegateDeclaration (FunctionDeclaration func
212214
return new CSDelegateTypeDecl (vis, csReturnType, new CSIdentifier (delegateName), csParams, isUnsafe);
213215
}
214216

217+
static CSType RecastBoolAsNint (CSType orig)
218+
{
219+
if (orig is CSSimpleType simp) {
220+
if (simp.Name == "bool" && !(simp.IsArray || simp.IsPointer))
221+
return CSSimpleType.NInt;
222+
}
223+
return orig;
224+
}
225+
215226
public CSMethod CompileMethod (FunctionDeclaration func, CSUsingPackages packs, string libraryPath,
216227
string mangledName, string functionName, bool isPinvoke, bool isFinal, bool isStatic)
217228
{

0 commit comments

Comments
 (0)