VM (callback+variables) changes

View: New views
5 Messages — Rating Filter:   Alert me  

VM (callback+variables) changes

by Andreas Raab :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Folks -

Attached my proposed changes for both, the variable tracking as well as
the callback support. I'll respond in the individual threads about more
specific issues; let's leave this one to discuss the more "mechanical"
issues if there are any. Included files:

- ExtraGCRoots.cs: The change set for tracking variables in plugins
- Callbacks.cs: The change set for VM callback support
- ExampleCallbacks.cs: An example plugin making use of both of the above
features
- sqVirtualMachine[.h|.c]: The (updated) VM proxy

If you install all of the above and build a complete VM you should be
able to execute the ExampleCallbackPlugin's exampleCallback and
successfully compute 3+4 using a callback.

Let me know if you have any problems.

Cheers,
   - Andreas




#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "sqVirtualMachine.h"

/*** Function prototypes ***/

/* InterpreterProxy methodsFor: 'stack access' */
sqInt  pop(sqInt nItems);
sqInt  popthenPush(sqInt nItems, sqInt oop);
sqInt  push(sqInt object);
sqInt  pushBool(sqInt trueOrFalse);
sqInt  pushFloat(double f);
sqInt  pushInteger(sqInt integerValue);
double stackFloatValue(sqInt offset);
sqInt  stackIntegerValue(sqInt offset);
sqInt  stackObjectValue(sqInt offset);
sqInt  stackValue(sqInt offset);

/*** variables ***/

extern sqInt (*compilerHooks[])();
extern sqInt setCompilerInitialized(sqInt flagValue);

/* InterpreterProxy methodsFor: 'object access' */
sqInt  argumentCountOf(sqInt methodPointer);
void  *arrayValueOf(sqInt oop);
sqInt  byteSizeOf(sqInt oop);
void  *fetchArrayofObject(sqInt fieldIndex, sqInt objectPointer);
sqInt  fetchClassOf(sqInt oop);
double fetchFloatofObject(sqInt fieldIndex, sqInt objectPointer);
sqInt  fetchIntegerofObject(sqInt fieldIndex, sqInt objectPointer);
sqInt  fetchPointerofObject(sqInt index, sqInt oop);
/* sqInt  fetchWordofObject(sqInt fieldIndex, sqInt oop);     *
 * has been rescinded as of VMMaker 3.8 and the 64bitclean VM *
 * work. To support old plugins we keep a valid function in   *
 * the same location in the VM struct but rename it to        *
 * something utterly horrible to scare off the natives. A new *
 * equivalent but 64 bit valid function is added as           *
 * 'fetchLong32OfObject'                                      */
sqInt  obsoleteDontUseThisFetchWordofObject(sqInt index, sqInt oop);
sqInt  fetchLong32ofObject(sqInt index, sqInt oop);
void  *firstFixedField(sqInt oop);
void  *firstIndexableField(sqInt oop);
sqInt  literalofMethod(sqInt offset, sqInt methodPointer);
sqInt  literalCountOf(sqInt methodPointer);
sqInt  methodArgumentCount(void);
sqInt  methodPrimitiveIndex(void);
sqInt  primitiveMethod(void);
sqInt  primitiveIndexOf(sqInt methodPointer);
sqInt  sizeOfSTArrayFromCPrimitive(void *cPtr);
sqInt  slotSizeOf(sqInt oop);
sqInt  stObjectat(sqInt array, sqInt index);
sqInt  stObjectatput(sqInt array, sqInt index, sqInt value);
sqInt  stSizeOf(sqInt oop);
sqInt  storeIntegerofObjectwithValue(sqInt index, sqInt oop, sqInt integer);
sqInt  storePointerofObjectwithValue(sqInt index, sqInt oop, sqInt valuePointer);


/* InterpreterProxy methodsFor: 'testing' */
sqInt isKindOf(sqInt oop, char *aString);
sqInt isMemberOf(sqInt oop, char *aString);
sqInt isBytes(sqInt oop);
sqInt isFloatObject(sqInt oop);
sqInt isIndexable(sqInt oop);
sqInt isIntegerObject(sqInt objectPointer);
sqInt isIntegerValue(sqInt intValue);
sqInt isPointers(sqInt oop);
sqInt isWeak(sqInt oop);
sqInt isWords(sqInt oop);
sqInt isWordsOrBytes(sqInt oop);
sqInt includesBehaviorThatOf(sqInt aClass, sqInt aSuperClass);
sqInt isArray(sqInt oop);

