/// <summary> /// Write opcodes and data section to stream /// References to string constants will be recalculated /// </summary> public void WriteToStream(Stream output) { // a string is [NanTag(UInt32): byte length] [string bytes, padded to 8 byte chunks] // 1) Calculate the string table size var dataLength = _stringTable.Select(CalculatePaddedSize).Sum() + _stringTable.Count; // 2) Write a jump command to skip the table var jumpCode = NanTags.EncodeLongOpcode('c', 's', (uint)dataLength); WriteCode(output, jumpCode); // 3) Write the strings, with a mapping dictionary long location = 1; // counting initial jump as 0 var mapping = new Dictionary <long, long>(); // original index, final memory location for (var index = 0; index < _stringTable.Count; index++) { var staticStr = _stringTable[index]; var bytes = Encoding.ASCII.GetBytes(staticStr); var chunks = CalculatePaddedSize(staticStr); var padSize = (chunks * 8) - bytes.Length; mapping.Add(index, location); var headerOpCode = NanTags.EncodeUInt32((uint)bytes.Length); WriteCode(output, headerOpCode); location++; output.Write(bytes, 0, bytes.Length); location += chunks; for (int p = 0; p < padSize; p++) { output.WriteByte(0); } } // 4) Write the op-codes foreach (var code in _opcodes) { var type = NanTags.TypeOf(code); switch (type) { case DataType.PtrString: case DataType.PtrStaticString: NanTags.DecodePointer(code, out var original, out _); var final = mapping[original]; WriteCode(output, NanTags.EncodePointer(final, DataType.PtrStaticString)); break; default: WriteCode(output, code); break; } } output.Flush(); }
/// <summary> /// Write a static string. /// Static strings aren't seen by the GC and exist in memory outside of the normal allocation space /// </summary> public void LiteralString(string s) { // duplication check if (_stringTable.Contains(s)) { var idx = _stringTable.IndexOf(s); _opcodes.Add(NanTags.EncodePointer(idx, DataType.PtrStaticString)); return; } // no existing matches _stringTable.Add(s); _opcodes.Add(NanTags.EncodePointer(_stringTable.Count - 1, DataType.PtrStaticString)); }