fix removeSlots and more documnetation.

This commit is contained in:
Vitor Santos Costa 2014-05-14 17:59:08 +01:00
parent e90fda2d5f
commit e0d0543e52
4 changed files with 115 additions and 30 deletions

View File

@ -494,16 +494,81 @@ X_API void YAP_SetOutputMessage(void);
X_API int YAP_StreamToFileNo(Term);
X_API void YAP_CloseAllOpenStreams(void);
X_API void YAP_FlushAllStreams(void);
/**
@group slotInterface Term Handles or Slots
@{
Term handles correspond to SWI-Prolog's term_t datatype: they are a safe representation
of terms. Slots are safe houses in the stack, the garbage collector and the stack
shifter know about them and make sure they have correct values. In this
case, we use a slot to preserve _t_ during the execution of
YAP_RunGoal). When the execution of _t_ is over we read the
(possibly changed) value of _t_ back from the slot _sl_ and tell
YAP that the slot _sl_ is not needed and can be given back to the
system.
YAP supports storing and manipulating term_t like slots or handles, but in the C
the programmer needs to take care as most operations still require unwrapping the term
inside.
For implementation details and more information, please check term_t_slots in the implementation section.
*/
/// @brief report the current position of the slots, assuming that they occupy the top of the stack.
///
///
X_API Int YAP_CurrentSlot(void);
X_API Int YAP_NewSlots(int);
X_API Int YAP_InitSlot(Term);
X_API Term YAP_GetFromSlot(Int);
X_API Term *YAP_AddressFromSlot(Int);
X_API Term *YAP_AddressOfTermInSlot(Int);
X_API void YAP_PutInSlot(Int, Term);
X_API int YAP_RecoverSlots(int);
X_API Int YAP_ArgsToSlots(int);
X_API void YAP_SlotsToArgs(int, Int);
/// @brief allocate n empty new slots
///
/// Return a handle to the system's default slot.
X_API Int YAP_NewSlots(int NumberOfSlots);
/// @brief allocate n empty new slots
///
/// Allocate _NumberOfSlots_ from the stack and return an handle to the
/// last one. The other handle can be obtained by decrementing the handle.
X_API Int YAP_InitSlot(YAP_Term t);
/// @brief read from a slot.
///
///
X_API YAP_Term YAP_GetFromSlot(YAP_Int slot);
/// @brief get the memory address of a slot
///
/// Return the address of slot _slot_: please use with care.
X_API YAP_Term *YAP_AddressFromSlot(YAP_Int);
/// @brief get the memory address of the term actually stored in a slot
///
///
X_API YAP_Term *YAP_AddressOfTermInSlot(YAP_Int);
/// @brief store term in a slot
///
///
X_API void YAP_PutInSlot(YAP_Int slot, YAP_Term t);
/// @brief Succeeds if it recovers the space allocated for $n$ contiguous slots starting at topSlot.
///
/// Set the contents of slot _slot_ to _t_.
X_API int YAP_RecoverSlots(int, YAP_Int topSlot);
/// @brief copies the first new n YAAM registers to slots
///
/// Store the current first _HowMany_ arguments in new slots.
X_API YAP_Int YAP_ArgsToSlots(int HowMany);
/// @brief copies n slots such that sl is copied to the last abstract ,achine register.
///
/// Set the first _HowMany_ arguments to the _HowMany_ slots
// starting at _slot_.
X_API void YAP_SlotsToArgs(int HowMany, YAP_Int slot);
/// @}
X_API void YAP_Throw(Term);
X_API void YAP_AsyncThrow(Term);
X_API void YAP_Halt(int);
@ -995,7 +1060,7 @@ YAP_MkPairTerm(Term t1, Term t2)
BACKUP_H();
t1 = Yap_GetFromSlot(sl1 PASS_REGS);
t2 = Yap_GetFromSlot(sl2 PASS_REGS);
Yap_RecoverSlots(2 PASS_REGS);
Yap_RecoverSlots(2, sl2 PASS_REGS);
}
t = MkPairTerm(t1, t2);
RECOVER_H();
@ -1019,7 +1084,7 @@ YAP_MkListFromTerms(Term *ta, Int sz)
}
BACKUP_H();
ta = (CELL *)Yap_GetFromSlot(sl1 PASS_REGS);
Yap_RecoverSlots(1 PASS_REGS);
Yap_RecoverSlots(1, sl1 PASS_REGS);
}
h = HR;
t = AbsPair(h);
@ -1330,10 +1395,10 @@ YAP_InitSlot(Term t)
}
X_API int
YAP_RecoverSlots(int n)
YAP_RecoverSlots(int n, Int sl)
{
CACHE_REGS
return Yap_RecoverSlots(n PASS_REGS);
return Yap_RecoverSlots(n, sl PASS_REGS);
}
X_API Term

View File

