// execute.h -- platform-independent execution machinery
//
// Author: Ian.Piumarta@inria.fr
//
// Last edited: Thu Feb 25 18:58:23 1999 by piumarta (Ian Piumarta) on pingu
		     
#ifndef _execute_h_
#define _execute_h_

///
/// EXECUTION STATE
///


extern int contextCacheSize;

extern CachedContext
  *contextCache,
  *lowestCachedContext,
  *activeCachedContext,
  *highestCachedContext;

extern oop *stackCache;
extern oop *temporaryPointer;

extern bool activated;

extern Context *topStableContext;

extern TranslatedMethod *translatedMethod;

extern oop returnResult;
extern Class *receiverClass;


///
/// STACK MANIPULATION
///


#define	areIntegerObjects(A,B)	((((int)(A)) & ((int)(B)) & 1) != 0)
		     
#define	push(object)		(*++stackPointer= (object))
#define	drop(nItems)		(stackPointer-= (nItems))
#define	pop()			(*stackPointer--)
#define	unPop(nItems)		(stackPointer+= (nItems))
#define	stackTop()		(*stackPointer)
#define	stackValue(index)	(stackPointer[-(index)])
		     
#define	drop1Push(object)	(*stackPointer= (object))
		     
#define	integerValueOf(anInt)	((anInt) >> 1)


///
/// METHOD ACTIVATION
///


extern void executeNewMethod(void);

extern void runJitter(bool initFlag);


///
/// PRIMITIVES
///


inline static bool primitiveResponse(void)
{
  PRINTF(("primitive: %d\n", primitiveIndex));
  successFlag= true;
  (primitiveTable[primitiveIndex])();
  if (successFlag && ((nextWakeupTick != 0) &&
		      ((ioMSecs()) >= nextWakeupTick))) {
    checkForInterrupts();
  }
  lkupClass= nilObj->asClass();	// disable atCache for supered sends
  return successFlag;
}

extern void primitiveBlockCopy(void);
extern void primitiveValue(void);
extern void primitiveValueWithArgs(void);
extern void primitiveDoPrimitiveWithArgs(void);
extern void primitivePerform(void);
extern void primitivePerformWithArgs(void);


///
/// EXECUTION STATISTICS
///


extern void printMemoStats(char *buf);
extern void memoStats(void);


///
/// DEBUG
///


#ifdef DEBUG
extern void okayJitterObjects(void);
#endif

#ifdef TRACE

extern void noteEntry(oop rcvr, TranslatedMethod *meth, word *ip,
		      CachedContext *ctx, oop *sp);

extern void noteActivation(oop rcvr, TranslatedMethod *meth, word *ip,
			   CachedContext *ctx, oop *sp);

extern void noteReturn(oop rcvr, TranslatedMethod *meth, word *ip,
		       CachedContext *ctx, oop *sp);

extern void noteExecutionState(oop recv, TranslatedMethod *meth, word *ip,
			       CachedContext *ctx, oop *sp);

#else !TRACE

#define noteEntry(rcvr, meth, ip, ctx, sp)
#define noteActivation(rcvr, meth, ip, ctx, sp)
#define noteReturn(rcvr, meth, ip, ctx, sp)
#define noteExecutionState(recv, meth, ip, ctx, sp)

#endif !TRACE


#if defined(SPY) && defined (GATHER_STATS)

  extern void spyStatistics(void);

# define UPDATE_SPY() spyStatistics()

  inline static void localCheckForInterrupts(void) {
    UPDATE_SPY();
    checkForInterrupts();
  }

# define checkForInterrupts	localCheckForInterrupts

#else
# define UPDATE_SPY()
#endif


#endif _execute_h_

