1 /*
   2  * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package vm.mlvm.cp.share;
  25 
  26 import jdk.internal.org.objectweb.asm.ClassWriter;
  27 import jdk.internal.org.objectweb.asm.ClassWriterExt;
  28 import jdk.internal.org.objectweb.asm.MethodVisitor;
  29 import jdk.internal.org.objectweb.asm.Opcodes;
  30 import jdk.internal.org.objectweb.asm.Handle;
  31 
  32 import vm.mlvm.share.ClassfileGenerator;
  33 import vm.mlvm.share.Env;
  34 
  35 public class GenCPFullOfMH extends GenFullCP {
  36 
  37     public static void main(String[] args) {
  38         ClassfileGenerator.main(args);
  39     }
  40 
  41     @Override
  42     protected void generateCommonData(ClassWriterExt cw) {
  43         cw.setCacheMHandles(false);
  44 
  45         cw.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
  46                 STATIC_FIELD_NAME,
  47                 STATIC_FIELD_SIGNATURE, null, false);
  48 
  49         cw.visitField(Opcodes.ACC_PUBLIC,
  50                 INSTANCE_FIELD_NAME,
  51                 INSTANCE_FIELD_SIGNATURE, null, false);
  52 
  53         createInitMethod(cw);
  54         createTargetMethod(cw);
  55 
  56         MethodVisitor mv = cw.visitMethod(
  57                 Opcodes.ACC_PUBLIC,
  58                 INSTANCE_TARGET_METHOD_NAME,
  59                 INSTANCE_TARGET_METHOD_SIGNATURE,
  60                 null,
  61                 new String[0]);
  62         finishMethodCode(mv);
  63     }
  64 
  65     @Override
  66     protected void generateCPEntryData(ClassWriter cw, MethodVisitor mw) {
  67         HandleType[] types = HandleType.values();
  68         HandleType type = types[Env.getRNG().nextInt(types.length)];
  69 
  70         switch (type) {
  71             case PUTFIELD:
  72             case PUTSTATIC:
  73                 mw.visitInsn(Opcodes.ICONST_0);
  74                 break;
  75             case INVOKESPECIAL:
  76             case INVOKEVIRTUAL:
  77             case INVOKEINTERFACE:
  78                 mw.visitInsn(Opcodes.ACONST_NULL);
  79                 break;
  80         }
  81 
  82         Handle handle;
  83         switch (type) {
  84             case GETFIELD:
  85             case PUTFIELD:
  86                 handle = new Handle(type.asmTag,
  87                         fullClassName,
  88                         INSTANCE_FIELD_NAME,
  89                         INSTANCE_FIELD_SIGNATURE);
  90                 break;
  91             case GETSTATIC:
  92             case PUTSTATIC:
  93                 handle = new Handle(type.asmTag,
  94                         fullClassName,
  95                         STATIC_FIELD_NAME,
  96                         STATIC_FIELD_SIGNATURE);
  97                 break;
  98             case NEWINVOKESPECIAL:
  99                 handle = new Handle(type.asmTag,
 100                         fullClassName,
 101                         INIT_METHOD_NAME,
 102                         INIT_METHOD_SIGNATURE);
 103                 break;
 104             case INVOKESTATIC:
 105                 handle = new Handle(type.asmTag,
 106                         fullClassName,
 107                         TARGET_METHOD_NAME,
 108                         TARGET_METHOD_SIGNATURE);
 109                 break;
 110             case INVOKEINTERFACE:
 111                 handle = new Handle(type.asmTag,
 112                         getDummyInterfaceClassName(),
 113                         INSTANCE_TARGET_METHOD_NAME,
 114                         INSTANCE_TARGET_METHOD_SIGNATURE);
 115                 break;
 116             case INVOKESPECIAL:
 117             case INVOKEVIRTUAL:
 118                 handle = new Handle(type.asmTag,
 119                         fullClassName,
 120                         INSTANCE_TARGET_METHOD_NAME,
 121                         INSTANCE_TARGET_METHOD_SIGNATURE);
 122                 break;
 123             default:
 124                 throw new Error("Unexpected handle type " + type);
 125         }
 126         mw.visitLdcInsn(handle);
 127 
 128         switch (type) {
 129             case GETFIELD:
 130             case GETSTATIC:
 131                 mw.visitInsn(Opcodes.POP);
 132                 break;
 133         }
 134     }
 135 }