@ -13,6 +13,8 @@
* version: $Id: Regs.h,v 1.42 2008-08-12 01:27:22 vsc Exp $ *
*************************************************************************/
#ifndef REGS_H
#define REGS_H 1
/********* abstract machine registers **********************************/
#ifdef YAP_H
@ -731,3 +733,4 @@ void SET_ASP__(CELL *yreg, Int sz USES_REGS) {
ASP = (CELL *)PROTECT_FROZEN_B(B);
}
#endif

View File

@ -15,36 +15,40 @@
#ifndef YAP_HANDLES_H
#define YAP_HANDLES_H 1
#include "Regs.h"
/*************************************************************************************************
slots
/**
@group term_t_slots
Also known as term handles, they provide a way to access terms without being exposed to stack shifts in gc.
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.
They should always be used as local variables.
Space is released when the function terminataes. Thus, slots will be automatically released at the end
of a function. Hence, slots should always be used as local variables.
They are organized as follows:
---- Tagged Offset of next pointer in chain
---- Tagged Number of entries
Slots are organized as follows:
---- Offset of next pointer in chain (tagged as an Int)
---- Number of entries (tagged as Int), in the example TAG(INT,4)
Entry
Entry
Entry
Entry
---- Tagged Number of entries
---- Number of entries (tagged as Int), in the example TAG(INT,4)
They are not known to the yaam. Instead,
they are created when entering user code (see YAP_Execute* functions). They are also created:
Slots are not known to the yaam. Instead, A new set of slots is created when the emulator calls user C-code.
(see YAP_Execute* functions). They are also created:
- by SWI PL_foreign_frame function,
- by YAP_*Goal routines, when they exit successfully. Notice that all handles created by c-goals within
a *Goal execution should not be used afterwards.
- by SWI's PL_foreign_frame() function,
- 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.
This section lists the main internal functions for slot management. These functions are then exported through corresponding FLI C-functions
*************************************************************************************************/
/// @brief start a new set of slots, linking them to the last active slots (who may, or not, be active).
static inline Int
Yap_StartSlots( USES_REGS1 ) {
Int CurSlot = LOCAL_CurSlot;
@ -58,46 +62,55 @@ Yap_StartSlots( USES_REGS1 ) {
return CurSlot;
}
/// @brief reset slots to a well-known position in the stack
static inline void
Yap_CloseSlots( Int slot USES_REGS ) {
LOCAL_CurSlot = slot;
}
/// @brief report the current position of the slots, assuming that they occupy the top of the stack.
static inline Int
Yap_CurrentSlot( USES_REGS1 ) {
return IntOfTerm(ASP[0]);
}
/// @brief read from a slot.
static inline Term
Yap_GetFromSlot(Int slot USES_REGS)
{
return(Deref(LCL0[slot]));
}
/// @brief read from a slot. but does not try to dereference the slot.
static inline Term
Yap_GetDerefedFromSlot(Int slot USES_REGS)
{
return LCL0[slot];
}
/// @brief read the object in a slot. but do not try to dereference the slot.
static inline Term
Yap_GetPtrFromSlot(Int slot USES_REGS)
{
return(LCL0[slot]);
}
/// @brief get the memory address of a slot
static inline Term *
Yap_AddressFromSlot(Int slot USES_REGS)
{
return(LCL0+slot);
}
/// @brief store term in a slot
static inline void
Yap_PutInSlot(Int slot, Term t USES_REGS)
{
LCL0[slot] = t;
}
/// @brief allocate n empty new slots
static inline Int
Yap_NewSlots(int n USES_REGS)
{
@ -111,6 +124,7 @@ Yap_NewSlots(int n USES_REGS)
return((ASP+1)-LCL0);
}
/// @brief create a new slot with term t
static inline Int
Yap_InitSlot(Term t USES_REGS)
{
@ -121,13 +135,16 @@ Yap_InitSlot(Term t USES_REGS)
return((ASP+1)-LCL0);
}
/// @brief Succeeds if it is to recover the space allocated for $n$ contiguos slots starting at topSlot.
static inline int
Yap_RecoverSlots(int n USES_REGS)
Yap_RecoverSlots(int n, Int topSlot USES_REGS)
{
Int old_slots = IntOfTerm(ASP[0]);
if (old_slots - n < 0) {
if (old_slots < n) {
return FALSE;
}
if (ASP+1 != LCL0+topSlot)
return FALSE;
ASP += n;
ASP[old_slots+(n-old_slots+1)] = ASP[0] = MkIntTerm(old_slots-n);
return TRUE;

View File

@ -234,7 +234,7 @@ X_API void PL_reset_term_refs(term_t after)
{
CACHE_REGS
term_t new = Yap_NewSlots(1 PASS_REGS);
Yap_RecoverSlots(after-new PASS_REGS);
Yap_RecoverSlots(after-new, new PASS_REGS);
}
/** @}