Author: eliot Date: 2011-05-31 13:26:50 -0700 (Tue, 31 May 2011) New Revision: 2384 Modified: branches/Cog/platforms/Cross/plugins/IA32ABI/dabusiness.h branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abi.h branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abicc.c branches/Cog/platforms/Cross/vm/dispdbg.h branches/Cog/platforms/Cross/vm/sq.h branches/Cog/platforms/Cross/vm/sqMemoryAccess.h branches/Cog/platforms/Cross/vm/sqVirtualMachine.c branches/Cog/platforms/Cross/vm/sqVirtualMachine.h branches/Cog/platforms/Mac OS/vm/osExports.c branches/Cog/platforms/Mac OS/vm/sqMacMain.c branches/Cog/platforms/Mac OS/vm/sqMacTime.c branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c branches/Cog/platforms/Mac OS/vm/sqMacWindowUniversal.c branches/Cog/platforms/Mac OS/vm/sqPlatformSpecific.h branches/Cog/platforms/unix/vm/sqPlatformSpecific.h branches/Cog/platforms/unix/vm/sqUnixMain.c branches/Cog/platforms/win32/vm/sqPlatformSpecific.h branches/Cog/platforms/win32/vm/sqWin32Exports.c branches/Cog/platforms/win32/vm/sqWin32Heartbeat.c branches/Cog/platforms/win32/vm/sqWin32Intel.c branches/Cog/platforms/win32/vm/sqWin32Prefs.c branches/Cog/platforms/win32/vm/sqWin32Window.c Log: Various reorganizations to support the Newspeak VM. Newspeak-specific code included under -DNewspeakVM=1. Minor ones are making available certain command-line args for debugging to the NewspeakVM, niot just the StackVM. Add microsecond clock supprot for the still-millisecond based NewspeakVM. Update the Alien IA32ABI plugin with better Newspeak callback support (serializ- ing callback returns), and make its callouts work in the Cog VMs (where the stack grows downwards). Needs VMMaker.oscog-eem.68 or later. Modified: branches/Cog/platforms/Cross/plugins/IA32ABI/dabusiness.h =================================================================== --- branches/Cog/platforms/Cross/plugins/IA32ABI/dabusiness.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/plugins/IA32ABI/dabusiness.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -2,10 +2,12 @@ * dabusiness.h * * Written by Eliot Miranda 11/07. - * Copyright 2007 Cadence Design Systems. All rights reserved. + * Updated 5/2011 to cope with Cog stack direction. * * Body of the various callIA32XXXReturn functions. * Call a foreign function according to IA32-ish ABI rules. + * N.B. In Cog Stack and Cogit VMs numArgs is negative to access args from + * the downward-growing stack. */ long i, size; sqInt funcAlien, resultMaybeAlien; @@ -14,6 +16,17 @@ char *argstart; #endif +#if STACKVM /* Need to access args downwards from first arg */ + if (numArgs < 0) + for (i = size = 0; --i > numArgs;) { + sqInt arg = argVector[i]; + if (objIsAlien(arg) && sizeField(arg)) + size += moduloPOT(sizeof(long),abs(sizeField(arg))); + else /* assume an integer or pointer. check below. */ + size += sizeof(long); + } + else +#endif /* STACKVM */ for (i = numArgs, size = 0; --i >= 0;) { sqInt arg = argVector[i]; if (objIsAlien(arg) && sizeField(arg)) @@ -42,6 +55,44 @@ # endif #endif +#if STACKVM /* Need to access args downwards from first arg */ + if (numArgs < 0) + for (i = size = 0; --i > numArgs;) { + sqInt arg = argVector[i]; + if (isSmallInt(arg)) { + *(long *)argvec = intVal(arg); + argvec += sizeof(long); + } + else if (objIsAlien(arg)) { + long argByteSize; + + if (!(size = sizeField(arg))) + size = argByteSize = sizeof(void *); + else + argByteSize = abs(size); + memcpy(argvec, startOfDataWithSize(arg,size), argByteSize); + argvec += moduloPOT(sizeof(long), argByteSize); + } + else if (objIsUnsafeAlien(arg)) { + sqInt bitsObj = interpreterProxy->fetchPointerofObject(0,arg); + void *v = interpreterProxy->firstIndexableField(bitsObj); + *(void **)argvec = v; + argvec += sizeof(long); + } + else { + long v = interpreterProxy->signed32BitValueOf(arg); + if (interpreterProxy->failed()) { + interpreterProxy->primitiveFailFor(0); + v = interpreterProxy->positive32BitValueOf(arg); + if (interpreterProxy->failed()) + return PrimErrBadArgument; + } + *(long *)argvec = v; + argvec += sizeof(long); + } + } + else +#endif /* STACKVM */ for (i = 0; i < numArgs; i++) { sqInt arg = argVector[i]; if (isSmallInt(arg)) { @@ -66,8 +117,12 @@ } else { long v = interpreterProxy->signed32BitValueOf(arg); - if (interpreterProxy->failed()) - return PrimErrBadArgument; + if (interpreterProxy->failed()) { + interpreterProxy->primitiveFailFor(0); + v = interpreterProxy->positive32BitValueOf(arg); + if (interpreterProxy->failed()) + return PrimErrBadArgument; + } *(long *)argvec = v; argvec += sizeof(long); } @@ -87,7 +142,7 @@ size = sizeof(void *); memcpy(startOfDataWithSize(resultMaybeAlien,size), &r, - min(abs(size), sizeof(r))); + min((unsigned)abs(size), sizeof(r))); } return PrimNoErr; Modified: branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abi.h =================================================================== --- branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abi.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abi.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -1,10 +1,10 @@ /* * platforms/Cross/plugins/IA32ABI/ia32abi.h * - * Written by Eliot Miranda 11/07. - * Copyright 2007 Cadence Design Systems. All rights reserved. + * Written by Eliot Miranda 11/2007. + * Updated 5/2011 to cope with Cog stack direction. * - * Call foreign functons returning results in either %eax, %edx (Integral) + * Call foreign functions returning results in either %eax, %edx (Integral) * or %f0 (Float, Double). * * The primitive will have signatures of the form @@ -20,10 +20,13 @@ * functionAddress <Alien> primFFICallResult: result <Alien> * with: firstArg <Alien> ... with: lastArg <Alien> * <primitive: 'primCallOutXXX' module: 'IA32ABI'> + * + * N.B. In Cog Stack and Cogit VMs numArgs is negative to access args from + * the downward-growing stack. */ #define SIGNATURE sqInt *argVector/* call args on stack or in array */, \ - int numArgs, /* arg count of function to call */ \ + int numArgs, /* arg count of function to call (*) */ \ int funcOffset, /* stack offset of func Alien */ \ int resultOffset/* stack offset of result Alien */ @@ -32,6 +35,7 @@ extern sqInt callIA32DoubleReturn (SIGNATURE); extern long thunkEntry (void *thunkp, long *stackp); extern void *allocateExecutablePage(long *pagesize); +extern VMCallbackContext *getMostRecentCallbackContext(void); /* Use the most minimal setjmp/longjmp pair available; no signal handling * wanted or necessary. Modified: branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abicc.c =================================================================== --- branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abicc.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/plugins/IA32ABI/ia32abicc.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -3,8 +3,6 @@ * * Support for Call-outs and Call-backs from the Plugin. * Written by Eliot Miranda 11/07. - * Copyright 2007 Cadence Design Systems. All rights reserved. - * */ #if defined(_MSC_VER) || defined(__MINGW32__) @@ -27,6 +25,7 @@ # include <sys/mman.h> /* for mprotect */ #endif +#include <string.h> /* for memcpy et al */ #include <setjmp.h> #include <stdio.h> /* for fprintf(stderr,...) */ @@ -69,7 +68,7 @@ # define setsp(ignored) 0 #endif -#define moduloPOT(m,v) ((v)+(m)-1 & ~((m)-1)) +#define moduloPOT(m,v) (((v)+(m)-1) & ~((m)-1)) #define alignModuloPOT(m,v) ((void *)moduloPOT(m,(unsigned long)(v))) #define objIsAlien(anOop) (interpreterProxy->includesBehaviorThatOf(interpreterProxy->fetchClassOf(anOop), interpreterProxy->classAlien())) @@ -127,6 +126,27 @@ #include "dabusiness.h" } +/* Queueing order for callback returns. To ensure that callback returns occur + * in LIFO order we provide mostRecentCallbackContext which is tested by the return + * primitive primReturnFromContextThrough. In a threaded VM this will have to + * be thread-specific (as yet unimplemented). + */ +#if COGMTVM +# error as yet unimplemented +/* Test if need and allocate a thread-local variable index in + * allocateExecutablePage (low frequency operation). Keep a per-thread + * mostRecentCallbackContext. + */ +#else +static VMCallbackContext *mostRecentCallbackContext = 0; + +VMCallbackContext * +getMostRecentCallbackContext() { return mostRecentCallbackContext; } + +# define getRMCC(t) mostRecentCallbackContext +# define setRMCC(t) (mostRecentCallbackContext = (void *)(t)) +#endif + /* * Entry-point for call-back thunks. Args are thunk address and stack pointer, * where the stack pointer is pointing one word below the return address of the @@ -155,6 +175,7 @@ thunkEntry(void *thunkp, long *stackp) { VMCallbackContext vmcc; + VMCallbackContext *previousCallbackContext; int flags, returnType; if ((flags = interpreterProxy->ownVM(0)) < 0) { @@ -163,15 +184,19 @@ } if (!(returnType = setjmp(vmcc.trampoline))) { + previousCallbackContext = getRMCC(); + setRMCC(&vmcc); vmcc.thunkp = thunkp; vmcc.stackp = stackp + 2; /* skip address of retpc & retpc (thunk) */ vmcc.intregargsp = 0; vmcc.floatregargsp = 0; interpreterProxy->sendInvokeCallbackContext(&vmcc); fprintf(stderr,"Warning; callback failed to invoke\n"); + setRMCC(previousCallbackContext); interpreterProxy->disownVM(flags); return -1; } + setRMCC(previousCallbackContext); interpreterProxy->disownVM(flags); switch (returnType) { Modified: branches/Cog/platforms/Cross/vm/dispdbg.h =================================================================== --- branches/Cog/platforms/Cross/vm/dispdbg.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/vm/dispdbg.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -17,6 +17,15 @@ * various definitions of the sendBreakpointreceiver macro for break-pointing at * specific sends. */ +#if STACKVM +# define warnSendBreak() do { \ + suppressHeartbeatFlag = 1; \ + warning("send breakpoint (heartbeat suppressed)"); \ + } while (0) +#else +# define warnSendBreak() warning("send breakpoint") +#endif + #if PRODUCTION /* default for no send breakpoint. */ # define sendBreakpointreceiver(sel, len, rcvr) 0 @@ -36,22 +45,18 @@ # define sendBreakpointreceiver(sel, len, rcvr) do { \ if ((len) == breakSelectorLength \ && !strncmp((char *)(sel), breakSelector, breakSelectorLength)) { \ - suppressHeartbeatFlag = 1; \ - warning("send breakpoint (heartbeat suppressed)"); \ + warnSendBreak(); \ if (0) sendTrace = 1; \ } \ - if (sendTrace) { \ + if (sendTrace) \ printf("%.*s\n", len, (char *)(sel)); \ - if (0 && !checkHeapIntegrity()) error("object leak"); \ - } \ } while (0) #elif 0 /* breakpoint with byteCount. */ # define sendBreakpointreceiver(sel, len, rcvr) do { \ if ((len) == breakSelectorLength \ && !strncmp((char *)(sel), breakSelector, breakSelectorLength)) { \ - suppressHeartbeatFlag = 1; \ - warning("send breakpoint (heartbeat suppressed)"); \ + warnSendBreak(); \ if (0) sendTrace = 1; \ } \ if (sendTrace) \ @@ -63,15 +68,22 @@ * various definitions of the bytecodeDispatchDebugHook macro for * debugging code at the bytecode dispatch switch. */ +#if STACKVM +# define ValidInstructionPointerCheck() \ + validInstructionPointerinMethodframePointer((usqInt)localIP, GIV(method), localFP) +#else +# define ValidInstructionPointerCheck() \ + validInstructionPointerinMethod((usqInt)localIP, GIV(method)) +#endif + #if PRODUCTION # define bytecodeDispatchDebugHook() 0 -#elif 1 /* check for valid instruction pointer */ +#elif 0 /* check for valid instruction pointer */ # define bytecodeDispatchDebugHook() do { \ - if (!validInstructionPointerinMethodframePointer((usqInt)localIP, GIV(method), localFP)) \ + if (!ValidInstructionPointerCheck()) \ warning("invalidInstructionPointerinMethod"); \ } while (0) - #elif 0 /* check for valid stack-related pointers */ # define DEBUG_DISABLE_HEARTBEAT 1 # define bytecodeDispatchDebugHook() do { \ @@ -104,18 +116,24 @@ # define bytecodeDispatchDebugHook() do { \ if (++GIV(byteCount) == 175779UL) \ warning("break byteCount reached\n"); \ - if (!validInstructionPointerinMethodframePointer((usqInt)localIP, GIV(method), localFP)) \ + if (!ValidInstructionPointerCheck()) \ warning("invalidInstructionPointerinMethod"); \ } while (0) #elif 0 /* maintain byteCount & check for valid instruction pointer */ -# define bytecodeDispatchDebugHook() do { \ - printf("%ld: %x %d\n", ++GIV(byteCount), localIP-GIV(method)-3, currentBytecode); \ - if (!validInstructionPointerinMethodframePointer((usqInt)localIP, GIV(method), localFP)) \ +#define bytecodeDispatchDebugHook() do { \ + printf("%ld: %d %x(%d)\n", ++GIV(byteCount), localIP-GIV(method)-3, currentBytecode, currentBytecode); \ + if (!ValidInstructionPointerCheck()) \ warning("invalidInstructionPointerinMethod"); \ - if (sendTrace) printCallStack(); \ + if (sendTrace > 1) printContext(GIV(activeContext)); \ } while (0) - +#elif 0 /* maintain byteCount & check for valid instruction pointer */ +#define bytecodeDispatchDebugHook() do { \ + printf("%ld: %d %x(%d)\n", ++GIV(byteCount), localIP-GIV(method)-3, currentBytecode, currentBytecode); \ + if (!ValidInstructionPointerCheck()) \ + warning("invalidInstructionPointerinMethod"); \ + if (sendTrace > 1) printCallStack(); \ + } while (0) #elif 0 /* print current frame & instruction pointer on every bytecode. */ # define bytecodeDispatchDebugHook() do { \ printFrameWithSP(localFP,localSP); \ @@ -129,4 +147,8 @@ printf("%d %x\n", localIP - GIV(method) - 3, currentBytecode); \ } \ } while (0) +#elif 0 +# define bytecodeDispatchDebugHook() printContextWithSP(activeContext,localSP) +#else +# define bytecodeDispatchDebugHook() 0 #endif Modified: branches/Cog/platforms/Cross/vm/sq.h =================================================================== --- branches/Cog/platforms/Cross/vm/sq.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/vm/sq.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -212,16 +212,10 @@ sqInt ioHasDisplayDepth(sqInt depth); sqInt ioSetDisplayMode(sqInt width, sqInt height, sqInt depth, sqInt fullscreenFlag); -#if STACKVM +#if STACKVM || NewspeakVM /* thread subsystem support for e.g. sqExternalSemaphores.c */ void ioInitThreads(); -/* Event polling via periodic heartbeat thread. */ -void ioInitHeartbeat(void); -int ioHeartbeatMilliseconds(void); -void ioSetHeartbeatMilliseconds(int); -unsigned long ioHeartbeatFrequency(int); - /* Management of the external semaphore table (max size set at startup) */ #if !defined(INITIAL_EXT_SEM_TABLE_SIZE) # define INITIAL_EXT_SEM_TABLE_SIZE 256 @@ -240,7 +234,16 @@ extern sqOSThread ioVMThread; # define getVMOSThread() ioVMThread # endif +#endif /* STACKVM || NewspeakVM */ + +#if STACKVM +/* Event polling via periodic heartbeat thread. */ +void ioInitHeartbeat(void); +int ioHeartbeatMilliseconds(void); +void ioSetHeartbeatMilliseconds(int); +unsigned long ioHeartbeatFrequency(int); #endif /* STACKVM */ + #if COGMTVM #define THRLOGSZ 256 extern int thrlogidx; Modified: branches/Cog/platforms/Cross/vm/sqMemoryAccess.h =================================================================== --- branches/Cog/platforms/Cross/vm/sqMemoryAccess.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/vm/sqMemoryAccess.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -133,10 +133,27 @@ #define long32At intAt #define long32Atput intAtput -/* platform-dependent float conversion macros */ -/* Note: Second argument must be a variable name, not an expression! */ -#if defined(DOUBLE_WORD_ALIGNMENT) +/* platform-dependent float conversion macros. + * Note: Second argument must be a variable name, not an expression! + * Pre-Cog systems stored floats in Mac PowerPC big-endian format. + * BigEndianFloats selects this behaviour for backwards-compatibility. + * RISC systems typically insist on double-word alignment of double-words, but + * the heap is only word-aligned. DOUBLE_WORD_ALIGNMENT selects word access. + */ +#if BigEndianFloats && !VMBIGENDIAN /* this is to allow strict aliasing assumption in the optimizer */ +typedef union { double d; int i[sizeof(double) / sizeof(int)]; } _swapper; +/* word-based copy with swapping for non-PowerPC order */ +# define storeFloatAtPointerfrom(intPointerToFloat, doubleVar) do { \ + *((int *)(intPointerToFloat) + 0) = ((_swapper *)(&doubleVar))->i[1]; \ + *((int *)(intPointerToFloat) + 1) = ((_swapper *)(&doubleVar))->i[0]; \ + } while (0) +# define fetchFloatAtPointerinto(intPointerToFloat, doubleVar) do { \ + ((_swapper *)(&doubleVar))->i[1] = *((int *)(intPointerToFloat) + 0); \ + ((_swapper *)(&doubleVar))->i[0] = *((int *)(intPointerToFloat) + 1); \ + } while (0) +# elif defined(DOUBLE_WORD_ALIGNMENT) +/* this is to allow strict aliasing assumption in the optimizer */ typedef union { double d; int i[sizeof(double) / sizeof(int)]; } _aligner; /* word-based copy for machines with alignment restrictions */ # define storeFloatAtPointerfrom(intPointerToFloat, doubleVar) do { \ @@ -147,11 +164,11 @@ ((_aligner *)(&doubleVar))->i[0] = *((int *)(intPointerToFloat) + 0); \ ((_aligner *)(&doubleVar))->i[1] = *((int *)(intPointerToFloat) + 1); \ } while (0) -#else /* !DOUBLE_WORD_ALIGNMENT */ +#else /* !(BigEndianFloats && !VMBIGENDIAN) && !DOUBLE_WORD_ALIGNMENT */ /* for machines that allow doubles to be on any word boundary */ # define storeFloatAtPointerfrom(i, doubleVar) (*((double *) (i)) = (doubleVar)) # define fetchFloatAtPointerinto(i, doubleVar) ((doubleVar) = *((double *) (i))) -#endif +#endif /* !(BigEndianFloats && !VMBIGENDIAN) && !DOUBLE_WORD_ALIGNMENT */ #define storeFloatAtfrom(i, doubleVar) storeFloatAtPointerfrom(pointerForOop(i), doubleVar) #define fetchFloatAtinto(i, doubleVar) fetchFloatAtPointerinto(pointerForOop(i), doubleVar) @@ -161,14 +178,11 @@ #define fetchSingleFloatAtinto(i, floatVar) fetchSingleFloatAtPointerinto(pointerForOop(i), floatVar) -/* This doesn't belong here, but neither do 'self flag: ...'s belong in the image. */ +/* This doesn't belong here, but neither do 'self flag: ...'s belong in the + image. We use a macro, not an inline function; we need no trace of flag. + */ +#define flag(foo) 0 -#ifdef _MSC_VER -static void flag(char *ignored) {} -#else -static inline void flag(char *ignored) {} -#endif - /* heap debugging facilities in sqHeapMap.c */ extern void clearHeapMap(void); extern int heapMapAtWord(void *wordPointer); Modified: branches/Cog/platforms/Cross/vm/sqVirtualMachine.c =================================================================== --- branches/Cog/platforms/Cross/vm/sqVirtualMachine.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/vm/sqVirtualMachine.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -173,8 +173,10 @@ sqInt isInMemory(sqInt address); sqInt classAlien(void); /* Alien FFI */ sqInt classUnsafeAlien(void); /* Alien FFI */ +sqInt getStackPointer(void); /* Newsqueak FFI */ void *startOfAlienData(sqInt); usqInt sizeOfAlienData(sqInt); +sqInt signalNoResume(sqInt); sqInt getStackPointer(void); /* Alien FFI */ sqInt sendInvokeCallbackStackRegistersJmpbuf(sqInt thunkPtrAsInt, sqInt stackPtrAsInt, sqInt regsPtrAsInt, sqInt jmpBufPtrAsInt); /* Alien FFI */ sqInt reestablishContextPriorToCallback(sqInt callbackContext); /* Alien FFI */ @@ -186,8 +188,15 @@ /* Proxy declarations for v1.8 */ +#if NewspeakVM +static sqInt +callbackEnter(sqInt *callbackID) { return 0; } +static sqInt +callbackLeave(sqInt *callbackID) { return 0; } +#else sqInt callbackEnter(sqInt *callbackID); sqInt callbackLeave(sqInt callbackID); +#endif sqInt addGCRoot(sqInt *varLoc); sqInt removeGCRoot(sqInt *varLoc); @@ -420,7 +429,7 @@ VM->sendInvokeCallbackStackRegistersJmpbuf = sendInvokeCallbackStackRegistersJmpbuf; VM->reestablishContextPriorToCallback = reestablishContextPriorToCallback; # if ALIEN_FFI - VM->getStackPointer = 0; + VM->getStackPointer = (sqInt *(*)(void))getStackPointer; # endif # if IMMUTABILITY VM->internalIsImmutable = internalIsImmutable; @@ -465,6 +474,7 @@ VM->cStringOrNullFor = cStringOrNullFor; VM->startOfAlienData = startOfAlienData; VM->sizeOfAlienData = sizeOfAlienData; + VM->signalNoResume = signalNoResume; #endif return VM; Modified: branches/Cog/platforms/Cross/vm/sqVirtualMachine.h =================================================================== --- branches/Cog/platforms/Cross/vm/sqVirtualMachine.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Cross/vm/sqVirtualMachine.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -311,6 +311,7 @@ char *(*cStringOrNullFor)(sqInt); void *(*startOfAlienData)(sqInt); usqInt (*sizeOfAlienData)(sqInt); + sqInt (*signalNoResume)(sqInt); #endif } VirtualMachine; Modified: branches/Cog/platforms/Mac OS/vm/osExports.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/osExports.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Mac OS/vm/osExports.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -14,7 +14,9 @@ #include <stdio.h> #include "sqMacUIEvents.h" -#include "SerialPlugin.h" +#if !NewspeakVM +# include "SerialPlugin.h" +#endif /* duh ... this is ugly */ @@ -26,9 +28,11 @@ void setMessageHook(eventMessageHook theHook); void setPostMessageHook(eventMessageHook theHook); char * GetAttributeString(int id); +#if !NewspeakVM int serialPortSetControl(int portNum,int control, char *data); int serialPortIsOpen(int portNum); int serialPortNames(int portNum, char *portName, char *inName, char *outName); +#endif Boolean IsKeyDown(void); int primitivePluginBrowserReady(void); #ifdef ENABLE_URL_FETCH @@ -47,6 +51,7 @@ XFN(setPostMessageHook) XFN(GetAttributeString) XFN(recordDragDropEvent) +#if !NewspeakVM XFN(serialPortSetControl) XFN(serialPortIsOpen) XFN(serialPortClose) @@ -55,6 +60,7 @@ XFN(serialPortOpen) XFN(serialPortReadInto) XFN(serialPortWriteFrom) +#endif XFN(IsKeyDown) XFN(getUIToLock) /* Plugin support primitives Modified: branches/Cog/platforms/Mac OS/vm/sqMacMain.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacMain.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Mac OS/vm/sqMacMain.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -163,7 +163,15 @@ printf("C stack backtrace:\n"); fflush(stdout); /* backtrace_symbols_fd uses unbuffered i/o */ depth = backtrace(addrs, BACKTRACE_DEPTH); +# if 0 /* Mac OS's backtrace_symbols_fd prints NULL byte droppings each line */ backtrace_symbols_fd(addrs, depth, fileno(stdout)); +# else + { int i; char **strings; + strings = backtrace_symbols(addrs, depth); + for (i = 0; i < depth; i++) + printf("%s\n", strings[i]); + } +# endif #endif if (ioOSThreadsEqual(ioCurrentOSThread(),getVMOSThread())) { @@ -211,8 +219,10 @@ } else printf("\nCan't dump Smalltalk stack(s). Not in VM thread\n"); +#if STACKVM printf("\nMost recent primitives\n"); dumpPrimTraceLog(); +#endif fflush(stdout); } @@ -362,15 +372,6 @@ SetVMPathFromApplicationDirectory(); - { - // Change working directory, this works under os-x, previous logic worked pre os-x 10.4 - - char target[4097],temp[4097]; - getVMPathWithEncoding(target,gCurrentVMEncoding); - sqFilenameFromStringOpen(temp,(sqInt) target, strlen(target)); - chdir(temp); - } - /* install apple event handlers and wait for open event */ InstallAppleEventHandlers(); while (ShortImageNameIsEmpty()) { Modified: branches/Cog/platforms/Mac OS/vm/sqMacTime.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacTime.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Mac OS/vm/sqMacTime.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -55,14 +55,46 @@ ioInitTime(); } #else /* STACKVM */ +static TMTask gTMTask; +static unsigned int lowResMSecs= 0; -void SetUpTimers(void) +#define LOW_RES_TICK_MSECS 16 +#define HIGH_RES_TICK_MSECS 2 +#define COUNTER_LIMIT LOW_RES_TICK_MSECS/HIGH_RES_TICK_MSECS + +static pascal void +MyTimerProc(QElemPtr time) { + lowResMSecs = ioMicroMSecs(); + PrimeTime((QElemPtr)time, LOW_RES_TICK_MSECS); + return; +} + +void +SetUpTimers(void) +{ /* set up the micro/millisecond clock */ gettimeofday(&startUpTime, 0); + + gTMTask.tmAddr = NewTimerUPP((TimerProcPtr) MyTimerProc); + gTMTask.tmCount = 0; + gTMTask.tmWakeUp = 0; + gTMTask.tmReserved = 0; + + InsXTime((QElemPtr)(&gTMTask.qLink)); + PrimeTime((QElemPtr)&gTMTask.qLink,LOW_RES_TICK_MSECS); } -int ioMicroMSecs(void) +#if 1 +int +ioLowResMSecs(void) { return lowResMSecs; } +#else +int +ioLowResMSecs(void) { return ioMicroMSecs(); } +#endif + +int +ioMicroMSecs(void) { struct timeval now; gettimeofday(&now, 0); @@ -74,7 +106,8 @@ return (now.tv_usec / 1000 + now.tv_sec * 1000); } -int ioSeconds(void) { +int +ioSeconds(void) { time_t unixTime; unixTime = time(0); @@ -112,6 +145,34 @@ int ioMSecs() { return ioMicroMSecs(); } + +#define SecondsFrom1901To1970 2177452800ULL +#define MicrosecondsFrom1901To1970 2177452800000000ULL + +#define MicrosecondsPerSecond 1000000ULL +#define MillisecondsPerSecond 1000ULL + +#define MicrosecondsPerMillisecond 1000ULL +/* Compute the current VM time basis, the number of microseconds from 1901. */ + +static unsigned long long +currentUTCMicroseconds() +{ + struct timeval utcNow; + + gettimeofday(&utcNow,0); + return ((utcNow.tv_sec * MicrosecondsPerSecond) + utcNow.tv_usec) + + MicrosecondsFrom1901To1970; +} + +usqLong +ioUTCMicroseconds() { return currentUTCMicroseconds(); } + +/* This is an expensive interface for use by profiling code that wants the time + * now rather than as of the last heartbeat. + */ +usqLong +ioUTCMicrosecondsNow() { return currentUTCMicroseconds(); } #endif /* STACKVM */ time_t convertToSqueakTime(time_t unixTime) Modified: branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Mac OS/vm/sqMacUIEventsUniversal.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -1547,3 +1547,11 @@ recordWindowEventCarbon(WindowEventClose,0, 0, 0, 0, 1 /* main ST window index */ ); } + +#if NewspeakVM +/* For now this is only here to make the linker happy; + the function really does something interesting only on Windows. + */ +void +ioDrainEventQueue() {} +#endif /* NewspeakVM */ Modified: branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -152,16 +152,22 @@ if (!strcmp(argv[0], "-help")) { usage(); return 1; } - else if (!strncmp(argv[0], "-psn_", 5)) { - return 1; } - else if (!strcmp(argv[0], "-headless")) { - gSqueakHeadless = true; return 1; } - else if (!strcmp(argv[0], "-headfull")) { - gSqueakHeadless = false; return 1; } + else if (!strncmp(argv[0], "-psn_", 5)) { return 1; } + else if (!strcmp(argv[0], "-headless")) { gSqueakHeadless = true; return 1; } + else if (!strcmp(argv[0], "-headfull")) { gSqueakHeadless = false; return 1; } +#if STACKVM && !COGVM || NewspeakVM + else if (!strcmp(argv[0], "-sendtrace")) { extern sqInt sendTrace; sendTrace = 1; return 1; } +#endif else if (argc > 1) { if (!strcmp(argv[0], "-memory")) { gMaxHeapSize = strtobkm(argv[1]); return 2; } +#if STACKVM || NewspeakVM + else if (!strcmp(argv[0], "-breaksel")) { + extern void setBreakSelector(char *); + setBreakSelector(argv[1]); + return 2; } +#endif #if STACKVM else if (!strcmp(argv[0], "-eden")) { extern sqInt desiredEdenBytes; @@ -175,10 +181,6 @@ extern sqInt desiredNumStackPages; desiredNumStackPages = atoi(argv[1]); return 2; } - else if (!strcmp(argv[0], "-breaksel")) { - extern void setBreakSelector(char *); - setBreakSelector(argv[1]); - return 2; } else if (!strcmp(argv[0], "-noheartbeat")) { extern sqInt suppressHeartbeatFlag; suppressHeartbeatFlag = 1; @@ -258,10 +260,13 @@ printf("\nCommon <option>s:\n"); printf(" -help print this help message, then exit\n"); printf(" -memory <size>[mk] use fixed heap size (added to image size)\n"); +#if STACKVM || NewspeakVM + printf(" -breaksel selector set breakpoint on send of selector\n"); +#endif #if STACKVM printf(" -eden <size>[mk] set eden memory to bytes\n"); + printf(" -leakcheck num check for leaks in the heap\n"); printf(" -stackpages num use n stack pages\n"); - printf(" -breaksel selector set breakpoint on send of selector\n"); #endif #if COGVM printf(" -codesize <size>[mk] set machine code memory to bytes\n"); Modified: branches/Cog/platforms/Mac OS/vm/sqMacWindowUniversal.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacWindowUniversal.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Mac OS/vm/sqMacWindowUniversal.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -234,15 +234,13 @@ if (gSqueakHeadless && !browserActiveAndDrawingContextOk()) return 0; giLocker = interpreterProxy->ioLoadFunctionFrom("getUIToLock", ""); if (giLocker != 0) { - sqInt *foo; - foo = malloc(sizeof(sqInt)*4); + sqInt foo[4]; foo[0] = 1; foo[1] = (sqInt) ioSetFullScreenActual; foo[2] = fullScreen; foo[3] = 0; ((sqInt (*) (void *)) giLocker)(foo); return_value = interpreterProxy->positive32BitIntegerFor(foo[3]); - free(foo); } return return_value; } @@ -368,14 +366,12 @@ if (gSqueakHeadless && browserActiveAndDrawingContextOkAndNOTInFullScreenMode()) return; giLocker = interpreterProxy->ioLoadFunctionFrom("getUIToLock", ""); if (giLocker != 0) { - sqInt *foo; - foo = malloc(sizeof(sqInt)*4); + sqInt foo[4]; foo[0] = 1; foo[1] = (sqInt) sqShowWindowActual; foo[2] = windowIndex; foo[3] = 0; ((sqInt (*) (void *)) giLocker)(foo); - free(foo); } } Modified: branches/Cog/platforms/Mac OS/vm/sqPlatformSpecific.h =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqPlatformSpecific.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/Mac OS/vm/sqPlatformSpecific.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -131,7 +131,7 @@ #define warnPrintf printf /* Thread support for thread-safe signalSemaphoreWithIndex and/or the COGMTVM */ -#if STACKVM +#if STACKVM || NewspeakVM # define sqLowLevelYield() sched_yield() # include <pthread.h> # define sqOSThread pthread_t @@ -157,7 +157,7 @@ # define ioTransferTimeslice() sched_yield() # define ioMilliSleep(ms) usleep((ms) * 1000) # endif /* COGMTVM */ -#endif /* STACKVM */ +#endif /* STACKVM || NewspeakVM */ #ifdef BROWSERPLUGIN # undef insufficientMemorySpecifiedError @@ -179,7 +179,9 @@ #ifdef __GNUC__ # undef EXPORT # define EXPORT(returnType) __attribute__((visibility("default"))) returnType -# define VM_LABEL(foo) asm("\n.globl L" #foo "\nL" #foo ":") +# if !defined(VM_LABEL) +# define VM_LABEL(foo) asm("\n.globl L" #foo "\nL" #foo ":") +# endif #endif #if !defined(VM_LABEL) || COGVM Modified: branches/Cog/platforms/unix/vm/sqPlatformSpecific.h =================================================================== --- branches/Cog/platforms/unix/vm/sqPlatformSpecific.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/unix/vm/sqPlatformSpecific.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -60,7 +60,7 @@ #define warnPrintf printf /* Thread support for thread-safe signalSemaphoreWithIndex and/or the COGMTVM */ -#if STACKVM +#if STACKVM || NewspeakVM # define sqLowLevelYield() sched_yield() /* linux's sched.h defines clone that conflicts with the interpreter's */ # define clone NameSpacePollutant @@ -89,7 +89,7 @@ # define ioTransferTimeslice() sched_yield() # define ioMilliSleep(ms) usleep((ms) * 1000) # endif /* COGMTVM */ -#endif /* STACKVM */ +#endif /* STACKVM || NewspeakVM */ #include <sys/types.h> @@ -114,7 +114,9 @@ #define fseek fseeko #if defined(__GNUC__) -# define VM_LABEL(foo) asm("\n.globl L" #foo "\nL" #foo ":") +# if !defined(VM_LABEL) +# define VM_LABEL(foo) asm("\n.globl L" #foo "\nL" #foo ":") +# endif #else # if HAVE_ALLOCA_H # include <alloca.h> Modified: branches/Cog/platforms/unix/vm/sqUnixMain.c =================================================================== --- branches/Cog/platforms/unix/vm/sqUnixMain.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/unix/vm/sqUnixMain.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -576,8 +576,10 @@ dataSize= preSnapshot(); writeImageFile(dataSize); +#if STACKVM printf("\nMost recent primitives\n"); dumpPrimTraceLog(); +#endif fprintf(stderr, "\n"); printCallStack(); fprintf(stderr, "\nTo recover valuable content from this image:\n"); @@ -809,8 +811,10 @@ } else printf("\nCan't dump Smalltalk stack(s). Not in VM thread\n"); +#if STACKVM printf("\nMost recent primitives\n"); dumpPrimTraceLog(); +#endif fflush(stdout); } @@ -1261,6 +1265,15 @@ else if (!strcmp(argv[0], "-plugins")) { squeakPlugins= strdup(argv[1]); return 2; } else if (!strcmp(argv[0], "-encoding")) { setEncoding(&sqTextEncoding, argv[1]); return 2; } else if (!strcmp(argv[0], "-pathenc")) { setEncoding(&uxPathEncoding, argv[1]); return 2; } +#if STACKVM && !COGVM || NewspeakVM + else if (!strcmp(argv[0], "-sendtrace")) { extern sqInt sendTrace; sendTrace = 1; return 1; } +#endif +#if STACKVM || NewspeakVM + else if (!strcmp(argv[0], "-breaksel")) { + extern void setBreakSelector(char *); + setBreakSelector(argv[1]); + return 2; } +#endif #if STACKVM else if (!strcmp(argv[0], "-eden")) { extern sqInt desiredEdenBytes; @@ -1274,10 +1287,6 @@ extern sqInt desiredNumStackPages; desiredNumStackPages = atoi(argv[1]); return 2; } - else if (!strcmp(argv[0], "-breaksel")) { - extern void setBreakSelector(char *); - setBreakSelector(argv[1]); - return 2; } else if (!strcmp(argv[0], "-noheartbeat")) { extern sqInt suppressHeartbeatFlag; suppressHeartbeatFlag = 1; @@ -1347,8 +1356,12 @@ printf(" -help print this help message, then exit\n"); printf(" -memory <size>[mk] use fixed heap size (added to image size)\n"); printf(" -mmap <size>[mk] limit dynamic heap size (default: %dm)\n", DefaultMmapSize); +#if STACKVM || NewspeakVM + printf(" -breaksel selector set breakpoint on send of selector\n"); +#endif #if STACKVM printf(" -eden <size>[mk] use given eden size\n"); + printf(" -leakcheck num check for leaks in the heap\n"); printf(" -stackpages <num> use given number of stack pages\n"); #endif printf(" -noevents disable event-driven input support\n"); Modified: branches/Cog/platforms/win32/vm/sqPlatformSpecific.h =================================================================== --- branches/Cog/platforms/win32/vm/sqPlatformSpecific.h 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/win32/vm/sqPlatformSpecific.h 2011-05-31 20:26:50 UTC (rev 2384) @@ -84,7 +84,7 @@ #endif /* Thread support for thread-safe signalSemaphoreWithIndex and/or the COGMTVM */ -#if STACKVM +#if STACKVM || NewspeakVM # define sqLowLevelYield() Sleep(0) /* these are used both in the STACKVM & the COGMTVM */ # define sqOSThread void * @@ -102,10 +102,12 @@ # define ioTransferTimeslice() Sleep(0) # define ioMilliSleep(ms) Sleep(ms) # endif /* COGMTVM */ -#endif /* STACKVM */ +#endif /* STACKVM || NewspeakVM */ #if defined(__GNUC__) -# define VM_LABEL(foo) asm("\n.globl L" #foo "\nL" #foo ":") +# if !defined(VM_LABEL) +# define VM_LABEL(foo) asm("\n.globl L" #foo "\nL" #foo ":") +# endif #endif #if !defined(VM_LABEL) || COGVM # undef VM_LABEL Modified: branches/Cog/platforms/win32/vm/sqWin32Exports.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Exports.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/win32/vm/sqWin32Exports.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -1,8 +1,11 @@ #include <stdio.h> +#include "interp.h" +#if !NewspeakVM int win32JoystickDebugInfo(void); int win32JoystickDebugPrintRawValues(void); int win32JoystickDebugPrintAlternativeValues(void); +#endif int win32DebugPrintSocketState(void); int primitivePluginBrowserReady(void); int primitivePluginRequestURLStream(void); @@ -18,9 +21,11 @@ extern int fUseOpenGL; void *os_exports[][3] = { +#if !NewspeakVM {"","win32JoystickDebugInfo", win32JoystickDebugInfo}, {"","win32JoystickDebugPrintRawValues", win32JoystickDebugPrintRawValues}, {"","win32JoystickDebugPrintAlternativeValues", win32JoystickDebugPrintAlternativeValues}, +#endif {"","win32DebugPrintSocketState", win32DebugPrintSocketState}, {"","primitivePluginBrowserReady", primitivePluginBrowserReady}, {"","primitivePluginRequestURLStream", primitivePluginRequestURLStream}, Modified: branches/Cog/platforms/win32/vm/sqWin32Heartbeat.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Heartbeat.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/win32/vm/sqWin32Heartbeat.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -401,7 +401,7 @@ if(timeGetDevCaps(&tCaps,sizeof(tCaps)) != 0) return; dwTimerPeriod = max(tCaps.wPeriodMin,beatMilliseconds); - if(timeBeginPeriod(dwTimerPeriod) != 0) + if (timeBeginPeriod(dwTimerPeriod) != 0) return; timerID = timeSetEvent( dwTimerPeriod, 0, Modified: branches/Cog/platforms/win32/vm/sqWin32Intel.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Intel.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/win32/vm/sqWin32Intel.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -796,6 +796,7 @@ fprintf(optionalFile,"\nCan't dump Smalltalk stack. Not in VM thread\n"); } +#if STACKVM static void dumpPrimTrace(FILE *optionalFile) { @@ -814,6 +815,9 @@ printf("\n"); } } +#else +# define dumpPrimTrace(f) 0 +#endif void printCommonCrashDumpInfo(FILE *f) { @@ -1145,12 +1149,17 @@ /****************************************************************************/ /* sqMain */ /****************************************************************************/ +#if STACKVM && !COGVM || NewspeakVM +extern sqInt sendTrace; +#endif +#if STACKVM || NewspeakVM +extern sqInt checkForLeaks; +extern void setBreakSelector(char *); +#endif /* STACKVM || NewspeakVM */ #if STACKVM extern sqInt desiredNumStackPages; extern sqInt desiredEdenBytes; extern sqInt suppressHeartbeatFlag; -extern sqInt checkForLeaks; -extern void setBreakSelector(char *); #endif /* STACKVM */ #if COGVM extern sqInt desiredCogCodeSize; @@ -1167,12 +1176,17 @@ { ARG_FLAG, &fHeadlessImage, "-headless" }, /* do we run headless? */ { ARG_STRING, &logName, "-log:" }, /* VM log file */ { ARG_UINT, &dwMemorySize, "-memory:" }, /* megabyte of memory to use */ +#if STACKVM && !COGVM || NewspeakVM + { ARG_FLAG, &sendTrace, "-sendtrace"}, +#endif +#if STACKVM || NewspeakVM + { ARG_STRING_FUNC, setBreakSelector, "-breaksel:"}, /* break-point selector string */ +#endif /* STACKVM || NewspeakVM */ #if STACKVM + { ARG_UINT, &checkForLeaks, "-leakcheck:"}, /* leak check on GC */ { ARG_UINT, &desiredEdenBytes, "-eden:" }, /* bytes of eden to use */ { ARG_UINT, &desiredNumStackPages, "-stackpages:"}, /* n stack pages to use */ - { ARG_UINT, &checkForLeaks, "-leakcheck:"}, /* leak check on GC */ { ARG_FLAG, &suppressHeartbeatFlag, "-noheartbeat"}, /* no heartbeat for dbg */ - { ARG_STRING_FUNC, setBreakSelector, "-breaksel:"}, /* break-point selector string */ #endif /* STACKVM */ #if COGVM { ARG_UINT, &desiredCogCodeSize, "-codesize:"}, /* machine code memory to use */ Modified: branches/Cog/platforms/win32/vm/sqWin32Prefs.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Prefs.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/win32/vm/sqWin32Prefs.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -286,7 +286,9 @@ } void CreatePrefsMenu(void) { +#if STACKVM extern sqInt recordPrimTraceFunc(); +#endif HMENU hMenu,pMenu; vmPrefsMenu = pMenu = CreatePopupMenu(); @@ -363,9 +365,11 @@ TEXT("Dump call stack")); AppendMenu(hMenu, MF_STRING | MF_UNCHECKED, ID_PRINTALLSTACKS, TEXT("Dump all processes")); +#if STACKVM if (recordPrimTraceFunc()) AppendMenu(hMenu, MF_STRING | MF_UNCHECKED, ID_DUMPPRIMLOG, TEXT("Dump recent primitives")); +#endif AppendMenu(pMenu, MF_STRING | MF_POPUP, (int)hMenu, TEXT("Debug Options")); } @@ -455,11 +459,13 @@ printf("Printing all processes:\n"); printAllStacks(); break; +#if STACKVM case ID_DUMPPRIMLOG: { extern void dumpPrimTraceLog(void); printf("Printing recent primitives:\n"); dumpPrimTraceLog(); break; } +#endif case ID_PRIORITYBOOST: fPriorityBoost = !fPriorityBoost; SetPriorityBoost(); Modified: branches/Cog/platforms/win32/vm/sqWin32Window.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Window.c 2011-04-28 01:16:17 UTC (rev 2383) +++ branches/Cog/platforms/win32/vm/sqWin32Window.c 2011-05-31 20:26:50 UTC (rev 2384) @@ -1539,6 +1539,9 @@ if(fRunService && !fWindows95) return 1; +#if NewspeakVM + return ioDrainEventQueue(); +#else /* WinCE doesn't retrieve WM_PAINTs from the queue with PeekMessage, so we won't get anything painted unless we use GetMessage() if there is a dirty rect. */ @@ -1566,8 +1569,73 @@ } lastMessage = NULL; return 1; +#endif } +#if NewspeakVM +sqInt +ioDrainEventQueue(void) +{ static MSG msg; + POINT mousePt; + + /* + * Callback support; ensure ioProcessEvents is non-reentrant to prevent + * callbacks being delivered during other earlier callbacks. + */ + + if(fRunService && !fWindows95) return 1; + + /* WinCE doesn't retrieve WM_PAINTs from the queue with PeekMessage, + so we won't get anything painted unless we use GetMessage() if there + is a dirty rect. */ + lastMessage = &msg; + while(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) + { + GetMessage(&msg,NULL,0,0); +#ifndef NO_PLUGIN_SUPPORT + if(msg.hwnd == NULL) { + pluginHandleEvent(&msg); + } else +#endif + if(msg.hwnd != stWindow) { + /* Messages not sent to Squeak window */ + if(msg.hwnd != consoleWindow && GetParent(msg.hwnd) == stWindow) { + /* This message has been sent to a plugin window */ + /* Selectively pass up certain events to the parent's level */ + switch (msg.message) { + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MOUSEMOVE: + mousePt.x = LOWORD(msg.lParam); + mousePt.y = HIWORD(msg.lParam); + MapWindowPoints(msg.hwnd, stWindow, &mousePt, 1); + PostMessage(stWindow, msg.message, msg.wParam, MAKELONG(mousePt.x,mousePt.y)); + } + } + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + +#ifndef NO_DIRECTINPUT + /* any buffered mouse input which hasn't been processed is obsolete */ + DumpBufferedMouseTrail(); +#endif + + /* If we're running in a browser check if the browser's still there */ + if(fBrowserMode && browserWindow) { + if(!IsWindow(browserWindow)) ioExit(); + } + lastMessage = NULL; + return 1; +} +#endif /* NewspeakVM */ + + /* returns the size of the Squeak window */ int ioScreenSize(void) { @@ -3106,12 +3174,14 @@ TEXT("\n\t-headless \t\t(force Squeak to run headless)") TEXT("\n\t-log: LogFile \t\t(use LogFile for VM messages)") TEXT("\n\t-memory: megaByte \t(set memory to megaByte MB)") +#if STACKVM || NewspeakVM + TEXT("\n\t-breaksel: string \t(set breakSelector to sel for debug)") +#endif /* STACKVM || NewspeakVM */ #if STACKVM + TEXT("\n\t-leakcheck: n \t(leak check on GC (1=full,2=incr,3=both))") TEXT("\n\t-eden: bytes \t(set eden memory size to bytes)") TEXT("\n\t-stackpages: n \t(use n stack pages)") - TEXT("\n\t-leakcheck: n \t(leak check on GC (1=full,2=incr,3=both))") TEXT("\n\t-noheartbeat \t(no heartbeat for debug)") - TEXT("\n\t-breaksel: string \t(set breakSelector to sel for debug)") #endif /* STACKVM */ #if COGVM TEXT("\n\t-codesize: bytes \t(set machine-code memory size to bytes)") |
Hi Eliot, I just pulled the latest code and when compiling I get: In function `sqGetInterpreterProxy': /home/dgraham/Cog/platforms/Cross/vm/sqVirtualMachine.c:477: undefined reference to `signalNoResume' I did a quick search and am guessing that this should be defined in the src/vm files, but didn't see anything? thanks, David |
Hi David, as the check-in says you need to use VMMaker.oscog-eem.68 to get the right sources. I've yet to finish that check-in so the build is broken for the moment. I shoudl fix it all tomorrow. In the interim generate your own sources from the VMMaker package. Sorry. Eliot On Tue, May 31, 2011 at 7:17 PM, David Graham <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |