* sysutils: changed RunErrorToExcept to use table instead of case statement for OS exceptions. This is to be able to extract exception class alone for the upcoming SEH support.

* Some Delphi-compatible changes:
  * For floating point underflow condition, raise EUnderflow, not EOverflow.
  * For unknown codes, raise EInOutError, not Exception.
  * Added entries for EZeroDivide and EStackOverflow (actually raising EZeroDivide on floating-point division by zero requires further changes to System because currently both integer and float division by zero is mapped to the same code 200).

  

git-svn-id: trunk@19707 -
This commit is contained in:
sergei 2011-11-29 18:41:13 +00:00
parent 0d562f04ff
commit 0093517227
2 changed files with 70 additions and 37 deletions

View File

@ -87,6 +87,7 @@ resourcestring
SOverflow = 'Floating point overflow';
SPrivilege = 'Privileged instruction';
SRangeError = 'Range check error';
SStackOverflow = 'Stack overflow';
SSafecallException = 'Exception in safecall method';
SiconvError = 'iconv error';
@ -116,6 +117,7 @@ resourcestring
SVarTypeRangeCheck2 = 'Range check error while converting variant of type (%s) into type (%s)';
SVarTypeTooManyCustom = 'Too many custom variant types have been registered';
SVarUnexpected = 'Unexpected variant error';
SZeroDivide = 'Floating point division by zero';
SFallbackError = 'An error, whose error code is larger than can be returned to the OS, has occured';

View File

@ -294,22 +294,80 @@ begin
Writeln(hstdout^,'');
end;
type
PExceptMapEntry=^TExceptMapEntry;
TExceptMapEntry=record
code: byte;
cls: ExceptClass;
msg: PResStringRec;
end;
const
exceptmap: array[0..27] of TExceptMapEntry = (
(code: 200; cls: EDivByZero; msg: @SDivByZero),
(code: 201; cls: ERangeError; msg: @SRangeError),
(code: 202; cls: EStackOverflow; msg: @SStackOverflow),
(code: 205; cls: EOverflow; msg: @SOverflow),
(code: 206; cls: EUnderflow; msg: @SUnderflow),
(code: 207; cls: EInvalidOp; msg: @SInvalidOp),
{ Delphi distinguishes reDivByZero from reZeroDivide, but maps both to code 200. }
(code: 208; cls: EZeroDivide; msg: @SZeroDivide),
(code: 211; cls: EAbstractError; msg: @SAbstractError),
(code: 212; cls: EExternalException; msg: @SExternalException),
(code: 214; cls: EBusError; msg: @SBusError),
(code: 215; cls: EIntOverflow; msg: @SIntOverflow),
(code: 216; cls: EAccessViolation; msg: @SAccessViolation),
(code: 217; cls: EControlC; msg: @SControlC),
(code: 218; cls: EPrivilege; msg: @SPrivilege),
(code: 219; cls: EInvalidCast; msg: @SInvalidCast),
(code: 220; cls: EVariantError; msg: @SInvalidVarCast),
(code: 221; cls: EVariantError; msg: @SInvalidVarOp),
(code: 222; cls: EVariantError; msg: @SDispatchError),
(code: 223; cls: EVariantError; msg: @SVarArrayCreate),
(code: 224; cls: EVariantError; msg: @SVarNotArray),
(code: 225; cls: EVariantError; msg: @SVarArrayBounds),
(code: 227; cls: EAssertionFailed; msg: @SAssertionFailed),
(code: 228; cls: EIntfCastError; msg: @SIntfCastError),
(code: 229; cls: ESafecallException; msg: @SSafecallException),
(code: 231; cls: EConvertError; msg: @SiconvError),
(code: 232; cls: ENoThreadSupport; msg: @SNoThreadSupport),
(code: 233; cls: ENoWideStringSupport; msg: @SSigQuit),
(code: 234; cls: ENoWideStringSupport; msg: @SMissingWStringManager)
);
function FindExceptMapEntry(err: longint): PExceptMapEntry;
var
i: longint;
begin
for i:=low(exceptmap) to high(exceptmap) do
if err=exceptmap[i].code then
begin
result:=@exceptmap[i];
exit;
end;
result:=nil;
end;
Var OutOfMemory : EOutOfMemory;
InValidPointer : EInvalidPointer;
Procedure RunErrorToExcept (ErrNo : Longint; Address,Frame : Pointer);
Var E : Exception;
HS : PString;
var
E: Exception;
HS: PString;
Entry: PExceptMapEntry;
begin
Case Errno of
1,203 : E:=OutOfMemory;
204 : E:=InvalidPointer;
2,3,4,5,6,100,101,102,103,105,106 : { I/O errors }
begin
else
Entry:=FindExceptMapEntry(ErrNo);
if Assigned(Entry) then
E:=Entry^.cls.CreateRes(Entry^.msg)
else
begin
HS:=nil;
Case Errno of
2 : HS:=@SFileNotFound;
3 : HS:=@SInvalidFileName;
@ -325,7 +383,10 @@ begin
105 : HS:=@SFileNotOpenForOutput;
106 : HS:=@SInvalidInput;
end;
E:=EinOutError.Create (HS^);
if Assigned(HS) then
E:=EInOutError.CreateRes(HS)
else
E:=EInOutError.CreateResFmt(@SUnknownRunTimeError,[errno]);
// this routine can be called from FPC_IOCHECK,
// which clears inoutres and then passes its
// original value to HandleErrorFrame() (which calls
@ -335,36 +396,6 @@ begin
EInoutError(E).ErrorCode:=errno;
inoutres:=0;
end;
// We don't set abstracterrorhandler, but we do it here.
// Unless the use sets another handler we'll get here anyway...
200 : E:=EDivByZero.Create(SDivByZero);
201 : E:=ERangeError.Create(SRangeError);
205 : E:=EOverflow.Create(SOverflow);
206 : E:=EOverflow.Create(SUnderflow);
207 : E:=EInvalidOp.Create(SInvalidOp);
211 : E:=EAbstractError.Create(SAbstractError);
212 : E:=EExternalException.Create(SExternalException);
214 : E:=EBusError.Create(SBusError);
215 : E:=EIntOverflow.Create(SIntOverflow);
216 : E:=EAccessViolation.Create(SAccessViolation);
217 : E:=EControlC.Create(SControlC);
218 : E:=EPrivilege.Create(SPrivilege);
219 : E:=EInvalidCast.Create(SInvalidCast);
220 : E:=EVariantError.Create(SInvalidVarCast);
221 : E:=EVariantError.Create(SInvalidVarOp);
222 : E:=EVariantError.Create(SDispatchError);
223 : E:=EVariantError.Create(SVarArrayCreate);
224 : E:=EVariantError.Create(SVarNotArray);
225 : E:=EVariantError.Create(SVarArrayBounds);
227 : E:=EAssertionFailed.Create(SAssertionFailed);
228 : E:=EIntfCastError.Create(SIntfCastError);
229 : E:=ESafecallException.Create(SSafecallException);
231 : E:=EConvertError.Create(SiconvError);
232 : E:=ENoThreadSupport.Create(SNoThreadSupport);
233 : E:=ENoWideStringSupport.Create(SSigQuit);
234 : E:=ENoWideStringSupport.Create(SMissingWStringManager);
else
E:=Exception.CreateFmt (SUnKnownRunTimeError,[Errno]);
end;
Raise E at Address,Frame;
end;