diff options
author | mihaylov <mihaylov@epfl.ch> | 2004-07-20 16:42:09 +0000 |
---|---|---|
committer | mihaylov <mihaylov@epfl.ch> | 2004-07-20 16:42:09 +0000 |
commit | 8991585adcacdfef75dc20ea267b6d8be6dc9df4 (patch) | |
tree | 2892712c4cd8200269f2c4b0c330e63b0e5755b1 /sources/scalac | |
parent | da852d8ff2f8e0a86a0eb7fe2fdb0f12ec7bbc12 (diff) | |
download | scala-8991585adcacdfef75dc20ea267b6d8be6dc9df4.tar.gz scala-8991585adcacdfef75dc20ea267b6d8be6dc9df4.tar.bz2 scala-8991585adcacdfef75dc20ea267b6d8be6dc9df4.zip |
- Small fixes
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/backend/msil/GenMSIL.java | 112 | ||||
-rw-r--r-- | sources/scalac/backend/msil/TypeCreator.java | 76 |
2 files changed, 134 insertions, 54 deletions
diff --git a/sources/scalac/backend/msil/GenMSIL.java b/sources/scalac/backend/msil/GenMSIL.java index c1c890442a..0374a8294c 100644 --- a/sources/scalac/backend/msil/GenMSIL.java +++ b/sources/scalac/backend/msil/GenMSIL.java @@ -100,10 +100,10 @@ public final class GenMSIL { */ public void apply(CompilationUnit unit) { currUnit = unit; -// try { - for (int i = 0; i < unit.body.length; i++) { - Tree tree = unit.body[i]; - Symbol sym = tree.symbol(); + for (int i = 0; i < unit.body.length; i++) { + Tree tree = unit.body[i]; + Symbol sym = tree.symbol(); + try { switch (tree) { case Empty: break; case ClassDef(_, _, _, _, _, Template(_, Tree[] body)): @@ -116,12 +116,13 @@ public final class GenMSIL { throw Debug.abort ("Illegal top-level definition: " + Debug.show(tree)); } - } -// } catch (Throwable e) { -// e.printStackTrace(); -// finalizeGen(); -// System.exit(1); -// } + } catch (Throwable e) { + currUnit.error(tree.pos, "Exception caught: " + e.getMessage()); + e.printStackTrace(); + tc.saveAssembly(); + System.exit(1); + } + } } /** @@ -246,7 +247,9 @@ public final class GenMSIL { */ private boolean willReturn; - private boolean enableTailCalls = true; + private boolean enableTailCalls = false; + + private Label methodEnd = null; /* * Generate code for constructors and methods. @@ -263,6 +266,7 @@ public final class GenMSIL { if (method.IsConstructor()) { ConstructorInfo ctor = (ConstructorInfo) method; code = ((ConstructorBuilder)ctor).GetILGenerator(); + methodEnd = code.DefineLabel(); if (global.args.debuginfo.value) code.setPosition(Position.line(rhs.pos)); if (sym.owner().isModuleClass() @@ -295,7 +299,7 @@ public final class GenMSIL { // emit the call to the superconstructor drop(gen(cstats[0], MSILType.VOID)); - code.Emit(OpCodes.Ret); // conclude the instance constructor + closeMethod(methodEnd); ConstructorBuilder cctor = ((TypeBuilder)(method.DeclaringType)). DefineConstructor((short)(MethodAttributes.Static | MethodAttributes.Public), @@ -314,11 +318,12 @@ public final class GenMSIL { code.Emit(OpCodes.Ret); // conclude the static constructor } else { drop(gen(rhs, MSILType.VOID)); - code.Emit(OpCodes.Ret); + closeMethod(methodEnd); } } else if (!method.IsAbstract()) { lastExpr = true; code = ((MethodBuilder)method).GetILGenerator(); + methodEnd = code.DefineLabel(); if (global.args.debuginfo.value) code.setPosition(Position.line(rhs.pos)); Item item = gen(rhs, toType); @@ -326,7 +331,7 @@ public final class GenMSIL { drop(item); else coerce(load(item), toType); // FIXME: coerce??? - code.Emit(OpCodes.Ret); + closeMethod(methodEnd); if (currentClass.isModuleClass()) { MethodBuilder staticMethod = tc.getStaticObjectMethod(sym); if (staticMethod != null) { @@ -344,8 +349,13 @@ public final class GenMSIL { lastExpr = false; code = null; + methodEnd = null; } // genDef(); + private void closeMethod(Label methodEnd) { + code.MarkLabel(methodEnd); + code.Emit(OpCodes.Ret); + } /* * Check if the result type of a method is void @@ -355,6 +365,14 @@ public final class GenMSIL { (((MethodInfo)method).ReturnType == tc.VOID); } + private boolean returnsVoid(Symbol fun) { + switch (fun.type()) { + case MethodType(_, scalac.symtab.Type restype): + return restype.isSameAs(defs.UNIT_TYPE().unbox()); + default: + return false; + } + } /* * Emit the code for this. @@ -428,6 +446,7 @@ public final class GenMSIL { catch (Throwable e) { currUnit.error(tree.pos, "Exception caught: " + e.getMessage()); e.printStackTrace(); + tc.saveAssembly(); System.exit(1); // + (global.debug ? "" : "; Use -debug to get a stack trace.")); // //if (global.debug) @@ -516,8 +535,10 @@ public final class GenMSIL { return coerce(item, toType); case Apply(Tree fun, Tree[] args): - //System.out.println("gen.Apply: " + Debug.show(fun.symbol()) + " toType " + toType); - return coerce(check(genApply(fun, args, msilType(tree.type))), toType); + Item i = check(genApply(fun, args, msilType(tree.type))); +// System.out.println("gen.Apply: " + Debug.show(fun.symbol()) + " toType = " + toType + +// "; tree.type = " + msilType(tree.type) + "; result = " + i); + return coerce(i, toType); case Assign(Tree lhs, Tree rhs): boolean tmpLastExpr = lastExpr; lastExpr = false; @@ -552,6 +573,12 @@ public final class GenMSIL { return items.VoidItem(); return coerce(items.LiteralItem(value), toType); + case Return(Tree expr): + genLoad(expr, toType); + //code.Emit(OpCodes.Ret); + code.Emit(OpCodes.Br, methodEnd); + return items.VoidItem(); + case If(Tree cond, Tree thenp, Tree elsep): item = genIf(cond, thenp, elsep, toType); return check(item); @@ -738,8 +765,13 @@ public final class GenMSIL { } - /** Generate the code for an Apply node */ private Item genApply(Tree fun, Tree[] args, MSILType resType) { + Item i = genApply0(fun, args, resType); + //System.out.println(Debug.show(fun.symbol()) + " -> " + i); + return i; + } + /** Generate the code for an Apply node */ + private Item genApply0(Tree fun, Tree[] args, MSILType resType) { boolean tmpLastExpr = lastExpr; lastExpr = false; Symbol sym = fun.symbol(); switch (fun) { @@ -767,8 +799,16 @@ public final class GenMSIL { assert args.length == 1; MSILType t = msilType(args[0].type); Item i = genLoad(args[0], t); - if (!i.type.isValueType()) - code.Emit(OpCodes.Call, (MethodInfo)tc.getMethod(sym)); + if (!i.type.isValueType()) { + MethodInfo method = (MethodInfo)tc.getMethod(sym); + code.Emit(OpCodes.Call, method); + i = returnsVoid(method) ? items.VoidItem() + : items.StackItem(msilType(method.ReturnType)); + return coerce(i, resType); + } + if (sym == primitives.UNBOX_UVALUE) { + return items.VoidItem(); + } return i; } MSILType convTo = primitiveConvert(sym); @@ -893,7 +933,8 @@ public final class GenMSIL { } } lastExpr = tmpLastExpr; - return check(invokeMethod(sym, args, resType, virtualCall)); + return check(invokeMethod(sym, args, resType, + virtualCall || method.IsAbstract())); default: throw Debug.abort(Debug.show(fun)); @@ -1015,7 +1056,8 @@ public final class GenMSIL { case ADD: if (tc.getType(right.type) == tc.STRING) { - System.out.println("primaryOp().ADD: string concat!"); + // TODO: check why this never gets printed + //System.out.println("primaryOp().ADD: string concat!"); genLoad(left, MSILType.OBJECT); genLoad(right, MSILType.OBJECT); code.Emit(OpCodes.Call, tc.CONCAT_OBJECT_OBJECT); @@ -1031,15 +1073,14 @@ public final class GenMSIL { case AS: // Item item = genLoad(left, MSILType.OBJECT); - Type ltype = tc.getType(left.type); - MSILType mltype = msilType(ltype); + MSILType mltype = msilType(left); Item item = genLoad(left, mltype); final Type rtype = tc.getType(right.type); final MSILType mrtype = msilType(rtype); - if (ltype.IsEnum()) { + if (mltype.isEnum()) { MSILType ptype = unboxValueType(mrtype); if (ptype != null) { - MSILType uetype = msilType(ltype.getUnderlyingType()); + MSILType uetype = msilType(mltype.getUnderlyingType()); //System.out.println("convert " + uetype + " -> " + ptype); emitConvert(uetype, ptype); return items.StackItem(ptype); @@ -1258,13 +1299,20 @@ public final class GenMSIL { (MethodInfo)method); res = returnsVoid(method) ? items.VoidItem() : items.StackItem(resType); } - return check(res); + if (returnsVoid(fun) && !returnsVoid(method)) { + res = drop(res); + } + return res; } /* * Returns the MSILType that corresponds to the given scala.symtab.Type */ private MSILType msilType(scalac.symtab.Type type) { + if (type.symbol() == defs.ALLREF_CLASS) { + //System.out.println("Ouch! " + Debug.show(defs.ALLREF_CLASS)); + return MSILType.NULL; + } return msilType(tc.getType(type)); } @@ -2110,12 +2158,22 @@ final class MSILType { public boolean isEnum() { switch (this) { case REF(Type t): - return t.BaseType == pp.ENUM; + return t.IsEnum(); default: return false; } } + /** Returns the underlying type of an enumeration; null otherwise */ + public Type getUnderlyingType() { + switch (this) { + case REF(Type t): + return t.getUnderlyingType(); + default: + return null; + } +} + public boolean isType(Type type) { return equals(fromType(type)); } diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java index 1ddda5432e..7dff21f430 100644 --- a/sources/scalac/backend/msil/TypeCreator.java +++ b/sources/scalac/backend/msil/TypeCreator.java @@ -9,6 +9,7 @@ package scalac.backend.msil; import scalac.Global; +import scalac.Phase; import scalac.CompilationUnit; import scalac.ApplicationError; import scalac.ast.Tree; @@ -91,10 +92,10 @@ final class TypeCreator { public final MethodInfo MONITOR_ENTER; public final MethodInfo MONITOR_EXIT; - private final MethodInfo MONITOR_PULSE; - private final MethodInfo MONITOR_PULSE_ALL; - private final MethodInfo MONITOR_WAIT; - private final MethodInfo MONITOR_WAIT_TIMEOUT; +// private final MethodInfo MONITOR_PULSE; +// private final MethodInfo MONITOR_PULSE_ALL; +// private final MethodInfo MONITOR_WAIT; +// private final MethodInfo MONITOR_WAIT_TIMEOUT; public final Type SCALA_BYTE; public final Type SCALA_SHORT; @@ -119,11 +120,14 @@ final class TypeCreator { private final CLRPackageParser ti; + private final Phase backPhase; + //########################################################################## TypeCreator(Global global, GenMSILPhase phase) { this.global = global; this.defs = global.definitions; + this.backPhase = global.PHASE.ADDINTERFACES.phase(); ti = CLRPackageParser.instance(); @@ -157,10 +161,10 @@ final class TypeCreator { CONCAT_OBJECT_OBJECT = STRING.GetMethod("Concat", new Type[] {OBJECT, OBJECT}); OBJECT_EQUALS = OBJECT.GetMethod("Equals", sObject1); - MONITOR_PULSE = MONITOR.GetMethod("Pulse", sObject1); - MONITOR_PULSE_ALL = MONITOR.GetMethod("PulseAll", sObject1); - MONITOR_WAIT = MONITOR.GetMethod("Wait", sObject1); - MONITOR_WAIT_TIMEOUT = MONITOR.GetMethod("Wait", new Type[] {OBJECT, INT}); +// MONITOR_PULSE = MONITOR.GetMethod("Pulse", sObject1); +// MONITOR_PULSE_ALL = MONITOR.GetMethod("PulseAll", sObject1); +// MONITOR_WAIT = MONITOR.GetMethod("Wait", sObject1); +// MONITOR_WAIT_TIMEOUT = MONITOR.GetMethod("Wait", new Type[] {OBJECT, INT}); MONITOR_ENTER = MONITOR.GetMethod("Enter", sObject1); MONITOR_EXIT = MONITOR.GetMethod("Exit", sObject1); @@ -181,12 +185,12 @@ final class TypeCreator { private boolean initialized = false; /* - * Called from GenMSIL + * Called from GenMSILPhase */ public void init() { if (initialized) return; - final Symbol JOBJECT = defs.getClass("java.lang.Object"); //defs.OBJECT_CLASS; + final Symbol JOBJECT = defs.OBJECT_CLASS; //defs.getClass("java.lang.Object"); final Symbol JSTRING = defs.STRING_CLASS; @@ -534,7 +538,6 @@ final class TypeCreator { /** Create the output assembly */ void initAssembly() { - AssemblyName an = new AssemblyName(); an.Name = assemName; msilAssembly = AssemblyBuilder.DefineDynamicAssembly(an); @@ -763,7 +766,7 @@ final class TypeCreator { staticType = msilModule.DefineType (staticTypeName, translateTypeAttributes(clazz.flags, false), - superType, interfaces); + superType, Type.EmptyTypes); } } } else { @@ -795,8 +798,8 @@ final class TypeCreator { { Symbol member = syms.next(); if (member.isMethod()) { - createMethod(member); - if (staticType != null) { + MethodBase m = createMethod(member); + if (staticType != null && !m.IsConstructor()) { MethodBase sm = createMethod(staticType, member, true); syms2staticMethods.put(member, sm); } @@ -923,14 +926,9 @@ final class TypeCreator { assert method != null : "cannot find " + owner + "::.ctor" + methodSignature(params); } else { - String name = sym.name.toString(); - if (sym.name == Names.toString) name = "ToString"; - else if (sym.name == Names.hashCode) name = "GetHashCode"; - else if (sym.name == Names.equals) name = "Equals"; - else if (sym.name == Name.fromString("clone")) name = "MemberwiseClone"; method = owner instanceof TypeBuilder ? findMethod(sym.owner(), sym) - : owner.GetMethod(name, params); + : owner.GetMethod(getMethodName(sym.name, params), params); } break; default: @@ -943,6 +941,18 @@ final class TypeCreator { return method; } + private String getMethodName(Name name, Type[] params) { + if (name == Names.finalize && params.length == 0) + return "Finalize"; + if (name == Names.toString && params.length == 0) + return "ToString"; + if (name == Names.hashCode && params.length == 0) + return "GetHashCode"; + if (name == Names.equals && params.length == 1 && params[0] == OBJECT) + return "Equals"; + return name.toString(); + } + private MethodBase findMethod(Symbol owner, Symbol member) { Symbol[] ms = owner.lookup(member.name).alternativeSymbols(); for (int i = 0; i < ms.length; i++) @@ -977,7 +987,24 @@ final class TypeCreator { attr = (short)((attr & ~MethodAttributes.Virtual & ~MethodAttributes.Final) | MethodAttributes.Static); - return createMethod(type, sym.name, sym.info(), attr); + Phase bkpCurrent = global.currentPhase; + global.currentPhase = backPhase; + Name name = sym.name; String sname = name.toString(); + switch (sym.info()) { + case PolyType(Symbol[] tparams, _): + if (tparams.length == 0) { + name = Name.fromString("get_" + name); + } + break; + default: + if (sname.endsWith("_$eq")) { + name = Name.fromString("set_" + sname + .substring(0, sname.length() - 4)); + } + } + global.currentPhase = bkpCurrent; + + return createMethod(type, name, sym.info(), attr); default: throw Debug.abort("Symbol doesn't have a method type: " + Debug.show(sym)); @@ -1007,12 +1034,7 @@ final class TypeCreator { (i, 0/*ParameterAttributes.In*/, vparams[i].name.toString()); return constructor; } else { - String sname; - if (name == Names.toString) sname = "ToString"; - else if (name == Names.equals) sname = "Equals"; - else if (name == Names.hashCode) sname = "GetHashCode"; - else sname = name.toString(); - + final String sname = getMethodName(name, params); MethodBuilder methodBuilder = type.DefineMethod (sname, attr, getType(result), params); |