* synchronized with trunk

git-svn-id: branches/wasm@46466 -
This commit is contained in:
nickysn 2020-08-16 23:43:13 +00:00
commit 78ad7b7dfa
39 changed files with 485 additions and 83 deletions

1
.gitattributes vendored
View File

@ -16596,6 +16596,7 @@ tests/webtbf/tw3740.pp svneol=native#text/plain
tests/webtbf/tw37460.pp svneol=native#text/pascal tests/webtbf/tw37460.pp svneol=native#text/pascal
tests/webtbf/tw37462.pp svneol=native#text/pascal tests/webtbf/tw37462.pp svneol=native#text/pascal
tests/webtbf/tw37475.pp svneol=native#text/pascal tests/webtbf/tw37475.pp svneol=native#text/pascal
tests/webtbf/tw37476.pp svneol=native#text/pascal
tests/webtbf/tw3790.pp svneol=native#text/plain tests/webtbf/tw3790.pp svneol=native#text/plain
tests/webtbf/tw3812.pp svneol=native#text/plain tests/webtbf/tw3812.pp svneol=native#text/plain
tests/webtbf/tw3930a.pp svneol=native#text/plain tests/webtbf/tw3930a.pp svneol=native#text/plain

View File

@ -50,6 +50,7 @@ Interface
function RemoveSuperfluousFMov(const p: tai; movp: tai; const optimizer: string): boolean; function RemoveSuperfluousFMov(const p: tai; movp: tai; const optimizer: string): boolean;
function OptPass1STP(var p: tai): boolean; function OptPass1STP(var p: tai): boolean;
function OptPass1Mov(var p: tai): boolean; function OptPass1Mov(var p: tai): boolean;
function OptPass1FMov(var p: tai): Boolean;
End; End;
Implementation Implementation
@ -60,6 +61,16 @@ Implementation
cgutils, cgutils,
verbose; verbose;
{$ifdef DEBUG_AOPTCPU}
const
SPeepholeOptimization: shortstring = 'Peephole Optimization: ';
{$else DEBUG_AOPTCPU}
{ Empty strings help the optimizer to remove string concatenations that won't
ever appear to the user on release builds. [Kit] }
const
SPeepholeOptimization = '';
{$endif DEBUG_AOPTCPU}
function CanBeCond(p : tai) : boolean; function CanBeCond(p : tai) : boolean;
begin begin
result:=(p.typ=ait_instruction) and (taicpu(p).condition=C_None); result:=(p.typ=ait_instruction) and (taicpu(p).condition=C_None);
@ -490,6 +501,31 @@ Implementation
end; end;
function TCpuAsmOptimizer.OptPass1FMov(var p: tai): Boolean;
var
hp1: tai;
begin
{
change
fmov reg0,reg1
fmov reg1,reg0
into
fmov reg0,reg1
}
Result := False;
while GetNextInstruction(p, hp1) and
MatchInstruction(hp1, A_FMOV, [taicpu(p).condition], [taicpu(p).oppostfix]) and
MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^) and
MatchOperand(taicpu(p).oper[1]^, taicpu(hp1).oper[0]^) do
begin
asml.Remove(hp1);
hp1.free;
DebugMsg(SPeepholeOptimization + 'FMovFMov2FMov done', p);
Result:=true;
end;
end;
function TCpuAsmOptimizer.OptPostCMP(var p : tai): boolean; function TCpuAsmOptimizer.OptPostCMP(var p : tai): boolean;
var var
hp1,hp2: tai; hp1,hp2: tai;
@ -580,7 +616,9 @@ Implementation
if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
RemoveSuperfluousFMov(p, hp1, 'FOpFMov2FOp') then RemoveSuperfluousFMov(p, hp1, 'FOpFMov2FOp') then
Result:=true; Result:=true;
end end;
A_FMOV:
Result:=OptPass1FMov(p);
else else
; ;
end; end;

View File

@ -882,7 +882,7 @@ Implementation
if (target_ar.id in [ar_gnu_ar_scripted,ar_sdcc_sdar_scripted]) then if (target_ar.id in [ar_gnu_ar_scripted,ar_sdcc_sdar_scripted]) then
writeln(script, 'CREATE ' + current_module.staticlibfilename) writeln(script, 'CREATE ' + current_module.staticlibfilename)
else { wlib case } else { wlib case }
writeln(script,'-q -fo -c -b '+ writeln(script,'-q -p=16 -fo -c -b '+
maybequoted(current_module.staticlibfilename)); maybequoted(current_module.staticlibfilename));
current := TCmdStrListItem(SmartLinkOFiles.First); current := TCmdStrListItem(SmartLinkOFiles.First);
while current <> nil do while current <> nil do
@ -1743,8 +1743,8 @@ Implementation
ar_watcom_wlib_omf_info : tarinfo = ar_watcom_wlib_omf_info : tarinfo =
( id : ar_watcom_wlib_omf; ( id : ar_watcom_wlib_omf;
addfilecmd : '+'; addfilecmd : '+';
arfirstcmd : 'wlib -q -fo -c -b -n -o=$OUTPUTLIB $LIB $FILES'; arfirstcmd : 'wlib -q -p=16 -fo -c -b -n -o=$OUTPUTLIB $LIB $FILES';
arcmd : 'wlib -q -fo -c -b -o=$OUTPUTLIB $LIB $FILES'; arcmd : 'wlib -q -p=16 -fo -c -b -o=$OUTPUTLIB $LIB $FILES';
arfinishcmd : '' arfinishcmd : ''
); );

View File

@ -1326,7 +1326,9 @@ implementation
(right.nodetype in [ltn,lten,gtn,gten]) and (right.nodetype in [ltn,lten,gtn,gten]) and
(not might_have_sideeffects(left)) and (not might_have_sideeffects(left)) and
(not might_have_sideeffects(right)) and (not might_have_sideeffects(right)) and
is_range_test(taddnode(left),taddnode(right),vl,cl,cr) then is_range_test(taddnode(left),taddnode(right),vl,cl,cr) and
{ avoid optimization being applied to (<string. var > charconst1) and (<string. var < charconst2) }
(vl.resultdef.typ in [orddef,enumdef]) then
begin begin
hdef:=get_unsigned_inttype(vl.resultdef); hdef:=get_unsigned_inttype(vl.resultdef);
vl:=ctypeconvnode.create_internal(vl.getcopy,hdef); vl:=ctypeconvnode.create_internal(vl.getcopy,hdef);
@ -3000,7 +3002,7 @@ implementation
end; end;
end; end;
if not codegenerror and if (errorcount=0) and
not assigned(result) then not assigned(result) then
result:=simplify(false); result:=simplify(false);
end; end;

View File

@ -623,6 +623,18 @@ implementation
assigned(funcretnode) then assigned(funcretnode) then
hlcg.gen_load_cgpara_loc(current_asmdata.CurrAsmList,realresdef,retloc,location,false); hlcg.gen_load_cgpara_loc(current_asmdata.CurrAsmList,realresdef,retloc,location,false);
if ((location.loc=LOC_REGISTER) and
not realresdef.is_intregable) or
((location.loc in [LOC_FPUREGISTER,LOC_MMREGISTER]) and
(not realresdef.is_fpuregable or
((location.loc=LOC_MMREGISTER)<>use_vectorfpu(realresdef)))) then
begin
hlcg.location_force_mem(current_asmdata.CurrAsmList,location,realresdef);
{ may have been record returned in a floating point register (-> location.size
will be the size of the fpuregister instead of the int size of the record) }
location.size:=def_cgsize(realresdef);
end;
{ copy value to the final location if this was already provided to the { copy value to the final location if this was already provided to the
callnode. This must be done after the call node, because the location can callnode. This must be done after the call node, because the location can
also be used as parameter and may not be finalized yet } also be used as parameter and may not be finalized yet }

View File

