Main Page   Class Hierarchy   Compound List   File List   Header Files   Compound Members   File Members  

byteCodes.h

This is the verbatim text of the byteCodes.h include file.
/* Sun-$Revision: 23.6 $ */

/* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University.
   See the LICENSE file for license information. */

# pragma interface

# define OPWIDTH        4
# define INDEXWIDTH     (8 - OPWIDTH)

# define MAXOP          nthMask(OPWIDTH)
# define MAXINDEX       nthMask(INDEXWIDTH)

enum ByteCodeKind {
  INDEX_CODE,           // shift index left, OR in my index field
  LITERAL_CODE,         // push lits[index]
  SEND_CODE,            // send w/ receiver on stack,
                        // selector in literals[indx]
  IMPLICIT_SEND_CODE,   // send w/ implicit receiver,
                        // selector in literals[indx]
  
  NO_OPERAND_CODE,      // no operand, opcode in index bits, see NoOparandKind
  READ_LOCAL_CODE,      // read  local; lexical lvl in lex reg, see below
  WRITE_LOCAL_CODE,     // write local; lexical lvl in lex reg, see below
  LEXICAL_LEVEL_CODE,   // lexical level of next RW_LOCAL op
  
  BRANCH_CODE,          // uncond branch via lit
  BRANCH_TRUE_CODE,     // branch on true via literal
  BRANCH_FALSE_CODE,    // branch on false via literal
  BRANCH_INDEXED_CODE,  // branch via literal vector, index on stack
  
  DELEGATEE_CODE        // delegate next send to lits[index]
};

enum NoOperandKind {
  SELF_CODE,              // push self onto stack
  POP_CODE,               // pop value from stack
  NONLOCAL_RETURN_CODE,   // non-local-return from block
  UNDIRECTED_RESEND_CODE  // next send is an undirected resend
};

inline ByteCodeKind getOp(u_char c) { return ByteCodeKind(c >> INDEXWIDTH); }
inline fint getIndex(fint c)        { return c & MAXINDEX; }
inline NoOperandKind getNoOpOp(u_char c) {return NoOperandKind(getIndex(c));}

inline bool isSendOp(ByteCodeKind op)   {
  return op == SEND_CODE || op == IMPLICIT_SEND_CODE;
}

inline fint BuildCode(fint op, fint x) {
  assert(x <= MAXINDEX, "bad index");
  return (op << INDEXWIDTH) | x; 
}
  
    
// the position table is generated by a parallel process, so
//  have one abstract superclass:

class AbstractByteCode: public preservedVmObj {
 public:
  
  objVectorOop literals;
  fint literalIndex;
  fint maxLiteralIndex;
  int32 stack_depth; // for branch checking

   LabelSet*  labelSet;
  BranchSet* branchSet;
  
  char* errorMessage;
  
 public:
 
   AbstractByteCode( objVectorOop lits = NULL) {
     if ( lits == NULL ) {
       literals= Memory->literalsObj->cloneSize(50);
       literalIndex= 0;
     }
     else {
       literals = lits;
       literalIndex= lits->length();
     }
     maxLiteralIndex= literals->length();

     stack_depth= 0;
     labelSet=  new LabelSet;
     branchSet= new BranchSet;
     errorMessage = "";
   }
   
  // generation routines
  
  void GenLiteralByteCode(   fint offset, fint length, oop literal);
  void GenDelegateeByteCode( fint offset, fint length, stringOop delegatee);

  void GenSendByteCode( fint offset, fint length,
                        stringOop selector, 
                        bool isSelfImplicit,
                        bool isUndirectedResend,
                        stringOop resendTarget);

  void GenSelfByteCode(fint offset, fint length);
  void GenPopByteCode( fint offset, fint length);
  void GenUndirectedResendByteCode( fint offset, fint length);
  void GenNonLocalReturnByteCode(fint offset, fint length);
  void GenRWLocalByteCode( fint offset, fint length,
                           bool isRead,
                           int32 lexicalLevel,
                           int32 index);
                           
  bool GenBranchByteCode(        fint offset, fint length, oop label);
  bool GenBranchTrueByteCode(    fint offset, fint length, oop label);
  bool GenBranchFalseByteCode(   fint offset, fint length, oop label);
  bool GenBranchIndexedByteCode( fint offset, fint length, objVectorOop labels);
  
  bool GenLabelDefinition( oop label);
  
  bool ResolveBranches();
                           

  // preserve  operation
  void oops_do(oopsDoFn f) { 
    (*f)((oop*)&literals);
    branchSet->oops_do(f);
    labelSet->oops_do(f);
  }
  // helpers
  virtual bool isPositionTable() = 0;
  virtual void GenCode(fint offset, fint length, fint c) = 0;
  virtual fint bci() = 0;

  bool GenSimpleBranchByteCode( fint offset,
                                fint length,
                                oop label,
                                ByteCodeKind op );
  fint GenLiteral(oop p);
  // must make a new object so literal slot won't get reused
  fint GenLabelLiteral() { return GenLiteral( Memory->nilObj->clone()); }
  fint GenIndex(fint offset, fint length, fint x);
  fint GenExtendedIndex(fint offset, fint length, fint x);

  int32 getLabelIndex( oop label);
};

class ByteCode: public AbstractByteCode {
 public:
  
  // instance variables
  byteVectorOop codes; // the finished vector is a canonical string
  fint codeIndex;
  fint maxCodeIndex;
  
  stringOop file;
  smiOop    line;
  stringOop source;
  smiOop    sourceOffset;
  smiOop    sourceLen;

  // constructors
       
  ByteCode() 
  : AbstractByteCode() {
    maxCodeIndex = 100;
    codeIndex = 0;
    codes= Memory->byteVectorObj->cloneSize(maxCodeIndex);
    file = NULL; source = NULL;     // must initialize for GC
    sourceOffset= smiOop_zero;
    sourceLen=    smiOop_zero;
  }

  
  ByteCode(byteVectorOop c,  objVectorOop l, stringOop f, smiOop ln, 
           stringOop s) 
        : AbstractByteCode( l ) {
    codes = c;
    codeIndex = maxCodeIndex = c->length();

    file = f;
    line = ln;
    source = s;
    sourceOffset= smiOop_zero;
    sourceLen=    smiOop_zero;
  }


  bool Finish();
  bool Finish(char* fname, fint sourceLine, char* srcStart, fint srcLen);
  bool Finish(char* fname, char* src);
  bool Finish(char* fname, fint sourceLine, fint srcOffset, fint srcLen);
  
  // preserve  operation
  void oops_do(oopsDoFn f) { 
    AbstractByteCode::oops_do(f);
    (*f)((oop*)&codes);
    (*f)((oop*)&file);
    (*f)((oop*)&source);
  }


  // helpers

  bool isPositionTable() { return false; }
  
  void GenCode(fint offset, fint length, fint c);
  
  fint bci() { return codeIndex; }
  

  // programming

  friend oop create_outer_method_prim( oop ignore,
                                       byteVectorOop bv,
                                       objVectorOop lits,
                                       stringOop file,
                                       smiOop line,
                                       stringOop source);
  
  friend oop create_block_method_prim( oop ignore,
                                      byteVectorOop bv,
                                      objVectorOop lits,
                                      stringOop file,
                                      smiOop line,
                                      stringOop source);
};

Generated at Tue Jun 27 12:07:06 2000 for SelfVM by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999