一个简单的groovy script生成的class文件及其反编译

页面导航:首页 > 网络编程 > JavaScript > 一个简单的groovy script生成的class文件及其反编译

一个简单的groovy script生成的class文件及其反编译

来源: 作者: 时间:2016-02-03 09:20 【

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

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 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 = [email protected]

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


Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<