This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/H/YapHandles.h

302 lines
11 KiB
C
Raw Normal View History

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
2016-01-31 10:41:38 +00:00
#include "Regs.h"
2016-02-01 02:48:07 +00:00
#include "Yatom.h"
2016-01-31 10:41:38 +00:00
#define LOCAL_CurHandle LOCAL_CurSlot
#define REMOTE_CurHandle REMOTE_CurSlot
2016-04-05 02:26:33 +01:00
#define LOCAL_NHandles LOCAL_NSlots
#define REMOTE_NHandles REMOTE_NSlots
2016-01-31 10:41:38 +00:00
#define LOCAL_HandleBase LOCAL_SlotBase
#define REMOTE_HanvdleBase SlotBase
2013-11-20 22:20:51 +00: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
of a function. Hence, slots should always be used as local variables.
2013-11-20 22:20:51 +00:00
2016-01-31 10:41:38 +00:00
Handles 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
2016-04-05 02:26:33 +01:00
Handles are not known to the yaam. Instead, A new set of slots is created when
the
2015-09-25 10:57:26 +01:00
emulator calls user C-code.
(see YAP_Execute* functions). They are also created:
2013-11-20 22:20:51 +00: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
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>
/// @brief reboot the slot system.
/// Used when wwe start from scratch (Reset).
2016-01-31 10:41:38 +00:00
#define Yap_RebootHandles(wid) Yap_RebootHandles__(wid PASS_REGS)
#define Yap_RebootSlots(wid) Yap_RebootHandles__(wid PASS_REGS)
2016-01-31 10:41:38 +00:00
static inline void Yap_RebootHandles__(int wid USES_REGS) {
// fprintf(stderr, " StartHandles = %ld", LOCAL_CurHandle);
REMOTE_CurHandle(wid) = 1;
}
2015-02-03 02:36:51 +00:00
/// @brief declares a new set of slots.
2016-04-05 02:26:33 +01:00
/// Used to tell how many slots we have so d=dara when we entered a segment of
/// code.
2016-01-31 10:41:38 +00:00
//#define Yap_StartHandles() (
// printf("[<<<%s,%s,%d-%ld\n",__FILE__,__FUNCTION__,__LINE__,LOCAL_CurHandle)?Yap_StartHandles__(PASS_REGS1):
2016-01-03 02:06:09 +00:00
//-1)
2016-01-31 10:41:38 +00:00
#define Yap_StartHandles() Yap_StartHandles__(PASS_REGS1)
#define Yap_StartSlots() Yap_StartHandles__(PASS_REGS1)
2016-01-31 10:41:38 +00:00
INLINE_ONLY inline EXTERN yhandle_t Yap_StartHandles__(USES_REGS1);
INLINE_ONLY inline EXTERN yhandle_t Yap_StartHandles__(USES_REGS1) {
// // fprintf(stderr, " StartHandles = %ld", LOCAL_CurHandle);
2016-01-03 02:06:09 +00:00
// fprintf(stderr,"SS %s:%d\n", __FILE__, __LINE__);;
2016-01-31 10:41:38 +00:00
if (LOCAL_CurHandle < 0) {
2016-04-05 02:26:33 +01:00
Yap_Error(SYSTEM_ERROR_INTERNAL, 0L, " StartHandles = %ld",
LOCAL_CurHandle);
}
2016-01-31 10:41:38 +00:00
return LOCAL_CurHandle;
2013-11-20 22:20:51 +00:00
}
2016-04-05 02:26:33 +01:00
/// @brief reset the nmber of slots _slot_ to the number existing before the
/// call that produce _slot_
2016-01-31 10:41:38 +00:00
///(eg, Yap_StartHandles(), YAP_NewHandles(), or YAP_PushHandle)
//#define Yap_CloseHandles(slot) ( printf("- %s,%s,%d
//%ld>>>]\n",__FILE__,__FUNCTION__,__LINE__, slot)?Yap_CloseHandles__(slot
2016-01-03 02:06:09 +00:00
// PASS_REGS):-1)
2016-01-31 10:41:38 +00:00
#define Yap_CloseHandles(slot) Yap_CloseHandles__(slot PASS_REGS)
#define Yap_CloseSlots(slot) Yap_CloseHandles__(slot PASS_REGS)
2015-02-03 02:36:51 +00:00
2016-01-31 10:41:38 +00:00
INLINE_ONLY inline EXTERN void Yap_CloseHandles__(yhandle_t slot USES_REGS);
INLINE_ONLY inline EXTERN void Yap_CloseHandles__(yhandle_t slot USES_REGS) {
// fprintf(stderr,"CS %s:%d\n", __FILE__, __LINE__);
LOCAL_CurHandle = slot;
}
2016-01-31 10:41:38 +00:00
#define Yap_CurrentHandle() Yap_CurrentHandle__(PASS_REGS1)
#define Yap_CurrentSlot() Yap_CurrentHandle__(PASS_REGS1)
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.
2016-01-31 10:41:38 +00:00
INLINE_ONLY inline EXTERN yhandle_t Yap_CurrentHandle__(USES_REGS1);
INLINE_ONLY inline EXTERN yhandle_t Yap_CurrentHandle__(USES_REGS1) {
return LOCAL_CurHandle;
2016-01-03 02:06:09 +00:00
}
2013-11-20 22:20:51 +00:00
2016-01-31 10:41:38 +00:00
#define Yap_GetFromHandle(slot) Yap_GetFromHandle__(slot PASS_REGS)
#define Yap_GetFromSlot(slot) Yap_GetFromHandle__(slot PASS_REGS)
/// @brief read from a slot.
2016-01-31 10:41:38 +00:00
INLINE_ONLY inline EXTERN Term Yap_GetFromHandle__(yhandle_t slot USES_REGS);
INLINE_ONLY inline EXTERN Term Yap_GetFromHandle__(yhandle_t slot USES_REGS) {
2016-01-03 02:06:09 +00:00
// fprintf(stderr, "GS %s:%d\n", __FILE__, __LINE__);
2016-01-31 10:41:38 +00:00
return Deref(LOCAL_HandleBase[slot]);
2013-11-20 22:20:51 +00:00
}
2016-04-05 02:26:33 +01:00
#define Yap_GetDerefedFromHandle(slot) \
Yap_GetDerefedFromHandle__(slot PASS_REGS)
#define Yap_GetDerefedFromSlot(slot) Yap_GetDerefedFromHandle__(slot PASS_REGS)
2016-01-31 10:41:38 +00:00
/// @brief read from a slot. but does not try to dereference the slot.
2016-04-05 02:26:33 +01:00
INLINE_ONLY inline EXTERN Term
Yap_GetDerefedFromHandle__(yhandle_t slot USES_REGS);
INLINE_ONLY inline EXTERN Term
Yap_GetDerefedFromHandle__(yhandle_t slot USES_REGS) {
2016-01-03 02:06:09 +00:00
// fprintf(stderr,"GDS %s:%d\n", __FILE__, __LINE__);
2016-01-31 10:41:38 +00:00
return LOCAL_HandleBase[slot];
2013-11-20 22:20:51 +00:00
}
2016-04-05 02:26:33 +01:00
#define Yap_GetPtrFromHandle(slot) Yap_GetPtrFromHandle__(slot PASS_REGS)
#define Yap_GetPtrFromSlot(slot) Yap_GetPtrFromHandle__(slot PASS_REGS)
2016-01-03 02:06:09 +00:00
/// @brief read the object in a slot. but do not try to dereference the slot.
2016-04-05 02:26:33 +01:00
INLINE_ONLY inline EXTERN Term *
Yap_GetPtrFromHandle__(yhandle_t slot USES_REGS);
INLINE_ONLY inline EXTERN Term *
Yap_GetPtrFromHandle__(yhandle_t slot USES_REGS) {
2016-01-03 02:06:09 +00:00
// fprintf(stderr,"GPS %s:%d\n", __FILE__, __LINE__);
2016-01-31 10:41:38 +00:00
return (Term *)LOCAL_HandleBase[slot];
2013-11-20 22:20:51 +00:00
}
2016-01-31 10:41:38 +00:00
#define Yap_AddressFromHandle(slot) Yap_AddressFromHandle__(slot PASS_REGS)
#define Yap_AddressFromSlot(slot) Yap_AddressFromHandle__(slot PASS_REGS)
2015-02-03 02:36:51 +00:00
2016-04-05 02:26:33 +01:00
INLINE_ONLY inline EXTERN CELL *
Yap_AddressFromHandle__(yhandle_t slot USES_REGS);
INLINE_ONLY inline EXTERN CELL *
Yap_AddressFromHandle__(yhandle_t slot USES_REGS) {
2016-01-03 02:06:09 +00:00
/// @brief get the memory address of a slot
2016-01-31 10:41:38 +00:00
return LOCAL_HandleBase + slot;
2013-11-20 22:20:51 +00:00
}
2016-01-31 10:41:38 +00:00
#define Yap_PutInSlot(slot, t) Yap_PutInHandle__(slot, t PASS_REGS)
#define Yap_PutInHandle(slot, t) Yap_PutInHandle__(slot, t PASS_REGS)
/// @brief store term in a slot
2016-04-05 02:26:33 +01:00
INLINE_ONLY inline EXTERN void Yap_PutInHandle__(yhandle_t slot,
Term t USES_REGS);
INLINE_ONLY inline EXTERN void Yap_PutInHandle__(yhandle_t slot,
Term t USES_REGS) {
2016-01-03 02:06:09 +00:00
// fprintf(stderr,"PS %s:%d\n", __FILE__, __LINE__);
2016-01-31 10:41:38 +00:00
LOCAL_HandleBase[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
2016-01-31 10:41:38 +00:00
#define ensure_handles ensure_slots
2016-01-03 02:06:09 +00:00
INLINE_ONLY inline EXTERN void ensure_slots(int N USES_REGS) {
2016-01-31 10:41:38 +00:00
if (LOCAL_CurHandle + N >= LOCAL_NHandles) {
size_t inc = max(16 * 1024, LOCAL_NHandles / 2); // measured in cells
2016-04-05 02:26:33 +01:00
inc = max(inc, (size_t)N + 16); // measured in cells
LOCAL_HandleBase = (CELL *)realloc(LOCAL_HandleBase,
(inc + LOCAL_NHandles) * sizeof(CELL));
2016-01-31 10:41:38 +00:00
LOCAL_NHandles += inc;
if (!LOCAL_HandleBase) {
2016-04-10 14:21:17 +01:00
size_t kneeds = ((inc + LOCAL_NHandles) * sizeof(CELL)) / 1024;
2015-09-25 10:57:26 +01:00
Yap_Error(
SYSTEM_ERROR_INTERNAL, 0 /* TermNil */,
"Out of memory for the term handles (term_t) aka slots, l needed",
kneeds);
}
}
}
2015-10-09 10:31:07 +01:00
/// @brief create a new slot with term t
2016-04-05 02:26:33 +01:00
// #define Yap_InitHandle(t)
// (printf("+%d %ld %s,%s,%d>>>]\n", 1, LOCAL_CurHandle,__FILE__, __FUNCTION__,
// __LINE__)
// ? Yap_InitHandle__(t PASS_REGS)
// : -1)
2016-01-31 10:41:38 +00:00
#define Yap_InitHandle(t) Yap_InitHandle__(t PASS_REGS)
#define Yap_PushHandle(t) Yap_InitHandle__(t PASS_REGS)
#define Yap_InitSlot(t) Yap_InitHandle__(t PASS_REGS)
2015-04-13 13:28:17 +01:00
2016-01-31 10:41:38 +00:00
INLINE_ONLY inline EXTERN yhandle_t Yap_InitHandle__(Term t USES_REGS);
INLINE_ONLY inline EXTERN yhandle_t Yap_InitHandle__(Term t USES_REGS) {
yhandle_t old_slots = LOCAL_CurHandle;
2015-04-13 13:28:17 +01:00
2015-09-25 10:57:26 +01:00
ensure_slots(1 PASS_REGS);
2016-01-31 10:41:38 +00:00
LOCAL_HandleBase[old_slots] = t;
LOCAL_CurHandle++;
return old_slots;
2013-11-20 22:20:51 +00:00
}
2016-04-05 02:26:33 +01:00
//#define Yap_NewHandles(n) ( printf("+%d %ld
//%s,%s,%d>>>]\n",n,LOCAL_CurHandle,__FILE__,__FUNCTION__,__LINE__)
//?Yap_NewHandles__(n PASS_REGS):-1)
#define Yap_NewHandles(n) Yap_NewHandles__(n PASS_REGS)
#define Yap_NewSlots(n) Yap_NewHandles__(n PASS_REGS)
2015-04-13 13:28:17 +01:00
2016-01-31 10:41:38 +00:00
INLINE_ONLY inline EXTERN yhandle_t Yap_NewHandles__(int n USES_REGS);
INLINE_ONLY inline EXTERN yhandle_t Yap_NewHandles__(int n USES_REGS) {
yhandle_t old_slots = LOCAL_CurHandle;
int i;
2016-04-05 02:26:33 +01:00
// fprintf(stderr, "NS %s:%d\n", __FILE__, __LINE__);
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++) {
2016-01-31 10:41:38 +00:00
LOCAL_HandleBase[old_slots + i] = MkVarTerm();
2013-11-20 22:20:51 +00:00
}
2016-01-31 10:41:38 +00:00
LOCAL_CurHandle += n;
return old_slots;
2013-11-20 22:20:51 +00:00
}
2016-04-05 02:26:33 +01:00
//#define Yap_InitHandles(n, ts)
// (printf("+%d %d %s,%s,%d>>>]\n", n, LOCAL_CurHandle, __FILE__, __FUNCTION__,
// __LINE__)
// ? Yap_InitHandles__(n, ts PASS_REGS)
// : -1)
2016-01-31 10:41:38 +00:00
#define Yap_InitHandles(n, ts) Yap_InitHandles__(n, ts PASS_REGS)
#define Yap_InitSlots(n, ts) Yap_InitHandles__(n, ts PASS_REGS)
/// @brief create n new slots with terms ts[]
2016-04-05 02:26:33 +01:00
INLINE_ONLY inline EXTERN yhandle_t Yap_InitHandles__(int n,
Term *ts USES_REGS);
INLINE_ONLY inline EXTERN yhandle_t Yap_InitHandles__(int n,
Term *ts USES_REGS) {
2016-01-31 10:41:38 +00:00
yhandle_t old_slots = LOCAL_CurHandle;
int i;
2015-09-25 10:57:26 +01:00
ensure_slots(n PASS_REGS);
for (i = 0; i < n; i++)
2016-01-31 10:41:38 +00:00
LOCAL_HandleBase[old_slots + i] = ts[i];
LOCAL_CurHandle += n;
return old_slots;
2013-11-20 22:20:51 +00:00
}
2016-01-31 10:41:38 +00:00
#define Yap_RecoverHandles(n, ts) Yap_RecoverHandles__(n, ts PASS_REGS)
#define Yap_RecoverSlots(n, ts) Yap_RecoverHandles__(n, ts PASS_REGS)
2016-01-03 02:06:09 +00:00
2015-09-25 10:57:26 +01:00
/// @brief Succeeds if it is to recover the space allocated for $n$ contiguos
2016-01-31 10:41:38 +00:00
/// slots starting at topHandle.
static inline bool Yap_RecoverHandles__(int n, yhandle_t topHandle USES_REGS);
static inline bool Yap_RecoverHandles__(int n, yhandle_t topHandle USES_REGS) {
if (topHandle + n < LOCAL_CurHandle)
return false;
2015-09-25 10:57:26 +01:00
#ifdef DEBUG
2016-01-31 10:41:38 +00:00
if (n > LOCAL_CurHandle) {
2016-01-03 02:06:09 +00:00
Yap_Error(SYSTEM_ERROR_INTERNAL, 0,
2016-01-31 10:41:38 +00:00
"Inconsistent slot state in Yap_RecoverHandles.", 0);
return false;
2013-11-20 22:20:51 +00:00
}
2015-09-25 10:57:26 +01:00
#endif
2016-01-31 10:41:38 +00:00
LOCAL_CurHandle -= n;
2016-04-05 02:26:33 +01:00
// fprintf(stderr,"RS %ld %s:%d\n", LOCAL_CurHandle, __FILE__, __LINE__);
return true;
2013-11-20 22:20:51 +00:00
}
2016-04-05 02:26:33 +01:00
#define Yap_PopSlot(ts) Yap_PopHandle__(ts PASS_REGS)
#define Yap_PopHandle(ts) Yap_PopHandle__(ts PASS_REGS)
2016-01-31 10:41:38 +00:00
/// @brief recovers the element at position $n$ dropping any other elements p
2016-04-05 02:26:33 +01:00
static inline Term Yap_PopHandle__(yhandle_t topHandle USES_REGS);
static inline Term Yap_PopHandle__(yhandle_t topHandle USES_REGS) {
2016-01-31 10:41:38 +00:00
if (LOCAL_CurHandle < topHandle)
return TermNil;
else {
2016-04-05 02:26:33 +01:00
LOCAL_CurHandle = topHandle;
// fprintf(stderr,"RS %ld %s:%d\n", LOCAL_CurHandle, __FILE__, __LINE__);≈
return Deref(LOCAL_HandleBase[topHandle]);
2016-01-31 10:41:38 +00:00
}
}
2013-11-20 22:20:51 +00:00
#endif