Skip to content

Commit 5e5bff6

Browse files
committed
[c] Destruct temporary objects returned from methods.
fusionlanguage#26
1 parent 4a3d11a commit 5e5bff6

File tree

7 files changed

+235
-177
lines changed

7 files changed

+235
-177
lines changed

GenBase.fu

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,15 @@ public abstract class GenBase : FuVisitor
876876
VisitLiteralLong(id);
877877
}
878878

879+
protected bool TryWriteTemporary!(FuExpr expr)
880+
{
881+
int id = this.CurrentTemporaries.IndexOf(expr);
882+
if (id < 0)
883+
return false;
884+
WriteTemporaryName(id);
885+
return true;
886+
}
887+
879888
protected void WriteResourceName!(string name)
880889
{
881890
foreach (int c in name)
@@ -910,10 +919,7 @@ public abstract class GenBase : FuVisitor
910919
if (dynamic.Class.Id == FuId.ArrayPtrClass)
911920
WriteNewArray(dynamic.GetElementType(), expr.Inner, parent);
912921
else if (expr.Inner is FuAggregateInitializer init) {
913-
int tempId = this.CurrentTemporaries.IndexOf(expr);
914-
if (tempId >= 0)
915-
WriteTemporaryName(tempId);
916-
else
922+
if (!TryWriteTemporary(expr))
917923
WriteNewWithFields(dynamic, init);
918924
}
919925
else

GenC.fu

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public class GenC : GenCCpp
115115
expr.Accept(this, FuPriority.Primary);
116116
}
117117
else
118-
WriteTemporaryOrExpr(expr, FuPriority.Argument);
118+
expr.Accept(this, FuPriority.Argument);
119119
}
120120

121121
void WriteStringPtrAdd!(FuCallExpr call, bool cast)
@@ -144,15 +144,6 @@ public class GenC : GenCCpp
144144
StartDefinition(type, true, true);
145145
}
146146

