<commit_before>This is an implementation of invokedynamic-based multi-language linking and 
metaobject protocol framework. Such framework allows JVM classes emitted by 
one language runtime to invoke methods, read and write properties, and so 
forth, on objects from a different language runtime, within a single JVM 
instance.

It consists of two different parts:

* a linker composition framework that allows invokedynamic linkers for 
multiple languages to be discovered in classpath, loaded, and composed into a 
single "master" linker, and
* a set of method naming and argument passing conventions, used through 
invokedynamic that make up the commonly understood metaobject protocol.

As an added bonus, it also contains a POJO linker that allows your language to
link with plain Java objects. It manages conformance to JavaBeans 
specification, and provides full support for vararg methods and optimized 
overloaded method resolution. 

Building
========
Here's how to build the JAR file:

    ant jar

Note that this will download a private copy of OpenJDK into the build directory
(about 60MB).
Here's how to test the JAR file:

    ant test

Known issues
============

* It doesn't currently work with <NAME>'s JSR-292 backport, as the backport
was not updated to reflect newest JSR-292
* Some tests still fail as MethodHandle.asCollector still doesn't work.

Using the library
=================
Suppose you have a language runtime and want to both use the linker and MOP of
other languages (be able to access objects of other runtimes) and want other 
language runtimes to be serviced by your linker and MOP (be able to expose your
runtime's objects to other runtimes).

Here's what you need to do in detail:

Using the linker facility
-------------------------
Have one class that creates a DynamicLinker and has a bootstrap method:

    package org.mycompany.mylanguage;

    import java.lang.invoke.*;
    import org.dynalang.dynalink.*;
    
    class MyLanguageRuntime {
        private static final DynamicLinker linker = 
            new DynamicLinkerFactory().createLinker();
    
        public static CallSite bootstrap(MethodHandles.Lookup lookup, String name,
            MethodType type)
        {
            final RelinkableCallSite callSite = new MonomorphicCallSite(caller, 
                name, type);
            linker.link(callSite);
            return callSite;
        }
    }

Now, from every class you emit that uses invokedynamic, you would need to emit
an invokedynamic instruction that specifies this method as its bootstrap 
method. I.e. if you used the ASM 4 library and wanted to emit an invokedynamic
call to a property getter "color" that you'd expect to return a string, you'd 
do:

    mv.visitIndyMethodInsn("dyn:getProp:color", "(Ljava/lang/Object;)Ljava/lang/String;", 
        new MHandle(MHandle.REF_invokeStatic, "org/mycompany/mylanguage/MyLanguageRuntime",
        "bootstrap", MethodType.methodType(CallSite.class, 
	        MethodHandles.Lookup.class, String.class, MethodType.class).toMethodDescriptorString()),
        new Object[0]);

Note how you'll need to use a special subclass of CallSite named 
`RelinkableCallSite`. It's actually an abstract class that allows its 
implementations to use any inline caching strategy they choose. A concrete 
subclass named `MonomorphicCallSite` is provided with the library that 
implements a monomorphic inline cache.
 
Having your own language linker
-------------------------------
That's it, now every `invokedynamic` call will go through the linker. The 
linker created by the `DynamicLinkerFactory` actually manages a collection of 
instances of classes that all implement 
`org.dynalang.dynalink.GuardingDynamicLinker` interface. If your runtime has 
its own object model, you need to create an implementation of this interface 
yourself to provide MOP functionality for your own language. The 
`DynamicLinkerFactory` uses the JAR service mechanism, and will look into a 
file named `META-INF/services/org.dynalang.dynalink.GuardingDynamicLinker` in 
every JAR file of the actual class loader. (By default, this is the thread 
context class loader. The factory has a method for setting a different class 
loader.) Therefore, if you wish for your language linker to be discovered by 
other language runtimes, you should have this file in the JAR file of your 
language runtime distribution, and declare its class name in it.

However, when you are creating a linker for your own use, you might want to
explicitly create an instance of your guarding linker and make sure that the
master linker gives it priority. You can do this by changing the code for
creating the linker in `MyLanguageRuntime` to:

    private static final DynamicLinker linker;
    static {
        final DynamicLinkerFactory factory = new DynamicLinkerFactory();
        final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
        factory.setPrioritizedLinker(myLanguageLinker);
        linker = factory.createLinker();
    }

The factory is smart enough that even if it discovers the `MyLanguageLinker` 
class through the JAR service mechanism, it will ignore it if you supplied a 
pre-created prioritized instance.

Guarding linker?
----------------
Yes, the interface is named `GuardingDynamicLinker`. It has a sole method with
this signature:

  public GuardedInvocation getGuardedInvocation(
      CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices,
      Object... arguments);
      
It is invoked for a particular invocation at particular call site. It needs to<commit_msg>Fix formatting<commit_after>This is an implementation of invokedynamic-based multi-language linking and 
metaobject protocol framework. Such framework allows JVM classes emitted by 
one language runtime to invoke methods, read and write properties, and so 
forth, on objects from a different language runtime, within a single JVM 
instance.

It consists of two different parts:

* a linker composition framework that allows invokedynamic linkers for 
multiple languages to be discovered in classpath, loaded, and composed into a 
single "master" linker, and
* a set of method naming and argument passing conventions, used through 
invokedynamic that make up the commonly understood metaobject protocol.

As an added bonus, it also contains a POJO linker that allows your language to
link with plain Java objects. It manages conformance to JavaBeans 
specification, and provides full support for vararg methods and optimized 
overloaded method resolution. 

Building
========
Here's how to build the JAR file:

    ant jar

Note that this will download a private copy of OpenJDK into the build directory
(about 60MB).
Here's how to test the JAR file:

    ant test

Known issues
============

* It doesn't currently work with <NAME>'s JSR-292 backport, as the backport
was not updated to reflect newest JSR-292
* Some tests still fail as MethodHandle.asCollector still doesn't work.

Using the library
=================
Suppose you have a language runtime and want to both use the linker and MOP of
other languages (be able to access objects of other runtimes) and want other 
language runtimes to be serviced by your linker and MOP (be able to expose your
runtime's objects to other runtimes).

Here's what you need to do in detail:

Using the linker facility
-------------------------
Have one class that creates a DynamicLinker and has a bootstrap method:

    package org.mycompany.mylanguage;

    import java.lang.invoke.*;
    import org.dynalang.dynalink.*;
    
    class MyLanguageRuntime {
        private static final DynamicLinker linker = 
            new DynamicLinkerFactory().createLinker();
    
        public static CallSite bootstrap(MethodHandles.Lookup lookup, String name,
            MethodType type)
        {
            final RelinkableCallSite callSite = new MonomorphicCallSite(caller, 
                name, type);
            linker.link(callSite);
            return callSite;
        }
    }

Now, from every class you emit that uses invokedynamic, you would need to emit
an invokedynamic instruction that specifies this method as its bootstrap 
method. I.e. if you used the ASM 4 library and wanted to emit an invokedynamic
call to a property getter "color" that you'd expect to return a string, you'd 
do:

    mv.visitIndyMethodInsn("dyn:getProp:color", "(Ljava/lang/Object;)Ljava/lang/String;", 
        new MHandle(MHandle.REF_invokeStatic, "org/mycompany/mylanguage/MyLanguageRuntime",
        "bootstrap", MethodType.methodType(CallSite.class, 
	        MethodHandles.Lookup.class, String.class, MethodType.class).toMethodDescriptorString()),
        new Object[0]);

Note how you'll need to use a special subclass of CallSite named 
`RelinkableCallSite`. It's actually an abstract class that allows its 
implementations to use any inline caching strategy they choose. A concrete 
subclass named `MonomorphicCallSite` is provided with the library that 
implements a monomorphic inline cache.
 
Having your own language linker
-------------------------------
That's it, now every `invokedynamic` call will go through the linker. The 
linker created by the `DynamicLinkerFactory` actually manages a collection of 
instances of classes that all implement 
`org.dynalang.dynalink.GuardingDynamicLinker` interface. If your runtime has 
its own object model, you need to create an implementation of this interface 
yourself to provide MOP functionality for your own language. The 
`DynamicLinkerFactory` uses the JAR service mechanism, and will look into a 
file named `META-INF/services/org.dynalang.dynalink.GuardingDynamicLinker` in 
every JAR file of the actual class loader. (By default, this is the thread 
context class loader. The factory has a method for setting a different class 
loader.) Therefore, if you wish for your language linker to be discovered by 
other language runtimes, you should have this file in the JAR file of your 
language runtime distribution, and declare its class name in it.

However, when you are creating a linker for your own use, you might want to
explicitly create an instance of your guarding linker and make sure that the
master linker gives it priority. You can do this by changing the code for
creating the linker in `MyLanguageRuntime` to:

    private static final DynamicLinker linker;
    static {
        final DynamicLinkerFactory factory = new DynamicLinkerFactory();
        final GuardingDynamicLinker myLanguageLinker = new MyLanguageLinker();
        factory.setPrioritizedLinker(myLanguageLinker);
        linker = factory.createLinker();
    }

The factory is smart enough that even if it discovers the `MyLanguageLinker` 
class through the JAR service mechanism, it will ignore it if you supplied a 
pre-created prioritized instance.

Guarding linker?
----------------
Yes, the interface is named `GuardingDynamicLinker`. It has a sole method with
this signature:

    public GuardedInvocation getGuardedInvocation(
        CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices,
        Object... arguments);
      
It is invoked for a particular invocation at particular call site. It needs to
{'fraction_non_alphanumeric': 0.06324251898168826, 'fraction_numerical': 0.001786511835640911, 'mean_word_length': 3.7846153846153845, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '754589', 'n_tokens_mistral': 2889, 'n_tokens_neox': 2725, 'n_words': 1390}