ru.malik.elaborarer.avtoo.generator.pas

Переключить прокрутку окна
Загрузить этот исходный код

{
    Набор генераторов кода для языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    Copyright © 2021, 2024, 2026 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
}

unit ru.malik.elaborarer.avtoo.generator;

    {$MODE OBJFPC}
    {$MODESWITCH TYPEHELPERS}

interface

    {%region} uses
        pascalx.lang,
        pascalx.lang.math.avo,
        pascalx.lang.math.vcoverage,
        pascalx.lang.table,
        pascalx.io,
        pascalx.io.bytearray,
        pascalx.io.charset,
        platform.independent.filesystem,
        platform.independent.osservices,
        platform.independent.streamformat,
        platform.independent.streamformat.compression.zlib,
        ru.malik.elaborarer.avtoo.lang,
        ru.malik.elaborarer.avtoo.compiler;
    {%endregion}

    {$TYPEINFO ON}
    {$CALLING REGISTER}

    const UNIT_NAME = 'ru.malik.elaborarer.avtoo.generator';

    {%region} type
        ResourceLocation           = class;
        CodeGenerator              = class;
        BinarySourceGenerator      = class;
        AssemblerElementWriter     = class;
        AssemblerSourcePrintStream = class;
        AssemblerSourceGenerator   = class;

        ResourceLocation = class(&Object)
        strict private
            fldLibrary: &Library;
            fldRelativePath: UnicodeString;
            fldDestinationPath: UnicodeString;
        public
            constructor create(__library: &Library; const __relativePath: UnicodeString);
            property &library: ru.malik.elaborarer.avtoo.lang.&Library read fldLibrary;
            property relativePath: UnicodeString read fldRelativePath;
            property destinationPath: UnicodeString read fldDestinationPath write fldDestinationPath;
        end;

        CodeGenerator = class abstract(ImmediateBuilder)
        strict private
            class procedure clearDirectory(fileSystem: FileSystem; const directoryPath: UnicodeString); static;
        public
            class procedure createImmediateDirectories(fileSystem: FileSystem; const directoryPath, relativePath: UnicodeString); static;
            class function prepareDestinationPath(fileSystem: FileSystem; const destinationPath: UnicodeString): UnicodeString; static;
        protected
            function getOverwritten(): UnicodeString; virtual; abstract;
            function isStaticFieldsOnly(): boolean; override; final;
            function isLibrary(): boolean; override; final;
        public
            constructor create(__library: boolean);
            property overwritten: UnicodeString read getOverwritten;
        end;

        BinarySourceGenerator = class(CodeGenerator)
        strict private type
            HashtableOfAnsiStringToObjectVector = specialize HashtableOfAnsiString<ObjectVector>;
        strict private
            class procedure appendClassType(__type: ClassType; constants, container: ObjectVector); static;
            class procedure createRecompilable(container: ObjectVector; fileSystem: FileSystem; const recompilablePath: UnicodeString); static;
            class procedure fillSourcesTable(table: HashtableOfAnsiStringToObjectVector; sources: SourceArray); static;
            class procedure freeSourcesTable(table: HashtableOfAnsiStringToObjectVector); static;
        public const
            { уровни создания файлов двоичного исходного кода }
            LEVEL_CLASS   = int(0);
            LEVEL_PACKAGE = int(1);
            LEVEL_LIBRARY = int(2);
        strict private
            fldLevel: int;
            fldOverwritten: UnicodeString;
            procedure setLevel(newLevel: int);
        protected
            function getOverwritten(): UnicodeString; override; final;
        public
            constructor create();
            procedure compile(); override;
            property level: int read fldLevel write setLevel;
        end;

        AssemblerElementWriter = class(AVTOOConstants)
        public const
            { флаги формирования сигнатуры типа }
            NORM  = int(0);
            WEAK  = int(1);
            STACK = int(2);
        protected
            fldOffset: int;
            fldText: char_Array1d;
        public
            procedure trim(); virtual;
            function get(): AnsiString; virtual;
            function &set(const text: char_Array1d; offset: int): AssemblerElementWriter; virtual;
            function writeChar(character: char): AssemblerElementWriter; virtual;
            function writeLabel(character: char; &label: int): AssemblerElementWriter; virtual;
            function writeLabel(&label: int): AssemblerElementWriter; virtual;
            function writeOffset(value: int): AssemblerElementWriter; virtual;
            function writeByte(value: int): AssemblerElementWriter; virtual;
            function writeShort(value: int): AssemblerElementWriter; virtual;
            function writeInt(value: int): AssemblerElementWriter; virtual;
            function writeLong(value: long): AssemblerElementWriter; virtual;
            function writeDecimal(value: int): AssemblerElementWriter; virtual;
            function writeString(const &string: AnsiString): AssemblerElementWriter; virtual;
            function writeString(const &string: AnsiString; beginIndex, endIndex: int): AssemblerElementWriter; virtual;
            function writeLabel(node: Node): AssemblerElementWriter; virtual;
            function writeSignature(kind, flags: int): AssemblerElementWriter; virtual;
            function writeSignature(&type: &Type; flags: int): AssemblerElementWriter; virtual;
            function &set(const text: char_Array1d): AssemblerElementWriter;
            property offset: int read fldOffset write fldOffset;
        end;

        AssemblerSourcePrintStream = class(&Object, DataEncoder, CharsetOutputAdapter, OutputAdapter, MutableDataHolder, DataHolder)
        strict private
            class var defaultEncoder: CharEncoder;
            class function getSeparator(state: int): AnsiString; static;
        private
            class procedure initialize(); static;
            class procedure finalize(); static;
        strict private
            fldState: int;
            fldMargin: int;
            fldText: AnsiString;
            fldSpaces: char_Array1d;
            fldEncoder: CharEncoder;
            procedure write(const src: char);
            procedure write(const src: AnsiString);
            function spaces(count: int): AnsiString;
        public
            constructor create();
            constructor create(encoder: CharEncoder);
            procedure saveToOutputStream(stream: ByteWriter); virtual;
            procedure saveToOutputStream(stream: ByteWriter; encoder: CharEncoder); virtual;
            procedure clear(); virtual;
            procedure increaseMargin(); virtual;
            procedure decreaseMargin(); virtual;
            procedure print(const src: AnsiString); virtual;
            procedure printHeader(const header: AnsiString); virtual;
            procedure printLabel(const &label: AnsiString); virtual;
            procedure printInstruction(const mnemonic: AnsiString); virtual;
            procedure printInstruction(const mnemonic, operand: AnsiString); virtual;
            procedure printInstruction(const mnemonic: AnsiString; const operands: AnsiString_Array1d; offset, length: int); virtual;
            procedure printContinuation(const operands: AnsiString_Array1d; offset, length: int); virtual;
            procedure println(); virtual;
            procedure println(const src: AnsiString); virtual;
            procedure printlnHeader(const header: AnsiString); virtual;
            procedure printlnLabel(const &label: AnsiString); virtual;
            procedure printlnInstruction(const mnemonic: AnsiString); virtual;
            procedure printlnInstruction(const mnemonic, operand: AnsiString); virtual;
            procedure printlnInstruction(const mnemonic: AnsiString; const operands: AnsiString_Array1d; offset, length: int); virtual;
            procedure printlnContinuation(const operands: AnsiString_Array1d; offset, length: int); virtual;
            function isEmpty(): boolean; virtual;
        end;

        AssemblerSourceGenerator = class(CodeGenerator)
        strict private type
            HashtableOfAnsiStringToType       = specialize HashtableOfAnsiString<&Type>;
            HashtableOfUnicodeStringToLibrary = specialize HashtableOfUnicodeString<&Library>;
        protected type
            HashtableOfUnicodeStringToResourceLocation = specialize HashtableOfUnicodeString<ResourceLocation>;
        protected const
            { флаги формирования сигнатуры типа }
            NORM  = AssemblerElementWriter.NORM;
            WEAK  = AssemblerElementWriter.WEAK;
            STACK = AssemblerElementWriter.STACK;
            { длина буфера для копирования ресурсов }
            COPY_BUFFER_LENGTH = int($8000);
        protected
            class procedure setResourceLocation(table: HashtableOfUnicodeStringToResourceLocation; const name: UnicodeString; newLocation: ResourceLocation); static;
            class procedure clearResourcesTable(table: HashtableOfUnicodeStringToResourceLocation); static;
            class procedure freeResourcesTable(table: HashtableOfUnicodeStringToResourceLocation); static;
            class function isTypeCastAvailable(kindBaseOfSrc, lengthOfSrc, kindBaseOfNew, lengthOfNew: int): boolean; static;
            class function toRuntimePrimitiveKind(kind: int): int; static;
            class function getNeedRegisterTypeKind(node: Node): int; static;
            class function getPayLength(const aarray: char_Array1d): int; static;
            class function getPayLengthPtr(const aarray): int; static;
            class function toString(const aarray: char_Array1d): AnsiString; overload; static;
            class function getTypedItem(itemC: Constant; itemI: TableItem): TypedItem; static;
        strict private
            fldReflect: boolean;
            fldOverwritten: UnicodeString;
            fldDestinationName: UnicodeString;
            fldGlobalWriter: AssemblerElementWriter;
            fldSourcesTable: HashtableOfUnicodeStringToLibrary;
            procedure findSourcesIn(__library: &Library);
            procedure findSourcesIn(__library: &Library; const __relativePath: UnicodeString);
            procedure constantToFasmString(value: Constant; const operand: char_Array1d);
            function additionalToFasmString(operandC: Constant; operandI: TableItem; const operand: char_Array1d): AnsiString;
            function additionalToFasmString(operandC: Constant; operandI: TableItem; const operand: char_Array1d; refsLocalTable: HashtableOfAnsiStringToType): AnsiString;
        protected
            fldRealStorage: RealStorage;
            fldDoubleStorage: DoubleStorage;
            fldDouble2Storage: Double2Storage;
            fldDouble4Storage: Double4Storage;
            fldDouble8Storage: Double8Storage;
            fldFloatStorage: FloatStorage;
            fldFloat2Storage: Float2Storage;
            fldFloat4Storage: Float4Storage;
            fldFloat8Storage: Float8Storage;
            fldByte2Storage: Byte2Storage;
            fldByte4Storage: Byte4Storage;
            fldByte8Storage: Byte8Storage;
            fldShort2Storage: Short2Storage;
            fldShort4Storage: Short4Storage;
            fldShort8Storage: Short8Storage;
            fldInt2Storage: Int2Storage;
            fldInt4Storage: Int4Storage;
            fldInt8Storage: Int8Storage;
            fldLongStorage: LongStorage;
            fldLong2Storage: Long2Storage;
            fldLong4Storage: Long4Storage;
            fldLong8Storage: Long8Storage;
            fldStringStorage: UnicodeStringStorage;
            fldDebugInfoSources: UnicodeStringStorage;
            fldDebugInfoStrings: AnsiStringStorage;
            fldResourcesTable: HashtableOfUnicodeStringToResourceLocation;
            procedure findResourcesIn(__library: &Library); virtual;
            procedure findResourcesIn(__library: &Library; const __relativePath: UnicodeString); virtual;
            procedure generatePackageData(__pack, __next: Package; output: AssemblerSourcePrintStream); virtual;
            procedure generatePrimitiveData(__type: PrimitiveType; output: AssemblerSourcePrintStream); virtual;
            procedure generateClassData(__type: ClassType; output: AssemblerSourcePrintStream); virtual;
            procedure generateClassCode(__type: ClassType; output: AssemblerSourcePrintStream); virtual;
            procedure generateCallableCode(__callable: Callable; output: AssemblerSourcePrintStream); virtual;
            procedure generateImplementorCode(__type, __superservice: ClassType; output: AssemblerSourcePrintStream); virtual;
            procedure generateConstants(output: AssemblerSourcePrintStream); virtual;
            procedure generateDebugInfoEntries(output: AssemblerSourcePrintStream); virtual;
            procedure generateDebugInfoSources(output: AssemblerSourcePrintStream); virtual;
            procedure generateDebugInfoStrings(output: AssemblerSourcePrintStream); virtual;
            procedure generateProgramme(output: AssemblerSourcePrintStream); virtual;
            function newAssemblerElementWriter(): AssemblerElementWriter; virtual;
            function newAssemblerSourcePrintStream(): AssemblerSourcePrintStream; virtual;
            function getOverwritten(): UnicodeString; override; final;
            function getAssemblerElementWriter(): AssemblerElementWriter;
        public
            constructor create(__reflect: boolean; const __destinationName: UnicodeString);
            destructor destroy; override;
            procedure afterConstruction(); override;
            procedure beforeDestruction(); override;
            procedure compile(); override;
            procedure clear(); override;
            property reflect: boolean read fldReflect;
            property destinationName: UnicodeString read fldDestinationName;
        end;
    {%endregion}