/* InterpreterProxy methodsFor: 'converting' */
sqInt  booleanValueOf(sqInt obj);
sqInt  checkedIntegerValueOf(sqInt intOop);
sqInt  floatObjectOf(double aFloat);
double floatValueOf(sqInt oop);
sqInt  integerObjectOf(sqInt value);
sqInt  integerValueOf(sqInt oop);
sqInt  positive32BitIntegerFor(sqInt integerValue);
sqInt  positive32BitValueOf(sqInt oop);
sqInt  signed32BitIntegerFor(sqInt integerValue);
sqInt  signed32BitValueOf(sqInt oop);
sqInt  positive64BitIntegerFor(sqLong integerValue);
sqLong positive64BitValueOf(sqInt oop);
sqInt  signed64BitIntegerFor(sqLong integerValue);
sqLong signed64BitValueOf(sqInt oop);

/* InterpreterProxy methodsFor: 'special objects' */
sqInt characterTable(void);
sqInt displayObject(void);
sqInt falseObject(void);
sqInt nilObject(void);
sqInt trueObject(void);


/* InterpreterProxy methodsFor: 'special classes' */
sqInt classArray(void);
sqInt classBitmap(void);
sqInt classByteArray(void);
sqInt classCharacter(void);
sqInt classFloat(void);
sqInt classLargePositiveInteger(void);
sqInt classLargeNegativeInteger(void);
sqInt classPoint(void);
sqInt classSemaphore(void);
sqInt classSmallInteger(void);
sqInt classString(void);


/* InterpreterProxy methodsFor: 'instance creation' */
sqInt clone(sqInt oop);
sqInt instantiateClassindexableSize(sqInt classPointer, sqInt size);
sqInt makePointwithxValueyValue(sqInt xValue, sqInt yValue);
sqInt popRemappableOop(void);
sqInt pushRemappableOop(sqInt oop);


