/** * @see * railo.transformer.bytecode.statement.StatementBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter) */ public void _writeOut(BytecodeContext bc) throws BytecodeException { GeneratorAdapter adapter = bc.getAdapter(); adapter.visitLabel(begin); // Reference ref=null; final int lRef = adapter.newLocal(Types.REFERENCE); adapter.visitInsn(Opcodes.ACONST_NULL); adapter.storeLocal(lRef); // has no try body, if there is no try body, no catches are executed, only finally if (!tryBody.hasStatements()) { if (finallyBody != null) finallyBody.writeOut(bc); return; } TryCatchFinallyVisitor tcfv = new TryCatchFinallyVisitor( new OnFinally() { public void writeOut(BytecodeContext bc) throws BytecodeException { _writeOutFinally(bc, lRef); } }, getFlowControlFinal()); // try tcfv.visitTryBegin(bc); tryBody.writeOut(bc); int lThrow = tcfv.visitTryEndCatchBeging(bc); _writeOutCatch(bc, lRef, lThrow); tcfv.visitCatchEnd(bc); }
@Override public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { int form = VALUE; int type = STRING; if (name instanceof Variable && !((Variable) name).fromHash()) { GeneratorAdapter adapter = bc.getAdapter(); String[] arr = VariableString.variableToStringArray((Variable) name, true); if (arr.length > 1) { form = ARRAY; ArrayVisitor av = new ArrayVisitor(); av.visitBegin(adapter, Types.STRING, arr.length); for (int y = 0; y < arr.length; y++) { av.visitBeginItem(adapter, y); adapter.push(varKeyUpperCase ? arr[y].toUpperCase() : arr[y]); av.visitEndItem(bc.getAdapter()); } av.visitEnd(); } else { // VariableString.toExprString(name).writeOut(bc, MODE_REF); String str = VariableString.variableToString((Variable) name, true); name = LitString.toExprString(varKeyUpperCase ? str.toUpperCase() : str); type = Variable.registerKey(bc, VariableString.toExprString(name)) ? KEY : STRING; } } else { // CastString.toExprString(name).writeOut(bc, MODE_REF); type = Variable.registerKey(bc, CastString.toExprString(name)) ? KEY : STRING; } // name.writeOut(bc, MODE_REF); super._writeOut(bc, MODE_REF); // bc.getAdapter().push(variableString); bc.getAdapter().invokeStatic(TYPE_FUNCTION_VALUE, NEW_INSTANCE[type][form]); return Types.FUNCTION_VALUE; }
private void forUpdate(GeneratorAdapter adapter, int step, boolean isLocal) { if (isLocal) { adapter.visitVarInsn(ILOAD, i); adapter.loadLocal(step); adapter.visitInsn(IADD); adapter.visitVarInsn(ISTORE, i); } else adapter.visitIincInsn(i, step); }
private void _writeOutFinally(BytecodeContext bc, int lRef) throws BytecodeException { // ref.remove(pc); // Reference r=null; GeneratorAdapter adapter = bc.getAdapter(); // if(fcf!=null && // fcf.getAfterFinalGOTOLabel()!=null)ASMUtil.visitLabel(adapter,fcf.getFinalEntryLabel()); ExpressionUtil.visitLine(bc, finallyLine); // if (reference != null) // reference.removeEL(pagecontext); Label removeEnd = new Label(); adapter.loadLocal(lRef); adapter.ifNull(removeEnd); adapter.loadLocal(lRef); adapter.loadArg(0); adapter.invokeInterface(Types.REFERENCE, REMOVE_EL); adapter.pop(); adapter.visitLabel(removeEnd); if (finallyBody != null) finallyBody.writeOut(bc); // finally /*if(fcf!=null){ Label l = fcf.getAfterFinalGOTOLabel(); if(l!=null)adapter.visitJumpInsn(Opcodes.GOTO, l); }*/ }
public int visitBeforeExpression(GeneratorAdapter adapter, int start, int step, boolean isLocal) { // init adapter.visitLabel(beforeInit); forInit(adapter, start, isLocal); adapter.goTo(beforeExpr); // update adapter.visitLabel(beforeUpdate); forUpdate(adapter, step, isLocal); // expression adapter.visitLabel(beforeExpr); return i; }
public static void leadFlow(BytecodeContext bc, Statement stat, int flowType, String label) throws BytecodeException { List<FlowControlFinal> finallyLabels = new ArrayList<FlowControlFinal>(); FlowControl fc; String name; if (FlowControl.BREAK == flowType) { fc = ASMUtil.getAncestorBreakFCStatement(stat, finallyLabels, label); name = "break"; } else if (FlowControl.CONTINUE == flowType) { fc = ASMUtil.getAncestorContinueFCStatement(stat, finallyLabels, label); name = "continue"; } else { fc = ASMUtil.getAncestorRetryFCStatement(stat, finallyLabels, label); name = "retry"; } if (fc == null) throw new BytecodeException( name + " must be inside a loop (for,while,do-while,<cfloop>,<cfwhile> ...)", stat.getStart()); GeneratorAdapter adapter = bc.getAdapter(); Label end; if (FlowControl.BREAK == flowType) end = ((FlowControlBreak) fc).getBreakLabel(); else if (FlowControl.CONTINUE == flowType) end = ((FlowControlContinue) fc).getContinueLabel(); else end = ((FlowControlRetry) fc).getRetryLabel(); // first jump to all final labels FlowControlFinal[] arr = finallyLabels.toArray(new FlowControlFinal[finallyLabels.size()]); if (arr.length > 0) { FlowControlFinal fcf; for (int i = 0; i < arr.length; i++) { fcf = arr[i]; // first if (i == 0) { adapter.visitJumpInsn(Opcodes.GOTO, fcf.getFinalEntryLabel()); } // last if (arr.length == i + 1) fcf.setAfterFinalGOTOLabel(end); else fcf.setAfterFinalGOTOLabel(arr[i + 1].getFinalEntryLabel()); } } else bc.getAdapter().visitJumpInsn(Opcodes.GOTO, end); }
private static byte[] visitEnd() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, RubyIDClassName, null, "java/lang/Object", null); Method staticBlock = Method.getMethod("void <clinit> ()V"); GeneratorAdapter staticBlockMg = new GeneratorAdapter(Opcodes.ACC_STATIC, staticBlock, null, null, cw); for (Map.Entry<String, String> e : idMap.entrySet()) { cw.visitField( Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, e.getValue(), Types.RUBY_ID_TYPE.getDescriptor(), null, null); staticBlockMg.push(e.getKey()); staticBlockMg.invokeStatic( Type.getType(RubyID.class), Method.getMethod("com.xruby.runtime.lang.RubyID intern(String)")); staticBlockMg.putStatic( Type.getType("L" + RubyIDClassName + ";"), e.getValue(), Types.RUBY_ID_TYPE); } staticBlockMg.returnValue(); staticBlockMg.endMethod(); cw.visitEnd(); return cw.toByteArray(); }
public static void getField(GeneratorAdapter mg, String s) { String id = idMap.get(s); if (id == null) { if (isValidJavaID(s)) { id = s + "ID"; } else { id = nextID(); } idMap.put(s, id); } mg.getStatic(Type.getType("L" + RubyIDClassName + ";"), id, Types.RUBY_ID_TYPE); }
/** * @see * lucee.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, * int) */ @Override public Type _writeOut(BytecodeContext bc, int mode) throws TransformerException { GeneratorAdapter adapter = bc.getAdapter(); if (mode == MODE_REF) { _writeOut(bc, MODE_VALUE); adapter.invokeStatic(Types.CASTER, Methods.METHOD_TO_BOOLEAN_FROM_BOOLEAN); return Types.BOOLEAN; } Label l1 = new Label(); Label l2 = new Label(); expr.writeOut(bc, MODE_VALUE); adapter.ifZCmp(Opcodes.IFEQ, l1); adapter.visitInsn(Opcodes.ICONST_0); adapter.visitJumpInsn(Opcodes.GOTO, l2); adapter.visitLabel(l1); adapter.visitInsn(Opcodes.ICONST_1); adapter.visitLabel(l2); return Types.BOOLEAN_VALUE; }
private void forInit(GeneratorAdapter adapter, int start, boolean isLocal) { i = adapter.newLocal(Types.INT_VALUE); if (isLocal) adapter.loadLocal(start, Types.INT_VALUE); else adapter.push(start); adapter.visitVarInsn(ISTORE, i); }
public void visitAfterExpressionBeginBody(GeneratorAdapter adapter) { adapter.ifZCmp(Opcodes.IFEQ, afterBody); }
public static void createEmptyArray(GeneratorAdapter adapter) { adapter.newInstance(Types.ARRAY_IMPL); adapter.dup(); adapter.invokeConstructor(Types.ARRAY_IMPL, Switch.INIT); }
@Override void write( final CompilerSettings settings, final Definition definition, final GeneratorAdapter adapter) { final Sort sort = actual.sort; switch (sort) { case STRING: adapter.push((String) constant); break; case DOUBLE: adapter.push((double) constant); break; case FLOAT: adapter.push((float) constant); break; case LONG: adapter.push((long) constant); break; case INT: adapter.push((int) constant); break; case CHAR: adapter.push((char) constant); break; case SHORT: adapter.push((short) constant); break; case BYTE: adapter.push((byte) constant); break; case BOOL: if (tru != null && (boolean) constant) { adapter.goTo(tru); } else if (fals != null && !(boolean) constant) { adapter.goTo(fals); } else if (tru == null && fals == null) { adapter.push((boolean) constant); } break; default: throw new IllegalStateException(error("Illegal tree structure.")); } if (sort != Sort.BOOL) { WriterUtility.writeBranch(adapter, tru, fals); } }
public static void visitLabel(GeneratorAdapter ga, Label label) { if (label != null) ga.visitLabel(label); }
public static void pop(GeneratorAdapter adapter, Type type) { if (type.equals(Types.DOUBLE_VALUE)) adapter.pop2(); else if (type.equals(Types.VOID)) ; else adapter.pop(); }
/** * @param adapter * @param expr * @param mode */ public static void pop(GeneratorAdapter adapter, Expression expr, int mode) { if (mode == Expression.MODE_VALUE && (expr instanceof ExprDouble)) adapter.pop2(); else adapter.pop(); }
private static void createProperty(ClassWriter cw, String classType, ASMProperty property) throws PageException { String name = property.getName(); Type type = property.getASMType(); Class clazz = property.getClazz(); cw.visitField(Opcodes.ACC_PRIVATE, name, type.toString(), null, null).visitEnd(); int load = loadFor(type); // int sizeOf=sizeOf(type); // get<PropertyName>():<type> Type[] types = new Type[0]; Method method = new Method( (clazz == boolean.class ? "get" : "get") + StringUtil.ucFirst(name), type, types); GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC, method, null, null, cw); Label start = new Label(); adapter.visitLabel(start); adapter.visitVarInsn(Opcodes.ALOAD, 0); adapter.visitFieldInsn(Opcodes.GETFIELD, classType, name, type.toString()); adapter.returnValue(); Label end = new Label(); adapter.visitLabel(end); adapter.visitLocalVariable("this", "L" + classType + ";", null, start, end, 0); adapter.visitEnd(); adapter.endMethod(); // set<PropertyName>(object):void types = new Type[] {type}; method = new Method("set" + StringUtil.ucFirst(name), Types.VOID, types); adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC, method, null, null, cw); start = new Label(); adapter.visitLabel(start); adapter.visitVarInsn(Opcodes.ALOAD, 0); adapter.visitVarInsn(load, 1); adapter.visitFieldInsn(Opcodes.PUTFIELD, classType, name, type.toString()); adapter.visitInsn(Opcodes.RETURN); end = new Label(); adapter.visitLabel(end); adapter.visitLocalVariable("this", "L" + classType + ";", null, start, end, 0); adapter.visitLocalVariable(name, type.toString(), null, start, end, 1); // adapter.visitMaxs(0, 0);//.visitMaxs(sizeOf+1, sizeOf+1);// hansx adapter.visitEnd(); adapter.endMethod(); }
public static byte[] createPojo( String className, ASMProperty[] properties, Class parent, Class[] interfaces, String srcName) throws PageException { className = className.replace('.', '/'); className = className.replace('\\', '/'); className = ListUtil.trim(className, "/"); String[] inter = null; if (interfaces != null) { inter = new String[interfaces.length]; for (int i = 0; i < inter.length; i++) { inter[i] = interfaces[i].getName().replace('.', '/'); } } // CREATE CLASS ClassWriter cw = ASMUtil.getClassWriter(); cw.visit( Opcodes.V1_6, Opcodes.ACC_PUBLIC, className, null, parent.getName().replace('.', '/'), inter); String md5; try { md5 = createMD5(properties); } catch (Throwable t) { md5 = ""; t.printStackTrace(); } FieldVisitor fv = cw.visitField( Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "_md5_", "Ljava/lang/String;", null, md5); fv.visitEnd(); // Constructor GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ACC_PUBLIC, CONSTRUCTOR_OBJECT, null, null, cw); adapter.loadThis(); adapter.invokeConstructor(toType(parent, true), CONSTRUCTOR_OBJECT); adapter.returnValue(); adapter.endMethod(); // properties for (int i = 0; i < properties.length; i++) { createProperty(cw, className, properties[i]); } // complexType src if (!StringUtil.isEmpty(srcName)) { GeneratorAdapter _adapter = new GeneratorAdapter( Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, _SRC_NAME, null, null, cw); _adapter.push(srcName); _adapter.returnValue(); _adapter.endMethod(); } cw.visitEnd(); return cw.toByteArray(); }
public static void invokeMethod(GeneratorAdapter adapter, Type type, Method method) { if (type.getClass().isInterface()) adapter.invokeInterface(type, method); else adapter.invokeVirtual(type, method); }
@Override public Type load(Context ctx) { GeneratorAdapter g = ctx.getGeneratorAdapter(); owner.load(ctx); List<Class<?>> argumentClasses = new ArrayList<>(); List<Type> argumentTypes = new ArrayList<>(); for (Expression argument : arguments) { argument.load(ctx); argumentTypes.add(argument.type(ctx)); argumentClasses.add(getJavaType(ctx.getClassLoader(), argument.type(ctx))); } Type returnType; try { if (ctx.getThisType().equals(owner.type(ctx))) { org.objectweb.asm.commons.Method method = null; for (org.objectweb.asm.commons.Method m : ctx.getMethods().keySet()) { if (m.getName().equals(methodName)) { if (m.getArgumentTypes().length == arguments.size()) { Type[] methodTypes = m.getArgumentTypes(); boolean isSame = true; for (int i = 0; i < arguments.size(); i++) { if (!methodTypes[i].equals(argumentTypes.get(i))) { isSame = false; break; } } if (isSame) { method = m; break; } } } } if (method == null) throw new NoSuchMethodException(); g.invokeVirtual(owner.type(ctx), method); return method.getReturnType(); } Class<?> ownerJavaType = getJavaType(ctx.getClassLoader(), owner.type(ctx)); Method method = ownerJavaType.getMethod(methodName, argumentClasses.toArray(new Class<?>[] {})); Class<?> returnClass = method.getReturnType(); returnType = getType(returnClass); invokeVirtualOrInterface( g, ownerJavaType, new org.objectweb.asm.commons.Method( methodName, returnType, argumentTypes.toArray(new Type[] {}))); } catch (NoSuchMethodException e) { throw new RuntimeException( format( "No method %s.%s(%s). %s", owner.type(ctx).getClassName(), methodName, (!argumentClasses.isEmpty() ? argsToString(argumentClasses) : ""), exceptionInGeneratedClass(ctx))); } return returnType; }
public static Type invokeScope(GeneratorAdapter adapter, Method m, Type type) { if (type == null) type = Types.PAGE_CONTEXT; adapter.invokeVirtual(type, m); return m.getReturnType(); }
private void _writeOutCatch(BytecodeContext bc, int lRef, int lThrow) throws BytecodeException { GeneratorAdapter adapter = bc.getAdapter(); int pe = adapter.newLocal(Types.PAGE_EXCEPTION); // instance of Abort Label abortEnd = new Label(); adapter.loadLocal(lThrow); adapter.invokeStatic(Types.ABORT, TryCatchFinally.IS_ABORT); // adapter.instanceOf(Types.ABORT); adapter.ifZCmp(Opcodes.IFEQ, abortEnd); adapter.loadLocal(lThrow); adapter.throwException(); adapter.visitLabel(abortEnd); // PageExceptionImpl old=pc.getCatch(); int old = adapter.newLocal(Types.PAGE_EXCEPTION); adapter.loadArg(0); adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.GET_CATCH); adapter.storeLocal(old); // cast to PageException Caster.toPagException(t); adapter.loadLocal(lThrow); adapter.invokeStatic(Types.CASTER, TO_PAGE_EXCEPTION); // PageException pe=... adapter.storeLocal(pe); // catch loop Label endAllIf = new Label(); Iterator<Catch> it = catches.iterator(); Catch ctElse = null; while (it.hasNext()) { Catch ct = it.next(); // store any for else if (ct.type != null && ct.type instanceof LitString && ((LitString) ct.type).getString().equalsIgnoreCase("any")) { ctElse = ct; continue; } ExpressionUtil.visitLine(bc, ct.line); // pe.typeEqual(type) if (ct.type == null) { LitBoolean.TRUE.writeOut(bc, Expression.MODE_VALUE); } else { adapter.loadLocal(pe); ct.type.writeOut(bc, Expression.MODE_REF); adapter.invokeVirtual(Types.PAGE_EXCEPTION, TYPE_EQUAL); } Label endIf = new Label(); adapter.ifZCmp(Opcodes.IFEQ, endIf); catchBody(bc, adapter, ct, pe, lRef, true, true); adapter.visitJumpInsn(Opcodes.GOTO, endAllIf); adapter.visitLabel(endIf); } if (ctElse != null) { catchBody(bc, adapter, ctElse, pe, lRef, true, true); } else { // pc.setCatch(pe,true); adapter.loadArg(0); adapter.loadLocal(pe); adapter.push(false); adapter.push(false); adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.SET_CATCH3); adapter.loadLocal(pe); adapter.throwException(); } adapter.visitLabel(endAllIf); // PageExceptionImpl old=pc.setCatch(old); adapter.loadArg(0); adapter.loadLocal(old); adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.SET_CATCH_PE); }
public static void main(final String args[]) throws Exception { // Generates the bytecode corresponding to the following Java class: // // public class Example { // public static void main (String[] args) { // System.out.println("Hello world!"); // } // } // creates a ClassWriter for the Example public class, // which inherits from Object ClassWriter cw = new ClassWriter(0); cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null); // creates a MethodWriter for the (implicit) constructor MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); // pushes the 'this' variable mw.visitVarInsn(ALOAD, 0); // invokes the super class constructor mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mw.visitInsn(RETURN); // this code uses a maximum of one stack element and one local variable mw.visitMaxs(1, 1); mw.visitEnd(); // creates a MethodWriter for the 'main' method mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); // pushes the 'out' field (of type PrintStream) of the System class mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // pushes the "Hello World!" String constant mw.visitLdcInsn("Hello world!"); // invokes the 'println' method (defined in the PrintStream class) mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); mw.visitInsn(RETURN); // this code uses a maximum of two stack elements and two local // variables mw.visitMaxs(2, 2); mw.visitEnd(); // gets the bytecode of the Example class, and loads it dynamically byte[] code = cw.toByteArray(); FileOutputStream fos = new FileOutputStream("Example.class"); fos.write(code); fos.close(); Helloworld loader = new Helloworld(); Class<?> exampleClass = loader.defineClass("Example", code, 0, code.length); // uses the dynamically generated class to print 'Helloworld' exampleClass.getMethods()[0].invoke(null, new Object[] {null}); // ------------------------------------------------------------------------ // Same example with a GeneratorAdapter (more convenient but slower) // ------------------------------------------------------------------------ cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null); // creates a GeneratorAdapter for the (implicit) constructor Method m = Method.getMethod("void <init> ()"); GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw); mg.loadThis(); mg.invokeConstructor(Type.getType(Object.class), m); mg.returnValue(); mg.endMethod(); // creates a GeneratorAdapter for the 'main' method m = Method.getMethod("void main (String[])"); mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw); mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class)); mg.push("Hello world!"); mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println (String)")); mg.returnValue(); mg.endMethod(); cw.visitEnd(); code = cw.toByteArray(); loader = new Helloworld(); exampleClass = loader.defineClass("Example", code, 0, code.length); // uses the dynamically generated class to print 'Helloworld' exampleClass.getMethods()[0].invoke(null, new Object[] {null}); }
private static void catchBody( BytecodeContext bc, GeneratorAdapter adapter, Catch ct, int pe, int lRef, boolean caugth, boolean store) throws BytecodeException { // pc.setCatch(pe,true); adapter.loadArg(0); adapter.loadLocal(pe); adapter.push(caugth); adapter.push(store); adapter.invokeVirtual(Types.PAGE_CONTEXT, TagTry.SET_CATCH3); // ref= ct.name.writeOut(bc, Expression.MODE_REF); adapter.storeLocal(lRef); adapter.loadLocal(lRef); adapter.loadArg(0); adapter.loadLocal(pe); // (...,pe.getCatchBlock(pc)) adapter.loadArg(0); adapter.invokeVirtual(Types.PAGE_EXCEPTION, GET_CATCH_BLOCK); adapter.invokeInterface(Types.REFERENCE, SET); adapter.pop(); ct.body.writeOut(bc); }
@Override public void compile(GeneratorAdapter ga, int narg) { ga.push(value); }
public static void createEmptyStruct(GeneratorAdapter adapter) { adapter.newInstance(Types.STRUCT_IMPL); adapter.dup(); adapter.invokeConstructor(Types.STRUCT_IMPL, Page.INIT_STRUCT_IMPL); }