#include "compiler.h" #include "compiler/CompilerTools.h" #include "compiler/CError.h" #include "compiler/enode.h" #include "compiler/objc.h" #include "compiler/objects.h" #include "compiler/scopes.h" #include "compiler/som.h" #include "compiler/templates.h" #include "compiler/types.h" #include "cos.h" // HACKS extern Type stvoid; extern Type stbool; extern Type stchar; extern Type stsignedchar; extern Type stunsignedchar; extern Type stwchar; extern Type stsignedshort; extern Type stunsignedshort; extern Type stsignedint; extern Type stunsignedint; extern Type stsignedlong; extern Type stunsignedlong; extern Type stsignedlonglong; extern Type stunsignedlonglong; extern Type stfloat; extern Type stshortdouble; extern Type stdouble; extern Type stlongdouble; extern Type elipsis; extern Type oldstyle; extern Type stillegal; extern Type sttemplexpr; extern Type stvoid; extern Type void_ptr; extern Type rt_func; extern Type catchinfostruct; extern void * newh_func; extern void * delh_func; extern void * copy_func; extern void * clear_func; extern void * Rgtid_func; extern void * Rdync_func; extern void * rt_ptmf_cast; extern void * rt_ptmf_cmpr; extern void * rt_ptmf_test; extern void * rt_ptmf_call; extern void * rt_ptmf_scall; extern void * rt_ptmf_null; extern void * rt_som_glue1; extern void * rt_som_glue2; extern void * rt_som_glue3; extern void * rt_som_check; extern void * rt_som_new; extern void * rt_som_newcheck; extern void * rt_ptmf_call4; extern void * rt_ptmf_scall4; extern void * carr_func; extern void * cnar_func; extern void * darr_func; extern void * dnar_func; extern void * dnar3_func; extern void * Xgreg_func; extern void * Xthrw_func; extern void * Xicth_func; extern void * Xecth_func; extern void * Xunex_func; extern Type stvectorunsignedchar; extern Type stvectorsignedchar; extern Type stvectorboolchar; extern Type stvectorunsignedshort; extern Type stvectorsignedshort; extern Type stvectorboolshort; extern Type stvectorunsignedlong; extern Type stvectorsignedlong; extern Type stvectorboollong; extern Type stvectorfloat; extern Type stvectorpixel; // HACKS // PUBLIC FUNCTIONS extern void SetupPrecompiler(); extern void CleanupPrecompiler(); extern void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2); extern void PrecompilerWrite(); extern void PrecompilerRead(short refnum, void *buffer); // END PUBLIC FUNCTIONS typedef struct Patch { struct Patch *next; SInt32 offset; } Patch; typedef struct AddrPatch { struct AddrPatch *next; void *addr; void *value; } AddrPatch; typedef struct BuiltIn { void *target; SInt32 idx; Patch *patches; } BuiltIn; static Boolean cprec_exportargnames; static Boolean cprec_dowrite; static OSErr cprec_ioerror; static void *cprec_rawbuffer; static void *cprec_buffer; static SInt32 cprec_zero_offset; static SInt32 cprec_offset; static int cprec_builtins; static void **cprec_builtin_array; typedef struct TokenPatch { struct TokenPatch *next; TStreamElement *tokens; SInt32 count; } TokenPatch; static TokenPatch *cprec_tokenpatches; static void *cprec_staticdata; static void *cprec_pointerhash; static BuiltIn *cprec_builtin; static Patch *cprec_patch_list; static AddrPatch **cprec_addrhash; static void *cprec_header; static GList cprec_glist; static short cprec_refnum; char *precomp_target_str; // Assorted forward declarations static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace); static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj); static Object *CPrec_GetObjectPatch(Object *obj); static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj); static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj); static Type *CPrec_GetTypePatch(Type *type); static ENode *CPrec_GetExpressionPatch(ENode *enode); static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth); static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst); static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg); static OSErr CPrec_FlushBufferCheck(); void SetupPrecompiler() { cprec_refnum = 0; cprec_glist.data = NULL; cprec_header = NULL; cprec_staticdata = NULL; cprec_ioerror = noErr; } void CleanupPrecompiler() { if (cprec_refnum) { COS_FileClose(cprec_refnum); cprec_refnum = 0; } if (cprec_glist.data) FreeGList(&cprec_glist); } static void CPrec_OLinkListCopy() {} void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2) { } static void CPrec_InitAddressHashTable() { cprec_addrhash = lalloc(0x4000 * sizeof(AddrPatch *)); memclrw(cprec_addrhash, 0x4000 * sizeof(AddrPatch *)); } static void CPrec_InitPointerHashTable() { cprec_pointerhash = lalloc(0x1000); memclrw(cprec_pointerhash, 0x1000); } static int CPrec_AddressHashVal(void *addr) { UInt32 v = (UInt32) addr; return ( v + ((unsigned char *) &v)[0] + ((unsigned char *) &v)[1] + ((unsigned char *) &v)[2] + ((unsigned char *) &v)[3] ) & 0x3FFF; } static AddrPatch *CPrec_FindAddrPatch(void *addr) { AddrPatch *scan; for (scan = cprec_addrhash[CPrec_AddressHashVal(addr)]; scan; scan = scan->next) { if (scan->addr == addr) return scan; } return NULL; } static AddrPatch *CPrec_NewAddrPatch(void *addr, void *value) { AddrPatch **loc; AddrPatch *patch; loc = cprec_addrhash + CPrec_AddressHashVal(addr); patch = lalloc(sizeof(AddrPatch)); patch->addr = addr; patch->value = value; patch->next = *loc; *loc = patch; return patch; } static void CPrec_SetupBuiltInArray() { int count1, count2; Boolean flag; void **array; #define REG_BUILTIN(a) \ if (!flag) { array[count2++] = (a); } else { count1++; } for (count2 = count1 = 0, flag = 1; ;) { REG_BUILTIN(cscope_root); REG_BUILTIN(&stvoid); REG_BUILTIN(&stbool); REG_BUILTIN(&stchar); REG_BUILTIN(&stsignedchar); REG_BUILTIN(&stunsignedchar); REG_BUILTIN(&stwchar); REG_BUILTIN(&stsignedshort); REG_BUILTIN(&stunsignedshort); REG_BUILTIN(&stsignedint); REG_BUILTIN(&stunsignedint); REG_BUILTIN(&stsignedlong); REG_BUILTIN(&stunsignedlong); REG_BUILTIN(&stsignedlonglong); REG_BUILTIN(&stunsignedlonglong); REG_BUILTIN(&stfloat); REG_BUILTIN(&stshortdouble); REG_BUILTIN(&stdouble); REG_BUILTIN(&stlongdouble); REG_BUILTIN(&elipsis); REG_BUILTIN(&oldstyle); REG_BUILTIN(&stillegal); REG_BUILTIN(&sttemplexpr); REG_BUILTIN(&stvoid); REG_BUILTIN(&void_ptr); REG_BUILTIN(&rt_func); REG_BUILTIN(&catchinfostruct); REG_BUILTIN(newh_func); REG_BUILTIN(delh_func); REG_BUILTIN(copy_func); REG_BUILTIN(clear_func); REG_BUILTIN(Rgtid_func); REG_BUILTIN(Rdync_func); REG_BUILTIN(rt_ptmf_cast); REG_BUILTIN(rt_ptmf_cmpr); REG_BUILTIN(rt_ptmf_test); REG_BUILTIN(rt_ptmf_call); REG_BUILTIN(rt_ptmf_scall); REG_BUILTIN(rt_ptmf_null); REG_BUILTIN(rt_som_glue1); REG_BUILTIN(rt_som_glue2); REG_BUILTIN(rt_som_glue3); REG_BUILTIN(rt_som_check); REG_BUILTIN(rt_som_new); REG_BUILTIN(rt_som_newcheck); REG_BUILTIN(rt_ptmf_call4); REG_BUILTIN(rt_ptmf_scall4); REG_BUILTIN(carr_func); REG_BUILTIN(cnar_func); REG_BUILTIN(darr_func); REG_BUILTIN(dnar_func); REG_BUILTIN(dnar3_func); REG_BUILTIN(Xgreg_func); REG_BUILTIN(Xthrw_func); REG_BUILTIN(Xicth_func); REG_BUILTIN(Xecth_func); REG_BUILTIN(Xunex_func); REG_BUILTIN(&stvectorunsignedchar); REG_BUILTIN(&stvectorsignedchar); REG_BUILTIN(&stvectorboolchar); REG_BUILTIN(&stvectorunsignedshort); REG_BUILTIN(&stvectorsignedshort); REG_BUILTIN(&stvectorboolshort); REG_BUILTIN(&stvectorunsignedlong); REG_BUILTIN(&stvectorsignedlong); REG_BUILTIN(&stvectorboollong); REG_BUILTIN(&stvectorfloat); REG_BUILTIN(&stvectorpixel); if (flag) { array = lalloc(sizeof(void *) * count1); cprec_builtin_array = array; cprec_builtins = count1; flag = 0; } else { return; } } } static void CPrec_SetupBuiltIn() { int x; CPrec_SetupBuiltInArray(); cprec_builtin = lalloc(sizeof(BuiltIn) * cprec_builtins); memclrw(cprec_builtin, sizeof(BuiltIn) * cprec_builtins); for (x = 0; x < cprec_builtins; x++) { cprec_builtin[x].target = cprec_builtin_array[x]; cprec_builtin[x].idx = ~x; CPrec_NewAddrPatch(cprec_builtin[x].target, (void *) cprec_builtin[x].idx); } } static void CPrec_NewPointerPatch(void *src, void *ptr) { if (cprec_dowrite) { Patch *patch = lalloc(sizeof(Patch)); patch->offset = (SInt32) src; #line 507 CError_ASSERT((patch->offset & 0x80000001) == 0); if ((SInt32) ptr < 0) { ptr = (void *) ~((SInt32) ptr); #line 513 CError_ASSERT((SInt32) ptr < cprec_builtins); patch->next = cprec_builtin[(SInt32) ptr].patches; cprec_builtin[(SInt32) ptr].patches = patch; ptr = NULL; } else { patch->next = cprec_patch_list; cprec_patch_list = patch; } src = (void *)((char *) src - cprec_zero_offset); #line 525 CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); *((void **) (*cprec_glist.data + (SInt32) src)) = ptr; } } static void CPrec_ExistingPointerPatch(void *src, void *ptr) { if (cprec_dowrite) { AddrPatch *addrPatch; Patch *patch; addrPatch = CPrec_FindAddrPatch(ptr); #line 543 CError_ASSERT(addrPatch); patch = lalloc(sizeof(Patch)); patch->offset = (SInt32) src; patch->next = cprec_patch_list; cprec_patch_list = patch; #line 548 CError_ASSERT((patch->offset & 0x80000001) == 0); src = (void *)((char *) src - cprec_zero_offset); #line 552 CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); *((void **) (*cprec_glist.data + (SInt32) src)) = addrPatch->value; } } static void CPrec_NamePatch(void *src, HashNameNode *name) { name->id = 1; CPrec_ExistingPointerPatch(src, name); } static void *CPrec_AppendAlign() { if (cprec_dowrite) { while (cprec_offset & 3) { AppendGListByte(&cprec_glist, 0); ++cprec_offset; } } return (void *) cprec_offset; } static UInt32 CPrec_AppendByte(UInt8 v) { if (cprec_dowrite) AppendGListByte(&cprec_glist, v); return cprec_offset++; } static UInt32 CPrec_AppendWord16(UInt16 v) { UInt32 offset; if (cprec_dowrite) AppendGListWord(&cprec_glist, v); offset = cprec_offset; cprec_offset += 2; return offset; } static UInt32 CPrec_AppendWord32(UInt32 v) { UInt32 offset; if (cprec_dowrite) AppendGListLong(&cprec_glist, v); offset = cprec_offset; cprec_offset += 4; return offset; } static UInt32 CPrec_AppendPointer(void *v) { UInt32 offset; if (cprec_dowrite) AppendGListLong(&cprec_glist, (SInt32) v); offset = cprec_offset; cprec_offset += 4; return offset; } static UInt32 CPrec_AppendPointerPatch(void *v) { AddrPatch *addrPatch; if (v) { addrPatch = CPrec_FindAddrPatch(v); #line 644 CError_ASSERT(addrPatch); if (cprec_dowrite) { Patch *patch = lalloc(sizeof(Patch)); patch->offset = cprec_offset; patch->next = cprec_patch_list; cprec_patch_list = patch; #line 651 CError_ASSERT((patch->offset & 0x80000001) == 0); } return CPrec_AppendPointer(addrPatch->value); } else { return CPrec_AppendPointer(NULL); } } static void CPrec_AppendNamePatch(HashNameNode *name) { if (name) { CPrec_AppendPointerPatch(name); name->id = 1; } } static void CPrec_AppendString(const char *str) { int len = strlen(str) + 1; if (cprec_dowrite) AppendGListData(&cprec_glist, str, len); cprec_offset += len; } static void CPrec_AppendData(const void *data, int len) { if (cprec_dowrite) AppendGListData(&cprec_glist, data, len); cprec_offset += len; } static void CPrec_RawMemPatch(void *source, const void *data, int len) { void *ptr = CPrec_AppendAlign(); CPrec_AppendData(data, len); CPrec_NewPointerPatch(source, ptr); } static void CPrec_DumpNameTable() {} static void CPrec_DumpMacroTable() {} static void CPrec_GetClassAccessPatch() {} static int CPrec_PointerHash(TypePointer *type) { Type *target; int work; FuncArg *arg; work = type->qual; target = type->target; restart: switch (target->type) { case TYPECLASS: if (TYPE_CLASS(target)->classname) work += TYPE_CLASS(target)->classname->hashval; break; case TYPEENUM: if (TYPE_ENUM(target)->enumname) work += TYPE_ENUM(target)->enumname->hashval; target = TYPE_ENUM(target)->enumtype; work += 3; case TYPEINT: case TYPEFLOAT: work += TYPE_INTEGRAL(target)->integral; break; case TYPEPOINTER: work += TYPE_POINTER(target)->qual; target = TYPE_POINTER(target)->target; goto restart; case TYPEARRAY: work += target->size; target = TYPE_POINTER(target)->target; goto restart; case TYPEFUNC: work += TYPE_FUNC(target)->functype->type; work += TYPE_FUNC(target)->functype->size; for (arg = TYPE_FUNC(target)->args; arg; arg = arg->next) { if (arg->type) { work += arg->type->type; work += arg->type->size; } } break; } work += target->type + target->size; return (work + (work >> 24) + (work >> 16) + (work >> 8)) & 0x3FF; } static TypePointer *CPrec_GetTypePointerPatch(TypePointer *type) { // requires copts } static TypeEnum *CPrec_GetTypeEnumPatch(TypeEnum *type) { TypeEnum *p = CPrec_AppendAlign(); CPrec_NewAddrPatch(type, p); CPrec_AppendData(type, sizeof(TypeEnum)); if (type->nspace) CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(type->nspace)); if (type->enumlist) CPrec_NewPointerPatch(&p->enumlist, CPrec_GetObjEnumConstPatch(type->enumlist)); CPrec_NewPointerPatch(&p->enumtype, CPrec_GetTypePatch(type->enumtype)); if (type->enumname) CPrec_NamePatch(&p->enumname, type->enumname); return p; } static TypeBitfield *CPrec_GetTypeBitfieldPatch(TypeBitfield *type) { TypeBitfield *p = CPrec_AppendAlign(); CPrec_NewAddrPatch(type, p); CPrec_AppendData(type, sizeof(TypeBitfield)); CPrec_NewPointerPatch(&p->bitfieldtype, type->bitfieldtype); return p; } static TypeStruct *CPrec_GetTypeStructPatch(TypeStruct *type) {} static ExceptSpecList *CPrec_GetExceptSpecPatch(ExceptSpecList *exspec) { ExceptSpecList *first, *current, *next; first = current = CPrec_AppendAlign(); while (exspec) { CPrec_AppendData(exspec, sizeof(ExceptSpecList)); if (exspec->type) CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(exspec->type)); if (!exspec->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; exspec = exspec->next; } return first; } static FuncArg *CPrec_GetArgListPatch(FuncArg *lst, Boolean includeNames) { // too many register swaps AddrPatch *addrPatch; FuncArg *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(lst))) return addrPatch->value; first = current = CPrec_AppendAlign(); restart: if (!includeNames) lst->name = NULL; CPrec_AppendData(lst, sizeof(FuncArg)); if (includeNames && lst->name) CPrec_NamePatch(¤t->name, lst->name); if (lst->dexpr) CPrec_NewPointerPatch(¤t->dexpr, CPrec_GetExpressionPatch(lst->dexpr)); if (lst->type) CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(lst->type)); else #line 1167 CError_FATAL(); if (lst->next) { if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; lst = lst->next; CPrec_NewAddrPatch(lst, next); goto restart; } } return first; } static TypeFunc *CPrec_GetTypeFuncPatch(TypeFunc *type) { TypeFunc *p = CPrec_AppendAlign(); CPrec_NewAddrPatch(type, p); CPrec_AppendData(type, (type->flags & FUNC_FLAGS_METHOD) ? sizeof(TypeMethod) : sizeof(TypeFunc)); CPrec_NewPointerPatch(&p->functype, CPrec_GetTypePatch(type->functype)); if (type->args) CPrec_NewPointerPatch(&p->args, CPrec_GetArgListPatch(type->args, (type->flags & FUNC_FLAGS_900000) != 0)); if (type->exspecs) CPrec_NewPointerPatch(&p->exspecs, CPrec_GetExceptSpecPatch(type->exspecs)); if (type->flags & FUNC_FLAGS_METHOD) CPrec_NewPointerPatch(&TYPE_METHOD(p)->theclass, CPrec_GetTypePatch((Type *) TYPE_METHOD(type)->theclass)); return p; } static TypeMemberPointer *CPrec_GetTypeMemberPointerPatch(TypeMemberPointer *type) { TypeMemberPointer *p = CPrec_AppendAlign(); CPrec_NewAddrPatch(type, p); CPrec_AppendData(type, sizeof(TypeMemberPointer)); CPrec_NewPointerPatch(&p->ty1, CPrec_GetTypePatch(type->ty1)); CPrec_NewPointerPatch(&p->ty2, CPrec_GetTypePatch(type->ty2)); return p; } static TypeTemplDep *CPrec_GetTypeTemplDepPatch(TypeTemplDep *type) { TypeTemplDep *p = CPrec_AppendAlign(); CPrec_NewAddrPatch(type, p); CPrec_AppendData(type, sizeof(TypeTemplDep)); switch (type->dtype) { case TEMPLDEP_ARGUMENT: break; case TEMPLDEP_QUALNAME: CPrec_NewPointerPatch(&p->u.qual.type, CPrec_GetTypeTemplDepPatch(type->u.qual.type)); CPrec_NamePatch(&p->u.qual.name, type->u.qual.name); break; case TEMPLDEP_TEMPLATE: CPrec_NewPointerPatch(&p->u.templ.templ, CPrec_GetTypePatch((Type *) type->u.templ.templ)); CPrec_NewPointerPatch(&p->u.templ.args, CPrec_GetTemplateArgPatch(type->u.templ.args)); break; case TEMPLDEP_ARRAY: CPrec_NewPointerPatch(&p->u.array.type, CPrec_GetTypePatch(type->u.array.type)); CPrec_NewPointerPatch(&p->u.array.index, CPrec_GetExpressionPatch(type->u.array.index)); break; case TEMPLDEP_QUALTEMPL: CPrec_NewPointerPatch(&p->u.qualtempl.type, CPrec_GetTypeTemplDepPatch(type->u.qualtempl.type)); CPrec_NewPointerPatch(&p->u.qualtempl.args, CPrec_GetTemplateArgPatch(type->u.qualtempl.args)); break; case TEMPLDEP_BITFIELD: CPrec_NewPointerPatch(&p->u.bitfield.type, CPrec_GetTypePatch(type->u.bitfield.type)); CPrec_NewPointerPatch(&p->u.bitfield.size, CPrec_GetExpressionPatch(type->u.bitfield.size)); break; default: #line 1295 CError_FATAL(); } return p; } static ClassList *CPrec_GetClassListPatch(ClassList *cl) { AddrPatch *addrPatch; ClassList *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(cl))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(cl, first); do { CPrec_AppendData(cl, sizeof(ClassList)); CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) cl->base)); if (!cl->next) break; if ((addrPatch = CPrec_FindAddrPatch(cl->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; cl = cl->next; } } while (1); return first; } static VClassList *CPrec_GetVClassListPatch(VClassList *vcl) { VClassList *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(vcl, sizeof(VClassList)); CPrec_NewPointerPatch(¤t->base, CPrec_GetTypePatch((Type *) vcl->base)); if (!vcl->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; vcl = vcl->next; } while (1); return first; } static ClassFriend *CPrec_GetClassFriendPatch(ClassFriend *cf) { ClassFriend *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(cf, sizeof(ClassFriend)); if (cf->isclass) CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetTypePatch((Type *) cf->u.theclass)); else CPrec_NewPointerPatch(¤t->u.theclass, CPrec_GetObjectPatch(cf->u.obj)); if (!cf->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; cf = cf->next; } while (1); return first; } static BClassList *CPrec_GetBClassListPatch(BClassList *bcl) { BClassList *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(bcl, sizeof(BClassList)); CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch((Type *) bcl->type)); if (!bcl->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; bcl = bcl->next; } while (1); return first; } static VTable *CPrec_GetVTablePatch(VTable *vtbl) { VTable *p = CPrec_AppendAlign(); CPrec_AppendData(vtbl, sizeof(VTable)); if (vtbl->object) CPrec_NewPointerPatch(&p->object, CPrec_GetObjectPatch(vtbl->object)); if (vtbl->owner) CPrec_NewPointerPatch(&p->owner, CPrec_GetTypePatch((Type *) vtbl->owner)); return p; } static SOMReleaseOrder *CPrec_GetSOMReleaseOrderPatch(SOMReleaseOrder *sro) { SOMReleaseOrder *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(sro, sizeof(SOMReleaseOrder)); CPrec_NamePatch(¤t->name, sro->name); if (!sro->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; sro = sro->next; } while (1); return first; } static SOMInfo *CPrec_GetSOMInfoPatch(SOMInfo *som) { SOMInfo *p = CPrec_AppendAlign(); CPrec_AppendData(som, sizeof(SOMInfo)); if (som->metaclass) CPrec_NewPointerPatch(&p->metaclass, CPrec_GetTypePatch((Type *) som->metaclass)); if (som->classdataobject) CPrec_NewPointerPatch(&p->classdataobject, CPrec_GetObjectPatch(som->classdataobject)); if (som->order) CPrec_NewPointerPatch(&p->order, CPrec_GetSOMReleaseOrderPatch(som->order)); return p; } static ObjCMethodArg *CPrec_GetObjCMethodArgPatch(ObjCMethodArg *arg) { ObjCMethodArg *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(arg, sizeof(ObjCMethodArg)); if (arg->selector) CPrec_NamePatch(¤t->selector, arg->selector); if (arg->name) CPrec_NamePatch(¤t->name, arg->name); if (arg->type) CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(arg->type)); if (!arg->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; arg = arg->next; } while (1); return first; } static ObjCMethodList *CPrec_GetObjCMethodListPatch(ObjCMethodList *lst) { AddrPatch *addrPatch; ObjCMethodList *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(lst))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(lst, first); do { CPrec_AppendData(lst, sizeof(ObjCMethodList)); if (lst->method) CPrec_NewPointerPatch(¤t->method, CPrec_GetObjCMethodPatch(lst->method)); if (!lst->next) break; if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; lst = lst->next; CPrec_NewAddrPatch(lst, next); } } while (1); return first; } static ObjCSelector *CPrec_GetObjCSelectorPatch(ObjCSelector *sel) { AddrPatch *addrPatch; ObjCSelector *current, *first, *next; if ((addrPatch = CPrec_FindAddrPatch(sel))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(sel, first); do { CPrec_AppendData(sel, sizeof(ObjCSelector)); if (sel->selobject) CPrec_NewPointerPatch(¤t->selobject, CPrec_GetObjectPatch(sel->selobject)); CPrec_NamePatch(¤t->name, sel->name); if (sel->methods) CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodListPatch(sel->methods)); if (!sel->next) break; if ((addrPatch = CPrec_FindAddrPatch(sel->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; sel = sel->next; CPrec_NewAddrPatch(sel, next); } } while (1); return first; } static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth) { // does not match - affected by weirdness where the arg goes into r31 instead of r28 AddrPatch *addrPatch; ObjCMethod *current, *first, *next; if ((addrPatch = CPrec_FindAddrPatch(meth))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(meth, first); do { CPrec_AppendData(meth, sizeof(ObjCMethod)); if (meth->object) CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(meth->object)); if (meth->functype) CPrec_NewPointerPatch(¤t->functype, CPrec_GetTypePatch((Type *) meth->functype)); if (meth->selector) CPrec_NewPointerPatch(¤t->selector, CPrec_GetObjCSelectorPatch(meth->selector)); if (meth->return_type) CPrec_NewPointerPatch(¤t->return_type, CPrec_GetTypePatch(meth->return_type)); if (meth->selector_args) CPrec_NewPointerPatch(¤t->selector_args, CPrec_GetObjCMethodArgPatch(meth->selector_args)); if (!meth->next) break; if ((addrPatch = CPrec_FindAddrPatch(meth->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; meth = meth->next; CPrec_NewAddrPatch(meth, next); } } while (1); return first; } static ObjCProtocol *CPrec_GetObjCProtocolPatch(ObjCProtocol *prot) { AddrPatch *addrPatch; ObjCProtocol *current, *first, *next; if ((addrPatch = CPrec_FindAddrPatch(prot))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(prot, first); do { CPrec_AppendData(prot, sizeof(ObjCProtocol)); CPrec_NamePatch(¤t->name, prot->name); if (prot->protocols) CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(prot->protocols)); if (prot->methods) CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(prot->methods)); if (prot->object) CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(prot->object)); if (!prot->next) break; if ((addrPatch = CPrec_FindAddrPatch(prot->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; prot = prot->next; CPrec_NewAddrPatch(prot, next); } } while (1); return first; } static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst) { AddrPatch *addrPatch; ObjCProtocolList *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(lst))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(lst, first); do { CPrec_AppendData(lst, sizeof(ObjCProtocolList)); CPrec_NewPointerPatch(¤t->protocol, CPrec_GetObjCProtocolPatch(lst->protocol)); if (!lst->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; lst = lst->next; } while (1); return first; } static ObjCCategory *CPrec_GetObjCCategoryPatch(ObjCCategory *cat) { AddrPatch *addrPatch; ObjCCategory *current, *first, *next; if ((addrPatch = CPrec_FindAddrPatch(cat))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(cat, first); do { CPrec_AppendData(cat, sizeof(ObjCCategory)); CPrec_NamePatch(¤t->name, cat->name); if (cat->protocols) CPrec_NewPointerPatch(¤t->protocols, CPrec_GetObjCProtocolListPatch(cat->protocols)); if (cat->methods) CPrec_NewPointerPatch(¤t->methods, CPrec_GetObjCMethodPatch(cat->methods)); if (!cat->next) break; if ((addrPatch = CPrec_FindAddrPatch(cat->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; cat = cat->next; CPrec_NewAddrPatch(cat, next); } } while (1); return first; } static ObjCInfo *CPrec_GetObjCInfoPatch(ObjCInfo *info) { ObjCInfo *p = CPrec_AppendAlign(); CPrec_AppendData(info, sizeof(ObjCInfo)); if (info->classobject) CPrec_NewPointerPatch(&p->classobject, CPrec_GetObjectPatch(info->classobject)); if (info->metaobject) CPrec_NewPointerPatch(&p->metaobject, CPrec_GetObjectPatch(info->metaobject)); if (info->classrefobj) CPrec_NewPointerPatch(&p->classrefobj, CPrec_GetObjectPatch(info->classrefobj)); if (info->methods) CPrec_NewPointerPatch(&p->methods, CPrec_GetObjCMethodPatch(info->methods)); if (info->protocols) CPrec_NewPointerPatch(&p->protocols, CPrec_GetObjCProtocolListPatch(info->protocols)); if (info->categories) CPrec_NewPointerPatch(&p->categories, CPrec_GetObjCCategoryPatch(info->categories)); return p; } static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg) { TemplArg *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(arg, sizeof(TemplArg)); switch (arg->pid.type) { case TPT_TYPE: if (arg->data.typeparam.type) CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(arg->data.typeparam.type)); break; case TPT_NONTYPE: if (arg->data.paramdecl.expr) CPrec_NewPointerPatch(¤t->data.paramdecl.expr, CPrec_GetExpressionPatch(arg->data.paramdecl.expr)); break; case TPT_TEMPLATE: if (arg->data.ttargtype) CPrec_NewPointerPatch(¤t->data.ttargtype, CPrec_GetTypePatch(arg->data.ttargtype)); break; default: #line 1879 CError_FATAL(); } if (!arg->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; arg = arg->next; } while (1); return first; } static TemplParam *CPrec_GetTemplateParamPatch(TemplParam *param) { // register swap issues TemplParam *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(param, sizeof(TemplParam)); if (param->name) CPrec_NamePatch(¤t->name, param->name); switch (param->pid.type) { case TPT_TYPE: if (param->data.typeparam.type) CPrec_NewPointerPatch(¤t->data.typeparam.type, CPrec_GetTypePatch(param->data.typeparam.type)); break; case TPT_NONTYPE: CPrec_NewPointerPatch(¤t->data.paramdecl.type, CPrec_GetTypePatch(param->data.paramdecl.type)); if (param->data.paramdecl.defaultarg) CPrec_NewPointerPatch(¤t->data.paramdecl.defaultarg, CPrec_GetExpressionPatch(param->data.paramdecl.defaultarg)); break; case TPT_TEMPLATE: if (param->data.templparam.plist) CPrec_NewPointerPatch(¤t->data.templparam.plist, CPrec_GetTemplateParamPatch(param->data.templparam.plist)); #line 1953 CError_ASSERT(!param->data.templparam.defaultarg); break; default: #line 1958 CError_FATAL(); } if (!param->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; param = param->next; } while (1); return first; } static TStreamElement *CPrec_GetTStreamPatch(TStreamElement *tokens, SInt32 count) { TStreamElement elem; TStreamElement *first, *current, *scan; SInt32 x; scan = tokens; x = 0; while (x < count) { elem = *scan; memclrw(scan, sizeof(TStreamElement)); scan->tokentype = elem.tokentype; switch (elem.tokentype) { case TK_IDENTIFIER: scan->data.tkidentifier = elem.data.tkidentifier; break; case TK_INTCONST: scan->subtype = elem.subtype; scan->data.tkintconst = elem.data.tkintconst; break; case TK_FLOATCONST: scan->subtype = elem.subtype; scan->data.tkfloatconst = elem.data.tkfloatconst; break; case TK_STRING: case TK_STRING_WIDE: scan->subtype = elem.subtype; scan->data.tkstring = elem.data.tkstring; break; } x++; scan++; } first = current = CPrec_AppendAlign(); CPrec_AppendData(tokens, count * sizeof(TStreamElement)); if (cprec_dowrite) { TokenPatch *tp = lalloc(sizeof(TokenPatch)); tp->tokens = current; tp->count = count; tp->next = cprec_tokenpatches; cprec_tokenpatches = tp; } x = 0; while (x < count) { switch (tokens->tokentype) { case TK_IDENTIFIER: CPrec_NamePatch(¤t->data.tkidentifier, tokens->data.tkidentifier); break; case TK_INTCONST: case TK_FLOATCONST: break; case TK_STRING: case TK_STRING_WIDE: CPrec_RawMemPatch(¤t->data.tkstring.data, tokens->data.tkstring.data, tokens->data.tkstring.size); break; case TK_NEG7: break; default: if (tokens->tokentype < 0) #line 2063 CError_FATAL(); } x++; tokens++; current++; } return first; } static TemplFuncInstance *CPrec_GetTemplFuncInstancePatch(TemplFuncInstance *inst) { AddrPatch *addrPatch; TemplFuncInstance *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(inst))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(inst, first); do { CPrec_AppendData(inst, sizeof(TemplFuncInstance)); CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(inst->object)); CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(inst->args)); if (!inst->next) break; if ((addrPatch = CPrec_FindAddrPatch(inst->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; inst = inst->next; CPrec_NewAddrPatch(inst, next); } } while (1); return first; } static TemplateMember *CPrec_GetTemplateMemberPatch(TemplateMember *memb) { TemplateMember *current, *first, *next; first = current = CPrec_AppendAlign(); do { memclrw(&memb->fileoffset, sizeof(FileOffsetInfo)); memb->srcfile = NULL; memb->startoffset = 0; memb->endoffset = 0; CPrec_AppendData(memb, sizeof(TemplateMember)); if (memb->params) CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(memb->params)); CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(memb->object)); if (memb->stream.firsttoken) CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(memb->stream.firsttoken, memb->stream.tokens)); if (!memb->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; memb = memb->next; } while (1); return first; } static TemplPartialSpec *CPrec_GetTemplPartialSpecPatch(TemplPartialSpec *pspec) { TemplPartialSpec *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(pspec, sizeof(TemplPartialSpec)); if (pspec->templ) CPrec_NewPointerPatch(¤t->templ, CPrec_GetTypePatch((Type *) pspec->templ)); if (pspec->args) CPrec_NewPointerPatch(¤t->args, CPrec_GetTemplateArgPatch(pspec->args)); if (!pspec->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; pspec = pspec->next; } while (1); return first; } static TemplateFriend *CPrec_GetTemplateFriendPatch(TemplateFriend *frnd) { TemplateFriend *p; memclrw(&frnd->fileoffset, sizeof(FileOffsetInfo)); p = CPrec_AppendAlign(); CPrec_AppendData(frnd, sizeof(TemplateFriend)); if (frnd->decl.thetype) CPrec_NewPointerPatch(&p->decl.thetype, CPrec_GetTypePatch(frnd->decl.thetype)); if (frnd->decl.nspace) CPrec_NewPointerPatch(&p->decl.nspace, CPrec_GetNameSpacePatch(frnd->decl.nspace)); if (frnd->decl.name) CPrec_NamePatch(&p->decl.name, frnd->decl.name); if (frnd->decl.expltargs) CPrec_NewPointerPatch(&p->decl.expltargs, CPrec_GetTemplateArgPatch(frnd->decl.expltargs)); if (frnd->stream.firsttoken) CPrec_NewPointerPatch(&p->stream.firsttoken, CPrec_GetTStreamPatch(frnd->stream.firsttoken, frnd->stream.tokens)); return p; } static TemplateAction *CPrec_GetTemplateActionPatch(TemplateAction *act) { // register swap issue TemplateAction *current, *first, *next; first = current = CPrec_AppendAlign(); do { memclrw(&act->source_ref, sizeof(TStreamElement)); CPrec_AppendData(act, sizeof(TemplateAction)); switch (act->type) { case TAT_NESTEDCLASS: CPrec_NewPointerPatch(¤t->u.tclasstype, CPrec_GetTypePatch((Type *) act->u.tclasstype)); break; case TAT_ENUMTYPE: CPrec_NewPointerPatch(¤t->u.enumtype, CPrec_GetTypePatch((Type *) act->u.enumtype)); break; case TAT_FRIEND: CPrec_NewPointerPatch(¤t->u.tfriend, CPrec_GetTemplateFriendPatch(act->u.tfriend)); break; case TAT_ENUMERATOR: CPrec_NewPointerPatch(¤t->u.enumerator.objenumconst, CPrec_GetObjEnumConstPatch(act->u.enumerator.objenumconst)); if (act->u.enumerator.initexpr) CPrec_NewPointerPatch(¤t->u.enumerator.initexpr, CPrec_GetExpressionPatch(act->u.enumerator.initexpr)); break; case TAT_BASE: CPrec_NewPointerPatch(¤t->u.base.type, CPrec_GetTypePatch(act->u.base.type)); if (act->u.base.insert_after) CPrec_NewPointerPatch(¤t->u.base.insert_after, CPrec_GetClassListPatch(act->u.base.insert_after)); break; case TAT_OBJECTINIT: CPrec_NewPointerPatch(¤t->u.objectinit.object, CPrec_GetObjectPatch(act->u.objectinit.object)); CPrec_NewPointerPatch(¤t->u.objectinit.initexpr, CPrec_GetExpressionPatch(act->u.objectinit.initexpr)); break; case TAT_USINGDECL: CPrec_NewPointerPatch(¤t->u.usingdecl.type, CPrec_GetTypeTemplDepPatch(act->u.usingdecl.type)); break; case TAT_OBJECTDEF: CPrec_NewPointerPatch(¤t->u.refobj, CPrec_GetObjBasePatch(act->u.refobj)); break; default: #line 2410 CError_FATAL(); } if (!act->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; act = act->next; } while (1); return first; } static TemplateFunction *CPrec_GetTemplateFunctionPatch(TemplateFunction *tf) { // the same cursed register swaps AddrPatch *addrPatch; TemplateFunction *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(tf))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(tf, first); do { memclrw(&tf->deftoken, sizeof(TStreamElement)); tf->srcfile = NULL; tf->startoffset = 0; tf->endoffset = 0; CPrec_AppendData(tf, sizeof(TemplateFunction)); if (tf->unk4) CPrec_NewPointerPatch(¤t->unk4, CPrec_GetTemplateFunctionPatch(tf->unk4)); CPrec_NamePatch(¤t->name, tf->name); if (tf->params) CPrec_NewPointerPatch(¤t->params, CPrec_GetTemplateParamPatch(tf->params)); if (tf->stream.firsttoken) CPrec_NewPointerPatch(¤t->stream.firsttoken, CPrec_GetTStreamPatch(tf->stream.firsttoken, tf->stream.tokens)); CPrec_NewPointerPatch(¤t->tfunc, CPrec_GetObjectPatch(tf->tfunc)); if (tf->instances) CPrec_NewPointerPatch(¤t->instances, CPrec_GetTemplFuncInstancePatch(tf->instances)); if (!tf->next) break; if ((addrPatch = CPrec_FindAddrPatch(tf->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; tf = tf->next; CPrec_NewAddrPatch(tf, next); } } while (1); return first; } static TypeClass *CPrec_GetTypeClassPatch(TypeClass *tclass) { TypeClass *first, *current, *next; Boolean hasNextTempl, hasNextTemplInst; first = current = CPrec_AppendAlign(); do_over: hasNextTempl = hasNextTemplInst = 0; CPrec_NewAddrPatch(tclass, current); if (tclass->flags & CLASS_FLAGS_100) { // template class CPrec_AppendData(tclass, sizeof(TemplClass)); if (TEMPL_CLASS(tclass)->next) hasNextTempl = 1; if (TEMPL_CLASS(tclass)->templ_parent) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ_parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->templ_parent)); if (TEMPL_CLASS(tclass)->inst_parent) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->inst_parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->inst_parent)); if (TEMPL_CLASS(tclass)->templ__params) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->templ__params, CPrec_GetTemplateParamPatch(TEMPL_CLASS(tclass)->templ__params)); if (TEMPL_CLASS(tclass)->members) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->members, CPrec_GetTemplateMemberPatch(TEMPL_CLASS(tclass)->members)); if (TEMPL_CLASS(tclass)->instances) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->instances, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->instances)); if (TEMPL_CLASS(tclass)->pspec_owner) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspec_owner, CPrec_GetTypePatch((Type *) TEMPL_CLASS(tclass)->pspec_owner)); if (TEMPL_CLASS(tclass)->pspecs) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->pspecs, CPrec_GetTemplPartialSpecPatch(TEMPL_CLASS(tclass)->pspecs)); if (TEMPL_CLASS(tclass)->actions) CPrec_NewPointerPatch(&TEMPL_CLASS(current)->actions, CPrec_GetTemplateActionPatch(TEMPL_CLASS(tclass)->actions)); } else if (tclass->flags & CLASS_FLAGS_800) { // template class instance CPrec_AppendData(tclass, sizeof(TemplClassInst)); if (TEMPL_CLASS_INST(tclass)->next) hasNextTemplInst = 1; if (TEMPL_CLASS_INST(tclass)->parent) CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->parent, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->parent)); if (TEMPL_CLASS_INST(tclass)->templ) CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->templ, CPrec_GetTypePatch((Type *) TEMPL_CLASS_INST(tclass)->templ)); if (TEMPL_CLASS_INST(tclass)->inst_args) CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->inst_args, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->inst_args)); if (TEMPL_CLASS_INST(tclass)->oargs) CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->oargs, CPrec_GetTemplateArgPatch(TEMPL_CLASS_INST(tclass)->oargs)); } else { // base CPrec_AppendData(tclass, sizeof(TypeClass)); } if (tclass->nspace) CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(tclass->nspace)); if (tclass->classname) CPrec_NamePatch(¤t->classname, tclass->classname); if (tclass->bases) CPrec_NewPointerPatch(¤t->bases, CPrec_GetClassListPatch(tclass->bases)); if (tclass->vbases) CPrec_NewPointerPatch(¤t->vbases, CPrec_GetVClassListPatch(tclass->vbases)); if (tclass->ivars) CPrec_NewPointerPatch(¤t->ivars, CPrec_GetObjMemberVarPatch(tclass->ivars)); if (tclass->friends) CPrec_NewPointerPatch(¤t->friends, CPrec_GetClassFriendPatch(tclass->friends)); if (tclass->vtable) CPrec_NewPointerPatch(¤t->vtable, CPrec_GetVTablePatch(tclass->vtable)); if (tclass->sominfo) CPrec_NewPointerPatch(¤t->sominfo, CPrec_GetSOMInfoPatch(tclass->sominfo)); if (tclass->objcinfo) CPrec_NewPointerPatch(¤t->objcinfo, CPrec_GetObjCInfoPatch(tclass->objcinfo)); if (hasNextTempl) { AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS(tclass)->next); if (!addrPatch) { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, next); current = next; tclass = (TypeClass *) TEMPL_CLASS(tclass)->next; goto do_over; } else { CPrec_NewPointerPatch(&TEMPL_CLASS(current)->next, addrPatch->value); } } if (hasNextTemplInst) { AddrPatch *addrPatch = CPrec_FindAddrPatch(TEMPL_CLASS_INST(tclass)->next); if (!addrPatch) { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, next); current = next; tclass = (TypeClass *) TEMPL_CLASS_INST(tclass)->next; goto do_over; } else { CPrec_NewPointerPatch(&TEMPL_CLASS_INST(current)->next, addrPatch->value); } } return first; } static Type *CPrec_GetTypePatch(Type *type) { AddrPatch *addrPatch = CPrec_FindAddrPatch(type); if (addrPatch) return addrPatch->value; switch (type->type) { case TYPEPOINTER: case TYPEARRAY: return (Type *) CPrec_GetTypePointerPatch(TYPE_POINTER(type)); case TYPEENUM: return (Type *) CPrec_GetTypeEnumPatch(TYPE_ENUM(type)); case TYPEBITFIELD: return (Type *) CPrec_GetTypeBitfieldPatch(TYPE_BITFIELD(type)); case TYPESTRUCT: return (Type *) CPrec_GetTypeStructPatch(TYPE_STRUCT(type)); case TYPEFUNC: return (Type *) CPrec_GetTypeFuncPatch(TYPE_FUNC(type)); case TYPEMEMBERPOINTER: return (Type *) CPrec_GetTypeMemberPointerPatch(TYPE_MEMBER_POINTER(type)); case TYPETEMPLATE: return (Type *) CPrec_GetTypeTemplDepPatch(TYPE_TEMPLATE(type)); case TYPECLASS: return (Type *) CPrec_GetTypeClassPatch(TYPE_CLASS(type)); case TYPEVOID: case TYPEINT: case TYPEFLOAT: case TYPELABEL: case TYPEOBJCID: case TYPETEMPLDEPEXPR: default: #line 2796 CError_FATAL(); return NULL; } } static ExceptionAction *CPrec_GetExceptionPatch(ExceptionAction *exc) { ExceptionAction *first, *current, *next; first = current = CPrec_AppendAlign(); repeat: CPrec_AppendData(exc, sizeof(ExceptionAction)); switch (exc->type) { case EAT_DESTROYLOCAL: CPrec_NewPointerPatch(¤t->data.destroy_local.dtor, CPrec_GetObjectPatch(exc->data.destroy_local.dtor)); break; case EAT_DESTROYLOCALCOND: CPrec_NewPointerPatch(¤t->data.destroy_local_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_cond.dtor)); break; case EAT_DESTROYLOCALOFFSET: CPrec_NewPointerPatch(¤t->data.destroy_local_offset.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_offset.dtor)); break; case EAT_DESTROYLOCALPOINTER: CPrec_NewPointerPatch(¤t->data.destroy_local_pointer.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_pointer.dtor)); break; case EAT_DESTROYLOCALARRAY: CPrec_NewPointerPatch(¤t->data.destroy_local_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_local_array.dtor)); break; case EAT_DESTROYPARTIALARRAY: break; case EAT_DESTROYMEMBER: case EAT_DESTROYBASE: CPrec_NewPointerPatch(¤t->data.destroy_member.dtor, CPrec_GetObjectPatch(exc->data.destroy_member.dtor)); break; case EAT_DESTROYMEMBERCOND: CPrec_NewPointerPatch(¤t->data.destroy_member_cond.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_cond.dtor)); break; case EAT_DESTROYMEMBERARRAY: CPrec_NewPointerPatch(¤t->data.destroy_member_array.dtor, CPrec_GetObjectPatch(exc->data.destroy_member_array.dtor)); break; case EAT_DELETEPOINTER: case EAT_DELETELOCALPOINTER: CPrec_NewPointerPatch(¤t->data.delete_pointer.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer.deletefunc)); break; case EAT_DELETEPOINTERCOND: CPrec_NewPointerPatch(¤t->data.delete_pointer_cond.deletefunc, CPrec_GetObjectPatch(exc->data.delete_pointer_cond.deletefunc)); break; case EAT_CATCHBLOCK: if (exc->data.catch_block.catch_typeid) { CPrec_NewPointerPatch(¤t->data.catch_block.catch_typeid, CPrec_GetObjectPatch(exc->data.catch_block.catch_typeid)); CPrec_NewPointerPatch(¤t->data.catch_block.catch_type, CPrec_GetTypePatch(exc->data.catch_block.catch_type)); } break; case EAT_ACTIVECATCHBLOCK: break; case EAT_SPECIFICATION: if (exc->data.specification.unexp_id) { int x; char *ptrs; ptrs = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->data.specification.unexp_id, ptrs); CPrec_AppendData(exc->data.specification.unexp_id, sizeof(Object *) * exc->data.specification.unexp_ids); for (x = 0; x < exc->data.specification.unexp_ids; x++) { CPrec_NewPointerPatch(ptrs + x * sizeof(Object *), CPrec_GetObjectPatch(exc->data.specification.unexp_id[x])); } } break; case EAT_TERMINATE: break; default: #line 2905 CError_FATAL(); } if (exc->prev) { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->prev, next); current = next; exc = exc->prev; goto repeat; } return first; } static ENodeList *CPrec_GetExpressionListPatch(ENodeList *lst) { ENodeList *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(lst, sizeof(ENodeList)); CPrec_NewPointerPatch(¤t->node, CPrec_GetExpressionPatch(lst->node)); if (!lst->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; lst = lst->next; } while (1); return first; } static void CPrec_GetEMemberInfoPatch() {} static ENode *CPrec_GetExpressionPatch(ENode *enode) { } static void CPrec_GetSwitchInfoPatch() {} static void CPrec_GetInlineAsmPatch() {} static void CPrec_GetStatementPatch() {} static void CPrec_GetLocObjectPatch() {} static void CPrec_GetInlineFuncPatch() {} static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj) { AddrPatch *addrPatch; ObjEnumConst *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(obj))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(obj, first); do { CPrec_AppendData(obj, sizeof(ObjEnumConst)); if (cprec_dowrite) { #line 3349 CError_ASSERT(obj->access != 255); obj->access = 255; } CPrec_NamePatch(¤t->name, obj->name); CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch( obj->type)); if (!obj->next) break; if ((addrPatch = CPrec_FindAddrPatch(obj->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; obj = obj->next; CPrec_NewAddrPatch(obj, next); } } while (1); return first; } static ObjType *CPrec_GetObjTypePatch(ObjType *obj) { AddrPatch *addrPatch; ObjType *p; if ((addrPatch = CPrec_FindAddrPatch(obj))) return addrPatch->value; p = CPrec_AppendAlign(); CPrec_NewAddrPatch(obj, p); CPrec_AppendData(obj, sizeof(ObjType)); CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); return p; } static ObjTypeTag *CPrec_GetObjTypeTagPatch(ObjTypeTag *obj) { AddrPatch *addrPatch; ObjTypeTag *p; if ((addrPatch = CPrec_FindAddrPatch(obj))) return addrPatch->value; p = CPrec_AppendAlign(); CPrec_NewAddrPatch(obj, p); CPrec_AppendData(obj, sizeof(ObjTypeTag)); CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); return p; } static ObjNameSpace *CPrec_GetObjNameSpacePatch(ObjNameSpace *obj) { AddrPatch *addrPatch; ObjNameSpace *p; if ((addrPatch = CPrec_FindAddrPatch(obj))) return addrPatch->value; p = CPrec_AppendAlign(); CPrec_NewAddrPatch(obj, p); CPrec_AppendData(obj, sizeof(ObjNameSpace)); CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(obj->nspace)); return p; } static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj) { } static DefArgCtorInfo *CPrec_GetDefArgCtorInfoPatch(DefArgCtorInfo *dac) { DefArgCtorInfo *p = CPrec_AppendAlign(); CPrec_AppendData(dac, sizeof(DefArgCtorInfo)); CPrec_NewPointerPatch(&p->default_func, CPrec_GetObjectPatch(dac->default_func)); CPrec_NewPointerPatch(&p->default_arg, CPrec_GetExpressionPatch(dac->default_arg)); return p; } static InlineXRef *CPrec_GetInlineXRefPatch(InlineXRef *ix) { InlineXRef *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(ix, sizeof(InlineXRef) + sizeof(XRefOffset) * (ix->numxrefs - 1)); CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ix->object)); if (!ix->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; ix = ix->next; } while (1); return first; } static Object *CPrec_GetObjectPatch(Object *o) { } static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj) { switch (obj->otype) { default: #line 3694 CError_FATAL(); case OT_ENUMCONST: return (ObjBase *) CPrec_GetObjEnumConstPatch((ObjEnumConst *) obj); case OT_TYPE: return (ObjBase *) CPrec_GetObjTypePatch((ObjType *) obj); case OT_TYPETAG: return (ObjBase *) CPrec_GetObjTypeTagPatch((ObjTypeTag *) obj); case OT_NAMESPACE: return (ObjBase *) CPrec_GetObjNameSpacePatch((ObjNameSpace *) obj); case OT_MEMBERVAR: return (ObjBase *) CPrec_GetObjMemberVarPatch((ObjMemberVar *) obj); case OT_OBJECT: return (ObjBase *) CPrec_GetObjectPatch((Object *) obj); } } static ObjectList *CPrec_GetObjectListPatch(ObjectList *ol) { AddrPatch *addrPatch; ObjectList *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(ol))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(ol, first); restart: CPrec_AppendData(ol, sizeof(ObjectList)); CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(ol->object)); if (ol->next) { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; ol = ol->next; goto restart; } return first; } static NameSpaceObjectList *CPrec_GetNameSpaceObjectListPatch(NameSpaceObjectList *nsol) { AddrPatch *addrPatch; NameSpaceObjectList *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(nsol))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(nsol, first); do { CPrec_AppendData(nsol, sizeof(NameSpaceObjectList)); CPrec_NewPointerPatch(¤t->object, CPrec_GetObjBasePatch(nsol->object)); if (!nsol->next) break; if ((addrPatch = CPrec_FindAddrPatch(nsol->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; nsol = nsol->next; CPrec_NewAddrPatch(nsol, next); } } while (1); return first; } static NameSpaceName *CPrec_GetNameSpaceNamePatch(NameSpaceName *nsn, Boolean flag) { AddrPatch *addrPatch; NameSpaceName *first, *current, *next; if ((addrPatch = CPrec_FindAddrPatch(nsn))) return addrPatch->value; first = current = CPrec_AppendAlign(); CPrec_NewAddrPatch(nsn, first); do { CPrec_AppendData(nsn, sizeof(NameSpaceName)); CPrec_NamePatch(¤t->name, nsn->name); CPrec_NewPointerPatch(¤t->first.object, CPrec_GetObjBasePatch(nsn->first.object)); if (nsn->first.next) CPrec_NewPointerPatch(¤t->first.next, CPrec_GetNameSpaceObjectListPatch(nsn->first.next)); if (!nsn->next) break; if ((addrPatch = CPrec_FindAddrPatch(nsn->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); break; } else { next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; nsn = nsn->next; CPrec_NewAddrPatch(nsn, next); } } while (!flag || !cprec_dowrite || CPrec_FlushBufferCheck() == noErr); return first; } static NameSpaceList *CPrec_GetNameSpaceListPatch(NameSpaceList *nsl) { NameSpaceList *first, *current, *next; first = current = CPrec_AppendAlign(); do { CPrec_AppendData(nsl, sizeof(NameSpaceList)); CPrec_NewPointerPatch(¤t->nspace, CPrec_GetNameSpacePatch(nsl->nspace)); if (!nsl->next) break; next = CPrec_AppendAlign(); CPrec_NewPointerPatch(¤t->next, next); current = next; nsl = nsl->next; } while (1); return first; } static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace) { NameSpace *p; AddrPatch *addrPatch; if ((addrPatch = CPrec_FindAddrPatch(nspace))) return addrPatch->value; p = CPrec_AppendAlign(); CPrec_NewAddrPatch(nspace, p); CPrec_AppendData(nspace, sizeof(NameSpace)); if (nspace->parent) CPrec_NewPointerPatch(&p->parent, CPrec_GetNameSpacePatch(nspace->parent)); if (nspace->name) CPrec_NamePatch(&p->name, nspace->name); if (nspace->usings) CPrec_NewPointerPatch(&p->usings, CPrec_GetNameSpaceListPatch(nspace->usings)); if (nspace->theclass) CPrec_NewPointerPatch(&p->theclass, CPrec_GetTypePatch((Type *) nspace->theclass)); if (nspace->is_hash) { char *hash; int i; hash = CPrec_AppendAlign(); CPrec_NewPointerPatch(&p->data.hash, hash); CPrec_AppendData(nspace->data.hash, sizeof(NameSpaceName *) * 1024); for (i = 0; i < 1024; i++) { if (nspace->data.hash[i]) CPrec_NewPointerPatch(hash + (i * sizeof(NameSpaceName *)), CPrec_GetNameSpaceNamePatch(nspace->data.hash[i], 0)); } } else if (nspace->data.list) { CPrec_NewPointerPatch(&p->data.list, CPrec_GetNameSpaceNamePatch(nspace->data.list, 0)); } return p; } static void CPrec_DumpRootNameSpace() {} static void CPrec_GetSOMPatch() {} static void CPrec_GetOLinkPatch() {} static void CPrec_GetStaticDataPatch() {} static void CPrec_GetCallbackPatch() {} static void CPrec_GetSelHashTablePatch() {} static void CPrec_GetIExpressionPatch() {} static void CPrec_GetInlineActionPatch() {} static void CPrec_GenerateBuiltinPatches() { int x; int y; Patch *scan; for (x = 0; x < cprec_builtins; x++) { y = 0; for (scan = cprec_builtin[x].patches; scan; scan = scan->next) ++y; if (y) { CPrec_AppendWord32(y); CPrec_AppendWord32(x); for (scan = cprec_builtin[x].patches; scan; scan = scan->next) CPrec_AppendWord32(scan->offset); } } CPrec_AppendWord32(0); } static void CPrec_GenerateTokenStreamPatches() { TokenPatch *scan; for (scan = cprec_tokenpatches; scan; scan = scan->next) { CPrec_AppendWord32((UInt32) scan->tokens); CPrec_AppendWord32((UInt32) scan->count); } CPrec_AppendWord32(0); } static OSErr CPrec_CompressWrite(const char *data, SInt32 size) { char buf[2048 + 256]; OSErr err; int bufpos = 0; int blockstart; int c; const char *p = data; const char *end = data + size; for (;;) { if (p < end) { if (!*p) { c = 224; while (!*p && p < end && c < 256) { c++; p++; } buf[bufpos++] = c - 1; } else { blockstart = bufpos++; c = 0; while (p < end && c < 224) { if (!p[0] && !p[1]) { break; } else { buf[bufpos++] = *(p++); c++; } } buf[blockstart] = c - 1; } } if (p >= end || bufpos > 2048) { if ((err = COS_FileWrite(cprec_refnum, buf, bufpos))) return err; if (p >= end) break; else bufpos = 0; } } return noErr; } static OSErr CPrec_FlushRawBuffer() { OSErr err; if (cprec_dowrite) { CPrec_AppendAlign(); cprec_zero_offset += cprec_glist.size; COS_LockHandle(cprec_glist.data); err = CPrec_CompressWrite(*cprec_glist.data, cprec_glist.size); COS_UnlockHandle(cprec_glist.data); cprec_glist.size = 0; return err; } else { return noErr; } } static OSErr CPrec_FlushBufferCheck() { static SInt32 flushmax; OSErr err; if (cprec_glist.size > flushmax) flushmax = cprec_glist.size; if (cprec_glist.size > 10000) { err = CPrec_FlushRawBuffer(); if (err) { cprec_ioerror = err; return err; } } return noErr; } static int CPrec_CompressPatches() { Patch *scan; int count; SInt32 last; cprec_glist.size = 0; scan = cprec_patch_list; last = 0; count = 0; while (scan) { #line 4339 CError_ASSERT((scan->offset & 0x80000001) == 0); if ((scan->offset - last) >= -128 && (scan->offset - last) <= 126) CPrec_AppendByte(((scan->offset - last) >> 1) | 0x80); else CPrec_AppendWord32(scan->offset); last = scan->offset; scan = scan->next; count++; } return count; } static void CPrec_DumpColorSymbolTable() {} static OSErr CPrec_FileAlign(short refnum, SInt32 *len) { OSErr err; SInt32 n; char buf[8]; n = *len; if ((n & 7) == 0) return noErr; memclrw(buf, 8); err = COS_FileWrite(refnum, buf, n = 8 - (n & 7)); *len += n; return err; } static void CPrec_WriteFile() {} void PrecompilerWrite() { } static void CPrec_ReadData() {} static void CPrec_ReadRawBuffer() {} static void CPrec_RelocateRawBuffer() {} static void CPrec_RelocateBuiltins() {} static void CPrec_RelocateTokenStreams() {} static void CPrec_RelocateMacroTable() {} static void CPrec_RelocateTable() {} static void CPrec_RelocateRootNameSpace() {} static void CPrec_FixNameIds() { int i; HashNameNode *node; for (i = 0; i < 2048; i++) { for (node = name_hash_nodes[i]; node; node = node->next) node->id = -1; } } static void CPrec_DefineStaticData() {} void PrecompilerRead(short refnum, void *buffer) { }