summaryrefslogtreecommitdiff
path: root/src/jvm
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-01-04 19:26:21 +0000
committerRich Hickey <richhickey@gmail.com>2008-01-04 19:26:21 +0000
commit443cce766feb8477b2480840bea6d7967212da0c (patch)
tree399abd917e808ec2dc8fe6b849ba6ff2f7b7e56d /src/jvm
parent0fab8baef52f660ea391a2e84ad016f72f71f4b2 (diff)
reflective/compiled calling unification
Diffstat (limited to 'src/jvm')
-rw-r--r--src/jvm/clojure/lang/Compiler.java22
-rw-r--r--src/jvm/clojure/lang/Reflector.java62
2 files changed, 33 insertions, 51 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 83fd19e9..903759aa 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -471,6 +471,7 @@ static interface AssignableExpr{
}
static abstract class HostExpr implements Expr{
+ final static Type BOOLEAN_TYPE = Type.getType(Boolean.class);
final static Type CHAR_TYPE = Type.getType(Character.class);
final static Type INTEGER_TYPE = Type.getType(Integer.class);
final static Type LONG_TYPE = Type.getType(Long.class);
@@ -481,6 +482,7 @@ static abstract class HostExpr implements Expr{
final static Type NUMBER_TYPE = Type.getType(Number.class);
final static Method charValueMethod = Method.getMethod("char charValue()");
+ final static Method booleanValueMethod = Method.getMethod("boolean booleanValue()");
final static Method charValueOfMethod = Method.getMethod("Character valueOf(char)");
final static Method intValueOfMethod = Method.getMethod("Integer valueOf(int)");
@@ -602,14 +604,16 @@ static abstract class HostExpr implements Expr{
{
if(paramType == boolean.class)
{
- Label falseLabel = gen.newLabel();
- Label endLabel = gen.newLabel();
- gen.ifNull(falseLabel);
- gen.push(1);
- gen.goTo(endLabel);
- gen.mark(falseLabel);
- gen.push(0);
- gen.mark(endLabel);
+ gen.checkCast(BOOLEAN_TYPE);
+ gen.invokeVirtual(BOOLEAN_TYPE, booleanValueMethod);
+// Label falseLabel = gen.newLabel();
+// Label endLabel = gen.newLabel();
+// gen.ifNull(falseLabel);
+// gen.push(1);
+// gen.goTo(endLabel);
+// gen.mark(falseLabel);
+// gen.push(0);
+// gen.mark(endLabel);
}
else if(paramType == char.class)
{
@@ -2098,7 +2102,7 @@ static class InvokeExpr implements Expr{
PersistentVector argvs = PersistentVector.EMPTY;
for(int i = 0; i < args.count(); i++)
argvs = argvs.cons(((Expr) args.nth(i)).eval());
- return Reflector.prepRet(fn.applyTo(RT.seq(argvs)));
+ return fn.applyTo(RT.seq(argvs));
}
public void emit(C context, FnExpr fn, GeneratorAdapter gen){
diff --git a/src/jvm/clojure/lang/Reflector.java b/src/jvm/clojure/lang/Reflector.java
index a99dcaa2..2192ce1f 100644
--- a/src/jvm/clojure/lang/Reflector.java
+++ b/src/jvm/clojure/lang/Reflector.java
@@ -23,7 +23,7 @@ public class Reflector{
public static Object invokeInstanceMethod(Object target, String methodName, Object[] args) throws Exception{
Class c = target.getClass();
List methods = getMethods(c, args.length, methodName, false);
- return prepRet(invokeMatchingMethod(methodName, methods, target, args));
+ return invokeMatchingMethod(methodName, methods, target, args);
}
static Object invokeMatchingMethod(String methodName, List methods, Object target, Object[] args)
@@ -65,7 +65,7 @@ static Object invokeMatchingMethod(String methodName, List methods, Object targe
}
if(m == null)
throw new IllegalArgumentException("No matching method found: " + methodName);
- return prepRet(m.invoke(target, boxedArgs));
+ return prepRet(m.getReturnType(),m.invoke(target, boxedArgs));
}
public static Method getAsMethodOfPublicBase(Class c, Method m){
@@ -149,7 +149,7 @@ public static Object getStaticField(String className, String fieldName) throws E
Field f = getField(c, fieldName, true);
if(f != null)
{
- return prepRet(f.get(null));
+ return prepRet(f.getType(),f.get(null));
}
throw new IllegalArgumentException("No matching field found");
}
@@ -170,7 +170,7 @@ public static Object getInstanceField(Object target, String fieldName) throws Ex
Field f = getField(c, fieldName, false);
if(f != null)
{
- return prepRet(f.get(target));
+ return prepRet(f.getType(),f.get(target));
}
throw new IllegalArgumentException("No matching field found");
}
@@ -192,7 +192,7 @@ public static Object invokeInstanceMember(Object target, String name) throws Exc
Field f = getField(c, name, false);
if(f != null) //field get
{
- return prepRet(f.get(target));
+ return prepRet(f.getType(),f.get(target));
}
return invokeInstanceMethod(target, name, RT.EMPTY_ARRAY);
}
@@ -242,18 +242,13 @@ static public List getMethods(Class c, int arity, String name, boolean getStatic
static Object boxArg(Class paramType, Object arg){
- if(arg == null && !paramType.isPrimitive())
- return arg;
-// Class argType = arg.getClass();
-// if(primBoxTypeMatch(paramType, argType))
-// return arg;
- if(paramType == boolean.class)
- {
- if(arg == null)
- return Boolean.FALSE;
- return Boolean.TRUE;
- }
- else if(paramType.isPrimitive() && arg instanceof Number)
+ if(!paramType.isPrimitive())
+ return paramType.cast(arg);
+ else if(paramType == boolean.class)
+ return Boolean.class.cast(arg);
+ else if(paramType == char.class)
+ return Character.class.cast(arg);
+ else if(arg instanceof Number)
{
Number n = (Number) arg;
if(paramType == int.class)
@@ -264,15 +259,12 @@ static Object boxArg(Class paramType, Object arg){
return n.doubleValue();
else if(paramType == long.class)
return n.longValue();
-// else if(paramType == char.class)
-// return (char) n.intValue();
else if(paramType == short.class)
return n.shortValue();
- else
+ else if(paramType == byte.class)
return n.byteValue();
}
- else
- return arg;
+ throw new IllegalArgumentException("Unexpected param type");
}
static Object[] boxArgs(Class[] params, Object[] args){
@@ -289,6 +281,8 @@ static Object[] boxArgs(Class[] params, Object[] args){
}
static public boolean paramArgTypeMatch(Class paramType, Class argType){
+ if(argType == null)
+ return !paramType.isPrimitive();
if(paramType == argType || paramType.isAssignableFrom(argType))
return true;
if(paramType == int.class)
@@ -322,31 +316,15 @@ static boolean isCongruent(Class[] params, Object[] args){
Object arg = args[i];
Class argType = (arg == null) ? null : arg.getClass();
Class paramType = params[i];
- if(paramType == boolean.class)
- {
- ret = arg == null || argType == Boolean.class;
- }
- else if(paramType.isPrimitive())
- {
- if(arg == null)
- ret = false;
- else
- ret = paramArgTypeMatch(paramType, argType);
- }
- else
- {
- ret = arg == null
- || argType == paramType
- || paramType.isAssignableFrom(argType);
- }
+ ret = paramArgTypeMatch(paramType, argType);
}
}
return ret;
}
-static Object prepRet(Object x){
- if(x instanceof Boolean)
- return ((Boolean) x).booleanValue() ? x : null;
+static Object prepRet(Class c, Object x){
+ if(c == boolean.class)
+ return ((Boolean) x).booleanValue() ? RT.T : null;
return x;
}
}