summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--Makefile.config5
-rw-r--r--Makefile.distrib6
-rw-r--r--config/list/compiler.lst2
-rw-r--r--sources/bin/.scala_wrapper.tmpl9
-rw-r--r--sources/scalac/CompilerCommand.java2
-rw-r--r--sources/scalac/CompilerPhases.java6
-rw-r--r--sources/scalac/Global.java3
-rw-r--r--sources/scalac/backend/jvm/GenJVMBCEL.java1567
-rw-r--r--sources/scalac/backend/jvm/GenJVMBCELPhase.java50
-rw-r--r--sources/scalac/transformer/AddConstructors.java3
11 files changed, 3 insertions, 1654 deletions
diff --git a/Makefile b/Makefile
index 37aef50723..e671af4957 100644
--- a/Makefile
+++ b/Makefile
@@ -79,7 +79,7 @@ COMPILER_ROOT = $(PROJECT_SOURCEDIR)/scalac
COMPILER_LIST = $(call READLIST,$(PROJECT_LISTDIR)/compiler.lst)
COMPILER_SOURCES += $(COMPILER_LIST:%=$(COMPILER_ROOT)/%)
COMPILER_JC_FILES = $(filter %.java,$(COMPILER_SOURCES))
-COMPILER_JC_CLASSPATH = $(PROJECT_CLASSPATH):$(BCEL_JARFILE):$(MSIL_JARFILE):$(FJBG_JARFILE)
+COMPILER_JC_CLASSPATH = $(PROJECT_CLASSPATH):$(MSIL_JARFILE):$(FJBG_JARFILE)
COMPILER_SC_FILES = $(filter %.scala,$(COMPILER_SOURCES))
COMPILER_SC_CLASSPATH = $(COMPILER_JC_CLASSPATH)
COMPILER_SCALAC = $(PROJECT_BOOTSTRAPDIR)/bin/scalac
@@ -353,7 +353,6 @@ $(SCRIPTS_WRAPPER) : MACRO_VERSION ?= $(PROJECT_VERSION)
$(SCRIPTS_WRAPPER) : MACRO_RUNTIME_SOURCES ?= $(PROJECT_SOURCEDIR)
$(SCRIPTS_WRAPPER) : MACRO_RUNTIME_CLASSES ?= $(PROJECT_OUTPUTDIR)
$(SCRIPTS_WRAPPER) : MACRO_TOOLS_CLASSES ?= $(PROJECT_OUTPUTDIR)
-$(SCRIPTS_WRAPPER) : MACRO_BCEL_CLASSES ?= $(BCEL_JARFILE)
$(SCRIPTS_WRAPPER) : MACRO_FJBG_CLASSES ?= $(FJBG_JARFILE)
$(SCRIPTS_WRAPPER) : MACRO_MSIL_CLASSES ?= $(MSIL_JARFILE)
$(SCRIPTS_WRAPPER) : MACRO_JAVA_ARGS ?= -enableassertions
@@ -369,7 +368,6 @@ $(SCRIPTS_WRAPPER) : $(SCRIPTS_WRAPPER).tmpl
$(call SCRIPTS_WRAPPER_MACRO,RUNTIME_SOURCES) \
$(call SCRIPTS_WRAPPER_MACRO,RUNTIME_CLASSES) \
$(call SCRIPTS_WRAPPER_MACRO,TOOLS_CLASSES) \
- $(call SCRIPTS_WRAPPER_MACRO,BCEL_CLASSES) \
$(call SCRIPTS_WRAPPER_MACRO,FJBG_CLASSES) \
$(call SCRIPTS_WRAPPER_MACRO,MSIL_CLASSES) \
$(call SCRIPTS_WRAPPER_MACRO,JAVA_ARGS) \
diff --git a/Makefile.config b/Makefile.config
index c83f790815..abcff258a7 100644
--- a/Makefile.config
+++ b/Makefile.config
@@ -36,11 +36,6 @@ FJBG_JARFILE ?= $(FJBG_HOME)/fjbg.jar
MSIL_HOME ?= $(PROJECT_LIBDIR)/msil
MSIL_JARFILE ?= $(MSIL_HOME)/msil.jar
-# BCEL (http://jakarta.apache.org/bcel/)
-BCEL_HOME ?= $(PROJECT_LIBDIR)/bcel
-BCEL_JARFILE ?= $(BCEL_HOME)/bcel.jar
-BCEL_LICENSE ?= $(BCEL_HOME)/LICENSE
-
##############################################################################
# Standard tools
diff --git a/Makefile.distrib b/Makefile.distrib
index 3abb1f6dc8..aaf45edda4 100644
--- a/Makefile.distrib
+++ b/Makefile.distrib
@@ -50,8 +50,6 @@ INSTALL_RUNTIME_JARFILE = $(INSTALL_LIBDIR)/$(PROJECT_NAME).jar
INSTALL_TOOLS_JARFILE = $(INSTALL_LIBDIR)/$(TOOLS_NAME).jar
INSTALL_FJBG_JARFILE = $(INSTALL_LIBDIR)/fjbg.jar
INSTALL_MSIL_JARFILE = $(INSTALL_LIBDIR)/msil.jar
-INSTALL_BCEL_JARFILE = $(INSTALL_LIBDIR)/bcel.jar
-INSTALL_BCEL_LICENSE = $(INSTALL_LIBDIR)/bcel.LICENSE
install-clean :
$(RM) -r $(INSTALL_PREFIX)
@@ -74,7 +72,6 @@ install : $(TOOLS_JAR_ARCHIVE)
MACRO_RUNTIME_SOURCES=$(INSTALL_SRCDIR) \
MACRO_RUNTIME_CLASSES=$(INSTALL_RUNTIME_JARFILE) \
MACRO_TOOLS_CLASSES=$(INSTALL_TOOLS_JARFILE) \
- MACRO_BCEL_CLASSES=$(INSTALL_BCEL_JARFILE) \
MACRO_FJBG_CLASSES=$(INSTALL_FJBG_JARFILE) \
MACRO_MSIL_CLASSES=$(INSTALL_MSIL_JARFILE) \
MACRO_JAVA_ARGS= \
@@ -85,8 +82,6 @@ install : $(TOOLS_JAR_ARCHIVE)
$(INSTALL) -m 644 -p $(TOOLS_JAR_ARCHIVE) $(INSTALL_TOOLS_JARFILE)
$(INSTALL) -m 644 -p $(FJBG_JARFILE) $(INSTALL_FJBG_JARFILE)
$(INSTALL) -m 644 -p $(MSIL_JARFILE) $(INSTALL_MSIL_JARFILE)
- $(INSTALL) -m 644 -p $(BCEL_JARFILE) $(INSTALL_BCEL_JARFILE)
- $(INSTALL) -m 644 -p $(BCEL_LICENSE) $(INSTALL_BCEL_LICENSE)
$(INSTALL) -m 755 -d $(INSTALL_SRCDIR)
$(strip $(MIRROR) -m 644 -p -C $(LIBRARY_ROOT) $(LIBRARY_LIST:%='%') \
$(INSTALL_SRCDIR)/$(PROJECT_NAME))
@@ -136,7 +131,6 @@ install-windows :
$(UNIX2DOS) $(INSTALL_PREFIX)/README
$(UNIX2DOS) $(INSTALL_PREFIX)/LICENSE
$(UNIX2DOS) $(INSTALL_PREFIX)/VERSION
- $(UNIX2DOS) $(INSTALL_BCEL_LICENSE)
$(TOUCH) $(INSTALL_PREFIX)/VERSION-$(INSTALL_VERSION)
@root=`cd "$(INSTALL_PREFIX)"; pwd`; \
for file in "" $(SCRIPTS_WRAPPER_ALIASES); do \
diff --git a/config/list/compiler.lst b/config/list/compiler.lst
index d14aa81552..4702e62f3b 100644
--- a/config/list/compiler.lst
+++ b/config/list/compiler.lst
@@ -42,8 +42,6 @@ backend/Primitive.java
backend/Primitives.java
backend/jvm/GenJVMPhase.java
backend/jvm/GenJVM.java
-backend/jvm/GenJVMBCELPhase.java
-backend/jvm/GenJVMBCEL.java
backend/msil/GenMSIL.java
backend/msil/GenMSILPhase.java
backend/msil/TypeCreator.java
diff --git a/sources/bin/.scala_wrapper.tmpl b/sources/bin/.scala_wrapper.tmpl
index c0c43f8d77..16c7745ce7 100644
--- a/sources/bin/.scala_wrapper.tmpl
+++ b/sources/bin/.scala_wrapper.tmpl
@@ -61,11 +61,6 @@ configure() {
# This variable must refer a directory or a zip or jar file.
MSIL_CLASSES={#MSIL_CLASSES#};
- # Location of the compiled bcel library. This library may be found
- # at http://jakarta.apache.org/bcel/.
- # This variable must refer a directory or a zip or jar file.
- BCEL_CLASSES={#BCEL_CLASSES#};
-
# Command to start the Java VM.
JAVA_EXEC="java";
@@ -241,7 +236,6 @@ compute_variable() {
TOOLS_CLASSES ) configure_path_variable "$1";;
FJBG_CLASSES ) configure_path_variable "$1";;
MSIL_CLASSES ) configure_path_variable "$1";;
- BCEL_CLASSES ) configure_path_variable "$1";;
JAVA_EXEC ) configure_variable "$1";;
JAVA_ARGS ) configure_variable "$1";;
EXEC ) configure_variable "$1";;
@@ -286,7 +280,6 @@ exec_compile() {
# compute Java classpath
append_path JAVA_CLASSPATH TOOLS_CLASSES;
- append_path JAVA_CLASSPATH BCEL_CLASSES;
append_path JAVA_CLASSPATH FJBG_CLASSES;
append_path JAVA_CLASSPATH MSIL_CLASSES;
@@ -416,7 +409,6 @@ scala_info_option_x_variable() {
TOOLS_CLASSES ) variable=$2;;
FJBG_CLASSES ) variable=$2;;
MSIL_CLASSES ) variable=$2;;
- BCEL_CLASSES ) variable=$2;;
JAVA_EXEC ) variable=$2;;
JAVA_ARGS ) variable=$2;;
EXEC ) variable=$2;;
@@ -442,7 +434,6 @@ scala_info_option_help() {
echo " TOOLS_CLASSES Location of the Scala tools";
echo " FJBG_CLASSES Location of the fjbg library";
echo " MSIL_CLASSES Location of the msil library";
- echo " BCEL_CLASSES Location of the bcel library";
echo " JAVA_EXEC Command to start the Java VM";
echo " JAVA_ARGS Additional arguments to pass to the Java VM";
echo " EXEC Command to start subprocesses";
diff --git a/sources/scalac/CompilerCommand.java b/sources/scalac/CompilerCommand.java
index 906dddebf9..b67cf14b26 100644
--- a/sources/scalac/CompilerCommand.java
+++ b/sources/scalac/CompilerCommand.java
@@ -160,7 +160,7 @@ public class CompilerCommand extends CommandParser {
"directory", "."),
this.target = new ChoiceOptionParser(this,
- "target", "Specify which bakend to use (jvm, jvm-bcel, msil)",
+ "target", "Specify which bakend to use (jvm, msil)",
"target", Global.TARGETS, Global.TARGET_JVM),
this.noimports = new BooleanOptionParser(this,
diff --git a/sources/scalac/CompilerPhases.java b/sources/scalac/CompilerPhases.java
index d1db650724..93007eda28 100644
--- a/sources/scalac/CompilerPhases.java
+++ b/sources/scalac/CompilerPhases.java
@@ -38,7 +38,6 @@ public class CompilerPhases {
public final PhaseDescriptor ERASURE;
public final PhaseDescriptor GENMSIL;
public final PhaseDescriptor GENJVM;
- public final PhaseDescriptor GENJVM_BCEL;
public final PhaseDescriptor TERMINAL;
//########################################################################
@@ -139,11 +138,6 @@ public class CompilerPhases {
"generate JVM bytecodes",
"generated JVM code",
scalac.backend.jvm.GenJVMPhase.class),
- this.GENJVM_BCEL = new PhaseDescriptor(
- "genjvm-bcel",
- "generate JVM bytecodes",
- "generated JVM code",
- scalac.backend.jvm.GenJVMBCELPhase.class),
this.TERMINAL = new PhaseDescriptor(
"terminal",
"compilation terminated",
diff --git a/sources/scalac/Global.java b/sources/scalac/Global.java
index 25780805d2..d13798fd8d 100644
--- a/sources/scalac/Global.java
+++ b/sources/scalac/Global.java
@@ -132,13 +132,11 @@ public class Global {
*/
public static final String TARGET_INT;
public static final String TARGET_JVM;
- public static final String TARGET_JVM_BCEL;
public static final String TARGET_MSIL;
public static final String[] TARGETS = new String[] {
TARGET_INT = "int".intern(),
TARGET_JVM = "jvm".intern(),
- TARGET_JVM_BCEL = "jvm-bcel".intern(),
TARGET_MSIL = "msil".intern(),
};
@@ -213,7 +211,6 @@ public class Global {
if (target != TARGET_JVM) args.phases.TAILCALL.addSkipFlag();
if (target != TARGET_MSIL) args.phases.GENMSIL.addSkipFlag();
if (target != TARGET_JVM) args.phases.GENJVM.addSkipFlag();
- if (target != TARGET_JVM_BCEL) args.phases.GENJVM_BCEL.addSkipFlag();
PHASE.freeze();
PhaseDescriptor[] descriptors = PHASE.phases();
this.firstPhase = descriptors[0].create(this);
diff --git a/sources/scalac/backend/jvm/GenJVMBCEL.java b/sources/scalac/backend/jvm/GenJVMBCEL.java
deleted file mode 100644
index cb26af50d9..0000000000
--- a/sources/scalac/backend/jvm/GenJVMBCEL.java
+++ /dev/null
@@ -1,1567 +0,0 @@
-/* ____ ____ ____ ____ ______ *\
-** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
-** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
-** /_____/\____/\___/\____/____/ **
-\* */
-
-// $Id$
-
-// TODO: create arrays with ANEWARRAY & friends
-
-// TODO: (maybe) add InnerClass attributes to .class files
-
-package scalac.backend.jvm;
-
-import ch.epfl.lamp.util.Position;
-
-import scalac.*;
-import scalac.backend.*;
-import scalac.util.*;
-import scalac.ast.*;
-import scalac.symtab.*;
-import scalac.symtab.classfile.ClassfileConstants;
-import scalac.transformer.*;
-
-import org.apache.bcel.*;
-import org.apache.bcel.generic.*;
-import org.apache.bcel.classfile.*;
-import org.apache.bcel.generic.Type;
-
-import java.util.*;
-import java.io.*;
-
-/**
- * Backend generating JVM byte-codes.
- *
- * @version 1.0
- * @author Michel Schinz
- */
-
-class GenJVMBCEL {
- protected final static String JAVA_LANG_OBJECT = "java.lang.Object";
- protected final static String JAVA_LANG_STRING = "java.lang.String";
- protected final static String JAVA_LANG_STRINGBUFFER = "java.lang.StringBuffer";
- protected final static String SCALA_RUNTIME_RUNTIME = "scala.runtime.RunTime";
- protected final static String SCALA_UNIT = "scala.Unit";
-
- protected final static String MODULE_INSTANCE_FIELD_NAME = "MODULE$";
- protected final static String VOID_NO_ARGS_SIG =
- Type.getMethodSignature(Type.VOID, Type.NO_ARGS);
- protected final static String[] EMPTY_STRING_ARRAY = new String[0];
-
- protected final static String UNIT_SIG =
- (new ObjectType(SCALA_UNIT)).getSignature();
-
- protected final static String CONSTRUCTOR_STRING =
- Constants.CONSTRUCTOR_NAME;
- protected final static Name CONSTRUCTOR_NAME =
- Name.fromString(CONSTRUCTOR_STRING);
-
- protected Unit unit = null;
- protected String sourceFileName = null;
-
- // Shortcut names for interfaces.
- protected final static InstructionConstants ic = null;
- protected final static Constants cst = null;
-
- protected final Global global;
- protected final Definitions defs;
- protected final Primitives prims;
-
- public GenJVMBCEL(Global global) {
- this.global = global;
- this.defs = global.definitions;
- this.prims = global.primitives;
- initTypeMap();
- initArithPrimMap();
- }
-
- public void translate(Unit unit) {
- this.unit = unit;
- sourceFileName = unit.source.toString();
- for (int i = 0; i < unit.body.length; ++i)
- gen(unit.body[i]);
- sourceFileName = null;
- this.unit = null;
- }
-
- // Context
- protected ClassGen currClass = null;
- protected String currClassName = null;
- protected ConstantPoolGen currPool = null;
- protected MethodGen currMethod = null;
- protected InstructionList currIL = null;
- protected Map currLocals = null;
- protected boolean isModuleClass = false;
-
- static class InstrContext {
- public case Empty;
- public case New;
- public case Assign;
- public case If(InstructionHandle target, boolean when);
- }
-
- // Line numbers attribution
- protected HashMap/*<InstructionHandle,Integer>*/ lineAttributedInstrs;
-
- protected void gen(Tree tree) {
- gen(tree, cst.T_VOID, InstrContext.Empty);
- }
-
- protected void gen(Tree tree, byte expectedType) {
- gen(tree, expectedType, InstrContext.Empty);
- }
-
- protected void gen(Tree tree, InstrContext ctx) {
- gen(tree, cst.T_VOID, ctx);
- }
-
- protected void gen(Tree[] trees) {
- for (int i = 0; i < trees.length; ++i)
- gen(trees[i]);
- }
-
- protected void gen(Tree[] trees, byte expectedType) {
- for (int i = 0; i < trees.length; ++i)
- gen(trees[i], expectedType);
- }
-
- protected void gen(Tree[] trees, InstrContext ctx) {
- for (int i = 0; i < trees.length; ++i)
- gen(trees[i], ctx);
- }
-
- protected void gen(Tree[] trees, byte expectedType, InstrContext ctx) {
- for (int i = 0; i < trees.length; ++i)
- gen(trees[i], expectedType, ctx);
- }
-
- protected void gen(Tree tree, byte expectedType, InstrContext ctx) {
- Symbol sym = tree.symbol();
- byte generatedType = cst.T_VOID;
-
- // Remember first instruction associated to this tree, to
- // generate line numbers.
- InstructionHandle startHandle;
- if (currIL != null)
- startHandle = currIL.getEnd();
- else
- startHandle = null;
-
- switch (tree) {
- case PackageDef(_, Tree.Template impl):
- gen(impl);
- break;
-
- case ClassDef(_, _, _, _, _, Tree.Template impl) : {
- Tree.ClassDef classDef = (Tree.ClassDef)tree;
-
- boolean oldIsModuleClass = isModuleClass;
- isModuleClass = Modifiers.Helper.isModClass(sym.flags);
- enterClass(sym);
-
- addValueClassMembers(classDef);
- if (isModuleClass)
- addModuleInstanceField();
-
- gen(impl);
- leaveClass(sym);
- isModuleClass = oldIsModuleClass;
- } break;
-
- case Template(_, Tree[] body):
- gen(body);
- break;
-
- case ValDef(_, Name name, _, Tree rhs): {
- if (currMethod == null)
- break; // ignore ValDefs in classes, handled elsewhere
-
- Type valType = typeStoJ(sym.info());
- LocalVariableGen lGen = currMethod.addLocalVariable(name.toString(),
- valType,
- currIL.getEnd(),
- null);
- int index = lGen.getIndex();
-
- if (rhs != Tree.Empty)
- gen(rhs, valType.getType());
- else {
- switch (valType.getType()) {
- case cst.T_BOOLEAN:
- case cst.T_BYTE:
- case cst.T_CHAR:
- case cst.T_SHORT:
- case cst.T_INT:
- currIL.append(new PUSH(currPool, 0)); break;
- case cst.T_LONG:
- currIL.append(new PUSH(currPool, 0L)); break;
- case cst.T_FLOAT:
- currIL.append(new PUSH(currPool, 0F)); break;
- case cst.T_DOUBLE:
- currIL.append(new PUSH(currPool, 0D)); break;
- default:
- currIL.append(ic.ACONST_NULL); break;
- }
- }
- currIL.append(new Generic_STORE(index, valType));
-
- currLocals.put(sym, new Integer(index));
- } break;
-
- case DefDef(_, _, _, _, _, Tree rhs): {
- enterMethod((Tree.DefDef)tree);
- if (! Modifiers.Helper.isAbstract(sym.flags)) {
- Type retType = currMethod.getReturnType();
- gen(rhs, retType.getType());
- currIL.append(new Generic_RETURN(retType));
- }
- leaveMethod();
- } break;
-
- case LabelDef(_, _, _):
- global.fail("not implemented yet " + tree);
- break;
-
- case Block(Tree[] stats): {
- int statsNum = stats.length;
- for (int i = 0; i < statsNum - 1; ++i)
- gen(stats[i], cst.T_VOID);
- if (statsNum == 0)
- maybeLoadUnit(expectedType);
- else
- gen(stats[stats.length - 1], expectedType, ctx);
- generatedType = expectedType;
- } break;
-
- case Typed(Tree expr, _):
- gen(expr, expectedType, ctx);
- generatedType = expectedType;
- break;
-
- case New(Tree.Template templ): {
- assert templ.body.length == 0;
- assert templ.parents.length == 1;
-
- String className = javaName(tree.type.symbol());
- currIL.append(new NEW(currPool.addClass(className)));
- currIL.append(ic.DUP);
- gen(templ.parents[0], InstrContext.New);
-
- generatedType = cst.T_OBJECT;
- } break;
-
- case Apply(TypeApply(Tree fun, Tree[] args), _): {
- Type type = typeStoJ(args[0].type);
- int typeIndex;
- if (type instanceof ObjectType)
- typeIndex = currPool.addClass((ObjectType)type);
- else if (type instanceof ArrayType)
- typeIndex = currPool.addArrayClass((ArrayType)type);
- else
- throw global.fail("unexpected type " + type);
-
- genLoadQualifier(fun);
-
- if (fun.symbol() == defs.IS) {
- currIL.append(new INSTANCEOF(typeIndex));
- generatedType = cst.T_BOOLEAN;
- } else if (fun.symbol() == defs.AS) {
- currIL.append(new CHECKCAST(typeIndex));
- generatedType = type.getType();
- } else
- global.fail("unexpected type application");
- } break;
-
- case Apply(Tree fun, Tree[] args): {
- if (isPrimitive(fun.symbol())) {
- Tree.Select selectFun = (Tree.Select)fun;
- Primitive prim = prims.getPrimitive(fun.symbol());
-
- if (prim == Primitive.CONCAT) {
- genStringConcatenation(liftStringConcatenations(tree));
- generatedType = cst.T_OBJECT;
- } else {
- Tree[] allArgs = new Tree[args.length + 1];
- allArgs[0] = unbox(selectFun.qualifier);
- System.arraycopy(args, 0, allArgs, 1, args.length);
- generatedType = genPrimitive(prim,
- allArgs,
- typeStoJ(tree.type).getType(),
- expectedType,
- ctx);
- }
- } else {
- Symbol funSym = fun.symbol();
- Type[] argTypes = argTypesStoJ(funSym.info());
- Type retType = retTypeStoJ(funSym.info());
- boolean isStatic = isStaticMember(funSym);
- if (!isStatic && ctx != InstrContext.New)
- genLoadQualifier(fun);
- for (int i = 0; i < args.length; ++i)
- gen(args[i], argTypes[i].getType());
-
- String className = javaName(funSym.owner());
- String methodName = funSym.name.toString();
- String methodSig = Type.getMethodSignature(retType, argTypes);
-
- if (funSym.owner().isInterface()) {
- int methodIndex =
- currPool.addInterfaceMethodref(className, methodName, methodSig);
- int argsSize = 1;
-
- for (int i = 0; i < args.length; ++i)
- argsSize += argTypes[i].getSize();
- currIL.append(new INVOKEINTERFACE(methodIndex, argsSize));
- } else {
- int methodIndex =
- currPool.addMethodref(className, methodName, methodSig);
- boolean isConstrCall = (funSym.name == CONSTRUCTOR_NAME);
- boolean isSuperCall;
- switch (fun) {
- case Select(Super(_, _), _): isSuperCall = true; break;
- default: isSuperCall = false; break;
- }
-
- if (isConstrCall || isSuperCall) {
- currIL.append(new INVOKESPECIAL(methodIndex));
- if (isConstrCall && isSuperCall && isModuleClass) {
- // Initialise module instance field ASAP
- String currClassSig =
- new ObjectType(currClassName).getSignature();
- int fieldRef =
- currPool.addFieldref(currClassName,
- MODULE_INSTANCE_FIELD_NAME,
- currClassSig);
- currIL.append(ic.THIS);
- currIL.append(new PUTSTATIC(fieldRef));
- }
- } else if (isStatic)
- currIL.append(new INVOKESTATIC(methodIndex));
- else
- currIL.append(new INVOKEVIRTUAL(methodIndex));
- }
-
- generatedType = retType.getType();
- }
- } break;
-
- case Ident(Name name): {
- Type type = typeStoJ(sym.info());
- if (sym.isModule())
- generatedType = genLoadModule(sym);
- else if (sym == defs.NULL) {
- currIL.append(ic.ACONST_NULL);
- generatedType = expectedType;
- } else if (sym.owner().isClass()) {
- currIL.append(ic.THIS);
- int fieldIdx = currPool.addFieldref(currClassName,
- name.toString(),
- type.getSignature());
- if (ctx == InstrContext.Assign) {
- currIL.append(new PUTFIELD(fieldIdx));
- generatedType = cst.T_VOID;
- } else {
- currIL.append(new GETFIELD(fieldIdx));
- generatedType = type.getType();
- }
- } else {
- assert currLocals.containsKey(sym)
- : Debug.show(sym) + " not in " + currLocals;
- int pos = ((Integer)currLocals.get(sym)).intValue();
- if (ctx == InstrContext.Assign) {
- currIL.append(new Generic_STORE(pos, type));
- generatedType = cst.T_VOID;
- } else {
- currIL.append(new Generic_LOAD(pos, type));
- generatedType = type.getType();
- }
- }
- } break;
-
- case Select(Tree qualifier, Name selector): {
- if (sym.isModule())
- generatedType = genLoadModule(sym);
- else {
- Type fieldType = typeStoJ(sym.info());
- int fieldIdx = currPool.addFieldref(javaName(sym.owner()),
- selector.toString(),
- fieldType.getSignature());
- if (isStaticMember(sym)) {
- if (ctx == InstrContext.Assign) {
- currIL.append(new PUTSTATIC(fieldIdx));
- generatedType = cst.T_VOID;
- } else {
- currIL.append(new GETSTATIC(fieldIdx));
- generatedType = fieldType.getType();
- }
- } else {
- genLoadQualifier(tree);
- if (ctx == InstrContext.Assign) {
- currIL.append(new PUTFIELD(fieldIdx));
- generatedType = cst.T_VOID;
- } else {
- currIL.append(new GETFIELD(fieldIdx));
- generatedType = fieldType.getType();
- }
- }
- }
- } break;
-
- case Assign(Tree lhs, Tree rhs): {
- gen(lhs, InstrContext.Assign);
- InstructionHandle storeHandle = currIL.getEnd();
- gen(rhs, typeStoJ(lhs.symbol().info()).getType());
- // Work around BCEL bug (see below)
- currIL.move(storeHandle, currIL.append(ic.NOP).getPrev());
- } break;
-
- case If(Tree cond, Tree thenp, Tree elsep): {
- byte finalType = typeStoJ(tree.type).getType();
-
- InstructionHandle fakeElseH = currIL.append(ic.NOP);
- gen(cond, cst.T_VOID, new InstrContext.If(fakeElseH, false));
- InstructionHandle thenH = currIL.append(ic.NOP);
- gen(thenp, finalType);
- BranchInstruction gotoAfter = new GOTO(null);
- currIL.append(gotoAfter);
- InstructionHandle elseH = currIL.append(ic.NOP);
- if (elsep == Tree.Empty)
- maybeLoadUnit(finalType);
- else
- gen(elsep, finalType);
- gotoAfter.setTarget(currIL.append(ic.NOP));
- // We cannot move the instructions sooner because BCEL has
- // a bug which makes it impossible to move instructions at
- // the end of the list.
- currIL.move(fakeElseH, elseH);
- generatedType = finalType;
- } break;
-
- case This(_):
- currIL.append(ic.THIS);
- generatedType = cst.T_OBJECT;
- break;
-
- case Literal(Object value):
- if (value instanceof Integer) {
- generatedType = cst.T_INT;
- currIL.append(new PUSH(currPool, (Integer)value));
- } else if (value instanceof Long) {
- generatedType = cst.T_LONG;
- currIL.append(new PUSH(currPool, (Long)value));
- } else if (value instanceof Float) {
- generatedType = cst.T_FLOAT;
- currIL.append(new PUSH(currPool, (Float)value));
- } else if (value instanceof Double) {
- generatedType = cst.T_DOUBLE;
- currIL.append(new PUSH(currPool, (Double)value));
- } else if (value instanceof Character) {
- generatedType = cst.T_CHAR;
- currIL.append(new PUSH(currPool, (Character)value));
- } else if (value instanceof String) {
- generatedType = cst.T_OBJECT;
- currIL.append(new PUSH(currPool, (String)value));
- } else if (value instanceof Boolean) {
- generatedType = cst.T_BOOLEAN;
- currIL.append(new PUSH(currPool, (Boolean)value));
- } else
- throw global.fail("unknown literal " + value);
- break;
-
- case Empty:
- case AbsTypeDef(_, _, _, _):
- case AliasTypeDef(_, _, _, _):
- case TypeApply(_, _):
- case FunType(_, _):
- case CompoundType(_, _):
- case AppliedType(_,_):
- break;
-
- case Sequence(_):
- case Super(_, _):
- case ModuleDef(_,_,_,_):
- case PatDef(_,_,_):
- case Import(_, _):
- case CaseDef(_, _, _):
- case Visitor(_):
- case Function(_, _):
- throw global.fail("unexpected node", tree);
- case Bad():
- throw global.fail("bad tree");
- default:
- throw global.fail("unknown node", tree);
- }
-
- // Pop unneeded result from stack, or widen it if needed.
- if (expectedType == cst.T_VOID && generatedType != cst.T_VOID) {
- if (generatedType == cst.T_LONG || generatedType == cst.T_DOUBLE)
- currIL.append(ic.POP2);
- else {
- switch (ctx) {
- case If(InstructionHandle target, boolean when):
- assert generatedType == cst.T_BOOLEAN : generatedType;
- currIL.append(when ? new IFNE(target) : new IFEQ(target));
- break;
- default:
- currIL.append(ic.POP);
- }
- }
- } else if (! (expectedType == cst.T_VOID
- || generatedType == expectedType
- || (generatedType == cst.T_ARRAY
- && expectedType == cst.T_OBJECT)))
- genWidenConversion(generatedType, expectedType);
-
- // Associate line numbers to instructions we just generated.
- if (currIL != null) {
- InstructionHandle ih =
- (startHandle == null ? currIL.getStart() : startHandle);
- int prevLine = -1;
- while (ih != null) {
- if (lineAttributedInstrs.containsKey(ih))
- prevLine = ((Integer)lineAttributedInstrs.get(ih)).intValue();
- else {
- int line = Position.line(tree.pos);
- lineAttributedInstrs.put(ih, new Integer(line));
- if (line != prevLine) {
- currMethod.addLineNumber(ih, line);
- prevLine = line;
- }
- }
- ih = ih.getNext();
- }
- }
- }
-
- protected Tree unbox(Tree tree) {
- switch (tree) {
- case Apply(Tree fun, Tree[] args):
- if (prims.getPrimitive(fun.symbol()) == Primitive.BOX) {
- assert args.length == 1;
- return args[0];
- } else
- return tree;
- case Block(Tree[] stats):
- if (stats.length == 2
- && prims.getPrimitive(stats[1].symbol()) == Primitive.BOX) {
- return stats[0];
- } else
- return tree;
- default:
- return tree;
- }
- }
-
- // Add field containing module instance, and code to
- // initialize it, to current class.
- protected void addModuleInstanceField() {
- FieldGen instanceField =
- new FieldGen(cst.ACC_PUBLIC
- | cst.ACC_FINAL
- | cst.ACC_STATIC,
- new ObjectType(currClassName),
- MODULE_INSTANCE_FIELD_NAME,
- currPool);
- currClass.addField(instanceField.getField());
-
- InstructionList initIL = new InstructionList();
-
- int constrRef = currPool.addMethodref(currClassName,
- CONSTRUCTOR_STRING,
- VOID_NO_ARGS_SIG);
-
- initIL.append(new NEW(currPool.addClass(currClassName)));
- initIL.append(new INVOKESPECIAL(constrRef));
- initIL.append(ic.RETURN);
-
- MethodGen initMethod =
- new MethodGen(cst.ACC_PUBLIC | cst.ACC_STATIC,
- Type.VOID, Type.NO_ARGS, Strings.EMPTY_ARRAY,
- "<clinit>",
- currClassName,
- initIL,
- currPool);
- initMethod.setMaxStack();
- currClass.addMethod(initMethod.getMethod());
- }
-
- // Add value members (i.e. fields) to current class.
- protected void addValueClassMembers(Tree.ClassDef cDef) {
- Symbol cSym = cDef.symbol();
- Scope.SymbolIterator memberIt =
- new Scope.UnloadIterator(cSym.members().iterator());
- while (memberIt.hasNext()) {
- Symbol member = memberIt.next();
- if (member.isTerm() && !member.isMethod()) {
- FieldGen fGen = new FieldGen(modifiersStoJ(member.flags),
- typeStoJ(member.info()),
- member.name.toString(),
- currPool);
- currClass.addField(fGen.getField());
- }
- }
- }
-
- protected void maybeLoadUnit(byte expectedType) {
- if (expectedType == cst.T_OBJECT) {
- int unitFieldRef = currPool.addFieldref(SCALA_RUNTIME_RUNTIME,
- "UNIT_VAL",
- UNIT_SIG);
- currIL.append(new GETSTATIC(unitFieldRef));
- }
- }
-
- protected byte genLoadModule(Symbol sym) {
- String javaSymName = javaName(sym.moduleClass());
- if (javaSymName.equals(currClassName))
- currIL.append(ic.THIS);
- else {
- int moduleInstIdx =
- currPool.addFieldref(javaSymName,
- MODULE_INSTANCE_FIELD_NAME,
- typeStoJ(sym.info()).getSignature());
- currIL.append(new GETSTATIC(moduleInstIdx));
- }
- return cst.T_OBJECT;
- }
-
- protected void genLoadQualifier(Tree tree) {
- switch (tree) {
- case Select(Super(_, _), _):
- case Ident(_):
- currIL.append(ic.THIS);
- break;
- case Select(Tree qualifier, _):
- gen(qualifier, cst.T_OBJECT);
- break;
- default:
- throw global.fail("unknown qualifier");
- }
- }
-
- protected boolean isStaticMember(Symbol sym) {
- return (sym.name != CONSTRUCTOR_NAME)
- && sym.owner().isModuleClass()
- && sym.owner().isJava();
- }
-
- protected boolean isPrimitive(Symbol sym) {
- if (prims.isPrimitive(sym)) {
- switch (prims.getPrimitive(sym)) {
- case POS : case NEG :
- case ADD : case SUB : case MUL : case DIV : case MOD :
- case NOT : case OR : case XOR : case AND :
- case LSL : case LSR : case ASR :
- case EQ : case NE : case LT : case LE : case GE : case GT :
- case ZNOT : case ZOR : case ZAND :
- case NEW_ZARRAY : case NEW_BARRAY : case NEW_SARRAY :
- case NEW_CARRAY : case NEW_IARRAY : case NEW_LARRAY :
- case NEW_FARRAY : case NEW_DARRAY :
- case ZARRAY_GET : case BARRAY_GET : case SARRAY_GET :
- case CARRAY_GET : case IARRAY_GET : case LARRAY_GET :
- case FARRAY_GET : case DARRAY_GET : case OARRAY_GET :
- case ZARRAY_SET : case BARRAY_SET : case SARRAY_SET :
- case CARRAY_SET : case IARRAY_SET : case LARRAY_SET :
- case FARRAY_SET : case DARRAY_SET : case OARRAY_SET :
- case ZARRAY_LENGTH : case BARRAY_LENGTH : case SARRAY_LENGTH :
- case CARRAY_LENGTH : case IARRAY_LENGTH : case LARRAY_LENGTH :
- case FARRAY_LENGTH : case DARRAY_LENGTH : case OARRAY_LENGTH :
- case IS : case AS :
- case CONCAT :
- case THROW :
- case AS_UVALUE :
- return true;
-
- case AS_ZVALUE : case AS_BVALUE : case AS_SVALUE :
- case AS_CVALUE : case AS_IVALUE : case AS_LVALUE :
- case AS_FVALUE : case AS_DVALUE :
- case AS_ZARRAY : case AS_BARRAY : case AS_SARRAY :
- case AS_CARRAY : case AS_IARRAY : case AS_LARRAY :
- case AS_FARRAY : case AS_DARRAY : case AS_OARRAY :
- case NEW_OARRAY :
- case EQUALS :
- case HASHCODE :
- case TOSTRING :
- case BOX :
- case APPLY : case UPDATE : case LENGTH :
- return false;
- default:
- throw Debug.abort("unknown primitive", sym);
- }
- } else
- return false;
- }
-
- protected byte genPrimitive(Primitive prim,
- Tree[] args,
- byte resType,
- byte expectedType,
- InstrContext ctx) {
- switch (prim) {
- case POS: case NEG:
- case ADD: case SUB: case MUL: case DIV: case MOD:
- case NOT: case OR : case XOR: case AND:
- case LSL: case LSR: case ASR:
- return genArithPrim(prim, args, resType, expectedType, ctx);
- case EQ: case NE: case LT: case LE: case GE: case GT:
- case ZNOT: case ZOR: case ZAND:
- return genCompOrLogicalPrim(prim, args, resType, expectedType, ctx);
- case THROW:
- assert args.length == 1;
- return genThrow(args[0]);
- case NEW_ZARRAY :
- case NEW_BARRAY :
- case NEW_SARRAY :
- case NEW_CARRAY :
- case NEW_IARRAY :
- case NEW_LARRAY :
- case NEW_FARRAY :
- case NEW_DARRAY :
- return genArrayCreate(prim, args[1]);
-// case NEW_OARRAY :
-// return genArrayCreate(prim, args[1], args[2]);
- case ZARRAY_SET : case BARRAY_SET : case SARRAY_SET :
- case CARRAY_SET : case IARRAY_SET : case LARRAY_SET :
- case FARRAY_SET : case DARRAY_SET : case OARRAY_SET :
- assert args.length == 4;
- return genArrayUpdate(args[1], args[2], args[3]);
- case ZARRAY_GET : case BARRAY_GET : case SARRAY_GET :
- case CARRAY_GET : case IARRAY_GET : case LARRAY_GET :
- case FARRAY_GET : case DARRAY_GET : case OARRAY_GET :
- assert args.length == 3 : "get - " + args.length;
- return genArrayAccess(args[1], args[2]);
- case ZARRAY_LENGTH : case BARRAY_LENGTH : case SARRAY_LENGTH :
- case CARRAY_LENGTH : case IARRAY_LENGTH : case LARRAY_LENGTH :
- case FARRAY_LENGTH : case DARRAY_LENGTH : case OARRAY_LENGTH :
- assert args.length == 2 : args.length;
- return genArrayLength(args[1]);
- case AS_UVALUE :
- assert args.length == 1;
- gen(args[0], cst.T_VOID);
- return cst.T_VOID;
- default:
- throw Debug.abort("unknown primitive ", prim);
- }
- }
-
- protected Map/*<Primitive, Instruction>*/ arithPrimMap;
- protected void addPrim(Primitive prim,
- Instruction z,
- Instruction i,
- Instruction l,
- Instruction f,
- Instruction d) {
- arithPrimMap.put(prim, new Instruction[] { z, i, l, f, d });
- }
-
- protected void initArithPrimMap() {
- arithPrimMap = new HashMap();
- /* boolean int ... long float double */
- addPrim(Primitive.ADD , null, ic.IADD , ic.LADD , ic.FADD , ic.DADD);
- addPrim(Primitive.SUB , null, ic.ISUB , ic.LSUB , ic.FSUB , ic.DSUB);
- addPrim(Primitive.MUL , null, ic.IMUL , ic.LMUL , ic.FMUL , ic.DMUL);
- addPrim(Primitive.DIV , null, ic.IDIV , ic.LDIV , ic.FDIV , ic.DDIV);
- addPrim(Primitive.MOD , null, ic.IREM , ic.LREM , ic.FREM , ic.DREM);
- addPrim(Primitive.AND , ic.IAND, ic.IAND , ic.LAND , null , null);
- addPrim(Primitive.OR , ic.IOR, ic.IOR , ic.LOR , null , null);
- addPrim(Primitive.XOR , ic.IXOR, ic.IXOR , ic.LXOR , null , null);
- addPrim(Primitive.LSL , null, ic.ISHL , ic.LSHL , null , null);
- addPrim(Primitive.LSR , null, ic.IUSHR , ic.LUSHR , null , null);
- addPrim(Primitive.ASR , null, ic.ISHR , ic.LSHR , null , null);
- addPrim(Primitive.POS , null, null , null , null , null);
- addPrim(Primitive.NEG , null, ic.INEG , ic.LNEG , ic.FNEG , ic.DNEG);
- }
-
- protected byte genArithPrim(Primitive prim,
- Tree[] args,
- byte resType,
- byte expectedType,
- InstrContext ctx) {
- int arity = args.length;
- int resTypeIdx = getTypeIndex(resType);
-
- for (int i = 0; i < arity; ++i)
- gen(args[i], resType);
-
- if (prim == Primitive.NOT) {
- assert resType == cst.T_INT || resType == cst.T_LONG;
- boolean isLong = (resType == cst.T_LONG);
- if (isLong) {
- currIL.append(new PUSH(currPool, -1L));
- currIL.append(ic.LXOR);
- } else {
- currIL.append(new PUSH(currPool, -1));
- currIL.append(ic.IXOR);
- }
- } else {
- assert arithPrimMap.containsKey(prim);
- Instruction primInst = ((Instruction[])arithPrimMap.get(prim))[resTypeIdx];
- if (primInst != null)
- currIL.append(primInst);
- }
- return resType;
- }
-
- protected byte genCompOrLogicalPrim(Primitive prim,
- Tree[] args,
- byte resType,
- byte expectedType,
- InstrContext ctx) {
- // Ensure that all comparisons happen in the context of an
- // "if".
- InstructionHandle target;
- boolean when;
- InstructionList epilogue = new InstructionList();
- byte realResType;
- switch (ctx) {
- case InstrContext.If(InstructionHandle t, boolean w):
- target = t; when = w; realResType = cst.T_VOID; break;
- default:
- epilogue.append(ic.ICONST_1);
- BranchInstruction gotoAfter = new GOTO(null);
- epilogue.append(gotoAfter);
- target = epilogue.append(ic.ICONST_0);
- gotoAfter.setTarget(epilogue.append(ic.NOP));
- when = false;
- realResType = cst.T_BOOLEAN;
- break;
- }
-
- if (prim == Primitive.ZNOT
- || prim == Primitive.ZOR
- || prim == Primitive.ZAND)
- genLogicalPrim(prim, args, resType, expectedType, target, when);
- else
- genCompPrim(prim, args, resType, expectedType, target, when);
-
- currIL.append(epilogue);
- return realResType;
- }
-
- protected byte getMaxType(Tree[] trees) {
- byte maxType = cst.T_BOOLEAN;
- int maxTypeIdx = getTypeIndex(maxType);
-
- for (int i = 0; i < trees.length; ++i) {
- byte argType = typeStoJ(trees[i].type).getType();
- if (getTypeIndex(argType) > maxTypeIdx) {
- maxType = argType;
- maxTypeIdx = getTypeIndex(maxType);
- }
- }
- return maxType;
- }
-
- protected static int tempCounter = 1;
- protected void genCompPrim(Primitive prim,
- Tree[] args,
- byte resType,
- byte expectedType,
- InstructionHandle target,
- boolean when) {
- byte maxType = getMaxType(args);
- int maxTypeIdx = getTypeIndex(maxType);
- int intTypeIdx = getTypeIndex(Type.INT);
- boolean intCompareWithZero = false;
- for (int i = 0; i < args.length; ++i) {
- boolean isIntZero = false;
- if (maxTypeIdx <= intTypeIdx) {
- switch (args[i]) {
- case Literal(Object val):
- int intVal;
- if (val instanceof Number)
- intVal = ((Number)val).intValue();
- else if (val instanceof Character)
- intVal = ((Character)val).charValue();
- else if (val instanceof Boolean)
- intVal = ((Boolean)val).booleanValue() ? 1 : 0;
- else
- throw Debug.abort("unknown literal", val);
- if (intVal == 0) {
- isIntZero = true;
- if (i == 0) prim = prim.swap();
- }
- }
- }
- if (intCompareWithZero || !isIntZero)
- gen(args[i], maxType);
- intCompareWithZero |= isIntZero;
- }
-
- if (maxType == cst.T_OBJECT) {
- assert prim == Primitive.EQ || prim == Primitive.NE;
-
- LocalVariableGen lGen =
- currMethod.addLocalVariable("temp" + tempCounter++,
- Type.OBJECT,
- currIL.getEnd(),
- null);
- currIL.append(new ASTORE(lGen.getIndex()));
- currIL.append(ic.DUP);
- BranchInstruction ifNonNull = new IFNONNULL(null);
- currIL.append(ifNonNull);
- currIL.append(ic.POP);
- currIL.append(new ALOAD(lGen.getIndex()));
- if (when ^ (prim != Primitive.EQ))
- currIL.append(new IFNULL(target));
- else
- currIL.append(new IFNONNULL(target));
- BranchInstruction gotoAfter = new GOTO(null);
- currIL.append(gotoAfter);
- InstructionHandle nonNullHandle =
- currIL.append(new ALOAD(lGen.getIndex()));
- ifNonNull.setTarget(nonNullHandle);
- lGen.setEnd(nonNullHandle);
- String equalsSig =
- Type.getMethodSignature(Type.BOOLEAN,
- new Type[] { Type.OBJECT });
- int equalsIndex =
- currPool.addMethodref(JAVA_LANG_OBJECT, "equals", equalsSig);
- currIL.append(new INVOKEVIRTUAL(equalsIndex));
- if (when ^ (prim != Primitive.EQ))
- currIL.append(new IFNE(target));
- else
- currIL.append(new IFEQ(target));
- gotoAfter.setTarget(currIL.append(ic.NOP));
- } else if (maxTypeIdx <= intTypeIdx && !intCompareWithZero) {
- switch (maybeNegatedPrim(prim, !when)) {
- case LT: currIL.append(new IF_ICMPLT(target)); break;
- case LE: currIL.append(new IF_ICMPLE(target)); break;
- case EQ: currIL.append(new IF_ICMPEQ(target)); break;
- case NE: currIL.append(new IF_ICMPNE(target)); break;
- case GE: currIL.append(new IF_ICMPGE(target)); break;
- case GT: currIL.append(new IF_ICMPGT(target)); break;
- default: throw global.fail("unknown primitive " + prim);
- }
- } else {
- switch (maxType) {
- case cst.T_LONG: currIL.append(ic.LCMP); break;
- case cst.T_FLOAT: currIL.append(ic.FCMPG); break;
- case cst.T_DOUBLE: currIL.append(ic.DCMPG); break;
- default:
- ; // do nothing (int comparison with 0)
- }
- switch (maybeNegatedPrim(prim, !when)) {
- case LT: currIL.append(new IFLT(target)); break;
- case LE: currIL.append(new IFLE(target)); break;
- case EQ: currIL.append(new IFEQ(target)); break;
- case NE: currIL.append(new IFNE(target)); break;
- case GE: currIL.append(new IFGE(target)); break;
- case GT: currIL.append(new IFGT(target)); break;
- default: throw global.fail("unknown primitive " + prim);
- }
- }
- }
-
- protected Primitive maybeNegatedPrim(Primitive prim, boolean negate) {
- return negate ? prim.negate() : prim;
- }
-
- protected void genLogicalPrim(Primitive prim,
- Tree[] args,
- byte resType,
- byte expectedType,
- InstructionHandle target,
- boolean when) {
- if (prim == Primitive.ZNOT)
- gen(args[0], new InstrContext.If(target, !when));
- else {
- InstructionHandle fakeAfterH = currIL.append(ic.NOP);
- if (when ^ (prim == Primitive.ZAND)) {
- // x || y jump if true or x && y jump if false
- gen(args[0], new InstrContext.If(target, when));
- gen(args[1], new InstrContext.If(target, when));
- } else {
- // x || y jump if false or x && y jump if true
- gen(args[0], new InstrContext.If(fakeAfterH, !when));
- gen(args[1], new InstrContext.If(target, when));
- currIL.move(fakeAfterH, currIL.append(ic.NOP).getPrev());
- }
- }
- }
-
- protected byte genThrow(Tree arg) {
- gen(arg, cst.T_OBJECT);
- currIL.append(new CHECKCAST(currPool.addClass("java.lang.Throwable")));
- currIL.append(ic.ATHROW);
- return cst.T_OBJECT;
- }
-
- protected byte genArrayCreate(Primitive prim, Tree size) {
- gen(size, cst.T_INT);
- byte type;
- switch (prim) {
- case NEW_ZARRAY : type = cst.T_BOOLEAN; break;
- case NEW_BARRAY : type = cst.T_BYTE; break;
- case NEW_SARRAY : type = cst.T_SHORT; break;
- case NEW_CARRAY : type = cst.T_CHAR; break;
- case NEW_IARRAY : type = cst.T_INT; break;
- case NEW_LARRAY : type = cst.T_LONG; break;
- case NEW_FARRAY : type = cst.T_FLOAT; break;
- case NEW_DARRAY : type = cst.T_DOUBLE; break;
- default: throw Debug.abort("unexpected primitive", prim);
- }
- currIL.append(new NEWARRAY(type));
- return cst.T_ARRAY;
- }
-
- protected byte genArrayUpdate(Tree array, Tree index, Tree value) {
- ArrayType arrayType = (ArrayType)typeStoJ(array.type);
- Type elemType = arrayType.getElementType();
- gen(array, cst.T_ARRAY);
- gen(index, cst.T_INT);
- if (elemType instanceof BasicType)
- value = unbox(value);
- gen(value, elemType.getType());
- currIL.append(new Generic_ASTORE(elemType));
- return cst.T_VOID;
- }
-
- protected byte genArrayAccess(Tree array, Tree index) {
- ArrayType arrayType = (ArrayType)typeStoJ(array.type);
- Type elemType = arrayType.getElementType();
- gen(array, cst.T_ARRAY);
- gen(index, cst.T_INT);
- currIL.append(new Generic_ALOAD(elemType));
- return elemType.getType();
- }
-
- protected byte genArrayLength(Tree array) {
- gen(array, cst.T_ARRAY);
- currIL.append(ic.ARRAYLENGTH);
- return cst.T_INT;
- }
-
- protected Tree[] liftStringConcatenations(Tree tree) {
- LinkedList accu = new LinkedList();
- liftStringConcatenations(tree, accu);
- return (Tree[])accu.toArray(new Tree[accu.size()]);
- }
-
- protected void liftStringConcatenations(Tree tree, LinkedList accu) {
- switch (tree) {
- case Apply(Select(Tree qualifier, Name selector), Tree[] args): {
- Symbol funSym = ((Tree.Apply)tree).fun.symbol();
- if (prims.isPrimitive(funSym)
- && prims.getPrimitive(funSym) == Primitive.CONCAT) {
- liftStringConcatenations(qualifier, accu);
- liftStringConcatenations(args[0], accu);
- } else
- accu.addLast(tree);
- } break;
- default:
- accu.addLast(tree);
- }
- }
-
- protected void genStringConcatenation(Tree[] elements) {
- ObjectType strBufType = new ObjectType (JAVA_LANG_STRINGBUFFER);
-
- int constRef = currPool.addMethodref(JAVA_LANG_STRINGBUFFER,
- "<init>",
- VOID_NO_ARGS_SIG);
- currIL.append (new NEW (currPool.addClass (JAVA_LANG_STRINGBUFFER)));
- currIL.append (ic.DUP);
- currIL.append (new INVOKESPECIAL (constRef));
-
- for (int i = 0; i < elements.length; ++i) {
- Type elemType = typeStoJ(elements[i].type);
- if (!elemType.equals(Type.STRING)
- && elemType.getType() == cst.T_OBJECT)
- elemType = Type.OBJECT;
- String appendSig =
- Type.getMethodSignature(strBufType, new Type[] { elemType });
- int appendRef =
- currPool.addMethodref(JAVA_LANG_STRINGBUFFER, "append", appendSig);
- gen(elements[i], elemType.getType());
- currIL.append(new INVOKEVIRTUAL(appendRef));
- }
-
- String toStringSig = Type.getMethodSignature (Type.STRING, Type.NO_ARGS);
- final int toStringRef =
- currPool.addMethodref (JAVA_LANG_STRINGBUFFER, "toString", toStringSig);
- currIL.append (new INVOKEVIRTUAL (toStringRef));
- }
-
- protected int getTypeIndex(Type tp) {
- return getTypeIndex(tp.getType());
- }
-
- protected int getTypeIndex(byte tp) {
- switch (tp) {
- case cst.T_BOOLEAN: return 0;
- case cst.T_BYTE:
- case cst.T_CHAR:
- case cst.T_SHORT:
- case cst.T_INT: return 1;
- case cst.T_LONG: return 2;
- case cst.T_FLOAT: return 3;
- case cst.T_DOUBLE: return 4;
- case cst.T_ARRAY:
- case cst.T_OBJECT: return 5;
- default: return -1;
- }
- }
-
- protected Instruction[][] WIDENING_CONVERSION_TABLE = {
- /* bool int long float double */
- /* boolean */ { null, null , null , null , null },
- /* int ... */ { null, null , ic.I2L , ic.I2F , ic.I2D },
- /* long */ { null, null , null , ic.L2F , ic.L2D },
- /* float */ { null, null , null , null , ic.F2D },
- /* double */ { null, null , null , null , null }
- };
-
- protected void genWidenConversion(byte origType, byte finalType) {
- int origIdx = getTypeIndex(origType);
- int finalIdx = getTypeIndex(finalType);
-
- assert (origIdx <= 4 && finalIdx <= 4)
- : cst.TYPE_NAMES[origType] + " -> " + cst.TYPE_NAMES[finalType];
- Instruction instr = WIDENING_CONVERSION_TABLE[origIdx][finalIdx];
- if (instr != null)
- currIL.append(instr);
- }
-
- protected void dumpModuleMainClass(ClassGen modClassGen) {
- String moduleName = modClassGen.getClassName();
- String mainClassName = moduleName.substring(0, moduleName.length() - 1);
- ClassGen mainClassGen = new ClassGen(mainClassName,
- JAVA_LANG_OBJECT,
- sourceFileName,
- cst.ACC_SUPER
- | cst.ACC_PUBLIC
- | cst.ACC_FINAL,
- Strings.EMPTY_ARRAY);
- ConstantPoolGen mainPool = mainClassGen.getConstantPool();
-
- Method[] methods = modClassGen.getMethods();
- for (int i = 0; i < methods.length; ++i) {
- Method m = methods[i];
- if (m.isProtected() || m.isPrivate() || m.isStatic()
- || m.getName().equals("<init>"))
- continue;
-
- MethodGen mGen = new MethodGen(m, moduleName, mainPool);
-
- Type[] argTypes = mGen.getArgumentTypes();
- Type retType = mGen.getReturnType();
-
- InstructionList mainIL = new InstructionList();
- MethodGen mainMGen = new MethodGen(m.getAccessFlags() | cst.ACC_STATIC,
- retType,
- argTypes, mGen.getArgumentNames(),
- mGen.getName(),
- mainClassName,
- mainIL,
- mainPool);
- int moduleFieldIndex =
- mainPool.addFieldref(moduleName,
- MODULE_INSTANCE_FIELD_NAME,
- (new ObjectType(moduleName)).getSignature());
- int mIndex = mainPool.addMethodref(mGen);
-
- mainIL.append(new GETSTATIC(moduleFieldIndex));
- int pos = 0;
- for (int j = 0; j < argTypes.length; ++j) {
- mainIL.append(new Generic_LOAD(pos, argTypes[j]));
- pos += argTypes[j].getSize();
- }
- mainIL.append(new INVOKEVIRTUAL(mIndex));
- mainIL.append(new Generic_RETURN(retType));
- mainMGen.setMaxStack();
- mainClassGen.addMethod(mainMGen.getMethod());
- }
-
- addScalaAttr(mainClassGen);
- JavaClass mainClass = mainClassGen.getJavaClass();
- try {
- mainClass.dump(javaFileName(mainClassName));
- } catch (java.io.IOException e) {
- throw global.fail(e.getMessage());
- }
- }
-
-
- protected void addScalaAttr(ClassGen classGen) {
- ConstantPoolGen poolGen = classGen.getConstantPool();
-
- int scalaNameIndex =
- poolGen.addUtf8(ClassfileConstants.SCALA_N.toString());
- Unknown scalaAttr = new Unknown(scalaNameIndex,
- 0,
- null,
- poolGen.getConstantPool());
-
- classGen.addAttribute(scalaAttr);
- }
-
- // Context manipulation
-
- protected LinkedList/*<ClassGen>*/ classStack = new LinkedList();
-
- protected void enterClass(Symbol cSym) {
- String javaName = javaName(cSym);
-
- scalac.symtab.Type[] baseTps = cSym.info().parents();
- assert baseTps.length > 0 : Debug.show(cSym);
-
- int offset;
- String superClassName;
- if (cSym.isInterface()) {
- offset = baseTps[0].isSameAs(defs.ANY_TYPE) ? 1 : 0;
- superClassName = JAVA_LANG_OBJECT;
- } else {
- offset = 1;
- superClassName = javaName(baseTps[0].symbol());
- }
- String[] interfaceNames = new String[baseTps.length - offset];
- for (int i = offset; i < baseTps.length; ++i) {
- Symbol baseSym = baseTps[i].symbol();
- assert baseSym.isInterface() : cSym + " implements " + baseSym;
- interfaceNames[i - offset] = javaName(baseSym);
- }
-
- ClassGen cGen = new ClassGen(javaName,
- superClassName,
- sourceFileName,
- modifiersStoJ(cSym.flags) | cst.ACC_SUPER,
- interfaceNames);
- classStack.addFirst(cGen);
- updateClassContext();
- }
-
- protected HashSet seenClasses = new HashSet();
- protected void leaveClass(Symbol cSym) {
- if (isModuleClass) {
- if (!seenClasses.contains(cSym.fullName()))
- dumpModuleMainClass(currClass);
- } else
- seenClasses.add(cSym.fullName());
-
- addScalaAttr(currClass);
- JavaClass cls = currClass.getJavaClass();
- try {
- String fileName = javaFileName(cls.getClassName());
- cls.dump(fileName);
- global.operation("wrote " + fileName);
- } catch (java.io.IOException e) {
- throw global.fail(e.getMessage());
- }
- classStack.removeFirst();
- updateClassContext();
- }
-
- protected void updateClassContext() {
- if (classStack.isEmpty()) {
- currClass = null;
- currClassName = null;
- currPool = null;
- } else {
- ClassGen cGen = (ClassGen)classStack.getFirst();
- currClass = cGen;
- currClassName = currClass.getClassName();
- currPool = currClass.getConstantPool();
- }
- }
-
- protected void enterMethod(Tree.DefDef dDef) {
- Symbol dSym = dDef.symbol();
-
- global.log("entering method " + Debug.toString(dSym)
- + " (type: " + Debug.toString(dSym.info()) + ")");
-
- Map locals;
- if (currLocals == null)
- locals = new HashMap();
- else
- locals = new HashMap(currLocals);
-
- Tree.ValDef[] args = dDef.vparams[0];
- int argsNum = args.length;
-
- Type[] argTypes = new Type[argsNum];
- String[] argNames = new String[argsNum];
- for (int i = 0, pos = 1; i < argsNum; ++i) {
- argTypes[i] = typeStoJ(args[i].symbol().info());
- argNames[i] = args[i].name.toString();
- locals.put(args[i].symbol(), new Integer(pos));
- pos += argTypes[i].getSize();
- }
-
- MethodGen mGen = new MethodGen(modifiersStoJ(dDef.mods),
- retTypeStoJ(dSym.info()),
- argTypes,
- argNames,
- dDef.name.toString(),
- currClassName,
- new InstructionList(),
- currPool);
-
- currMethod = mGen;
- currLocals = locals;
- currIL = currMethod.getInstructionList();
-
- lineAttributedInstrs = new HashMap();
- }
-
- protected void leaveMethod() {
- global.log(" leaving method");
-
- currMethod.setMaxStack();
- currMethod.removeNOPs();
- currClass.addMethod(currMethod.getMethod());
-
- currMethod = null;
- currLocals = null;
- currIL = null;
-
- lineAttributedInstrs = null;
- }
-
- protected int modifiersStoJ(int flags) {
- int jFlags = 0;
-
- if (Modifiers.Helper.isPrivate(flags))
- jFlags |= cst.ACC_PRIVATE;
- else
- jFlags |= cst.ACC_PUBLIC;
-
- if (Modifiers.Helper.isAbstract(flags))
- jFlags |= cst.ACC_ABSTRACT;
- if (Modifiers.Helper.isInterface(flags))
- jFlags |= cst.ACC_INTERFACE;
-
- if (Modifiers.Helper.isFinal(flags)
- && !(Modifiers.Helper.isAbstract(flags)
- || Modifiers.Helper.isInterface(flags)))
- jFlags |= cst.ACC_FINAL;
-
- return jFlags;
- }
-
- protected boolean isUnboxedType(scalac.symtab.Type tp) {
- switch (tp) {
- case UnboxedType(_):
- case UnboxedArrayType(_): return true;
- default: return false;
- }
- }
-
- protected HashMap typeMap/*<Symbol,Type>*/ = new HashMap();
- protected void initTypeMap() {
- typeMap.put(defs.ANY_CLASS, Type.OBJECT);
- typeMap.put(defs.ANYREF_CLASS, Type.OBJECT);
- }
- protected Type typeStoJ(scalac.symtab.Type tp) {
- switch (tp) {
- case UnboxedType(TypeTags.BYTE):
- return Type.BYTE;
- case UnboxedType(TypeTags.CHAR):
- return Type.CHAR;
- case UnboxedType(TypeTags.SHORT):
- return Type.SHORT;
- case UnboxedType(TypeTags.INT):
- return Type.INT;
- case UnboxedType(TypeTags.LONG):
- return Type.LONG;
- case UnboxedType(TypeTags.FLOAT):
- return Type.FLOAT;
- case UnboxedType(TypeTags.DOUBLE):
- return Type.DOUBLE;
- case UnboxedType(TypeTags.BOOLEAN):
- return Type.BOOLEAN;
- case UnboxedType(TypeTags.UNIT):
- return Type.VOID;
- case UnboxedType(TypeTags.STRING):
- return Type.STRING;
- case UnboxedArrayType(scalac.symtab.Type elementType):
- return new ArrayType(typeStoJ(elementType), 1);
- default: {
- Symbol sym = tp.symbol();
- if (sym == Symbol.NONE)
- throw global.fail("invalid type ", tp);
- else if (typeMap.containsKey(sym))
- return (Type)typeMap.get(sym);
- else {
- Type jTp = new ObjectType(javaName(sym));
- typeMap.put(sym, jTp);
- return jTp;
- }
- }
- }
- }
-
- protected Type[] argTypesStoJ(scalac.symtab.Type tp) {
- switch (tp) {
- case MethodType(Symbol[] vparams, _):
- Type[] argTypes = new Type[vparams.length];
- for (int i = 0; i < vparams.length; ++i)
- argTypes[i] = typeStoJ(vparams[i].info());
- return argTypes;
- default:
- throw global.fail("invalid method type", tp);
- }
- }
-
- protected Type retTypeStoJ(scalac.symtab.Type tp) {
- switch (tp) {
- case MethodType(_, _):
- return typeStoJ(tp.resultType());
- default:
- throw global.fail("invalid method type", tp);
- }
- }
-
- protected String javaName(Symbol sym) {
- assert sym.isClass() : Debug.show(sym);
- if (sym == defs.ANY_CLASS || sym == defs.ANYREF_CLASS)
- return JAVA_LANG_OBJECT;
- else {
- StringBuffer buf = new StringBuffer(sym.name.toString());
- if ((sym.isModule() || sym.isModuleClass()) && !sym.isJava())
- buf.append('$');
- for (sym = sym.owner(); !sym.isPackage(); sym = sym.owner()) {
- buf.insert(0, '$');
- buf.insert(0, sym.name);
- }
- if (!sym.isRoot()) {
- buf.insert(0, '.');
- buf.insert(0, sym.fullName());
- }
- return buf.toString();
- }
- }
-
- protected String javaFileName(String className) {
- StringTokenizer tokens = new StringTokenizer(className, ".");
- File file = new File(global.outpath);
- while (tokens.hasMoreElements())
- file = new File(file, tokens.nextToken());
-
- return file.getPath() + ".class";
- }
-
- // Generic instructions
- static class Generic_RETURN implements CompoundInstruction {
- private ReturnInstruction inst;
-
- public Generic_RETURN(Type type) {
- switch (type.getType()) {
- case cst.T_VOID: inst = ic.RETURN; break;
- case cst.T_BOOLEAN:
- case cst.T_BYTE:
- case cst.T_CHAR:
- case cst.T_SHORT:
- case cst.T_INT: inst = ic.IRETURN; break;
- case cst.T_LONG: inst = ic.LRETURN; break;
- case cst.T_FLOAT: inst = ic.FRETURN; break;
- case cst.T_DOUBLE: inst = ic.DRETURN; break;
- case cst.T_ARRAY:
- case cst.T_OBJECT: inst = ic.ARETURN; break;
- default: throw Debug.abort("unexpected type " + type.getType());
- }
- }
-
- public InstructionList getInstructionList() {
- return new InstructionList(inst);
- }
- }
-
- static class Generic_LOAD implements CompoundInstruction {
- private LoadInstruction inst;
-
- public Generic_LOAD(int pos, Type type) {
- switch (type.getType()) {
- case cst.T_BOOLEAN:
- case cst.T_BYTE:
- case cst.T_CHAR:
- case cst.T_SHORT:
- case cst.T_INT: inst = new ILOAD(pos); break;
- case cst.T_LONG: inst = new LLOAD(pos); break;
- case cst.T_FLOAT: inst = new FLOAD(pos); break;
- case cst.T_DOUBLE: inst = new DLOAD(pos); break;
- case cst.T_ARRAY:
- case cst.T_OBJECT: inst = new ALOAD(pos); break;
- default: throw Debug.abort("unexpected type");
- }
- }
-
- public InstructionList getInstructionList() {
- return new InstructionList(inst);
- }
- }
-
- static class Generic_STORE implements CompoundInstruction {
- private StoreInstruction inst;
-
- public Generic_STORE(int pos, Type type) {
- switch (type.getType()) {
- case cst.T_BOOLEAN:
- case cst.T_BYTE:
- case cst.T_CHAR:
- case cst.T_SHORT:
- case cst.T_INT: inst = new ISTORE(pos); break;
- case cst.T_LONG: inst = new LSTORE(pos); break;
- case cst.T_FLOAT: inst = new FSTORE(pos); break;
- case cst.T_DOUBLE: inst = new DSTORE(pos); break;
- case cst.T_ARRAY:
- case cst.T_OBJECT: inst = new ASTORE(pos); break;
- default: throw Debug.abort("unexpected type", type);
- }
- }
-
- public InstructionList getInstructionList() {
- return new InstructionList(inst);
- }
- }
-
- static class Generic_ALOAD implements CompoundInstruction {
- private ArrayInstruction inst;
-
- public Generic_ALOAD(Type type) {
- switch (type.getType()) {
- case cst.T_BOOLEAN:
- case cst.T_BYTE: inst = ic.BALOAD; break;
- case cst.T_CHAR: inst = ic.CALOAD; break;
- case cst.T_SHORT: inst = ic.SALOAD; break;
- case cst.T_INT: inst = ic.IALOAD; break;
- case cst.T_LONG: inst = ic.LALOAD; break;
- case cst.T_FLOAT: inst = ic.FALOAD; break;
- case cst.T_DOUBLE: inst = ic.DALOAD; break;
- case cst.T_ARRAY:
- case cst.T_OBJECT: inst = ic.AALOAD; break;
- default: throw Debug.abort("unexpected type");
- }
- }
-
- public InstructionList getInstructionList() {
- return new InstructionList(inst);
- }
- }
-
- static class Generic_ASTORE implements CompoundInstruction {
- private ArrayInstruction inst;
-
- public Generic_ASTORE(Type type) {
- switch (type.getType()) {
- case cst.T_BOOLEAN:
- case cst.T_BYTE: inst = ic.BASTORE; break;
- case cst.T_CHAR: inst = ic.CASTORE; break;
- case cst.T_SHORT: inst = ic.SASTORE; break;
- case cst.T_INT: inst = ic.IASTORE; break;
- case cst.T_LONG: inst = ic.LASTORE; break;
- case cst.T_FLOAT: inst = ic.FASTORE; break;
- case cst.T_DOUBLE: inst = ic.DASTORE; break;
- case cst.T_ARRAY:
- case cst.T_OBJECT: inst = ic.AASTORE; break;
- default: throw Debug.abort("unexpected type");
- }
- }
-
- public InstructionList getInstructionList() {
- return new InstructionList(inst);
- }
- }
-}
diff --git a/sources/scalac/backend/jvm/GenJVMBCELPhase.java b/sources/scalac/backend/jvm/GenJVMBCELPhase.java
deleted file mode 100644
index 3d1b50a77e..0000000000
--- a/sources/scalac/backend/jvm/GenJVMBCELPhase.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ____ ____ ____ ____ ______ *\
-** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
-** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
-** /_____/\____/\___/\____/____/ **
-\* */
-
-// $Id$
-
-package scalac.backend.jvm;
-
-import scalac.Global;
-import scalac.Phase;
-import scalac.PhaseDescriptor;
-import scalac.Unit;
-
-
-/**
- * Phase to generate Java bytecodes using the BCEL library.
- *
- * @author Michel Schinz
- * @version 1.0
- */
-
-public class GenJVMBCELPhase extends Phase {
-
- //########################################################################
- // Private Fields
-
- /** The tree to code translator */
- private final GenJVMBCEL translator;
-
- //########################################################################
- // Public Constructors
-
- /** Initializes this instance. */
- public GenJVMBCELPhase(Global global, PhaseDescriptor descriptor) {
- super(global, descriptor);
- this.translator = new GenJVMBCEL(global);
- }
-
- //########################################################################
- // Public Methods
-
- /** Applies this phase to the given compilation units. */
- public void apply(Unit[] units) {
- for (int i = 0; i < units.length; i++) translator.translate(units[i]);
- }
-
- //########################################################################
-}
diff --git a/sources/scalac/transformer/AddConstructors.java b/sources/scalac/transformer/AddConstructors.java
index 4cb258e230..4fdf9f6221 100644
--- a/sources/scalac/transformer/AddConstructors.java
+++ b/sources/scalac/transformer/AddConstructors.java
@@ -64,8 +64,7 @@ public class AddConstructors extends Transformer {
super(global);
this.constructors = constructors;
this.forINT = global.target == global.TARGET_INT;
- this.forJVM = (global.target == global.TARGET_JVM
- || global.target == global.TARGET_JVM_BCEL);
+ this.forJVM = (global.target == global.TARGET_JVM);
}
/** return new constructor symbol if it isn't already defined