just a mirror
parent
3209078bda
commit
6798b40dbf
|
@ -1 +0,0 @@
|
|||
Subproject commit bea2431c3ed833d81f5297e32c3776760c047561
|
|
@ -0,0 +1,201 @@
|
|||
The Artistic License 2.0
|
||||
|
||||
Copyright (c) 2000-2006, The Perl Foundation.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
This license establishes the terms under which a given free software
|
||||
Package may be copied, modified, distributed, and/or redistributed.
|
||||
The intent is that the Copyright Holder maintains some artistic
|
||||
control over the development of that Package while still keeping the
|
||||
Package available as open source and free software.
|
||||
|
||||
You are always permitted to make arrangements wholly outside of this
|
||||
license directly with the Copyright Holder of a given Package. If the
|
||||
terms of this license do not permit the full use that you propose to
|
||||
make of the Package, you should contact the Copyright Holder and seek
|
||||
a different licensing arrangement.
|
||||
|
||||
Definitions
|
||||
|
||||
"Copyright Holder" means the individual(s) or organization(s)
|
||||
named in the copyright notice for the entire Package.
|
||||
|
||||
"Contributor" means any party that has contributed code or other
|
||||
material to the Package, in accordance with the Copyright Holder's
|
||||
procedures.
|
||||
|
||||
"You" and "your" means any person who would like to copy,
|
||||
distribute, or modify the Package.
|
||||
|
||||
"Package" means the collection of files distributed by the
|
||||
Copyright Holder, and derivatives of that collection and/or of
|
||||
those files. A given Package may consist of either the Standard
|
||||
Version, or a Modified Version.
|
||||
|
||||
"Distribute" means providing a copy of the Package or making it
|
||||
accessible to anyone else, or in the case of a company or
|
||||
organization, to others outside of your company or organization.
|
||||
|
||||
"Distributor Fee" means any fee that you charge for Distributing
|
||||
this Package or providing support for this Package to another
|
||||
party. It does not mean licensing fees.
|
||||
|
||||
"Standard Version" refers to the Package if it has not been
|
||||
modified, or has been modified only in ways explicitly requested
|
||||
by the Copyright Holder.
|
||||
|
||||
"Modified Version" means the Package, if it has been changed, and
|
||||
such changes were not explicitly requested by the Copyright
|
||||
Holder.
|
||||
|
||||
"Original License" means this Artistic License as Distributed with
|
||||
the Standard Version of the Package, in its current version or as
|
||||
it may be modified by The Perl Foundation in the future.
|
||||
|
||||
"Source" form means the source code, documentation source, and
|
||||
configuration files for the Package.
|
||||
|
||||
"Compiled" form means the compiled bytecode, object code, binary,
|
||||
or any other form resulting from mechanical transformation or
|
||||
translation of the Source form.
|
||||
|
||||
|
||||
Permission for Use and Modification Without Distribution
|
||||
|
||||
(1) You are permitted to use the Standard Version and create and use
|
||||
Modified Versions for any purpose without restriction, provided that
|
||||
you do not Distribute the Modified Version.
|
||||
|
||||
|
||||
Permissions for Redistribution of the Standard Version
|
||||
|
||||
(2) You may Distribute verbatim copies of the Source form of the
|
||||
Standard Version of this Package in any medium without restriction,
|
||||
either gratis or for a Distributor Fee, provided that you duplicate
|
||||
all of the original copyright notices and associated disclaimers. At
|
||||
your discretion, such verbatim copies may or may not include a
|
||||
Compiled form of the Package.
|
||||
|
||||
(3) You may apply any bug fixes, portability changes, and other
|
||||
modifications made available from the Copyright Holder. The resulting
|
||||
Package will still be considered the Standard Version, and as such
|
||||
will be subject to the Original License.
|
||||
|
||||
|
||||
Distribution of Modified Versions of the Package as Source
|
||||
|
||||
(4) You may Distribute your Modified Version as Source (either gratis
|
||||
or for a Distributor Fee, and with or without a Compiled form of the
|
||||
Modified Version) provided that you clearly document how it differs
|
||||
from the Standard Version, including, but not limited to, documenting
|
||||
any non-standard features, executables, or modules, and provided that
|
||||
you do at least ONE of the following:
|
||||
|
||||
(a) make the Modified Version available to the Copyright Holder
|
||||
of the Standard Version, under the Original License, so that the
|
||||
Copyright Holder may include your modifications in the Standard
|
||||
Version.
|
||||
|
||||
(b) ensure that installation of your Modified Version does not
|
||||
prevent the user installing or running the Standard Version. In
|
||||
addition, the Modified Version must bear a name that is different
|
||||
from the name of the Standard Version.
|
||||
|
||||
(c) allow anyone who receives a copy of the Modified Version to
|
||||
make the Source form of the Modified Version available to others
|
||||
under
|
||||
|
||||
(i) the Original License or
|
||||
|
||||
(ii) a license that permits the licensee to freely copy,
|
||||
modify and redistribute the Modified Version using the same
|
||||
licensing terms that apply to the copy that the licensee
|
||||
received, and requires that the Source form of the Modified
|
||||
Version, and of any works derived from it, be made freely
|
||||
available in that license fees are prohibited but Distributor
|
||||
Fees are allowed.
|
||||
|
||||
|
||||
Distribution of Compiled Forms of the Standard Version
|
||||
or Modified Versions without the Source
|
||||
|
||||
(5) You may Distribute Compiled forms of the Standard Version without
|
||||
the Source, provided that you include complete instructions on how to
|
||||
get the Source of the Standard Version. Such instructions must be
|
||||
valid at the time of your distribution. If these instructions, at any
|
||||
time while you are carrying out such distribution, become invalid, you
|
||||
must provide new instructions on demand or cease further distribution.
|
||||
If you provide valid instructions or cease distribution within thirty
|
||||
days after you become aware that the instructions are invalid, then
|
||||
you do not forfeit any of your rights under this license.
|
||||
|
||||
(6) You may Distribute a Modified Version in Compiled form without
|
||||
the Source, provided that you comply with Section 4 with respect to
|
||||
the Source of the Modified Version.
|
||||
|
||||
|
||||
Aggregating or Linking the Package
|
||||
|
||||
(7) You may aggregate the Package (either the Standard Version or
|
||||
Modified Version) with other packages and Distribute the resulting
|
||||
aggregation provided that you do not charge a licensing fee for the
|
||||
Package. Distributor Fees are permitted, and licensing fees for other
|
||||
components in the aggregation are permitted. The terms of this license
|
||||
apply to the use and Distribution of the Standard or Modified Versions
|
||||
as included in the aggregation.
|
||||
|
||||
(8) You are permitted to link Modified and Standard Versions with
|
||||
other works, to embed the Package in a larger work of your own, or to
|
||||
build stand-alone binary or bytecode versions of applications that
|
||||
include the Package, and Distribute the result without restriction,
|
||||
provided the result does not expose a direct interface to the Package.
|
||||
|
||||
|
||||
Items That are Not Considered Part of a Modified Version
|
||||
|
||||
(9) Works (including, but not limited to, modules and scripts) that
|
||||
merely extend or make use of the Package, do not, by themselves, cause
|
||||
the Package to be a Modified Version. In addition, such works are not
|
||||
considered parts of the Package itself, and are not subject to the
|
||||
terms of this license.
|
||||
|
||||
|
||||
General Provisions
|
||||
|
||||
(10) Any use, modification, and distribution of the Standard or
|
||||
Modified Versions is governed by this Artistic License. By using,
|
||||
modifying or distributing the Package, you accept this license. Do not
|
||||
use, modify, or distribute the Package, if you do not accept this
|
||||
license.
|
||||
|
||||
(11) If your Modified Version has been derived from a Modified
|
||||
Version made by someone other than you, you are nevertheless required
|
||||
to ensure that your Modified Version complies with the requirements of
|
||||
this license.
|
||||
|
||||
(12) This license does not grant you the right to use any trademark,
|
||||
service mark, tradename, or logo of the Copyright Holder.
|
||||
|
||||
(13) This license includes the non-exclusive, worldwide,
|
||||
free-of-charge patent license to make, have made, use, offer to sell,
|
||||
sell, import and otherwise transfer the Package with respect to any
|
||||
patent claims licensable by the Copyright Holder that are necessarily
|
||||
infringed by the Package. If you institute patent litigation
|
||||
(including a cross-claim or counterclaim) against any party alleging
|
||||
that the Package constitutes direct or contributory patent
|
||||
infringement, then this Artistic License to you shall terminate on the
|
||||
date that such litigation is filed.
|
||||
|
||||
(14) Disclaimer of Warranty:
|
||||
THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
|
||||
IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||||
NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
|
||||
LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,295 @@
|
|||
/*************************************************************************
|
||||
* *
|
||||
* BEAM -> Basic Extended Andorra Model *
|
||||
* BEAM extends the YAP Prolog system to support the EAM *
|
||||
* *
|
||||
* Copyright: Ricardo Lopes and NCC - University of Porto, Portugal *
|
||||
* *
|
||||
**************************************************************************
|
||||
* comments: eam compiler data structures and routines *
|
||||
*************************************************************************/
|
||||
|
||||
#define Print_Code 0
|
||||
/* To help on compiler debuging
|
||||
1 -> show predicates info
|
||||
2 -> show YAP abstract machine code (YAAM)
|
||||
4 -> show YAAM after transformation
|
||||
8 -> show indexing code
|
||||
|
||||
16 -> show EAM intermediate code
|
||||
32 -> show EAM intermediate code with direct_calls
|
||||
128 -> show EAM abstrac machine code
|
||||
*/
|
||||
|
||||
#define Variavel 1
|
||||
#define Lista 2
|
||||
#define Estrutura 4
|
||||
#define Constante 8
|
||||
|
||||
typedef unsigned long Cell;
|
||||
|
||||
|
||||
typedef struct PCODE{
|
||||
struct PCODE *nextInst;
|
||||
int op, new1;
|
||||
unsigned long new4;
|
||||
} CInstr;
|
||||
|
||||
struct Clauses {
|
||||
unsigned int idx; /* info for indexing on first arg */
|
||||
Cell val; /* atom or functor in first arg */
|
||||
unsigned int nr_vars; /* nr of local vars */
|
||||
struct Predicates *predi; /* predicate struct */
|
||||
int side_effects; /* clause has side effects */
|
||||
Cell *code;
|
||||
|
||||
struct Clauses *next; /* next clause within the same predicate */
|
||||
};
|
||||
|
||||
|
||||
struct HASH_TABLE {
|
||||
Cell value;
|
||||
Cell *code;
|
||||
struct HASH_TABLE *next;
|
||||
};
|
||||
|
||||
struct Predicates { /* To register information about predicates */
|
||||
unsigned long id;
|
||||
unsigned char *name;
|
||||
unsigned int arity;
|
||||
unsigned int nr_alt; /* nr of alternativas */
|
||||
unsigned int calls; /* nr of existent calls to this predicate */
|
||||
struct Clauses *first;
|
||||
struct Clauses *last;
|
||||
int idx; /* is code indexed ? 0= needs compilation -1= no indexing possible 1= indexed */
|
||||
unsigned int idx_var; /* nr clauses with 1st argument var */
|
||||
unsigned int idx_list; /* nr clauses with 1st argument list */
|
||||
unsigned int idx_atom; /* nr clauses with 1st argument atom */
|
||||
unsigned int idx_functor; /* nr clauses with 1st argument functor */
|
||||
short int eager_split; /* allow eager splitting */
|
||||
|
||||
Cell *code; /* try, retry and trust code or Indexing code */
|
||||
struct HASH_TABLE **atom;
|
||||
struct HASH_TABLE **functor;
|
||||
Cell *list;
|
||||
Cell *vars;
|
||||
struct Predicates *next;
|
||||
};
|
||||
|
||||
/**************************** EAM TRUE STUFF *************/
|
||||
|
||||
struct SUSPENSIONS {
|
||||
struct AND_BOX *and_box; /* And_box where the variable has suspended */
|
||||
short int reason; /* suspended before executing call number nr_call */
|
||||
struct SUSPENSIONS *next; /* Pointer to the next suspention */
|
||||
struct SUSPENSIONS *prev;
|
||||
};
|
||||
|
||||
struct SUSPENSIONS_VAR {
|
||||
struct AND_BOX *and_box; /* And_box where the variable has suspended */
|
||||
struct SUSPENSIONS_VAR *next; /* Pointer to the next suspention */
|
||||
};
|
||||
|
||||
struct PERM_VAR {
|
||||
Cell value; /* value assigned to the variable */
|
||||
struct AND_BOX *home; /* pointer to the goal_box structure of the variable */
|
||||
Cell *yapvar;
|
||||
struct SUSPENSIONS_VAR *suspensions; /* Pointer to a Suspension List */
|
||||
struct PERM_VAR *next;
|
||||
};
|
||||
|
||||
struct EXTERNAL_VAR { /* to be used as some kind of trail */
|
||||
Cell value; /* value assign to the variable */
|
||||
struct PERM_VAR *var; /* pointer to the local_var struct */
|
||||
struct EXTERNAL_VAR *next;
|
||||
};
|
||||
|
||||
struct status_and {
|
||||
struct OR_BOX *call; /* POINTER TO A OR_BOX */
|
||||
Cell *locals; /* temporary vars vector */
|
||||
Cell *code; /* Pointer to the start code */
|
||||
int state; /* State of the OR_BOX */
|
||||
struct status_and *previous;
|
||||
struct status_and *next;
|
||||
};
|
||||
|
||||
struct status_or {
|
||||
struct AND_BOX *alternative; /* POINTER TO A AND_BOX */
|
||||
Cell *args; /* Saved Arguments */
|
||||
Cell *code; /* Pointer to Start Code */
|
||||
int state; /* State of the AND_BOX */
|
||||
struct status_or *previous;
|
||||
struct status_or *next;
|
||||
};
|
||||
|
||||
struct OR_BOX {
|
||||
struct AND_BOX *parent;
|
||||
struct status_and *nr_call; /* order of this box */
|
||||
short int nr_all_alternatives; /* number of existing alternatives */
|
||||
struct status_or *alternatives; /* alternatives of the or_box */
|
||||
short int eager_split;
|
||||
};
|
||||
|
||||
struct AND_BOX {
|
||||
struct OR_BOX *parent; /* pointer to the parent or-box */
|
||||
struct status_or *nr_alternative; /* This box is alternative id */
|
||||
short int nr_all_calls; /* numger of all goals */
|
||||
struct PERM_VAR *perms;
|
||||
struct status_and *calls;
|
||||
|
||||
short int level; /* indicates the level in the tree */
|
||||
struct EXTERNAL_VAR *externals; /* pointer to a list of external_vars */
|
||||
struct SUSPENSIONS *suspended; /* pointer to a list of suspended boxes */
|
||||
short int side_effects; /* to mark if are calls to builtins with side_efects (like write) */
|
||||
};
|
||||
|
||||
|
||||
/* TYPE OF STATES */
|
||||
#define ZERO 0 /* No State yet */
|
||||
#define SUCCESS 1
|
||||
#define FAILS 2
|
||||
#define READY 4 /* Is ready to start execution */
|
||||
#define RUNNING 8 /* Is running */
|
||||
#define RUNAGAIN 16 /* Is running again */
|
||||
#define SUSPEND 32 /* Has suspended */
|
||||
#define WAKE 64 /* Was Suspended, but now is Ready again */
|
||||
#define CHANGED 128 /* Has received some change on it's external variables, needs to re-run */
|
||||
#define END 256 /* Has suspended on end, on wake up can pass to a success state */
|
||||
#define WAITING 512 /* The clause is waiting for the previous predicates to leave the Suspended state */
|
||||
#define FAILED 1024 /* has failed */
|
||||
|
||||
#define CUT_RIGHT 2048
|
||||
#define SKIP_VAR 4096
|
||||
#define LEFTMOST_PARENT 8192
|
||||
#define FIRST 16384
|
||||
#define LEFTMOST 32768
|
||||
|
||||
#define WAITING_TO_BE_FIRST (WAITING + FIRST)
|
||||
#define WAITING_TO_BE_LEFTMOST (WAITING + LEFTMOST)
|
||||
#define WAITING_TO_BE_LEFTMOST_PARENT (WAITING + LEFTMOST_PARENT)
|
||||
#define WAITING_TO_CUT (WAITING + CUT_RIGHT)
|
||||
#define WAITING_SKIP_VAR (WAITING + SKIP_VAR)
|
||||
#define SUSPEND_END (SUSPEND+END)
|
||||
#define WAKE_END (WAKE+END)
|
||||
|
||||
|
||||
#define NORMAL_SUSPENSION 0
|
||||
#define LEFTMOST_SUSPENSION 1
|
||||
#define WAIT_SUSPENSION 2
|
||||
#define CUT_SUSPENSION 3
|
||||
#define WRITE_SUSPENSION 4
|
||||
#define VAR_SUSPENSION 5
|
||||
#define YAP_VAR_SUSPENSION 6
|
||||
|
||||
/* TYPE OF SIDE_EFFECTS */
|
||||
|
||||
#define WRITE 1
|
||||
#define COMMIT 2
|
||||
#define VAR 4
|
||||
#define SEQUENCIAL 8
|
||||
|
||||
#define CUT 32 /* Greater than 32 always cut */
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
|
||||
struct EAM_TEMP {
|
||||
|
||||
|
||||
|
||||
struct EAM_TEMP *previous;
|
||||
struct EAM_TEMP *next;
|
||||
};
|
||||
|
||||
struct EAM_Global {
|
||||
Cell *pc;
|
||||
Cell *_H;
|
||||
Cell *_S;
|
||||
short _Mode; /* read or write mode */
|
||||
short ES; /* goal shoud do Eager Split yes or no ? */
|
||||
short MemGoing; /* Direction the that stacks use to grow */
|
||||
Cell *varlocals; /* local vars to the working AND-BOX */
|
||||
struct AND_BOX *ABX; /* working AND-BOX */
|
||||
struct OR_BOX *OBX; /* working OR-BOX */
|
||||
struct SUSPENSIONS *su; /* list with suspended work */
|
||||
struct AND_BOX *top;
|
||||
|
||||
struct status_and *USE_SAME_ANDBOX; /* when only 1 alternative */
|
||||
struct status_or *nr_alternative; /* working alternative */
|
||||
struct status_and *nr_call; /* working goal */
|
||||
|
||||
Cell *VAR_TRAIL;
|
||||
int VAR_TRAIL_NR;
|
||||
int Mem_FULL; /* if mem_full, then perform GC */
|
||||
int nr_call_forking; /* number of splits already performed */
|
||||
unsigned long START_ADDR_HEAP, START_ADDR_BOXES, END_BOX, END_H;
|
||||
unsigned int nr_gc_heap;
|
||||
unsigned int nr_gc_boxed;
|
||||
Cell **IndexFree;
|
||||
Cell *NextFree;
|
||||
Cell *sp;
|
||||
struct PERM_VAR *NextVar;
|
||||
|
||||
#if Memory_Stat
|
||||
unsigned long TOTAL_MEM, MEM_REUSED, TOTAL_TEMPS,TEMPS_REUSED, TOTAL_PERMS, PERMS_REUSED;
|
||||
unsigned long Memory_STAT[5000][5];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#define beam_X XREGS /* use the same X-Regs as YAP */
|
||||
|
||||
#define beam_pc (eamGlobal->pc)
|
||||
#define beam_H (eamGlobal->_H)
|
||||
#define beam_S (eamGlobal->_S)
|
||||
#define beam_Mode (eamGlobal->_Mode)
|
||||
#define beam_ES (eamGlobal->ES)
|
||||
#define beam_MemGoing (eamGlobal->MemGoing)
|
||||
#define beam_varlocals (eamGlobal->varlocals)
|
||||
#define beam_ABX (eamGlobal->ABX)
|
||||
#define beam_OBX (eamGlobal->OBX)
|
||||
#define beam_su (eamGlobal->su)
|
||||
#define beam_top (eamGlobal->top)
|
||||
#define beam_USE_SAME_ANDBOX (eamGlobal->USE_SAME_ANDBOX)
|
||||
#define beam_nr_alternative (eamGlobal->nr_alternative)
|
||||
#define beam_nr_call (eamGlobal->nr_call)
|
||||
#define beam_VAR_TRAIL (eamGlobal->VAR_TRAIL)
|
||||
#define beam_VAR_TRAIL_NR (eamGlobal->VAR_TRAIL_NR)
|
||||
#define beam_Mem_FULL (eamGlobal->Mem_FULL)
|
||||
#define beam_nr_call_forking (eamGlobal->nr_call_forking)
|
||||
#define beam_START_ADDR_HEAP (eamGlobal->START_ADDR_HEAP)
|
||||
#define beam_START_ADDR_BOXES (eamGlobal->START_ADDR_BOXES)
|
||||
#define beam_END_BOX (eamGlobal->END_BOX)
|
||||
#define beam_END_H (eamGlobal->END_H)
|
||||
#define beam_nr_gc_heap (eamGlobal->nr_gc_heap)
|
||||
#define beam_nr_gc_boxed (eamGlobal->nr_gc_boxed)
|
||||
#define beam_IndexFree (eamGlobal->IndexFree)
|
||||
#define beam_NextFree (eamGlobal->NextFree)
|
||||
#define beam_sp (eamGlobal->sp)
|
||||
#define beam_NextVar (eamGlobal->NextVar)
|
||||
#if Memory_Stat
|
||||
#define beam_TOTAL_MEM (eamGlobal->TOTAL_MEM)
|
||||
#define beam_MEM_REUSED (eamGlobal->MEM_REUSED)
|
||||
#define beam_TOTAL_TEMPS (eamGlobal->TOTAL_TEMPS)
|
||||
#define beam_TEMPS_REUSED (eamGlobal->TEMPS_REUSED)
|
||||
#define beam_TOTAL_PERMS (eamGlobal->TOTAL_PERMS)
|
||||
#define beam_PERMS_REUSED (eamGlobal->PERMS_REUSED)
|
||||
#define beam_Memory_STAT (eamGlobal->Memory_STAT)
|
||||
#endif
|
||||
|
||||
#define arg1 *(beam_pc+1)
|
||||
#define arg2 *(beam_pc+2)
|
||||
#define arg3 *(beam_pc+3)
|
||||
#define arg4 *(beam_pc+4)
|
||||
|
||||
#define CELL_SIZE (sizeof(Cell))
|
||||
#define POINTER_SIZE (sizeof(Cell *))
|
||||
#define ANDBOX_SIZE (sizeof(struct AND_BOX))
|
||||
#define ORBOX_SIZE (sizeof(struct OR_BOX))
|
||||
#define PERM_VAR_SIZE (sizeof(struct PERM_VAR))
|
||||
#define EXTERNAL_VAR_SIZE (sizeof(struct EXTERNAL_VAR))
|
||||
#define SUSPENSIONS_SIZE (sizeof(struct SUSPENSIONS))
|
||||
#define SUSPENSIONS_VAR_SIZE (sizeof(struct SUSPENSIONS_VAR))
|
||||
#define STATUS_AND_SIZE (sizeof(struct status_and))
|
||||
#define STATUS_OR_SIZE (sizeof(struct status_or))
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,498 @@
|
|||
/*************************************************************************
|
||||
* *
|
||||
* BEAM -> Basic Extended Andorra Model *
|
||||
* BEAM extends the YAP Prolog system to support the EAM *
|
||||
* *
|
||||
* Copyright: Ricardo Lopes and NCC - University of Porto, Portugal *
|
||||
* *
|
||||
**************************************************************************
|
||||
* comments: garbage collector routines *
|
||||
*************************************************************************/
|
||||
|
||||
|
||||
void garbage_collector(void);
|
||||
struct OR_BOX *move_orbox(struct OR_BOX *o,struct AND_BOX *parent,struct status_and *nr_call);
|
||||
struct AND_BOX *move_andbox(struct AND_BOX *a,struct OR_BOX *parent,struct status_or *alt);
|
||||
Cell refresh_structures(Cell c);
|
||||
Cell move_structures(Cell c);
|
||||
void refresh_andbox(struct AND_BOX *a);
|
||||
void refresh_orbox(struct OR_BOX *o);
|
||||
|
||||
Cell refresh_structures(Cell c)
|
||||
{
|
||||
Cell *C, OldC;
|
||||
|
||||
OldC=deref((Cell) c);
|
||||
|
||||
if (isvar(OldC)) {
|
||||
return(OldC);
|
||||
}
|
||||
if (isatom(OldC)) {
|
||||
return(OldC);
|
||||
}
|
||||
|
||||
if (isappl(OldC)) {
|
||||
int i,arity;
|
||||
|
||||
C=(Cell *) repappl(OldC);
|
||||
arity = ((int) ArityOfFunctor((Functor) *C));
|
||||
for(i=0;i<arity ;i++) {
|
||||
C++;
|
||||
*C=refresh_structures((Cell) C);
|
||||
}
|
||||
return(OldC);
|
||||
}
|
||||
/* else if (ispair(c)) { */
|
||||
C=(Cell *) reppair(OldC);
|
||||
*C=refresh_structures((Cell) C);
|
||||
C++;
|
||||
*C=refresh_structures((Cell) C);
|
||||
return(OldC);
|
||||
}
|
||||
|
||||
Cell move_structures(Cell c)
|
||||
{
|
||||
Cell *NewC, *NewH;
|
||||
Cell OldC,LOCAL_OldH;
|
||||
|
||||
OldC=deref((Cell) c);
|
||||
/*
|
||||
if (beam_MemGoing==1 && ((unsigned long) OldC) <beam_START_ADDR_HEAP+beam_MEM_H/2) return(OldC);
|
||||
if (beam_MemGoing==-1 && ((unsigned long) OldC)>=beam_START_ADDR_HEAP+beam_MEM_H/2 && ((unsigned long) OldC) <beam_START_ADDR_BOXES) return(OldC);
|
||||
*/
|
||||
if (isvar(OldC)) {
|
||||
return(OldC);
|
||||
}
|
||||
if (isatom(OldC)) {
|
||||
return(OldC);
|
||||
}
|
||||
|
||||
LOCAL_OldH=(Cell) beam_H;
|
||||
NewH=beam_H;
|
||||
if (isappl(OldC)) {
|
||||
int i,arity;
|
||||
|
||||
NewC=(Cell *) repappl(OldC);
|
||||
arity = ((int) ArityOfFunctor((Functor) *NewC));
|
||||
*NewH++=*NewC++;
|
||||
beam_H+=arity+1;
|
||||
for(i=0;i<arity ;i++) {
|
||||
*NewH=move_structures((Cell) NewC);
|
||||
NewH++;
|
||||
NewC++;
|
||||
}
|
||||
return(absappl(LOCAL_OldH));
|
||||
}
|
||||
/* else if (ispair(c)) { */
|
||||
NewC=(Cell *) reppair(OldC);
|
||||
beam_H+=2;
|
||||
*NewH=move_structures((Cell) NewC);
|
||||
NewC++;
|
||||
NewH++;
|
||||
*NewH=move_structures((Cell) NewC);
|
||||
return(abspair(LOCAL_OldH));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void garbage_collector()
|
||||
{
|
||||
#if GARBAGE_COLLECTOR==2
|
||||
struct AND_BOX *new_top;
|
||||
#endif
|
||||
|
||||
if (beam_Mem_FULL & 2) beam_nr_gc_heap++; else beam_nr_gc_boxed++;
|
||||
#if Debug || Debug_GC
|
||||
printf("Entering Garbage Collector for the %dth time (Reason=%d)\n",beam_nr_gc_heap+beam_nr_gc_boxed,beam_Mem_FULL);
|
||||
#endif
|
||||
#if Debug_Dump_State & 2
|
||||
dump_eam_state();
|
||||
printf("--------------------------------------------------------------------\n");
|
||||
#endif
|
||||
|
||||
beam_Mem_FULL=0;
|
||||
|
||||
#if Memory_Stat
|
||||
if (beam_MemGoing==1) {
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][1]=(unsigned long) beam_H-beam_START_ADDR_HEAP;
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][2]=(unsigned long) beam_NextFree-beam_START_ADDR_BOXES;
|
||||
} else {
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][1]=(unsigned long) beam_H-beam_START_ADDR_HEAP-MEM_H/2;
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][2]=beam_END_BOX- ((unsigned long) beam_NextFree);
|
||||
}
|
||||
if (GARBAGE_COLLECTOR==1)
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][2]=beam_END_BOX- ((unsigned long) beam_NextFree);
|
||||
#endif
|
||||
|
||||
#if GARBAGE_COLLECTOR==1
|
||||
if (beam_MemGoing==1) {
|
||||
if (beam_H < (Cell *) (beam_START_ADDR_HEAP+MEM_H/2)) beam_H=(Cell *) (beam_START_ADDR_HEAP+MEM_H/2); else beam_H++;
|
||||
beam_MemGoing=-1;
|
||||
beam_sp=(Cell *) beam_START_ADDR_HEAP+MEM_H/2;
|
||||
beam_sp--;
|
||||
} else {
|
||||
beam_H=(Cell *) beam_START_ADDR_HEAP;
|
||||
beam_MemGoing=1;
|
||||
beam_sp=(Cell *) beam_END_H;
|
||||
beam_sp--;
|
||||
}
|
||||
refresh_andbox(beam_top);
|
||||
|
||||
#if Clear_MEMORY
|
||||
if (beam_MemGoing==-1) {
|
||||
memset(beam_START_ADDR_HEAP,0,MEM_H/2);
|
||||
} else {
|
||||
memset(beam_START_ADDR_HEAP+MEM_H/2,0,MEM_H/2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
memset(beam_IndexFree,0,INDEX_SIZE*POINTER_SIZE);
|
||||
if (beam_MemGoing==1) {
|
||||
if (beam_H < (Cell *) (beam_START_ADDR_HEAP+MEM_H/2)) beam_H=(Cell *) (beam_START_ADDR_HEAP+MEM_H/2); else beam_H++;
|
||||
beam_NextFree=(Cell *) beam_END_BOX;
|
||||
beam_MemGoing=-1;
|
||||
beam_sp=(Cell *) beam_START_ADDR_HEAP+MEM_H/2; beam_sp-=2;
|
||||
} else {
|
||||
if (beam_H>=(Cell *) beam_START_ADDR_BOXES) beam_NextFree=beam_H+1; else beam_NextFree=(Cell *) beam_START_ADDR_BOXES;
|
||||
beam_H=(Cell *) beam_START_ADDR_HEAP;
|
||||
beam_MemGoing=1;
|
||||
beam_sp=(Cell *) beam_END_H; beam_sp-=2;
|
||||
}
|
||||
beam_Mem_FULL=0;
|
||||
|
||||
beam_su=NULL;
|
||||
new_top=move_andbox(beam_top,NULL,NULL);
|
||||
beam_top=new_top;
|
||||
|
||||
#if Clear_MEMORY
|
||||
if (beam_MemGoing==-1) {
|
||||
memset((void *) beam_START_ADDR_HEAP,0,MEM_H/2);
|
||||
memset((void *) beam_START_ADDR_BOXES,0,MEM_BOXES/2);
|
||||
} else {
|
||||
memset((void *) beam_START_ADDR_HEAP+MEM_H/2,0,MEM_H/2);
|
||||
memset((void *) beam_START_ADDR_BOXES+MEM_BOXES/2,0,MEM_BOXES/2);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if Memory_Stat
|
||||
if (beam_MemGoing==1) {
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][3]=(unsigned long) beam_H- beam_START_ADDR_HEAP;
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][4]=(unsigned long) beam_NextFree- beam_START_ADDR_BOXES;
|
||||
} else {
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][3]=(unsigned long) beam_H- beam_START_ADDR_HEAP-MEM_H/2;
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][4]= beam_END_BOX- ((unsigned long) beam_NextFree);
|
||||
}
|
||||
if (GARBAGE_COLLECTOR==1)
|
||||
beam_Memory_STAT[beam_nr_gc_heap+beam_nr_gc_boxed][4]= beam_END_BOX- ((unsigned long) beam_NextFree);
|
||||
#endif
|
||||
|
||||
#if Debug_Dump_State & 2
|
||||
dump_eam_state();
|
||||
#endif
|
||||
#if Debug
|
||||
printf("End of Garbage Collector\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if GARBAGE_COLLECTOR!=1
|
||||
|
||||
|
||||
struct OR_BOX *move_orbox(struct OR_BOX *o,struct AND_BOX *parent,struct status_and *nr_call)
|
||||
{
|
||||
struct OR_BOX *new_orbox;
|
||||
struct status_or *old, *new, *first=NULL, *last=NULL;
|
||||
Cell *args,*newargs;
|
||||
|
||||
if (o==NULL) return(NULL);
|
||||
#if !Fast_go
|
||||
if ((Cell *) o<(Cell *) beam_START_ADDR_BOXES || (Cell *) o>(Cell *) beam_END_BOX) return (NULL);
|
||||
#endif
|
||||
new_orbox=(struct OR_BOX *) request_memory(ORBOX_SIZE);
|
||||
if (beam_Mem_FULL) abort_eam("Sem Memoria para GC\n");
|
||||
if (beam_OBX==o) beam_OBX=new_orbox;
|
||||
new_orbox->parent=parent;
|
||||
new_orbox->nr_call=nr_call;
|
||||
new_orbox->nr_all_alternatives=o->nr_all_alternatives;
|
||||
|
||||
old=o->alternatives;
|
||||
while(old!=NULL) {
|
||||
new=(struct status_or *) request_memory(STATUS_OR_SIZE);
|
||||
if (beam_Mem_FULL) abort_eam("Sem Memoria para GC\n");
|
||||
|
||||
if (beam_nr_alternative==old) beam_nr_alternative=new;
|
||||
new->args=old->args;
|
||||
new->code=old->code;
|
||||
new->state=old->state;
|
||||
new->alternative=move_andbox(old->alternative,new_orbox,new);
|
||||
|
||||
if (first==NULL) first=new;
|
||||
else last->next=new;
|
||||
new->previous=last;
|
||||
new->next=NULL;
|
||||
last=new;
|
||||
old=old->next;
|
||||
}
|
||||
new_orbox->alternatives=first;
|
||||
|
||||
args=NULL;
|
||||
newargs=NULL;
|
||||
while(last!=NULL) {
|
||||
if (last->args==NULL) {
|
||||
args=NULL;
|
||||
newargs=NULL;
|
||||
} else if (args!=last->args) {
|
||||
int y;
|
||||
args=last->args;
|
||||
#if Debug
|
||||
printf("Request args=%d \n",(int) args[0]);
|
||||
#endif
|
||||
newargs=(Cell *)request_memory((args[0])*sizeof(Cell));
|
||||
if (beam_Mem_FULL) abort_eam("Sem Memoria para GC\n");
|
||||
newargs[0]=args[0];
|
||||
for(y=1;y<args[0];y++) newargs[y]=move_structures(args[y]);
|
||||
}
|
||||
last->args=newargs;
|
||||
last=last->previous;
|
||||
}
|
||||
|
||||
return(new_orbox);
|
||||
}
|
||||
|
||||
struct AND_BOX *move_andbox(struct AND_BOX *a,struct OR_BOX *parent, struct status_or *alt )
|
||||
{
|
||||
int OLD_VAR_TRAIL_NR;
|
||||
struct AND_BOX *new_andbox;
|
||||
struct PERM_VAR *l;
|
||||
struct EXTERNAL_VAR *old_externals,*externals;
|
||||
|
||||
if (a==NULL) return(NULL);
|
||||
OLD_VAR_TRAIL_NR=beam_VAR_TRAIL_NR;
|
||||
|
||||
new_andbox=(struct AND_BOX *) request_memory(ANDBOX_SIZE);
|
||||
if (beam_Mem_FULL) abort_eam("Sem Memoria para GC\n");
|
||||
if (beam_ABX==a) beam_ABX=new_andbox;
|
||||
new_andbox->parent=parent;
|
||||
new_andbox->nr_alternative=alt;
|
||||
new_andbox->level=a->level;
|
||||
new_andbox->side_effects=a->side_effects;
|
||||
new_andbox->suspended=NULL;
|
||||
if (a->suspended) {
|
||||
new_andbox->suspended=addto_suspensions_list(new_andbox,a->suspended->reason);
|
||||
}
|
||||
new_andbox->perms=a->perms;
|
||||
l=a->perms;
|
||||
while(l!=NULL) { /* ainda nao estou a fazer GC nas Var Perm */
|
||||
l->value=move_structures(l->value);
|
||||
l->home=new_andbox;
|
||||
l->suspensions=NULL;
|
||||
l=l->next;
|
||||
}
|
||||
|
||||
old_externals=a->externals;
|
||||
externals=NULL;
|
||||
while(old_externals) {
|
||||
struct EXTERNAL_VAR *e;
|
||||
struct SUSPENSIONS_VAR *s;
|
||||
|
||||
e=(struct EXTERNAL_VAR *) request_memory(EXTERNAL_VAR_SIZE);
|
||||
|
||||
e->next=externals;
|
||||
externals=e;
|
||||
|
||||
e->value=move_structures(old_externals->value);
|
||||
e->var=(struct PERM_VAR *) old_externals->var;
|
||||
//e->var=(struct PERM_VAR *) old_externals->var; CUIDADO QUANDO FIZER GC PERM_VARS
|
||||
|
||||
if (isvar(e->var)) {
|
||||
s=(struct SUSPENSIONS_VAR *) request_memory(SUSPENSIONS_VAR_SIZE);
|
||||
s->and_box=new_andbox;
|
||||
s->next=e->var->suspensions;
|
||||
e->var->suspensions=s;
|
||||
}
|
||||
old_externals=old_externals->next;
|
||||
}
|
||||
new_andbox->externals=externals;
|
||||
if (beam_Mem_FULL) abort_eam("Sem Memoria para GC\n");
|
||||
|
||||
|
||||
/* CUIDADO: Preciso agora de duplicar os vectores das variaveis locais */
|
||||
{ struct status_and *calls;
|
||||
#if !Fast_go
|
||||
Cell **backup=NULL; int i, counted=0,max=1000;
|
||||
backup=(Cell **) malloc(max);
|
||||
#else
|
||||
Cell *backup[1000]; int i, counted=0;
|
||||
#endif
|
||||
|
||||
calls=a->calls;
|
||||
while(calls!=NULL) {
|
||||
if (calls->locals!=NULL) {
|
||||
/* primeiro vou ver se já foi copiado */
|
||||
for(i=0;i<counted;i+=2) {
|
||||
if (backup[i]==calls->locals) {
|
||||
calls->locals=backup[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i==counted) { /* afinal ainda nao foi copiado: fazer copia em duas fases*/
|
||||
Cell *c, *newvars, *oldvars; int nr;
|
||||
|
||||
oldvars=calls->locals;
|
||||
nr=oldvars[-1];
|
||||
newvars=request_memory_locals(nr);
|
||||
|
||||
if (beam_varlocals==oldvars) beam_varlocals=newvars;
|
||||
|
||||
calls->locals=newvars;
|
||||
/* primeiro actualizo as variaveis */
|
||||
for(i=0;i<nr;i++) {
|
||||
c=&oldvars[i];
|
||||
if ((Cell *)*c==c) {
|
||||
newvars[i]=(Cell) &newvars[i];
|
||||
*c=newvars[i];
|
||||
} else {
|
||||
newvars[i]= (Cell) *c;
|
||||
*c=(Cell) &newvars[i];
|
||||
}
|
||||
}
|
||||
/* depois copio as estruturas */
|
||||
for(i=0;i<nr;i++) {
|
||||
newvars[i]=move_structures(oldvars[i]);
|
||||
}
|
||||
#if !Fast_go
|
||||
if (max<counted+2) {
|
||||
max+=200;
|
||||
backup=realloc(backup,max);
|
||||
if (backup==NULL) abort_eam("No more memory... realloc in gc \n");
|
||||
}
|
||||
#else
|
||||
if (counted>=998) abort_eam("No more memory... realloc in gc \n");
|
||||
#endif
|
||||
backup[counted]=oldvars;
|
||||
backup[counted+1]=newvars;
|
||||
counted+=2;
|
||||
}
|
||||
}
|
||||
calls=calls->next;
|
||||
}
|
||||
#if !Fast_go
|
||||
free(backup);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
new_andbox->nr_all_calls=a->nr_all_calls;
|
||||
{ struct status_and *first=NULL, *last=NULL,*calls,*calls_new;
|
||||
calls=a->calls;
|
||||
while(calls!=NULL){
|
||||
calls_new=(struct status_and *) request_memory(STATUS_AND_SIZE);
|
||||
if (beam_Mem_FULL) abort_eam("Sem Memoria para GC\n");
|
||||
calls_new->code=calls->code;
|
||||
calls_new->state=calls->state;
|
||||
calls_new->locals=calls->locals;
|
||||
if (beam_nr_call==calls) beam_nr_call=calls_new;
|
||||
|
||||
calls_new->call=move_orbox(calls->call,new_andbox,calls_new);
|
||||
|
||||
if (first==NULL) first=calls_new;
|
||||
else last->next=calls_new;
|
||||
calls_new->previous=last;
|
||||
calls_new->next=NULL;
|
||||
last=calls_new;
|
||||
calls=calls->next;
|
||||
}
|
||||
new_andbox->calls=first;
|
||||
}
|
||||
|
||||
return(new_andbox);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#else /* used by GC Only on Heap || Keep boxes on same memory */
|
||||
|
||||
void refresh_orbox(struct OR_BOX *o)
|
||||
{
|
||||
struct status_or *old, *last=NULL;
|
||||
Cell *args;
|
||||
|
||||
if (o==NULL) return;
|
||||
|
||||
old=o->alternatives;
|
||||
while(old!=NULL) {
|
||||
refresh_andbox(old->alternative);
|
||||
last=old;
|
||||
old=old->next;
|
||||
}
|
||||
|
||||
args=NULL;
|
||||
while(last!=NULL) {
|
||||
if (last->args==NULL) {
|
||||
args=NULL;
|
||||
}else if (args!=last->args) {
|
||||
int y;
|
||||
args=last->args;
|
||||
for(y=1;y<args[0];y++) {
|
||||
args[y]=move_structures(args[y]);
|
||||
}
|
||||
}
|
||||
last=last->previous;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void refresh_andbox(struct AND_BOX *a)
|
||||
{
|
||||
struct PERM_VAR *l;
|
||||
struct EXTERNAL_VAR *externals;
|
||||
struct status_and *calls;
|
||||
|
||||
if (a==NULL) return;
|
||||
|
||||
l=a->perms;
|
||||
while(l!=NULL) {
|
||||
l->value=move_structures(l->value);
|
||||
l=l->next;
|
||||
}
|
||||
|
||||
externals=a->externals;
|
||||
while(externals) {
|
||||
externals->value=move_structures(externals->value);
|
||||
externals=externals->next;
|
||||
}
|
||||
|
||||
calls=a->calls;
|
||||
while(calls!=NULL) {
|
||||
// if (calls->calls!=NULL) {
|
||||
if (calls->locals!=NULL && ((int) calls->locals[-1]>0) {
|
||||
int nr,i;
|
||||
nr=calls->locals[-1];
|
||||
calls->locals[-1]=-nr;
|
||||
for(i=0;i<nr;i++) {
|
||||
calls->locals[i]=move_structures(calls->locals[i]);
|
||||
}
|
||||
}
|
||||
refresh_orbox(calls->call);
|
||||
// }
|
||||
calls=calls->next;
|
||||
}
|
||||
calls=a->calls;
|
||||
while(calls!=NULL) {
|
||||
if (calls->locals!=NULL && ((int) calls->locals[-1])<0) {
|
||||
int nr;
|
||||
nr=calls->locals[-1];
|
||||
calls->locals[-1]=-nr;
|
||||
}
|
||||
calls=calls->next;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,374 @@
|
|||
/*************************************************************************
|
||||
* *
|
||||
* BEAM -> Basic Extended Andorra Model *
|
||||
* BEAM extends the YAP Prolog system to support the EAM *
|
||||
* *
|
||||
* Copyright: Ricardo Lopes and NCC - University of Porto, Portugal *
|
||||
* *
|
||||
**************************************************************************
|
||||
* comments: eam show abstract machine assembler *
|
||||
*************************************************************************/
|
||||
|
||||
#ifdef BEAM
|
||||
|
||||
#include<stdio.h>
|
||||
#include "Yap.h"
|
||||
#include "Yatom.h"
|
||||
#include "eam.h"
|
||||
#include "eamamasm.h"
|
||||
|
||||
void eam_showcode(Cell *code);
|
||||
extern int am_to_inst(Cell inst);
|
||||
|
||||
void eam_showcode(Cell *code)
|
||||
{
|
||||
int n;
|
||||
#define carg1 *(code+1)
|
||||
#define carg2 *(code+2)
|
||||
#define carg3 *(code+3)
|
||||
#define carg4 *(code+4)
|
||||
|
||||
printf("--------------------------------------------------\n");
|
||||
while (1) {
|
||||
n=am_to_inst(*code);
|
||||
printf("%ld->",(long) code);
|
||||
switch(n) {
|
||||
case(_exit_eam):
|
||||
printf("_exit\n");
|
||||
code++;
|
||||
if (*(code)==-1) return;
|
||||
break;
|
||||
case(_top_tree):
|
||||
printf("_top_tree \n");
|
||||
code++;
|
||||
break;
|
||||
case(_scheduler):
|
||||
printf("_scheduler \n");
|
||||
code++;
|
||||
break;
|
||||
case(_prepare_tries):
|
||||
printf("_prepare_tries for %d clauses with arity=%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_prepare_calls ):
|
||||
printf("_prepare_calls %d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_get_var_X_op ):
|
||||
printf("_get_var_X_op X%d, X%d\n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_get_var_Y_op ):
|
||||
printf("_get_var_Y_op X%d, Y%d\n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_get_val_X_op ):
|
||||
printf("_get_val_X_op X%d, X%d\n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_get_val_Y_op ):
|
||||
printf("_get_val_Y_op X%d, Y%d\n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_get_atom_op ):
|
||||
printf("_get_atom_op X%d, %d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_get_list_op ):
|
||||
printf("_get_list_op X%d\n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_get_struct_op ):
|
||||
printf("_get_struct_op X%d, %lX/%d\n",(int) carg1,(unsigned long) carg2,(int) carg3);
|
||||
code+=4;
|
||||
break;
|
||||
case(_unify_void_op ):
|
||||
printf("_unify_void_op\n");
|
||||
code++;
|
||||
break;
|
||||
case(_unify_val_X_op ):
|
||||
printf("_unify_val_X_op X%d\n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_unify_val_Y_op ):
|
||||
printf("_unify_val_Y_op Y%d\n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_unify_var_X_op ):
|
||||
printf("_unify_var_X_op X%d\n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_unify_var_Y_op ):
|
||||
printf("_unify_var_Y_op Y%d\n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_unify_atom_op ):
|
||||
printf("_unify_atom_op 0x%lX\n",(unsigned long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_unify_list_op ):
|
||||
printf("_unify_list_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_unify_last_list_op ):
|
||||
printf("_unify_last_list_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_unify_struct_op ):
|
||||
printf("_unify_struct_op 0x%lX,%d\n",(unsigned long) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_unify_last_struct_op ):
|
||||
printf("_unify_last_struct_op 0x%lX,%d\n",(unsigned long) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_unify_last_atom_op ):
|
||||
printf("_unify_last_atom_op 0x%lX\n",(unsigned long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_unify_local_X_op ):
|
||||
printf("_unify_local_X_op X%d\n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_unify_local_Y_op ):
|
||||
printf("_unify_local_Y_op X%d\n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_put_var_X_op ):
|
||||
printf("_put_var_X_op X%d,X%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_put_var_Y_op ):
|
||||
printf("_put_var_Y_op X%d,Y%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_put_var_P_op ):
|
||||
printf("_put_var_P_op X%d,Y%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_put_val_X_op ):
|
||||
printf("_put_val_X_op X%d,X%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_put_val_Y_op ):
|
||||
printf("_put_val_Y_op X%d,Y%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_put_atom_op ):
|
||||
printf("_put_atom_op X%d, %d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_put_list_op ):
|
||||
printf("_put_list_op X%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_put_struct_op ):
|
||||
printf("_put_struct_op X%d,%d,%d \n",(int) carg1,(int) carg2,(int) carg3);
|
||||
code+=4;
|
||||
break;
|
||||
case(_put_unsafe_op ):
|
||||
printf("_put_unsafe_op X%d, Y%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_write_void ):
|
||||
printf("_write_void \n");
|
||||
code++;
|
||||
break;
|
||||
case(_write_var_X_op ):
|
||||
printf("_write_var_X_op X%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_write_var_Y_op ):
|
||||
printf("_write_var_Y_op Y%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_write_var_P_op ):
|
||||
printf("_write_var_P_op Y%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_write_val_X_op ):
|
||||
printf("_write_val_X_op X%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_write_val_Y_op ):
|
||||
printf("_write_val_Y_op Y%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_write_atom_op ):
|
||||
printf("_write_atom_op %d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_write_list_op ):
|
||||
printf("_write_list_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_write_struct_op ):
|
||||
printf("_write_struct_op %d,%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_write_last_list_op ):
|
||||
printf("_write_last_list_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_write_last_struct_op ):
|
||||
printf("_write_last_struct_op %d,%d \n",(int) carg1,(int) carg2);
|
||||
code+=3;
|
||||
break;
|
||||
case(_write_local_X_op ):
|
||||
printf("_write_local_X_op X%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_write_local_Y_op ):
|
||||
printf("_write_local_Y_op Y%d \n",(int) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_pop_op ):
|
||||
printf("_pop_read_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_jump_op ):
|
||||
printf("_jump_op %ld\n",(long int) carg1);
|
||||
code+=4;
|
||||
break;
|
||||
case(_proceed_op ):
|
||||
printf("_proceed_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_call_op ):
|
||||
printf("_call_op %s/%d \n", ((PredEntry *) carg1)->beamTable->name,((PredEntry *) carg1)->beamTable->arity);
|
||||
code+=2;
|
||||
break;
|
||||
case(_safe_call_op ):
|
||||
printf("_safe_call_op %ld \n",(long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_safe_call_unary_op ):
|
||||
printf("_safe_call_unary_op %ld \n",(long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_safe_call_binary_op ):
|
||||
printf("_safe_call_binary_op %ld \n",(long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
|
||||
case(_only_1_clause_op ):
|
||||
printf("_only_1_clause_op -> Use the same AND_BOX for the %dth clause of predicate %s/%d (Yvars=%d) \n",(int) carg4,((struct Clauses *)carg1)->predi->name,(int) carg2,(int) carg3);
|
||||
code+=4;
|
||||
break;
|
||||
case(_try_me_op ):
|
||||
printf("_try_me_op (not final)\n");
|
||||
code+=5;
|
||||
break;
|
||||
case(_retry_me_op ):
|
||||
printf("_retry_me_op (not final)\n");
|
||||
code+=5;
|
||||
break;
|
||||
case(_trust_me_op ):
|
||||
printf("_trust_me_op (not final)\n");
|
||||
code+=5;
|
||||
break;
|
||||
case(_do_nothing_op ):
|
||||
printf("do_nothing_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_direct_safe_call_op ):
|
||||
printf("_direct_safe_call_op %ld \n",(long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_direct_safe_call_unary_op ):
|
||||
printf("_direct_safe_call_unary_op %ld \n",(long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
case(_direct_safe_call_binary_op ):
|
||||
printf("_direct_safe_call_binary_op %ld \n",(long) carg1);
|
||||
code+=2;
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case(_skip_while_var ):
|
||||
printf("_skip_while_var \n");
|
||||
code++;
|
||||
break;
|
||||
case(_wait_while_var ):
|
||||
printf("_wait_while_var \n");
|
||||
code++;
|
||||
break;
|
||||
case(_force_wait ):
|
||||
printf("_force_wait \n");
|
||||
code++;
|
||||
break;
|
||||
case(_write_call ):
|
||||
printf("_write_call \n");
|
||||
code++;
|
||||
break;
|
||||
case(_is_call ):
|
||||
printf("_is_call \n");
|
||||
code++;
|
||||
break;
|
||||
case(_equal_call ):
|
||||
printf("_equal_call \n");
|
||||
code++;
|
||||
break;
|
||||
case(_cut_op ):
|
||||
printf("_cut_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_commit_op ):
|
||||
printf("_commit_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_fail_op ):
|
||||
printf("_fail_op \n");
|
||||
code++;
|
||||
break;
|
||||
|
||||
case(_save_b_X_op ):
|
||||
printf("_save_b_X_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_save_b_Y_op ):
|
||||
printf("_save_b_Y_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_save_appl_X_op ):
|
||||
printf("_save_appl_X_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_save_appl_Y_op ):
|
||||
printf("_save_appl_Y_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_save_pair_X_op ):
|
||||
printf("_save_pair_X_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_save_pair_Y_op ):
|
||||
printf("_save_pair_Y_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_either_op ):
|
||||
printf("_either_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_orelse_op ):
|
||||
printf("_orelse_op \n");
|
||||
code++;
|
||||
break;
|
||||
case(_orlast_op ):
|
||||
printf("_orlast_op \n");
|
||||
code++;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (n!=*code) printf("inst(%d)\n",n);
|
||||
else printf("Label Next Call %d\n",n);
|
||||
code++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* BEAM */
|
|
@ -0,0 +1,478 @@
|
|||
/*************************************************************************
|
||||
* *
|
||||
* BEAM -> Basic Extended Andorra Model *
|
||||
* BEAM extends the YAP Prolog system to support the EAM *
|
||||
* *
|
||||
* Copyright: Ricardo Lopes and NCC - University of Porto, Portugal *
|
||||
* *
|
||||
**************************************************************************
|
||||
* comments: split related functions *
|
||||
*************************************************************************/
|
||||
|
||||
void do_forking_andbox(struct AND_BOX *a);
|
||||
Cell copy_structures(Cell c);
|
||||
void replicate_local_variables(struct AND_BOX *a);
|
||||
struct OR_BOX *copy_orbox(struct OR_BOX *o,struct AND_BOX *parent,struct status_and *nr_call);
|
||||
struct AND_BOX *copy_andbox(struct AND_BOX *a,struct OR_BOX *parent);
|
||||
|
||||
|
||||
void do_forking_andbox(struct AND_BOX *a)
|
||||
{
|
||||
struct OR_BOX *op,*opp, *new_orbox;
|
||||
struct AND_BOX *ap, *new_andbox;
|
||||
int nr_all_alternatives, nr_all_calls;
|
||||
struct status_and *nr_call,*new_call;
|
||||
struct status_or *nr_alternative, *alternatives, *new_alternatives;
|
||||
|
||||
beam_nr_call_forking++;
|
||||
op=a->parent; /* or box parent */
|
||||
ap=op->parent; /* and box parent */
|
||||
opp=ap->parent; /* or box parent parent */
|
||||
if (opp==NULL) {
|
||||
abort_eam("Forking with orbox parent parent NULL, maybe I'm on top ?????");
|
||||
}
|
||||
|
||||
alternatives=opp->alternatives;
|
||||
nr_all_alternatives=opp->nr_all_alternatives;
|
||||
nr_alternative=ap->nr_alternative;
|
||||
nr_all_calls=ap->nr_all_calls;
|
||||
nr_call=op->nr_call;
|
||||
|
||||
new_andbox=(struct AND_BOX *) request_memory(ANDBOX_SIZE);
|
||||
new_orbox=(struct OR_BOX *) request_memory(ORBOX_SIZE);
|
||||
new_andbox->parent=opp;
|
||||
// new_andbox->nr_alternative=nr_alternative; /* seted after creating a new status_or */
|
||||
new_andbox->nr_all_calls=nr_all_calls;
|
||||
new_andbox->level=ap->level;
|
||||
new_andbox->perms=ap->perms;
|
||||
new_andbox->suspended=NULL;
|
||||
if (ap->suspended) new_andbox->suspended=addto_suspensions_list(new_andbox,ap->suspended->reason);
|
||||
new_andbox->side_effects=ap->side_effects;
|
||||
|
||||
if (ap->externals) {
|
||||
struct EXTERNAL_VAR *old_externals, *list=NULL;
|
||||
old_externals=ap->externals;
|
||||
while (old_externals) {
|
||||
struct EXTERNAL_VAR *e;
|
||||
struct SUSPENSIONS_VAR *s;
|
||||
|
||||
e=(struct EXTERNAL_VAR *) request_memory(EXTERNAL_VAR_SIZE);
|
||||
e->value=old_externals->value;
|
||||
e->var=(struct PERM_VAR *) old_externals->var;
|
||||
e->next=list;
|
||||
list=e;
|
||||
|
||||
if (isvar(e->var)) {
|
||||
s=(struct SUSPENSIONS_VAR *) request_memory(SUSPENSIONS_VAR_SIZE); /* Add and_box to suspension list of var*/
|
||||
s->and_box=new_andbox;
|
||||
s->next=e->var->suspensions;
|
||||
e->var->suspensions=s;
|
||||
}
|
||||
|
||||
old_externals=old_externals->next;
|
||||
}
|
||||
new_andbox->externals=list;
|
||||
} else new_andbox->externals=NULL;
|
||||
|
||||
new_call=(struct status_and *) request_memory(STATUS_AND_SIZE);
|
||||
new_call->call=new_orbox;
|
||||
new_call->locals=nr_call->locals;
|
||||
new_call->code=nr_call->code;
|
||||
new_call->state=WAKE;
|
||||
nr_call->state=WAKE; /* NEW PARA TORNAR A CALL NUM WAKE STATE */
|
||||
|
||||
new_orbox->parent=new_andbox;
|
||||
new_orbox->nr_call=new_call;
|
||||
new_orbox->nr_all_alternatives=1;
|
||||
new_alternatives=a->nr_alternative;
|
||||
new_orbox->alternatives=new_alternatives;
|
||||
|
||||
/* remove andbox from op */
|
||||
op->nr_all_alternatives-=1;
|
||||
if (new_alternatives->previous==NULL) op->alternatives=new_alternatives->next;
|
||||
else new_alternatives->previous->next=new_alternatives->next;
|
||||
if (new_alternatives->next!=NULL) new_alternatives->next->previous=new_alternatives->previous;
|
||||
new_alternatives->next=NULL;
|
||||
new_alternatives->previous=NULL;
|
||||
|
||||
a->parent=new_orbox;
|
||||
|
||||
/* increase the nr_alternatives by 1 in opp or_box parent parent and conect new_andbox*/
|
||||
new_alternatives=(struct status_or *) request_memory(STATUS_OR_SIZE);
|
||||
new_andbox->nr_alternative=new_alternatives;
|
||||
|
||||
new_alternatives->next=nr_alternative;
|
||||
new_alternatives->previous=nr_alternative->previous;
|
||||
if (nr_alternative->previous==NULL) opp->alternatives=new_alternatives;
|
||||
else nr_alternative->previous->next=new_alternatives;
|
||||
nr_alternative->previous=new_alternatives;
|
||||
|
||||
new_alternatives->args=nr_alternative->args;
|
||||
new_alternatives->code=nr_alternative->code;
|
||||
new_alternatives->state=nr_alternative->state;
|
||||
new_alternatives->alternative=new_andbox;
|
||||
|
||||
opp->nr_all_alternatives=nr_all_alternatives+1;
|
||||
|
||||
/* copy and_box ap to new_and-box */
|
||||
{ struct status_and *first=NULL, *last=NULL,*calls,*calls_new;
|
||||
calls=ap->calls;
|
||||
while(calls!=NULL) {
|
||||
if (calls==nr_call) {
|
||||
calls_new=new_call;
|
||||
} else {
|
||||
calls_new=(struct status_and *) request_memory(STATUS_AND_SIZE);
|
||||
calls_new->code=calls->code;
|
||||
calls_new->locals=calls->locals;
|
||||
calls_new->state=calls->state;
|
||||
< |