private processAssembly()

in impl/src/tooling/icpp/transpiler/icppdecls_emitter.ts [51:189]


    private processAssembly(entrypoint: MIRInvokeKey) {
        const cinits = [...this.assembly.constantDecls].map((cdecl) => cdecl[1].value);
        xxxx; //see SMT version
        const cginfo = constructCallGraphInfo([entrypoint, ...cinits], this.assembly);
        const rcg = [...cginfo.topologicalOrder].reverse();

        for (let i = 0; i < rcg.length; ++i) {
            const cn = rcg[i];
            
            const cscc = cginfo.recursive.find((scc) => scc.has(cn.invoke));
            let worklist = cscc !== undefined ? [...cscc].sort() : [cn.invoke];

            for (let mi = 0; mi < worklist.length; ++mi) {
                const ikey = worklist[mi];

                const idcl = (this.assembly.invokeDecls.get(ikey) || this.assembly.primitiveInvokeDecls.get(ikey)) as MIRInvokeDecl;
                const finfo = this.bemitter.generateICPPInvoke(idcl);

                this.processVirtualEntityUpdates();

                if (finfo !== undefined) {
                    this.icppasm.invdecls.push(finfo);
                }
            }
        }
        
        this.bemitter.requiredProjectVirtualTupleIndex.forEach((rvpt) => {
            const vtype = rvpt.argflowtype;
            const opts = [...this.assembly.typeMap].filter((tme) => this.temitter.isUniqueTupleType(tme[1]) && this.assembly.subtypeOf(tme[1], vtype)).map((tme) => tme[1]);

            opts.forEach((ttup) => {
                const oper = this.bemitter.generateProjectTupleIndexVirtual(rvpt, new SourceInfo(-1, -1, -1 ,-1), ttup);
                this.icppasm.invdecls.push(oper);

                let vte = this.icppasm.vtable.find((v) => v.oftype === ttup.trkey);
                if(vte !== undefined) {
                    vte.vtable.push({vcall: rvpt.inv, inv: oper.ikey});
                }
                else {
                    vte = { oftype: ttup.trkey, vtable: [{vcall: rvpt.inv, inv: oper.ikey}] };
                    this.icppasm.vtable.push(vte);
                }
            });
        });

        this.bemitter.requiredProjectVirtualRecordProperty.forEach((rvpr) => {
            const vtype = rvpr.argflowtype;
            const opts = [...this.assembly.typeMap].filter((tme) => this.temitter.isUniqueRecordType(tme[1]) && this.assembly.subtypeOf(tme[1], vtype)).map((tme) => tme[1]);

            opts.forEach((trec) => {
                const oper = this.bemitter.generateProjectRecordPropertyVirtual(rvpr, new SourceInfo(-1, -1, -1 ,-1), trec);
                this.icppasm.invdecls.push(oper);

                let vte = this.icppasm.vtable.find((v) => v.oftype === trec.trkey);
                if(vte !== undefined) {
                    vte.vtable.push({vcall: rvpr.inv, inv: oper.ikey});
                }
                else {
                    vte = { oftype: trec.trkey, vtable: [{vcall: rvpr.inv, inv: oper.ikey}] };
                    this.icppasm.vtable.push(vte);
                }
            });
        });

        this.bemitter.requiredProjectVirtualEntityField.forEach((rvpe) => {
            const vtype = rvpe.argflowtype;
            const opts = [...this.assembly.typeMap].filter((tme) => this.temitter.isUniqueEntityType(tme[1]) && this.assembly.subtypeOf(tme[1], vtype)).map((tme) => tme[1]);

            opts.forEach((tentity) => {
                const oper = this.bemitter.generateProjectEntityFieldVirtual(rvpe, new SourceInfo(-1, -1, -1 ,-1), tentity);
                this.icppasm.invdecls.push(oper);

                let vte = this.icppasm.vtable.find((v) => v.oftype === tentity.trkey);
                if(vte !== undefined) {
                    vte.vtable.push({vcall: rvpe.inv, inv: oper.ikey});
                }
                else {
                    vte = { oftype: tentity.trkey, vtable: [{vcall: rvpe.inv, inv: oper.ikey}] };
                    this.icppasm.vtable.push(vte);
                }
            });
        });

        this.icppasm.cbuffsize = this.bemitter.constsize;
        this.icppasm.cmask = "111111";
        for(let i = 1; i < this.bemitter.constlayout.length; ++i) {
            this.icppasm.cmask += this.bemitter.constlayout[i].storage.allocinfo.inlinedmask;
        }

        this.assembly.constantDecls.forEach((cdecl) => {
            const decltype = this.temitter.getICPPTypeData(this.temitter.getMIRType(cdecl.declaredType));
            const offset = this.bemitter.constMap.get(cdecl.gkey) as number;

            let optenumname: [string, string] | undefined = undefined;
            if(cdecl.attributes.includes("enum")) {
                optenumname = [cdecl.enclosingDecl as string, cdecl.cname];
            }

            const icppdecl = new ICPPConstDecl(cdecl.gkey, optenumname, offset, cdecl.value, decltype);
            this.icppasm.constdecls.push(icppdecl);

            this.icppasm.cbuffsize += decltype.allocinfo.inlinedatasize;
            this.icppasm.cmask += decltype.allocinfo.inlinedmask;
        });

        this.icppasm.litdecls = this.bemitter.constlayout.slice(1)
            .filter((cle) => cle.isliteral)
            .map((cle) => {
                return { offset: cle.offset, storage: cle.storage, value: cle.value };
            });

        const basetypes = [...this.assembly.typeMap].map((tt) => tt[1]).filter((tt) => tt.options.length === 1 && !(tt.options[0] instanceof MIRConceptType));
        this.icppasm.typenames.forEach((tt) => {
            const mirtype = this.temitter.getMIRType(tt);
            const icpptype = this.temitter.getICPPTypeData(mirtype);

            if (icpptype.ptag !== ICPPParseTag.BuiltinTag) {
                this.icppasm.typedecls.push(icpptype);

                if (icpptype instanceof ICPPTypeInlineUnion || icpptype instanceof ICPPTypeRefUnion) {
                    const subtypes = basetypes.filter((btype) => this.assembly.subtypeOf(btype, mirtype)).map((tt) => tt.trkey).sort();
                    this.icppasm.subtypes.set(mirtype.trkey, new Set<MIRResolvedTypeKey>(subtypes));
                }

                if (this.temitter.isUniqueEntityType(mirtype)) {
                    const mdecl = this.assembly.entityDecls.get(mirtype.trkey) as MIREntityTypeDecl;
                    let vte = this.icppasm.vtable.find((v) => v.oftype === mdecl.tkey);
                    if (vte === undefined) {
                        vte = { oftype: mdecl.tkey, vtable: [] };
                        this.icppasm.vtable.push(vte);
                    }

                    mdecl.vcallMap.forEach((vc) => {
                        (vte as { oftype: MIRResolvedTypeKey, vtable: { vcall: MIRVirtualMethodKey, inv: MIRInvokeKey }[] }).vtable.push({ vcall: vc[0], inv: vc[1] });
                    });
                }
            }
        });
    }