Stephan,
- A compiler warning would be nice, if someone overrides a
predefined function.
See above - this shouldn't be necessary if in a plugin.
But I have run exactly in this problem, because I have defined a function which was also defined in interp.c. I'm strongly supposing that my VM crashed, because isBytes() is not static there and interfered with my also not static function.
Hm ... interesting. I'm not sure what the reason is - perhaps Unix gets confused with the scope of a function. Have you checked from where your #isBytes: was called?! This might give you a hint if there was some confusion. Side note: I'm not an expert regarding the rules of binding exported names from a DSO - perhaps Ian knows?! AFAIK, the Unix Makefiles just export *everything* from the plugin. Windows and Mac don't do this - they just export those functions that are marked as #export (and in this sense any non-exported functions are static to the plugin automatically without the need to declare them as static). Perhaps that's where your problem is coming from.
Does regenerating interp.c also create a new sqVirtualMachine.h?
No, it does not.
Then it is impossible to call
class := interpreterProxy classLargeNegativeInteger.
, because in case of LargePositiveInteger it is compiled to
class = interpreterProxy->classLargePositiveInteger();
; and the interpreter struct is declared in sqVirtualMachine.h. But the function int classLargePositiveInteger(void); is defined in interp.c. Because it is not static, the variant for LargeNegativeIntegers should be directly callable after regenerating the interpreter.
The reason for having a proxy instead of direct bindings to the interpreter is mainly to allow for evolution of the interpreter without breaking what plugins rely on. If you call functions without going through the proxy somebody may use an older VM that doesn't even provide the functions you're relying on (which is okay since the plugin DSO should never start up then) or, even worse, may have a newer VM where some of the meaning has changed. By providing the proxy we know exactly what functions plugins rely on and can make sure that the associated semantics of these functions don't change. Also, the negotiating process upon plugin startup makes sure that the VM and the plugin can work with one another - again this would be very hard to find out if you bind the plugin to the VM directly.
Finally, it is true that regenerating the interpreter does not automatically provide you with the latest version of sqVirtualMachine.h - however, 'InterpreterSupportCode writeSupportFiles' does give you the latest version of it. sqVirtualMachine.h is (somewhat) independent from the interpreter because of exactly the reason I mentioned above.
I have to note that I need access to classLargeNegativeInteger in my plugin. This is possible in my - updated - image, but the interpreter is the original one from 2.6. So I have to regenerate the interpreter and asked if sqVirtualMachine.h - now it is clear that also sqVirtualMachine.c - is/are regenerated, too.
Yes, exactly.
Therefore I think now that making interp.c functions static could lead to problems for someone who hasn't used the sqVirtualMachine.h interface only. But in spite of this I think that making 'static' as much as possible is a more clean and better programming style.
Ah ... well yes, it's cleaner programming style. But there are a few users of interpreter functions in the VM support code for instance that really want to know what's going on inside the interpreter (such as for printing stack dumps on fatal errors).
Couldn't there arise any compatibility problems between different plugins in the current situation?
Not that I know of.
I think there could arise such problems if name clashes occure. Or is there a name space separation between different *.so libraries? At least between VM executable and my plugin *.so there seemed to be such a name clash...
That's a good point. Somebody with more experience than I should look into the problem of exported names in Unix DSOs.
Es muesste wohl J2T (Tausend!) heissen...
Sehr lustig ;-)
Are you German native speaker?
Nicht nur das, sogar deutscher Staatsbuerger (aber Ossi, disqualifiziert mich das als Muttersprachler, auch wenn ich nicht saechsele?! ;-)) Bin erst vor fast genau einem Jahr nach Kalifornien gezogen.
Ciao, Andreas
"Raab, Andreas" wrote:
Stephan,
- A compiler warning would be nice, if someone overrides a
predefined function.
See above - this shouldn't be necessary if in a plugin.
But I have run exactly in this problem, because I have defined a function which was also defined in interp.c. I'm strongly supposing that my VM crashed, because isBytes() is not static there and interfered with my also not static function.
Hm ... interesting. I'm not sure what the reason is - perhaps Unix gets confused with the scope of a function. Have you checked from where your #isBytes: was called?! This might give you a hint if there was some confusion. Side note: I'm not an expert regarding the rules of binding exported names from a DSO - perhaps Ian knows?! AFAIK, the Unix Makefiles just export *everything* from the plugin. Windows and Mac don't do this - they just export those functions that are marked as #export (and in this sense any non-exported functions are static to the plugin automatically without the need to declare them as static). Perhaps that's where your problem is coming from.
*** That's it! ***
I have checked it with an example which runs on a Mac, but crashes under Linux.
The reason for having a proxy instead of direct bindings to the interpreter is mainly to allow for evolution of the interpreter without breaking what plugins rely on. If you call functions without going through the proxy somebody may use an older VM that doesn't even provide the functions you're relying on (which is okay since the plugin DSO should never start up then) or, even worse, may have a newer VM where some of the meaning has changed. By providing the proxy we know exactly what functions plugins rely on and can make sure that the associated semantics of these functions don't change. Also, the negotiating process upon plugin startup makes sure that the VM and the plugin can work with one another - again this would be very hard to find out if you bind the plugin to the VM directly.
Remark: This means, that at least for plugin programmers all interp.c functions could be 'static'.
Finally, it is true that regenerating the interpreter does not automatically provide you with the latest version of sqVirtualMachine.h - however, 'InterpreterSupportCode writeSupportFiles' does give you the latest version of it. sqVirtualMachine.h is (somewhat) independent from the interpreter because of exactly the reason I mentioned above.
It's the interface. The implementation in 'interp.c' can be updated without changing the interface 'sqVirtualMachine.h'.
Therefore I think now that making interp.c functions static could lead to problems for someone who hasn't used the sqVirtualMachine.h interface only. But in spite of this I think that making 'static' as much as possible is a more clean and better programming style.
Ah ... well yes, it's cleaner programming style. But there are a few users of interpreter functions in the VM support code for instance that really want to know what's going on inside the interpreter (such as for printing stack dumps on fatal errors).
Such people are ordinarily very experienced in compiling issues and therefore able to change a flag in a makefile. I think it would be a good idea to introduce a '#define STATIC_INTERPRETER static', which could be changed by such an experienced programmer... All functions in 'interp.c' which normally should be invisible from outside could be prefixed by such a define.
Couldn't there arise any compatibility problems between different plugins in the current situation?
Not that I know of.
I think there could arise such problems if name clashes occure. Or is there a name space separation between different *.so libraries? At least between VM executable and my plugin *.so there seemed to be such a name clash...
That's a good point. Somebody with more experience than I should look into the problem of exported names in Unix DSOs.
The other direction is to make plugin functions 'static' as default, too. It would also solve the potential problems with name clashes between different plugins.
Greetings,
Stephan
squeak-dev@lists.squeakfoundation.org