@ -623,7 +623,7 @@ implementation
begin begin
sym:=tsym(fields[i]); sym:=tsym(fields[i]);
write_rtti_reference(tcb,tfieldvarsym(sym).vardef,rt); write_rtti_reference(tcb,tfieldvarsym(sym).vardef,rt);
tcb.emit_ord_const(tfieldvarsym(sym).fieldoffset,ptruinttype); tcb.emit_ord_const(tfieldvarsym(sym).fieldoffset,sizeuinttype);
end; end;
fields.free; fields.free;
end; end;

View File

@ -3178,9 +3178,14 @@ const
result:=target_info.Cprefix+tprocdef(pd).procsym.realname result:=target_info.Cprefix+tprocdef(pd).procsym.realname
else else
result:=pd.procsym.realname; result:=pd.procsym.realname;
{$ifdef i8086}
{ Turbo Pascal expects names of external routines
to be all uppercase }
if (target_info.system=system_i8086_msdos) and if (target_info.system=system_i8086_msdos) and
(m_tp7 in current_settings.modeswitches) and
(pd.proccalloption=pocall_pascal) then (pd.proccalloption=pocall_pascal) then
result:=UpCase(result); result:=UpCase(result);
{$endif i8086}
end; end;
end; end;
end; end;

View File

@ -460,6 +460,16 @@ implementation
end; end;
end; end;
end; end;
{$ifdef i8086}
{ enable cs_force_far_calls when m_nested_procvars is enabled }
if switch=m_nested_procvars then
begin
include(current_settings.localswitches,cs_force_far_calls);
if changeinit then
include(init_settings.localswitches,cs_force_far_calls);
end;
{$endif i8086}
end; end;
@ -605,12 +615,18 @@ implementation
end; end;
{$ifdef i8086} {$ifdef i8086}
{ Do not force far calls in the TP mode by default } { Do not force far calls in the TP mode by default, force it in other modes }
if (m_tp7 in current_settings.modeswitches) then if (m_tp7 in current_settings.modeswitches) then
begin begin
exclude(current_settings.localswitches,cs_force_far_calls); exclude(current_settings.localswitches,cs_force_far_calls);
if changeinit then if changeinit then
exclude(init_settings.localswitches,cs_force_far_calls); exclude(init_settings.localswitches,cs_force_far_calls);
end
else
begin
include(current_settings.localswitches,cs_force_far_calls);
if changeinit then
include(init_settings.localswitches,cs_force_far_calls);
end; end;
{$endif i8086} {$endif i8086}

View File

@ -100,8 +100,8 @@ interface
tarinfo = record tarinfo = record
id : tar; id : tar;
addfilecmd : string[10]; addfilecmd : string[10];
arfirstcmd : string[50]; arfirstcmd : string[60];
arcmd : string[50]; arcmd : string[60];
arfinishcmd : string[11]; arfinishcmd : string[11];
end; end;

View File

@ -1788,14 +1788,16 @@ unit aoptx86;
InternalError(2020072501); InternalError(2020072501);
{ do not mess with the stack point as adjusting it by lea is recommend, except if we optimize for size } { do not mess with the stack point as adjusting it by lea is recommend, except if we optimize for size }
if (taicpu(p).oper[1]^.reg=NR_STACK_POINTER_REG) and if (p.oper[1]^.reg=NR_STACK_POINTER_REG) and
not(cs_opt_size in current_settings.optimizerswitches) then not(cs_opt_size in current_settings.optimizerswitches) then
exit; exit;
with p.oper[0]^.ref^ do with p.oper[0]^.ref^ do
begin begin
if (base <> p.oper[1]^.reg) or (index <> NR_NO) then if (base <> p.oper[1]^.reg) or
Exit(False); (index <> NR_NO) or
assigned(symbol) then
exit;
l:=offset; l:=offset;
if (l=1) and UseIncDec then if (l=1) and UseIncDec then

View File

@ -43,6 +43,8 @@ Interface
function InstructionLoadsFromReg(const reg: TRegister; const hp: tai): boolean;override; function InstructionLoadsFromReg(const reg: TRegister; const hp: tai): boolean;override;
function GetNextInstructionUsingReg(Current : tai; out Next : tai; reg : TRegister) : Boolean; function GetNextInstructionUsingReg(Current : tai; out Next : tai; reg : TRegister) : Boolean;
procedure DebugMsg(const s : string; p : tai); procedure DebugMsg(const s : string; p : tai);
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
private private
function RemoveSuperfluousMove(const p: tai; movp: tai; const optimizer: string): boolean; function RemoveSuperfluousMove(const p: tai; movp: tai; const optimizer: string): boolean;
End; End;
@ -145,6 +147,24 @@ Implementation
Result := false; Result := false;
if not ((assigned(hp)) and (hp.typ = ait_instruction)) then if not ((assigned(hp)) and (hp.typ = ait_instruction)) then
exit; exit;
if Result then
exit;
case p.opcode of
A_B,
A_SSI,A_SSIU,A_SSX,A_SSXU,
A_S16I,A_S32C1I,A_S32E,A_S32I,A_S32RI,A_S8I:
exit;
else
;
end;
case p.oper[0]^.typ of
top_reg:
Result := (p.oper[0]^.reg = reg) ;
else
;
end;
end; end;
@ -192,7 +212,6 @@ Implementation
begin begin
Result:=false; Result:=false;
if MatchInstruction(movp, A_MOV, [PF_None,PF_N]) and if MatchInstruction(movp, A_MOV, [PF_None,PF_N]) and
(taicpu(p).ops>=3) and
{ We can't optimize if there is a shiftop } { We can't optimize if there is a shiftop }
(taicpu(movp).ops=2) and (taicpu(movp).ops=2) and
MatchOperand(taicpu(movp).oper[1]^, taicpu(p).oper[0]^.reg) and MatchOperand(taicpu(movp).oper[1]^, taicpu(p).oper[0]^.reg) and
@ -200,10 +219,10 @@ Implementation
not(RegUsedBetween(taicpu(movp).oper[0]^.reg,p,movp)) and not(RegUsedBetween(taicpu(movp).oper[0]^.reg,p,movp)) and
{ Take care to only do this for instructions which REALLY load to the first register. { Take care to only do this for instructions which REALLY load to the first register.
Otherwise Otherwise
str reg0, [reg1] s* reg0, [reg1]
mov reg2, reg0 mov reg2, reg0
will be optimized to will be optimized to
str reg2, [reg1] s* reg2, [reg1]
} }
RegLoadedWithNewValue(taicpu(p).oper[0]^.reg, p) then RegLoadedWithNewValue(taicpu(p).oper[0]^.reg, p) then
begin begin
@ -239,25 +258,38 @@ Implementation
{ finally get rid of the mov } { finally get rid of the mov }
taicpu(p).loadreg(0,taicpu(movp).oper[0]^.reg); taicpu(p).loadreg(0,taicpu(movp).oper[0]^.reg);
{ Remove preindexing and postindexing for LDR in some cases.
For example:
ldr reg2,[reg1, xxx]!
mov reg1,reg2
must be translated to:
ldr reg1,[reg1, xxx]
Preindexing must be removed there, since the same register is used as the base and as the target.
Such case is not allowed for ARM CPU and produces crash. }
//if (taicpu(p).opcode = A_LDR) and (taicpu(p).oper[1]^.typ = top_ref)
// and (taicpu(movp).oper[0]^.reg = taicpu(p).oper[1]^.ref^.base)
//then
// taicpu(p).oper[1]^.ref^.addressmode:=AM_OFFSET;
asml.remove(movp); asml.remove(movp);
movp.free; movp.free;
end; end;
end; end;
end; end;
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
var
hp1: tai;
begin
result := false;
case p.typ of
ait_instruction:
begin
case taicpu(p).opcode of
A_L32I:
begin
if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
RemoveSuperfluousMove(p, hp1, 'L32IMov2L32I') then
Result:=true;
end;
else
;
end;
end
else
;
end
end;
begin begin
casmoptimizer:=TCpuAsmOptimizer; casmoptimizer:=TCpuAsmOptimizer;
End. End.

