alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (GenJVMUtil.scala)

This example Scala source code file (GenJVMUtil.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

array, eq, eq, ge, gt, int, jobjecttype, jobjecttype, jtype, le, le, lt, ne, ne

The Scala GenJVMUtil.scala source code

/* NSC -- new Scala compiler
 * Copyright 2005-2011 LAMP/EPFL
 * @author  Iulian Dragos
 */


package scala.tools.nsc
package backend.jvm

import scala.collection.{ mutable, immutable }

import ch.epfl.lamp.fjbg._

trait GenJVMUtil {
  self: GenJVM =>

  import global._
  import icodes._
  import icodes.opcodes._
  import definitions._

  /** Map from type kinds to the Java reference types. It is used for
   *  loading class constants. @see Predef.classOf.
   */
  val classLiteral = immutable.Map[TypeKind, JObjectType](
    UNIT   -> new JObjectType("java.lang.Void"),
    BOOL   -> new JObjectType("java.lang.Boolean"),
    BYTE   -> new JObjectType("java.lang.Byte"),
    SHORT  -> new JObjectType("java.lang.Short"),
    CHAR   -> new JObjectType("java.lang.Character"),
    INT    -> new JObjectType("java.lang.Integer"),
    LONG   -> new JObjectType("java.lang.Long"),
    FLOAT  -> new JObjectType("java.lang.Float"),
    DOUBLE -> new JObjectType("java.lang.Double")
  ) 

  private val javaNameCache = {
    val map = new mutable.WeakHashMap[Symbol, String]()
    map ++= List(
      NothingClass        -> RuntimeNothingClass.fullName('/'),
      RuntimeNothingClass -> RuntimeNothingClass.fullName('/'),
      NullClass           -> RuntimeNullClass.fullName('/'),
      RuntimeNullClass    -> RuntimeNullClass.fullName('/')    
    )
    map
  }

  /** This trait may be used by tools who need access to 
   *  utility methods like javaName and javaType. (for instance,
   *  the Eclipse plugin uses it).
   */
  trait BytecodeUtil {

    val conds = immutable.Map[TestOp, Int](
      EQ -> JExtendedCode.COND_EQ,
      NE -> JExtendedCode.COND_NE,
      LT -> JExtendedCode.COND_LT,
      GT -> JExtendedCode.COND_GT,
      LE -> JExtendedCode.COND_LE,
      GE -> JExtendedCode.COND_GE
    )
    val negate = immutable.Map[TestOp, TestOp](
      EQ -> NE,
      NE -> EQ,
      LT -> GE,
      GT -> LE,
      LE -> GT,
      GE -> LT
    )

    /** Specialized array conversion to prevent calling 
     *  java.lang.reflect.Array.newInstance via TraversableOnce.toArray
     */
    
    def mkArray(xs: Traversable[JType]): Array[JType] = { val a = new Array[JType](xs.size); xs.copyToArray(a); a }
    def mkArray(xs: Traversable[String]): Array[String] = { val a = new Array[String](xs.size); xs.copyToArray(a); a }
    

    /** Return the a name of this symbol that can be used on the Java
     *  platform.  It removes spaces from names.
     *
     *  Special handling:
     *    scala.Nothing erases to scala.runtime.Nothing$
     *       scala.Null erases to scala.runtime.Null$
     *
     *  This is needed because they are not real classes, and they mean
     *  'abrupt termination upon evaluation of that expression' or null respectively.
     *  This handling is done already in GenICode, but here we need to remove
     *  references from method signatures to these types, because such classes can
     *  not exist in the classpath: the type checker will be very confused.
     */
    def javaName(sym: Symbol): String =      
      javaNameCache.getOrElseUpdate(sym, {
        if (sym.isClass || (sym.isModule && !sym.isMethod))
          sym.fullName('/') + moduleSuffix(sym)
        else
          sym.simpleName.toString.trim() + moduleSuffix(sym)
      })

    def javaType(t: TypeKind): JType = (t: @unchecked) match {
      case UNIT            => JType.VOID
      case BOOL            => JType.BOOLEAN
      case BYTE            => JType.BYTE
      case SHORT           => JType.SHORT
      case CHAR            => JType.CHAR
      case INT             => JType.INT
      case LONG            => JType.LONG
      case FLOAT           => JType.FLOAT
      case DOUBLE          => JType.DOUBLE
      case REFERENCE(cls)  => new JObjectType(javaName(cls))
      case ARRAY(elem)     => new JArrayType(javaType(elem))
    }

    def javaType(t: Type): JType = javaType(toTypeKind(t))

    def javaType(s: Symbol): JType =
      if (s.isMethod)
        new JMethodType(
          if (s.isClassConstructor) JType.VOID else javaType(s.tpe.resultType),
          mkArray(s.tpe.paramTypes map javaType)
        )
      else
        javaType(s.tpe)

    protected def genConstant(jcode: JExtendedCode, const: Constant) {
      const.tag match {
        case UnitTag    => ()
        case BooleanTag => jcode emitPUSH const.booleanValue
        case ByteTag    => jcode emitPUSH const.byteValue
        case ShortTag   => jcode emitPUSH const.shortValue
        case CharTag    => jcode emitPUSH const.charValue
        case IntTag     => jcode emitPUSH const.intValue
        case LongTag    => jcode emitPUSH const.longValue
        case FloatTag   => jcode emitPUSH const.floatValue
        case DoubleTag  => jcode emitPUSH const.doubleValue
        case StringTag  => jcode emitPUSH const.stringValue
        case NullTag    => jcode.emitACONST_NULL()
        case ClassTag   =>
          val kind = toTypeKind(const.typeValue)
          val toPush =
            if (kind.isValueType) classLiteral(kind)
            else javaType(kind).asInstanceOf[JReferenceType]

          jcode emitPUSH toPush

        case EnumTag   =>
          val sym = const.symbolValue
          jcode.emitGETSTATIC(javaName(sym.owner),
                              javaName(sym),
                              javaType(sym.tpe.underlying))
        case _         =>
          abort("Unknown constant value: " + const)
      }
    }
  }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala GenJVMUtil.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.