/* InterpreterProxy methodsFor: 'other' */
sqInt becomewith(sqInt array1, sqInt array2);
sqInt byteSwapped(sqInt w);
sqInt failed(void);
sqInt fullDisplayUpdate(void);
sqInt fullGC(void);
sqInt incrementalGC(void);
sqInt primitiveFail(void);
sqInt showDisplayBitsLeftTopRightBottom(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
sqInt signalSemaphoreWithIndex(sqInt semaIndex);
sqInt success(sqInt aBoolean);
sqInt superclassOf(sqInt classPointer);
sqInt ioMicroMSecs(void);
sqInt forceInterruptCheck(void);
sqInt getThisSessionID(void);
sqInt ioFilenamefromStringofLengthresolveAliases(char* aCharBuffer, char* filenameIndex, sqInt filenameLength, sqInt resolveFlag);
sqInt  vmEndianness(void);

/* InterpreterProxy methodsFor: 'BitBlt support' */
sqInt loadBitBltFrom(sqInt bbOop);
sqInt copyBits(void);
sqInt copyBitsFromtoat(sqInt leftX, sqInt rightX, sqInt yValue);

/* InterpreterProxy methodsFor: 'FFI support' */
sqInt classExternalAddress(void);
sqInt classExternalData(void);
sqInt classExternalFunction(void);
sqInt classExternalLibrary(void);
sqInt classExternalStructure(void);
sqInt ioLoadModuleOfLength(sqInt moduleNameIndex, sqInt moduleNameLength);
sqInt ioLoadSymbolOfLengthFromModule(sqInt functionNameIndex, sqInt functionNameLength, sqInt moduleHandle);
sqInt isInMemory(sqInt address);

void *ioLoadFunctionFrom(char *fnName, char *modName);


/* Proxy declarations for v1.8 */
sqInt callbackEnter(sqInt *callbackID);
sqInt callbackLeave(sqInt  callbackID);
sqInt addGCRoot(sqInt *varLoc);
sqInt removeGCRoot(sqInt *varLoc);

struct VirtualMachine *VM = NULL;

static sqInt majorVersion(void) {
        return VM_PROXY_MAJOR;
}

static sqInt minorVersion(void) {
        return VM_PROXY_MINOR;
}

static CompilerHook *compilerHookVector(void) {
  return compilerHooks;
}


struct VirtualMachine* sqGetInterpreterProxy(void)
{
        if(VM) return VM;
        VM = (struct VirtualMachine *)calloc(1, sizeof(VirtualMachine));
        /* Initialize Function pointers */
        VM->majorVersion = majorVersion;
        VM->minorVersion = minorVersion;

        /* InterpreterProxy methodsFor: 'stack access' */
        VM->pop = pop;
        VM->popthenPush = popthenPush;
        VM->push = push;
        VM->pushBool = pushBool;
        VM->pushFloat = pushFloat;
        VM->pushInteger = pushInteger;
        VM->stackFloatValue = stackFloatValue;
        VM->stackIntegerValue = stackIntegerValue;
        VM->stackObjectValue = stackObjectValue;
        VM->stackValue = stackValue;
       
        /* InterpreterProxy methodsFor: 'object access' */
        VM->argumentCountOf = argumentCountOf;
        VM->arrayValueOf = arrayValueOf;
        VM->byteSizeOf = byteSizeOf;
        VM->fetchArrayofObject = fetchArrayofObject;
        VM->fetchClassOf = fetchClassOf;
        VM->fetchFloatofObject = fetchFloatofObject;
        VM->fetchIntegerofObject = fetchIntegerofObject;
        VM->fetchPointerofObject = fetchPointerofObject;
        VM->obsoleteDontUseThisFetchWordofObject = obsoleteDontUseThisFetchWordofObject;
        VM->firstFixedField = firstFixedField;
        VM->firstIndexableField = firstIndexableField;
        VM->literalofMethod = literalofMethod;
        VM->literalCountOf = literalCountOf;
        VM->methodArgumentCount = methodArgumentCount;
        VM->methodPrimitiveIndex = methodPrimitiveIndex;
        VM->primitiveIndexOf = primitiveIndexOf;
        VM->primitiveMethod = primitiveMethod;
        VM->sizeOfSTArrayFromCPrimitive = sizeOfSTArrayFromCPrimitive;
        VM->slotSizeOf = slotSizeOf;
        VM->stObjectat = stObjectat;
        VM->stObjectatput = stObjectatput;
        VM->stSizeOf = stSizeOf;
        VM->storeIntegerofObjectwithValue = storeIntegerofObjectwithValue;
        VM->storePointerofObjectwithValue = storePointerofObjectwithValue;
       
        /* InterpreterProxy methodsFor: 'testing' */
        VM->isKindOf = isKindOf;
        VM->isMemberOf = isMemberOf;
        VM->isBytes = isBytes;
        VM->isFloatObject = isFloatObject;
        VM->isIndexable = isIndexable;
        VM->isIntegerObject = isIntegerObject;
        VM->isIntegerValue = isIntegerValue;
        VM->isPointers = isPointers;
        VM->isWeak = isWeak;
        VM->isWords = isWords;
        VM->isWordsOrBytes = isWordsOrBytes;

        /* InterpreterProxy methodsFor: 'converting' */
        VM->booleanValueOf = booleanValueOf;
        VM->checkedIntegerValueOf = checkedIntegerValueOf;
        VM->floatObjectOf = floatObjectOf;
        VM->floatValueOf = floatValueOf;
        VM->integerObjectOf = integerObjectOf;
        VM->integerValueOf = integerValueOf;
        VM->positive32BitIntegerFor = positive32BitIntegerFor;
        VM->positive32BitValueOf = positive32BitValueOf;

        /* InterpreterProxy methodsFor: 'special objects' */
        VM->characterTable = characterTable;
        VM->displayObject = displayObject;
        VM->falseObject = falseObject;
        VM->nilObject = nilObject;
        VM->trueObject = trueObject;
       
        /* InterpreterProxy methodsFor: 'special classes' */
        VM->classArray = classArray;
        VM->classBitmap = classBitmap;
        VM->classByteArray = classByteArray;
        VM->classCharacter = classCharacter;
        VM->classFloat = classFloat;
        VM->classLargePositiveInteger = classLargePositiveInteger;
        VM->classPoint = classPoint;
        VM->classSemaphore = classSemaphore;
        VM->classSmallInteger = classSmallInteger;
        VM->classString = classString;
       
        /* InterpreterProxy methodsFor: 'instance creation' */
        VM->clone = clone;
        VM->instantiateClassindexableSize = instantiateClassindexableSize;
        VM->makePointwithxValueyValue = makePointwithxValueyValue;
        VM->popRemappableOop = popRemappableOop;
        VM->pushRemappableOop = pushRemappableOop;

        /* InterpreterProxy methodsFor: 'other' */
        VM->becomewith = becomewith;
        VM->byteSwapped = byteSwapped;
        VM->failed = failed;
        VM->fullDisplayUpdate = fullDisplayUpdate;
        VM->fullGC = fullGC;
        VM->incrementalGC = incrementalGC;
        VM->primitiveFail = primitiveFail;
        VM->showDisplayBitsLeftTopRightBottom = showDisplayBitsLeftTopRightBottom;
        VM->signalSemaphoreWithIndex = signalSemaphoreWithIndex;
        VM->success = success;
        VM->superclassOf = superclassOf;

        VM->compilerHookVector= compilerHookVector;
        VM->setCompilerInitialized= setCompilerInitialized;

#if VM_PROXY_MINOR > 1

        /* InterpreterProxy methodsFor: 'BitBlt support' */
        VM->loadBitBltFrom = loadBitBltFrom;
        VM->copyBits = copyBits;
        VM->copyBitsFromtoat = copyBitsFromtoat;

#endif

#if VM_PROXY_MINOR > 2

        /* InterpreterProxy methodsFor: 'FFI support' */
        VM->classExternalAddress = classExternalAddress;
        VM->classExternalData = classExternalData;
        VM->classExternalFunction = classExternalFunction;
        VM->classExternalLibrary = classExternalLibrary;
        VM->classExternalStructure = classExternalStructure;
        VM->ioLoadModuleOfLength = ioLoadModuleOfLength;
        VM->ioLoadSymbolOfLengthFromModule = ioLoadSymbolOfLengthFromModule;
        VM->isInMemory = isInMemory;
        VM->signed32BitIntegerFor = signed32BitIntegerFor;
        VM->signed32BitValueOf = signed32BitValueOf;
        VM->includesBehaviorThatOf = includesBehaviorThatOf;
        VM->classLargeNegativeInteger = classLargeNegativeInteger;

#endif

#if VM_PROXY_MINOR > 3

        VM->ioLoadFunctionFrom = ioLoadFunctionFrom;
        VM->ioMicroMSecs = ioMicroMSecs;

#endif

#if VM_PROXY_MINOR > 4

        VM->positive64BitIntegerFor = positive64BitIntegerFor;
        VM->positive64BitValueOf = positive64BitValueOf;
        VM->signed64BitIntegerFor = signed64BitIntegerFor;
        VM->signed64BitValueOf = signed64BitValueOf;

#endif

#if VM_PROXY_MINOR > 5
        VM->isArray = isArray;
        VM->forceInterruptCheck = forceInterruptCheck;
#endif

#if VM_PROXY_MINOR > 6
        VM->fetchLong32ofObject = fetchLong32ofObject;
        VM->getThisSessionID = getThisSessionID;
        VM->ioFilenamefromStringofLengthresolveAliases = ioFilenamefromStringofLengthresolveAliases;
        VM->vmEndianness = vmEndianness;
#endif

#if VM_PROXY_MINOR > 7
        VM->callbackEnter = callbackEnter;
        VM->callbackLeave = callbackLeave;
        VM->addGCRoot = addGCRoot;
        VM->removeGCRoot = removeGCRoot;
#endif

        return VM;
}

#ifndef _SqueakVM_H
#define _SqueakVM_H

/* Increment the following number if you change the order of
   functions listed or if you remove functions */
#define VM_PROXY_MAJOR 1

/* Note: You can define a different VM_PROXY_MINOR if the plugin
   should work with older VMs. */
#ifndef VM_PROXY_MINOR
/* Increment the following number if you add functions at the end */
#define VM_PROXY_MINOR 8
#endif

#include "sqMemoryAccess.h"

typedef sqInt (*CompilerHook)();

struct VirtualMachine* sqGetInterpreterProxy(void);

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

        /* InterpreterProxy methodsFor: 'stack access' */

        sqInt  (*pop)(sqInt nItems);
        sqInt  (*popthenPush)(sqInt nItems, sqInt oop);
        sqInt  (*push)(sqInt object);
        sqInt  (*pushBool)(sqInt trueOrFalse);
        sqInt  (*pushFloat)(double f);
        sqInt  (*pushInteger)(sqInt integerValue);
        double (*stackFloatValue)(sqInt offset);
        sqInt  (*stackIntegerValue)(sqInt offset);
        sqInt  (*stackObjectValue)(sqInt offset);
        sqInt  (*stackValue)(sqInt offset);

        /* InterpreterProxy methodsFor: 'object access' */

        sqInt  (*argumentCountOf)(sqInt methodPointer);
        void  *(*arrayValueOf)(sqInt oop);
        sqInt  (*byteSizeOf)(sqInt oop);
        void  *(*fetchArrayofObject)(sqInt fieldIndex, sqInt objectPointer);
        sqInt  (*fetchClassOf)(sqInt oop);
        double (*fetchFloatofObject)(sqInt fieldIndex, sqInt objectPointer);
        sqInt  (*fetchIntegerofObject)(sqInt fieldIndex, sqInt objectPointer);
        sqInt  (*fetchPointerofObject)(sqInt fieldIndex, sqInt oop);
/*  sqInt  (*fetchWordofObject)(sqInt fieldFieldIndex, sqInt oop); *
 * has been rescinded as of VMMaker 3.8 and the 64bitclean VM      *
 * work. To support old plugins we keep a valid function in        *
 * the same location in the VM struct but rename it to             *
 * something utterly horrible to scare off the natives. A new      *
 * equivalent but 64 bit valid function is added as                *
 * 'fetchLong32OfObject'                                           */
        sqInt  (*obsoleteDontUseThisFetchWordofObject)(sqInt fieldFieldIndex, sqInt oop);
        void  *(*firstFixedField)(sqInt oop);
        void  *(*firstIndexableField)(sqInt oop);
        sqInt  (*literalofMethod)(sqInt offset, sqInt methodPointer);
        sqInt  (*literalCountOf)(sqInt methodPointer);
        sqInt  (*methodArgumentCount)(void);
        sqInt  (*methodPrimitiveIndex)(void);
        sqInt  (*primitiveIndexOf)(sqInt methodPointer);
        sqInt  (*sizeOfSTArrayFromCPrimitive)(void *cPtr);
        sqInt  (*slotSizeOf)(sqInt oop);
        sqInt  (*stObjectat)(sqInt array, sqInt fieldIndex);
        sqInt  (*stObjectatput)(sqInt array, sqInt fieldIndex, sqInt value);
        sqInt  (*stSizeOf)(sqInt oop);
        sqInt  (*storeIntegerofObjectwithValue)(sqInt fieldIndex, sqInt oop, sqInt integer);
        sqInt  (*storePointerofObjectwithValue)(sqInt fieldIndex, sqInt oop, sqInt valuePointer);

        /* InterpreterProxy methodsFor: 'testing' */

        sqInt (*isKindOf)(sqInt oop, char *aString);
        sqInt (*isMemberOf)(sqInt oop, char *aString);
        sqInt (*isBytes)(sqInt oop);
        sqInt (*isFloatObject)(sqInt oop);
        sqInt (*isIndexable)(sqInt oop);
        sqInt (*isIntegerObject)(sqInt objectPointer);
        sqInt (*isIntegerValue)(sqInt intValue);
        sqInt (*isPointers)(sqInt oop);
        sqInt (*isWeak)(sqInt oop);
        sqInt (*isWords)(sqInt oop);
        sqInt (*isWordsOrBytes)(sqInt oop);

        /* InterpreterProxy methodsFor: 'converting' */

        sqInt  (*booleanValueOf)(sqInt obj);
        sqInt  (*checkedIntegerValueOf)(sqInt intOop);
        sqInt  (*floatObjectOf)(double aFloat);
        double (*floatValueOf)(sqInt oop);
        sqInt  (*integerObjectOf)(sqInt value);
        sqInt  (*integerValueOf)(sqInt oop);
        sqInt  (*positive32BitIntegerFor)(sqInt integerValue);
        sqInt  (*positive32BitValueOf)(sqInt oop);

        /* InterpreterProxy methodsFor: 'special objects' */

        sqInt (*characterTable)(void);
        sqInt (*displayObject)(void);
        sqInt (*falseObject)(void);
        sqInt (*nilObject)(void);
        sqInt (*trueObject)(void);

        /* InterpreterProxy methodsFor: 'special classes' */

        sqInt (*classArray)(void);
        sqInt (*classBitmap)(void);
        sqInt (*classByteArray)(void);
        sqInt (*classCharacter)(void);
        sqInt (*classFloat)(void);
        sqInt (*classLargePositiveInteger)(void);
        sqInt (*classPoint)(void);
        sqInt (*classSemaphore)(void);
        sqInt (*classSmallInteger)(void);
        sqInt (*classString)(void);

        /* InterpreterProxy methodsFor: 'instance creation' */

        sqInt (*clone)(sqInt oop);
        sqInt (*instantiateClassindexableSize)(sqInt classPointer, sqInt size);
        sqInt (*makePointwithxValueyValue)(sqInt xValue, sqInt yValue);
        sqInt (*popRemappableOop)(void);
        sqInt (*pushRemappableOop)(sqInt oop);

        /* InterpreterProxy methodsFor: 'other' */

        sqInt (*becomewith)(sqInt array1, sqInt array2);
        sqInt (*byteSwapped)(sqInt w);
        sqInt (*failed)(void);
        sqInt (*fullDisplayUpdate)(void);
        sqInt (*fullGC)(void);
        sqInt (*incrementalGC)(void);
        sqInt (*primitiveFail)(void);
        sqInt (*showDisplayBitsLeftTopRightBottom)(sqInt aForm, sqInt l, sqInt t, sqInt r, sqInt b);
        sqInt (*signalSemaphoreWithIndex)(sqInt semaIndex);
        sqInt (*success)(sqInt aBoolean);
        sqInt (*superclassOf)(sqInt classPointer);

        /* InterpreterProxy methodsFor: 'compiler' */

        CompilerHook *(*compilerHookVector)(void);
        sqInt          (*setCompilerInitialized)(sqInt initFlag);

#if VM_PROXY_MINOR > 1

        /* InterpreterProxy methodsFor: 'BitBlt support' */

        sqInt (*loadBitBltFrom)(sqInt bbOop);
        sqInt (*copyBits)(void);
        sqInt (*copyBitsFromtoat)(sqInt leftX, sqInt rightX, sqInt yValue);

#endif

#if VM_PROXY_MINOR > 2

        sqInt (*classLargeNegativeInteger)(void);
        sqInt (*signed32BitIntegerFor)(sqInt integerValue);
        sqInt (*signed32BitValueOf)(sqInt oop);
        sqInt (*includesBehaviorThatOf)(sqInt aClass, sqInt aSuperClass);
        sqInt (*primitiveMethod)(void);

        /* InterpreterProxy methodsFor: 'FFI support' */

        sqInt (*classExternalAddress)(void);
        sqInt (*classExternalData)(void);
        sqInt (*classExternalFunction)(void);
        sqInt (*classExternalLibrary)(void);
        sqInt (*classExternalStructure)(void);
        sqInt (*ioLoadModuleOfLength)(sqInt modIndex, sqInt modLength);
        sqInt (*ioLoadSymbolOfLengthFromModule)(sqInt fnIndex, sqInt fnLength, sqInt handle);
        sqInt (*isInMemory)(sqInt address);

#endif

#if VM_PROXY_MINOR > 3

        void *(*ioLoadFunctionFrom)(char *fnName, char *modName);
        sqInt (*ioMicroMSecs)(void);

#endif

#if VM_PROXY_MINOR > 4

#  if !defined(sqLong)
#   if _MSC_VER
#     define sqLong __int64
#   else
#     define sqLong long long
#   endif
#  endif

        sqInt  (*positive64BitIntegerFor)(sqLong integerValue);
        sqLong (*positive64BitValueOf)(sqInt oop);
        sqInt  (*signed64BitIntegerFor)(sqLong integerValue);
        sqLong (*signed64BitValueOf)(sqInt oop);

#endif

#if VM_PROXY_MINOR > 5
        sqInt (*isArray)(sqInt oop);
        sqInt (*forceInterruptCheck)(void);
#endif

#if VM_PROXY_MINOR > 6
        sqInt  (*fetchLong32ofObject)(sqInt fieldFieldIndex, sqInt oop);
        sqInt  (*getThisSessionID)(void);
        sqInt  (*ioFilenamefromStringofLengthresolveAliases)(char* aCharBuffer, char* filenameIndex, sqInt filenameLength, sqInt resolveFlag);
        sqInt  (*vmEndianness)(void);
#endif

#if VM_PROXY_MINOR > 7
  /* New methods for proxy version 1.8 */

  /* callbackEnter: Re-enter the interpreter loop for a callback.
     Arguments:
       callbackID: Pointer to a location receiving the callback ID
                   used in callbackLeave
     Returns: True if successful, false otherwise */
  sqInt (*callbackEnter)(sqInt *callbackID);

  /* callbackLeave: Leave the interpreter from a previous callback
     Arguments:
       callbackID: The ID of the callback received from callbackEnter()
     Returns: True if succcessful, false otherwise. */
  sqInt (*callbackLeave)(sqInt  callbackID);

  /* addGCRoot: Add a variable location to the garbage collector.
     The contents of the variable location will be updated accordingly.
     Arguments:
       varLoc: Pointer to the variable location
     Returns: True if successful, false otherwise. */
  sqInt (*addGCRoot)(sqInt *varLoc);

  /* removeGCRoot: Remove a variable location from the garbage collector.
     Arguments:
       varLoc: Pointer to the variable location
     Returns: True if successful, false otherwise.
  */
  sqInt (*removeGCRoot)(sqInt *varLoc);
#endif

} VirtualMachine;