View File

@ -2880,7 +2880,10 @@ begin
Result:=TSQLAsteriskExpression(CreateElement(TSQLAsteriskExpression,APArent)); Result:=TSQLAsteriskExpression(CreateElement(TSQLAsteriskExpression,APArent));
GetNextToken; GetNextToken;
end; end;
tsqlIdentifier: else
// some keywords (FirstKeyword..LastKeyWord) can also be functions/identifiers (LEFT, RIGHT)
// To-Do: remove some of them if necessary
if CurrentToken in [tsqlIdentifier, FirstKeyword..LastKeyWord] then
begin begin
N:=CurrentTokenString; N:=CurrentTokenString;
If (GetNextToken<>tsqlBraceOpen) then If (GetNextToken<>tsqlBraceOpen) then
@ -2941,10 +2944,10 @@ begin
TSQLFunctionCallExpression(Result).IDentifier:=N; TSQLFunctionCallExpression(Result).IDentifier:=N;
TSQLFunctionCallExpression(Result).Arguments:=L; TSQLFunctionCallExpression(Result).Arguments:=L;
end; end;
end; end
else else
UnexpectedToken; UnexpectedToken;
end; end;
except except
FreeAndNil(Result); FreeAndNil(Result);
Raise; Raise;

View File

@ -450,6 +450,7 @@ type
procedure TestAggregateAvgDistinct; procedure TestAggregateAvgDistinct;
procedure TestUpperConst; procedure TestUpperConst;
procedure TestUpperError; procedure TestUpperError;
procedure TestLeft;
procedure TestGenID; procedure TestGenID;
procedure TestGenIDError1; procedure TestGenIDError1;
procedure TestGenIDError2; procedure TestGenIDError2;
@ -4778,6 +4779,31 @@ begin
AssertAggregateExpression(H.Left,afCount,'C',aoNone); AssertAggregateExpression(H.Left,afCount,'C',aoNone);
end; end;
procedure TTestSelectParser.TestLeft;
Var
E : TSQLFunctionCallExpression;
L : TSQLLiteralExpression;
S : TSQLStringLiteral;
I : TSQLIntegerLiteral;
begin
TestSelect('SELECT LEFT(''abc'', 1) FROM A');
AssertEquals('One field',1,Select.Fields.Count);
AssertEquals('One table',1,Select.Tables.Count);
AssertTable(Select.Tables[0],'A');
CheckClass(Select.Fields[0],TSQLSelectField);
E:=TSQLFunctionCallExpression(CheckClass(TSQLSelectField(Select.Fields[0]).Expression,TSQLFunctionCallExpression));
AssertEquals('LEFT function name','LEFT',E.Identifier);
AssertEquals('Two function elements',2,E.Arguments.Count);
L:=TSQLLiteralExpression(CheckClass(E.Arguments[0],TSQLLiteralExpression));
S:=TSQLStringLiteral(CheckClass(L.Literal,TSQLStringLiteral));
AssertEquals('Correct string constant','abc',S.Value);
L:=TSQLLiteralExpression(CheckClass(E.Arguments[1],TSQLLiteralExpression));
I:=TSQLIntegerLiteral(CheckClass(L.Literal,TSQLIntegerLiteral));
AssertEquals('Correct integer constant',1,I.Value);
end;
procedure TTestSelectParser.TestNoTable; procedure TTestSelectParser.TestNoTable;
Var Var

View File

