March 25, 2013

How to check Scala/Java in real Bytecode?

Imagine you have the following code in  AntiTailRecursive.scala

object bc {

  def factorial(n: BigInt): BigInt = {
    if (n == 0)
      1
    else {
      //n*factorial(n-1)
      val t1 = n - 1
      val t2 = factorial(t1)
      n * t2
    }
  }

  def main(args: Array[String]): Unit = {
    println(factorial(5))

  }
}

$ scalac AntiTailRecursive.scala  #compile the code
$ scala b # verify that the code works
$ javap -l -p -c -v b     #To view the java byte code of this scala source code/class:



Classfile /home/morteza/Dropbox/workspaces/eclipse/c_scala/helloScala/src/basics/b.class
  Last modified Mar 25, 2013; size 799 bytes
  MD5 checksum 8772a0dbdf5617958f98e7b3ab627d85
  Compiled from "AntiTailRecursive.scala"
public final class b
  SourceFile: "AntiTailRecursive.scala"
    ScalaSig: length = 0x3
     05 00 00
  RuntimeVisibleAnnotations:
    0: #19(#20=s#21)
  minor version: 0
  major version: 49
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = Utf8               SourceFile
   #2 = Utf8               AntiTailRecursive.scala
   #3 = Utf8               main
   #4 = Utf8               ([Ljava/lang/String;)V
   #5 = Utf8               Code
   #6 = Utf8               b$
   #7 = Class              #6             //  b$
   #8 = Utf8               MODULE$
   #9 = Utf8               Lb$;
  #10 = NameAndType        #8:#9          //  MODULE$:Lb$;
  #11 = Fieldref           #7.#10         //  b$.MODULE$:Lb$;
  #12 = NameAndType        #3:#4          //  main:([Ljava/lang/String;)V
  #13 = Methodref          #7.#12         //  b$.main:([Ljava/lang/String;)V
  #14 = Utf8               factorial
  #15 = Utf8               (Lscala/math/BigInt;)Lscala/math/BigInt;
  #16 = NameAndType        #14:#15        //  factorial:(Lscala/math/BigInt;)Lscala/math/BigInt;
  #17 = Methodref          #7.#16         //  b$.factorial:(Lscala/math/BigInt;)Lscala/math/BigInt;
  #18 = Utf8               ScalaSig
  #19 = Utf8               Lscala/reflect/ScalaSignature;
  #20 = Utf8               bytes
  #21 = Utf8               ##y:Q!##\t##\t#A#####9A(Z7qift4##\t#\r#i#A####\tA)!###EN#qA#\n##-#R\"####5q###7b]#T#aD##U#4#-####\t1qJ#6fGR#\"a#
##QQ#!F##g#
G.Y##/Q#1bU2bY#|%M[3di\")#d#C#5#1A(#8jiz\"#!###9#!\t!H#\nM##Go#:jC2$\"A####}9cB##&#\t\tC%D###\t#C!##=e>|GOP##+%#a#F##a##7.Y4f#\tA#F##CS#Le####MQAQaK#A#y\t#A###[#!\tAL##[#Lg###0eA#1#M##cQ#A!#8ji\")1#
a#i#!#M]4t!\r#RgN##mQ#Q!#:sCf#\"#O###MI#B######&/#3fM&#A(###'R##N\4##i\"#
  #22 = Utf8               RuntimeVisibleAnnotations
  #23 = Utf8               b
  #24 = Class              #23            //  b
  #25 = Utf8               java/lang/Object
  #26 = Class              #25            //  java/lang/Object
{
  public static final void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #11                 // Field b$.MODULE$:Lb$;
         3: aload_0      
         4: invokevirtual #13                 // Method b$.main:([Ljava/lang/String;)V
         7: return       

  public static final scala.math.BigInt factorial(scala.math.BigInt);
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #11                 // Field b$.MODULE$:Lb$;
         3: aload_0      
         4: invokevirtual #17                 // Method b$.factorial:(Lscala/math/BigInt;)Lscala/math/BigInt;
         7: areturn      
}





No comments:

Post a Comment