<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>build_lib/invokedynamic.jar</filename>
    </added>
    <added>
      <filename>src/org/jruby/compiler/impl/InvokeDynamicInvocationCompiler.java</filename>
    </added>
    <added>
      <filename>src/org/jruby/runtime/invokedynamic/InvokeDynamicSupport.java</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -168,6 +168,9 @@
     &lt;java classname=&quot;org.jruby.anno.InvokerGenerator&quot; fork=&quot;true&quot; failonerror=&quot;true&quot;&gt;
       &lt;classpath refid=&quot;build.classpath&quot;/&gt;
       &lt;classpath path=&quot;${jruby.classes.dir}&quot;/&gt;
+      &lt;!-- uncomment this line when building on a JVM with invokedynamic
+      &lt;jvmarg line=&quot;-XX:+InvokeDynamic&quot;/&gt;
+      --&gt;
       &lt;arg value=&quot;src_gen/annotated_classes.txt&quot;/&gt;
       &lt;arg value=&quot;${jruby.classes.dir}&quot;/&gt;
     &lt;/java&gt;
@@ -193,6 +196,9 @@
     &lt;java classname=&quot;org.jruby.util.unsafe.UnsafeGenerator&quot; fork=&quot;true&quot; failonerror=&quot;true&quot;&gt;
         &lt;classpath refid=&quot;build.classpath&quot;/&gt;
         &lt;classpath path=&quot;${jruby.classes.dir}&quot;/&gt;
+        &lt;!-- uncomment this line when building on a JVM with invokedynamic
+        &lt;jvmarg line=&quot;-XX:+InvokeDynamic&quot;/&gt;
+        --&gt;
         &lt;arg value=&quot;org.jruby.util.unsafe&quot;/&gt;
         &lt;arg value=&quot;${jruby.classes.dir}/org/jruby/util/unsafe&quot;/&gt;
     &lt;/java&gt;</diff>
      <filename>build.xml</filename>
    </modified>
    <modified>
      <diff>@@ -89,7 +89,7 @@
         &lt;java-data xmlns=&quot;http://www.netbeans.org/ns/freeform-project-java/2&quot;&gt;
             &lt;compilation-unit&gt;
                 &lt;package-root&gt;${src.dir}&lt;/package-root&gt;
-                &lt;classpath mode=&quot;compile&quot;&gt;lib/bsf.jar:build_lib/junit.jar:build_lib/jline-0.9.93.jar:build_lib/asm-3.0.jar:build_lib/asm-commons-3.0.jar:build_lib/asm-util-3.0.jar:build_lib/jna.jar:build_lib/nailgun-0.7.1.jar:build_lib/joni.jar:build_lib/joda-time-1.5.1.jar:build_lib/jna-posix.jar:build_lib/bytelist-0.1.jar:build_lib/jvyamlb-0.2.3.jar:build_lib/dynalang-0.3.jar&lt;/classpath&gt;
+                &lt;classpath mode=&quot;compile&quot;&gt;lib/bsf.jar:build_lib/junit.jar:build_lib/jline-0.9.93.jar:build_lib/asm-3.0.jar:build_lib/asm-commons-3.0.jar:build_lib/asm-util-3.0.jar:build_lib/jna.jar:build_lib/nailgun-0.7.1.jar:build_lib/joni.jar:build_lib/joda-time-1.5.1.jar:build_lib/jna-posix.jar:build_lib/bytelist-0.1.jar:build_lib/jvyamlb-0.2.3.jar:build_lib/dynalang-0.3.jar:build_lib/invokedynamic.jar&lt;/classpath&gt;
                 &lt;built-to&gt;${jruby.classes.dir}&lt;/built-to&gt;
                 &lt;built-to&gt;${lib.dir}/jruby.jar&lt;/built-to&gt;
                 &lt;javadoc-built-to&gt;docs/api&lt;/javadoc-built-to&gt;</diff>
      <filename>nbproject/project.xml</filename>
    </modified>
    <modified>
      <diff>@@ -32,9 +32,11 @@ package org.jruby.compiler.impl;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.math.BigInteger;
 import java.util.Arrays;
 
@@ -95,6 +97,7 @@ import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.util.CheckClassAdapter;
 import org.objectweb.asm.util.TraceClassVisitor;
@@ -146,6 +149,30 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
     
     CacheCompiler cacheCompiler;
     
