/*
* 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.ArrayList;
import java.util.Collections;
import java.util.List;
import polyglot.ast.Assign;
import polyglot.ast.Binary;
import polyglot.ast.Call;
import polyglot.ast.Expr;
import polyglot.ast.Formal;
import polyglot.ast.If;
import polyglot.ast.Local;
import polyglot.ast.Stmt;
import polyglot.types.ClassType;
import polyglot.types.Flags;
import polyglot.types.Name;
import polyglot.types.SemanticException;
import polyglot.types.Type;
import polyglot.util.Pair;
import x10.ast.AtStmt;
import x10.ast.When;
import x10.compiler.ws.util.AddIndirectLocalDeclareVisitor;
import x10.compiler.ws.util.ClosureDefReinstantiator;
import x10.compiler.ws.util.Triple;
import x10.compiler.ws.util.WSUtil;
import x10.util.synthesizer.CodeBlockSynth;
import x10.util.synthesizer.ConstructorSynth;
import x10.util.synthesizer.InstanceCallSynth;
import x10.util.synthesizer.MethodSynth;
import x10.util.synthesizer.NewLocalVarSynth;
import x10.util.synthesizer.SwitchSynth;
/**
* @author Haichuan
*
* Generate the remote main frame class
* It is used to express at(p) S and async at(p) S
*
*/
public class WSRemoteMainFrameClassGen extends WSRegularFrameClassGen {
protected final AbstractWSClassGen parentR; //it's a remote parent, cannot accessed directly
protected final AtStmt atStmt;
protected final List<Pair<Name,Type>> formals; //the formals are not real formals, but local var copied from parent frames;
public WSRemoteMainFrameClassGen(AbstractWSClassGen parent, AtStmt atStmt) {
super(parent, null, //up frame is null
atStmt.body(),
WSUtil.getRemoteRemoteClassName(parent.getClassName()), parent.xts.RegularFrame());
this.atStmt = atStmt;
this.parentR = parent; //the parent is not the real parent
formals = new ArrayList<Pair<Name, Type>>();
}
public Expr getPlace(){
return atStmt.place();
}
/**
* This method will be called by localvartofieldaccess replacer
* If a local var is found in remote main frame, but defined above outside it
* it should be copied into the remote frame as a formal
*
* And it should be called in case of "at(p)S" to add the flag as one formal
*
* For a local var, it should be called only once. This is enforced by the cache in localvartofieldaccess
* @param name
* @param type
*/
protected void addFormal(Name name, Type type){
formals.add(new Pair<Name, Type>(name, type));
//now create a field
classSynth.createField(compilerPos, name.toString(), type);
fieldNames.add(name);
}
/*
* Need add blockFlag and other accessed outside local var as formals.
* And need set the _pc = 0, to make sure the resume could be called directly
* @see x10.compiler.ws.codegen.WSRegularFrameClassGen#genClassConstructor()
*/
protected void genClassConstructor() throws SemanticException{
ConstructorSynth conSynth = wsynth.genClassConstructorType2Base(classSynth);
CodeBlockSynth codeBlockSynth = conSynth.createConstructorBody(compilerPos);
//This ref
Expr thisRef = wsynth.genThisRef(classSynth);
//all formals as constructor's formal
for(Pair<Name, Type> formal: formals){
Name formalName = formal.fst();
Type formalType = formal.snd();
Expr fRef = conSynth.addFormal(compilerPos, Flags.FINAL, formalType, formalName);
//make a field access
Stmt s = xnf.Eval(compilerPos,
synth.makeFieldAssign(compilerPos, thisRef, formalName, fRef, xct));
codeBlockSynth.addStmt(s);
}
//assign pc
codeBlockSynth.addStmt(wsynth.genPCAssign(classSynth, 0));
}
/*
* Cannot inline RemoteMainFrame's fast path
* @see x10.compiler.ws.codegen.AbstractWSClassGen#isFastPathInline()
*/
public boolean isFastPathInline(ClassType frameType){
return false; //default true;
}
}