#endif /* _SqueakVM_H */

ExtraGCRoots.cs.gz (5K) Download Attachment
Callbacks.cs.gz (10K) Download Attachment
ExampleCallbacks.cs.gz (2K) Download Attachment

Re: VM (callback+variables) changes

by Rob Gayvert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Andreas,

This looks great. I tried this out with a fresh 3.9-7033 image and
latest Win32 VM source, and your example worked as advertised. It also
works fine as a replacement for my wxSqueak setjmp/longjmp calls, and
removes the need for an extra semaphore on the calling process. Thanks!

.. Rob


Andreas Raab wrote:

> Hi Folks -
>
> Attached my proposed changes for both, the variable tracking as well as
> the callback support. I'll respond in the individual threads about more
> specific issues; let's leave this one to discuss the more "mechanical"
> issues if there are any. Included files:
>
> - ExtraGCRoots.cs: The change set for tracking variables in plugins
> - Callbacks.cs: The change set for VM callback support
> - ExampleCallbacks.cs: An example plugin making use of both of the above
> features
> - sqVirtualMachine[.h|.c]: The (updated) VM proxy
>
> If you install all of the above and build a complete VM you should be
> able to execute the ExampleCallbackPlugin's exampleCallback and
> successfully compute 3+4 using a callback.
>
> Let me know if you have any problems.
>
> Cheers,
>   - Andreas
>
>



