Stephan,
isBytes: oop ^ (interpreterProxy isIntegerObject: oop) not and: [interpreterProxy isBytes: oop]
has led to
int isBytes(int oop) { return (!((oop & 1))) && (interpreterProxy->isBytes(oop)); }
. Compiling works only without inlining, otherwise it runs into an infinite recursion.
That's a bug in the code generator, but trivial to fix. Just change your method into
isBytes: oop self inline: false. ^(interpreterProxy isIntegerObject: oop) not and: [interpreterProxy isBytes: oop]
The code generator doesn't take the receiver into account which is somewhat ugly and should be fixed but I don't know a simple way of fixing this.
The plugin runs in simulation, but in calling this function in C crashes the VM.
The problem here is that this function interferes with the same signatured function from 'sqVirtualMachine.c'.
sqVirtualMachine.c must *never* be compiled with the plugin itself. It merely defines the interpreter interface and is compiled with the VM not with the plugin! All you need in the plugin is the definition of the interface (e.g., from sqVirtualMachine.h) since you don't know beforehand with what version of the interpreter you're running.
This leads me to the following suggestions:
- A compiler warning would be nice, if someone overrides a predefined
function.
See above - this shouldn't be necessary if in a plugin.
- Wouldn't it be good to make all user plugin functions which are not
exported 'static' as default?
Yes and no ... sometimes it's very convenient if one has outside access to these functions and so far I haven't found a case where this causes any problems.
- Wouldn't it be better to make 'int isBytes(int oop);' and similar
functions in 'sqVirtualMachine.c' static? For plugins they are called indirectly by 'interpreterProxy->isBytes(oop)' anyway.
sqVirtualMachine.c does *not* define these functions. Again, sqVirtualMachine.c is just for the VM - not for the plugin.
Couldn't there arise any compatibility problems between different plugins in the current situation?
Not that I know of.
Greetings, Merry Christmas,
Und ebenfalls schoene Weihnachten und ein frohes neues J2K (oder wie heisst das in Deutsch?!)
Andreas
Dear Andreas,
please take a deeper look onto my suggestions:
"Raab, Andreas" wrote:
Stephan,
isBytes: oop ^ (interpreterProxy isIntegerObject: oop) not and: [interpreterProxy isBytes: oop]
has led to
int isBytes(int oop) { return (!((oop & 1))) && (interpreterProxy->isBytes(oop)); }
. Compiling works only without inlining, otherwise it runs into an infinite recursion.
That's a bug in the code generator, but trivial to fix. Just change your method into
isBytes: oop self inline: false. ^(interpreterProxy isIntegerObject: oop) not and: [interpreterProxy isBytes: oop]
The code generator doesn't take the receiver into account which is somewhat ugly and should be fixed but I don't know a simple way of fixing this.
The plugin runs in simulation, but in calling this function in C crashes the VM.
The problem here is that this function interferes with the same signatured function from 'sqVirtualMachine.c'.
After taking a second look I have found the _definition_ of isBytes() in interp.c. In sqVirtualMachine.c there is only an (extern) declaration of it.
sqVirtualMachine.c must *never* be compiled with the plugin itself.
I'm working at a plugin and compile only the plugin.
It merely defines the interpreter interface and is compiled with the VM not with the plugin! All you need in the plugin is the definition of the interface (e.g., from sqVirtualMachine.h) since you don't know beforehand with what version of the interpreter you're running.
I know that C interface declarations ordinarily are in *.h files...
This leads me to the following suggestions:
- 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.
As test I have made _my_ function 'static' in the plugin source file, and then it worked in C!
But because the compiler doesn't know about possible conflicts at running time - it doesn't link the plugin with the VM statically - there is no solution without - making 'static' the functions in interp.c, or (not exclusive) - making 'static' the functions in the plugin sources (see below).
- Wouldn't it be good to make all user plugin functions which are not
exported 'static' as default?
Yes and no ... sometimes it's very convenient if one has outside access to these functions and so far I haven't found a case where this causes any problems.
Now I have probably found such a case ;-) , a snipped from another communication follows:
## begin snipped
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.
## end snipped
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.
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.
- Wouldn't it be better to make 'int isBytes(int oop);' and similar
functions in 'sqVirtualMachine.c' static? For plugins they are called indirectly by 'interpreterProxy->isBytes(oop)' anyway.
sqVirtualMachine.c does *not* define these functions.
I've overlooked that they are _defined_ in interp.c and only _declared_ (implicitly extern) in sqVirtualMachine.c to make the function pointer assignments to the entries of the VM 'struct VirtualMachine', what on the other hand is _declared_ in sqVirtualMachine.h together with the accessing function 'sqGetInterpreterProxy(void)'.
But this doesn't change the problem of external visibility of the VM functions: If they are _defined_ in this or that source file is irrelevant.
Again, sqVirtualMachine.c is just for the VM - not for the plugin.
It is not the interface.
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...
Greetings, Merry Christmas,
Und ebenfalls schoene Weihnachten und ein frohes neues J2K (oder wie heisst das in Deutsch?!)
Es muesste wohl J2T (Tausend!) heissen... Mir ist dieses Kuerzel bisher allerdings noch nicht aufgefallen.
Andreas
Are you German native speaker?
Greetings,
Stephan
squeak-dev@lists.squeakfoundation.org