memory handling

This commit is contained in:
Vitor Santos Costa 2017-09-26 15:15:15 +01:00
parent a40fbe420f
commit 46d997713f
13 changed files with 2433 additions and 2175 deletions

1106
C/atomic.c

File diff suppressed because it is too large Load Diff

View File

@ -2006,9 +2006,11 @@ static Int JumpToEnv() {
handler->cp_b != NULL) { handler->cp_b != NULL) {
handler = handler->cp_b; handler = handler->cp_b;
} }
pop_text_stack(1);
if (LOCAL_PrologMode & AsyncIntMode) { if (LOCAL_PrologMode & AsyncIntMode) {
Yap_signal(YAP_FAIL_SIGNAL); Yap_signal(YAP_FAIL_SIGNAL);
} }
B = handler; B = handler;
P = FAILCODE; P = FAILCODE;
return true; return true;

332
C/text.c
View File

@ -51,9 +51,16 @@ typedef struct TextBuffer_manager {
int lvl; int lvl;
} text_buffer_t; } text_buffer_t;
int push_text_stack(USES_REGS1) { return LOCAL_TextBuffer->lvl++; } int AllocLevel(void) { return LOCAL_TextBuffer->lvl; }
int push_text_stack__(USES_REGS1) {
int i = LOCAL_TextBuffer->lvl;
i++;
LOCAL_TextBuffer->lvl = i;
int pop_text_stack(int i) { return i;
}
int pop_text_stack__(int i) {
int lvl = LOCAL_TextBuffer->lvl; int lvl = LOCAL_TextBuffer->lvl;
while (lvl >= i) { while (lvl >= i) {
struct mblock *p = LOCAL_TextBuffer->first[lvl]; struct mblock *p = LOCAL_TextBuffer->first[lvl];
@ -66,7 +73,7 @@ int pop_text_stack(int i) {
LOCAL_TextBuffer->last[lvl] = NULL; LOCAL_TextBuffer->last[lvl] = NULL;
lvl--; lvl--;
} }
LOCAL_TextBuffer->lvl = i; LOCAL_TextBuffer->lvl = lvl;
return lvl; return lvl;
} }
@ -116,24 +123,25 @@ void *Malloc(size_t sz USES_REGS) {
return o + 1; return o + 1;
} }
void *Realloc(void *pt, size_t sz USES_REGS) { void *MallocAtLevel(size_t sz, int atL USES_REGS) {
int lvl = LOCAL_TextBuffer->lvl;
if (atL > 0 && atL <= lvl) {
lvl = atL;
} else if (atL < 0 && lvl - atL >= 0) {
lvl += atL;
} else {
return NULL;
}
if (sz == 0)
sz = 1024;
sz = ALIGN_BY_TYPE(sz + sizeof(struct mblock), CELL); sz = ALIGN_BY_TYPE(sz + sizeof(struct mblock), CELL);
struct mblock *old = pt, *o; struct mblock *o = malloc(sz);
old--; if (!o)
int lvl = old->lvl; return NULL;
o = realloc(old, sz);
if (o->prev)
o->prev->next = o;
if (o->next)
o->next->prev = o;
if (LOCAL_TextBuffer->first[lvl] == old) {
LOCAL_TextBuffer->first[lvl] = o;
}
if (LOCAL_TextBuffer->last[lvl] == old) {
LOCAL_TextBuffer->last[lvl] = o;
}
o->sz = sz; o->sz = sz;
o->lvl = lvl;
o->prev = o->next = 0;
insert_block(o);
return o + 1; return o + 1;
} }
@ -149,6 +157,17 @@ void *export_block(int i, void *protected USES_REGS) {
return o; return o;
} }
} }
void *Realloc(void *pt, size_t sz USES_REGS) {
sz += sizeof(struct mblock);
struct mblock *old = pt, *o;
old--;
release_block(old);
o = realloc(old, sz);
o->sz = sz;
insert_block(o);
return o + 1;
}
void Free(void *pt USES_REGS) { void Free(void *pt USES_REGS) {
struct mblock *o = pt; struct mblock *o = pt;
@ -179,96 +198,89 @@ static Term Globalize(Term v USES_REGS) {
return v; return v;
} }
static Int SkipListCodes(unsigned char **bufp, Term *l, Term **tailp, static void *codes2buf(Term t0, void *b0, bool *get_codes USES_REGS) {
Int *atoms, bool *wide, seq_tv_t *inp USES_REGS) { unsigned char *st0, *st, ar[16];
Int length = 0; Term t = t0;
Term v; /* temporary */ size_t length = 0;
*wide = false;
unsigned char *st0 = *bufp, *st;
bool atomst;
size_t max_lim = 1024;
if (!st0) { if (t == TermNil) {
st0 = Malloc(1024); st0 = Malloc(4);
st0[0] = 0;
export_block(0, st0);
return st0;
} }
if (!IsPairTerm(t))
do_derefa(v, l, derefa_unk, derefa_nonvar); return NULL;
*tailp = l; bool codes = IsIntegerTerm(HeadOfTerm(t));
if (get_codes)
*bufp = st = st0; *get_codes = codes;
if (codes) {
if (*l == TermNil) { while (IsPairTerm(t)) {
st[0] = '\0'; Term hd = HeadOfTerm(t);
return 0;
}
if (IsPairTerm(*l)) {
Term hd0 = HeadOfTerm(*l);
if (IsVarTerm(hd0)) {
return -INSTANTIATION_ERROR;
}
// are we looking for atoms/codes?
// whatever the case, we should be consistent throughout,
// so we should be consistent with the first arg.
if (st > st0 + max_lim) {
max_lim += 2048;
*bufp = st0 = Realloc(st0, max_lim);
}
if (IsAtomTerm(hd0)) {
atomst = true;
} else {
atomst = false;
}
while (IsPairTerm(*l)) {
int ch;
length++;
{
Term hd = Deref(RepPair(*l)[0]);
if (IsVarTerm(hd)) { if (IsVarTerm(hd)) {
return -INSTANTIATION_ERROR; Yap_Error(INSTANTIATION_ERROR, t0, "scanning list of codes");
} else if (IsAtomTerm(hd)) { return NULL;
if (!atomst) {
return -REPRESENTATION_ERROR_CHARACTER;
} else {
AtomEntry *ae = RepAtom(AtomOfTerm(hd));
st = (unsigned char *)stpcpy((char *)st, ae->StrOfAE);
} }
} else if (IsIntegerTerm(hd)) { if (!IsIntegerTerm(hd)) {
ch = IntegerOfTerm(hd); Yap_Error(TYPE_ERROR_INTEGER, t0, "scanning list of codes");
if (atomst) return NULL;
return -REPRESENTATION_ERROR_CHARACTER; }
else if (ch < 0) { Int code = IntegerOfTerm(hd);
*tailp = l; if (code < 0) {
return -REPRESENTATION_ERROR_CHARACTER_CODE; Yap_Error(REPRESENTATION_ERROR_CHARACTER_CODE, t0,
} else { "scanning list of codes");
st += put_utf8(st, ch); return NULL;
}
length += put_utf8(ar, code);
t = TailOfTerm(t);
} }
} else { } else {
return -TYPE_ERROR_INTEGER; while (IsPairTerm(t)) {
Term hd = HeadOfTerm(t);
if (!IsAtomTerm(hd)) {
Yap_Error(TYPE_ERROR_ATOM, t0, "scanning list of atoms");
return NULL;
} }
if (length < 0) { const char *code = RepAtom(AtomOfTerm(hd))->StrOfAE;
*tailp = l; if (code < 0) {
return length; Yap_Error(REPRESENTATION_ERROR_CHARACTER, t0, "scanning list of atoms");
return NULL;
}
length += strlen(code);
t = TailOfTerm(t);
} }
} }
l = RepPair(*l) + 1; if (!IsVarTerm(t)) {
do_derefa(v, l, derefa2_unk, derefa2_nonvar); if (t != TermNil) {
Yap_Error(TYPE_ERROR_INTEGER, t0, "scanning list of codes");
return NULL;
} }
} }
if (IsVarTerm(*l)) {
return -INSTANTIATION_ERROR; st0 = st = Malloc(length + 1);
export_block(0, st0);
t = t0;
if (codes) {
while (IsPairTerm(t)) {
Term hd = HeadOfTerm(t);
Int code = IntegerOfTerm(hd);
st = st + put_utf8(st, code);
t = TailOfTerm(t);
}
} else {
while (IsPairTerm(t)) {
Term hd = HeadOfTerm(t);
const char *code = RepAtom(AtomOfTerm(hd))->StrOfAE;
st = (unsigned char *)stpcpy((char *)st, code);
t = TailOfTerm(t);
} }
if (*l != TermNil) {
return -TYPE_ERROR_LIST;
} }
st[0] = '\0'; st[0] = '\0';
*tailp = l;
*atoms = length;
length = (st - st0);
return length; return st0;
} }
static unsigned char *latin2utf8(seq_tv_t *inp) { static unsigned char *latin2utf8(seq_tv_t *inp) {
@ -281,8 +293,9 @@ static unsigned char *latin2utf8(seq_tv_t *inp) {
return NULL; return NULL;
while ((ch = *b0++)) { while ((ch = *b0++)) {
int off = put_utf8(pt, ch); int off = put_utf8(pt, ch);
if (off < 0) if (off < 0) {
continue; continue;
}
pt += off; pt += off;
} }
*pt++ = '\0'; *pt++ = '\0';
@ -304,41 +317,28 @@ static unsigned char *wchar2utf8(seq_tv_t *inp) {
static void *slice(size_t min, size_t max, const unsigned char *buf USES_REGS); static void *slice(size_t min, size_t max, const unsigned char *buf USES_REGS);
static unsigned char *to_buffer(unsigned char *buf, Term t, seq_tv_t *inp,
bool *widep, Int *atoms USES_REGS) {
CELL *r = NULL;
Int n;
unsigned char *bufc = buf;
if (bufc == NULL) {
bufc = malloc(1024);
}
n = SkipListCodes(&bufc, &t, &r, atoms, widep, inp PASS_REGS);
if (n < 0) {
LOCAL_Error_TYPE = -n;
return NULL;
}
return bufc;
}
static unsigned char *Yap_ListOfCodesToBuffer(unsigned char *buf, Term t, static unsigned char *Yap_ListOfCodesToBuffer(unsigned char *buf, Term t,
seq_tv_t *inp, seq_tv_t *inp USES_REGS) {
bool *widep USES_REGS) { bool codes;
Int atoms = 1; // we only want lists of atoms unsigned char *nbuf = codes2buf(t, buf, &codes PASS_REGS);
return to_buffer(buf, t, inp, widep, &atoms PASS_REGS); if (!codes)
return NULL;
return nbuf;
} }
static unsigned char *Yap_ListOfAtomsToBuffer(unsigned char *buf, Term t, static unsigned char *Yap_ListOfAtomsToBuffer(unsigned char *buf, Term t,
seq_tv_t *inp, seq_tv_t *inp USES_REGS) {
bool *widep USES_REGS) { bool codes;
Int atoms = 2; // we only want lists of integer codes unsigned char *nbuf = codes2buf(t, buf, &codes PASS_REGS);
return to_buffer(buf, t, inp, widep, &atoms PASS_REGS); if (!codes)
return NULL;
return nbuf;
} }
static unsigned char *Yap_ListToBuffer(unsigned char *buf, Term t, static unsigned char *Yap_ListToBuffer(unsigned char *buf, Term t,
seq_tv_t *inp, bool *widep USES_REGS) { seq_tv_t *inp USES_REGS) {
Int atoms = 0; // we accept both types of lists. unsigned char *nbuf = codes2buf(t, buf, NULL PASS_REGS);
return to_buffer(buf, t, inp, widep, &atoms PASS_REGS); return nbuf;
} }
#if USE_GEN_TYPE_ERROR #if USE_GEN_TYPE_ERROR
@ -369,13 +369,7 @@ static yap_error_number gen_type_error(int flags) {
// static int cnt; // static int cnt;
unsigned char *Yap_readText(seq_tv_t *inp USES_REGS) { unsigned char *Yap_readText(seq_tv_t *inp USES_REGS) {
unsigned char *s0 = NULL;
bool wide;
if (LOCAL_Error_TYPE != YAP_NO_ERROR) {
fprintf(stderr, "Spurious error %u\n", LOCAL_Error_TYPE);
LOCAL_Error_TYPE = YAP_NO_ERROR;
}
/* we know what the term is */ /* we know what the term is */
if (!(inp->type & (YAP_STRING_CHARS | YAP_STRING_WCHARS))) { if (!(inp->type & (YAP_STRING_CHARS | YAP_STRING_WCHARS))) {
if (!(inp->type & YAP_STRING_TERM)) { if (!(inp->type & YAP_STRING_TERM)) {
@ -401,25 +395,32 @@ unsigned char *Yap_readText(seq_tv_t *inp USES_REGS) {
// this is a term, extract to a buffer, and representation is wide // this is a term, extract to a buffer, and representation is wide
// Yap_DebugPlWriteln(inp->val.t); // Yap_DebugPlWriteln(inp->val.t);
Atom at = AtomOfTerm(inp->val.t); Atom at = AtomOfTerm(inp->val.t);
if (RepAtom(at)->UStrOfAE[0] == 0) {
unsigned char *o = Malloc(4);
memset(o, 0, 4);
return o;
}
if (inp->type & YAP_STRING_WITH_BUFFER) if (inp->type & YAP_STRING_WITH_BUFFER)
return at->UStrOfAE; return at->UStrOfAE;
size_t sz = strlen(at->StrOfAE); size_t sz = strlen(at->StrOfAE);
inp->type |= YAP_STRING_IN_TMP; inp->type |= YAP_STRING_IN_TMP;
char *o = Malloc(sz + 1); char *o = BaseMalloc(sz + 1);
strcpy(o, at->StrOfAE); strcpy(o, at->StrOfAE);
o = export_block(0, o);
return (unsigned char *)o; return (unsigned char *)o;
} }
if (IsStringTerm(inp->val.t) && inp->type & YAP_STRING_STRING) { if (IsStringTerm(inp->val.t) && inp->type & YAP_STRING_STRING) {
// this is a term, extract to a buffer, and representation is wide // this is a term, extract to a buffer, and representation is wide
// Yap_DebugPlWriteln(inp->val.t); // Yap_DebugPlWriteln(inp->val.t);
const char *s = StringOfTerm(inp->val.t); const char *s = StringOfTerm(inp->val.t);
if (s[0] == 0) {
char *o = BaseMalloc(4);
memset(o, 0, 4);
}
if (inp->type & YAP_STRING_WITH_BUFFER) if (inp->type & YAP_STRING_WITH_BUFFER)
return (unsigned char *)UStringOfTerm(inp->val.t); return (unsigned char *)UStringOfTerm(inp->val.t);
inp->type |= YAP_STRING_IN_TMP; inp->type |= YAP_STRING_IN_TMP;
size_t sz = strlen(s); size_t sz = strlen(s);
char *o = Malloc(sz + 1); char *o = BaseMalloc(sz + 1);
o = export_block(0, o);
strcpy(o, s); strcpy(o, s);
return (unsigned char *)o; return (unsigned char *)o;
} }
@ -427,24 +428,24 @@ unsigned char *Yap_readText(seq_tv_t *inp USES_REGS) {
(YAP_STRING_CODES | YAP_STRING_ATOMS)) && (YAP_STRING_CODES | YAP_STRING_ATOMS)) &&
IsPairOrNilTerm(inp->val.t)) { IsPairOrNilTerm(inp->val.t)) {
// Yap_DebugPlWriteln(inp->val.t); // Yap_DebugPlWriteln(inp->val.t);
return Yap_ListToBuffer(s0, inp->val.t, inp, &wide PASS_REGS); return Yap_ListToBuffer(NULL, inp->val.t, inp PASS_REGS);
// this is a term, extract to a sfer, and representation is wide // this is a term, extract to a sfer, and representation is wide
} }
if (inp->type & YAP_STRING_CODES && IsPairOrNilTerm(inp->val.t)) { if (inp->type & YAP_STRING_CODES && IsPairOrNilTerm(inp->val.t)) {
// Yap_DebugPlWriteln(inp->val.t); // Yap_DebugPlWriteln(inp->val.t);
return Yap_ListOfCodesToBuffer(s0, inp->val.t, inp, &wide PASS_REGS); return Yap_ListOfCodesToBuffer(NULL, inp->val.t, inp PASS_REGS);
// this is a term, extract to a sfer, and representation is wide // this is a term, extract to a sfer, and representation is wide
} }
if (inp->type & YAP_STRING_ATOMS && IsPairOrNilTerm(inp->val.t)) { if (inp->type & YAP_STRING_ATOMS && IsPairOrNilTerm(inp->val.t)) {
// Yap_DebugPlWriteln(inp->val.t); // Yap_DebugPlWriteln(inp->val.t);
return Yap_ListOfAtomsToBuffer(s0, inp->val.t, inp, &wide PASS_REGS); return Yap_ListOfAtomsToBuffer(NULL, inp->val.t, inp PASS_REGS);
// this is a term, extract to a buffer, and representation is wide // this is a term, extract to a buffer, and representation is wide
} }
if (inp->type & YAP_STRING_INT && IsIntegerTerm(inp->val.t)) { if (inp->type & YAP_STRING_INT && IsIntegerTerm(inp->val.t)) {
// ASCII, so both LATIN1 and UTF-8 // ASCII, so both LATIN1 and UTF-8
// Yap_DebugPlWriteln(inp->val.t); // Yap_DebugPlWriteln(inp->val.t);
char *s; char *s;
s = Malloc(2 * MaxTmp(PASS_REGS1)); s = BaseMalloc(2 * MaxTmp(PASS_REGS1));
if (snprintf(s, MaxTmp(PASS_REGS1) - 1, Int_FORMAT, if (snprintf(s, MaxTmp(PASS_REGS1) - 1, Int_FORMAT,
IntegerOfTerm(inp->val.t)) < 0) { IntegerOfTerm(inp->val.t)) < 0) {
AUX_ERROR(inp->val.t, 2 * MaxTmp(PASS_REGS1), s, char); AUX_ERROR(inp->val.t, 2 * MaxTmp(PASS_REGS1), s, char);
@ -463,7 +464,7 @@ unsigned char *Yap_readText(seq_tv_t *inp USES_REGS) {
if (inp->type & YAP_STRING_BIG && IsBigIntTerm(inp->val.t)) { if (inp->type & YAP_STRING_BIG && IsBigIntTerm(inp->val.t)) {
// Yap_DebugPlWriteln(inp->val.t); // Yap_DebugPlWriteln(inp->val.t);
char *s; char *s;
s = Malloc(MaxTmp()); s = BaseMalloc(MaxTmp());
if (!Yap_mpz_to_string(Yap_BigIntOfTerm(inp->val.t), s, MaxTmp() - 1, 10)) { if (!Yap_mpz_to_string(Yap_BigIntOfTerm(inp->val.t), s, MaxTmp() - 1, 10)) {
AUX_ERROR(inp->val.t, MaxTmp(PASS_REGS1), s, char); AUX_ERROR(inp->val.t, MaxTmp(PASS_REGS1), s, char);
} }
@ -627,29 +628,29 @@ static Atom write_atom(void *s0, seq_tv_t *out USES_REGS) {
} }
} }
size_t write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) {
size_t leng = strlen((char *)s0); size_t leng = strlen((char *)s0);
size_t min = 0, max = leng, room_end; size_t min = 0, max = leng;
if (out->enc == ENC_ISO_UTF8) { if (out->enc == ENC_ISO_UTF8) {
room_end = strlen((char *)s0) + 1; if (true || out->val.uc == NULL) { // this should always be the case
if (out->val.uc == NULL) { // this should always be the case out->val.uc = BaseMalloc(leng + 1);
out->val.uc = malloc(room_end < 16 ? 16 : room_end); strcpy(out->val.c, (char *)s0);
} } else if (out->val.uc != s0) {
if (out->val.uc != s0) { out->val.c = Realloc(out->val.c, leng + 1);
strcpy(out->val.c, (char *)s0); strcpy(out->val.c, (char *)s0);
} }
} else if (out->enc == ENC_ISO_LATIN1) { } else if (out->enc == ENC_ISO_LATIN1) {
room_end = strlen((char *)s0) + 1;
unsigned char *s = s0; unsigned char *s = s0;
unsigned char *cp = s; unsigned char *cp = s;
unsigned char *buf = out->val.uc; unsigned char *buf = out->val.uc;
if (!buf) if (!buf)
return -1; return NULL;
while (*cp) { while (*cp) {
utf8proc_int32_t chr; utf8proc_int32_t chr;
int off = get_utf8(cp, -1, &chr); int off = get_utf8(cp, -1, &chr);
if (off <= 0 || chr > 255) if (off <= 0 || chr > 255)
return -1; return NULL;
if (off == max) if (off == max)
break; break;
cp += off; cp += off;
@ -664,7 +665,6 @@ size_t write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) {
cp += get_utf8(cp, -1, &chr); cp += get_utf8(cp, -1, &chr);
*buf++ = chr; *buf++ = chr;
} }
room_end = buf - out->val.uc;
} else if (out->enc == ENC_WCHAR) { } else if (out->enc == ENC_WCHAR) {
unsigned char *s = s0, *lim = s + (max = strnlen((char *)s0, max)); unsigned char *s = s0, *lim = s + (max = strnlen((char *)s0, max));
unsigned char *cp = s; unsigned char *cp = s;
@ -672,7 +672,7 @@ size_t write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) {
buf = buf0 = out->val.w; buf = buf0 = out->val.w;
if (!buf) if (!buf)
return -1; return NULL;
while (*cp && cp < lim) { while (*cp && cp < lim) {
utf8proc_int32_t chr; utf8proc_int32_t chr;
cp += get_utf8(cp, -1, &chr); cp += get_utf8(cp, -1, &chr);
@ -688,12 +688,11 @@ size_t write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) {
*buf++ = chr; *buf++ = chr;
} }
*buf = '\0'; *buf = '\0';
room_end = (buf - buf0) + 1;
} else { } else {
// no other encodings are supported. // no other encodings are supported.
room_end = -1; return NULL;
} }
return room_end; return out->val.c;
} }
static size_t write_length(const unsigned char *s0, seq_tv_t *out USES_REGS) { static size_t write_length(const unsigned char *s0, seq_tv_t *out USES_REGS) {
@ -726,10 +725,6 @@ bool write_Text(unsigned char *inp, seq_tv_t *out USES_REGS) {
return true; return true;
} }
if (out->type & YAP_STRING_DATUM) {
if ((out->val.t = string_to_term(inp, out PASS_REGS)) != 0L)
return out->val.t != 0;
}
if (out->type & (YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_BIG)) { if (out->type & (YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_BIG)) {
if ((out->val.t = write_number( if ((out->val.t = write_number(
inp, out, !(out->type & YAP_STRING_ATOM) PASS_REGS)) != 0L) { inp, out, !(out->type & YAP_STRING_ATOM) PASS_REGS)) != 0L) {
@ -750,17 +745,21 @@ bool write_Text(unsigned char *inp, seq_tv_t *out USES_REGS) {
return at != NIL; return at != NIL;
} }
} }
if (out->type & YAP_STRING_DATUM) {
if ((out->val.t = string_to_term(inp, out PASS_REGS)) != 0L)
return out->val.t != 0;
}
switch (out->type & YAP_TYPE_MASK) { switch (out->type & YAP_TYPE_MASK) {
case YAP_STRING_CHARS: { case YAP_STRING_CHARS: {
size_t room = write_buffer(inp, out PASS_REGS); void *room = write_buffer(inp, out PASS_REGS);
// printf("%s\n", out->val.c); // printf("%s\n", out->val.c);
return ((Int)room > 0); return room != NULL;
} }
case YAP_STRING_WCHARS: { case YAP_STRING_WCHARS: {
size_t room = write_buffer(inp, out PASS_REGS); void *room = write_buffer(inp, out PASS_REGS);
// printf("%S\n", out->val.w); // printf("%S\n", out->val.w);
return ((Int)room > 0); return room != NULL;
} }
case YAP_STRING_STRING: case YAP_STRING_STRING:
out->val.t = write_strings(inp, out PASS_REGS); out->val.t = write_strings(inp, out PASS_REGS);
@ -821,7 +820,7 @@ bool Yap_CVT_Text(seq_tv_t *inp, seq_tv_t *out USES_REGS) {
unsigned char *buf; unsigned char *buf;
bool rc; bool rc;
/* /*
f//printfmark(stderr, "[ %d ", n++) ; //printf(stderr, "[ %d ", n++) ;
if (inp->type & (YAP_STRING_TERM|YAP_STRING_ATOM|YAP_STRING_ATOMS_CODES if (inp->type & (YAP_STRING_TERM|YAP_STRING_ATOM|YAP_STRING_ATOMS_CODES
|YAP_STRING_STRING)) |YAP_STRING_STRING))
//Yap_DebugPlWriteln(inp->val.t); //Yap_DebugPlWriteln(inp->val.t);
@ -970,6 +969,9 @@ bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp,
return false; return false;
} }
b_l = strlen((char *)buf); b_l = strlen((char *)buf);
if (b_l == 0) {
return false;
}
u_l = strlen_utf8(buf); u_l = strlen_utf8(buf);
if (!cuts) { if (!cuts) {
if (n == 2) { if (n == 2) {
@ -1091,8 +1093,8 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) {
smax = s + 1024; smax = s + 1024;
Term tmod = ap->ModuleOfPred; Term tmod = ap->ModuleOfPred;
if (tmod) { if (tmod) {
Yap_AtomToUTF8Text(AtomOfTerm(tmod), s); char *sn = Yap_AtomToUTF8Text(AtomOfTerm(tmod));
s += strlen(s); stpcpy(s, sn);
if (smax - s > 1) { if (smax - s > 1) {
strcat(s, ":"); strcat(s, ":");
} else { } else {
@ -1114,7 +1116,7 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) {
return LOCAL_FileNameBuf; return LOCAL_FileNameBuf;
} else if (ap->PredFlags & AtomDBPredFlag) { } else if (ap->PredFlags & AtomDBPredFlag) {
at = (Atom)(ap->FunctorOfPred); at = (Atom)(ap->FunctorOfPred);
if (!Yap_AtomToUTF8Text(at, s)) if (!stpcpy(s, Yap_AtomToUTF8Text(at)))
return NULL; return NULL;
} else { } else {
f = ap->FunctorOfPred; f = ap->FunctorOfPred;
@ -1129,7 +1131,7 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) {
at = (Atom)(ap->FunctorOfPred); at = (Atom)(ap->FunctorOfPred);
} }
} }
if (!Yap_AtomToUTF8Text(at, s)) { if (!stpcpy(s,Yap_AtomToUTF8Text(at))) {
return NULL; return NULL;
} }
s += strlen(s); s += strlen(s);

View File

@ -346,7 +346,7 @@ bool low_level_trace__(yap_low_level_port port, PredEntry *pred, CELL *args) {
if (p == pe) { if (p == pe) {
UNLOCK(Yap_heap_regs->low_level_trace_lock); UNLOCK(Yap_heap_regs->low_level_trace_lock);
pop_text_stack(l); pop_text_stack(l);
ReleaseAndReturn(true); return (true);
} }
if (env_ptr != NULL) if (env_ptr != NULL)
env_ptr = (CELL *)(env_ptr[E_E]); env_ptr = (CELL *)(env_ptr[E_E]);
@ -354,7 +354,8 @@ bool low_level_trace__(yap_low_level_port port, PredEntry *pred, CELL *args) {
printf("\n"); printf("\n");
} }
#endif #endif
b += snprintf(b, top - b, "%llud "UInt_FORMAT " ", vsc_count, LCL0 - (CELL *)B); b += snprintf(b, top - b, "%llud " UInt_FORMAT " ", vsc_count,
LCL0 - (CELL *)B);
b += snprintf(b, top - b, Int_FORMAT " ", LCL0 - (CELL *)Yap_REGS.CUT_C_TOP); b += snprintf(b, top - b, Int_FORMAT " ", LCL0 - (CELL *)Yap_REGS.CUT_C_TOP);
#if defined(THREADS) || defined(YAPOR) #if defined(THREADS) || defined(YAPOR)
b += snprintf(b, top - b, "(%d)", worker_id); b += snprintf(b, top - b, "(%d)", worker_id);
@ -363,12 +364,13 @@ bool low_level_trace__(yap_low_level_port port, PredEntry *pred, CELL *args) {
if (pred == NULL) { if (pred == NULL) {
UNLOCK(Yap_low_level_trace_lock); UNLOCK(Yap_low_level_trace_lock);
pop_text_stack(l); pop_text_stack(l);
ReleaseAndReturn(true); return (true);
} }
if (pred->ModuleOfPred == PROLOG_MODULE) { if (pred->ModuleOfPred == PROLOG_MODULE) {
if (!LOCAL_do_trace_primitives) { if (!LOCAL_do_trace_primitives) {
UNLOCK(Yap_low_level_trace_lock); UNLOCK(Yap_low_level_trace_lock);
ReleaseAndReturn(true); pop_text_stack(l);
return (true);
} }
mname = "prolog"; mname = "prolog";
} else { } else {
@ -460,7 +462,7 @@ bool low_level_trace__(yap_low_level_port port, PredEntry *pred, CELL *args) {
fputs(buf, stderr); fputs(buf, stderr);
#endif #endif
pop_text_stack(l); pop_text_stack(l);
ReleaseAndReturn(true); return (true);
} }
void toggle_low_level_trace(void) { void toggle_low_level_trace(void) {

View File

@ -390,7 +390,7 @@ int Yap_FormatFloat(Float f, char **s, size_t sz) {
wglb.stream = GLOBAL_Stream + sno; wglb.stream = GLOBAL_Stream + sno;
wrputf(f, &wglb); wrputf(f, &wglb);
so = Yap_MemExportStreamPtr(sno); so = Yap_MemExportStreamPtr(sno);
*s = Malloc( strlen(so)+1 ); *s = BaseMalloc( strlen(so)+1 );
strcpy(*s, so ); strcpy(*s, so );
Yap_CloseStream(sno); Yap_CloseStream(sno);
return true; return true;

View File

@ -406,7 +406,7 @@ YAPListTerm::YAPListTerm(YAPTerm ts[], arity_t n)
} }
} }
const char *YAPAtom::getName(void) { return Yap_AtomToUTF8Text(a, nullptr); } const char *YAPAtom::getName(void) { return Yap_AtomToUTF8Text(a); }
void YAPQuery::openQuery(Term *ts) void YAPQuery::openQuery(Term *ts)
{ {

View File

@ -31,31 +31,14 @@
#include "../utf8proc/utf8proc.h" #include "../utf8proc/utf8proc.h"
#include "Yap.h" #include "Yap.h"
#define ReleaseAndReturn(r) \
{ \
pop_text_stack(l); \
return r; \
}
#define release_cut_fail() \
{ \
pop_text_stack(l); \
cut_fail(); \
}
#define release_cut_succeed() \
{ \
pop_text_stack(l); \
cut_succeed(); \
}
/// allocate a temporary text block /// allocate a temporary text block
/// ///
extern void *Malloc(size_t sz USES_REGS); extern void *Malloc(size_t sz USES_REGS);
extern void *Realloc(void *buf, size_t sz USES_REGS); extern void *Realloc(void *buf, size_t sz USES_REGS);
extern void Free(void *buf USES_REGS); extern void Free(void *buf USES_REGS);
extern int push_text_stack(USES_REGS1); extern void *MallocAtLevel(size_t sz, int atL USES_REGS);
extern int pop_text_stack(int lvl USES_REGS); #define BaseMalloc(sz) MallocAtLevel(sz, 1)
extern void *export_block(int lvl, void *exp USES_REGS);
#ifndef Yap_Min #ifndef Yap_Min
#define Yap_Min(x, y) (x < y ? x : y) #define Yap_Min(x, y) (x < y ? x : y)
@ -65,6 +48,17 @@ extern void *export_block(int lvl, void *exp USES_REGS);
#define MBYTE (1024 * 1024) #define MBYTE (1024 * 1024)
/* Character types for tokenizer and write.c */ /* Character types for tokenizer and write.c */
extern int AllocLevel(void);
#define push_text_stack() \
(/* fprintf(stderr, "^ %*c %s:%s:%d\n", AllocLevel(), AllocLevel()+'0', __FILE__, __FUNCTION__, __LINE__), */ \
push_text_stack__(PASS_REGS1))
extern int push_text_stack__(USES_REGS1);
#define pop_text_stack(lvl) \
(/*fprintf(stderr, "v %*c %s:%s:%d\n", AllocLevel(), ' ', __FILE__, __FUNCTION__, __LINE__),*/ \
pop_text_stack__(lvl))
extern int pop_text_stack__(int lvl USES_REGS);
/****************** character definition table **************************/ /****************** character definition table **************************/
@ -878,24 +872,8 @@ static inline Term Yap_CharsToString(const char *s, encoding_t enc USES_REGS) {
return out.val.t; return out.val.t;
} }
static inline char *Yap_AtomToUTF8Text(Atom at, const char *s USES_REGS) { static inline char *Yap_AtomToUTF8Text(Atom at USES_REGS) {
seq_tv_t inp, out; return RepAtom(at)->StrOfAE;
inp.val.a = at;
inp.type = YAP_STRING_ATOM;
out.type = YAP_STRING_CHARS;
out.val.uc = NULL;
out.enc = ENC_ISO_UTF8;
if (s) {
out.val.c0 = s;
out.type |= YAP_STRING_WITH_BUFFER;
} else {
out.type |= YAP_STRING_MALLOC;
out.val.c = NULL;
}
if (!Yap_CVT_Text(&inp, &out PASS_REGS))
return 0L;
return out.val.c;
} }
static inline Term Yap_CharsToTDQ(const char *s, Term mod, static inline Term Yap_CharsToTDQ(const char *s, Term mod,
@ -1635,6 +1613,5 @@ static inline Term Yap_SubtractTailString(Term t1, Term th USES_REGS) {
#endif // ≈YAP_TEXT_H #endif // ≈YAP_TEXT_H
const char *Yap_TextTermToText(Term t, char *bufwrite_Text, const char *Yap_TextTermToText(Term t, char *s, encoding_t e USES_REGS);
encoding_t e USES_REGS);
Term Yap_MkTextTerm(const char *s, encoding_t e, Term tguide); Term Yap_MkTextTerm(const char *s, encoding_t e, Term tguide);

View File

@ -223,12 +223,13 @@ X_API int PL_get_nchars(term_t l, size_t *lengthp, char **s, unsigned flags) {
out.type |= YAP_STRING_NCHARS; out.type |= YAP_STRING_NCHARS;
out.max = *lengthp; out.max = *lengthp;
} }
char *sf = malloc(strlen(out.val.c)+1);
strcpy(sf, out.val.c);
if (!Yap_CVT_Text(&inp, &out PASS_REGS)) { if (!Yap_CVT_Text(&inp, &out PASS_REGS)) {
pop_text_stack(lvl); pop_text_stack(lvl);
return false; return false;
} }
out.val.c = export_block(-1, out.val.c PASS_REGS); *s = out.val.c = sf;
*s = out.val.c;
return true; return true;
} }

View File

@ -453,11 +453,11 @@ static Int is_absolute_file_name(USES_REGS1) { /* file_base_name(Stream,N) */
Term t = Deref(ARG1); Term t = Deref(ARG1);
Atom at; Atom at;
bool rc; bool rc;
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
Yap_Error(INSTANTIATION_ERROR, t, "file_base_name/2"); Yap_Error(INSTANTIATION_ERROR, t, "file_base_name/2");
return false; return false;
} }
int l = push_text_stack();
const char *buf = Yap_TextTermToText(t, NULL, LOCAL_encoding); const char *buf = Yap_TextTermToText(t, NULL, LOCAL_encoding);
if (buf) { if (buf) {
rc = Yap_IsAbsolutePath(buf); rc = Yap_IsAbsolutePath(buf);
@ -468,8 +468,8 @@ static Int is_absolute_file_name(USES_REGS1) { /* file_base_name(Stream,N) */
#else #else
rc = RepAtom(at)->StrOfAE[0] == '/'; rc = RepAtom(at)->StrOfAE[0] == '/';
#endif #endif
freeBuffer(buf);
} }
pop_text_stack(l);
return rc; return rc;
} }

View File

@ -335,9 +335,9 @@ format_clean_up(int sno, int sno0, format_info *finf, const unsigned char *fstr,
sno = format_synch(sno, sno0, finf); sno = format_synch(sno, sno0, finf);
Yap_CloseStream(sno); Yap_CloseStream(sno);
} }
if (fstr) {
free((void *)fstr); pop_text_stack(finf->lvl);
}
if (targs) if (targs)
Yap_FreeAtomSpace((void *)targs); Yap_FreeAtomSpace((void *)targs);
} }
@ -409,17 +409,21 @@ static Int doformat(volatile Term otail, volatile Term oargs,
args = oargs; args = oargs;
tail = otail; tail = otail;
targ = 0; targ = 0;
int l = push_text_stack();
if (IsVarTerm(tail)) { if (IsVarTerm(tail)) {
pop_text_stack(l);
Yap_Error(INSTANTIATION_ERROR, tail, "format/2"); Yap_Error(INSTANTIATION_ERROR, tail, "format/2");
return (FALSE); return (FALSE);
} else if ((fptr = Yap_TextToUTF8Buffer(tail))) { } else if ((fptr = Yap_TextToUTF8Buffer(tail))) {
fstr = fptr; fstr = fptr;
alloc_fstr = true; alloc_fstr = true;
} else { } else {
pop_text_stack(l);
Yap_Error(TYPE_ERROR_TEXT, tail, "format/2"); Yap_Error(TYPE_ERROR_TEXT, tail, "format/2");
return false; return false;
} }
if (IsVarTerm(args)) { if (IsVarTerm(args)) {
pop_text_stack(l);
Yap_Error(INSTANTIATION_ERROR, args, "format/2"); Yap_Error(INSTANTIATION_ERROR, args, "format/2");
return FALSE; return FALSE;
} }
@ -427,14 +431,17 @@ static Int doformat(volatile Term otail, volatile Term oargs,
fmod = ArgOfTerm(1, args); fmod = ArgOfTerm(1, args);
args = ArgOfTerm(2, args); args = ArgOfTerm(2, args);
if (IsVarTerm(fmod)) { if (IsVarTerm(fmod)) {
pop_text_stack(l);
Yap_Error(INSTANTIATION_ERROR, fmod, "format/2"); Yap_Error(INSTANTIATION_ERROR, fmod, "format/2");
return FALSE; return FALSE;
} }
if (!IsAtomTerm(fmod)) { if (!IsAtomTerm(fmod)) {
pop_text_stack(l);
Yap_Error(TYPE_ERROR_ATOM, fmod, "format/2"); Yap_Error(TYPE_ERROR_ATOM, fmod, "format/2");
return FALSE; return FALSE;
} }
if (IsVarTerm(args)) { if (IsVarTerm(args)) {
pop_text_stack(l);
Yap_Error(INSTANTIATION_ERROR, args, "format/2"); Yap_Error(INSTANTIATION_ERROR, args, "format/2");
return FALSE; return FALSE;
} }
@ -470,6 +477,7 @@ static Int doformat(volatile Term otail, volatile Term oargs,
finfo.gapi = 0; finfo.gapi = 0;
finfo.phys_start = 0; finfo.phys_start = 0;
finfo.lstart = 0; finfo.lstart = 0;
finfo.lvl = l;
if (true || !(GLOBAL_Stream[sno].status & InMemory_Stream_f)) if (true || !(GLOBAL_Stream[sno].status & InMemory_Stream_f))
sno = Yap_OpenBufWriteStream(PASS_REGS1); sno = Yap_OpenBufWriteStream(PASS_REGS1);
if (sno < 0) { if (sno < 0) {

View File

@ -18,6 +18,7 @@ typedef struct format_status {
// number of characters // number of characters
int lstart; int lstart;
int gapi; int gapi;
int lvl;
} format_info; } format_info;
#define FORMAT_COPY_ARGS_ERROR -1 #define FORMAT_COPY_ARGS_ERROR -1

View File

@ -171,7 +171,7 @@ static const char *PlExpandVars(const char *source, const char *root,
CACHE_REGS CACHE_REGS
const char *src = source; const char *src = source;
if (!result) if (!result)
result = malloc(YAP_FILENAME_MAX + 1); result = BaseMalloc(YAP_FILENAME_MAX + 1);
if (strlen(source) >= YAP_FILENAME_MAX) { if (strlen(source) >= YAP_FILENAME_MAX) {
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, TermNil, Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, TermNil,
@ -844,19 +844,22 @@ static Int expand_file_name3(USES_REGS1) {
static Int absolute_file_system_path(USES_REGS1) { static Int absolute_file_system_path(USES_REGS1) {
Term t = Deref(ARG1); Term t = Deref(ARG1);
int l = push_text_stack();
const char *text = Yap_TextTermToText(t, NULL, LOCAL_encoding);
const char *fp; const char *fp;
bool rc; bool rc;
char s[MAXPATHLEN + 1];
const char *text = Yap_TextTermToText(t, s, LOCAL_encoding);
if (text == NULL) { if (text == NULL) {
pop_text_stack(l);
return false; return false;
} }
if (!(fp = Yap_AbsoluteFile(RepAtom(AtomOfTerm(t))->StrOfAE, NULL, true))) if (!(fp = Yap_AbsoluteFile(RepAtom(AtomOfTerm(t))->StrOfAE, NULL, true))) {
pop_text_stack(l);
return false; return false;
}
pop_text_stack(l);
rc = Yap_unify(Yap_MkTextTerm(fp, LOCAL_encoding, t), ARG2); rc = Yap_unify(Yap_MkTextTerm(fp, LOCAL_encoding, t), ARG2);
if (fp != s)
freeBuffer((void *)fp);
return rc; return rc;
} }
@ -1359,14 +1362,18 @@ static Int p_expand_file_name(USES_REGS1) {
Yap_Error(INSTANTIATION_ERROR, t, "argument to true_file_name unbound"); Yap_Error(INSTANTIATION_ERROR, t, "argument to true_file_name unbound");
return FALSE; return FALSE;
} }
int l = push_text_stack();
text = Yap_TextTermToText(t, NULL, LOCAL_encoding); text = Yap_TextTermToText(t, NULL, LOCAL_encoding);
if (!text) if (!text) {
pop_text_stack(l);
return false; return false;
if (!(text2 = PlExpandVars(text, NULL, NULL))) }
if (!(text2 = PlExpandVars(text, NULL, NULL))) {
pop_text_stack(l);
return false; return false;
freeBuffer(text); }
bool rc = Yap_unify(ARG2, Yap_MkTextTerm(text2, LOCAL_encoding, t)); bool rc = Yap_unify(ARG2, Yap_MkTextTerm(text2, LOCAL_encoding, t));
freeBuffer(text2); pop_text_stack(l);
return rc; return rc;
} }