From c454690a6756070fd19a9d5951b4c8544c4439fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Mon, 29 Nov 2010 18:44:39 +0000 Subject: [PATCH] fix save_program to reload foreign files SWI style when restarting. --- C/load_foreign.c | 55 ++++++-------------------------- Makefile.in | 4 ++- pl/boot.yap | 7 ++++ pl/init.yap | 1 + pl/save.yap | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ pl/udi.yap | 6 ++-- pl/utils.yap | 51 +++++++++++++++++++++++------ 7 files changed, 149 insertions(+), 58 deletions(-) create mode 100644 pl/save.yap diff --git a/C/load_foreign.c b/C/load_foreign.c index ead46aa76..63e085b5a 100755 --- a/C/load_foreign.c +++ b/C/load_foreign.c @@ -111,10 +111,10 @@ p_load_foreign(void) static Int p_open_shared_object(void) { - StringList ofiles = NULL; Term t = Deref(ARG1); Term tflags = Deref(ARG2); - void *ptr; + char *s; + void *handle; if (IsVarTerm(t)) { Yap_Error(INSTANTIATION_ERROR,t,"open_shared_object/3"); @@ -129,35 +129,22 @@ p_open_shared_object(void) { Yap_Error(INSTANTIATION_ERROR,tflags,"open_shared_object/3"); return FALSE; } - if (!IsIntTerm(tflags)) { + if (!IsIntegerTerm(tflags)) { Yap_Error(TYPE_ERROR_INTEGER,tflags,"open_shared_object/3"); return FALSE; } - ofiles = (StringList) Yap_AllocCodeSpace(sizeof(StringListItem)); - ofiles->next = NULL; - ofiles->s = RepAtom(AtomOfTerm(t))->StrOfAE; - if ((ptr = Yap_LoadForeignFile(ofiles->s, IntOfTerm(tflags)))==NULL) { - return FALSE; + s = RepAtom(AtomOfTerm(t))->StrOfAE; + if ((handle = Yap_LoadForeignFile(s, IntegerOfTerm(tflags)))==NULL) { + return FALSE; } else { - ForeignObj *f_code = (ForeignObj *)Yap_AllocCodeSpace(sizeof(ForeignObj)); - ofiles->handle = ptr; - - f_code->objs = ofiles; - f_code->libs = NULL; - f_code->f = NULL; - f_code->next = ForeignCodeLoaded; - f_code->module = CurrentModule; - ForeignCodeLoaded = f_code; - - return Yap_unify(MkIntegerTerm((Int)f_code),ARG3); + return Yap_unify(MkIntegerTerm((Int)handle),ARG3); } } static Int p_close_shared_object(void) { Term t = Deref(ARG1); - ForeignObj *f, *f0 = NULL, *fi = ForeignCodeLoaded; void *handle; if (IsVarTerm(t)) { @@ -168,30 +155,15 @@ p_close_shared_object(void) { Yap_Error(TYPE_ERROR_INTEGER,t,"open_shared_object/3"); return FALSE; } - f = (ForeignObj *)IntegerOfTerm(t); + handle = (char *)IntegerOfTerm(t); - while (fi != f && fi) { - f0 = fi; - fi = f->next; - } - if (!fi) - return FALSE; - if (f0) { - f0->next = f->next; - } else { - ForeignCodeLoaded = f->next; - } - handle = f->objs->handle; - Yap_FreeCodeSpace((ADDR)f->objs); - Yap_FreeCodeSpace((ADDR)f); - return Yap_CloseForeignFile(f->f); + return Yap_CloseForeignFile(handle); } static Int p_call_shared_object_function(void) { Term t = Deref(ARG1); Term tfunc = Deref(ARG2); - ForeignObj *f, *f0 = NULL, *fi = ForeignCodeLoaded; void *handle; if (IsVarTerm(t)) { @@ -202,7 +174,7 @@ p_call_shared_object_function(void) { Yap_Error(TYPE_ERROR_INTEGER,t,"open_shared_object/3"); return FALSE; } - f = (ForeignObj *)IntegerOfTerm(t); + handle = (void *)IntegerOfTerm(t); if (IsVarTerm(tfunc)) { Yap_Error(INSTANTIATION_ERROR,t,"open_shared_object/3"); return FALSE; @@ -212,13 +184,6 @@ p_call_shared_object_function(void) { return FALSE; } - while (fi != f && fi) { - f0 = fi; - fi = f->next; - } - if (!fi) - return FALSE; - handle = f->objs->handle; return Yap_CallForeignFile(handle, RepAtom(AtomOfTerm(tfunc))->StrOfAE); } diff --git a/Makefile.in b/Makefile.in index 6f0bb5e64..4df75a563 100755 --- a/Makefile.in +++ b/Makefile.in @@ -260,7 +260,9 @@ PL_SOURCES= \ $(srcdir)/pl/load_foreign.yap \ $(srcdir)/pl/modules.yap $(srcdir)/pl/preds.yap \ $(srcdir)/pl/profile.yap \ - $(srcdir)/pl/protect.yap $(srcdir)/pl/setof.yap \ + $(srcdir)/pl/protect.yap \ + $(srcdir)/pl/save.yap \ + $(srcdir)/pl/setof.yap \ $(srcdir)/pl/signals.yap \ $(srcdir)/pl/sockets.yap $(srcdir)/pl/sort.yap \ $(srcdir)/pl/statistics.yap \ diff --git a/pl/boot.yap b/pl/boot.yap index 4a45b263b..695a2b0fb 100755 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -159,6 +159,13 @@ true :- true. '$enter_top_level' :- '$clean_up_dead_clauses', fail. +% use if we come from a save_program and we have SWI's shlib +'$enter_top_level' :- + recorded('$reload_foreign_libraries',G,R), + erase(R), + shlib:reload_foreign_libraries, + fail. +% use if we come from a save_program and we have a goal to execute '$enter_top_level' :- recorded('$restore_goal',G,R), erase(R), diff --git a/pl/init.yap b/pl/init.yap index 21a272e4b..7123b3a54 100644 --- a/pl/init.yap +++ b/pl/init.yap @@ -72,6 +72,7 @@ otherwise. 'profile.yap', 'callcount.yap', 'load_foreign.yap', + 'save.yap', 'sockets.yap', 'sort.yap', 'setof.yap', diff --git a/pl/save.yap b/pl/save.yap new file mode 100644 index 000000000..800128021 --- /dev/null +++ b/pl/save.yap @@ -0,0 +1,83 @@ + /************************************************************************* + * * + * YAP Prolog * + * * + * Yap Prolog was developed at NCCUP - Universidade do Porto * + * * + * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-2010 * + * * + ************************************************************************** + * * + * File: save.yap * + * Last rev: 11/29/10 * + * mods: * + * comments: Some utility predicates to support save/restore in yap * + * * + *************************************************************************/ + +%%% Saving and restoring a computation + +save(A) :- save(A,_). + +save(A,_) :- var(A), !, + '$do_error'(instantiation_error,save(A)). +save(A,OUT) :- atom(A), !, atom_codes(A,S), '$save'(S,OUT). +save(S,OUT) :- '$save'(S,OUT). + +save_program(A) :- var(A), !, + '$do_error'(instantiation_error,save_program(A)). +save_program(A) :- atom(A), !, + atom_codes(A,S), + '$save_program2'(S, true). +save_program(S) :- '$save_program2'(S, true). + +save_program(A, G) :- var(A), !, + '$do_error'(instantiation_error, save_program(A,G)). +save_program(A, G) :- var(G), !, + '$do_error'(instantiation_error, save_program(A,G)). +save_program(A, G) :- \+ callable(G), !, + '$do_error'(type_error(callable,G), save_program(A,G)). +save_program(A, G) :- + ( atom(A) -> atom_codes(A,S) ; A = S), + '$save_program2'(S, G), + fail. +save_program(_,_). + +'$save_program2'(S,G) :- + ( + G == true + -> + true + ; + recorda('$restore_goal', G ,R) + ), + ( + '$undefined'(reload_foreign_libraries, shlib) + -> + true + ; + recorda('$reload_foreign_libraries', true, R1) + ), + '$save_program'(S), + ( + var(R1) + -> + true + ; + erase(R1) + ), + ( + var(R) + -> + true + ; + erase(R) + ), + fail. +'$save_program2'(_,_). + +restore(A) :- var(A), !, + '$do_error'(instantiation_error,restore(A)). +restore(A) :- atom(A), !, name(A,S), '$restore'(S). +restore(S) :- '$restore'(S). + diff --git a/pl/udi.yap b/pl/udi.yap index 4209eae50..a1e177174 100644 --- a/pl/udi.yap +++ b/pl/udi.yap @@ -4,14 +4,14 @@ * * * Yap Prolog was developed at NCCUP - Universidade do Porto * * * -* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * +* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-2010 * * * ************************************************************************** * * -* File: tabling.yap * +* File: udi.yap * * Last rev: 8/2/88 * * mods: * -* comments: support tabling predicates * +* comments: support user defined indexing * * * *************************************************************************/ diff --git a/pl/utils.yap b/pl/utils.yap index 798450484..5315dc5a1 100644 --- a/pl/utils.yap +++ b/pl/utils.yap @@ -316,23 +316,56 @@ save(S,OUT) :- '$save'(S,OUT). save_program(A) :- var(A), !, '$do_error'(instantiation_error,save_program(A)). -save_program(A) :- atom(A), !, atom_codes(A,S), '$save_program'(S). -save_program(S) :- '$save_program'(S). +save_program(A) :- atom(A), !, + atom_codes(A,S), + '$save_program2'(S, true). +save_program(S) :- '$save_program2'(S, true). save_program(A, G) :- var(A), !, - '$do_error'(instantiation_error,save_program(A,G)). + '$do_error'(instantiation_error, save_program(A,G)). save_program(A, G) :- var(G), !, - '$do_error'(instantiation_error,save_program(A,G)). + '$do_error'(instantiation_error, save_program(A,G)). save_program(A, G) :- \+ callable(G), !, - '$do_error'(type_error(callable,G),save_program(A,G)). + '$do_error'(type_error(callable,G), save_program(A,G)). save_program(A, G) :- - ( atom(A) -> name(A,S) ; A = S), - recorda('$restore_goal',G,R), - '$save_program'(S), - erase(R), + ( atom(A) -> atom_codes(A,S) ; A = S), + '$save_program2'(S, G), fail. save_program(_,_). +'$save_program2'(S,G) :- + ( + G == true + -> + true + ; + recorda('$restore_goal', G ,R) + ), + ( + '$undefined'(reload_foreign_libraries, shlib) + -> + true + ; + recorda('$reload_foreign_libraries', true, R1) + ), + '$save_program'(S), + ( + var(R1) + -> + true + ; + erase(R1) + ), + ( + var(R) + -> + true + ; + erase(R) + ), + fail. +'$save_program2'(_,_). + restore(A) :- var(A), !, '$do_error'(instantiation_error,restore(A)). restore(A) :- atom(A), !, name(A,S), '$restore'(S).