/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2010. */ package x10.compiler.ws.codegen; import java.util.Collections; import java.util.List; import polyglot.ast.Expr; import polyglot.ast.Stmt; import polyglot.types.ClassType; import polyglot.types.Flags; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.Types; import x10.ast.Finish; import x10.ast.FinishExpr; import x10.compiler.ws.util.TransCodes; import x10.compiler.ws.util.WSUtil; import x10.types.ConstrainedType; import x10.types.X10ParsedClassType; import x10.util.synthesizer.CodeBlockSynth; import x10.util.synthesizer.InstanceCallSynth; import x10.util.synthesizer.SuperCallSynth; import x10.util.synthesizer.SwitchSynth; /** * @author Haichuan * * Transform a finish stmt to a inner class * */ public class WSFinishStmtClassGen extends AbstractWSClassGen { Type reducerBaseType; //only used for collecting-finish frame boolean isCollectingFinishFrame; //For FinishStmt public WSFinishStmtClassGen(AbstractWSClassGen parent, Finish finishStmt) { super(parent, parent, WSUtil.getFinishStmtClassName(parent.getClassName()), parent.xts.FinishFrame(), finishStmt.body()); if(!wts.OPT_PC_FIELD){ wsynth.createPCField(classSynth); } } //For FinishExpr public WSFinishStmtClassGen(AbstractWSClassGen parent, Type reducerBaseType, FinishExpr finishExpr) { super(parent, parent, WSUtil.getFinishStmtClassName(parent.getClassName()), parent.xts.CollectingFinish().typeArguments(Collections.singletonList(reducerBaseType)), finishExpr.body()); if(!wts.OPT_PC_FIELD){ wsynth.createPCField(classSynth); } //now start extract the collecting finish's type. this.reducerBaseType = reducerBaseType; assert(reducerBaseType != null); isCollectingFinishFrame = true; } protected void genClassConstructor() throws SemanticException { if(isCollectingFinishFrame){ wsynth.genClassConstructorType3Base(classSynth, getReducerBaseType()); } else{ wsynth.genClassConstructorType1Base(classSynth); } } public Type getReducerBaseType() { return reducerBaseType; } @Override protected void genMethods() throws SemanticException { CodeBlockSynth fastBodySynth = fastMSynth.getMethodBodySynth(compilerPos); AbstractWSClassGen childFrameGen = genChildFrame(xts.RegularFrame(), codeBlock, WSUtil.getBlockFrameClassName(getClassName())); List<Stmt> fastCallCodes = wsynth.genInvocateFrameStmts(1, classSynth, fastMSynth, childFrameGen); if(wts.DISABLE_EXCEPTION_HANDLE){ fastBodySynth.addStmts(fastCallCodes); } else{ fastBodySynth.addStmt(wsynth.genExceptionHandler(fastCallCodes, classSynth)); fastBodySynth.addStmt(wsynth.genRethrowStmt(classSynth)); } //resume/back path if(!wts.OPT_PC_FIELD){ Expr pcRef = wsynth.genPCRef(classSynth); CodeBlockSynth resumeBodySynth = resumeMSynth.getMethodBodySynth(compilerPos); SwitchSynth resumeSwitchSynth = resumeBodySynth.createSwitchStmt(compilerPos, pcRef); List<Stmt> resumeCallCodes = wsynth.genInvocateFrameStmts(1, classSynth, resumeMSynth, childFrameGen); if(wts.DISABLE_EXCEPTION_HANDLE){ resumeSwitchSynth.insertStatementsInCondition(0, resumeCallCodes); } else{ resumeSwitchSynth.insertStatementInCondition(0, wsynth.genExceptionHandler(resumeCallCodes, classSynth)); resumeSwitchSynth.insertStatementInCondition(0, wsynth.genRethrowStmt(classSynth)); } } } }