summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2004-09-09 16:27:54 +0000
committermihaylov <mihaylov@epfl.ch>2004-09-09 16:27:54 +0000
commitbefce84f58d16a32baef78e9852d0f322bbf0717 (patch)
tree825639db118e01dbe9a6578639539e23dd7615d5 /sources
parent388a7262cbe5f9b91081303d9061754e6a2bb7bb (diff)
downloadscala-befce84f58d16a32baef78e9852d0f322bbf0717.tar.gz
scala-befce84f58d16a32baef78e9852d0f322bbf0717.tar.bz2
scala-befce84f58d16a32baef78e9852d0f322bbf0717.zip
- Several bugfixes and small optimizations
Diffstat (limited to 'sources')
-rw-r--r--sources/scalac/backend/msil/GenMSIL.java137
-rw-r--r--sources/scalac/backend/msil/TypeCreator.java34
2 files changed, 138 insertions, 33 deletions
diff --git a/sources/scalac/backend/msil/GenMSIL.java b/sources/scalac/backend/msil/GenMSIL.java
index 0374a8294c..bbf8c95310 100644
--- a/sources/scalac/backend/msil/GenMSIL.java
+++ b/sources/scalac/backend/msil/GenMSIL.java
@@ -26,7 +26,7 @@ import scalac.symtab.TypeTags;
import scalac.symtab.Modifiers;
import scalac.symtab.Definitions;
import scalac.symtab.classfile.Pickle;
-import scalac.symtab.classfile.CLRPackageParser;
+import scalac.symtab.classfile.CLRTypes;
import scalac.backend.Primitive;
import scalac.backend.Primitives;
@@ -138,7 +138,7 @@ public final class GenMSIL {
case ClassDef(_, _, _, _, _, Template(_, Tree[] classBody)):
Type type = tc.getType(sym);
assert type instanceof TypeBuilder
- : Debug.show(sym) + " => [" + type.Assembly + "]" + type;
+ : Debug.show(sym) + " => [" + type.Assembly() + "]" + type;
if (type instanceof TypeBuilder)
genClass(sym, classBody);
break;
@@ -574,7 +574,8 @@ public final class GenMSIL {
return coerce(items.LiteralItem(value), toType);
case Return(Tree expr):
- genLoad(expr, toType);
+ //System.out.println(Debug.show(expr) + "; toType = " + toType);
+ genLoad(expr, msilType(expr));
//code.Emit(OpCodes.Ret);
code.Emit(OpCodes.Br, methodEnd);
return items.VoidItem();
@@ -928,8 +929,8 @@ public final class GenMSIL {
load(items.SelfItem(tc.getType(currentClass)));
break;
default:
- genLoad(qualifier, msilType(qualifier));
- virtualCall = true;
+ genAddr(qualifier, msilType(qualifier));
+ virtualCall = !msilType(qualifier).isValueType();
}
}
lastExpr = tmpLastExpr;
@@ -966,15 +967,15 @@ public final class GenMSIL {
Label l1 = code.DefineLabel(), l2 = code.DefineLabel();
genLoad(left, MSILType.OBJECT);
genLoad(right, MSILType.OBJECT);
- code.Emit(OpCodes.Stloc, tmpLocal);
+ emitStloc(tmpLocal);
code.Emit(OpCodes.Dup);
code.Emit(OpCodes.Ldnull);
code.Emit(OpCodes.Bne_Un, l1);
- code.Emit(OpCodes.Ldloc, tmpLocal);
+ emitLdloc(tmpLocal);
code.Emit(OpCodes.Ceq);
code.Emit(OpCodes.Br, l2);
code.MarkLabel(l1);
- code.Emit(OpCodes.Ldloc, tmpLocal);
+ emitLdloc(tmpLocal);
code.Emit(OpCodes.Callvirt, tc.OBJECT_EQUALS);
code.MarkLabel(l2);
return items.StackItem(MSILType.BOOL);
@@ -1102,11 +1103,11 @@ public final class GenMSIL {
// TODO: reuse temporary local variable whenever possible
LocalBuilder tmp = code.DeclareLocal(tc.OBJECT);
genLoad(left, MSILType.OBJECT);
- code.Emit(OpCodes.Stloc, tmp);
- code.Emit(OpCodes.Ldloc, tmp);
+ emitStloc(tmp);
+ emitLdloc(tmp);
code.Emit(OpCodes.Call, tc.MONITOR_ENTER);
genLoad(right, MSILType.OBJECT);
- code.Emit(OpCodes.Ldloc, tmp);
+ emitLdloc(tmp);
code.Emit(OpCodes.Call, tc.MONITOR_EXIT);
return items.StackItem(MSILType.OBJECT);
}
@@ -1146,10 +1147,14 @@ public final class GenMSIL {
code.Emit(OpCodes.Not);
return iLeft;
case ZNOT:
- return negate(mkCond(iLeft));
+ Item i1 = mkCond(iLeft);
+ Item i2 = negate(i1);
+ //System.out.println("!" + i1 + " -> " + i2);
+ return i2;
case ZOR:
Item.CondItem lcond = mkCond(iLeft), rcond = null;
Chain success = lcond.success, failure = lcond.failure;
+ //System.out.println("ZOR: lcond = " + lcond);
switch (lcond.test) {
case True:
return lcond;
@@ -1466,6 +1471,36 @@ public final class GenMSIL {
}
}
+ private void emitLdarga(int slot) {
+ code.Emit(slot < 256 ? OpCodes.Ldarga_S : OpCodes.Ldarga, slot);
+ }
+
+ private void emitLdloc(LocalBuilder loc) {
+ switch (loc.slot) {
+ case 0: code.Emit(OpCodes.Ldloc_0); break;
+ case 1: code.Emit(OpCodes.Ldloc_1); break;
+ case 2: code.Emit(OpCodes.Ldloc_2); break;
+ case 3: code.Emit(OpCodes.Ldloc_3); break;
+ default:
+ code.Emit(loc.slot < 256 ? OpCodes.Ldloc_S : OpCodes.Ldloc, loc);
+ }
+ }
+
+ private void emitLdloca(LocalBuilder loc) {
+ code.Emit(loc.slot < 256 ? OpCodes.Ldloca_S : OpCodes.Ldloca, loc);
+ }
+
+ private void emitStloc(LocalBuilder loc) {
+ switch (loc.slot) {
+ case 0: code.Emit(OpCodes.Stloc_0); break;
+ case 1: code.Emit(OpCodes.Stloc_1); break;
+ case 2: code.Emit(OpCodes.Stloc_2); break;
+ case 3: code.Emit(OpCodes.Stloc_3); break;
+ default:
+ code.Emit(loc.slot < 256 ? OpCodes.Stloc_S : OpCodes.Stloc, loc);
+ }
+ }
+
/*
* Load the value of an item on the stack.
*/
@@ -1489,7 +1524,7 @@ public final class GenMSIL {
return items.StackItem(that.type);
case LocalItem(LocalBuilder local):
- code.Emit(OpCodes.Ldloc, local);
+ emitLdloc(local);
return items.StackItem(that.type);
case StaticItem(FieldInfo field):
@@ -1730,7 +1765,7 @@ public final class GenMSIL {
break;
case LocalItem(LocalBuilder local):
- code.Emit(OpCodes.Stloc, local);
+ emitStloc(local);
break;
case StaticItem(FieldInfo field):
@@ -1806,13 +1841,63 @@ public final class GenMSIL {
}
}
+ // load the address of a value type item;
+ // for reference types load a reference
+ private Item genAddr(Tree tree, MSILType toType) {
+ Item item = gen(tree, toType);
+ if (!item.type.isValueType())
+ return load(item);
+ switch (item) {
+ case ArgItem(int slot):
+ emitLdarga(slot);
+ break;
+ case LocalItem(LocalBuilder local):
+ emitLdloca(local);
+ break;
+ case StaticItem(FieldInfo field):
+ if (field.IsInitOnly()) {
+ load(item);
+ genLocalAddr(field.FieldType);
+ } else
+ code.Emit(OpCodes.Ldsflda, field);
+ break;
+ case SelectItem(Item qual, FieldInfo field):
+ if (field.IsInitOnly()) {
+ load(item);
+ genLocalAddr(field.FieldType);
+ } else {
+ load(qual);
+ code.Emit(OpCodes.Ldflda, field);
+ }
+ break;
+ case StackItem():
+ genLocalAddr(item.type.toType());
+ break;
+ default:
+ throw Debug.abort(item.toString());
+ }
+ return items.StackItem(toType);
+ }
+
+ private void genLocalAddr(Type localType) {
+ assert localType.IsValueType() : localType.toString();
+ LocalBuilder tmpLocal = (LocalBuilder)locals.get(localType);
+ if (tmpLocal == null) {
+ tmpLocal = code.DeclareLocal(localType);
+ locals.put(localType, tmpLocal);
+ }
+ emitStloc(tmpLocal);
+ emitLdloca(tmpLocal);
+ }
+
/*
* Negate a condition.
*/
private Item.CondItem negate(Item item) {
Item.CondItem cond = mkCond(item);
// swap the failure and success chains
- return items.CondItem(negate(cond.test), cond.success, cond.failure);
+ //return items.CondItem(negate(cond.test), cond.success, cond.failure);
+ return items.CondItem(negate(cond.test), cond.failure, cond.success);
}
/*
@@ -2036,7 +2121,7 @@ final class MSILType {
public case REF(Type t) { assert t != null && !t.IsArray(); }
public case ARRAY(MSILType t) { assert t != null; }
- private final static CLRPackageParser pp = CLRPackageParser.instance();
+ private final static CLRTypes pp = CLRTypes.instance();
public static final MSILType OBJECT = REF(pp.OBJECT);
public static final MSILType STRING = REF(pp.STRING);
@@ -2111,6 +2196,26 @@ final class MSILType {
}
}
+ public Type toType() {
+ switch (this) {
+ case I1: return pp.BYTE;
+ case I2: return pp.SHORT;
+ //case U2: return ;
+ case I4: return pp.INT;
+ case I8: return pp.LONG;
+ case R4: return pp.FLOAT;
+ case R8: return pp.DOUBLE;
+ case BOOL: return pp.BOOLEAN;
+ case CHAR: return pp.CHAR;
+ case REF(Type t): return t;
+ case ARRAY(MSILType t): return pp.mkArrayType(t.toType());
+ case VOID: return pp.VOID;
+ //case NULL: return "NULL";
+ default: throw Debug.abort(getClass().toString());
+ }
+
+ }
+
//##########################################################################
public boolean equals(Object that) {
diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java
index 7dff21f430..9c2ced21f9 100644
--- a/sources/scalac/backend/msil/TypeCreator.java
+++ b/sources/scalac/backend/msil/TypeCreator.java
@@ -24,7 +24,7 @@ import scalac.symtab.Symbol;
import scalac.symtab.Scope;
import scalac.symtab.Modifiers;
import scalac.symtab.Definitions;
-import scalac.symtab.classfile.CLRPackageParser;
+import scalac.symtab.classfile.CLRTypes;
import scala.tools.util.Position;
import scala.tools.util.SourceFile;
@@ -118,7 +118,7 @@ final class TypeCreator {
private scalac.symtab.Type MAIN_METHOD_TYPE;
- private final CLRPackageParser ti;
+ private final CLRTypes ti;
private final Phase backPhase;
@@ -129,7 +129,7 @@ final class TypeCreator {
this.defs = global.definitions;
this.backPhase = global.PHASE.ADDINTERFACES.phase();
- ti = CLRPackageParser.instance();
+ ti = CLRTypes.instance();
types2symbols = phase.types2symbols;
symbols2types = phase.symbols2types;
@@ -266,18 +266,18 @@ final class TypeCreator {
translateMethod(JSTRING, "replace", jChar2, STRING, "Replace");
translateMethod(JSTRING, "toCharArray", STRING, "ToCharArray");
- translateMethod(defs.getModule("java.lang.Byte").moduleClass()
- , "parseByte", jString1, BYTE, "Parse");
- translateMethod(defs.getModule("java.lang.Short").moduleClass()
- , "parseShort", jString1, SHORT, "Parse");
- translateMethod(defs.getModule("java.lang.Integer").moduleClass()
- , "parseInt", jString1, INT, "Parse");
- translateMethod(defs.getModule("java.lang.Long").moduleClass()
- , "parseLong", jString1, LONG, "Parse");
- translateMethod(defs.getModule("java.lang.Float").moduleClass()
- , "parseFloat", jString1, FLOAT, "Parse");
- translateMethod(defs.getModule("java.lang.Double").moduleClass()
- , "parseDouble", jString1, DOUBLE, "Parse");
+// translateMethod(defs.getModule("java.lang.Byte").moduleClass()
+// , "parseByte", jString1, BYTE, "Parse");
+// translateMethod(defs.getModule("java.lang.Short").moduleClass()
+// , "parseShort", jString1, SHORT, "Parse");
+// translateMethod(defs.getModule("java.lang.Integer").moduleClass()
+// , "parseInt", jString1, INT, "Parse");
+// translateMethod(defs.getModule("java.lang.Long").moduleClass()
+// , "parseLong", jString1, LONG, "Parse");
+// translateMethod(defs.getModule("java.lang.Float").moduleClass()
+// , "parseFloat", jString1, FLOAT, "Parse");
+// translateMethod(defs.getModule("java.lang.Double").moduleClass()
+// , "parseDouble", jString1, DOUBLE, "Parse");
SYM_SUBSTRING_INT_INT = lookupMethod(JSTRING, "substring", jInt2);
SUBSTRING_INT_INT =
@@ -766,7 +766,7 @@ final class TypeCreator {
staticType = msilModule.DefineType
(staticTypeName,
translateTypeAttributes(clazz.flags, false),
- superType, Type.EmptyTypes);
+ OBJECT, Type.EmptyTypes);
}
}
} else {
@@ -799,7 +799,7 @@ final class TypeCreator {
Symbol member = syms.next();
if (member.isMethod()) {
MethodBase m = createMethod(member);
- if (staticType != null && !m.IsConstructor()) {
+ if (staticType != null && m.IsPublic() && !m.IsConstructor()) {
MethodBase sm = createMethod(staticType, member, true);
syms2staticMethods.put(member, sm);
}