+    private static final Constructor invDynInvCompilerConstructor;
+    private static final Method invDynSupportInstaller;
+
+    static {
+        Constructor compilerConstructor = null;
+        Method installerMethod = null;
+        try {
+            // try to load java.dyn.Dynamic first
+            Class.forName(&quot;java.dyn.Dynamic&quot;);
+            
+            // if that succeeds, the others should as well
+            Class compiler =
+                    Class.forName(&quot;org.jruby.compiler.impl.InvokeDynamicInvocationCompiler&quot;);
+            Class support =
+                    Class.forName(&quot;org.jruby.runtime.invokedynamic.InvokeDynamicSupport&quot;);
+            compilerConstructor = compiler.getConstructor(AbstractMethodCompiler.class, SkinnyMethodAdapter.class);
+            installerMethod = support.getDeclaredMethod(&quot;installBytecode&quot;, MethodVisitor.class, String.class);
+        } catch (Exception e) {
+            // leave it null and fall back on our normal invocation logic
+        }
+        invDynInvCompilerConstructor = compilerConstructor;
+        invDynSupportInstaller = installerMethod;
+    }
+    
     /** Creates a new instance of StandardCompilerContext */
     public StandardASMCompiler(String classname, String sourcename) {
         this.classname = classname;
@@ -400,6 +427,20 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
 
         clinitMethod = new SkinnyMethodAdapter(cv.visitMethod(ACC_PUBLIC | ACC_STATIC, &quot;&lt;clinit&gt;&quot;, sig(Void.TYPE), null, null));
         clinitMethod.start();
+
+        if (invDynSupportInstaller != null) {
+            // install invokedynamic bootstrapper
+            // TODO need to abstract this setup behind another compiler interface
+            try {
+                invDynSupportInstaller.invoke(null, clinitMethod, classname);
+            } catch (IllegalAccessException ex) {
+                // ignore; we won't use invokedynamic
+            } catch (IllegalArgumentException ex) {
+                // ignore; we won't use invokedynamic
+            } catch (InvocationTargetException ex) {
+                // ignore; we won't use invokedynamic
+            }
+        }
     }
 
     private void endClassInit() {
@@ -461,7 +502,20 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
             method = new SkinnyMethodAdapter(getClassVisitor().visitMethod(ACC_PUBLIC, methodName, getSignature(), null, null));
             
             createVariableCompiler();
-            invocationCompiler = new StandardInvocationCompiler(this, method);
+            if (invDynInvCompilerConstructor != null) {
+                try {
+                    invocationCompiler = (InvocationCompiler)invDynInvCompilerConstructor.newInstance(this, method);
+                } catch (InstantiationException ie) {
+                    // do nothing, fall back on default compiler below
+                } catch (IllegalAccessException ie) {
+                    // do nothing, fall back on default compiler below
+                } catch (InvocationTargetException ie) {
+                    // do nothing, fall back on default compiler below
+                }
+            }
+            if (invocationCompiler == null) {
+                invocationCompiler = new StandardInvocationCompiler(this, method);
+            }
         }
         
         protected abstract String getSignature();
@@ -477,6 +531,7 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
                 super(methodName, inspector, scope);
             }
 
