mirror of https://git.wuffs.org/MWCC
2143 lines
67 KiB
C
2143 lines
67 KiB
C
#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) {
|
|
}
|