@ -1423,10 +1423,21 @@ type
//ToDo: proStaticArrayConcat, // concat works with static arrays, returning a dynamic array //ToDo: proStaticArrayConcat, // concat works with static arrays, returning a dynamic array
proProcTypeWithoutIsNested, // proc types can use nested procs without 'is nested' proProcTypeWithoutIsNested, // proc types can use nested procs without 'is nested'
proMethodAddrAsPointer, // can assign @method to a pointer proMethodAddrAsPointer, // can assign @method to a pointer
proSafecallAllowsDefault // allow assigning a default calling convetnion to a SafeCall proc proSafecallAllowsDefault // allow assigning a default calling convention to a SafeCall proc
); );
TPasResolverOptions = set of TPasResolverOption; TPasResolverOptions = set of TPasResolverOption;
{ TPasResolverHub }
TPasResolverHub = class
private
FOwner: TObject;
public
constructor Create(TheOwner: TObject);
property Owner: TObject read FOwner;
end;
TPasResolverHubClass = class of TPasResolverHub;
TPasResolverStep = ( TPasResolverStep = (
prsInit, prsInit,
prsParsing, prsParsing,
@ -1480,6 +1491,7 @@ type
FDefaultScope: TPasDefaultScope; FDefaultScope: TPasDefaultScope;
FDynArrayMaxIndex: TMaxPrecInt; FDynArrayMaxIndex: TMaxPrecInt;
FDynArrayMinIndex: TMaxPrecInt; FDynArrayMinIndex: TMaxPrecInt;
FHub: TPasResolverHub;
FLastCreatedData: array[TResolveDataListKind] of TResolveData; FLastCreatedData: array[TResolveDataListKind] of TResolveData;
FLastElement: TPasElement; FLastElement: TPasElement;
FLastMsg: string; FLastMsg: string;
@ -2363,10 +2375,12 @@ type
function FindLocalBuiltInSymbol(El: TPasElement): TPasElement; virtual; function FindLocalBuiltInSymbol(El: TPasElement): TPasElement; virtual;
function GetFirstSection(WithUnitImpl: boolean): TPasSection; function GetFirstSection(WithUnitImpl: boolean): TPasSection;
function GetLastSection: TPasSection; function GetLastSection: TPasSection;
function GetParentSection(El: TPasElement): TPasSection;
function FindUsedUnitInSection(aMod: TPasModule; Section: TPasSection): TPasUsesUnit; function FindUsedUnitInSection(aMod: TPasModule; Section: TPasSection): TPasUsesUnit;
function GetShiftAndMaskForLoHiFunc(BaseType: TResolverBaseType; function GetShiftAndMaskForLoHiFunc(BaseType: TResolverBaseType;
isLoFunc: Boolean; out Mask: LongWord): Integer; isLoFunc: Boolean; out Mask: LongWord): Integer;
public public
property Hub: TPasResolverHub read FHub write FHub;
// options // options
property Options: TPasResolverOptions read FOptions write FOptions; property Options: TPasResolverOptions read FOptions write FOptions;
property AnonymousElTypePostfix: String read FAnonymousElTypePostfix property AnonymousElTypePostfix: String read FAnonymousElTypePostfix
@ -2381,15 +2395,15 @@ type
property ExprEvaluator: TResExprEvaluator read fExprEvaluator; property ExprEvaluator: TResExprEvaluator read fExprEvaluator;
property DynArrayMinIndex: TMaxPrecInt read FDynArrayMinIndex write FDynArrayMinIndex; property DynArrayMinIndex: TMaxPrecInt read FDynArrayMinIndex write FDynArrayMinIndex;
property DynArrayMaxIndex: TMaxPrecInt read FDynArrayMaxIndex write FDynArrayMaxIndex; property DynArrayMaxIndex: TMaxPrecInt read FDynArrayMaxIndex write FDynArrayMaxIndex;
property StoreSrcColumns: boolean read FStoreSrcColumns write FStoreSrcColumns; {
If true Line and Column is mangled together in TPasElement.SourceLineNumber.
Use method UnmangleSourceLineNumber to extract. }
// parsed values // parsed values
property DefaultNameSpace: String read FDefaultNameSpace; property DefaultNameSpace: String read FDefaultNameSpace;
property RootElement: TPasModule read FRootElement write SetRootElement; property RootElement: TPasModule read FRootElement write SetRootElement;
property Step: TPasResolverStep read FStep; property Step: TPasResolverStep read FStep;
property ActiveHelpers: TPRHelperEntryArray read FActiveHelpers; property ActiveHelpers: TPRHelperEntryArray read FActiveHelpers;
// scopes // scopes
property StoreSrcColumns: boolean read FStoreSrcColumns write FStoreSrcColumns; {
If true Line and Column is mangled together in TPasElement.SourceLineNumber.
Use method UnmangleSourceLineNumber to extract. }
property Scopes[Index: integer]: TPasScope read GetScopes; property Scopes[Index: integer]: TPasScope read GetScopes;
property ScopeCount: integer read FScopeCount; property ScopeCount: integer read FScopeCount;
property TopScope: TPasScope read FTopScope; property TopScope: TPasScope read FTopScope;
@ -3063,6 +3077,13 @@ begin
str(a,Result); str(a,Result);
end; end;
{ TPasResolverHub }
constructor TPasResolverHub.Create(TheOwner: TObject);
begin
FOwner:=TheOwner;
end;
{ TPRSpecializedItem } { TPRSpecializedItem }
destructor TPRSpecializedItem.Destroy; destructor TPRSpecializedItem.Destroy;
@ -11780,6 +11801,8 @@ var
C: TClass; C: TClass;
ModScope: TPasModuleScope; ModScope: TPasModuleScope;
begin begin
if Hub=nil then
RaiseNotYetImplemented(20200815182122,El);
if TopScope<>DefaultScope then if TopScope<>DefaultScope then
RaiseInvalidScopeForElement(20160922163504,El); RaiseInvalidScopeForElement(20160922163504,El);
ModScope:=TPasModuleScope(PushScope(El,FScopeClass_Module)); ModScope:=TPasModuleScope(PushScope(El,FScopeClass_Module));
@ -29229,6 +29252,16 @@ begin
Result:=Module.InterfaceSection; Result:=Module.InterfaceSection;
end; end;
function TPasResolver.GetParentSection(El: TPasElement): TPasSection;
begin
while El<>nil do
begin
if El is TPasSection then exit(TPasSection(El));
El:=El.Parent;
end;
Result:=nil;
end;
function TPasResolver.FindUsedUnitInSection(aMod: TPasModule; function TPasResolver.FindUsedUnitInSection(aMod: TPasModule;
Section: TPasSection): TPasUsesUnit; Section: TPasSection): TPasUsesUnit;
var var

View File

@ -1750,7 +1750,7 @@ const
cPasMemberHint : Array[TPasMemberHint] of string = cPasMemberHint : Array[TPasMemberHint] of string =
( 'deprecated', 'library', 'platform', 'experimental', 'unimplemented' ); ( 'deprecated', 'library', 'platform', 'experimental', 'unimplemented' );
cCallingConventions : Array[TCallingConvention] of string = cCallingConventions : Array[TCallingConvention] of string =
( '', 'Register','Pascal','CDecl','StdCall','OldFPCCall','SafeCall','SysCall','MWPascal', ( '', 'Register','Pascal','cdecl','stdcall','OldFPCCall','safecall','SysCall','MWPascal',
'HardFloat','SysV_ABI_Default','SysV_ABI_CDecl', 'HardFloat','SysV_ABI_Default','SysV_ABI_CDecl',
'MS_ABI_Default','MS_ABI_CDecl', 'MS_ABI_Default','MS_ABI_CDecl',
'VectorCall'); 'VectorCall');
@ -4208,7 +4208,7 @@ end;
function TPasClassOfType.GetDeclaration (full : boolean) : string; function TPasClassOfType.GetDeclaration (full : boolean) : string;
begin begin
Result:='Class of '+DestType.SafeName; Result:='class of '+DestType.SafeName;
If Full then If Full then
Result:=FixTypeDecl(Result); Result:=FixTypeDecl(Result);
end; end;

View File

@ -43,6 +43,8 @@ type
); );
TPasWriterOptions = Set of TPasWriterOption; TPasWriterOptions = Set of TPasWriterOption;
TOnUnitAlias = function(const UnitName : String) : String of Object;
TPasWriter = class TPasWriter = class
private private
FCurrentLineNumber : Integer; FCurrentLineNumber : Integer;
@ -51,6 +53,7 @@ type
FForwardClasses: TStrings; FForwardClasses: TStrings;
FLineEnding: String; FLineEnding: String;
FLineNumberWidth: Integer; FLineNumberWidth: Integer;
FOnUnitAlias: TOnUnitAlias;
FOPtions: TPasWriterOptions; FOPtions: TPasWriterOptions;
FStream: TStream; FStream: TStream;
FIndentSize : Integer; FIndentSize : Integer;
@ -63,6 +66,7 @@ type
FInImplementation : Boolean; FInImplementation : Boolean;
procedure SetForwardClasses(AValue: TStrings); procedure SetForwardClasses(AValue: TStrings);
procedure SetIndentSize(AValue: Integer); procedure SetIndentSize(AValue: Integer);
function CheckUnitAlias(const AUnitName : String) : String;
protected protected
procedure DisableHintsWarnings; procedure DisableHintsWarnings;
procedure PrepareDeclSectionInStruct(const ADeclSection: string); procedure PrepareDeclSectionInStruct(const ADeclSection: string);
@ -132,6 +136,7 @@ type
procedure wrtln;overload; deprecated ; procedure wrtln;overload; deprecated ;
property Stream: TStream read FStream; property Stream: TStream read FStream;
Published Published
Property OnUnitAlias : TOnUnitAlias Read FOnUnitAlias Write FOnUnitAlias;
Property Options : TPasWriterOptions Read FOPtions Write FOptions; Property Options : TPasWriterOptions Read FOPtions Write FOptions;
Property IndentSize : Integer Read FIndentSize Write SetIndentSize; Property IndentSize : Integer Read FIndentSize Write SetIndentSize;
Property LineEnding : String Read FLineEnding Write FLineEnding; Property LineEnding : String Read FLineEnding Write FLineEnding;
@ -478,7 +483,7 @@ end;
procedure TPasWriter.WriteUnit(aModule: TPasModule); procedure TPasWriter.WriteUnit(aModule: TPasModule);
begin begin
AddLn('unit ' + AModule.SafeName + ';'); AddLn('unit ' + CheckUnitAlias(AModule.SafeName) + ';');
if Assigned(AModule.GlobalDirectivesSection) then if Assigned(AModule.GlobalDirectivesSection) then
begin begin
AddLn; AddLn;
@ -556,7 +561,7 @@ Var
Add(', ') Add(', ')
else else
Add('uses '); Add('uses ');
Add(AName); Add(CheckUnitAlias(AName));
if (AUnitFile<>Nil) then if (AUnitFile<>Nil) then
Add(' in '+GetExpr(AUnitFile)); Add(' in '+GetExpr(AUnitFile));
Inc(c); Inc(c);
@ -848,9 +853,7 @@ end;
procedure TPasWriter.WriteRecordType(AType: TPasRecordType); procedure TPasWriter.WriteRecordType(AType: TPasRecordType);
Var Var
I : Integer;
Temp : String; Temp : String;
el : TPasElement;
begin begin
Temp:='record'; Temp:='record';
@ -1490,6 +1493,14 @@ begin
FIndentStep:=StringOfChar(' ',aValue); FIndentStep:=StringOfChar(' ',aValue);
end; end;
function TPasWriter.CheckUnitAlias(const AUnitName: String): String;
begin
if Assigned(FOnUnitAlias) then
Result := FOnUnitAlias(AUnitName)
else
Result := AUnitName;
end;
function TPasWriter.HasOption(aOption: TPasWriterOption): Boolean; function TPasWriter.HasOption(aOption: TPasWriterOption): Boolean;
begin begin
Result:=(aOption in FOptions) Result:=(aOption in FOptions)

View File

