/* * REFS.C */ #include "defs.h" static __inline void rsget(RefStor *rs, const char *name, int hard) { refassert(rs->rs_Lock.rl_Count >= 0); refassert(rs->rs_Refs > 0); RuneLockEx(&rs->rs_Lock, hard); atomic_add_rune(&rs->rs_Refs, 1); refprintf(">>>> %-7s %p %04x refs=%jd lock=%jd type=%p base=%p\n", name, rs, rs->rs_Op, (intmax_t)rs->rs_Refs, (intmax_t)rs->rs_Lock.rl_Count / RLCOUNT_INCR, rs->rs_Type, rs->rs_Base); } static __inline void rsput(RefStor *rs, const char *name, int hard) { refassert(rs->rs_Lock.rl_Count > 0); refassert(rs->rs_Refs > 0); RuneUnlockEx(&rs->rs_Lock, hard); refprintf(">>>> %-7s %p %04x refs=%jd lock=%jd type=%p base=%p\n", name, rs, rs->rs_Op, (intmax_t)rs->rs_Refs - 1, (intmax_t)rs->rs_Lock.rl_Count / RLCOUNT_INCR, rs->rs_Type, rs->rs_Base); if (atomic_fetchadd_rune(&rs->rs_Refs, -1) == 1) freeRefStor(rs); } static __inline void rsref(RefStor *rs, const char *name) { refassert(rs->rs_Lock.rl_Count >= 0); refassert(rs->rs_Refs > 0); atomic_add_rune(&rs->rs_Refs, 1); refprintf(">>>> %-7s %p %04x refs=%jd lock=%jd type=%p base=%p\n", name, rs, rs->rs_Op, (intmax_t)rs->rs_Refs, (intmax_t)rs->rs_Lock.rl_Count / RLCOUNT_INCR, rs->rs_Type, rs->rs_Base); } static __inline void rsrel(RefStor *rs, const char *name) { refassert(rs->rs_Lock.rl_Count >= 0); refassert(rs->rs_Refs > 0); refprintf(">>>> %-7s %p %04x refs=%jd lock=%jd type=%p base=%p\n", name, rs, rs->rs_Op, (intmax_t)rs->rs_Refs - 1, (intmax_t)rs->rs_Lock.rl_Count / RLCOUNT_INCR, rs->rs_Type, rs->rs_Base); if (atomic_fetchadd_rune(&rs->rs_Refs, -1) == 1) freeRefStor(rs); } static __inline void rslock(RefStor *rs, const char *name, int hard) { refassert(rs->rs_Lock.rl_Count >= 0); refassert(rs->rs_Refs > 0); RuneLockEx(&rs->rs_Lock, hard); refprintf(">>>> %-7s %p %04x refs=%jd lock=%jd type=%p\n", name, rs, rs->rs_Op, (intmax_t)rs->rs_Refs, (intmax_t)rs->rs_Lock.rl_Count / RLCOUNT_INCR, rs->rs_Type); } static __inline void rsunlock(RefStor *rs, const char *name, int hard) { refassert(rs->rs_Lock.rl_Count > 0); refassert(rs->rs_Refs > 0); RuneUnlockEx(&rs->rs_Lock, hard); refprintf(">>>> %-7s %p %04x refs=%jd lock=%jd type=%p\n", name, rs, rs->rs_Op, (intmax_t)rs->rs_Refs, (intmax_t)rs->rs_Lock.rl_Count / RLCOUNT_INCR, rs->rs_Type); } /* * NOTE: Don't scrap type field */ void RuneRunTime_PGet(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rsget(rs, "PGET", 0); } } void RuneRunTime_PGetH(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rsget(rs, "PGET", 1); } } void RuneRunTime_PPut(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { ps->s_Addr = NULL; ps->s_Beg = NULL; ps->s_End = NULL; ps->s_RefStor = NULL; rsput(rs, "PPUT", 0); } } void RuneRunTime_PPutH(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { ps->s_Addr = NULL; ps->s_Beg = NULL; ps->s_End = NULL; ps->s_RefStor = NULL; rsput(rs, "PPUT", 1); } } void RuneRunTime_PRef(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rsref(rs, "PREF"); } } void RuneRunTime_PRel(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { ps->s_Addr = NULL; ps->s_Beg = NULL; ps->s_End = NULL; ps->s_RefStor = NULL; rsrel(rs, "PREL"); } } void RuneRunTime_PLock(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rslock(rs, "PLOCK", 0); } } void RuneRunTime_PLockH(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rslock(rs, "PLOCK", 1); } } void RuneRunTime_PUnlock(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rsunlock(rs, "PUNLOCK", 0); } } void RuneRunTime_PUnlockH(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rsunlock(rs, "PUNLOCK", 1); } } void RuneRunTime_LVGet(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rsget(rs, "LVGET", 0 ); } } void RuneRunTime_LVGetH(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rsget(rs, "LVGET", 1); } } void RuneRunTime_LVPut(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { lvs->s_Addr = NULL; lvs->s_RefStor = NULL; rsput(rs, "LVPUT", 0); } } void RuneRunTime_LVPutH(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { lvs->s_Addr = NULL; lvs->s_RefStor = NULL; rsput(rs, "LVPUT", 1); } } void RuneRunTime_LVRef(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rsref(rs, "LVREF"); } } void RuneRunTime_LVRel(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { lvs->s_Addr = NULL; lvs->s_RefStor = NULL; rsrel(rs, "LVREL"); } } void RuneRunTime_LVLock(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rslock(rs, "LVLOCK", 0); } } void RuneRunTime_LVLockH(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rslock(rs, "LVLOCK", 1); } } void RuneRunTime_LVUnlock(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rsunlock(rs, "LVUNLOCK", 0); } } void RuneRunTime_LVUnlockH(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rsunlock(rs, "LVUNLOCK", 1); } } void * RuneRunTime_PRSGet(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rsget(rs, "PRSGET", 0); } return rs; } void * RuneRunTime_PRSGetH(PointerStor *ps) { RefStor *rs; if ((rs = ps->s_RefStor) != NULL) { rsget(rs, "PRSGET", 1); } return rs; } void * RuneRunTime_LVRSGet(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rsget(rs, "LVRSGET", 0); } return rs; } void * RuneRunTime_LVRSGetH(LValueStor *lvs) { RefStor *rs; if ((rs = lvs->s_RefStor) != NULL) { rsget(rs, "LVRSGET", 1); } return rs; } void * RuneRunTime_STKRSGet(void) { RefStor *rs = getrgd()->CurThread->td_StackRS; dassert(rs); rsget(rs, "STKRSGET", 0); return rs; } void * RuneRunTime_STKRSGetH(void) { RefStor *rs = getrgd()->CurThread->td_StackRS; dassert(rs); rsget(rs, "STKRSGET", 1); return rs; } void RuneRunTime_RSGet(RefStor *rs) { if (rs) { rsget(rs, "RSGET", 0); } } void RuneRunTime_RSGetH(RefStor *rs) { if (rs) { rsget(rs, "RSGET", 1); } } void RuneRunTime_RSPut(RefStor *rs) { if (rs) { rsput(rs, "RSPUT", 0); } } void RuneRunTime_RSPutH(RefStor *rs) { if (rs) { rsput(rs, "RSPUT", 1); } } void RuneRunTime_RSRef(RefStor *rs) { if (rs) { rsref(rs, "RSREF"); } } void RuneRunTime_RSRel(RefStor *rs) { if (rs) { rsrel(rs, "RSREL"); } } void RuneRunTime_RSLock(RefStor *rs) { if (rs) { rslock(rs, "RSLOCK", 0); } } void RuneRunTime_RSLockH(RefStor *rs) { if (rs) { rslock(rs, "RSLOCK", 1); } } void RuneRunTime_RSUnlock(RefStor *rs) { if (rs) { rsunlock(rs, "RSUNLOCK", 0); } } void RuneRunTime_RSUnlockH(RefStor *rs) { if (rs) { rsunlock(rs, "RSUNLOCK", 1); } } void RuneRunTime_BoundsTrap(void) { dpanic("BoundsTrap"); } void RuneRunTime_PCheck(char *addr, PointerStor *ps) { #if 1 if (addr < ps->s_Beg || addr >= ps->s_End) printf("PCheck: addr=%p ps=%p { %p (%p-%p) %p %p }\n", addr, ps, ps->s_Addr, ps->s_Beg, ps->s_End, ps->s_RefStor, ps->s_Type); #endif dassert(addr >= ps->s_Beg && addr < ps->s_End); } void RuneRunTime_PCopy(PointerStor *ps, PointerStor *pd) { *pd = *ps; } /* * Copy of FindDeclByIndex() in librune/decl.c. We don't want the run-time * to require librune (for now anyway). */ static Declaration * findDeclByIndex(SemGroup *sg, int i) { Declaration *d; RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) { if (d->d_Index == i) return(d); } return(NULL); } void * RuneRunTime_GetVarType(runesize_t index, char *ap, SemGroup *sg) { Declaration *d; Type *type; #if 0 printf("GETVARTYPE @%p index=%jd ap=%p sg=%p\n", &d, index, ap, sg); #endif d = findDeclByIndex(sg, sg->sg_DeclCount - sg->sg_VarCount + index); if (d == NULL) { printf("RuneRunTime_GetVarType: Cannot find declaration %jd\n", index); } #if 0 printf("DOP %p %d\n", d, d->d_Op); #endif switch(d->d_Op) { case DOP_TYPEDEF: type = d->d_TypedefDecl.ed_Type; break; case DOP_ARGS_STORAGE: case DOP_STACK_STORAGE: case DOP_GLOBAL_STORAGE: case DOP_GROUP_STORAGE: type = d->d_StorDecl.ed_Type; break; default: dpanic("Unknown DOP %d (d=%p)", d->d_Op, d); type = NULL; break; } #if 0 printf("TYPE %s\n", TypeToStr(type, NULL)); #endif return type; } void * RuneRunTime_GetVarData(runesize_t index, char *ap, SemGroup *sg, Type *compat_type) { Declaration *d; Type *type __unused; #if 0 printf("GETVARDATA index=%jd ap=%p sg=%p\n", index, ap, sg); #endif d = findDeclByIndex(sg, sg->sg_DeclCount - sg->sg_VarCount + index); if (d == NULL) { printf("RuneRunTime_GetVarData: Cannot find declaration %jd\n", index); } switch(d->d_Op) { case DOP_ARGS_STORAGE: case DOP_STACK_STORAGE: case DOP_GLOBAL_STORAGE: case DOP_GROUP_STORAGE: type = d->d_StorDecl.ed_Type; break; default: dpanic("Unknown DOP %d (d=%p)", d->d_Op, d); type = NULL; break; } #if 0 printf("TYPE %s DATA %p+%jd\n", TypeToStr(type, NULL), ap, (intmax_t)d->d_Offset); #endif return (ap + d->d_Offset); } void RuneRunTime_GetVarType2(void *ap, void *rp) { struct { runesize_t index; char *ap; SemGroup *sg; } *args = ap; void **res = rp; *res = RuneRunTime_GetVarType(args->index, args->ap, args->sg); } void RuneRunTime_GetVarData2(void *ap, void *rp) { struct { runesize_t index; char *ap; SemGroup *sg; Type *compat_type; } *args = ap; void **res = rp; *res = RuneRunTime_GetVarData(args->index, args->ap, args->sg, args->compat_type); } int RuneRunTime_SWCmpType(Type *super, Type *sub) { return (SimilarType(super, sub)); } void RuneRunTime_SRSGet(void) { RuneSRSGet(0); /* see lock2.h */ } void RuneRunTime_SRSGetH(void) { RuneSRSGet(1); /* see lock2.h */ } void RuneRunTime_SRSPut(void) { RuneSRSPut(0); /* see lock2.h */ } void RuneRunTime_SRSPutH(void) { RuneSRSPut(1); /* see lock2.h */ }