Skip to content

Commit

Permalink
[c] Destruct temporary objects returned from methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
pfusik committed Mar 12, 2024
1 parent 4a3d11a commit 5e5bff6
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 177 deletions.
14 changes: 10 additions & 4 deletions GenBase.fu
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,15 @@ public abstract class GenBase : FuVisitor
VisitLiteralLong(id);
}

protected bool TryWriteTemporary!(FuExpr expr)
{
int id = this.CurrentTemporaries.IndexOf(expr);
if (id < 0)
return false;
WriteTemporaryName(id);
return true;
}

protected void WriteResourceName!(string name)
{
foreach (int c in name)
Expand Down Expand Up @@ -910,10 +919,7 @@ public abstract class GenBase : FuVisitor
if (dynamic.Class.Id == FuId.ArrayPtrClass)
WriteNewArray(dynamic.GetElementType(), expr.Inner, parent);
else if (expr.Inner is FuAggregateInitializer init) {
int tempId = this.CurrentTemporaries.IndexOf(expr);
if (tempId >= 0)
WriteTemporaryName(tempId);
else
if (!TryWriteTemporary(expr))
WriteNewWithFields(dynamic, init);
}
else
Expand Down
85 changes: 45 additions & 40 deletions GenC.fu
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public class GenC : GenCCpp
expr.Accept(this, FuPriority.Primary);
}
else
WriteTemporaryOrExpr(expr, FuPriority.Argument);
expr.Accept(this, FuPriority.Argument);
}

void WriteStringPtrAdd!(FuCallExpr call, bool cast)
Expand Down Expand Up @@ -144,15 +144,6 @@ public class GenC : GenCCpp
StartDefinition(type, true, true);
}

void WriteTemporaryOrExpr!(FuExpr expr, FuPriority parent)
{
int id = this.CurrentTemporaries.IndexOf(expr);
if (id >= 0)
WriteTemporaryName(id);
else
expr.Accept(this, parent);
}

