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; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.asm4.MethodVisitor; 022 import org.jetbrains.jet.codegen.context.MethodContext; 023 import org.jetbrains.jet.codegen.signature.JvmMethodSignature; 024 import org.jetbrains.jet.codegen.state.GenerationState; 025 import org.jetbrains.jet.codegen.state.JetTypeMapper; 026 import org.jetbrains.jet.lang.descriptors.CallableDescriptor; 027 import org.jetbrains.jet.lang.psi.JetDeclarationWithBody; 028 029 public abstract class FunctionGenerationStrategy { 030 031 private FrameMap frameMap; 032 033 public abstract void generateBody( 034 @NotNull MethodVisitor mv, 035 @NotNull JvmMethodSignature signature, 036 @NotNull MethodContext context, 037 @Nullable MemberCodegen parentCodegen 038 ); 039 040 @NotNull 041 protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) { 042 return context.prepareFrame(typeMapper); 043 } 044 045 @NotNull 046 public FrameMap getFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) { 047 if (frameMap == null) { 048 frameMap = createFrameMap(typeMapper, context); 049 } 050 return frameMap; 051 } 052 053 public boolean generateLocalVarTable() { 054 return true; 055 } 056 057 public static class FunctionDefault extends CodegenBased<CallableDescriptor> { 058 private final JetDeclarationWithBody declaration; 059 060 public FunctionDefault( 061 @NotNull GenerationState state, 062 @NotNull CallableDescriptor descriptor, 063 @NotNull JetDeclarationWithBody declaration 064 ) { 065 super(state, descriptor); 066 this.declaration = declaration; 067 } 068 069 @Override 070 public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) { 071 codegen.returnExpression(declaration.getBodyExpression()); 072 } 073 } 074 075 public abstract static class CodegenBased<T extends CallableDescriptor> extends FunctionGenerationStrategy { 076 protected final GenerationState state; 077 protected final T callableDescriptor; 078 079 public CodegenBased(@NotNull GenerationState state, @NotNull T callableDescriptor) { 080 this.state = state; 081 this.callableDescriptor = callableDescriptor; 082 } 083 084 @Override 085 public final void generateBody( 086 @NotNull MethodVisitor mv, 087 @NotNull JvmMethodSignature signature, 088 @NotNull MethodContext context, 089 @Nullable MemberCodegen parentCodegen 090 ) { 091 ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context), 092 signature.getReturnType(), context, state, parentCodegen); 093 doGenerateBody(codegen, signature); 094 } 095 096 public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature); 097 } 098 }