147-
void WriteTemporaryOrExpr!(FuExpr expr, FuPriority parent)
148-
{
149-
int id = this.CurrentTemporaries.IndexOf(expr);
150-
if (id >= 0)
151-
WriteTemporaryName(id);
152-
else
153-
expr.Accept(this, parent);
154-
}
155-
156147
void WriteUpcast!(FuClass resultClass, FuSymbol klass)
157148
{
158149
for (; klass != resultClass; klass = klass.Parent)
@@ -164,7 +155,7 @@ public class GenC : GenCCpp
164155
switch (expr.Type) {
165156
case FuStorageType storage when storage.Class.Id == FuId.None && !IsDictionaryClassStgIndexing(expr):
166157
WriteChar('&');
167-
WriteTemporaryOrExpr(expr, FuPriority.Primary);
158+
expr.Accept(this, FuPriority.Primary);
168159
WriteUpcast(resultClass, storage.Class);
169160
break;
170161
case FuClassType ptr when ptr.Class != resultClass:
@@ -200,6 +191,8 @@ public class GenC : GenCCpp
200191

201192
internal override void VisitInterpolatedString!(FuInterpolatedString expr, FuPriority parent)
202193
{
194+
if (TryWriteTemporary(expr))
195+
return;
203196
Include("stdarg.h");
204197
Include("stdio.h");
205198
this.StringFormat = true;
@@ -413,9 +406,11 @@ public class GenC : GenCCpp
413406
WriteMatchProperty(expr, 2);
414407
break;
415408
case FuId.MatchValue:
416-
Write("g_match_info_fetch(");
417-
expr.Left.Accept(this, FuPriority.Argument);
418-
Write(", 0)");
409+
if (!TryWriteTemporary(expr)) {
410+
Write("g_match_info_fetch(");
411+
expr.Left.Accept(this, FuPriority.Argument);
412+
Write(", 0)");
413+
}
419414
break;
420415
default:
421416
if (expr.Left == null || expr.Symbol is FuConst)
@@ -1057,7 +1052,7 @@ public class GenC : GenCCpp
10571052
void WriteStorageTemporary!(FuExpr expr)
10581053
{
10591054
if (expr.IsNewString(false)
1060-
|| (expr is FuCallExpr && expr.Type is FuStorageType))
1055+
|| (expr is FuCallExpr && expr.Type is FuOwningType))
10611056
WriteCTemporary(expr.Type, expr);
10621057
}
10631058

@@ -1152,11 +1147,13 @@ public class GenC : GenCCpp
11521147

11531148
protected override void CleanupTemporary!(int i, FuExpr temp)
11541149
{
1155-
if (temp.Type.Id == FuId.StringStorageType) {
1156-
Write("free(futemp");
1157-
VisitLiteralLong(i);
1158-
WriteLine(");");
1159-
}
1150+
if (!NeedToDestructType(temp.Type)
1151+
|| (temp is FuPrefixExpr dynamicObjectLiteral && dynamicObjectLiteral.Inner is FuAggregateInitializer)) // FIXME: if temporary, still needs to be destructed
1152+
return;
1153+
WriteDestructMethodName(temp.Type.AsClassType());
1154+
Write("(futemp");
1155+
VisitLiteralLong(i);
1156+
WriteLine(");");
11601157
}
11611158

11621159
protected override void WriteVar!(FuNamedValue def)
@@ -1572,7 +1569,7 @@ public class GenC : GenCCpp
15721569
if (type.Id == FuId.StringStorageType)
15731570
WriteStringStorageValue(expr);
15741571
else if (expr.Type.Id == FuId.StringStorageType)
1575-
WriteTemporaryOrExpr(expr, parent);
1572+
expr.Accept(this, parent);
15761573
else
15771574
base.WriteCoercedInternal(type, expr, parent);
15781575
break;
@@ -1603,9 +1600,9 @@ public class GenC : GenCCpp
16031600
WriteChar('(');
16041601
Include("string.h");
16051602
Write("strcmp("); // TODO: WriteCall("strcmp", left, right);
1606-
WriteTemporaryOrExpr(left, FuPriority.Argument);
1603+
left.Accept(this, FuPriority.Argument);
16071604
Write(", ");
1608-
WriteTemporaryOrExpr(right, FuPriority.Argument);
1605+
right.Accept(this, FuPriority.Argument);
16091606
WriteChar(')');
16101607
Write(GetEqOp(not));
16111608
WriteChar('0');
@@ -1812,11 +1809,11 @@ public class GenC : GenCCpp
18121809
Write("g_string_append(");
18131810
obj.Accept(this, FuPriority.Argument);
18141811
Write(", ");
1815-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
1812+
args[0].Accept(this, FuPriority.Argument);
18161813
}
18171814
else {
18181815
Write("fputs(");
1819-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
1816+
args[0].Accept(this, FuPriority.Argument);
18201817
Write(", ");
18211818
obj.Accept(this, FuPriority.Argument);
18221819
}
@@ -1841,7 +1838,7 @@ public class GenC : GenCCpp
18411838
Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
18421839
obj.Accept(this, FuPriority.Argument);
18431840
Write(", \"%s\\n\", ");
1844-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
1841+
args[0].Accept(this, FuPriority.Argument);
18451842
WriteChar(')');
18461843
}
18471844
}
@@ -1953,7 +1950,7 @@ public class GenC : GenCCpp
19531950
Write("_TryParse(&");
19541951
obj.Accept(this, FuPriority.Primary);
19551952
Write(", ");
1956-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
1953+
args[0].Accept(this, FuPriority.Argument);
19571954
if (obj.Type is FuIntegerType)
19581955
WriteTryParseRadix(args);
19591956
WriteChar(')');
@@ -2102,12 +2099,12 @@ public class GenC : GenCCpp
21022099
break;
21032100
case FuId.StringToLower:
21042101
WriteGlib("g_utf8_strdown(");
2105-
WriteTemporaryOrExpr(obj, FuPriority.Argument);
2102+
obj.Accept(this, FuPriority.Argument);
21062103
Write(", -1)");
21072104
break;
21082105
case FuId.StringToUpper:
21092106
WriteGlib("g_utf8_strup(");
2110-
WriteTemporaryOrExpr(obj, FuPriority.Argument);
2107+
obj.Accept(this, FuPriority.Argument);
21112108
Write(", -1)");
21122109
break;
21132110
case FuId.ArrayBinarySearchAll:
@@ -2425,21 +2422,21 @@ public class GenC : GenCCpp
24252422
break;
24262423
case FuId.RegexCompile:
24272424
WriteGlib("g_regex_new(");
2428-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
2425+
args[0].Accept(this, FuPriority.Argument);
24292426
Write(", ");
24302427
WriteCRegexOptions(args);
24312428
Write(", 0, NULL)");
24322429
break;
24332430
case FuId.RegexEscape:
24342431
WriteGlib("g_regex_escape_string(");
2435-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
2432+
args[0].Accept(this, FuPriority.Argument);
24362433
Write(", -1)");
24372434
break;
24382435
case FuId.RegexIsMatchStr:
24392436
WriteGlib("g_regex_match_simple(");
2440-
WriteTemporaryOrExpr(args[1], FuPriority.Argument);
2437+
args[1].Accept(this, FuPriority.Argument);
24412438
Write(", ");
2442-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
2439+
args[0].Accept(this, FuPriority.Argument);
24432440
Write(", ");
24442441
WriteCRegexOptions(args);
24452442
Write(", 0)");
@@ -2448,17 +2445,17 @@ public class GenC : GenCCpp
24482445
Write("g_regex_match(");
24492446
obj.Accept(this, FuPriority.Argument);
24502447
Write(", ");
2451-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
2448+
args[0].Accept(this, FuPriority.Argument);
24522449
Write(", 0, NULL)");
24532450
break;
24542451
case FuId.MatchFindStr:
24552452
this.MatchFind = true;
24562453
Write("FuMatch_Find(&");
24572454
obj.Accept(this, FuPriority.Primary);
24582455
Write(", ");
2459-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
2456+
args[0].Accept(this, FuPriority.Argument);
24602457
Write(", ");
2461-
WriteTemporaryOrExpr(args[1], FuPriority.Argument);
2458+
args[1].Accept(this, FuPriority.Argument);
24622459
Write(", ");
24632460
WriteCRegexOptions(args);
24642461
WriteChar(')');
@@ -2467,7 +2464,7 @@ public class GenC : GenCCpp
24672464
Write("g_regex_match(");
24682465
args[1].Accept(this, FuPriority.Argument);
24692466
Write(", ");
2470-
WriteTemporaryOrExpr(args[0], FuPriority.Argument);
2467+
args[0].Accept(this, FuPriority.Argument);
24712468
Write(", 0, &");
24722469
obj.Accept(this, FuPriority.Primary);
24732470
WriteChar(')');
@@ -2536,6 +2533,12 @@ public class GenC : GenCCpp
25362533
}
25372534
}
25382535

