SYMBOL * FetchVirtual(int n) { if (n < 0) return 0; if (n >= GetVirtualIndex()) return 0; return (SYMBOL *) vtable[n]; }
void SortVirtuals() { SYMBOL *Sym; int n, i, vCount; vCount = GetVirtualIndex(); if (!vCount) return; // printf("\nVIRTUALS (%d)\n\n", vCount); vtable = (int *) NewPtrClear((vCount+2) * sizeof(int *)); if (!vtable) return; Sym = SymTab; n = SYMMAX; do { if ((Sym->Section == section_Enum) && (Sym->LocalScope != 0)) { if (Sym->LabelType == label_Virtual) { i = Sym->VirtualIndex & 0xffff; vtable[i] = (int) Sym; } } Sym++; } while(--n); /* for (n=0;n<vCount;n++) { Sym = (SYMBOL *) vtable[n]; if (print) DumpEnumEntry(Sym); } */ return; }
void RebuildCpp_CallReg() { SYMBOL *sym; int n, count; SortVirtuals(); count = GetVirtualIndex(); // if (!count) if (!CppUsedCallReg) { RebuildEmit("\n// No virtuals\n\n"); return; } RebuildEmit("\n"); RebuildEmit("//****************************************\n"); RebuildEmit("// CallReg Sink\n"); RebuildEmit("//****************************************\n\n"); RebuildEmit("int CallReg(int s, int i0, int i1, int i2, int i3)\n"); RebuildEmit("{\n"); // RebuildEmit(" int r14,r15;\n"); // RebuildEmit(" r14 = r15 = 0;\n\n"); RebuildEmit(" int r14 = 0;\n\n"); if (count) { RebuildEmit(" switch(s & 0xffffff)\n"); RebuildEmit(" {\n"); for (n=0;n<count;n++) { sym = FetchVirtual(n); if (sym->Flags & SymFlag_Ref) { RebuildEmit(" case 0x%x:\n", sym->VirtualIndex); RebuildEmit(" "); CppCallFunction(sym, 0); RebuildEmit("\n\t"); ThisFunctionRetType = sym->RetType; if(ThisFunctionRetType == RET_void) { RebuildEmit(" return 0;\n\n"); } else { CppDecodeReturn(0); // was 1 RebuildEmit("\n\n"); } } } RebuildEmit(" default:\n"); RebuildEmit(" break;\n"); RebuildEmit(" }\n"); } RebuildEmit(" return 0;\n"); RebuildEmit("}\n"); }