[Vm-dev] Problem: Cog vs Squeak VM InterpreterProxy interfaces mismatch

Igor Stasenko siguctua at gmail.com
Wed Sep 29 02:32:20 UTC 2010


>From Squeak VM:

#if VM_PROXY_MINOR > 7
	sqInt  (*internalIsImmutable)(sqInt oop);
	sqInt  (*internalIsMutable)(sqInt oop);
	sqInt  (*primitiveFailFor)(sqInt code);
	sqInt  (*classAlien)(void);
	sqInt *(*getStackPointer)(void);
	sqInt  (*sendInvokeCallbackStackRegistersJmpbuf)(sqInt thunkPtrAsInt,
sqInt stackPtrAsInt, sqInt regsPtrAsInt, sqInt jmpBufPtrAsInt);
	sqInt  (*reestablishContextPriorToCallback)(sqInt callbackContext);
	sqInt  (*classUnsafeAlien)(void);
	sqInt (*callbackEnter)(sqInt *callbackID);
	sqInt (*callbackLeave)(sqInt  callbackID);
	sqInt (*addGCRoot)(sqInt *varLoc);
	sqInt (*removeGCRoot)(sqInt *varLoc);

>From Cog VM:

#if VM_PROXY_MINOR > 7
  sqInt (*callbackEnter)(sqInt *callbackID);
  sqInt (*callbackLeave)(sqInt  callbackID);
  sqInt (*addGCRoot)(sqInt *varLoc);
  sqInt (*removeGCRoot)(sqInt *varLoc);
#endif

#if VM_PROXY_MINOR > 8
	sqInt  (*primitiveFailFor)(sqInt code);
	void (*(*setInterruptCheckChain)(void (*aFunction)(void)))();
	sqInt  (*classAlien)(void);
	sqInt  (*classUnsafeAlien)(void);
	sqInt  (*sendInvokeCallbackStackRegistersJmpbuf)(sqInt thunkPtrAsInt,
sqInt stackPtrAsInt, sqInt regsPtrAsInt, sqInt jmpBufPtrAsInt);
	sqInt  (*reestablishContextPriorToCallback)(sqInt callbackContext);
	sqInt *(*getStackPointer)(void);
	sqInt  (*internalIsImmutable)(sqInt oop);
	sqInt  (*internalIsMutable)(sqInt oop);
#endif

#if VM_PROXY_MINOR > 9
  sqInt  (*methodArg)  (sqInt index);
  sqInt  (*objectArg)  (sqInt index);
  sqInt  (*integerArg) (sqInt index);
  double (*floatArg)   (sqInt index);
  sqInt  (*methodReturnValue) (sqInt oop);
  sqInt  (*topRemappableOop)  (void);
#endif

#if VM_PROXY_MINOR > 10
  sqInt	(*disownVM)(sqInt flags);
  void	(*ownVM)   (sqInt threadIdAndFlags);
  void  (*addHighPriorityTickee)(void (*ticker)(void), unsigned periodms);
  void  (*addSynchronousTickee)(void (*ticker)(void), unsigned
periodms, unsigned roundms);
  usqLong (*utcMicroseconds)(void);
  sqInt (*tenuringIncrementalGC)(void);
  sqInt (*isYoung) (sqInt anOop);
  sqInt (*isKindOfClass)(sqInt oop, sqInt aClass);
  sqInt (*primitiveErrorTable)(void);
  sqInt (*primitiveFailureCode)(void);
  sqInt (*instanceSizeOf)(sqInt aClass);
#endif

Apparently, NativeBoost relies heavily on this interface, and any
mismatch automatically leads to problems :)

This also may pose a problem to external plugins, since in Squeak VM
promising to support VM_PROXY_MINOR = 8,
as well as Cog.
But if you take an external plugin, which using these functions, it
won't work for both VMs.


Eliot, have you considered employing a scheme, which i did for Hydra?

Some bits from Hydra's sqVirtualMachine.h:

#  define OBJVM_PROXY_MAJOR 2
#  define OBJVM_PROXY_MINOR 1

struct ObjVirtualMachine * sqGetObjInterpreterProxy(void);

typedef struct ObjVirtualMachine {
	sqInt (*minorVersion)(void);
	sqInt (*majorVersion)(void);

/* IMPORTANT!!!
*	The rest of functions can be obtained by plugin by calling a
getVMFunctionPointerBySelector function.
*	The need in defining additional functions in this struct is gone forever
*/
	void * (*getVMFunctionPointerBySelector)(char * selector);

} ObjVirtualMachine;

VMMaker generating a table of these functions , like:

/*** Public methods function pointers ***/

struct {
char * sel_1; sqInt (*addGCRoot)  _iargs(sqInt *varLoc);
char * sel_2; sqInt (*argumentCountOf)  (sqInt methodPointer);
char * sel_3; void * (*arrayValueOf)  (sqInt arrayOop);
char * sel_4; sqInt (*attachStateBufferinitializeFnfinalizeFn)  (sqInt
numberOfBytes, AttachedStateFn stateInitializeFn, AttachedStateFn
stateFinalizeFn);
char * sel_5; sqInt (*becomewith)  _iargs(sqInt array1, sqInt array2);
char * sel_6; sqInt (*booleanValueOf)  _iargs(sqInt obj);
char * sel_7; sqInt (*byteSizeOf)  (sqInt oop);
...
} vmFunctionPointers = {
"addGCRoot:", addGCRoot,
"argumentCountOf:", argumentCountOf,
"arrayValueOf:", arrayValueOf,
"attachStateBuffer:initializeFn:finalizeFn:",
attachStateBufferinitializeFnfinalizeFn,
"become:with:", becomewith,
"booleanValueOf:", booleanValueOf,
...
};

And i think you can easily extract a list of them in Cog, since you
marking them with <api> annotation.
The getVMFunctionPointerBySelector proxy function does a simple lookup
in this table and returns either valid pointer to function,
if it found or null if not.

Plugins code generator composing a table of used VM functions, and during
setInterpreterProxy() initializing this table through number of calls
to getVMFunctionPointerBySelector()
if one or more of retrieved function pointers is null, then it fails
to initialize, and returns 0, means that
this plugin can't be used with current VM.
Simple.

So, we can deal with the subject problem once and for all.
I think with Cog you can bravely change the VM_PROXY_MAJOR number, as
i did it in Hydra,
so no external plugins for version 1 will run with Cog.

I can help with taking a portions from Hydra to Cog, which doing the above.

-- 
Best regards,
Igor Stasenko AKA sig.


More information about the Vm-dev mailing list