summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2004-07-20 16:42:09 +0000
committermihaylov <mihaylov@epfl.ch>2004-07-20 16:42:09 +0000
commit8991585adcacdfef75dc20ea267b6d8be6dc9df4 (patch)
tree2892712c4cd8200269f2c4b0c330e63b0e5755b1
parentda852d8ff2f8e0a86a0eb7fe2fdb0f12ec7bbc12 (diff)
downloadscala-8991585adcacdfef75dc20ea267b6d8be6dc9df4.tar.gz
scala-8991585adcacdfef75dc20ea267b6d8be6dc9df4.tar.bz2
scala-8991585adcacdfef75dc20ea267b6d8be6dc9df4.zip
- Small fixes
-rw-r--r--sources/scalac/backend/msil/GenMSIL.java112
-rw-r--r--sources/scalac/backend/msil/TypeCreator.java76
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);