[Vm-dev] [commit] r2384 - Various reorganizations to support the Newspeak VM.

commits at squeakvm.org commits at squeakvm.org
Tue May 31 20:26:50 UTC 2011


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)")



More information about the Vm-dev mailing list