trying to revive this project
This commit is contained in:
110
lib/hcl.c
110
lib/hcl.c
@ -32,7 +32,7 @@ hcl_t* hcl_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_oow_t heapsize, const
|
||||
hcl_t* hcl;
|
||||
|
||||
/* if this assertion fails, correct the type definition in hcl.h */
|
||||
HCL_ASSERT (HCL_SIZEOF(hcl_oow_t) == HCL_SIZEOF(hcl_oop_t));
|
||||
HCL_ASSERT (hcl, HCL_SIZEOF(hcl_oow_t) == HCL_SIZEOF(hcl_oop_t));
|
||||
|
||||
hcl = HCL_MMGR_ALLOC (mmgr, HCL_SIZEOF(*hcl) + xtnsize);
|
||||
if (hcl)
|
||||
@ -87,13 +87,24 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t
|
||||
{
|
||||
HCL_MEMSET (hcl, 0, HCL_SIZEOF(*hcl));
|
||||
hcl->mmgr = mmgr;
|
||||
hcl->cmgr = hcl_getutf8cmgr();
|
||||
hcl->vmprim = *vmprim;
|
||||
|
||||
hcl->option.log_mask = ~0u;
|
||||
hcl->option.log_maxcapa = HCL_DFL_LOG_MAXCAPA;
|
||||
hcl->option.dfl_symtab_size = HCL_DFL_SYMTAB_SIZE;
|
||||
hcl->option.dfl_sysdic_size = HCL_DFL_SYSDIC_SIZE;
|
||||
hcl->option.dfl_procstk_size = HCL_DFL_PROCSTK_SIZE;
|
||||
|
||||
hcl->log.capa = HCL_ALIGN_POW2(1, HCL_LOG_CAPA_ALIGN); /* TODO: is this a good initial size? */
|
||||
/* alloate the log buffer in advance though it may get reallocated
|
||||
* in put_oocs and put_ooch in logfmt.c. this is to let the logging
|
||||
* routine still function despite some side-effects when
|
||||
* reallocation fails */
|
||||
/* +1 required for consistency with put_oocs and put_ooch in logfmt.c */
|
||||
hcl->log.ptr = hcl_allocmem (hcl, (hcl->log.capa + 1) * HCL_SIZEOF(*hcl->log.ptr));
|
||||
if (!hcl->log.ptr) goto oops;
|
||||
|
||||
/*hcl->permheap = hcl_makeheap (hcl, what is the best size???);
|
||||
if (!hcl->curheap) goto oops; */
|
||||
hcl->curheap = hcl_makeheap (hcl, heapsz);
|
||||
@ -101,7 +112,7 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t
|
||||
hcl->newheap = hcl_makeheap (hcl, heapsz);
|
||||
if (!hcl->newheap) goto oops;
|
||||
|
||||
if (hcl_rbt_init (&hcl->pmtable, mmgr, HCL_SIZEOF(hcl_ooch_t), 1) <= -1) goto oops;
|
||||
if (hcl_rbt_init (&hcl->pmtable, hcl, HCL_SIZEOF(hcl_ooch_t), 1) <= -1) goto oops;
|
||||
hcl_rbt_setstyle (&hcl->pmtable, hcl_getrbtstyle(HCL_RBT_STYLE_INLINE_COPIERS));
|
||||
|
||||
fill_bigint_tables (hcl);
|
||||
@ -111,6 +122,8 @@ oops:
|
||||
if (hcl->newheap) hcl_killheap (hcl, hcl->newheap);
|
||||
if (hcl->curheap) hcl_killheap (hcl, hcl->curheap);
|
||||
if (hcl->permheap) hcl_killheap (hcl, hcl->permheap);
|
||||
if (hcl->log.ptr) hcl_freemem (hcl, hcl->log.ptr);
|
||||
hcl->log.capa = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -121,7 +134,7 @@ static hcl_rbt_walk_t unload_primitive_module (hcl_rbt_t* rbt, hcl_rbt_pair_t* p
|
||||
|
||||
md = HCL_RBT_VPTR(pair);
|
||||
if (md->mod.unload) md->mod.unload (hcl, &md->mod);
|
||||
if (md->handle) hcl->vmprim.mod_close (hcl, md->handle);
|
||||
if (md->handle) hcl->vmprim.dl_close (hcl, md->handle);
|
||||
|
||||
return HCL_RBT_WALK_FORWARD;
|
||||
}
|
||||
@ -130,6 +143,34 @@ void hcl_fini (hcl_t* hcl)
|
||||
{
|
||||
hcl_cb_t* cb;
|
||||
|
||||
hcl_rbt_walk (&hcl->pmtable, unload_primitive_module, hcl);
|
||||
hcl_rbt_fini (&hcl->pmtable);
|
||||
|
||||
if (hcl->log.len > 0)
|
||||
{
|
||||
/* flush pending log messages just in case. */
|
||||
HCL_ASSERT (hcl, hcl->log.ptr != HCL_NULL);
|
||||
hcl->vmprim.log_write (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len);
|
||||
}
|
||||
|
||||
for (cb = hcl->cblist; cb; cb = cb->next)
|
||||
{
|
||||
if (cb->fini) cb->fini (hcl);
|
||||
}
|
||||
|
||||
if (hcl->log.len > 0)
|
||||
{
|
||||
/* flush pending log message that could be generated by the fini
|
||||
* callbacks. however, the actual logging might not be produced at
|
||||
* this point because one of the callbacks could arrange to stop
|
||||
* logging */
|
||||
HCL_ASSERT (hcl, hcl->log.ptr != HCL_NULL);
|
||||
hcl->vmprim.log_write (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len);
|
||||
}
|
||||
|
||||
/* deregister all callbacks */
|
||||
while (hcl->cblist) hcl_deregcb (hcl, hcl->cblist);
|
||||
|
||||
if (hcl->sem_list)
|
||||
{
|
||||
hcl_freemem (hcl, hcl->sem_list);
|
||||
@ -144,13 +185,6 @@ void hcl_fini (hcl_t* hcl)
|
||||
hcl->sem_heap_count = 0;
|
||||
}
|
||||
|
||||
for (cb = hcl->cblist; cb; cb = cb->next)
|
||||
{
|
||||
if (cb->fini) cb->fini (hcl);
|
||||
}
|
||||
|
||||
hcl_rbt_walk (&hcl->pmtable, unload_primitive_module, hcl);
|
||||
hcl_rbt_fini (&hcl->pmtable);
|
||||
|
||||
if (hcl->code.bc.arr)
|
||||
{
|
||||
@ -178,53 +212,33 @@ void hcl_fini (hcl_t* hcl)
|
||||
hcl_killheap (hcl, hcl->curheap);
|
||||
hcl_killheap (hcl, hcl->permheap);
|
||||
|
||||
/* deregister all callbacks */
|
||||
while (hcl->cblist) hcl_deregcb (hcl, hcl->cblist);
|
||||
|
||||
if (hcl->log.ptr)
|
||||
{
|
||||
/* make sure to flush your log message */
|
||||
/* TODO: flush unwritten message */
|
||||
|
||||
hcl_freemem (hcl, hcl->log.ptr);
|
||||
hcl->log.capa = 0;
|
||||
hcl->log.len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hcl_mmgr_t* hcl_getmmgr (hcl_t* hcl)
|
||||
{
|
||||
return hcl->mmgr;
|
||||
}
|
||||
|
||||
void* hcl_getxtn (hcl_t* hcl)
|
||||
{
|
||||
return (void*)(hcl + 1);
|
||||
}
|
||||
|
||||
|
||||
hcl_errnum_t hcl_geterrnum (hcl_t* hcl)
|
||||
{
|
||||
return hcl->errnum;
|
||||
}
|
||||
|
||||
void hcl_seterrnum (hcl_t* hcl, hcl_errnum_t errnum)
|
||||
{
|
||||
hcl->errnum = errnum;
|
||||
}
|
||||
|
||||
int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case HCL_TRAIT:
|
||||
hcl->option.trait = *(const int*)value;
|
||||
hcl->option.trait = *(const unsigned int*)value;
|
||||
#if !defined(NDEBUG)
|
||||
hcl->option.karatsuba_cutoff = ((hcl->option.trait & HCL_DEBUG_BIGINT)? HCL_KARATSUBA_CUTOFF_DEBUG: HCL_KARATSUBA_CUTOFF);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
case HCL_LOG_MASK:
|
||||
hcl->option.log_mask = *(const unsigned int*)value;
|
||||
return 0;
|
||||
|
||||
case HCL_LOG_MAXCAPA:
|
||||
hcl->option.log_maxcapa = *(hcl_oow_t*)value;
|
||||
return 0;
|
||||
|
||||
case HCL_SYMTAB_SIZE:
|
||||
{
|
||||
hcl_oow_t w;
|
||||
@ -260,7 +274,7 @@ int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value)
|
||||
}
|
||||
|
||||
einval:
|
||||
hcl->errnum = HCL_EINVAL;
|
||||
hcl_seterrnum (hcl, HCL_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -269,13 +283,17 @@ int hcl_getoption (hcl_t* hcl, hcl_option_t id, void* value)
|
||||
switch (id)
|
||||
{
|
||||
case HCL_TRAIT:
|
||||
*(int*)value = hcl->option.trait;
|
||||
*(unsigned int*)value = hcl->option.trait;
|
||||
return 0;
|
||||
|
||||
case HCL_LOG_MASK:
|
||||
*(unsigned int*)value = hcl->option.log_mask;
|
||||
return 0;
|
||||
|
||||
case HCL_LOG_MAXCAPA:
|
||||
*(hcl_oow_t*)value = hcl->option.log_maxcapa;
|
||||
return 0;
|
||||
|
||||
case HCL_SYMTAB_SIZE:
|
||||
*(hcl_oow_t*)value = hcl->option.dfl_symtab_size;
|
||||
return 0;
|
||||
@ -289,7 +307,7 @@ int hcl_getoption (hcl_t* hcl, hcl_option_t id, void* value)
|
||||
return 0;
|
||||
};
|
||||
|
||||
hcl->errnum = HCL_EINVAL;
|
||||
hcl_seterrnum (hcl, HCL_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -330,7 +348,7 @@ void* hcl_allocmem (hcl_t* hcl, hcl_oow_t size)
|
||||
void* ptr;
|
||||
|
||||
ptr = HCL_MMGR_ALLOC (hcl->mmgr, size);
|
||||
if (!ptr) hcl->errnum = HCL_ESYSMEM;
|
||||
if (!ptr) hcl_seterrnum (hcl, HCL_ESYSMEM);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -339,7 +357,7 @@ void* hcl_callocmem (hcl_t* hcl, hcl_oow_t size)
|
||||
void* ptr;
|
||||
|
||||
ptr = HCL_MMGR_ALLOC (hcl->mmgr, size);
|
||||
if (!ptr) hcl->errnum = HCL_ESYSMEM;
|
||||
if (!ptr) hcl_seterrnum (hcl, HCL_ESYSMEM);
|
||||
else HCL_MEMSET (ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
@ -347,7 +365,7 @@ void* hcl_callocmem (hcl_t* hcl, hcl_oow_t size)
|
||||
void* hcl_reallocmem (hcl_t* hcl, void* ptr, hcl_oow_t size)
|
||||
{
|
||||
ptr = HCL_MMGR_REALLOC (hcl->mmgr, ptr, size);
|
||||
if (!ptr) hcl->errnum = HCL_ESYSMEM;
|
||||
if (!ptr) hcl_seterrnum (hcl, HCL_ESYSMEM);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -359,13 +377,13 @@ void hcl_freemem (hcl_t* hcl, void* ptr)
|
||||
|
||||
void hcl_getsynerr (hcl_t* hcl, hcl_synerr_t* synerr)
|
||||
{
|
||||
HCL_ASSERT (hcl->c != HCL_NULL);
|
||||
HCL_ASSERT (hcl, hcl->c != HCL_NULL);
|
||||
if (synerr) *synerr = hcl->c->synerr;
|
||||
}
|
||||
|
||||
void hcl_setsynerr (hcl_t* hcl, hcl_synerrnum_t num, const hcl_ioloc_t* loc, const hcl_oocs_t* tgt)
|
||||
{
|
||||
hcl->errnum = HCL_ESYNERR;
|
||||
hcl_seterrnum (hcl, HCL_ESYNERR);
|
||||
hcl->c->synerr.num = num;
|
||||
|
||||
/* The SCO compiler complains of this ternary operation saying:
|
||||
|
Reference in New Issue
Block a user