Re: VM (callback+variables) changes

by Andreas Raab :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Rob -

Good to hear it works. There are two things that bothers me slightly and
I'd like to get some feedback from someone who's been in that area
before: First, the callback identifier. While it seems a good safeguard
at first it gets into ones way pretty quickly (like in the example
plugin where the absence of callback-id management makes it impossible
to have more than one callback). So... do you think it's worthwhile to
keep it and force people to go through the hoops of maintaining it?

Second, I'm somewhat unhappy about the management of the suspended
processs. I am wondering if we shouldn't use a semaphore in the
splObjects for this purpose and link/unlink properly. This has the
disadvantage that some image-side changes are required but it might be
worth it for better house-keeping.

Comments welcome!
   - Andreas

Rob Gayvert wrote:

> Andreas,
>
> This looks great. I tried this out with a fresh 3.9-7033 image and
> latest Win32 VM source, and your example worked as advertised. It also
> works fine as a replacement for my wxSqueak setjmp/longjmp calls, and
> removes the need for an extra semaphore on the calling process. Thanks!
>
> .. Rob
>
>
> Andreas Raab wrote:
>> Hi Folks -
>>
>> Attached my proposed changes for both, the variable tracking as well
>> as the callback support. I'll respond in the individual threads about
>> more specific issues; let's leave this one to discuss the more
>> "mechanical" issues if there are any. Included files:
>>
>> - ExtraGCRoots.cs: The change set for tracking variables in plugins
>> - Callbacks.cs: The change set for VM callback support
>> - ExampleCallbacks.cs: An example plugin making use of both of the
>> above features
>> - sqVirtualMachine[.h|.c]: The (updated) VM proxy
>>
>> If you install all of the above and build a complete VM you should be
>> able to execute the ExampleCallbackPlugin's exampleCallback and
>> successfully compute 3+4 using a callback.
>>
>> Let me know if you have any problems.
>>
>> Cheers,
>>   - Andreas
>>
>>
>
>
>

