summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2004-03-29 08:52:17 +0000
committermihaylov <mihaylov@epfl.ch>2004-03-29 08:52:17 +0000
commitdd33f4d02ba446b899b8bb2c552466d15eea0caf (patch)
tree61994c8d717cfa18f07a270a55652ec9df30a0ae /sources
parent70e9690e72bae30eccc9ce46eda67615a0d48111 (diff)
downloadscala-dd33f4d02ba446b899b8bb2c552466d15eea0caf.tar.gz
scala-dd33f4d02ba446b899b8bb2c552466d15eea0caf.tar.bz2
scala-dd33f4d02ba446b899b8bb2c552466d15eea0caf.zip
- For objects whose name doesn't coincide with ...
- For objects whose name doesn't coincide with the name of a class, introduce a class with the name of the object with static methods with the same signatures as the methods of the object that forward the call to the instance methods of the object.
Diffstat (limited to 'sources')
-rw-r--r--sources/scalac/backend/msil/GenMSIL.java45
-rw-r--r--sources/scalac/backend/msil/TypeCreator.java134
2 files changed, 120 insertions, 59 deletions
diff --git a/sources/scalac/backend/msil/GenMSIL.java b/sources/scalac/backend/msil/GenMSIL.java
index c06a1ef680..82002c6a41 100644
--- a/sources/scalac/backend/msil/GenMSIL.java
+++ b/sources/scalac/backend/msil/GenMSIL.java
@@ -252,7 +252,7 @@ public final class GenMSIL {
private void genClass(Symbol clazz, Tree[] body) {
Symbol outerClass = currentClass;
currentClass = clazz;
- if ( clazz.isModule() || clazz.isModuleClass() ) {
+ if (clazz.isModuleClass()) {
tc.getModuleField(clazz);
}
emitSymtab(clazz);
@@ -273,9 +273,9 @@ public final class GenMSIL {
break;
case DefDef(_, _, _, ValDef[][] vparams, Tree tpe, Tree rhs):
- currentMethod = tc.getMethod(sym);
// if (!currentMethod.IsAbstract()) {
if (!sym.isDeferred()) {
+ currentMethod = tc.getMethod(sym);
checkMain(currentMethod);
genDef(sym, vparams[0], rhs, msilType(tpe.type));
}
@@ -320,9 +320,8 @@ public final class GenMSIL {
if (method.IsConstructor()) {
ConstructorInfo ctor = (ConstructorInfo) method;
code = ((ConstructorBuilder)ctor).GetILGenerator();
- FieldInfo moduleField = tc.getModuleField(currentClass);
- if (moduleField != null
- && moduleField.DeclaringType.DeclaringType == null) {
+ if (sym.owner().isModuleClass()
+ && sym.owner().owner().isPackageClass()) {
Tree[] cstats = null;
switch (rhs) {
case Block(Tree[] stats, Tree value):
@@ -362,7 +361,7 @@ public final class GenMSIL {
code = cctor.GetILGenerator();
// initialize the static module reference
code.Emit(OpCodes.Newobj, ctor);
- code.Emit(OpCodes.Stsfld, moduleField);
+ code.Emit(OpCodes.Stsfld, tc.getModuleField(currentClass));
for (int i = 1; i < cstats.length; i++) {
drop(gen(cstats[i], MSILType.VOID));
}
@@ -380,6 +379,17 @@ public final class GenMSIL {
else
coerce(load(item), toType); // FIXME: coerce???
code.Emit(OpCodes.Ret);
+ if (currentClass.isModuleClass()) {
+ MethodBuilder staticMethod = tc.getStaticObjectMethod(sym);
+ if (staticMethod != null) {
+ code = staticMethod.GetILGenerator();
+ code.Emit(OpCodes.Ldsfld, tc.getModuleField(currentClass));
+ for (int i = 0; i < parameters.length; i++)
+ emitLdarg(i);
+ code.Emit(OpCodes.Call, (MethodInfo)method);
+ code.Emit(OpCodes.Ret);
+ }
+ }
}
lastExpr = false;
@@ -1408,6 +1418,18 @@ public final class GenMSIL {
return item;
}
+ private void emitLdarg(int slot) {
+ assert slot >= 0;
+ switch (slot) {
+ case 0: code.Emit(OpCodes.Ldarg_0); break;
+ case 1: code.Emit(OpCodes.Ldarg_1); break;
+ case 2: code.Emit(OpCodes.Ldarg_2); break;
+ case 3: code.Emit(OpCodes.Ldarg_3); break;
+ default:
+ code.Emit(slot < 256 ? OpCodes.Ldarg_S : OpCodes.Ldarg, slot);
+ }
+ }
+
/*
* Load the value of an item on the stack.
*/
@@ -1427,16 +1449,7 @@ public final class GenMSIL {
return items.StackItem(that.type);
case ArgItem(int slot):
- if (slot > 255)
- code.Emit(OpCodes.Ldarg, slot);
- else if(slot > 3)
- code.Emit(OpCodes.Ldarg_S, slot);
- else switch (slot) {
- case 0: code.Emit(OpCodes.Ldarg_0); break;
- case 1: code.Emit(OpCodes.Ldarg_1); break;
- case 2: code.Emit(OpCodes.Ldarg_2); break;
- case 3: code.Emit(OpCodes.Ldarg_3); break;
- }
+ emitLdarg(slot);
return items.StackItem(that.type);
case LocalItem(LocalBuilder local):
diff --git a/sources/scalac/backend/msil/TypeCreator.java b/sources/scalac/backend/msil/TypeCreator.java
index 2e701e7544..7b31b1f05f 100644
--- a/sources/scalac/backend/msil/TypeCreator.java
+++ b/sources/scalac/backend/msil/TypeCreator.java
@@ -50,6 +50,10 @@ final class TypeCreator {
private final ArrayList typeBuilders = new ArrayList();
+ // for every method of an object give the corresponding static method
+ // of the accompanying class
+ private final Map/*<Symbol, MethodBuilder>*/ syms2staticMethods = new HashMap();
+
private final Map types2symbols;
private final Map symbols2types;
private final Map symbols2fields;
@@ -274,6 +278,7 @@ final class TypeCreator {
Type scalaSymtab = Type.GetType("scala.support.SymtabAttribute");
SCALA_SYMTAB_ATTR_CONSTR = scalaSymtab.GetConstructors()[0];
+
} // init()
/*
@@ -531,17 +536,19 @@ final class TypeCreator {
public Type createType0(Symbol clazz) {
assert !clazz.isExternal() : "Can not create type " + Debug.show(clazz);
Type type = (Type)symbols2types.get(clazz);
+ TypeBuilder staticType = null;
assert type == null : "Type " + type +
" already defined for symbol: " + Debug.show(clazz);
//System.out.println("createType: " + Debug.show(clazz));
final Symbol owner = clazz.owner();
+ final String staticTypeName = owner.isClass()
+ ? clazz.nameString()
+ : global.primitives.getCLRClassName(clazz);
final String typeName =
- (owner.isClass() ? clazz.nameString() : global.primitives.getCLRClassName(clazz)) +
- (clazz.isModuleClass() ? "$" : "");
+ staticTypeName + (clazz.isModuleClass() ? "$" : "");
final ModuleBuilder module = gen.getCurrentModule();
-
final scalac.symtab.Type classType = clazz.info();
switch (classType) {
case CompoundType(scalac.symtab.Type[] baseTypes, _):
@@ -571,10 +578,18 @@ final class TypeCreator {
if (type != null)
return type;
- if (owner.isRoot() || owner.isPackageClass()) { // i.e. top level class
+ if (owner.isPackageClass()) { // i.e. top level class
type = module.DefineType
(typeName, translateTypeAttributes(clazz.flags, false),
superType, interfaces);
+ if (clazz.isModuleClass()
+ && owner.members().lookup(clazz.name).isNone())
+ {
+ staticType = module.DefineType
+ (staticTypeName,
+ translateTypeAttributes(clazz.flags, false),
+ superType, interfaces);
+ }
} else {
final Type outerType = (Type) getType(owner);
// check if the type have not been created by
@@ -598,8 +613,13 @@ final class TypeCreator {
syms.hasNext(); )
{
Symbol member = syms.next();
- if (member.isMethod())
+ if (member.isMethod()) {
createMethod(member);
+ if (staticType != null) {
+ MethodBase sm = createMethod(staticType, member, true);
+ syms2staticMethods.put(member, sm);
+ }
+ }
else if (!member.isClass() && !member.isModule()
&& !member.isType())
createField(member);
@@ -654,10 +674,22 @@ final class TypeCreator {
return set;
}
+ public MethodBase getMethod(Symbol sym) {
+ MethodBase method = null;
+ try {
+ method = getMethod0(sym);
+ } catch (RuntimeException e) {
+ System.err.println("for method " + Debug.show(sym));
+ System.err.println(symbols2methods);
+ throw e;
+ }
+ return method;
+ }
+
/**
* Returns the MethodBase object corresponding to the symbol.
*/
- public MethodBase getMethod(Symbol sym) {
+ public MethodBase getMethod0(Symbol sym) {
MethodBase method = (MethodBase) symbols2methods.get(sym);
if (method != null)
return method;
@@ -701,25 +733,36 @@ final class TypeCreator {
}
+ private MethodBase createMethod(Symbol sym) {
+ MethodBase method =
+ createMethod((TypeBuilder)getType(sym.owner()), sym, false);
+ symbols2methods.put(sym, method);
+ return method;
+ }
+
+
/**
* Create the method corresponding to the symbol.
+
+ * @param isStatic - forces the created method to be static
*/
- private MethodBase createMethod(Symbol sym) {
+ private MethodBase createMethod(TypeBuilder type, Symbol sym, boolean isStatic)
+ {
MethodBase method = null;
switch (sym.info()) {
case MethodType(Symbol[] vparams, scalac.symtab.Type result):
- TypeBuilder type = (TypeBuilder)getType(sym.owner());
- method = createMethod
- (type, sym.name, sym.info(), translateMethodAttributes(sym));
- break;
+ short attr = translateMethodAttributes(sym);
+ if (isStatic)
+ attr = (short)((attr & ~MethodAttributes.Virtual)
+ | MethodAttributes.Static);
+ return createMethod(type, sym.name, sym.info(), attr);
default:
- assert false : "Symbol doesn't have a method type: " + Debug.show(sym);
+ throw Debug.abort("Symbol doesn't have a method type: "
+ + Debug.show(sym));
}
- assert method != null;
- symbols2methods.put(sym, method);
- return method;
}
+
/**
* Helper method to createMethod(Symbol)
*/
@@ -740,7 +783,7 @@ final class TypeCreator {
for (int i = 0; i < vparams.length; i++)
constructor.DefineParameter
(i, 0/*ParameterAttributes.In*/, vparams[i].name.toString());
- method = constructor;
+ return constructor;
} else {
String sname;
if (name == Names.toString) sname = "ToString";
@@ -754,14 +797,11 @@ final class TypeCreator {
for (int i = 0; i < vparams.length; i++)
methodBuilder.DefineParameter
(i, 0/*ParameterAttributes.In*/, vparams[i].name.toString());
- method = methodBuilder;
+ return methodBuilder;
}
- break;
default:
- assert false : "Method type expected: " + Debug.show(symType);
+ throw Debug.abort("Method type expected: " + Debug.show(symType));
}
-
- return method;
}
@@ -817,6 +857,16 @@ final class TypeCreator {
return getModuleField(sym);
}
+ /**
+ *
+ */
+ public MethodBuilder getStaticObjectMethod(Symbol sym) {
+ assert sym.owner().isModuleClass() : Debug.show(sym);
+ MethodBuilder method = (MethodBuilder)syms2staticMethods.get(sym);
+ assert sym != null : Debug.show(sym);
+ return method;
+ }
+
/*
*
*/
@@ -834,32 +884,30 @@ final class TypeCreator {
* @return the field descriptor of the object instance
*/
public FieldInfo getModuleField(Symbol sym) {
- FieldInfo moduleField = null;
- if (sym.isModule() || sym.isModuleClass()) {
- moduleField = (FieldInfo) symbols2moduleFields.get(sym);
- if (moduleField == null) {
- Symbol s = getTypeSymbol(sym.type());
- if (sym != s) {
- moduleField = getModuleField(s);
+ assert sym.isModule() || sym.isModuleClass() : Debug.show(sym);
+ FieldInfo moduleField = (FieldInfo) symbols2moduleFields.get(sym);
+ if (moduleField == null) {
+ Symbol s = getTypeSymbol(sym.type());
+ if (sym != s) {
+ moduleField = getModuleField(s);
+ } else {
+ Type type = getType(sym);
+ if (type instanceof TypeBuilder) {
+ TypeBuilder module = (TypeBuilder) type;
+ moduleField = module.DefineField
+ (MODULE_S,
+ module,
+ (short)(FieldAttributes.Public
+ | FieldAttributes.InitOnly
+ | FieldAttributes.Static));
} else {
- Type type = getType(sym);
- if (type instanceof TypeBuilder) {
- TypeBuilder module = (TypeBuilder) type;
- moduleField = module.DefineField
- (MODULE_S,
- module,
- (short)(FieldAttributes.Public
- | FieldAttributes.InitOnly
- | FieldAttributes.Static));
- } else {
- moduleField = type.GetField(MODULE_S);
- assert moduleField != null;
- }
+ moduleField = type.GetField(MODULE_S);
+ assert moduleField != null;
}
- symbols2moduleFields.put(sym, moduleField);
}
- } else {
+ symbols2moduleFields.put(sym, moduleField);
}
+ assert moduleField != null : Debug.show(sym);
return moduleField;
}