2013-11-20 22:20:51 +00:00
|
|
|
/*************************************************************************
|
|
|
|
* *
|
|
|
|
* YAP Prolog %W% %G% *
|
|
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
|
|
* *
|
|
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
|
|
* *
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
|
|
|
* File: YapHandles.h *
|
|
|
|
* mods: *
|
|
|
|
* comments: term handles for YAP: basic ops *
|
|
|
|
* version: $Id: Yap.h,v 1.38 2008-06-18 10:02:27 vsc Exp $ *
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
#ifndef YAP_HANDLES_H
|
|
|
|
#define YAP_HANDLES_H 1
|
2014-05-14 17:59:08 +01:00
|
|
|
#include "Regs.h"
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
/**
|
2014-07-27 01:14:15 +01:00
|
|
|
@groupdef term_t_slots
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
Also known as term handles, slots are offsets to entries in the local stack. YAP
|
|
|
|
never compresses the local stack, so slots are respected by the garbage
|
|
|
|
collector,
|
|
|
|
hence providing a way to access terms without being exposed to stack shifts or
|
|
|
|
garbage-collection.
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
Space is released when the function terminates. Thus, slots will be
|
|
|
|
automatically released at the end
|
2014-05-14 17:59:08 +01:00
|
|
|
of a function. Hence, slots should always be used as local variables.
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
Slots are organized as follows:
|
2014-06-11 19:36:50 +01:00
|
|
|
---- Offset of next pointer in chain (tagged as an handle_t)
|
|
|
|
---- Number of entries (tagged as handle_t), in the example TAG(INT,4)
|
2015-04-13 13:28:17 +01:00
|
|
|
Entry
|
|
|
|
Entry
|
|
|
|
Entry
|
|
|
|
Entry
|
2014-06-11 19:36:50 +01:00
|
|
|
---- Number of entries (tagged as handle_t), in the example TAG(INT,4)
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
Slots are not known to the yaam. Instead, A new set of slots is created when the
|
|
|
|
emulator calls user C-code.
|
2014-05-14 17:59:08 +01:00
|
|
|
(see YAP_Execute* functions). They are also created:
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
- by SWI's PL_foreign_frame() function,
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
- by the YAP_RunGoal() routines and friends, when they exit successfully.
|
|
|
|
Notice that all handles created by c-goals within
|
2014-05-14 17:59:08 +01:00
|
|
|
a `Goal` execution should not be used afterwards.
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
This section lists the main internal functions for slot management. These
|
|
|
|
functions are then exported through corresponding FLI C-functions
|
2013-11-20 22:20:51 +00:00
|
|
|
|
|
|
|
*************************************************************************************************/
|
|
|
|
|
2015-08-07 22:57:53 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2015-02-10 09:19:05 +00:00
|
|
|
/// @brief reboot the slot system.
|
|
|
|
/// Used when wwe start from scratch (Reset).
|
2015-09-25 10:57:26 +01:00
|
|
|
#define Yap_RebootSlots(wid) Yap_RebootSlots__(wid PASS_REGS)
|
2015-02-10 09:19:05 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline void Yap_RebootSlots__(int wid USES_REGS) {
|
2015-08-07 22:57:53 +01:00
|
|
|
// // fprintf(stderr, " StartSlots = %ld", LOCAL_CurSlot);
|
2015-04-13 13:28:17 +01:00
|
|
|
REMOTE_CurSlot(wid) = 1;
|
2015-02-10 09:19:05 +00:00
|
|
|
}
|
|
|
|
|
2015-02-03 02:36:51 +00:00
|
|
|
/// @brief declares a new set of slots.
|
|
|
|
/// Used to tell how many slots we had when we entered a segment of code.
|
2015-10-09 10:31:07 +01:00
|
|
|
//#define Yap_StartSlots() ( printf("[<<<%s,%s,%d-%ld\n",__FILE__,__FUNCTION__,__LINE__,LOCAL_CurSlot)?Yap_StartSlots__(PASS_REGS1): -1)
|
2015-09-25 10:57:26 +01:00
|
|
|
#define Yap_StartSlots() Yap_StartSlots__(PASS_REGS1)
|
2015-01-30 07:25:34 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline yhandle_t Yap_StartSlots__(USES_REGS1) {
|
2015-08-07 22:57:53 +01:00
|
|
|
// // fprintf(stderr, " StartSlots = %ld", LOCAL_CurSlot);
|
2015-09-25 10:57:26 +01:00
|
|
|
// fprintf(stderr,"SS %s:%d\n", __FUNCTION__, __LINE__);;
|
|
|
|
if (LOCAL_CurSlot < 0) {
|
|
|
|
Yap_Error(SYSTEM_ERROR_INTERNAL, 0L, " StartSlots = %ld", LOCAL_CurSlot);
|
2015-01-30 07:25:34 +00:00
|
|
|
}
|
|
|
|
return LOCAL_CurSlot;
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2015-10-09 10:31:07 +01:00
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
/// @brief reset slots to a well-known position in the stack
|
2015-10-09 10:31:07 +01:00
|
|
|
//#define Yap_CloseSlots(slot) ( printf("- %s,%s,%d %ld>>>]\n",__FILE__,__FUNCTION__,__LINE__, slot)?Yap_CloseSlots__(slot PASS_REGS):-1)
|
2015-09-25 10:57:26 +01:00
|
|
|
#define Yap_CloseSlots(slot) Yap_CloseSlots__(slot PASS_REGS)
|
2015-02-03 02:36:51 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline void Yap_CloseSlots__(yhandle_t slot USES_REGS) {
|
|
|
|
// fprintf(stderr,"CS %s:%d\n", __FUNCTION__, __LINE__);;
|
2013-12-15 08:37:10 +00:00
|
|
|
LOCAL_CurSlot = slot;
|
|
|
|
}
|
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
/// @brief report the current position of the slots, assuming that they occupy
|
|
|
|
/// the top of the stack.
|
|
|
|
static inline yhandle_t Yap_CurrentSlot(USES_REGS1) { return LOCAL_CurSlot; }
|
2013-11-20 22:20:51 +00:00
|
|
|
|
2015-04-13 13:28:17 +01:00
|
|
|
#define Yap_GetFromSlot(slot) Yap_GetFromSlot__(slot PASS_REGS)
|
2014-05-14 17:59:08 +01:00
|
|
|
/// @brief read from a slot.
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline Term Yap_GetFromSlot__(yhandle_t slot USES_REGS) {
|
|
|
|
// fprintf(stderr,"GS %s:%d\n", __FUNCTION__, __LINE__);;
|
|
|
|
return (Deref(LOCAL_SlotBase[slot]));
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
/// @brief read from a slot. but does not try to dereference the slot.
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline Term Yap_GetDerefedFromSlot(yhandle_t slot USES_REGS) {
|
|
|
|
// fprintf(stderr,"GDS %s:%d\n", __FUNCTION__, __LINE__);
|
2015-01-30 07:25:34 +00:00
|
|
|
return LOCAL_SlotBase[slot];
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
/// @brief read the object in a slot. but do not try to dereference the slot.
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline Term Yap_GetPtrFromSlot(yhandle_t slot USES_REGS) {
|
|
|
|
// fprintf(stderr,"GPS %s:%d\n", __FUNCTION__, __LINE__);
|
2015-01-30 07:25:34 +00:00
|
|
|
return LOCAL_SlotBase[slot];
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
#define Yap_AddressFromSlot(slot) Yap_AddressFromSlot__(slot PASS_REGS)
|
2015-02-03 02:36:51 +00:00
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
/// @brief get the memory address of a slot
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline Term *Yap_AddressFromSlot__(yhandle_t slot USES_REGS) {
|
|
|
|
return LOCAL_SlotBase + slot;
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
/// @brief store term in a slot
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline void Yap_PutInSlot(yhandle_t slot, Term t USES_REGS) {
|
|
|
|
// fprintf(stderr,"PS %s:%d\n", __FUNCTION__, __LINE__);
|
2015-01-30 07:25:34 +00:00
|
|
|
LOCAL_SlotBase[slot] = t;
|
|
|
|
}
|
|
|
|
|
2015-02-09 10:30:24 +00:00
|
|
|
#ifndef max
|
2015-09-25 10:57:26 +01:00
|
|
|
#define max(X, Y) (X > Y ? X : Y)
|
2015-02-09 10:30:24 +00:00
|
|
|
#endif
|
2015-01-30 07:25:34 +00:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline void ensure_slots(int N USES_REGS) {
|
|
|
|
if (LOCAL_CurSlot + N >= LOCAL_NSlots) {
|
|
|
|
size_t inc = max(16 * 1024, LOCAL_NSlots / 2); // measured in cells
|
|
|
|
inc = max(inc, N + 16); // measured in cells
|
|
|
|
LOCAL_SlotBase =
|
|
|
|
(CELL *)realloc(LOCAL_SlotBase, (inc + LOCAL_NSlots) * sizeof(CELL));
|
2015-08-07 22:57:53 +01:00
|
|
|
LOCAL_NSlots += inc;
|
2015-01-30 07:25:34 +00:00
|
|
|
if (!LOCAL_SlotBase) {
|
2015-09-25 10:57:26 +01:00
|
|
|
unsigned long int kneeds = ((inc + LOCAL_NSlots) * sizeof(CELL)) / 1024;
|
|
|
|
Yap_Error(
|
|
|
|
SYSTEM_ERROR_INTERNAL, 0 /* TermNil */,
|
|
|
|
"Out of memory for the term handles (term_t) aka slots, l needed",
|
|
|
|
kneeds);
|
2015-01-30 07:25:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-09 10:31:07 +01:00
|
|
|
/// @brief create a new slot with term t
|
|
|
|
//#define Yap_InitSlot(t) ( printf("+%d %s,%s,%d>>>]\n",1,__FILE__,__FUNCTION__,__LINE__)?Yap_InitSlot__(t PASS_REGS):-1)
|
2015-09-25 10:57:26 +01:00
|
|
|
#define Yap_InitSlot(t) Yap_InitSlot__(t PASS_REGS)
|
2015-04-13 13:28:17 +01:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline yhandle_t Yap_InitSlot__(Term t USES_REGS) {
|
2015-01-30 07:25:34 +00:00
|
|
|
yhandle_t old_slots = LOCAL_CurSlot;
|
2015-08-07 22:57:53 +01:00
|
|
|
// fprintf(stderr,"IS %s:%d\n", __FUNCTION__, __LINE__);
|
2015-04-13 13:28:17 +01:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
ensure_slots(1 PASS_REGS);
|
2015-01-30 07:25:34 +00:00
|
|
|
LOCAL_SlotBase[old_slots] = t;
|
|
|
|
LOCAL_CurSlot++;
|
|
|
|
return old_slots;
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2015-10-09 10:31:07 +01:00
|
|
|
//#define Yap_NewSlots(n) ( printf("+%d %s,%s,%d>>>]\n",n,__FILE__,__FUNCTION__,__LINE__)?Yap_NewSlots__(n PASS_REGS):-1)
|
2015-09-25 10:57:26 +01:00
|
|
|
#define Yap_NewSlots(n) Yap_NewSlots__(n PASS_REGS)
|
2015-04-13 13:28:17 +01:00
|
|
|
|
2014-05-14 17:59:08 +01:00
|
|
|
/// @brief allocate n empty new slots
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline yhandle_t Yap_NewSlots__(int n USES_REGS) {
|
2015-01-30 07:25:34 +00:00
|
|
|
yhandle_t old_slots = LOCAL_CurSlot;
|
|
|
|
int i;
|
2015-08-07 22:57:53 +01:00
|
|
|
// fprintf(stderr,"NS %s:%d\n", __FUNCTION__, __LINE__);
|
2015-01-30 07:25:34 +00:00
|
|
|
|
2015-02-03 02:36:51 +00:00
|
|
|
ensure_slots(n PASS_REGS);
|
2015-09-25 10:57:26 +01:00
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
LOCAL_SlotBase[old_slots + i] = MkVarTerm();
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
2015-01-30 07:25:34 +00:00
|
|
|
LOCAL_CurSlot += n;
|
|
|
|
return old_slots;
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2015-10-09 10:31:07 +01:00
|
|
|
//#define Yap_InitSlots(n, ts) ( printf("+%d %s,%s,%d>>>]\n",n,__FILE__,__FUNCTION__,__LINE__)?Yap_InitSlots__(n, ts PASS_REGS):-1)
|
2015-09-25 10:57:26 +01:00
|
|
|
#define Yap_InitSlots(n, ts) Yap_InitSlots__(n, ts PASS_REGS)
|
2014-10-23 01:16:30 +01:00
|
|
|
|
2015-01-30 07:25:34 +00:00
|
|
|
/// @brief create n new slots with terms ts[]
|
2015-09-25 10:57:26 +01:00
|
|
|
static inline yhandle_t Yap_InitSlots__(int n, Term *ts USES_REGS) {
|
2015-01-30 07:25:34 +00:00
|
|
|
yhandle_t old_slots = LOCAL_CurSlot;
|
|
|
|
int i;
|
2015-08-07 22:57:53 +01:00
|
|
|
// fprintf(stderr,"1S %s:%d\n", __FUNCTION__, __LINE__);
|
2015-04-13 13:28:17 +01:00
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
ensure_slots(n PASS_REGS);
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
LOCAL_SlotBase[old_slots + i] = ts[i];
|
2015-01-30 07:25:34 +00:00
|
|
|
LOCAL_CurSlot += n;
|
|
|
|
return old_slots;
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
2015-09-25 10:57:26 +01:00
|
|
|
/// @brief Succeeds if it is to recover the space allocated for $n$ contiguos
|
|
|
|
/// slots starting at topSlot.
|
|
|
|
static inline bool Yap_RecoverSlots(int n, yhandle_t topSlot USES_REGS) {
|
2015-10-09 10:31:07 +01:00
|
|
|
if (topSlot+n < LOCAL_CurSlot)
|
2015-01-30 07:25:34 +00:00
|
|
|
return false;
|
2015-09-25 10:57:26 +01:00
|
|
|
#ifdef DEBUG
|
2015-10-09 10:31:07 +01:00
|
|
|
if (n > LOCAL_CurSlot) {
|
2015-09-25 10:57:26 +01:00
|
|
|
Yap_Error(SYSTEM_ERROR_INTERNAL, 0 , "Inconsistent slot state in Yap_RecoverSlots.", 0);
|
2015-01-30 07:25:34 +00:00
|
|
|
return false;
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
2015-09-25 10:57:26 +01:00
|
|
|
#endif
|
2015-10-09 10:31:07 +01:00
|
|
|
LOCAL_CurSlot -= n;
|
|
|
|
// fprintf(stderr,"RS %s:%d\n", __FUNCTION__, __LINE__);
|
2015-01-30 07:25:34 +00:00
|
|
|
return true;
|
2013-11-20 22:20:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|