浏览代码

* 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 -

sergei 14 年之前
父节点
当前提交
0093517227
共有 2 个文件被更改,包括 70 次插入37 次删除
  1. 2 0
      rtl/objpas/sysconst.pp
  2. 68 37
      rtl/objpas/sysutils/sysutils.inc

+ 2 - 0
rtl/objpas/sysconst.pp

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

+ 68 - 37
rtl/objpas/sysutils/sysutils.inc

@@ -294,22 +294,80 @@ begin
   Writeln(hstdout^,'');
   Writeln(hstdout^,'');
 end;
 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;
 Var OutOfMemory : EOutOfMemory;
     InValidPointer : EInvalidPointer;
     InValidPointer : EInvalidPointer;
 
 
 
 
 Procedure RunErrorToExcept (ErrNo : Longint; Address,Frame : Pointer);
 Procedure RunErrorToExcept (ErrNo : Longint; Address,Frame : Pointer);
-
-Var E : Exception;
-    HS : PString;
-
+var
+  E: Exception;
+  HS: PString;
+  Entry: PExceptMapEntry;
 begin
 begin
   Case Errno of
   Case Errno of
    1,203 : E:=OutOfMemory;
    1,203 : E:=OutOfMemory;
    204 : E:=InvalidPointer;
    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
      Case Errno of
        2 : HS:=@SFileNotFound;
        2 : HS:=@SFileNotFound;
        3 : HS:=@SInvalidFileName;
        3 : HS:=@SInvalidFileName;
@@ -325,7 +383,10 @@ begin
        105 : HS:=@SFileNotOpenForOutput;
        105 : HS:=@SFileNotOpenForOutput;
        106 : HS:=@SInvalidInput;
        106 : HS:=@SInvalidInput;
      end;
      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,
      // this routine can be called from FPC_IOCHECK,
      // which clears inoutres and then passes its
      // which clears inoutres and then passes its
      // original value to HandleErrorFrame() (which calls
      // original value to HandleErrorFrame() (which calls
@@ -335,36 +396,6 @@ begin
      EInoutError(E).ErrorCode:=errno;
      EInoutError(E).ErrorCode:=errno;
      inoutres:=0;
      inoutres:=0;
      end;
      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;
   end;
   Raise E at Address,Frame;
   Raise E at Address,Frame;
 end;
 end;