2536+
internal override void VisitCallExpr!(FuCallExpr expr, FuPriority parent)
2537+
{
2538+
if (!TryWriteTemporary(expr))
2539+
base.VisitCallExpr(expr, parent);
2540+
}
2541+
25392542
void WriteDictionaryIndexing!(string function, FuBinaryExpr expr, FuPriority parent)
25402543
{
25412544
FuType valueType = expr.Left.Type.AsClassType().GetValueType();
@@ -2604,13 +2607,15 @@ public class GenC : GenCCpp
26042607
switch (expr.Op) {
26052608
case FuToken.Plus:
26062609
if (expr.Type.Id == FuId.StringStorageType) {
2610+
if (TryWriteTemporary(expr))
2611+
return;
26072612
this.StringFormat = true;
26082613
Include("stdarg.h");
26092614
Include("stdio.h");
26102615
Write("FuString_Format(\"%s%s\", ");
2611-
WriteTemporaryOrExpr(expr.Left, FuPriority.Argument);
2616+
expr.Left.Accept(this, FuPriority.Argument);
26122617
Write(", ");
2613-
WriteTemporaryOrExpr(expr.Right, FuPriority.Argument);
2618+
expr.Right.Accept(this, FuPriority.Argument);
26142619
WriteChar(')');
26152620
return;
26162621
}
@@ -2636,7 +2641,7 @@ public class GenC : GenCCpp
26362641
Write(", FuString_Format(\"%s");
26372642
WritePrintfFormat(rightInterpolated);
26382643
Write("\", ");
2639-
WriteTemporaryOrExpr(expr.Left, FuPriority.Argument); // FIXME: side effect
2644+
expr.Left.Accept(this, FuPriority.Argument); // FIXME: side effect
26402645
WriteInterpolatedStringArgs(rightInterpolated);
26412646
WriteChar(')');
26422647
}

0 commit comments

Comments
 (0)