/* * is the next assembler directive an non-instruction generation * * this is used to keep marksequencepoint from getting multiple calls * with no intervening instructions, which causes it to work incorrectly */ private bool IsNextNonInsnGen(IAsm a) { IAsm cur = a.getNext(); if (cur == null) { return(true); } int type = cur.getIType(); /* * skip intervening labels */ while (type == IAsm.I_LABEL) { cur = cur.getNext(); type = cur.getIType(); } /* * if next is comment then return true */ if (type == IAsm.I_COMMENT) { return(true); } return(false); }
public void LoadConst(IAsm a) { int value = Convert.ToInt32(a.getInsn()); if (value > 127 || value < -128) /* if must use long form */ { il.Emit(OpCodes.Ldc_I4, value); } else if (value > 8 || value < -1) /* if must use medium form */ { il.Emit(OpCodes.Ldc_I4_S, value); } else if (value == -1) { il.Emit(OpCodes.Ldc_I4_M1); } else /* else use short form */ { Object o = opcodehash["ldc.i4." + a.getInsn()]; if (o == null) { Io.ICE("Could not find opcode for (Ldc_I4_" + a.getInsn() + ")"); } il.Emit((OpCode)o); } }
public void FieldDef(IAsm a) { Var e = a.getVar(); /* get the field var ptr */ String prefix = ""; switch (e.getClassId()) { case Tok.T_STATIC: prefix = "\t.field "; break; case Tok.T_AUTO: case Tok.T_DEFCLASS: prefix = "\t.field "; break; default: Console.WriteLine("?Unhandled field def type\n"); Environment.Exit(1); break; } StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append(prefix); /* copy the prefix */ sb.Append(genDataTypeSig(e)); /* gen type info, rets updated dp */ sb.Append(" "); sb.Append(e.getName()); /* copy the variable name */ sb.Append("\r\n"); io.Out(sb.ToString()); }
public void Call(IAsm a) { Var func = a.getVar(); String funcsig = genDataTypeSig(a.getVar()); /* gen type info */ VarList x = func.getParams(); /* get any params */ String paramsig = ""; if (x.Length() > 0) { int max = x.Length(); StringBuilder t = new StringBuilder(MyC.MAXSTR); for (int i = 0; i < max; i++) { Var e = x.FindByIndex(i); t.Append(genDataTypeSig(e)); if (i < max - 1) { t.Append(","); } } paramsig = t.ToString(); } StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append("\tcall "); sb.Append(funcsig); sb.Append("("); sb.Append(paramsig); sb.Append(")\t//"); sb.Append(a.getICount()); sb.Append("\r\n"); io.Out(sb.ToString()); }
public void CommentHolder() { NextInsn(0); icur.setIType(IAsm.I_COMMENT); LastComment = icur; /* save away this insn loc to store comment */ icur.setCommentLine(io.commentGetCurrentLine()); }
public void LoadConst(IAsm a) { StringBuilder sb = new StringBuilder(MyC.MAXSTR); int value = Convert.ToInt32(a.getInsn()); sb.Append("\tldc.i4"); if (value > 127 || value < -128) /* if must use long form */ { sb.Append(" "); } else if (value > 8 || value < -1) /* if must use medium form */ { sb.Append(".s "); } else /* else use short form */ { sb.Append("."); } sb.Append(a.getInsn()); sb.Append("\t//"); sb.Append(a.getICount()); sb.Append("\r\n"); io.Out(sb.ToString()); }
public void Label(IAsm a) { StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append(a.getLabel()); sb.Append(":\r\n"); io.Out(sb.ToString()); }
public void Ret(IAsm a) { StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append("\tret\t\t//"); sb.Append(a.getICount()); sb.Append("\r\n"); io.Out(sb.ToString()); }
public void Branch(IAsm a) { Object o = opcodehash[a.getInsn()]; if (o == null) { Io.ICE("Instruction branch opcode (" + a.getInsn() + ") not found in hash"); } il.Emit((OpCode)o, (Label)getILLabel(a)); }
public void Insn(IAsm a) { Object o = opcodehash[a.getInsn()]; if (o == null) { Io.ICE("Instruction opcode (" + a.getInsn() + ") not found in hash"); } il.Emit((OpCode)o); }
public void Load(IAsm a) { StringBuilder sb = new StringBuilder(MyC.MAXSTR); Var e = a.getVar(); if (e == null) { Console.WriteLine("?Load instruction with no variable ptr"); Environment.Exit(1); } switch (e.getClassId()) { case Tok.T_STATIC: { sb.Append("\tldsfld "); sb.Append(genFieldRef(e)); sb.Append("\t//"); sb.Append(a.getICount()); sb.Append(", "); sb.Append(e.getName()); sb.Append("\r\n"); break; } case Tok.T_AUTO: case Tok.T_DEFCLASS: sb.Append("\tldloc "); sb.Append(e.getIndex()); sb.Append("\t//"); sb.Append(a.getICount()); sb.Append(", "); sb.Append(e.getName()); sb.Append("\r\n"); break; case Tok.T_PARAM: sb.Append("\tldarg "); sb.Append(e.getIndex()); sb.Append("\t//"); sb.Append(a.getICount()); sb.Append(", "); sb.Append(e.getName()); sb.Append("\r\n"); break; default: Console.Write("?Instruction load of unknown class ("); Console.Write(e.getClassId()); Console.WriteLine(")"); Environment.Exit(1); break; } io.Out(sb.ToString()); }
private Hashtable labelhash; /* labelname hashtable */ /* * get and/or create IL label * put it in hash for reuse */ private Object getILLabel(IAsm a) { String s = a.getLabel(); Object l = labelhash[s]; if (l == null) { l = (Object)il.DefineLabel(); labelhash[s] = l; } return(l); }
public void Store(IAsm a) { Var e = a.getVar(); int id = e.getClassId(); if (e == null) { Io.ICE("Store instruction with no variable ptr"); } if (e.getLocalToken() != null) { // LocalToken lt = (LocalToken) e.getLocalToken(); LocalBuilder lt = (LocalBuilder)e.getLocalToken(); il.Emit(OpCodes.Stloc, lt); } else if (e.getFieldBuilder() != null) { FieldBuilder fb = (FieldBuilder)e.getFieldBuilder(); if (id == Tok.T_STATIC) { il.Emit(OpCodes.Stsfld, fb); } else { il.Emit(OpCodes.Stfld, fb); } } else { int index = e.getIndex(); if (id == Tok.T_PARAM) { if (index <= 256) { il.Emit(OpCodes.Starg_S, index); } else { il.Emit(OpCodes.Starg, index); } } else if (id == Tok.T_AUTO || id == Tok.T_DEFCLASS) { il.Emit(OpCodes.Stloc, index); } else { Io.ICE("Instruction load of unknown class (" + e.getClassId() + ")"); } } }
public void Branch(IAsm a) { StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append("\t"); sb.Append(a.getInsn()); sb.Append(" "); sb.Append(a.getLabel()); sb.Append("\t//"); sb.Append(a.getICount()); sb.Append("\r\n"); io.Out(sb.ToString()); }
void NextInsn(int incr) { int ncount = 0; if (iroot == null) { icur = iroot = new IAsm(); } else { ncount = icur.getICount() + incr; /* propogate previous count */ icur.setNext(new IAsm()); icur = icur.getNext(); } icur.setICount(ncount); }
public void FieldDef(IAsm a) { Var e = a.getVar(); /* get the field var ptr */ FieldAttributes attr = FieldAttributes.Private; /* default attributes is private */ if (e.getClassId() == Tok.T_STATIC) { attr |= FieldAttributes.Static; } Type t = genDataTypeSig(e); /* gen type info */ FieldBuilder f = eclass.DefineField(e.getName(), t, attr); // returns token e.setFieldBuilder((Object)f); // store token for later usage }
public void FuncBegin(IAsm a) { Var func = a.getVar(); Type funcsig = genDataTypeSig(a.getVar()); /* gen return type info */ VarList paramlist = func.getParams(); /* get any params */ Type[] paramTypes = null; // in case no params if (paramlist.Length() > 0) { int max = paramlist.Length(); paramTypes = new Type[max]; for (int i = 0; i < max; i++) { Var e = paramlist.FindByIndex(i); paramTypes[i] = genDataTypeSig(e); } } emethod = eclass.DefineMethod(func.getName(), MethodAttributes.Static | MethodAttributes.Public, funcsig, paramTypes); func.setMethodBuilder(emethod); // save the method ref /* * set the argument symbol info */ for (int i = 0; i < paramlist.Length(); i++) { emethod.DefineParameter(i + 1, 0, paramlist.FindByIndex(i).getName()); } il = emethod.GetILGenerator(); // create new il generator if (func.getName().Equals("main")) /* special entry point for main */ { appbuild.SetEntryPoint(emethod); } // emodule.SetUserEntryPoint(emethod); /* * must also re-init the label hashtable for each function */ labelhash = new Hashtable(); localsdone = false; }
public void Comment(IAsm a) { if (Io.gendebug) { if (localsdone) { if (a != null && il != null) { if (!IsNextNonInsnGen(a)) { // Console.WriteLine("Line ("+a.getCommentLine().ToString()+")="+a.getComment()); int l = a.getCommentLine(); il.MarkSequencePoint(srcdoc, l, 0, l, 0); } } } } }
public void FuncBegin(IAsm a) { Var func = a.getVar(); String funcsig = genDataTypeSig(a.getVar()); /* gen type info */ VarList x = func.getParams(); /* get any params */ String paramsig = ""; if (x.Length() > 0) { int max = x.Length(); StringBuilder t = new StringBuilder(MyC.MAXSTR); for (int i = 0; i < max; i++) { Var e = x.FindByIndex(i); t.Append(genDataTypeSig(e)); if (i < max - 1) { t.Append(","); } } paramsig = t.ToString(); } StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append("\t.method "); sb.Append(funcsig); sb.Append(" "); sb.Append(func.getName()); sb.Append("("); sb.Append(paramsig); sb.Append("){\r\n"); io.Out(sb.ToString()); if (func.getName().Equals("main")) /* special entry point for main */ { io.Out("\t.entrypoint\r\n"); } }
public void Call(IAsm a) { Var func = a.getVar(); Object o = func.getMethodBuilder(); // get previous declared reference if (o == null) { Io.ICE("No previous extern for (" + func.getName() + ")"); } MethodBuilder mb = (MethodBuilder)o; // il.Emit(OpCodes.Ldc_I4_0); // push 0 for the "this" ptr // VarList x = func.getParams(); /* get any params */ // if (x.Length() > 0) // { // int max = x.Length(); // for (int i = 0; i < max; i++) // { // Var e = x.FindByIndex(i); // genLoad(e); // } // } il.Emit(OpCodes.Call, mb); // call the MethodBuilder }
public void Load(IAsm a) { Var e = a.getVar(); genLoad(e); }
private int linenumber; /* line number */ public void setNext(IAsm n) { next = n; }
/* * is the next assembler directive an non-instruction generation * * this is used to keep marksequencepoint from getting multiple calls * with no intervening instructions, which causes it to work incorrectly */ private bool IsNextNonInsnGen(IAsm a) { IAsm cur = a.getNext(); if (cur == null) return true; int type = cur.getIType(); /* * skip intervening labels */ while (type == IAsm.I_LABEL) { cur = cur.getNext(); type = cur.getIType(); } /* * if next is comment then return true */ if (type == IAsm.I_COMMENT) return true; return false; }
/* * Emit assembly instructions now * this flushes the istream */ public void LIST() { IAsm a = iroot; IAsm p; Asm x = new Asm(io); while (a != null) { switch (a.getIType()) { case IAsm.I_INSN: x.Insn(a); break; case IAsm.I_LABEL: x.Label(a); break; case IAsm.I_BRANCH: x.Branch(a); break; case IAsm.I_INSN_STORE: x.Store(a); break; case IAsm.I_INSN_LOAD: x.Load(a); break; case IAsm.I_INSN_LOAD_CONST: x.LoadConst(a); break; case IAsm.I_FUNC_BEGIN: x.FuncBegin(a); /* Emit function beginning */ break; case IAsm.I_FUNC_END: x.FuncEnd(); break; case IAsm.I_CALL: x.Call(a); break; case IAsm.I_RET: x.Ret(a); break; case IAsm.I_COMMENT: x.Comment(a); break; case IAsm.I_FIELD: x.FieldDef(a); break; case IAsm.I_LOCALDEF: x.LocalVars(localvars); break; default: io.Abort("Unhandled instruction type " + a.getIType()); break; } p = a; a = a.getNext(); } }
public void LoadConst(IAsm a) { int value = Convert.ToInt32(a.getInsn()); if (value > 127 || value < -128) /* if must use long form */ { il.Emit(OpCodes.Ldc_I4, value); } else if (value > 8 || value < -1) /* if must use medium form */ { il.Emit(OpCodes.Ldc_I4_S, value); } else if (value == -1) { il.Emit(OpCodes.Ldc_I4_M1); } else /* else use short form */ { Object o = opcodehash["ldc.i4."+a.getInsn()]; if (o == null) Io.ICE("Could not find opcode for (Ldc_I4_" + a.getInsn() + ")"); il.Emit((OpCode) o); } }
public void Label(IAsm a) { il.MarkLabel((Label)getILLabel(a)); }
public void FuncBegin(IAsm a) { Var func = a.getVar(); String funcsig = genDataTypeSig(a.getVar()); /* gen type info */ VarList x = func.getParams(); /* get any params */ String paramsig = ""; if (x.Length() > 0) { int max = x.Length(); StringBuilder t = new StringBuilder(MyC.MAXSTR); for (int i = 0; i < max; i++) { Var e = x.FindByIndex(i); t.Append(genDataTypeSig(e)); if (i < max-1) t.Append(","); } paramsig = t.ToString(); } StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append("\t.method "); sb.Append(funcsig); sb.Append(" "); sb.Append(func.getName()); sb.Append("("); sb.Append(paramsig); sb.Append("){\r\n"); io.Out(sb.ToString()); if (func.getName().Equals("main")) /* special entry point for main */ io.Out("\t.entrypoint\r\n"); }
public void Comment(IAsm a) { String sp = a.getComment(); /* source ptr */ if (sp == null) { return; // empty comment } sp.Trim(); // remove extra whitespace if (sp == null || sp.Length == 0) /* sanity check, is there a comment? */ { return; /* no, then nothing to do */ } #if DEBUG Console.Write("Comment SP="); for (int _debug_i = 0; _debug_i < sp.Length; _debug_i++) { int _debug_d = sp[_debug_i]; char _debug_c = (char)(_debug_d + 96); if (_debug_d < 32) { Console.Write("^" + Char.ToString(_debug_c)); } else { Console.Write(sp[_debug_i]); } Console.Write("["); Console.Write(_debug_d); Console.Write("],"); } Console.WriteLine(";"); #endif StringBuilder buf = new StringBuilder(MyC.MAXSTR); /* a buffer to work with */ buf.Append("//"); buf.Append(a.getCommentLine()); buf.Append(": "); int i = 0; int p = 0; while ((i = sp.IndexOf('\n', i)) >= 0) { i++; // move past the newline string ts = sp.Substring(p, i - p); String s = ts.Trim(); if (s.Length > 0) { buf.Append(s); // copy the substr } buf.Append("\r\n"); // add the line seperator if (i < sp.Length) { buf.Append("//"); // insert the comment block } p = i; } buf.Append(sp.Substring(p)); // append the remaining chars buf.Append("\r\n"); io.Out(buf.ToString()); /* output the comment */ }
public void Comment(IAsm a) { String sp = a.getComment(); /* source ptr */ if (sp == null) return; // empty comment sp.Trim(); // remove extra whitespace if (sp == null || sp.Length == 0) /* sanity check, is there a comment? */ return; /* no, then nothing to do */ #if DEBUG Console.Write("Comment SP="); for (int _debug_i=0; _debug_i<sp.Length;_debug_i++) { int _debug_d = sp[_debug_i]; char _debug_c = (char) (_debug_d + 96); if (_debug_d < 32) Console.Write("^"+Char.ToString(_debug_c)); else Console.Write(sp[_debug_i]); Console.Write("["); Console.Write(_debug_d); Console.Write("],"); } Console.WriteLine(";"); #endif StringBuilder buf = new StringBuilder(MyC.MAXSTR); /* a buffer to work with */ buf.Append("//"); buf.Append(a.getCommentLine()); buf.Append(": "); int i = 0; int p = 0; while ((i = sp.IndexOf('\n', i)) >= 0) { i++; // move past the newline string ts = sp.Substring(p, i-p); String s = ts.Trim(); if (s.Length > 0) buf.Append(s); // copy the substr buf.Append("\r\n"); // add the line seperator if (i < sp.Length) buf.Append("//"); // insert the comment block p = i; } buf.Append(sp.Substring(p)); // append the remaining chars buf.Append("\r\n"); io.Out(buf.ToString()); /* output the comment */ }
public void Ret(IAsm a) { il.Emit(OpCodes.Ret); }
public void FieldDef(IAsm a) { Var e = a.getVar(); /* get the field var ptr */ FieldAttributes attr = FieldAttributes.Private; /* default attributes is private */ if (e.getClassId() == Tok.T_STATIC) attr |= FieldAttributes.Static; Type t = genDataTypeSig(e); /* gen type info */ FieldBuilder f = eclass.DefineField(e.getName(), t, attr); // returns token e.setFieldBuilder((Object) f); // store token for later usage }
public void Store(IAsm a) { Var e = a.getVar(); int id = e.getClassId(); if (e == null) Io.ICE("Store instruction with no variable ptr"); if (e.getLocalToken() != null) { // LocalToken lt = (LocalToken) e.getLocalToken(); LocalBuilder lt = (LocalBuilder) e.getLocalToken(); il.Emit(OpCodes.Stloc, lt); } else if (e.getFieldBuilder() != null) { FieldBuilder fb = (FieldBuilder) e.getFieldBuilder(); if (id == Tok.T_STATIC) il.Emit(OpCodes.Stsfld, fb); else il.Emit(OpCodes.Stfld, fb); } else { int index = e.getIndex(); if (id == Tok.T_PARAM) { if (index <= 256) il.Emit(OpCodes.Starg_S, index); else il.Emit(OpCodes.Starg, index); } else if (id == Tok.T_AUTO || id == Tok.T_DEFCLASS) il.Emit(OpCodes.Stloc, index); else Io.ICE("Instruction load of unknown class (" + e.getClassId()+")"); } }
public void Finish() { iroot = icur = null; }
public void Call(IAsm a) { Var func = a.getVar(); String funcsig = genDataTypeSig(a.getVar()); /* gen type info */ VarList x = func.getParams(); /* get any params */ String paramsig = ""; if (x.Length() > 0) { int max = x.Length(); StringBuilder t = new StringBuilder(MyC.MAXSTR); for (int i = 0; i < max; i++) { Var e = x.FindByIndex(i); t.Append(genDataTypeSig(e)); if (i < max-1) t.Append(","); } paramsig = t.ToString(); } StringBuilder sb = new StringBuilder(MyC.MAXSTR); sb.Append("\tcall "); sb.Append(funcsig); sb.Append("("); sb.Append(paramsig); sb.Append(")\t//"); sb.Append(a.getICount()); sb.Append("\r\n"); io.Out(sb.ToString()); }
public void FuncBegin(IAsm a) { Var func = a.getVar(); Type funcsig = genDataTypeSig(a.getVar()); /* gen return type info */ VarList paramlist = func.getParams(); /* get any params */ Type[] paramTypes = null; // in case no params if (paramlist.Length() > 0) { int max = paramlist.Length(); paramTypes = new Type[max]; for (int i = 0; i < max; i++) { Var e = paramlist.FindByIndex(i); paramTypes[i] = genDataTypeSig(e); } } emethod = eclass.DefineMethod(func.getName(), MethodAttributes.Static|MethodAttributes.Public, funcsig, paramTypes); func.setMethodBuilder(emethod); // save the method ref /* * set the argument symbol info */ for (int i = 0; i < paramlist.Length(); i++) emethod.DefineParameter(i+1, 0, paramlist.FindByIndex(i).getName()); il = emethod.GetILGenerator(); // create new il generator if (func.getName().Equals("main")) /* special entry point for main */ appbuild.SetEntryPoint(emethod); // emodule.SetUserEntryPoint(emethod); /* * must also re-init the label hashtable for each function */ labelhash = new Hashtable(); localsdone = false; }
public void Call(IAsm a) { Var func = a.getVar(); Object o = func.getMethodBuilder(); // get previous declared reference if (o == null) Io.ICE("No previous extern for (" + func.getName() + ")"); MethodBuilder mb = (MethodBuilder) o; // il.Emit(OpCodes.Ldc_I4_0); // push 0 for the "this" ptr // VarList x = func.getParams(); /* get any params */ // if (x.Length() > 0) // { // int max = x.Length(); // for (int i = 0; i < max; i++) // { // Var e = x.FindByIndex(i); // genLoad(e); // } // } il.Emit(OpCodes.Call, mb); // call the MethodBuilder }
public void Insn(IAsm a) { Object o = opcodehash[a.getInsn()]; if (o == null) Io.ICE("Instruction opcode (" + a.getInsn() + ") not found in hash"); il.Emit((OpCode) o); }
private Hashtable labelhash; /* labelname hashtable */ /* * get and/or create IL label * put it in hash for reuse */ private Object getILLabel(IAsm a) { String s = a.getLabel(); Object l = labelhash[s]; if (l == null) { l = (Object) il.DefineLabel(); labelhash[s] = l; } return l; }
public void Label(IAsm a) { il.MarkLabel((Label) getILLabel(a)); }
public void Branch(IAsm a) { Object o = opcodehash[a.getInsn()]; if (o == null) Io.ICE("Instruction branch opcode (" + a.getInsn() + ") not found in hash"); il.Emit((OpCode) o, (Label) getILLabel(a)); }