diff --git a/.gitignore b/.gitignore index 4523933..9b20757 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -*.dcu \ No newline at end of file +*.dcu +__history \ No newline at end of file diff --git a/Source/PascalScriptFCL.lpk b/Source/PascalScriptFCL.lpk index 9907f4e..ae48905 100644 --- a/Source/PascalScriptFCL.lpk +++ b/Source/PascalScriptFCL.lpk @@ -51,7 +51,7 @@ Carlo Kok RemObjects Software "/> - + @@ -152,6 +152,18 @@ RemObjects Software + + + + + + + + + + + + diff --git a/Source/PascalScriptFPC.inc b/Source/PascalScriptFPC.inc index 387464d..7f65006 100644 --- a/Source/PascalScriptFPC.inc +++ b/Source/PascalScriptFPC.inc @@ -1,7 +1,9 @@ {$DEFINE PS_HAVEVARIANT} {$DEFINE PS_DYNARRAY} - {$DEFINE PS_NOIDISPATCH} + {$ifndef mswindows} + {$DEFINE PS_NOIDISPATCH} + {$endif} {.$if (fpc_version=2) and (fpc_release>=3) and (fpc_patch>=1)} {$if (fpc_version=2) and ((fpc_release=2) and (fpc_patch>=4)) or (fpc_release>2)} {$UNDEF FPC_OLD_FIX} @@ -9,6 +11,11 @@ {$UNDEF PS_FPCSTRINGWORKAROUND} {$DEFINE PS_RESBEFOREPARAMETERS} {$DEFINE x64_string_result_as_varparameter} + {$ifdef mswindows} + {$if (fpc_version=2) and (fpc_release>5)} + {$DEFINE PS_FPC_HAS_COM} + {$endif} + {$endif} {FreePascal 2.3.1 and above has much Delphi compatibility bugs fixed} {$else} {$DEFINE FPC_OLD_FIX} diff --git a/Source/PascalScript_Core_Reg.pas b/Source/PascalScript_Core_Reg.pas index a076b77..cd87428 100644 --- a/Source/PascalScript_Core_Reg.pas +++ b/Source/PascalScript_Core_Reg.pas @@ -30,9 +30,7 @@ uses uPSComponent, uPSDebugger, uPSComponent_Default, - {$IFNDEF FPC} uPSComponent_COM, - {$ENDIF} uPSComponent_DB, uPSComponent_Forms, uPSComponent_Controls, @@ -45,9 +43,7 @@ begin TPSDllPlugin, TPSImport_Classes, TPSImport_DateUtils, - {$IFNDEF FPC} TPSImport_ComObj, - {$ENDIF} TPSImport_DB, TPSImport_Forms, TPSImport_Controls, diff --git a/Source/pascalscript.pas b/Source/pascalscript.pas index d5bf447..fa37a2b 100644 --- a/Source/pascalscript.pas +++ b/Source/pascalscript.pas @@ -15,7 +15,7 @@ uses uPSDisassembly, uPSPreProcessor, uPSR_buttons, uPSR_classes, uPSR_controls, uPSR_dateutils, uPSR_DB, uPSR_dll, uPSR_extctrls, uPSR_forms, uPSR_graphics, uPSR_menus, uPSR_std, uPSR_stdctrls, uPSUtils, - LazarusPackageIntf; + uPSComponent_COM, uPSC_comobj, uPSR_comobj, LazarusPackageIntf; implementation diff --git a/Source/uPSC_comobj.pas b/Source/uPSC_comobj.pas index b436468..4b4eb8b 100644 --- a/Source/uPSC_comobj.pas +++ b/Source/uPSC_comobj.pas @@ -21,6 +21,19 @@ implementation procedure SIRegister_ComObj(cl: TPSPascalCompiler); begin +{$IFDEF FPC} + {$IFDEF PS_FPC_HAS_COM} + cl.AddTypeS('HResult', 'LongInt'); + cl.AddTypeS('TGUID', 'record D1: LongWord; D2: Word; D3: Word; D4: array[0..7] of Byte; end;'); + cl.AddTypeS('TCLSID', 'TGUID'); + cl.AddTypeS('TIID', 'TGUID'); + cl.AddDelphiFunction('procedure OleCheck(Result: HResult);'); + cl.AddDelphiFunction('function StringToGUID(const S: string): TGUID;'); + cl.AddDelphiFunction('function CreateComObject(const ClassID: TGUID): IUnknown;'); + cl.AddDelphiFunction('function CreateOleObject(const ClassName: String): IDispatch;'); + cl.AddDelphiFunction('function GetActiveOleObject(const ClassName: String): IDispatch;'); + {$ENDIF} +{$ELSE} cl.AddTypeS('HResult', 'LongInt'); cl.AddTypeS('TGUID', 'record D1: LongWord; D2: Word; D3: Word; D4: array[0..7] of Byte; end;'); cl.AddTypeS('TCLSID', 'TGUID'); @@ -34,6 +47,7 @@ begin {$ENDIF} cl.AddDelphiFunction('function CreateOleObject(const ClassName: String): IDispatch;'); cl.AddDelphiFunction('function GetActiveOleObject(const ClassName: String): IDispatch;'); +{$ENDIF} end; end. diff --git a/Source/uPSCompiler.pas b/Source/uPSCompiler.pas index b59995e..0856b1b 100644 --- a/Source/uPSCompiler.pas +++ b/Source/uPSCompiler.pas @@ -923,6 +923,7 @@ type FAllowNoBegin: Boolean; FAllowNoEnd: Boolean; FAllowUnit: Boolean; + FAllowDuplicateRegister : Boolean; FBooleanShortCircuit: Boolean; FDebugOutput: tbtString; FOnExternalProc: TPSOnExternalProc; @@ -1177,6 +1178,7 @@ type property AllowNoEnd: Boolean read FAllowNoEnd write FAllowNoEnd; + property AllowDuplicateRegister : Boolean read FAllowDuplicateRegister write FAllowDuplicateRegister; property BooleanShortCircuit: Boolean read FBooleanShortCircuit write FBooleanShortCircuit; @@ -1724,7 +1726,7 @@ procedure DisposeVariant(p: PIfRVariant); implementation -uses {$IFDEF DELPHI5}ComObj, {$ENDIF}Classes, typInfo; +uses {$IFDEF DELPHI5}ComObj, {$ENDIF}{$IFDEF PS_FPC_HAS_COM}ComObj, {$ENDIF}Classes, typInfo; {$IFDEF DELPHI3UP} resourceString @@ -1804,7 +1806,6 @@ const RPS_AbstractClass = 'Abstract Class Construction'; RPS_UnknownWarning = 'Unknown warning'; - {$IFDEF DEBUG } RPS_UnableToRegister = 'Unable to register %s'; {$ENDIF} @@ -2383,6 +2384,9 @@ begin raise EPSCompilerException.Create(RPS_OnUseEventOnly); end; + if not(AllowDuplicateRegister) and IsDuplicate(FastUpperCase(Name),[dcTypes, dcProcs, dcVars]) then + Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]); + case BaseType of btProcPtr: Result := TPSProceduralType.Create; BtTypeCopy: Result := TPSTypeLink.Create; @@ -2908,8 +2912,8 @@ end; function TPSPascalCompiler.GetUnicodeString(Src: PIfRVariant; var s: Boolean): tbtunicodestring; begin case Src.FType.BaseType of - btChar: Result := Src^.tchar; - btString: Result := tbtstring(src^.tstring); + btChar: Result := tbtunicodestring(Src^.tchar); + btString: Result := tbtunicodestring(tbtstring(src^.tstring)); btWideChar: Result := src^.twidechar; btWideString: Result := tbtWideString(src^.twidestring); btUnicodeString: result := tbtUnicodeString(src^.tunistring); @@ -3564,12 +3568,12 @@ var h, l: Longint; x: TPSProcedure; begin - h := MakeHash(s); if (s = 'RESULT') then begin Result := True; exit; end; + h := MakeHash(s); if dcTypes in Check then for l := FTypes.Count - 1 downto 0 do begin @@ -6035,7 +6039,7 @@ function TPSPascalCompiler.ProcessSub(BlockInfo: TPSBlockInfo): Boolean; for i := 0 to arr.count -1 do begin mType := GetTypeNo(BlockInfo, arr.Item[i]); - if mType <> SetType.SetType then + if (mType <> SetType.SetType) and not (IsIntType(mType.FBaseType) and IsIntType(SetType.SetType.BaseType)) then begin with MakeError('', ecTypeMismatch, '') do begin @@ -6055,6 +6059,18 @@ function TPSPascalCompiler.ProcessSub(BlockInfo: TPSBlockInfo): Boolean; dataval.Free; exit; end; + if (c < Low(Byte)) or (c > High(Byte)) then + begin + with MakeError('', ecTypeMismatch, '') do + begin + FCol := arr.item[i].Col; + FRow := arr.item[i].Row; + FPosition := arr.item[i].Pos; + end; + DataVal.Free; + Result := False; + exit; + end; Set_MakeMember(c, dataval.Data.tstring); end else begin @@ -6140,9 +6156,9 @@ function TPSPascalCompiler.ProcessSub(BlockInfo: TPSBlockInfo): Boolean; exit; end; if TPSType(FarrType).BaseType = btVariant then - FArrType := FindAndAddType(self, '', 'array of variant'); + FArrType := at2ut(FindAndAddType(self, '!OPENARRAYOFVARIANT', 'array of variant')); if TPSType(FarrType).BaseType <> btArray then - FArrType := FindAndAddType(self, '', 'array of variant'); + FArrType := at2ut(FindAndAddType(self, '!OPENARRAYOFVARIANT', 'array of variant')); tmpp := AllocStackReg(FArrType); tmpc := AllocStackReg(FindBaseType(bts32)); @@ -12259,6 +12275,7 @@ begin FParser.OnParserError := ParserError; FAutoFreeList := TPSList.Create; FOutput := ''; + FAllowDuplicateRegister := true; {$IFDEF PS_USESSUPPORT} FAllowUnit := true; {$ENDIF} @@ -12407,6 +12424,10 @@ begin FType := GetTypeCopyLink(FType); if FType = nil then Raise EPSCompilerException.CreateFmt(RPS_UnableToRegisterConst, [name]); + + if not(AllowDuplicateRegister) and IsDuplicate(FastUpperCase(Name),[dcProcs, dcVars, dcConsts]) then + Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]); + pc := TPSConstant.Create; pc.OrgName := name; pc.Name := FastUppercase(name); @@ -13368,6 +13389,10 @@ begin if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly); Parser := TPSPascalParser.Create; Parser.SetText(Decl); + + if not(AllowDuplicateRegister) and (FindType(Name)<>nil) then + Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]); + Result := ReadType(Name, Parser); if Result<>nil then begin @@ -13475,6 +13500,9 @@ begin if not ParseMethod(Self, '', Decl, DOrgName, pDecl, FT) then Raise EPSCompilerException.CreateFmt(RPS_UnableToRegisterFunction, [Decl]); + if (FindProc(DOrgName)<>InvalidVal) and not(FAllowDuplicateRegister) then + Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Decl]); + p := TPSRegProc.Create; P.Name := FastUppercase(DOrgName); p.OrgName := DOrgName; @@ -13508,6 +13536,9 @@ var begin if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly); f := FindType(Name); + if (f<>nil) and not(FAllowDuplicateRegister) then + Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]); + if (f <> nil) and (f is TPSInterfaceType) then begin result := TPSInterfaceType(f).Intf; @@ -13544,7 +13575,8 @@ var begin if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly); Result := FindClass(tbtstring(aClass.ClassName)); - if Result <> nil then exit; + if (Result<>nil) and not(FAllowDuplicateRegister) then + Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [aClass.ClassName]); f := AddType(tbtstring(aClass.ClassName), btClass); Result := TPSCompileTimeClass.CreateC(aClass, Self, f); Result.FInheritsFrom := InheritsFrom; @@ -13559,6 +13591,8 @@ var begin if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly); Result := FindClass(aClass); + if (Result<>nil) and (Result.FInheritsFrom<>nil) and not(FAllowDuplicateRegister) then + Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [aClass]); if Result <> nil then begin if InheritsFrom <> nil then diff --git a/Source/uPSR_comobj.pas b/Source/uPSR_comobj.pas index 3d354aa..73e1500 100644 --- a/Source/uPSR_comobj.pas +++ b/Source/uPSR_comobj.pas @@ -11,11 +11,16 @@ uses procedure RIRegister_ComObj(cl: TPSExec); implementation -uses -{$IFDEF DELPHI3UP} - ComObj; +{$IFDEF FPC} + {$IFDEF PS_FPC_HAS_COM} + uses SysUtils, ComObj; + {$ENDIF} {$ELSE} - SysUtils, Ole2; + {$IFDEF DELPHI3UP} + uses ComObj; + {$ELSE} + uses SysUtils, Ole2; + {$ENDIF} {$ENDIF} {$IFNDEF DELPHI3UP} @@ -89,6 +94,15 @@ end; procedure RIRegister_ComObj(cl: TPSExec); begin +{$IFDEF FPC} + {$IFDEF PS_FPC_HAS_COM} + cl.RegisterDelphiFunction(@OleCheck, 'OleCheck', cdRegister); + cl.RegisterDelphiFunction(@StringToGUID, 'StringToGUID', cdRegister); + cl.RegisterDelphiFunction(@CreateComObject, 'CreateComObject', cdRegister); + cl.RegisterDelphiFunction(@CreateOleObject, 'CREATEOLEOBJECT', cdRegister); + cl.RegisterDelphiFunction(@GetActiveOleObject, 'GETACTIVEOLEOBJECT', cdRegister); + {$ENDIF} +{$ELSE} cl.RegisterDelphiFunction(@OleCheck, 'OleCheck', cdRegister); {$IFNDEF PS_NOINTERFACES} {$IFDEF DELPHI3UP} @@ -98,6 +112,7 @@ begin {$ENDIF} cl.RegisterDelphiFunction(@CreateOleObject, 'CREATEOLEOBJECT', cdRegister); cl.RegisterDelphiFunction(@GetActiveOleObject, 'GETACTIVEOLEOBJECT', cdRegister); +{$ENDIF} end; end. diff --git a/Source/uPSRuntime.pas b/Source/uPSRuntime.pas index 4b9794e..dc2bf1c 100644 --- a/Source/uPSRuntime.pas +++ b/Source/uPSRuntime.pas @@ -1101,7 +1101,7 @@ function IDispatchInvoke(Self: IDispatch; PropertySet: Boolean; const Name: tbtS implementation uses - TypInfo {$IFDEF DELPHI3UP}{$IFNDEF FPC}{$IFNDEF KYLIX} , ComObj {$ENDIF}{$ENDIF}{$ENDIF}; + TypInfo {$IFDEF DELPHI3UP}{$IFNDEF FPC}{$IFNDEF KYLIX} , ComObj {$ENDIF}{$ENDIF}{$ENDIF}{$IFDEF PS_FPC_HAS_COM}, ComObj{$ENDIF}; {$IFDEF DELPHI3UP } resourceString @@ -1822,15 +1822,15 @@ const type TDynArrayRecHeader = packed record + {$ifdef FPC} + refCnt : ptrint; + high : tdynarrayindex; + {$else} {$ifdef CPUX64} _Padding: LongInt; // Delphi XE2+ expects 16 byte align {$endif} /// dynamic array reference count (basic garbage memory mechanism) refCnt: Longint; - {$ifdef FPC} - high: sizeint; - function length: sizeint; inline; - {$else} /// length in element count // - size in bytes = length*ElemSize length: NativeInt; @@ -3585,10 +3585,10 @@ begin case aType.BaseType of btU8: Result := chr(tbtu8(src^)); btU16: Result := widechar(src^); - btChar: Result := tbtchar(Src^); - btPchar: Result := pansichar(src^); + btChar: Result := tbtunicodestring(tbtchar(Src^)); + btPchar: Result := tbtunicodestring(pansichar(src^)); btWideChar: Result := tbtwidechar(Src^); - btString: Result := tbtstring(src^); + btString: Result := tbtunicodestring(tbtstring(src^)); btWideString: Result := tbtwidestring(src^); btVariant: Result := Variant(src^); btUnicodeString: result := tbtUnicodeString(src^); @@ -4231,7 +4231,6 @@ begin {$ENDIF CPUX64} darr^.header.refCnt:=1; {$IFDEF FPC} - darr^.header.length := nil; darr^.header.high := NewLength - 1; {$ELSE} darr^.header.length := NewLength; @@ -9077,12 +9076,15 @@ var arr: TPSVariantIFC; begin Arr := NewTPSVariantIFC(Stack[Stack.Count-2], True); - if (arr.Dta = nil) or (arr.aType.BaseType <> btArray) then + if (arr.aType.BaseType <> btStaticArray) and ((arr.Dta = nil) or (arr.aType.BaseType <> btArray)) then begin Result := false; exit; end; - Stack.SetInt(-1, PSDynArrayGetLength(Pointer(arr.Dta^), arr.aType)); + if arr.aType.BaseType = btStaticArray then + Stack.SetInt(-1, TPSTypeRec_StaticArray(arr.aType).Size) + else + Stack.SetInt(-1, PSDynArrayGetLength(Pointer(arr.Dta^), arr.aType)); Result := True; end; @@ -9379,7 +9381,9 @@ begin RegisterDelphiFunction(@VarIsEmpty, 'VARISEMPTY', cdRegister); RegisterDelphiFunction(@Null, 'NULL', cdRegister); RegisterDelphiFunction(@VarIsNull, 'VARISNULL', cdRegister); + {$IFNDEF FPC} RegisterDelphiFunction(@VarType, 'VARTYPE', cdRegister); + {$ENDIF} {$IFNDEF PS_NOIDISPATCH} RegisterDelphiFunction(@IDispatchInvoke, 'IDISPATCHINVOKE', cdregister); {$ENDIF} @@ -12655,7 +12659,11 @@ begin if not Succeeded(i) then begin if i = DISP_E_EXCEPTION then + {$IFDEF FPC} + raise Exception.Create(ExceptInfo.Source+': '+ExceptInfo.Description) + {$ELSE} raise Exception.Create(ExceptInfo.bstrSource+': '+ExceptInfo.bstrDescription) + {$ENDIF} else raise Exception.Create(SysErrorMessage(i)); end; diff --git a/Source/x64.inc b/Source/x64.inc index 1e5b733..d52a5ad 100644 --- a/Source/x64.inc +++ b/Source/x64.inc @@ -610,6 +610,7 @@ begin {$ENDIF} btInterface, btArray, btVariant, btStaticArray: GetPtr(res); + btRecord, btSet: begin if res.aType.RealSize > PointerSize then GetPtr(res); @@ -629,6 +630,7 @@ begin {$ENDIF} btInterface, btArray, btVariant, btStaticArray: GetPtr(res); + btRecord, btSet: begin if res.aType.RealSize > PointerSize then GetPtr(res); @@ -666,7 +668,7 @@ begin btu32,bts32: tbtu32(res.dta^) := _RAX; btPChar: pansichar(res.dta^) := Pansichar(_RAX); bts64: tbts64(res.dta^) := Int64(_RAX); - btCurrency: tbtCurrency(res.Dta^) := Int64(_RAX); + btCurrency: tbts64(res.Dta^) := Int64(_RAX); btInterface, btVariant, {$IFDEF x64_string_result_as_varparameter}