logo

class

compiler::FMethod

sys::Obj
  compiler::FSlot
    compiler::FMethod : compiler::CMethod
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   26 Dec 05  Brian Frank  Creation
   7  //   19 Aug 06  Brian Frank  Ported from Java to Fan
   8  //
   9  
  10  **
  11  ** FMethod is the read/write fcode representation of sys::Method.
  12  **
  13  class FMethod : FSlot, CMethod
  14  {
  15  
  16  //////////////////////////////////////////////////////////////////////////
  17  // Constructor
  18  //////////////////////////////////////////////////////////////////////////
  19  
  20    new make(FType fparent)
  21      : super(fparent)
  22    {
  23    }
  24  
  25  //////////////////////////////////////////////////////////////////////////
  26  // Access
  27  //////////////////////////////////////////////////////////////////////////
  28  
  29    FMethodVar[] fparams()
  30    {
  31      return vars.findAll |FMethodVar v->Bool| { return v.isParam }
  32    }
  33  
  34  //////////////////////////////////////////////////////////////////////////
  35  // CMethod
  36  //////////////////////////////////////////////////////////////////////////
  37  
  38    override CType returnType() { return fparent.fpod.toType(ret) }
  39    override CParam[] params() { return fparams }
  40  
  41    override Str signature()
  42    {
  43      return "$returnType $name(" + params.join(",") + ")"
  44    }
  45  
  46    override Bool isGeneric
  47    {
  48      get
  49      {
  50        if (@isGeneric == null) @isGeneric = calcGeneric(this)
  51        return @isGeneric
  52      }
  53    }
  54  
  55    override CType inheritedReturnType()
  56    {
  57      return fparent.fpod.toType(inheritedRet)
  58    }
  59  
  60  //////////////////////////////////////////////////////////////////////////
  61  // IO
  62  //////////////////////////////////////////////////////////////////////////
  63  
  64    Void write(OutStream out)
  65    {
  66      super.writeCommon(out)
  67      out.writeI2(ret)
  68      out.writeI2(inheritedRet)
  69      out.write(maxStack)
  70      out.write(paramCount)
  71      out.write(localCount)
  72      vars.each |FMethodVar var| { var.write(out) }
  73      FUtil.writeBuf(out, code)
  74      super.writeAttrs(out)
  75    }
  76  
  77    FMethod read(InStream in)
  78    {
  79      super.readCommon(in)
  80      ret = in.readU2
  81      inheritedRet = in.readU2
  82      maxStack   = in.readU1
  83      paramCount = in.readU1
  84      localCount = in.readU1
  85      vars = FMethodVar[,];
  86      (paramCount+localCount).times |,| { vars.add(FMethodVar.make(this).read(in)) }
  87      code = FUtil.readBuf(in)
  88      super.readAttrs(in)
  89      return this
  90    }
  91  
  92  //////////////////////////////////////////////////////////////////////////
  93  // Fields
  94  //////////////////////////////////////////////////////////////////////////
  95  
  96    Int ret              // type qname index
  97    Int inheritedRet     // type qname index
  98    FMethodVar[] vars    // parameters and local variables
  99    Int paramCount       // number of params in vars
 100    Int localCount       // number of locals in vars
 101    Buf code             // method executable code
 102    Int maxStack := 16   // TODO - need to calculate in compiler
 103  
 104  }
 105  
 106  **************************************************************************
 107  ** FMethodVar
 108  **************************************************************************
 109  
 110  **
 111  ** FMethodVar models one parameter or local variable in a FMethod
 112  **
 113  class FMethodVar : FConst, CParam
 114  {
 115    new make(FMethod fmethod) { this.fmethod = fmethod }
 116  
 117    override Str name() { return fpod.n(nameIndex) }
 118    override CType paramType() { return fpod.toType(typeRef) }
 119    override Bool hasDefault() { return def != null }
 120    override Str toStr() { return "$paramType $name" }
 121  
 122    Bool isParam()  { return flags & FConst.Param != 0 }
 123  
 124    Void write(OutStream out)
 125    {
 126      out.writeI2(nameIndex)
 127      out.writeI2(typeRef)
 128      out.write(flags)
 129  
 130      // we currently only support the DefaultParam attr
 131      if (def == null) out.writeI2(0)
 132      else
 133      {
 134        out.writeI2(1)
 135        out.writeI2(defNameIndex)
 136        FUtil.writeBuf(out, def)
 137      }
 138    }
 139  
 140    FMethodVar read(InStream in)
 141    {
 142      nameIndex = in.readU2
 143      typeRef   = in.readU2
 144      flags     = in.readU1
 145  
 146      // we currently only support the DefaultParam attr
 147      in.readU2.times |,|
 148      {
 149        attrNameIndex := in.readU2
 150        attrBuf  := FUtil.readBuf(in)
 151        if (fmethod.pod.n(attrNameIndex) == ParamDefaultAttr)
 152        {
 153          defNameIndex = attrNameIndex
 154          def = attrBuf
 155        }
 156      }
 157      return this
 158    }
 159  
 160    FPod fpod() { return fmethod.fparent.fpod }
 161  
 162    readonly FMethod fmethod
 163    Int nameIndex    // name index
 164    Int typeRef      // typeRef index
 165    Int flags        // method variable flags
 166    Int defNameIndex // name index of DefaultParamAttr
 167    Buf def          // default expression or null (only for params)
 168  
 169  }