@ -112,6 +112,7 @@ type
TCustomTestResolver = Class(TTestParser) TCustomTestResolver = Class(TTestParser)
Private Private
FHub: TPasResolverHub;
{$IF defined(VerbosePasResolver) or defined(VerbosePasResolverMem)} {$IF defined(VerbosePasResolver) or defined(VerbosePasResolverMem)}
FStartElementRefCount: int64; FStartElementRefCount: int64;
{$ENDIF} {$ENDIF}
@ -173,6 +174,7 @@ type
procedure StartUnit(NeedSystemUnit: boolean); procedure StartUnit(NeedSystemUnit: boolean);
property Modules[Index: integer]: TTestEnginePasResolver read GetModules; property Modules[Index: integer]: TTestEnginePasResolver read GetModules;
property ModuleCount: integer read GetModuleCount; property ModuleCount: integer read GetModuleCount;
property Hub: TPasResolverHub read FHub;
property ResolverEngine: TTestEnginePasResolver read FResolverEngine; property ResolverEngine: TTestEnginePasResolver read FResolverEngine;
property MsgCount: integer read GetMsgCount; property MsgCount: integer read GetMsgCount;
property Msgs[Index: integer]: TTestResolverMessage read GetMsgs; property Msgs[Index: integer]: TTestResolverMessage read GetMsgs;
@ -1060,6 +1062,7 @@ begin
FStartElementRefCount:=TPasElement.GlobalRefCount; FStartElementRefCount:=TPasElement.GlobalRefCount;
{$ENDIF} {$ENDIF}
FModules:=TObjectList.Create(true); FModules:=TObjectList.Create(true);
FHub:=TPasResolverHub.Create(Self);
inherited SetUp; inherited SetUp;
Parser.Options:=Parser.Options+[po_ResolveStandardTypes]; Parser.Options:=Parser.Options+[po_ResolveStandardTypes];
Scanner.OnDirective:=@OnScannerDirective; Scanner.OnDirective:=@OnScannerDirective;
@ -1096,6 +1099,7 @@ begin
FModules.OwnsObjects:=true; FModules.OwnsObjects:=true;
FreeAndNil(FModules);// free all other modules FreeAndNil(FModules);// free all other modules
end; end;
FreeAndNil(FHub);
{$IFDEF VerbosePasResolverMem} {$IFDEF VerbosePasResolverMem}
writeln('TTestResolver.TearDown inherited'); writeln('TTestResolver.TearDown inherited');
{$ENDIF} {$ENDIF}
@ -2171,6 +2175,7 @@ begin
Result.AddObjFPCBuiltInIdentifiers; Result.AddObjFPCBuiltInIdentifiers;
Result.OnFindUnit:=@OnPasResolverFindUnit; Result.OnFindUnit:=@OnPasResolverFindUnit;
Result.OnLog:=@OnPasResolverLog; Result.OnLog:=@OnPasResolverLog;
Result.Hub:=Hub;
FModules.Add(Result); FModules.Add(Result);
end; end;

View File

@ -1369,6 +1369,11 @@ type
property TargetProcessor: TPasToJsProcessor read FTargetProcessor write FTargetProcessor; property TargetProcessor: TPasToJsProcessor read FTargetProcessor write FTargetProcessor;
end; end;
{ TPas2JSResolverHub }
TPas2JSResolverHub = class(TPasResolverHub)
end;
{ TPas2JSResolver } { TPas2JSResolver }
TPas2JSResolver = class(TPasResolver) TPas2JSResolver = class(TPasResolver)
@ -1473,6 +1478,7 @@ type
// generic/specialize // generic/specialize
procedure SpecializeGenericImpl(SpecializedItem: TPRSpecializedItem); procedure SpecializeGenericImpl(SpecializedItem: TPRSpecializedItem);
override; override;
function SpecializeNeedsDelay(SpecializedItem: TPRSpecializedItem): TPasElement;
protected protected
const const
cJSValueConversion = 2*cTypeConversion; cJSValueConversion = 2*cTypeConversion;
@ -4900,6 +4906,47 @@ begin
end; end;
end; end;
function TPas2JSResolver.SpecializeNeedsDelay(
SpecializedItem: TPRSpecializedItem): TPasElement;
// finds first specialize param defined later than the generic
// For example: generic in the unit interface, param in implementation
// or param in another unit, not used by the generic
var
Gen: TPasElement;
GenMod, ParamMod: TPasModule;
Params: TPasTypeArray;
Param: TPasType;
i: Integer;
GenSection, ParamSection: TPasSection;
begin
Result:=nil;
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;
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
ParamSection:=GetParentSection(Param);
if ParamSection=GenSection then continue;
// not in same section
ParamMod:=ParamSection.GetModule;
if ParamMod=GenMod then
exit(Param); // generic in unit interface, specialize in implementation
// param in another unit
if ParamSection is TImplementationSection then
exit(Param); // generic in unit interface, specialize in another(later) implementation
// param in another unit interface
//xxx
end;
end;
function TPas2JSResolver.AddJSBaseType(const aName: string; Typ: TPas2jsBaseType function TPas2JSResolver.AddJSBaseType(const aName: string; Typ: TPas2jsBaseType
): TResElDataPas2JSBaseType; ): TResElDataPas2JSBaseType;
var var

View File

@ -500,6 +500,7 @@ type
FPostProcessorSupport: TPas2JSPostProcessorSupport; FPostProcessorSupport: TPas2JSPostProcessorSupport;
FPrecompileGUID: TGUID; FPrecompileGUID: TGUID;
FReadingModules: TFPList; // list of TPas2jsCompilerFile ordered by uses sections FReadingModules: TFPList; // list of TPas2jsCompilerFile ordered by uses sections
FResolverHub: TPas2JSResolverHub;
FRTLVersionCheck: TP2jsRTLVersionCheck; FRTLVersionCheck: TP2jsRTLVersionCheck;
FSrcMapBaseDir: string; FSrcMapBaseDir: string;
FSrcMapSourceRoot: string; FSrcMapSourceRoot: string;
@ -680,14 +681,15 @@ type
property DefaultNamespace: String read GetDefaultNamespace; property DefaultNamespace: String read GetDefaultNamespace;
property Defines: TStrings read FDefines; property Defines: TStrings read FDefines;
property FS: TPas2jsFS read FFS write SetFS; property FS: TPas2jsFS read FFS write SetFS;
property OwnsFS: boolean read FOwnsFS write FOwnsFS; property OwnsFS: boolean read FOwnsFS write FOwnsFS; // true = auto free FS when compiler is freed
property FileCount: integer read GetFileCount; property FileCount: integer read GetFileCount;
property InterfaceType: TPasClassInterfaceType read FInterfaceType write FInterfaceType; property InterfaceType: TPasClassInterfaceType read FInterfaceType write FInterfaceType; // default interface type
property Log: TPas2jsLogger read FLog; property Log: TPas2jsLogger read FLog;
property MainFile: TPas2jsCompilerFile read FMainFile; property MainFile: TPas2jsCompilerFile read FMainFile;
property ModeSwitches: TModeSwitches read FModeSwitches write SetModeSwitches; property ModeSwitches: TModeSwitches read FModeSwitches write SetModeSwitches;
property Options: TP2jsCompilerOptions read FOptions write SetOptions; property Options: TP2jsCompilerOptions read FOptions write SetOptions;
property ConverterGlobals: TPasToJSConverterGlobals read FConverterGlobals write SetConverterGlobals; property ConverterGlobals: TPasToJSConverterGlobals read FConverterGlobals write SetConverterGlobals;
property ResolverHub: TPas2JSResolverHub read FResolverHub;
property ParamMacros: TPas2jsMacroEngine read FParamMacros; property ParamMacros: TPas2jsMacroEngine read FParamMacros;
property PrecompileGUID: TGUID read FPrecompileGUID write FPrecompileGUID; property PrecompileGUID: TGUID read FPrecompileGUID write FPrecompileGUID;
property RTLVersionCheck: TP2jsRTLVersionCheck read FRTLVersionCheck write FRTLVersionCheck; property RTLVersionCheck: TP2jsRTLVersionCheck read FRTLVersionCheck write FRTLVersionCheck;
@ -965,6 +967,7 @@ begin
FPasResolver.OnCheckSrcName:=@OnResolverCheckSrcName; FPasResolver.OnCheckSrcName:=@OnResolverCheckSrcName;
FPasResolver.OnLog:=@OnPasResolverLog; FPasResolver.OnLog:=@OnPasResolverLog;
FPasResolver.Log:=Log; FPasResolver.Log:=Log;
FPasResolver.Hub:=aCompiler.ResolverHub;
FPasResolver.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs); FPasResolver.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs);
FIsMainFile:=Compiler.FS.SameFileName(Compiler.MainSrcFile,PasFilename); FIsMainFile:=Compiler.FS.SameFileName(Compiler.MainSrcFile,PasFilename);
for ub in TUsedBySection do for ub in TUsedBySection do
@ -4191,6 +4194,7 @@ constructor TPas2jsCompiler.Create;
begin begin
FOptions:=DefaultP2jsCompilerOptions; FOptions:=DefaultP2jsCompilerOptions;
FConverterGlobals:=TPasToJSConverterGlobals.Create(Self); FConverterGlobals:=TPasToJSConverterGlobals.Create(Self);
FResolverHub:=TPas2JSResolverHub.Create(Self);
FNamespaces:=TStringList.Create; FNamespaces:=TStringList.Create;
FDefines:=TStringList.Create; FDefines:=TStringList.Create;
FInsertFilenames:=TStringList.Create; FInsertFilenames:=TStringList.Create;
@ -4232,6 +4236,7 @@ destructor TPas2jsCompiler.Destroy;
FreeAndNil(FPostProcessorSupport); FreeAndNil(FPostProcessorSupport);
FreeAndNil(FConfigSupport); FreeAndNil(FConfigSupport);
ConverterGlobals:=nil; ConverterGlobals:=nil;
FreeAndNil(FResolverHub);
ClearDefines; ClearDefines;
FreeAndNil(FDefines); FreeAndNil(FDefines);

