001 /*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.jet.codegen.inline;
018
019 import org.jetbrains.asm4.AnnotationVisitor;
020 import org.jetbrains.asm4.Label;
021 import org.jetbrains.asm4.MethodVisitor;
022 import org.jetbrains.asm4.Opcodes;
023 import org.jetbrains.asm4.commons.InstructionAdapter;
024 import org.jetbrains.asm4.tree.FieldInsnNode;
025 import org.jetbrains.jet.codegen.StackValue;
026
027 public class RemapVisitor extends InstructionAdapter {
028
029 private final Label end;
030
031 private final LocalVarRemapper remapper;
032
033 private final boolean remapReturn;
034
035 private final FieldRemapper nodeRemapper;
036
037 private final InstructionAdapter instructionAdapter;
038
039 protected RemapVisitor(
040 MethodVisitor mv,
041 Label end,
042 LocalVarRemapper localVarRemapper,
043 boolean remapReturn,
044 FieldRemapper nodeRemapper
045 ) {
046 super(InlineCodegenUtil.API, mv);
047 this.instructionAdapter = new InstructionAdapter(mv);
048 this.end = end;
049 this.remapper = localVarRemapper;
050 this.remapReturn = remapReturn;
051 this.nodeRemapper = nodeRemapper;
052 }
053
054 @Override
055 public void visitInsn(int opcode) {
056 if (remapReturn && opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
057 super.visitJumpInsn(Opcodes.GOTO, end);
058 }
059 else {
060 super.visitInsn(opcode);
061 }
062 }
063
064 @Override
065 public void visitIincInsn(int var, int increment) {
066 remapper.visitIincInsn(var, increment, mv);
067 }
068
069 @Override
070 public void visitVarInsn(int opcode, int var) {
071 remapper.visitVarInsn(opcode, var, instructionAdapter);
072 }
073
074 @Override
075 public void visitLocalVariable(
076 String name, String desc, String signature, Label start, Label end, int index
077 ) {
078 remapper.visitLocalVariable(name, desc, signature, start, end, index, mv);
079 }
080
081 @Override
082 public void visitFieldInsn(int opcode, String owner, String name, String desc) {
083 if (name.startsWith("$$$")) {
084 if (nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot()) {
085 FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc);
086 StackValue inline = nodeRemapper.getFieldForInline(fin, null);
087 assert inline != null : "Captured field should have not null stackValue " + fin;
088 inline.put(inline.type, this);
089 }
090 else {
091 super.visitFieldInsn(opcode, owner, name, desc);
092 }
093 }
094 else {
095 super.visitFieldInsn(opcode, owner, name, desc);
096 }
097 }
098
099 @Override
100 public AnnotationVisitor visitAnnotationDefault() {
101 return null;
102 }
103
104 @Override
105 public void visitMaxs(int maxStack, int maxLocals) {
106
107 }
108
109 @Override
110 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
111 return null;
112 }
113
114 @Override
115 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
116 return null;
117 }
118
119 }