//
// Copyright (c) 2006, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 26 Dec 05 Brian Frank Creation
// 19 Aug 06 Brian Frank Ported from Java to Fan
//
**
** FMethod is the read/write fcode representation of sys::Method.
**
class FMethod : FSlot, CMethod
{
//////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////
new make(FType fparent)
: super(fparent)
{
}
//////////////////////////////////////////////////////////////////////////
// Access
//////////////////////////////////////////////////////////////////////////
FMethodVar[] fparams()
{
return vars.findAll |FMethodVar v->Bool| { v.isParam }
}
//////////////////////////////////////////////////////////////////////////
// CMethod
//////////////////////////////////////////////////////////////////////////
override CType returnType() { fparent.fpod.toType(ret) }
override CParam[] params() { fparams }
override Str signature()
{
return "$returnType $name(" + params.join(",") + ")"
}
override once Bool isGeneric()
{
return calcGeneric(this)
}
override CType inheritedReturnType()
{
return fparent.fpod.toType(inheritedRet)
}
//////////////////////////////////////////////////////////////////////////
// IO
//////////////////////////////////////////////////////////////////////////
Void write(OutStream out)
{
super.writeCommon(out)
out.writeI2(ret)
out.writeI2(inheritedRet)
out.write(maxStack)
out.write(paramCount)
out.write(localCount)
vars.each |FMethodVar var| { var.write(out) }
FUtil.writeBuf(out, code)
FUtil.writeAttrs(out, fattrs)
}
This read(InStream in)
{
super.readCommon(in)
ret = in.readU2
inheritedRet = in.readU2
maxStack = in.readU1
paramCount = in.readU1
localCount = in.readU1
vars = FMethodVar[,];
(paramCount+localCount).times { vars.add(FMethodVar(this).read(in)) }
code = FUtil.readBuf(in)
fattrs = FUtil.readAttrs(in)
return this
}
Void dump()
{
p := FPrinter(fparent.fpod)
p.showCode = true
p.method(this)
}
//////////////////////////////////////////////////////////////////////////
// Fields
//////////////////////////////////////////////////////////////////////////
Int ret // type qname index
Int inheritedRet // type qname index
FMethodVar[]? vars // parameters and local variables
Int paramCount // number of params in vars
Int localCount // number of locals in vars
Buf? code // method executable code
Int maxStack := 16 // TODO - need to calculate in compiler
}
**************************************************************************
** FMethodVar
**************************************************************************
**
** FMethodVar models one parameter or local variable in a FMethod
**
class FMethodVar : FConst, CParam
{
new make(FMethod fmethod) { this.fmethod = fmethod }
override Str name() { fpod.n(nameIndex) }
override CType paramType() { fpod.toType(typeRef) }
override Bool hasDefault() { def != null }
override Str toStr() { "$paramType $name" }
Bool isParam() { flags.and(FConst.Param) != 0 }
Void write(OutStream out)
{
out.writeI2(nameIndex)
out.writeI2(typeRef)
out.write(flags)
// we currently only support the DefaultParam attr
if (def == null) out.writeI2(0)
else
{
out.writeI2(1)
out.writeI2(defNameIndex)
FUtil.writeBuf(out, def)
}
}
FMethodVar read(InStream in)
{
nameIndex = in.readU2
typeRef = in.readU2
flags = in.readU1
// we currently only support the DefaultParam attr
in.readU2.times
{
attrNameIndex := in.readU2
attrBuf := FUtil.readBuf(in)
if (fmethod.pod.n(attrNameIndex) == ParamDefaultAttr)
{
defNameIndex = attrNameIndex
def = attrBuf
}
}
return this
}
FPod fpod() { fmethod.fparent.fpod }
FMethod fmethod
Int nameIndex // name index
Int typeRef // typeRef index
Int flags // method variable flags
Int defNameIndex // name index of DefaultParamAttr
Buf? def // default expression or null (only for params)
}