how scala code is expressed in the jvm
Post on 06-Jan-2017
5.752 Views
Preview:
TRANSCRIPT
関ジャバです!
2
@jyukutyo
produced three Java framework books one was translated into Korean
JUG Leader (KansaiJUG)
blog:Fight the Future http://jyukutyo.hatenablog.com/
FURYU CORPORATION
age: 36
Koichi Sakata (阪田 浩一)
フリューの阪田です 関ジャバの会長です
Java
Scala
JRuby
Groovy
Compiler
Class file
cafe babe 0000 0032 0017 0100
JVM
Class fileClass fileClass fileClass fileClass file § Runs
§ Interprets § Translates bytecode into Native Machine Code
Hello World (Java)
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, world!"); } } § Compiled into...
§ HelloWorld.class
cafe babe 0000 0032 0017 0100 0a48 656c 6c6f 576f 726c 6407 0001 0100 106a 6176 612f 6c61 6e67 2f4f 626a 6563 7407 0003 0100 1048 656c 6c6f 576f 726c 642e 7363 616c 6101 001e 4c73 6361 6c61 2f72 6566 6c65 6374 2f53 6361 6c61 5369 676e 6174 7572 653b 0100 0562 7974 6573 0100 ef06 0115 3a51 2101 0209 0215 0921 0253 336d 593e 3c76 4e1d 3765 1505 1911 6102 1f66 5b42 2418 5050 0201 2109 3171 2144 0103 0d15 4121 0123 010a 0529 4155 0d1c 3770 2f3e 1448 0e5a 0a03 0f29 0122 6103 080e 0331 5111 2144 0106 670e 0c47 2e59 0503 1f31 1161 2111 387a 2516 3407 2242 0908
ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-‐1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; ... -‐-‐ u1 represents one-‐byte quantity, Hexadecimal 2 digit.
... u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } -‐-‐ u1 represents one-‐byte quantity, Hexadecimal 2 digit.
u1が1バイト 16進数では2桁になります
cafe babe 0000 0032 0017 0100 0a48 656c 6c6f 576f 726c 6407 0001 0100 106a 6176 612f 6c61 6e67 2f4f 626a 6563 7407 0003 0100 1048 656c 6c6f 576f 726c 642e 7363 616c 6101 001e 4c73 6361 6c61 2f72 6566 6c65 6374 2f53 6361 6c61 5369 676e 6174 7572 653b 0100 0562 7974 6573 0100 ef06 0115 3a51 2101 0209 0215 0921 0253 336d 593e 3c76 4e1d 3765 1505 1911 6102 1f66 5b42 2418 5050 0201 2109 3171 2144 0103 0d15 4121 0123 010a 0529 4155 0d1c 3770 2f3e 1448 0e5a 0a03 0f29 0122 6103 080e 0331 5111 2144 0106 670e 0c47 2e59 0503 1f31 1161 2111 387a 2516 3407 2242 0908
javap command The Java Class File Disassembler § included in JDK § `javap -‐v [FQCN]` § Scala REPL § scala> :javap [FQCN] § equivalent to `javap -‐v`
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html
javap - Java クラスファイル逆アセンブラ
public class HelloWorld minor version: 0 major version: 52 Constant pool: #1 = Methodref #6.#15 // java/lang/Object."<init>":()V #2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #18 // Hello, world! #4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V
public static void main(java.lang.String[]);
Code: 0: getstatic #2 3: ldc #3 5: invokevirtual #4 8: return
JVM instructions aaload aastore aconst_null aload
anewarray areturn arraylength astore
athrow baload bastore bipush
caload castore checkcast d2f
d2i d2l dadd daload
dastore dcmp<op> dconst_<d> ddiv
dload dmul dneg ...
instructions of method call
invokevirtual invoke instance method; dispatched based on class
invokeinterface invoke interface method
invokestatic invoke static method
invokespecialinvoke method;
superclass, private, constructor...
invokedynamic invoke dynamic method
public static void main(java.lang.String[]);
Code: 0: getstatic #2 3: ldc #3 5: invokevirtual #4 8: return -‐-‐ #0 = index of Constant pool
public class HelloWorld Constant pool: #1 = Methodref #6.#15 // java/lang/Object."<init>":()V #2 = Fieldref #16.#17 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #18 // Hello, world! #4 = Methodref #19.#20 // java/io/PrintStream.println:(Ljava/lang/String;)V ...
Hello World (Scala)
object HelloWorld { def main(args: Array[String]) { println("Hello, world!") } } § Compiled into...
§ HelloWorld.class § HelloWorld$.class
public final class HelloWorld Constant pool:
#15 = NameAndType #13:#14 // MODULE$:LHelloWorld$; #16 = Fieldref #12.#15 // HelloWorld$.MODULE$:LHelloWorld$; #17 = NameAndType #9:#10 // main:([Ljava/lang/String;)V #18 = Methodref #12.#17 // HelloWorld$.main:
([Ljava/lang/String;)V ...
public static void main(java.lang.String[]);
0: getstatic #16 // Field HelloWorld$.
MODULE$:LHelloWorld$; 3: aload_0 4: invokevirtual #18 // Method HelloWorld$.main:
([Ljava/lang/String;)V 7: return
-‐-‐ 4: in Java HelloWorld$.MODULE$.main(arg);
public final class HelloWorld$ -‐-‐ omit Constant pool
public static {}; 0: new #2 // class HelloWorld$ 3: invokespecial #12 // Method "<init>":()V 6: return
-‐-‐ <init> means constructor
public void main(java.lang.String[]); 0: getstatic #19 // Field scala/Predef$.MODULE$:
Lscala/Predef$; 3: ldc #21 // String Hello, world! 5: invokevirtual #25 // Method scala/Predef$.println:
(Ljava/lang/Object;)V 8: return
The following samples are quoted
from tutorials in Scala official site
http://docs.scala-‐lang.org/tutorials/
これ以降で使用するサンプルは Scalaの公式サイトのチュートリアルです
trait Similarity { def isSimilar(x: Any): Boolean def isNotSimilar(x: Any): Boolean =
!isSimilar(x) } class Point(xc: Int, yc: Int)
extends Similarity { var x: Int = xc var y: Int = yc def isSimilar(obj: Any) = obj.isInstanceOf[Point] && obj.asInstanceOf[Point].x == x }
public interface Similarity
public abstract boolean isSimilar(java.lang.Object);
public abstract boolean
isNotSimilar(java.lang.Object);
public abstract class Similarity$class public static boolean
isNotSimilar(Similarity,j.l.Object); 0: aload_0 1: aload_1 2: invokeinterface #13, 2 // InterfaceMethod Similarity.isSimilar:
(Ljava/lang/Object;)Z 7: ifeq 14 10: iconst_0 11: goto 15 14: iconst_1 15: ireturn
abstract class Term
case class Var(name: String) extends Term
case class Fun(arg: String, body: Term) extends Term
case class App(f: Term, v: Term) extends Term
§ Compiled into... § Term.class § App.class § App$.class § Fun.class § Fun$.class § Var.class § Var$.class
public class App extends Term implements s.Product,s.Serializable
public static s.Option<scala.Tuple2<Term, Term>>
unapply(App); public static App apply(Term, Term); public ... tupled(); public ... curried(); public Term f(); public Term v(); public App copy(Term, Term); public j.l.String productPrefix(); public boolean equals(j.l.Object); ...
public final class App$ extends s.r.AbstractFunction2<Term, Term, App>
implements scala.Serializable public App apply(Term, Term); 0: new #23 // class App 3: dup 4: aload_1 5: aload_2 6: invokespecial #26 // Method App."<init>":(LTerm;LTerm;)V 9: areturn
object MatchTest2 extends App { def matchTest(x: Any): Any = x match { case 1 => "one" case "two" => 2 case y: Int => "scala.Int" }
println(matchTest("two")) }
public final class MatchTest2$ implements scala.App
7: invokestatic #67 // Method BoxesRunTime.equals:.. 10: ifeq 19 13: ldc #69 // String one 15: astore_3 16: goto 46 19: ldc #71 // String two 21: aload_2 22: invokevirtual #74 // Method java/lang/Object.equals:
19: ldc #71 // String two 21: aload_2 22: invokevirtual #74 // Method java/lang/Object.equals:
(Ljava/lang/Object;)Z 25: ifeq 36 28: iconst_2 32: astore_3 33: goto 46
36: aload_2 37: instanceof #76 // class java/lang/Integer 40: ifeq 48 43: ldc #78 // String scala.Int 45: astore_3 46: aload_3 47: areturn ...
object MatchTest1 { def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" case _ => "many" } def main(args: Array[String]) { println(matchTest(3)) } }
3: tableswitch { // 1 to 2 1: 34 2: 29 default: 24 } 24: ldc #16 // String many 26: goto 36 29: ldc #18 // String two 31: goto 36 34: ldc #20 // String one 36: areturn
object CurryTest { def filter(xs: List[Int],
p: Int => Boolean): List[Int] = if (xs.isEmpty) xs else if (p(xs.head))
xs.head :: filter(xs.tail, p) else filter(xs.tail, p)
def modN(n: Int)(x: Int) = ((x % n) == 0)
def main(args: Array[String]) { val nums = List(1, 2, 3, 4,
5, 6, 7, 8) println(filter(nums, modN(2))) println(filter(nums, modN(3))) } }
§ Compiled into... § CurryTest.class § CurryTest$.class § CurryTest$$anonfun$main$1.class § CurryTest$$anonfun$main$2.class
public final class CurryTest$$anonfun$main$1 extends
scala.runtime.AbstractFunction1$mcZI$sp implements scala.Serializable
public boolean apply$mcZI$sp(int); 3: iconst_2 4: iload_1 5: invokevirtual #33 // Method CurryTest$.modN:(II)Z 8: ireturn
public final class CurryTest$$anonfun$main$2 extends
scala.runtime.AbstractFunction1$mcZI$sp implements scala.Serializable
public boolean apply$mcZI$sp(int); 3: iconst_3 4: iload_1 5: invokevirtual #33 // Method CurryTest$.modN:(II)Z 8: ireturn
def main(args: Array[String]) { val nums = List(1, 2, 3, 4,
5, 6, 7, 8) println(filter(nums, modN(2))) println(filter(nums, modN(3))) } }
public final class CurryTest$ ... public void main(java.lang.String[]); 63: invokespecial #82 // Method CurryTest$$anonfun$main$1.
"<init>":()V 66: invokevirtual #41 // Method filter:(Lscala/collection/
immutable/List;Lscala/Function1;) Lscala/collection/immutable/List;
69: invokevirtual #86 // Method scala/Predef$.println:
(Ljava/lang/Object;)V
public final class CurryTest$$anonfun$main$1 extends
scala.runtime.AbstractFunction1$mcZI$sp implements scala.Serializable
81: invokespecial #89 // Method CurryTest$$anonfun$main$2.
"<init>":()V 84: invokevirtual #41 // Method filter:(Lscala/collection/
immutable/List;Lscala/Function1;) Lscala/collection/immutable/List;
87: invokevirtual #86 // Method scala/Predef$.println:
(Ljava/lang/Object;)V
§ Summary § JVM is excellent! § class file has a format § javap is useful to understand Scala at the bytecode level
Try typing "javap" after you compile
Scala code
top related