Permalink
Browse files

Fixed most of the invocation issues for Blocks. not nearly safe yet, …

…though

git-svn-id: http://svn.codehaus.org/jruby/branches/enebo_block@2824 961051c9-f516-0410-bf72-c9f7e237a7b7
  • Loading branch information...
1 parent b7f7c46 commit be47832214a2d832b70a0a84c438b9645dda3eb8 @olabini olabini committed Jan 23, 2007
@@ -50,8 +50,9 @@
private final static String FULL_SUPER_CLASS = FullInvocationMethod.class.getName().replace('.','/');
private final static String IRUB_ID = "Lorg/jruby/runtime/builtin/IRubyObject;";
private final static String BLOCK_ID = "Lorg/jruby/runtime/Block;";
- private final static String CALL_SIG = "(" + IRUB_ID + "[" + IRUB_ID + ")" + IRUB_ID;
- private final static String COMPILED_CALL_SIG = "(Lorg/jruby/runtime/ThreadContext;" + IRUB_ID + "[" + IRUB_ID + "Lorg/jruby/runtime/Block;)" + IRUB_ID;
+ private final static String CALL_SIG = "(" + IRUB_ID + "[" + IRUB_ID + BLOCK_ID + ")" + IRUB_ID;
+ private final static String CALL_SIG_NB = "(" + IRUB_ID + "[" + IRUB_ID + ")" + IRUB_ID;
+ private final static String COMPILED_CALL_SIG = "(Lorg/jruby/runtime/ThreadContext;" + IRUB_ID + "[" + IRUB_ID + BLOCK_ID + ")" + IRUB_ID;
private final static String SUPER_SIG = "(" + ci(RubyModule.class) + ci(Arity.class) + ci(Visibility.class) + ")V";
private final static String COMPILED_SUPER_SIG = "(" + ci(RubyModule.class) + ci(Arity.class) + ci(Visibility.class) + ci(SinglyLinkedList.class) + ")V";
@@ -126,7 +127,7 @@ private String getReturnName(Class type, String method, Class[] args) throws Exc
return t;
}
- private DynamicMethod getMethod(RubyModule implementationClass, Class type, String method, Arity arity, Visibility visibility, String sup) {
+ private DynamicMethod getMethod(RubyModule implementationClass, Class type, String method, Arity arity, Visibility visibility, String sup, boolean block) {
String typePath = p(type);
String mname = type.getName() + "Invoker" + method + arity;
String mnamePath = typePath + "Invoker" + method + arity;
@@ -137,15 +138,20 @@ private DynamicMethod getMethod(RubyModule implementationClass, Class type, Stri
MethodVisitor mv = null;
if(arity.isFixed()) {
int ar_len = arity.getValue();
- Class[] sign = new Class[ar_len];
+ Class[] sign = new Class[ block ? ar_len+1 : ar_len ];
java.util.Arrays.fill(sign,IRubyObject.class);
+ if(block) {
+ sign[sign.length-1] = Block.class;
+ }
StringBuffer sbe = new StringBuffer();
for(int i=0;i<ar_len;i++) {
sbe.append(IRUB_ID);
}
- sbe.append(BLOCK_ID);
+ if(block) {
+ sbe.append(BLOCK_ID);
+ }
String ret = getReturnName(type, method, sign);
- mv = cw.visitMethod(ACC_PUBLIC, "call", CALL_SIG, null, null);
+ mv = cw.visitMethod(ACC_PUBLIC, "call", block ? CALL_SIG : CALL_SIG_NB, null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, typePath);
@@ -158,16 +164,22 @@ private DynamicMethod getMethod(RubyModule implementationClass, Class type, Stri
}
mv.visitInsn(AALOAD);
}
+ if(block) {
+ mv.visitVarInsn(ALOAD, 3);
+ }
mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "(" + sbe + ")" + ret);
mv.visitInsn(ARETURN);
} else {
- String ret = getReturnName(type, method, new Class[]{IRubyObject[].class, Block.class});
- mv = cw.visitMethod(ACC_PUBLIC, "call", CALL_SIG, null, null);
+ String ret = getReturnName(type, method, block ? new Class[]{IRubyObject[].class, Block.class} : new Class[]{IRubyObject[].class});
+ mv = cw.visitMethod(ACC_PUBLIC, "call", block ? CALL_SIG : CALL_SIG_NB, null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, typePath);
mv.visitVarInsn(ALOAD, 2);
- mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "([" + IRUB_ID + BLOCK_ID + ")" + ret);
+ if(block) {
+ mv.visitVarInsn(ALOAD, 3);
+ }
+ mv.visitMethodInsn(INVOKEVIRTUAL, typePath, method, "([" + IRUB_ID + (block ? BLOCK_ID : "") + ")" + ret);
mv.visitInsn(ARETURN);
}
c = endCall(implementationClass.getRuntime(), cw,mv,mname);
@@ -213,11 +225,11 @@ private DynamicMethod getCompleteMethod(RubyModule implementationClass, Class ty
}
public DynamicMethod getFullMethod(RubyModule implementationClass, Class type, String method, Arity arity, Visibility visibility) {
- return getMethod(implementationClass,type,method,arity,visibility,FULL_SUPER_CLASS);
+ return getMethod(implementationClass,type,method,arity,visibility,FULL_SUPER_CLASS, true);
}
public DynamicMethod getSimpleMethod(RubyModule implementationClass, Class type, String method, Arity arity, Visibility visibility) {
- return getMethod(implementationClass,type,method,arity,visibility,SIMPLE_SUPER_CLASS);
+ return getMethod(implementationClass,type,method,arity,visibility,SIMPLE_SUPER_CLASS, false);
}
public DynamicMethod getCompiledMethod(RubyModule implementationClass, Class type, String method, Arity arity, Visibility visibility, SinglyLinkedList cref) {
@@ -0,0 +1,74 @@
+/***** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2007 Ola Bini <ola@ologix.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/
+package org.jruby.runtime.callback;
+
+import org.jruby.IRuby;
+import org.jruby.runtime.Arity;
+import org.jruby.runtime.Block;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.exceptions.RaiseException;
+import org.jruby.exceptions.JumpException;
+import org.jruby.exceptions.ThreadKill;
+import org.jruby.exceptions.MainExitException;
+
+/**
+ * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
+ */
+public abstract class FastInvocationCallback implements Callback {
+ private Arity arity;
+
+ public IRubyObject execute(IRubyObject recv, IRubyObject[] oargs, Block block) {
+ IRuby runtime = recv.getRuntime();
+ arity.checkArity(runtime, oargs);
+ try {
+ return call(recv,oargs);
+ } catch(RaiseException e) {
+ throw e;
+ } catch(JumpException e) {
+ throw e;
+ } catch(ThreadKill e) {
+ throw e;
+ } catch(MainExitException e) {
+ throw e;
+ } catch(Exception e) {
+ runtime.getJavaSupport().handleNativeException(e);
+ return runtime.getNil();
+ }
+ }
+
+ public abstract IRubyObject call(Object receiver, Object[] args);
+
+ public void setArity(Arity arity) {
+ this.arity = arity;
+ }
+
+ public Arity getArity() {
+ return arity;
+ }
+
+}// FastInvocationCallback
@@ -29,6 +29,7 @@
import org.jruby.IRuby;
import org.jruby.runtime.Arity;
+import org.jruby.runtime.Block;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.exceptions.RaiseException;
import org.jruby.exceptions.JumpException;
@@ -41,11 +42,11 @@
public abstract class InvocationCallback implements Callback {
private Arity arity;
- public IRubyObject execute(IRubyObject recv, IRubyObject[] oargs) {
+ public IRubyObject execute(IRubyObject recv, IRubyObject[] oargs, Block block) {
IRuby runtime = recv.getRuntime();
arity.checkArity(runtime, oargs);
try {
- return call(recv,oargs);
+ return call(recv,oargs,block);
} catch(RaiseException e) {
throw e;
} catch(JumpException e) {
@@ -60,7 +61,7 @@ public IRubyObject execute(IRubyObject recv, IRubyObject[] oargs) {
}
}
- public abstract IRubyObject call(Object receiver, Object[] args);
+ public abstract IRubyObject call(Object receiver, Object[] args, Block block);
public void setArity(Arity arity) {
this.arity = arity;
Oops, something went wrong.

0 comments on commit be47832

Please sign in to comment.