void WriteUpcast!(FuClass resultClass, FuSymbol klass)
{
for (; klass != resultClass; klass = klass.Parent)
Expand All @@ -164,7 +155,7 @@ public class GenC : GenCCpp
switch (expr.Type) {
case FuStorageType storage when storage.Class.Id == FuId.None && !IsDictionaryClassStgIndexing(expr):
WriteChar('&');
WriteTemporaryOrExpr(expr, FuPriority.Primary);
expr.Accept(this, FuPriority.Primary);
WriteUpcast(resultClass, storage.Class);
break;
case FuClassType ptr when ptr.Class != resultClass:
Expand Down Expand Up @@ -200,6 +191,8 @@ public class GenC : GenCCpp

internal override void VisitInterpolatedString!(FuInterpolatedString expr, FuPriority parent)
{
if (TryWriteTemporary(expr))
return;
Include("stdarg.h");
Include("stdio.h");
this.StringFormat = true;
Expand Down Expand Up @@ -413,9 +406,11 @@ public class GenC : GenCCpp
WriteMatchProperty(expr, 2);
break;
case FuId.MatchValue:
Write("g_match_info_fetch(");
expr.Left.Accept(this, FuPriority.Argument);
Write(", 0)");
if (!TryWriteTemporary(expr)) {
Write("g_match_info_fetch(");
expr.Left.Accept(this, FuPriority.Argument);
Write(", 0)");
}
break;
default:
if (expr.Left == null || expr.Symbol is FuConst)
Expand Down Expand Up @@ -1057,7 +1052,7 @@ public class GenC : GenCCpp
void WriteStorageTemporary!(FuExpr expr)
{
if (expr.IsNewString(false)
|| (expr is FuCallExpr && expr.Type is FuStorageType))
|| (expr is FuCallExpr && expr.Type is FuOwningType))
WriteCTemporary(expr.Type, expr);
}

Expand Down Expand Up @@ -1152,11 +1147,13 @@ public class GenC : GenCCpp

protected override void CleanupTemporary!(int i, FuExpr temp)
{
if (temp.Type.Id == FuId.StringStorageType) {
Write("free(futemp");
VisitLiteralLong(i);
WriteLine(");");
}
if (!NeedToDestructType(temp.Type)
|| (temp is FuPrefixExpr dynamicObjectLiteral && dynamicObjectLiteral.Inner is FuAggregateInitializer)) // FIXME: if temporary, still needs to be destructed
return;
WriteDestructMethodName(temp.Type.AsClassType());
Write("(futemp");
VisitLiteralLong(i);
WriteLine(");");
}

protected override void WriteVar!(FuNamedValue def)
Expand Down Expand Up @@ -1572,7 +1569,7 @@ public class GenC : GenCCpp
if (type.Id == FuId.StringStorageType)
WriteStringStorageValue(expr);
else if (expr.Type.Id == FuId.StringStorageType)
WriteTemporaryOrExpr(expr, parent);
expr.Accept(this, parent);
else
base.WriteCoercedInternal(type, expr, parent);
break;
Expand Down Expand Up @@ -1603,9 +1600,9 @@ public class GenC : GenCCpp
WriteChar('(');
Include("string.h");
Write("strcmp("); // TODO: WriteCall("strcmp", left, right);
WriteTemporaryOrExpr(left, FuPriority.Argument);
left.Accept(this, FuPriority.Argument);
Write(", ");
WriteTemporaryOrExpr(right, FuPriority.Argument);
right.Accept(this, FuPriority.Argument);
WriteChar(')');
Write(GetEqOp(not));
WriteChar('0');
Expand Down Expand Up @@ -1812,11 +1809,11 @@ public class GenC : GenCCpp
Write("g_string_append(");
obj.Accept(this, FuPriority.Argument);
Write(", ");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
}
else {
Write("fputs(");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
Write(", ");
obj.Accept(this, FuPriority.Argument);
}
Expand All @@ -1841,7 +1838,7 @@ public class GenC : GenCCpp
Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj.Accept(this, FuPriority.Argument);
Write(", \"%s\\n\", ");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
WriteChar(')');
}
}
Expand Down Expand Up @@ -1953,7 +1950,7 @@ public class GenC : GenCCpp
Write("_TryParse(&");
obj.Accept(this, FuPriority.Primary);
Write(", ");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
if (obj.Type is FuIntegerType)
WriteTryParseRadix(args);
WriteChar(')');
Expand Down Expand Up @@ -2102,12 +2099,12 @@ public class GenC : GenCCpp
break;
case FuId.StringToLower:
WriteGlib("g_utf8_strdown(");
WriteTemporaryOrExpr(obj, FuPriority.Argument);
obj.Accept(this, FuPriority.Argument);
Write(", -1)");
break;
case FuId.StringToUpper:
WriteGlib("g_utf8_strup(");
WriteTemporaryOrExpr(obj, FuPriority.Argument);
obj.Accept(this, FuPriority.Argument);
Write(", -1)");
break;
case FuId.ArrayBinarySearchAll:
Expand Down Expand Up @@ -2425,21 +2422,21 @@ public class GenC : GenCCpp
break;
case FuId.RegexCompile:
WriteGlib("g_regex_new(");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
Write(", ");
WriteCRegexOptions(args);
Write(", 0, NULL)");
break;
case FuId.RegexEscape:
WriteGlib("g_regex_escape_string(");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
Write(", -1)");
break;
case FuId.RegexIsMatchStr:
WriteGlib("g_regex_match_simple(");
WriteTemporaryOrExpr(args[1], FuPriority.Argument);
args[1].Accept(this, FuPriority.Argument);
Write(", ");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
Write(", ");
WriteCRegexOptions(args);
Write(", 0)");
Expand All @@ -2448,17 +2445,17 @@ public class GenC : GenCCpp
Write("g_regex_match(");
obj.Accept(this, FuPriority.Argument);
Write(", ");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
Write(", 0, NULL)");
break;
case FuId.MatchFindStr:
this.MatchFind = true;
Write("FuMatch_Find(&");
obj.Accept(this, FuPriority.Primary);
Write(", ");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
Write(", ");
WriteTemporaryOrExpr(args[1], FuPriority.Argument);
args[1].Accept(this, FuPriority.Argument);
Write(", ");
WriteCRegexOptions(args);
WriteChar(')');
Expand All @@ -2467,7 +2464,7 @@ public class GenC : GenCCpp
Write("g_regex_match(");
args[1].Accept(this, FuPriority.Argument);
Write(", ");
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
args[0].Accept(this, FuPriority.Argument);
Write(", 0, &");
obj.Accept(this, FuPriority.Primary);
WriteChar(')');
Expand Down Expand Up @@ -2536,6 +2533,12 @@ public class GenC : GenCCpp
}
}

internal override void VisitCallExpr!(FuCallExpr expr, FuPriority parent)
{
if (!TryWriteTemporary(expr))
base.VisitCallExpr(expr, parent);
}

void WriteDictionaryIndexing!(string function, FuBinaryExpr expr, FuPriority parent)
{
FuType valueType = expr.Left.Type.AsClassType().GetValueType();
Expand Down Expand Up @@ -2604,13 +2607,15 @@ public class GenC : GenCCpp
switch (expr.Op) {
case FuToken.Plus:
if (expr.Type.Id == FuId.StringStorageType) {
if (TryWriteTemporary(expr))
return;
this.StringFormat = true;
Include("stdarg.h");
Include("stdio.h");
Write("FuString_Format(\"%s%s\", ");
WriteTemporaryOrExpr(expr.Left, FuPriority.Argument);
expr.Left.Accept(this, FuPriority.Argument);
Write(", ");
WriteTemporaryOrExpr(expr.Right, FuPriority.Argument);
expr.Right.Accept(this, FuPriority.Argument);
WriteChar(')');
return;
}
Expand All @@ -2636,7 +2641,7 @@ public class GenC : GenCCpp
Write(", FuString_Format(\"%s");
WritePrintfFormat(rightInterpolated);
Write("\", ");
WriteTemporaryOrExpr(expr.Left, FuPriority.Argument); // FIXME: side effect
expr.Left.Accept(this, FuPriority.Argument); // FIXME: side effect
WriteInterpolatedStringArgs(rightInterpolated);
WriteChar(')');
}
Expand Down
Loading

0 comments on commit 5e5bff6

Please sign in to comment.