Re: VM (callback+variables) changes

by Rob Gayvert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

My callback usage is intense but of limited variety, so the callback ids
are not much of a burden. Without an id, there would be no way to check
whether the callbacks were being exited in the proper order. For some
cases that might not be important, but it might also result in some
nasty bugs. How about making it optional by passing a null value?

On the process management question, I'm afraid I don't understand this
area well enough. Is your concern as aesthetic one, or are there
performance or correctness issues with your current implementation?

.. Rob


Andreas Raab wrote:

> Hi Rob -
>
> Good to hear it works. There are two things that bothers me slightly and
> I'd like to get some feedback from someone who's been in that area
> before: First, the callback identifier. While it seems a good safeguard
> at first it gets into ones way pretty quickly (like in the example
> plugin where the absence of callback-id management makes it impossible
> to have more than one callback). So... do you think it's worthwhile to
> keep it and force people to go through the hoops of maintaining it?
>
> Second, I'm somewhat unhappy about the management of the suspended
> processs. I am wondering if we shouldn't use a semaphore in the
> splObjects for this purpose and link/unlink properly. This has the
> disadvantage that some image-side changes are required but it might be
> worth it for better house-keeping.
>
> Comments welcome!
>   - Andreas
>
> Rob Gayvert wrote:
>
>> Andreas,
>>
>> This looks great. I tried this out with a fresh 3.9-7033 image and
>> latest Win32 VM source, and your example worked as advertised. It also
>> works fine as a replacement for my wxSqueak setjmp/longjmp calls, and
>> removes the need for an extra semaphore on the calling process. Thanks!
>>
>> .. Rob
>>
>>
>> Andreas Raab wrote:
>>
>>> Hi Folks -
>>>
>>> Attached my proposed changes for both, the variable tracking as well
>>> as the callback support. I'll respond in the individual threads about
>>> more specific issues; let's leave this one to discuss the more
>>> "mechanical" issues if there are any. Included files:
>>>
>>> - ExtraGCRoots.cs: The change set for tracking variables in plugins
>>> - Callbacks.cs: The change set for VM callback support
>>> - ExampleCallbacks.cs: An example plugin making use of both of the
>>> above features
>>> - sqVirtualMachine[.h|.c]: The (updated) VM proxy
>>>
>>> If you install all of the above and build a complete VM you should be
>>> able to execute the ExampleCallbackPlugin's exampleCallback and
>>> successfully compute 3+4 using a callback.
>>>
>>> Let me know if you have any problems.
>>>
>>> Cheers,
>>>   - Andreas
>>>
>>>
>>
>>
>>
>



Re: VM (callback+variables) changes

by Andreas Raab :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Rob -

Rob Gayvert wrote:
> My callback usage is intense but of limited variety, so the callback ids
> are not much of a burden. Without an id, there would be no way to check
> whether the callbacks were being exited in the proper order. For some
> cases that might not be important, but it might also result in some
> nasty bugs. How about making it optional by passing a null value?

Well, in this case let's just leave it the way it is. There is nothing
worse than somebody else (who is not using the interface) screwing up
your callback return ;-)

> On the process management question, I'm afraid I don't understand this
> area well enough. Is your concern as aesthetic one, or are there
> performance or correctness issues with your current implementation?

Well, I just kinda dislike the idea of an array holding onto a bunch of
processes without a way about reflecting about them. At some point this
is going to get us into trouble when somebody wonders why the heck this
process doesn't get garbage collected. It would be better if there were
an explicit reference to it somewhere. So I guess it ain't critical (and
requires some image-side support too).

Cheers,
   - Andreas