Who calls InvalidObjectError and why (other than the obvious!). I searched the code but couldn't find any enlightening references as to who actually detects an invalid object and calls this...? Thanks, Peter. -- Check out Interarchy 8.1.1, just released, now with Amazon S3 support. <http://www.stairways.com/> <http://download.stairways.com/>
Peter N Lewis wrote:
Who calls InvalidObjectError and why (other than the obvious!).
I searched the code but couldn't find any enlightening references as to who actually detects an invalid object and calls this...?
AFAIK InvalidObjectError is only called when you give `-fobject-checking' option. In this case the compiler emits inline code to check that virtual method table looks sane (exists and does not correspond to an abstract object). -- Waldek Hebisch hebisch@math.uni.wroc.pl
Waldek Hebisch wrote:
Peter N Lewis wrote:
Who calls InvalidObjectError and why (other than the obvious!).
I searched the code but couldn't find any enlightening references as to who actually detects an invalid object and calls this...?
BTW, it's called from compiler-generated code (not from RTS routines). The relevant line is in objects.c: convert (TREE_TYPE (fun), build_predef_call (p_InvalidObjectError, NULL_TREE)), fun)); It is done before virtual method calls.
AFAIK InvalidObjectError is only called when you give `-fobject-checking' option. In this case the compiler emits inline code to check that virtual method table looks sane (exists and does not correspond to an abstract object).
Where "VMT exists" means that its VMT pointer is not nil, and in the structure it points to, the "NegatedSize" field contains the negative value of its "Size" field -- as a check against unintialized VMT pointers etc., not 100% foolproof, of course, and the same that BP does, BTW. It doesn't actually check for abstract object types, but now that you mention it, I think it should. Though it's not easy to get an object with a VMT pointer to an abstract type (the compiler will normally prevent it), it is possible with some tricks (and of course, due to dangling pointers, memory corruption etc., which such runtime checks are meant to catch). There are several ways to achieve it. One is to check for Size = 0. Since all object types in GPC have at least the VMT pointer, their size can never be 0, and GPC explicitly sets the Size field to 0 for abstract types. Another way is to produce an intentional mismatch of the NegatedSize field for abstract type VMTs. The following patch does the latter, as it avoids one more runtime check, and only changes the initialization of abstract VMTs. Frank -- Frank Heckenbach, f.heckenbach@fh-soft.de, http://fjf.gnu.de/, 7977168E GPC To-Do list, latest features, fixed bugs: http://www.gnu-pascal.de/todo.html GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE D101 CD02 4C9D 0FE0 E5E8
I wrote:
It doesn't actually check for abstract object types, but now that you mention it, I think it should. Though it's not easy to get an object with a VMT pointer to an abstract type (the compiler will normally prevent it), it is possible with some tricks (and of course, due to dangling pointers, memory corruption etc., which such runtime checks are meant to catch).
There are several ways to achieve it.
(I.e., to achieve the checking, not producing the problem.)
One is to check for Size = 0. Since all object types in GPC have at least the VMT pointer, their size can never be 0, and GPC explicitly sets the Size field to 0 for abstract types. Another way is to produce an intentional mismatch of the NegatedSize field for abstract type VMTs. The following patch does the latter, as it avoids one more runtime check, and only changes the initialization of abstract VMTs.
PS: Necessary test program adjustment: --- p/test/fjf636e.pas.orig Sat Jan 11 15:23:13 2003 +++ p/test/fjf636e.pas Thu Aug 3 21:02:10 2006 @@ -71,16 +71,16 @@ WriteLn ('failed 20 ', Name^, ' d') else with TypeOf (C)^ do if Size <> 0 then WriteLn ('failed 21 ', Size, ' ', 0) - else if NegatedSize <> 0 then - WriteLn ('failed 22 ', NegatedSize, ' ', 0) + else if NegatedSize <> -1 then + WriteLn ('failed 22 ', NegatedSize, ' ', -1) else if Parent <> nil then WriteLn ('failed 23 ', PtrInt (Parent), ' ', 0) else if Name^ <> 'C' then WriteLn ('failed 24 ', Name^, ' C') else with TypeOf (Ee)^ do if Size <> 0 then WriteLn ('failed 25 ', Size, ' ', 0) - else if NegatedSize <> 0 then - WriteLn ('failed 26 ', NegatedSize, ' ', 0) + else if NegatedSize <> -1 then + WriteLn ('failed 26 ', NegatedSize, ' ', -1) else if Parent <> nil then WriteLn ('failed 27 ', PtrInt (Parent), ' ', 0) else if Name^ <> 'Ee' then Frank -- Frank Heckenbach, f.heckenbach@fh-soft.de, http://fjf.gnu.de/, 7977168E GPC To-Do list, latest features, fixed bugs: http://www.gnu-pascal.de/todo.html GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE D101 CD02 4C9D 0FE0 E5E8
Frank Heckenbach wrote:
I wrote:
It doesn't actually check for abstract object types, but now that you mention it, I think it should. Though it's not easy to get an object with a VMT pointer to an abstract type (the compiler will normally prevent it), it is possible with some tricks (and of course, due to dangling pointers, memory corruption etc., which such runtime checks are meant to catch).
There are several ways to achieve it.
(I.e., to achieve the checking, not producing the problem.)
One is to check for Size = 0. Since all object types in GPC have at least the VMT pointer, their size can never be 0, and GPC explicitly sets the Size field to 0 for abstract types. Another way is to produce an intentional mismatch of the NegatedSize field for abstract type VMTs. The following patch does the latter, as it avoids one more runtime check, and only changes the initialization of abstract VMTs.
PS: Necessary test program adjustment:
I have already (1 hour ago) applied the patch (thanks) and adjusted the test program. BTW: Thanks for gpc.diff-volatile -- Waldek Hebisch hebisch@math.uni.wroc.pl
participants (3)
-
Frank Heckenbach -
Peter N Lewis -
Waldek Hebisch