package org.rascalmpl.library.experiments.Compiler.RVM.Interpreter;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.rascalmpl.library.experiments.Compiler.RVM.Interpreter.Instructions.*;
import org.rascalmpl.value.IList;
import org.rascalmpl.value.IMap;
import org.rascalmpl.value.ISourceLocation;
import org.rascalmpl.value.IString;
import org.rascalmpl.value.IValue;
import org.rascalmpl.value.IValueFactory;
import org.rascalmpl.value.type.Type;
import org.rascalmpl.value.type.TypeStore;
import org.rascalmpl.values.uptr.RascalValueFactory;
import org.nustaq.serialization.FSTBasicObjectSerializer;
import org.nustaq.serialization.FSTClazzInfo;
import org.nustaq.serialization.FSTClazzInfo.FSTFieldInfo;
import org.nustaq.serialization.FSTObjectInput;
import org.nustaq.serialization.FSTObjectOutput;
/**
* CodeBlock contains all instructions needed for a single RVM function
*
* CodeBlock is serialized by FSTCodeBlockerializer, make sure that
* all fields declared here are synced with the serializer.
*/
public class CodeBlock implements Serializable {
private static final long serialVersionUID = 6955775282462381062L;
// Transient fields
transient public IValueFactory vf;
//transient private static TypeSerializer typeserializer;
transient int pc;
transient int labelIndex = 0;
transient private ArrayList<Instruction> insList;
transient private HashMap<String, LabelInfo> labelInfo;
// Serializable fields
String name;
private Map<IValue, Integer> constantMap;
private ArrayList<IValue> constantStore;
IValue[] finalConstantStore;
private Map<Type, Integer> typeConstantMap;
private ArrayList<Type> typeConstantStore;
protected Type[] finalTypeConstantStore;
Map<String, Integer> functionMap;
Map<String, Integer> resolver;
Map<String, Integer> constructorMap;
public long[] finalCode;
CodeBlock(String name, Map<IValue, Integer> constantMap, ArrayList<IValue> constantStore, IValue[] finalConstantStore,
Map<Type, Integer> typeConstantMap, ArrayList<Type> typeConstantStore, Type[] finalTypeConstantStore,
Map<String, Integer> functionMap, Map<String, Integer> resolver, Map<String, Integer> constructorMap, long[] finalCode
){
this.name = name;
this.constantMap = constantMap;
this.constantStore = constantStore;
this.finalConstantStore = finalConstantStore;
this.typeConstantMap = typeConstantMap;
this.typeConstantStore = typeConstantStore;
this.finalTypeConstantStore = finalTypeConstantStore;
this.functionMap = functionMap;
this.resolver = resolver;
this.constructorMap = constructorMap;
this.finalCode = finalCode;
}
public CodeBlock(String name, IValueFactory factory){
labelInfo = new HashMap<String, LabelInfo>();
insList = new ArrayList<Instruction>();
new ArrayList<Integer>();
pc = 0;
this.name = name;
this.vf = factory;
constantMap = new HashMap<IValue, Integer>();
this.constantStore = new ArrayList<IValue>();
this.typeConstantMap = new HashMap<Type, Integer>();
this.typeConstantStore = new ArrayList<Type>();
}
void clearForJVM(){
finalCode = new long[] {};
}
public void defLabel(String label, Instruction ins){
LabelInfo info = labelInfo.get(label);
if(info == null){
labelInfo.put(label, new LabelInfo(ins, labelIndex++, pc));
} else {
if(info.isResolved()){
throw new CompilerError("In function " + name + ": double declaration of label " + label);
}
info.instruction = ins;
info.PC = pc;
}
}
protected int useLabel(String label){
LabelInfo info = labelInfo.get(label);
if(info == null){
info = new LabelInfo(labelIndex++);
labelInfo.put(label, info);
}
return info.index;
}
public int getLabelPC(String label){
LabelInfo info = labelInfo.get(label);
if(info == null){
throw new CompilerError("In function " + name + " undefined label " + label);
}
return info.PC;
}
public Instruction getLabelInstruction(String label){
LabelInfo info = labelInfo.get(label);
if(info == null){
throw new CompilerError("In function " + name + ": undefined label " + label);
}
return info.instruction;
}
public IValue getConstantValue(long finalCode2){
for(IValue constant : constantMap.keySet()){
if(constantMap.get(constant) == finalCode2){
return constant;
}
}
throw new CompilerError("In function " + name + ": undefined constant index " + finalCode2);
}
public int getConstantIndex(IValue v){
Integer n = constantMap.get(v);
if(n == null){
n = constantStore.size();
constantStore.add(v);
constantMap.put(v, n);
}
return n;
}
public Type getConstantType(int n){
for(Type type : typeConstantMap.keySet()){
if(typeConstantMap.get(type) == n){
return type;
}
}
throw new CompilerError("In function " + name + ": undefined type constant index " + n);
}
public int getTypeConstantIndex(Type type){
Integer n = typeConstantMap.get(type);
if(n == null){
n = typeConstantStore.size();
typeConstantStore.add(type);
typeConstantMap.put(type, n);
}
return n;
}
public String getFunctionName(int n){
for(String fname : functionMap.keySet()){
if(functionMap.get(fname) == n){
return fname;
}
}
throw new CompilerError("In function " + name + ": undefined function index " + n);
}
public String getFunctionName(String name){
int n = getFunctionIndex(name);
for(String fname : functionMap.keySet()){
if(functionMap.get(fname) == n){
return fname;
}
}
throw new CompilerError("In function " + name + ": undefined function index " + n);
}
public int getFunctionIndex(String name){
Integer n = functionMap.get(name);
if(n == null){
throw new CompilerError("In function " + name + ": undefined function name " + name);
}
return n;
}
public String getOverloadedFunctionName(int n){
for(String fname : resolver.keySet()){
if(resolver.get(fname) == n) {
return fname;
}
}
throw new CompilerError("In function " + name + ": undefined overloaded function index " + n);
}
public int getOverloadedFunctionIndex(String name){
Integer n = resolver.get(name);
if(n == null){
return getFunctionIndex(name);
//throw new CompilerError("In function " + name + ": undefined overloaded function name " + name);
}
return n;
}
public String getConstructorName(int n) {
for(String cname : constructorMap.keySet()) {
if(constructorMap.get(cname) == n)
return cname;
}
throw new CompilerError("In function " + name + ": undefined constructor index " + n);
}
public int getConstructorIndex(String name) {
Integer n = constructorMap.get(name);
if(n == null)
throw new CompilerError("In function " + name + ": undefined constructor name " + name);
return n;
}
public String getModuleVarName(int n){
return ((IString)getConstantValue(n)).getValue();
}
public int getModuleVarIndex(String name){
return getConstantIndex(vf.string(name));
}
CodeBlock add(Instruction ins){
insList.add(ins);
pc += ins.pcIncrement();
return this;
}
public void addCode(long c){
finalCode[pc++] = c;
}
public void addCode0(int op){
finalCode[pc++] = op;
}
public void addCode1(int op, int arg1){
// finalCode[pc++] = op;
// finalCode[pc++] = arg1;
finalCode[pc++] = encode1(op, arg1);
}
public void addCode2(int op, int arg1, int arg2){
// finalCode[pc++] = op;
// finalCode[pc++] = arg1;
// finalCode[pc++] = arg2;
finalCode[pc++] = encode2(op, arg1, arg2);
}
/*
* Instruction encoding:
*
* argument2 argument1 op
* |-----------| |-----------| |---------|
* sizeArg2 bits sizeArg1 bits sizeOp bits
*/
public final static int sizeOp = 8;
public final static int sizeArg1 = 28;
public final static int sizeArg2 = 28;
public final static long maskOp = (1L << sizeOp) - 1;
public final static long maskArg1 = (1L << sizeArg1) - 1;
public final static long maskArg2 = (1L << sizeArg2) - 1;
public final static int shiftArg1 = sizeOp;
public final static int shiftArg2 = sizeOp + sizeArg1;
public final static int maxArg1 = (int) ((1L << sizeArg1) - 1);
public final static int maxArg2 = (int) ((1L << sizeArg2) - 1);
public final static int maxArg = Math.min(maxArg1,maxArg2);
public final static long encode0(int op){
return op;
}
public final static long encode1(int op, int arg1){
assert arg1 < (1L << sizeArg1);
long larg1 = arg1;
return (larg1 << shiftArg1) | op;
}
public final static long encode2(int op, int arg1, int arg2){
assert arg1 < (1L << sizeArg1) && arg2 < (1L << sizeArg2);
long larg1 = arg1;
long larg2 = arg2;
return (larg2 << shiftArg2) | (larg1 << shiftArg1) | op;
}
public final static int fetchOp(long instruction){
return (int) (instruction & maskOp);
}
public final static int fetchArg1(long instruction){
return (int) ((instruction >> shiftArg1) & maskArg1);
}
public final static int fetchArg2(long instruction){
return (int) ((instruction >> shiftArg2) & maskArg2);
}
public final static boolean isMaxArg1(int arg){
return arg == maskArg1;
}
public final static boolean isMaxArg2(int arg){
return arg == maskArg2;
}
/*
* All Instructions
*/
public CodeBlock POP(){
return add(new Pop(this));
}
public CodeBlock HALT(){
return add(new Halt(this));
}
public CodeBlock RETURN0() {
return add(new Return0(this));
}
public CodeBlock RETURN1(){
return add(new Return1(this));
}
public CodeBlock CORETURN0() {
return add(new CoReturn0(this));
}
public CodeBlock CORETURN1(int arity){
return add(new CoReturn1(this,arity));
}
public CodeBlock LABEL(String arg){
return add(new Label(this, arg));
}
public CodeBlock LOADCON(boolean arg){
return add(new LoadCon(this, getConstantIndex(vf.bool(arg))));
}
public CodeBlock LOADCON(int arg){
return add(new LoadCon(this, getConstantIndex(vf.integer(arg))));
}
public CodeBlock LOADCON(String arg){
return add(new LoadCon(this, getConstantIndex(vf.string(arg))));
}
public CodeBlock LOADCON(IValue val){
return add(new LoadCon(this, getConstantIndex(val)));
}
public CodeBlock PUSHCON(IValue val){
return add(new PushCon(this, getConstantIndex(val)));
}
public CodeBlock LOADBOOL(boolean bool){
return add(new LoadBool(this, bool));
}
public CodeBlock LOADINT(int n){
return add(new LoadInt(this, n));
}
public CodeBlock CALL(String fuid, int arity,int ctpt){
return add(new Call(this, fuid, arity, ctpt));
}
public CodeBlock JMP(String arg){
return add(new Jmp(this, arg));
}
public CodeBlock JMPTRUE(String arg){
return add(new JmpTrue(this, arg));
}
public CodeBlock JMPFALSE(String arg){
return add(new JmpFalse(this, arg));
}
public CodeBlock LOADLOC (int pos){
switch(pos){
case 0: return add(new LoadLoc0(this));
case 1: return add(new LoadLoc1(this));
case 2: return add(new LoadLoc2(this));
case 3: return add(new LoadLoc3(this));
case 4: return add(new LoadLoc4(this));
case 5: return add(new LoadLoc5(this));
case 6: return add(new LoadLoc6(this));
case 7: return add(new LoadLoc7(this));
case 8: return add(new LoadLoc8(this));
case 9: return add(new LoadLoc9(this));
default:
return add(new LoadLoc(this, pos));
}
}
public CodeBlock PUSHLOC (int pos){
return add(new PushLoc(this, pos));
}
public CodeBlock RESETLOC (int pos){
return add(new ResetLoc(this, pos));
}
public CodeBlock STORELOC (int pos){
return add(new StoreLoc(this, pos));
}
public CodeBlock LOADVAR(String fuid, int pos){
if(pos == -1){
getConstantIndex(vf.string(fuid));
}
return add(new LoadVar(this, fuid, pos));
}
public CodeBlock PUSHVAR(String fuid, int pos){
if(pos == -1){
getConstantIndex(vf.string(fuid));
}
return add(new PushVar(this, fuid, pos));
}
public CodeBlock STOREVAR (String fuid, int pos){
if(pos == -1){
getConstantIndex(vf.string(fuid));
}
return add(new StoreVar(this, fuid, pos));
}
public CodeBlock RESETVAR (String fuid, int pos){
if(pos == -1){
getConstantIndex(vf.string(fuid));
}
return add(new ResetVar(this, fuid, pos));
}
public CodeBlock CALLMUPRIM0 (MuPrimitive muprim){
return add(new CallMuPrim0(this, muprim));
}
public CodeBlock PUSHCALLMUPRIM0 (MuPrimitive muprim){
return add(new PushCallMuPrim0(this, muprim));
}
public CodeBlock CALLMUPRIM1 (MuPrimitive muprim){
return add(new CallMuPrim1(this, muprim));
}
public CodeBlock PUSHCALLMUPRIM1 (MuPrimitive muprim){
return add(new PushCallMuPrim1(this, muprim));
}
public CodeBlock CALLMUPRIM2 (MuPrimitive muprim){
return add(new CallMuPrim2(this, muprim));
}
public CodeBlock PUSHCALLMUPRIM2 (MuPrimitive muprim){
return add(new PushCallMuPrim2(this, muprim));
}
public CodeBlock CALLMUPRIMN (MuPrimitive muprim, int arity){
return add(new CallMuPrimN(this, muprim, arity));
}
public CodeBlock PUSHCALLMUPRIMN (MuPrimitive muprim, int arity){
return add(new PushCallMuPrimN(this, muprim, arity));
}
public CodeBlock CALLPRIM0 (RascalPrimitive prim, ISourceLocation src){
return add(new CallPrim0(this, prim, src));
}
public CodeBlock PUSHCALLPRIM0 (RascalPrimitive prim, ISourceLocation src){
return add(new PushCallPrim0(this, prim, src));
}
public CodeBlock CALLPRIM1 (RascalPrimitive prim, ISourceLocation src){
return add(new CallPrim1(this, prim, src));
}
public CodeBlock PUSHCALLPRIM1 (RascalPrimitive prim, ISourceLocation src){
return add(new PushCallPrim1(this, prim, src));
}
public CodeBlock CALLPRIM2 (RascalPrimitive prim, ISourceLocation src){
return add(new CallPrim2(this, prim, src));
}
public CodeBlock PUSHCALLPRIM2 (RascalPrimitive prim, ISourceLocation src){
return add(new PushCallPrim2(this, prim, src));
}
public CodeBlock CALLPRIMN (RascalPrimitive prim, int arity, ISourceLocation src){
return add(new CallPrimN(this, prim, arity, src));
}
public CodeBlock PUSHCALLPRIMN (RascalPrimitive prim, int arity, ISourceLocation src){
return add(new PushCallPrimN(this, prim, arity, src));
}
public CodeBlock PUSH_ROOT_FUN (String fuid){
return add(new PushRootFun(this, fuid));
}
public CodeBlock CALLDYN(int arity, int ctpt){
return add(new CallDyn(this, arity, ctpt));
}
public CodeBlock CREATE(String fuid, int arity) {
return add(new Create(this, fuid, arity));
}
public CodeBlock CREATEDYN(int arity) {
return add(new CreateDyn(this, arity));
}
public CodeBlock NEXT0() {
return add(new Next0(this));
}
public CodeBlock NEXT1() {
return add(new Next1(this));
}
public CodeBlock YIELD0(int ctpt) {
return add(new Yield0(this, ctpt));
}
public CodeBlock YIELD1(int arity, int ctpt) {
return add(new Yield1(this, arity, ctpt));
}
public CodeBlock PRINTLN(int arity){
return add(new Println(this, arity));
}
public CodeBlock LOADLOCREF(int pos) {
return add(new LoadLocRef(this, pos));
}
public CodeBlock PUSHLOCREF(int pos) {
return add(new PushLocRef(this, pos));
}
public CodeBlock LOADVARREF(String fuid, int pos) {
return add(new LoadVarRef(this, fuid, pos));
}
public CodeBlock PUSHVARREF(String fuid, int pos) {
return add(new PushVarRef(this, fuid, pos));
}
public CodeBlock LOADLOCDEREF(int pos) {
return add(new LoadLocDeref(this, pos));
}
public CodeBlock PUSHLOCDEREF(int pos) {
return add(new PushLocDeref(this, pos));
}
public CodeBlock LOADVARDEREF(String fuid, int pos) {
return add(new LoadVarDeref(this, fuid, pos));
}
public CodeBlock PUSHVARDEREF(String fuid, int pos) {
return add(new PushVarDeref(this, fuid, pos));
}
public CodeBlock STORELOCDEREF(int pos) {
return add(new StoreLocDeref(this, pos));
}
public CodeBlock STOREVARDEREF(String fuid, int pos) {
return add(new StoreVarDeref(this, fuid, pos));
}
public CodeBlock PUSHCONSTR(String name) {
return add(new PushConstr(this, name));
}
public CodeBlock CALLCONSTR(String name, int arity/*, ISourceLocation src*/) {
return add(new CallConstr(this, name, arity/*, src*/));
}
public CodeBlock PUSHNESTEDFUN(String fuid, String scopeIn) {
return add(new PushNestedFun(this, fuid, scopeIn));
}
public CodeBlock LOADTYPE(Type type) {
return add(new LoadType(this, getTypeConstantIndex(type)));
}
public CodeBlock PUSHTYPE(Type type) {
return add(new PushType(this, getTypeConstantIndex(type)));
}
public CodeBlock FAILRETURN(){
return add(new FailReturn(this));
}
public CodeBlock PUSHOFUN(String fuid) {
return add(new PushOFun(this, fuid));
}
public CodeBlock OCALL(String fuid, int arity, ISourceLocation src) {
return add(new OCall(this, fuid, arity, src));
}
public CodeBlock OCALLDYN(Type types, int arity, ISourceLocation src) {
return add(new OCallDyn(this, getTypeConstantIndex(types), arity, src));
}
public CodeBlock CALLJAVA(String methodName, String className, Type parameterTypes, Type keywordTypes, int reflect){
return add(new CallJava(this, getConstantIndex(vf.string(methodName)),
getConstantIndex(vf.string(className)),
getTypeConstantIndex(parameterTypes),
getTypeConstantIndex(keywordTypes),
reflect));
}
public CodeBlock THROW(ISourceLocation src) {
return add(new Throw(this, src));
}
public CodeBlock TYPESWITCH(IList labels){
return add(new TypeSwitch(this, labels));
}
public CodeBlock UNWRAPTHROWNLOC(int pos) {
return add(new UnwrapThrownLoc(this, pos));
}
public CodeBlock FILTERRETURN(){
return add(new FilterReturn(this));
}
public CodeBlock EXHAUST() {
return add(new Exhaust(this));
}
public CodeBlock GUARD(int ctpt) {
return add(new Guard(this,ctpt));
}
public CodeBlock SUBSCRIPTARRAY() {
return add(new SubscriptArray(this));
}
public CodeBlock SUBSCRIPTLIST() {
return add(new SubscriptList(this));
}
public CodeBlock LESSINT() {
return add(new LessInt(this));
}
public CodeBlock GREATEREQUALINT() {
return add(new GreaterEqualInt(this));
}
public CodeBlock ADDINT() {
return add(new AddInt(this));
}
public CodeBlock SUBTRACTINT() {
return add(new SubtractInt(this));
}
public CodeBlock ANDBOOL() {
return add(new AndBool(this));
}
public CodeBlock TYPEOF() {
return add(new TypeOf(this));
}
public CodeBlock SUBTYPE() {
return add(new SubType(this));
}
public CodeBlock CHECKARGTYPEANDCOPY(int pos1, Type type, int pos2) {
return add(new CheckArgTypeAndCopy(this, pos1, getTypeConstantIndex(type), pos2));
}
public CodeBlock LOADLOCKWP(String name) {
return add(new LoadLocKwp(this, name));
}
public CodeBlock PUSHLOCKWP(String name) {
return add(new PushLocKwp(this, name));
}
public CodeBlock LOADVARKWP(String fuid, String name) {
return add(new LoadVarKwp(this, fuid, name));
}
public CodeBlock PUSHVARKWP(String fuid, String name) {
return add(new PushVarKwp(this, fuid, name));
}
public CodeBlock STORELOCKWP(String name) {
return add(new StoreLocKwp(this, name));
}
public CodeBlock STOREVARKWP(String fuid, String name) {
return add(new StoreVarKwp(this, fuid, name));
}
public CodeBlock UNWRAPTHROWNVAR(String fuid, int pos) {
return add(new UnwrapThrownVar(this, fuid, pos));
}
public CodeBlock APPLY(String fuid, int arity) {
return add(new Apply(this, fuid, arity));
}
public CodeBlock APPLYDYN(int arity) {
return add(new ApplyDyn(this, arity));
}
public CodeBlock SWITCH(IMap caseLabels, String caseDefault, boolean useConcreteFingerprint) {
return add(new Switch(this, caseLabels, caseDefault, useConcreteFingerprint));
}
public CodeBlock RESETLOCS(IList positions) {
return add(new ResetLocs(this, getConstantIndex(positions)));
}
public CodeBlock VISIT(boolean direction, boolean progress, boolean fixedpoint, boolean rebuild){
return add(new Visit(this,
getConstantIndex(vf.bool(direction)),
getConstantIndex(vf.bool(progress)),
getConstantIndex(vf.bool(fixedpoint)),
getConstantIndex(vf.bool(rebuild))));
}
public CodeBlock CHECKMEMO(){
return add(new CheckMemo(this));
}
public CodeBlock PUSHEMPTYKWMAP(){
return add(new PushEmptyKwMap(this));
}
public CodeBlock VALUESUBTYPE(Type type){
return add(new ValueSubtype(this, getTypeConstantIndex(type)));
}
public CodeBlock PUSHACCU(){
return add(new PushAccu(this));
}
public CodeBlock POPACCU(){
return add(new PopAccu(this));
}
public CodeBlock done(String fname, Map<String, Integer> codeMap, Map<String, Integer> constructorMap, Map<String, Integer> resolver) {
this.functionMap = codeMap;
this.constructorMap = constructorMap;
this.resolver = resolver;
int codeSize = pc;
pc = 0;
finalCode = new long[codeSize];
for(Instruction ins : insList){
ins.generate();
}
finalConstantStore = new IValue[constantStore.size()];
for(int i = 0; i < constantStore.size(); i++ ){
finalConstantStore[i] = constantStore.get(i);
}
finalTypeConstantStore = new Type[typeConstantStore.size()];
for(int i = 0; i < typeConstantStore.size(); i++) {
finalTypeConstantStore[i] = typeConstantStore.get(i);
}
if(constantStore.size() >= maxArg){
throw new CompilerError("In function " + fname + ": constantStore size " + constantStore.size() + "exceeds limit " + maxArg);
}
if(typeConstantStore.size() >= maxArg){
throw new CompilerError("In function " + fname + ": typeConstantStore size " + typeConstantStore.size() + "exceeds limit " + maxArg);
}
return this;
}
public long[] getInstructions(){
return finalCode;
}
public IValue[] getConstants(){
return finalConstantStore;
}
public Type[] getTypeConstants() {
return finalTypeConstantStore;
}
void listing(String fname){
int pc = 0;
while(pc < finalCode.length){
Opcode opc = Opcode.fromInteger(fetchOp((int) finalCode[pc]));
System.out.println(fname + "[" + pc +"]: " + Opcode.toString(this, opc, pc));
pc += opc.getPcIncrement();
}
System.out.println();
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("\n") ;
boolean prevLabel = false ;
if(insList != null){
for (Instruction ins : insList ) {
if ( ins instanceof Label ) {
sb.append(ins).append(": ");
prevLabel = true ;
}
else {
if ( prevLabel ) {
sb.append("\t").append(ins).append("\n") ;
prevLabel = false ;
}
else {
sb.append("\t\t").append(ins).append("\n") ;
}
}
}
}
return sb.toString();
}
public String toString(int n){
Opcode opc = Opcode.fromInteger(fetchOp(finalCode[n]));
return Opcode.toString(this, opc, n);
}
public void genByteCode(BytecodeGenerator gen, boolean debug) {
for(Instruction ins : insList){
ins.generateByteCode(gen, debug);
}
if (insList.get(insList.size() - 1) instanceof Label) {
// The mu2rvm code generator emits faulty code and jumps outside existing space
// put in a panic return, code is also generated on a not used label.
// Activate the peephole optimizer :).
gen.emitPanicReturn();
}
}
}
class LabelInfo {
final int index;
int PC;
Instruction instruction;
LabelInfo(Instruction ins, int index, int pc){
this.instruction = ins;
this.index = index;
this.PC = pc;
}
public LabelInfo(int index) {
this.index = index;
PC = -1;
}
public boolean isResolved(){
return PC >= 0;
}
}
/**
* FSTCodeBlockSerializer: serializer for CodeBlock objects
*
*/
class FSTCodeBlockSerializer extends FSTBasicObjectSerializer {
private static TypeStore store;
public static void initSerialization(IValueFactory vfactory, TypeStore ts){
store = ts;
store.extendStore(RascalValueFactory.getStore());
}
@Override
public void writeObject(FSTObjectOutput out, Object toWrite,
FSTClazzInfo arg2, FSTFieldInfo arg3, int arg4)
throws IOException {
int n;
CodeBlock cb = (CodeBlock) toWrite;
// private String name;
out.writeObject(cb.name);
// private Map<IValue, Integer> constantMap;
// private ArrayList<IValue> constantStore;
// private IValue[] finalConstantStore;
n = cb.finalConstantStore.length;
out.writeObject(n);
for(int i = 0; i < n; i++){
out.writeObject(new FSTSerializableIValue(cb.finalConstantStore[i]));
}
// private Map<Type, Integer> typeConstantMap;
// private ArrayList<Type> typeConstantStore;
// private Type[] finalTypeConstantStore;
n = cb.finalTypeConstantStore.length;
out.writeObject(n);
for(int i = 0; i < n; i++){
out.writeObject(new FSTSerializableType(cb.finalTypeConstantStore[i]));
}
// private Map<String, Integer> functionMap;
out.writeObject(cb.functionMap);
// private Map<String, Integer> resolver;
out.writeObject(cb.resolver);
// private Map<String, Integer> constructorMap;
out.writeObject(cb.constructorMap);
// public int[] finalCode;
out.writeObject(cb.finalCode);
}
public void readObject(FSTObjectInput in, Object toRead, FSTClazzInfo clzInfo, FSTClazzInfo.FSTFieldInfo referencedBy)
{
}
@SuppressWarnings("unchecked")
public Object instantiate(@SuppressWarnings("rawtypes") Class objectClass, FSTObjectInput in, FSTClazzInfo serializationInfo, FSTClazzInfo.FSTFieldInfo referencee, int streamPosition) throws ClassNotFoundException, IOException
{
int n;
// private String name;
String name = (String) in.readObject();
// private Map<IValue, Integer> constantMap;
// private ArrayList<IValue> constantStore;
// private IValue[] finalConstantStore;
n = (Integer) in.readObject();
Map<IValue,Integer> constantMap = new HashMap<IValue, Integer> ();
ArrayList<IValue> constantStore = new ArrayList<IValue>();
IValue[] finalConstantStore = new IValue[n];
for(int i = 0; i < n; i++){
IValue val = (IValue) in.readObject();
constantMap.put(val, i);
constantStore.add(i, val);
finalConstantStore[i] = val;
}
// private Map<Type, Integer> typeConstantMap;
// private ArrayList<Type> typeConstantStore;
// private Type[] finalTypeConstantStore;
n = (Integer) in.readObject();
Map<Type, Integer> typeConstantMap = new HashMap<Type, Integer>();
ArrayList<Type> typeConstantStore = new ArrayList<Type>();
Type[] finalTypeConstantStore = new Type[n];
for(int i = 0; i < n; i++){
Type type = (Type) in.readObject();
typeConstantMap.put(type, i);
typeConstantStore.add(i, type);
finalTypeConstantStore[i] = type;
}
// private Map<String, Integer> functionMap;
Map<String, Integer> functionMap = (HashMap<String, Integer>) in.readObject();
// private Map<String, Integer> resolver;
Map<String, Integer> resolver = (HashMap<String, Integer>) in.readObject();
// private Map<String, Integer> constructorMap;
Map<String, Integer> constructorMap = (HashMap<String, Integer>) in.readObject();
// public int[] finalCode;
long[] finalCode = (long[]) in.readObject();
return new CodeBlock(name, constantMap, constantStore, finalConstantStore, typeConstantMap, typeConstantStore, finalTypeConstantStore,
functionMap, resolver, constructorMap, finalCode);
}
}