diff options
Diffstat (limited to 'compiler_and_linker/unsorted/CSOM.c')
-rw-r--r-- | compiler_and_linker/unsorted/CSOM.c | 2069 |
1 files changed, 0 insertions, 2069 deletions
diff --git a/compiler_and_linker/unsorted/CSOM.c b/compiler_and_linker/unsorted/CSOM.c deleted file mode 100644 index afd68a3..0000000 --- a/compiler_and_linker/unsorted/CSOM.c +++ /dev/null @@ -1,2069 +0,0 @@ -#include "compiler/CSOM.h" -#include "compiler/CClass.h" -#include "compiler/CDecl.h" -#include "compiler/CError.h" -#include "compiler/CException.h" -#include "compiler/CExpr.h" -#include "compiler/CFunc.h" -#include "compiler/CInit.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CParser.h" -#include "compiler/CPrep.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CScope.h" -#include "compiler/CodeGen.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/types.h" -#include "cos.h" - -// all pointers have been converted to UInt32 for the sake of maintaining 32-bit compat - -typedef struct { - SInt32 zero; - /* struct somStaticClassInfo * */ UInt32 sci; - /* void * */ UInt32 instanceDataToken; - SInt32 reserved[3]; - /* void * */ UInt32 tokens[1]; -} somClassDataStructure; - -enum { - mtVirtualMethod = 0, - mtProcedure = 1, - mtNonStatic = 2, - mtEmpty = 3, - mtDToken = 4 -}; - -enum { - pdUByte = 0, - pdSByte = 1, - pdUHalf = 2, - pdSHalf = 3, - pdULong = 4, - pdSLong = 5, - pdVLong = 6, - pdVoid = 7, - pdSFlt = 8, - pdDFlt = 9, - pdLFlt = 10, - pdVSAgg = 11, - pdNPtr = 12, - pdLPtr = 13, - pdSAgg = 14, - pdLAgg = 15 -}; - -enum { - fgShortOrChars = 1, - fgShortFloats = 2, - fgAnyFloats = 4, - fgAnyNon4Bytes = 8 -}; - -enum { - cfSharedStrings = 1, - cfTempClass = 2, - cfProxyClass = 4, - cfClassAllocate = 0x100, - cfClassDeallocate = 0x200, - cfClassInit = 0x400, - cfClassUninit = 0x800 -}; - -typedef struct { - UInt32 majorVersion; - UInt32 minorVersion; - UInt32 flags; - UInt16 dataAlignment; - UInt16 classTokenCount; - UInt16 numDirectParents; - UInt16 numMetaClasses; - UInt16 numOverriddenAncestors; - UInt16 numMigratedMethods; - UInt16 numSelectInherited; - UInt16 numUnused; - UInt16 dummy2a[4]; -} somStaticClassCounts; - -typedef UInt8 somSlotUsage; -typedef UInt8 somSignatureInfo; -typedef UInt16 somOverrideData; -typedef UInt16 somMigratedMethods; -typedef UInt16 somSelectedInherited; -typedef UInt32 somParentVersions; - -typedef struct { - /* const char * */ UInt32 className; - UInt32 instanceDataSize; - /* const somParentVersions * */ UInt32 parentVersions; - /* const somSlotUsage * */ UInt32 ttSlotUsage; - /* const somSignatureInfo * */ UInt32 signatureInfo; - /* const char * */ UInt32 methodNames; - /* const somOverrideData * */ UInt32 overrideData; - /* const somMigratedMethods * */ UInt32 migratedMethods; - /* const somSelectedInherited * */ UInt32 selectedInherited; - /* const void * */ UInt32 unused; - /* const void * */ UInt32 dummy4b[4]; -} somStaticClassDescription; - -typedef struct somStaticClassInfo { - UInt32 layoutVersion; - /* somClassDataStructure * */ UInt32 tokenTable; - /* somMethodPtr * */ UInt32 overrideMethods; - /* somClassDataStructure ** */ UInt32 specifiedAncestry; - /* somOpaque */ UInt32 DLLDesignator; - /* somMethodPtr * */ UInt32 specialProcs; - /* somRuntimeClassInfo * */ UInt32 runtimeClassInfo; - SInt32 interesting; - /* somClassDataStructure ** */ UInt32 actualAncestry; - /* void * */ UInt32 extra[4]; - /* const somStaticClassCounts * */ UInt32 classCounts; - somStaticClassDescription classDescription; -} somStaticClassInfo; - -CSOMStub *csom_stubs; -static HashNameNode *csom_initname; -static HashNameNode *csom_uninitname; -static HashNameNode *csom_envname; -static HashNameNode *csom_selfname; - -static FuncArg SOMIDT_arg1 = { - NULL, - NULL, - NULL, - TYPE(&void_ptr), - 0, - 0, - 0, - 0 -}; - -static TypeFunc SOMIDT_type = { - TYPEFUNC, - 0, - &SOMIDT_arg1, - NULL, - TYPE(&void_ptr), - 0, - 0 -}; - -void CSOM_Setup(Boolean flag) { - if (!flag) - csom_stubs = NULL; - - csom_initname = GetHashNameNodeExport("somInit"); - csom_uninitname = GetHashNameNodeExport("somUninit"); - csom_envname = GetHashNameNodeExport("Environment"); - csom_selfname = GetHashNameNodeExport("__somself"); -} - -void CSOM_Cleanup(void) { - CSOMStub *stub; - - if (cparamblkptr->precompile != 1) { - for (stub = csom_stubs; stub; stub = stub->next) { - switch (stub->x10) { - case 0: - CodeGen_SOMStub(stub->object, rt_som_glue1, stub->tclass->sominfo->classdataobject, stub->offset); - break; - case 1: - CodeGen_SOMStub(stub->object, rt_som_glue2, stub->tclass->sominfo->classdataobject, stub->offset); - break; - case 2: - CodeGen_SOMStub(stub->object, rt_som_glue3, stub->tclass->sominfo->classdataobject, stub->offset); - break; - default: - CError_FATAL(132); - } - } - } -} - -static HashNameNode *CSOM_NameTranslate(HashNameNode *name) { - if (name == constructor_name_node) - name = csom_initname; - else if (name == destructor_name_node) - name = csom_uninitname; - return name; -} - -static Type *CSOM_FindClassType(HashNameNode *name) { - Type *type; - - type = CScope_GetTagType(cscope_current, name); - if (!type) { - CPrep_ErrorName(CErrorStr281, name->name); - type = &stvoid; - } - - return type; -} - -CW_INLINE UInt16 CSOM_GetTokenTableIndex(const Object *object) { - CError_ASSERT(173, IS_TYPE_METHOD(object->type)); - return TYPE_METHOD(object->type)->vtbl_index; -} - -static SInt32 CSOM_GetTokenOffset(Object *object) { - return 24 + 4 * CSOM_GetTokenTableIndex(object); -} - -typedef struct TypeSig { - UInt8 x0; - UInt8 x1; - UInt8 x2; -} TypeSig; - -static int CSOM_GetTypeSig(TypeSig *sig, Type *type, Boolean flag) { - if (type->size > 4) - sig->x1 |= fgAnyNon4Bytes; - - switch (type->type) { - case TYPEVOID: - if (flag) - return pdVoid; - break; - case TYPEINT: - case TYPEENUM: - if (is_unsigned(type)) { - switch (type->size) { - case 1: - sig->x1 |= fgShortOrChars; - return pdUByte; - case 2: - sig->x1 |= fgShortOrChars; - return pdUHalf; - case 4: - return pdULong; - case 8: - return pdVLong; - } - } else { - switch (type->size) { - case 1: - sig->x1 |= fgShortOrChars; - return pdSByte; - case 2: - sig->x1 |= fgShortOrChars; - return pdSHalf; - case 4: - return pdSLong; - case 8: - return pdVLong; - } - } - break; - case TYPEFLOAT: - sig->x1 |= fgAnyFloats; - switch (type->size) { - case 4: - sig->x1 |= fgShortFloats; - return pdSFlt; - case 8: - return pdDFlt; - case 12: - case 16: - return pdLFlt; - } - break; - case TYPEPOINTER: - return pdNPtr; - case TYPESTRUCT: - case TYPECLASS: - if (flag) { - if (type->size <= 2) { - sig->x1 |= fgShortOrChars; - return pdVSAgg; - } else if (type->size <= 4) { - return pdSAgg; - } else { - return pdLAgg; - } - } - break; - } - - CError_Error(CErrorStr273); - return 5; -} - -static void CSOM_GetFuncSig(TypeFunc *tfunc, Boolean flag) { - FuncArg *arg; - Boolean pendingData; - UInt8 work; - TypeSig sig; - - sig.x2 = CSOM_GetTypeSig(&sig, tfunc->functype, 1); - sig.x1 = 0; - sig.x0 = 0; - - for (arg = tfunc->args; arg; arg = arg->next) { - if (arg == &elipsis || arg == &oldstyle || (++sig.x0 == 0)) { - CError_Error(CErrorStr273); - break; - } - - CSOM_GetTypeSig(&sig, arg->type, 0); - } - - if (flag) { - if ((arg = tfunc->args)) { - if (TYPE_METHOD(tfunc)->is_static == 0) - arg = arg->next; - if (arg && CMach_GetFunctionResultClass(tfunc) != 0) - arg = arg->next; - } - - AppendGListByte(&name_mangle_list, sig.x0); - AppendGListByte(&name_mangle_list, (sig.x1 << 4) | sig.x2); - if (sig.x1) { - pendingData = 0; - work = 0; - while (arg) { - work = (work << 4) | CSOM_GetTypeSig(&sig, arg->type, 0); - if (pendingData) { - AppendGListByte(&name_mangle_list, work); - pendingData = 0; - work = 0; - } else { - pendingData = 1; - } - arg = arg->next; - } - - if (pendingData) - AppendGListByte(&name_mangle_list, work << 4); - } - } -} - -void CSOM_CheckFuncType(TypeFunc *tfunc) { - CSOM_GetFuncSig(tfunc, 0); -} - -static Object *CSOM_MakeObject(char *name1, char *name2, SInt32 size) { - Object *object = CParser_NewCompilerDefDataObject(); - object->name = CParser_NameConcat(name1, name2); - object->type = CDecl_NewStructType(size, 4); - CScope_AddObject(object->nspace, object->name, OBJ_BASE(object)); - return object; -} - -void CSOM_MakeSOMClass(TypeClass *tclass) { - ClassList *base; - - for (base = tclass->bases; base; base = base->next) { - if (!base->base->sominfo) { - CError_Error(CErrorStr267); - break; - } - } - - if (!tclass->sominfo) { - SOMInfo *info = galloc(sizeof(SOMInfo)); - memclrw(info, sizeof(SOMInfo)); - tclass->sominfo = info; - - info->classdataobject = CSOM_MakeObject(tclass->classname->name, "ClassData", 28); - info->classdataobject->flags = info->classdataobject->flags | OBJECT_EXPORT; - } -} - -static Boolean CSOM_IsTokenListFunc(Object *object) { - Type *type = object->type; - if ( - IS_TYPE_FUNC(type) && - !(TYPE_FUNC(type)->flags & FUNC_FLAGS_20) && - !TYPE_METHOD(type)->is_static && - (!(object->qual & Q_INLINE) || object->datatype == DVFUNC) - ) - return 1; - - return 0; -} - -static Object **CSOM_GetLexicalOrderMethodArray(TypeClass *tclass, int *resultCount) { - Object *object; - int count; - Object **array; - CScopeObjectIterator iter; - - count = 0; - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (IS_TYPE_METHOD(object->type)) { - if (CSOM_IsTokenListFunc(object)) { - if (TYPE_METHOD(object->type)->vtbl_index > count) - count = TYPE_METHOD(object->type)->vtbl_index; - } else { - TYPE_METHOD(object->type)->vtbl_index = 0; - } - } - } - - *resultCount = ++count; - - array = lalloc(sizeof(Object *) * count); - memclrw(array, sizeof(Object *) * count); - - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (CSOM_IsTokenListFunc(object)) - array[TYPE_METHOD(object->type)->vtbl_index] = object; - } - - return array; -} - -void CSOM_ClassComplete(TypeClass *tclass) { - Object *object; - CScopeObjectIterator iter; - SInt32 counter; - SOMReleaseOrder *order; - - if (tclass->sominfo->order) { - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (CSOM_IsTokenListFunc(object)) { - HashNameNode *name; - - name = CSOM_NameTranslate(object->name); - for (order = tclass->sominfo->order, counter = 0; order; order = order->next, counter++) { - if (order->name == name) { - order->state = SOMMS_Method; - TYPE_METHOD(object->type)->vtbl_index = counter; - break; - } - } - - if (!order) - CError_Error(CErrorStr278, object); - } - } - - for (order = tclass->sominfo->order; order; order = order->next) { - if (order->state == SOMMS_Deleted) { - SOMReleaseOrder *order2; - VClassList *vbase; - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - for (order2 = vbase->base->sominfo->order; order2; order2 = order2->next) { - if (order->name == order2->name && order2->state == SOMMS_Method) { - order->state = SOMMS_Migrated; - break; - } - } - } - } - } - } else { - Object **array; - int arrayCount; - SInt32 i; - - array = CSOM_GetLexicalOrderMethodArray(tclass, &arrayCount); - for (i = counter = 0; i < arrayCount; i++) { - object = array[i]; - if (object) { - if (counter == 0 && copts.pedantic) - CError_Warning(CErrorStr291); - TYPE_METHOD(object->type)->vtbl_index = counter++; - } - } - } - - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - NameSpaceObjectList *nsol; - if (!(nsol = CScope_NextObjectIteratorObjectList(&iter))) - break; - - if (nsol->object->otype == OT_OBJECT && nsol->next && nsol->next->object->otype == OT_OBJECT) { - while (nsol) { - if ( - nsol->object->otype == OT_OBJECT && - (!(OBJECT(nsol->object)->qual & Q_INLINE) || OBJECT(nsol->object)->datatype == DVFUNC) - ) - CError_Error(CErrorStr270, nsol->object); - nsol = nsol->next; - } - } - } - - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (!(object->qual & Q_INLINE)) { - CError_ASSERT(529, IS_TYPE_FUNC(object->type)); - - TYPE_FUNC(object->type)->flags |= FUNC_FLAGS_4; - tclass->action = CLASS_ACTION_1; - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (IS_TYPE_FUNC(object->type)) - TYPE_FUNC(object->type)->flags &= ~FUNC_FLAGS_4; - } - break; - } - } - - if (tclass->sominfo->oidl_callstyle == 0) { - Type *envType; - envType = CSOM_FindClassType(csom_envname); - - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if ( - IS_TYPE_FUNC(object->type) && - TYPE_METHOD(object->type)->is_static == 0 && - !(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_20) && - !( - TYPE_FUNC(object->type)->args && - TYPE_FUNC(object->type)->args->next && - IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->args->next->type) && - TPTR_TARGET(TYPE_FUNC(object->type)->args->next->type) == envType - ) - ) - { - CError_Error(CErrorStr282, object); - } - } - } - - if (tclass->action == CLASS_ACTION_0) - CError_Error(CErrorStr280); -} - -#ifdef __MWERKS__ -#pragma options align=mac68k -#endif -typedef struct SOMOverride { - struct SOMOverride *next; - Object *a; - Object *b; -} SOMOverride; - -typedef struct SOMAncestor { - struct SOMAncestor *next; - TypeClass *tclass; - SOMOverride *overrides; - Boolean xC; - Boolean xD; -} SOMAncestor; - -typedef struct SOMMethod { - struct SOMMethod *next; - HashNameNode *name; - union { - Object *object; - struct { - UInt16 a; - UInt16 b; - } pair; - } u; - SOMMethodState state; -} SOMMethod; - -typedef struct SOMGenerator { - SOMMethod *methods; - SOMAncestor *ancestors; - Object *sciObj; - Object *classAncestorsObj; - Object *overrideProcsObj; - Object *dlldFunc; - Object *specialProcsObj; - somStaticClassCounts counts; - int overrideProcsCount; - Boolean hasNew; - Boolean hasDelete; -} SOMGenerator; -#ifdef __MWERKS__ -#pragma options align=reset -#endif - -static SOMAncestor *CSOM_FindAddAncestor(SOMGenerator *gen, TypeClass *tclass, TypeClass *ancestorClass, UInt16 *resultIndex) { - SOMAncestor *ancestor; - SOMAncestor *scan; - UInt16 index; - - ancestor = gen->ancestors; - for (scan = ancestor, index = 0; scan; scan = scan->next, index++) { - if (scan->tclass == ancestorClass) { - if (resultIndex) - *resultIndex = index; - return scan; - } - } - - if (ancestor) { - index = 1; - while (ancestor->next) { - index++; - ancestor = ancestor->next; - } - - ancestor->next = lalloc(sizeof(SOMAncestor)); - memclrw(ancestor->next, sizeof(SOMAncestor)); - ancestor = ancestor->next; - } else { - index = 0; - ancestor = lalloc(sizeof(SOMAncestor)); - memclrw(ancestor, sizeof(SOMAncestor)); - gen->ancestors = ancestor; - } - - ancestor->tclass = ancestorClass; - if (resultIndex) - *resultIndex = index; - return ancestor; -} - -static void CSOM_GenerateOverrideIntroLists(SOMGenerator *gen, TypeClass *tclass) { - Object *object; - VClassList *vbase; - ClassList *base; - SOMMethod *method; - SOMMethod **ptr; - CScopeObjectIterator iter; - - for (base = tclass->bases; base; base = base->next) { - SOMAncestor *ancestor = CSOM_FindAddAncestor(gen, tclass, base->base, NULL); - ancestor->xD = 1; - gen->counts.numDirectParents++; - } - - if (tclass->sominfo->metaclass && tclass->sominfo->metaclass->sominfo) { - SOMAncestor *ancestor = CSOM_FindAddAncestor(gen, tclass, tclass->sominfo->metaclass, NULL); - ancestor->xC = 1; - gen->counts.numMetaClasses++; - } - - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (IS_TYPE_FUNC(object->type) && (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_20)) { - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - Object *object2; - CScopeObjectIterator iter2; - CScope_InitObjectIterator(&iter2, vbase->base->nspace); - while (1) { - if (!(object2 = OBJECT(CScope_NextObjectIteratorObject(&iter2)))) - break; - - if ( - IS_TYPE_FUNC(object2->type) && - object->name == object2->name && - object2->datatype == DVFUNC && - !(TYPE_FUNC(object2->type)->flags & FUNC_FLAGS_20) && - CClass_GetOverrideKind(TYPE_FUNC(object->type), TYPE_FUNC(object2->type), 0) != 0 - ) - { - SOMAncestor *ancestor; - SOMOverride *override; - ancestor = CSOM_FindAddAncestor(gen, tclass, vbase->base, NULL); - if (ancestor->overrides) { - override = lalloc(sizeof(SOMOverride)); - memclrw(override, sizeof(SOMOverride)); - override->next = ancestor->overrides; - ancestor->overrides = override; - } else { - override = lalloc(sizeof(SOMOverride)); - memclrw(override, sizeof(SOMOverride)); - ancestor->overrides = override; - gen->counts.numOverriddenAncestors++; - } - override->a = object; - override->b = object2; - break; - } - } - } - gen->overrideProcsCount++; - } - } - - ptr = &gen->methods; - if (tclass->sominfo->order) { - SOMReleaseOrder *order; - SOMReleaseOrder *order2; - SInt32 index; - UInt16 index2; - - for (order = tclass->sominfo->order, index = 0; order; order = order->next, index++) { - method = lalloc(sizeof(SOMMethod)); - memclrw(method, sizeof(SOMMethod)); - *ptr = method; - ptr = &method->next; - - method->name = order->name; - method->state = order->state; - switch (order->state) { - case SOMMS_Migrated: - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - for (order2 = vbase->base->sominfo->order, index2 = 0; order2; order2 = order2->next, index2++) { - if (order->name == order2->name && order2->state == SOMMS_Method) { - CSOM_FindAddAncestor(gen, tclass, vbase->base, &method->u.pair.a); - method->u.pair.b = index2; - break; - } - } - - if (order2) - break; - } - gen->counts.numMigratedMethods++; - break; - - case SOMMS_Method: - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if ( - IS_TYPE_FUNC(object->type) && - CSOM_NameTranslate(object->name) == order->name - ) - { - CError_ASSERT(733, TYPE_METHOD(object->type)->vtbl_index == index); - method->u.object = object; - break; - } - } - - CError_ASSERT(737, object != NULL); - break; - } - - gen->counts.classTokenCount++; - } - } else { - Object **array; - int arrayCount; - SInt32 i; - - array = CSOM_GetLexicalOrderMethodArray(tclass, &arrayCount); - for (i = 0; i < arrayCount; i++) { - object = array[i]; - if (object) { - method = lalloc(sizeof(SOMMethod)); - memclrw(method, sizeof(SOMMethod)); - *ptr = method; - ptr = &method->next; - - method->u.object = object; - method->name = object->name; - method->state = SOMMS_Method; - gen->counts.classTokenCount++; - } - } - } -} - -static void CSOM_GenerateClassAncestors(SOMGenerator *gen, TypeClass *tclass) { - SOMAncestor *ancestor; - Object *object; - OLinkList *relocs; - SInt32 size; - char *buf; - - if (gen->ancestors) { - object = CSOM_MakeObject(tclass->classname->name, "ClassAncestors", 4); - object->sclass = TK_STATIC; - - relocs = NULL; - size = 0; - for (ancestor = gen->ancestors; ancestor; ancestor = ancestor->next) { - OLinkList *reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = ancestor->tclass->sominfo->classdataobject; - reloc->offset = size; - reloc->somevalue = 0; - size += 4; - } - - buf = lalloc(size); - memclrw(buf, size); - object->type->size = size; - CInit_DeclareData(object, buf, relocs, object->type->size); - gen->classAncestorsObj = object; - } -} - -static void CSOM_GenerateOverrideProcs(SOMGenerator *gen, TypeClass *tclass) { - SOMOverride *override; - SOMAncestor *ancestor; - Object *object; - OLinkList *relocs; - SInt32 size; - SInt32 offset; - char *buf; - - if (gen->overrideProcsCount) { - size = gen->overrideProcsCount * 4; - object = CSOM_MakeObject(tclass->classname->name, "OverrideProcs", size); - object->sclass = TK_STATIC; - - relocs = NULL; - offset = 0; - for (ancestor = gen->ancestors; ancestor; ancestor = ancestor->next) { - if (ancestor->overrides) { - for (override = ancestor->overrides; override; override = override->next) { - OLinkList *reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = override->a; - reloc->offset = offset; - reloc->somevalue = 0; - offset += 4; - } - } - } - - buf = lalloc(size); - memclrw(buf, size); - CInit_DeclareData(object, buf, relocs, object->type->size); - gen->overrideProcsObj = object; - } -} - -static Object *CSOM_GenerateOverrideData(SOMGenerator *gen) { - SOMAncestor *ancestor; - Object *object; - short ancestorIndex; - - name_mangle_list.size = 0; - for (ancestor = gen->ancestors, ancestorIndex = 0; ancestor; ancestor = ancestor->next, ancestorIndex++) { - if (ancestor->overrides) { - SOMOverride *override; - short overrideCount; - - AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(ancestorIndex)); - - override = ancestor->overrides; - overrideCount = 0; - while (override) { - overrideCount++; - override = override->next; - } - AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(overrideCount)); - - for (override = ancestor->overrides; override; override = override->next) { - AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(CSOM_GetTokenTableIndex(override->b))); - } - } - } - - COS_LockHandle(name_mangle_list.data); - object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0); - COS_UnlockHandle(name_mangle_list.data); - return object; -} - -static Object *CSOM_GenerateMigrateData(SOMGenerator *gen) { - SOMMethod *method; - Object *object; - int index; - - name_mangle_list.size = 0; - for (method = gen->methods, index = 0; method; method = method->next, index++) { - if (method->state == SOMMS_Migrated) { - AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(method->u.pair.a)); - AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(method->u.pair.b)); - AppendGListWord(&name_mangle_list, CTool_EndianConvertWord16(index)); - } - } - - COS_LockHandle(name_mangle_list.data); - object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0); - COS_UnlockHandle(name_mangle_list.data); - return object; -} - -static void CSOM_GenerateDLLDFunc(SOMGenerator *gen, TypeClass *tclass) { - TypeFunc *tfunc; - Object *object; - - tfunc = galloc(sizeof(TypeFunc)); - memclrw(tfunc, sizeof(TypeFunc)); - tfunc->type = TYPEFUNC; - tfunc->functype = &stvoid; - - object = CParser_NewCompilerDefFunctionObject(); - object->type = TYPE(tfunc); - object->sclass = TK_STATIC; - object->name = CParser_NameConcat(tclass->classname->name, "DLLD"); - - if (CScope_GetLocalObject(cscope_root, object->name)) - CError_Error(CErrorStr333, object); - - gen->dlldFunc = object; - CFunc_GenerateDummyFunction(object); -} - -static void CSOM_GenerateSpecialProcs(SOMGenerator *gen, TypeClass *tclass) { - Object *newFunc; - Object *deleteFunc; - Object *object; - OLinkList *relocs; - SInt32 size; - CScopeObjectIterator iter; - char buf[16]; - - newFunc = deleteFunc = NULL; - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (IS_TYPE_FUNC(object->type)) { - if (object->name == CMangler_OperatorName(TK_NEW)) { - newFunc = object; - gen->hasNew = 1; - } else if (object->name == CMangler_OperatorName(TK_DELETE)) { - deleteFunc = object; - gen->hasDelete = 1; - } - } - } - - if (newFunc || deleteFunc) { - object = CSOM_MakeObject(tclass->classname->name, "SpecialProcs", 4); - object->sclass = TK_STATIC; - - relocs = NULL; - size = 0; - - if (newFunc) { - OLinkList *reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = newFunc; - reloc->offset = size; - reloc->somevalue = 0; - size += 4; - } - - if (deleteFunc) { - OLinkList *reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = deleteFunc; - reloc->offset = size; - reloc->somevalue = 0; - size += 4; - } - - memclrw(buf, sizeof(buf)); - object->type->size = size; - CInit_DeclareData(object, buf, relocs, object->type->size); - gen->specialProcsObj = object; - } -} - -static Object *CSOM_GenerateParentVersion(SOMGenerator *gen) { - SInt32 size; - UInt32 *buf; - SOMAncestor *ancestor; - SInt32 offset; - - size = 8 * (gen->counts.numDirectParents + gen->counts.numMetaClasses); - buf = lalloc(size); - - for (ancestor = gen->ancestors, offset = 0; ancestor; ancestor = ancestor->next) { - if (ancestor->xC || ancestor->xD) { - buf[offset++] = CTool_EndianConvertWord32(ancestor->tclass->sominfo->majorversion); - buf[offset++] = CTool_EndianConvertWord32(ancestor->tclass->sominfo->minorversion); - } - } - - return CInit_DeclareString((char *) buf, size, 0, 0); -} - -static void CSOM_SetNibble(char *buf, int offset, UInt8 value) { - int i = offset >> 1; - if (offset & 1) { - int left = buf[i] & 0xF0; - int right = value & 0xF; - buf[i] = left | right; - } else { - int left = value << 4; - int right = buf[i] & 0xF; - buf[i] = left | right; - } -} - -static Object *CSOM_GenerateSlotUsage(SOMGenerator *gen) { - SInt32 size; - SOMMethod *method; - char *buf; - int offset; - - size = (gen->counts.classTokenCount + 1) / 2; - buf = lalloc(size); - memclrw(buf, size); - - for (method = gen->methods, offset = 0; method; method = method->next, offset++) { - switch (method->state) { - case SOMMS_Deleted: - case SOMMS_Migrated: - CSOM_SetNibble(buf, offset, mtEmpty); - break; - case SOMMS_Method: - CSOM_SetNibble(buf, offset, mtVirtualMethod); - break; - default: - CError_FATAL(1048); - } - } - - return CInit_DeclareString(buf, size, 0, 0); -} - -static Object *CSOM_GenerateSignature(SOMGenerator *gen) { - Object *object; - SOMMethod *method; - - name_mangle_list.size = 0; - - for (method = gen->methods; method; method = method->next) { - if (method->state == SOMMS_Method) - CSOM_GetFuncSig(TYPE_FUNC(method->u.object->type), 1); - } - - COS_LockHandle(name_mangle_list.data); - object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0); - COS_UnlockHandle(name_mangle_list.data); - return object; -} - -static Object *CSOM_GenerateMethodNames(SOMGenerator *gen) { - Object *object; - SOMMethod *method; - HashNameNode *name; - - name_mangle_list.size = 0; - - for (method = gen->methods; method; method = method->next) { - if (method->name) { - name = CSOM_NameTranslate(method->name); - AppendGListID(&name_mangle_list, name->name); - } - } - - COS_LockHandle(name_mangle_list.data); - object = CInit_DeclareString(*name_mangle_list.data, name_mangle_list.size, 0, 0); - COS_UnlockHandle(name_mangle_list.data); - return object; -} - -static void CSOM_SetupClassCounts(SOMGenerator *gen, TypeClass *tclass, somStaticClassCounts *counts) { - gen->counts.majorVersion = tclass->sominfo->majorversion; - gen->counts.minorVersion = tclass->sominfo->minorversion; - gen->counts.flags = cfSharedStrings; - if (gen->hasNew) - gen->counts.flags |= cfClassAllocate; - if (gen->hasDelete) - gen->counts.flags |= cfClassDeallocate; - - switch (tclass->align) { - case 1: - gen->counts.dataAlignment = 0; - break; - case 2: - gen->counts.dataAlignment = 1; - break; - case 4: - gen->counts.dataAlignment = 2; - break; - case 8: - gen->counts.dataAlignment = 3; - break; - default: - gen->counts.dataAlignment = 4; - break; - } - - gen->counts.numSelectInherited = 0; - - memclrw(counts, sizeof(somStaticClassCounts)); - counts->majorVersion = CTool_EndianConvertWord32(gen->counts.majorVersion); - counts->minorVersion = CTool_EndianConvertWord32(gen->counts.minorVersion); - counts->flags = CTool_EndianConvertWord32(gen->counts.flags); - counts->dataAlignment = CTool_EndianConvertWord16(gen->counts.dataAlignment); - counts->classTokenCount = CTool_EndianConvertWord16(gen->counts.classTokenCount); - counts->numDirectParents = CTool_EndianConvertWord16(gen->counts.numDirectParents); - counts->numMetaClasses = CTool_EndianConvertWord16(gen->counts.numMetaClasses); - counts->numOverriddenAncestors = CTool_EndianConvertWord16(gen->counts.numOverriddenAncestors); - counts->numMigratedMethods = CTool_EndianConvertWord16(gen->counts.numMigratedMethods); - counts->numSelectInherited = CTool_EndianConvertWord16(gen->counts.numSelectInherited); -} - -static void CSOM_GenerateSCIObject(SOMGenerator *gen, TypeClass *tclass) { - Object *object; - OLinkList *relocs; - OLinkList *reloc; - somStaticClassInfo sci; - somStaticClassCounts classCounts; - - object = CSOM_MakeObject(tclass->classname->name, "SCI", sizeof(sci)); - object->sclass = TK_STATIC; - - memclrw(&sci, sizeof(sci)); - sci.layoutVersion = CTool_EndianConvertWord32(70); - - reloc = lalloc(sizeof(OLinkList)); - reloc->next = NULL; - relocs = reloc; - reloc->obj = tclass->sominfo->classdataobject; - reloc->offset = 4; - reloc->somevalue = 0; - - if (gen->overrideProcsObj) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = gen->overrideProcsObj; - reloc->offset = 8; - reloc->somevalue = 0; - } - - if (gen->classAncestorsObj) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = gen->classAncestorsObj; - reloc->offset = 12; - reloc->somevalue = 0; - } - - if (gen->dlldFunc) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = gen->dlldFunc; - reloc->offset = 16; - reloc->somevalue = 0; - } - - if (gen->specialProcsObj) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = gen->specialProcsObj; - reloc->offset = 20; - reloc->somevalue = 0; - } - - CSOM_SetupClassCounts(gen, tclass, &classCounts); - - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CInit_DeclareString((char *) &classCounts, sizeof(classCounts), 0, 0); - reloc->offset = 52; - reloc->somevalue = 0; - - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CInit_DeclareString(tclass->classname->name, strlen(tclass->classname->name) + 1, 0, 0); - reloc->offset = 56; - reloc->somevalue = 0; - - sci.classDescription.instanceDataSize = CTool_EndianConvertWord32(tclass->size); - - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CSOM_GenerateParentVersion(gen); - reloc->offset = 64; - reloc->somevalue = 0; - - if (gen->methods) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CSOM_GenerateSlotUsage(gen); - reloc->offset = 68; - reloc->somevalue = 0; - - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CSOM_GenerateSignature(gen); - reloc->offset = 72; - reloc->somevalue = 0; - - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CSOM_GenerateMethodNames(gen); - reloc->offset = 76; - reloc->somevalue = 0; - } - - if (gen->overrideProcsObj) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CSOM_GenerateOverrideData(gen); - reloc->offset = 80; - reloc->somevalue = 0; - } - - if (gen->counts.numMigratedMethods) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = CSOM_GenerateMigrateData(gen); - reloc->offset = 84; - reloc->somevalue = 0; - } - - sci.classDescription.selectedInherited = 0; - - CInit_DeclareData(object, &sci, relocs, object->type->size); - gen->sciObj = object; -} - -static void CSOM_GenerateClassDataObject(SOMGenerator *gen, TypeClass *tclass) { - void *buf; - OLinkList *relocs; - OLinkList *reloc; - SInt32 size; - SOMMethod *method; - - relocs = NULL; - for (size = 24, method = gen->methods; method; method = method->next) { - if (method->state == SOMMS_Method) { - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = method->u.object; - reloc->offset = size; - reloc->somevalue = 0; - } - size += 4; - } - - buf = lalloc(size); - memclrw(buf, size); - - reloc = lalloc(sizeof(OLinkList)); - reloc->next = relocs; - relocs = reloc; - reloc->obj = gen->sciObj; - reloc->offset = 4; - reloc->somevalue = 0; - - tclass->sominfo->classdataobject->type->size = size; - CInit_DeclareData(tclass->sominfo->classdataobject, buf, relocs, tclass->sominfo->classdataobject->type->size); -} - -void CSOM_GenerateClassStructures(TypeClass *tclass) { - SOMGenerator gen; - - memclrw(&gen, sizeof(gen)); - CSOM_GenerateOverrideIntroLists(&gen, tclass); - CSOM_GenerateClassAncestors(&gen, tclass); - CSOM_GenerateOverrideProcs(&gen, tclass); - CSOM_GenerateDLLDFunc(&gen, tclass); - CSOM_GenerateSpecialProcs(&gen, tclass); - CSOM_GenerateSCIObject(&gen, tclass); - CSOM_GenerateClassDataObject(&gen, tclass); -} - -static TypeClass *CSOM_GetCurrentSOMClass(void) { - if (cscope_current->theclass && cscope_current->theclass->sominfo) - return cscope_current->theclass; - - CError_Error(CErrorStr277); - return NULL; -} - -void CSOM_PragmaReleaseOrder(void) { - TypeClass *tclass; - SOMReleaseOrder *firstOrder; - SOMReleaseOrder *order; - SOMReleaseOrder **ptr; - Boolean flag; - short token; - - if (!(tclass = CSOM_GetCurrentSOMClass())) - return; - - token = CPrep_PragmaLex(0); - if (token != '(') { - if (token != TK_IDENTIFIER) { - CPrep_Error(CErrorStr114); - return; - } - - if (!strcmp(tkidentifier->name, "list")) { - token = CPrep_PragmaLex(0); - if (token != TK_IDENTIFIER) { - CPrep_Error(CErrorStr107); - return; - } - } - - flag = 1; - } else { - flag = 0; - token = CPrep_PragmaLex(0); - } - - firstOrder = NULL; - if (flag || token != ')') { - ptr = &firstOrder; - while (1) { - if (token != TK_IDENTIFIER) { - CPrep_Error(CErrorStr107); - return; - } - - for (order = firstOrder; order; order = order->next) { - if (order->name == tkidentifier) { - CError_Error(CErrorStr122, tkidentifier->name); - return; - } - } - - order = galloc(sizeof(SOMReleaseOrder)); - *ptr = order; - ptr = &order->next; - - order->next = NULL; - order->name = tkidentifier; - order->state = SOMMS_Deleted; - - if (flag) { - token = CPrep_PragmaLex(1); - if (!token) - break; - } else { - token = CPrep_PragmaLex(0); - if (token == ')') - break; - } - - if (token != ',') { - CPrep_Error(CErrorStr116); - return; - } - - token = CPrep_PragmaLex(flag); - } - } - - tclass->sominfo->order = firstOrder; -} - -void CSOM_PragmaClassVersion(void) { - Type *type; - - if (CPrep_PragmaLex(0) != '(') { - CPrep_Error(CErrorStr114); - return; - } - - if (CPrep_PragmaLex(0) != TK_IDENTIFIER) { - CPrep_Error(CErrorStr107); - return; - } - - type = CScope_GetTagType(cscope_current, tkidentifier); - if (!(type && IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)) { - CPrep_ErrorName(CErrorStr276, tkidentifier->name); - return; - } - - if (CPrep_PragmaLex(0) != ',') { - CPrep_Error(CErrorStr116); - return; - } - - if (CPrep_PragmaLex(0) != TK_INTCONST) { - CPrep_Error(CErrorStr186); - return; - } - - TYPE_CLASS(type)->sominfo->majorversion = CInt64_GetULong(&tkintconst); - - if (CPrep_PragmaLex(0) != ',') { - CPrep_Error(CErrorStr116); - return; - } - - if (CPrep_PragmaLex(0) != TK_INTCONST) { - CPrep_Error(CErrorStr186); - return; - } - - TYPE_CLASS(type)->sominfo->minorversion = CInt64_GetULong(&tkintconst); - - if (CPrep_PragmaLex(0) != ')') { - CPrep_Error(CErrorStr115); - return; - } -} - -void CSOM_PragmaMetaClass(void) { - Type *type; - Type *type2; - - if (CPrep_PragmaLex(0) != '(') { - CPrep_Error(CErrorStr114); - return; - } - - if (CPrep_PragmaLex(0) != TK_IDENTIFIER) { - CPrep_Error(CErrorStr107); - return; - } - - type = CScope_GetTagType(cscope_current, tkidentifier); - if (!(type && IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo)) { - CPrep_ErrorName(CErrorStr276, tkidentifier->name); - return; - } - - if (CPrep_PragmaLex(0) != ',') { - CPrep_Error(CErrorStr116); - return; - } - - if (CPrep_PragmaLex(0) != TK_IDENTIFIER) { - CPrep_Error(CErrorStr107); - return; - } - - type2 = CScope_GetTagType(cscope_current, tkidentifier); - if (!(type2 && IS_TYPE_CLASS(type2) && TYPE_CLASS(type2)->sominfo)) { - CPrep_ErrorName(CErrorStr276, tkidentifier->name); - return; - } - - TYPE_CLASS(type)->sominfo->metaclass = TYPE_CLASS(type2); - - if (CPrep_PragmaLex(0) != ')') { - CPrep_Error(CErrorStr115); - return; - } -} - -void CSOM_PragmaCallStyle(void) { - TypeClass *tclass; - - if (!(tclass = CSOM_GetCurrentSOMClass())) - return; - - if (CPrep_PragmaLex(0) != TK_IDENTIFIER) { - CPrep_Error(CErrorStr107); - return; - } - - if (!strcmp(tkidentifier->name, "IDL")) { - tclass->sominfo->oidl_callstyle = 0; - return; - } - - if (!strcmp(tkidentifier->name, "OIDL")) { - tclass->sominfo->oidl_callstyle = 1; - return; - } - - CPrep_Error(CErrorStr186); -} - -void CSOM_FixNewDeleteFunctype(TypeFunc *tfunc) { - FuncArg *arg = CParser_NewFuncArg(); - arg->name = GetHashNameNodeExport("__theclass"); - arg->type = CDecl_NewPointerType(CSOM_FindClassType(GetHashNameNodeExport("SOMClass"))); - arg->next = tfunc->args; - tfunc->args = arg; -} - -static Object *CSOM_FindRTFunc(char *namestr, char *sig) { - NameSpaceObjectList *nsol; - Object *object; - FuncArg *arg; - - if ( - (nsol = CScope_GetLocalObject(cscope_root, GetHashNameNodeExport(namestr))) && - nsol->object->otype == OT_OBJECT - ) - { - object = OBJECT(nsol->object); - if ( - IS_TYPE_FUNC(object->type) && - *(sig++) == 'p' && - IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->functype) - ) - { - for (arg = TYPE_FUNC(object->type)->args; arg; arg = arg->next) { - switch (*(sig++)) { - case 'p': - if (IS_TYPE_POINTER_ONLY(arg->type)) - continue; - break; - case 'i': - if (arg->type == TYPE(&stsignedint)) - continue; - break; - case 'I': - if (arg->type == TYPE(&stunsignedint)) - continue; - break; - case 'l': - if (arg->type == TYPE(&stsignedlong)) - continue; - break; - case 'L': - if (arg->type == TYPE(&stunsignedlong)) - continue; - break; - } - break; - } - - if (arg == NULL && *sig == 0) - return object; - } - - CError_Error(CErrorStr275, namestr); - } else { - CError_Error(CErrorStr274, namestr); - } - - return NULL; -} - -static ENode *CSOM_MakeTempCondition(ENode *left, ENode *cond, ENode *expr1, ENode *right) { - ENode *expr; - - expr = lalloc(sizeof(ENode)); - expr->type = ECOND; - expr->cost = 0; - expr->flags = 0; - expr->rtype = &stvoid; - expr->data.cond.cond = cond; - expr->data.cond.expr1 = expr1; - expr->data.cond.expr2 = nullnode(); - expr->data.cond.expr2->rtype = &stvoid; - - if (left) - expr = makediadicnode(left, expr, ECOMMA); - - if (right) { - expr = makediadicnode(expr, right, ECOMMA); - expr->rtype = right->rtype; - } - - return expr; -} - -ENode *CSOM_New(TypeClass *tclass) { - Object *newFunc; - ENode *expr; - - if (tk == '(') { - if ((tk = lex()) == ')') { - tk = lex(); - } else { - CError_Error(CErrorStr272); - } - } - - if (!copts.som_env_check || !copts.som_call_optimize) { - newFunc = CSOM_FindRTFunc("somNewObjectInstance", "ppll"); - if (!newFunc) - return nullnode(); - } else { - newFunc = rt_som_new; - } - - expr = funccallexpr( - newFunc, - create_objectrefnode(tclass->sominfo->classdataobject), - intconstnode(TYPE(&stunsignedlong), tclass->sominfo->majorversion), - intconstnode(TYPE(&stunsignedlong), tclass->sominfo->minorversion), - NULL - ); - expr->rtype = CDecl_NewPointerType(TYPE(tclass)); - - if (copts.som_env_check && !copts.som_call_optimize) { - ENode *tempExpr; - ENode *checkExpr; - ENode *notExpr; - tempExpr = CExpr_GetETEMPCopy(expr); - checkExpr = funccallexpr(rt_som_newcheck, nullnode(), NULL, NULL, NULL); - notExpr = makemonadicnode(tempExpr, ELOGNOT); - notExpr->rtype = CParser_GetBoolType(); - expr = CSOM_MakeTempCondition(NULL, notExpr, checkExpr, tempExpr); - } - - return expr; -} - -ENode *CSOM_Delete(TypeClass *tclass, ENode *objExpr) { - Object *func; - - if ((func = CSOM_FindRTFunc("somReleaseObjectReference", "pp"))) - return funccallexpr(func, objExpr, NULL, NULL, NULL); - - return nullnode(); -} - -void CSOM_InitAutoClass(Object *object) { - Type *type; - Statement *stmt; - Object *func; - - if ((func = CSOM_FindRTFunc("somReleaseObjectReference", "pp"))) { - type = object->type; - object->type = CDecl_NewPointerType(type); - TPTR_QUAL(object->type) = Q_REFERENCE; - - stmt = CFunc_AppendStatement(ST_EXPRESSION); - stmt->expr = makediadicnode(create_objectnode2(object), CSOM_New(TYPE_CLASS(type)), EASS); - CExcept_RegisterDeleteObject(stmt, object, func); - } -} - -static void CSOM_FindIntroClassOffset(TypeClass *tclass, Object *func, TypeClass **resultClass, SInt32 *resultOffset) { - Object *scan; - VClassList *vbase; - CScopeObjectIterator iter; - - if (!(TYPE_FUNC(func->type)->flags & FUNC_FLAGS_20)) { - CScope_InitObjectIterator(&iter, tclass->nspace); - while (1) { - if (!(scan = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (scan == func) { - *resultClass = tclass; - *resultOffset = CSOM_GetTokenOffset(scan); - return; - } - } - - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - CScope_InitObjectIterator(&iter, vbase->base->nspace); - while (1) { - if (!(scan = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (scan == func) { - *resultClass = vbase->base; - *resultOffset = CSOM_GetTokenOffset(scan); - return; - } - } - } - } else { - for (vbase = tclass->vbases; vbase; vbase = vbase->next) { - CScope_InitObjectIterator(&iter, vbase->base->nspace); - while (1) { - if (!(scan = OBJECT(CScope_NextObjectIteratorObject(&iter)))) - break; - - if (scan->name == func->name) { - if ( - IS_TYPE_FUNC(scan->type) && - scan->datatype == DVFUNC && - !(TYPE_FUNC(scan->type)->flags & FUNC_FLAGS_20) && - CClass_GetOverrideKind(TYPE_FUNC(func->type), TYPE_FUNC(scan->type), 0) - ) - { - *resultClass = vbase->base; - *resultOffset = CSOM_GetTokenOffset(scan); - return; - } - break; - } - } - } - } - - CError_FATAL(1731); -} - -static ENode *CSOM_ComputeSOMSelf(TypeClass *tclass, ENode *selfExpr) { - ENode *expr; - Object obj; - - expr = create_objectrefnode(tclass->sominfo->classdataobject); - expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), 8), EADD); - expr->rtype = CDecl_NewPointerType(TYPE(&SOMIDT_type)); - expr = makemonadicnode(expr, EINDIRECT); - - memclrw(&obj, sizeof(Object)); - obj.otype = OT_OBJECT; - obj.type = TYPE(&SOMIDT_type); - obj.name = no_name_node; - obj.datatype = DFUNC; - selfExpr = funccallexpr(&obj, selfExpr, NULL, NULL, NULL); - - CError_ASSERT(1761, ENODE_IS(selfExpr, EFUNCCALL)); - - selfExpr->data.funccall.funcref = expr; - - return selfExpr; -} - -ENode *CSOM_SOMSelfObjectExpr(TypeClass *tclass) { - ObjectList *list; - Object *obj; - - for (list = locals; list; list = list->next) { - if (list->object->name == csom_selfname) - return create_objectnode(list->object); - } - - obj = CParser_NewLocalDataObject(NULL, 1); - obj->name = csom_selfname; - obj->type = CDecl_NewPointerType(TYPE(tclass)); - CFunc_SetupLocalVarInfo(obj); - return create_objectnode(obj); -} - -void CSOM_InitSOMSelf(TypeClass *tclass, Statement *stmt) { - ObjectList *list; - HashNameNode *name; - ENode *selfExpr; - - name = GetHashNameNodeExport("__somself"); - for (list = locals; list; list = list->next) { - if (list->object->name == name) { - selfExpr = CClass_CreateThisSelfExpr(); - CError_ASSERT(1811, selfExpr); - - selfExpr = CSOM_ComputeSOMSelf(tclass, selfExpr); - - stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); - stmt->expr = makediadicnode(create_objectnode(list->object), selfExpr, EASS); - break; - } - } -} - -ENode *CSOM_EnvCheck(ENode *funccall, ENodeList *checkArg) { - ENodeList *arg; // r26 - ENodeList *arg2; // r28 - ENode *expr26; // r26 - ENode *expr27; // r27 - ENode *expr28; // r28 - Type *returnType; // r31 - - returnType = funccall->rtype; - CError_ASSERT(1842, arg = funccall->data.funccall.args); - - if (arg == checkArg) - CError_ASSERT(1845, arg = arg->next); - - CError_ASSERT(1847, arg2 = arg->next); - - if (arg2 == checkArg) - CError_ASSERT(1850, arg2 = arg2->next); - - CError_ASSERT(1852, IS_TYPE_POINTER_ONLY(arg2->node->rtype)); - - if (!IS_TYPE_VOID(funccall->data.funccall.functype->functype)) { - if (checkArg) { - if (ENODE_IS(checkArg->node, ETEMP)) { - if (checkArg->node->data.temp.uniqueid == 0) - checkArg->node->data.temp.uniqueid = CParser_GetUniqueID(); - - expr26 = lalloc(sizeof(ENode)); - *expr26 = *checkArg->node; - expr26->data.temp.needs_dtor = 0; - } else { - expr26 = CExpr_GetETEMPCopy(checkArg->node); - } - } else { - expr26 = CExpr_GetETEMPCopy(funccall); - } - } else { - expr26 = NULL; - } - - if (!ENODE_IS(arg2->node, EOBJREF)) { - if (ENODE_IS_INDIRECT_TO(arg2->node, EOBJREF) && arg2->node->data.monadic->data.objref->datatype == DLOCAL) { - expr27 = lalloc(sizeof(ENode)); - *expr27 = *arg2->node; - } else { - expr27 = CExpr_GetETEMPCopy(arg2->node); - } - } else { - expr27 = lalloc(sizeof(ENode)); - *expr27 = *arg2->node; - } - - if (copts.som_call_optimize) { - funccall = makediadicnode(funccall, funccallexpr(rt_som_check, expr27, NULL, NULL, NULL), ECOMMA); - if (expr26) - funccall = makediadicnode(funccall, expr26, ECOMMA); - } else { - expr28 = lalloc(sizeof(ENode)); - *expr28 = *expr27; - expr28 = makemonadicnode(expr28, EINDIRECT); - expr28->rtype = TYPE(&stsignedlong); - - funccall = CSOM_MakeTempCondition( - funccall, - expr28, - funccallexpr(rt_som_check, expr27, NULL, NULL, NULL), - expr26); - } - - funccall->rtype = returnType; - return funccall; -} - -static Boolean CSOM_CanUseGlueCall(TypeFunc *tfunc) { - int gprCounter; - int fprCounter; - FuncArg *arg; - - gprCounter = 8; - fprCounter = 13; - if (CMach_GetFunctionResultClass(tfunc) != 0) - gprCounter = 7; - - for (arg = tfunc->args; arg; arg = arg->next) { - if (arg == &elipsis || arg == &oldstyle) - return 0; - - switch (arg->type->type) { - case TYPEINT: - case TYPEENUM: - case TYPEPOINTER: - if (--gprCounter < 0) - return 0; - break; - case TYPEFLOAT: - if (--fprCounter < 0) - return 0; - break; - default: - return 0; - } - } - - return 1; -} - -static char *CSOM_AppendString(char *dst, char *src) { - int ch; - while ((ch = *(src++))) - *(dst++) = ch; - return dst; -} - -static ENode *CSOM_SOMGlueCall(TypeClass *tclass, SInt32 offset, Object *object) { - UInt8 funcResultClass; - UInt32 bufsize; - char *buf; - char *ptr; - Object *stubObj; - CSOMStub *stub; - ENode *expr; - char mybuf[256]; - char numberbuf[16]; - - for (stub = csom_stubs; stub; stub = stub->next) { - if (stub->tclass == tclass && stub->offset == offset) - break; - } - - if (!stub) { - funcResultClass = CMach_GetFunctionResultClass(TYPE_FUNC(object->type)); - - bufsize = strlen(tclass->sominfo->classdataobject->name->name) + 32; - buf = (bufsize > sizeof(mybuf)) ? lalloc(bufsize) : mybuf; - - ptr = CSOM_AppendString(buf, "___glue_"); - if (tclass->sominfo->oidl_callstyle == 0) { - if (funcResultClass == 0) { - *(ptr++) = '4'; - } else { - *(ptr++) = '5'; - } - } else { - *(ptr++) = '_'; - } - *(ptr++) = '_'; - - sprintf(numberbuf, "%ld", strlen(tclass->sominfo->classdataobject->name->name)); - ptr = CSOM_AppendString(ptr, numberbuf); - ptr = CSOM_AppendString(ptr, tclass->sominfo->classdataobject->name->name); - *(ptr++) = '_'; - sprintf(numberbuf, "%" PRId32, offset); - ptr = CSOM_AppendString(ptr, numberbuf); - *ptr = 0; - - stubObj = CParser_NewCompilerDefFunctionObject(); - stubObj->nspace = cscope_root; - stubObj->name = GetHashNameNodeExport(buf); - stubObj->u.func.linkname = stubObj->name; - stubObj->type = object->type; - stubObj->qual = object->qual | Q_20000; - stubObj->flags = OBJECT_INTERNAL; - CScope_AddObject(stubObj->nspace, stubObj->name, OBJ_BASE(stubObj)); - - stub = galloc(sizeof(CSOMStub)); - stub->next = csom_stubs; - stub->object = stubObj; - stub->tclass = tclass; - stub->offset = offset; - csom_stubs = stub; - - if (tclass->sominfo->oidl_callstyle == 0) { - if (funcResultClass == 0) - stub->x10 = 0; - else - stub->x10 = 1; - } else { - stub->x10 = 2; - } - } - - expr = create_objectrefnode(stub->object); - expr->rtype = CDecl_NewPointerType(object->type); - return expr; -} - -ENode *CSOM_MemberVarAccess(BClassList *path, ObjMemberVar *ivar, ENode *thisExpr) { - if (!thisExpr) { - if ( - !cscope_currentfunc || - !cscope_currentclass || - !cscope_is_member_func || - !(thisExpr = CClass_CreateThisSelfExpr()) - ) - { - CError_Error(CErrorStr221); - return NULL; - } - } - - CError_ASSERT(2069, ENODE_IS(thisExpr, EINDIRECT)); - - thisExpr = thisExpr->data.monadic; - - if ( - path->next == NULL && - cscope_currentclass == TYPE_CLASS(path->type) && - ENODE_IS(thisExpr, EOBJREF) && - thisExpr->data.objref->name == this_name_node - ) - { - thisExpr = CSOM_SOMSelfObjectExpr(cscope_currentclass); - } - else - { - CClass_CheckPathAccess(path, NULL, ivar->access); - if (ivar->has_path) - path = OBJ_MEMBER_VAR_PATH(ivar)->path; - while (path->next) - path = path->next; - thisExpr = CSOM_ComputeSOMSelf(TYPE_CLASS(path->type), thisExpr); - } - - thisExpr = makemonadicnode(thisExpr, EINDIRECT); - thisExpr->rtype = path->type; - return CClass_AccessMember(thisExpr, ivar->type, ivar->qual, ivar->offset); -} - -ENode *CSOM_MethodAccess(BClassList *path, Object *func, Boolean flag) { - TypeClass *tclass; - TypeClass *tclass2; - TypeClass *tclass3; - ENode *expr; - SInt32 offset; - ClassList *base; - - CError_ASSERT(2107, path != NULL); - - tclass = TYPE_CLASS(path->type); - if (path->next) - path = path->next; - tclass2 = TYPE_CLASS(path->type); - - if (flag) { - SInt32 counter; - ENode *indirectExpr; - Object *resolveFunc; - - counter = 0; - if (tclass != tclass2) { - for (base = tclass->bases; base; base = base->next) { - counter++; - if (base->base == tclass2) - break; - } - - if (!base) - CError_Error(CErrorStr279); - } - - CSOM_FindIntroClassOffset(tclass2, func, &tclass3, &offset); - expr = create_objectrefnode(tclass3->sominfo->classdataobject); - expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), offset), EADD); - indirectExpr = makemonadicnode(expr, EINDIRECT); - indirectExpr->rtype = CDecl_NewPointerType(func->type); - - resolveFunc = CSOM_FindRTFunc("somParentNumResolve", "ppip"); - if (!resolveFunc) - return nullnode(); - - expr = funccallexpr( - resolveFunc, - create_objectrefnode(tclass->sominfo->classdataobject), - intconstnode(TYPE(&stsignedint), counter), - indirectExpr, - NULL); - expr->rtype = indirectExpr->rtype; - if (copts.som_env_check && tclass3->sominfo->oidl_callstyle == 0) - expr->flags = expr->flags | ENODE_FLAG_10; - } else { - CSOM_FindIntroClassOffset(tclass2, func, &tclass3, &offset); - if (copts.som_call_optimize && CSOM_CanUseGlueCall(TYPE_FUNC(func->type))) - return CSOM_SOMGlueCall(tclass3, offset, func); - - expr = create_objectrefnode(tclass3->sominfo->classdataobject); - expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), offset), EADD); - expr = makemonadicnode(expr, EINDIRECT); - expr->rtype = CDecl_NewPointerType(func->type); - if (copts.som_env_check && tclass3->sominfo->oidl_callstyle == 0) - expr->flags = expr->flags | ENODE_FLAG_10; - } - - return expr; -} |