Home | History | Annotate | Download | only in code
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      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  */
     16 package com.android.dx.cf.code;
     17 
     18 import com.android.dx.rop.cst.CstMethodHandle;
     19 import com.android.dx.rop.cst.CstType;
     20 import com.android.dx.util.FixedSizeList;
     21 
     22 /**
     23  * List of bootstrap method entries, which are the contents of
     24  * {@code BootstrapMethods} attributes.
     25  */
     26 public class BootstrapMethodsList extends FixedSizeList {
     27     /** {@code non-null;} zero-size instance */
     28     public static final BootstrapMethodsList EMPTY = new BootstrapMethodsList(0);
     29 
     30     /**
     31      * Constructs an instance.
     32      *
     33      * @param count the number of elements to be in the list
     34      */
     35     public BootstrapMethodsList(int count) {
     36         super(count);
     37     }
     38 
     39     /**
     40      * Gets the indicated item.
     41      *
     42      * @param n {@code >= 0;} which item
     43      * @return {@code null-ok;} the indicated item
     44      */
     45     public Item get(int n) {
     46         return (Item) get0(n);
     47     }
     48 
     49     /**
     50      * Sets the item at the given index.
     51      *
     52      * @param n {@code >= 0, < size();} which element
     53      * @param item {@code non-null;} the item
     54      */
     55     public void set(int n, Item item) {
     56         if (item == null) {
     57             throw new NullPointerException("item == null");
     58         }
     59 
     60         set0(n, item);
     61     }
     62 
     63     /**
     64      * Sets the item at the given index.
     65      *
     66      * @param n {@code >= 0, < size();} which element
     67      * @param declaringClass {@code non-null;} the class declaring bootstrap method.
     68      * @param bootstrapMethodHandle {@code non-null;} the bootstrap method handle
     69      * @param arguments {@code non-null;} the arguments of the bootstrap method
     70      */
     71     public void set(int n, CstType declaringClass, CstMethodHandle bootstrapMethodHandle,
     72                     BootstrapMethodArgumentsList arguments) {
     73         set(n, new Item(declaringClass, bootstrapMethodHandle, arguments));
     74     }
     75 
     76     /**
     77      * Returns an instance which is the concatenation of the two given
     78      * instances.
     79      *
     80      * @param list1 {@code non-null;} first instance
     81      * @param list2 {@code non-null;} second instance
     82      * @return {@code non-null;} combined instance
     83      */
     84     public static BootstrapMethodsList concat(BootstrapMethodsList list1,
     85                                               BootstrapMethodsList list2) {
     86         if (list1 == EMPTY) {
     87             return list2;
     88         } else if (list2 == EMPTY) {
     89             return list1;
     90         }
     91 
     92         int sz1 = list1.size();
     93         int sz2 = list2.size();
     94         BootstrapMethodsList result = new BootstrapMethodsList(sz1 + sz2);
     95 
     96         for (int i = 0; i < sz1; i++) {
     97             result.set(i, list1.get(i));
     98         }
     99 
    100         for (int i = 0; i < sz2; i++) {
    101             result.set(sz1 + i, list2.get(i));
    102         }
    103 
    104         return result;
    105     }
    106 
    107     public static class Item {
    108         private final BootstrapMethodArgumentsList bootstrapMethodArgumentsList;
    109         private final CstMethodHandle bootstrapMethodHandle;
    110         private final CstType declaringClass;
    111 
    112         public Item(CstType declaringClass, CstMethodHandle bootstrapMethodHandle,
    113                     BootstrapMethodArgumentsList bootstrapMethodArguments) {
    114             if (declaringClass == null) {
    115                 throw new NullPointerException("declaringClass == null");
    116             }
    117             if (bootstrapMethodHandle == null) {
    118                 throw new NullPointerException("bootstrapMethodHandle == null");
    119             }
    120             if (bootstrapMethodArguments == null) {
    121                 throw new NullPointerException("bootstrapMethodArguments == null");
    122             }
    123             this.bootstrapMethodHandle = bootstrapMethodHandle;
    124             this.bootstrapMethodArgumentsList = bootstrapMethodArguments;
    125             this.declaringClass = declaringClass;
    126         }
    127 
    128         public CstMethodHandle getBootstrapMethodHandle() {
    129             return bootstrapMethodHandle;
    130         }
    131 
    132         public BootstrapMethodArgumentsList getBootstrapMethodArguments() {
    133             return bootstrapMethodArgumentsList;
    134         }
    135 
    136         public CstType getDeclaringClass() {
    137             return declaringClass;
    138         }
    139     }
    140 }
    141