summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2005-10-15 16:45:59 +0000
committerIulian Dragos <jaguarul@gmail.com>2005-10-15 16:45:59 +0000
commitd8522ed174ce5a098634b2b4a26d83a04a81554a (patch)
treeb92eee6608d1cfa51674b4175fb8cd4b5ff095a4
parent11a9eecb4d8b406690b76230ff91e1fac01651a6 (diff)
downloadscala-d8522ed174ce5a098634b2b4a26d83a04a81554a.tar.gz
scala-d8522ed174ce5a098634b2b4a26d83a04a81554a.tar.bz2
scala-d8522ed174ce5a098634b2b4a26d83a04a81554a.zip
Special treatment of scala.All and scala.AllRef...
Special treatment of scala.All and scala.AllRef in GenICode.
-rw-r--r--sources/scala/tools/nsc/backend/icode/GenICode.scala43
-rw-r--r--sources/scala/tools/nsc/backend/icode/Members.scala1
-rw-r--r--sources/scala/tools/nsc/backend/jvm/GenJVM.scala47
3 files changed, 71 insertions, 20 deletions
diff --git a/sources/scala/tools/nsc/backend/icode/GenICode.scala b/sources/scala/tools/nsc/backend/icode/GenICode.scala
index e170dfd5e7..1b84f0250c 100644
--- a/sources/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/sources/scala/tools/nsc/backend/icode/GenICode.scala
@@ -40,8 +40,9 @@ abstract class GenICode extends SubComponent {
// this depends on the backend! should be changed.
val ANY_REF_CLASS = REFERENCE(definitions.ObjectClass);
- val SCALA_ALL = REFERENCE(definitions.AllClass);
- val THROWABLE = REFERENCE(definitions.ThrowableClass);
+ val SCALA_ALL = REFERENCE(definitions.AllClass);
+ val SCALA_ALLREF = REFERENCE(definitions.AllRefClass);
+ val THROWABLE = REFERENCE(definitions.ThrowableClass);
///////////////////////////////////////////////////////////
@@ -96,15 +97,15 @@ abstract class GenICode extends SubComponent {
log("Entering method " + name);
val m = new IMethod(tree.symbol);
m.sourceFile = unit.source.toString();
+ m.returnType = if (tree.symbol.isConstructor) UNIT
+ else toTypeKind(tree.symbol.info.resultType);
ctx.clazz.addMethod(m);
var ctx1 = ctx.enterMethod(m, tree.asInstanceOf[DefDef]);
addMethodParams(ctx1, vparamss);
- val resTpe = if (tree.symbol.isConstructor) UNIT
- else toTypeKind(ctx1.method.symbol.info.resultType);
if (!m.isDeferred) {
- ctx1 = genLoad(rhs, ctx1, resTpe);
+ ctx1 = genLoad(rhs, ctx1, m.returnType);
// reverse the order of the local variables, to match the source-order
m.locals = m.locals.reverse;
@@ -112,7 +113,7 @@ abstract class GenICode extends SubComponent {
rhs match {
case Block(_, Return(_)) => ();
case Return(_) => ();
- case _ => ctx1.bb.emit(RETURN(resTpe), tree.pos);
+ case _ => ctx1.bb.emit(RETURN(m.returnType), rhs.pos);
}
ctx1.bb.close;
} else
@@ -222,8 +223,8 @@ abstract class GenICode extends SubComponent {
ctx1 = genLoad(larg, ctx1, resKind);
code match {
case scalaPrimitives.POS => (); // nothing
- case scalaPrimitives.NEG => ctx1.bb.emit(CALL_PRIMITIVE(Negation(resKind)), tree.pos);
- case scalaPrimitives.NOT => ctx1.bb.emit(CALL_PRIMITIVE(Arithmetic(NOT, resKind)), tree.pos);
+ case scalaPrimitives.NEG => ctx1.bb.emit(CALL_PRIMITIVE(Negation(resKind)), larg.pos);
+ case scalaPrimitives.NOT => ctx1.bb.emit(CALL_PRIMITIVE(Arithmetic(NOT, resKind)), larg.pos);
case _ => abort("Unknown unary operation: " + fun.symbol.fullNameString + " code: " + code);
}
generatedType = resKind;
@@ -765,8 +766,17 @@ abstract class GenICode extends SubComponent {
assert(generatedType != UNIT, "Can't convert from UNIT to " + expectedType);
resCtx.bb.emit(CALL_PRIMITIVE(Conversion(generatedType, expectedType)), tree.pos);
}
- } else if (generatedType == SCALA_ALL && expectedType == UNIT)
+// } else if (generatedType == SCALA_ALL && expectedType == UNIT)
+// resCtx.bb.emit(DROP(generatedType));
+ } else if (generatedType == SCALA_ALL) {
resCtx.bb.emit(DROP(generatedType));
+ resCtx.bb.emit(getZeroOf(ctx.method.returnType));
+ resCtx.bb.emit(RETURN(ctx.method.returnType));
+ resCtx.bb.enterIgnoreMode;
+ } else if (generatedType == SCALA_ALLREF) {
+ resCtx.bb.emit(DROP(generatedType));
+ resCtx.bb.emit(CONSTANT(Constant(null)));
+ }
resCtx;
}
@@ -858,6 +868,21 @@ abstract class GenICode extends SubComponent {
case ARRAY(elem) => Literal(null: Any);
}
+ def getZeroOf(k: TypeKind): Instruction = k match {
+ case UNIT => CONSTANT(Constant(()));
+ case BOOL => CONSTANT(Constant(false));
+ case BYTE => CONSTANT(Constant(0: Byte));
+ case SHORT => CONSTANT(Constant(0: Short));
+ case CHAR => CONSTANT(Constant(0: Char));
+ case INT => CONSTANT(Constant(0: Int));
+ case LONG => CONSTANT(Constant(0: Long));
+ case FLOAT => CONSTANT(Constant(0.0f));
+ case DOUBLE => CONSTANT(Constant(0.0d));
+ case REFERENCE(cls) => CONSTANT(Constant(null: Any));
+ case ARRAY(elem) => CONSTANT(Constant(null: Any));
+ }
+
+
/** Is the given symbol a primitive operation? */
def isPrimitive(fun: Symbol): Boolean = {
import scalaPrimitives._;
diff --git a/sources/scala/tools/nsc/backend/icode/Members.scala b/sources/scala/tools/nsc/backend/icode/Members.scala
index 14995a671d..c8f73ab368 100644
--- a/sources/scala/tools/nsc/backend/icode/Members.scala
+++ b/sources/scala/tools/nsc/backend/icode/Members.scala
@@ -157,6 +157,7 @@ trait Members: ICodes {
var code: Code = null;
var exh: List[ExceptionHandler] = _;
var sourceFile: String = _;
+ var returnType: TypeKind = _;
/** local variables and method parameters */
var locals: List[Local] = Nil;
diff --git a/sources/scala/tools/nsc/backend/jvm/GenJVM.scala b/sources/scala/tools/nsc/backend/jvm/GenJVM.scala
index 4b0621e6d0..971fff3eda 100644
--- a/sources/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/sources/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -86,9 +86,6 @@ abstract class GenJVM extends SubComponent {
ifaces,
c.cunit.source.toString());
- clasz.fields foreach genField;
- clasz.methods foreach genMethod;
-
if (isTopLevelModule(c.symbol)) {
addModuleInstanceField;
addStaticInit(jclass);
@@ -99,6 +96,10 @@ abstract class GenJVM extends SubComponent {
dumpMirrorClass;
}
+ clasz.fields foreach genField;
+ clasz.methods foreach genMethod;
+
+ addScalaAttribute(c.symbol);
jclass.writeTo(getFile(jclass, ".class"));
}
@@ -106,6 +107,20 @@ abstract class GenJVM extends SubComponent {
sym.isModuleClass && !sym.isImplClass && !sym.hasFlag(Flags.LIFTED) /* && !atPhase(currentRun.erasurePhase)(sym.isNestedClass) */
}
+ def addScalaAttribute(sym: Symbol): Unit = {
+ currentRun.symData.get(sym) match {
+ case Some(pickle) =>
+ val scalaAttr = fjbgContext.JOtherAttribute(jclass,
+ jclass,
+ nme.ScalaSignatureATTR.toString(),
+ pickle.bytes,
+ pickle.writeIndex);
+ jclass.addAttribute(scalaAttr);
+ case _ =>
+ log("Could not find pickle information for " + sym);
+ }
+ }
+
def genField(f: IField): Unit = {
log("Adding field: " + f.symbol.fullNameString);
jclass.addNewField(javaFlags(f.symbol),
@@ -166,9 +181,6 @@ abstract class GenJVM extends SubComponent {
clinit.emitINVOKESPECIAL(cls.getName(),
JMethod.INSTANCE_CONSTRUCTOR_NAME,
JMethodType.ARGLESS_VOID_FUNCTION);
- clinit.emitPUTSTATIC(cls.getName(),
- MODULE_INSTANCE_NAME,
- jclass.getType());
clinit.emitRETURN();
}
@@ -324,6 +336,16 @@ abstract class GenJVM extends SubComponent {
jcode.emitINVOKESPECIAL(owner,
javaName(method),
javaType(method).asInstanceOf[JMethodType]);
+
+ // we initialize the MODULE$ field immediately after the super ctor
+ if (isTopLevelModule(clasz.symbol) &&
+ jmethod.getName() == JMethod.INSTANCE_CONSTRUCTOR_NAME &&
+ javaName(method) == JMethod.INSTANCE_CONSTRUCTOR_NAME) {
+ jcode.emitALOAD_0();
+ jcode.emitPUTSTATIC(jclass.getName(),
+ MODULE_INSTANCE_NAME,
+ jclass.getType());
+ }
} else
jcode.emitINVOKESTATIC(owner,
javaName(method),
@@ -338,10 +360,6 @@ abstract class GenJVM extends SubComponent {
case NEW(REFERENCE(cls)) =>
val className = javaName(cls);
jcode.emitNEW(className);
-// jcode.emitDUP();
-// jcode.emitINVOKESPECIAL(className,
-// JMethod.INSTANCE_CONSTRUCTOR_NAME,
-// javaType(ctor).asInstanceOf[JMethodType]);
case CREATE_ARRAY(elem) => elem match {
case REFERENCE(_) | ARRAY(_) =>
@@ -583,6 +601,10 @@ abstract class GenJVM extends SubComponent {
case Conversion(src, dst) =>
log("Converting from: " + src + " to: " + dst);
+ if (dst == BOOL) {
+
+ }
+
jcode.emitT2T(javaType(src), javaType(dst));
case ArrayLength(_) =>
@@ -671,6 +693,9 @@ abstract class GenJVM extends SubComponent {
////////////////////// Utilities ////////////////////////
+ /** Return the a name of this symbol that can be used on the Java
+ * platform. It removes spaces from names.
+ */
def javaName(sym: Symbol) = {
val suffix = if (sym.hasFlag(Flags.MODULE) && !sym.isMethod &&
!sym.isImplClass &&
@@ -679,7 +704,7 @@ abstract class GenJVM extends SubComponent {
(if (sym.isClass || (sym.isModule && !sym.isMethod))
sym.fullNameString('/')
else
- sym.simpleName.toString()) + suffix;
+ sym.simpleName.toString().trim()) + suffix;
}
def javaNames(syms: List[Symbol]): Array[String] = {