mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 11:19:58 +02:00
pastojs: fixed mem leak
git-svn-id: trunk@39462 -
This commit is contained in:
parent
4b973bf22d
commit
acea898d9c
@ -5137,117 +5137,123 @@ Var
|
|||||||
ModuleName, ModVarName: String;
|
ModuleName, ModVarName: String;
|
||||||
IntfContext: TSectionContext;
|
IntfContext: TSectionContext;
|
||||||
ImplVarSt: TJSVariableStatement;
|
ImplVarSt: TJSVariableStatement;
|
||||||
HasImplUsesClause: Boolean;
|
HasImplUsesClause, ok: Boolean;
|
||||||
UsesClause: TPasUsesClause;
|
UsesClause: TPasUsesClause;
|
||||||
begin
|
begin
|
||||||
Result:=Nil;
|
Result:=Nil;
|
||||||
OuterSrc:=TJSSourceElements(CreateElement(TJSSourceElements, El));
|
OuterSrc:=TJSSourceElements(CreateElement(TJSSourceElements, El));
|
||||||
Result:=OuterSrc;
|
Result:=OuterSrc;
|
||||||
|
ok:=false;
|
||||||
// create 'rtl.module(...)'
|
|
||||||
RegModuleCall:=CreateCallExpression(El);
|
|
||||||
AddToSourceElements(OuterSrc,RegModuleCall);
|
|
||||||
RegModuleCall.Expr:=CreateMemberExpression([FBuiltInNames[pbivnRTL],'module']);
|
|
||||||
ArgArray := RegModuleCall.Args;
|
|
||||||
RegModuleCall.Args:=ArgArray;
|
|
||||||
|
|
||||||
// add unitname parameter: unitname
|
|
||||||
ModuleName:=TransformModuleName(El,false,AContext);
|
|
||||||
ArgArray.Elements.AddElement.Expr:=CreateLiteralString(El,ModuleName);
|
|
||||||
|
|
||||||
// add interface-uses-section parameter: [<interface uses1>,<uses2>, ...]
|
|
||||||
UsesSection:=nil;
|
|
||||||
if (El is TPasProgram) then
|
|
||||||
UsesSection:=TPasProgram(El).ProgramSection
|
|
||||||
else if (El is TPasLibrary) then
|
|
||||||
UsesSection:=TPasLibrary(El).LibrarySection
|
|
||||||
else
|
|
||||||
UsesSection:=El.InterfaceSection;
|
|
||||||
ArgArray.Elements.AddElement.Expr:=CreateUsesList(UsesSection,AContext);
|
|
||||||
|
|
||||||
// add interface parameter: function(){}
|
|
||||||
FunDecl:=CreateFunctionSt(El,true,true);
|
|
||||||
ArgArray.AddElement(FunDecl);
|
|
||||||
Src:=FunDecl.AFunction.Body.A as TJSSourceElements;
|
|
||||||
|
|
||||||
if coUseStrict in Options then
|
|
||||||
// "use strict" must be the first statement in a function
|
|
||||||
AddToSourceElements(Src,CreateLiteralString(El,'use strict'));
|
|
||||||
|
|
||||||
ImplVarSt:=nil;
|
|
||||||
HasImplUsesClause:=false;
|
|
||||||
|
|
||||||
IntfContext:=TSectionContext.Create(El,Src,AContext);
|
|
||||||
try
|
try
|
||||||
// add "var $mod = this;"
|
// create 'rtl.module(...)'
|
||||||
IntfContext.ThisPas:=El;
|
RegModuleCall:=CreateCallExpression(El);
|
||||||
if El.CustomData is TPasModuleScope then
|
AddToSourceElements(OuterSrc,RegModuleCall);
|
||||||
IntfContext.ScannerBoolSwitches:=TPasModuleScope(El.CustomData).BoolSwitches;
|
RegModuleCall.Expr:=CreateMemberExpression([FBuiltInNames[pbivnRTL],'module']);
|
||||||
ModVarName:=FBuiltInNames[pbivnModule];
|
ArgArray := RegModuleCall.Args;
|
||||||
IntfContext.AddLocalVar(ModVarName,El);
|
RegModuleCall.Args:=ArgArray;
|
||||||
AddToSourceElements(Src,CreateVarStatement(ModVarName,
|
|
||||||
CreatePrimitiveDotExpr('this',El),El));
|
|
||||||
|
|
||||||
|
// add unitname parameter: unitname
|
||||||
|
ModuleName:=TransformModuleName(El,false,AContext);
|
||||||
|
ArgArray.Elements.AddElement.Expr:=CreateLiteralString(El,ModuleName);
|
||||||
|
|
||||||
|
// add interface-uses-section parameter: [<interface uses1>,<uses2>, ...]
|
||||||
|
UsesSection:=nil;
|
||||||
if (El is TPasProgram) then
|
if (El is TPasProgram) then
|
||||||
begin // program
|
UsesSection:=TPasProgram(El).ProgramSection
|
||||||
if Assigned(TPasProgram(El).ProgramSection) then
|
else if (El is TPasLibrary) then
|
||||||
AddToSourceElements(Src,ConvertDeclarations(TPasProgram(El).ProgramSection,IntfContext));
|
UsesSection:=TPasLibrary(El).LibrarySection
|
||||||
CreateInitSection(El,Src,IntfContext);
|
|
||||||
end
|
|
||||||
else if El is TPasLibrary then
|
|
||||||
begin // library
|
|
||||||
if Assigned(TPasLibrary(El).LibrarySection) then
|
|
||||||
AddToSourceElements(Src,ConvertDeclarations(TPasLibrary(El).LibrarySection,IntfContext));
|
|
||||||
CreateInitSection(El,Src,IntfContext);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin // unit
|
UsesSection:=El.InterfaceSection;
|
||||||
if Assigned(El.ImplementationSection) then
|
ArgArray.Elements.AddElement.Expr:=CreateUsesList(UsesSection,AContext);
|
||||||
begin
|
|
||||||
// add var $impl = $mod.$impl
|
|
||||||
ImplVarSt:=CreateVarStatement(FBuiltInNames[pbivnImplementation],
|
|
||||||
CreateMemberExpression([ModVarName,FBuiltInNames[pbivnImplementation]]),El);
|
|
||||||
AddToSourceElements(Src,ImplVarSt);
|
|
||||||
// register local var $impl
|
|
||||||
IntfContext.AddLocalVar(FBuiltInNames[pbivnImplementation],El.ImplementationSection);
|
|
||||||
end;
|
|
||||||
if Assigned(El.InterfaceSection) then
|
|
||||||
AddToSourceElements(Src,ConvertDeclarations(El.InterfaceSection,IntfContext));
|
|
||||||
CreateInitSection(El,Src,IntfContext);
|
|
||||||
|
|
||||||
// add optional implementation uses list: [<implementation uses1>,<uses2>, ...]
|
// add interface parameter: function(){}
|
||||||
if Assigned(El.ImplementationSection) then
|
FunDecl:=CreateFunctionSt(El,true,true);
|
||||||
begin
|
ArgArray.AddElement(FunDecl);
|
||||||
UsesClause:=El.ImplementationSection.UsesClause;
|
Src:=FunDecl.AFunction.Body.A as TJSSourceElements;
|
||||||
if length(UsesClause)>0 then
|
|
||||||
|
if coUseStrict in Options then
|
||||||
|
// "use strict" must be the first statement in a function
|
||||||
|
AddToSourceElements(Src,CreateLiteralString(El,'use strict'));
|
||||||
|
|
||||||
|
ImplVarSt:=nil;
|
||||||
|
HasImplUsesClause:=false;
|
||||||
|
|
||||||
|
IntfContext:=TSectionContext.Create(El,Src,AContext);
|
||||||
|
try
|
||||||
|
// add "var $mod = this;"
|
||||||
|
IntfContext.ThisPas:=El;
|
||||||
|
if El.CustomData is TPasModuleScope then
|
||||||
|
IntfContext.ScannerBoolSwitches:=TPasModuleScope(El.CustomData).BoolSwitches;
|
||||||
|
ModVarName:=FBuiltInNames[pbivnModule];
|
||||||
|
IntfContext.AddLocalVar(ModVarName,El);
|
||||||
|
AddToSourceElements(Src,CreateVarStatement(ModVarName,
|
||||||
|
CreatePrimitiveDotExpr('this',El),El));
|
||||||
|
|
||||||
|
if (El is TPasProgram) then
|
||||||
|
begin // program
|
||||||
|
if Assigned(TPasProgram(El).ProgramSection) then
|
||||||
|
AddToSourceElements(Src,ConvertDeclarations(TPasProgram(El).ProgramSection,IntfContext));
|
||||||
|
CreateInitSection(El,Src,IntfContext);
|
||||||
|
end
|
||||||
|
else if El is TPasLibrary then
|
||||||
|
begin // library
|
||||||
|
if Assigned(TPasLibrary(El).LibrarySection) then
|
||||||
|
AddToSourceElements(Src,ConvertDeclarations(TPasLibrary(El).LibrarySection,IntfContext));
|
||||||
|
CreateInitSection(El,Src,IntfContext);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin // unit
|
||||||
|
if Assigned(El.ImplementationSection) then
|
||||||
begin
|
begin
|
||||||
ArgArray.AddElement(CreateUsesList(El.ImplementationSection,AContext));
|
// add var $impl = $mod.$impl
|
||||||
HasImplUsesClause:=true;
|
ImplVarSt:=CreateVarStatement(FBuiltInNames[pbivnImplementation],
|
||||||
|
CreateMemberExpression([ModVarName,FBuiltInNames[pbivnImplementation]]),El);
|
||||||
|
AddToSourceElements(Src,ImplVarSt);
|
||||||
|
// register local var $impl
|
||||||
|
IntfContext.AddLocalVar(FBuiltInNames[pbivnImplementation],El.ImplementationSection);
|
||||||
end;
|
end;
|
||||||
|
if Assigned(El.InterfaceSection) then
|
||||||
|
AddToSourceElements(Src,ConvertDeclarations(El.InterfaceSection,IntfContext));
|
||||||
|
CreateInitSection(El,Src,IntfContext);
|
||||||
|
|
||||||
|
// add optional implementation uses list: [<implementation uses1>,<uses2>, ...]
|
||||||
|
if Assigned(El.ImplementationSection) then
|
||||||
|
begin
|
||||||
|
UsesClause:=El.ImplementationSection.UsesClause;
|
||||||
|
if length(UsesClause)>0 then
|
||||||
|
begin
|
||||||
|
ArgArray.AddElement(CreateUsesList(El.ImplementationSection,AContext));
|
||||||
|
HasImplUsesClause:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
finally
|
||||||
end;
|
IntfContext.Free;
|
||||||
finally
|
|
||||||
IntfContext.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// add implementation function
|
|
||||||
if ImplVarSt<>nil then
|
|
||||||
begin
|
|
||||||
ImplFunc:=CreateImplementationSection(El,AContext);
|
|
||||||
if ImplFunc=nil then
|
|
||||||
begin
|
|
||||||
// remove unneeded $impl from interface
|
|
||||||
RemoveFromSourceElements(Src,ImplVarSt);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
// add param
|
|
||||||
if not HasImplUsesClause then
|
|
||||||
ArgArray.AddElement(CreateLiteralNull(El));
|
|
||||||
ArgArray.AddElement(ImplFunc);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// add implementation function
|
||||||
|
if ImplVarSt<>nil then
|
||||||
|
begin
|
||||||
|
ImplFunc:=CreateImplementationSection(El,AContext);
|
||||||
|
if ImplFunc=nil then
|
||||||
|
begin
|
||||||
|
// remove unneeded $impl from interface
|
||||||
|
RemoveFromSourceElements(Src,ImplVarSt);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// add param
|
||||||
|
if not HasImplUsesClause then
|
||||||
|
ArgArray.AddElement(CreateLiteralNull(El));
|
||||||
|
ArgArray.AddElement(ImplFunc);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ok:=true;
|
||||||
|
finally
|
||||||
|
if not ok then
|
||||||
|
FreeAndNil(Result);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.CreateElement(C: TJSElementClass; Src: TPasElement
|
function TPasToJSConverter.CreateElement(C: TJSElementClass; Src: TPasElement
|
||||||
@ -7653,7 +7659,10 @@ var
|
|||||||
begin
|
begin
|
||||||
AccessEl:=aResolver.GetPasPropertySetter(Prop);
|
AccessEl:=aResolver.GetPasPropertySetter(Prop);
|
||||||
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,true) then
|
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,true) then
|
||||||
|
begin
|
||||||
|
FreeAndNil(Call);
|
||||||
exit;
|
exit;
|
||||||
|
end;
|
||||||
AssignContext:=AContext.AccessContext as TAssignContext;
|
AssignContext:=AContext.AccessContext as TAssignContext;
|
||||||
AssignContext.PropertyEl:=Prop;
|
AssignContext.PropertyEl:=Prop;
|
||||||
AssignContext.Setter:=AccessEl;
|
AssignContext.Setter:=AccessEl;
|
||||||
@ -7663,7 +7672,10 @@ var
|
|||||||
begin
|
begin
|
||||||
AccessEl:=aResolver.GetPasPropertyGetter(Prop);
|
AccessEl:=aResolver.GetPasPropertyGetter(Prop);
|
||||||
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,true) then
|
if IsJSBracketAccessorAndConvert(Prop,AccessEl,AContext,true) then
|
||||||
|
begin
|
||||||
|
FreeAndNil(Call);
|
||||||
exit;
|
exit;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
RaiseNotSupported(El,AContext,20170213213317);
|
RaiseNotSupported(El,AContext,20170213213317);
|
||||||
|
@ -1139,6 +1139,13 @@ begin
|
|||||||
{$IFDEF EnablePasTreeGlobalRefCount}
|
{$IFDEF EnablePasTreeGlobalRefCount}
|
||||||
FElementRefCountAtSetup:=TPasElement.GlobalRefCount;
|
FElementRefCountAtSetup:=TPasElement.GlobalRefCount;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
if FModules<>nil then
|
||||||
|
begin
|
||||||
|
writeln('TCustomTestModule.SetUp FModules<>nil');
|
||||||
|
Halt;
|
||||||
|
end;
|
||||||
|
|
||||||
inherited SetUp;
|
inherited SetUp;
|
||||||
FSkipTests:=false;
|
FSkipTests:=false;
|
||||||
FSource:=TStringList.Create;
|
FSource:=TStringList.Create;
|
||||||
@ -1196,7 +1203,6 @@ begin
|
|||||||
FHintMsgs.Clear;
|
FHintMsgs.Clear;
|
||||||
FHintMsgsGood.Clear;
|
FHintMsgsGood.Clear;
|
||||||
FSkipTests:=false;
|
FSkipTests:=false;
|
||||||
FJSModule:=nil;
|
|
||||||
FJSRegModuleCall:=nil;
|
FJSRegModuleCall:=nil;
|
||||||
FJSModuleCallArgs:=nil;
|
FJSModuleCallArgs:=nil;
|
||||||
FJSImplentationUses:=nil;
|
FJSImplentationUses:=nil;
|
||||||
@ -1704,6 +1710,7 @@ begin
|
|||||||
writeln('CheckUnit '+Filename+' converting ...');
|
writeln('CheckUnit '+Filename+' converting ...');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
aConverter:=CreateConverter;
|
aConverter:=CreateConverter;
|
||||||
|
aJSModule:=nil;
|
||||||
try
|
try
|
||||||
try
|
try
|
||||||
aJSModule:=aConverter.ConvertPasElement(aResolver.Module,aResolver) as TJSSourceElements;
|
aJSModule:=aConverter.ConvertPasElement(aResolver.Module,aResolver) as TJSSourceElements;
|
||||||
@ -1720,6 +1727,7 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
CheckDiff('Converted unit: "'+ChangeFileExt(Filename,'.js')+'"',ExpectedSrc,ActualSrc);
|
CheckDiff('Converted unit: "'+ChangeFileExt(Filename,'.js')+'"',ExpectedSrc,ActualSrc);
|
||||||
finally
|
finally
|
||||||
|
aJSModule.Free;
|
||||||
aConverter.Free;
|
aConverter.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -17,6 +17,7 @@ program testpas2js;
|
|||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
//MemCheck,
|
||||||
Classes, consoletestrunner, tcconverter, tcmodules, tcoptimizations, tcsrcmap,
|
Classes, consoletestrunner, tcconverter, tcmodules, tcoptimizations, tcsrcmap,
|
||||||
tcfiler, Pas2JsFiler, tcunitsearch, tcprecompile;
|
tcfiler, Pas2JsFiler, tcunitsearch, tcprecompile;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user