implementation

    {$R *.res}

    {$INLINE ON}
    {$TYPEINFO OFF}
    {$CALLING REGISTER}

    {%region} type
        BinarySourceGeneratorConstants = class;

        BinarySourceGeneratorConstants = class(ObjectVector)
        public
            class function serializeVersion(): ByteArrayOutputStream; static;
            class function serializeTextSource(source: TextSource; charset: Charset): ByteArrayOutputStream; static;
            class function serializeEnd(): ByteArrayOutputStream; static;
        strict private
            procedure removeAllElements();
            function getOperandIndex(operandC: Constant; operandI: TableItem; thisArgument: Local): int;
            function indexOf(const item: AnsiString): int; overload;
            function indexAcquire(const item: AnsiString): int;
            function indexAcquire(const item: UnicodeString): int;
            function indexAcquire(const item: TableItem): int;
            function indexAcquire(const item: TypedMember): int;
            function indexAcquire(const item: Constant): int;
        public
            constructor create();
            destructor destroy; override;
            procedure afterConstruction(); override;
            procedure clear(); override;
            function serializeConstants(charset: Charset): ByteArrayOutputStream;
            function serializePackage(__pack: Package): ByteArrayOutputStream;
            function serializeClassType(__type: ClassType): ByteArrayOutputStream;
            function serializeClassField(__field: Field): ByteArrayOutputStream;
            function serializeStructField(__field: Field): ByteArrayOutputStream;
            function serializeProperty(__property: &Property): ByteArrayOutputStream;
            function serializeCallable(__callable: Callable): ByteArrayOutputStream;
            function serializeMethod(__method: Method): ByteArrayOutputStream;
            function serializeCode(__code: Code): ByteArrayOutputStream;
        end;

        BinarySourceGeneratorCodeDataOutput = type helper for DataOutput
        public
            procedure writeByte2(const value: byte2);
            procedure writeByte4(const value: byte4);
            procedure writeByte8(const value: byte8);
            procedure writeShort2(const value: short2);
            procedure writeShort4(const value: short4);
            procedure writeShort8(const value: short8);
            procedure writeInt2(const value: int2);
            procedure writeInt4(const value: int4);
            procedure writeInt8(const value: int8);
            procedure writeLong2(const value: long2);
            procedure writeLong4(const value: long4);
            procedure writeLong8(const value: long8);
            procedure writeFloat2(const value: float2);
            procedure writeFloat4(const value: float4);
            procedure writeFloat8(const value: float8);
            procedure writeDouble2(const value: double2);
            procedure writeDouble4(const value: double4);
            procedure writeDouble8(const value: double8);
            procedure writeIndex(index: int);
            procedure writeLabel(target: Node);
        end;

        AssemblerSourceGeneratorClassType = class helper for ClassType
        public
            function hasOverriddingMembersFor(superservice: ClassType; isSuperclassesLook: boolean): boolean;
        end;
    {%endregion}

    {%region  ResourceLocation }
        constructor ResourceLocation.create(__library: &Library; const __relativePath: UnicodeString);
        begin
            inherited create();
            fldLibrary := __library;
            fldRelativePath := __relativePath;
        end;
    {%endregion}

    {%region  CodeGenerator }
        class procedure CodeGenerator.clearDirectory(fileSystem: FileSystem; const directoryPath: UnicodeString);
        var
            index: int;
            dir: UnicodeString;
            oname: UnicodeString;
            dirs: ObjectVector;
            files: ObjectVector;
        begin
            dirs := nil;
            files := nil;
            try
                dirs := ObjectVector.create(true);
                files := ObjectVector.create(true);
                with fileSystem.findFirst(directoryPath) do try
                    repeat
                        oname := name;
                        if (oname <> '.') and (oname <> '..') then begin
                            if directory then begin
                                dirs.append(CoUnicodeString.create(oname));
                            end else begin
                                files.append(CoUnicodeString.create(oname));
                            end;
                        end;
                    until not findNext();
                finally
                    close();
                end;
                for index := 0 to dirs.getLength() - 1 do begin
                    dir := directoryPath + CoUnicodeString(dirs.readComponent(index)).asUnicodeString();
                    clearDirectory(fileSystem, dir + '/');
                    fileSystem.deleteDirectory(dir);
                end;
                for index := 0 to files.getLength() - 1 do begin
                    fileSystem.deleteFile(directoryPath + CoUnicodeString(files.readComponent(index)).asUnicodeString());
                end;
            finally
                dirs.free();
                files.free();
            end;
        end;

        class procedure CodeGenerator.createImmediateDirectories(fileSystem: FileSystem; const directoryPath, relativePath: UnicodeString);
        var
            index: int;
            directoryName: UnicodeString;
            attributes: ObjectAttributes;
        begin
            if fileSystem = nil then begin
                fileSystem := FileSystemRoot.get(Process.current().workingDirectory).fileSystem;
            end;
            attributes := ObjectAttributes.create(fileSystem);
            try
                index := 0;
                repeat
                    index := relativePath.indexOf('/', index + 1);
                    if index < 1 then break;
                    directoryName := directoryPath + relativePath.substring(1, index);
                    if fileSystem.isObjectExists(directoryName) then begin
                        fileSystem.readAttributes(directoryName, attributes);
                        if not attributes.directory then fileSystem.createDirectory(directoryName);
                        continue;
                    end;
                    fileSystem.createDirectory(directoryName);
                until false;
            finally
                attributes.free();
            end;
        end;

        class function CodeGenerator.prepareDestinationPath(fileSystem: FileSystem; const destinationPath: UnicodeString): UnicodeString;
        var
            path: UnicodeString;
            attributes: ObjectAttributes;
        begin
            if fileSystem = nil then begin
                fileSystem := FileSystemRoot.get(Process.current().workingDirectory).fileSystem;
            end;
            if not fileSystem.isObjectExists(destinationPath) then begin
                fileSystem.createDirectory(destinationPath);
                result := destinationPath + '/';
                exit;
            end;
            attributes := ObjectAttributes.create(fileSystem);
            try
                fileSystem.readAttributes(destinationPath, attributes);
                if not attributes.directory then begin
                    fileSystem.createDirectory(destinationPath);
                    result := destinationPath + '/';
                    exit;
                end;
            finally
                attributes.free();
            end;
            path := destinationPath + '/';
            clearDirectory(fileSystem, path);
            result := path;
        end;

        function CodeGenerator.isStaticFieldsOnly(): boolean;
        begin
            result := false;
        end;

        function CodeGenerator.isLibrary(): boolean;
        begin
            result := inherited isLibrary();
        end;

        constructor CodeGenerator.create(__library: boolean);
        begin
            inherited create(false, __library);
        end;
    {%endregion}

    {%region  BinarySourceGenerator }
        class procedure BinarySourceGenerator.appendClassType(__type: ClassType; constants, container: ObjectVector);
        label
            break_label0;
        var
            index: int;
            isStruct: boolean;
            __code: Code;
            __member: Member;
            __method: Method;
            __callable: Callable;
            __constants: BinarySourceGeneratorConstants absolute constants;
        begin
            container.append(__constants.serializeClassType(__type));
            isStruct := __type.isStruct();
            for index := 0 to __type.getLength() - 1 do begin
                __code := nil;
                begin
                    __member := __type.readComponent(index);
                    if __member is Method then begin
                        __method := Method(__member);
                        __code := __method.code;
                        container.append(__constants.serializeMethod(__method));
                        goto break_label0;
                    end;
                    if __member is Callable then begin
                        __callable := Callable(__member);
                        __code := __callable.code;
                        container.append(__constants.serializeCallable(__callable));
                        goto break_label0;
                    end;
                    if __member is &Property then begin
                        container.append(__constants.serializeProperty(&Property(__member)));
                        continue;
                    end;
                    if __member is Field then begin
                        if isStruct then begin
                            container.append(__constants.serializeStructField(Field(__member)));
                            continue;
                        end;
                        container.append(__constants.serializeClassField(Field(__member)));
                    end;
                    continue;
                end;
                break_label0:
                if __code <> nil then container.append(__constants.serializeCode(__code));
            end;
        end;

        class procedure BinarySourceGenerator.createRecompilable(container: ObjectVector; fileSystem: FileSystem; const recompilablePath: UnicodeString);
        type
            ByteArrayOutputStream_Array1d = specialize DynamicArray<ByteArrayOutputStream>;
        var
            cindex: int;
            dlength: int;
            dbytes: byte_Array1d;
            chunks: ByteArrayOutputStream_Array1d;
            stream: ByteWriter;
        begin
            chunks := ByteArrayOutputStream_Array1d(container.clone());
            stream := fileSystem.createFile(recompilablePath + BINARY_SOURCE_EXTENSION);
            try
                with DataOutputStream.create(stream), bigEndianDataOutput do try
                    with Checksum32(CRC32.create()) do try
                        writeLong(AVTOORecompilable.SIGNATURE_AVTR);
                        for cindex := 0 to system.length(chunks) - 1 do begin
                            dbytes := chunks[cindex].toByteArray();
                            dlength := system.length(dbytes);
                            update(dbytes, 0, dlength);
                            writeInt((dlength - 4) shr 1);
                            write(dbytes);
                            writeInt(getValue());
                            reset();
                        end;
                    finally
                        free();
                    end;
                finally
                    free();
                end;
                stream.flush();
            finally
                stream.close();
            end;
        end;

        class procedure BinarySourceGenerator.fillSourcesTable(table: HashtableOfAnsiStringToObjectVector; sources: SourceArray);
        var
            index: int;
            name: AnsiString;
            owner: Package;
            source: TextSource;
            vector: ObjectVector;
        begin
            for index := sources.getLength() - 1 downto 0 do begin
                source := TextSource(Lang.cast(sources.readComponent(index), TextSource));
                owner := source.owner;
                if owner = nil then continue;
                name := owner.specialCanonicalName;
                if table.contains(name) then begin
                    vector := table[name];
                end else begin
                    vector := ObjectVector.create(false);
                    table[name] := vector;
                end;
                vector.append(source);
            end;
        end;

        class procedure BinarySourceGenerator.freeSourcesTable(table: HashtableOfAnsiStringToObjectVector);
        var
            index: int;
            key: AnsiString;
            value: TObject;
        begin
            for index := table.length - 1 downto 0 do begin
                key := table.keyAt(index);
                value := table[key];
                table[key] := nil;
                value.free();
            end;
            table.free();
        end;

        procedure BinarySourceGenerator.setLevel(newLevel: int);
        begin
            if newLevel < LEVEL_CLASS then newLevel := LEVEL_CLASS;
            if newLevel > LEVEL_LIBRARY then newLevel := LEVEL_LIBRARY;
            fldLevel := newLevel;
        end;

        function BinarySourceGenerator.getOverwritten(): UnicodeString;
        begin
            result := fldOverwritten;
        end;

        constructor BinarySourceGenerator.create();
        begin
            inherited create(true);
            fldLevel := LEVEL_CLASS;
        end;

        procedure BinarySourceGenerator.compile();
        type
            TextSource_Array1d = specialize DynamicArray<TextSource>;
        var
            dindex: int;
            pindex: int;
            sindex: int;
            packageName: AnsiString;
            directoryPath: UnicodeString;
            destinationPath: UnicodeString;
            chunkEnd: byte_Array1d;
            chunkVersion: byte_Array1d;
            sourcesArray: TextSource_Array1d;
            pack: Package;
            utf16: Charset;
            source: TextSource;
            __project: ru.malik.elaborarer.avtoo.lang.&Library;
            container: ObjectVector;
            __fileSystem: FileSystem;
            declared: ClassTypeArray;
            sourcesList: ObjectVector;
            constants: BinarySourceGeneratorConstants;
            __type: ru.malik.elaborarer.avtoo.lang.ClassType;
            sourcesTable: HashtableOfAnsiStringToObjectVector;
        begin
            { -- предыдущие стадии -- }
            inherited compile();
            { 8. Стадия выгрузки данных }
            utf16 := Charset.get('UTF-16 BE');
            __project := project;
            __fileSystem := __project.fileSystem;
            destinationPath := prepareDestinationPath(__fileSystem, __project.directoryPath + BINARY_SOURCE_PATH);
            fldOverwritten := destinationPath;
            container := nil;
            constants := nil;
            try
                container := ObjectVector.create(true);
                constants := BinarySourceGeneratorConstants.create();
                with BinarySourceGeneratorConstants.serializeVersion() do try
                    chunkVersion := toByteArray();
                finally
                    free();
                end;
                with BinarySourceGeneratorConstants.serializeEnd() do try
                    chunkEnd := toByteArray();
                finally
                    free();
                end;
                case fldLevel of
                LEVEL_LIBRARY: begin
                    container.append(ByteArrayOutputStream.create(chunkVersion));
                    sourcesTable := HashtableOfAnsiStringToObjectVector.create();
                    try
                        fillSourcesTable(sourcesTable, __project.sources);
                        for pindex := 0 to __project.getLength() - 1 do begin
                            pack := __project.readComponent(pindex);
                            packageName := pack.specialCanonicalName;
                            if packageName.length <= 0 then continue;
                            sourcesList := sourcesTable[packageName];
                            sourcesArray := nil;
                            if sourcesList <> nil then sourcesArray := TextSource_Array1d(sourcesList.clone());
                            container.append(constants.serializePackage(pack));
                            if sourcesArray <> nil then for sindex := 0 to system.length(sourcesArray) - 1 do begin
                                source := sourcesArray[sindex];
                                container.append(BinarySourceGeneratorConstants.serializeTextSource(source, utf16));
                                declared := source.declared;
                                for dindex := 0 to declared.getLength() - 1 do begin
                                    appendClassType(declared.readComponent(dindex), constants, container);
                                end;
                            end;
                        end;
                    finally
                        freeSourcesTable(sourcesTable);
                    end;
                    container.insert(1, constants.serializeConstants(utf16));
                    container.append(ByteArrayOutputStream.create(chunkEnd));
                    createRecompilable(container, __fileSystem, destinationPath + '!library');
                    container.clear();
                    constants.clear();
                end;
                LEVEL_PACKAGE: begin
                    sourcesTable := HashtableOfAnsiStringToObjectVector.create();
                    try
                        fillSourcesTable(sourcesTable, __project.sources);
                        for pindex := 0 to __project.getLength() - 1 do begin
                            pack := __project.readComponent(pindex);
                            packageName := pack.specialCanonicalName;
                            if packageName.length <= 0 then continue;
                            sourcesList := sourcesTable[packageName];
                            sourcesArray := nil;
                            if sourcesList <> nil then sourcesArray := TextSource_Array1d(sourcesList.clone());
                            container.append(ByteArrayOutputStream.create(chunkVersion));
                            container.append(constants.serializePackage(pack));
                            if sourcesArray <> nil then for sindex := 0 to system.length(sourcesArray) - 1 do begin
                                source := sourcesArray[sindex];
                                container.append(BinarySourceGeneratorConstants.serializeTextSource(source, utf16));
                                declared := source.declared;
                                for dindex := 0 to declared.getLength() - 1 do begin
                                    appendClassType(declared.readComponent(dindex), constants, container);
                                end;
                            end;
                            container.insert(1, constants.serializeConstants(utf16));
                            container.append(ByteArrayOutputStream.create(chunkEnd));
                            createRecompilable(container, __fileSystem, destinationPath + packageName.toUTF16());
                            container.clear();
                            constants.clear();
                        end;
                    finally
                        freeSourcesTable(sourcesTable);
                    end;
                end;
                else
                    for pindex := 0 to __project.getLength() - 1 do begin
                        pack := __project.readComponent(pindex);
                        packageName := pack.specialCanonicalName;
                        if packageName.length <= 0 then continue;
                        directoryPath := destinationPath + packageName.toUTF16();
                        __fileSystem.createDirectory(directoryPath);
                        directoryPath := directoryPath + '/';
                        begin
                            container.append(ByteArrayOutputStream.create(chunkVersion));
                            container.append(constants.serializePackage(pack));
                            container.insert(1, constants.serializeConstants(utf16));
                            container.append(ByteArrayOutputStream.create(chunkEnd));
                            createRecompilable(container, __fileSystem, directoryPath + '!package');
                            container.clear();
                            constants.clear();
                        end;
                        for dindex := 0 to pack.getLength() - 1 do begin
                            __type := pack.readComponent(dindex) as ru.malik.elaborarer.avtoo.lang.ClassType;
                            if __type is ArrayType then continue;
                            container.append(ByteArrayOutputStream.create(chunkVersion));
                            container.append(BinarySourceGeneratorConstants.serializeTextSource(TextSource(Lang.cast(__type.source, TextSource)), utf16));
                            appendClassType(__type, constants, container);
                            container.insert(1, constants.serializeConstants(utf16));
                            container.append(ByteArrayOutputStream.create(chunkEnd));
                            createRecompilable(container, __fileSystem, directoryPath + __type.specialSimpleName.toUTF16());
                            container.clear();
                            constants.clear();
                        end;
                    end;
                end;
            finally
                container.free();
                constants.free();
            end;
        end;
    {%endregion}

    {%region  AssemblerElementWriter }
        procedure AssemblerElementWriter.trim();
        var
            __offset: int;
            text: char_Array1d;
        begin
            __offset := fldOffset;
            text := fldText;
            if (__offset >= 0) and (__offset < system.length(text)) then begin
                text[__offset] := #0;
            end;
        end;

        function AssemblerElementWriter.get(): AnsiString;
        begin
            result := AnsiString.create(fldText, 0, fldOffset);
        end;

        function AssemblerElementWriter.&set(const text: char_Array1d; offset: int): AssemblerElementWriter;
        begin
            fldText := text;
            fldOffset := offset;
            result := self;
        end;

        function AssemblerElementWriter.writeChar(character: char): AssemblerElementWriter;
        var
            __offset: int;
        begin
            __offset := fldOffset;
            fldText[__offset] := character;
            fldOffset := __offset + 1;
            result := self;
        end;

        function AssemblerElementWriter.writeLabel(character: char; &label: int): AssemblerElementWriter;
        var
            index: int;
            length: int;
            __offset: int;
            text: char_Array1d;
        begin
            length := 7;
            if (&label >= $00010000) and (&label < $01000000) then begin
                length := 9;
            end else
            if (&label >= $01000000) or (&label < $00000000) then begin
                length := 11;
            end;
            __offset := fldOffset;
            text := fldText;
            text[__offset] := '.';
            text[__offset + 2] := '.';
            text[__offset + 1] := character;
            inc(__offset, 3);
            for index := 3 to length - 1 do begin
                text[__offset] := CoChar.toUpperCase(CoChar.toChar((&label shr ((length - index - 1) shl 2)) and $0f));
                inc(__offset);
            end;
            fldOffset := __offset;
            result := self;
        end;

        function AssemblerElementWriter.writeLabel(&label: int): AssemblerElementWriter;
        var
            index: int;
            length: int;
            __offset: int;
            text: char_Array1d;
        begin
            length := 7;
            if (&label >= $00010000) and (&label < $01000000) then begin
                length := 9;
            end else
            if (&label >= $01000000) or (&label < $00000000) then begin
                length := 11;
            end;
            __offset := fldOffset;
            text := fldText;
            text[__offset] := '.';
            inc(__offset);
            text[__offset] := '$';
            inc(__offset);
            text[__offset + length - 3] := '$';
            for index := 3 to length - 1 do begin
                text[__offset] := CoChar.toChar((&label shr ((length - index - 1) shl 2)) and $0f);
                inc(__offset);
            end;
            fldOffset := __offset + 1;
            result := self;
        end;

        function AssemblerElementWriter.writeOffset(value: int): AssemblerElementWriter;
        var
            index: int;
            length: int;
            __offset: int;
            text: char_Array1d;
        begin
            length := 2;
            if (value >= $00000010) and (value < $00000100) then begin
                length := 3;
            end else
            if (value >= $00000100) and (value < $00001000) then begin
                length := 4;
            end else
            if (value >= $00001000) and (value < $00010000) then begin
                length := 5;
            end else
            if (value >= $00010000) and (value < $00100000) then begin
                length := 6;
            end else
            if (value >= $00100000) and (value < $01000000) then begin
                length := 7;
            end else
            if (value >= $01000000) and (value < $10000000) then begin
                length := 8;
            end else
            if (value >= $10000000) or (value < $00000000) then begin
                length := 9;
            end;
            __offset := fldOffset;
            text := fldText;
            text[__offset] := '$';
            inc(__offset);
            for index := 1 to length - 1 do begin
                text[__offset] := CoChar.toChar((value shr ((length - index - 1) shl 2)) and $0f);
                inc(__offset);
            end;
            fldOffset := __offset;
            result := self;
        end;

        function AssemblerElementWriter.writeByte(value: int): AssemblerElementWriter;
        var
            index: int;
            __offset: int;
            text: char_Array1d;
        begin
            __offset := fldOffset;
            text := fldText;
            text[__offset] := '$';
            inc(__offset);
            for index := 1 to 2 do begin
                text[__offset] := CoChar.toChar(int(value shr ((2 - index) shl 2)) and $0f);
                inc(__offset);
            end;
            fldOffset := __offset;
            result := self;
        end;

        function AssemblerElementWriter.writeShort(value: int): AssemblerElementWriter;
        var
            index: int;
            __offset: int;
            text: char_Array1d;
        begin
            __offset := fldOffset;
            text := fldText;
            text[__offset] := '$';
            inc(__offset);
            for index := 1 to 4 do begin
                text[__offset] := CoChar.toChar(int(value shr ((4 - index) shl 2)) and $0f);
                inc(__offset);
            end;
            fldOffset := __offset;
            result := self;
        end;

        function AssemblerElementWriter.writeInt(value: int): AssemblerElementWriter;
        var
            index: int;
            __offset: int;
            text: char_Array1d;
        begin
            __offset := fldOffset;
            text := fldText;
            text[__offset] := '$';
            inc(__offset);
            for index := 1 to 8 do begin
                text[__offset] := CoChar.toChar(int(value shr ((8 - index) shl 2)) and $0f);
                inc(__offset);
            end;
            fldOffset := __offset;
            result := self;
        end;

        function AssemblerElementWriter.writeLong(value: long): AssemblerElementWriter;
        var
            index: int;
            __offset: int;
            text: char_Array1d;
        begin
            __offset := fldOffset;
            text := fldText;
            text[__offset] := '$';
            inc(__offset);
            for index := 1 to 16 do begin
                text[__offset] := CoChar.toChar(int(value shr ((16 - index) shl 2)) and $0f);
                inc(__offset);
            end;
            fldOffset := __offset;
            result := self;
        end;

        function AssemblerElementWriter.writeDecimal(value: int): AssemblerElementWriter;
        var
            index: int;
            length: int;
            __offset: int;
            text: char_Array1d;
        begin
            __offset := fldOffset;
            text := fldText;
            if value >= 0 then begin
                value := -value;
            end else begin
                text[__offset] := '-';
                inc(__offset);
            end;
            length := -1;
            if (value > -100) and (value <= -10) then begin
                length := -2;
            end else
            if (value > -1000) and (value <= -100) then begin
                length := -3;
            end else
            if (value > -10000) and (value <= -1000) then begin
                length := -4;
            end else
            if (value > -100000) and (value <= -10000) then begin
                length := -5;
            end else
            if (value > -1000000) and (value <= -100000) then begin
                length := -6;
            end else
            if (value > -10000000) and (value <= -1000000) then begin
                length := -7;
            end else
            if (value > -100000000) and (value <= -10000000) then begin
                length := -8;
            end else
            if (value > -1000000000) and (value <= -100000000) then begin
                length := -9;
            end else
            if value <= -1000000000 then begin
                length := -10;
            end;
            dec(__offset, length);
            index := 0;
            while index > length do begin
                dec(index);
                text[__offset + index] := char(int('0') - (value mod 10));
                value := value div 10;
            end;
            fldOffset := __offset;
            result := self;
        end;

        function AssemblerElementWriter.writeString(const &string: AnsiString): AssemblerElementWriter;
        var
            length: int;
            __offset: int;
        begin
            __offset := fldOffset;
            length := &string.length;
            &Array.copyRaw(&string[1], fldText[__offset], length * sizeof(char));
            fldOffset := __offset + length;
            result := self;
        end;

        function AssemblerElementWriter.writeString(const &string: AnsiString; beginIndex, endIndex: int): AssemblerElementWriter;
        var
            length: int;
            __offset: int;
        begin
            __offset := fldOffset;
            length := endIndex - beginIndex;
            &Array.copyRaw(&string[beginIndex], fldText[__offset], length * sizeof(char));
            fldOffset := __offset + length;
            result := self;
        end;

        function AssemblerElementWriter.writeLabel(node: Node): AssemblerElementWriter;
        var
            &label: int;
        begin
            &label := node.debugIndex;
            if &label >= 0 then begin
                result := writeLabel('D', &label);
                exit;
            end;
            result := writeLabel('L', node.labelIndex);
        end;

        function AssemblerElementWriter.writeSignature(kind, flags: int): AssemblerElementWriter;
        var
            signature: AnsiString;
        begin
            case kind of
            TYP_REF: begin
                if (flags and WEAK) <> 0 then begin
                    signature := 'w';
                end else begin
                    signature := 'r';
                end;
            end;
            TYP_CHAR: begin
                if (flags and STACK) <> 0 then begin
                    signature := 'i';
                end else begin
                    signature := 'c';
                end;
            end;
            TYP_REAL: begin
                signature := 'e';
            end;
            TYP_DOUBLE: begin
                signature := 'd';
            end;
            TYP_DOUBLE2: begin
                signature := 'd2';
            end;
            TYP_DOUBLE4: begin
                signature := 'd4';
            end;
            TYP_DOUBLE8: begin
                signature := 'd8';
            end;
            TYP_FLOAT: begin
                signature := 'f';
            end;
            TYP_FLOAT2: begin
                signature := 'f2';
            end;
            TYP_FLOAT4: begin
                signature := 'f4';
            end;
            TYP_FLOAT8: begin
                signature := 'f8';
            end;
            TYP_BOOLEAN,
            TYP_BYTE: begin
                if (flags and STACK) <> 0 then begin
                    signature := 'i';
                end else begin
                    signature := 'b';
                end;
            end;
            TYP_BYTE2: begin
                signature := 'b2';
            end;
            TYP_BYTE4: begin
                signature := 'b4';
            end;
            TYP_BYTE8: begin
                signature := 'b8';
            end;
            TYP_SHORT: begin
                if (flags and STACK) <> 0 then begin
                    signature := 'i';
                end else begin
                    signature := 's';
                end;
            end;
            TYP_SHORT2: begin
                signature := 's2';
            end;
            TYP_SHORT4: begin
                signature := 's4';
            end;
            TYP_SHORT8: begin
                signature := 's8';
            end;
            TYP_INT: begin
                signature := 'i';
            end;
            TYP_INT2: begin
                signature := 'i2';
            end;
            TYP_INT4: begin
                signature := 'i4';
            end;
            TYP_INT8: begin
                signature := 'i8';
            end;
            TYP_LONG: begin
                signature := 'l';
            end;
            TYP_LONG2: begin
                signature := 'l2';
            end;
            TYP_LONG4: begin
                signature := 'l4';
            end;
            TYP_LONG8: begin
                signature := 'l8';
            end;
            else
                signature := '';
            end;
            result := writeString(signature);
        end;

        function AssemblerElementWriter.writeSignature(&type: &Type; flags: int): AssemblerElementWriter;
        var
            signature: AnsiString;
        begin
            case &type.kind of
            TYP_REF: begin
                if (flags and WEAK) <> 0 then begin
                    signature := 'w';
                end else begin
                    signature := 'r';
                end;
            end;
            TYP_CHAR: begin
                if (flags and STACK) <> 0 then begin
                    signature := 'i';
                end else begin
                    signature := 'c';
                end;
            end;
            TYP_REAL: begin
                signature := 'e';
            end;
            TYP_DOUBLE: begin
                signature := 'd';
            end;
            TYP_DOUBLE2: begin
                signature := 'd2';
            end;
            TYP_DOUBLE4: begin
                signature := 'd4';
            end;
            TYP_DOUBLE8: begin
                signature := 'd8';
            end;
            TYP_FLOAT: begin
                signature := 'f';
            end;
            TYP_FLOAT2: begin
                signature := 'f2';
            end;
            TYP_FLOAT4: begin
                signature := 'f4';
            end;
            TYP_FLOAT8: begin
                signature := 'f8';
            end;
            TYP_BOOLEAN,
            TYP_BYTE: begin
                if (flags and STACK) <> 0 then begin
                    signature := 'i';
                end else begin
                    signature := 'b';
                end;
            end;
            TYP_BYTE2: begin
                signature := 'b2';
            end;
            TYP_BYTE4: begin
                signature := 'b4';
            end;
            TYP_BYTE8: begin
                signature := 'b8';
            end;
            TYP_SHORT: begin
                if (flags and STACK) <> 0 then begin
                    signature := 'i';
                end else begin
                    signature := 's';
                end;
            end;
            TYP_SHORT2: begin
                signature := 's2';
            end;
            TYP_SHORT4: begin
                signature := 's4';
            end;
            TYP_SHORT8: begin
                signature := 's8';
            end;
            TYP_INT: begin
                signature := 'i';
            end;
            TYP_INT2: begin
                signature := 'i2';
            end;
            TYP_INT4: begin
                signature := 'i4';
            end;
            TYP_INT8: begin
                signature := 'i8';
            end;
            TYP_LONG: begin
                signature := 'l';
            end;
            TYP_LONG2: begin
                signature := 'l2';
            end;
            TYP_LONG4: begin
                signature := 'l4';
            end;
            TYP_LONG8: begin
                signature := 'l8';
            end;
            else
                signature := '';
            end;
            result := writeString(signature);
        end;

        function AssemblerElementWriter.&set(const text: char_Array1d): AssemblerElementWriter;
        begin
            result := &set(text, 0);
        end;
    {%endregion}

    {%region  AssemblerSourcePrintStream }
        class function AssemblerSourcePrintStream.getSeparator(state: int): AnsiString;
        begin
            if state > 0 then begin
                result := CoAnsiString.LINE_ENDING;
                exit;
            end;
            result := '';
        end;

        class procedure AssemblerSourcePrintStream.initialize();
        begin
            defaultEncoder := Charset.getDefault().newEncoder();
        end;

        class procedure AssemblerSourcePrintStream.finalize();
        begin
            defaultEncoder.free();
        end;

        procedure AssemblerSourcePrintStream.write(const src: char);
        begin
            fldText := fldText + src;
        end;

        procedure AssemblerSourcePrintStream.write(const src: AnsiString);
        begin
            fldText := fldText + src;
        end;

        function AssemblerSourcePrintStream.spaces(count: int): AnsiString;
        var
            capacity: int;
            buffer: char_Array1d;
        begin
            buffer := fldSpaces;
            if count > system.length(buffer) then begin
                capacity := AVTOOService.getBestArrayCapacity(count);
                buffer := &Array.newChar1d(capacity);
                &Array.fillPrimitives(buffer, 0, capacity, #$20);
                fldSpaces := buffer;
            end;
            result := AnsiString.create(buffer, 0, count);
        end;

        constructor AssemblerSourcePrintStream.create();
        begin
            create(nil);
        end;

        constructor AssemblerSourcePrintStream.create(encoder: CharEncoder);
        var
            buffer: char_Array1d;
        begin
            inherited create();
            buffer := &Array.newChar1d($ff);
            &Array.fillPrimitives(buffer, 0, $ff, #$20);
            if encoder = nil then encoder := defaultEncoder;
            fldSpaces := buffer;
            fldEncoder := encoder;
        end;

        procedure AssemblerSourcePrintStream.saveToOutputStream(stream: ByteWriter);
        begin
            saveToOutputStream(stream, nil);
        end;

        procedure AssemblerSourcePrintStream.saveToOutputStream(stream: ByteWriter; encoder: CharEncoder);
        begin
            if encoder = nil then encoder := fldEncoder;
            encoder.encodeToWriter(stream, fldText.toUTF16());
        end;

        procedure AssemblerSourcePrintStream.clear();
        begin
            fldState := 0;
            fldMargin := 0;
            fldText := '';
        end;

        procedure AssemblerSourcePrintStream.increaseMargin();
        begin
            inc(fldMargin);
        end;

        procedure AssemblerSourcePrintStream.decreaseMargin();
        begin
            dec(fldMargin);
        end;

        procedure AssemblerSourcePrintStream.print(const src: AnsiString);
        begin
            write(src);
            fldState := 1;
        end;

        procedure AssemblerSourcePrintStream.printHeader(const header: AnsiString);
        begin
            write(getSeparator(fldState));
            write(spaces(CoInt.max(fldMargin, 0) shl 2));
            write(header);
            fldState := 1;
        end;

        procedure AssemblerSourcePrintStream.printLabel(const &label: AnsiString);
        var
            str: AnsiString;
        begin
            str := &label;
            if str.length <= 0 then str := #$20#$20#$20#$20#$20'@@';
            write(getSeparator(fldState));
            write(spaces(CoInt.max(fldMargin, 0) shl 2));
            write(str);
            write(':');
            fldState := str.length + 1;
        end;

        procedure AssemblerSourcePrintStream.printInstruction(const mnemonic: AnsiString);
        var
            state: int;
            str: AnsiString;
        begin
            str := mnemonic;
            if str.length <= 0 then str := 'nop';
            state := fldState;
            if (state < 0) or (state > 1) and (state < 12) then begin
                write(spaces(CoInt.max(12 - state, 1)));
            end else begin
                write(getSeparator(state));
                write(spaces((CoInt.max(fldMargin, 0) + 3) shl 2));
            end;
            write(str);
            fldState := 1;
        end;

        procedure AssemblerSourcePrintStream.printInstruction(const mnemonic, operand: AnsiString);
        var
            state: int;
            str: AnsiString;
        begin
            str := mnemonic;
            if str.length <= 0 then str := 'nop';
            state := fldState;
            if (state < 0) or (state > 1) and (state < 12) then begin
                write(spaces(CoInt.max(12 - state, 1)));
            end else begin
                write(getSeparator(state));
                write(spaces((CoInt.max(fldMargin, 0) + 3) shl 2));
            end;
            write(str);
            write(spaces(CoInt.max(12 - str.length, 1)));
            write(operand);
            fldState := 1;
        end;

        procedure AssemblerSourcePrintStream.printInstruction(const mnemonic: AnsiString; const operands: AnsiString_Array1d; offset, length: int);
        var
            state: int;
            limit: int;
            bounds: int2;
            str: AnsiString;
        begin
            str := mnemonic;
            if str.length <= 0 then str := 'nop';
            if operands = nil then begin
                offset := 0;
                length := 0;
            end else begin
                bounds := VArray.intersectBounds(operands, offset, length);
                offset := bounds[0];
                length := bounds[1];
            end;
            state := fldState;
            if (state < 0) or (state > 1) and (state < 12) then begin
                write(spaces(CoInt.max(12 - state, 1)));
            end else begin
                write(getSeparator(state));
                write(spaces((CoInt.max(fldMargin, 0) + 3) shl 2));
            end;
            write(str);
            if length > 0 then begin
                write(spaces(CoInt.max(12 - str.length, 1)));
            end;
            limit := offset + length - 1;
            while offset <= limit do begin
                write(operands[offset]);
                if offset < limit then write(','#$20);
                inc(offset);
            end;
            fldState := 1;
        end;

        procedure AssemblerSourcePrintStream.printContinuation(const operands: AnsiString_Array1d; offset, length: int);
        var
            limit: int;
            bounds: int2;
        begin
            if operands = nil then begin
                offset := 0;
                length := 0;
            end else begin
                bounds := VArray.intersectBounds(operands, offset, length);
                offset := bounds[0];
                length := bounds[1];
            end;
            write(getSeparator(fldState));
            write(spaces((CoInt.max(fldMargin, 0) + 6) shl 2));
            limit := offset + length - 1;
            while offset <= limit do begin
                write(operands[offset]);
                if offset < limit then write(','#$20);
                inc(offset);
            end;
            fldState := 1;
        end;

        procedure AssemblerSourcePrintStream.println();
        begin
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        procedure AssemblerSourcePrintStream.println(const src: AnsiString);
        begin
            write(src);
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        procedure AssemblerSourcePrintStream.printlnHeader(const header: AnsiString);
        begin
            write(getSeparator(fldState));
            write(spaces(CoInt.max(fldMargin, 0) shl 2));
            write(header);
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        procedure AssemblerSourcePrintStream.printlnLabel(const &label: AnsiString);
        var
            str: AnsiString;
        begin
            str := &label;
            if str.length <= 0 then str := #$20#$20#$20#$20#$20'@@';
            write(getSeparator(fldState));
            write(spaces(CoInt.max(fldMargin, 0) shl 2));
            write(str);
            write(':');
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        procedure AssemblerSourcePrintStream.printlnInstruction(const mnemonic: AnsiString);
        var
            state: int;
            str: AnsiString;
        begin
            str := mnemonic;
            if str.length <= 0 then str := 'nop';
            state := fldState;
            if (state < 0) or (state > 1) and (state < 12) then begin
                write(spaces(CoInt.max(12 - state, 1)));
            end else begin
                write(getSeparator(state));
                write(spaces((CoInt.max(fldMargin, 0) + 3) shl 2));
            end;
            write(str);
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        procedure AssemblerSourcePrintStream.printlnInstruction(const mnemonic, operand: AnsiString);
        var
            state: int;
            str: AnsiString;
        begin
            str := mnemonic;
            if str.length <= 0 then str := 'nop';
            state := fldState;
            if (state < 0) or (state > 1) and (state < 12) then begin
                write(spaces(CoInt.max(12 - state, 1)));
            end else begin
                write(getSeparator(state));
                write(spaces((CoInt.max(fldMargin, 0) + 3) shl 2));
            end;
            write(str);
            write(spaces(CoInt.max(12 - str.length, 1)));
            write(operand);
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        procedure AssemblerSourcePrintStream.printlnInstruction(const mnemonic: AnsiString; const operands: AnsiString_Array1d; offset, length: int);
        var
            state: int;
            limit: int;
            bounds: int2;
            str: AnsiString;
        begin
            str := mnemonic;
            if str.length <= 0 then str := 'nop';
            if operands = nil then begin
                offset := 0;
                length := 0;
            end else begin
                bounds := VArray.intersectBounds(operands, offset, length);
                offset := bounds[0];
                length := bounds[1];
            end;
            state := fldState;
            if (state < 0) or (state > 1) and (state < 12) then begin
                write(spaces(CoInt.max(12 - state, 1)));
            end else begin
                write(getSeparator(state));
                write(spaces((CoInt.max(fldMargin, 0) + 3) shl 2));
            end;
            write(str);
            if length > 0 then begin
                write(spaces(CoInt.max(12 - str.length, 1)));
            end;
            limit := offset + length - 1;
            while offset <= limit do begin
                write(operands[offset]);
                if offset < limit then write(','#$20);
                inc(offset);
            end;
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        procedure AssemblerSourcePrintStream.printlnContinuation(const operands: AnsiString_Array1d; offset, length: int);
        var
            limit: int;
            bounds: int2;
        begin
            if operands = nil then begin
                offset := 0;
                length := 0;
            end else begin
                bounds := VArray.intersectBounds(operands, offset, length);
                offset := bounds[0];
                length := bounds[1];
            end;
            write(getSeparator(fldState));
            write(spaces((CoInt.max(fldMargin, 0) + 6) shl 2));
            limit := offset + length - 1;
            while offset <= limit do begin
                write(operands[offset]);
                if offset < limit then write(','#$20);
                inc(offset);
            end;
            write(CoAnsiString.LINE_ENDING);
            fldState := 0;
        end;

        function AssemblerSourcePrintStream.isEmpty(): boolean;
        begin
            result := ((fldMargin or fldState) = 0) and (fldText = '');
        end;
    {%endregion}

    {%region  AssemblerSourceGenerator }
        class procedure AssemblerSourceGenerator.setResourceLocation(table: HashtableOfUnicodeStringToResourceLocation; const name: UnicodeString; newLocation: ResourceLocation);
        var
            oldLocation: ResourceLocation;
        begin
            oldLocation := table[name];
            if (oldLocation <> nil) and (oldLocation <> newLocation) then oldLocation.free();
            table[name] := newLocation;
        end;

        class procedure AssemblerSourceGenerator.clearResourcesTable(table: HashtableOfUnicodeStringToResourceLocation);
        var
            index: int;
            key: UnicodeString;
            value: TObject;
        begin
            for index := table.length - 1 downto 0 do begin
                key := table.keyAt(index);
                value := table[key];
                table[key] := nil;
                value.free();
            end;
        end;

        class procedure AssemblerSourceGenerator.freeResourcesTable(table: HashtableOfUnicodeStringToResourceLocation);
        begin
            clearResourcesTable(table);
            table.free();
        end;

        class function AssemblerSourceGenerator.isTypeCastAvailable(kindBaseOfSrc, lengthOfSrc, kindBaseOfNew, lengthOfNew: int): boolean;
        begin
            result := (
                (kindBaseOfSrc <> kindBaseOfNew) or (lengthOfSrc <> lengthOfNew)
            ) and (
                (lengthOfSrc > 1) or (lengthOfNew > 1) or
                ((kindBaseOfSrc <> TYP_BYTE) or (kindBaseOfNew <> TYP_SHORT) and (kindBaseOfNew <> TYP_INT)) and ((kindBaseOfSrc <> TYP_SHORT) or (kindBaseOfNew <> TYP_INT))
            );
        end;

        class function AssemblerSourceGenerator.toRuntimePrimitiveKind(kind: int): int;
        const
            CLASS_VOID    = int(8);
            CLASS_BOOLEAN = int(16);
            CLASS_CHAR    = int(20);
            CLASS_BYTE    = int(24);
            CLASS_SHORT   = int(28);
            CLASS_INT     = int(32);
            CLASS_LONG    = int(36);
            CLASS_FLOAT   = int(40);
            CLASS_DOUBLE  = int(44);
            CLASS_REAL    = int(48);
        begin
            case kind of
            TYP_VOID:
                result := CLASS_VOID;
            TYP_BOOLEAN:
                result := CLASS_BOOLEAN;
            TYP_CHAR:
                result := CLASS_CHAR;
            TYP_REAL:
                result := CLASS_REAL;
            TYP_DOUBLE,
            TYP_DOUBLE2,
            TYP_DOUBLE4,
            TYP_DOUBLE8:
                result := kind and 3 or CLASS_DOUBLE;
            TYP_FLOAT,
            TYP_FLOAT2,
            TYP_FLOAT4,
            TYP_FLOAT8:
                result := kind and 3 or CLASS_FLOAT;
            TYP_BYTE,
            TYP_BYTE2,
            TYP_BYTE4,
            TYP_BYTE8:
                result := kind and 3 or CLASS_BYTE;
            TYP_SHORT,
            TYP_SHORT2,
            TYP_SHORT4,
            TYP_SHORT8:
                result := kind and 3 or CLASS_SHORT;
            TYP_INT,
            TYP_INT2,
            TYP_INT4,
            TYP_INT8:
                result := kind and 3 or CLASS_INT;
            TYP_LONG,
            TYP_LONG2,
            TYP_LONG4,
            TYP_LONG8:
                result := kind and 3 or CLASS_LONG;
            else
                result := 0;
            end;
        end;

        class function AssemblerSourceGenerator.getNeedRegisterTypeKind(node: Node): int;
        var
            kind: int;
            jump: Node;
            operand: TableItem;
            synthetic: Callable;
            __property: &Property;
        begin
            if node <> nil then repeat
                case node.instruction of
                SWAP,
                FCT_THROW,
                REF_EQ,
                REF_NE,
                EXP_INSTANCEOF,
                REF_IS_NULL,
                REF_IS_OBJECT,
                NEW_ARRAY_MULTI: begin
                    result := TYP_REF;
                    exit;
                end;
                FCT_BRANCH,
                NEW_ARRAY_MONO: begin
                    result := TYP_INT;
                    exit;
                end;
                DUP1,
                DUP2,
                DUP1X1,
                DUP1X2,
                TEST_EQZ,
                TEST_NEZ,
                O_BIT_OR,
                O_BIT_AND,
                O_BIT_XOR,
                O_BIT_NOT,
                O_SCAL_NEG,
                O_SCAL_MUL,
                O_SCAL_DIV,
                O_SCAL_DIVU,
                O_SCAL_REM,
                O_SCAL_REMU,
                O_SCAL_ADD,
                O_SCAL_SUB,
                O_SCAL_EQ,
                O_SCAL_NE,
                O_SCAL_GT,
                O_SCAL_GE,
                O_SCAL_LT,
                O_SCAL_LE,
                O_VECT_LUP,
                O_VECT_UUP,
                O_VECT_PCK,
                O_VECT_NEG,
                O_VECT_MUL,
                O_VECT_DIV,
                O_VECT_ADD,
                O_VECT_SUB,
                O_VECT_EQ,
                O_VECT_NE,
                O_VECT_GT,
                O_VECT_GE,
                O_VECT_LT,
                O_VECT_LE,
                O_VECT_HMUL,
                O_VECT_HMULU,
                O_VECT_SADD,
                O_VECT_SADDU,
                O_VECT_SSUB,
                O_VECT_SSUBU: begin
                    result := (node.operand1 as &Type).kind;
                    exit;
                end;
                WRITE_COMPONENT: begin
                    kind := (node.operand1 as &Type).kind;
                    if kind = TYP_REF then break;
                    result := kind;
                    exit;
                end;
                CAST_TO: begin
                    result := (node.operand2 as &Type).kind;
                    exit;
                end;
                WRITE_FIELD: begin
                    result := (node.operand1 as TypedMember).&type.kind;
                    exit;
                end;
                WRITE_SPECIAL: begin
                    __property := node.operand1 as &Property;
                    if __property.hasIndex() or not Lang.isInstance(__property.writeMember, Field) then break;
                    result := __property.&type.kind;
                    exit;
                end;
                WRITE_PROPERTY: begin
                    __property := node.operand1 as &Property;
                    synthetic := __property.writeSynthetic;
                    if __property.hasIndex() or ((synthetic.serviceIndex and synthetic.virtualIndex) >= 0) or not Lang.isInstance(__property.writeMember, Field) then break;
                    result := __property.&type.kind;
                    exit;
                end;
                NEW_VECTOR: begin
                    result := (node.operand1 as PrimitiveType).vectorBaseKind;
                    exit;
                end;
                READ_FIELD: begin
                    if (node.operand2 <> nil) or (node.operandC <> nil) then break;
                    result := TYP_REF;
                    exit;
                end;
                READ_SPECIAL: begin
                    __property := node.operand1 as &Property;
                    if __property.hasIndex() or not Lang.isInstance(__property.readMember, Field) or (node.operand2 <> nil) or (node.operandC <> nil) then break;
                    result := TYP_REF;
                    exit;
                end;
                READ_PROPERTY: begin
                    __property := node.operand1 as &Property;
                    synthetic := __property.readSynthetic;
                    if
                        __property.hasIndex() or ((synthetic.serviceIndex and synthetic.virtualIndex) >= 0) or not Lang.isInstance(__property.readMember, Field) or
                        (node.operand2 <> nil) or (node.operandC <> nil)
                    then break;
                    result := TYP_REF;
                    exit;
                end;
                READ_COMPONENT: begin
                    if (node.operand2 = nil) and (node.operandC = nil) then begin
                        result := TYP_INT;
                        exit;
                    end;
                    result := TYP_REF;
                    exit;
                end;
                O_SCAL_SHL,
                O_SCAL_SHR,
                O_SCAL_SHRU,
                O_VECT_SHL,
                O_VECT_SHR,
                O_VECT_SHRU,
                READ_ELEMENT: begin
                    if (node.operand2 = nil) and (node.operandC = nil) then begin
                        result := TYP_INT;
                        exit;
                    end;
                    result := (node.operand1 as &Type).kind;
                    exit;
                end;
                STORE_STATIC: begin
                    if (node.operand2 <> nil) or (node.operandC <> nil) then break;
                    result := (node.operand1 as Field).&type.kind;
                    exit;
                end;
                STORE_LOCAL,
                DECLARE_WITH,
                DECLARE_LOCAL: begin
                    if node.operandC <> nil then break;
                    operand := node.operand2;
                    if operand is &Type then begin
                        result := &Type(operand).kind;
                        exit;
                    end;
                    result := (node.operand1 as Local).&type.kind;
                    exit;
                end;
                FCT_RETURN,
                METHOD_LEAVE: begin
                    result := node.parentCode.parentCallable.&type.kind;
                    exit;
                end;
                FCT_JUMP: begin
                    jump := node.jumpDefault;
                    if node = jump then break;
                    node := jump;
                end;
                else
                    break;
                end;
            until false;
            result := 0;
        end;

        class function AssemblerSourceGenerator.getPayLength(const aarray: char_Array1d): int;
        var
            length: int;
        begin
            length := &Array.indexOf(#0, aarray, 0, 0);
            if length < 0 then length := system.length(aarray);
            result := length;
        end;

        class function AssemblerSourceGenerator.getPayLengthPtr(const aarray): int;
        var
            length: int;
        begin
            length := &Array.indexOf(nil, aarray, 0, 0);
            if length < 0 then length := system.length(Pointer_Array1d(aarray));
            result := length;
        end;

        class function AssemblerSourceGenerator.toString(const aarray: char_Array1d): AnsiString;
        begin
            result := AnsiString.create(aarray, 0, getPayLength(aarray));
        end;

        class function AssemblerSourceGenerator.getTypedItem(itemC: Constant; itemI: TableItem): TypedItem;
        begin
            if itemC <> nil then begin
                result := TypedItem(Lang.cast(itemC, TypedItem));
                exit;
            end;
            if itemI <> nil then begin
                result := itemI as TypedItem;
                exit;
            end;
            result := nil;
        end;

        procedure AssemblerSourceGenerator.findSourcesIn(__library: &Library);
        var
            oname: UnicodeString;
            directoryPath: UnicodeString;
            table: HashtableOfUnicodeStringToLibrary;
        begin
            table := fldSourcesTable;
            with __library.fileSystem do begin
                directoryPath := __library.directoryPath + ASSEMBLER_SOURCE_PATH;
                if isObjectExists(directoryPath) then with findFirst(directoryPath + '/') do try
                    repeat
                        oname := name;
                        if not isObjectNameCaseSensitive() then oname := oname.toLowerCase();
                        if (oname <> '.') and (oname <> '..') and (oname <> 'code') and (oname <> 'data') and (oname <> 'dbgi') then begin
                            if directory then begin
                                findSourcesIn(__library, oname + '/');
                            end else begin
                                table[oname] := __library;
                            end;
                        end;
                    until not findNext();
                finally
                    close();
                end;
            end;
        end;

        procedure AssemblerSourceGenerator.findSourcesIn(__library: &Library; const __relativePath: UnicodeString);
        var
            path: UnicodeString;
            oname: UnicodeString;
            table: HashtableOfUnicodeStringToLibrary;
        begin
            table := fldSourcesTable;
            with __library.fileSystem.findFirst(__library.directoryPath + (ASSEMBLER_SOURCE_PATH + '/') + __relativePath) do try
                repeat
                    oname := name;
                    if (oname <> '.') and (oname <> '..') then begin
                        if directory then begin
                            findSourcesIn(__library, __relativePath + oname + '/');
                        end else begin
                            path := __relativePath + oname;
                            table[path] := __library;
                        end;
                    end;
                until not findNext();
            finally
                close();
            end;
        end;

        procedure AssemblerSourceGenerator.constantToFasmString(value: Constant; const operand: char_Array1d);
        var
            ivalue: int;
            bvalue: AnsiString;
        begin
            if value.isNull() then begin
                getAssemblerElementWriter().&set(operand).writeString('null').trim();
                exit;
            end;
            if value.isReflective() then begin
                getAssemblerElementWriter().&set(operand).writeString((value.asObject() as RequiredReflectItem).fasmFullName).trim();
                exit;
            end;
            if value.isBoolean() then begin
                if value.asBoolean() then begin
                    bvalue := 'true';
                end else begin
                    bvalue := 'false';
                end;
                getAssemblerElementWriter().&set(operand).writeString(bvalue).trim();
                exit;
            end;
            case value.&type.kind of
            TYP_REAL:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$e+').writeDecimal(fldRealStorage.indexAcquire(value.asReal()) * 10).writeChar(']').trim();
            TYP_DOUBLE:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$d+').writeOffset(fldDoubleStorage.indexAcquire(value.asDouble()) shl 4).writeChar(']').trim();
            TYP_DOUBLE2:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$d2+').writeOffset(fldDouble2Storage.indexAcquire(value.asDouble2()) shl 4).writeChar(']').trim();
            TYP_DOUBLE4:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$d4+').writeOffset(fldDouble4Storage.indexAcquire(value.asDouble4()) shl 5).writeChar(']').trim();
            TYP_DOUBLE8:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$d8+').writeOffset(fldDouble8Storage.indexAcquire(value.asDouble8()) shl 6).writeChar(']').trim();
            TYP_FLOAT:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$f+').writeOffset(fldFloatStorage.indexAcquire(value.asFloat()) shl 4).writeChar(']').trim();
            TYP_FLOAT2:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$f2+').writeOffset(fldFloat2Storage.indexAcquire(value.asFloat2()) shl 4).writeChar(']').trim();
            TYP_FLOAT4:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$f4+').writeOffset(fldFloat4Storage.indexAcquire(value.asFloat4()) shl 4).writeChar(']').trim();
            TYP_FLOAT8:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$f8+').writeOffset(fldFloat8Storage.indexAcquire(value.asFloat8()) shl 5).writeChar(']').trim();
            TYP_BYTE2:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$b2+').writeOffset(fldByte2Storage.indexAcquire(value.asByte2()) shl 4).writeChar(']').trim();
            TYP_BYTE4:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$b4+').writeOffset(fldByte4Storage.indexAcquire(value.asByte4()) shl 4).writeChar(']').trim();
            TYP_BYTE8:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$b8+').writeOffset(fldByte8Storage.indexAcquire(value.asByte8()) shl 4).writeChar(']').trim();
            TYP_SHORT2:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$s2+').writeOffset(fldShort2Storage.indexAcquire(value.asShort2()) shl 4).writeChar(']').trim();
            TYP_SHORT4:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$s4+').writeOffset(fldShort4Storage.indexAcquire(value.asShort4()) shl 4).writeChar(']').trim();
            TYP_SHORT8:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$s8+').writeOffset(fldShort8Storage.indexAcquire(value.asShort8()) shl 4).writeChar(']').trim();
            TYP_INT2:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$i2+').writeOffset(fldInt2Storage.indexAcquire(value.asInt2()) shl 4).writeChar(']').trim();
            TYP_INT4:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$i4+').writeOffset(fldInt4Storage.indexAcquire(value.asInt4()) shl 4).writeChar(']').trim();
            TYP_INT8:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$i8+').writeOffset(fldInt8Storage.indexAcquire(value.asInt8()) shl 5).writeChar(']').trim();
            TYP_LONG:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$l+').writeOffset(fldLongStorage.indexAcquire(value.asLong()) shl 3).writeChar(']').trim();
            TYP_LONG2:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$l2+').writeOffset(fldLong2Storage.indexAcquire(value.asLong2()) shl 4).writeChar(']').trim();
            TYP_LONG4:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$l4+').writeOffset(fldLong4Storage.indexAcquire(value.asLong4()) shl 5).writeChar(']').trim();
            TYP_LONG8:
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString('cons$l8+').writeOffset(fldLong8Storage.indexAcquire(value.asLong8()) shl 6).writeChar(']').trim();
            else
                ivalue := value.asInt();
                if ivalue >= 0 then begin
                    getAssemblerElementWriter().&set(operand).writeInt(ivalue).trim();
                    exit;
                end;
                getAssemblerElementWriter().&set(operand).writeChar('-').writeInt(-ivalue).trim();
            end;
        end;

        function AssemblerSourceGenerator.additionalToFasmString(operandC: Constant; operandI: TableItem; const operand: char_Array1d): AnsiString;
        begin
            if operandC <> nil then begin
                constantToFasmString(operandC, operand);
                result := '_g';
                exit;
            end;
            if operandI = nil then begin
                getAssemblerElementWriter().&set(operand).trim();
                result := '';
                exit;
            end;
            if operandI is Local then begin
                getAssemblerElementWriter().&set(operand).writeString(operandI.fasmSimpleName).trim();
                result := '_l';
                exit;
            end;
            if operandI is Field then begin
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString(Field(operandI).fasmFullName).writeChar(']').trim();
                result := '_g';
                exit;
            end;
            raise IllegalArgumentException.create(AnsiString.format(AResource.readUnitResourceAsAnsiString(pascalx.lang.UNIT_NAME, 'illegal-argument'), [ CoAnsiString.create('operandI') ]));
        end;

        function AssemblerSourceGenerator.additionalToFasmString(operandC: Constant; operandI: TableItem; const operand: char_Array1d; refsLocalTable: HashtableOfAnsiStringToType): AnsiString;
        var
            name: AnsiString;
        begin
            if operandC <> nil then begin
                constantToFasmString(operandC, operand);
                result := '_g';
                exit;
            end;
            if operandI = nil then begin
                getAssemblerElementWriter().&set(operand).trim();
                result := '';
                exit;
            end;
            if operandI is Local then begin
                name := operandI.fasmSimpleName;
                if not Local(operandI).&type.isPrimitive() and refsLocalTable.contains(name) then begin
                    getAssemblerElementWriter().&set(operand).writeChar('$').writeString(name).trim();
                end else begin
                    getAssemblerElementWriter().&set(operand).writeString(name).trim();
                end;
                result := '_l';
                exit;
            end;
            if operandI is Field then begin
                getAssemblerElementWriter().&set(operand).writeChar('[').writeString(Field(operandI).fasmFullName).writeChar(']').trim();
                result := '_g';
                exit;
            end;
            raise IllegalArgumentException.create(AnsiString.format(AResource.readUnitResourceAsAnsiString(pascalx.lang.UNIT_NAME, 'illegal-argument'), [ CoAnsiString.create('operandI') ]));
        end;

        procedure AssemblerSourceGenerator.findResourcesIn(__library: &Library);
        var
            directoryPath: UnicodeString;
        begin
            directoryPath := __library.directoryPath;
            with __library.fileSystem do begin
                if isObjectExists(directoryPath + TEXT_SOURCE_MAIN_PATH) then begin
                    findResourcesIn(__library, TEXT_SOURCE_MAIN_PATH + '/');
                    exit;
                end;
                if isObjectExists(directoryPath + TEXT_SOURCE_ALTERNATIVE_PATH) then begin
                    findResourcesIn(__library, TEXT_SOURCE_ALTERNATIVE_PATH + '/');
                end;
            end;
        end;

        procedure AssemblerSourceGenerator.findResourcesIn(__library: &Library; const __relativePath: UnicodeString);
        var
            path: UnicodeString;
            oname: UnicodeString;
            table: HashtableOfUnicodeStringToResourceLocation;
        begin
            table := fldResourcesTable;
            with __library.fileSystem.findFirst(__library.directoryPath + __relativePath) do try
                repeat
                    oname := name;
                    if (oname <> '.') and (oname <> '..') then begin
                        if directory then begin
                            findResourcesIn(__library, __relativePath + oname + '/');
                        end else
                        if not isTypeSourceFileName(oname) then begin
                            path := __relativePath.substring(__relativePath.indexOf('/')).replaceAll('.', '/') + oname;
                            setResourceLocation(table, path, ResourceLocation.create(__library, __relativePath + oname));
                        end;
                    end;
                until not findNext();
            finally
                close();
            end;
        end;

        procedure AssemblerSourceGenerator.generatePackageData(__pack, __next: Package; output: AssemblerSourcePrintStream);
        var
            tcount: int;
            tindex: int;
            tlength: int;
            intZero: AnsiString;
            longZero: AnsiString;
            specialCanonicalName: AnsiString;
            operandA: char_Array1d;
            operandB: char_Array1d;
            operands: AnsiString_Array1d;
            __type: &Type;
            writer: AssemblerElementWriter;
        begin
            writer := getAssemblerElementWriter();
            tcount := 0;
            tlength := __pack.getLength();
            operandA := &Array.newChar1d($0100);
            operandB := &Array.newChar1d($0020);
            intZero := writer.&set(operandB).writeInt(0).get();
            longZero := writer.&set(operandB).writeLong(0).get();
            operands := &Array.newAnsiString1d(4);
            specialCanonicalName := __pack.specialCanonicalName;
            if specialCanonicalName = '' then specialCanonicalName := AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.system-package');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            for tindex := 0 to tlength - 1 do if __pack.readComponent(tindex).isCompilable() then inc(tcount);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.println();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printHeader('; <fold ');
            output.print(specialCanonicalName);
            output.print(' — ');
            output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.data.package'));
            output.println('>');
            output.increaseMargin();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnInstruction('package', __pack.fasmFullName);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := writer.&set(operandA).writeInt(__pack.attributes).get();
            operands[1] := writer.&set(operandB).writeInt(fldStringStorage.indexAcquire(__pack.specialSimpleName.toUTF16())).get();
            operands[2] := intZero;
            operands[3] := intZero;
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := intZero;
            operands[1] := intZero;
            operands[2] := intZero;
            operands[3] := writer.&set(operandA).writeInt(tcount).get();
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := intZero;
            operands[1] := intZero;
            operands[2] := intZero;
            operands[3] := intZero;
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := intZero;
            operands[1] := intZero;
            operands[2] := intZero;
            operands[3] := '-.this+.$type$';
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := intZero;
            operands[1] := intZero;
            operands[2] := intZero;
            operands[3] := intZero;
            output.printlnInstruction('dd', operands, 0, 4);
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := longZero;
            operands[1] := longZero;
            if __next = nil then begin
                operands[2] := writer.&set(operandA).writeLong(0).get();
            end else begin
                operands[2] := writer.&set(operandA).writeString('-.this+').writeString(__next.fasmFullName).get();
            end;
            operands[3] := longZero;
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 2, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := longZero;
            operands[1] := longZero;
            output.printlnInstruction('dq', operands, 0, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := intZero;
            operands[1] := intZero;
            operands[2] := intZero;
            operands[3] := '-.this+.$iend$';
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := longZero;
            operands[1] := longZero;
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 0, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printLabel('.$type$');
            for tindex := 0 to tlength - 1 do begin
                __type := __pack.readComponent(tindex);
                if __type.isCompilable() then begin
                    writer.&set(operandA).writeString('-.$type$+').writeString(__type.fasmFullName).trim();
                    output.printlnInstruction('dq', toString(operandA));
                end;
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnLabel('.$iend$');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
        end;

        procedure AssemblerSourceGenerator.generatePrimitiveData(__type: PrimitiveType; output: AssemblerSourcePrintStream);
        var
            intZero: AnsiString;
            longZero: AnsiString;
            operandA: char_Array1d;
            operandB: char_Array1d;
            operandC: char_Array1d;
            operands: AnsiString_Array1d;
            writer: AssemblerElementWriter;
        begin
            writer := getAssemblerElementWriter();
            operandA := &Array.newChar1d($0100);
            operandB := &Array.newChar1d($0020);
            operandC := &Array.newChar1d($0020);
            intZero := writer.&set(operandB).writeInt(0).get();
            longZero := writer.&set(operandB).writeLong(0).get();
            operands := &Array.newAnsiString1d(4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.println();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printHeader('; <fold ');
            output.print(__type.specialCanonicalName);
            output.print(' — ');
            output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.data.type'));
            output.println('>');
            output.increaseMargin();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnInstruction('class', __type.fasmFullName);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := writer.&set(operandA).writeInt(__type.attributes).get();
            operands[1] := writer.&set(operandB).writeInt(fldStringStorage.indexAcquire(__type.specialSimpleName.toUTF16())).get();
            operands[2] := writer.&set(operandC).writeInt(__type.fieldWidth).get();
            operands[3] := intZero;
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := intZero;
            operands[1] := intZero;
            operands[2] := intZero;
            operands[3] := intZero;
            output.printlnInstruction('dd', operands, 0, 4);
            output.printlnInstruction('dd', operands, 0, 4);
            output.printlnInstruction('dd', operands, 0, 4);
            output.printlnInstruction('dd', operands, 0, 4);
            output.printlnInstruction('dd', operands, 0, 4);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := longZero;
            operands[1] := longZero;
            operands[2] := writer.&set(operandA).writeString('-.this+').writeString(__type.parentPackage.fasmFullName).get();
            operands[3] := longZero;
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 2, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := longZero;
            operands[1] := longZero;
            output.printlnInstruction('dq', operands, 0, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnInstruction('dq', longZero);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := writer.&set(operandA).writeInt(toRuntimePrimitiveKind(__type.kind)).get();
            operands[1] := '-.this+.$iend$';
            output.printlnInstruction('dd', operands, 0, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := longZero;
            operands[1] := longZero;
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 0, 2);
            output.printlnInstruction('dq', operands, 0, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnLabel('.$iend$');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
        end;

        procedure AssemblerSourceGenerator.generateClassData(__type: ClassType; output: AssemblerSourcePrintStream);
        type
            Field_Array1d    = specialize DynamicArray<Field>;
            Property_Array1d = specialize DynamicArray<&Property>;
        var
            hasName: boolean;
            isClass: boolean;
            isHelper: boolean;
            isStruct: boolean;
            isService: boolean;
            isReflect: boolean;
            limit: int;
            index: int;
            aindex: int;
            cindex: int;
            sindex: int;
            tindex: int;
            vindex: int;
            ivalue: int;
            length: int;
            flength: int;
            glength: int;
            ilength: int;
            mlength: int;
            nlength: int;
            plength: int;
            slength: int;
            tlength: int;
            vlength: int;
            tcapacity: int;
            i8value: int8;
            l8value: long8;
            l2value: long2 absolute l8value;
            name: AnsiString;
            gname: AnsiString;
            mnmnc: AnsiString;
            intZero: AnsiString;
            longZero: AnsiString;
            implements: AnsiString;
            fasmFullName: AnsiString;
            specialCanonicalName: AnsiString;
            source: UnicodeString;
            operandA: char_Array1d;
            operandB: char_Array1d;
            operandC: char_Array1d;
            operandD: char_Array1d;
            fasmNums: char_Array2d;
            dmai: int_Array1d;
            operands: AnsiString_Array1d;
            rfld: Field_Array1d; { нулевые ссылки в конце! }
            sfld: Field_Array1d; { нулевые ссылки в конце! }
            dfld: Field_Array1d; { нулевые ссылки в конце! }
            buffer: Field_Array1d;
            globals: Field_Array1d; { нулевые ссылки в конце! }
            structs: Field_Array1d; { нулевые ссылки в конце! }
            dprp: Property_Array1d; { нулевые ссылки в конце! }
            dmth: Callable_Array1d; { нулевые ссылки в конце! }
            virt: Callable_Array1d;
            srvc: Callable_Array1d;
            impl: ClassType_Array1d; { нулевые ссылки в конце! }
            serv: ClassType_Array1d;
            instances: Field_Array1d; { нулевые ссылки в конце! }
            gtype: &Type;
            global: Field;
            defc: Callable;
            __field: Field;
            __member: Member;
            gvalue: Constant;
            component: &Type;
            __method: Callable;
            prim: PrimitiveType;
            __callable: Callable;
            __property: &Property;
            arguments: ArgumentArray;
            astrings: AnsiStringStorage;
            astore: ArgumentArrayStorage;
            ustrings: UnicodeStringStorage;
            curr: ru.malik.elaborarer.avtoo.lang.ClassType;
            superclass: ru.malik.elaborarer.avtoo.lang.ClassType;
            superservice: ru.malik.elaborarer.avtoo.lang.ClassType;
            writer: AssemblerElementWriter;
        begin
            isReflect := fldReflect;
            isService := false;
            isStruct := false;
            isHelper := __type.isHelper();
            if isHelper then begin
                isClass := false;
            end else begin
                if __type.isClass() then begin
                    isClass := true;
                end else begin
                    isStruct := __type.isStruct();
                    if isStruct then begin
                        isClass := true;
                    end else begin
                        isService := __type.isService();
                        isClass := isService and not __type.isAbstract();
                    end;
                end;
            end;
            tlength := __type.getLength();
            superclass := __type.getSuperclassType();
            component := nil;
            if __type is ArrayType then component := ArrayType(__type).componentType;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            rfld := nil;
            if isClass then begin
                length := 0;
                curr := __type;
                repeat
                    for cindex := 0 to curr.getLength() - 1 do begin
                        __member := curr.readComponent(cindex);
                        if (__member is Field) and not __member.isStatic() then begin
                            __field := Field(__member);
                            name := __member.specialSimpleName;
                            if not __field.&type.isPrimitive() and (name <> '') then begin
                                if rfld = nil then begin
                                    rfld := Field_Array1d(&Array.newTObject1d($ff));
                                end else
                                if system.length(rfld) = length then begin
                                    buffer := Field_Array1d(&Array.newTObject1d((length shl 1) or 1));
                                    &Array.copyObjects(rfld, 0, buffer, 0, length);
                                    rfld := buffer;
                                end;
                                rfld[length] := __field;
                                inc(length);
                            end;
                        end;
                    end;
                    curr := curr.getSuperclassType();
                until curr = nil;
            end;
            virt := nil;
            if isClass then virt := __type.virtualCallables();
            srvc := nil;
            if isService then srvc := __type.serviceCallables();
            impl := nil;
            serv := nil;
            begin
                slength := __type.getSuperservicesLength();
                if isClass then begin
                    length := 0;
                    if isService then begin
                        sindex := -1;
                    end else begin
                        sindex := 0;
                    end;
                    while sindex < slength do begin
                        if sindex < 0 then begin
                            superservice := __type;
                        end else begin
                            superservice := __type.getSuperserviceTypeAt(sindex);
                        end;
                        if
                            (superclass = nil) or not superclass.isSuperservice(superservice) or
                            not superservice.isInterface() and not superclass.hasOverriddingMembersFor(superservice, true) and __type.hasOverriddingMembersFor(superservice, false)
                        then begin
                            if impl = nil then impl := ClassType_Array1d(&Array.newTObject1d(slength + 1));
                            impl[length] := superservice;
                            inc(length);
                        end;
                        inc(sindex);
                    end;
                end;
                if not isHelper then begin
                    length := 0;
                    for sindex := 0 to slength - 1 do begin
                        superservice := __type.getSuperserviceTypeAt(sindex);
                        if serv = nil then serv := ClassType_Array1d(&Array.newTObject1d(slength));
                        serv[length] := superservice;
                        inc(length);
                    end;
                end;
            end;
            sfld := nil;
            if isStruct then begin
                length := 0;
                curr := __type;
                repeat
                    for cindex := 0 to curr.getLength() - 1 do begin
                        __member := curr.readComponent(cindex);
                        if (__member is Field) and not __member.isStatic() then begin
                            __field := Field(__member);
                            name := __member.specialSimpleName;
                            if (__field.&type is ReferenceType) and (name <> '') then begin
                                if sfld = nil then begin
                                    sfld := Field_Array1d(&Array.newTObject1d($ff));
                                end else
                                if system.length(sfld) = length then begin
                                    buffer := Field_Array1d(&Array.newTObject1d((length shl 1) or 1));
                                    &Array.copyObjects(sfld, 0, buffer, 0, length);
                                    sfld := buffer;
                                end;
                                sfld[length] := __field;
                                inc(length);
                            end;
                        end;
                    end;
                    curr := curr.getSuperclassType();
                until (curr = nil) or not curr.isStruct();
            end;
            tcapacity := getBestArrayCapacity(tlength);
            dmai := nil;
            globals := nil;
            if not isStruct then globals := Field_Array1d(&Array.newTObject1d(tcapacity));
            structs := nil;
            if isStruct then structs := Field_Array1d(&Array.newTObject1d(tcapacity));
            instances := nil;
            if not isHelper and not isService then instances := Field_Array1d(&Array.newTObject1d(tcapacity));
            dfld := nil;
            dprp := nil;
            dmth := nil;
            astore := nil;
            try
                begin
                    ilength := 0;
                    slength := 0;
                    glength := 0;
                    flength := 0;
                    mlength := 0;
                    plength := 0;
                    for tindex := 0 to tlength - 1 do begin
                        __member := __type.readComponent(tindex);
                        if __member.isStatic() then begin
                            if (globals <> nil) and (__member is Field) then begin
                                globals[glength] := Field(__member);
                                inc(glength);
                            end;
                            continue;
                        end;
                        if __member is Field then begin
                            __field := Field(__member);
                            name := __member.specialSimpleName;
                            hasName := name <> '';
                            if (instances <> nil) and (not isStruct or hasName and not __field.&type.isPrimitive()) then begin
                                instances[ilength] := __field;
                                inc(ilength);
                            end;
                            if (structs <> nil) and hasName then begin
                                structs[slength] := __field;
                                inc(slength);
                            end;
                            if isReflect and not isStruct then begin
                                if dfld = nil then dfld := Field_Array1d(&Array.newTObject1d(tlength));
                                dfld[flength] := __field;
                                inc(flength);
                            end;
                            continue;
                        end;
                        if isReflect and not isStruct then begin
                            if __member is &Property then begin
                                if dprp = nil then dprp := Property_Array1d(&Array.newTObject1d(tlength));
                                dprp[plength] := &Property(__member);
                                inc(plength);
                                continue;
                            end;
                            if __member is Callable then begin
                                if dmth = nil then begin
                                    dmai := &Array.newInt1d(tlength);
                                    dmth := Callable_Array1d(&Array.newTObject1d(tlength));
                                    astore := ArgumentArrayStorage.create();
                                end;
                                __method := Callable(__member);
                                dmai[mlength] := astore.indexAcquire(__method.arguments);
                                dmth[mlength] := __method;
                                inc(mlength);
                            end;
                        end;
                    end;
                end;
                if isHelper then begin
                    defc := nil;
                end else begin
                    if isService then begin
                        curr := superclass;
                    end else
                    if not isStruct then begin
                        curr := __type;
                    end else begin
                        curr := getClassType(PACKNAME_LANG + '.' + TYPENAME_STRUCT);
                    end;
                    defc := curr.getChildCallable(SPECNAME_INST_INIT, Type_Array1d(nil));
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                writer := getAssemblerElementWriter();
                operandA := &Array.newChar1d($2000);
                operandB := &Array.newChar1d($0100);
                operandC := &Array.newChar1d($0100);
                operandD := &Array.newChar1d($2000);
                intZero := writer.&set(operandB).writeInt(0).get();
                longZero := writer.&set(operandB).writeLong(0).get();
                operands := &Array.newAnsiString1d(8);
                source := __type.textSourcePath;
                fasmFullName := __type.fasmFullName;
                specialCanonicalName := __type.specialCanonicalName;
                astrings := fldDebugInfoStrings;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.data.type'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('class', fasmFullName);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := writer.&set(operandA).writeInt(__type.attributes).get();
                operands[1] := writer.&set(operandB).writeInt(fldStringStorage.indexAcquire(__type.specialSimpleName.toUTF16())).get();
                operands[2] := writer.&set(operandC).writeInt(__type.instanceSize).get();
                operands[3] := writer.&set(operandD).writeInt(__type.structSize).get();
                output.printlnInstruction('dd', operands, 0, 4);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := writer.&set(operandA).writeInt(getPayLengthPtr(rfld)).get();
                operands[1] := writer.&set(operandB).writeInt(getPayLengthPtr(virt)).get();
                operands[2] := writer.&set(operandC).writeInt(getPayLengthPtr(impl)).get();
                operands[3] := writer.&set(operandD).writeInt(getPayLengthPtr(serv)).get();
                output.printlnInstruction('dd', operands, 0, 4);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := writer.&set(operandA).writeInt(getPayLengthPtr(sfld)).get();
                operands[1] := writer.&set(operandB).writeInt(getPayLengthPtr(dfld)).get();
                operands[2] := writer.&set(operandC).writeInt(getPayLengthPtr(dmth)).get();
                operands[3] := writer.&set(operandD).writeInt(getPayLengthPtr(dprp)).get();
                output.printlnInstruction('dd', operands, 0, 4);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                &Array.fillStrings(operands, 0, 4, intZero);
                if rfld <> nil then operands[0] := '-.this+.$rfld$';
                if virt <> nil then operands[1] := '-.this+.$virt$';
                if impl <> nil then operands[2] := '-.this+.$impl$';
                if serv <> nil then operands[3] := '-.this+.$serv$';
                output.printlnInstruction('dd', operands, 0, 4);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                &Array.fillStrings(operands, 0, 4, intZero);
                if sfld <> nil then operands[0] := '-.this+.$sfld$';
                if dfld <> nil then operands[1] := '-.this+.$dfld$';
                if dmth <> nil then operands[2] := '-.this+.$dmth$';
                if dprp <> nil then operands[3] := '-.this+.$dprp$';
                output.printlnInstruction('dd', operands, 0, 4);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                &Array.fillStrings(operands, 0, 4, intZero);
                if defc <> nil then operands[0] := writer.&set(operandA).writeInt(defc.attributes).get();
                output.printlnInstruction('dd', operands, 0, 4);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if isHelper then superclass := __type.getHelperForType();
                &Array.fillStrings(operands, 0, 4, longZero);
                if superclass <> nil then operands[0] := writer.&set(operandA).writeString('-.this+').writeString(superclass.fasmFullName).get();
                if component <> nil then operands[1] := writer.&set(operandB).writeString('-.this+').writeString(component.fasmFullName).get();
                operands[2] := writer.&set(operandC).writeString('-.this+').writeString(__type.parentPackage.fasmFullName).get();
                if defc <> nil then operands[3] := writer.&set(operandD).writeString('-.this+').writeString(defc.fasmFullName).get();
                output.printlnInstruction('dq', operands, 0, 2);
                output.printlnInstruction('dq', operands, 2, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := longZero;
                operands[1] := longZero;
                output.printlnInstruction('dq', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                writer.&set(operandA).writeString('-.this+dbgi$isrc').writeLabel(fldDebugInfoSources.indexAcquire(source)).trim();
                output.printlnInstruction('dq', toString(operandA));
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := intZero;
                operands[1] := '-.this+.$iend$';
                output.printlnInstruction('dd', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := longZero;
                operands[1] := longZero;
                output.printlnInstruction('dq', operands, 0, 2);
                output.printlnInstruction('dq', operands, 0, 2);
                output.printlnInstruction('dq', operands, 0, 2);
                output.printlnInstruction('dq', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if rfld <> nil then begin
                    output.printLabel('.$rfld$');
                    length := getPayLengthPtr(rfld);
                    limit := length + (length and 1);
                    for index := 0 to limit - 1 do begin
                        if index >= length then begin
                            output.printlnInstruction('dd', intZero);
                        end else begin
                            output.printlnInstruction('dd', rfld[index].fasmFullName);
                        end;
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if virt <> nil then begin
                    output.printLabel('.$virt$');
                    for index := 0 to getPayLengthPtr(virt) - 1 do begin
                        writer.&set(operandA).writeString('-.$virt$+').writeString(virt[index].fasmFullName).trim();
                        output.printlnInstruction('dq', toString(operandA));
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if impl <> nil then begin
                    output.printLabel('.$impl$');
                    for index := 0 to getPayLengthPtr(impl) - 1 do begin
                        implements := impl[index].fasmFullName;
                        operands[0] := writer.&set(operandA).writeString('-.$impl$+').writeString(fasmFullName).writeString('$$impl$$').writeString(implements).get();
                        operands[1] := writer.&set(operandB).writeString('-.$impl$+').writeString(implements).get();
                        output.printlnInstruction('dq', operands, 0, 2);
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if serv <> nil then begin
                    output.printLabel('.$serv$');
                    for index := 0 to getPayLengthPtr(serv) - 1 do begin
                        writer.&set(operandA).writeString('-.$serv$+').writeString(serv[index].fasmFullName).trim();
                        output.printlnInstruction('dq', toString(operandA));
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if sfld <> nil then begin
                    output.printLabel('.$sfld$');
                    for index := 0 to getPayLengthPtr(sfld) - 1 do begin
                        __field := sfld[index];
                        name := __field.specialSimpleName;
                        astrings.indexAcquire(name);
                        operands[0] := writer.&set(operandA).writeInt(__field.attributes).get();
                        operands[1] := name;
                        operands[2] := __field.&type.fasmFullName;
                        operands[3] := writer.&set(operandB).writeInt(__field.capacity).get();
                        operands[4] := __field.fasmFullName;
                        output.printlnInstruction('dsfld', operands, 0, 5);
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if dfld <> nil then begin
                    output.printLabel('.$dfld$');
                    for index := 0 to getPayLengthPtr(dfld) - 1 do begin
                        __field := dfld[index];
                        name := __field.specialSimpleName;
                        astrings.indexAcquire(name);
                        operands[0] := writer.&set(operandA).writeInt(__field.attributes).get();
                        operands[1] := name;
                        operands[2] := __field.&type.fasmFullName;
                        operands[3] := __field.fasmFullName;
                        output.printlnInstruction('dfild', operands, 0, 4);
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if dmth <> nil then begin
                    output.printLabel('.$dmth$');
                    for index := 0 to getPayLengthPtr(dmth) - 1 do begin
                        __method := dmth[index];
                        name := __method.specialSimpleName;
                        arguments := __method.arguments;
                        nlength := name.length;
                        astrings.indexAcquire(name);
                        operands[0] := writer.&set(operandA).writeInt(__method.attributes or (arguments.getLength() shl $10)).get();
                        if (nlength > 1) and (name[1] = '<') and (name[nlength] = '>') then begin
                            mnmnc := 'dmeths';
                            operands[1] := writer.&set(operandB).writeString(name, 2, nlength).get();
                        end else begin
                            mnmnc := 'dmeth';
                            operands[1] := name;
                        end;
                        operands[2] := __method.&type.fasmFullName;
                        operands[3] := __method.fasmFullName;
                        operands[4] := writer.&set(operandC).writeLabel(dmai[index]).get();
                        output.printlnInstruction(mnmnc, operands, 0, 5);
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if dprp <> nil then begin
                    output.printLabel('.$dprp$');
                    for index := 0 to getPayLengthPtr(dprp) - 1 do begin
                        __property := dprp[index];
                        name := __property.specialSimpleName;
                        astrings.indexAcquire(name);
                        operands[0] := writer.&set(operandA).writeInt(__property.attributes).get();
                        operands[1] := name;
                        operands[2] := __property.&type.fasmFullName;
                        &Array.fillStrings(operands, 3, 3, '.$dprp$');
                        __method := __property.readSynthetic;
                        if __method <> nil then operands[3] := __method.fasmFullName;
                        __method := __property.writeSynthetic;
                        if __method <> nil then operands[4] := __method.fasmFullName;
                        __method := __property.storedSynthetic;
                        if __method <> nil then operands[5] := __method.fasmFullName;
                        output.printlnInstruction('dprop', operands, 0, 6);
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                if astore <> nil then for aindex := 0 to astore.getLength() - 1 do begin
                    output.printLabel(writer.&set(operandA).writeLabel(aindex).get());
                    arguments := astore.readComponent(aindex);
                    for index := 0 to arguments.getLength() - 1 do begin
                        writer.&set(operandA).writeChar('-').writeLabel(aindex).writeChar('+').writeString(arguments.readComponent(index).&type.fasmFullName).trim();
                        output.printlnInstruction('dq', toString(operandA));
                    end;
                end;
            finally
                astore.free();
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnLabel('.$iend$');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            if globals <> nil then begin
                fasmNums := [ operandA, operandB, operandC, operandD, &Array.newChar1d($20), &Array.newChar1d($20), &Array.newChar1d($20), &Array.newChar1d($20) ];
                ustrings := fldStringStorage;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.field.static'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                for index := 0 to getPayLengthPtr(globals) - 1 do begin
                    global := globals[index];
                    gname := global.fasmFullName;
                    gvalue := global.value;
                    gtype := global.&type;
                    if not global.isFinal() or (gvalue = nil) then begin
                        operands[0] := gname;
                        operands[1] := gtype.fasmSimpleName;
                        output.printlnInstruction('glob', operands, 0, 2);
                        if gvalue = nil then begin
                            if not(gtype is PrimitiveType) then begin
                                output.printlnInstruction('dq', 'null');
                                continue;
                            end;
                            prim := PrimitiveType(gtype);
                            vlength := prim.vectorLength;
                            case prim.kind of
                            TYP_BYTE2,
                            TYP_BYTE4,
                            TYP_BYTE8: begin
                                &Array.fillStrings(operands, 0, vlength, writer.&set(operandA).writeByte(0).get());
                                output.printlnInstruction('db', operands, 0, vlength);
                                continue;
                            end;
                            TYP_SHORT2,
                            TYP_SHORT4,
                            TYP_SHORT8: begin
                                &Array.fillStrings(operands, 0, vlength, writer.&set(operandA).writeShort(0).get());
                                output.printlnInstruction('dw', operands, 0, vlength);
                                continue;
                            end;
                            TYP_INT2,
                            TYP_INT4,
                            TYP_INT8,
                            TYP_FLOAT,
                            TYP_FLOAT2,
                            TYP_FLOAT4,
                            TYP_FLOAT8: begin
                                &Array.fillStrings(operands, 0, vlength, writer.&set(operandA).writeInt(0).get());
                                output.printlnInstruction('dd', operands, 0, vlength);
                                continue;
                            end;
                            TYP_LONG,
                            TYP_LONG2,
                            TYP_LONG4,
                            TYP_LONG8,
                            TYP_DOUBLE,
                            TYP_DOUBLE2,
                            TYP_DOUBLE4,
                            TYP_DOUBLE8: begin
                                &Array.fillStrings(operands, 0, vlength, writer.&set(operandA).writeLong(0).get());
                                output.printlnInstruction('dq', operands, 0, vlength);
                                continue;
                            end;
                            TYP_REAL: begin
                                &Array.fillStrings(operands, 0, 5, writer.&set(operandA).writeShort(0).get());
                                output.printlnInstruction('dw', operands, 0, 5);
                                continue;
                            end;
                            else
                                output.printlnInstruction('dd', intZero);
                                continue;
                            end;
                        end;
                        prim := gtype as PrimitiveType;
                        vlength := prim.vectorLength;
                        case prim.kind of
                        TYP_BYTE2,
                        TYP_BYTE4,
                        TYP_BYTE8: begin
                            i8value := gvalue.asByte8();
                            for vindex := 0 to vlength - 1 do begin
                                operands[vindex] := writer.&set(fasmNums[vindex]).writeByte(i8value[vindex]).get();
                            end;
                            output.printlnInstruction('db', operands, 0, vlength);
                            continue;
                        end;
                        TYP_SHORT2,
                        TYP_SHORT4,
                        TYP_SHORT8: begin
                            i8value := gvalue.asShort8();
                            for vindex := 0 to vlength - 1 do begin
                                operands[vindex] := writer.&set(fasmNums[vindex]).writeShort(i8value[vindex]).get();
                            end;
                            output.printlnInstruction('dw', operands, 0, vlength);
                            continue;
                        end;
                        TYP_INT2,
                        TYP_INT4,
                        TYP_INT8: begin
                            i8value := gvalue.asInt8();
                            for vindex := 0 to vlength - 1 do begin
                                operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i8value[vindex]).get();
                            end;
                            output.printlnInstruction('dd', operands, 0, vlength);
                            continue;
                        end;
                        TYP_LONG,
                        TYP_LONG2,
                        TYP_LONG4,
                        TYP_LONG8: begin
                            l8value := gvalue.asLong8();
                            for vindex := 0 to vlength - 1 do begin
                                operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l8value[vindex]).get();
                            end;
                            output.printlnInstruction('dq', operands, 0, vlength);
                            continue;
                        end;
                        TYP_FLOAT,
                        TYP_FLOAT2,
                        TYP_FLOAT4,
                        TYP_FLOAT8: begin
                            i8value := VCoFloat8.toInt8Bits(gvalue.asFloat8());
                            for vindex := 0 to vlength - 1 do begin
                                operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i8value[vindex]).get();
                            end;
                            output.printlnInstruction('dd', operands, 0, vlength);
                            continue;
                        end;
                        TYP_DOUBLE,
                        TYP_DOUBLE2,
                        TYP_DOUBLE4,
                        TYP_DOUBLE8: begin
                            l8value := VCoDouble8.toLong8Bits(gvalue.asDouble8());
                            for vindex := 0 to vlength - 1 do begin
                                operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l8value[vindex]).get();
                            end;
                            output.printlnInstruction('dq', operands, 0, vlength);
                            continue;
                        end;
                        TYP_REAL: begin
                            l2value := VCoReal.toLong2Bits(gvalue.asReal());
                            i8value := short8((@l2value)^);
                            for vindex := 0 to 4 do begin
                                operands[vindex] := writer.&set(fasmNums[vindex]).writeShort(i8value[vindex]).get();
                            end;
                            output.printlnInstruction('dw', operands, 0, 5);
                            continue;
                        end;
                        else
                            begin
                                operands[0] := writer.&set(fasmNums[0]).writeInt(gvalue.asInt()).get();
                            end;
                            output.printlnInstruction('dd', operands, 0, 1);
                            continue;
                        end;
                    end;
                    if gvalue.isNull() then begin
                        operands[0] := gname;
                        operands[1] := 'null';
                        output.printlnInstruction('iconst', operands, 0, 2);
                        continue;
                    end;
                    if gvalue.isReflective() then begin
                        operands[0] := gname;
                        operands[1] := (gvalue.asObject() as RequiredReflectItem).fasmFullName;
                        output.printlnInstruction('oconst', operands, 0, 2);
                        continue;
                    end;
                    if gvalue.isString() then begin
                        operands[0] := gname;
                        operands[1] := writer.&set(operandA).writeInt(ustrings.indexAcquire((gvalue.asInterface() as Value).asUnicodeString())).get();
                        output.printlnInstruction('sconst', operands, 0, 2);
                        continue;
                    end;
                    if gvalue.isBoolean() then begin
                        operands[0] := gname;
                        if gvalue.asBoolean() then begin
                            operands[1] := 'true';
                        end else begin
                            operands[1] := 'false';
                        end;
                        output.printlnInstruction('iconst', operands, 0, 2);
                        continue;
                    end;
                    case gtype.kind of
                    TYP_REAL:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$e+').writeDecimal(fldRealStorage.indexAcquire(gvalue.asReal()) * 10).trim();
                    TYP_DOUBLE:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$d+').writeOffset(fldDoubleStorage.indexAcquire(gvalue.asDouble()) shl 4).trim();
                    TYP_DOUBLE2:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$d2+').writeOffset(fldDouble2Storage.indexAcquire(gvalue.asDouble2()) shl 4).trim();
                    TYP_DOUBLE4:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$d4+').writeOffset(fldDouble4Storage.indexAcquire(gvalue.asDouble4()) shl 5).trim();
                    TYP_DOUBLE8:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$d8+').writeOffset(fldDouble8Storage.indexAcquire(gvalue.asDouble8()) shl 6).trim();
                    TYP_FLOAT:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$f+').writeOffset(fldFloatStorage.indexAcquire(gvalue.asFloat()) shl 4).trim();
                    TYP_FLOAT2:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$f2+').writeOffset(fldFloat2Storage.indexAcquire(gvalue.asFloat2()) shl 4).trim();
                    TYP_FLOAT4:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$f4+').writeOffset(fldFloat4Storage.indexAcquire(gvalue.asFloat4()) shl 4).trim();
                    TYP_FLOAT8:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$f8+').writeOffset(fldFloat8Storage.indexAcquire(gvalue.asFloat8()) shl 5).trim();
                    TYP_BYTE2:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$b2+').writeOffset(fldByte2Storage.indexAcquire(gvalue.asByte2()) shl 4).trim();
                    TYP_BYTE4:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$b4+').writeOffset(fldByte4Storage.indexAcquire(gvalue.asByte4()) shl 4).trim();
                    TYP_BYTE8:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$b8+').writeOffset(fldByte8Storage.indexAcquire(gvalue.asByte8()) shl 4).trim();
                    TYP_SHORT2:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$s2+').writeOffset(fldShort2Storage.indexAcquire(gvalue.asShort2()) shl 4).trim();
                    TYP_SHORT4:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$s4+').writeOffset(fldShort4Storage.indexAcquire(gvalue.asShort4()) shl 4).trim();
                    TYP_SHORT8:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$s8+').writeOffset(fldShort8Storage.indexAcquire(gvalue.asShort8()) shl 4).trim();
                    TYP_INT2:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$i2+').writeOffset(fldInt2Storage.indexAcquire(gvalue.asInt2()) shl 4).trim();
                    TYP_INT4:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$i4+').writeOffset(fldInt4Storage.indexAcquire(gvalue.asInt4()) shl 4).trim();
                    TYP_INT8:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$i8+').writeOffset(fldInt8Storage.indexAcquire(gvalue.asInt8()) shl 5).trim();
                    TYP_LONG:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$l+').writeOffset(fldLongStorage.indexAcquire(gvalue.asLong()) shl 3).trim();
                    TYP_LONG2:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$l2+').writeOffset(fldLong2Storage.indexAcquire(gvalue.asLong2()) shl 4).trim();
                    TYP_LONG4:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$l4+').writeOffset(fldLong4Storage.indexAcquire(gvalue.asLong4()) shl 5).trim();
                    TYP_LONG8:
                        writer.&set(operandA).writeString(gname).writeString(' at cons$l8+').writeOffset(fldLong8Storage.indexAcquire(gvalue.asLong8()) shl 6).trim();
                    else
                        ivalue := gvalue.asInt();
                        operands[0] := gname;
                        if ivalue >= 0 then begin
                            operands[1] := writer.&set(operandA).writeInt(ivalue).get();
                        end else begin
                            operands[1] := writer.&set(operandA).writeChar('-').writeInt(-ivalue).get();
                        end;
                        output.printlnInstruction('iconst', operands, 0, 2);
                        continue;
                    end;
                    output.printlnInstruction('label', toString(operandA));
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('separator_d');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            if instances <> nil then begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.field.instance'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                for index := 0 to getPayLengthPtr(instances) - 1 do begin
                    __field := instances[index];
                    operands[0] := writer.&set(operandA).writeInt(__field.instanceOffset).get();
                    operands[1] := __field.fasmFullName;
                    output.printlnInstruction('field', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            if structs <> nil then begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.field.struct'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                for index := 0 to getPayLengthPtr(structs) - 1 do begin
                    __field := structs[index];
                    operands[0] := writer.&set(operandA).writeInt(__field.structOffset).get();
                    operands[1] := writer.&set(operandB).writeString(__field.fasmFullName).writeString('.struct').get();
                    output.printlnInstruction('field', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            if virt <> nil then begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.index.virtual'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                for index := 0 to system.length(virt) - 1 do begin
                    __callable := virt[index];
                    if __callable.parentType = __type then begin
                        operands[0] := writer.&set(operandA).writeInt(index).get();
                        operands[1] := __callable.fasmFullName;
                        output.printlnInstruction('idxvirt', operands, 0, 2);
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            if srvc <> nil then begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.index.service'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                for index := 0 to system.length(srvc) - 1 do begin
                    __callable := srvc[index];
                    if __callable.parentType = __type then begin
                        operands[0] := writer.&set(operandA).writeInt(index).get();
                        operands[1] := __callable.fasmFullName;
                        output.printlnInstruction('idxserv', operands, 0, 2);
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
        end;

        procedure AssemblerSourceGenerator.generateClassCode(__type: ClassType; output: AssemblerSourcePrintStream);
        var
            isNone: boolean;
            index: int;
            length: int;
            specialCanonicalName: AnsiString;
            __member: Member;
            __method: Callable;
            superclass: ru.malik.elaborarer.avtoo.lang.ClassType;
            superservice: ru.malik.elaborarer.avtoo.lang.ClassType;
        begin
            specialCanonicalName := __type.specialCanonicalName;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.code.compiled'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                isNone := true;
                for index := 0 to __type.getLength() - 1 do begin
                    __member := __type.readComponent(index);
                    if __member is Callable then begin
                        __method := Callable(__member);
                        if not __method.isNative() then begin
                            if isNone then begin
                                isNone := false;
                            end else begin
                                output.println();
                            end;
                            generateCallableCode(__method, output);
                        end;
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            if not __type.isHelper() and (__type.isClass() or __type.isStruct() or __type.isService() and not __type.isAbstract()) then begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(specialCanonicalName);
                output.print(' — ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.implementors'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                superclass := __type.getSuperclassType();
                isNone := true;
                length := __type.getSuperservicesLength();
                if __type.isService() then begin
                    index := -1;
                end else begin
                    index := 0;
                end;
                while index < length do begin
                    if index < 0 then begin
                        superservice := __type;
                    end else begin
                        superservice := __type.getSuperserviceTypeAt(index);
                    end;
                    if
                        (superclass = nil) or not superclass.isSuperservice(superservice) or
                        not superservice.isInterface() and not superclass.hasOverriddingMembersFor(superservice, true) and __type.hasOverriddingMembersFor(superservice, false)
                    then begin
                        if isNone then begin
                            isNone := false;
                        end else begin
                            output.println();
                        end;
                        generateImplementorCode(__type, superservice, output);
                    end;
                    inc(index);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
        end;

        procedure AssemblerSourceGenerator.generateCallableCode(__callable: Callable; output: AssemblerSourcePrintStream);
        label
            break_label0,
            break_label2,
            break_labelPop,
            break_labelPush,
            break_labelConj,
            continue_label1;
        var
            isVoid: boolean;
            anonymus: boolean;
            isInstance: boolean;
            isConditionalJump: boolean;
            cur: int;
            max: int;
            min: int;
            line: int;
            order: int;
            flags: int;
            index: int;
            limit: int;
            aindex: int;
            alimit: int;
            cindex: int;
            jindex: int;
            jlower: int;
            jvalue: int;
            sindex: int;
            vindex: int;
            length: int;
            alength: int;
            clength: int;
            jlength: int;
            __label: int;
            kindOfNew: int;
            kindOfMid: int;
            kindOfSrc: int;
            lengthOfNew: int;
            lengthOfMid: int;
            lengthOfSrc: int;
            instruction: int;
            kindBaseOfNew: int;
            kindBaseOfMid: int;
            kindBaseOfSrc: int;
            kindOfPushType: int;
            kindOfResultType: int;
            name: AnsiString;
            mnmnc: AnsiString;
            suffix: AnsiString;
            fasmFullName: AnsiString;
            textSourcePath: AnsiString;
            labels: char_Array2d;
            mnemonic: char_Array1d;
            operandA: char_Array1d;
            operandB: char_Array1d;
            operands: AnsiString_Array1d;
            target: Node;
            __code: Code;
            __node: Node;
            __next: Node;
            __type: &Type;
            __prev: &Type;
            typeNew: &Type;
            typeSrc: &Type;
            typeLoc: &Type;
            __field: Field;
            __local: Local;
            __global: Field;
            __value: Constant;
            argument: Local;
            itemC: Constant;
            itemI: TableItem;
            itemT: TypedItem;
            __method: Method;
            __source: Source;
            jumpIsTrue: Node;
            jumpIsFalse: Node;
            jumpDefault: Node;
            __index: Constant;
            __methodc: Callable;
            synthetic: Callable;
            thisArgument: Local;
            reference: TableItem;
            __property: &Property;
            __member: TypedMember;
            arguments: ArgumentArray;
            mainArray: UnicodeStringArray;
            refsArray: UnicodeStringArray;
            mainTable: HashtableOfAnsiStringToType;
            refsTable: HashtableOfAnsiStringToType;
            lines: ru.malik.elaborarer.avtoo.lang.UnicodeStringArray;
            writer: AssemblerElementWriter;
            function isNoStackFrameCriteria(): boolean; inline;
            begin
                { критерии кусков кода, не создающих стаковый кадр }
                if
                    (
                        not __callable.isStatic() or (alength > 0)
                    ) or (
                        (clength <= 2) or
                        (__code.readComponent(0).instruction <> METHOD_ENTER)
                    )
                then begin
                    result := false;
                    exit;
                end;
                __node := __code.readComponent(1);
                instruction := __node.instruction;
                result :=
                    (
                        (instruction = LOAD_CONST) and not __node.operandC.isString() or
                        (instruction = LOAD_STATIC)
                    ) and
                    (__code.readComponent(2).instruction = METHOD_LEAVE)
                ;
            end;
            function isFastMethodCriteria(): boolean; inline;
            begin
                { критерии кода быстрого метода }
                if
                    (clength > 1) and
                    (__code.readComponent(0).instruction = METHOD_ENTER) and
                    (__code.readComponent(1).instruction = METHOD_LEAVE)
                then begin
                    result := true;
                    exit;
                end;
                if
                    (clength > 2) and
                    (__code.readComponent(0).instruction = METHOD_ENTER)
                then begin
                    __node := __code.readComponent(1);
                    instruction := __node.instruction;
                    if
                        (
                            (instruction = LOAD_CONST) and not __node.operandC.isString() or
                            (instruction = READ_FIELD) and ((__node.operand2 <> nil) or (__node.operandC <> nil)) or
                            (instruction = LOAD_LOCAL)
                        ) and
                        (__code.readComponent(2).instruction = METHOD_LEAVE)
                    then begin
                        result := true;
                        exit;
                    end;
                end;
                if
                    (clength <= 4) or
                    (__code.readComponent(0).instruction <> METHOD_ENTER)
                then begin
                    result := false;
                    exit;
                end;
                instruction := __code.readComponent(1).instruction;
                if
                    (instruction <> LOAD_LOCAL) and
                    (instruction <> LOAD_STATIC)
                then begin
                    result := false;
                    exit;
                end;
                __node := __code.readComponent(2);
                instruction := __node.instruction;
                result :=
                    (
                        (instruction = LOAD_CONST) and not __node.operandC.isString() or
                        (instruction = READ_FIELD) and ((__node.operand2 <> nil) or (__node.operandC <> nil)) or
                        (instruction = LOAD_LOCAL)
                    ) and
                    (__code.readComponent(3).instruction = WRITE_FIELD) and
                    (__code.readComponent(4).instruction = METHOD_LEAVE)
                ;
            end;
        begin
            writer := getAssemblerElementWriter();
            mnemonic := &Array.newChar1d($0010);
            operandA := &Array.newChar1d($2000);
            operandB := &Array.newChar1d($0100);
            labels := nil;
            operands := &Array.newAnsiString1d(9);
            __code := __callable.code;
            __source := __callable.source;
            textSourcePath := __callable.parentType.textSourcePath.toUTF8();
            fasmFullName := __callable.fasmFullName;
            arguments := __callable.arguments;
            thisArgument := arguments.thisArgument;
            isInstance := thisArgument <> nil;
            alength := arguments.getLength();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            begin
                __type := __callable.&type;
                isVoid := __type.isVoid();
                output.printHeader('if(used ');
                output.print(fasmFullName);
                output.print(') ; <fold ');
                if not isVoid then begin
                    output.print('returns ');
                    output.print(__type.specialCanonicalName);
                end;
                if __callable is Method then begin
                    __method := Method(__callable);
                    for index := 0 to __method.getThrowablesLength() - 1 do begin
                        if index > 0 then begin
                            output.print(', ');
                        end else
                        if isVoid then begin
                            output.print('throws ');
                        end else begin
                            output.print(', throws ');
                        end;
                        output.print(__method.getThrowableTypeAt(index).specialCanonicalName);
                    end;
                end;
                output.println('>');
                output.increaseMargin();
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            if __code = nil then begin
                { заголовок абстрактного метода }
                operands[0] := fasmFullName;
                operands[1] := '\';
                if not isInstance and (alength <= 0) then begin
                    output.printlnInstruction('method', operands, 0, 1);
                end else begin
                    output.printlnInstruction('method', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[2] := '\';
                alimit := alength - 1;
                if isInstance then begin
                    aindex := -1;
                end else begin
                    aindex := 0;
                end;
                while aindex < alength do begin
                    if aindex < 0 then begin
                        argument := thisArgument;
                    end else begin
                        argument := arguments.readComponent(aindex);
                    end;
                    operands[0] := argument.fasmSimpleName;
                    operands[1] := argument.&type.fasmSimpleName;
                    if aindex >= alimit then begin
                        output.printlnContinuation(operands, 0, 2);
                    end else begin
                        output.printlnContinuation(operands, 0, 3);
                    end;
                    inc(aindex);
                end;
            end else begin
                clength := __code.getLength();
                if not __callable.isInterrupt() then begin
                    if isNoStackFrameCriteria() then begin
                        { заголовок куска кода }
                        output.printlnInstruction('proc', fasmFullName);
                        { -------------------------------------------------------------------------------------------------------------------------------- }
                        lines := nil;
                        if Lang.isInstance(__source, TextSource) then begin
                            lines := TextSource(Lang.cast(__source, TextSource)).lines;
                        end;
                        for cindex := 0 to clength - 1 do begin
                            { метки }
                            __node := __code.readComponent(cindex);
                            __label := __node.debugIndex;
                            if __label >= 0 then begin
                                if textSourcePath <> '' then begin
                                    line := __node.location[0];
                                    if line >= 0 then begin
                                        { строка текстового исходного кода }
                                        writer.&set(operandA).writeDecimal(line + 1).trim();
                                        output.printHeader('; ');
                                        output.print(textSourcePath);
                                        output.print('[');
                                        output.print(toString(operandA));
                                        output.print(']');
                                        if (lines <> nil) and (line < lines.getLength()) then begin
                                            output.print(': ');
                                            output.print(lines.readComponent(line).toString().trim());
                                        end;
                                        output.println();
                                    end;
                                end;
                                output.printLabel(writer.&set(operandA).writeLabel('D', __label).get());
                            end;
                            __label := __node.labelIndex;
                            if __label >= 0 then begin
                                output.printLabel(writer.&set(operandA).writeLabel('L', __label).get());
                            end;
                            { инструкции }
                            case __node.instruction of
                            LOAD_CONST: begin
                                __value := __node.operandC;
                                constantToFasmString(__value, operandA);
                                writer.&set(mnemonic).writeString('load').writeSignature(__value.&type, STACK).writeString('_g').trim();
                                output.printlnInstruction(toString(mnemonic), toString(operandA));
                            end;
                            LOAD_STATIC: begin
                                __global := __node.operand1 as Field;
                                writer.&set(mnemonic).writeString('load').writeSignature(__global.&type, STACK).writeString('_g').trim();
                                writer.&set(operandA).writeChar('[').writeString(__global.fasmFullName).writeChar(']').trim();
                                output.printlnInstruction(toString(mnemonic), toString(operandA));
                            end;
                            METHOD_LEAVE: begin
                                output.printlnInstruction('ret');
                                output.printlnInstruction('end_proc');
                                goto break_label0;
                            end;
                            end;
                        end;
                    end;
                    if isFastMethodCriteria() then begin
                        { заголовок быстрого метода }
                        operands[0] := fasmFullName;
                        operands[1] := '\';
                        if not isInstance and (alength <= 0) then begin
                            output.printlnInstruction('fast', operands, 0, 1);
                        end else begin
                            output.printlnInstruction('fast', operands, 0, 2);
                        end;
                        { -------------------------------------------------------------------------------------------------------------------------------- }
                        operands[2] := '\';
                        alimit := alength - 1;
                        if isInstance then begin
                            aindex := -1;
                        end else begin
                            aindex := 0;
                        end;
                        while aindex < alength do begin
                            if aindex < 0 then begin
                                argument := thisArgument;
                            end else begin
                                argument := arguments.readComponent(aindex);
                            end;
                            operands[0] := argument.fasmSimpleName;
                            operands[1] := argument.&type.fasmSimpleName;
                            if aindex >= alimit then begin
                                output.printlnContinuation(operands, 0, 2);
                            end else begin
                                output.printlnContinuation(operands, 0, 3);
                            end;
                            inc(aindex);
                        end;
                        { -------------------------------------------------------------------------------------------------------------------------------- }
                        reference := nil;
                        lines := nil;
                        if Lang.isInstance(__source, TextSource) then begin
                            lines := TextSource(Lang.cast(__source, TextSource)).lines;
                        end;
                        __node := nil;
                        if clength > 0 then begin
                            __node := __code.readComponent(0);
                        end;
                        cindex := 0;
                        repeat
                            inc(cindex);
                            if cindex >= clength then begin
                                __next := nil;
                            end else begin
                                __next := __code.readComponent(cindex);
                            end;
                            { метки }
                            __label := __node.debugIndex;
                            if __label >= 0 then begin
                                if textSourcePath <> '' then begin
                                    line := __node.location[0];
                                    if line >= 0 then begin
                                        { строка текстового исходного кода }
                                        writer.&set(operandA).writeDecimal(line + 1).trim();
                                        output.printHeader('; ');
                                        output.print(textSourcePath);
                                        output.print('[');
                                        output.print(toString(operandA));
                                        output.print(']');
                                        if (lines <> nil) and (line < lines.getLength()) then begin
                                            output.print(': ');
                                            output.print(lines.readComponent(line).toString().trim());
                                        end;
                                        output.println();
                                    end;
                                end;
                                output.printLabel(writer.&set(operandA).writeLabel('D', __label).get());
                            end;
                            __label := __node.labelIndex;
                            if __label >= 0 then begin
                                output.printLabel(writer.&set(operandA).writeLabel('L', __label).get());
                            end;
                            { инструкции }
                            case __node.instruction of
                            METHOD_ENTER: begin
                                output.printlnInstruction('fenter');
                            end;
                            LOAD_CONST: begin
                                __value := __node.operandC;
                                constantToFasmString(__value, operandA);
                                if __next.instruction = WRITE_FIELD then begin
                                    flags := STACK or WEAK;
                                end else begin
                                    flags := STACK;
                                end;
                                writer.&set(mnemonic).writeString('load').writeSignature(__value.&type, flags).writeString('_g').trim();
                                output.printlnInstruction(toString(mnemonic), toString(operandA));
                            end;
                            LOAD_LOCAL: begin
                                if (cindex = 2) and (__next.instruction <> METHOD_LEAVE) then begin
                                    reference := __node.operand1 as Local;
                                end else begin
                                    __local := __node.operand1 as Local;
                                    typeLoc := __node.operand2 as &Type;
                                    if typeLoc = nil then typeLoc := __local.&type;
                                    if __next.instruction = WRITE_FIELD then begin
                                        flags := STACK or WEAK;
                                    end else begin
                                        flags := STACK;
                                    end;
                                    writer.&set(mnemonic).writeString('load').writeSignature(typeLoc, flags).writeString('_l').trim();
                                    output.printlnInstruction(toString(mnemonic), __local.fasmSimpleName);
                                end;
                            end;
                            LOAD_STATIC: begin
                                reference := __node.operand1 as Field;
                            end;
                            READ_FIELD: begin
                                __field := __node.operand1 as Field;
                                itemI := __node.operand2;
                                itemC := __node.operandC;
                                __type := __field.&type;
                                suffix := additionalToFasmString(itemC, itemI, operandA);
                                if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                    mnmnc := 'frdsf';
                                end else begin
                                    mnmnc := 'frdif';
                                end;
                                if __next.instruction = WRITE_FIELD then begin
                                    flags := WEAK;
                                end else begin
                                    flags := NORM;
                                end;
                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, flags).writeString(suffix).trim();
                                operands[0] := __field.fasmFullName;
                                operands[1] := toString(operandA);
                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                if (__next.instruction = METHOD_LEAVE) and (itemI is Local) then begin
                                    reference := itemI;
                                    output.printlnInstruction('frelease_o', itemI.fasmSimpleName);
                                end;
                            end;
                            WRITE_FIELD: begin
                                __field := __node.operand1 as Field;
                                __type := __field.&type;
                                suffix := additionalToFasmString(nil, reference, operandA);
                                if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                    mnmnc := 'fwrsf';
                                end else begin
                                    mnmnc := 'fwrif';
                                end;
                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, WEAK).writeString(suffix).trim();
                                operands[0] := __field.fasmFullName;
                                operands[1] := toString(operandA);
                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                            end;
                            METHOD_LEAVE: begin
                                if thisArgument <> nil then begin
                                    aindex := -1;
                                end else begin
                                    aindex := 0;
                                end;
                                while aindex < alength do begin
                                    if aindex < 0 then begin
                                        argument := thisArgument;
                                    end else begin
                                        argument := arguments.readComponent(aindex);
                                    end;
                                    if argument <> reference then case argument.&type.kind of
                                    TYP_INT8,
                                    TYP_LONG4,
                                    TYP_FLOAT8,
                                    TYP_DOUBLE4: begin
                                        output.printlnInstruction('fcltag_y', argument.fasmSimpleName);
                                    end;
                                    TYP_LONG8,
                                    TYP_DOUBLE8: begin
                                        output.printlnInstruction('fcltag_z', argument.fasmSimpleName);
                                    end;
                                    TYP_REF: begin
                                        name := argument.fasmSimpleName;
                                        output.printlnInstruction('frelease', name);
                                        output.printlnInstruction('fcltag_x', name);
                                    end;
                                    end;
                                    inc(aindex);
                                end;
                                output.printlnInstruction('fleave');
                                goto break_label0;
                            end;
                            end;
                            __node := __next;
                        until false;
                    end;
                end;
                { заголовок нормального метода }
                operands[0] := fasmFullName;
                operands[1] := '\';
                if not isInstance and (alength <= 0) then begin
                    output.printlnInstruction('method', operands, 0, 1);
                end else begin
                    output.printlnInstruction('method', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[2] := '\';
                alimit := alength - 1;
                if isInstance then begin
                    aindex := -1;
                end else begin
                    aindex := 0;
                end;
                while aindex < alength do begin
                    if aindex < 0 then begin
                        argument := thisArgument;
                    end else begin
                        argument := arguments.readComponent(aindex);
                    end;
                    operands[0] := argument.fasmSimpleName;
                    operands[1] := argument.&type.fasmSimpleName;
                    if aindex >= alimit then begin
                        output.printlnContinuation(operands, 0, 2);
                    end else begin
                        output.printlnContinuation(operands, 0, 3);
                    end;
                    inc(aindex);
                end;
                { локальные переменные }
                refsTable := HashtableOfAnsiStringToType.create();
                try
                    refsArray := nil;
                    mainArray := nil;
                    mainTable := HashtableOfAnsiStringToType.create();
                    try
                        refsArray := UnicodeStringArray.create();
                        mainArray := UnicodeStringArray.create();
                        with __code.locals do for index := 0 to getLength() - 1 do with readComponent(index) do if not isConstant() then begin
                            __type := &type;
                            name := fasmSimpleName;
                            if not mainTable.contains(name) then begin
                                mainArray.append(name);
                                mainTable[name] := __type;
                            end else
                            if not refsTable.contains(name) then begin
                                __prev := mainTable[name];
                                if __prev.isPrimitive() then begin
                                    if not __type.isPrimitive() then begin
                                        refsArray.append(name);
                                        refsTable[name] := __type;
                                    end else
                                    if __prev.fieldWidth < __type.fieldWidth then begin
                                        mainTable[name] := __type;
                                    end;
                                end else
                                if __type.isPrimitive() then begin
                                    refsArray.append(name);
                                    refsTable[name] := __prev;
                                    mainTable[name] := __type;
                                end;
                            end else
                            if __type.isPrimitive() and (mainTable[name].fieldWidth < __type.fieldWidth) then begin
                                mainTable[name] := __type;
                            end;
                        end;
                        operands[2] := '\';
                        length := mainArray.getLength();
                        limit := refsArray.getLength() + length - 1;
                        for index := 0 to limit do begin
                            if index < length then begin
                                name := mainArray.readComponent(index).asAnsiString();
                                __type := mainTable[name];
                                operands[0] := name;
                            end else begin
                                name := refsArray.readComponent(index - length).asAnsiString();
                                __type := refsTable[name];
                                operands[0] := writer.&set(operandA).writeChar('$').writeString(name).get();
                            end;
                            operands[1] := __type.fasmSimpleName;
                            if index <= 0 then begin
                                if index < limit then begin
                                    output.printlnInstruction('loc', operands, 0, 3);
                                    continue;
                                end;
                                output.printlnInstruction('loc', operands, 0, 2);
                                continue;
                            end;
                            if index < limit then begin
                                output.printlnContinuation(operands, 0, 3);
                                continue;
                            end;
                            output.printlnContinuation(operands, 0, 2);
                        end;
                    finally
                        refsArray.free();
                        mainArray.free();
                        mainTable.free();
                        refsArray := nil;
                        mainArray := nil;
                        mainTable := nil;
                    end;
                    { -------------------------------------------------------------------------------------------------------------------------------- }
                    anonymus := false;
                    lines := nil;
                    if Lang.isInstance(__source, TextSource) then begin
                        lines := TextSource(Lang.cast(__source, TextSource)).lines;
                    end;
                    __node := nil;
                    if clength > 0 then begin
                        __node := __code.readComponent(0);
                    end;
                    cindex := 0;
                    while cindex < clength do begin
                        inc(cindex);
                        if cindex >= clength then begin
                            __next := nil;
                        end else begin
                            __next := __code.readComponent(cindex);
                        end;
                        jumpIsTrue := __node.jumpIsTrue;
                        jumpIsFalse := __node.jumpIsFalse;
                        isConditionalJump := (jumpIsTrue <> nil) and (jumpIsFalse <> nil);
                        if isConditionalJump then begin
                            kindOfResultType := TYP_BOOLEAN;
                        end else begin
                            kindOfResultType := getNeedRegisterTypeKind(__next);
                        end;
                        { метки }
                        __label := __node.debugIndex;
                        if __label >= 0 then begin
                            if textSourcePath <> '' then begin
                                line := __node.location[0];
                                if line >= 0 then begin
                                    { строка текстового исходного кода }
                                    writer.&set(operandA).writeDecimal(line + 1).trim();
                                    output.printHeader('; ');
                                    output.print(textSourcePath);
                                    output.print('[');
                                    output.print(toString(operandA));
                                    output.print(']');
                                    if (lines <> nil) and (line < lines.getLength()) then begin
                                        output.print(': ');
                                        output.print(lines.readComponent(line).toString().trim());
                                    end;
                                    output.println();
                                end;
                            end;
                            output.printLabel(writer.&set(operandA).writeLabel('D', __label).get());
                        end;
                        __label := __node.labelIndex;
                        if __label >= 0 then begin
                            output.printLabel(writer.&set(operandA).writeLabel('L', __label).get());
                        end;
                        { инструкции }
                        begin
                            begin
                                kindOfPushType := TYP_BOOLEAN;
                                begin
                                    instruction := __node.instruction;
                                    case instruction of
                                    FCT_END,
                                    FCT_BEGIN,
                                    FCT_BOUND: begin
                                        goto continue_label1;
                                    end;
                                    EXP_INSTANCEOF: begin
                                        output.printlnInstruction('instof', (__node.operand1 as ru.malik.elaborarer.avtoo.lang.ClassType).fasmFullName);
                                    end;
                                    FCT_JUMP,
                                    FCT_RETURN,
                                    FCT_BRANCH: begin
                                        if instruction = FCT_BRANCH then begin
                                            jlength := __node.getJumpCasesLength();
                                            if jlength > 0 then begin
                                                if labels = nil then labels := &Array.newChar2d($0008, $0020);
                                                min := __node.getJumpCaseValueAt(0);
                                                max := min;
                                                for jindex := 1 to jlength - 1 do begin
                                                    cur := __node.getJumpCaseValueAt(jindex);
                                                    if min > cur then min := cur;
                                                    if max < cur then max := cur;
                                                end;
                                                jumpDefault := __node.jumpDefault;
                                                if ((long(max) - min + 1) shl 2) + 48 > (long(jlength) + 1) * 10 then begin
                                                    operands[0] := writer.&set(operandA).writeLabel(jumpDefault).get();
                                                    operands[1] := '\';
                                                    output.printlnInstruction('switch_l', operands, 0, 2);
                                                    operands[2] := '\';
                                                    jindex := 0;
                                                    while jindex < jlength do begin
                                                        jvalue := __node.getJumpCaseValueAt(jindex);
                                                        target := __node.getJumpCaseNodeAt(jindex);
                                                        operands[0] := writer.&set(labels[0]).writeInt(jvalue).get();
                                                        operands[1] := writer.&set(labels[1]).writeLabel(target).get();
                                                        inc(jindex);
                                                        if jindex < jlength then begin
                                                            output.printlnContinuation(operands, 0, 3);
                                                            continue;
                                                        end;
                                                        output.printlnContinuation(operands, 0, 2);
                                                    end;
                                                    goto continue_label1;
                                                end;
                                                operands[0] := writer.&set(operandA).writeLabel(jumpDefault).get();
                                                operands[1] := writer.&set(operandB).writeInt(min).get();
                                                operands[2] := '\';
                                                output.printlnInstruction('switch_t', operands, 0, 3);
                                                operands[8] := '\';
                                                jlength := max - min + 1;
                                                jvalue := min;
                                                for jindex := 0 to jlength - 1 do begin
                                                    jlower := jindex and 7;
                                                    target := __node.getJumpCase(jvalue);
                                                    if target = nil then target := jumpDefault;
                                                    operands[jlower] := writer.&set(labels[jlower]).writeLabel(target).get();
                                                    inc(jlower);
                                                    if jvalue = max then begin
                                                        output.printlnContinuation(operands, 0, jlower);
                                                    end else
                                                    if jlower = 8 then begin
                                                        output.printlnContinuation(operands, 0, 9);
                                                    end;
                                                    inc(jvalue);
                                                end;
                                                goto continue_label1;
                                            end;
                                        end;
                                        writer.&set(operandA).writeLabel(__node.jumpDefault).trim();
                                        output.printlnInstruction('jmp', toString(operandA));
                                        goto continue_label1;
                                    end;
                                    FCT_THROW: begin
                                        output.printlnInstruction('throw');
                                        goto continue_label1;
                                    end;
                                    INVOKE_FINALLY: begin
                                        writer.&set(operandA).writeLabel(__node.reference1 as Node).trim();
                                        output.printlnInstruction('invfin', toString(operandA));
                                        goto break_labelPop;
                                    end;
                                    CLINIT_TRY_LOCK: begin
                                        output.printlnInstruction('citrlock', (__node.operand1 as ReflectItem).fasmFullName);
                                    end;
                                    CLINIT_UNLOCK: begin
                                        output.printlnInstruction('ciunlock', (__node.operand1 as ReflectItem).fasmFullName);
                                        goto continue_label1;
                                    end;
                                    FINALLY_ENTER: begin
                                        output.printlnInstruction('finenter');
                                        goto continue_label1;
                                    end;
                                    FINALLY_LEAVE: begin
                                        output.printlnInstruction('finleave');
                                        goto continue_label1;
                                    end;
                                    MONITOR_ENTER: begin
                                        output.printlnInstruction('monenter');
                                        goto continue_label1;
                                    end;
                                    MONITOR_LEAVE: begin
                                        output.printlnInstruction('monleave');
                                        goto continue_label1;
                                    end;
                                    METHOD_ENTER: begin
                                        writer.&set(operandA).writeOffset((__node.reference1 as CoInt).asInt()).trim();
                                        if __callable.isInterrupt() then begin
                                            mnmnc := 'ienter';
                                        end else begin
                                            mnmnc := 'menter';
                                        end;
                                        output.printlnInstruction(mnmnc, toString(operandA));
                                        goto continue_label1;
                                    end;
                                    METHOD_LEAVE: begin
                                        if __callable.isInterrupt() then begin
                                            mnmnc := 'ileave';
                                        end else begin
                                            mnmnc := 'mleave';
                                        end;
                                        output.printlnInstruction(mnmnc);
                                        goto continue_label1;
                                    end;
                                    LOAD_CONST: begin
                                        __value := __node.operandC;
                                        __type := __value.&type;
                                        if __value.isString() then begin
                                            writer.&set(operandA).writeOffset(fldStringStorage.indexAcquire((__value.asInterface() as Value).asUnicodeString())).trim();
                                            output.printlnInstruction('loadstr', toString(operandA));
                                            kindOfPushType := TYP_REF;
                                            goto break_labelPush;
                                        end;
                                        constantToFasmString(__value, operandA);
                                        if __node.weak then begin
                                            flags := STACK or WEAK;
                                        end else begin
                                            flags := STACK;
                                        end;
                                        writer.&set(mnemonic).writeString('load').writeSignature(__type, flags).writeString('_g').trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    LOAD_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        __type := __node.operand2 as &Type;
                                        name := __local.fasmSimpleName;
                                        if __type = nil then __type := __local.&type;
                                        if __node.weak then begin
                                            flags := STACK or WEAK;
                                        end else begin
                                            flags := STACK;
                                        end;
                                        writer.&set(mnemonic).writeString('load').writeSignature(__type, flags).writeString('_l').trim();
                                        if __type.isPrimitive() or not refsTable.contains(name) then begin
                                            operands[0] := name;
                                        end else begin
                                            operands[0] := writer.&set(operandA).writeChar('$').writeString(name).get();
                                        end;
                                        output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                        kindOfPushType := __type.kind;
                                    end;
                                    LOAD_INTERRUPT: begin
                                        output.printlnInstruction('loadint', (__node.operand1 as ReflectItem).fasmFullName);
                                        kindOfPushType := TYP_LONG;
                                        goto break_labelPush;
                                    end;
                                    LOAD_STATIC: begin
                                        __global := __node.operand1 as Field;
                                        __type := __global.&type;
                                        if __node.weak then begin
                                            flags := STACK or WEAK;
                                        end else begin
                                            flags := STACK;
                                        end;
                                        writer.&set(mnemonic).writeString('load').writeSignature(__type, flags).writeString('_g').trim();
                                        writer.&set(operandA).writeChar('[').writeString(__global.fasmFullName).writeChar(']').trim();
                                        output.printlnInstruction(toString(mnemonic),  toString(operandA));
                                        kindOfPushType := __type.kind;
                                    end;
                                    READ_ELEMENT: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        __index := __node.operandC;
                                        if __index = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('rdve').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('rdve').writeSignature(__type, NORM).writeString('_c').trim();
                                        writer.&set(operandA).writeDecimal(__index.asInt()).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := PrimitiveType(__type).vectorBaseKind;
                                        goto break_labelPush;
                                    end;
                                    READ_COMPONENT: begin
                                        __type := __node.operand1 as &Type;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('rdac').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto break_labelConj;
                                        end;
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        writer.&set(mnemonic).writeString('rdac').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                    end;
                                    READ_FIELD: begin
                                        __field := __node.operand1 as Field;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        __type := __field.&type;
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                            mnmnc := 'rdsf';
                                        end else begin
                                            mnmnc := 'rdif';
                                        end;
                                        writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, NORM).writeString(suffix).trim();
                                        operands[0] := __field.fasmFullName;
                                        operands[1] := toString(operandA);
                                        if itemT = nil then begin
                                            output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                        end else begin
                                            output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                        end;
                                        kindOfPushType := __type.kind;
                                    end;
                                    READ_SPECIAL: begin
                                        __property := __node.operand1 as &Property;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        synthetic := __property.readSynthetic;
                                        if not __property.hasIndex() then begin
                                            __member := __property.readMember;
                                            if Lang.isInstance(__member, Field) then begin
                                                __field := Field(Lang.cast(__member, Field));
                                                __type := __field.&type;
                                                suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                                if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                                    mnmnc := 'rdsf';
                                                end else begin
                                                    mnmnc := 'rdif';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, NORM).writeString(suffix).trim();
                                                operands[0] := __field.fasmFullName;
                                                operands[1] := toString(operandA);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                                kindOfPushType := __type.kind;
                                                goto break_label2;
                                            end;
                                            if Lang.isInstance(__member, Callable) then begin
                                                if itemT <> nil then begin
                                                    suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                                    writer.&set(mnemonic).writeString('load').writeSignature(itemT.&type, STACK).writeString(suffix).trim();
                                                    output.printlnInstruction(toString(mnemonic), toString(operandA));
                                                    output.printlnInstruction('tpushr');
                                                end;
                                                __methodc := Callable(Lang.cast(__member, Callable));
                                                if __methodc.serviceIndex >= 0 then begin
                                                    operands[0] := __methodc.parentType.fasmFullName;
                                                    operands[1] := writer.&set(operandA).writeString(__methodc.fasmSimpleName).writeString(__methodc.arguments.toFasmString()).get();
                                                    output.printlnInstruction('invserv', operands, 0, 2);
                                                end else
                                                if __methodc.virtualIndex >= 0 then begin
                                                    output.printlnInstruction('invvirt', __methodc.fasmFullName);
                                                end else begin
                                                    output.printlnInstruction('invspec', __methodc.fasmFullName);
                                                end;
                                                kindOfPushType := __methodc.&type.kind;
                                                goto break_label2;
                                            end;
                                        end;
                                        if itemT <> nil then begin
                                            suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                            writer.&set(mnemonic).writeString('load').writeSignature(itemT.&type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic), toString(operandA));
                                            output.printlnInstruction('tpushr');
                                        end;
                                        output.printlnInstruction('invspec', synthetic.fasmFullName);
                                        kindOfPushType := synthetic.&type.kind;
                                    end;
                                    READ_PROPERTY: begin
                                        __property := __node.operand1 as &Property;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        synthetic := __property.readSynthetic;
                                        sindex := synthetic.serviceIndex;
                                        vindex := synthetic.virtualIndex;
                                        if not __property.hasIndex() and ((sindex and vindex) < 0) then begin
                                            __member := __property.readMember;
                                            if Lang.isInstance(__member, Field) then begin
                                                __field := Field(Lang.cast(__member, Field));
                                                __type := __field.&type;
                                                suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                                if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                                    mnmnc := 'rdsf';
                                                end else begin
                                                    mnmnc := 'rdif';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, NORM).writeString(suffix).trim();
                                                operands[0] := __field.fasmFullName;
                                                operands[1] := toString(operandA);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                                kindOfPushType := __type.kind;
                                                goto break_label2;
                                            end;
                                            if Lang.isInstance(__member, Callable) then begin
                                                if itemT <> nil then begin
                                                    suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                                    writer.&set(mnemonic).writeString('load').writeSignature(itemT.&type, STACK).writeString(suffix).trim();
                                                    output.printlnInstruction(toString(mnemonic), toString(operandA));
                                                    output.printlnInstruction('tpushr');
                                                end;
                                                __methodc := Callable(Lang.cast(__member, Callable));
                                                if __methodc.serviceIndex >= 0 then begin
                                                    operands[0] := __methodc.parentType.fasmFullName;
                                                    operands[1] := writer.&set(operandA).writeString(__methodc.fasmSimpleName).writeString(__methodc.arguments.toFasmString()).get();
                                                    output.printlnInstruction('invserv', operands, 0, 2);
                                                end else
                                                if __methodc.virtualIndex >= 0 then begin
                                                    output.printlnInstruction('invvirt', __methodc.fasmFullName);
                                                end else begin
                                                    output.printlnInstruction('invspec', __methodc.fasmFullName);
                                                end;
                                                kindOfPushType := __methodc.&type.kind;
                                                goto break_label2;
                                            end;
                                        end;
                                        if itemT <> nil then begin
                                            suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                            writer.&set(mnemonic).writeString('load').writeSignature(itemT.&type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic), toString(operandA));
                                            output.printlnInstruction('tpushr');
                                        end;
                                        if sindex >= 0 then begin
                                            operands[0] := synthetic.parentType.fasmFullName;
                                            operands[1] := writer.&set(operandA).writeString(synthetic.fasmSimpleName).writeString(synthetic.arguments.toFasmString()).get();
                                            output.printlnInstruction('invserv', operands, 0, 2);
                                        end else
                                        if vindex >= 0 then begin
                                            output.printlnInstruction('invvirt', synthetic.fasmFullName);
                                        end else begin
                                            output.printlnInstruction('invspec', synthetic.fasmFullName);
                                        end;
                                        kindOfPushType := synthetic.&type.kind;
                                    end;
                                    SWAP: begin
                                        writer.&set(mnemonic).writeString('tswap').writeSignature(__node.operand1 as &Type, STACK).writeString('_p').trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        goto continue_label1;
                                    end;
                                    DUP1: begin
                                        if kindOfResultType <= TYP_VOID then begin
                                            suffix := '_p';
                                        end else begin
                                            suffix := '';
                                        end;
                                        writer.&set(mnemonic).writeString('tdup1').writeSignature(__node.operand1 as &Type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        goto break_labelConj;
                                    end;
                                    DUP1X1: begin
                                        if kindOfResultType <= TYP_VOID then begin
                                            suffix := '_p';
                                        end else begin
                                            suffix := '';
                                        end;
                                        writer.&set(mnemonic).writeString('tdup1x1').writeSignature(__node.operand1 as &Type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        goto break_labelConj;
                                    end;
                                    DUP1X2: begin
                                        if kindOfResultType <= TYP_VOID then begin
                                            suffix := '_p';
                                        end else begin
                                            suffix := '';
                                        end;
                                        writer.&set(mnemonic).writeString('tdup1x2').writeSignature(__node.operand1 as &Type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        goto break_labelConj;
                                    end;
                                    DUP2: begin
                                        if kindOfResultType <= TYP_VOID then begin
                                            suffix := '_p';
                                        end else begin
                                            suffix := '';
                                        end;
                                        writer.&set(mnemonic).writeString('tdup2').writeSignature(__node.operand1 as &Type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        goto break_labelConj;
                                    end;
                                    INVOKE_STATIC: begin
                                        __methodc := __node.operand1 as Callable;
                                        __type := __methodc.&type;
                                        output.printlnInstruction('invstat', __methodc.fasmFullName);
                                        if __type.isVoid() then goto break_labelPop;
                                        if __node.weak then begin
                                            writer.&set(mnemonic).writeString('release').writeSignature(__type, STACK).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto break_labelPop;
                                        end;
                                        kindOfPushType := __type.kind;
                                    end;
                                    INVOKE_SPECIAL: begin
                                        __methodc := __node.operand1 as Callable;
                                        __type := __methodc.&type;
                                        output.printlnInstruction('invspec', __methodc.fasmFullName);
                                        if __type.isVoid() then goto break_labelPop;
                                        if __node.weak then begin
                                            writer.&set(mnemonic).writeString('release').writeSignature(__type, STACK).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto break_labelPop;
                                        end;
                                        kindOfPushType := __type.kind;
                                    end;
                                    INVOKE_VIRTUAL: begin
                                        __methodc := __node.operand1 as Callable;
                                        __type := __methodc.&type;
                                        if __methodc.virtualIndex >= 0 then begin
                                            output.printlnInstruction('invvirt', __methodc.fasmFullName);
                                        end else begin
                                            output.printlnInstruction('invspec', __methodc.fasmFullName);
                                        end;
                                        if __type.isVoid() then goto break_labelPop;
                                        if __node.weak then begin
                                            writer.&set(mnemonic).writeString('release').writeSignature(__type, STACK).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto break_labelPop;
                                        end;
                                        kindOfPushType := __type.kind;
                                    end;
                                    INVOKE_SERVICE: begin
                                        __methodc := __node.operand1 as Callable;
                                        __type := __methodc.&type;
                                        if __methodc.serviceIndex >= 0 then begin
                                            operands[0] := __methodc.parentType.fasmFullName;
                                            operands[1] := writer.&set(operandA).writeString(__methodc.fasmSimpleName).writeString(__methodc.arguments.toFasmString()).get();
                                            output.printlnInstruction('invserv', operands, 0, 2);
                                        end else
                                        if __methodc.virtualIndex >= 0 then begin
                                            output.printlnInstruction('invvirt', __methodc.fasmFullName);
                                        end else begin
                                            output.printlnInstruction('invspec', __methodc.fasmFullName);
                                        end;
                                        if __type.isVoid() then goto break_labelPop;
                                        if __node.weak then begin
                                            writer.&set(mnemonic).writeString('release').writeSignature(__type, STACK).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto break_labelPop;
                                        end;
                                        kindOfPushType := __type.kind;
                                    end;
                                    NEW_VECTOR: begin
                                        if kindOfResultType <= TYP_VOID then begin
                                            suffix := '_p';
                                        end else begin
                                            suffix := '';
                                        end;
                                        writer.&set(mnemonic).writeString('newv').writeSignature(__node.operand1 as PrimitiveType, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        goto continue_label1;
                                    end;
                                    NEW_ARRAY: begin
                                        operands[0] := (__node.operand1 as ArrayType).fasmFullName;
                                        operands[1] := writer.&set(operandA).writeInt(__node.operandC.asInt()).get();
                                        output.printlnInstruction('newa_c', operands, 0, 2);
                                        kindOfPushType := TYP_REF;
                                        goto break_labelPush;
                                    end;
                                    NEW_ARRAY_MONO: begin
                                        output.printlnInstruction('newa', (__node.operand1 as ArrayType).fasmFullName);
                                        kindOfPushType := TYP_REF;
                                        goto break_labelPush;
                                    end;
                                    NEW_ARRAY_MULTI: begin
                                        output.printlnInstruction('newam', (__node.operand1 as ArrayType).fasmFullName);
                                        kindOfPushType := TYP_REF;
                                        goto break_labelPush;
                                    end;
                                    NEW_INSTANCE: begin
                                        output.printlnInstruction('newi', (__node.operand1 as ru.malik.elaborarer.avtoo.lang.ClassType).fasmFullName);
                                        kindOfPushType := TYP_REF;
                                        goto break_labelPush;
                                    end;
                                    CAST_TO: begin
                                        typeNew := __node.operand1 as &Type;
                                        typeSrc := __node.operand2 as &Type;
                                        if not typeNew.isPrimitive() then begin
                                            output.printlnInstruction('castrto', typeNew.fasmFullName);
                                            kindOfPushType := TYP_REF;
                                            goto break_labelPush;
                                        end;
                                        with typeNew as PrimitiveType do begin
                                            kindOfNew := kind;
                                            lengthOfNew := vectorLength;
                                            kindBaseOfNew := vectorBaseKind;
                                        end;
                                        with typeSrc as PrimitiveType do begin
                                            kindOfSrc := kind;
                                            lengthOfSrc := vectorLength;
                                            kindBaseOfSrc := vectorBaseKind;
                                        end;
                                        if kindOfSrc = TYP_CHAR then begin
                                            kindOfSrc := TYP_INT;
                                            lengthOfSrc := 1;
                                            kindBaseOfSrc := TYP_INT;
                                        end;
                                        if kindOfNew = TYP_CHAR then begin
                                            case kindBaseOfSrc of
                                            TYP_CHAR: ;
                                            TYP_BYTE,
                                            TYP_SHORT,
                                            TYP_INT: begin
                                                if lengthOfSrc > 1 then begin
                                                    writer.&set(mnemonic).writeString('cast').writeSignature(kindOfSrc, STACK).writeString('to').writeSignature(kindBaseOfSrc, NORM).trim();
                                                    output.printlnInstruction(toString(mnemonic));
                                                end;
                                                output.printlnInstruction('castitoc');
                                            end;
                                            else
                                                if lengthOfSrc > 1 then begin
                                                    writer.&set(mnemonic).writeString('cast').writeSignature(kindOfSrc, STACK).writeString('to').writeSignature(kindBaseOfSrc, NORM).trim();
                                                    output.printlnInstruction(toString(mnemonic));
                                                end;
                                                writer.&set(mnemonic).writeString('cast').writeSignature(kindBaseOfSrc, STACK).writeString('toi').trim();
                                                output.printlnInstruction(toString(mnemonic));
                                                output.printlnInstruction('castitoc');
                                            end;
                                        end else
                                        if lengthOfNew < lengthOfSrc then begin
                                            kindOfMid := kindBaseOfSrc or kindOfNew and 3;
                                            lengthOfMid := lengthOfNew;
                                            kindBaseOfMid := kindBaseOfSrc;
                                            { понижение длины вектора }
                                            begin
                                                writer.&set(mnemonic).writeString('cast').writeSignature(kindOfSrc, STACK).writeString('to').writeSignature(kindOfMid, NORM).trim();
                                                output.printlnInstruction(toString(mnemonic));
                                            end;
                                            { изменение типа элементов вектора }
                                            if isTypeCastAvailable(kindBaseOfMid, lengthOfMid, kindBaseOfNew, lengthOfNew) then begin
                                                writer.&set(mnemonic).writeString('cast').writeSignature(kindOfMid, STACK).writeString('to').writeSignature(kindOfNew, NORM).trim();
                                                output.printlnInstruction(toString(mnemonic));
                                            end;
                                        end else
                                        if lengthOfNew > lengthOfSrc then begin
                                            kindOfMid := kindBaseOfNew or kindOfSrc and 3;
                                            lengthOfMid := lengthOfSrc;
                                            kindBaseOfMid := kindBaseOfNew;
                                            { изменение типа элементов вектора }
                                            if isTypeCastAvailable(kindBaseOfSrc, lengthOfSrc, kindBaseOfMid, lengthOfMid) then begin
                                                writer.&set(mnemonic).writeString('cast').writeSignature(kindOfSrc, STACK).writeString('to').writeSignature(kindOfMid, NORM).trim();
                                                output.printlnInstruction(toString(mnemonic));
                                            end;
                                            { повышение длины вектора }
                                            begin
                                                writer.&set(mnemonic).writeString('cast').writeSignature(kindOfMid, STACK).writeString('to').writeSignature(kindOfNew, NORM).trim();
                                                output.printlnInstruction(toString(mnemonic));
                                            end;
                                        end else begin
                                            { изменение типа элементов вектора }
                                            if isTypeCastAvailable(kindBaseOfSrc, lengthOfSrc, kindBaseOfNew, lengthOfNew) then begin
                                                writer.&set(mnemonic).writeString('cast').writeSignature(kindOfSrc, STACK).writeString('to').writeSignature(kindOfNew, NORM).trim();
                                                output.printlnInstruction(toString(mnemonic));
                                            end;
                                        end;
                                        kindOfPushType := kindOfNew;
                                        goto break_labelPush;
                                    end;
                                    INC_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        __type := __node.operand2 as &Type;
                                        if __type = nil then __type := __local.&type;
                                        writer.&set(mnemonic).writeString('inc').writeSignature(__type, NORM).writeString('_l').trim();
                                        output.printlnInstruction(toString(mnemonic), __local.fasmSimpleName);
                                        goto continue_label1;
                                    end;
                                    DEC_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        __type := __node.operand2 as &Type;
                                        if __type = nil then __type := __local.&type;
                                        writer.&set(mnemonic).writeString('dec').writeSignature(__type, NORM).writeString('_l').trim();
                                        output.printlnInstruction(toString(mnemonic), __local.fasmSimpleName);
                                        goto continue_label1;
                                    end;
                                    INC_PRED_LOAD_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        __type := __node.operand2 as &Type;
                                        if __type = nil then __type := __local.&type;
                                        writer.&set(mnemonic).writeString('incload').writeSignature(__type, NORM).writeString('_l').trim();
                                        output.printlnInstruction(toString(mnemonic), __local.fasmSimpleName);
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    DEC_PRED_LOAD_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        __type := __node.operand2 as &Type;
                                        if __type = nil then __type := __local.&type;
                                        writer.&set(mnemonic).writeString('decload').writeSignature(__type, NORM).writeString('_l').trim();
                                        output.printlnInstruction(toString(mnemonic), __local.fasmSimpleName);
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    INC_POST_LOAD_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        __type := __node.operand2 as &Type;
                                        if __type = nil then __type := __local.&type;
                                        writer.&set(mnemonic).writeString('loadinc').writeSignature(__type, NORM).writeString('_l').trim();
                                        output.printlnInstruction(toString(mnemonic), __local.fasmSimpleName);
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    DEC_POST_LOAD_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        __type := __node.operand2 as &Type;
                                        if __type = nil then __type := __local.&type;
                                        writer.&set(mnemonic).writeString('loaddec').writeSignature(__type, NORM).writeString('_l').trim();
                                        output.printlnInstruction(toString(mnemonic), __local.fasmSimpleName);
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    REF_EQ: begin
                                        itemI := __node.operand1;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                if __node.weak then begin
                                                    mnmnc := 'jweq';
                                                end else begin
                                                    mnmnc := 'jreq';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                if __node.weak then begin
                                                    mnmnc := 'jwne';
                                                end else begin
                                                    mnmnc := 'jrne';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                mnmnc := 'setreq_p';
                                            end else begin
                                                mnmnc := 'setreq';
                                            end;
                                            output.printlnInstruction(mnmnc);
                                            goto continue_label1;
                                        end;
                                        if __node.weak then begin
                                            mnmnc := 'setweq';
                                        end else begin
                                            mnmnc := 'setreq';
                                        end;
                                        writer.&set(mnemonic).writeString(mnmnc).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    REF_NE: begin
                                        itemI := __node.operand1;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                if __node.weak then begin
                                                    mnmnc := 'jwne';
                                                end else begin
                                                    mnmnc := 'jrne';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                if __node.weak then begin
                                                    mnmnc := 'jweq';
                                                end else begin
                                                    mnmnc := 'jreq';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                mnmnc := 'setrne_p';
                                            end else begin
                                                mnmnc := 'setrne';
                                            end;
                                            output.printlnInstruction(mnmnc);
                                            goto continue_label1;
                                        end;
                                        if __node.weak then begin
                                            mnmnc := 'setwne';
                                        end else begin
                                            mnmnc := 'setrne';
                                        end;
                                        writer.&set(mnemonic).writeString(mnmnc).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    REF_IS_NULL: begin
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                if __node.weak then begin
                                                    mnmnc := 'jwisnull';
                                                end else begin
                                                    mnmnc := 'jrisnull';
                                                end;
                                                output.printlnInstruction(mnmnc, toString(operandA));
                                                goto continue_label1;
                                            end;
                                            begin
                                                writer.&set(operandA).writeLabel(jumpIsFalse).trim();
                                                if __node.weak then begin
                                                    mnmnc := 'jwisobj';
                                                end else begin
                                                    mnmnc := 'jrisobj';
                                                end;
                                                output.printlnInstruction(mnmnc, toString(operandA));
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if __node.weak then begin
                                            mnmnc := 'setwisnull';
                                        end else begin
                                            mnmnc := 'setrisnull';
                                        end;
                                        output.printlnInstruction(mnmnc);
                                        goto break_labelPush;
                                    end;
                                    REF_IS_OBJECT: begin
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                if __node.weak then begin
                                                    mnmnc := 'jwisobj';
                                                end else begin
                                                    mnmnc := 'jrisobj';
                                                end;
                                                output.printlnInstruction(mnmnc, toString(operandA));
                                                goto continue_label1;
                                            end;
                                            begin
                                                writer.&set(operandA).writeLabel(jumpIsFalse).trim();
                                                if __node.weak then begin
                                                    mnmnc := 'jwisnull';
                                                end else begin
                                                    mnmnc := 'jrisnull';
                                                end;
                                                output.printlnInstruction(mnmnc, toString(operandA));
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if __node.weak then begin
                                            mnmnc := 'setwisobj';
                                        end else begin
                                            mnmnc := 'setrisobj';
                                        end;
                                        output.printlnInstruction(mnmnc);
                                        goto break_labelPush;
                                    end;
                                    TEST_EQZ: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                writer.&set(mnemonic).writeString('jteq').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                writer.&set(mnemonic).writeString('jtne').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('setteq').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('setteq').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    TEST_NEZ: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                writer.&set(mnemonic).writeString('jtne').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                writer.&set(mnemonic).writeString('jteq').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('settne').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('settne').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    O_BIT_NOT: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        writer.&set(mnemonic).writeString('bnot').writeSignature(__type, STACK).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        kindOfPushType := __type.kind;
                                    end;
                                    O_BIT_AND: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                writer.&set(mnemonic).writeString('jtne').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                writer.&set(mnemonic).writeString('jteq').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('band').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('band').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_BIT_OR: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('bor').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto break_labelConj;
                                        end;
                                        writer.&set(mnemonic).writeString('bor').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                    end;
                                    O_BIT_XOR: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('bxor').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto break_labelConj;
                                        end;
                                        writer.&set(mnemonic).writeString('bxor').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                    end;
                                    O_SCAL_NEG: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        writer.&set(mnemonic).writeString('sneg').writeSignature(__type, STACK).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_MUL: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('smul').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('smul').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_DIV: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('sdiv').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('sdiv').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_DIVU: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('sdivu').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('sdivu').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_REM: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('srem').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('srem').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_REMU: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('sremu').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('sremu').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_ADD: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('sadd').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('sadd').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_SUB: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('ssub').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('ssub').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_SHR: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('sshr').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('sshr').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_SHRU: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('sshru').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('sshru').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_SHL: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('sshl').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('sshl').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_EQ: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                writer.&set(mnemonic).writeString('jseq').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                writer.&set(mnemonic).writeString('jsne').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('setseq').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('setseq').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_NE: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                writer.&set(mnemonic).writeString('jsne').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                writer.&set(mnemonic).writeString('jseq').writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('setsne').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('setsne').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_GT: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jsgtl';
                                                end else begin
                                                    mnmnc := 'jsgt';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jslel';
                                                end else begin
                                                    mnmnc := 'jsle';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('setsgt').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('setsgt').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_GE: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jsgel';
                                                end else begin
                                                    mnmnc := 'jsge';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jsltl';
                                                end else begin
                                                    mnmnc := 'jslt';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('setsge').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('setsge').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_LT: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jsltg';
                                                end else begin
                                                    mnmnc := 'jslt';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jsgeg';
                                                end else begin
                                                    mnmnc := 'jsge';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('setslt').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('setslt').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    O_SCAL_LE: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, ItemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandB, refsTable);
                                        if isConditionalJump then begin
                                            order := __node.order + 1;
                                            if jumpIsFalse.order = order then begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jsleg';
                                                end else begin
                                                    mnmnc := 'jsle';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsTrue).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                    goto continue_label1;
                                                end;
                                                output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                goto continue_label1;
                                            end;
                                            begin
                                                if __type.isFloating() then begin
                                                    mnmnc := 'jsgtg';
                                                end else begin
                                                    mnmnc := 'jsgt';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, STACK).writeString(suffix).trim();
                                                operands[0] := writer.&set(operandA).writeLabel(jumpIsFalse).get();
                                                operands[1] := toString(operandB);
                                                if itemT = nil then begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                                end else begin
                                                    output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                                end;
                                            end;
                                            if jumpIsTrue.order <> order then begin
                                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                                output.printlnInstruction('jmp', toString(operandA));
                                            end;
                                            goto continue_label1;
                                        end;
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('setsle').writeSignature(__type, STACK).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('setsle').writeSignature(__type, STACK).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandB));
                                        goto break_labelPush;
                                    end;
                                    O_VECT_LUP: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        writer.&set(mnemonic).writeString('vlup').writeSignature(__type, NORM).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        kindOfPushType := __type.kind + (TYP_SHORT - TYP_BYTE);
                                        goto break_labelPush;
                                    end;
                                    O_VECT_UUP: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        writer.&set(mnemonic).writeString('vuup').writeSignature(__type, NORM).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        kindOfPushType := __type.kind + (TYP_SHORT - TYP_BYTE);
                                        goto break_labelPush;
                                    end;
                                    O_VECT_PCK: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        writer.&set(mnemonic).writeString('vpck').writeSignature(__type, NORM).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        kindOfPushType := __type.kind + (TYP_BYTE - TYP_SHORT);
                                        goto break_labelPush;
                                    end;
                                    O_VECT_NEG: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        writer.&set(mnemonic).writeString('vneg').writeSignature(__type, NORM).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_MUL: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vmul').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vmul').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_DIV: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vdiv').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vdiv').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        if not __type.isFloating() then begin
                                            kindOfPushType := TYP_DOUBLE or __type.kind and 3;
                                            goto break_labelPush;
                                        end;
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_ADD: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vadd').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vadd').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SUB: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vsub').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vsub').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SHR: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vshr').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vshr').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SHRU: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vshru').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vshru').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SHL: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vshl').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vshl').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_EQ: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('veq').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('veq').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        if (kindOfPushType >= TYP_DOUBLE) and (kindOfPushType <= TYP_DOUBLE8) then begin
                                            inc(kindOfPushType, TYP_LONG - TYP_DOUBLE);
                                            goto break_labelPush;
                                        end;
                                        if (kindOfPushType >= TYP_FLOAT) and (kindOfPushType <= TYP_FLOAT8) then begin
                                            inc(kindOfPushType, TYP_INT - TYP_FLOAT);
                                        end;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_NE: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vne').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vne').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        if (kindOfPushType >= TYP_DOUBLE) and (kindOfPushType <= TYP_DOUBLE8) then begin
                                            inc(kindOfPushType, TYP_LONG - TYP_DOUBLE);
                                            goto break_labelPush;
                                        end;
                                        if (kindOfPushType >= TYP_FLOAT) and (kindOfPushType <= TYP_FLOAT8) then begin
                                            inc(kindOfPushType, TYP_INT - TYP_FLOAT);
                                        end;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_GT: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vgt').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vgt').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        if (kindOfPushType >= TYP_DOUBLE) and (kindOfPushType <= TYP_DOUBLE8) then begin
                                            inc(kindOfPushType, TYP_LONG - TYP_DOUBLE);
                                            goto break_labelPush;
                                        end;
                                        if (kindOfPushType >= TYP_FLOAT) and (kindOfPushType <= TYP_FLOAT8) then begin
                                            inc(kindOfPushType, TYP_INT - TYP_FLOAT);
                                        end;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_GE: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vge').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vge').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        if (kindOfPushType >= TYP_DOUBLE) and (kindOfPushType <= TYP_DOUBLE8) then begin
                                            inc(kindOfPushType, TYP_LONG - TYP_DOUBLE);
                                            goto break_labelPush;
                                        end;
                                        if (kindOfPushType >= TYP_FLOAT) and (kindOfPushType <= TYP_FLOAT8) then begin
                                            inc(kindOfPushType, TYP_INT - TYP_FLOAT);
                                        end;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_LT: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vlt').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vlt').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        if (kindOfPushType >= TYP_DOUBLE) and (kindOfPushType <= TYP_DOUBLE8) then begin
                                            inc(kindOfPushType, TYP_LONG - TYP_DOUBLE);
                                            goto break_labelPush;
                                        end;
                                        if (kindOfPushType >= TYP_FLOAT) and (kindOfPushType <= TYP_FLOAT8) then begin
                                            inc(kindOfPushType, TYP_INT - TYP_FLOAT);
                                        end;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_LE: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vle').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vle').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        if (kindOfPushType >= TYP_DOUBLE) and (kindOfPushType <= TYP_DOUBLE8) then begin
                                            inc(kindOfPushType, TYP_LONG - TYP_DOUBLE);
                                            goto break_labelPush;
                                        end;
                                        if (kindOfPushType >= TYP_FLOAT) and (kindOfPushType <= TYP_FLOAT8) then begin
                                            inc(kindOfPushType, TYP_INT - TYP_FLOAT);
                                        end;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_HMUL: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vhmul').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vhmul').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_HMULU: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vhmulu').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vhmulu').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SADD: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vsadd').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vsadd').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SADDU: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vsaddu').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vsaddu').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SSUB: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vssub').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vssub').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    O_VECT_SSUBU: begin
                                        __type := __node.operand1 as PrimitiveType;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        itemT := getTypedItem(itemC, itemI);
                                        suffix := additionalToFasmString(itemC, itemI, operandA, refsTable);
                                        if itemT = nil then begin
                                            if kindOfResultType <= TYP_VOID then begin
                                                suffix := '_p';
                                            end else begin
                                                suffix := '';
                                            end;
                                            writer.&set(mnemonic).writeString('vssubu').writeSignature(__type, NORM).writeString(suffix).trim();
                                            output.printlnInstruction(toString(mnemonic));
                                            goto continue_label1;
                                        end;
                                        writer.&set(mnemonic).writeString('vssubu').writeSignature(__type, NORM).writeString(suffix).trim();
                                        output.printlnInstruction(toString(mnemonic), toString(operandA));
                                        kindOfPushType := __type.kind;
                                        goto break_labelPush;
                                    end;
                                    STORE_LOCAL: begin
                                        __local := __node.operand1 as Local;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        name := __local.fasmSimpleName;
                                        if itemC = nil then begin
                                            if itemI = nil then begin
                                                __type := __local.&type;
                                            end else begin
                                                __type := itemI as &Type;
                                            end;
                                            writer.&set(mnemonic).writeString('store').writeSignature(__type, STACK).writeString('_l').trim();
                                            if __type.isPrimitive() or not refsTable.contains(name) then begin
                                                operands[0] := name;
                                            end else begin
                                                operands[0] := writer.&set(operandA).writeChar('$').writeString(name).get();
                                            end;
                                            output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                            goto break_labelPop;
                                        end;
                                        __type := itemC.&type;
                                        constantToFasmString(itemC, operandB);
                                        writer.&set(mnemonic).writeString('store').writeSignature(__type, STACK).writeString('_lc').trim();
                                        if __type.isPrimitive() or not refsTable.contains(name) then begin
                                            operands[0] := name;
                                        end else begin
                                            operands[0] := writer.&set(operandA).writeChar('$').writeString(name).get();
                                        end;
                                        operands[1] := toString(operandB);
                                        output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                        goto break_labelPop;
                                    end;
                                    DECLARE_LOCAL,
                                    DECLARE_WITH: begin
                                        __local := __node.operand1 as Local;
                                        itemI := __node.operand2;
                                        itemC := __node.operandC;
                                        name := __local.fasmSimpleName;
                                        if itemC = nil then begin
                                            if itemI = nil then begin
                                                __type := __local.&type;
                                            end else begin
                                                __type := itemI as &Type;
                                            end;
                                            writer.&set(mnemonic).writeString('declare').writeSignature(__type, STACK).trim();
                                            if __type.isPrimitive() or not refsTable.contains(name) then begin
                                                operands[0] := name;
                                            end else begin
                                                operands[0] := writer.&set(operandA).writeChar('$').writeString(name).get();
                                            end;
                                            output.printlnInstruction(toString(mnemonic), operands, 0, 1);
                                            goto break_labelPop;
                                        end;
                                        __type := itemC.&type;
                                        constantToFasmString(itemC, operandB);
                                        writer.&set(mnemonic).writeString('declare').writeSignature(__type, STACK).writeString('_c').trim();
                                        if __type.isPrimitive() or not refsTable.contains(name) then begin
                                            operands[0] := name;
                                        end else begin
                                            operands[0] := writer.&set(operandA).writeChar('$').writeString(name).get();
                                        end;
                                        operands[1] := toString(operandB);
                                        output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                        goto break_labelPop;
                                    end;
                                    STORE_STATIC: begin
                                        __global := __node.operand1 as Field;
                                        __value := __node.operandC;
                                        if __value = nil then begin
                                            writer.&set(mnemonic).writeString('store').writeSignature(__global.&type, STACK).writeString('_g').trim();
                                            writer.&set(operandA).writeChar('[').writeString(__global.fasmFullName).writeChar(']').trim();
                                            output.printlnInstruction(toString(mnemonic), toString(operandA));
                                            goto break_labelPop;
                                        end;
                                        constantToFasmString(__value, operandB);
                                        writer.&set(mnemonic).writeString('store').writeSignature(__global.&type, STACK).writeString('_gc').trim();
                                        operands[0] := writer.&set(operandA).writeChar('[').writeString(__global.fasmFullName).writeChar(']').get();
                                        operands[1] := toString(operandB);
                                        output.printlnInstruction(toString(mnemonic), operands, 0, 2);
                                        goto break_labelPop;
                                    end;
                                    WRITE_COMPONENT: begin
                                        __type := __node.operand1 as &Type;
                                        writer.&set(mnemonic).writeString('wrac').writeSignature(__type, NORM).trim();
                                        output.printlnInstruction(toString(mnemonic));
                                        goto break_labelPop;
                                    end;
                                    WRITE_FIELD: begin
                                        __field := __node.operand1 as Field;
                                        __type := __field.&type;
                                        if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                            mnmnc := 'wrsf';
                                        end else begin
                                            mnmnc := 'wrif';
                                        end;
                                        writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, NORM).trim();
                                        output.printlnInstruction(toString(mnemonic), __field.fasmFullName);
                                        goto break_labelPop;
                                    end;
                                    WRITE_SPECIAL: begin
                                        __property := __node.operand1 as &Property;
                                        synthetic := __property.writeSynthetic;
                                        if not __property.hasIndex() then begin
                                            __member := __property.writeMember;
                                            if Lang.isInstance(__member, Field) then begin
                                                __field := Field(Lang.cast(__member, Field));
                                                __type := __field.&type;
                                                if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                                    mnmnc := 'wrsf';
                                                end else begin
                                                    mnmnc := 'wrif';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, NORM).trim();
                                                output.printlnInstruction(toString(mnemonic), __field.fasmFullName);
                                                goto break_labelPop;
                                            end;
                                            if Lang.isInstance(__member, Callable) then begin
                                                __methodc := Callable(Lang.cast(__member, Callable));
                                                if __methodc.serviceIndex >= 0 then begin
                                                    operands[0] := __methodc.parentType.fasmFullName;
                                                    operands[1] := writer.&set(operandA).writeString(__methodc.fasmSimpleName).writeString(__methodc.arguments.toFasmString()).get();
                                                    output.printlnInstruction('invserv', operands, 0, 2);
                                                    goto break_labelPop;
                                                end;
                                                if __methodc.virtualIndex >= 0 then begin
                                                    output.printlnInstruction('invvirt', __methodc.fasmFullName);
                                                    goto break_labelPop;
                                                end;
                                                output.printlnInstruction('invspec', __methodc.fasmFullName);
                                                goto break_labelPop;
                                            end;
                                        end;
                                        output.printlnInstruction('invspec', synthetic.fasmFullName);
                                        goto break_labelPop;
                                    end;
                                    WRITE_PROPERTY: begin
                                        __property := __node.operand1 as &Property;
                                        synthetic := __property.writeSynthetic;
                                        sindex := synthetic.serviceIndex;
                                        vindex := synthetic.virtualIndex;
                                        if not __property.hasIndex() and ((sindex and vindex) < 0) then begin
                                            __member := __property.writeMember;
                                            if Lang.isInstance(__member, Field) then begin
                                                __field := Field(Lang.cast(__member, Field));
                                                __type := __field.&type;
                                                if __field.parentType.isStruct() and __type.isPrimitive() then begin
                                                    mnmnc := 'wrsf';
                                                end else begin
                                                    mnmnc := 'wrif';
                                                end;
                                                writer.&set(mnemonic).writeString(mnmnc).writeSignature(__type, NORM).trim();
                                                output.printlnInstruction(toString(mnemonic), __field.fasmFullName);
                                                goto break_labelPop;
                                            end;
                                            if Lang.isInstance(__member, Callable) then begin
                                                __methodc := Callable(Lang.cast(__member, Callable));
                                                if __methodc.serviceIndex >= 0 then begin
                                                    operands[0] := __methodc.parentType.fasmFullName;
                                                    operands[1] := writer.&set(operandA).writeString(__methodc.fasmSimpleName).writeString(__methodc.arguments.toFasmString()).get();
                                                    output.printlnInstruction('invserv', operands, 0, 2);
                                                    goto break_labelPop;
                                                end;
                                                if __methodc.virtualIndex >= 0 then begin
                                                    output.printlnInstruction('invvirt', __methodc.fasmFullName);
                                                    goto break_labelPop;
                                                end;
                                                output.printlnInstruction('invspec', __methodc.fasmFullName);
                                                goto break_labelPop;
                                            end;
                                        end;
                                        if sindex >= 0 then begin
                                            operands[0] := synthetic.parentType.fasmFullName;
                                            operands[1] := writer.&set(operandA).writeString(synthetic.fasmSimpleName).writeString(synthetic.arguments.toFasmString()).get();
                                            output.printlnInstruction('invserv', operands, 0, 2);
                                            goto break_labelPop;
                                        end;
                                        if vindex >= 0 then begin
                                            output.printlnInstruction('invvirt', synthetic.fasmFullName);
                                            goto break_labelPop;
                                        end;
                                        output.printlnInstruction('invspec', synthetic.fasmFullName);
                                        goto break_labelPop;
                                    end;
                                    EXCEPT_ENTER: begin
                                        output.printlnInstruction('eenter');
                                        goto continue_label1;
                                    end;
                                    EXCEPT_TRY: begin
                                        if anonymus then output.printLabel('');
                                        operands[0] := writer.&set(operandA).writeLabel(__node.reference1 as Node).get();
                                        operands[1] := writer.&set(operandB).writeLabel(__node.reference2 as Node).get();
                                        operands[2] := '@F';
                                        output.printlnInstruction('try', operands, 0, 3);
                                        anonymus := true;
                                        goto continue_label1;
                                    end;
                                    EXCEPT_CATCH: begin
                                        operands[0] := (__node.reference2 as ru.malik.elaborarer.avtoo.lang.ClassType).fasmFullName;
                                        operands[1] := writer.&set(operandA).writeLabel(__node.reference1 as Node).get();
                                        output.printlnInstruction('catch', operands, 0, 2);
                                        goto continue_label1;
                                    end;
                                    EXCEPT_FINALLY: begin
                                        writer.&set(operandA).writeLabel(__node.reference1 as Node).trim();
                                        output.printlnInstruction('finally', toString(operandA));
                                        goto continue_label1;
                                    end;
                                    EXCEPT_LEAVE: begin
                                        if anonymus then output.printLabel('');
                                        output.printlnInstruction('eleave');
                                        goto continue_label1;
                                    end;
                                    end;
                                    break_label2:
                                    if isConditionalJump then begin
                                        order := __node.order + 1;
                                        if jumpIsFalse.order = order then begin
                                            writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                            output.printlnInstruction('jt', toString(operandA));
                                            goto continue_label1;
                                        end;
                                        begin
                                            writer.&set(operandA).writeLabel(jumpIsFalse).trim();
                                            output.printlnInstruction('jf', toString(operandA));
                                        end;
                                        if jumpIsTrue.order <> order then begin
                                            writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                            output.printlnInstruction('jmp', toString(operandA));
                                        end;
                                        goto continue_label1;
                                    end;
                                end;
                                break_labelPush:
                                if kindOfResultType <= TYP_VOID then begin
                                    writer.&set(mnemonic).writeString('tpush').writeSignature(kindOfPushType, STACK).trim();
                                    output.printlnInstruction(toString(mnemonic));
                                end;
                                goto continue_label1;
                            end;
                            break_labelPop:
                            if kindOfResultType > TYP_VOID then begin
                                writer.&set(mnemonic).writeString('tpop').writeSignature(kindOfResultType, STACK).trim();
                                output.printlnInstruction(toString(mnemonic));
                            end;
                        end;
                        break_labelConj:
                        if isConditionalJump then begin
                            order := __node.order + 1;
                            if jumpIsFalse.order = order then begin
                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                output.printlnInstruction('jt', toString(operandA));
                                goto continue_label1;
                            end;
                            begin
                                writer.&set(operandA).writeLabel(jumpIsFalse).trim();
                                output.printlnInstruction('jf', toString(operandA));
                            end;
                            if jumpIsTrue.order <> order then begin
                                writer.&set(operandA).writeLabel(jumpIsTrue).trim();
                                output.printlnInstruction('jmp', toString(operandA));
                            end;
                        end;
                        continue_label1:
                        __node := __next;
                    end;
                finally
                    refsTable.free();
                    refsTable := nil;
                end;
            end;
            break_label0:
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('end if ; </fold>');
        end;

        procedure AssemblerSourceGenerator.generateImplementorCode(__type, __superservice: ClassType; output: AssemblerSourcePrintStream);
        var
            index: int;
            mnemonic: AnsiString;
            operands: AnsiString_Array1d;
            methods: Callable_Array1d;
            __method: Callable;
        begin
            operands := &Array.newAnsiString1d(2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printHeader('; <fold ');
            output.print(__superservice.specialCanonicalName);
            output.println('>');
            output.increaseMargin();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            operands[0] := __type.fasmFullName;
            operands[1] := __superservice.fasmFullName;
            output.printlnInstruction('impl', operands, 0, 2);
            { -------------------------------------------------------------------------------------------------------------------------------- }
            methods := __superservice.serviceCallables();
            for index := 0 to system.length(methods) - 1 do begin
                __method := methods[index].overridesIn(__type, Method.CURRENT_TYPE or Method.SUPERTYPES) as Callable;
                if __method.virtualIndex < 0 then begin
                    mnemonic := 'jmpspec';
                end else begin
                    mnemonic := 'jmpvirt';
                end;
                output.printlnInstruction(mnemonic, __method.fasmFullName);
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
        end;

        procedure AssemblerSourceGenerator.generateConstants(output: AssemblerSourcePrintStream);
        type
            Value_Array1d = specialize DynamicArray<Value>;
        var
            slimit: int;
            vlimit: int;
            slower: int;
            vlower: int;
            sindex: int;
            vindex: int;
            vlength: int;
            dummvalue: long8;
            b2value: byte2 absolute dummvalue;
            b4value: byte4 absolute dummvalue;
            b8value: byte8 absolute dummvalue;
            s2value: short2 absolute dummvalue;
            s4value: short4 absolute dummvalue;
            s8value: short8 absolute dummvalue;
            i2value: int2 absolute dummvalue;
            i4value: int4 absolute dummvalue;
            i8value: int8 absolute dummvalue;
            l2value: long2 absolute dummvalue;
            l4value: long4 absolute dummvalue;
            l8value: long8 absolute dummvalue;
            commstring: AnsiString;
            stvalue: UnicodeString;
            chars: uchar_Array1d;
            operandA: char_Array1d;
            fasmNums: char_Array2d;
            commdata: Value_Array1d;
            operands: AnsiString_Array1d;
            writer: AssemblerElementWriter;
        begin
            writer := getAssemblerElementWriter();
            operandA := &Array.newChar1d($0020);
            fasmNums := &Array.newChar2d($0010, $0020);
            operands := &Array.newAnsiString1d($10);
            commdata := Value_Array1d(&Array.newIUnknown1d(1));
            commstring := AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.constants.type');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.println();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printHeader('; <fold ');
            output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.constants.programme'));
            output.println('>');
            output.increaseMargin();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            begin
                commdata[0] := CoAnsiString.create('real');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'e';
                operands[1] := writer.&set(operandA).writeByte($04).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldRealStorage do for sindex := 0 to getLength() - 1 do begin
                    l2value := VCoReal.toLong2Bits(readComponent(sindex));
                    for vindex := 0 to 4 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeShort(s8value[vindex]).get();
                    end;
                    output.printlnInstruction('dw', operands, 0, 5);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('double');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'd';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldDoubleStorage do for sindex := 0 to getLength() - 1 do begin
                    begin
                        operands[0] := writer.&set(fasmNums[0]).writeLong(CoDouble.toLongBits(readComponent(sindex))).get();
                    end;
                    begin
                        operands[1] := writer.&set(fasmNums[1]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('double2');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'd2';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldDouble2Storage do for sindex := 0 to getLength() - 1 do begin
                    l2value := VCoDouble2.toLong2Bits(readComponent(sindex));
                    for vindex := 0 to 1 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l2value[vindex]).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('double4');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'd4';
                operands[1] := writer.&set(operandA).writeByte($20).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldDouble4Storage do for sindex := 0 to getLength() - 1 do begin
                    l4value := VCoDouble4.toLong4Bits(readComponent(sindex));
                    for vindex := 0 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l4value[vindex]).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 4);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('double8');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'd8';
                operands[1] := writer.&set(operandA).writeByte($40).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldDouble8Storage do for sindex := 0 to getLength() - 1 do begin
                    l8value := VCoDouble8.toLong8Bits(readComponent(sindex));
                    for vindex := 0 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l8value[vindex]).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 8);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('float');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'f';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldFloatStorage do for sindex := 0 to getLength() - 1 do begin
                    begin
                        operands[0] := writer.&set(fasmNums[0]).writeInt(CoFloat.toIntBits(readComponent(sindex))).get();
                    end;
                    for vindex := 1 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('dd', operands, 0, 4);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('float2');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'f2';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldFloat2Storage do for sindex := 0 to getLength() - 1 do begin
                    i2value := VCoFloat2.toInt2Bits(readComponent(sindex));
                    for vindex := 0 to 1 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i2value[vindex]).get();
                    end;
                    for vindex := 2 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('dd', operands, 0, 4);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('float4');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'f4';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldFloat4Storage do for sindex := 0 to getLength() - 1 do begin
                    i4value := VCoFloat4.toInt4Bits(readComponent(sindex));
                    for vindex := 0 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i4value[vindex]).get();
                    end;
                    output.printlnInstruction('dd', operands, 0, 4);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('float8');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'f8';
                operands[1] := writer.&set(operandA).writeByte($20).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldFloat8Storage do for sindex := 0 to getLength() - 1 do begin
                    i8value := VCoFloat8.toInt8Bits(readComponent(sindex));
                    for vindex := 0 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i8value[vindex]).get();
                    end;
                    output.printlnInstruction('dd', operands, 0, 8);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('byte2');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'b2';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldByte2Storage do for sindex := 0 to getLength() - 1 do begin
                    b2value := readComponent(sindex);
                    for vindex := 0 to 1 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeByte(b2value[vindex]).get();
                    end;
                    for vindex := 2 to 15 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('db', operands, 0, 16);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('byte4');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'b4';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldByte4Storage do for sindex := 0 to getLength() - 1 do begin
                    b4value := readComponent(sindex);
                    for vindex := 0 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeByte(b4value[vindex]).get();
                    end;
                    for vindex := 4 to 15 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('db', operands, 0, 16);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('byte8');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'b8';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldByte8Storage do for sindex := 0 to getLength() - 1 do begin
                    b8value := readComponent(sindex);
                    for vindex := 0 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeByte(b8value[vindex]).get();
                    end;
                    for vindex := 8 to 15 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('db', operands, 0, 16);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('short2');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 's2';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldShort2Storage do for sindex := 0 to getLength() - 1 do begin
                    s2value := readComponent(sindex);
                    for vindex := 0 to 1 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeShort(s2value[vindex]).get();
                    end;
                    for vindex := 2 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('dw', operands, 0, 8);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('short4');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 's4';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldShort4Storage do for sindex := 0 to getLength() - 1 do begin
                    s4value := readComponent(sindex);
                    for vindex := 0 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeShort(s4value[vindex]).get();
                    end;
                    for vindex := 4 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('dw', operands, 0, 8);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('short8');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 's8';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldShort8Storage do for sindex := 0 to getLength() - 1 do begin
                    s8value := readComponent(sindex);
                    for vindex := 0 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeShort(s8value[vindex]).get();
                    end;
                    output.printlnInstruction('dw', operands, 0, 8);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('int2');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'i2';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldInt2Storage do for sindex := 0 to getLength() - 1 do begin
                    i2value := readComponent(sindex);
                    for vindex := 0 to 1 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i2value[vindex]).get();
                    end;
                    for vindex := 2 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeDecimal(0).get();
                    end;
                    output.printlnInstruction('dd', operands, 0, 4);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('int4');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'i4';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldInt4Storage do for sindex := 0 to getLength() - 1 do begin
                    i4value := readComponent(sindex);
                    for vindex := 0 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i4value[vindex]).get();
                    end;
                    output.printlnInstruction('dd', operands, 0, 4);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('int8');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'i8';
                operands[1] := writer.&set(operandA).writeByte($20).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldInt8Storage do for sindex := 0 to getLength() - 1 do begin
                    i8value := readComponent(sindex);
                    for vindex := 0 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeInt(i8value[vindex]).get();
                    end;
                    output.printlnInstruction('dd', operands, 0, 8);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('long');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'l';
                operands[1] := writer.&set(operandA).writeByte($08).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldLongStorage do for sindex := 0 to getLength() - 1 do begin
                    begin
                        operands[0] := writer.&set(fasmNums[0]).writeLong(readComponent(sindex)).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 1);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('long2');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'l2';
                operands[1] := writer.&set(operandA).writeByte($10).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldLong2Storage do for sindex := 0 to getLength() - 1 do begin
                    l2value := readComponent(sindex);
                    for vindex := 0 to 1 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l2value[vindex]).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('long4');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'l4';
                operands[1] := writer.&set(operandA).writeByte($20).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldLong4Storage do for sindex := 0 to getLength() - 1 do begin
                    l4value := readComponent(sindex);
                    for vindex := 0 to 3 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l4value[vindex]).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 4);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create('long8');
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 'l8';
                operands[1] := writer.&set(operandA).writeByte($40).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldLong8Storage do for sindex := 0 to getLength() - 1 do begin
                    l8value := readComponent(sindex);
                    for vindex := 0 to 7 do begin
                        operands[vindex] := writer.&set(fasmNums[vindex]).writeLong(l8value[vindex]).get();
                    end;
                    output.printlnInstruction('dq', operands, 0, 8);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                commdata[0] := CoAnsiString.create(PACKNAME_LANG + '.' + TYPENAME_STRING);
                output.printHeader('; <fold ');
                output.print(AnsiString.format(commstring, commdata));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                operands[0] := 's';
                operands[1] := writer.&set(operandA).writeByte($04).get();
                output.printlnInstruction('cons', operands, 0, 2);
                { -------------------------------------------------------------------------------------------------------------------------------- }
                with fldStringStorage do begin
                    slimit := getLength() - 1;
                    for sindex := 0 to slimit do begin
                        slower := sindex and 7;
                        begin
                            operands[slower] := writer.&set(fasmNums[slower]).writeString('-cons$s+').writeLabel(sindex).get();
                        end;
                        inc(slower);
                        if (slower = 8) or (sindex = slimit) then begin
                            output.printlnInstruction('dd', operands, 0, slower);
                        end;
                    end;
                    chars := &Array.newUChar1d($ffff);
                    for sindex := 0 to slimit do begin
                        stvalue := readComponent(sindex);
                        vlength := stvalue.length;
                        if vlength > $ffff then begin
                            raise IndexOutOfBoundsException.create(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.too-long-string'));
                        end;
                        stvalue.getChars(1, vlength + 1, chars, 0);
                        output.printLabel(writer.&set(operandA).writeLabel(sindex).get());
                        vlimit := vlength - 1;
                        for vindex := -1 to vlimit do begin
                            vlower := (vindex + 1) and $0f;
                            if vindex < 0 then begin
                                operands[vlower] := writer.&set(fasmNums[vlower]).writeShort(vlength).get();
                            end else begin
                                operands[vlower] := writer.&set(fasmNums[vlower]).writeShort(int(chars[vindex])).get();
                            end;
                            inc(vlower);
                            if (vlower = $10) or (vindex = vlimit) then begin
                                output.printlnInstruction('dw', operands, 0, vlower);
                            end;
                        end;
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
        end;

        procedure AssemblerSourceGenerator.generateDebugInfoEntries(output: AssemblerSourcePrintStream);
        var
            index: int;
            length: int;
            mindex: int;
            pindex: int;
            tindex: int;
            nlength: int;
            name: AnsiString;
            mnemonic: AnsiString;
            classFullName: AnsiString;
            methodFullName: AnsiString;
            operandA: char_Array1d;
            operandB: char_Array1d;
            operandC: char_Array1d;
            operands: AnsiString_Array1d;
            __code: Code;
            __type: &Type;
            __pack: Package;
            lines: IntArray;
            __member: Member;
            __method: Callable;
            __packages: PackageArray;
            strings: AnsiStringStorage;
            sources: UnicodeStringStorage;
            __clas: ru.malik.elaborarer.avtoo.lang.ClassType;
            writer: AssemblerElementWriter;
        begin
            writer := getAssemblerElementWriter();
            operandA := &Array.newChar1d($0020);
            operandB := &Array.newChar1d($0100);
            operandC := &Array.newChar1d($0020);
            operands := &Array.newAnsiString1d(5);
            sources := fldDebugInfoSources;
            strings := fldDebugInfoStrings;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.println();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printHeader('; <fold ');
            output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.debug.entries'));
            output.println('>');
            output.increaseMargin();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnInstruction('align_d', writer.&set(operandA).writeByte($20).get());
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnLabel('dbgi$ient');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            __packages := packages;
            for pindex := 0 to __packages.getLength() - 1 do begin
                __pack := __packages.readComponent(pindex);
                for tindex := 0 to __pack.getLength() - 1 do begin
                    __type := __pack.readComponent(tindex);
                    if not(__type is ru.malik.elaborarer.avtoo.lang.ClassType) or not __type.isCompilable() then continue;
                    __clas := ru.malik.elaborarer.avtoo.lang.ClassType(__type);
                    classFullName := __clas.fasmFullName;
                    for mindex := 0 to __clas.getLength() - 1 do begin
                        __member := __clas.readComponent(mindex);
                        if not(__member is Callable) or __member.isAbstract() then continue;
                        __method := Callable(__member);
                        mnemonic := 'dientry';
                        name := __method.specialSimpleName;
                        methodFullName := __method.fasmFullName;
                        nlength := name.length;
                        strings.indexAcquire(name);
                        if (nlength > 1) and (name[1] = '<') and (name[nlength] = '>') then begin
                            mnemonic := 'dientry_s';
                            name := name.substring(2, nlength);
                        end;
                        { -------------------------------------------------------------------------------------------------------------------------------- }
                        output.printHeader('if(used ');
                        output.print(methodFullName);
                        output.print(') ; <fold ');
                        output.print(__method.toString());
                        output.println('>');
                        output.increaseMargin();
                        { -------------------------------------------------------------------------------------------------------------------------------- }
                        operands[0] := writer.&set(operandA).writeLabel(sources.indexAcquire(__clas.textSourcePath)).get();
                        operands[1] := classFullName;
                        operands[2] := name;
                        operands[3] := methodFullName;
                        operands[4] := '\';
                        output.printlnInstruction(mnemonic, operands, 0, 5);
                        { -------------------------------------------------------------------------------------------------------------------------------- }
                        __code := __method.code;
                        lines := nil;
                        length := 0;
                        if __code <> nil then begin
                            lines := __code.debugLineIndices;
                            length := lines.getLength();
                        end;
                        if length <= 0 then begin
                            operands[0] := writer.&set(operandA).writeDecimal(0).get();
                            operands[1] := '';
                            operands[2] := '.D.IEND';
                            output.printlnContinuation(operands, 0, 3);
                        end else begin
                            operands[3] := '\';
                            index := 0;
                            repeat
                                operands[0] := writer.&set(operandA).writeDecimal(lines.readComponent(index) + 1).get();
                                operands[1] := writer.&set(operandB).writeLabel('D', index).get();
                                inc(index);
                                if index >= length then begin
                                    operands[2] := '.D.IEND';
                                    output.printlnContinuation(operands, 0, 3);
                                    break;
                                end;
                                operands[2] := writer.&set(operandC).writeLabel('D', index).get();
                                output.printlnContinuation(operands, 0, 4);
                            until false;
                        end;
                        { -------------------------------------------------------------------------------------------------------------------------------- }
                        output.decreaseMargin();
                        output.printlnHeader('end if ; </fold>');
                    end;
                end;
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnLabel('.$iend$');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
        end;

        procedure AssemblerSourceGenerator.generateDebugInfoSources(output: AssemblerSourcePrintStream);
        var
            index: int;
            nlimit: int;
            nlower: int;
            nindex: int;
            nlength: int;
            name: UnicodeString;
            chars: uchar_Array1d;
            operandA: char_Array1d;
            fasmNums: char_Array2d;
            operands: AnsiString_Array1d;
            sources: UnicodeStringStorage;
            writer: AssemblerElementWriter;
        begin
            writer := getAssemblerElementWriter();
            operandA := &Array.newChar1d($0020);
            fasmNums := &Array.newChar2d($0010, $0020);
            operands := &Array.newAnsiString1d($10);
            sources := fldDebugInfoSources;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.println();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printHeader('; <fold ');
            output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.debug.sources'));
            output.println('>');
            output.increaseMargin();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnInstruction('align_d', writer.&set(operandA).writeByte($10).get());
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printLabel('dbgi$isrc');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            chars := &Array.newUChar1d($ffff);
            for index := 0 to sources.getLength() - 1 do begin
                name := sources.readComponent(index);
                nlength := name.length;
                if nlength > $ffff then nlength := $ffff;
                name.getChars(1, nlength + 1, chars, 0);
                output.printLabel(writer.&set(operandA).writeLabel(index).get());
                nlimit := nlength - 1;
                for nindex := -1 to nlimit do begin
                    nlower := (nindex + 1) and $0f;
                    if nindex < 0 then begin
                        operands[nlower] := writer.&set(fasmNums[nlower]).writeShort(nlength).get();
                    end else begin
                        operands[nlower] := writer.&set(fasmNums[nlower]).writeShort(int(chars[nindex])).get();
                    end;
                    inc(nlower);
                    if (nlower = $10) or (nindex = nlimit) then begin
                        output.printlnInstruction('dw', operands, 0, nlower);
                    end;
                end;
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnLabel('.$iend$');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
        end;

        procedure AssemblerSourceGenerator.generateDebugInfoStrings(output: AssemblerSourcePrintStream);
        var
            index: int;
            nlength: int;
            name: AnsiString;
            mnemonic: AnsiString;
            operandA: char_Array1d;
            strings: AnsiStringStorage;
            writer: AssemblerElementWriter;
        begin
            writer := getAssemblerElementWriter();
            operandA := &Array.newChar1d($0100);
            strings := fldDebugInfoStrings;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.println();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printHeader('; <fold ');
            output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.debug.strings'));
            output.println('>');
            output.increaseMargin();
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnInstruction('align_d', writer.&set(operandA).writeByte($10).get());
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printLabel('dbgi$istr');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            for index := 0 to strings.getLength() - 1 do begin
                name := strings.readComponent(index);
                nlength := name.length;
                if (nlength > 1) and (name[1] = '<') and (name[nlength] = '>') then begin
                    mnemonic := 'distring_s';
                    name := name.substring(2, nlength);
                end else begin
                    mnemonic := 'distring';
                end;
                output.printlnInstruction(mnemonic, name);
            end;
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.printlnLabel('.$iend$');
            { -------------------------------------------------------------------------------------------------------------------------------- }
            output.decreaseMargin();
            output.printlnHeader('; </fold>');
        end;

        procedure AssemblerSourceGenerator.generateProgramme(output: AssemblerSourcePrintStream);
        var
            index: int;
            pindex: int;
            tindex: int;
            plength: int;
            codeLength: int;
            pathLength: int;
            name: UnicodeString;
            path: UnicodeString;
            operandA: char_Array1d;
            operandB: char_Array1d;
            operands: AnsiString_Array1d;
            __type: &Type;
            __pack: Package;
            __packages: PackageArray;
            resourcesTable: HashtableOfUnicodeStringToResourceLocation;
            writer: AssemblerElementWriter;
        begin
            writer := getAssemblerElementWriter();
            operandA := &Array.newChar1d($ffff);
            operandB := &Array.newChar1d($ffff);
            operands := &Array.newAnsiString1d(2);
            __packages := packages;
            resourcesTable := fldResourcesTable;
            plength := __packages.getLength();
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.header'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!format/!header.inc"');
                output.printlnInstruction('include', '"!macro/!main.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.code'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!format/chapter/code.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printLabel('code$begin');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!proc/!main.inc"');
                output.printlnInstruction('include', '"!inst/!main.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                codeLength := writer.&set(operandA).writeString('"code/').offset;
                for pindex := 0 to plength - 1 do begin
                    __pack := __packages.readComponent(pindex);
                    pathLength := writer.&set(operandA, codeLength).writeString(__pack.fasmFullName).writeChar('/').offset;
                    for tindex := 0 to __pack.getLength() - 1 do begin
                        __type := __pack.readComponent(tindex);
                        if
                            (__type is ru.malik.elaborarer.avtoo.lang.ClassType) and
                            (not(__type is ArrayType) or not ru.malik.elaborarer.avtoo.lang.ClassType(__type).getSuperclassType().isArray())
                        then begin
                            output.printlnInstruction('include', writer.&set(operandA, pathLength).writeString(__type.fasmFileName.toUTF8()).writeString('.inc"').get());
                        end;
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnLabel('code$end');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.data'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!format/chapter/data.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printLabel('data$begin');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                codeLength := writer.&set(operandA).writeString('"data/').offset;
                for pindex := 0 to plength - 1 do begin
                    __pack := __packages.readComponent(pindex);
                    pathLength := writer.&set(operandA, codeLength).writeString(__pack.fasmFullName).writeChar('/').offset;
                    output.printlnInstruction('include', writer.&set(operandA, pathLength).writeString('!package.inc"').get());
                    for tindex := 0 to __pack.getLength() - 1 do begin
                        __type := __pack.readComponent(tindex);
                        if __type.isCompilable() then begin
                            output.printlnInstruction('include', writer.&set(operandA, pathLength).writeString(__type.fasmFileName.toUTF8()).writeString('.inc"').get());
                        end;
                    end;
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnLabel('data$end');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.constants'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!format/chapter/const.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printLabel('cons$begin');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"const/proc.inc"');
                output.printlnInstruction('include', '"const/inst.inc"');
                output.printlnInstruction('include', '"const/prog.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnLabel('cons$end');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.resources'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!format/chapter/rsrc.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printLabel('rsrc$begin');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                for index := 0 to resourcesTable.length - 1 do begin
                    name := resourcesTable.keyAt(index);
                    path := resourcesTable[name].destinationPath;
                    operands[0] := writer.&set(operandA).writeChar('"').writeString(path.toUTF8()).writeChar('"').get();
                    operands[1] := writer.&set(operandB).writeChar('"').writeString(name.toUTF8()).writeChar('"').get();
                    output.printlnInstruction('avtrsrc', operands, 0, 2);
                end;
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnLabel('rsrc$end');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.debug'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!format/chapter/dbgi.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printLabel('dbgi$begin');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('dbinfob', '"AVTC 0.5 [2022-08-04]"');
                output.printlnInstruction('include', '"dbgi/strings.inc"');
                output.printlnInstruction('include', '"dbgi/sources.inc"');
                output.printlnInstruction('include', '"dbgi/entries.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnLabel('dbgi$end');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
            begin
                output.println();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printHeader('; <fold ');
                output.print(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'comment.footer'));
                output.println('>');
                output.increaseMargin();
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.printlnInstruction('include', '"!format/!footer.inc"');
                { -------------------------------------------------------------------------------------------------------------------------------- }
                output.decreaseMargin();
                output.printlnHeader('; </fold>');
            end;
        end;

        function AssemblerSourceGenerator.newAssemblerElementWriter(): AssemblerElementWriter;
        begin
            result := nil;
        end;

        function AssemblerSourceGenerator.newAssemblerSourcePrintStream(): AssemblerSourcePrintStream;
        begin
            result := nil;
        end;

        function AssemblerSourceGenerator.getOverwritten(): UnicodeString;
        begin
            result := fldOverwritten;
        end;

        function AssemblerSourceGenerator.getAssemblerElementWriter(): AssemblerElementWriter;
        begin
            result := fldGlobalWriter;
        end;

        constructor AssemblerSourceGenerator.create(__reflect: boolean; const __destinationName: UnicodeString);
        begin
            inherited create(false);
            fldReflect := __reflect;
            fldDestinationName := __destinationName;
            fldSourcesTable := HashtableOfUnicodeStringToLibrary.create();
            fldRealStorage := RealStorage.create();
            fldDoubleStorage := DoubleStorage.create();
            fldDouble2Storage := Double2Storage.create();
            fldDouble4Storage := Double4Storage.create();
            fldDouble8Storage := Double8Storage.create();
            fldFloatStorage := FloatStorage.create();
            fldFloat2Storage := Float2Storage.create();
            fldFloat4Storage := Float4Storage.create();
            fldFloat8Storage := Float8Storage.create();
            fldByte2Storage := Byte2Storage.create();
            fldByte4Storage := Byte4Storage.create();
            fldByte8Storage := Byte8Storage.create();
            fldShort2Storage := Short2Storage.create();
            fldShort4Storage := Short4Storage.create();
            fldShort8Storage := Short8Storage.create();
            fldInt2Storage := Int2Storage.create();
            fldInt4Storage := Int4Storage.create();
            fldInt8Storage := Int8Storage.create();
            fldLongStorage := LongStorage.create();
            fldLong2Storage := Long2Storage.create();
            fldLong4Storage := Long4Storage.create();
            fldLong8Storage := Long8Storage.create();
            fldStringStorage := UnicodeStringStorage.create();
            fldDebugInfoSources := UnicodeStringStorage.create();
            fldDebugInfoStrings := AnsiStringStorage.create();
            fldResourcesTable := HashtableOfUnicodeStringToResourceLocation.create();
        end;

        destructor AssemblerSourceGenerator.destroy;
        begin
            fldSourcesTable.free();
            fldRealStorage.free();
            fldDoubleStorage.free();
            fldDouble2Storage.free();
            fldDouble4Storage.free();
            fldDouble8Storage.free();
            fldFloatStorage.free();
            fldFloat2Storage.free();
            fldFloat4Storage.free();
            fldFloat8Storage.free();
            fldByte2Storage.free();
            fldByte4Storage.free();
            fldByte8Storage.free();
            fldShort2Storage.free();
            fldShort4Storage.free();
            fldShort8Storage.free();
            fldInt2Storage.free();
            fldInt4Storage.free();
            fldInt8Storage.free();
            fldLongStorage.free();
            fldLong2Storage.free();
            fldLong4Storage.free();
            fldLong8Storage.free();
            fldStringStorage.free();
            fldDebugInfoSources.free();
            fldDebugInfoStrings.free();
            freeResourcesTable(fldResourcesTable);
            inherited destroy;
        end;

        procedure AssemblerSourceGenerator.afterConstruction();
        var
            writer: AssemblerElementWriter;
        begin
            inherited afterConstruction();
            writer := newAssemblerElementWriter();
            if writer = nil then writer := AssemblerElementWriter.create();
            fldGlobalWriter := writer;
        end;

        procedure AssemblerSourceGenerator.beforeDestruction();
        begin
            fldGlobalWriter.free();
            inherited beforeDestruction();
        end;

        procedure AssemblerSourceGenerator.compile();
        var
            index: int;
            boundA: int;
            boundB: int;
            aindex: int;
            lindex: int;
            mindex: int;
            pindex: int;
            tindex: int;
            blength: int;
            plength: int;
            name: UnicodeString;
            codePath: UnicodeString;
            dataPath: UnicodeString;
            __destinationName: UnicodeString;
            __destinationPath: UnicodeString;
            writerRelativePath: UnicodeString;
            readerRelativePath: UnicodeString;
            path: uchar_Array1d;
            buffer: byte_Array1d;
            __type: &Type;
            __pack: Package;
            __next: Package;
            __member: Member;
            reader: ByteReader;
            writer: ByteWriter;
            __method: Callable;
            __project: ru.malik.elaborarer.avtoo.lang.&Library;
            __library: ru.malik.elaborarer.avtoo.lang.&Library;
            __fileSystem: FileSystem;
            __packages: PackageArray;
            __classes: ClassTypeArray;
            __libraries: LibraryArray;
            location: ResourceLocation;
            output: AssemblerSourcePrintStream;
            sourcesTable: HashtableOfUnicodeStringToLibrary;
            __clas: ru.malik.elaborarer.avtoo.lang.ClassType;
            resourcesTable: HashtableOfUnicodeStringToResourceLocation;
        begin
            { -- предыдущие стадии -- }
            inherited compile();
            { 8. Стадия выгрузки данных }
            __libraries := libraries;
            for lindex := 0 to __libraries.getLength() - 1 do begin
                __library := __libraries.readComponent(lindex);
                findSourcesIn(__library);
                findResourcesIn(__library);
            end;
            if fldReflect then begin
                __classes := classes;
                for tindex := __classes.getLength() - 1 downto 0 do begin
                    __clas := __classes.readComponent(tindex);
                    if __clas.isCompilable() then for mindex := __clas.getLength() - 1 downto 0 do begin
                        __member := __clas.readComponent(mindex);
                        if not __member.isStatic() then begin
                            if __member is Field then begin
                                Field(__member).&type.makeCompilable();
                                continue;
                            end;
                            if __member is Callable then begin
                                __method := Callable(__member);
                                __method.&type.makeCompilable();
                                with __method.arguments do for aindex := getLength() - 1 downto 0 do readComponent(aindex).&type.makeCompilable();
                            end;
                        end;
                    end;
                end;
            end;
            buffer := &Array.newByte1d(COPY_BUFFER_LENGTH);
            __destinationName := fldDestinationName;
            if __destinationName = '' then begin
                __destinationName := PROGRAMME_DESTINATION_PATH;
            end else begin
                __destinationName := (PROGRAMME_DESTINATION_PATH + '.') + __destinationName;
            end;
            __project := project;
            __fileSystem := __project.fileSystem;
            __destinationPath := prepareDestinationPath(__fileSystem, __project.directoryPath + __destinationName);
            fldOverwritten := __destinationPath;
            sourcesTable := fldSourcesTable;
            for index := 0 to sourcesTable.length - 1 do begin
                writerRelativePath := sourcesTable.keyAt(index);
                readerRelativePath := (ASSEMBLER_SOURCE_PATH + '/') + writerRelativePath;
                __library := sourcesTable[writerRelativePath];
                createImmediateDirectories(__fileSystem, __destinationPath, writerRelativePath);
                reader := __library.fileSystem.openFileForRead(__library.directoryPath + readerRelativePath);
                try
                    writer := __fileSystem.createFile(__destinationPath + writerRelativePath);
                    try
                        repeat
                            blength := reader.read(buffer);
                            if blength > 0 then writer.write(buffer, 0, blength);
                        until blength < COPY_BUFFER_LENGTH;
                        writer.flush();
                    finally
                        writer.close();
                    end;
                finally
                    reader.close();
                end;
            end;
            resourcesTable := fldResourcesTable;
            for index := 0 to resourcesTable.length - 1 do begin
                location := resourcesTable[resourcesTable.keyAt(index)];
                readerRelativePath := location.relativePath;
                __library := location.&library;
                path := ('rsrc' + readerRelativePath.substring(readerRelativePath.indexOf('/'))).toUCharArray();
                boundA := &Array.indexOf('/', path, 0, 0);
                boundB := &Array.lastIndexOf('/', path, CoInt.MAX_VALUE, 0);
                pindex := boundA;
                repeat
                    pindex := &Array.indexOf('/', path, pindex + 1, 0);
                    if (pindex <= boundA) or (pindex >= boundB) then break;
                    path[pindex] := '.';
                until false;
                writerRelativePath := UnicodeString.create(path);
                location.destinationPath := writerRelativePath;
                createImmediateDirectories(__fileSystem, __destinationPath, writerRelativePath);
                reader := __library.fileSystem.openFileForRead(__library.directoryPath + readerRelativePath);
                try
                    writer := __fileSystem.createFile(__destinationPath + writerRelativePath);
                    try
                        repeat
                            blength := reader.read(buffer);
                            if blength > 0 then writer.write(buffer, 0, blength);
                        until blength < COPY_BUFFER_LENGTH;
                        writer.flush();
                    finally
                        writer.close();
                    end;
                finally
                    reader.close();
                end;
            end;
            __fileSystem.createDirectory(__destinationPath + 'code');
            __fileSystem.createDirectory(__destinationPath + 'data');
            output := newAssemblerSourcePrintStream();
            if output = nil then begin
                output := AssemblerSourcePrintStream.create();
            end;
            try
                with output as DataEncoder do begin
                    __packages := packages;
                    plength := __packages.getLength();
                    __pack := nil;
                    if plength > 0 then begin
                        __pack := __packages.readComponent(0);
                    end;
                    pindex := 0;
                    while pindex < plength do begin
                        inc(pindex);
                        if pindex >= plength then begin
                            __next := nil;
                        end else begin
                            __next := __packages.readComponent(pindex);
                        end;
                        name := __pack.fasmFileName;
                        codePath := __destinationPath + 'code/' + name + '/';
                        dataPath := __destinationPath + 'data/' + name + '/';
                        __fileSystem.createDirectory(codePath.substring(1, codePath.length));
                        __fileSystem.createDirectory(dataPath.substring(1, dataPath.length));
                        begin
                            generatePackageData(__pack, __next, output);
                            writer := __fileSystem.createFile(dataPath + '!package.inc');
                            try
                                saveToOutputStream(writer);
                                writer.flush();
                            finally
                                writer.close();
                            end;
                            clear();
                        end;
                        for tindex := 0 to __pack.getLength() - 1 do begin
                            __type := __pack.readComponent(tindex);
                            if __type is PrimitiveType then begin
                                generatePrimitiveData(PrimitiveType(__type), output);
                                writer := __fileSystem.createFile(dataPath + __type.fasmFileName + '.inc');
                                try
                                    saveToOutputStream(writer);
                                    writer.flush();
                                finally
                                    writer.close();
                                end;
                                clear();
                                continue;
                            end;
                            if (__type is ru.malik.elaborarer.avtoo.lang.ClassType) and __type.isCompilable() then begin
                                __clas := ru.malik.elaborarer.avtoo.lang.ClassType(__type);
                                begin
                                    generateClassData(__clas, output);
                                    writer := __fileSystem.createFile(dataPath + __type.fasmFileName + '.inc');
                                    try
                                        saveToOutputStream(writer);
                                        writer.flush();
                                    finally
                                        writer.close();
                                    end;
                                    clear();
                                end;
                                if not(__clas is ArrayType) or not __clas.getSuperclassType().isArray() then begin
                                    generateClassCode(__clas, output);
                                    writer := __fileSystem.createFile(codePath + __type.fasmFileName + '.inc');
                                    try
                                        if __clas.hasNativeCallables() then begin
                                            __library := __pack.parentLibrary;
                                            reader := __library.fileSystem.openFileForRead(
                                                __library.directoryPath + (ASSEMBLER_SOURCE_PATH + '/code/') + __pack.fasmFileName + '/' + __clas.fasmFileName + '.inc'
                                            );
                                            try
                                                repeat
                                                    blength := reader.read(buffer);
                                                    if blength > 0 then writer.write(buffer, 0, blength);
                                                until blength < COPY_BUFFER_LENGTH;
                                            finally
                                                reader.close();
                                            end;
                                        end;
                                        saveToOutputStream(writer);
                                        writer.flush();
                                    finally
                                        writer.close();
                                    end;
                                    clear();
                                end;
                            end;
                        end;
                        __pack := __next;
                    end;
                    createImmediateDirectories(__fileSystem, __destinationPath, 'const/');
                    begin
                        generateConstants(output);
                        writer := __fileSystem.createFile(__destinationPath + 'const/prog.inc');
                        try
                            saveToOutputStream(writer);
                            writer.flush();
                        finally
                            writer.close();
                        end;
                        clear();
                    end;
                    createImmediateDirectories(__fileSystem, __destinationPath, 'dbgi/');
                    begin
                        generateDebugInfoEntries(output);
                        writer := __fileSystem.createFile(__destinationPath + 'dbgi/entries.inc');
                        try
                            saveToOutputStream(writer);
                            writer.flush();
                        finally
                            writer.close();
                        end;
                        clear();
                    end;
                    begin
                        generateDebugInfoSources(output);
                        writer := __fileSystem.createFile(__destinationPath + 'dbgi/sources.inc');
                        try
                            saveToOutputStream(writer);
                            writer.flush();
                        finally
                            writer.close();
                        end;
                        clear();
                    end;
                    begin
                        generateDebugInfoStrings(output);
                        writer := __fileSystem.createFile(__destinationPath + 'dbgi/strings.inc');
                        try
                            saveToOutputStream(writer);
                            writer.flush();
                        finally
                            writer.close();
                        end;
                        clear();
                    end;
                    begin
                        generateProgramme(output);
                        writer := __fileSystem.createFile(__destinationPath + 'programme.asm');
                        try
                            saveToOutputStream(writer);
                            writer.flush();
                        finally
                            writer.close();
                        end;
                        clear();
                    end;
                end;
            finally
                output.free();
            end;
        end;

        procedure AssemblerSourceGenerator.clear();
        begin
            fldSourcesTable.clear();
            fldRealStorage.clear();
            fldDoubleStorage.clear();
            fldDouble2Storage.clear();
            fldDouble4Storage.clear();
            fldDouble8Storage.clear();
            fldFloatStorage.clear();
            fldFloat2Storage.clear();
            fldFloat4Storage.clear();
            fldFloat8Storage.clear();
            fldByte2Storage.clear();
            fldByte4Storage.clear();
            fldByte8Storage.clear();
            fldShort2Storage.clear();
            fldShort4Storage.clear();
            fldShort8Storage.clear();
            fldInt2Storage.clear();
            fldInt4Storage.clear();
            fldInt8Storage.clear();
            fldLongStorage.clear();
            fldLong2Storage.clear();
            fldLong4Storage.clear();
            fldLong8Storage.clear();
            fldStringStorage.clear();
            fldDebugInfoSources.clear();
            fldDebugInfoStrings.clear();
            clearResourcesTable(fldResourcesTable);
            inherited clear();
        end;
    {%endregion}

    {%region  BinarySourceGeneratorConstants }
        class function BinarySourceGeneratorConstants.serializeVersion(): ByteArrayOutputStream;
        var
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_VERS);
                    writeInt(VERSION_AVTR);
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        class function BinarySourceGeneratorConstants.serializeTextSource(source: TextSource; charset: Charset): ByteArrayOutputStream;
        var
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_SURC);
                    write(charset.encode(source.textSourcePath.toUCharArray()));
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        class function BinarySourceGeneratorConstants.serializeEnd(): ByteArrayOutputStream;
        var
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_IEND);
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        procedure BinarySourceGeneratorConstants.removeAllElements();
        var
            index: int;
            element: TObject;
            &array: TObject_Array1d;
        begin
            &array := fldArray;
            for index := 0 to fldLength - 1 do begin
                element := &array[index];
                if element is RefCountObject then begin
                    &array[index] := nil;
                    element.free();
                end;
            end;
            fldLength := 0;
        end;

        function BinarySourceGeneratorConstants.getOperandIndex(operandC: Constant; operandI: TableItem; thisArgument: Local): int;
        begin
            if operandC <> nil then begin
                result := indexAcquire(operandC);
                exit;
            end;
            if operandI = thisArgument then begin
                result := 0;
                exit;
            end;
            if operandI is Local then begin
                result := indexOf(operandI.specialSimpleName);
                exit;
            end;
            result := indexAcquire(operandI);
        end;

        function BinarySourceGeneratorConstants.indexOf(const item: AnsiString): int;
        var
            asObject: TObject;
        begin
            asObject := CoUnicodeString.create(item.toUTF16());
            try
                result := indexOf(asObject);
            finally
                asObject.free();
            end;
        end;

        function BinarySourceGeneratorConstants.indexAcquire(const item: AnsiString): int;
        var
            isIgnored: boolean;
            index: int;
            asObject: TObject;
        begin
            isIgnored := true;
            asObject := CoUnicodeString.create(item.toUTF16());
            try
                index := indexOf(asObject);
                if index < 0 then begin
                    index := fldLength;
                    append(asObject);
                    isIgnored := false;
                end;
            finally
                if isIgnored then asObject.free();
            end;
            result := index;
        end;

        function BinarySourceGeneratorConstants.indexAcquire(const item: UnicodeString): int;
        var
            isIgnored: boolean;
            index: int;
            asObject: TObject;
        begin
            isIgnored := true;
            asObject := CoUnicodeString.create(item);
            try
                index := indexOf(asObject);
                if index < 0 then begin
                    index := fldLength;
                    append(asObject);
                    isIgnored := false;
                end;
            finally
                if isIgnored then asObject.free();
            end;
            result := index;
        end;

        function BinarySourceGeneratorConstants.indexAcquire(const item: TableItem): int;
        label
            break_label0;
        var
            index: int;
        begin
            index := indexOf(item);
            if index < 0 then begin
                begin
                    if item is RequiredReflectItem then with RequiredReflectItem(item) do begin
                        indexAcquire(recompilableName);
                        goto break_label0;
                    end;
                    if item is Fieldoid then with item as Member do begin
                        indexAcquire(parentType);
                        indexAcquire(recompilableName);
                        goto break_label0;
                    end;
                    if item is Callable then with Callable(item), arguments do begin
                        indexAcquire(parentType);
                        indexAcquire(recompilableName);
                        for index := 0 to getLength() - 1 do indexAcquire(readComponent(index).&type);
                    end;
                end;
                break_label0:
                index := fldLength;
                append(item);
            end;
            result := index;
        end;

        function BinarySourceGeneratorConstants.indexAcquire(const item: TypedMember): int;
        begin
            result := indexAcquire(TableItem(Lang.cast(item, TableItem)));
        end;

        function BinarySourceGeneratorConstants.indexAcquire(const item: Constant): int;
        var
            isIgnored: boolean;
            index: int;
            asObject: TObject;
        begin
            if item.isString() then begin
                result := indexAcquire((item.asInterface() as Value).asUnicodeString());
                exit;
            end;
            if item.isReference() then begin
                result := indexAcquire(item.asObject() as RequiredReflectItem);
                exit;
            end;
            isIgnored := true;
            if item.isBoolean() then begin
                asObject := CoBoolean.create(item.asBoolean());
            end else
            with AVTOOConstants do case item.&type.kind of
            TYP_BYTE:
                asObject := VCoByte.create(item.asLong());
            TYP_BYTE2:
                asObject := VCoByte2.create(item.asLong2());
            TYP_BYTE4:
                asObject := VCoByte4.create(item.asLong4());
            TYP_BYTE8:
                asObject := VCoByte8.create(item.asLong8());
            TYP_SHORT:
                asObject := VCoShort.create(item.asLong());
            TYP_SHORT2:
                asObject := VCoShort2.create(item.asLong2());
            TYP_SHORT4:
                asObject := VCoShort4.create(item.asLong4());
            TYP_SHORT8:
                asObject := VCoShort8.create(item.asLong8());
            TYP_INT:
                asObject := VCoInt.create(item.asLong());
            TYP_INT2:
                asObject := VCoInt2.create(item.asLong2());
            TYP_INT4:
                asObject := VCoInt4.create(item.asLong4());
            TYP_INT8:
                asObject := VCoInt8.create(item.asLong8());
            TYP_LONG:
                asObject := VCoLong.create(item.asLong());
            TYP_LONG2:
                asObject := VCoLong2.create(item.asLong2());
            TYP_LONG4:
                asObject := VCoLong4.create(item.asLong4());
            TYP_LONG8:
                asObject := VCoLong8.create(item.asLong8());
            TYP_FLOAT:
                asObject := VCoFloat.create(item.asDouble());
            TYP_FLOAT2:
                asObject := VCoFloat2.create(item.asDouble2());
            TYP_FLOAT4:
                asObject := VCoFloat4.create(item.asDouble4());
            TYP_FLOAT8:
                asObject := VCoFloat8.create(item.asDouble8());
            TYP_DOUBLE:
                asObject := VCoDouble.create(item.asDouble());
            TYP_DOUBLE2:
                asObject := VCoDouble2.create(item.asDouble2());
            TYP_DOUBLE4:
                asObject := VCoDouble4.create(item.asDouble4());
            TYP_DOUBLE8:
                asObject := VCoDouble8.create(item.asDouble8());
            TYP_REAL:
                asObject := VCoReal.create(item.asReal());
            else
                asObject := CoUChar.create(item.asUChar());
            end;
            try
                index := indexOf(asObject);
                if index < 0 then begin
                    index := fldLength;
                    append(asObject);
                    isIgnored := false;
                end;
            finally
                if isIgnored then asObject.free();
            end;
            result := index;
        end;

        constructor BinarySourceGeneratorConstants.create();
        begin
            inherited create(false);
        end;

        destructor BinarySourceGeneratorConstants.destroy;
        begin
            removeAllElements();
            inherited destroy;
        end;

        procedure BinarySourceGeneratorConstants.afterConstruction();
        begin
            inherited afterConstruction();
            append(nil);
        end;

        procedure BinarySourceGeneratorConstants.clear();
        begin
            removeAllElements();
            append(nil);
        end;

        function BinarySourceGeneratorConstants.serializeConstants(charset: Charset): ByteArrayOutputStream;
        var
            aindex: int;
            eindex: int;
            alength: int;
            dataString: UnicodeString;
            elements: TObject_Array1d;
            etype: TClass;
            element: TObject;
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_CONS);
                    elements := fldArray;
                    for eindex := 1 to fldLength - 1 do begin
                        element := elements[eindex];
                        if element = nil then begin
                            raise UnencodableDataException.create(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.null-pointer'));
                        end;
                        etype := element.classType();
                        if etype = CoBoolean then begin
                            writeShort(CONST_Z);
                            if CoBoolean(element).asBoolean() then begin
                                writeShort(-1);
                                continue;
                            end;
                            writeShort(0);
                            continue;
                        end;
                        if etype = CoUChar then begin
                            writeShort(CONST_C);
                            writeShort(short(CoUChar(element).asInt()));
                            continue;
                        end;
                        if etype = VCoByte then begin
                            writeShort(CONST_B);
                            writeShort(VCoByte(element).asByte());
                            continue;
                        end;
                        if etype = VCoByte2 then begin
                            writeShort(CONST_B2);
                            writeByte2(VCoByte2(element).asByte2());
                            continue;
                        end;
                        if etype = VCoByte4 then begin
                            writeShort(CONST_B4);
                            writeByte4(VCoByte4(element).asByte4());
                            continue;
                        end;
                        if etype = VCoByte8 then begin
                            writeShort(CONST_B8);
                            writeByte8(VCoByte8(element).asByte8());
                            continue;
                        end;
                        if etype = VCoShort then begin
                            writeShort(CONST_S);
                            writeShort(VCoShort(element).asShort());
                            continue;
                        end;
                        if etype = VCoShort2 then begin
                            writeShort(CONST_S2);
                            writeShort2(VCoShort2(element).asShort2());
                            continue;
                        end;
                        if etype = VCoShort4 then begin
                            writeShort(CONST_S4);
                            writeShort4(VCoShort4(element).asShort4());
                            continue;
                        end;
                        if etype = VCoShort8 then begin
                            writeShort(CONST_S8);
                            writeShort8(VCoShort8(element).asShort8());
                            continue;
                        end;
                        if etype = VCoInt then begin
                            writeShort(CONST_I);
                            writeInt(VCoInt(element).asInt());
                            continue;
                        end;
                        if etype = VCoInt2 then begin
                            writeShort(CONST_I2);
                            writeInt2(VCoInt2(element).asInt2());
                            continue;
                        end;
                        if etype = VCoInt4 then begin
                            writeShort(CONST_I4);
                            writeInt4(VCoInt4(element).asInt4());
                            continue;
                        end;
                        if etype = VCoInt8 then begin
                            writeShort(CONST_I8);
                            writeInt8(VCoInt8(element).asInt8());
                            continue;
                        end;
                        if etype = VCoLong then begin
                            writeShort(CONST_J);
                            writeLong(VCoLong(element).asLong());
                            continue;
                        end;
                        if etype = VCoLong2 then begin
                            writeShort(CONST_J2);
                            writeLong2(VCoLong2(element).asLong2());
                            continue;
                        end;
                        if etype = VCoLong4 then begin
                            writeShort(CONST_J4);
                            writeLong4(VCoLong4(element).asLong4());
                            continue;
                        end;
                        if etype = VCoLong8 then begin
                            writeShort(CONST_J8);
                            writeLong8(VCoLong8(element).asLong8());
                            continue;
                        end;
                        if etype = VCoFloat then begin
                            writeShort(CONST_F);
                            writeFloat(VCoFloat(element).asFloat());
                            continue;
                        end;
                        if etype = VCoFloat2 then begin
                            writeShort(CONST_F2);
                            writeFloat2(VCoFloat2(element).asFloat2());
                            continue;
                        end;
                        if etype = VCoFloat4 then begin
                            writeShort(CONST_F4);
                            writeFloat4(VCoFloat4(element).asFloat4());
                            continue;
                        end;
                        if etype = VCoFloat8 then begin
                            writeShort(CONST_F8);
                            writeFloat8(VCoFloat8(element).asFloat8());
                            continue;
                        end;
                        if etype = VCoDouble then begin
                            writeShort(CONST_D);
                            writeDouble(VCoDouble(element).asDouble());
                            continue;
                        end;
                        if etype = VCoDouble2 then begin
                            writeShort(CONST_D2);
                            writeDouble2(VCoDouble2(element).asDouble2());
                            continue;
                        end;
                        if etype = VCoDouble4 then begin
                            writeShort(CONST_D4);
                            writeDouble4(VCoDouble4(element).asDouble4());
                            continue;
                        end;
                        if etype = VCoDouble8 then begin
                            writeShort(CONST_D8);
                            writeDouble8(VCoDouble8(element).asDouble8());
                            continue;
                        end;
                        if etype = VCoReal then begin
                            writeShort(CONST_R);
                            writeReal(VCoReal(element).asReal());
                            continue;
                        end;
                        if etype = CoUnicodeString then begin
                            dataString := CoUnicodeString(element).asUnicodeString();
                            writeShort(CONST_ST);
                            writeShort(dataString.length);
                            write(charset.encode(dataString.toUCharArray()));
                            continue;
                        end;
                        if etype.inheritsFrom(Package) then with TableItem(element) do begin
                            writeShort(CONST_PK);
                            writeInt(indexOf(recompilableName));
                            continue;
                        end;
                        if etype.inheritsFrom(&Type) then with TableItem(element) do begin
                            writeShort(CONST_TP);
                            writeInt(indexOf(recompilableName));
                            continue;
                        end;
                        if etype.inheritsFrom(Field) then with Member(element) do begin
                            writeShort(CONST_FL);
                            writeInt(indexOf(parentType));
                            writeInt(indexOf(recompilableName));
                            continue;
                        end;
                        if etype.inheritsFrom(&Property) then with Member(element) do begin
                            writeShort(CONST_PR);
                            writeInt(indexOf(parentType));
                            writeInt(indexOf(recompilableName));
                            continue;
                        end;
                        if etype.inheritsFrom(Callable) then with Callable(element), arguments do begin
                            writeShort(CONST_CL);
                            writeInt(indexOf(parentType));
                            writeInt(indexOf(recompilableName));
                            alength := getLength();
                            writeShort(alength);
                            for aindex := 0 to alength - 1 do writeInt(indexOf(readComponent(aindex).&type));
                            continue;
                        end;
                        raise UnencodableDataException.create(AnsiString.format(AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.constant-type'), [
                            CoAnsiString.create(etype.className())
                        ]))
                    end;
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializePackage(__pack: Package): ByteArrayOutputStream;
        var
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_PACK);
                    writeShort(__pack.attributes);
                    writeInt(indexAcquire(__pack.specialCanonicalName));
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializeClassType(__type: ClassType): ByteArrayOutputStream;
        var
            index: int;
            supertype: ClassType;
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_TYPE);
                    writeShort(__type.attributes);
                    writeInt(indexAcquire(__type.parentPackage));
                    writeInt(indexAcquire(__type.specialSimpleName));
                    if __type.isHelper() then begin
                        writeInt(indexAcquire(__type.getHelperForType().specialCanonicalName));
                    end else begin
                        supertype := __type.getSuperclassType();
                        if supertype = nil then begin
                            writeInt(0);
                        end else begin
                            writeInt(indexAcquire(supertype.specialCanonicalName));
                        end;
                        for index := 0 to __type.getSuperservicesLength() - 1 do begin
                            writeInt(indexAcquire(__type.getSuperserviceTypeAt(index).specialCanonicalName));
                        end;
                    end;
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializeClassField(__field: Field): ByteArrayOutputStream;
        var
            value: Constant;
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_CFLD);
                    writeShort(__field.attributes);
                    writeInt(indexAcquire(__field.&type));
                    writeInt(indexAcquire(__field.specialSimpleName));
                    value := __field.value;
                    if value <> nil then writeInt(indexAcquire(value));
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializeStructField(__field: Field): ByteArrayOutputStream;
        var
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_SFLD);
                    writeShort(__field.attributes);
                    writeInt(indexAcquire(__field.&type));
                    writeInt(indexAcquire(__field.specialSimpleName));
                    writeInt(__field.capacity);
                    writeInt(__field.structOffset);
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializeProperty(__property: &Property): ByteArrayOutputStream;
        var
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_PROP);
                    writeShort(__property.attributes);
                    writeInt(indexAcquire(__property.&type));
                    writeInt(indexAcquire(__property.specialSimpleName));
                    writeInt(indexAcquire(__property.indexMember));
                    writeInt(indexAcquire(__property.storedMember));
                    writeInt(indexAcquire(__property.readMember));
                    writeInt(indexAcquire(__property.writeMember));
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializeCallable(__callable: Callable): ByteArrayOutputStream;
        var
            index: int;
            length: int;
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_OPER);
                    writeShort(__callable.attributes);
                    writeInt(indexAcquire(__callable.&type));
                    writeInt(indexAcquire(__callable.specialSimpleName));
                    with __callable.arguments do begin
                        length := getLength();
                        writeShort(length);
                        for index := 0 to length - 1 do with readComponent(index) do begin
                            writeInt(indexAcquire(&type));
                            writeInt(indexAcquire(specialSimpleName));
                        end;
                    end;
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializeMethod(__method: Method): ByteArrayOutputStream;
        var
            index: int;
            length: int;
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_METH);
                    writeShort(__method.attributes);
                    writeInt(indexAcquire(__method.&type));
                    writeInt(indexAcquire(__method.specialSimpleName));
                    with __method.arguments do begin
                        length := getLength();
                        writeShort(length);
                        for index := 0 to length - 1 do with readComponent(index) do begin
                            writeInt(indexAcquire(&type));
                            writeInt(indexAcquire(specialSimpleName));
                        end;
                    end;
                    for index := 0 to __method.getThrowablesLength() - 1 do begin
                        writeInt(indexAcquire(__method.getThrowableTypeAt(index).specialCanonicalName));
                    end;
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;

        function BinarySourceGeneratorConstants.serializeCode(__code: Code): ByteArrayOutputStream;
        label
            break_label0;
        type
            HashtableOfAnsiStringToType = specialize HashtableOfAnsiString<&Type>;
        var
            cur: int;
            max: int;
            min: int;
            store: int;
            index: int;
            ivalue: int;
            jvalue: int;
            cindex: int;
            jindex: int;
            length: int;
            jlength: int;
            encoded: int;
            lastIndex: int;
            lineIndex: int;
            primLength: int;
            refsLength: int;
            formInstruction: int;
            nodeInstruction: int;
            name: AnsiString;
            __end: Node;
            block: Node;
            target: Node;
            __node: Node;
            __begin: Node;
            __type: &Type;
            __local: Local;
            oldType: &Type;
            refObj: TObject;
            refInt: IUnknown;
            jumpDefault: Node;
            __index: Constant;
            __length: Constant;
            operandC: Constant;
            newType: TableItem;
            __global: TableItem;
            operandI: TableItem;
            thisArgument: Local;
            __constant: Constant;
            __fieldoid: TableItem;
            __callable: TableItem;
            primTable: HashtableOfAnsiStringToType;
            refsTable: HashtableOfAnsiStringToType;
            stream: ByteArrayOutputStream;
        begin
            stream := ByteArrayOutputStream.create();
            try
                with AVTOORecompilable, DataOutputStream.create(stream), bigEndianDataOutput do try
                    writeInt(CHUNK_CODE);
                    begin
                        primTable := nil;
                        refsTable := nil;
                        try
                            primTable := HashtableOfAnsiStringToType.create();
                            refsTable := HashtableOfAnsiStringToType.create();
                            with __code.locals do for index := 0 to getLength() - 1 do with readComponent(index) do if not isConstant() then begin
                                __type := &type;
                                name := specialSimpleName;
                                if __type.isPrimitive() then begin
                                    if not primTable.contains(name) or (primTable[name].fieldWidth < __type.fieldWidth) then begin
                                        primTable[name] := __type;
                                    end;
                                end else begin
                                    if not refsTable.contains(name) then begin
                                        refsTable[name] := __type;
                                    end;
                                end;
                            end;
                            primLength := primTable.length;
                            refsLength := refsTable.length;
                            length := primLength + refsLength;
                            if length + CoInt.MIN_VALUE > $ffff + CoInt.MIN_VALUE then begin
                                raise UnencodableDataException.create(AnsiString.format(
                                    AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.too-many-locals'), [
                                        CoObject.create(__code.parentCallable)
                                    ]
                                ));
                            end;
                            writeShort(length);
                            for index := 0 to primLength - 1 do begin
                                name := primTable.keyAt(index);
                                __type := primTable[name];
                                writeInt(indexAcquire(__type));
                                writeInt(indexAcquire(name));
                            end;
                            for index := 0 to refsLength - 1 do begin
                                name := refsTable.keyAt(index);
                                __type := refsTable[name];
                                writeInt(indexAcquire(__type));
                                writeInt(indexAcquire(name));
                            end;
                        finally
                            primTable.free();
                            refsTable.free();
                        end;
                    end;
                    thisArgument := __code.parentCallable.arguments.thisArgument;
                    lastIndex := -1;
                    for cindex := 0 to __code.getLength() - 1 do begin
                        __node := __code.readComponent(cindex);
                        begin
                            lineIndex := __node.location[0];
                            if (lineIndex >= 0) and (lineIndex <> lastIndex) then begin
                                lastIndex := lineIndex;
                                encoded := encodeDeclare(false, lineIndex);
                                if isLongEncoded(encoded) then begin
                                    writeInt(encoded);
                                end else begin
                                    writeShort(encoded);
                                end;
                            end;
                            lineIndex := __node.debugIndex;
                            if lineIndex >= 0 then begin
                                encoded := encodeDeclare(true, not lineIndex);
                                if isLongEncoded(encoded) then begin
                                    writeInt(encoded);
                                end else begin
                                    writeShort(encoded);
                                end;
                            end;
                            lineIndex := __node.labelIndex;
                            if lineIndex >= 0 then begin
                                encoded := encodeDeclare(true, lineIndex);
                                if isLongEncoded(encoded) then begin
                                    writeInt(encoded);
                                end else begin
                                    writeShort(encoded);
                                end;
                            end;
                        end;
                        jlength := __node.getJumpCasesLength();
                        nodeInstruction := __node.instruction;
                        if jlength > 0 then begin
                            formInstruction := FLAG_BOOLEAN_JUMP;
                        end else begin
                            formInstruction := 0;
                        end;
                        case nodeInstruction of
                        METHOD_ENTER: begin
                            writeShort(INST_METHOD_ENTER);
                            writeIndex((__node.reference1 as CoInt).asInt());
                            continue;
                        end;
                        SWAP: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_SWAP or encodeType(__type));
                            continue;
                        end;
                        FCT_BOUND,
                        FCT_BEGIN,
                        FCT_END: begin
                            writeShort(INST_BOUND);
                            continue;
                        end;
                        FCT_THROW: begin
                            __type := __node.reference1 as &Type;
                            writeShort(INST_THROW);
                            writeIndex(indexAcquire(__type));
                            continue;
                        end;
                        LOAD_STATIC: begin
                            __global := __node.operand1;
                            if __node.weak then begin
                                writeShort(INST_LOAD_STATICW);
                                writeIndex(indexAcquire(__global));
                                continue;
                            end;
                            writeShort(formInstruction or INST_LOAD_STATIC);
                            writeIndex(indexAcquire(__global));
                        end;
                        LOAD_LOCAL: begin
                            __local := __node.operand1 as Local;
                            if __node.weak then begin
                                writeShort(INST_LOAD_LOCALW or encodeType(TYP_REF));
                                if __local = thisArgument then begin
                                    writeIndex(0);
                                    continue;
                                end;
                                writeIndex(indexOf(__local.specialSimpleName));
                                continue;
                            end;
                            writeShort(formInstruction or INST_LOAD_LOCAL or encodeType(__local.&type));
                            if __local = thisArgument then begin
                                writeIndex(0);
                                goto break_label0;
                            end;
                            writeIndex(indexOf(__local.specialSimpleName));
                        end;
                        LOAD_CONST: begin
                            __constant := __node.operandC;
                            if __constant.isReference() then begin
                                refObj := __constant.asObject();
                                if refObj = nil then begin
                                    writeShort(INST_LOAD_CONST_NULL);
                                    continue;
                                end;
                                if refObj is RequiredReflectItem then begin
                                    if __node.weak then begin
                                        writeShort(INST_LOAD_CONSTW);
                                    end else begin
                                        writeShort(INST_LOAD_CONST);
                                    end;
                                    writeIndex(indexAcquire(RequiredReflectItem(refObj)));
                                    continue;
                                end;
                                refInt := __constant.asInterface();
                                if refInt is Value then begin
                                    writeShort(INST_LOAD_CONST);
                                    writeIndex(indexAcquire((refInt as Value).asUnicodeString()));
                                    continue;
                                end;
                                raise UnencodableDataException.create(AnsiString.format(
                                    AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.constant-value'), [
                                        CoAnsiString.create(refObj.getClass().getCanonicalName())
                                    ]
                                ));
                            end;
                            __type := __constant.&type;
                            if __type.isBoolean() then begin
                                if __constant.asBoolean() then begin
                                    writeShort(INST_LOAD_CONST_BYTE or $ff);
                                    continue;
                                end;
                                writeShort(INST_LOAD_CONST_BYTE or $00);
                                continue;
                            end;
                            if __type.isInt() then begin
                                ivalue := __constant.asInt();
                                if (ivalue >= CoByte.MIN_VALUE) and (ivalue <= CoByte.MAX_VALUE) then begin
                                    writeShort(INST_LOAD_CONST_BYTE or __constant.asByte() and $ff);
                                    continue;
                                end;
                                if (ivalue >= CoShort.MIN_VALUE) and (ivalue <= CoShort.MAX_VALUE) then begin
                                    writeShort(INST_LOAD_CONST_SHORT);
                                    writeShort(ivalue);
                                    continue;
                                end;
                                writeShort(INST_LOAD_CONST_INT);
                                writeInt(ivalue);
                                continue;
                            end;
                            writeShort(INST_LOAD_CONST);
                            writeIndex(indexAcquire(__constant));
                            continue;
                        end;
                        READ_ELEMENT: begin
                            __type := __node.operand1 as &Type;
                            __index := __node.operandC;
                            if __index <> nil then begin
                                writeShort(INST_READ_ELEMENTI or encodeVectorIndex(__index.asInt()) or encodeType(__type));
                                continue;
                            end;
                            writeShort(INST_READ_ELEMENT or encodeType(__type));
                            continue;
                        end;
                        READ_COMPONENT: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_READ_COMPONENT or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        READ_FIELD: begin
                            __fieldoid := __node.operand1;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_READ_FIELD or encodeOperand(operandC, operandI));
                            writeIndex(indexAcquire(__fieldoid));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        READ_SPECIAL: begin
                            __fieldoid := __node.operand1;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_READ_SPECIAL or encodeOperand(operandC, operandI));
                            writeIndex(indexAcquire(__fieldoid));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        READ_PROPERTY: begin
                            __fieldoid := __node.operand1;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_READ_PROPERTY or encodeOperand(operandC, operandI));
                            writeIndex(indexAcquire(__fieldoid));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        STORE_STATIC: begin
                            __global := __node.operand1;
                            __constant := __node.operandC;
                            if __constant <> nil then begin
                                if __constant.isNull() then begin
                                    writeShort(INST_STORE_STATIC_NULL);
                                    writeIndex(indexAcquire(__global));
                                    continue;
                                end;
                                __type := __constant.&type;
                                if __type.isBoolean() then begin
                                    writeShort(formInstruction or INST_STORE_STATIC_SHORT);
                                    writeIndex(indexAcquire(__global));
                                    if __constant.asBoolean() then begin
                                        writeShort(-1);
                                        goto break_label0;
                                    end;
                                    writeShort(0);
                                    goto break_label0;
                                end;
                                if __type.isInt() then begin
                                    ivalue := __constant.asInt();
                                    if (ivalue >= CoShort.MIN_VALUE) and (ivalue <= CoShort.MAX_VALUE) then begin
                                        writeShort(INST_STORE_STATIC_SHORT);
                                        writeIndex(indexAcquire(__global));
                                        writeShort(ivalue);
                                        continue;
                                    end;
                                    writeShort(INST_STORE_STATIC_INT);
                                    writeIndex(indexAcquire(__global));
                                    writeInt(ivalue);
                                    continue;
                                end;
                                raise UnencodableDataException.create(AnsiString.format(
                                    AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.assignable.global'), [
                                        CoObject.create(__type)
                                    ]
                                ));
                            end;
                            writeShort(formInstruction or INST_STORE_STATIC);
                            writeIndex(indexAcquire(__global));
                        end;
                        STORE_LOCAL,
                        DECLARE_WITH,
                        DECLARE_LOCAL: begin
                            store := nodeInstruction - (STORE_LOCAL - STORE_NORMAL);
                            __local := __node.operand1 as Local;
                            __constant := __node.operandC;
                            if __constant <> nil then begin
                                if __constant.isNull() then begin
                                    writeShort(INST_STORE_LOCAL_NULL or encodeStore(store) or encodeType(TYP_REF));
                                    writeIndex(getOperandIndex(nil, __local, thisArgument));
                                    continue;
                                end;
                                __type := __constant.&type;
                                if __type.isBoolean() then begin
                                    writeShort(formInstruction or INST_STORE_LOCAL_SHORT or encodeStore(store) or encodeType(TYP_BOOLEAN));
                                    writeIndex(getOperandIndex(nil, __local, thisArgument));
                                    if __constant.asBoolean() then begin
                                        writeShort(-1);
                                        goto break_label0;
                                    end;
                                    writeShort(0);
                                    goto break_label0;
                                end;
                                if __type.isInt() then begin
                                    ivalue := __constant.asInt();
                                    if (ivalue >= CoShort.MIN_VALUE) and (ivalue <= CoShort.MAX_VALUE) then begin
                                        writeShort(INST_STORE_LOCAL_SHORT or encodeStore(store) or encodeType(__type));
                                        writeIndex(getOperandIndex(nil, __local, thisArgument));
                                        writeShort(ivalue);
                                        continue;
                                    end;
                                    writeShort(INST_STORE_LOCAL_INT or encodeStore(store) or encodeType(__type));
                                    writeIndex(getOperandIndex(nil, __local, thisArgument));
                                    writeInt(ivalue);
                                    continue;
                                end;
                                raise UnencodableDataException.create(AnsiString.format(
                                    AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.assignable.local'), [
                                        CoObject.create(__type)
                                    ]
                                ));
                            end;
                            writeShort(formInstruction or INST_STORE_LOCAL or encodeStore(store) or encodeType(__local.&type));
                            writeIndex(getOperandIndex(nil, __local, thisArgument));
                        end;
                        INC_PRED_LOAD_LOCAL: begin
                            __local := __node.operand1 as Local;
                            writeShort(INST_INC_PRED_LOAD_LOCAL or encodeType(__local.&type));
                            writeIndex(indexOf(__local.specialSimpleName));
                            continue;
                        end;
                        DEC_PRED_LOAD_LOCAL: begin
                            __local := __node.operand1 as Local;
                            writeShort(INST_DEC_PRED_LOAD_LOCAL or encodeType(__local.&type));
                            writeIndex(indexOf(__local.specialSimpleName));
                            continue;
                        end;
                        INC_POST_LOAD_LOCAL: begin
                            __local := __node.operand1 as Local;
                            writeShort(INST_INC_POST_LOAD_LOCAL or encodeType(__local.&type));
                            writeIndex(indexOf(__local.specialSimpleName));
                            continue;
                        end;
                        DEC_POST_LOAD_LOCAL: begin
                            __local := __node.operand1 as Local;
                            writeShort(INST_DEC_POST_LOAD_LOCAL or encodeType(__local.&type));
                            writeIndex(indexOf(__local.specialSimpleName));
                            continue;
                        end;
                        WRITE_COMPONENT: begin
                            __type := __node.operand1 as &Type;
                            writeShort(formInstruction or INST_WRITE_COMPONENT or encodeType(__type));
                        end;
                        WRITE_FIELD: begin
                            __fieldoid := __node.operand1;
                            writeShort(formInstruction or INST_WRITE_FIELD);
                            writeIndex(indexAcquire(__fieldoid));
                        end;
                        WRITE_SPECIAL: begin
                            __fieldoid := __node.operand1;
                            writeShort(formInstruction or INST_WRITE_SPECIAL);
                            writeIndex(indexAcquire(__fieldoid));
                        end;
                        WRITE_PROPERTY: begin
                            __fieldoid := __node.operand1;
                            writeShort(formInstruction or INST_WRITE_PROPERTY);
                            writeIndex(indexAcquire(__fieldoid));
                        end;
                        FCT_JUMP,
                        FCT_RETURN,
                        FCT_BRANCH: begin
                            if (nodeInstruction = FCT_BRANCH) and (jlength > 0) then begin
                                min := __node.getJumpCaseValueAt(0);
                                max := min;
                                for jindex := 1 to jlength - 1 do begin
                                    cur := __node.getJumpCaseValueAt(jindex);
                                    if min > cur then min := cur;
                                    if max < cur then max := cur;
                                end;
                                jumpDefault := __node.jumpDefault;
                                if (long(max) - min + 2) <= (long(jlength) shl 1) then begin
                                    writeShort(INST_SWITCH_TABLE);
                                    writeInt(min);
                                    jlength := max - min + 1;
                                    writeIndex(jlength);
                                    jvalue := min;
                                    for jindex := 0 to jlength - 1 do begin
                                        target := __node.getJumpCase(jvalue);
                                        if target = nil then target := jumpDefault;
                                        writeLabel(target);
                                        inc(jvalue);
                                    end;
                                end else begin
                                    writeShort(INST_SWITCH_LOOKUP);
                                    writeIndex(jlength);
                                    for jindex := 0 to jlength - 1 do begin
                                        jvalue := __node.getJumpCaseValueAt(jindex);
                                        target := __node.getJumpCaseNodeAt(jindex);
                                        writeInt(jvalue);
                                        writeLabel(target);
                                    end;
                                end;
                                writeLabel(jumpDefault);
                                continue;
                            end;
                            writeShort(INST_JUMP);
                            writeLabel(__node.jumpDefault);
                            continue;
                        end;
                        LOAD_INTERRUPT: begin
                            __callable := __node.operand1;
                            writeShort(INST_LOAD_INTERRUPT);
                            writeIndex(indexAcquire(__callable));
                            continue;
                        end;
                        REF_EQ: begin
                            operandI := __node.operand1;
                            operandC := __node.operandC;
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_REF_EQW;
                            end else begin
                                formInstruction := formInstruction or INST_REF_EQ;
                            end;
                            writeShort(formInstruction or encodeOperand(operandC, operandI) or encodeType(TYP_REF));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        REF_NE: begin
                            operandI := __node.operand1;
                            operandC := __node.operandC;
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_REF_NEW;
                            end else begin
                                formInstruction := formInstruction or INST_REF_NE;
                            end;
                            writeShort(formInstruction or encodeOperand(operandC, operandI) or encodeType(TYP_REF));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        REF_IS_NULL: begin
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_REF_IS_NULLW;
                            end else begin
                                formInstruction := formInstruction or INST_REF_IS_NULL;
                            end;
                            writeShort(formInstruction or encodeType(TYP_REF));
                        end;
                        REF_IS_OBJECT: begin
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_REF_IS_OBJECTW;
                            end else begin
                                formInstruction := formInstruction or INST_REF_IS_OBJECT;
                            end;
                            writeShort(formInstruction or encodeType(TYP_REF));
                        end;
                        CLINIT_TRY_LOCK: begin
                            operandI := __node.operand1;
                            writeShort(formInstruction or INST_CLINIT_TRY_LOCK);
                            writeIndex(indexAcquire(operandI));
                        end;
                        CLINIT_UNLOCK: begin
                            operandI := __node.operand1;
                            writeShort(INST_CLINIT_UNLOCK);
                            writeIndex(indexAcquire(operandI));
                            continue;
                        end;
                        MONITOR_ENTER: begin
                            writeShort(INST_MONITOR_ENTER or encodeType(TYP_REF));
                            continue;
                        end;
                        MONITOR_LEAVE: begin
                            writeShort(INST_MONITOR_LEAVE or encodeType(TYP_REF));
                            continue;
                        end;
                        FINALLY_ENTER: begin
                            writeShort(INST_FINALLY_ENTER);
                            continue;
                        end;
                        FINALLY_LEAVE: begin
                            writeShort(INST_FINALLY_LEAVE);
                            continue;
                        end;
                        NEW_ARRAY: begin
                            operandI := __node.operand1;
                            __length := __node.operandC;
                            writeShort(INST_NEW_ARRAY);
                            writeIndex(indexAcquire(operandI));
                            writeInt(__length.asInt());
                            continue;
                        end;
                        INVOKE_FINALLY: begin
                            target := __node.reference1 as Node;
                            writeShort(INST_INVOKE_FINALLY);
                            writeLabel(target);
                            continue;
                        end;
                        INVOKE_STATIC: begin
                            __callable := __node.operand1;
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_INVOKE_STATICD;
                            end else begin
                                formInstruction := formInstruction or INST_INVOKE_STATIC;
                            end;
                            writeShort(formInstruction);
                            writeIndex(indexAcquire(__callable));
                        end;
                        INVOKE_SPECIAL: begin
                            __callable := __node.operand1;
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_INVOKE_SPECIALD;
                            end else begin
                                formInstruction := formInstruction or INST_INVOKE_SPECIAL;
                            end;
                            writeShort(formInstruction);
                            writeIndex(indexAcquire(__callable));
                        end;
                        INVOKE_VIRTUAL: begin
                            __callable := __node.operand1;
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_INVOKE_VIRTUALD;
                            end else begin
                                formInstruction := formInstruction or INST_INVOKE_VIRTUAL;
                            end;
                            writeShort(formInstruction);
                            writeIndex(indexAcquire(__callable));
                        end;
                        INVOKE_SERVICE: begin
                            __callable := __node.operand1;
                            if __node.weak then begin
                                formInstruction := formInstruction or INST_INVOKE_SERVICED;
                            end else begin
                                formInstruction := formInstruction or INST_INVOKE_SERVICE;
                            end;
                            writeShort(formInstruction);
                            writeIndex(indexAcquire(__callable));
                        end;
                        O_VECT_DIV: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_DIV or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_PCK: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_VECT_PCK or encodeType(__type));
                            continue;
                        end;
                        O_VECT_LUP: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_VECT_LUP or encodeType(__type));
                            continue;
                        end;
                        O_VECT_UUP: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_VECT_UUP or encodeType(__type));
                            continue;
                        end;
                        O_VECT_MUL: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_MUL or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SHL: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SHL or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SHR: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SHR or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SHRU: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SHRU or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_ADD: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_ADD or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SUB: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SUB or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_EQ: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_EQ or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_NE: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_NE or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_GT: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_GT or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_GE: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_GE or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_LT: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_LT or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_LE: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_LE or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_DIV: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_DIV or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_DIVU: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_DIVU or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_REM: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_REM or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_REMU: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_REMU or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_MUL: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_MUL or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_SHL: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_SHL or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_SHR: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_SHR or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_SHRU: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_SHRU or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_ADD: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_ADD or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_SUB: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_SCAL_SUB or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_EQ: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_SCAL_EQ or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_SCAL_NE: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_SCAL_NE or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_SCAL_GT: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_SCAL_GT or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_SCAL_GE: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_SCAL_GE or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_SCAL_LT: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_SCAL_LT or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_SCAL_LE: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_SCAL_LE or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_VECT_NEG: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_VECT_NEG or encodeType(__type));
                            continue;
                        end;
                        CAST_TO: begin
                            newType := __node.operand1;
                            oldType := __node.operand2 as &Type;
                            writeShort(INST_CAST_TO or encodeType(oldType));
                            writeIndex(indexAcquire(newType));
                            continue;
                        end;
                        INC_LOCAL: begin
                            __local := __node.operand1 as Local;
                            writeShort(INST_INC_LOCAL or encodeType(__local.&type));
                            writeIndex(indexOf(__local.specialSimpleName));
                            continue;
                        end;
                        DEC_LOCAL: begin
                            __local := __node.operand1 as Local;
                            writeShort(INST_DEC_LOCAL or encodeType(__local.&type));
                            writeIndex(indexOf(__local.specialSimpleName));
                            continue;
                        end;
                        O_BIT_NOT: begin
                            __type := __node.operand1 as &Type;
                            writeShort(formInstruction or INST_BIT_NOT or encodeType(__type));
                        end;
                        O_BIT_AND: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_BIT_AND or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_BIT_OR: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_BIT_OR or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        O_BIT_XOR: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_BIT_XOR or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        DUP1: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_DUP1 or encodeType(__type));
                            continue;
                        end;
                        DUP2: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_DUP2 or encodeType(__type));
                            continue;
                        end;
                        O_VECT_HMUL: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_HMUL or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_HMULU: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_HMULU or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SADD: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SADD or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SADDU: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SADDU or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SSUB: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SSUB or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_VECT_SSUBU: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(INST_VECT_SSUBU or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                            continue;
                        end;
                        O_SCAL_NEG: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_SCAL_NEG or encodeType(__type));
                            continue;
                        end;
                        EXP_INSTANCEOF: begin
                            __type := __node.operand1 as &Type;
                            writeShort(formInstruction or INST_INSTANCE_OF or encodeType(__type));
                            writeIndex(indexAcquire(__type));
                        end;
                        TEST_EQZ: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_TEST_EQZ or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        TEST_NEZ: begin
                            __type := __node.operand1 as &Type;
                            operandI := __node.operand2;
                            operandC := __node.operandC;
                            writeShort(formInstruction or INST_TEST_NEZ or encodeOperand(operandC, operandI) or encodeType(__type));
                            if (operandC <> nil) or (operandI <> nil) then writeIndex(getOperandIndex(operandC, operandI, thisArgument));
                        end;
                        NEW_VECTOR: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_NEW_VECTOR or encodeType(__type));
                            continue;
                        end;
                        NEW_INSTANCE: begin
                            operandI := __node.operand1;
                            writeShort(INST_NEW_INSTANCE);
                            writeIndex(indexAcquire(operandI));
                            continue;
                        end;
                        NEW_ARRAY_MONO: begin
                            operandI := __node.operand1;
                            writeShort(INST_NEW_ARRAY_MONO);
                            writeIndex(indexAcquire(operandI));
                            continue;
                        end;
                        NEW_ARRAY_MULTI: begin
                            operandI := __node.operand1;
                            writeShort(INST_NEW_ARRAY_MULTI);
                            writeIndex(indexAcquire(operandI));
                            continue;
                        end;
                        DUP1X1: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_DUP1X1 or encodeType(__type));
                            continue;
                        end;
                        DUP1X2: begin
                            __type := __node.operand1 as &Type;
                            writeShort(INST_DUP1X2 or encodeType(__type));
                            continue;
                        end;
                        METHOD_LEAVE: begin
                            writeShort(INST_METHOD_LEAVE);
                            continue;
                        end;
                        EXCEPT_ENTER: begin
                            writeShort(INST_EXCEPT_ENTER);
                            continue;
                        end;
                        EXCEPT_TRY: begin
                            __begin := __node.reference1 as Node;
                            __end := __node.reference2 as Node;
                            writeShort(INST_EXCEPT_TRY);
                            writeLabel(__begin);
                            writeLabel(__end);
                            continue;
                        end;
                        EXCEPT_CATCH: begin
                            block := __node.reference1 as Node;
                            __type := __node.reference2 as &Type;
                            writeShort(INST_EXCEPT_CATCH);
                            writeLabel(block);
                            writeIndex(indexAcquire(__type));
                            continue;
                        end;
                        EXCEPT_FINALLY: begin
                            block := __node.reference1 as Node;
                            writeShort(INST_EXCEPT_FINALLY);
                            writeLabel(block);
                            continue;
                        end;
                        EXCEPT_LEAVE: begin
                            writeShort(INST_EXCEPT_LEAVE);
                            continue;
                        end;
                        else
                            raise UnencodableDataException.create(AnsiString.format(
                                AResource.readUnitResourceAsAnsiString(ru.malik.elaborarer.avtoo.generator.UNIT_NAME, 'not-encodable.instruction'), [
                                    CoAnsiString.create(CoInt.toHexString(nodeInstruction))
                                ]
                            ));
                        end;
                        break_label0:
                        if (formInstruction and FLAG_BOOLEAN_JUMP) <> 0 then begin
                            writeLabel(__node.jumpIsTrue);
                            writeLabel(__node.jumpIsFalse);
                        end;
                    end;
                finally
                    free();
                end;
            except
                stream.free();
                raise;
            end;
            result := stream;
        end;
    {%endregion}

    {%region  BinarySourceGeneratorCodeDataOutput }
        procedure BinarySourceGeneratorCodeDataOutput.writeByte2(const value: byte2);
        var
            index: int;
        begin
            for index := 1 downto 0 do writeByte(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeByte4(const value: byte4);
        var
            index: int;
        begin
            for index := 3 downto 0 do writeByte(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeByte8(const value: byte8);
        var
            index: int;
        begin
            for index := 7 downto 0 do writeByte(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeShort2(const value: short2);
        var
            index: int;
        begin
            for index := 1 downto 0 do writeShort(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeShort4(const value: short4);
        var
            index: int;
        begin
            for index := 3 downto 0 do writeShort(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeShort8(const value: short8);
        var
            index: int;
        begin
            for index := 7 downto 0 do writeShort(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeInt2(const value: int2);
        var
            index: int;
        begin
            for index := 1 downto 0 do writeInt(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeInt4(const value: int4);
        var
            index: int;
        begin
            for index := 3 downto 0 do writeInt(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeInt8(const value: int8);
        var
            index: int;
        begin
            for index := 7 downto 0 do writeInt(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeLong2(const value: long2);
        var
            index: int;
        begin
            for index := 1 downto 0 do writeLong(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeLong4(const value: long4);
        var
            index: int;
        begin
            for index := 3 downto 0 do writeLong(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeLong8(const value: long8);
        var
            index: int;
        begin
            for index := 7 downto 0 do writeLong(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeFloat2(const value: float2);
        var
            index: int;
        begin
            for index := 1 downto 0 do writeFloat(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeFloat4(const value: float4);
        var
            index: int;
        begin
            for index := 3 downto 0 do writeFloat(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeFloat8(const value: float8);
        var
            index: int;
        begin
            for index := 7 downto 0 do writeFloat(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeDouble2(const value: double2);
        var
            index: int;
        begin
            for index := 1 downto 0 do writeDouble(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeDouble4(const value: Double4);
        var
            index: int;
        begin
            for index := 3 downto 0 do writeDouble(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeDouble8(const value: double8);
        var
            index: int;
        begin
            for index := 7 downto 0 do writeDouble(value[index]);
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeIndex(index: int);
        begin
            if index <= CoShort.MAX_VALUE then begin
                writeShort(index);
            end else begin
                writeInt(CoInt.MIN_VALUE or index);
            end;
        end;

        procedure BinarySourceGeneratorCodeDataOutput.writeLabel(target: Node);
        var
            index: int;
            encoded: int;
        begin
            index := target.debugIndex;
            if index >= 0 then begin
                encoded := AVTOORecompilable.encodeUsing(not index);
            end else begin
                index := target.labelIndex;
                if index >= 0 then begin
                    encoded := AVTOORecompilable.encodeUsing(index);
                end else begin
                    encoded := AVTOORecompilable.encodeNext();
                end;
            end;
            if AVTOORecompilable.isLongEncoded(encoded) then begin
                writeInt(encoded);
            end else begin
                writeShort(encoded);
            end;
        end;
    {%endregion}

    {%region  AssemblerSourceGeneratorClassType }
        function AssemblerSourceGeneratorClassType.hasOverriddingMembersFor(superservice: ClassType; isSuperclassesLook: boolean): boolean;
        var
            place: int;
            index: int;
            member: ProgrammeItem;
            overridden: OverriddableMember;
            overridding: OverriddableMember;
        begin
            if isSuperclassesLook then begin
                place := Method.CURRENT_TYPE or Method.SUPERCLASSES;
            end else begin
                place := Method.CURRENT_TYPE;
            end;
            for index := superservice.getLength() - 1 downto 0 do begin
                member := superservice.readComponent(index);
                if not(member is OverriddableMember) then continue;
                { переопределённый член } overridden := OverriddableMember(member);
                if (overridden.visibility < VIS_PROTECTED) or overridden.isAbstract() then continue;
                { переопределяющий член } overridding := overridden.overridesIn(self, place);
                if (overridding <> nil) and (overridding.visibility >= VIS_PROTECTED) then begin
                    result := true;
                    exit;
                end;
            end;
            result := false;
        end;
    {%endregion}

    {%region} initialization
        AssemblerSourcePrintStream.initialize();
    {%endregion}

    {%region} finalization
        AssemblerSourcePrintStream.finalize();
    {%endregion}
end.