internal override void PrintValue(TextWriter tw) { tw.WriteLine(); string tname = Compiler.Encode(xo.ObjectType.Name); string name = string.Format("t1v_{0}_{1}", xo.Serial, tname); if (xo is XObjectGen) { XObjectGen xog = (XObjectGen)xo; tw.Write("static const struct t1s_{0} {1} = ", tname, name); PrintObjectGen(tw, 0, xog); } else if (xo is XArrayGeneric) { XArrayGeneric xag = (XArrayGeneric)xo; tw.WriteLine("static const t1x_array {0} = ", name); PrintArray(tw, 0, xag); } else { throw new Exception(string.Format("internal error: EmitInstanceTopLevel on {0}", xo.GetType())); } tw.WriteLine(";"); }
void FinishInterpreter(CPU cpu) { XValue[] vv = cpu.PopToMarker(); XArrayGeneric a = new XArrayGeneric(XType.ARRAY_OBJECT); a.Init(new XBufferGen(vv), 0, vv.Length); cpu.Push(new XValue(a)); }
internal void InitSub(XArrayGeneric src, int off, int len) { if (src.dataBuf == null) { throw new Exception("making sub-view of uninitialized array"); } if (off < 0 || off > src.dataLen || len < 0 || len > (src.dataLen - off)) { throw new Exception(string.Format("sub-view ({0},{1}) does not fit in source array length {2}", off, len, src.dataLen)); } this.dataBuf = src.dataBuf; this.dataOff = src.dataOff + off; this.dataLen = len; }
internal static void PrintArray( TextWriter tw, int indent, XArrayGeneric xag) { XType xt = xag.ObjectType; tw.WriteLine("{"); Compiler.Indent(tw, indent + 1); tw.WriteLine("(void *)&t1t_{0},", Compiler.Encode(xt.Name)); XBuffer xb = xag.dataBuf; if (xb == null) { /* * Uninitialized array. */ Compiler.Indent(tw, indent + 1); tw.WriteLine("0, 0, 0"); } else { EmitInstance ei; if (!toEmit.TryGetValue(xb, out ei)) { throw new Exception("internal error: buffer is not scheduled for emission"); } EmitInstanceBuffer eib = ei as EmitInstanceBuffer; if (eib == null) { throw new Exception("buffer not associated with EmitInstanceBuffer"); } int range; int off; eib.FindRange(xag.dataOff, out range, out off); Compiler.Indent(tw, indent + 1); tw.WriteLine("(void *)&t1b_{0}_{1},", xb.Serial, range); Compiler.Indent(tw, indent + 1); tw.WriteLine("{0},", off); Compiler.Indent(tw, indent + 1); tw.WriteLine("{0}", xag.dataLen); } Compiler.Indent(tw, indent); tw.Write("}"); }
/* * Warning: this function does not check compatibility of values * with the destination type. */ internal static XArrayGeneric Concat( XType type, params XArrayGeneric[] aa) { List <XValue> r = new List <XValue>(); foreach (XArrayGeneric a in aa) { int n = a.Length; for (int i = 0; i < n; i++) { r.Add(a[i]); } } XArrayGeneric xag = new XArrayGeneric(type); XBuffer xb = new XBufferGen(r.ToArray()); xag.Init(xb, 0, r.Count); return(xag); }
/* * Implementation of std::check-type-element. */ internal void NativeCheckTypeElements(CPU cpu) { XArrayGeneric a = cpu.Pop().XObject as XArrayGeneric; int n = a.Length; if (n == 0) { cpu.Push(false); return; } if (n == 1) { XValue xv = a[0]; if (xv.VType == XType.INT) { cpu.Push(false); return; } if (xv.VType == XType.XTYPE) { cpu.Push(true); return; } throw new Exception(string.Format("unexpected object of type {0} in type definition", xv.VType.Name)); } if (n == 2) { XValue xv = a[0]; if (xv.VType != XType.INT) { throw new Exception(string.Format("unexpected object of type {0} in type definition", xv.VType.Name)); } xv = a[1]; if (xv.VType != XType.XTYPE) { throw new Exception(string.Format("unexpected object of type {0} in type definition", xv.VType.Name)); } cpu.Push(true); return; } throw new Exception("too many elements for type definition"); }
/* * Implementation of std::concat (on arrays of objects). */ internal void NativeConcatArrayObject(CPU cpu) { XArrayGeneric b = cpu.Pop().XObject as XArrayGeneric; XArrayGeneric a = cpu.Pop().XObject as XArrayGeneric; int alen = a.Length; int blen = b.Length; XBuffer xb = new XBufferGen(a.Length + b.Length); for (int i = 0; i < alen; i++) { xb.Set(i, a[i]); } for (int i = 0; i < blen; i++) { xb.Set(alen + i, b[i]); } XArrayGeneric c = new XArrayGeneric(XType.ARRAY_OBJECT); c.Init(xb, 0, alen + blen); cpu.Push(new XValue(c)); }
/* * Implementation of std::add-struct-element. */ internal void NativeAddStructElement(CPU cpu) { XArrayGeneric a = cpu.Pop().XObject as XArrayGeneric; bool embed = cpu.Pop().Bool; string name = cpu.Pop().String; if (currentStruct == null) { throw new Exception("no current struct"); } if (a.Length == 1) { XType xt = a[0].XTypeInstance; if (embed) { currentStruct.AddEmbed(name, xt); } else { currentStruct.AddField(name, xt); } } else if (a.Length == 2) { int size = a[0].Int; XType xt = a[1].XTypeInstance; if (embed) { currentStruct.AddArrayEmbed(name, size, xt); } else { currentStruct.AddArrayField(name, size, xt); } } else { throw new Exception("invalid type definition"); } }
/* * Implementation of std::define-typed-local. */ internal void NativeAddTypedLocal(CPU cpu) { XArrayGeneric a = cpu.Pop().XObject as XArrayGeneric; bool embed = cpu.Pop().Bool; string name = cpu.Pop().String; if (a.Length == 1) { XType xt = a[0].XTypeInstance; if (embed) { CurrentBuilder.DefLocalEmbed(name, xt); } else { CurrentBuilder.DefLocalField(name, xt); } } else if (a.Length == 2) { int size = a[0].Int; XType xt = a[1].XTypeInstance; if (embed) { CurrentBuilder.DefLocalEmbedArray( name, size, xt); } else { CurrentBuilder.DefLocalFieldArray( name, size, xt); } } else { throw new Exception("invalid type definition"); } }
static EmitInstance AddInstance(XObject xo, EmitInstance container, int index) { EmitInstance ei; if (toEmit.TryGetValue(xo, out ei)) { /* * We already have an EmitInstance for this object. * * If container is null, then we can simply keep * the existing instance, and we do not have to * propagate things any further: the object is * already handled. * * If container is not null, but the existing * instance is top-level, then we must convert it * to an EmitInstanceEmbedded; all its embedded * values automatically follow. * * Since embedding is a tree, there should be no * case where container is not null AND the * existing EmitInstance is also of embedded type. */ if (container != null) { if (!(ei is EmitInstanceTopLevel)) { throw new Exception("internal error: instance already embedded, or not embeddable"); } ei = new EmitInstanceEmbedded(xo, container, index); toEmit[xo] = ei; } return(ei); } /* * We have a new instance. We create the object, then * recursively walk over its fields and embedded values. */ if (xo is XObjectGen) { if (container != null) { ei = new EmitInstanceEmbedded(xo, container, index); } else { ei = new EmitInstanceTopLevel(xo); } XObjectGen xog = (XObjectGen)xo; int n; n = xog.fields.Length; for (int i = 0; i < n; i++) { AddValueInner(xog.fields[i]); } n = xog.embeds.Length; for (int i = 0; i < n; i++) { AddInstance(xog.embeds[i], ei, i); } } else if (xo is XArrayGeneric) { if (container != null) { ei = new EmitInstanceEmbedded(xo, container, index); } else { ei = new EmitInstanceTopLevel(xo); } XArrayGeneric xag = (XArrayGeneric)xo; AddBuffer(xag.dataBuf, xag.ObjectType.GetArrayElementType(), xag.ObjectType.arrayElementEmbedded, xag.dataOff, xag.dataLen); /* obsolete * } else if (xo is XString) { * throw new Exception("NYI"); */ } else if (xo is XType) { ei = new EmitXType((XType)xo); } else { throw new Exception(string.Format("unsupported object type for serialization: {0}", xo.ObjectType.Name)); } toEmit[xo] = ei; return(ei); }