lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Pointers to member functions still has to be treated specially, as they are actually physically the combination of a pointer to the object's type info containing the virtual table, and an index/offset in the virtual table. and so that the pointer to member function will be commiled with the additional implicit parameter for "this".
Changing such pointer to a normal function pointer would create a direct pointer to that function, but without any way to get back to the effective typeinfo and calling it would not work if we are passing parameters, at the "this" implicit parameter would be missing (so parameters would not match).

And if you typecast that blind pointer back to a member function, you need something at runtime to convert that blind pointer into an offset of the virtual table (at runtime, you need to perform a full scan of this virtual table to locate the function and validate it is effectively a member function: if this is not the case and you've not disabled this runtime check, any failed lookup would normally raise an exception. If you've disabled this runtime typechecking, you'll just call that function directly without using the virtual table (which is bypassed), but that function will still call its other virtual functions using the virtual table of its class by which it wxas created.

You loose the semantics for  virtual functions: you could with such unsafe typecast call a virtual function that was not the correct one defined for the object (which could be created with a derived subtype that change the function to another implementation according to the definition of its defininig class.

So a static (unchecked) typecasting from a pointer to member function into a normal function pointer can break: you've lost the effective type info of the defining class where the objcet was instantiated, and when you convert it back, you may force it to use a specific (static) class, Virtualization no longer works as expected: the called function may still work partly, but its own internal calls to other virtual methods would not use their correct implementation according to the effective type of the object.

However such static typecast is safe ONLY if:
* that member function itself does not perform ANY internal calls to other virtual functions for methods of the "this" object (including accessors, getters/setters for properties, or copy constructors)
* that member function itself does not perform ANY internal calls to other non-virtual functions that are not defined/implemented in a parent class (with which the effective instance could have been created), i.e. if the class for that method is NOT a derived class.
The compiler may treat these virtual functions specially, allowing them to not perform any typesafety check in their entry point (if such check is inserted by the compiler for debugging purpose, where the compiled function/method would receive also an additional parameter, in addition to the "this" pointer, for the pointer to the virtual table of its defining class to enforce an exception if the pointer given in the implicit parameter does not match the static pointer to the virtual table for which the function was compiled).

A normal "safe" pointer to member function contains two parts:
* the pointer to the "this object" (which contains a pointer to the virtual table of its defining class, so each instance keeps a track of its defining class), which will be passed to the called function as the implicit "this" parameter, and
* either the pointer to the entry point of the function or an offset in the virtual table containing the address of the entry point.

And a "safe" pointer to member function can use other runtime features, like dynamic type casts that will check that the target type (referenced at runtime by the pointer to its virtual table, read from the implicit member field of the object pointing to that table if the class has virtual methods, or taken from the static constant pointer to that virtual table, which also contains some other runtime type info like the "mangled" fully qualified class name) is a valid base class of the class of the input pointer to member function (referenced at runtime by the pointer to its virtual table) before validating it or will otherwise generate a type exception at runtime. Such runtime check will also be generated for the reverse dynamic typecast. Disabling these two runtime checks could make the behavior of the running program unpredictable, as there will no longer be any runtime exceptions for invalid typecasts (and the same should apply to the absence of type safety in the compiled preamble of virtual functions).

_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org