mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-28 17:03:09 +02:00
pastojs: started delay specialization
git-svn-id: trunk@46518 -
This commit is contained in:
parent
fcaf04686b
commit
c2cceaeba8
@ -465,9 +465,14 @@ unit FPPas2Js;
|
||||
interface
|
||||
|
||||
uses
|
||||
{$ifdef pas2js}
|
||||
js,
|
||||
{$else}
|
||||
AVL_Tree,
|
||||
{$endif}
|
||||
Classes, SysUtils, math, contnrs,
|
||||
jsbase, jstree, jswriter,
|
||||
PasTree, PScanner, PasResolveEval, PasResolver;
|
||||
PasTree, PScanner, PasResolveEval, PasResolver, PasUseAnalyzer;
|
||||
|
||||
// message numbers
|
||||
const
|
||||
@ -1372,6 +1377,15 @@ type
|
||||
{ TPas2JSResolverHub }
|
||||
|
||||
TPas2JSResolverHub = class(TPasResolverHub)
|
||||
private
|
||||
FJSSpecialized: TPasAnalyzerKeySet; // set of TPasGenericType
|
||||
public
|
||||
constructor Create(TheOwner: TObject); override;
|
||||
destructor Destroy; override;
|
||||
procedure Reset; override;
|
||||
// delayed type specialization
|
||||
procedure AddJSSpecialized(SpecType: TPasGenericType);
|
||||
function IsJSSpecialized(SpecType: TPasGenericType): boolean;
|
||||
end;
|
||||
|
||||
{ TPas2JSResolver }
|
||||
@ -1908,6 +1922,7 @@ type
|
||||
Function CreateVarStatement(const aName: String; Init: TJSElement;
|
||||
El: TPasElement): TJSVariableStatement; virtual;
|
||||
Function CreateVarDecl(const aName: String; Init: TJSElement; El: TPasElement): TJSVarDeclaration; virtual;
|
||||
Procedure InitJSSpecialization(aType: TPasType; AContext: TConvertContext; ErrorEl: TPasElement); virtual;
|
||||
// JS literals
|
||||
Function CreateLiteralNumber(El: TPasElement; const n: TJSNumber): TJSLiteral; virtual;
|
||||
Function CreateLiteralHexNumber(El: TPasElement; const n: TMaxPrecInt; Digits: byte): TJSLiteral; virtual;
|
||||
@ -2317,6 +2332,36 @@ begin
|
||||
Result:='['+Result+']';
|
||||
end;
|
||||
|
||||
{ TPas2JSResolverHub }
|
||||
|
||||
constructor TPas2JSResolverHub.Create(TheOwner: TObject);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
FJSSpecialized:=CreatePasElementSet;
|
||||
end;
|
||||
|
||||
destructor TPas2JSResolverHub.Destroy;
|
||||
begin
|
||||
FreeAndNil(FJSSpecialized);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TPas2JSResolverHub.Reset;
|
||||
begin
|
||||
inherited Reset;
|
||||
end;
|
||||
|
||||
procedure TPas2JSResolverHub.AddJSSpecialized(SpecType: TPasGenericType);
|
||||
begin
|
||||
if FJSSpecialized.FindItem(SpecType)=nil then
|
||||
FJSSpecialized.Add(SpecType,false);
|
||||
end;
|
||||
|
||||
function TPas2JSResolverHub.IsJSSpecialized(SpecType: TPasGenericType): boolean;
|
||||
begin
|
||||
Result:=FJSSpecialized.FindItem(SpecType)<>nil;
|
||||
end;
|
||||
|
||||
{ TPas2JSModuleScope }
|
||||
|
||||
procedure TPas2JSModuleScope.SetJSPromiseClass(const AValue: TPasClassType);
|
||||
@ -4918,32 +4963,44 @@ var
|
||||
Param: TPasType;
|
||||
i: Integer;
|
||||
GenSection, ParamSection: TPasSection;
|
||||
ParamResolver, GenResolver: TPasResolver;
|
||||
begin
|
||||
Result:=nil;
|
||||
{$IFNDEF EnableDelaySpecialize}
|
||||
exit;
|
||||
{$ENDIF}
|
||||
Gen:=SpecializedItem.GenericEl;
|
||||
GenSection:=GetParentSection(Gen);
|
||||
if not (GenSection is TInterfaceSection) then
|
||||
exit; // generic in unit implementation/program/library -> params cannot be defined a later section
|
||||
GenMod:=GenSection.GetModule;
|
||||
exit; // generic in unit implementation/program/library -> params cannot be defined in a later section -> no delay needed
|
||||
GenMod:=nil;
|
||||
GenResolver:=nil;
|
||||
|
||||
Params:=SpecializedItem.Params;
|
||||
for i:=0 to length(Params)-1 do
|
||||
begin
|
||||
Param:=ResolveAliasType(Params[i],false);
|
||||
if Param.ClassType=TPasUnresolvedSymbolRef then
|
||||
continue; // built-in type
|
||||
continue; // built-in type -> no delay needed
|
||||
ParamSection:=GetParentSection(Param);
|
||||
if ParamSection=GenSection then continue;
|
||||
if ParamSection=GenSection then
|
||||
continue; // same section -> no delay needed
|
||||
// not in same section
|
||||
ParamMod:=ParamSection.GetModule;
|
||||
if GenMod=nil then
|
||||
GenMod:=GenSection.GetModule;
|
||||
if ParamMod=GenMod then
|
||||
exit(Param); // generic in unit interface, specialize in implementation
|
||||
exit(Param); // generic in unit interface, param in implementation
|
||||
// param in another unit
|
||||
if ParamSection is TImplementationSection then
|
||||
exit(Param); // generic in unit interface, specialize in another(later) implementation
|
||||
exit(Param); // generic in unit interface, param in another implementation
|
||||
// param in another unit interface
|
||||
|
||||
//xxx
|
||||
if GenResolver=nil then
|
||||
GenResolver:=GetResolver(GenMod);
|
||||
ParamResolver:=GetResolver(ParamMod);
|
||||
if ParamResolver.FinishedInterfaceIndex<GenResolver.FinishedInterfaceIndex then
|
||||
exit(Param); // param in a later unit interface
|
||||
// generic in a later unit interface -> no delay needed
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -14422,7 +14479,7 @@ begin
|
||||
continue;
|
||||
end
|
||||
else if C=TPasAttributes then
|
||||
// ToDo
|
||||
continue
|
||||
else
|
||||
RaiseNotSupported(P as TPasElement,AContext,20161024191434);
|
||||
Add(E,P);
|
||||
@ -22545,6 +22602,53 @@ begin
|
||||
Result.Init:=Init;
|
||||
end;
|
||||
|
||||
procedure TPasToJSConverter.InitJSSpecialization(aType: TPasType;
|
||||
AContext: TConvertContext; ErrorEl: TPasElement);
|
||||
var
|
||||
aResolver: TPas2JSResolver;
|
||||
SpecTypeData: TPasSpecializeTypeData;
|
||||
Hub: TPas2JSResolverHub;
|
||||
SpecType: TPasGenericType;
|
||||
C: TClass;
|
||||
FuncCtx: TFunctionContext;
|
||||
SrcEl: TJSSourceElements;
|
||||
begin
|
||||
while aType<>nil do
|
||||
begin
|
||||
C:=aType.ClassType;
|
||||
if C=TPasAliasType then
|
||||
aType:=TPasAliasType(aType).DestType
|
||||
else if C=TPasSpecializeType then
|
||||
begin
|
||||
// specialized type
|
||||
SpecTypeData:=aType.CustomData as TPasSpecializeTypeData;
|
||||
if SpecTypeData=nil then
|
||||
RaiseNotSupported(aType,AContext,20200815210904);
|
||||
aResolver:=AContext.Resolver;
|
||||
Hub:=TPas2JSResolverHub(aResolver.Hub);
|
||||
SpecType:=SpecTypeData.SpecializedType;
|
||||
if Hub.IsJSSpecialized(SpecType) then exit;
|
||||
Hub.AddJSSpecialized(SpecType);
|
||||
FuncCtx:=AContext.GetGlobalFunc;
|
||||
SrcEl:=FuncCtx.JSElement as TJSSourceElements;
|
||||
|
||||
if SrcEl=nil then ;
|
||||
|
||||
if SpecType is TPasRecordType then
|
||||
begin
|
||||
// add $mod.TAnt$G1();
|
||||
//CreateReferencePath();
|
||||
RaiseNotSupported(ErrorEl,AContext,20200815215652);
|
||||
end
|
||||
else
|
||||
RaiseNotSupported(ErrorEl,AContext,20200815215338);
|
||||
exit;
|
||||
end
|
||||
else
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.CreateLiteralNumber(El: TPasElement;
|
||||
const n: TJSNumber): TJSLiteral;
|
||||
begin
|
||||
@ -24639,6 +24743,7 @@ var
|
||||
ok, IsFull: Boolean;
|
||||
VarSt: TJSVariableStatement;
|
||||
bifn: TPas2JSBuiltInName;
|
||||
RecScope: TPas2JSRecordScope;
|
||||
begin
|
||||
Result:=nil;
|
||||
if El.Name='' then
|
||||
@ -24657,14 +24762,14 @@ begin
|
||||
// rtl.recNewT()
|
||||
Call:=CreateCallExpression(El);
|
||||
bifn:=pbifnRecordCreateType;
|
||||
{$IFDEF EnableDelaySpecialize}
|
||||
|
||||
RecScope:=TPas2JSRecordScope(El.CustomData);
|
||||
if RecScope.SpecializedFromItem<>nil then
|
||||
begin
|
||||
if RecScope.SpecializedFromItem.FirstSpecialize.GetModule<>EL.GetModule then
|
||||
bifn:=pbifnRecordCreateSpecializeType;
|
||||
// ToDo
|
||||
//if aResolver.SpecializeNeedsDelay(RecScope.SpecializedFromItem)<>nil then
|
||||
//bifn:=pbifnRecordCreateSpecializeType;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
Call.Expr:=CreateMemberExpression([GetBIName(pbivnRTL),GetBIName(bifn)]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user