View File

@ -67,6 +67,7 @@ type
procedure TestGenProc_TypeInfo; procedure TestGenProc_TypeInfo;
procedure TestGenProc_Infer_Widen; procedure TestGenProc_Infer_Widen;
procedure TestGenProc_Infer_PassAsArg; procedure TestGenProc_Infer_PassAsArg;
// ToDo: delay create: type TRec=record end; ... r:=GenProc<TRec>();
// ToDo: FuncName:= instead of Result:= // ToDo: FuncName:= instead of Result:=
// generic methods // generic methods

View File

@ -111,6 +111,7 @@ type
FExpectedErrorNumber: integer; FExpectedErrorNumber: integer;
FFilename: string; FFilename: string;
FFileResolver: TStreamResolver; FFileResolver: TStreamResolver;
FHub: TPas2JSResolverHub;
FJSImplementationSrc: TJSSourceElements; FJSImplementationSrc: TJSSourceElements;
FJSImplementationUses: TJSArrayLiteral; FJSImplementationUses: TJSArrayLiteral;
FJSInitBody: TJSFunctionBody; FJSInitBody: TJSFunctionBody;
@ -216,6 +217,7 @@ type
public public
constructor Create; override; constructor Create; override;
destructor Destroy; override; destructor Destroy; override;
property Hub: TPas2JSResolverHub read FHub;
property Source: TStringList read FSource; property Source: TStringList read FSource;
property FileResolver: TStreamResolver read FFileResolver; property FileResolver: TStreamResolver read FFileResolver;
property Scanner: TPas2jsPasScanner read FScanner; property Scanner: TPas2jsPasScanner read FScanner;
@ -1310,6 +1312,8 @@ begin
inherited SetUp; inherited SetUp;
FSkipTests:=false; FSkipTests:=false;
FSource:=TStringList.Create; FSource:=TStringList.Create;
FHub:=TPas2JSResolverHub.Create(Self);
FModules:=TObjectList.Create(true); FModules:=TObjectList.Create(true);
FFilename:='test1.pp'; FFilename:='test1.pp';
@ -1404,6 +1408,7 @@ begin
ReleaseAndNil(TPasElement(FModule){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF}); ReleaseAndNil(TPasElement(FModule){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
FEngine:=nil; FEngine:=nil;
end; end;
FreeAndNil(FHub);
inherited TearDown; inherited TearDown;
{$IFDEF EnablePasTreeGlobalRefCount} {$IFDEF EnablePasTreeGlobalRefCount}
@ -1558,6 +1563,7 @@ begin
Result.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs); Result.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs);
Result.OnFindUnit:=@OnPasResolverFindUnit; Result.OnFindUnit:=@OnPasResolverFindUnit;
Result.OnLog:=@OnPasResolverLog; Result.OnLog:=@OnPasResolverLog;
Result.Hub:=Hub;
FModules.Add(Result); FModules.Add(Result);
end; end;

View File

@ -56,7 +56,8 @@ interface
{$BOOLEVAL OFF} {$BOOLEVAL OFF}
{$EXTENDEDSYNTAX ON} {$EXTENDEDSYNTAX ON}
{$LONGSTRINGS ON} {$LONGSTRINGS ON}
{$OPTIMIZATION ON} { use optimization settings passed via fpmake/make }
{OPTIMIZATION ON}
// ======== Define options for TRegExpr engine // ======== Define options for TRegExpr engine
{$DEFINE UseFirstCharSet} // Enable optimization, which finds possible first chars of input string {$DEFINE UseFirstCharSet} // Enable optimization, which finds possible first chars of input string

View File

@ -325,6 +325,7 @@ unit ComObj;
CoResumeClassObjects : TCoResumeClassObjectsProc = nil; CoResumeClassObjects : TCoResumeClassObjectsProc = nil;
CoSuspendClassObjects : TCoSuspendClassObjectsProc = nil; CoSuspendClassObjects : TCoSuspendClassObjectsProc = nil;
CoInitFlags : Longint = -1; CoInitFlags : Longint = -1;
CoInitDisable : Boolean = False;
{$ifdef DEBUG_COM} {$ifdef DEBUG_COM}
var printcom : boolean=true; var printcom : boolean=true;
@ -1877,6 +1878,20 @@ const
Initialized : boolean = false; Initialized : boolean = false;
var var
Ole32Dll : HModule; Ole32Dll : HModule;
SaveInitProc : CodePointer;
procedure InitComObj;
begin
if SaveInitProc<>nil then
TProcedure(SaveInitProc)();
if not CoInitDisable then
{$ifndef wince}
if (CoInitFlags=-1) or not(assigned(ComObj.CoInitializeEx)) then
Initialized:=Succeeded(CoInitialize(nil))
else
{$endif wince}
Initialized:=Succeeded(ComObj.CoInitializeEx(nil, CoInitFlags));
end;
initialization initialization
Uninitializing:=false; Uninitializing:=false;
@ -1893,12 +1908,10 @@ initialization
end; end;
if not(IsLibrary) then if not(IsLibrary) then
{$ifndef wince} begin
if (CoInitFlags=-1) or not(assigned(comobj.CoInitializeEx)) then SaveInitProc:=InitProc;
Initialized:=Succeeded(CoInitialize(nil)) InitProc:=@InitComObj;
else end;
{$endif wince}
Initialized:=Succeeded(comobj.CoInitializeEx(nil, CoInitFlags));
SafeCallErrorProc:=@SafeCallErrorHandler; SafeCallErrorProc:=@SafeCallErrorHandler;
VarDispProc:=@ComObjDispatchInvoke; VarDispProc:=@ComObjDispatchInvoke;

View File

@ -169,7 +169,7 @@ finalization
Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr)); Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr));
{ to get a nice symify } { to get a nice symify }
Writeln(pstdout^,BackTraceStrFunc(Erroraddr)); Writeln(pstdout^,BackTraceStrFunc(Erroraddr));
dump_stack(pstdout^,ErrorBase); dump_stack(pstdout^,ErrorBase,erroraddr);
Writeln(pstdout^,''); Writeln(pstdout^,'');
End; End;
SysFlushStdIO; SysFlushStdIO;

