Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Closures are executed?

Tags:

groovy

I'm very new to Groovy. I wonder how Closures are implemented in Groovy.

Lets say :

def a = { println "Hello" }
a()

when a() is done, what is actually happening behind the scenes? Which method does a() calls to make the closure executable?

Thanks in advance.

like image 577
batman Avatar asked Dec 27 '22 20:12

batman


1 Answers

Basically:

  • your closure is a class with specific name
  • a() invokes doCall() which invokes doCall(Object it) (implicit it in closures)
  • acallsite contains method names (2 x println) - and are invoked with appropriate arguments

Here you go:

For this Groovy Script:

def a = { println "Hello"; println "Hello2" }
a()

Closure a looks like this:

class Test$_run_closure1 extends Closure
implements GeneratedClosure
{

    public Object doCall(Object it)
    {
        CallSite acallsite[] = $getCallSiteArray();
        acallsite[0].callCurrent(this, "Hello");
        return acallsite[1].callCurrent(this, "Hello2");
    }

    public Object doCall()
    {
        CallSite acallsite[] = $getCallSiteArray();
        return doCall(null);
    }

    protected MetaClass $getStaticMetaClass()
    {
        if(getClass() != Test$_run_closure1)
            return ScriptBytecodeAdapter.initMetaClass(this);
        ClassInfo classinfo = $staticClassInfo;
        if(classinfo == null)
            $staticClassInfo = classinfo = ClassInfo.getClassInfo(getClass());
        return classinfo.getMetaClass();
    }

    public static void __$swapInit()
    {
        CallSite acallsite[] = $getCallSiteArray();
        $callSiteArray = null;
    }

    private static void $createCallSiteArray_1(String as[])
    {
        as[0] = "println";
        as[1] = "println";
    }

    private static CallSiteArray $createCallSiteArray()
    {
        String as[] = new String[2];
        $createCallSiteArray_1(as);
        return new CallSiteArray(Test$_run_closure1, as);
    }

    private static CallSite[] $getCallSiteArray()
    {
        CallSiteArray callsitearray;
        if($callSiteArray == null || (callsitearray = (CallSiteArray)$callSiteArray.get()) == null)
        {
            callsitearray = $createCallSiteArray();
            $callSiteArray = new SoftReference(callsitearray);
        }
        return callsitearray.array;
    }

    static Class _mthclass$(String s)
    {
        try
        {
            return Class.forName(s);
        }
        catch(ClassNotFoundException classnotfoundexception)
        {
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());
        }
    }

    private static ClassInfo $staticClassInfo;
    public static transient boolean __$stMC;
    private static SoftReference $callSiteArray;

    static 
    {
        __$swapInit();
    }

    public Test$_run_closure1(Object _outerInstance, Object _thisObject)
    {
        CallSite acallsite[] = $getCallSiteArray();
        super(_outerInstance, _thisObject);
    }
}
like image 177
Xeon Avatar answered Jan 03 '23 15:01

Xeon