+            @Override
             public void endMethod() {
                 // return last value from execution
                 method.areturn();
@@ -2406,15 +2461,15 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
                 final CompilerCallback pathCallback, 
                 final CompilerCallback bodyCallback, 
                 final CompilerCallback receiverCallback) {
-            String methodName = null;
+            String classMethodName = null;
             if (receiverCallback == null) {
                 String mangledName = JavaNameMangler.mangleStringForCleanJavaIdentifier(name);
-                methodName = &quot;class_&quot; + ++methodIndex + &quot;$RUBY$&quot; + mangledName;
+                classMethodName = &quot;class_&quot; + ++methodIndex + &quot;$RUBY$&quot; + mangledName;
             } else {
-                methodName = &quot;sclass_&quot; + ++methodIndex + &quot;$RUBY$__singleton__&quot;;
+                classMethodName = &quot;sclass_&quot; + ++methodIndex + &quot;$RUBY$__singleton__&quot;;
             }
 
-            final ASMMethodCompiler methodCompiler = new ASMMethodCompiler(methodName, null, staticScope);
+            final ASMMethodCompiler methodCompiler = new ASMMethodCompiler(classMethodName, null, staticScope);
             
             CompilerCallback bodyPrep = new CompilerCallback() {
                 public void call(MethodCompiler context) {
@@ -2510,14 +2565,14 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
             }
             method.getstatic(p(Block.class), &quot;NULL_BLOCK&quot;, ci(Block.class));
 
-            method.invokevirtual(classname, methodName, METHOD_SIGNATURES[0]);
+            method.invokevirtual(classname, classMethodName, METHOD_SIGNATURES[0]);
         }
 
         public void defineModule(final String name, final StaticScope staticScope, final CompilerCallback pathCallback, final CompilerCallback bodyCallback) {
             String mangledName = JavaNameMangler.mangleStringForCleanJavaIdentifier(name);
-            String methodName = &quot;module__&quot; + ++methodIndex + &quot;$RUBY$&quot; + mangledName;
+            String moduleMethodName = &quot;module__&quot; + ++methodIndex + &quot;$RUBY$&quot; + mangledName;
 
-            final ASMMethodCompiler methodCompiler = new ASMMethodCompiler(methodName, null, staticScope);
+            final ASMMethodCompiler methodCompiler = new ASMMethodCompiler(moduleMethodName, null, staticScope);
 
             CompilerCallback bodyPrep = new CompilerCallback() {
                 public void call(MethodCompiler context) {
@@ -2580,7 +2635,7 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
             method.getstatic(p(IRubyObject.class), &quot;NULL_ARRAY&quot;, ci(IRubyObject[].class));
             method.getstatic(p(Block.class), &quot;NULL_BLOCK&quot;, ci(Block.class));
 
-            method.invokevirtual(classname, methodName, METHOD_SIGNATURES[4]);
+            method.invokevirtual(classname, moduleMethodName, METHOD_SIGNATURES[4]);
         }
         
         public void unwrapPassedBlock() {
@@ -2696,15 +2751,15 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
                 CompilerCallback receiver, ASTInspector inspector, boolean root) {
             // TODO: build arg list based on number of args, optionals, etc
             ++methodIndex;
-            String methodName;
+            String newMethodName;
             if (root &amp;&amp; Boolean.getBoolean(&quot;jruby.compile.toplevel&quot;)) {
-                methodName = name;
+                newMethodName = name;
             } else {
                 String mangledName = JavaNameMangler.mangleStringForCleanJavaIdentifier(name);
-                methodName = &quot;method__&quot; + methodIndex + &quot;$RUBY$&quot; + mangledName;
+                newMethodName = &quot;method__&quot; + methodIndex + &quot;$RUBY$&quot; + mangledName;
             }
 
-            MethodCompiler methodCompiler = startMethod(methodName, args, scope, inspector);
+            MethodCompiler methodCompiler = startMethod(newMethodName, args, scope, inspector);
 
             // callbacks to fill in method body
             body.call(methodCompiler);
@@ -2723,7 +2778,7 @@ public class StandardASMCompiler implements ScriptCompiler, Opcodes {
 
             method.ldc(name);
 
-            method.ldc(methodName);
+            method.ldc(newMethodName);
 
             buildStaticScopeNames(method, scope);
 </diff>
      <filename>src/org/jruby/compiler/impl/StandardASMCompiler.java</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>12acf37baebf119b269fde02bc994a811614ee2a</id>
    </parent>
  </parents>
  <author>
    <name>headius</name>
    <email>headius@961051c9-f516-0410-bf72-c9f7e237a7b7</email>
  </author>
  <url>http://github.com/bobmcwhirter/jruby/commit/f2b76db0524126d8e3d24eb4d039402548d6351d</url>
  <id>f2b76db0524126d8e3d24eb4d039402548d6351d</id>
  <committed-date>2008-09-07T01:38:05-07:00</committed-date>
  <authored-date>2008-09-07T01:38:05-07:00</authored-date>
  <message>Initial support for invokedynamic-based dispatch in the compiler.


git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@7648 961051c9-f516-0410-bf72-c9f7e237a7b7</message>
  <tree>f6141e72898379a47d1778052f9093c19396aca9</tree>
  <committer>
    <name>headius</name>
    <email>headius@961051c9-f516-0410-bf72-c9f7e237a7b7</email>
  </committer>
</commit>
