
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 }