From b5d8828c5034b484ff068c206ae9cd9bfebcb45b Mon Sep 17 00:00:00 2001 From: Piotr Fusik Date: Wed, 13 Mar 2024 14:03:43 +0100 Subject: [PATCH] [c] Release temporary dynamic references. #26 --- GenC.fu | 6 +++--- libfut.cpp | 6 +++--- libfut.cs | 6 +++--- libfut.js | 6 +++--- test/MethodArgTempDynamic.fu | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/GenC.fu b/GenC.fu index 1ecb14e6..59b58d25 100644 --- a/GenC.fu +++ b/GenC.fu @@ -1061,7 +1061,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); } @@ -1116,7 +1116,7 @@ public class GenC : GenCCpp FuVar? param = method.FirstParameter(); foreach (FuExpr arg in call.Arguments) { WriteCTemporaries(arg); - if (call.Method.Symbol.Id != FuId.ConsoleWrite && call.Method.Symbol.Id != FuId.ConsoleWriteLine && !(param.Type is FuStorageType)) + if (call.Method.Symbol.Id != FuId.ConsoleWrite && call.Method.Symbol.Id != FuId.ConsoleWriteLine && param.Type.Id != FuId.TypeParam0NotFinal && !(param.Type is FuOwningType)) WriteStorageTemporary(arg); param = param.NextVar(); } @@ -1549,7 +1549,6 @@ public class GenC : GenCCpp { switch (type) { case FuDynamicPtrType dynamic when expr is FuSymbolReference && parent != FuPriority.Equality: - this.SharedAddRef = true; if (dynamic.Class.Id == FuId.ArrayPtrClass) WriteDynamicArrayCast(dynamic.GetElementType()); else { @@ -1557,6 +1556,7 @@ public class GenC : GenCCpp WriteName(dynamic.Class); Write(" *) "); } + this.SharedAddRef = true; WriteCall("FuShared_AddRef", expr); break; case FuClassType klass when klass.Class.Id != FuId.StringClass && klass.Class.Id != FuId.ArrayPtrClass && !(klass is FuStorageType): diff --git a/libfut.cpp b/libfut.cpp index 7e39e793..4fecf6bc 100644 --- a/libfut.cpp +++ b/libfut.cpp @@ -9971,7 +9971,7 @@ int GenC::writeCTemporary(const FuType * type, const FuExpr * expr) void GenC::writeStorageTemporary(const FuExpr * expr) { - if (expr->isNewString(false) || (dynamic_cast(expr) && dynamic_cast(expr->type.get()))) + if (expr->isNewString(false) || (dynamic_cast(expr) && dynamic_cast(expr->type.get()))) writeCTemporary(expr->type.get(), expr); } @@ -10021,7 +10021,7 @@ void GenC::writeCTemporaries(const FuExpr * expr) const FuVar * param = method->firstParameter(); for (const std::shared_ptr &arg : call->arguments) { writeCTemporaries(arg.get()); - if (call->method->symbol->id != FuId::consoleWrite && call->method->symbol->id != FuId::consoleWriteLine && !dynamic_cast(param->type.get())) + if (call->method->symbol->id != FuId::consoleWrite && call->method->symbol->id != FuId::consoleWriteLine && param->type->id != FuId::typeParam0NotFinal && !dynamic_cast(param->type.get())) writeStorageTemporary(arg.get()); param = param->nextVar(); } @@ -10446,7 +10446,6 @@ void GenC::writeCoercedInternal(const FuType * type, const FuExpr * expr, FuPrio const FuDynamicPtrType * dynamic; const FuClassType * klass; if ((dynamic = dynamic_cast(type)) && dynamic_cast(expr) && parent != FuPriority::equality) { - this->sharedAddRef = true; if (dynamic->class_->id == FuId::arrayPtrClass) writeDynamicArrayCast(dynamic->getElementType().get()); else { @@ -10454,6 +10453,7 @@ void GenC::writeCoercedInternal(const FuType * type, const FuExpr * expr, FuPrio writeName(dynamic->class_); write(" *) "); } + this->sharedAddRef = true; writeCall("FuShared_AddRef", expr); } else if ((klass = dynamic_cast(type)) && klass->class_->id != FuId::stringClass && klass->class_->id != FuId::arrayPtrClass && !dynamic_cast(klass)) { diff --git a/libfut.cs b/libfut.cs index f0fefbe8..9b1c69d0 100644 --- a/libfut.cs +++ b/libfut.cs @@ -10275,7 +10275,7 @@ int WriteCTemporary(FuType type, FuExpr expr) void WriteStorageTemporary(FuExpr expr) { - if (expr.IsNewString(false) || (expr is FuCallExpr && expr.Type is FuStorageType)) + if (expr.IsNewString(false) || (expr is FuCallExpr && expr.Type is FuOwningType)) WriteCTemporary(expr.Type, expr); } @@ -10330,7 +10330,7 @@ void WriteCTemporaries(FuExpr expr) FuVar param = method.FirstParameter(); foreach (FuExpr arg in call.Arguments) { WriteCTemporaries(arg); - if (call.Method.Symbol.Id != FuId.ConsoleWrite && call.Method.Symbol.Id != FuId.ConsoleWriteLine && !(param.Type is FuStorageType)) + if (call.Method.Symbol.Id != FuId.ConsoleWrite && call.Method.Symbol.Id != FuId.ConsoleWriteLine && param.Type.Id != FuId.TypeParam0NotFinal && !(param.Type is FuOwningType)) WriteStorageTemporary(arg); param = param.NextVar(); } @@ -10748,7 +10748,6 @@ protected override void WriteCoercedInternal(FuType type, FuExpr expr, FuPriorit { switch (type) { case FuDynamicPtrType dynamic when expr is FuSymbolReference && parent != FuPriority.Equality: - this.SharedAddRef = true; if (dynamic.Class.Id == FuId.ArrayPtrClass) WriteDynamicArrayCast(dynamic.GetElementType()); else { @@ -10756,6 +10755,7 @@ protected override void WriteCoercedInternal(FuType type, FuExpr expr, FuPriorit WriteName(dynamic.Class); Write(" *) "); } + this.SharedAddRef = true; WriteCall("FuShared_AddRef", expr); break; case FuClassType klass when klass.Class.Id != FuId.StringClass && klass.Class.Id != FuId.ArrayPtrClass && !(klass is FuStorageType): diff --git a/libfut.js b/libfut.js index 6ca875fc..a358e123 100644 --- a/libfut.js +++ b/libfut.js @@ -10616,7 +10616,7 @@ export class GenC extends GenCCpp #writeStorageTemporary(expr) { - if (expr.isNewString(false) || (expr instanceof FuCallExpr && expr.type instanceof FuStorageType)) + if (expr.isNewString(false) || (expr instanceof FuCallExpr && expr.type instanceof FuOwningType)) this.#writeCTemporary(expr.type, expr); } @@ -10677,7 +10677,7 @@ export class GenC extends GenCCpp let param = method.firstParameter(); for (const arg of call.arguments_) { this.#writeCTemporaries(arg); - if (call.method.symbol.id != FuId.CONSOLE_WRITE && call.method.symbol.id != FuId.CONSOLE_WRITE_LINE && !(param.type instanceof FuStorageType)) + if (call.method.symbol.id != FuId.CONSOLE_WRITE && call.method.symbol.id != FuId.CONSOLE_WRITE_LINE && param.type.id != FuId.TYPE_PARAM0_NOT_FINAL && !(param.type instanceof FuOwningType)) this.#writeStorageTemporary(arg); param = param.nextVar(); } @@ -11124,7 +11124,6 @@ export class GenC extends GenCCpp let dynamic; let klass; if ((dynamic = type) instanceof FuDynamicPtrType && expr instanceof FuSymbolReference && parent != FuPriority.EQUALITY) { - this.#sharedAddRef = true; if (dynamic.class.id == FuId.ARRAY_PTR_CLASS) this.#writeDynamicArrayCast(dynamic.getElementType()); else { @@ -11132,6 +11131,7 @@ export class GenC extends GenCCpp this.writeName(dynamic.class); this.write(" *) "); } + this.#sharedAddRef = true; this.writeCall("FuShared_AddRef", expr); } else if ((klass = type) instanceof FuClassType && klass.class.id != FuId.STRING_CLASS && klass.class.id != FuId.ARRAY_PTR_CLASS && !(klass instanceof FuStorageType)) { diff --git a/test/MethodArgTempDynamic.fu b/test/MethodArgTempDynamic.fu index be86c4fe..dd5426da 100644 --- a/test/MethodArgTempDynamic.fu +++ b/test/MethodArgTempDynamic.fu @@ -8,7 +8,7 @@ public class Test public static bool Run() { - Consume(Create()); //FAIL: c leak TODO + Consume(Create()); return true; } }