text: /*
   * tclDisassemble.c --
   *
   *	This file contains procedures that disassemble bytecode into either
   *	human-readable or Tcl-processable forms.
   *
   * Copyright (c) 1996-1998 Sun Microsystems, Inc.
   * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
   * Copyright (c) 2013 Donal K. Fellows.
  =======
   * Copyright (c) 2013-2016 Donal K. Fellows.
  >>>>>>> upstream/master
  =======
   * Copyright (c) 2013-2016 Donal K. Fellows.
  >>>>>>> upstream/master
  =======
   * Copyright (c) 2013-2016 Donal K. Fellows.
  >>>>>>> upstream/master
  =======
   * Copyright (c) 2013-2016 Donal K. Fellows.
  >>>>>>> upstream/master
   *
   * See the file "license.terms" for information on usage and redistribution of
   * this file, and for a DISCLAIMER OF ALL WARRANTIES.
   */
  
  #include "tclInt.h"
  #include "tclCompile.h"
  #include "tclOOInt.h"
  #include <assert.h>
  
  /*
   * Prototypes for procedures defined later in this file:
   */
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  static Tcl_Obj *	DisassembleByteCodeAsDicts(Tcl_Obj *objPtr);
  static int		FormatInstruction(ByteCode *codePtr,
  			    const unsigned char *pc, Tcl_Obj *bufferObj);
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  static Tcl_Obj *	DisassembleByteCodeAsDicts(Tcl_Interp *interp,
  			    Tcl_Obj *objPtr);
  static Tcl_Obj *	DisassembleByteCodeObj(Tcl_Interp *interp,
  			    Tcl_Obj *objPtr);
  =======
  static Tcl_Obj *	DisassembleByteCodeAsDicts(Tcl_Obj *objPtr);
  static Tcl_Obj *	DisassembleByteCodeObj(Tcl_Obj *objPtr);
  >>>>>>> upstream/master
  static int		FormatInstruction(ByteCode *codePtr,
  			    const unsigned char *pc, Tcl_Obj *bufferObj);
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  static void		GetLocationInformation(Tcl_Interp *interp,
  			    Proc *procPtr, Tcl_Obj **fileObjPtr,
  			    int *linePtr);
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  static void		GetLocationInformation(Proc *procPtr,
  			    Tcl_Obj **fileObjPtr, int *linePtr);
  >>>>>>> upstream/master
  =======
  static void		GetLocationInformation(Proc *procPtr,
  			    Tcl_Obj **fileObjPtr, int *linePtr);
  >>>>>>> upstream/master
  =======
  static void		GetLocationInformation(Proc *procPtr,
  			    Tcl_Obj **fileObjPtr, int *linePtr);
  >>>>>>> upstream/master
  static void		PrintSourceToObj(Tcl_Obj *appendObj,
  			    const char *stringPtr, int maxChars);
  static void		UpdateStringOfInstName(Tcl_Obj *objPtr);
  
  /*
   * The structure below defines an instruction name Tcl object to allow
   * reporting of inner contexts in errorstack without string allocation.
   */
  
  static const Tcl_ObjType instNameType = {
      "instname",			/* name */
      NULL,			/* freeIntRepProc */
      NULL,			/* dupIntRepProc */
      UpdateStringOfInstName,	/* updateStringProc */
      NULL,			/* setFromAnyProc */
  };
  
  #define InstNameSetIntRep(objPtr, inst)				\
      do {							\
  	Tcl_ObjIntRep ir;					\
  	ir.wideValue = (inst);					\
  	Tcl_StoreIntRep((objPtr), &instNameType, &ir);		\
      } while (0)
  
  #define InstNameGetIntRep(objPtr, inst)				\
      do {							\
  	const Tcl_ObjIntRep *irPtr;				\
  <<<<<<< HEAD
  	irPtr = Tcl_FetchIntRep((objPtr), &instNameType);	\
  =======
  	irPtr = TclFetchIntRep((objPtr), &instNameType);	\
  >>>>>>> upstream/master
  	assert(irPtr != NULL);					\
  	(inst) = (size_t)irPtr->wideValue;			\
      } while (0)
  
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  /*
   *----------------------------------------------------------------------
   *
   * GetLocationInformation --
   *
   *	This procedure looks up the information about where a procedure was
   *	originally declared.
   *
   * Results:
   *	Writes to the variables pointed at by fileObjPtr and linePtr.
   *
   * Side effects:
   *	None.
   *
   *----------------------------------------------------------------------
   */
  
  static void
  GetLocationInformation(
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      Tcl_Interp *interp,		/* Where to look up the location
  				 * information. */
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      Proc *procPtr,		/* What to look up the information for. */
      Tcl_Obj **fileObjPtr,	/* Where to write the information about what
  				 * file the code came from. Will be written
  				 * to, either with the object (assume shared!)
  				 * that describes what the file was, or with
  				 * NULL if the information is not
  				 * available. */
      int *linePtr)		/* Where to write the information about what
  				 * line number represented the start of the
  				 * code in question. Will be written to,
  				 * either with the line number or with -1 if
  				 * the information is not available. */
  {
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      Interp *iPtr = (Interp *) interp;
      Tcl_HashEntry *hePtr;
      CmdFrame *cfPtr;
  
      *fileObjPtr = NULL;
      *linePtr = -1;
      if (iPtr != NULL && procPtr != NULL) {
  	hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, procPtr);
  	if (hePtr != NULL && (cfPtr = Tcl_GetHashValue(hePtr)) != NULL) {
  	    *linePtr = cfPtr->line[0];
  	    if (cfPtr->type == TCL_LOCATION_SOURCE) {
  		*fileObjPtr = cfPtr->data.eval.path;
  	    }
  	}
      }
  }
  
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      CmdFrame *cfPtr = TclGetCmdFrameForProcedure(procPtr);
  
      *fileObjPtr = NULL;
      *linePtr = -1;
      if (cfPtr == NULL) {
  	return;
      }
  
      /*
       * Get the source location data out of the CmdFrame.
       */
  
      *linePtr = cfPtr->line[0];
      if (cfPtr->type == TCL_LOCATION_SOURCE) {
  	*fileObjPtr = cfPtr->data.eval.path;
      }
  }
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  #ifdef TCL_COMPILE_DEBUG
  /*
   *----------------------------------------------------------------------
   *
   * TclPrintByteCodeObj --
   *
   *	This procedure prints ("disassembles") the instructions of a bytecode
   *	object to stdout.
   *
   * Results:
   *	None.
   *
   * Side effects:
   *	None.
   *
   *----------------------------------------------------------------------
   */
  
  void
  TclPrintByteCodeObj(
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      Tcl_Interp *interp,		/* Used only for Tcl_GetStringFromObj. */
      Tcl_Obj *objPtr)		/* The bytecode object to disassemble. */
  {
      Tcl_Obj *bufPtr = TclDisassembleByteCodeObj(objPtr);
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      Tcl_Interp *interp,		/* Used only for getting location info. */
      Tcl_Obj *objPtr)		/* The bytecode object to disassemble. */
  {
      Tcl_Obj *bufPtr = DisassembleByteCodeObj(interp, objPtr);
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
      TCL_UNUSED(Tcl_Interp *),	/* Stuck with this in internal stubs */
      Tcl_Obj *objPtr)		/* The bytecode object to disassemble. */
  {
      Tcl_Obj *bufPtr = DisassembleByteCodeObj(objPtr);
  >>>>>>> upstream/master
  
      fprintf(stdout, "\n%s", TclGetString(bufPtr));
      Tcl_DecrRefCount(bufPtr);
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * TclPrintInstruction --
   *
   *	This procedure prints ("disassembles") one instruction from a bytecode
   *	object to stdout.
   *
   * Results:
   *	Returns the length in bytes of the current instruiction.
   *
   * Side effects:
   *	None.
   *
   *----------------------------------------------------------------------
   */
  
  int
  TclPrintInstruction(
      ByteCode *codePtr,		/* Bytecode containing the instruction. */
      const unsigned char *pc)	/* Points to first byte of instruction. */
  {
      Tcl_Obj *bufferObj;
      int numBytes;
  
      TclNewObj(bufferObj);
      numBytes = FormatInstruction(codePtr, pc, bufferObj);
      fprintf(stdout, "%s", TclGetString(bufferObj));
      Tcl_DecrRefCount(bufferObj);
      return numBytes;
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * TclPrintObject --
   *
   *	This procedure prints up to a specified number of characters from the
   *	argument Tcl object's string representation to a specified file.
   *
   * Results:
   *	None.
   *
   * Side effects:
   *	Outputs characters to the specified file.
   *
   *----------------------------------------------------------------------
   */
  
  void
  TclPrintObject(
      FILE *outFile,		/* The file to print the source to. */
      Tcl_Obj *objPtr,		/* Points to the Tcl object whose string
  				 * representation should be printed. */
  <<<<<<< HEAD
      int maxChars)		/* Maximum number of chars to print. */
  {
      char *bytes;
      int length;
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      bytes = Tcl_GetStringFromObj(objPtr, &length);
  =======
      bytes = TclGetStringFromObj(objPtr, &length);
  >>>>>>> upstream/master
  =======
      bytes = TclGetStringFromObj(objPtr, &length);
  >>>>>>> upstream/master
  =======
      bytes = TclGetStringFromObj(objPtr, &length);
  >>>>>>> upstream/master
  =======
      size_t maxChars)		/* Maximum number of chars to print. */
  {
      char *bytes;
      size_t length;
  
      bytes = TclGetStringFromObj(objPtr, &length);
  >>>>>>> upstream/master
      TclPrintSource(outFile, bytes, TclMin(length, maxChars));
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * TclPrintSource --
   *
   *	This procedure prints up to a specified number of characters from the
   *	argument string to a specified file. It tries to produce legible
   *	output by adding backslashes as necessary.
   *
   * Results:
   *	None.
   *
   * Side effects:
   *	Outputs characters to the specified file.
   *
   *----------------------------------------------------------------------
   */
  
  void
  TclPrintSource(
      FILE *outFile,		/* The file to print the source to. */
      const char *stringPtr,	/* The string to print. */
  <<<<<<< HEAD
      int maxChars)		/* Maximum number of chars to print. */
  =======
      size_t maxChars)		/* Maximum number of chars to print. */
  >>>>>>> upstream/master
  {
      Tcl_Obj *bufferObj;
  
      TclNewObj(bufferObj);
      PrintSourceToObj(bufferObj, stringPtr, maxChars);
      fprintf(outFile, "%s", TclGetString(bufferObj));
      Tcl_DecrRefCount(bufferObj);
  }
  #endif /* TCL_COMPILE_DEBUG */
  
  /*
   *----------------------------------------------------------------------
   *
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
   * TclDisassembleByteCodeObj --
  =======
   * DisassembleByteCodeObj --
  >>>>>>> upstream/master
  =======
   * DisassembleByteCodeObj --
  >>>>>>> upstream/master
  =======
   * DisassembleByteCodeObj --
  >>>>>>> upstream/master
  =======
   * DisassembleByteCodeObj --
  >>>>>>> upstream/master
  =======
   * DisassembleByteCodeObj --
  >>>>>>> upstream/master
   *
   *	Given an object which is of bytecode type, return a disassembled
   *	version of the bytecode (in a new refcount 0 object). No guarantees
   *	are made about the details of the contents of the result.
   *
   *----------------------------------------------------------------------
   */
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  Tcl_Obj *
  TclDisassembleByteCodeObj(
  =======
  static Tcl_Obj *
  DisassembleByteCodeObj(
      Tcl_Interp *interp,
  >>>>>>> upstream/master
  =======
  static Tcl_Obj *
  DisassembleByteCodeObj(
      Tcl_Interp *interp,
  >>>>>>> upstream/master
  =======
  static Tcl_Obj *
  DisassembleByteCodeObj(
      Tcl_Interp *interp,
  >>>>>>> upstream/master
  =======
  static Tcl_Obj *
  DisassembleByteCodeObj(
      Tcl_Interp *interp,
  >>>>>>> upstream/master
  =======
  static Tcl_Obj *
  DisassembleByteCodeObj(
  <<<<<<< HEAD
      Tcl_Interp *interp,
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      Tcl_Obj *objPtr)		/* The bytecode object to disassemble. */
  {
      ByteCode *codePtr;
      unsigned char *codeStart, *codeLimit, *pc;
      unsigned char *codeDeltaNext, *codeLengthNext;
      unsigned char *srcDeltaNext, *srcLengthNext;
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i;
      Interp *iPtr = (Interp *) *codePtr->interpHandle;
      Tcl_Obj *bufferObj;
  =======
      int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
      Interp *iPtr = (Interp *) *codePtr->interpHandle;
      Tcl_Obj *bufferObj, *fileObj;
  >>>>>>> upstream/master
  =======
      int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
      Interp *iPtr = (Interp *) *codePtr->interpHandle;
      Tcl_Obj *bufferObj, *fileObj;
  >>>>>>> upstream/master
      char ptrBuf1[20], ptrBuf2[20];
  =======
      int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
      Interp *iPtr = (Interp *) *codePtr->interpHandle;
      Tcl_Obj *bufferObj, *fileObj;
  >>>>>>> upstream/master
  =======
      int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
      Interp *iPtr;
      Tcl_Obj *bufferObj, *fileObj;
  >>>>>>> upstream/master
  =======
      int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
      Interp *iPtr;
      Tcl_Obj *bufferObj, *fileObj;
  >>>>>>> upstream/master
  
      ByteCodeGetIntRep(objPtr, &tclByteCodeType, codePtr);
  
      iPtr = (Interp *) *codePtr->interpHandle;
  
      TclNewObj(bufferObj);
      if (!codePtr->refCount) {
  	return bufferObj;	/* Already freed. */
      }
  
      codeStart = codePtr->codeStart;
      codeLimit = codeStart + codePtr->numCodeBytes;
      numCmds = codePtr->numCommands;
  
      /*
       * Print header lines describing the ByteCode.
       */
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      sprintf(ptrBuf1, "%p", codePtr);
      sprintf(ptrBuf2, "%p", iPtr);
      Tcl_AppendPrintfToObj(bufferObj,
  <<<<<<< HEAD
  	    "ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n",
  	    ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2,
  =======
      Tcl_AppendPrintfToObj(bufferObj,
  <<<<<<< HEAD
  	    "ByteCode %p, refCt %u, epoch %u, interp %p (epoch %u)\n",
  	    codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr,
  >>>>>>> upstream/master
  =======
      Tcl_AppendPrintfToObj(bufferObj,
  <<<<<<< HEAD
  	    "ByteCode %p, refCt %u, epoch %u, interp %p (epoch %u)\n",
  	    codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr,
  >>>>>>> upstream/master
  	    iPtr->compileEpoch);
  =======
  	    "ByteCode %p, refCt %u, epoch %" TCL_LL_MODIFIER "d, interp %p (epoch %" TCL_LL_MODIFIER "d)\n",
  	    codePtr, codePtr->refCount, (Tcl_WideUInt)codePtr->compileEpoch, iPtr,
  =======
  	    "ByteCode %p, refCt %" TCL_LL_MODIFIER "d, epoch %" TCL_LL_MODIFIER "d, interp %p (epoch %" TCL_LL_MODIFIER "d)\n",
  	    codePtr, (Tcl_WideUInt)codePtr->refCount, (Tcl_WideUInt)codePtr->compileEpoch, iPtr,
  >>>>>>> upstream/master
  		(Tcl_WideUInt)iPtr->compileEpoch);
  >>>>>>> upstream/master
  =======
  	    "ByteCode %p, refCt %" TCL_Z_MODIFIER "u, epoch %" TCL_Z_MODIFIER "u, interp %p (epoch %" TCL_Z_MODIFIER "u)\n",
  	    codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr, iPtr->compileEpoch);
  >>>>>>> upstream/master
      Tcl_AppendToObj(bufferObj, "  Source ", -1);
      PrintSourceToObj(bufferObj, codePtr->source,
  	    TclMin(codePtr->numSrcBytes, 55));
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  =======
  =======
  >>>>>>> upstream/master
      GetLocationInformation(interp, codePtr->procPtr, &fileObj, &line);
  =======
      GetLocationInformation(codePtr->procPtr, &fileObj, &line);
  >>>>>>> upstream/master
  =======
      GetLocationInformation(codePtr->procPtr, &fileObj, &line);
  >>>>>>> upstream/master
      if (line > -1 && fileObj != NULL) {
  	Tcl_AppendPrintfToObj(bufferObj, "\n  File \"%s\" Line %d",
  		Tcl_GetString(fileObj), line);
      }
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
      Tcl_AppendPrintfToObj(bufferObj,
  	    "ByteCode %p, refCt %" TCL_Z_MODIFIER "u, epoch %" TCL_Z_MODIFIER "u, interp %p (epoch %" TCL_Z_MODIFIER "u)\n",
  	    codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr, iPtr->compileEpoch);
      Tcl_AppendToObj(bufferObj, "  Source ", -1);
      PrintSourceToObj(bufferObj, codePtr->source,
  	    TclMin(codePtr->numSrcBytes, 55));
      GetLocationInformation(codePtr->procPtr, &fileObj, &line);
      if (line >= 0 && fileObj != NULL) {
  	Tcl_AppendPrintfToObj(bufferObj, "\n  File \"%s\" Line %d",
  		TclGetString(fileObj), line);
      }
  >>>>>>> upstream/master
      Tcl_AppendPrintfToObj(bufferObj,
  	    "\n  Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n",
  	    numCmds, codePtr->numSrcBytes, codePtr->numCodeBytes,
  	    codePtr->numLitObjects, codePtr->numAuxDataItems,
  	    codePtr->maxStackDepth,
  #ifdef TCL_COMPILE_STATS
  	    codePtr->numSrcBytes?
  		    codePtr->structureSize/(float)codePtr->numSrcBytes :
  #endif
  	    0.0);
  
  #ifdef TCL_COMPILE_STATS
      Tcl_AppendPrintfToObj(bufferObj,
  	    "  Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n",
  	    (unsigned long) codePtr->structureSize,
  	    (unsigned long) (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time)),
  	    codePtr->numCodeBytes,
  	    (unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)),
  	    (unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)),
  	    (unsigned long) (codePtr->numAuxDataItems * sizeof(AuxData)),
  	    codePtr->numCmdLocBytes);
  #endif /* TCL_COMPILE_STATS */
  
      /*
       * If the ByteCode is the compiled body of a Tcl procedure, print
       * information about that procedure. Note that we don't know the
       * procedure's name since ByteCode's can be shared among procedures.
       */
  
      if (codePtr->procPtr != NULL) {
  	Proc *procPtr = codePtr->procPtr;
  	int numCompiledLocals = procPtr->numCompiledLocals;
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  	sprintf(ptrBuf1, "%p", procPtr);
  	Tcl_AppendPrintfToObj(bufferObj,
  		"  Proc 0x%s, refCt %d, args %d, compiled locals %d\n",
  		ptrBuf1, procPtr->refCount, procPtr->numArgs,
  =======
  	Tcl_AppendPrintfToObj(bufferObj,
  		"  Proc %p, refCt %d, args %d, compiled locals %d\n",
  		procPtr, procPtr->refCount, procPtr->numArgs,
  >>>>>>> upstream/master
  =======
  	Tcl_AppendPrintfToObj(bufferObj,
  <<<<<<< HEAD
  <<<<<<< HEAD
  		"  Proc %p, refCt %d, args %d, compiled locals %d\n",
  		procPtr, procPtr->refCount, procPtr->numArgs,
  >>>>>>> upstream/master
  =======
  		"  Proc %p, refCt %" TCL_LL_MODIFIER "d, args %d, compiled locals %d\n",
  		procPtr, (Tcl_WideUInt)procPtr->refCount, procPtr->numArgs,
  >>>>>>> upstream/master
  =======
  		"  Proc %p, refCt %" TCL_Z_MODIFIER "u, args %d, compiled locals %d\n",
  		procPtr, procPtr->refCount, procPtr->numArgs,
  >>>>>>> upstream/master
  =======
  	Tcl_AppendPrintfToObj(bufferObj,
  		"  Proc %p, refCt %" TCL_Z_MODIFIER "u, args %d, compiled locals %d\n",
  		procPtr, procPtr->refCount, procPtr->numArgs,
  >>>>>>> upstream/master
  		numCompiledLocals);
  	if (numCompiledLocals > 0) {
  	    CompiledLocal *localPtr = procPtr->firstLocalPtr;
  
  	    for (i = 0;  i < numCompiledLocals;  i++) {
  		Tcl_AppendPrintfToObj(bufferObj,
  			"      slot %d%s%s%s%s%s%s", i,
  			(localPtr->flags & (VAR_ARRAY|VAR_LINK)) ? "" : ", scalar",
  			(localPtr->flags & VAR_ARRAY) ? ", array" : "",
  			(localPtr->flags & VAR_LINK) ? ", link" : "",
  			(localPtr->flags & VAR_ARGUMENT) ? ", arg" : "",
  			(localPtr->flags & VAR_TEMPORARY) ? ", temp" : "",
  			(localPtr->flags & VAR_RESOLVED) ? ", resolved" : "");
  		if (TclIsVarTemporary(localPtr)) {
  		    Tcl_AppendToObj(bufferObj, "\n", -1);
  		} else {
  		    Tcl_AppendPrintfToObj(bufferObj, ", \"%s\"\n",
  			    localPtr->name);
  		}
  		localPtr = localPtr->nextPtr;
  	    }
  	}
      }
  
      /*
       * Print the ExceptionRange array.
       */
  
      if (codePtr->numExceptRanges > 0) {
  	Tcl_AppendPrintfToObj(bufferObj, "  Exception ranges %d, depth %d:\n",
  		codePtr->numExceptRanges, codePtr->maxExceptDepth);
  	for (i = 0;  i < codePtr->numExceptRanges;  i++) {
  	    ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i];
  
  	    Tcl_AppendPrintfToObj(bufferObj,
  		    "      %d: level %d, %s, pc %d-%d, ",
  		    i, rangePtr->nestingLevel,
  		    (rangePtr->type==LOOP_EXCEPTION_RANGE ? "loop" : "catch"),
  		    rangePtr->codeOffset,
  		    (rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
  	    switch (rangePtr->type) {
  	    case LOOP_EXCEPTION_RANGE:
  		Tcl_AppendPrintfToObj(bufferObj, "continue %d, break %d\n",
  			rangePtr->continueOffset, rangePtr->breakOffset);
  		break;
  	    case CATCH_EXCEPTION_RANGE:
  		Tcl_AppendPrintfToObj(bufferObj, "catch %d\n",
  			rangePtr->catchOffset);
  		break;
  	    default:
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  		Tcl_Panic("TclDisassembleByteCodeObj: bad ExceptionRange type %d",
  =======
  		Tcl_Panic("DisassembleByteCodeObj: bad ExceptionRange type %d",
  >>>>>>> upstream/master
  =======
  		Tcl_Panic("DisassembleByteCodeObj: bad ExceptionRange type %d",
  >>>>>>> upstream/master
  =======
  		Tcl_Panic("DisassembleByteCodeObj: bad ExceptionRange type %d",
  >>>>>>> upstream/master
  =======
  		Tcl_Panic("DisassembleByteCodeObj: bad ExceptionRange type %d",
  >>>>>>> upstream/master
  =======
  		Tcl_Panic("DisassembleByteCodeObj: bad ExceptionRange type %d",
  >>>>>>> upstream/master
  			rangePtr->type);
  	    }
  	}
      }
  
      /*
       * If there were no commands (e.g., an expression or an empty string was
       * compiled), just print all instructions and return.
       */
  
      if (numCmds == 0) {
  	pc = codeStart;
  	while (pc < codeLimit) {
  	    Tcl_AppendToObj(bufferObj, "    ", -1);
  	    pc += FormatInstruction(codePtr, pc, bufferObj);
  	}
  	return bufferObj;
      }
  
      /*
       * Print table showing the code offset, source offset, and source length
       * for each command. These are encoded as a sequence of bytes.
       */
  
      Tcl_AppendPrintfToObj(bufferObj, "  Commands %d:", numCmds);
      codeDeltaNext = codePtr->codeDeltaStart;
      codeLengthNext = codePtr->codeLengthStart;
      srcDeltaNext = codePtr->srcDeltaStart;
      srcLengthNext = codePtr->srcLengthStart;
      codeOffset = srcOffset = 0;
      for (i = 0;  i < numCmds;  i++) {
  <<<<<<< HEAD
  	if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) {
  =======
  	if (*codeDeltaNext == 0xFF) {
  >>>>>>> upstream/master
  	    codeDeltaNext++;
  	    delta = TclGetInt4AtPtr(codeDeltaNext);
  	    codeDeltaNext += 4;
  	} else {
  	    delta = TclGetInt1AtPtr(codeDeltaNext);
  	    codeDeltaNext++;
  	}
  	codeOffset += delta;
  
  <<<<<<< HEAD
  	if ((unsigned) *codeLengthNext == (unsigned) 0xFF) {
  =======
  	if (*codeLengthNext == 0xFF) {
  >>>>>>> upstream/master
  	    codeLengthNext++;
  	    codeLen = TclGetInt4AtPtr(codeLengthNext);
  	    codeLengthNext += 4;
  	} else {
  	    codeLen = TclGetInt1AtPtr(codeLengthNext);
  	    codeLengthNext++;
  	}
  
  <<<<<<< HEAD
  	if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) {
  =======
  	if (*srcDeltaNext == 0xFF) {
  >>>>>>> upstream/master
  	    srcDeltaNext++;
  	    delta = TclGetInt4AtPtr(srcDeltaNext);
  	    srcDeltaNext += 4;
  	} else {
  	    delta = TclGetInt1AtPtr(srcDeltaNext);
  	    srcDeltaNext++;
  	}
  	srcOffset += delta;
  
  <<<<<<< HEAD
  	if ((unsigned) *srcLengthNext == (unsigned) 0xFF) {
  =======
  	if (*srcLengthNext == 0xFF) {
  >>>>>>> upstream/master
  	    srcLengthNext++;
  	    srcLen = TclGetInt4AtPtr(srcLengthNext);
  	    srcLengthNext += 4;
  	} else {
  	    srcLen = TclGetInt1AtPtr(srcLengthNext);
  	    srcLengthNext++;
  	}
  
  	Tcl_AppendPrintfToObj(bufferObj, "%s%4d: pc %d-%d, src %d-%d",
  		((i % 2)? "     " : "\n   "),
  		(i+1), codeOffset, (codeOffset + codeLen - 1),
  		srcOffset, (srcOffset + srcLen - 1));
      }
      if (numCmds > 0) {
  	Tcl_AppendToObj(bufferObj, "\n", -1);
      }
  
      /*
       * Print each instruction. If the instruction corresponds to the start of
       * a command, print the command's source. Note that we don't need the code
       * length here.
       */
  
      codeDeltaNext = codePtr->codeDeltaStart;
      srcDeltaNext = codePtr->srcDeltaStart;
      srcLengthNext = codePtr->srcLengthStart;
      codeOffset = srcOffset = 0;
      pc = codeStart;
      for (i = 0;  i < numCmds;  i++) {
  <<<<<<< HEAD
  	if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) {
  =======
  	if (*codeDeltaNext == 0xFF) {
  >>>>>>> upstream/master
  	    codeDeltaNext++;
  	    delta = TclGetInt4AtPtr(codeDeltaNext);
  	    codeDeltaNext += 4;
  	} else {
  	    delta = TclGetInt1AtPtr(codeDeltaNext);
  	    codeDeltaNext++;
  	}
  	codeOffset += delta;
  
  <<<<<<< HEAD
  	if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) {
  =======
  	if (*srcDeltaNext == 0xFF) {
  >>>>>>> upstream/master
  	    srcDeltaNext++;
  	    delta = TclGetInt4AtPtr(srcDeltaNext);
  	    srcDeltaNext += 4;
  	} else {
  	    delta = TclGetInt1AtPtr(srcDeltaNext);
  	    srcDeltaNext++;
  	}
  	srcOffset += delta;
  
  <<<<<<< HEAD
  	if ((unsigned) *srcLengthNext == (unsigned) 0xFF) {
  =======
  	if (*srcLengthNext == 0xFF) {
  >>>>>>> upstream/master
  	    srcLengthNext++;
  	    srcLen = TclGetInt4AtPtr(srcLengthNext);
  	    srcLengthNext += 4;
  	} else {
  	    srcLen = TclGetInt1AtPtr(srcLengthNext);
  	    srcLengthNext++;
  	}
  
  	/*
  	 * Print instructions before command i.
  	 */
  
  	while ((pc-codeStart) < codeOffset) {
  	    Tcl_AppendToObj(bufferObj, "    ", -1);
  	    pc += FormatInstruction(codePtr, pc, bufferObj);
  	}
  
  	Tcl_AppendPrintfToObj(bufferObj, "  Command %d: ", i+1);
  	PrintSourceToObj(bufferObj, (codePtr->source + srcOffset),
  		TclMin(srcLen, 55));
  	Tcl_AppendToObj(bufferObj, "\n", -1);
      }
      if (pc < codeLimit) {
  	/*
  	 * Print instructions after the last command.
  	 */
  
  	while (pc < codeLimit) {
  	    Tcl_AppendToObj(bufferObj, "    ", -1);
  	    pc += FormatInstruction(codePtr, pc, bufferObj);
  	}
      }
      return bufferObj;
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * FormatInstruction --
   *
   *	Appends a representation of a bytecode instruction to a Tcl_Obj.
   *
   *----------------------------------------------------------------------
   */
  
  static int
  FormatInstruction(
      ByteCode *codePtr,		/* Bytecode containing the instruction. */
      const unsigned char *pc,	/* Points to first byte of instruction. */
      Tcl_Obj *bufferObj)		/* Object to append instruction info to. */
  {
      Proc *procPtr = codePtr->procPtr;
      unsigned char opCode = *pc;
  <<<<<<< HEAD
      register const InstructionDesc *instDesc = &tclInstructionTable[opCode];
  =======
      const InstructionDesc *instDesc = &tclInstructionTable[opCode];
  >>>>>>> upstream/master
      unsigned char *codeStart = codePtr->codeStart;
      unsigned pcOffset = pc - codeStart;
      int opnd = 0, i, j, numBytes = 1;
      int localCt = procPtr ? procPtr->numCompiledLocals : 0;
      CompiledLocal *localPtr = procPtr ? procPtr->firstLocalPtr : NULL;
      char suffixBuffer[128];	/* Additional info to print after main opcode
  				 * and immediates. */
      char *suffixSrc = NULL;
      Tcl_Obj *suffixObj = NULL;
      AuxData *auxPtr = NULL;
  
      suffixBuffer[0] = '\0';
      Tcl_AppendPrintfToObj(bufferObj, "(%u) %s ", pcOffset, instDesc->name);
      for (i = 0;  i < instDesc->numOperands;  i++) {
  	switch (instDesc->opTypes[i]) {
  	case OPERAND_INT1:
  	    opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++;
  	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
  	    break;
  	case OPERAND_INT4:
  	    opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
  	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
  	    break;
  	case OPERAND_UINT1:
  	    opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
  <<<<<<< HEAD
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
  =======
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
  >>>>>>> upstream/master
  	    break;
  	case OPERAND_UINT4:
  	    opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
  	    if (opCode == INST_START_CMD) {
  		sprintf(suffixBuffer+strlen(suffixBuffer),
  			", %u cmds start here", opnd);
  	    }
  <<<<<<< HEAD
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
  =======
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
  >>>>>>> upstream/master
  	    break;
  	case OPERAND_OFFSET1:
  	    opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++;
  	    sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
  	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
  	    break;
  	case OPERAND_OFFSET4:
  	    opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
  	    if (opCode == INST_START_CMD) {
  		sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd);
  	    } else {
  		sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
  	    }
  	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
  	    break;
  	case OPERAND_LIT1:
  	    opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
  	    suffixObj = codePtr->objArrayPtr[opnd];
  <<<<<<< HEAD
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
  =======
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
  >>>>>>> upstream/master
  	    break;
  	case OPERAND_LIT4:
  	    opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
  	    suffixObj = codePtr->objArrayPtr[opnd];
  <<<<<<< HEAD
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
  	    break;
  	case OPERAND_AUX4:
  	    opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
  =======
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
  	    break;
  	case OPERAND_AUX4:
  	    opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
  	    Tcl_AppendPrintfToObj(bufferObj, "%u ", opnd);
  >>>>>>> upstream/master
  	    auxPtr = &codePtr->auxDataArrayPtr[opnd];
  	    break;
  	case OPERAND_IDX4:
  	    opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
  	    if (opnd >= -1) {
  		Tcl_AppendPrintfToObj(bufferObj, "%d ", opnd);
  	    } else if (opnd == -2) {
  		Tcl_AppendPrintfToObj(bufferObj, "end ");
  	    } else {
  		Tcl_AppendPrintfToObj(bufferObj, "end-%d ", -2-opnd);
  	    }
  	    break;
  	case OPERAND_LVT1:
  	    opnd = TclGetUInt1AtPtr(pc+numBytes);
  	    numBytes++;
  	    goto printLVTindex;
  	case OPERAND_LVT4:
  	    opnd = TclGetUInt4AtPtr(pc+numBytes);
  	    numBytes += 4;
  	printLVTindex:
  	    if (localPtr != NULL) {
  		if (opnd >= localCt) {
  		    Tcl_Panic("FormatInstruction: bad local var index %u (%u locals)",
  <<<<<<< HEAD
  			    (unsigned) opnd, localCt);
  =======
  			    opnd, localCt);
  >>>>>>> upstream/master
  		}
  		for (j = 0;  j < opnd;  j++) {
  		    localPtr = localPtr->nextPtr;
  		}
  		if (TclIsVarTemporary(localPtr)) {
  <<<<<<< HEAD
  		    sprintf(suffixBuffer, "temp var %u", (unsigned) opnd);
  =======
  		    sprintf(suffixBuffer, "temp var %u", opnd);
  >>>>>>> upstream/master
  		} else {
  		    sprintf(suffixBuffer, "var ");
  		    suffixSrc = localPtr->name;
  		}
  	    }
  <<<<<<< HEAD
  	    Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", (unsigned) opnd);
  =======
  	    Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", opnd);
  >>>>>>> upstream/master
  	    break;
  	case OPERAND_SCLS1:
  	    opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
  	    Tcl_AppendPrintfToObj(bufferObj, "%s ",
  		    tclStringClassTable[opnd].name);
  	    break;
  	case OPERAND_NONE:
  	default:
  	    break;
  	}
      }
      if (suffixObj) {
  	const char *bytes;
  <<<<<<< HEAD
  	int length;
  
  	Tcl_AppendToObj(bufferObj, "\t# ", -1);
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  	bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length);
  =======
  	bytes = TclGetStringFromObj(codePtr->objArrayPtr[opnd], &length);
  >>>>>>> upstream/master
  =======
  	bytes = TclGetStringFromObj(codePtr->objArrayPtr[opnd], &length);
  >>>>>>> upstream/master
  =======
  	bytes = TclGetStringFromObj(codePtr->objArrayPtr[opnd], &length);
  >>>>>>> upstream/master
  =======
  	size_t length;
  
  	Tcl_AppendToObj(bufferObj, "\t# ", -1);
  	bytes = TclGetStringFromObj(codePtr->objArrayPtr[opnd], &length);
  >>>>>>> upstream/master
  	PrintSourceToObj(bufferObj, bytes, TclMin(length, 40));
      } else if (suffixBuffer[0]) {
  	Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer);
  	if (suffixSrc) {
  	    PrintSourceToObj(bufferObj, suffixSrc, 40);
  	}
      }
      Tcl_AppendToObj(bufferObj, "\n", -1);
      if (auxPtr && auxPtr->type->printProc) {
  	Tcl_AppendToObj(bufferObj, "\t\t[", -1);
  	auxPtr->type->printProc(auxPtr->clientData, bufferObj, codePtr,
  		pcOffset);
  	Tcl_AppendToObj(bufferObj, "]\n", -1);
      }
      return numBytes;
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * TclGetInnerContext --
   *
   *	If possible, returns a list capturing the inner context. Otherwise
   *	return NULL.
   *
   *----------------------------------------------------------------------
   */
  
  Tcl_Obj *
  TclGetInnerContext(
      Tcl_Interp *interp,
      const unsigned char *pc,
      Tcl_Obj **tosPtr)
  {
      int objc = 0, off = 0;
      Tcl_Obj *result;
      Interp *iPtr = (Interp *) interp;
  
      switch (*pc) {
      case INST_STR_LEN:
      case INST_LNOT:
      case INST_BITNOT:
      case INST_UMINUS:
      case INST_UPLUS:
      case INST_TRY_CVT_TO_NUMERIC:
      case INST_EXPAND_STKTOP:
      case INST_EXPR_STK:
          objc = 1;
          break;
  
      case INST_LIST_IN:
      case INST_LIST_NOT_IN:	/* Basic list containment operators. */
      case INST_STR_EQ:
      case INST_STR_NEQ:		/* String (in)equality check */
      case INST_STR_CMP:		/* String compare. */
      case INST_STR_INDEX:
      case INST_STR_MATCH:
      case INST_REGEXP:
      case INST_EQ:
      case INST_NEQ:
      case INST_LT:
      case INST_GT:
      case INST_LE:
      case INST_GE:
      case INST_MOD:
      case INST_LSHIFT:
      case INST_RSHIFT:
      case INST_BITOR:
      case INST_BITXOR:
      case INST_BITAND:
      case INST_EXPON:
      case INST_ADD:
      case INST_SUB:
      case INST_DIV:
      case INST_MULT:
          objc = 2;
          break;
  
      case INST_RETURN_STK:
          /* early pop. TODO: dig out opt dict too :/ */
          objc = 1;
          break;
  
      case INST_SYNTAX:
      case INST_RETURN_IMM:
          objc = 2;
          break;
  
      case INST_INVOKE_STK4:
  	objc = TclGetUInt4AtPtr(pc+1);
          break;
  
      case INST_INVOKE_STK1:
  	objc = TclGetUInt1AtPtr(pc+1);
  	break;
      }
  
      result = iPtr->innerContext;
      if (Tcl_IsShared(result)) {
          Tcl_DecrRefCount(result);
          iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL);
          Tcl_IncrRefCount(result);
      } else {
          int len;
  
          /*
           * Reset while keeping the list intrep as much as possible.
           */
  
  	Tcl_ListObjLength(interp, result, &len);
          Tcl_ListObjReplace(interp, result, 0, len, 0, NULL);
      }
      Tcl_ListObjAppendElement(NULL, result, TclNewInstNameObj(*pc));
  
      for (; objc>0 ; objc--) {
          Tcl_Obj *objPtr;
  
          objPtr = tosPtr[1 - objc + off];
          if (!objPtr) {
              Tcl_Panic("InnerContext: bad tos -- appending null object");
          }
          if ((objPtr->refCount<=0)
  #ifdef TCL_MEM_DEBUG
                  || (objPtr->refCount==0x61616161)
  #endif
          ) {
              Tcl_Panic("InnerContext: bad tos -- appending freed object %p",
                      objPtr);
          }
          Tcl_ListObjAppendElement(NULL, result, objPtr);
      }
  
      return result;
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * TclNewInstNameObj --
   *
   *	Creates a new InstName Tcl_Obj based on the given instruction
   *
   *----------------------------------------------------------------------
   */
  
  Tcl_Obj *
  TclNewInstNameObj(
      unsigned char inst)
  {
      Tcl_Obj *objPtr;
  
      TclNewObj(objPtr);
      TclInvalidateStringRep(objPtr);
      InstNameSetIntRep(objPtr, (long) inst);
  
      return objPtr;
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * UpdateStringOfInstName --
   *
   *	Update the string representation for an instruction name object.
   *
   *----------------------------------------------------------------------
   */
  
  static void
  UpdateStringOfInstName(
      Tcl_Obj *objPtr)
  {
  <<<<<<< HEAD
  <<<<<<< HEAD
      size_t len, inst = (size_t)objPtr->internalRep.wideValue;
      char *s, buf[TCL_INTEGER_SPACE + 5];
  
      if (inst >= LAST_INST_OPCODE) {
          sprintf(buf, "inst_%" TCL_Z_MODIFIER "d", inst);
          s = buf;
  =======
  =======
  >>>>>>> upstream/master
      size_t inst;	/* NOTE: We know this is really an unsigned char */
      char *dst;
  
      InstNameGetIntRep(objPtr, inst);
  
      if (inst > LAST_INST_OPCODE) {
  	dst = Tcl_InitStringRep(objPtr, NULL, TCL_INTEGER_SPACE + 5);
  	TclOOM(dst, (size_t)TCL_INTEGER_SPACE + 5);
          sprintf(dst, "inst_%" TCL_Z_MODIFIER "u", inst);
  	(void) Tcl_InitStringRep(objPtr, NULL, strlen(dst));
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      } else {
  	const char *s = tclInstructionTable[inst].name;
  	size_t len = strlen(s);
  	dst = Tcl_InitStringRep(objPtr, s, len);
  	TclOOM(dst, len);
      }
  <<<<<<< HEAD
  <<<<<<< HEAD
      len = strlen(s);
      /* assert (len < UINT_MAX) */
      objPtr->bytes = ckalloc(len + 1);
      memcpy(objPtr->bytes, s, len + 1);
      objPtr->length = len;
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * PrintSourceToObj --
   *
   *	Appends a quoted representation of a string to a Tcl_Obj.
   *
   *----------------------------------------------------------------------
   */
  
  static void
  PrintSourceToObj(
      Tcl_Obj *appendObj,		/* The object to print the source to. */
      const char *stringPtr,	/* The string to print. */
      int maxChars)		/* Maximum number of chars to print. */
  {
  <<<<<<< HEAD
      register const char *p;
      register int i = 0, len;
  =======
      const char *p;
      int i = 0, len;
  <<<<<<< HEAD
  >>>>>>> upstream/master
      Tcl_UniChar ch = 0;
  =======
  >>>>>>> upstream/master
  
      if (stringPtr == NULL) {
  	Tcl_AppendToObj(appendObj, "\"\"", -1);
  	return;
      }
  
      Tcl_AppendToObj(appendObj, "\"", -1);
      p = stringPtr;
      for (;  (*p != '\0') && (i < maxChars);  p+=len) {
  	int ucs4;
  
  	len = TclUtfToUCS4(p, &ucs4);
  	switch (ucs4) {
  	case '"':
  	    Tcl_AppendToObj(appendObj, "\\\"", -1);
  	    i += 2;
  	    continue;
  	case '\f':
  	    Tcl_AppendToObj(appendObj, "\\f", -1);
  	    i += 2;
  	    continue;
  	case '\n':
  	    Tcl_AppendToObj(appendObj, "\\n", -1);
  	    i += 2;
  	    continue;
  	case '\r':
  	    Tcl_AppendToObj(appendObj, "\\r", -1);
  	    i += 2;
  	    continue;
  	case '\t':
  	    Tcl_AppendToObj(appendObj, "\\t", -1);
  	    i += 2;
  	    continue;
  	case '\v':
  	    Tcl_AppendToObj(appendObj, "\\v", -1);
  	    i += 2;
  	    continue;
  	default:
  	    if (ucs4 > 0xFFFF) {
  		Tcl_AppendPrintfToObj(appendObj, "\\U%08x", ucs4);
  		i += 10;
  	    } else if (ucs4 < 0x20 || ucs4 >= 0x7F) {
  		Tcl_AppendPrintfToObj(appendObj, "\\u%04x", ucs4);
  		i += 6;
  	    } else {
  		Tcl_AppendPrintfToObj(appendObj, "%c", ucs4);
  		i++;
  	    }
  	    continue;
  	}
      }
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      Tcl_AppendToObj(appendObj, "\"", -1);
      if (*p != '\0') {
  	Tcl_AppendToObj(appendObj, "...", -1);
      }
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      if (*p != '\0') {
  	Tcl_AppendToObj(appendObj, "...", -1);
      }
      Tcl_AppendToObj(appendObj, "\"", -1);
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * DisassembleByteCodeAsDicts --
   *
   *	Given an object which is of bytecode type, return a disassembled
   *	version of the bytecode (in a new refcount 0 object) in a dictionary.
   *	No guarantees are made about the details of the contents of the
   *	result, but it is intended to be more readable than the old output
   *	format.
   *
   *----------------------------------------------------------------------
   */
  
  static Tcl_Obj *
  DisassembleByteCodeAsDicts(
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  =======
      Tcl_Interp *interp,		/* Used for looking up the CmdFrame for the
  				 * procedure, if one exists. */
  >>>>>>> upstream/master
  =======
      Tcl_Interp *interp,		/* Used for looking up the CmdFrame for the
  				 * procedure, if one exists. */
  >>>>>>> upstream/master
  =======
      Tcl_Interp *interp,		/* Used for looking up the CmdFrame for the
  				 * procedure, if one exists. */
  >>>>>>> upstream/master
  =======
      Tcl_Interp *interp,		/* Used for looking up the CmdFrame for the
  				 * procedure, if one exists. */
  >>>>>>> upstream/master
  =======
      Tcl_Interp *interp,		/* Used for looking up the CmdFrame for the
  				 * procedure, if one exists. */
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      Tcl_Obj *objPtr)		/* The bytecode-holding value to take apart */
  {
      ByteCode *codePtr;
      Tcl_Obj *description, *literals, *variables, *instructions, *inst;
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      Tcl_Obj *aux, *exn, *commands;
      unsigned char *pc, *opnd, *codeOffPtr, *codeLenPtr, *srcOffPtr, *srcLenPtr;
      int codeOffset, codeLength, sourceOffset, sourceLength;
      int i, val;
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      Tcl_Obj *aux, *exn, *commands, *file;
      unsigned char *pc, *opnd, *codeOffPtr, *codeLenPtr, *srcOffPtr, *srcLenPtr;
      int codeOffset, codeLength, sourceOffset, sourceLength;
      int i, val, line;
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  
      ByteCodeGetIntRep(objPtr, &tclByteCodeType, codePtr);
  
      /*
       * Get the literals from the bytecode.
       */
  
      TclNewObj(literals);
      for (i=0 ; i<codePtr->numLitObjects ; i++) {
  	Tcl_ListObjAppendElement(NULL, literals, codePtr->objArrayPtr[i]);
      }
  
      /*
       * Get the variables from the bytecode.
       */
  
      TclNewObj(variables);
      if (codePtr->procPtr) {
  	int localCount = codePtr->procPtr->numCompiledLocals;
  	CompiledLocal *localPtr = codePtr->procPtr->firstLocalPtr;
  
  	for (i=0 ; i<localCount ; i++,localPtr=localPtr->nextPtr) {
  	    Tcl_Obj *descriptor[2];
  
  	    TclNewObj(descriptor[0]);
  	    if (!(localPtr->flags & (VAR_ARRAY|VAR_LINK))) {
  		Tcl_ListObjAppendElement(NULL, descriptor[0],
  			Tcl_NewStringObj("scalar", -1));
  	    }
  	    if (localPtr->flags & VAR_ARRAY) {
  		Tcl_ListObjAppendElement(NULL, descriptor[0],
  			Tcl_NewStringObj("array", -1));
  	    }
  	    if (localPtr->flags & VAR_LINK) {
  		Tcl_ListObjAppendElement(NULL, descriptor[0],
  			Tcl_NewStringObj("link", -1));
  	    }
  	    if (localPtr->flags & VAR_ARGUMENT) {
  		Tcl_ListObjAppendElement(NULL, descriptor[0],
  			Tcl_NewStringObj("arg", -1));
  	    }
  	    if (localPtr->flags & VAR_TEMPORARY) {
  		Tcl_ListObjAppendElement(NULL, descriptor[0],
  			Tcl_NewStringObj("temp", -1));
  	    }
  	    if (localPtr->flags & VAR_RESOLVED) {
  		Tcl_ListObjAppendElement(NULL, descriptor[0],
  			Tcl_NewStringObj("resolved", -1));
  	    }
  	    if (localPtr->flags & VAR_TEMPORARY) {
  		Tcl_ListObjAppendElement(NULL, variables,
  			Tcl_NewListObj(1, descriptor));
  	    } else {
  		descriptor[1] = Tcl_NewStringObj(localPtr->name, -1);
  		Tcl_ListObjAppendElement(NULL, variables,
  			Tcl_NewListObj(2, descriptor));
  	    }
  	}
      }
  
      /*
       * Get the instructions from the bytecode.
       */
  
      TclNewObj(instructions);
      for (pc=codePtr->codeStart; pc<codePtr->codeStart+codePtr->numCodeBytes;){
  	const InstructionDesc *instDesc = &tclInstructionTable[*pc];
  	int address = pc - codePtr->codeStart;
  
  	TclNewObj(inst);
  	Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj(
  		instDesc->name, -1));
  	opnd = pc + 1;
  	for (i=0 ; i<instDesc->numOperands ; i++) {
  	    switch (instDesc->opTypes[i]) {
  	    case OPERAND_INT1:
  		val = TclGetInt1AtPtr(opnd);
  		opnd += 1;
  		goto formatNumber;
  	    case OPERAND_UINT1:
  		val = TclGetUInt1AtPtr(opnd);
  		opnd += 1;
  		goto formatNumber;
  	    case OPERAND_INT4:
  		val = TclGetInt4AtPtr(opnd);
  		opnd += 4;
  		goto formatNumber;
  	    case OPERAND_UINT4:
  		val = TclGetUInt4AtPtr(opnd);
  		opnd += 4;
  	    formatNumber:
  		Tcl_ListObjAppendElement(NULL, inst, Tcl_NewWideIntObj(val));
  		break;
  
  	    case OPERAND_OFFSET1:
  		val = TclGetInt1AtPtr(opnd);
  		opnd += 1;
  		goto formatAddress;
  	    case OPERAND_OFFSET4:
  		val = TclGetInt4AtPtr(opnd);
  		opnd += 4;
  	    formatAddress:
  		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
  			"pc %d", address + val));
  		break;
  
  	    case OPERAND_LIT1:
  		val = TclGetUInt1AtPtr(opnd);
  		opnd += 1;
  		goto formatLiteral;
  	    case OPERAND_LIT4:
  		val = TclGetUInt4AtPtr(opnd);
  		opnd += 4;
  	    formatLiteral:
  		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
  			"@%d", val));
  		break;
  
  	    case OPERAND_LVT1:
  		val = TclGetUInt1AtPtr(opnd);
  		opnd += 1;
  		goto formatVariable;
  	    case OPERAND_LVT4:
  		val = TclGetUInt4AtPtr(opnd);
  		opnd += 4;
  	    formatVariable:
  		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
  			"%%%d", val));
  		break;
  	    case OPERAND_IDX4:
  		val = TclGetInt4AtPtr(opnd);
  		opnd += 4;
  		if (val >= -1) {
  		    Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
  			    ".%d", val));
  		} else if (val == -2) {
  		    Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj(
  			    ".end", -1));
  		} else {
  		    Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
  			    ".end-%d", -2-val));
  		}
  		break;
  	    case OPERAND_AUX4:
  		val = TclGetInt4AtPtr(opnd);
  		opnd += 4;
  		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
  			"?%d", val));
  		break;
  	    case OPERAND_SCLS1:
  		val = TclGetUInt1AtPtr(opnd);
  		opnd++;
  		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
  			"=%s", tclStringClassTable[val].name));
  		break;
  	    case OPERAND_NONE:
  		Tcl_Panic("opcode %d with more than zero 'no' operands", *pc);
  	    }
  	}
  	Tcl_DictObjPut(NULL, instructions, Tcl_NewWideIntObj(address), inst);
  	pc += instDesc->numBytes;
      }
  
      /*
       * Get the auxiliary data from the bytecode.
       */
  
      TclNewObj(aux);
      for (i=0 ; i<codePtr->numAuxDataItems ; i++) {
  	AuxData *auxData = &codePtr->auxDataArrayPtr[i];
  	Tcl_Obj *auxDesc = Tcl_NewStringObj(auxData->type->name, -1);
  
  	if (auxData->type->disassembleProc) {
  	    Tcl_Obj *desc;
  
  	    TclNewObj(desc);
  	    Tcl_DictObjPut(NULL, desc, Tcl_NewStringObj("name", -1), auxDesc);
  	    auxDesc = desc;
  	    auxData->type->disassembleProc(auxData->clientData, auxDesc,
  		    codePtr, 0);
  	} else if (auxData->type->printProc) {
  	    Tcl_Obj *desc;
  
  	    TclNewObj(desc);
  	    auxData->type->printProc(auxData->clientData, desc, codePtr, 0);
  	    Tcl_ListObjAppendElement(NULL, auxDesc, desc);
  	}
  	Tcl_ListObjAppendElement(NULL, aux, auxDesc);
      }
  
      /*
       * Get the exception ranges from the bytecode.
       */
  
      TclNewObj(exn);
      for (i=0 ; i<codePtr->numExceptRanges ; i++) {
  	ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i];
  
  	switch (rangePtr->type) {
  	case LOOP_EXCEPTION_RANGE:
  	    Tcl_ListObjAppendElement(NULL, exn, Tcl_ObjPrintf(
  		    "type %s level %d from %d to %d break %d continue %d",
  		    "loop", rangePtr->nestingLevel, rangePtr->codeOffset,
  		    rangePtr->codeOffset + rangePtr->numCodeBytes - 1,
  		    rangePtr->breakOffset, rangePtr->continueOffset));
  	    break;
  	case CATCH_EXCEPTION_RANGE:
  	    Tcl_ListObjAppendElement(NULL, exn, Tcl_ObjPrintf(
  		    "type %s level %d from %d to %d catch %d",
  		    "catch", rangePtr->nestingLevel, rangePtr->codeOffset,
  		    rangePtr->codeOffset + rangePtr->numCodeBytes - 1,
  		    rangePtr->catchOffset));
  	    break;
  	}
      }
  
      /*
       * Get the command information from the bytecode.
       *
       * The way these are encoded in the bytecode is non-trivial; the Decode
       * macro (which updates its argument and returns the next decoded value)
       * handles this so that the rest of the code does not.
       */
  
  #define Decode(ptr) \
      ((TclGetUInt1AtPtr(ptr) == 0xFF)			\
  	? ((ptr)+=5 , TclGetInt4AtPtr((ptr)-4))		\
  	: ((ptr)+=1 , TclGetInt1AtPtr((ptr)-1)))
  
      TclNewObj(commands);
      codeOffPtr = codePtr->codeDeltaStart;
      codeLenPtr = codePtr->codeLengthStart;
      srcOffPtr = codePtr->srcDeltaStart;
      srcLenPtr = codePtr->srcLengthStart;
      codeOffset = sourceOffset = 0;
      for (i=0 ; i<codePtr->numCommands ; i++) {
  	Tcl_Obj *cmd;
  
  	codeOffset += Decode(codeOffPtr);
  	codeLength = Decode(codeLenPtr);
  	sourceOffset += Decode(srcOffPtr);
  	sourceLength = Decode(srcLenPtr);
  	TclNewObj(cmd);
  	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codefrom", -1),
  		Tcl_NewWideIntObj(codeOffset));
  	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codeto", -1),
  		Tcl_NewWideIntObj(codeOffset + codeLength - 1));
  
  	/*
  	 * Convert byte offsets to character offsets; important if multibyte
  	 * characters are present in the source!
  	 */
  
  	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptfrom", -1),
  		Tcl_NewWideIntObj(Tcl_NumUtfChars(codePtr->source,
  			sourceOffset)));
  	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptto", -1),
  		Tcl_NewWideIntObj(Tcl_NumUtfChars(codePtr->source,
  			sourceOffset + sourceLength - 1)));
  	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("script", -1),
  		Tcl_NewStringObj(codePtr->source+sourceOffset, sourceLength));
  	Tcl_ListObjAppendElement(NULL, commands, cmd);
      }
  
  #undef Decode
  
      /*
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
       * Get the source file and line number information from the CmdFrame
       * system if it is available.
       */
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
      GetLocationInformation(interp, codePtr->procPtr, &file, &line);
  
      /*
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
      GetLocationInformation(codePtr->procPtr, &file, &line);
  
      /*
  >>>>>>> upstream/master
  =======
      GetLocationInformation(codePtr->procPtr, &file, &line);
  
      /*
  >>>>>>> upstream/master
  =======
      GetLocationInformation(codePtr->procPtr, &file, &line);
  
      /*
  >>>>>>> upstream/master
       * Build the overall result.
       */
  
      TclNewObj(description);
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("literals", -1),
  	    literals);
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("variables", -1),
  	    variables);
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exception", -1), exn);
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("instructions", -1),
  	    instructions);
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("auxiliary", -1), aux);
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("commands", -1),
  	    commands);
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("script", -1),
  	    Tcl_NewStringObj(codePtr->source, codePtr->numSrcBytes));
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("namespace", -1),
  	    Tcl_NewStringObj(codePtr->nsPtr->fullName, -1));
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("stackdepth", -1),
  	    Tcl_NewWideIntObj(codePtr->maxStackDepth));
      Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exceptdepth", -1),
  <<<<<<< HEAD
  	    Tcl_NewIntObj(codePtr->maxExceptDepth));
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      if (line > -1) {
  =======
  	    Tcl_NewWideIntObj(codePtr->maxExceptDepth));
      if (line >= 0) {
  >>>>>>> upstream/master
  	Tcl_DictObjPut(NULL, description,
  		Tcl_NewStringObj("initiallinenumber", -1),
  		Tcl_NewWideIntObj(line));
      }
      if (file) {
  	Tcl_DictObjPut(NULL, description,
  		Tcl_NewStringObj("sourcefile", -1), file);
      }
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      return description;
  }
  
  /*
   *----------------------------------------------------------------------
   *
   * Tcl_DisassembleObjCmd --
   *
   *	Implementation of the "::tcl::unsupported::disassemble" command. This
   *	command is not documented, but will disassemble procedures, lambda
   *	terms and general scripts. Note that will compile terms if necessary
   *	in order to disassemble them.
   *
   *----------------------------------------------------------------------
   */
  
  int
  Tcl_DisassembleObjCmd(
      ClientData clientData,	/* What type of operation. */
      Tcl_Interp *interp,		/* Current interpreter. */
      int objc,			/* Number of arguments. */
      Tcl_Obj *const objv[])	/* Argument objects. */
  {
      static const char *const types[] = {
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  	"lambda", "method", "objmethod", "proc", "script", NULL
      };
      enum Types {
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  	"constructor", "destructor",
  	"lambda", "method", "objmethod", "proc", "script", NULL
      };
      enum Types {
  	DISAS_CLASS_CONSTRUCTOR, DISAS_CLASS_DESTRUCTOR,
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  	DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC,
  	DISAS_SCRIPT
      };
      int idx, result;
      Tcl_Obj *codeObjPtr = NULL;
      Proc *procPtr = NULL;
      Tcl_HashEntry *hPtr;
      Object *oPtr;
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  =======
      Method *methodPtr;
  >>>>>>> upstream/master
  =======
  =======
      ByteCode *codePtr;
  >>>>>>> upstream/master
      Method *methodPtr;
  >>>>>>> upstream/master
  =======
      Method *methodPtr;
  >>>>>>> upstream/master
  =======
      ByteCode *codePtr;
      Method *methodPtr;
  >>>>>>> upstream/master
  
      if (objc < 2) {
  	Tcl_WrongNumArgs(interp, 1, objv, "type ...");
  	return TCL_ERROR;
      }
      if (Tcl_GetIndexFromObj(interp, objv[1], types, "type", 0, &idx)!=TCL_OK){
  	return TCL_ERROR;
      }
  
      switch ((enum Types) idx) {
      case DISAS_LAMBDA: {
  	Command cmd;
  	Tcl_Obj *nsObjPtr;
  	Tcl_Namespace *nsPtr;
  
  	/*
  	 * Compile (if uncompiled) and disassemble a lambda term.
  	 */
  
  	if (objc != 3) {
  	    Tcl_WrongNumArgs(interp, 2, objv, "lambdaTerm");
  	    return TCL_ERROR;
  	}
  
  	procPtr = TclGetLambdaFromObj(interp, objv[2], &nsObjPtr);
  	if (procPtr == NULL) {
  	    return TCL_ERROR;
  	}
  
  	memset(&cmd, 0, sizeof(Command));
  	result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
  	if (result != TCL_OK) {
  	    return result;
  	}
  	cmd.nsPtr = (Namespace *) nsPtr;
  	procPtr->cmdPtr = &cmd;
  	result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1);
  	if (result != TCL_OK) {
  	    return result;
  	}
  	TclPopStackFrame(interp);
  	codeObjPtr = procPtr->bodyPtr;
  	break;
      }
      case DISAS_PROC:
  	if (objc != 3) {
  	    Tcl_WrongNumArgs(interp, 2, objv, "procName");
  	    return TCL_ERROR;
  	}
  
  	procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2]));
  	if (procPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  		    "\"%s\" isn't a procedure", TclGetString(objv[2])));
  	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC",
  		    TclGetString(objv[2]), NULL);
  	    return TCL_ERROR;
  	}
  
  	/*
  	 * Compile (if uncompiled) and disassemble a procedure.
  	 */
  
  	result = TclPushProcCallFrame(procPtr, interp, 2, objv+1, 1);
  	if (result != TCL_OK) {
  	    return result;
  	}
  	TclPopStackFrame(interp);
  	codeObjPtr = procPtr->bodyPtr;
  	break;
      case DISAS_SCRIPT:
  	/*
  	 * Compile and disassemble a script.
  	 */
  
  	if (objc != 3) {
  	    Tcl_WrongNumArgs(interp, 2, objv, "script");
  	    return TCL_ERROR;
  	}
  
  <<<<<<< HEAD
  	if ((NULL == Tcl_FetchIntRep(objv[2], &tclByteCodeType)) && (TCL_OK
  =======
  	if (!TclHasIntRep(objv[2], &tclByteCodeType) && (TCL_OK
  >>>>>>> upstream/master
  		!= TclSetByteCodeFromAny(interp, objv[2], NULL, NULL))) {
  	    return TCL_ERROR;
  	}
  	codeObjPtr = objv[2];
  	break;
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      case DISAS_CLASS_CONSTRUCTOR:
  	if (objc != 3) {
  	    Tcl_WrongNumArgs(interp, 2, objv, "className");
  	    return TCL_ERROR;
  	}
  
  	/*
  	 * Look up the body of a constructor.
  	 */
  
  	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
  	if (oPtr == NULL) {
  	    return TCL_ERROR;
  	}
  	if (oPtr->classPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  		    "\"%s\" is not a class", TclGetString(objv[2])));
  	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
  		    TclGetString(objv[2]), NULL);
  	    return TCL_ERROR;
  	}
  
  	methodPtr = oPtr->classPtr->constructorPtr;
  	if (methodPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  		    "\"%s\" has no defined constructor",
  		    TclGetString(objv[2])));
  	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
  		    "CONSRUCTOR", NULL);
  	    return TCL_ERROR;
  	}
  	procPtr = TclOOGetProcFromMethod(methodPtr);
  	if (procPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
  		    "body not available for this kind of constructor", -1));
  	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
  		    "METHODTYPE", NULL);
  	    return TCL_ERROR;
  	}
  
  	/*
  	 * Compile if necessary.
  	 */
  
  <<<<<<< HEAD
  	if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
  =======
  	if (!TclHasIntRep(procPtr->bodyPtr, &tclByteCodeType)) {
  >>>>>>> upstream/master
  	    Command cmd;
  
  	    /*
  	     * Yes, this is ugly, but we need to pass the namespace in to the
  	     * compiler in two places.
  	     */
  
  	    cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
  	    procPtr->cmdPtr = &cmd;
  	    result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
  		    (Namespace *) oPtr->namespacePtr, "body of constructor",
  		    TclGetString(objv[2]));
  	    procPtr->cmdPtr = NULL;
  	    if (result != TCL_OK) {
  		return result;
  	    }
  	}
  	codeObjPtr = procPtr->bodyPtr;
  	break;
  
      case DISAS_CLASS_DESTRUCTOR:
  	if (objc != 3) {
  	    Tcl_WrongNumArgs(interp, 2, objv, "className");
  	    return TCL_ERROR;
  	}
  
  	/*
  	 * Look up the body of a destructor.
  	 */
  
  	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
  	if (oPtr == NULL) {
  	    return TCL_ERROR;
  	}
  	if (oPtr->classPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  		    "\"%s\" is not a class", TclGetString(objv[2])));
  	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
  		    TclGetString(objv[2]), NULL);
  	    return TCL_ERROR;
  	}
  
  	methodPtr = oPtr->classPtr->destructorPtr;
  	if (methodPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  		    "\"%s\" has no defined destructor",
  		    TclGetString(objv[2])));
  	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
  		    "DESRUCTOR", NULL);
  	    return TCL_ERROR;
  	}
  	procPtr = TclOOGetProcFromMethod(methodPtr);
  	if (procPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
  		    "body not available for this kind of destructor", -1));
  	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
  		    "METHODTYPE", NULL);
  	    return TCL_ERROR;
  	}
  
  	/*
  	 * Compile if necessary.
  	 */
  
  <<<<<<< HEAD
  	if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
  =======
  	if (!TclHasIntRep(procPtr->bodyPtr, &tclByteCodeType)) {
  >>>>>>> upstream/master
  	    Command cmd;
  
  	    /*
  	     * Yes, this is ugly, but we need to pass the namespace in to the
  	     * compiler in two places.
  	     */
  
  	    cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
  	    procPtr->cmdPtr = &cmd;
  	    result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
  		    (Namespace *) oPtr->namespacePtr, "body of destructor",
  		    TclGetString(objv[2]));
  	    procPtr->cmdPtr = NULL;
  	    if (result != TCL_OK) {
  		return result;
  	    }
  	}
  	codeObjPtr = procPtr->bodyPtr;
  	break;
  
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
      case DISAS_CLASS_METHOD:
  	if (objc != 4) {
  	    Tcl_WrongNumArgs(interp, 2, objv, "className methodName");
  	    return TCL_ERROR;
  	}
  
  	/*
  	 * Look up the body of a class method.
  	 */
  
  	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
  	if (oPtr == NULL) {
  	    return TCL_ERROR;
  	}
  	if (oPtr->classPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  		    "\"%s\" is not a class", TclGetString(objv[2])));
  	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
  		    TclGetString(objv[2]), NULL);
  	    return TCL_ERROR;
  	}
  	hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods,
  		(char *) objv[3]);
  	goto methodBody;
      case DISAS_OBJECT_METHOD:
  	if (objc != 4) {
  	    Tcl_WrongNumArgs(interp, 2, objv, "objectName methodName");
  	    return TCL_ERROR;
  	}
  
  	/*
  	 * Look up the body of an instance method.
  	 */
  
  	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
  	if (oPtr == NULL) {
  	    return TCL_ERROR;
  	}
  	if (oPtr->methodsPtr == NULL) {
  	    goto unknownMethod;
  	}
  	hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[3]);
  
  	/*
  	 * Compile (if necessary) and disassemble a method body.
  	 */
  
      methodBody:
  	if (hPtr == NULL) {
  	unknownMethod:
  	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  		    "unknown method \"%s\"", TclGetString(objv[3])));
  	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
  		    TclGetString(objv[3]), NULL);
  	    return TCL_ERROR;
  	}
  	procPtr = TclOOGetProcFromMethod((Method *)Tcl_GetHashValue(hPtr));
  	if (procPtr == NULL) {
  	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
  		    "body not available for this kind of method", -1));
  	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
  		    "METHODTYPE", NULL);
  	    return TCL_ERROR;
  	}
  <<<<<<< HEAD
  	if (NULL == Tcl_FetchIntRep(procPtr->bodyPtr, &tclByteCodeType)) {
  =======
  	if (!TclHasIntRep(procPtr->bodyPtr, &tclByteCodeType)) {
  >>>>>>> upstream/master
  	    Command cmd;
  
  	    /*
  	     * Yes, this is ugly, but we need to pass the namespace in to the
  	     * compiler in two places.
  	     */
  
  	    cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
  	    procPtr->cmdPtr = &cmd;
  	    result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
  		    (Namespace *) oPtr->namespacePtr, "body of method",
  		    TclGetString(objv[3]));
  	    procPtr->cmdPtr = NULL;
  	    if (result != TCL_OK) {
  		return result;
  	    }
  	}
  	codeObjPtr = procPtr->bodyPtr;
  	break;
      default:
  	CLANG_ASSERT(0);
      }
  
      /*
       * Do the actual disassembly.
       */
  
      ByteCodeGetIntRep(codeObjPtr, &tclByteCodeType, codePtr);
  
      if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
  	Tcl_SetObjResult(interp, Tcl_NewStringObj(
  		"may not disassemble prebuilt bytecode", -1));
  	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
  		"BYTECODE", NULL);
  	return TCL_ERROR;
      }
  <<<<<<< HEAD
  <<<<<<< HEAD
      if (PTR2INT(clientData)) {
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  	Tcl_SetObjResult(interp, DisassembleByteCodeAsDicts(codeObjPtr));
      } else {
  	Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr));
  =======
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
      if (clientData) {
  >>>>>>> upstream/master
  =======
      if (clientData) {
  >>>>>>> upstream/master
  	Tcl_SetObjResult(interp,
  		DisassembleByteCodeAsDicts(codeObjPtr));
      } else {
  	Tcl_SetObjResult(interp,
  <<<<<<< HEAD
  		DisassembleByteCodeObj(interp, codeObjPtr));
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  <<<<<<< HEAD
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  >>>>>>> upstream/master
  =======
  		DisassembleByteCodeObj(codeObjPtr));
  >>>>>>> upstream/master
      }
      return TCL_OK;
  }
  
  /*
   * Local Variables:
   * mode: c
   * c-basic-offset: 4
   * fill-column: 78
   * tab-width: 8
   * End:
   */
  