home *** CD-ROM | disk | FTP | other *** search
Wrap
package espresso; import java.util.Enumeration; import java.util.Hashtable; class FunDef extends Def { boolean isInitializer = false; boolean isConstructor = false; Block body; AST[] thrown; VarDef[] params; AST dcltyp; void print(int var1) { System.out.print(Obj.modNames(super.mods)); if (this.dcltyp != null) { this.dcltyp.print(); } System.out.print(String.valueOf(String.valueOf(" ").concat(String.valueOf(super.name))).concat(String.valueOf("("))); AST.printSeq(this.params); System.out.print(") "); AST.printSeq(this.thrown); if (this.body != null) { this.body.print(); } else { System.out.print(";"); } } Item gen() { FunObj var1 = (FunObj)super.obj; FunTyp var2 = (FunTyp)var1.typ; if (super.tag == 66) { Try var3 = (Try)super.localEnv.next.parent; Gen.registerCatch(var3.startPc, var3.endPc, Gen.curPc(), Gen.mkref(var2.argtyps[0])); Gen.entryPoint(1, var3.uninits); int var4 = Gen.nextLocal(); Gen.adrLocal((VarObj)this.params[0].obj, var3.excVar.disp); var3.excVar.store(var2.argtyps[0]); this.body.genDrop(); Gen.endScopes(var4); } else if (this.body != null) { this.genTry(false); } return Item.voidItem; } private void genTry(boolean var1) { FunObj var2 = (FunObj)super.obj; FunTyp var3 = (FunTyp)var2.typ; var2.code = Gen.newCode(var2, false, var1); if ((super.mods & 8) == 0) { Gen.newLocal(var2.owner.typ); } for(int var4 = 0; var4 < this.params.length; ++var4) { Gen.adrLocal((VarObj)this.params[var4].obj, Gen.newLocal(this.params[var4].obj.typ)); } Gen.entryPoint(0, new Bits()); byte var5 = 0; if (this.isInitializer) { this.body.stats[0].genDrop(); ClassDef var6 = super.localEnv.enclClass; for(int var7 = 0; var7 < var6.initcode.cp; ++var7) { Gen.emit1(var6.initcode.code[var7] & 255); } if (var2.code.max_stack < var6.initcode.max_stack) { var2.code.max_stack = var6.initcode.max_stack; } var5 = 1; } for(int var8 = var5; var8 < this.body.stats.length; ++var8) { this.body.stats[var8].genDrop(); } Gen.endScopes(0); if (Gen.alive) { if (var3.restyp.tag != 12) { Report.error(super.pos, "missing function return"); Gen.alive = false; } else { Gen.emitop(177); } } if (!var1 && var2.code.fatCode) { boolean var9 = Report.silent; Report.silent = true; this.genTry(true); Report.silent = var9; } } AST simplify() { FunTyp var1 = (FunTyp)((FunObj)super.obj).typ; if (this.dcltyp != null) { this.dcltyp = Simplify.annot(this.dcltyp.simplify(), var1.restyp); } for(int var2 = 0; var2 < this.thrown.length; ++var2) { this.thrown[var2] = this.thrown[var2].simplify(); } if (this.body != null) { this.body = (Block)this.body.simplify(); } ASTS var3 = this.simplifyParams(); if (var3.length != 0) { var3.append(new ASTS(this.body.stats)); this.body = new Block(0, var3); } if (super.tag == 67) { return this.makeClosure(var1.restyp); } else { super.obj = null; return this; } } private AST makeClosure(Typ var1) { ASTS var2 = new ASTS(); ASTS var3 = new ASTS(); Enumeration var4 = ((FunObj)super.obj).freevars.elements(); while(var4.hasMoreElements()) { VarObj var5 = (VarObj)var4.nextElement(); Object var6 = var5.typ; if (var5.passByRef) { var6 = new ArrayTyp((Typ)var6); } var2.append(new VarDef(super.pos, var5.name, 0, Simplify.annot(Simplify.toAST(super.pos, (Typ)var6), (Typ)var6), (AST)null)); var3.append(Simplify.box(new Ident(super.pos, var5.name))); } ClassObj var7 = (ClassObj)super.localEnv.enclClass.obj; int var8 = super.localEnv.enclClass.closures.length + Simplify.totalClosures(var7.superclass); super.name = Name.fromString(String.valueOf("$closure").concat(String.valueOf(var8))); super.mods = super.localEnv.isStatic ? 8 : 0; super.tag = 65; this.dcltyp = Simplify.annot(Simplify.toAST(super.pos, var1), var1); if (var2.length != 0) { VarDef[] var9 = this.params; this.params = new VarDef[var2.length + var9.length]; for(int var10 = 0; var10 < var2.length; ++var10) { this.params[var10] = (VarDef)var2.elems[var10]; } for(int var11 = 0; var11 < var9.length; ++var11) { this.params[var2.length + var11] = var9[var11]; } } super.localEnv.enclClass.closures.append(this); Object var12 = super.localEnv.isStatic ? new Ident(super.pos, Simplify.nullS) : new Self(super.pos, 80); return new New(super.pos, new Apply(super.pos, new Ident(super.pos, super.localEnv.enclClass.name.append(Simplify.closureS)), new ASTS(new Aggregate(super.pos, var3), (AST)var12, new Literal(super.pos, 90, new Integer(var8))))); } private ASTS simplifyParams() { ASTS var1 = new ASTS(); for(int var2 = 0; var2 < this.params.length; ++var2) { VarObj var3 = (VarObj)this.params[var2].obj; this.params[var2] = (VarDef)this.params[var2].simplify(); VarDef var4 = this.params[var2]; if (var3.passByRef) { var4.name = var4.name.append(Simplify.dollarS); AST var5 = Simplify.annot(new Subscript(var4.dcltyp.pos, Simplify.strip(var4.dcltyp), (AST)null), new ArrayTyp(var3.typ)); var1.append(new VarDef(var4.pos, var3.name, 0, var5, new Ident(var4.pos, var4.name))); } } return var1; } void markCaptured(Bits var1) { switch (super.tag) { case 65: if (this.body != null) { this.body.markCaptured(new Bits()); } break; case 66: this.body.markCaptured(var1); break; case 67: Enumeration var2 = ((FunObj)super.obj).freevars.elements(); while(var2.hasMoreElements()) { var1.incl(((VarObj)var2.nextElement()).vnum); } this.body.markCaptured(var1); break; default: throw new CompilerError("markcaptured"); } } Typ attr(Env var1, int var2, Typ var3) { if (super.obj == null) { this.enter(var1); } for(int var4 = 0; var4 < this.thrown.length; ++var4) { Attr.checkTyp(this.thrown[var4].pos, this.thrown[var4].typ, Predef.throwableTyp); } if (super.name != null) { this.checkOverridden(var1.scope); } super.typ = var3; if (this.body == null) { if (!var1.isInterface() && (super.mods & 1280) == 0) { Report.error(super.pos, "missing function body, or declare as abstract"); } } else if (var1.isInterface()) { Report.error(super.pos, "interface methods cannot have body"); this.body = null; } else if ((super.mods & 1024) != 0) { Report.error(super.pos, "abstract methods cannot have body"); this.body = null; } else if ((super.mods & 256) != 0) { Report.error(super.pos, "native methods cannot have body"); this.body = null; } else { super.localEnv.scope.restore(); switch (super.tag) { case 65: this.attrFun(); break; case 66: super.typ = this.body.attr(super.localEnv, 12, var3); break; case 67: ((FunObj)super.obj).freevars = new Hashtable(10); this.attrFun(); FunTyp var5 = (FunTyp)super.obj.typ; var5.restyp = this.body.typ.tag == 16 ? Typ.voidTyp : this.body.typ; super.typ = Attr.checkTyp(super.pos, var5, var3); ++((ClassObj)super.localEnv.enclClass.obj).nclosures; } super.localEnv.scope.leave(); } return super.typ; } private void attrFun() { byte var1 = 0; if (this.isConstructor && !((ClassObj)super.localEnv.enclClass.obj).isRoot()) { this.attrConstructorCall(); var1 = 1; } FunTyp var2 = (FunTyp)super.obj.typ; this.body.typ = var2.restyp; for(int var3 = var1; var3 < this.body.stats.length; ++var3) { this.body.typ = Attr.join(this.body.stats[var3].pos, this.body.typ, this.body.stats[var3].attr(super.localEnv, 12, var2.restyp)); } } private void attrConstructorCall() { if (this.body.stats.length <= 0 || !isSelfCall(this.body.stats[0])) { this.body.pushStat(new Exec(super.pos, new Apply(super.pos, new Self(super.pos, 81), new ASTS()))); } this.isInitializer = ((Apply)((Exec)this.body.stats[0]).expr).fn.tag == 81; this.body.stats[0].attr(super.localEnv, 32, Typ.voidTyp); } private static boolean isSelfCall(AST var0) { return var0.tag == 27 && ((Exec)var0).expr.tag == 5 && ((Apply)((Exec)var0).expr).fn instanceof Self; } void enter(Env var1) { this.isConstructor = super.name != null && super.name.equals(Predef.initS); FunObj var2 = new FunObj(); super.obj = var2; var2.name = super.name; var2.modifiers = Attr.completeMods(super.pos, super.mods, var1, this.isConstructor ? 7 : 1343, 1025); var2.owner = var1.scope.owner; switch (super.tag) { case 65: super.localEnv = new Env(var1, this, var1.enclClass.funscope.duplicate()); super.localEnv.scope.owner = var2; super.localEnv.enclMeth = this; break; case 66: super.localEnv = new Env(var1, this, var1.scope.duplicate()); break; case 67: super.localEnv = new Env(var1, this, var1.scope.duplicate()); super.localEnv.scope.owner = var2; } super.localEnv.enclFun = this; super.localEnv.isStatic = var1.isStatic || (var2.modifiers & 8) != 0; if (super.tag == 66) { this.enterCatch(var2); } else { this.enterFun(var1, var2); } } void enterFun(Env var1, FunObj var2) { Typ[] var3 = new Typ[this.params.length]; Typ[] var4 = new Typ[this.params.length]; boolean var5 = false; for(int var6 = 0; var6 < this.params.length; ++var6) { this.params[var6].attr(super.localEnv, 12, Typ.anyTyp); var3[var6] = this.params[var6].dcltyp.typ; var4[var6] = Simplify.trueType(this.params[var6].dcltyp); var5 = var5 || var3[var6] != var4[var6]; } super.localEnv.scope.leave(); Typ var7; Typ var8; if (this.isConstructor) { var7 = Typ.voidTyp; var8 = var7; } else if (this.dcltyp == null) { var7 = Typ.anyTyp; var8 = var7; } else { var7 = this.dcltyp.attr(var1, 2, Typ.anyTyp); var8 = Simplify.trueType(this.dcltyp); var5 = var5 || var7 != var8; } FunTyp var9 = new FunTyp(var3, var7, (TypSet)null); for(int var10 = 0; var10 < this.thrown.length; ++var10) { var9.thrown = TypSet.incl(var9.thrown, this.thrown[var10].attr(var1, 2, Typ.anyTyp)); } var2.typ = var9; if (var5) { var2.alttyp = new FunTyp(var4, var8, var9.thrown); } else { var2.alttyp = null; } super.localEnv.reported = var9.thrown; if (super.name != null && this.checkUnique(var1.scope)) { var1.scope.enter(var2); } } void enterCatch(FunObj var1) { this.params[0].attr(super.localEnv, 12, Predef.throwableTyp); Typ[] var2 = new Typ[]{this.params[0].obj.typ}; var1.typ = new FunTyp(var2, Typ.anyTyp, (TypSet)null); super.localEnv.scope.leave(); } private void checkOverridden(Scope var1) { for(ScopeEntry var2 = var1.lookup(super.name); var2.scope != null; var2 = var2.next()) { if (((FunObj)super.obj).overrides(var2.obj)) { Obj var3 = var2.obj; if ((var3.modifiers & 24) != 0) { Report.error(super.pos, String.valueOf(String.valueOf(String.valueOf(String.valueOf(Obj.modName(Obj.firstMod(var3.modifiers & 280))).concat(String.valueOf(" "))).concat(String.valueOf(var3))).concat(String.valueOf(Attr.location(var3)))).concat(String.valueOf(" cannot be overridden"))); return; } if ((super.obj.modifiers & 8) != 0) { Report.error(super.pos, String.valueOf(String.valueOf(String.valueOf("static ").concat(String.valueOf(super.obj))).concat(String.valueOf(Attr.location(super.obj)))).concat(String.valueOf(" cannot override"))); return; } if (this.protection(super.obj.modifiers) > this.protection(var3.modifiers)) { int var4 = var3.modifiers & 7; Report.error(super.pos, String.valueOf(String.valueOf(String.valueOf(String.valueOf("cannot override ").concat(String.valueOf(var3))).concat(String.valueOf(Attr.location(var3)))).concat(String.valueOf(" with weaker access privileges, was "))).concat(String.valueOf(var4 == 0 ? "package" : Obj.modName(Obj.firstMod(var4)).toString()))); return; } if (!((FunTyp)super.obj.typ).restyp.sametype(((FunTyp)var3.typ).restyp)) { Report.error(super.pos, String.valueOf(String.valueOf(String.valueOf(String.valueOf("cannot override ").concat(String.valueOf(var3))).concat(String.valueOf(Attr.location(var3)))).concat(String.valueOf(" with different return type, was "))).concat(String.valueOf(((FunTyp)var3.typ).restyp))); return; } Typ var5 = Attr.unHandled(((FunTyp)super.obj.typ).thrown, ((FunTyp)var3.typ).thrown); if (var5 != null) { Report.error(super.pos, String.valueOf(String.valueOf(String.valueOf(String.valueOf("overridden method ").concat(String.valueOf(var3))).concat(String.valueOf(Attr.location(var3)))).concat(String.valueOf(" does not throw "))).concat(String.valueOf(var5))); return; } } } } private int protection(int var1) { switch (var1 & 7) { case 0: return 2; case 1: return 0; case 2: return 4; case 3: case 5: default: throw new CompilerError("protection"); case 4: return 1; case 6: return 3; } } private boolean checkUnique(Scope var1) { ScopeEntry var2; for(var2 = var1.lookup(super.obj.name); var2.scope == var1 && (var2.obj == super.obj || !(var2.obj instanceof VarObj) && (!(var2.obj instanceof FunObj) || !Typ.subtypes(((FunTyp)super.obj.typ).argtyps, ((FunTyp)var2.obj.typ).argtyps) || !Typ.subtypes(((FunTyp)var2.obj.typ).argtyps, ((FunTyp)super.obj.typ).argtyps))); var2 = var2.next()) { } if (var2.scope == var1) { Report.error(super.pos, String.valueOf(String.valueOf("duplicate definition of ").concat(String.valueOf(var2.obj instanceof VarObj ? super.name.toString() : super.obj.toString()))).concat(String.valueOf(Attr.location(var1)))); return false; } else { return true; } } FunDef(int var1, int var2, Name var3, int var4, AST var5, ASTS var6, ASTS var7, Block var8) { super(var1, var2, var3, var4); this.dcltyp = var5; this.params = new VarDef[var6.length]; for(int var9 = 0; var9 < var6.length; ++var9) { this.params[var9] = (VarDef)var6.elems[var9]; } this.thrown = var7.shrink(); this.body = var8; } }