View File

@ -208,6 +208,7 @@ const calculated_cmdline:Pchar=nil;
{***************************************************************************** {*****************************************************************************
Misc. System Dependent Functions Misc. System Dependent Functions
*****************************************************************************} *****************************************************************************}
{$ifndef FPC_SYSTEM_HAS_STACKTOP}
var var
_stack_top: record end; external name '_stack_top'; _stack_top: record end; external name '_stack_top';
@ -215,6 +216,7 @@ function StackTop: pointer;
begin begin
StackTop:=@_stack_top; StackTop:=@_stack_top;
end; end;
{$endif FPC_SYSTEM_HAS_STACKTOP}
procedure haltproc;cdecl;external name '_haltproc'; procedure haltproc;cdecl;external name '_haltproc';

View File

@ -62,8 +62,7 @@ Procedure ResetFPU;
var var
l_fpucw : longint; l_fpucw : longint;
begin begin
{$if defined(FPU68881) or defined(FPUCOLDFIRE)}
{$ifdef CPU68020}
asm asm
fmove.l fpcr,l_fpucw fmove.l fpcr,l_fpucw
end; end;

View File

@ -23,8 +23,8 @@ type
pfpstate = ^tfpstate; pfpstate = ^tfpstate;
tfpstate = record tfpstate = record
pcr,psr,fpiaddr : longint; pcr,psr,fpiaddr : longint;
fpreg : array [0..7] of tfpreg; fpreg : array [0..7] of tfpreg;
end; end;
{ as defined in asm_m68k/signal.h } { as defined in asm_m68k/signal.h }

View File

