Added class operators AddRef and Finalize. The user must implement their own refcounting if needed:
type
TManagedRecord = record
MyObject: Int32;
Ref: ^Int32;
end;
class operator TManagedRecord.AddRef(var Obj: TManagedRecord);
begin
Assert(Obj.Ref <> nil);
Obj.Ref^ += 1;
end;
class operator TManagedRecord.Finalize(var Obj: TManagedRecord);
var
i: Int32;
begin
Assert(Obj.Ref <> nil);
Assert(Obj.Ref^ > 0);
Dec(Obj.Ref^);
if (Obj.Ref^ > 0) then
Exit;
// Free stuff here!
FreeMem(Obj.Ref);
end;
function GetManagedRecord: TManagedRecord;
begin
Result.MyObject := 123;
Result.Ref := GetMem(SizeOf(Int32));
Result.Ref^ := 1;
end;
Perhaps in the future an magic record can be added to inherit from which would do the refcounting internally?
Most of the work is on in TLapeTree_Operator.Compile when assigning:
If Left is writable: Call Finalize
If Right isn't a constant: Call AddRef
After assignment if Right is an TLapeTree_Invoke result call VarToDefault to prevent double finalizing when the function cleans up.
Other changes:
Replaced Eval(op_Assign) calls with TLapeTree_Operator.Create(op_Assign) so these management operators are considered.
Skip writable check in TLapeTree_Operator only if Left.VarPos.MemPos=mpStack. Assume the stack has been correctly grown if Left is constant and so on.
Check PType in TLapeType_Pointer.Equals
Remove full disposal mode, The finalize operator can be used to replace this.
Removed operator method parsing from ParseMethod by adding ParseOperatorMethod. lpcompiler.pas diff is large due to mostly changing the indent of ParseMethod.
_Dispose is now generated if type has finalize/addref operator and calls finalize operator.
_Assign is now generated if type has finalize/addref operator.
Added class operators
AddRef
andFinalize
. The user must implement their own refcounting if needed:Perhaps in the future an magic record can be added to inherit from which would do the refcounting internally?
Most of the work is on in
TLapeTree_Operator.Compile
when assigning:Left
is writable: CallFinalize
Right
isn't a constant: CallAddRef
Right
is anTLapeTree_Invoke
result callVarToDefault
to prevent double finalizing when the function cleans up.Other changes:
Eval(op_Assign)
calls withTLapeTree_Operator.Create(op_Assign)
so these management operators are considered.TLapeTree_Operator
only ifLeft.VarPos.MemPos=mpStack
. Assume the stack has been correctly grown ifLeft
is constant and so on.PType
inTLapeType_Pointer.Equals
ParseMethod
by addingParseOperatorMethod
.lpcompiler.pas
diff is large due to mostly changing the indent ofParseMethod
._Dispose
is now generated if type has finalize/addref operator and calls finalize operator._Assign
is now generated if type has finalize/addref operator.