ParallelSorterEmitter.java revision 674060f01e9090cd21b3c5656cc3204912ad17a6
1/* 2 * Copyright 2003 The Apache Software Foundation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package org.mockito.cglib.util; 17 18import java.lang.reflect.Method; 19import java.lang.reflect.Modifier; 20 21import org.mockito.asm.ClassVisitor; 22import org.mockito.asm.Type; 23import org.mockito.cglib.core.*; 24 25class ParallelSorterEmitter extends ClassEmitter { 26 private static final Type PARALLEL_SORTER = 27 TypeUtils.parseType("org.mockito.cglib.util.ParallelSorter"); 28 private static final Signature CSTRUCT_OBJECT_ARRAY = 29 TypeUtils.parseConstructor("Object[]"); 30 private static final Signature NEW_INSTANCE = 31 new Signature("newInstance", PARALLEL_SORTER, new Type[]{ Constants.TYPE_OBJECT_ARRAY }); 32 private static final Signature SWAP = 33 TypeUtils.parseSignature("void swap(int, int)"); 34 35 public ParallelSorterEmitter(ClassVisitor v, String className, Object[] arrays) { 36 super(v); 37 begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, PARALLEL_SORTER, null, Constants.SOURCE_FILE); 38 EmitUtils.null_constructor(this); 39 EmitUtils.factory_method(this, NEW_INSTANCE); 40 generateConstructor(arrays); 41 generateSwap(arrays); 42 end_class(); 43 } 44 45 private String getFieldName(int index) { 46 return "FIELD_" + index; 47 } 48 49 private void generateConstructor(Object[] arrays) { 50 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null); 51 e.load_this(); 52 e.super_invoke_constructor(); 53 e.load_this(); 54 e.load_arg(0); 55 e.super_putfield("a", Constants.TYPE_OBJECT_ARRAY); 56 for (int i = 0; i < arrays.length; i++) { 57 Type type = Type.getType(arrays[i].getClass()); 58 declare_field(Constants.ACC_PRIVATE, getFieldName(i), type, null); 59 e.load_this(); 60 e.load_arg(0); 61 e.push(i); 62 e.aaload(); 63 e.checkcast(type); 64 e.putfield(getFieldName(i)); 65 } 66 e.return_value(); 67 e.end_method(); 68 } 69 70 private void generateSwap(final Object[] arrays) { 71 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SWAP, null); 72 for (int i = 0; i < arrays.length; i++) { 73 Type type = Type.getType(arrays[i].getClass()); 74 Type component = TypeUtils.getComponentType(type); 75 Local T = e.make_local(type); 76 77 e.load_this(); 78 e.getfield(getFieldName(i)); 79 e.store_local(T); 80 81 e.load_local(T); 82 e.load_arg(0); 83 84 e.load_local(T); 85 e.load_arg(1); 86 e.array_load(component); 87 88 e.load_local(T); 89 e.load_arg(1); 90 91 e.load_local(T); 92 e.load_arg(0); 93 e.array_load(component); 94 95 e.array_store(component); 96 e.array_store(component); 97 } 98 e.return_value(); 99 e.end_method(); 100 } 101} 102