internal EmitInstanceEmbedded(XObject xo, EmitInstance container, int index) { this.xo = xo; this.container = container; this.index = index; }
/* * Add the provided value, and get the index to use to reference * that value from generated code. If the value is uninitialized, * restricted, or virtual (i.e. std::int), then no extra bytes * will appear in the output, and this method returns -1. */ internal static int AddValue(XValue xv) { EmitInstance ei = AddValueInner(xv); if (ei == null) { return(-1); } int r = valueRefs.Count; valueRefs.Add(ei); return(r); }
/* * Print the provided value (reference). Indentation has already * been applied. Separators from previous values have already been * printed. This function should not add a terminating newline. */ static internal void PrintRef(TextWriter tw, XValue xv) { if (xv.IsUninitialized) { tw.Write("0"); return; } XType xt = xv.VType; if (xt.IsRestricted) { if (xt == XType.BOOL) { tw.Write("{0}", (bool)xv ? "1" : "0"); } else if (xt == XType.U8) { tw.Write("{0}", (byte)xv); } else if (xt == XType.U16) { tw.Write("{0}", (ushort)xv); } else if (xt == XType.U32) { tw.Write("{0}", (uint)xv); } else if (xt == XType.U64) { tw.Write("{0}U", (ulong)xv); } else if (xt == XType.I8) { tw.Write("{0}", (sbyte)xv); } else if (xt == XType.I16) { tw.Write("{0}", (short)xv); } else if (xt == XType.I32) { tw.Write("{0}", (int)xv); } else if (xt == XType.I64) { long m = (long)xv; if (m == -9223372036854775808) { tw.Write("-9223372036854775807 - 1"); } else { tw.Write("{0}", m); } } else { throw new Exception(string.Format("unknown restricted type: {0}", xt.Name)); } } else if (xt == XType.INT) { int z = xv.Int; minInt = Math.Min(minInt, z); maxInt = Math.Max(maxInt, z); tw.Write("(void *)(((uintptr_t){0} << 1) + 1)", z); /* obsolete * } else if (xt == XType.STRING) { * throw new Exception("NYI"); */ } else if (xt == XType.XTYPE) { throw new Exception("NYI"); } else { XObject xo = xv.XObject; EmitInstance ei = toEmit[xo]; ei.PrintRef(tw); } }
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); }