static ClassGenerator createInvokerClassGenerator( final String className, final InvokerDataProvider data, final CompositeClassLoader classLoader, final TypeResolver typeResolver) { final ClassGenerator generator = new ClassGenerator(className, classLoader, typeResolver) .addStaticField( ACC_PRIVATE + ACC_FINAL, "serialVersionUID", Long.TYPE, INVOKER_SERIAL_UID) .addDefaultConstructor(); generator .addMethod( ACC_PUBLIC, "hashCode", generator.methodDescr(Integer.TYPE), new ClassGenerator.MethodBody() { public void body(MethodVisitor mv) { push(data.hashCode()); mv.visitInsn(IRETURN); } }) .addMethod( ACC_PUBLIC, "getMethodBytecode", generator.methodDescr(List.class), new GetMethodBytecodeMethod(data)) .addMethod( ACC_PUBLIC, "equals", generator.methodDescr(Boolean.TYPE, Object.class), new EqualsMethod()); return generator; }
public String toString() { StringBuilder sb = new StringBuilder(); sb.append("\t"); if (jag.getVisibilityType() != null) { switch (jag.getVisibilityType()) { case PRIVATE: sb.append("private"); break; case PROTECTED: sb.append("protected"); break; case PUBLIC: sb.append("public"); break; } } else { sb.append("private"); } if (jag.isStatic()) { sb.append(" static"); } sb.append( " enum " + ClassGenerator.getName(jag.getOriginalName(), NamingSyntaxType.PASCAL, false) + " {"); int cnt = 0; for (String type : this.types) { if (cnt > 0) { sb.append(","); } sb.append( ClassGenerator.getName( "\n\t\t" + type, ClassGenerator.NamingSyntaxType.UPPERCASE, false)); cnt++; } // TODO: This should not be hard-coded into the Enum, but instead needs to be added as a // JavaAttributeGenerator attribute via API sb.append( ";\n\n\t\tpublic static final " + ClassGenerator.getName(jag.getOriginalName(), NamingSyntaxType.PASCAL, false) + "[] value = " + ClassGenerator.getName(jag.getOriginalName(), NamingSyntaxType.PASCAL, false) + ".values();\n\t}\n"); return sb.toString(); }
/** Translates an object of this type to its unboxed representation. */ public void translateUnBox(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); il.append(new CHECKCAST(cpg.addClass(INTEGER_CLASS))); final int index = cpg.addMethodref(INTEGER_CLASS, INT_VALUE, INT_VALUE_SIG); il.append(new INVOKEVIRTUAL(index)); }
/** * Translates an integer into the Java type denoted by <code>clazz</code>. Expects an integer on * the stack and pushes a number of the appropriate type after coercion. */ public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, Class clazz) { final InstructionList il = methodGen.getInstructionList(); if (clazz == Character.TYPE) { il.append(I2C); } else if (clazz == Byte.TYPE) { il.append(I2B); } else if (clazz == Short.TYPE) { il.append(I2S); } else if (clazz == Integer.TYPE) { il.append(NOP); } else if (clazz == Long.TYPE) { il.append(I2L); } else if (clazz == Float.TYPE) { il.append(I2F); } else if (clazz == Double.TYPE) { il.append(I2D); } // Is Double <: clazz? I.e. clazz in { Double, Number, Object } else if (clazz.isAssignableFrom(java.lang.Double.class)) { il.append(I2D); Type.Real.translateTo(classGen, methodGen, Type.Reference); } else { ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, toString(), clazz.getName()); classGen.getParser().reportError(Constants.FATAL, err); } }
private Class<?> generateClass(final CallStack callstack, final Interpreter interpreter) throws EvalError { int child = 0; // resolve superclass if any Class superClass = null; if (extend) { BSHAmbiguousName superNode = (BSHAmbiguousName) jjtGetChild(child++); superClass = superNode.toClass(callstack, interpreter); } // Get interfaces Class[] interfaces = new Class[numInterfaces]; for (int i = 0; i < numInterfaces; i++) { BSHAmbiguousName node = (BSHAmbiguousName) jjtGetChild(child++); interfaces[i] = node.toClass(callstack, interpreter); if (!interfaces[i].isInterface()) throw new EvalError("Type: " + node.text + " is not an interface!", this, callstack); } BSHBlock block; // Get the class body BSHBlock if (child < jjtGetNumChildren()) block = (BSHBlock) jjtGetChild(child); else block = new BSHBlock(ParserTreeConstants.JJTBLOCK); return ClassGenerator.getClassGenerator() .generateClass( name, modifiers, interfaces, superClass, block, isInterface, callstack, interpreter); }
public JavaClassGenerator(String name, String path, NamingSyntaxType type, String pkg) { super( name, path + System.getProperty("file.separator") + ClassGenerator.getClassName(name) + ".java", type); this.pkg = pkg; }
/** * Expects an integer on the stack and pushes a boxed integer. Boxed integers are represented by * an instance of <code>java.lang.Integer</code>. * * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo */ public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, ReferenceType type) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); il.append(new NEW(cpg.addClass(INTEGER_CLASS))); il.append(DUP_X1); il.append(SWAP); il.append(new INVOKESPECIAL(cpg.addMethodref(INTEGER_CLASS, "<init>", "(I)V"))); }
/** * Translates a void into an object of internal type <code>type</code>. This translation is needed * when calling external functions that return void. * * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo */ public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, Type type) { if (type == Type.String) { translateTo(classGen, methodGen, (StringType) type); } else { ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, toString(), type.toString()); classGen.getParser().reportError(Constants.FATAL, err); } }
/** * Expects an integer on the stack and pushes its string value by calling <code> * Integer.toString(int i)</code>. * * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo */ public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, StringType type) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); il.append(new INVOKESTATIC(cpg.addMethodref(INTEGER_CLASS, "toString", "(I)" + STRING_SIG))); }
public void addSubclass(JavaClassGenerator jcg) { super.addSubclass(); this.subclasses.add(jcg); }
public void addAttribute(JavaAttributeGenerator jag) { super.addAttribute(); this.attributes.add(jag); }
public JavaClassGenerator(String name, String path) { super( name, path + System.getProperty("file.separator") + ClassGenerator.getClassName(name) + ".java"); }
/** * Translates an external (primitive) Java type into a void. Only an external "void" can be * converted to this class. */ public void translateFrom(ClassGenerator classGen, MethodGenerator methodGen, Class clazz) { if (!clazz.getName().equals("void")) { ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR, toString(), clazz.getName()); classGen.getParser().reportError(Constants.FATAL, err); } }
/** * Translates a void into a string by pushing the empty string ''. * * @see org.apache.xalan.xsltc.compiler.util.Type#translateTo */ public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, StringType type) { final InstructionList il = methodGen.getInstructionList(); il.append(new PUSH(classGen.getConstantPool(), "")); }
public static void generate( final ReturnValueStub stub, final Tuple tuple, final Declaration[] previousDeclarations, final Declaration[] localDeclarations, final WorkingMemory workingMemory) { final LeftTuple leftTuple = (LeftTuple) tuple; final String[] globals = stub.getGlobals(); final String[] globalTypes = stub.getGlobalTypes(); // Sort declarations based on their offset, so it can ascend the tuple's parents stack only once final List<DeclarationMatcher> declarationMatchers = matchDeclarationsToTuple(previousDeclarations); final ClassGenerator generator = createInvokerClassGenerator(stub, workingMemory) .setInterfaces(ReturnValueExpression.class, CompiledInvoker.class); generator .addMethod( ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() { public void body(MethodVisitor mv) { mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); } }) .addMethod( ACC_PUBLIC, "replaceDeclaration", generator.methodDescr(null, Declaration.class, Declaration.class)) .addMethod( ACC_PUBLIC, "evaluate", generator.methodDescr( FieldValue.class, Object.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class), new String[] {"java/lang/Exception"}, new GeneratorHelper.EvaluateMethod() { public void body(MethodVisitor mv) { objAstorePos = 9; int[] previousDeclarationsParamsPos = new int[previousDeclarations.length]; mv.visitVarInsn(ALOAD, 2); cast(LeftTuple.class); mv.visitVarInsn(ASTORE, 7); // LeftTuple LeftTuple currentLeftTuple = leftTuple; for (DeclarationMatcher matcher : declarationMatchers) { int i = matcher.getOriginalIndex(); previousDeclarationsParamsPos[i] = objAstorePos; currentLeftTuple = traverseTuplesUntilDeclaration( currentLeftTuple, i, matcher.getRootDistance(), 3, 7, 8); mv.visitVarInsn(ALOAD, 3); push(i); mv.visitInsn(AALOAD); // declarations[i] mv.visitVarInsn(ALOAD, 5); // workingMemory mv.visitVarInsn(ALOAD, 7); invokeInterface(LeftTuple.class, "getHandle", InternalFactHandle.class); invokeInterface( InternalFactHandle.class, "getObject", Object.class); // tuple.getHandle().getObject() storeObjectFromDeclaration( previousDeclarations[i], previousDeclarations[i].getTypeName()); } int[] localDeclarationsParamsPos = parseDeclarations(localDeclarations, 4, 2, 5, false); // @{ruleClassName}.@{methodName}(@foreach{previousDeclarations}, // @foreach{localDeclarations}, @foreach{globals}) StringBuilder returnValueMethodDescr = new StringBuilder("("); for (int i = 0; i < previousDeclarations.length; i++) { load(previousDeclarationsParamsPos[i]); // previousDeclarations[i] returnValueMethodDescr.append(typeDescr(previousDeclarations[i].getTypeName())); } for (int i = 0; i < localDeclarations.length; i++) { load(localDeclarationsParamsPos[i]); // localDeclarations[i] returnValueMethodDescr.append(typeDescr(localDeclarations[i].getTypeName())); } // @foreach{type : globalTypes, identifier : globals} @{type} @{identifier} = ( // @{type} ) workingMemory.getGlobal( "@{identifier}" ); parseGlobals(globals, globalTypes, 5, returnValueMethodDescr); returnValueMethodDescr.append(")Lorg/drools/spi/FieldValue;"); mv.visitMethodInsn( INVOKESTATIC, stub.getInternalRuleClassName(), stub.getMethodName(), returnValueMethodDescr.toString()); mv.visitInsn(ARETURN); } }); stub.setReturnValue(generator.<ReturnValueExpression>newInstance()); }
protected byte[] createReturnValueBytecode( final RuleBuildContext ruleContext, final Map vars, final boolean readLocalsFromTuple) { final InvokerDataProvider data = new InvokerContext(vars); final ClassGenerator generator = createInvokerClassGenerator(data, ruleContext) .setInterfaces(ReturnValueExpression.class, CompiledInvoker.class); generator .addMethod( ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() { public void body(MethodVisitor mv) { mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); } }) .addMethod( ACC_PUBLIC, "replaceDeclaration", generator.methodDescr(null, Declaration.class, Declaration.class)) .addMethod( ACC_PUBLIC, "evaluate", generator.methodDescr( FieldValue.class, Object.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class), new String[] {"java/lang/Exception"}, new EvaluateMethod() { public void body(MethodVisitor mv) { final Declaration[] previousDeclarations = (Declaration[]) vars.get("declarations"); final String[] previousDeclarationTypes = (String[]) vars.get("declarationTypes"); final Declaration[] localDeclarations = (Declaration[]) vars.get("localDeclarations"); final String[] localDeclarationTypes = (String[]) vars.get("localDeclarationTypes"); final String[] globals = (String[]) vars.get("globals"); final String[] globalTypes = (String[]) vars.get("globalTypes"); objAstorePos = 7; int[] previousDeclarationsParamsPos = parseDeclarations( previousDeclarations, previousDeclarationTypes, 3, 2, 5, true); int[] localDeclarationsParamsPos = parseDeclarations( localDeclarations, localDeclarationTypes, 4, 2, 5, readLocalsFromTuple); // @{ruleClassName}.@{methodName}(@foreach{previousDeclarations}, // @foreach{localDeclarations}, @foreach{globals}) StringBuilder predicateMethodDescr = new StringBuilder("("); for (int i = 0; i < previousDeclarations.length; i++) { load(previousDeclarationsParamsPos[i]); // previousDeclarations[i] predicateMethodDescr.append(typeDescr(previousDeclarationTypes[i])); } for (int i = 0; i < localDeclarations.length; i++) { load(localDeclarationsParamsPos[i]); // localDeclarations[i] predicateMethodDescr.append(typeDescr(localDeclarationTypes[i])); } // @foreach{type : globalTypes, identifier : globals} @{type} @{identifier} = ( // @{type} ) workingMemory.getGlobal( "@{identifier}" ); parseGlobals(globals, globalTypes, 5, predicateMethodDescr); predicateMethodDescr.append(")Lorg/drools/spi/FieldValue;"); mv.visitMethodInsn( INVOKESTATIC, data.getInternalRuleClassName(), data.getMethodName(), predicateMethodDescr.toString()); mv.visitInsn(ARETURN); } }); return generator.generateBytecode(); }