Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 29 additions & 18 deletions src/bgen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1755,6 +1755,27 @@ void GenerateTrampolinesForQueue (TrampolineInfo [] queue)
}
indent--;
print ("}");
print ("");
print ("internal static unsafe BlockLiteral CreateNullableBlock ({0}? callback)", ti.UserDelegate);
print ("{");
indent++;
print ("if (callback is null)");
indent++;
print ("return default (BlockLiteral);");
indent--;
print ("return CreateBlock (callback);");
indent--;
print ("}");
print ("");
print ("[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]");
print ("internal static unsafe BlockLiteral CreateBlock ({0} callback)", ti.UserDelegate);
print ("{");
indent++;
print ("var block = new BlockLiteral ();");
print ("block.SetupBlockUnsafe (Handler, callback);");
print ("return block;");
indent--;
print ("}");
indent--;
print ("}} /* class {0} */", ti.StaticName);

Expand Down Expand Up @@ -3632,6 +3653,7 @@ void GenerateTypeLowering (MethodInfo mi, bool null_allowed_override, out String
by_ref_init = new StringBuilder ();

foreach (var pi in mi.GetParameters ()) {
var safe_name = pi.Name.GetSafeParamName ();
MarshalInfo mai = new MarshalInfo (this, mi, pi);

if (!IsTarget (pi)) {
Expand Down Expand Up @@ -3687,32 +3709,21 @@ void GenerateTypeLowering (MethodInfo mi, bool null_allowed_override, out String
}
} else if (mai.Type.IsSubclassOf (TypeManager.System_Delegate)) {
string trampoline_name = MakeTrampoline (pi.ParameterType).StaticName;
string extra = "";
bool null_allowed = AttributeManager.HasAttribute<NullAllowedAttribute> (pi);
if (!null_allowed) {
var property = GetProperty (mi);
if (property is not null)
null_allowed = AttributeManager.HasAttribute<NullAllowedAttribute> (property);
}

convs.AppendFormat ("BlockLiteral *block_ptr_{0};\n", pi.Name);
convs.AppendFormat ("BlockLiteral block_{0};\n", pi.Name);
var createBlockMethod = null_allowed ? "CreateNullableBlock" : "CreateBlock";
convs.AppendFormat ("using var block_{0} = Trampolines.{1}.{3} ({2});\n", pi.Name, trampoline_name, safe_name, createBlockMethod);
if (null_allowed) {
convs.AppendFormat ("if ({0} is null){{\n", pi.Name.GetSafeParamName ());
convs.AppendFormat ("\tblock_ptr_{0} = null;\n", pi.Name);
convs.AppendFormat ("}} else {{\n");
extra = "\t";
}
convs.AppendFormat (extra + "block_{0} = new BlockLiteral ();\n", pi.Name);
convs.AppendFormat (extra + "block_ptr_{0} = &block_{0};\n", pi.Name);
convs.AppendFormat (extra + "block_{0}.SetupBlockUnsafe (Trampolines.{1}.Handler, {2});\n", pi.Name, trampoline_name, pi.Name.GetSafeParamName ());
if (null_allowed)
convs.AppendFormat ("}}\n");

if (null_allowed) {
disposes.AppendFormat ("if (block_ptr_{0} != null)\n", pi.Name);
convs.AppendFormat ("BlockLiteral *block_ptr_{0} = null;\n", pi.Name);
convs.AppendFormat ("if ({0} is not null)\n", safe_name);
convs.AppendFormat ("\tblock_ptr_{0} = &block_{0};\n", pi.Name);
} else {
convs.AppendFormat ("BlockLiteral *block_ptr_{0} = &block_{0};\n", pi.Name);
}
disposes.AppendFormat (extra + "block_ptr_{0}->CleanupBlock ();\n", pi.Name);
} else if (pi.ParameterType.IsGenericParameter) {
// convs.AppendFormat ("{0}.Handle", pi.Name.GetSafeParamName ());
} else if (HasBindAsAttribute (pi)) {
Expand Down
6 changes: 6 additions & 0 deletions tools/linker/CoreOptimizeGeneratedCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ static protected bool IsExport (ICustomAttributeProvider provider)
// less risky to nop-ify if branches are pointing to this instruction
static protected void Nop (Instruction ins)
{
// Leave 'leave' instructions in place, they might be required for the resulting IL to be correct/verifiable.
switch (ins.OpCode.Code) {
case Code.Leave:
case Code.Leave_S:
return;
}
ins.OpCode = OpCodes.Nop;
ins.Operand = null;
}
Expand Down