X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/ff0cee690d2ef6ba882e59dd4baaa0c944adb7a2..ea0efc06fdad2019ffceb86d079dd853e9d79cea:/perl.h diff --git a/perl.h b/perl.h index d62c035..c8a33a0 100644 --- a/perl.h +++ b/perl.h @@ -1,6 +1,6 @@ /* perl.h * - * Copyright (c) 1987-1994, Larry Wall + * Copyright (c) 1987-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -29,6 +29,14 @@ #include "embed.h" +#ifdef OP_IN_REGISTER +# ifdef __GNUC__ +# define stringify_immed(s) #s +# define stringify(s) stringify_immed(s) +register struct op *op asm(stringify(OP_IN_REGISTER)); +# endif +#endif + /* * STMT_START { statements; } STMT_END; * can be used as a single statement, as in @@ -37,7 +45,7 @@ * Trying to select a version that gives no warnings... */ #if !(defined(STMT_START) && defined(STMT_END)) -# if defined(__GNUC__) && !defined(__STRICT_ANSI__) +# if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(__cplusplus) # define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */ # define STMT_END ) # else @@ -52,6 +60,25 @@ # endif #endif +#define NOOP (void)0 + +#define WITH_THR(s) do { dTHR; s; } while (0) + +#ifdef USE_THREADS +# ifdef FAKE_THREADS +# include "fakethr.h" +# else +# ifdef WIN32 +# include "win32/win32thread.h" +# else +# include +typedef pthread_mutex_t perl_mutex; +typedef pthread_cond_t perl_cond; +typedef pthread_key_t perl_key; +# endif /* WIN32 */ +# endif /* FAKE_THREADS */ +#endif /* USE_THREADS */ + /* * SOFT_CAST can be used for args to prototyped functions to retain some * type checking; it only casts if the compiler does not know prototypes. @@ -80,7 +107,7 @@ */ /* define this once if either system, instead of cluttering up the src */ -#if defined(MSDOS) || defined(atarist) +#if defined(MSDOS) || defined(atarist) || defined(WIN32) #define DOSISH 1 #endif @@ -88,6 +115,10 @@ # define STANDARD_C 1 #endif +#if defined(__cplusplus) || defined(WIN32) +# define DONT_DECLARE_STD 1 +#endif + #if defined(HASVOLATILE) || defined(STANDARD_C) # ifdef __cplusplus # define VOL // to temporarily suppress warnings @@ -300,15 +331,8 @@ extern char *memset _((char*, int, int)); # endif # endif -# define memzero(d,l) memset(d,0,l) #else -# ifndef memzero -# ifdef HAS_BZERO -# define memzero(d,l) bzero(d,l) -# else -# define memzero(d,l) my_bzero(d,l) -# endif -# endif +# define memset(d,c,l) my_memset(d,c,l) #endif /* HAS_MEMSET */ #if !defined(HAS_MEMMOVE) && !defined(memmove) @@ -342,6 +366,18 @@ # endif #endif /* HAS_MEMCMP && HAS_SANE_MEMCMP */ +#ifndef memzero +# ifdef HAS_MEMSET +# define memzero(d,l) memset(d,0,l) +# else +# ifdef HAS_BZERO +# define memzero(d,l) bzero(d,l) +# else +# define memzero(d,l) my_bzero(d,l) +# endif +# endif +#endif + #ifndef HAS_BCMP # ifndef bcmp # define bcmp(s1,s2,l) memcmp(s1,s2,l) @@ -352,8 +388,14 @@ # include #endif +#if defined(SF_APPEND) && defined(USE_SFIO) && defined(I_SFIO) +/* defines SF_APPEND and might define SF_APPEND + * (the neo-BSD seem to do this). */ +# undef SF_APPEND +#endif + #ifdef I_SYS_STAT -#include +# include #endif /* The stat macros for Amdahl UTS, Unisoft System V/88 (and derivatives @@ -427,7 +469,9 @@ # ifdef VMS char *strerror _((int,...)); # else +#ifndef DONT_DECLARE_STD char *strerror _((int)); +#endif # endif # ifndef Strerror # define Strerror strerror @@ -443,55 +487,6 @@ # endif #endif -#ifdef VMS -# define STATUS_NATIVE statusvalue_vms -# define STATUS_NATIVE_EXPORT \ - ((I32)statusvalue_vms == -1 ? 44 : statusvalue_vms) -# define STATUS_NATIVE_SET(n) \ - STMT_START { \ - statusvalue_vms = (n); \ - if ((I32)statusvalue_vms == -1) \ - statusvalue = -1; \ - else if (statusvalue_vms & STS$M_SUCCESS) \ - statusvalue = 0; \ - else if ((statusvalue_vms & STS$M_SEVERITY) == 0) \ - statusvalue = 1 << 8; \ - else \ - statusvalue = (statusvalue_vms & STS$M_SEVERITY) << 8; \ - } STMT_END -# define STATUS_POSIX statusvalue -# ifdef VMSISH_STATUS -# define STATUS_CURRENT (VMSISH_STATUS ? STATUS_NATIVE : STATUS_POSIX) -# else -# define STATUS_CURRENT STATUS_POSIX -# endif -# define STATUS_POSIX_SET(n) \ - STMT_START { \ - statusvalue = (n); \ - if (statusvalue != -1) { \ - statusvalue &= 0xFFFF; \ - statusvalue_vms = statusvalue ? 44 : 1; \ - } \ - else statusvalue_vms = -1; \ - } STMT_END -# define STATUS_ALL_SUCCESS (statusvalue = 0, statusvalue_vms = 1) -# define STATUS_ALL_FAILURE (statusvalue = 1, statusvalue_vms = 44) -#else -# define STATUS_NATIVE STATUS_POSIX -# define STATUS_NATIVE_EXPORT STATUS_POSIX -# define STATUS_NATIVE_SET STATUS_POSIX_SET -# define STATUS_POSIX statusvalue -# define STATUS_POSIX_SET(n) \ - STMT_START { \ - statusvalue = (n); \ - if (statusvalue != -1) \ - statusvalue &= 0xFFFF; \ - } STMT_END -# define STATUS_CURRENT STATUS_POSIX -# define STATUS_ALL_SUCCESS (statusvalue = 0) -# define STATUS_ALL_FAILURE (statusvalue = 1) -#endif - #ifdef I_SYS_IOCTL # ifndef _IOCTL_ # include @@ -877,6 +872,11 @@ #endif +/* Digital UNIX defines a typedef CONTEXT when pthreads is in use */ +#if defined(__osf__) +# define CONTEXT PERL_CONTEXT +#endif + typedef MEM_SIZE STRLEN; typedef struct op OP; @@ -894,7 +894,9 @@ typedef struct loop LOOP; typedef struct Outrec Outrec; typedef struct interpreter PerlInterpreter; -typedef struct ff FF; +#ifndef __BORLANDC__ +typedef struct ff FF; /* XXX not defined anywhere, should go? */ +#endif typedef struct sv SV; typedef struct av AV; typedef struct hv HV; @@ -949,6 +951,55 @@ typedef I32 (*filter_t) _((int, SV *, int)); # endif #endif +#ifdef VMS +# define STATUS_NATIVE statusvalue_vms +# define STATUS_NATIVE_EXPORT \ + ((I32)statusvalue_vms == -1 ? 44 : statusvalue_vms) +# define STATUS_NATIVE_SET(n) \ + STMT_START { \ + statusvalue_vms = (n); \ + if ((I32)statusvalue_vms == -1) \ + statusvalue = -1; \ + else if (statusvalue_vms & STS$M_SUCCESS) \ + statusvalue = 0; \ + else if ((statusvalue_vms & STS$M_SEVERITY) == 0) \ + statusvalue = 1 << 8; \ + else \ + statusvalue = (statusvalue_vms & STS$M_SEVERITY) << 8; \ + } STMT_END +# define STATUS_POSIX statusvalue +# ifdef VMSISH_STATUS +# define STATUS_CURRENT (VMSISH_STATUS ? STATUS_NATIVE : STATUS_POSIX) +# else +# define STATUS_CURRENT STATUS_POSIX +# endif +# define STATUS_POSIX_SET(n) \ + STMT_START { \ + statusvalue = (n); \ + if (statusvalue != -1) { \ + statusvalue &= 0xFFFF; \ + statusvalue_vms = statusvalue ? 44 : 1; \ + } \ + else statusvalue_vms = -1; \ + } STMT_END +# define STATUS_ALL_SUCCESS (statusvalue = 0, statusvalue_vms = 1) +# define STATUS_ALL_FAILURE (statusvalue = 1, statusvalue_vms = 44) +#else +# define STATUS_NATIVE STATUS_POSIX +# define STATUS_NATIVE_EXPORT STATUS_POSIX +# define STATUS_NATIVE_SET STATUS_POSIX_SET +# define STATUS_POSIX statusvalue +# define STATUS_POSIX_SET(n) \ + STMT_START { \ + statusvalue = (n); \ + if (statusvalue != -1) \ + statusvalue &= 0xFFFF; \ + } STMT_END +# define STATUS_CURRENT STATUS_POSIX +# define STATUS_ALL_SUCCESS (statusvalue = 0) +# define STATUS_ALL_FAILURE (statusvalue = 1) +#endif + /* Some unistd.h's give a prototype for pause() even though HAS_PAUSE ends up undefined. This causes the #define below to be rejected by the compmiler. Sigh. @@ -977,6 +1028,17 @@ union any { void (*any_dptr) _((void*)); }; +#ifdef USE_THREADS +#define ARGSproto struct thread * +#else +#define ARGSproto void +#endif /* USE_THREADS */ + +/* Work around some cygwin32 problems with importing global symbols */ +#if defined(CYGWIN32) && defined(DLLIMPORT) +# include "cw32imp.h" +#endif + #include "regexp.h" #include "sv.h" #include "util.h" @@ -1172,7 +1234,7 @@ struct ufuncs { }; /* Fix these up for __STDC__ */ -#ifndef __cplusplus +#ifndef DONT_DECLARE_STD char *mktemp _((char*)); double atof _((const char*)); #endif @@ -1194,7 +1256,10 @@ char *strcpy(), *strcat(); # endif double exp _((double)); double log _((double)); + double log10 _((double)); double sqrt _((double)); + double frexp _((double,int*)); + double ldexp _((double,int)); double modf _((double,double*)); double sin _((double)); double cos _((double)); @@ -1211,8 +1276,12 @@ char *crypt (); /* Maybe more hosts will need the unprototyped version */ #else char *crypt _((const char*, const char*)); #endif +#ifndef DONT_DECLARE_STD +#ifndef getenv char *getenv _((const char*)); +#endif Off_t lseek _((int,Off_t,int)); +#endif char *getlogin _((void)); #endif @@ -1252,14 +1321,21 @@ typedef Sighandler_t Sigsave_t; # ifndef register # define register # endif -# ifdef MYMALLOC -# ifndef DEBUGGING_MSTATS -# define DEBUGGING_MSTATS -# endif -# endif # define PAD_SV(po) pad_sv(po) +# define RUNOPS_DEFAULT runops_debug #else # define PAD_SV(po) curpad[po] +# define RUNOPS_DEFAULT runops_standard +#endif + +/* + * These need prototyping here because isn't + * included until after runops is initialised. + */ + +int runops_standard _((void)); +#ifdef DEBUGGING +int runops_debug _((void)); #endif /****************/ @@ -1268,9 +1344,26 @@ typedef Sighandler_t Sigsave_t; /* global state */ EXT PerlInterpreter * curinterp; /* currently running interpreter */ +#ifdef USE_THREADS +EXT perl_key thr_key; /* For per-thread struct thread ptr */ +EXT perl_mutex sv_mutex; /* Mutex for allocating SVs in sv.c */ +EXT perl_mutex malloc_mutex; /* Mutex for malloc */ +EXT perl_mutex eval_mutex; /* Mutex for doeval */ +EXT perl_cond eval_cond; /* Condition variable for doeval */ +EXT struct thread * eval_owner; /* Owner thread for doeval */ +EXT int nthreads; /* Number of threads currently */ +EXT perl_mutex threads_mutex; /* Mutex for nthreads and thread list */ +EXT perl_cond nthreads_cond; /* Condition variable for nthreads */ +#ifdef FAKE_THREADS +EXT struct thread * thr; /* Currently executing (fake) thread */ +#endif +#endif /* USE_THREADS */ + /* VMS doesn't use environ array and NeXT has problems with crt0.o globals */ #if !defined(VMS) && !(defined(NeXT) && defined(__DYNAMIC__)) +#ifndef DONT_DECLARE_STD extern char ** environ; /* environment variables supplied via exec */ +#endif #else # if defined(NeXT) && defined(__DYNAMIC__) @@ -1297,6 +1390,7 @@ EXT U32 * profiledata; EXT int maxo INIT(MAXO);/* Number of ops */ EXT char * osname; /* operating system */ EXT char * sh_path INIT(SH_PATH); /* full path of shell */ +EXT Sighandler_t sighandlerp; EXT XPV* xiv_arenaroot; /* list of allocated xiv areas */ EXT IV ** xiv_root; /* free xiv list--shared by interpreters */ @@ -1314,8 +1408,12 @@ EXT SV ** stack_max; /* stack->array_ary + stack->array_max */ /* likewise for these */ -EXT OP * op; /* current op--oughta be in a global register */ - +#ifdef OP_IN_REGISTER +EXT OP * opsave; /* save current op register across longjmps */ +#else +EXT OP * op; /* current op--when not in a global register */ +#endif +EXT int (*runops) _((void)) INIT(RUNOPS_DEFAULT); EXT I32 * scopestack; /* blocks we've entered */ EXT I32 scopestack_ix; EXT I32 scopestack_max; @@ -1337,7 +1435,6 @@ EXT SV ** curpad; /* temp space */ EXT SV * Sv; EXT XPV * Xpv; -EXT char buf[2048]; /* should be longer than PATH_MAX */ EXT char tokenbuf[256]; EXT struct stat statbuf; #ifdef HAS_TIMES @@ -1357,37 +1454,37 @@ EXTCONST char * hexdigit INIT("0123456789abcdef0123456789ABCDEFx"); EXTCONST char * patleave INIT("\\.^$@dDwWsSbB+*?|()-nrtfeaxc0123456789[{]}"); EXTCONST char * vert INIT("|"); -EXTCONST char warn_uninit[] +EXTCONST char warn_uninit[] INIT("Use of uninitialized value"); -EXTCONST char warn_nosemi[] +EXTCONST char warn_nosemi[] INIT("Semicolon seems to be missing"); -EXTCONST char warn_reserved[] +EXTCONST char warn_reserved[] INIT("Unquoted string \"%s\" may clash with future reserved word"); -EXTCONST char warn_nl[] +EXTCONST char warn_nl[] INIT("Unsuccessful %s on filename containing newline"); -EXTCONST char no_wrongref[] +EXTCONST char no_wrongref[] INIT("Can't use %s ref as %s ref"); -EXTCONST char no_symref[] +EXTCONST char no_symref[] INIT("Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use"); -EXTCONST char no_usym[] +EXTCONST char no_usym[] INIT("Can't use an undefined value as %s reference"); -EXTCONST char no_aelem[] +EXTCONST char no_aelem[] INIT("Modification of non-creatable array value attempted, subscript %d"); -EXTCONST char no_helem[] +EXTCONST char no_helem[] INIT("Modification of non-creatable hash value attempted, subscript \"%s\""); -EXTCONST char no_modify[] +EXTCONST char no_modify[] INIT("Modification of a read-only value attempted"); -EXTCONST char no_mem[] +EXTCONST char no_mem[] INIT("Out of memory!\n"); -EXTCONST char no_security[] +EXTCONST char no_security[] INIT("Insecure dependency in %s%s"); -EXTCONST char no_sock_func[] +EXTCONST char no_sock_func[] INIT("Unsupported socket function \"%s\" called"); -EXTCONST char no_dir_func[] +EXTCONST char no_dir_func[] INIT("Unsupported directory function \"%s\" called"); -EXTCONST char no_func[] +EXTCONST char no_func[] INIT("The %s function is unimplemented"); -EXTCONST char no_myglob[] +EXTCONST char no_myglob[] INIT("\"my\" variable %s can't be in a package"); EXT SV sv_undef; @@ -1551,6 +1648,8 @@ EXTCONST char* block_type[]; #include "perly.h" +#define LEX_NOTPARSING 11 /* borrowed from toke.c */ + typedef enum { XOPERATOR, XTERM, @@ -1618,6 +1717,7 @@ EXT char * last_uni; /* position of last named-unary operator */ EXT char * last_lop; /* position of last list operator */ EXT OPCODE last_lop_op; /* last list operator */ EXT bool in_my; /* we're compiling a "my" declaration */ +EXT HV * in_my_stash; /* declared class of this "my" declaration */ #ifdef FCRYPT EXT I32 cryptseen; /* has fast crypt() been initialized? */ #endif @@ -1775,6 +1875,7 @@ IEXT HV * Idebstash; /* symbol table for perldb package */ IEXT SV * Icurstname; /* name of current package */ IEXT AV * Ibeginav; /* names of BEGIN subroutines */ IEXT AV * Iendav; /* names of END subroutines */ +IEXT AV * Iinitav; /* names of INIT subroutines */ IEXT HV * Istrtab; /* shared string table */ /* memory management */ @@ -1825,15 +1926,13 @@ IEXT line_t Icopline IINIT(NOLINE); IEXT CONTEXT * Icxstack; IEXT I32 Icxstack_ix IINIT(-1); IEXT I32 Icxstack_max IINIT(128); -IEXT Sigjmp_buf Itop_env; +IEXT JMPENV Istart_env; /* empty startup sigjmp() environment */ +IEXT JMPENV * Itop_env; /* ptr. to current sigjmp() environment */ IEXT I32 Irunlevel; /* stack stuff */ IEXT AV * Icurstack; /* THE STACK */ IEXT AV * Imainstack; /* the stack when nothing funny is happening */ -IEXT SV ** Imystack_base; /* stack->array_ary */ -IEXT SV ** Imystack_sp; /* stack pointer now */ -IEXT SV ** Imystack_max; /* stack->array_ary + stack->array_max */ /* format accumulators */ IEXT SV * Iformtarget; @@ -1861,6 +1960,12 @@ IEXT bool Ipreambled; IEXT AV * Ipreambleav; IEXT int Ilaststatval IINIT(-1); IEXT I32 Ilaststype IINIT(OP_STAT); +IEXT SV * Imess_sv; + +#ifdef USE_THREADS +/* threads stuff */ +IEXT SV * Ithrsv; /* holds struct thread for main thread */ +#endif /* USE_THREADS */ #undef IEXT #undef IINIT @@ -1873,6 +1978,7 @@ struct interpreter { }; #endif +#include "thread.h" #include "pp.h" #ifdef __cplusplus @@ -1901,7 +2007,9 @@ EXT MGVTBL vtbl_sv = {magic_get, magic_set, magic_len, 0, 0}; -EXT MGVTBL vtbl_env = {0, 0, 0, 0, 0}; +EXT MGVTBL vtbl_env = {0, magic_set_all_env, + 0, magic_clear_all_env, + 0}; EXT MGVTBL vtbl_envelem = {0, magic_setenv, 0, magic_clearenv, 0}; @@ -1919,7 +2027,8 @@ EXT MGVTBL vtbl_packelem = {magic_getpack, EXT MGVTBL vtbl_dbline = {0, magic_setdbline, 0, 0, 0}; EXT MGVTBL vtbl_isa = {0, magic_setisa, - 0, 0, 0}; + 0, magic_setisa, + 0}; EXT MGVTBL vtbl_isaelem = {0, magic_setisa, 0, 0, 0}; EXT MGVTBL vtbl_arylen = {magic_getarylen, @@ -1948,8 +2057,11 @@ EXT MGVTBL vtbl_fm = {0, magic_setfm, EXT MGVTBL vtbl_uvar = {magic_getuvar, magic_setuvar, 0, 0, 0}; -EXT MGVTBL vtbl_itervar = {magic_getitervar,magic_setitervar, - 0, 0, magic_freeitervar}; +#ifdef USE_THREADS +EXT MGVTBL vtbl_mutex = {0, 0, 0, 0, magic_mutexfree}; +#endif /* USE_THREADS */ +EXT MGVTBL vtbl_defelem = {magic_getdefelem,magic_setdefelem, + 0, 0, magic_freedefelem}; #ifdef USE_LOCALE_COLLATE EXT MGVTBL vtbl_collxfrm = {0, @@ -1987,7 +2099,12 @@ EXT MGVTBL vtbl_pos; EXT MGVTBL vtbl_bm; EXT MGVTBL vtbl_fm; EXT MGVTBL vtbl_uvar; -EXT MGVTBL vtbl_itervar; + +#ifdef USE_THREADS +EXT MGVTBL vtbl_mutex; +#endif /* USE_THREADS */ + +EXT MGVTBL vtbl_defelem; #ifdef USE_LOCALE_COLLATE EXT MGVTBL vtbl_collxfrm; @@ -2130,6 +2247,22 @@ enum { #endif /* OVERLOAD */ +#define PERLDB_ALL 0xff +#define PERLDBf_SUB 0x01 /* Debug sub enter/exit. */ +#define PERLDBf_LINE 0x02 /* Keep line #. */ +#define PERLDBf_NOOPT 0x04 /* Switch off optimizations. */ +#define PERLDBf_INTER 0x08 /* Preserve more data for + later inspections. */ +#define PERLDBf_SUBLINE 0x10 /* Keep subr source lines. */ +#define PERLDBf_SINGLE 0x20 /* Start with single-step on. */ + +#define PERLDB_SUB (perldb && (perldb & PERLDBf_SUB)) +#define PERLDB_LINE (perldb && (perldb & PERLDBf_LINE)) +#define PERLDB_NOOPT (perldb && (perldb & PERLDBf_NOOPT)) +#define PERLDB_INTER (perldb && (perldb & PERLDBf_INTER)) +#define PERLDB_SUBLINE (perldb && (perldb & PERLDBf_SUBLINE)) +#define PERLDB_SINGLE (perldb && (perldb & PERLDBf_SINGLE)) + #ifdef USE_LOCALE_COLLATE EXT U32 collation_ix; /* Collation generation index */ EXT char * collation_name; /* Name of current collation */ @@ -2171,5 +2304,18 @@ EXT bool numeric_local INIT(TRUE); /* Assume local numerics */ #define printf PerlIO_stdoutf #endif +/* + * nice_chunk and nice_chunk size need to be set + * and queried under the protection of sv_mutex + */ +#define offer_nice_chunk(chunk, chunk_size) do { \ + MUTEX_LOCK(&sv_mutex); \ + if (!nice_chunk) { \ + nice_chunk = (char*)(chunk); \ + nice_chunk_size = (chunk_size); \ + } \ + MUTEX_UNLOCK(&sv_mutex); \ + } while (0) + #endif /* Include guard */