一個簡單的groovy script生成的class文件及其反編譯

Groovy

def task = {
	println "Hello from source code-Task"
	}
task()

def task2 = {
	println "Hello from source code-Task2"
	}
	
class B {
	String getName(){
		return "Young"
	}
}

println new B().getName();

task2();

結果

Hello from source code-Task
Young
Hello from source code-Task2

Groovy默認是不爲這個script寫class文件的,但是我們可以通過配置文件或者直接修改原碼, 

conf.setTargetDirectory

指定class的存放路徑

這裏生成四個class文件

B.class  test$_run_closure1, test$_run_closure2.class, test.class

反編譯以後

import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class B
  implements GroovyObject
{
  public B()
  {
    B this;
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    MetaClass localMetaClass = $getStaticMetaClass();
    this.metaClass = localMetaClass;
  }
  
  public String getName()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();return "Young";return null;
  }
  
  static
  {
    __$swapInit();
    Long localLong1 = Long.valueOf(0L);
    __timeStamp__239_neverHappen1423373575093 = localLong1.longValue();
    Long localLong2 = Long.valueOf(1423373575093L);
    __timeStamp = localLong2.longValue();
  }
}


import groovy.lang.Closure;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.callsite.CallSite;

class test$_run_closure1
  extends Closure
  implements GeneratedClosure
{
  public test$_run_closure1(Object _outerInstance, Object _thisObject)
  {
    super(_outerInstance, _thisObject);
  }
  
  public Object doCall(Object it)
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task");return null;
  }
  
  public Object doCall()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    return doCall(null);
    return null;
  }
  
  static {}
}

import groovy.lang.Closure;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.callsite.CallSite;

class test$_run_closure2
  extends Closure
  implements GeneratedClosure
{
  public test$_run_closure2(Object _outerInstance, Object _thisObject)
  {
    super(_outerInstance, _thisObject);
  }
  
  public Object doCall(Object it)
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task2");return null;
  }
  
  public Object doCall()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    return doCall(null);
    return null;
  }
  
  static {}
}

import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;

public class test
  extends Script
{
  public test()
  {
    test this;
    CallSite[] arrayOfCallSite = $getCallSiteArray();
  }
  
  public test(Binding arg1)
  {
    Binding context;
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    ScriptBytecodeAdapter.invokeMethodOnSuperN(Script.class, this, "setBinding", new Object[] { context });
  }
  
  public static void main(String... args)
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();
    arrayOfCallSite[0].call(InvokerHelper.class, test.class, args);
  }
  
  class _run_closure1
    extends Closure
    implements GeneratedClosure
  {
    public _run_closure1(Object _thisObject)
    {
      super(_thisObject);
    }
    
    public Object doCall(Object it)
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task");return null;
    }
    
    public Object doCall()
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();
      return doCall(null);
      return null;
    }
    
    static {}
  }
  
  class _run_closure2
    extends Closure
    implements GeneratedClosure
  {
    public _run_closure2(Object _thisObject)
    {
      super(_thisObject);
    }
    
    public Object doCall(Object it)
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();return arrayOfCallSite[0].callCurrent(this, "Hello from source code-Task2");return null;
    }
    
    public Object doCall()
    {
      CallSite[] arrayOfCallSite = $getCallSiteArray();
      return doCall(null);
      return null;
    }
    
    static {}
  }
  
  public Object run()
  {
    CallSite[] arrayOfCallSite = $getCallSiteArray();Object task = new test._run_closure1(this);
    

    arrayOfCallSite[1].call(task);
    
    Object task2 = new test._run_closure2(this);
    








    arrayOfCallSite[2].callCurrent(this, arrayOfCallSite[3].call(arrayOfCallSite[4].callConstructor(B.class)));
    
    return arrayOfCallSite[5].call(task2);return null;
  }
  
  static
  {
    __$swapInit();
    Long localLong1 = Long.valueOf(0L);
    __timeStamp__239_neverHappen1423373575421 = localLong1.longValue();
    Long localLong2 = Long.valueOf(1423373575421L);
    __timeStamp = localLong2.longValue();
  }
}

核心的執行代碼是

script = (Script) scriptClass.newInstance();        ---->1

script.run(); ----->2


執行1的時候

首先執行了一個內布生成的createCallSiteArray 函數,它會執行

    public CallSiteArray(Class owner, String [] names) {
        this.owner = owner;
        array = new CallSite[names.length];
        for (int i = 0; i < array.length; i++) {
            array[i] = new AbstractCallSite(this, i, names[i]);
        }
    }

owner = class<T> test

names = [runScript, call, println, getName, <$constructor$>, call]


接下來執行Script的構造函數

接着執行2的時候

1 test$_run_closure1.$createCallSiteArray     owner = class test$_run_closure1,   names=[println]

2. Closure的構造函數  owner = test , thisObject=test

    public Closure(Object owner, Object thisObject) {
        this.owner = owner;
        this.delegate = owner;
        this.thisObject = thisObject;

...

}

3.   走到test.groovy的 task()處

調用 AbstractCallSite.java        receiver = test$_run_closure1

public Object call(Object receiver) throws Throwable {
        return call(receiver, CallSiteArray.NOPARAM);
    }

->

    public Object call(Object receiver, Object[] args) throws Throwable {
        return CallSiteArray.defaultCall(this, receiver, args);
    }

->

CallSiteArray.java

    public static Object defaultCall(CallSite callSite, Object receiver, Object[] args) throws Throwable {
        return createCallSite(callSite, receiver, args).call(receiver, args);
    }

//createCallSite will return an PogoMetaClassSite object, which is also subclass of AbstractCallSite

->

MetaMethod.java

public Object doMethodInvoke(Object object, Object[] argumentArray)

->很奇怪的調用堆棧

    public Object callCurrent(GroovyObject receiver, Object arg1) throws Throwable {
        return callCurrent(receiver, ArrayUtil.createArray(arg1));
    }

//receiver = test$_run_closure1@186062a

//arg1 = "Hello from source code-Task"


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章