1 package gnu.kawa.reflect; 2 import gnu.bytecode.*; 3 import gnu.mapping.*; 4 import gnu.expr.*; 5 6 public class InstanceOf extends Procedure2 implements CanInline, Inlineable 7 { 8 protected Language language; 9 10 public InstanceOf(Language language) 11 { 12 this.language = language; 13 } 14 15 public InstanceOf(Language language, String name) 16 { 17 this.language = language; 18 setName(name); 19 } 20 21 public Object apply2 (Object arg1, Object arg2) 22 { 23 Type type = language.asType(arg2); 24 return language.booleanObject(type.isInstance(arg1)); 25 } 26 27 static gnu.bytecode.ClassType typeType; 28 static gnu.bytecode.Method instanceMethod; 29 30 public Expression inline (ApplyExp exp, ExpWalker walker) 31 { 32 exp = Invoke.inlineClassName(exp, 1, (InlineCalls) walker); 33 Expression[] args = exp.getArgs(); 34 if (args.length == 2) 35 { 36 Expression value = args[0]; 37 Expression texp = args[1]; 38 if (texp instanceof QuoteExp) 39 { 40 Object t = ((QuoteExp) texp).getValue(); 41 if (t instanceof Type) 42 { 43 Type type = (Type) t; 44 if (value instanceof QuoteExp) 45 return type.isInstance(((QuoteExp) value).getValue()) 46 ? QuoteExp.trueExp : QuoteExp.falseExp; 47 if (! value.side_effects()) 48 { 49 int comp = type.compare(value.getType()); 50 if (comp == 1 || comp == 0) 51 return QuoteExp.trueExp; 52 if (comp == -3) 53 return QuoteExp.falseExp; 54 } 55 } 56 } 57 } 58 return exp; 59 } 60 61 public void compile (ApplyExp exp, Compilation comp, Target target) 62 { 63 Expression[] args = exp.getArgs(); 64 CodeAttr code = comp.getCode(); 65 Type type = null; 66 Expression typeArg = args[1]; 67 if (typeArg instanceof QuoteExp) 68 { 69 try 70 { 71 type = language.asType(((QuoteExp) typeArg).getValue()); 72 } 73 catch (Exception ex) 74 { 75 comp.error('w', "unknown type spec: "+type); 76 } 77 } 78 else 79 type = language.getTypeFor(typeArg); 80 if (type != null) 81 { 82 args[0].compile(comp, Target.pushObject); 83 if (type instanceof TypeValue) 84 { 85 ((TypeValue) type).emitIsInstance(null, comp, target); 86 return; 87 } 88 else 89 type.emitIsInstance(code); 90 comp.usedClass(type); 91 } 92 else 93 { 94 if (typeType == null) 95 { 96 typeType = ClassType.make("gnu.bytecode.Type"); 97 instanceMethod = typeType.addMethod("isInstance", 98 Compilation.apply1args, 99 Type.boolean_type, 100 gnu.bytecode.Access.PUBLIC); 101 } 102 args[1].compile(comp, typeType); 103 args[0].compile(comp, Target.pushObject); 104 code.emitInvokeVirtual(instanceMethod); 105 } 106 target.compileFromStack(comp, language.getTypeFor(Boolean.TYPE)); 107 } 108 109 public Type getReturnType (Expression[] args) 110 { 111 return language.getTypeFor(Boolean.TYPE); 112 } 113 114 public static void emitIsInstance(TypeValue type, Variable incoming, 115 Compilation comp, Target target) 116 { 117 CodeAttr code = comp.getCode(); 118 type.emitTestIf(null, null, comp); 119 ConditionalTarget cond = null; 120 if (target instanceof ConditionalTarget) 121 { 122 cond = (ConditionalTarget) target; 123 code.emitGoto(cond.ifTrue); 124 } 125 else 126 code.emitPushInt(1); 127 code.emitElse(); 128 if (cond != null) 129 code.emitGoto(cond.ifFalse); 130 else 131 code.emitPushInt(0); 132 code.emitFi(); 133 if (cond == null) 134 target.compileFromStack(comp, 135 comp.getLanguage().getTypeFor(Boolean.TYPE)); 136 } 137 } 138 | Popular Tags |