From 83a1269553e35b343625165ec929f7cb9fb77dd5 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Tue, 10 May 2016 08:33:44 +0100 Subject: [PATCH] change bootstrap sequence to support -B and to allow booting from pl files --- .gitignore | 4 +- C/c_interface.c | 165 ++++++++++++++--------------------------- C/load_dl.c | 10 +-- C/load_dll.c | 3 +- C/load_dyld.c | 3 +- C/load_shl.c | 3 +- C/qlyr.c | 5 +- C/save.c | 10 +-- C/stdpreds.c | 2 +- C/yap-args.c | 31 ++++++-- H/YapGFlagInfo.h | 9 +++ H/Yapproto.h | 13 ++-- console/yap.c | 9 +-- include/YapDefs.h | 35 ++++++--- include/YapInterface.h | 4 +- os/chartypes.c | 6 ++ os/iopreds.c | 3 +- os/sysbits.c | 68 +++++++++-------- pl/CMakeLists.txt | 2 +- pl/atoms.yap | 24 +++--- pl/boot.yap | 59 ++++++++++----- 21 files changed, 245 insertions(+), 223 deletions(-) diff --git a/.gitignore b/.gitignore index 607727898..7d46d0b04 100644 --- a/.gitignore +++ b/.gitignore @@ -159,9 +159,9 @@ yPQ YAP.sublime* yap32 Eclipse - +codeblocks yap-6.3.tags - +android yap.prj yap.VITORs-MBP.vsc.pui diff --git a/C/c_interface.c b/C/c_interface.c index be8d276d7..537b10fb4 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -1407,7 +1407,7 @@ X_API Term YAP_ReadBuffer(const char *s, Term *tp) { return 0L; } LOCAL_ErrorMessage = NULL; - continue; + return 0; } else { break; } @@ -1989,6 +1989,7 @@ X_API void YAP_PruneGoal(YAP_dogoalinfo *gi) { break; B = B->cp_b; } + Yap_TrimTrail(); RECOVER_B(); @@ -2008,35 +2009,37 @@ X_API void YAP_ClearExceptions(void) { Yap_ResetException(worker_id); } -X_API int YAP_InitConsult(int mode, const char *filename, int *osnop) { +X_API int YAP_InitConsult(int mode, const char *filename, char *full, + int *osnop) { CACHE_REGS - FILE *f; + FILE *f = NULL; int sno; - char full[FILENAME_MAX] BACKUP_MACHINE_REGS(); + BACKUP_MACHINE_REGS(); if (mode == YAP_BOOT_MODE) { mode = YAP_CONSULT_MODE; } bool consulted = (mode == YAP_CONSULT_MODE); Yap_init_consult(consulted, filename); - const char *fl = Yap_AbsoluteFile(filename, full, true); + const char *fl = + Yap_findFile(filename, NULL, NULL, full, true, YAP_BOOT_PL, true, true); if (!fl) return -1; f = fopen(fl, "r"); if (!f) return -1; - else if (fl != filename && fl != full && fl != LOCAL_FileNameBuf && - fl != LOCAL_FileNameBuf2) - free((void *)fl); + if (!f) { + return -1; + } sno = Yap_OpenStream(f, NULL, TermNil, Input_Stream_f); *osnop = Yap_CheckAlias(AtomLoopStream); if (!Yap_AddAlias(AtomLoopStream, sno)) { Yap_CloseStream(sno); sno = -1; } - GLOBAL_Stream[sno].name = Yap_LookupAtom(filename); + GLOBAL_Stream[sno].name = Yap_LookupAtom(fl); GLOBAL_Stream[sno].user_name = MkAtomTerm(Yap_LookupAtom(filename)); - GLOBAL_Stream[sno].encoding = ENC_ISO_LATIN1; + GLOBAL_Stream[sno].encoding = ENC_ISO_UTF8; RECOVER_MACHINE_REGS(); UNLOCK(GLOBAL_Stream[sno].streamlock); return sno; @@ -2180,19 +2183,16 @@ X_API char *YAP_CompileClause(Term t) { static int yap_lineno = 0; /* do initial boot by consulting the file boot.yap */ -static void do_bootfile(char *bootfilename USES_REGS) { +static void do_bootfile(const char *bootfilename USES_REGS) { Term t; int bootfile, osno; Functor functor_query = Yap_MkFunctor(Yap_LookupAtom("?-"), 1); Functor functor_command1 = Yap_MkFunctor(Yap_LookupAtom(":-"), 1); + char full[YAP_FILENAME_MAX + 1]; /* consult boot.pl */ /* the consult mode does not matter here, really */ - /* - To be honest, YAP_InitConsult does not really do much, - it's here for the future. It also makes what we want to do clearer. - */ - bootfile = YAP_InitConsult(YAP_BOOT_MODE, bootfilename, &osno); + bootfile = YAP_InitConsult(YAP_BOOT_MODE, bootfilename, full, &osno); if (bootfile < 0) { fprintf(stderr, "[ FATAL ERROR: could not open bootfile %s ]\n", bootfilename); @@ -2243,58 +2243,27 @@ static void do_bootfile(char *bootfilename USES_REGS) { #endif } -/* trust YAPSHAREDIR over YAP_PL_SRCDIR, and notice that the code is - * dependent. */ -static bool construct_init_file(char *boot_file, char *BootFile) { -#if HAVE_GETENV - if (getenv("YAPSHAREDIR")) { - strncpy(boot_file, getenv("YAPSHAREDIR"), 256); - strncat(boot_file, "/pl/", 255); - if (Yap_Exists(boot_file)) { - return true; - } - } -#endif -#if __ANDROID__ - strncpy(boot_file, "/assets/share/pl/", 256); - if (Yap_Exists(boot_file)) { - return true; - } -#endif - strncpy(boot_file, YAP_SHAREDIR "/pl/", 256); - strncat(boot_file, BootFile, 255); - if (Yap_Exists(boot_file)) { - return true; - } - - strncpy(boot_file, YAP_PL_SRCDIR "/", 256); - strncat(boot_file, BootFile, 255); - if (Yap_Exists(boot_file)) { - return true; - } - return false; -} - /* this routine is supposed to be called from an external program that wants to control Yap */ #define BOOT_FROM_SAVED_STATE TRUE static char BootFile[] = "boot.yap"; -static char InitFile[] = "init.yap"; Int YAP_Init(YAP_init_args *yap_init) { - int restore_result; - bool do_bootstrap = (yap_init->YapPrologBootFile != NULL); + YAP_file_type_t restore_result = yap_init->initial_file_type; + bool do_bootstrap = (restore_result & YAP_CONSULT_MODE); CELL Trail = 0, Stack = 0, Heap = 0, Atts = 0; char boot_file[YAP_FILENAME_MAX + 1]; static int initialized = FALSE; + Int rc; /* ignore repeated calls to YAP_Init */ if (initialized) - return YAP_BOOT_DONE_BEFOREHAND; + return YAP_BOOT_ERROR; initialized = TRUE; - Yap_InitPageSize(); /* init memory page size, required by later functions */ + Yap_page_size = Yap_InitPageSize(); /* init memory page size, required by + later functions */ #if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA) Yap_init_yapor_global_local_memory(); #endif /* YAPOR_COPY || YAPOR_COW || YAPOR_SBA */ @@ -2303,13 +2272,19 @@ Int YAP_Init(YAP_init_args *yap_init) { functions */ GLOBAL_argv = yap_init->Argv; GLOBAL_argc = yap_init->Argc; -#if BOOT_FROM_SAVED_STATE - if (!yap_init->SavedState) { - yap_init->SavedState = - Yap_locateFile(YAP_STARTUP, boot_file, sizeof(boot_file) - 1); + if (restore_result == YAP_QLY) { + yap_init->SavedState = Yap_findFile(yap_init->SavedState, YAP_STARTUP, NULL, + boot_file, true, YAP_QLY, true, true); + if (yap_init->SavedState == NULL) + restore_result = YAP_BOOT_PL; + } + if (restore_result == YAP_BOOT_PL) { + yap_init->YapPrologBootFile = + Yap_findFile(yap_init->YapPrologBootFile, BootFile, NULL, boot_file, true, + YAP_BOOT_PL, true, true); } -#else +#if 0 if (yap_init->SavedState) { fprintf(stderr, "[ WARNING: YAP will ignore saved state %s ]\n", yap_init->SavedState); @@ -2366,26 +2341,24 @@ Int YAP_Init(YAP_init_args *yap_init) { setBooleanGlobalPrologFlag(HALT_AFTER_CONSULT_FLAG, yap_init->HaltAfterConsult); } - /* tell the scystem who should cope with interrupts */ + /* tell the system who should cope with interrupts */ Yap_ExecutionMode = yap_init->ExecutionMode; if (do_bootstrap) { - restore_result = YAP_BOOT_FROM_PROLOG; + restore_result |= YAP_BOOT_FROM_PROLOG; } else { // try always to boot from the saved state. - if (restore_result != YAP_BOOT_FROM_PROLOG) { + if (restore_result == YAP_QLY) { if (!Yap_SavedInfo(yap_init->SavedState, yap_init->YapLibDir, &Trail, &Stack, &Heap)) { - restore_result = YAP_BOOT_FROM_PROLOG; - yap_init->ErrorNo = LOCAL_Error_TYPE; - yap_init->ErrorCause = LOCAL_ErrorMessage; - return YAP_BOOT_ERROR; + restore_result |= YAP_BOOT_FROM_PROLOG; + } else { + restore_result = + Yap_Restore(yap_init->SavedState, yap_init->YapLibDir); + } + if (restore_result == FAIL_RESTORE) { + restore_result = YAP_BOOT_PL; } } - restore_result = Yap_Restore(yap_init->SavedState, yap_init->YapLibDir); - if (restore_result == FAIL_RESTORE) { - restore_result = YAP_BOOT_FROM_PROLOG; - } } - GLOBAL_FAST_BOOT_FLAG = yap_init->FastBoot; #if defined(YAPOR) || defined(TABLING) Yap_init_root_frames(); @@ -2459,48 +2432,25 @@ Int YAP_Init(YAP_init_args *yap_init) { setVerbosity(TermSilent); } if (restore_result == DO_EVERYTHING || restore_result == DO_ONLY_CODE) { + setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG, + MkAtomTerm(Yap_LookupAtom(yap_init->SavedState))); LOCAL_PrologMode &= ~BootMode; if (restore_result == DO_ONLY_CODE) { /* first, initialize the saved state */ - Term t_goal = MkAtomTerm(AtomInitProlog); - YAP_RunGoalOnce(t_goal); - return YAP_BOOT_FROM_SAVED_CODE; + rc = YAP_BOOT_FROM_SAVED_CODE; } else { CurrentModule = LOCAL_SourceModule = USER_MODULE; - return YAP_BOOT_FROM_SAVED_STACKS; + rc = YAP_BOOT_FROM_SAVED_STACKS; } + } else { + if (!yap_init->YapPrologBootFile) + yap_init->YapPrologBootFile = BootFile; + setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG, + MkAtomTerm(Yap_LookupAtom(yap_init->YapPrologBootFile))); + do_bootfile(yap_init->YapPrologBootFile); + rc = YAP_BOOT_FROM_PROLOG; } - /* read the bootfile */ - if (!do_bootstrap) { - construct_init_file(boot_file, BootFile); - yap_init->YapPrologBootFile = boot_file; - } - do_bootfile(yap_init->YapPrologBootFile ? yap_init->YapPrologBootFile - : BootFile PASS_REGS); - /* initialize the top-level */ - if (!do_bootstrap) { - char init_file[256]; - Atom atfile; - Functor fgoal; - YAP_Term goal, as[2]; - if (!construct_init_file(init_file, InitFile)) - Yap_exit(1); - /* consult init file */ - atfile = Yap_LookupAtom(init_file); - as[0] = MkAtomTerm(atfile); - fgoal = Yap_MkFunctor(Yap_FullLookupAtom("$silent_bootstrap"), 1); - goal = Yap_MkApplTerm(fgoal, 1, as); - /* launch consult */ - YAP_RunGoalOnce(goal); - /* set default module to user */ - as[0] = MkAtomTerm(AtomUser); - fgoal = Yap_MkFunctor(Yap_LookupAtom("module"), 1); - goal = Yap_MkApplTerm(fgoal, 1, as); - YAP_RunGoalOnce(goal); - } - Yap_PutValue(Yap_FullLookupAtom("$live"), - MkAtomTerm(Yap_FullLookupAtom("$true"))); - return YAP_BOOT_FROM_PROLOG; + return rc; } Int Yap_InitDefaults(YAP_init_args *init_args, char saved_state[]) { @@ -2515,13 +2465,8 @@ Int Yap_InitDefaults(YAP_init_args *init_args, char saved_state[]) { init_args->MaxGlobalSize = 0; init_args->MaxTrailSize = 0; init_args->YapLibDir = NULL; -#if __ANDROID__ init_args->YapPrologBootFile = "boot.yap"; init_args->YapPrologInitGoal = "bootstrap"; -#else - init_args->YapPrologBootFile = NULL; - init_args->YapPrologInitGoal = NULL; -#endif init_args->YapPrologRCFile = NULL; init_args->YapPrologGoal = NULL; init_args->YapPrologTopLevelGoal = NULL; diff --git a/C/load_dl.c b/C/load_dl.c index b283a61ee..8208af415 100755 --- a/C/load_dl.c +++ b/C/load_dl.c @@ -131,7 +131,7 @@ void *Yap_LoadForeignFile(char *file, int flags) { else dlflag |= RTLD_LOCAL; #endif - if (!Yap_locateFile(file, LOCAL_FileNameBuf, true)) { + if (!Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true)) { /* use LD_LIBRARY_PATH */ strncpy(LOCAL_FileNameBuf, file, YAP_FILENAME_MAX - 1); strncat(LOCAL_FileNameBuf, ".", YAP_FILENAME_MAX - 1); @@ -177,8 +177,8 @@ static Int LoadForeign(StringList ofiles, StringList libs, char *proc_name, CACHE_REGS while (libs) { - if (!Yap_locateFile((char *)AtomName(libs->name), LOCAL_FileNameBuf, - true)) { + const char *file = AtomName(libs->name); + if (!Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true)) { /* use LD_LIBRARY_PATH */ strncpy(LOCAL_FileNameBuf, (char *)AtomName(libs->name), YAP_FILENAME_MAX); @@ -204,8 +204,8 @@ static Int LoadForeign(StringList ofiles, StringList libs, char *proc_name, other routines */ /* dlopen wants to follow the LD_CONFIG_PATH */ - if (!Yap_locateFile((char *)AtomName(ofiles->name), LOCAL_FileNameBuf, - TRUE)) { + const char *file = AtomName(ofiles->name); + if (!Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true)) { strcpy(LOCAL_ErrorSay, "%% Trying to open unexisting file in LoadForeign"); return LOAD_FAILLED; diff --git a/C/load_dll.c b/C/load_dll.c index 6ec4c2ddb..98facdb65 100755 --- a/C/load_dll.c +++ b/C/load_dll.c @@ -82,7 +82,8 @@ LoadForeign(StringList ofiles, StringList libs, while (ofiles) { HINSTANCE handle; - if (Yap_locateFile(AtomName(ofiles->name), LOCAL_FileNameBuf, TRUE) && + const char *file = AtomName(ofiles->name); + if (!Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true) && (handle=LoadLibrary(LOCAL_FileNameBuf)) != 0) { LOCAL_ErrorSay[0]=~'\0'; diff --git a/C/load_dyld.c b/C/load_dyld.c index 565612c85..2c6ae3d66 100755 --- a/C/load_dyld.c +++ b/C/load_dyld.c @@ -158,7 +158,8 @@ LoadForeign(StringList ofiles, StringList libs, void *handle; /* mydlopen wants to follow the LD_CONFIG_PATH */ - if (!Yap_locateFile(AtomName(ofiles->name), LOCAL_FileNameBuf, TRUE)) { + iconst char *file = AtomName(ofiles->name); + if (!Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true) ) { strcpy(LOCAL_ErrorSay, "%% Trying to open unexisting file in LoadForeign"); return LOAD_FAILLED; } diff --git a/C/load_shl.c b/C/load_shl.c index 19e17cc3e..0fdd3b121 100644 --- a/C/load_shl.c +++ b/C/load_shl.c @@ -61,7 +61,8 @@ LoadForeign( StringList ofiles, StringList libs, int valid_fname; /* shl_load wants to follow the LD_CONFIG_PATH */ - valid_fname = Yap_locateFile( AtomName(ofiles->name), LOCAL_FileNameBuf, TRUE ); + const char *file = AtomName(ofiles->name); + valid_fname = Yap_findFile(file, NULL, NULL, LOCAL_FileNameBuf, true, YAP_OBJ, true, true); if( !valid_fname ) { strcpy( LOCAL_ErrorSay, "%% Trying to open non-existing file in LoadForeign" ); diff --git a/C/qlyr.c b/C/qlyr.c index a98cf3e96..acd436d7e 100755 --- a/C/qlyr.c +++ b/C/qlyr.c @@ -1062,7 +1062,7 @@ static Int qload_program(USES_REGS1) { return true; } -int Yap_Restore(const char *s, char *lib_dir) { +int Yap_Restore(const char *s, const char *lib_dir) { CACHE_REGS FILE *stream = Yap_OpenRestore(s, lib_dir); @@ -1072,6 +1072,7 @@ int Yap_Restore(const char *s, char *lib_dir) { if (do_header(stream) == NIL) return FALSE; read_module(stream); + setBooleanGlobalPrologFlag(SAVED_PROGRAM_FLAG, true); fclose(stream); GLOBAL_RestoreFile = NULL; LOCAL_SourceModule = CurrentModule = USER_MODULE; @@ -1085,7 +1086,7 @@ void Yap_InitQLYR(void) { SyncPredFlag | HiddenPredFlag); Yap_InitCPred("$qload_program", 1, qload_program, SyncPredFlag | HiddenPredFlag); - Yap_InitCPred("$q_header", 2, get_header, SyncPredFlag | HiddenPredFlag); + Yap_InitCPred("$q_header", 2, get_header, SyncPredFlag | HiddenPredFlag); if (FALSE) { restore_codes(); } diff --git a/C/save.c b/C/save.c index e0b2a0fae..6559da9bc 100755 --- a/C/save.c +++ b/C/save.c @@ -125,7 +125,7 @@ static void restore_heap(void); static void ShowAtoms(void); static void ShowEntries(PropEntry *); #endif -static int OpenRestore(const char *, char *, CELL *, CELL *, CELL *, CELL *, FILE **); +static int OpenRestore(const char *, const char *, CELL *, CELL *, CELL *, CELL *, FILE **); static void CloseRestore(void); #ifndef _WIN32 static int check_opcodes(OPCODE []); @@ -1385,7 +1385,7 @@ commit_to_saved_state(char *s, CELL *Astate, CELL *ATrail, CELL *AStack, CELL *A LOCAL_PrologMode = BootMode; if (Yap_HeapBase) { if (falseGlobalPrologFlag( HALT_AFTER_CONSULT_FLAG ) && !silentMode( )) { - Yap_locateFile(s,LOCAL_FileNameBuf2, YAP_FILENAME_MAX); + Yap_findFile(s, NULL, NULL, LOCAL_FileNameBuf2, true, YAP_QLY, true, true); fprintf(stderr, "%% Restoring file %s\n", LOCAL_FileNameBuf2); } Yap_CloseStreams(TRUE); @@ -1420,7 +1420,7 @@ static int try_open(char *inpf, CELL *Astate, CELL *ATrail, CELL *AStack, CELL * } static int -OpenRestore(const char *inpf, char *YapLibDir, CELL *Astate, CELL *ATrail, CELL *AStack, CELL *AHeap, FILE **streamp) +OpenRestore(const char *inpf, const char *YapLibDir, CELL *Astate, CELL *ATrail, CELL *AStack, CELL *AHeap, FILE **streamp) { CACHE_REGS @@ -1445,7 +1445,7 @@ OpenRestore(const char *inpf, char *YapLibDir, CELL *Astate, CELL *ATrail, CELL } FILE * -Yap_OpenRestore(const char *inpf, char *YapLibDir) +Yap_OpenRestore(const char *inpf, const char *YapLibDir) { FILE *stream = NULL; @@ -1535,7 +1535,7 @@ RestoreHeap(OPCODE old_ops[] USES_REGS) * state */ int -Yap_SavedInfo(const char *FileName, char *YapLibDir, CELL *ATrail, CELL *AStack, CELL *AHeap) +Yap_SavedInfo(const char *FileName, const char *YapLibDir, CELL *ATrail, CELL *AStack, CELL *AHeap) { return DO_ONLY_CODE; diff --git a/C/stdpreds.c b/C/stdpreds.c index b7ab85295..b8c2fb56b 100755 --- a/C/stdpreds.c +++ b/C/stdpreds.c @@ -1338,7 +1338,7 @@ static Int p_statistics_lu_db_size(USES_REGS1) { static Int p_executable(USES_REGS1) { if (GLOBAL_argv && GLOBAL_argv[0]) - Yap_locateFile(GLOBAL_argv[0], LOCAL_FileNameBuf, FALSE); + Yap_findFile(GLOBAL_argv[0], NULL, NULL, LOCAL_FileNameBuf, true, YAP_EXE, true, true); else strncpy(LOCAL_FileNameBuf, Yap_FindExecutable(), YAP_FILENAME_MAX - 1); diff --git a/C/yap-args.c b/C/yap-args.c index d95110f7a..8d0423acd 100755 --- a/C/yap-args.c +++ b/C/yap-args.c @@ -155,12 +155,14 @@ static int dump_runtime_variables(void) { return 1; } -X_API int YAP_parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap) { +X_API YAP_file_type_t YAP_parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap) { char *p; - int BootMode = YAP_BOOT_FROM_SAVED_CODE; + int BootMode = YAP_QLY; unsigned long int *ssize; iap->SavedState = NULL; + iap->initial_file_type = YAP_QLY; + iap->HeapSize = 0; iap->StackSize = 0; iap->TrailSize = 0; @@ -178,7 +180,7 @@ X_API int YAP_parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap) { iap->YapPrologTopLevelGoal = NULL; iap->YapPrologAddPath = NULL; iap->HaltAfterConsult = FALSE; - iap->FastBoot = FALSE; + iap->FastBoot = false; iap->MaxTableSpaceSize = 0; iap->NumberWorkers = DEFAULT_NUMBERWORKERS; iap->SchedulerLoop = DEFAULT_SCHEDULERLOOP; @@ -197,9 +199,26 @@ X_API int YAP_parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap) { if (*p == '-') switch (*++p) { case 'b': - BootMode = YAP_BOOT_FROM_PROLOG; - iap->YapPrologBootFile = *++argv; - argc--; + iap->initial_file_type = BootMode = YAP_PL; + if (p[1]) + iap->YapPrologBootFile = p+1; + else if (argv[1] && *argv[1] != '-') { + iap->YapPrologBootFile = *++argv; + argc--; + } else { + iap->YapPrologBootFile = "boot.yap"; + } + break; + case 'B': + iap->initial_file_type = BootMode = YAP_BOOT_PL; + if (p[1]) + iap->YapPrologBootFile = p+1; + else if (argv[1] && *argv[1] != '-') { + iap->YapPrologBootFile = *++argv; + argc--; + } else { + iap->YapPrologBootFile = "boot.yap"; + } break; case '?': print_usage(); diff --git a/H/YapGFlagInfo.h b/H/YapGFlagInfo.h index c27820781..ad07bc451 100644 --- a/H/YapGFlagInfo.h +++ b/H/YapGFlagInfo.h @@ -338,6 +338,15 @@ goal succeeded while leaving choicepoints. */ enable the use of the readline library for console interactions, true by default if readline was found. */ YAP_FLAG(REPORT_ERROR_FLAG, "report_error", true, booleanFlag, "true", NULL), + YAP_FLAG(RESOURCE_DATABASE_FLAG, "resource_database", false, isatom, "boot.yap", NULL), +/**<`resource_database` + Name of the resource file (saved-state or Prolog file) used to construct the YAP +run-time environment. +*/ + YAP_FLAG(SAVED_PROGRAM_FLAG, "saved_program", false, booleanFlag, "false", NULL), +/**<`saved_program` + if `true` YAP booted from a `yss` file, usually `startup.yss'. If `false`, YAP booted from a Prolog file, by default `boot.yap`. +*/ YAP_FLAG(SHARED_OBJECT_EXTENSION_FLAG, "shared_object_extension", false, isatom, SO_EXT, NULL), /**< `shared_object_extension ` diff --git a/H/Yapproto.h b/H/Yapproto.h index aa551d182..3b19651d0 100755 --- a/H/Yapproto.h +++ b/H/Yapproto.h @@ -355,16 +355,16 @@ void Yap_InitReadUtil(void); /* qly.c */ void Yap_InitQLY(void); -int Yap_Restore(const char *, char *); +int Yap_Restore(const char *, const char *); void Yap_InitQLYR(void); /* range.c */ void Yap_InitRange(void); /* save.c */ -int Yap_SavedInfo(const char *, char *, CELL *, CELL *, CELL *); +int Yap_SavedInfo(const char *, const char *, CELL *, CELL *, CELL *); int Yap_SavedStateRestore(char *, char *); -FILE *Yap_OpenRestore(const char *, char *); +FILE *Yap_OpenRestore(const char *, const char *); void Yap_InitSavePreds(void); /* scanner.c */ @@ -396,7 +396,7 @@ void Yap_show_statistics(void); int Yap_IsOpMaxPrio(Atom); /* sysbits.c */ -void Yap_InitPageSize(void); +size_t Yap_InitPageSize(void); bool Yap_set_fpu_exceptions(Term); UInt Yap_cputime(void); uint64_t Yap_walltime(void); @@ -420,21 +420,18 @@ void Yap_InitSysbits(int wid); void Yap_InitSysPreds(void); void Yap_InitcTime(int); void Yap_InitTime(int); -const char *Yap_locateFile(const char *, char *, bool); double Yap_random(void); #ifdef _WIN32 char *Yap_RegistryGetString(char *); void Yap_WinError(char *); #endif -typedef enum { YAP_STD, YAP_SAVED_STATE, YAP_OBJ, YAP_PL, YAP_QLY } file_type_t; - const char *Yap_AbsoluteFile(const char *spec, char *obuf, bool ok); const char *Yap_AbsoluteFileInBuffer(const char *spec, char *outp, size_t sz, bool ok); const char *Yap_findFile(const char *isource, const char *idef, const char *root, char *result, bool access, - file_type_t ftype, bool expand_root, bool in_lib); + YAP_file_type_t ftype, bool expand_root, bool in_lib); /* threads.c */ void Yap_InitThreadPreds(void); void Yap_InitFirstWorkerThreadHandle(void); diff --git a/console/yap.c b/console/yap.c index 7ef790ed8..0b1e4cb39 100755 --- a/console/yap.c +++ b/console/yap.c @@ -73,10 +73,11 @@ static void do_top_goal(YAP_Term Goal) { YAP_RunGoalOnce(Goal); } static int init_standard_system(int argc, char *argv[], YAP_init_args *iap) { - int BootMode = YAP_parse_yap_arguments(argc, argv, iap); + YAP_file_type_t BootMode = YAP_parse_yap_arguments(argc, argv, iap); /* init memory */ - BootMode = YAP_Init(iap); + iap->initial_file_type = + BootMode = YAP_Init(iap); if (iap->ErrorNo) { /* boot failed */ YAP_Error(iap->ErrorNo, 0L, iap->ErrorCause); @@ -91,10 +92,8 @@ static void exec_top_level(int BootMode, YAP_init_args *iap) { if (BootMode == YAP_BOOT_FROM_SAVED_STACKS) { /* continue executing from the frozen stacks */ YAP_ContinueGoal(); - livegoal = YAP_FullLookupAtom("$live"); - } else { - livegoal = YAP_FullLookupAtom("$bootstrap"); } + livegoal = YAP_FullLookupAtom("$live"); /* the top-level is now ready */ /* read it before case someone, that is, Ashwin, hides diff --git a/include/YapDefs.h b/include/YapDefs.h index ec3a80c17..b36683d70 100755 --- a/include/YapDefs.h +++ b/include/YapDefs.h @@ -166,6 +166,18 @@ typedef struct YAP_thread_attr_struct { #include #endif +typedef enum { YAP_BIN = 0x0001, + YAP_TEXT = 0x0002, + YAP_SAVED_STATE = 0x0004, + YAP_OBJ = 0x0008, + YAP_PL = 0x0010, + YAP_BOOT_PL = 0x0030, + YAP_QLY = 0x0040, + YAP_EXE = 0x0080 +} YAP_file_type_t; + +#define YAP_ANY_FILE (0x00ff) + typedef enum { YAP_TAG_ATT = 0x1, YAP_TAG_UNBOUND = 0x2, @@ -179,13 +191,13 @@ typedef enum { YAP_TAG_FLOAT = 0x200, YAP_TAG_OPAQUE = 0x400, YAP_TAG_APPL = 0x800, - YAP_TAG_DBREF = 0x1000 + YAP_TAG_DBREF = 0x1000, + YAP_TAG_STRING = 0x2000, + YAP_TAG_ARRAY = 0x4000 } YAP_tag_t; #define YAP_BOOT_FROM_SAVED_CODE 1 #define YAP_BOOT_FROM_SAVED_STACKS 2 -#define YAP_FULL_BOOT_FROM_PROLOG 4 -#define YAP_BOOT_DONE_BEFOREHAND 8 #define YAP_BOOT_ERROR -1 #define YAP_WRITE_QUOTED 1 @@ -204,6 +216,8 @@ typedef enum { #define YAP_BOOT_MODE 2 typedef struct yap_boot_params { + /* boot type as suggested by the user */ + YAP_file_type_t initial_file_type; /* if NON-NULL, path where we can find the saved state */ const char *SavedState; /* if NON-0, minimal size for Heap or Code Area */ @@ -219,25 +233,24 @@ typedef struct yap_boot_params { unsigned long int TrailSize; /* if NON-0, maximal size for Trail */ unsigned long int MaxTrailSize; - /* if NON-0, minimal size for AttributeVarStack */ unsigned long int AttsSize; /* if NON-0, maximal size for AttributeVarStack */ unsigned long int MaxAttsSize; /* if NON-NULL, value for YAPLIBDIR */ - char *YapLibDir; + const char *YapLibDir; /* if NON-NULL, name for a Prolog file to use when booting */ - char *YapPrologBootFile; + const char *YapPrologBootFile; /* if NON-NULL, name for a Prolog file to use when initializing */ - char *YapPrologInitGoal; + const char *YapPrologInitGoal; /* if NON-NULL, name for a Prolog file to consult before entering top-level */ - char *YapPrologRCFile; + const char *YapPrologRCFile; /* if NON-NULL, a goal to run before top-level */ - char *YapPrologGoal; + const char *YapPrologGoal; /* if NON-NULL, a goal to run as top-level */ - char *YapPrologTopLevelGoal; + const char *YapPrologTopLevelGoal; /* if NON-NULL, a path to extend file-search-path */ - char *YapPrologAddPath; + const char *YapPrologAddPath; /* if previous NON-NULL and TRUE, halt after consulting that file */ bool HaltAfterConsult; /* ignore .yaprc, .prolog.ini, etc. files. */ diff --git a/include/YapInterface.h b/include/YapInterface.h index 18d6a6c70..e24d9986e 100755 --- a/include/YapInterface.h +++ b/include/YapInterface.h @@ -1947,7 +1947,7 @@ extern X_API void YAP_Write(YAP_Term t, FILE *s, int); extern X_API FILE *YAP_TermToStream(YAP_Term t); -extern X_API int YAP_InitConsult(int mode, const char *filename, +extern X_API int YAP_InitConsult(int mode, const char *filename, char *buf, int *previous_sno); extern X_API void YAP_EndConsult(int s, int *previous_sno); @@ -2212,7 +2212,7 @@ extern X_API int YAP_RequiresExtraStack(size_t); * reserved memory for alloc IF DEBUG * -P only in development versions */ -extern X_API int YAP_parse_yap_arguments(int argc, char *argv[], +extern X_API YAP_file_type_t YAP_parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap); extern X_API YAP_Int YAP_AtomToInt(YAP_Atom At); diff --git a/os/chartypes.c b/os/chartypes.c index 64b0c0ce4..e2dca1c2f 100644 --- a/os/chartypes.c +++ b/os/chartypes.c @@ -92,8 +92,14 @@ Term Yap_StringToNumberTerm(char *s, encoding_t *encp) { GLOBAL_Stream[sno].encoding = *encp; else GLOBAL_Stream[sno].encoding = LOCAL_encoding; + #ifdef __ANDROID__ + while (*s && isblank(*s) && Yap_wide_chtype(*s) == BS) + s++ + ; + #else while (*s && iswblank(*s++)) ; + #endif t = Yap_scan_num(GLOBAL_Stream + sno); if (LOCAL_Error_TYPE == SYNTAX_ERROR) LOCAL_Error_TYPE = YAP_NO_ERROR; diff --git a/os/iopreds.c b/os/iopreds.c index 573a76db9..7867a94e9 100644 --- a/os/iopreds.c +++ b/os/iopreds.c @@ -1431,8 +1431,7 @@ static Int p_file_expansion(USES_REGS1) { /* '$file_expansion'(+File,-Name) */ PlIOError(INSTANTIATION_ERROR, file_name, "absolute_file_name/3"); return (FALSE); } - if (!Yap_locateFile(RepAtom(AtomOfTerm(file_name))->StrOfAE, - LOCAL_FileNameBuf, false)) + if (!Yap_findFile(RepAtom(AtomOfTerm(file_name))->StrOfAE, NULL, NULL, LOCAL_FileNameBuf, true, YAP_ANY_FILE, true, false)) return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name, "absolute_file_name/3")); return (Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf)))); diff --git a/os/sysbits.c b/os/sysbits.c index c2f283721..b77f9f310 100644 --- a/os/sysbits.c +++ b/os/sysbits.c @@ -759,6 +759,7 @@ static Int real_path(USES_REGS1) { } #if _WIN32 char cmd2[YAP_FILENAME_MAX + 1]; + char *rc; if ((rc = unix2win(cmd, cmd2, YAP_FILENAME_MAX)) == NULL) { return false; @@ -1150,20 +1151,20 @@ static Int p_dir_sp(USES_REGS1) { return Yap_unify_constant(ARG1, t) || Yap_unify_constant(ARG1, t2); } -void Yap_InitPageSize(void) { +size_t Yap_InitPageSize(void) { #ifdef _WIN32 SYSTEM_INFO si; GetSystemInfo(&si); - Yap_page_size = si.dwPageSize; + return si.dwPageSize; #elif HAVE_UNISTD_H #if defined(__FreeBSD__) || defined(__DragonFly__) - Yap_page_size = getpagesize(); + return getpagesize(); #elif defined(_AIX) - Yap_page_size = sysconf(_SC_PAGE_SIZE); + return sysconf(_SC_PAGE_SIZE); #elif !defined(_SC_PAGESIZE) - Yap_page_size = getpagesize(); + return getpagesize(); #else - Yap_page_size = sysconf(_SC_PAGESIZE); + return sysconf(_SC_PAGESIZE); #endif #else bla bla @@ -1247,7 +1248,7 @@ static Int working_directory(USES_REGS1) { */ const char *Yap_findFile(const char *isource, const char *idef, const char *iroot, char *result, bool access, - file_type_t ftype, bool expand_root, bool in_lib) { + YAP_file_type_t ftype, bool expand_root, bool in_lib) { char save_buffer[YAP_FILENAME_MAX + 1]; const char *root, *source = isource; int rc = FAIL_RESTORE; @@ -1261,40 +1262,47 @@ const char *Yap_findFile(const char *isource, const char *idef, switch (try ++) { case 0: // path or file name is given; root = iroot; - if (iroot || isource) { + if (!root && ftype == YAP_BOOT_PL) { + root = YAP_PL_SRCDIR; + } + if (idef || isource) { source = (isource ? isource : idef); - } else { - done = true; } break; case 1: // library directory is given in command line if (in_lib && ftype == YAP_SAVED_STATE) { root = iroot; source = (isource ? isource : idef); - } else + } else { done = true; + } break; case 2: // use environment variable YAPLIBDIR #if HAVE_GETENV if (in_lib) { if (ftype == YAP_SAVED_STATE || ftype == YAP_OBJ) { - root = getenv("YAPLIBDIR"); - } else { + root = getenv("YAPLIBDIR"); + } else if (ftype == YAP_BOOT_PL) { root = getenv("YAPSHAREDIR"); + if (root == NULL) { + continue; + } else { + strncpy(save_buffer, root, YAP_FILENAME_MAX); + strncat(save_buffer, "/pl", YAP_FILENAME_MAX); + } } source = (isource ? isource : idef); } else - done = true; - break; -#else - done = true; #endif + done = true; break; case 3: // use compilation variable YAPLIBDIR if (in_lib) { source = (isource ? isource : idef); - if (ftype == YAP_PL || ftype == YAP_QLY) { + if (ftype == YAP_PL) { root = YAP_SHAREDIR; + } else if (ftype == YAP_BOOT_PL) { + root = YAP_SHAREDIR "/pl"; } else { root = YAP_LIBDIR; } @@ -1314,7 +1322,6 @@ const char *Yap_findFile(const char *isource, const char *idef, break; case 5: // search from the binary - { #ifndef __ANDROID__ done = true; break; @@ -1322,10 +1329,16 @@ const char *Yap_findFile(const char *isource, const char *idef, const char *pt = Yap_FindExecutable(); if (pt) { - source = - (ftype == YAP_SAVED_STATE || ftype == YAP_OBJ ? "../../lib/Yap" - : "../../share/Yap"); - if (Yap_findFile(source, NULL, pt, save_buffer, access, ftype, + if (ftype == YAP_BOOT_PL) { + root = "../../share/Yap/pl"; + } else { + root = + (ftype == YAP_SAVED_STATE + || ftype == YAP_OBJ + ? "../../lib/Yap" + : "../../share/Yap"); + } + if (Yap_findFile(source, NULL, root, save_buffer, access, ftype, expand_root, in_lib)) root = save_buffer; else @@ -1334,7 +1347,7 @@ const char *Yap_findFile(const char *isource, const char *idef, done = true; } source = (isource ? isource : idef); - } break; + break; case 6: // default, try current directory if (!isource && ftype == YAP_SAVED_STATE) source = idef; @@ -1352,16 +1365,13 @@ const char *Yap_findFile(const char *isource, const char *idef, // expand names in case you have // to add a prefix - if (!access || Yap_Exists(work)) + if (!access || Yap_Exists(work)) { return work; // done + } } return NULL; } -const char *Yap_locateFile(const char *source, char *result, bool in_lib) { - return Yap_findFile(source, NULL, NULL, result, true, YAP_PL, true, in_lib); -} - static Int true_file_name(USES_REGS1) { Term t = Deref(ARG1); const char *s; diff --git a/pl/CMakeLists.txt b/pl/CMakeLists.txt index b7f3eeab7..ed13c9f61 100644 --- a/pl/CMakeLists.txt +++ b/pl/CMakeLists.txt @@ -60,7 +60,7 @@ add_custom_target (${YAP_STARTUP} ALL SOURCES ${PL_SOURCES} WORKING_DIRECTORY ${ # Create a startup.yss on the top directory. add_custom_command (TARGET ${YAP_STARTUP} - COMMAND yap-bin -b ${CMAKE_SOURCE_DIR}/pl/boot.yap -L ${CMAKE_SOURCE_DIR}/pl/init.yap -z qend_program + COMMAND yap-bin -B VERBATIM WORKING_DIRECTORY ${CMAKE_TOP_BINARY_DIR} DEPENDS yap-bin ${PL_SOURCES} diff --git a/pl/atoms.yap b/pl/atoms.yap index d2f7e3aed..23e5d2e61 100644 --- a/pl/atoms.yap +++ b/pl/atoms.yap @@ -25,16 +25,16 @@ * @addtogroup Predicates_on_Atoms * @ingroup YAPChars * -*/ +*/ -/** @pred atom_concat(+ _As_,? _A_) +/** @pred atom_concat(+ _As_,? _A_) The predicate holds when the first argument is a list of atoms, and the second unifies with the atom obtained by concatenating all the atoms in the first list. - + */ atom_concat(Xs,At) :- ( var(At) -> @@ -75,8 +75,8 @@ atom_concat(Xs,At) :- Follow is Next+Sz, '$process_atom_holes'(Unbound). - -/** @pred atomic_list_concat(+ _As_,? _A_) + +/** @pred atomic_list_concat(+ _As_,? _A_) The predicate holds when the first argument is a list of atomic terms, and @@ -84,11 +84,11 @@ the second unifies with the atom obtained by concatenating all the atomic terms in the first list. The first argument thus may contain atoms or numbers. - + */ atomic_list_concat(L,At) :- atomic_concat(L, At). - + /** @pred atomic_list_concat(? _As_,+ _Separator_,? _A_) Creates an atom just like atomic_list_concat/2, but inserts @@ -110,7 +110,7 @@ shown below. L = [gnu, gnat] ~~~~~ - + */ atomic_list_concat(L, El, At) :- var(El), !, @@ -133,7 +133,7 @@ atomic_list_concat(L, El, At) :- '$add_els'([A,B|L],El,[A,El|NL]) :- !, '$add_els'([B|L],El,NL). '$add_els'(L,_,L). - + % % small compatibility hack @@ -142,7 +142,7 @@ atomic_list_concat(L, El, At) :- '$variables_in_term'(T,[],V10), '$sort'(V10, V1), '$non_singletons_in_term'(T,[],V20), - '$sort'(V20, V2), + '$sort'(V20, V2), '$subtract_lists_of_variables'(V2,V1,VL). '$subtract_lists_of_variables'([],VL,VL). @@ -153,13 +153,13 @@ atomic_list_concat(L, El, At) :- '$subtract_lists_of_variables'([V1|VL1],[V2|VL2],[V2|VL]) :- '$subtract_lists_of_variables'([V1|VL1],VL2,VL). -/** @pred current_atom( _A_) +/** @pred current_atom( _A_) Checks whether _A_ is a currently defined atom. It is used to find all currently defined atoms by backtracking. - + */ current_atom(A) :- % check atom(A), !. diff --git a/pl/boot.yap b/pl/boot.yap index 5d33c0fae..c7f29ea8e 100644 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -415,28 +415,49 @@ true :- true. % simple trick to find out if this is we are booting from Prolog. % boot from a saved state ( - '$undefined'('$init_preds',prolog) + current_prolog_flag(saved_program, False), + writeln(False), + current_prolog_flag(saved_program, false) + -> + current_prolog_flag(resource_database, RootPath), + writeln(RootPath), + file_directory_name( RootPath, Dir ), + atom_concat( Dir, '/init.yap' , Init), + bootstrap(Init), + module( user ), + '$make_saved_state', + get_value('$consult_on_boot',X), + ( + X \= [] + -> + qsave_program( 'startup.yss'), + halt + ; + true + ) + ; + '$init_state' + ), + '$db_clean_queues'(0), + % this must be executed from C-code. + % '$startup_saved_state', + set_input(user_input), + set_output(user_output), + '$init_or_threads', + '$run_at_thread_start'. + +'$make_saved_state' :- + current_prolog_flag(os_argv, Args), + ( + member( Arg, Args ), + atom_concat( '-B', _, Arg ) -> - get_value('$consult_on_boot',X), - ( - X \= [] - -> - bootstrap(X), - module( user ), - qsave_program( 'startup.yss') + qsave_program( 'startup.yss'), + halt(0) ; true - ) - ; - '$init_state' - ), - '$db_clean_queues'(0), - % this must be executed from C-code. -% '$startup_saved_state', - set_input(user_input), - set_output(user_output), - '$init_or_threads', - '$run_at_thread_start'. + ). + '$init_globals' :- % set_prolog_flag(break_level, 0),