@ -31,27 +31,114 @@ begin
SysInitFPU; SysInitFPU;
end; end;
{$ifdef fpc_abi_windowed}
const
// Minimum call8 calls to force register spilling to stack for caller of forceSpilledRegs
spillcount = 6;
procedure forceSpilledRegs(n: uint32); assembler; public name 'forcespilledregs';
label
done, fin;
asm
beqz a2, done
addi a10, a2, -1
call8 forcespilledregs
done:
bnez a2, fin
movi a15, 0
fin:
end;
procedure fixCodeAddress(var addr: pointer);
begin
// Check if valid code address
if ptruint(addr) and $C0000000 >= $40000000 then
begin
// Replace windowed call prefix
addr:=codepointer((ptruint(addr)and$00FFFFFF) or $40000000);
// Rewind to call instruction address
dec(addr,3);
end
else
addr:=nil;
end;
{$endif fpc_abi_windowed}
{$IFNDEF INTERNAL_BACKTRACE} {$IFNDEF INTERNAL_BACKTRACE}
{$define FPC_SYSTEM_HAS_GET_FRAME} {$define FPC_SYSTEM_HAS_GET_FRAME}
function get_frame:pointer;assembler;nostackframe; function get_frame:pointer;assembler;
asm label
end; done;
asm
{$ifdef fpc_abi_windowed}
// Force registers to spill onto stack
movi a10, spillcount
call8 forcespilledregs
// now get frame pointer of caller
addi a2, a1, -12
l32i a2, a2, 0
done:
{$else}
mov a2, a1
{$endif}
end;
{$ENDIF not INTERNAL_BACKTRACE} {$ENDIF not INTERNAL_BACKTRACE}
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe; function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;
asm begin
{$ifdef fpc_abi_windowed}
forceSpilledRegs(spillcount);
if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
begin
get_caller_addr:=pointer((framebp-16)^);
fixCodeAddress(get_caller_addr);
end
else
get_caller_addr:=nil;
{$else}
get_caller_addr:=nil;
{$endif}
end; end;
{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe; function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;
asm begin
{$ifdef fpc_abi_windowed}
if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
begin
forceSpilledRegs(spillcount);
get_caller_frame:=pointer((framebp-12)^);
end
else
get_caller_frame:=nil;
{$else}
get_caller_frame:=nil;
{$endif}
end; end;
{$ifdef fpc_abi_windowed}
{$define FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
procedure get_caller_stackinfo(var framebp : pointer; var addr : codepointer);
begin
if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
begin
forceSpilledRegs(spillcount);
addr:=codepointer((framebp-16)^);
framebp := pointer((framebp-12)^);
fixCodeAddress(addr);
end
else
begin
addr:=nil;
framebp:=nil;
end;
end;
{$endif fpc_abi_windowed}
{$define FPC_SYSTEM_HAS_SPTR} {$define FPC_SYSTEM_HAS_SPTR}
Function Sptr : pointer;assembler; Function Sptr : pointer;assembler;
asm asm
@ -59,6 +146,16 @@ Function Sptr : pointer;assembler;
end; end;
{$define FPC_SYSTEM_HAS_STACKTOP}
// Interim fix for now, set to large address
// TODO: provide more realistic value, possibly by inspecting stack pointer
// when main or task is started
function StackTop: pointer;
begin
StackTop:=pointer($3fffffff);
end;
function InterLockedDecrement (var Target: longint) : longint; function InterLockedDecrement (var Target: longint) : longint;
var var
temp_sreg : byte; temp_sreg : byte;

View File

@ -2,6 +2,7 @@
{ in tp mode can't use the procvar in writeln OK 0.99.11 (PFV) } { in tp mode can't use the procvar in writeln OK 0.99.11 (PFV) }
{$ifdef fpc}{$mode tp}{$endif} {$ifdef fpc}{$mode tp}{$endif}
{$F+}
type tmpproc=function:longint; type tmpproc=function:longint;

View File

@ -2,6 +2,7 @@
{ problem with procvars in tp mode OK 0.99.11 (PM) } { problem with procvars in tp mode OK 0.99.11 (PM) }
{$mode tp} {$mode tp}
{$F+}
type proc = procedure(a : longint); type proc = procedure(a : longint);
procedure test(b : longint); procedure test(b : longint);

View File

@ -2,6 +2,7 @@
{ @procvar in tp mode bugss OK 0.99.13 (PFV) } { @procvar in tp mode bugss OK 0.99.13 (PFV) }
{$ifdef fpc}{$mode tp}{$endif} {$ifdef fpc}{$mode tp}{$endif}
{$F+}
function ReturnString: string; function ReturnString: string;
begin begin

View File

@ -4,6 +4,7 @@
type type
codepointer = pointer; codepointer = pointer;
{$endif fpc} {$endif fpc}
{$F+}
function times2(x : longint) : longint; function times2(x : longint) : longint;

View File

@ -16,6 +16,7 @@ program taddr;
{$ifdef fpc} {$ifdef fpc}
{$mode tp} {$mode tp}
{$endif} {$endif}
{$F+}
procedure testprocvar; procedure testprocvar;
begin begin

View File

@ -1,7 +1,7 @@
{$F+}
{$ifdef fpc} {$ifdef fpc}
{$mode tp} {$mode tp}
{$endif fpc} {$endif fpc}
{$F+}
type type
tproc = procedure; tproc = procedure;

5
tests/webtbf/tw37476.pp Normal file
View File

@ -0,0 +1,5 @@
{ %fail }
var a : string = (a >= 'A') and (a <= 'F');
begin
end.

View File

@ -1,4 +1,5 @@
{$mode tp} {$mode tp}
{$F+}
type ProcType = procedure(s:string); type ProcType = procedure(s:string);
GetProcType = function(s:string;var Proc:ProcType):boolean; GetProcType = function(s:string;var Proc:ProcType):boolean;

View File

@ -2,6 +2,7 @@
{ Submitted by "marco" on 2002-12-19 } { Submitted by "marco" on 2002-12-19 }
{ e-mail: marco@freepascal.org } { e-mail: marco@freepascal.org }
{$ifdef fpc}{$mode TP}{$endif} {$ifdef fpc}{$mode TP}{$endif}
{$F+}
function P1:longint; begin end; function P1:longint; begin end;
function P2:longint; begin end; function P2:longint; begin end;

View File

@ -147,6 +147,17 @@ begin
Move(C[1],AErrorClass^,L); Move(C[1],AErrorClass^,L);
end; end;
Procedure SetStubCreatorUnitAliasCallBack(P : PStubCreator; ACallBack : TUnitAliasCallBack; CallBackData : Pointer); stdcall;
begin
TStubCreator(P).OnUnitAlias:=ACallBack;
TStubCreator(P).OnUnitAliasData:=CallBackData;
end;
Procedure AddStubCreatorExtraUnit(P : PStubCreator; AUnitName : PAnsiChar); stdcall;
begin
TStubCreator(P).ExtraUnits:=AUnitName;
end;
exports exports
// Stub creator // Stub creator
GetStubCreator, GetStubCreator,
@ -160,7 +171,9 @@ exports
GetStubCreatorLastError, GetStubCreatorLastError,
AddStubCreatorDefine, AddStubCreatorDefine,
AddStubCreatorForwardClass, AddStubCreatorForwardClass,
ExecuteStubCreator; AddStubCreatorExtraUnit,
ExecuteStubCreator,
SetStubCreatorUnitAliasCallBack;
end. end.

View File

@ -19,9 +19,6 @@ interface
uses uses
Classes, SysUtils, strutils, inifiles, pscanner, pparser, pastree, iostream, paswrite; Classes, SysUtils, strutils, inifiles, pscanner, pparser, pastree, iostream, paswrite;
Const
DTypesUnit = 'jsdelphisystem';
type type
{ We have to override abstract TPasTreeContainer methods } { We have to override abstract TPasTreeContainer methods }
@ -36,6 +33,8 @@ type
TWriteCallBack = Procedure (Data : Pointer; AFileData : PAnsiChar; AFileDataLen: Int32); stdcall; TWriteCallBack = Procedure (Data : Pointer; AFileData : PAnsiChar; AFileDataLen: Int32); stdcall;
TWriteEvent = Procedure(AFileData : String) of object; TWriteEvent = Procedure(AFileData : String) of object;
TUnitAliasCallBack = Function (Data: Pointer; AUnitName: PAnsiChar;
var AUnitNameMaxLen: Int32): boolean; {$IFDEF UseCDecl}cdecl{$ELSE}stdcall{$ENDIF};
{ TStubCreator } { TStubCreator }
@ -45,6 +44,7 @@ type
FHeaderStream: TStream; FHeaderStream: TStream;
FIncludePaths: TStrings; FIncludePaths: TStrings;
FInputFile: String; FInputFile: String;
FOnUnitAliasData: Pointer;
FOnWrite: TWriteEvent; FOnWrite: TWriteEvent;
FOnWriteCallBack: TWriteCallBack; FOnWriteCallBack: TWriteCallBack;
FOutputFile: String; FOutputFile: String;
@ -60,10 +60,12 @@ type
FCallBackData : Pointer; FCallBackData : Pointer;
FLastErrorClass : String; FLastErrorClass : String;
FLastError : String; FLastError : String;
FOnUnitAlias : TUnitAliasCallBack;
procedure SetDefines(AValue: TStrings); procedure SetDefines(AValue: TStrings);
procedure SetIncludePaths(AValue: TStrings); procedure SetIncludePaths(AValue: TStrings);
procedure SetOnWrite(AValue: TWriteEvent); procedure SetOnWrite(AValue: TWriteEvent);
procedure SetWriteCallback(AValue: TWriteCallBack); procedure SetWriteCallback(AValue: TWriteCallBack);
function CheckUnitAlias(const AUnitName: String): String;
Protected Protected
procedure DoExecute;virtual; procedure DoExecute;virtual;
Procedure DoWriteEvent; virtual; Procedure DoWriteEvent; virtual;
@ -81,9 +83,11 @@ type
// OutputStream can be used combined with write callbacks. // OutputStream can be used combined with write callbacks.
Property OutputStream : TStream Read FOutputStream Write FOutputStream; Property OutputStream : TStream Read FOutputStream Write FOutputStream;
Property HeaderStream : TStream Read FHeaderStream Write FHeaderStream; Property HeaderStream : TStream Read FHeaderStream Write FHeaderStream;
Property OnUnitAlias: TUnitAliasCallBack read FOnUnitAlias Write FOnUnitAlias;
Property OnUnitAliasData : Pointer Read FOnUnitAliasData Write FOnUnitAliasData;
Property OnWriteCallBack : TWriteCallBack Read FOnWriteCallBack Write SetWriteCallback; Property OnWriteCallBack : TWriteCallBack Read FOnWriteCallBack Write SetWriteCallback;
Property CallbackData : Pointer Read FCallBackData Write FCallBackData; Property CallbackData : Pointer Read FCallBackData Write FCallBackData;
Property ExtraUnits : String Read FExtraUnits write FExtraUnits;
Published Published
Property Defines : TStrings Read FDefines Write SetDefines; Property Defines : TStrings Read FDefines Write SetDefines;
Property ConfigFileName : String Read FConfigFile Write FConfigFile; Property ConfigFileName : String Read FConfigFile Write FConfigFile;
@ -97,6 +101,8 @@ type
Implementation Implementation
uses Math;
ResourceString ResourceString
SErrNoDestGiven = 'No destination file specified.'; SErrNoDestGiven = 'No destination file specified.';
SErrNoSourceParsed = 'Parsing produced no file.'; SErrNoSourceParsed = 'Parsing produced no file.';
@ -131,6 +137,23 @@ begin
FWriteStream:=TStringStream.Create(''); FWriteStream:=TStringStream.Create('');
end; end;
function TStubCreator.CheckUnitAlias(const AUnitName: String): String;
const
MAX_UNIT_NAME_LENGTH = 255;
var
UnitMaxLenthName: Integer;
begin
Result := AUnitName;
UnitMaxLenthName := Max(MAX_UNIT_NAME_LENGTH, Result.Length);
SetLength(Result, UnitMaxLenthName);
if FOnUnitAlias(OnUnitAliasData, @Result[1], UnitMaxLenthName) then
Result := LeftStr(PChar(Result), UnitMaxLenthName);
end;
procedure TStubCreator.DoWriteEvent; procedure TStubCreator.DoWriteEvent;
Var Var
@ -279,7 +302,7 @@ end;
Function TStubCreator.GetModule : TPasModule; function TStubCreator.GetModule: TPasModule;
Var Var
SE : TSimpleEngine; SE : TSimpleEngine;
@ -327,7 +350,8 @@ begin
end; end;
end; end;
function TStubCreator.MaybeGetFileStream(AStream: TStream; const AFileName: String; AfileMode : Word) : TStream; function TStubCreator.MaybeGetFileStream(AStream: TStream;
const AFileName: String; aFileMode: Word): TStream;
begin begin
If Assigned(AStream) then If Assigned(AStream) then
Result:=AStream Result:=AStream
@ -359,12 +383,11 @@ begin
end; end;
procedure TStubCreator.WriteModule(M : TPAsModule); procedure TStubCreator.WriteModule(M: TPasModule);
Var Var
F,H : TStream; F,H : TStream;
W : TPasWriter; W : TPasWriter;
U : String;
begin begin
W:=Nil; W:=Nil;
@ -385,14 +408,11 @@ begin
end; end;
W:=TPasWriter.Create(F); W:=TPasWriter.Create(F);
W.Options:=FOptions; W.Options:=FOptions;
U:=FExtraUnits; W.ExtraUnits:=FExtraUnits;
if Pos(LowerCase(DTypesUnit),LowerCase(U)) = 0 then
begin if Assigned(FOnUnitAlias) then
if (U<>'') then W.OnUnitAlias:=@CheckUnitAlias;
U:=','+U;
U:=DTypesUnit+U;
end;
W.ExtraUnits:=U;
if FIndentSize<>-1 then if FIndentSize<>-1 then
W.IndentSize:=FIndentSize; W.IndentSize:=FIndentSize;
if FLineNumberWidth>0 then if FLineNumberWidth>0 then