• Like
  • Save
Groovy kisobenkyoukai20130309
Upcoming SlideShare
Loading in...5
×
 

Groovy kisobenkyoukai20130309

on

  • 2,689 views

 

Statistics

Views

Total Views
2,689
Views on SlideShare
1,567
Embed Views
1,122

Actions

Likes
4
Downloads
3
Comments
0

7 Embeds 1,122

http://d.hatena.ne.jp 716
http://act2012bl.wordpress.com 263
http://orangeclover.hatenablog.com 86
https://twitter.com 54
http://webcache.googleusercontent.com 1
https://act2012bl.wordpress.com 1
http://cache.yahoofs.jp 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Groovy kisobenkyoukai20130309 Groovy kisobenkyoukai20130309 Presentation Transcript

    • Groovy 基礎勉強会 Groovy実行の基礎 ∼コンパイラ処理系としての Groovyを読み解く∼ 2013/3/9 @青山オラクルセンター NTTソフトウェア Grails推進室 上原潤二 Slide # 1 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • 自己紹介 上原潤二(@uehaj) NTTソフトウェア株式会社Grails推進室 JGGUG(日本Grails/Groovyユーザグループ)運営委員 書籍執筆: プログラミングGROOVY(技術評論社) Grails徹底入門(翔泳社) G*Magazine Vol 6記事書きました → ブログ「Grな日々」 GroovyServ, LispBuilder, GVM(Groovy JVM), Staticalizer開発者 Slide # Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • お品書き Groovyの実行のしくみ ANTLRによる構文解析 ASMによるコード生成 まとめ Slide # 3 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • Groovy実行 のしくみ Slide # 4 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • Groovyソースツリー src/main │ ├─builder │ ├─typehandling ├─groovy │ ├─expr │ └─wrappers │ ├─beans │ ├─stmt ├─syntax │ ├─grape │ └─tools ├─tools │ ├─inspect 今日の ├─classgen │ ├─ast │ ├─io │ └─asm │ ├─gse │ ├─lang テーマ │ ├─indy │ ├─javac │ ├─security │ └─sc │ ├─shell │ ├─time ├─cli │ │ └─util │ ├─transform ├─control │ └─xml │ ├─ui │ ├─customizers ├─transform │ ├─util │ │ └─builder │ ├─sc │ │ └─logging │ ├─io │ │ └─transformers │ └─xml │ └─messages │ └─stc └─org ├─plugin ├─util ├─apache ├─reflection └─vmplugin │ └─commons │ └─stdclasses ├─v5 │ └─cli ├─runtime ├─v6 └─codehaus │ ├─callsite └─v7 └─groovy │ ├─dgmimpl ├─antlr │ │ └─arrays │ ├─java │ ├─m12n │ ├─parser │ ├─memoize │ └─treewalker │ ├─metaclass ├─ast │ ├─powerassert Slide # 5 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • Javaコードの実行 Javaソース javacコマンド .classファイル javaコマンド JVM 標準クラスローダ Javaクラス Slide # 6 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • Groovyコードの実行 Javaソース Groovyコード javacコマンド groovycコマンド .classファイル .classファイル javaコマンド groovyコマンド JVM Groovyクラスローダ 標準クラスローダ (オンメモリ実行時コンパイラ) Javaクラス Javaクラス Javaクラス Slide # 7 Groovy基礎勉強会 2011 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • Groovyコードの実行 Groovyコード groovycコマンド .classファイル groovyコマンド JVM 標準クラスローダ Groovyクラスローダ (オンメモリ実行時コンパイラ) Javaクラス Javaクラス Slide # 8 6 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • Groovyコード実行のためのコマンドとクラス groovycコマンド groovyコマンド groovysh groovy.ui.GroovyMain o.c.g.tools.FileS groovyConsole ystemCompiler groovy.lang.GroovyShell groovy.util.Groo vyScriptEngine groovy.lang.GroovyClass Loader org.codehaus.groovy.controll.CompilationUnit Slide # 9 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • CompilationUnit org.codehaus.groovy.controll.CompilationUnit CompilationUnitはコンパイル処理の中核 「コンパイル処理を実行する単位」を表わすと同時 にコンパイルのすべての過程を制御している。 Slide # 10 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • JavaAwareCompilationUnit extends CompilationUnit (余談)JavaAwareCompilationUnit extends CompilationUnit ジョイントコンパイルオプション(-j, --jointCompilation)を指定した場合に発動 Groovyソースに加えJavaソースをコンパイル する能力を持つ -jをつけないと、拡張子.javaのファイルは Groovyコードとして解釈/コンパイルされる(!!) Slide # 11 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved. 13年3月9日土曜日
    • CompilationUnit#compile() public  void  compile()  ..  {        compile(Phases.ALL);  //全フェイズのコンパ イル処理を実行 } public  void  compile(int  throughPhase)  ..  { //  指定したフェイズ「まで」コンパイル処理実行    : } Slide # 12 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • フェイズとは何か? CompilationUnitが保持するコンパイルの進行 状態である。 INITIALIZATION(1)                //ファイルを開いたり PARSING(2)                  //字句・構文解析、ANTLRのAST構築 CONVERSION(3)                        //CSTからASTへの変換 SEMANTIC_ANALYSIS(4)          //ASTの意味解析と解明 CANONICALIZATION(5)            //ASTの補完 INSTRUCTION_SELECTION(6)  //クラス生成(フェーズ1) CLASS_GENERATION(7)            //クラス生成(フェーズ2) OUTPUT(8)                                //クラスをファイルに出力 FINALIZATION(9)                    //後始末 ALL(9)                                      //後始末まですべて実行 Slide # 13 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • (参考) ASTとは? AST…Abstract Syntax Tree,抽象構文木 構文木の一種で、論理的な構造を表わす CST(Concrete Syntax Tree, 具象構文木) 例えば「a.foo(b,c)」を構文解析すると… CST . AST . a foo a foo () , b c b c Slide # 14 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • GroovyConsoleのGroovy AST Browser Slide # 15 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • フェイズにもとづいたコンパイル処理 CompilationUnitに、フェイズを指定して種々 のphaseOperation(後述)を追加することで処 理が制御される CompilationUnit#addPhaseOperation() あらかじめ決まっているもの以外に、以下が実 行時に追加される AST変換 CompilerCustomizerとしてのAST変換 Slide # 16 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • (参考)フェイズとAST変換 AST変換は、それぞれ適用されるフェイズを 指定して定義されている フェイズ 実行されるAST変換 INITIALIZATION - PARSING - CONVERSION @Grab SEMANTIC_ANALYSIS @Field, @Log, @PackageScope, CANONICALIZATION ほとんどのAST変換がここに所属 INSTRUCTION_SELECTIO @TypeChecked, @CompileStatic CategoryASTTransformation CLASS_GENERATION N - DelegateASTTransformation OUTPUT - FINALIZATION - ImmutableASTTransformation Slide # 17 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • phaseOperations PARSING: AnnotationCollectorTransform SourceUnit#parse() StaticVerifier AntlrParserPlugin#parseCST()// InnerClassCompletionVisitor CSTを作る EnumCompletionVisitor CONVERSION: CANONICALIZATION: convert(SourceUnit#convert() // compileCompleteCheck Generates an AST from the CST), CLASS_GENERATION: AntlrParserPlugin.buildAST()// classgen(OptimizerVisitor,Generics ANTLR ASTからGroovyのASTを生成 Visitor, LabelVerifier, EnumVisitor ClassCompletionVerifier, SEMANTIC_ANALYSIS: ExtendedVerifier, ClassVisitor, resolve(VariableScopeVisitor, AsmClassGenerator) ResolveVisitor) OUTPUT: staticImport(StaticImportVisitor) output InnerClassVisitor Slide # 18 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • phaseOperations PARSING: AnnotationCollectorTransform SourceUnit#parse() StaticVerifier AntlrParserPlugin#parseCST()// InnerClassCompletionVisitor CSTを作る EnumCompletionVisitor CONVERSION: CANONICALIZATION: convert(SourceUnit#convert() // compileCompleteCheck Generates an AST from the CST), CLASS_GENERATION: AntlrParserPlugin.buildAST()// classgen(OptimizerVisitor,Generics ANTLR ASTからGroovyのASTを生成 Visitor, LabelVerifier, EnumVisitor ClassCompletionVerifier, SEMANTIC_ANALYSIS: 今日の ExtendedVerifier, ClassVisitor, resolve(VariableScopeVisitor, AsmClassGenerator) ResolveVisitor) テーマ OUTPUT: staticImport(StaticImportVisitor) output InnerClassVisitor Slide # 18 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • ANTLRによる 構文解析 Slide # 19 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • ANTLRによる構文解析処理 ANTLRって何? Wikipediaより ANTLR(ANother Tool for Language Recognition)とは、LL(*)構文解析に 基づくパーサジェネレータである(バージョン3.xはLL(*)、2.xまではLL(k))。 PCCTS(Purdue Compiler Construction Tool Set)の後継として1989年に 開発され、現在も活発に開発が続いている。中心となっているのは、サンフラン シスコ大学の Terence Parr 教授である。 ANTLR はLR法に基づいたパーサジェネレータと競合関係にあり、"ANT(i)- LR"(反LR)と読めるのも偶然ではない[要出典]。 ANTLR はパーサだけでなくレキサーおよびツリーパーサも生成可能である。 文 法の記述方法は、EBNFに似た形式となっている。 再帰下降構文解析のコードを自動生成する Groovy 2.1が使っているのはANTLR 2.7.7 3もしくは4への移行も企画されているらしい Slide # 20 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • AntlrParserPlugin.java パーサ(構文解析器)のメイン処理 parseCST() …以下を呼び出してCSTを作った上 で、ANTLRのASTに変換 o.c.g.antlr.parser.GroovyLexer o.c.g.antlr.parser.GroovyRecognizer buildAST() …ANTLRのASTをGroovyのASTに変換 Slide # 21 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • GroovyLexer.java, GroovyRecognizer.java groovy.gから自動生成されるのでGroovyソー スコードには含まれていない Groovyソースコードをコンパイルすると target/generated-sources配下にJavaソース が生成される。 groovy.g GroovyLexer.java (Groovy構文定義) ANTLR GroovyRecognizer.java Slide # 22 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • groovy.g ANTLR 2.7用のGroovy構文定義ファイル 4324行あり、groovy中の最大級ソースの一つ ./src/main/org/codehaus/groovy/runtime/ 14239行 DefaultGroovyMethods.java ./src/main/org/codehaus/groovy/antlr/ 4323行 groovy.g ./subprojects/groovy-sql/src/main/java/groovy/sql/ 4229行 Sql.java ./src/main/org/codehaus/groovy/runtime/ 3865行 StringGroovyMethods.java Slide # 23 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • groovy.gを覗いてみる ANTLRによるCompilationUnitの定義 //  Compilation  Unit:  Groovyでは単一ファイルもしくはスクリプト。   //  このパーサの開始ルールです。 compilationUnit              : //  ファイル冒頭文字列が"#!"の場合最初の行を無視                (SH_COMMENT!)? //  ファイル冒頭にコメントがあっても良い                nls! //  compilation  unitはopitionalなパッケージ定義から開始される                (      (annotationsOpt  "package")=>  packageDefinition                |      (statement[EOF])?                ) //  スクリプト本体は任意個数の文のシーケンス。 //  セミコロンand/or改行をセパレータとして扱う                (  sep!  (statement[sepToken])?  )*                EOF!        ; Slide # 24 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • do-whileはどうなっている? /*OBS*  no  do-­‐while  statement  in   Groovy  (too  ambiguous) //  do-­‐while  statement    |      "do"^  statement  "while"!   LPAREN!  strictContextExpression   RPAREN!  SEMI! *OBS*/ Slide # 25 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • (余談)AntlrPerserPluginをCompilerlerConfigrationで差し替える import  org.codehaus.groovy.control.* import  org.codehaus.groovy.antlr.* import  org.codehaus.groovy.syntax.*   class  Pascalizer  extends  ParserPluginFactory  {    ParserPlugin  createParserPlugin()  {        new  AntlrParserPlugin()  {            Reduction  parseCST(SourceUnit  sourceUnit,  Reader  reader)  {                def  s  =  reader.text.replaceAll(begin,  {).replaceAll(end,  })                s  =  s.replaceAll(/(*/,  /*).replaceAll(/*)/,  */)                super.parseCST(sourceUnit,  new  StringReader(s))            }        }    } }   def  conf  =  new  CompilerConfiguration(pluginFactory:  new  Pascalizer()) new  GroovyShell(binding,  conf).evaluate(""" def  foo(arg)  begin  (*  コメントです  *)  println  arg end foo("hello  pascal!") """) Slide # 26 Groovy基礎勉強会 参考: http://groovyconsole.appspot.com/script/3 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • ASMによる コード生成 Slide # 27 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • ASMって何? Wikipediaより ObjectWeb ASM The ASM library is a project of the ObjectWeb consortium. It provides a simple API for decomposing, modifying, and recomposing binary Java classes (i.e. bytecode). The project was originally conceived and developed by Eric Bruneton. ASM is Java-centric at present, and does not currently have a backend that exposes other bytecode implementations (such as .NET bytecode,Python bytecode, etc.). Groovy 2.1が使っているのはASM 4.0 Slide # 28 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • CompilatoinUnit#classgen CLASS_GENERATIONフェイズのphaseOperation new OptimizerVisitor(this).visitClass(classNode, source) new GenericsVisitor(source).visitClass(classNode) new Verifier().visitClass(classNode) new LabelVerifier(source).visitClass(classNode) new ClassCompletionVerifier(source).visitClass(classNode) new ExtendedVerifier(source).visitClass(classNode) ClassVisitor visitor = createClassVisitor() new AsmClassGenerator(source, context, visitor, sourceName) .visitClass(classNode) byte[] bytes = visitor.toByteArray(); generatedClasses.add(new GroovyClass(classNode.getName(), bytes)) // bytesに出力されたバイトコード列をGroovyクラス実体として結び付ける // 次のoutputフェーズでバイトコード列を出力する Slide # 29 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • AsmClassGenerator 以下を定義するVisitor visitSynchronizedStatement() visitClass() visitThrowStatement() visitClass() visitReturnStatement() visitGenericType() visitExpressionStatement() visitConstructor() visitTernaryExpression() visitMethod() visitDeclarationExpression() visitField() visitBinaryExpression() visitProperty() visitPostfixExpression() visitCatchStatement() visitPrefixExpression() visitBlockStatement() visitClosureExpression() visitForLoop() visitConstantExpression() visitWhileLoop() visitSpreadExpression() visitDoWhileLoop() visitSpreadMapExpression() visitIfElse() visitMethodPointerExpression() visitAssertStatement() visitUnaryMinusExpression() visitTryCatchFinally() visitUnaryPlusExpression() visitSwitch() visitBitwiseNegationExpression() visitCaseStatement() visitCastExpression() visitBreakStatement() visitNotExpression() visitContinueStatement() (以下略) Slide # 30 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • コード生成の例(whileループ) public  void  visitWhileLoop(WhileStatement  loop)  {    controller.getStatementWriter().writeWhileLoop(loop); } StatementWriter#writeWhileLoop(WhileStatement loop): 生成バイトコード(予想) mv.visitLabel(continueLabel) continueLabel: Expression  bool  =  loop.getBooleanExpression(); bool.visit(controller.getAcg());  <bool式> controller.getOperandStack().jump(IFEQ, IFEQ    breaklabel1                                                                    breakLabel);  <loopBlock> loop.getLoopBlock().visit(controller.getAcg()); GOTO  continueLabel breakLabel mv.visitJumpInsn(GOTO,  continueLabel); mv.visitLabel(breakLabel); IFEQ: スタックトップの値が0の場合にジャンプする命令 Slide # 31 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • (おまけ)Bytecode DSL @Bytecode int  foo()  {        aload  0        invokedynamic   experiment,  (LMain;)I,  [H_INVOKESTATIC,  Main,   bootstrap,  [CallSite,  Lookup,  String,  MethodType]]        ireturn } ASMより簡単にbytecodeが生成できるyo! 参考URL https://github.com/melix/groovy-bytecode-ast.git http://www.jroller.com/melix/entry/using_groovy_to_play_with Slide # 32 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • まとめ Groovyの実行のコアにはいわゆる一つのコン パイラがある ANTLR、ASMなどの既存ライブラリ・ツール を上手くつかって綺麗に制御している 構文解析にしろコード生成にしろVisitorだらけ である Slide # 33 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日
    • 参考URL・商標 http://www.antlr.org/ http://asm.ow2.org/ OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国 における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合 があります。 記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標 です Slide # 34 Groovy基礎勉強会 Copyright(C) 2013 NTT Software Corporation All rights reserved.13年3月9日土曜日