62028 lines
1.9 MiB
62028 lines
1.9 MiB
/*
|
||
* Symisc PH7: An embeddable bytecode compiler and a virtual machine for the PHP(5) programming language.
|
||
* Copyright (C) 2011, 2012, 2013, 2014 Symisc Systems http://ph7.symisc.net/
|
||
* Version 2.1.4
|
||
* For information on licensing,redistribution of this file,and for a DISCLAIMER OF ALL WARRANTIES
|
||
* please contact Symisc Systems via:
|
||
* legal@symisc.net
|
||
* licensing@symisc.net
|
||
* contact@symisc.net
|
||
* or visit:
|
||
* http://ph7.symisc.net/
|
||
*/
|
||
/*
|
||
* Copyright (C) 2011, 2012, 2013, 2014 Symisc Systems. All rights reserved.
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without
|
||
* modification, are permitted provided that the following conditions
|
||
* are met:
|
||
* 1. Redistributions of source code must retain the above copyright
|
||
* notice, this list of conditions and the following disclaimer.
|
||
* 2. Redistributions in binary form must reproduce the above copyright
|
||
* notice, this list of conditions and the following disclaimer in the
|
||
* documentation and/or other materials provided with the distribution.
|
||
* 3. Redistributions in any form must be accompanied by information on
|
||
* how to obtain complete source code for the PH7 engine and any
|
||
* accompanying software that uses the PH7 engine software.
|
||
* The source code must either be included in the distribution
|
||
* or be available for no more than the cost of distribution plus
|
||
* a nominal fee, and must be freely redistributable under reasonable
|
||
* conditions. For an executable file, complete source code means
|
||
* the source code for all modules it contains.It does not include
|
||
* source code for modules or files that typically accompany the major
|
||
* components of the operating system on which the executable file runs.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY SYMISC SYSTEMS ``AS IS'' AND ANY EXPRESS
|
||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SYMISC SYSTEMS
|
||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
*/
|
||
/*
|
||
* $SymiscID: ph7.c v2.1 UNIX|WIN32/64 2012-09-15 09:00 stable <chm@symisc.net> $
|
||
*/
|
||
/* This file is an amalgamation of many separate C source files from PH7 version 2.1.
|
||
* By combining all the individual C code files into this single large file, the entire code
|
||
* can be compiled as a single translation unit.This allows many compilers to do optimization's
|
||
* that would not be possible if the files were compiled separately.Performance improvements
|
||
* are commonly seen when PH7 is compiled as a single translation unit.
|
||
*
|
||
* This file is all you need to compile PH7.To use PH7 in other programs, you need
|
||
* this file and the "ph7.h" header file that defines the programming interface to the
|
||
* PH7 engine.(If you do not have the "ph7.h" header file at hand, you will find
|
||
* a copy embedded within the text of this file.Search for "Header file: <ph7.h>" to find
|
||
* the start of the embedded ph7.h header file.) Additional code files may be needed if
|
||
* you want a wrapper to interface PH7 with your choice of programming language.
|
||
* To get the official documentation,please visit http://ph7.symisc.net/
|
||
*/
|
||
/*
|
||
* Make the sure the following is defined in the amalgamation build
|
||
*/
|
||
#ifndef PH7_AMALGAMATION
|
||
#define PH7_AMALGAMATION
|
||
#endif /* PH7_AMALGAMATION */
|
||
/*
|
||
* Embedded header file for the PH7 engine: <ph7.h>
|
||
*/
|
||
/*
|
||
* ----------------------------------------------------------
|
||
* File: ph7.h
|
||
* MD5: b5527f9c7eb410a9f9367a6b03014a65
|
||
* ----------------------------------------------------------
|
||
*/
|
||
/* This file was automatically generated. Do not edit (except for compile time directive)! */
|
||
#ifndef _PH7_H_
|
||
#define _PH7_H_
|
||
/*
|
||
* Symisc PH7: An embeddable bytecode compiler and a virtual machine for the PHP(5) programming language.
|
||
* Copyright (C) 2011-2012, Symisc Systems http://ph7.symisc.net/
|
||
* Version 2.1.4
|
||
* For information on licensing,redistribution of this file,and for a DISCLAIMER OF ALL WARRANTIES
|
||
* please contact Symisc Systems via:
|
||
* legal@symisc.net
|
||
* licensing@symisc.net
|
||
* contact@symisc.net
|
||
* or visit:
|
||
* http://ph7.symisc.net/
|
||
*/
|
||
/*
|
||
* Copyright (C) 2011, 2012 Symisc Systems. All rights reserved.
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without
|
||
* modification, are permitted provided that the following conditions
|
||
* are met:
|
||
* 1. Redistributions of source code must retain the above copyright
|
||
* notice, this list of conditions and the following disclaimer.
|
||
* 2. Redistributions in binary form must reproduce the above copyright
|
||
* notice, this list of conditions and the following disclaimer in the
|
||
* documentation and/or other materials provided with the distribution.
|
||
* 3. Redistributions in any form must be accompanied by information on
|
||
* how to obtain complete source code for the PH7 engine and any
|
||
* accompanying software that uses the PH7 engine software.
|
||
* The source code must either be included in the distribution
|
||
* or be available for no more than the cost of distribution plus
|
||
* a nominal fee, and must be freely redistributable under reasonable
|
||
* conditions. For an executable file, complete source code means
|
||
* the source code for all modules it contains.It does not include
|
||
* source code for modules or files that typically accompany the major
|
||
* components of the operating system on which the executable file runs.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY SYMISC SYSTEMS ``AS IS'' AND ANY EXPRESS
|
||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||
* NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SYMISC SYSTEMS
|
||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
*/
|
||
/* $SymiscID: ph7.h v2.1 UNIX|WIN32/64 2012-09-15 09:43 stable <chm@symisc.net> $ */
|
||
#include <stdarg.h> /* needed for the definition of va_list */
|
||
/*
|
||
* Compile time engine version, signature, identification in the symisc source tree
|
||
* and copyright notice.
|
||
* Each macro have an equivalent C interface associated with it that provide the same
|
||
* information but are associated with the library instead of the header file.
|
||
* Refer to [ph7_lib_version()], [ph7_lib_signature()], [ph7_lib_ident()] and
|
||
* [ph7_lib_copyright()] for more information.
|
||
*/
|
||
/*
|
||
* The PH7_VERSION C preprocessor macroevaluates to a string literal
|
||
* that is the ph7 version in the format "X.Y.Z" where X is the major
|
||
* version number and Y is the minor version number and Z is the release
|
||
* number.
|
||
*/
|
||
#define PH7_VERSION "2.1.4"
|
||
/*
|
||
* The PH7_VERSION_NUMBER C preprocessor macro resolves to an integer
|
||
* with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
|
||
* numbers used in [PH7_VERSION].
|
||
*/
|
||
#define PH7_VERSION_NUMBER 2001004
|
||
/*
|
||
* The PH7_SIG C preprocessor macro evaluates to a string
|
||
* literal which is the public signature of the ph7 engine.
|
||
* This signature could be included for example in a host-application
|
||
* generated Server MIME header as follows:
|
||
* Server: YourWebServer/x.x PH7/x.x.x \r\n
|
||
*/
|
||
#define PH7_SIG "PH7/2.1.4"
|
||
/*
|
||
* PH7 identification in the Symisc source tree:
|
||
* Each particular check-in of a particular software released
|
||
* by symisc systems have an unique identifier associated with it.
|
||
* This macro hold the one associated with ph7.
|
||
*/
|
||
#define PH7_IDENT "ph7:c193f4d8a6b90ee60f9afad11840f1010054fdf9"
|
||
/*
|
||
* Copyright notice.
|
||
* If you have any questions about the licensing situation,please
|
||
* visit http://ph7.symisc.net/licensing.html
|
||
* or contact Symisc Systems via:
|
||
* legal@symisc.net
|
||
* licensing@symisc.net
|
||
* contact@symisc.net
|
||
*/
|
||
#define PH7_COPYRIGHT "Copyright (C) Symisc Systems 2011-2012, http://ph7.symisc.net/"
|
||
/* Make sure we can call this stuff from C++ */
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
/* Forward declaration to public objects */
|
||
typedef struct ph7_io_stream ph7_io_stream;
|
||
typedef struct ph7_context ph7_context;
|
||
typedef struct ph7_value ph7_value;
|
||
typedef struct ph7_vfs ph7_vfs;
|
||
typedef struct ph7_vm ph7_vm;
|
||
typedef struct ph7 ph7;
|
||
/*
|
||
* ------------------------------
|
||
* Compile time directives
|
||
* ------------------------------
|
||
* For most purposes, PH7 can be built just fine using the default compilation options.
|
||
* However, if required, the compile-time options documented below can be used to omit
|
||
* PH7 features (resulting in a smaller compiled library size) or to change the default
|
||
* values of some parameters.
|
||
* Every effort has been made to ensure that the various combinations of compilation
|
||
* options work harmoniously and produce a working library.
|
||
*
|
||
* PH7_ENABLE_THREADS
|
||
* This option controls whether or not code is included in PH7 to enable it to operate
|
||
* safely in a multithreaded environment. The default is not. That is,all mutexing code
|
||
* is omitted and it is unsafe to use PH7 in a multithreaded program. When compiled
|
||
* with the PH7_ENABLE_THREADS directive enabled, PH7 can be used in a multithreaded
|
||
* program and it's safe to share the same virtual machine and engine instance between
|
||
* two or more threads.
|
||
* The value of PH7_ENABLE_THREADS can be determined at run-time using the
|
||
* ph7_lib_is_threadsafe() interface.When PH7 has been compiled with PH7_ENABLE_THREAD
|
||
* then the threading mode can be altered at run-time using the ph7_lib_config()
|
||
* interface together with one of these verbs:
|
||
* PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE
|
||
* PH7_LIB_CONFIG_THREAD_LEVEL_MULTI
|
||
* Also note,platforms others than Windows and UNIX systems must install their own
|
||
* mutex subsystem via ph7_lib_config() with a configuration verb set to
|
||
* PH7_LIB_CONFIG_USER_MUTEX. Otherwise the library is not threadsafe.
|
||
* Note that you must link PH7 with the POSIX threads library under UNIX-like systems
|
||
* (i.e: -lpthread).Otherwise you will get a link time error.
|
||
* Options To Omit/Enable Features:
|
||
* The following options can be used to reduce the size of the compiled library
|
||
* by omitting optional features. This is probably only useful in embedded systems
|
||
* where space is especially tight, as even with all features included the PH7 library
|
||
* is relatively small. Don't forget to tell your compiler to optimize for binary
|
||
* size! (the -Os option if using GCC).
|
||
* Telling your compiler to optimize for size usually has a much larger impact
|
||
* on library footprint than employing any of these compile-time options.
|
||
* PH7_DISABLE_BUILTIN_FUNC
|
||
* PH7 come with more than 460 built-in functions suitable for most purposes ranging
|
||
* from string/XML/INI processing to ZIP extracting, Base64 encoding/decoding and so on.
|
||
* If this directive is enabled, all the built-in functions are omitted from the build.
|
||
* Note that language construct functions such as is_int(), is_string(), func_get_arg(),
|
||
* define(), etc. are not omitted from the build and are not affected by this directive.
|
||
* PH7_ENABLE_MATH_FUNC
|
||
* If this directive is enabled, built-in math functions such as sqrt(),abs(),
|
||
* log(), ceil(), etc. are included in the build. Note that you may need to link
|
||
* PH7 with the math library in same linux/BSD flavor (i.e: -lm).Otherwise you
|
||
* will get a link time error.
|
||
* PH7_DISABLE_DISK_IO
|
||
* If this directive is enabled, built-in Virtual File System functions such as
|
||
* chdir(), mkdir(), chroot(), unlink(), delete(), etc. are omitted from the build.
|
||
* PH7_DISABLE_HASH_IO
|
||
* If this directive is enabled, built-in hash functions such as md5(), sha1(),
|
||
* md5_file(), crc32(), etc. are omitted from the build.
|
||
* PH7_OMIT_FLOATING_POINT
|
||
* This option is used to omit floating-point number support from the PH7 library
|
||
* if compiling for a processor that lacks floating point support. When specified
|
||
* the library will substitute 64-bit integer arithmetic for floating-point which
|
||
* mean that 25.e-3 and 25 are equals and are of type integer.
|
||
*/
|
||
/* Symisc public definitions */
|
||
#if !defined(SYMISC_STANDARD_DEFS)
|
||
#define SYMISC_STANDARD_DEFS
|
||
#if defined (_WIN32) || defined (WIN32) || defined(__MINGW32__) || defined (_MSC_VER) || defined (_WIN32_WCE)
|
||
/* Windows Systems */
|
||
#if !defined(__WINNT__)
|
||
#define __WINNT__
|
||
#endif
|
||
#else
|
||
/*
|
||
* By default we will assume that we are compiling on a UNIX systems.
|
||
* Otherwise the OS_OTHER directive must be defined.
|
||
*/
|
||
#if !defined(OS_OTHER)
|
||
#if !defined(__UNIXES__)
|
||
#define __UNIXES__
|
||
#endif /* __UNIXES__ */
|
||
#else
|
||
#endif /* OS_OTHER */
|
||
#endif /* __WINNT__/__UNIXES__ */
|
||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||
typedef signed __int64 sxi64; /* 64 bits(8 bytes) signed int64 */
|
||
typedef unsigned __int64 sxu64; /* 64 bits(8 bytes) unsigned int64 */
|
||
#else
|
||
typedef signed long long int sxi64; /* 64 bits(8 bytes) signed int64 */
|
||
typedef unsigned long long int sxu64; /* 64 bits(8 bytes) unsigned int64 */
|
||
#endif /* _MSC_VER */
|
||
/* Signature of the consumer routine */
|
||
typedef int (*ProcConsumer)(const void *,unsigned int,void *);
|
||
/* Forward reference */
|
||
typedef struct SyMutexMethods SyMutexMethods;
|
||
typedef struct SyMemMethods SyMemMethods;
|
||
typedef struct SyString SyString;
|
||
typedef struct syiovec syiovec;
|
||
typedef struct SyMutex SyMutex;
|
||
typedef struct Sytm Sytm;
|
||
/* Scatter and gather array. */
|
||
struct syiovec
|
||
{
|
||
#if defined (__WINNT__)
|
||
/* Same fields type and offset as WSABUF structure defined one winsock2 header */
|
||
unsigned long nLen;
|
||
char *pBase;
|
||
#else
|
||
void *pBase;
|
||
unsigned long nLen;
|
||
#endif
|
||
};
|
||
struct SyString
|
||
{
|
||
const char *zString; /* Raw string (may not be null terminated) */
|
||
unsigned int nByte; /* Raw string length */
|
||
};
|
||
/* Time structure. */
|
||
struct Sytm
|
||
{
|
||
int tm_sec; /* seconds (0 - 60) */
|
||
int tm_min; /* minutes (0 - 59) */
|
||
int tm_hour; /* hours (0 - 23) */
|
||
int tm_mday; /* day of month (1 - 31) */
|
||
int tm_mon; /* month of year (0 - 11) */
|
||
int tm_year; /* year + 1900 */
|
||
int tm_wday; /* day of week (Sunday = 0) */
|
||
int tm_yday; /* day of year (0 - 365) */
|
||
int tm_isdst; /* is summer time in effect? */
|
||
char *tm_zone; /* abbreviation of timezone name */
|
||
long tm_gmtoff; /* offset from UTC in seconds */
|
||
};
|
||
/* Convert a tm structure (struct tm *) found in <time.h> to a Sytm structure */
|
||
#define STRUCT_TM_TO_SYTM(pTM,pSYTM) \
|
||
(pSYTM)->tm_hour = (pTM)->tm_hour;\
|
||
(pSYTM)->tm_min = (pTM)->tm_min;\
|
||
(pSYTM)->tm_sec = (pTM)->tm_sec;\
|
||
(pSYTM)->tm_mon = (pTM)->tm_mon;\
|
||
(pSYTM)->tm_mday = (pTM)->tm_mday;\
|
||
(pSYTM)->tm_year = (pTM)->tm_year + 1900;\
|
||
(pSYTM)->tm_yday = (pTM)->tm_yday;\
|
||
(pSYTM)->tm_wday = (pTM)->tm_wday;\
|
||
(pSYTM)->tm_isdst = (pTM)->tm_isdst;\
|
||
(pSYTM)->tm_gmtoff = 0;\
|
||
(pSYTM)->tm_zone = 0;
|
||
|
||
/* Convert a SYSTEMTIME structure (LPSYSTEMTIME: Windows Systems only ) to a Sytm structure */
|
||
#define SYSTEMTIME_TO_SYTM(pSYSTIME,pSYTM) \
|
||
(pSYTM)->tm_hour = (pSYSTIME)->wHour;\
|
||
(pSYTM)->tm_min = (pSYSTIME)->wMinute;\
|
||
(pSYTM)->tm_sec = (pSYSTIME)->wSecond;\
|
||
(pSYTM)->tm_mon = (pSYSTIME)->wMonth - 1;\
|
||
(pSYTM)->tm_mday = (pSYSTIME)->wDay;\
|
||
(pSYTM)->tm_year = (pSYSTIME)->wYear;\
|
||
(pSYTM)->tm_yday = 0;\
|
||
(pSYTM)->tm_wday = (pSYSTIME)->wDayOfWeek;\
|
||
(pSYTM)->tm_gmtoff = 0;\
|
||
(pSYTM)->tm_isdst = -1;\
|
||
(pSYTM)->tm_zone = 0;
|
||
|
||
/* Dynamic memory allocation methods. */
|
||
struct SyMemMethods
|
||
{
|
||
void * (*xAlloc)(unsigned int); /* [Required:] Allocate a memory chunk */
|
||
void * (*xRealloc)(void *,unsigned int); /* [Required:] Re-allocate a memory chunk */
|
||
void (*xFree)(void *); /* [Required:] Release a memory chunk */
|
||
unsigned int (*xChunkSize)(void *); /* [Optional:] Return chunk size */
|
||
int (*xInit)(void *); /* [Optional:] Initialization callback */
|
||
void (*xRelease)(void *); /* [Optional:] Release callback */
|
||
void *pUserData; /* [Optional:] First argument to xInit() and xRelease() */
|
||
};
|
||
/* Out of memory callback signature. */
|
||
typedef int (*ProcMemError)(void *);
|
||
/* Mutex methods. */
|
||
struct SyMutexMethods
|
||
{
|
||
int (*xGlobalInit)(void); /* [Optional:] Global mutex initialization */
|
||
void (*xGlobalRelease)(void); /* [Optional:] Global Release callback () */
|
||
SyMutex * (*xNew)(int); /* [Required:] Request a new mutex */
|
||
void (*xRelease)(SyMutex *); /* [Optional:] Release a mutex */
|
||
void (*xEnter)(SyMutex *); /* [Required:] Enter mutex */
|
||
int (*xTryEnter)(SyMutex *); /* [Optional:] Try to enter a mutex */
|
||
void (*xLeave)(SyMutex *); /* [Required:] Leave a locked mutex */
|
||
};
|
||
#if defined (_MSC_VER) || defined (__MINGW32__) || defined (__GNUC__) && defined (__declspec)
|
||
#define SX_APIIMPORT __declspec(dllimport)
|
||
#define SX_APIEXPORT __declspec(dllexport)
|
||
#else
|
||
#define SX_APIIMPORT
|
||
#define SX_APIEXPORT
|
||
#endif
|
||
/* Standard return values from Symisc public interfaces */
|
||
#define SXRET_OK 0 /* Not an error */
|
||
#define SXERR_MEM (-1) /* Out of memory */
|
||
#define SXERR_IO (-2) /* IO error */
|
||
#define SXERR_EMPTY (-3) /* Empty field */
|
||
#define SXERR_LOCKED (-4) /* Locked operation */
|
||
#define SXERR_ORANGE (-5) /* Out of range value */
|
||
#define SXERR_NOTFOUND (-6) /* Item not found */
|
||
#define SXERR_LIMIT (-7) /* Limit reached */
|
||
#define SXERR_MORE (-8) /* Need more input */
|
||
#define SXERR_INVALID (-9) /* Invalid parameter */
|
||
#define SXERR_ABORT (-10) /* User callback request an operation abort */
|
||
#define SXERR_EXISTS (-11) /* Item exists */
|
||
#define SXERR_SYNTAX (-12) /* Syntax error */
|
||
#define SXERR_UNKNOWN (-13) /* Unknown error */
|
||
#define SXERR_BUSY (-14) /* Busy operation */
|
||
#define SXERR_OVERFLOW (-15) /* Stack or buffer overflow */
|
||
#define SXERR_WILLBLOCK (-16) /* Operation will block */
|
||
#define SXERR_NOTIMPLEMENTED (-17) /* Operation not implemented */
|
||
#define SXERR_EOF (-18) /* End of input */
|
||
#define SXERR_PERM (-19) /* Permission error */
|
||
#define SXERR_NOOP (-20) /* No-op */
|
||
#define SXERR_FORMAT (-21) /* Invalid format */
|
||
#define SXERR_NEXT (-22) /* Not an error */
|
||
#define SXERR_OS (-23) /* System call return an error */
|
||
#define SXERR_CORRUPT (-24) /* Corrupted pointer */
|
||
#define SXERR_CONTINUE (-25) /* Not an error: Operation in progress */
|
||
#define SXERR_NOMATCH (-26) /* No match */
|
||
#define SXERR_RESET (-27) /* Operation reset */
|
||
#define SXERR_DONE (-28) /* Not an error */
|
||
#define SXERR_SHORT (-29) /* Buffer too short */
|
||
#define SXERR_PATH (-30) /* Path error */
|
||
#define SXERR_TIMEOUT (-31) /* Timeout */
|
||
#define SXERR_BIG (-32) /* Too big for processing */
|
||
#define SXERR_RETRY (-33) /* Retry your call */
|
||
#define SXERR_IGNORE (-63) /* Ignore */
|
||
#endif /* SYMISC_PUBLIC_DEFS */
|
||
/* Standard PH7 return values */
|
||
#define PH7_OK SXRET_OK /* Successful result */
|
||
/* beginning-of-error-codes */
|
||
#define PH7_NOMEM SXERR_MEM /* Out of memory */
|
||
#define PH7_ABORT SXERR_ABORT /* Foreign Function request operation abort/Another thread have released this instance */
|
||
#define PH7_IO_ERR SXERR_IO /* IO error */
|
||
#define PH7_CORRUPT SXERR_CORRUPT /* Corrupt pointer/Unknown configuration option */
|
||
#define PH7_LOOKED SXERR_LOCKED /* Forbidden Operation */
|
||
#define PH7_COMPILE_ERR (-70) /* Compilation error */
|
||
#define PH7_VM_ERR (-71) /* Virtual machine error */
|
||
/* end-of-error-codes */
|
||
/*
|
||
* If compiling for a processor that lacks floating point
|
||
* support, substitute integer for floating-point.
|
||
*/
|
||
#ifdef PH7_OMIT_FLOATING_POINT
|
||
typedef sxi64 ph7_real;
|
||
#else
|
||
typedef double ph7_real;
|
||
#endif
|
||
typedef sxi64 ph7_int64;
|
||
#define PH7_APIEXPORT SX_APIEXPORT
|
||
/*
|
||
* Engine Configuration Commands.
|
||
*
|
||
* The following set of constants are the available configuration verbs that can
|
||
* be used by the host-application to configure the PH7 engine.
|
||
* These constants must be passed as the second argument to the [ph7_config()]
|
||
* interface.
|
||
* Each options require a variable number of arguments.
|
||
* The [ph7_config()] interface will return PH7_OK on success, any other
|
||
* return value indicates failure.
|
||
* For a full discussion on the configuration verbs and their expected
|
||
* parameters, please refer to this page:
|
||
* http://ph7.symisc.net/c_api_func.html#ph7_config
|
||
*/
|
||
#define PH7_CONFIG_ERR_OUTPUT 1 /* TWO ARGUMENTS: int (*xConsumer)(const void *pOut,unsigned int nLen,void *pUserData),void *pUserData */
|
||
#define PH7_CONFIG_ERR_ABORT 2 /* RESERVED FOR FUTURE USE */
|
||
#define PH7_CONFIG_ERR_LOG 3 /* TWO ARGUMENTS: const char **pzBuf,int *pLen */
|
||
/*
|
||
* Virtual Machine Configuration Commands.
|
||
*
|
||
* The following set of constants are the available configuration verbs that can
|
||
* be used by the host-application to configure the PH7 Virtual machine.
|
||
* These constants must be passed as the second argument to the [ph7_vm_config()]
|
||
* interface.
|
||
* Each options require a variable number of arguments.
|
||
* The [ph7_vm_config()] interface will return PH7_OK on success, any other return
|
||
* value indicates failure.
|
||
* There are many options but the most importants are: PH7_VM_CONFIG_OUTPUT which install
|
||
* a VM output consumer callback, PH7_VM_CONFIG_HTTP_REQUEST which parse and register
|
||
* a HTTP request and PH7_VM_CONFIG_ARGV_ENTRY which populate the $argv array.
|
||
* For a full discussion on the configuration verbs and their expected parameters, please
|
||
* refer to this page:
|
||
* http://ph7.symisc.net/c_api_func.html#ph7_vm_config
|
||
*/
|
||
#define PH7_VM_CONFIG_OUTPUT 1 /* TWO ARGUMENTS: int (*xConsumer)(const void *pOut,unsigned int nLen,void *pUserData),void *pUserData */
|
||
#define PH7_VM_CONFIG_IMPORT_PATH 3 /* ONE ARGUMENT: const char *zIncludePath */
|
||
#define PH7_VM_CONFIG_ERR_REPORT 4 /* NO ARGUMENTS: Report all run-time errors in the VM output */
|
||
#define PH7_VM_CONFIG_RECURSION_DEPTH 5 /* ONE ARGUMENT: int nMaxDepth */
|
||
#define PH7_VM_OUTPUT_LENGTH 6 /* ONE ARGUMENT: unsigned int *pLength */
|
||
#define PH7_VM_CONFIG_CREATE_SUPER 7 /* TWO ARGUMENTS: const char *zName,ph7_value *pValue */
|
||
#define PH7_VM_CONFIG_CREATE_VAR 8 /* TWO ARGUMENTS: const char *zName,ph7_value *pValue */
|
||
#define PH7_VM_CONFIG_HTTP_REQUEST 9 /* TWO ARGUMENTS: const char *zRawRequest,int nRequestLength */
|
||
#define PH7_VM_CONFIG_SERVER_ATTR 10 /* THREE ARGUMENTS: const char *zKey,const char *zValue,int nLen */
|
||
#define PH7_VM_CONFIG_ENV_ATTR 11 /* THREE ARGUMENTS: const char *zKey,const char *zValue,int nLen */
|
||
#define PH7_VM_CONFIG_SESSION_ATTR 12 /* THREE ARGUMENTS: const char *zKey,const char *zValue,int nLen */
|
||
#define PH7_VM_CONFIG_POST_ATTR 13 /* THREE ARGUMENTS: const char *zKey,const char *zValue,int nLen */
|
||
#define PH7_VM_CONFIG_GET_ATTR 14 /* THREE ARGUMENTS: const char *zKey,const char *zValue,int nLen */
|
||
#define PH7_VM_CONFIG_COOKIE_ATTR 15 /* THREE ARGUMENTS: const char *zKey,const char *zValue,int nLen */
|
||
#define PH7_VM_CONFIG_HEADER_ATTR 16 /* THREE ARGUMENTS: const char *zKey,const char *zValue,int nLen */
|
||
#define PH7_VM_CONFIG_EXEC_VALUE 17 /* ONE ARGUMENT: ph7_value **ppValue */
|
||
#define PH7_VM_CONFIG_IO_STREAM 18 /* ONE ARGUMENT: const ph7_io_stream *pStream */
|
||
#define PH7_VM_CONFIG_ARGV_ENTRY 19 /* ONE ARGUMENT: const char *zValue */
|
||
#define PH7_VM_CONFIG_EXTRACT_OUTPUT 20 /* TWO ARGUMENTS: const void **ppOut,unsigned int *pOutputLen */
|
||
#define PH7_VM_CONFIG_ERR_LOG_HANDLER 21 /* ONE ARGUMENT: void (*xErrLog)(const char *,int,const char *,const char *) */
|
||
/*
|
||
* Global Library Configuration Commands.
|
||
*
|
||
* The following set of constants are the available configuration verbs that can
|
||
* be used by the host-application to configure the whole library.
|
||
* These constants must be passed as the first argument to the [ph7_lib_config()]
|
||
* interface.
|
||
* Each options require a variable number of arguments.
|
||
* The [ph7_lib_config()] interface will return PH7_OK on success, any other return
|
||
* value indicates failure.
|
||
* Notes:
|
||
* The default configuration is recommended for most applications and so the call to
|
||
* [ph7_lib_config()] is usually not necessary. It is provided to support rare
|
||
* applications with unusual needs.
|
||
* The [ph7_lib_config()] interface is not threadsafe. The application must insure that
|
||
* no other [ph7_*()] interfaces are invoked by other threads while [ph7_lib_config()]
|
||
* is running. Furthermore, [ph7_lib_config()] may only be invoked prior to library
|
||
* initialization using [ph7_lib_init()] or [ph7_init()] or after shutdown
|
||
* by [ph7_lib_shutdown()]. If [ph7_lib_config()] is called after [ph7_lib_init()]
|
||
* or [ph7_init()] and before [ph7_lib_shutdown()] then it will return PH7_LOCKED.
|
||
* Refer to the official documentation for more information on the configuration verbs
|
||
* and their expected parameters.
|
||
* For a full discussion on the configuration verbs and their expected parameters,please
|
||
* refer to this page:
|
||
* http://ph7.symisc.net/c_api_func.html#Global_Library_Management_Interfaces
|
||
*/
|
||
#define PH7_LIB_CONFIG_USER_MALLOC 1 /* ONE ARGUMENT: const SyMemMethods *pMemMethods */
|
||
#define PH7_LIB_CONFIG_MEM_ERR_CALLBACK 2 /* TWO ARGUMENTS: int (*xMemError)(void *),void *pUserData */
|
||
#define PH7_LIB_CONFIG_USER_MUTEX 3 /* ONE ARGUMENT: const SyMutexMethods *pMutexMethods */
|
||
#define PH7_LIB_CONFIG_THREAD_LEVEL_SINGLE 4 /* NO ARGUMENTS */
|
||
#define PH7_LIB_CONFIG_THREAD_LEVEL_MULTI 5 /* NO ARGUMENTS */
|
||
#define PH7_LIB_CONFIG_VFS 6 /* ONE ARGUMENT: const ph7_vfs *pVfs */
|
||
/*
|
||
* Compile-time flags.
|
||
* The new compile interfaces [ph7_compile_v2()] and [ph7_compile_file()] takes
|
||
* as their last argument zero or more combination of compile time flags.
|
||
* These flags are used to control the behavior of the PH7 compiler while
|
||
* processing the input.
|
||
* Refer to the official documentation for additional information.
|
||
*/
|
||
#define PH7_PHP_ONLY 0x01 /* If this flag is set then the code to compile is assumed
|
||
* to be plain PHP only. That is, there is no need to delimit
|
||
* the PHP code using the standard tags such as <?php ?> or <? ?>.
|
||
* Everything will pass through the PH7 compiler.
|
||
*/
|
||
#define PH7_PHP_EXPR 0x02 /* This flag is reserved for future use. */
|
||
/*
|
||
* Call Context Error Message Serverity Level.
|
||
*
|
||
* The following constans are the allowed severity level that can
|
||
* passed as the second argument to the [ph7_context_throw_error()] or
|
||
* [ph7_context_throw_error_format()] interfaces.
|
||
* Refer to the official documentation for additional information.
|
||
*/
|
||
#define PH7_CTX_ERR 1 /* Call context error such as unexpected number of arguments,invalid types and so on. */
|
||
#define PH7_CTX_WARNING 2 /* Call context Warning */
|
||
#define PH7_CTX_NOTICE 3 /* Call context Notice */
|
||
/* Current VFS structure version*/
|
||
#define PH7_VFS_VERSION 2
|
||
/*
|
||
* PH7 Virtual File System (VFS).
|
||
*
|
||
* An instance of the ph7_vfs object defines the interface between the PH7 core
|
||
* and the underlying operating system. The "vfs" in the name of the object stands
|
||
* for "virtual file system". The vfs is used to implement PHP system functions
|
||
* such as mkdir(), chdir(), stat(), get_user_name() and many more.
|
||
* The value of the iVersion field is initially 2 but may be larger in future versions
|
||
* of PH7.
|
||
* Additional fields may be appended to this object when the iVersion value is increased.
|
||
* Only a single vfs can be registered within the PH7 core. Vfs registration is done
|
||
* using the ph7_lib_config() interface with a configuration verb set to PH7_LIB_CONFIG_VFS.
|
||
* Note that Windows and UNIX (Linux, FreeBSD, Solaris, Mac OS X, etc.) users does not have to
|
||
* worry about registering and installing a vfs since PH7 come with a built-in vfs for these
|
||
* platforms which implement most the methods defined below.
|
||
* Host-application running on exotic systems (ie: Other than Windows and UNIX systems) must
|
||
* register their own vfs in order to be able to use and call PHP system function.
|
||
* Also note that the ph7_compile_file() interface depend on the xMmap() method of the underlying
|
||
* vfs which mean that this method must be available (Always the case using the built-in VFS)
|
||
* in order to use this interface.
|
||
* Developers wishing to implement the vfs methods can contact symisc systems to obtain
|
||
* the PH7 VFS C/C++ Specification manual.
|
||
*/
|
||
struct ph7_vfs
|
||
{
|
||
const char *zName; /* Underlying VFS name [i.e: FreeBSD/Linux/Windows...] */
|
||
int iVersion; /* Current VFS structure version [default 2] */
|
||
/* Directory functions */
|
||
int (*xChdir)(const char *); /* Change directory */
|
||
int (*xChroot)(const char *); /* Change the root directory */
|
||
int (*xGetcwd)(ph7_context *); /* Get the current working directory */
|
||
int (*xMkdir)(const char *,int,int); /* Make directory */
|
||
int (*xRmdir)(const char *); /* Remove directory */
|
||
int (*xIsdir)(const char *); /* Tells whether the filename is a directory */
|
||
int (*xRename)(const char *,const char *); /* Renames a file or directory */
|
||
int (*xRealpath)(const char *,ph7_context *); /* Return canonicalized absolute pathname*/
|
||
/* Systems functions */
|
||
int (*xSleep)(unsigned int); /* Delay execution in microseconds */
|
||
int (*xUnlink)(const char *); /* Deletes a file */
|
||
int (*xFileExists)(const char *); /* Checks whether a file or directory exists */
|
||
int (*xChmod)(const char *,int); /* Changes file mode */
|
||
int (*xChown)(const char *,const char *); /* Changes file owner */
|
||
int (*xChgrp)(const char *,const char *); /* Changes file group */
|
||
ph7_int64 (*xFreeSpace)(const char *); /* Available space on filesystem or disk partition */
|
||
ph7_int64 (*xTotalSpace)(const char *); /* Total space on filesystem or disk partition */
|
||
ph7_int64 (*xFileSize)(const char *); /* Gets file size */
|
||
ph7_int64 (*xFileAtime)(const char *); /* Gets last access time of file */
|
||
ph7_int64 (*xFileMtime)(const char *); /* Gets file modification time */
|
||
ph7_int64 (*xFileCtime)(const char *); /* Gets inode change time of file */
|
||
int (*xStat)(const char *,ph7_value *,ph7_value *); /* Gives information about a file */
|
||
int (*xlStat)(const char *,ph7_value *,ph7_value *); /* Gives information about a file */
|
||
int (*xIsfile)(const char *); /* Tells whether the filename is a regular file */
|
||
int (*xIslink)(const char *); /* Tells whether the filename is a symbolic link */
|
||
int (*xReadable)(const char *); /* Tells whether a file exists and is readable */
|
||
int (*xWritable)(const char *); /* Tells whether the filename is writable */
|
||
int (*xExecutable)(const char *); /* Tells whether the filename is executable */
|
||
int (*xFiletype)(const char *,ph7_context *); /* Gets file type [i.e: fifo,dir,file..] */
|
||
int (*xGetenv)(const char *,ph7_context *); /* Gets the value of an environment variable */
|
||
int (*xSetenv)(const char *,const char *); /* Sets the value of an environment variable */
|
||
int (*xTouch)(const char *,ph7_int64,ph7_int64); /* Sets access and modification time of file */
|
||
int (*xMmap)(const char *,void **,ph7_int64 *); /* Read-only memory map of the whole file */
|
||
void (*xUnmap)(void *,ph7_int64); /* Unmap a memory view */
|
||
int (*xLink)(const char *,const char *,int); /* Create hard or symbolic link */
|
||
int (*xUmask)(int); /* Change the current umask */
|
||
void (*xTempDir)(ph7_context *); /* Get path of the temporary directory */
|
||
unsigned int (*xProcessId)(void); /* Get running process ID */
|
||
int (*xUid)(void); /* user ID of the process */
|
||
int (*xGid)(void); /* group ID of the process */
|
||
void (*xUsername)(ph7_context *); /* Running username */
|
||
int (*xExec)(const char *,ph7_context *); /* Execute an external program */
|
||
};
|
||
/* Current PH7 IO stream structure version. */
|
||
#define PH7_IO_STREAM_VERSION 1
|
||
/*
|
||
* Possible open mode flags that can be passed to the xOpen() routine
|
||
* of the underlying IO stream device .
|
||
* Refer to the PH7 IO Stream C/C++ specification manual (http://ph7.symisc.net/io_stream_spec.html)
|
||
* for additional information.
|
||
*/
|
||
#define PH7_IO_OPEN_RDONLY 0x001 /* Read-only open */
|
||
#define PH7_IO_OPEN_WRONLY 0x002 /* Write-only open */
|
||
#define PH7_IO_OPEN_RDWR 0x004 /* Read-write open. */
|
||
#define PH7_IO_OPEN_CREATE 0x008 /* If the file does not exist it will be created */
|
||
#define PH7_IO_OPEN_TRUNC 0x010 /* Truncate the file to zero length */
|
||
#define PH7_IO_OPEN_APPEND 0x020 /* Append mode.The file offset is positioned at the end of the file */
|
||
#define PH7_IO_OPEN_EXCL 0x040 /* Ensure that this call creates the file,the file must not exist before */
|
||
#define PH7_IO_OPEN_BINARY 0x080 /* Simple hint: Data is binary */
|
||
#define PH7_IO_OPEN_TEMP 0x100 /* Simple hint: Temporary file */
|
||
#define PH7_IO_OPEN_TEXT 0x200 /* Simple hint: Data is textual */
|
||
/*
|
||
* PH7 IO Stream Device.
|
||
*
|
||
* An instance of the ph7_io_stream object defines the interface between the PH7 core
|
||
* and the underlying stream device.
|
||
* A stream is a smart mechanism for generalizing file, network, data compression
|
||
* and other IO operations which share a common set of functions using an abstracted
|
||
* unified interface.
|
||
* A stream device is additional code which tells the stream how to handle specific
|
||
* protocols/encodings. For example, the http device knows how to translate a URL
|
||
* into an HTTP/1.1 request for a file on a remote server.
|
||
* PH7 come with two built-in IO streams device:
|
||
* The file:// stream which perform very efficient disk IO and the php:// stream
|
||
* which is a special stream that allow access various I/O streams (See the PHP official
|
||
* documentation for more information on this stream).
|
||
* A stream is referenced as: scheme://target
|
||
* scheme(string) - The name of the wrapper to be used. Examples include: file,http,https,ftp,
|
||
* ftps, compress.zlib, compress.bz2, and php. If no wrapper is specified,the function default
|
||
* is used (typically file://).
|
||
* target - Depends on the device used. For filesystem related streams this is typically a path
|
||
* and filename of the desired file.For network related streams this is typically a hostname,often
|
||
* with a path appended.
|
||
* IO stream devices are registered using a call to ph7_vm_config() with a configuration verb
|
||
* set to PH7_VM_CONFIG_IO_STREAM.
|
||
* Currently the PH7 development team is working on the implementation of the http:// and ftp://
|
||
* IO stream protocols. These devices will be available in the next major release of the PH7 engine.
|
||
* Developers wishing to implement their own IO stream devices must understand and follow
|
||
* The PH7 IO Stream C/C++ specification manual (http://ph7.symisc.net/io_stream_spec.html).
|
||
*/
|
||
struct ph7_io_stream
|
||
{
|
||
const char *zName; /* Underlying stream name [i.e: file/http/zip/php,..] */
|
||
int iVersion; /* IO stream structure version [default 1]*/
|
||
int (*xOpen)(const char *,int,ph7_value *,void **); /* Open handle*/
|
||
int (*xOpenDir)(const char *,ph7_value *,void **); /* Open directory handle */
|
||
void (*xClose)(void *); /* Close file handle */
|
||
void (*xCloseDir)(void *); /* Close directory handle */
|
||
ph7_int64 (*xRead)(void *,void *,ph7_int64); /* Read from the open stream */
|
||
int (*xReadDir)(void *,ph7_context *); /* Read entry from directory handle */
|
||
ph7_int64 (*xWrite)(void *,const void *,ph7_int64); /* Write to the open stream */
|
||
int (*xSeek)(void *,ph7_int64,int); /* Seek on the open stream */
|
||
int (*xLock)(void *,int); /* Lock/Unlock the open stream */
|
||
void (*xRewindDir)(void *); /* Rewind directory handle */
|
||
ph7_int64 (*xTell)(void *); /* Current position of the stream read/write pointer */
|
||
int (*xTrunc)(void *,ph7_int64); /* Truncates the open stream to a given length */
|
||
int (*xSync)(void *); /* Flush open stream data */
|
||
int (*xStat)(void *,ph7_value *,ph7_value *); /* Stat an open stream handle */
|
||
};
|
||
/*
|
||
* C-API-REF: Please refer to the official documentation for interfaces
|
||
* purpose and expected parameters.
|
||
*/
|
||
/* Engine Handling Interfaces */
|
||
PH7_APIEXPORT int ph7_init(ph7 **ppEngine);
|
||
PH7_APIEXPORT int ph7_config(ph7 *pEngine,int nConfigOp,...);
|
||
PH7_APIEXPORT int ph7_release(ph7 *pEngine);
|
||
/* Compile Interfaces */
|
||
PH7_APIEXPORT int ph7_compile(ph7 *pEngine,const char *zSource,int nLen,ph7_vm **ppOutVm);
|
||
PH7_APIEXPORT int ph7_compile_v2(ph7 *pEngine,const char *zSource,int nLen,ph7_vm **ppOutVm,int iFlags);
|
||
PH7_APIEXPORT int ph7_compile_file(ph7 *pEngine,const char *zFilePath,ph7_vm **ppOutVm,int iFlags);
|
||
/* Virtual Machine Handling Interfaces */
|
||
PH7_APIEXPORT int ph7_vm_config(ph7_vm *pVm,int iConfigOp,...);
|
||
PH7_APIEXPORT int ph7_vm_exec(ph7_vm *pVm,int *pExitStatus);
|
||
PH7_APIEXPORT int ph7_vm_reset(ph7_vm *pVm);
|
||
PH7_APIEXPORT int ph7_vm_release(ph7_vm *pVm);
|
||
PH7_APIEXPORT int ph7_vm_dump_v2(ph7_vm *pVm,int (*xConsumer)(const void *,unsigned int,void *),void *pUserData);
|
||
/* In-process Extending Interfaces */
|
||
PH7_APIEXPORT int ph7_create_function(ph7_vm *pVm,const char *zName,int (*xFunc)(ph7_context *,int,ph7_value **),void *pUserData);
|
||
PH7_APIEXPORT int ph7_delete_function(ph7_vm *pVm,const char *zName);
|
||
PH7_APIEXPORT int ph7_create_constant(ph7_vm *pVm,const char *zName,void (*xExpand)(ph7_value *,void *),void *pUserData);
|
||
PH7_APIEXPORT int ph7_delete_constant(ph7_vm *pVm,const char *zName);
|
||
/* Foreign Function Parameter Values */
|
||
PH7_APIEXPORT int ph7_value_to_int(ph7_value *pValue);
|
||
PH7_APIEXPORT int ph7_value_to_bool(ph7_value *pValue);
|
||
PH7_APIEXPORT ph7_int64 ph7_value_to_int64(ph7_value *pValue);
|
||
PH7_APIEXPORT double ph7_value_to_double(ph7_value *pValue);
|
||
PH7_APIEXPORT const char * ph7_value_to_string(ph7_value *pValue,int *pLen);
|
||
PH7_APIEXPORT void * ph7_value_to_resource(ph7_value *pValue);
|
||
PH7_APIEXPORT int ph7_value_compare(ph7_value *pLeft,ph7_value *pRight,int bStrict);
|
||
/* Setting The Result Of A Foreign Function */
|
||
PH7_APIEXPORT int ph7_result_int(ph7_context *pCtx,int iValue);
|
||
PH7_APIEXPORT int ph7_result_int64(ph7_context *pCtx,ph7_int64 iValue);
|
||
PH7_APIEXPORT int ph7_result_bool(ph7_context *pCtx,int iBool);
|
||
PH7_APIEXPORT int ph7_result_double(ph7_context *pCtx,double Value);
|
||
PH7_APIEXPORT int ph7_result_null(ph7_context *pCtx);
|
||
PH7_APIEXPORT int ph7_result_string(ph7_context *pCtx,const char *zString,int nLen);
|
||
PH7_APIEXPORT int ph7_result_string_format(ph7_context *pCtx,const char *zFormat,...);
|
||
PH7_APIEXPORT int ph7_result_value(ph7_context *pCtx,ph7_value *pValue);
|
||
PH7_APIEXPORT int ph7_result_resource(ph7_context *pCtx,void *pUserData);
|
||
/* Call Context Handling Interfaces */
|
||
PH7_APIEXPORT int ph7_context_output(ph7_context *pCtx,const char *zString,int nLen);
|
||
PH7_APIEXPORT int ph7_context_output_format(ph7_context *pCtx,const char *zFormat,...);
|
||
PH7_APIEXPORT int ph7_context_throw_error(ph7_context *pCtx,int iErr,const char *zErr);
|
||
PH7_APIEXPORT int ph7_context_throw_error_format(ph7_context *pCtx,int iErr,const char *zFormat,...);
|
||
PH7_APIEXPORT unsigned int ph7_context_random_num(ph7_context *pCtx);
|
||
PH7_APIEXPORT int ph7_context_random_string(ph7_context *pCtx,char *zBuf,int nBuflen);
|
||
PH7_APIEXPORT void * ph7_context_user_data(ph7_context *pCtx);
|
||
PH7_APIEXPORT int ph7_context_push_aux_data(ph7_context *pCtx,void *pUserData);
|
||
PH7_APIEXPORT void * ph7_context_peek_aux_data(ph7_context *pCtx);
|
||
PH7_APIEXPORT void * ph7_context_pop_aux_data(ph7_context *pCtx);
|
||
PH7_APIEXPORT unsigned int ph7_context_result_buf_length(ph7_context *pCtx);
|
||
PH7_APIEXPORT const char * ph7_function_name(ph7_context *pCtx);
|
||
/* Call Context Memory Management Interfaces */
|
||
PH7_APIEXPORT void * ph7_context_alloc_chunk(ph7_context *pCtx,unsigned int nByte,int ZeroChunk,int AutoRelease);
|
||
PH7_APIEXPORT void * ph7_context_realloc_chunk(ph7_context *pCtx,void *pChunk,unsigned int nByte);
|
||
PH7_APIEXPORT void ph7_context_free_chunk(ph7_context *pCtx,void *pChunk);
|
||
/* On Demand Dynamically Typed Value Object allocation interfaces */
|
||
PH7_APIEXPORT ph7_value * ph7_new_scalar(ph7_vm *pVm);
|
||
PH7_APIEXPORT ph7_value * ph7_new_array(ph7_vm *pVm);
|
||
PH7_APIEXPORT int ph7_release_value(ph7_vm *pVm,ph7_value *pValue);
|
||
PH7_APIEXPORT ph7_value * ph7_context_new_scalar(ph7_context *pCtx);
|
||
PH7_APIEXPORT ph7_value * ph7_context_new_array(ph7_context *pCtx);
|
||
PH7_APIEXPORT void ph7_context_release_value(ph7_context *pCtx,ph7_value *pValue);
|
||
/* Dynamically Typed Value Object Management Interfaces */
|
||
PH7_APIEXPORT int ph7_value_int(ph7_value *pVal,int iValue);
|
||
PH7_APIEXPORT int ph7_value_int64(ph7_value *pVal,ph7_int64 iValue);
|
||
PH7_APIEXPORT int ph7_value_bool(ph7_value *pVal,int iBool);
|
||
PH7_APIEXPORT int ph7_value_null(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_double(ph7_value *pVal,double Value);
|
||
PH7_APIEXPORT int ph7_value_string(ph7_value *pVal,const char *zString,int nLen);
|
||
PH7_APIEXPORT int ph7_value_string_format(ph7_value *pVal,const char *zFormat,...);
|
||
PH7_APIEXPORT int ph7_value_reset_string_cursor(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_resource(ph7_value *pVal,void *pUserData);
|
||
PH7_APIEXPORT int ph7_value_release(ph7_value *pVal);
|
||
PH7_APIEXPORT ph7_value * ph7_array_fetch(ph7_value *pArray,const char *zKey,int nByte);
|
||
PH7_APIEXPORT int ph7_array_walk(ph7_value *pArray,int (*xWalk)(ph7_value *,ph7_value *,void *),void *pUserData);
|
||
PH7_APIEXPORT int ph7_array_add_elem(ph7_value *pArray,ph7_value *pKey,ph7_value *pValue);
|
||
PH7_APIEXPORT int ph7_array_add_strkey_elem(ph7_value *pArray,const char *zKey,ph7_value *pValue);
|
||
PH7_APIEXPORT int ph7_array_add_intkey_elem(ph7_value *pArray,int iKey,ph7_value *pValue);
|
||
PH7_APIEXPORT unsigned int ph7_array_count(ph7_value *pArray);
|
||
PH7_APIEXPORT int ph7_object_walk(ph7_value *pObject,int (*xWalk)(const char *,ph7_value *,void *),void *pUserData);
|
||
PH7_APIEXPORT ph7_value * ph7_object_fetch_attr(ph7_value *pObject,const char *zAttr);
|
||
PH7_APIEXPORT const char * ph7_object_get_class_name(ph7_value *pObject,int *pLength);
|
||
PH7_APIEXPORT int ph7_value_is_int(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_float(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_bool(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_string(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_null(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_numeric(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_callable(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_scalar(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_array(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_object(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_resource(ph7_value *pVal);
|
||
PH7_APIEXPORT int ph7_value_is_empty(ph7_value *pVal);
|
||
/* Global Library Management Interfaces */
|
||
PH7_APIEXPORT int ph7_lib_init(void);
|
||
PH7_APIEXPORT int ph7_lib_config(int nConfigOp,...);
|
||
PH7_APIEXPORT int ph7_lib_shutdown(void);
|
||
PH7_APIEXPORT int ph7_lib_is_threadsafe(void);
|
||
PH7_APIEXPORT const char * ph7_lib_version(void);
|
||
PH7_APIEXPORT const char * ph7_lib_signature(void);
|
||
PH7_APIEXPORT const char * ph7_lib_ident(void);
|
||
PH7_APIEXPORT const char * ph7_lib_copyright(void);
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif /* __cplusplus */
|
||
#endif /* _PH7_H_ */
|
||
|
||
/*
|
||
* ----------------------------------------------------------
|
||
* File: ph7int.h
|
||
* MD5: cdd8bb8c737e7e3ae5b14e01a01b98dd
|
||
* ----------------------------------------------------------
|
||
*/
|
||
/*
|
||
* Symisc PH7: An embeddable bytecode compiler and a virtual machine for the PHP(5) programming language.
|
||
* Copyright (C) 2011-2012, Symisc Systems http://ph7.symisc.net/
|
||
* Version 2.1.4
|
||
* For information on licensing,redistribution of this file,and for a DISCLAIMER OF ALL WARRANTIES
|
||
* please contact Symisc Systems via:
|
||
* legal@symisc.net
|
||
* licensing@symisc.net
|
||
* contact@symisc.net
|
||
* or visit:
|
||
* http://ph7.symisc.net/
|
||
*/
|
||
/* $SymiscID: ph7int.h v1.9 FreeBSD 2012-08-13 26:25 devel <chm@symisc.net> $ */
|
||
#ifndef __PH7INT_H__
|
||
#define __PH7INT_H__
|
||
/* Internal interface definitions for PH7. */
|
||
#ifdef PH7_AMALGAMATION
|
||
/* Marker for routines not intended for external use */
|
||
#define PH7_PRIVATE static
|
||
#else
|
||
#define PH7_PRIVATE
|
||
#include "ph7.h"
|
||
#endif
|
||
#ifndef PH7_PI
|
||
/* Value of PI */
|
||
#define PH7_PI 3.1415926535898
|
||
#endif
|
||
/*
|
||
* Constants for the largest and smallest possible 64-bit signed integers.
|
||
* These macros are designed to work correctly on both 32-bit and 64-bit
|
||
* compilers.
|
||
*/
|
||
#ifndef LARGEST_INT64
|
||
#define LARGEST_INT64 (0xffffffff|(((sxi64)0x7fffffff)<<32))
|
||
#endif
|
||
#ifndef SMALLEST_INT64
|
||
#define SMALLEST_INT64 (((sxi64)-1) - LARGEST_INT64)
|
||
#endif
|
||
/* Forward declaration of private structures */
|
||
typedef struct ph7_class_instance ph7_class_instance;
|
||
typedef struct ph7_foreach_info ph7_foreach_info;
|
||
typedef struct ph7_foreach_step ph7_foreach_step;
|
||
typedef struct ph7_hashmap_node ph7_hashmap_node;
|
||
typedef struct ph7_hashmap ph7_hashmap;
|
||
typedef struct ph7_class ph7_class;
|
||
/* Symisc Standard types */
|
||
#if !defined(SYMISC_STD_TYPES)
|
||
#define SYMISC_STD_TYPES
|
||
#ifdef __WINNT__
|
||
/* Disable nuisance warnings on Borland compilers */
|
||
#if defined(__BORLANDC__)
|
||
#pragma warn -rch /* unreachable code */
|
||
#pragma warn -ccc /* Condition is always true or false */
|
||
#pragma warn -aus /* Assigned value is never used */
|
||
#pragma warn -csu /* Comparing signed and unsigned */
|
||
#pragma warn -spa /* Suspicious pointer arithmetic */
|
||
#endif
|
||
#endif
|
||
typedef signed char sxi8; /* signed char */
|
||
typedef unsigned char sxu8; /* unsigned char */
|
||
typedef signed short int sxi16; /* 16 bits(2 bytes) signed integer */
|
||
typedef unsigned short int sxu16; /* 16 bits(2 bytes) unsigned integer */
|
||
typedef int sxi32; /* 32 bits(4 bytes) integer */
|
||
typedef unsigned int sxu32; /* 32 bits(4 bytes) unsigned integer */
|
||
typedef long sxptr;
|
||
typedef unsigned long sxuptr;
|
||
typedef long sxlong;
|
||
typedef unsigned long sxulong;
|
||
typedef sxi32 sxofft;
|
||
typedef sxi64 sxofft64;
|
||
typedef long double sxlongreal;
|
||
typedef double sxreal;
|
||
#define SXI8_HIGH 0x7F
|
||
#define SXU8_HIGH 0xFF
|
||
#define SXI16_HIGH 0x7FFF
|
||
#define SXU16_HIGH 0xFFFF
|
||
#define SXI32_HIGH 0x7FFFFFFF
|
||
#define SXU32_HIGH 0xFFFFFFFF
|
||
#define SXI64_HIGH 0x7FFFFFFFFFFFFFFF
|
||
#define SXU64_HIGH 0xFFFFFFFFFFFFFFFF
|
||
#if !defined(TRUE)
|
||
#define TRUE 1
|
||
#endif
|
||
#if !defined(FALSE)
|
||
#define FALSE 0
|
||
#endif
|
||
/*
|
||
* The following macros are used to cast pointers to integers and
|
||
* integers to pointers.
|
||
*/
|
||
#if defined(__PTRDIFF_TYPE__)
|
||
# define SX_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
|
||
# define SX_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
|
||
#elif !defined(__GNUC__)
|
||
# define SX_INT_TO_PTR(X) ((void*)&((char*)0)[X])
|
||
# define SX_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
|
||
#else
|
||
# define SX_INT_TO_PTR(X) ((void*)(X))
|
||
# define SX_PTR_TO_INT(X) ((int)(X))
|
||
#endif
|
||
#define SXMIN(a,b) ((a < b) ? (a) : (b))
|
||
#define SXMAX(a,b) ((a < b) ? (b) : (a))
|
||
#endif /* SYMISC_STD_TYPES */
|
||
/* Symisc Run-time API private definitions */
|
||
#if !defined(SYMISC_PRIVATE_DEFS)
|
||
#define SYMISC_PRIVATE_DEFS
|
||
|
||
typedef sxi32 (*ProcRawStrCmp)(const SyString *,const SyString *);
|
||
#define SyStringData(RAW) ((RAW)->zString)
|
||
#define SyStringLength(RAW) ((RAW)->nByte)
|
||
#define SyStringInitFromBuf(RAW,ZBUF,NLEN){\
|
||
(RAW)->zString = (const char *)ZBUF;\
|
||
(RAW)->nByte = (sxu32)(NLEN);\
|
||
}
|
||
#define SyStringUpdatePtr(RAW,NBYTES){\
|
||
if( NBYTES > (RAW)->nByte ){\
|
||
(RAW)->nByte = 0;\
|
||
}else{\
|
||
(RAW)->zString += NBYTES;\
|
||
(RAW)->nByte -= NBYTES;\
|
||
}\
|
||
}
|
||
#define SyStringDupPtr(RAW1,RAW2)\
|
||
(RAW1)->zString = (RAW2)->zString;\
|
||
(RAW1)->nByte = (RAW2)->nByte;
|
||
|
||
#define SyStringTrimLeadingChar(RAW,CHAR)\
|
||
while((RAW)->nByte > 0 && (RAW)->zString[0] == CHAR ){\
|
||
(RAW)->zString++;\
|
||
(RAW)->nByte--;\
|
||
}
|
||
#define SyStringTrimTrailingChar(RAW,CHAR)\
|
||
while((RAW)->nByte > 0 && (RAW)->zString[(RAW)->nByte - 1] == CHAR){\
|
||
(RAW)->nByte--;\
|
||
}
|
||
#define SyStringCmp(RAW1,RAW2,xCMP)\
|
||
(((RAW1)->nByte == (RAW2)->nByte) ? xCMP((RAW1)->zString,(RAW2)->zString,(RAW2)->nByte) : (sxi32)((RAW1)->nByte - (RAW2)->nByte))
|
||
|
||
#define SyStringCmp2(RAW1,RAW2,xCMP)\
|
||
(((RAW1)->nByte >= (RAW2)->nByte) ? xCMP((RAW1)->zString,(RAW2)->zString,(RAW2)->nByte) : (sxi32)((RAW2)->nByte - (RAW1)->nByte))
|
||
|
||
#define SyStringCharCmp(RAW,CHAR) \
|
||
(((RAW)->nByte == sizeof(char)) ? ((RAW)->zString[0] == CHAR ? 0 : CHAR - (RAW)->zString[0]) : ((RAW)->zString[0] == CHAR ? 0 : (RAW)->nByte - sizeof(char)))
|
||
|
||
#define SX_ADDR(PTR) ((sxptr)PTR)
|
||
#define SX_ARRAYSIZE(X) (sizeof(X)/sizeof(X[0]))
|
||
#define SXUNUSED(P) (P = 0)
|
||
#define SX_EMPTY(PTR) (PTR == 0)
|
||
#define SX_EMPTY_STR(STR) (STR == 0 || STR[0] == 0 )
|
||
typedef struct SyMemBackend SyMemBackend;
|
||
typedef struct SyBlob SyBlob;
|
||
typedef struct SySet SySet;
|
||
/* Standard function signatures */
|
||
typedef sxi32 (*ProcCmp)(const void *,const void *,sxu32);
|
||
typedef sxi32 (*ProcPatternMatch)(const char *,sxu32,const char *,sxu32,sxu32 *);
|
||
typedef sxi32 (*ProcSearch)(const void *,sxu32,const void *,sxu32,ProcCmp,sxu32 *);
|
||
typedef sxu32 (*ProcHash)(const void *,sxu32);
|
||
typedef sxi32 (*ProcHashSum)(const void *,sxu32,unsigned char *,sxu32);
|
||
typedef sxi32 (*ProcSort)(void *,sxu32,sxu32,ProcCmp);
|
||
#define MACRO_LIST_PUSH(Head,Item)\
|
||
Item->pNext = Head;\
|
||
Head = Item;
|
||
#define MACRO_LD_PUSH(Head,Item)\
|
||
if( Head == 0 ){\
|
||
Head = Item;\
|
||
}else{\
|
||
Item->pNext = Head;\
|
||
Head->pPrev = Item;\
|
||
Head = Item;\
|
||
}
|
||
#define MACRO_LD_REMOVE(Head,Item)\
|
||
if( Head == Item ){\
|
||
Head = Head->pNext;\
|
||
}\
|
||
if( Item->pPrev ){ Item->pPrev->pNext = Item->pNext;}\
|
||
if( Item->pNext ){ Item->pNext->pPrev = Item->pPrev;}
|
||
/*
|
||
* A generic dynamic set.
|
||
*/
|
||
struct SySet
|
||
{
|
||
SyMemBackend *pAllocator; /* Memory backend */
|
||
void *pBase; /* Base pointer */
|
||
sxu32 nUsed; /* Total number of used slots */
|
||
sxu32 nSize; /* Total number of available slots */
|
||
sxu32 eSize; /* Size of a single slot */
|
||
sxu32 nCursor; /* Loop cursor */
|
||
void *pUserData; /* User private data associated with this container */
|
||
};
|
||
#define SySetBasePtr(S) ((S)->pBase)
|
||
#define SySetBasePtrJump(S,OFFT) (&((char *)(S)->pBase)[OFFT*(S)->eSize])
|
||
#define SySetUsed(S) ((S)->nUsed)
|
||
#define SySetSize(S) ((S)->nSize)
|
||
#define SySetElemSize(S) ((S)->eSize)
|
||
#define SySetCursor(S) ((S)->nCursor)
|
||
#define SySetGetAllocator(S) ((S)->pAllocator)
|
||
#define SySetSetUserData(S,DATA) ((S)->pUserData = DATA)
|
||
#define SySetGetUserData(S) ((S)->pUserData)
|
||
/*
|
||
* A variable length containers for generic data.
|
||
*/
|
||
struct SyBlob
|
||
{
|
||
SyMemBackend *pAllocator; /* Memory backend */
|
||
void *pBlob; /* Base pointer */
|
||
sxu32 nByte; /* Total number of used bytes */
|
||
sxu32 mByte; /* Total number of available bytes */
|
||
sxu32 nFlags; /* Blob internal flags,see below */
|
||
};
|
||
#define SXBLOB_LOCKED 0x01 /* Blob is locked [i.e: Cannot auto grow] */
|
||
#define SXBLOB_STATIC 0x02 /* Not allocated from heap */
|
||
#define SXBLOB_RDONLY 0x04 /* Read-Only data */
|
||
|
||
#define SyBlobFreeSpace(BLOB) ((BLOB)->mByte - (BLOB)->nByte)
|
||
#define SyBlobLength(BLOB) ((BLOB)->nByte)
|
||
#define SyBlobData(BLOB) ((BLOB)->pBlob)
|
||
#define SyBlobCurData(BLOB) ((void*)(&((char*)(BLOB)->pBlob)[(BLOB)->nByte]))
|
||
#define SyBlobDataAt(BLOB,OFFT) ((void *)(&((char *)(BLOB)->pBlob)[OFFT]))
|
||
#define SyBlobGetAllocator(BLOB) ((BLOB)->pAllocator)
|
||
|
||
#define SXMEM_POOL_INCR 3
|
||
#define SXMEM_POOL_NBUCKETS 12
|
||
#define SXMEM_BACKEND_MAGIC 0xBAC3E67D
|
||
#define SXMEM_BACKEND_CORRUPT(BACKEND) (BACKEND == 0 || BACKEND->nMagic != SXMEM_BACKEND_MAGIC)
|
||
|
||
#define SXMEM_BACKEND_RETRY 3
|
||
/* A memory backend subsystem is defined by an instance of the following structures */
|
||
typedef union SyMemHeader SyMemHeader;
|
||
typedef struct SyMemBlock SyMemBlock;
|
||
struct SyMemBlock
|
||
{
|
||
SyMemBlock *pNext,*pPrev; /* Chain of allocated memory blocks */
|
||
#ifdef UNTRUST
|
||
sxu32 nGuard; /* magic number associated with each valid block,so we
|
||
* can detect misuse.
|
||
*/
|
||
#endif
|
||
};
|
||
/*
|
||
* Header associated with each valid memory pool block.
|
||
*/
|
||
union SyMemHeader
|
||
{
|
||
SyMemHeader *pNext; /* Next chunk of size 1 << (nBucket + SXMEM_POOL_INCR) in the list */
|
||
sxu32 nBucket; /* Bucket index in aPool[] */
|
||
};
|
||
struct SyMemBackend
|
||
{
|
||
const SyMutexMethods *pMutexMethods; /* Mutex methods */
|
||
const SyMemMethods *pMethods; /* Memory allocation methods */
|
||
SyMemBlock *pBlocks; /* List of valid memory blocks */
|
||
sxu32 nBlock; /* Total number of memory blocks allocated so far */
|
||
ProcMemError xMemError; /* Out-of memory callback */
|
||
void *pUserData; /* First arg to xMemError() */
|
||
SyMutex *pMutex; /* Per instance mutex */
|
||
sxu32 nMagic; /* Sanity check against misuse */
|
||
SyMemHeader *apPool[SXMEM_POOL_NBUCKETS+SXMEM_POOL_INCR]; /* Pool of memory chunks */
|
||
};
|
||
/* Mutex types */
|
||
#define SXMUTEX_TYPE_FAST 1
|
||
#define SXMUTEX_TYPE_RECURSIVE 2
|
||
#define SXMUTEX_TYPE_STATIC_1 3
|
||
#define SXMUTEX_TYPE_STATIC_2 4
|
||
#define SXMUTEX_TYPE_STATIC_3 5
|
||
#define SXMUTEX_TYPE_STATIC_4 6
|
||
#define SXMUTEX_TYPE_STATIC_5 7
|
||
#define SXMUTEX_TYPE_STATIC_6 8
|
||
|
||
#define SyMutexGlobalInit(METHOD){\
|
||
if( (METHOD)->xGlobalInit ){\
|
||
(METHOD)->xGlobalInit();\
|
||
}\
|
||
}
|
||
#define SyMutexGlobalRelease(METHOD){\
|
||
if( (METHOD)->xGlobalRelease ){\
|
||
(METHOD)->xGlobalRelease();\
|
||
}\
|
||
}
|
||
#define SyMutexNew(METHOD,TYPE) (METHOD)->xNew(TYPE)
|
||
#define SyMutexRelease(METHOD,MUTEX){\
|
||
if( MUTEX && (METHOD)->xRelease ){\
|
||
(METHOD)->xRelease(MUTEX);\
|
||
}\
|
||
}
|
||
#define SyMutexEnter(METHOD,MUTEX){\
|
||
if( MUTEX ){\
|
||
(METHOD)->xEnter(MUTEX);\
|
||
}\
|
||
}
|
||
#define SyMutexTryEnter(METHOD,MUTEX){\
|
||
if( MUTEX && (METHOD)->xTryEnter ){\
|
||
(METHOD)->xTryEnter(MUTEX);\
|
||
}\
|
||
}
|
||
#define SyMutexLeave(METHOD,MUTEX){\
|
||
if( MUTEX ){\
|
||
(METHOD)->xLeave(MUTEX);\
|
||
}\
|
||
}
|
||
/* Comparison,byte swap,byte copy macros */
|
||
#define SX_MACRO_FAST_CMP(X1,X2,SIZE,RC){\
|
||
register unsigned char *r1 = (unsigned char *)X1;\
|
||
register unsigned char *r2 = (unsigned char *)X2;\
|
||
register sxu32 LEN = SIZE;\
|
||
for(;;){\
|
||
if( !LEN ){ break; }if( r1[0] != r2[0] ){ break; } r1++; r2++; LEN--;\
|
||
if( !LEN ){ break; }if( r1[0] != r2[0] ){ break; } r1++; r2++; LEN--;\
|
||
if( !LEN ){ break; }if( r1[0] != r2[0] ){ break; } r1++; r2++; LEN--;\
|
||
if( !LEN ){ break; }if( r1[0] != r2[0] ){ break; } r1++; r2++; LEN--;\
|
||
}\
|
||
RC = !LEN ? 0 : r1[0] - r2[0];\
|
||
}
|
||
#define SX_MACRO_FAST_MEMCPY(SRC,DST,SIZ){\
|
||
register unsigned char *xSrc = (unsigned char *)SRC;\
|
||
register unsigned char *xDst = (unsigned char *)DST;\
|
||
register sxu32 xLen = SIZ;\
|
||
for(;;){\
|
||
if( !xLen ){ break; }xDst[0] = xSrc[0]; xDst++; xSrc++; --xLen;\
|
||
if( !xLen ){ break; }xDst[0] = xSrc[0]; xDst++; xSrc++; --xLen;\
|
||
if( !xLen ){ break; }xDst[0] = xSrc[0]; xDst++; xSrc++; --xLen;\
|
||
if( !xLen ){ break; }xDst[0] = xSrc[0]; xDst++; xSrc++; --xLen;\
|
||
}\
|
||
}
|
||
#define SX_MACRO_BYTE_SWAP(X,Y,Z){\
|
||
register unsigned char *s = (unsigned char *)X;\
|
||
register unsigned char *d = (unsigned char *)Y;\
|
||
sxu32 ZLong = Z; \
|
||
sxi32 c; \
|
||
for(;;){\
|
||
if(!ZLong){ break; } c = s[0] ; s[0] = d[0]; d[0] = (unsigned char)c; s++; d++; --ZLong;\
|
||
if(!ZLong){ break; } c = s[0] ; s[0] = d[0]; d[0] = (unsigned char)c; s++; d++; --ZLong;\
|
||
if(!ZLong){ break; } c = s[0] ; s[0] = d[0]; d[0] = (unsigned char)c; s++; d++; --ZLong;\
|
||
if(!ZLong){ break; } c = s[0] ; s[0] = d[0]; d[0] = (unsigned char)c; s++; d++; --ZLong;\
|
||
}\
|
||
}
|
||
#define SX_MSEC_PER_SEC (1000) /* Millisec per seconds */
|
||
#define SX_USEC_PER_SEC (1000000) /* Microsec per seconds */
|
||
#define SX_NSEC_PER_SEC (1000000000) /* Nanosec per seconds */
|
||
#endif /* SYMISC_PRIVATE_DEFS */
|
||
/* Symisc Run-time API auxiliary definitions */
|
||
#if !defined(SYMISC_PRIVATE_AUX_DEFS)
|
||
#define SYMISC_PRIVATE_AUX_DEFS
|
||
|
||
typedef struct SyHashEntry_Pr SyHashEntry_Pr;
|
||
typedef struct SyHashEntry SyHashEntry;
|
||
typedef struct SyHash SyHash;
|
||
/*
|
||
* Each public hashtable entry is represented by an instance
|
||
* of the following structure.
|
||
*/
|
||
struct SyHashEntry
|
||
{
|
||
const void *pKey; /* Hash key */
|
||
sxu32 nKeyLen; /* Key length */
|
||
void *pUserData; /* User private data */
|
||
};
|
||
#define SyHashEntryGetUserData(ENTRY) ((ENTRY)->pUserData)
|
||
#define SyHashEntryGetKey(ENTRY) ((ENTRY)->pKey)
|
||
/* Each active hashtable is identified by an instance of the following structure */
|
||
struct SyHash
|
||
{
|
||
SyMemBackend *pAllocator; /* Memory backend */
|
||
ProcHash xHash; /* Hash function */
|
||
ProcCmp xCmp; /* Comparison function */
|
||
SyHashEntry_Pr *pList,*pCurrent; /* Linked list of hash entries user for linear traversal */
|
||
sxu32 nEntry; /* Total number of entries */
|
||
SyHashEntry_Pr **apBucket; /* Hash buckets */
|
||
sxu32 nBucketSize; /* Current bucket size */
|
||
};
|
||
#define SXHASH_BUCKET_SIZE 16 /* Initial bucket size: must be a power of two */
|
||
#define SXHASH_FILL_FACTOR 3
|
||
/* Hash access macro */
|
||
#define SyHashFunc(HASH) ((HASH)->xHash)
|
||
#define SyHashCmpFunc(HASH) ((HASH)->xCmp)
|
||
#define SyHashTotalEntry(HASH) ((HASH)->nEntry)
|
||
#define SyHashGetPool(HASH) ((HASH)->pAllocator)
|
||
/*
|
||
* An instance of the following structure define a single context
|
||
* for an Pseudo Random Number Generator.
|
||
*
|
||
* Nothing in this file or anywhere else in the library does any kind of
|
||
* encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
|
||
* number generator) not as an encryption device.
|
||
* This implementation is taken from the SQLite3 source tree.
|
||
*/
|
||
typedef struct SyPRNGCtx SyPRNGCtx;
|
||
struct SyPRNGCtx
|
||
{
|
||
sxu8 i,j; /* State variables */
|
||
unsigned char s[256]; /* State variables */
|
||
sxu16 nMagic; /* Sanity check */
|
||
};
|
||
typedef sxi32 (*ProcRandomSeed)(void *,unsigned int,void *);
|
||
/* High resolution timer.*/
|
||
typedef struct sytime sytime;
|
||
struct sytime
|
||
{
|
||
long tm_sec; /* seconds */
|
||
long tm_usec; /* microseconds */
|
||
};
|
||
/* Forward declaration */
|
||
typedef struct SyStream SyStream;
|
||
typedef struct SyToken SyToken;
|
||
typedef struct SyLex SyLex;
|
||
/*
|
||
* Tokenizer callback signature.
|
||
*/
|
||
typedef sxi32 (*ProcTokenizer)(SyStream *,SyToken *,void *,void *);
|
||
/*
|
||
* Each token in the input is represented by an instance
|
||
* of the following structure.
|
||
*/
|
||
struct SyToken
|
||
{
|
||
SyString sData; /* Token text and length */
|
||
sxu32 nType; /* Token type */
|
||
sxu32 nLine; /* Token line number */
|
||
void *pUserData; /* User private data associated with this token */
|
||
};
|
||
/*
|
||
* During tokenization, information about the state of the input
|
||
* stream is held in an instance of the following structure.
|
||
*/
|
||
struct SyStream
|
||
{
|
||
const unsigned char *zInput; /* Complete text of the input */
|
||
const unsigned char *zText; /* Current input we are processing */
|
||
const unsigned char *zEnd; /* End of input marker */
|
||
sxu32 nLine; /* Total number of processed lines */
|
||
sxu32 nIgn; /* Total number of ignored tokens */
|
||
SySet *pSet; /* Token containers */
|
||
};
|
||
/*
|
||
* Each lexer is represented by an instance of the following structure.
|
||
*/
|
||
struct SyLex
|
||
{
|
||
SyStream sStream; /* Input stream */
|
||
ProcTokenizer xTokenizer; /* Tokenizer callback */
|
||
void * pUserData; /* Third argument to xTokenizer() */
|
||
SySet *pTokenSet; /* Token set */
|
||
};
|
||
#define SyLexTotalToken(LEX) SySetTotalEntry(&(LEX)->aTokenSet)
|
||
#define SyLexTotalLines(LEX) ((LEX)->sStream.nLine)
|
||
#define SyLexTotalIgnored(LEX) ((LEX)->sStream.nIgn)
|
||
#define XLEX_IN_LEN(STREAM) (sxu32)(STREAM->zEnd - STREAM->zText)
|
||
#endif /* SYMISC_PRIVATE_AUX_DEFS */
|
||
/*
|
||
** Notes on UTF-8 (According to SQLite3 authors):
|
||
**
|
||
** Byte-0 Byte-1 Byte-2 Byte-3 Value
|
||
** 0xxxxxxx 00000000 00000000 0xxxxxxx
|
||
** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx
|
||
** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx
|
||
** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx
|
||
**
|
||
*/
|
||
/*
|
||
** Assuming zIn points to the first byte of a UTF-8 character,
|
||
** advance zIn to point to the first byte of the next UTF-8 character.
|
||
*/
|
||
#define SX_JMP_UTF8(zIn,zEnd)\
|
||
while(zIn < zEnd && (((unsigned char)zIn[0] & 0xc0) == 0x80) ){ zIn++; }
|
||
#define SX_WRITE_UTF8(zOut, c) { \
|
||
if( c<0x00080 ){ \
|
||
*zOut++ = (sxu8)(c&0xFF); \
|
||
}else if( c<0x00800 ){ \
|
||
*zOut++ = 0xC0 + (sxu8)((c>>6)&0x1F); \
|
||
*zOut++ = 0x80 + (sxu8)(c & 0x3F); \
|
||
}else if( c<0x10000 ){ \
|
||
*zOut++ = 0xE0 + (sxu8)((c>>12)&0x0F); \
|
||
*zOut++ = 0x80 + (sxu8)((c>>6) & 0x3F); \
|
||
*zOut++ = 0x80 + (sxu8)(c & 0x3F); \
|
||
}else{ \
|
||
*zOut++ = 0xF0 + (sxu8)((c>>18) & 0x07); \
|
||
*zOut++ = 0x80 + (sxu8)((c>>12) & 0x3F); \
|
||
*zOut++ = 0x80 + (sxu8)((c>>6) & 0x3F); \
|
||
*zOut++ = 0x80 + (sxu8)(c & 0x3F); \
|
||
} \
|
||
}
|
||
/* Rely on the standard ctype */
|
||
#include <ctype.h>
|
||
#define SyToUpper(c) toupper(c)
|
||
#define SyToLower(c) tolower(c)
|
||
#define SyisUpper(c) isupper(c)
|
||
#define SyisLower(c) islower(c)
|
||
#define SyisSpace(c) isspace(c)
|
||
#define SyisBlank(c) isspace(c)
|
||
#define SyisAlpha(c) isalpha(c)
|
||
#define SyisDigit(c) isdigit(c)
|
||
#define SyisHex(c) isxdigit(c)
|
||
#define SyisPrint(c) isprint(c)
|
||
#define SyisPunct(c) ispunct(c)
|
||
#define SyisSpec(c) iscntrl(c)
|
||
#define SyisCtrl(c) iscntrl(c)
|
||
#define SyisAscii(c) isascii(c)
|
||
#define SyisAlphaNum(c) isalnum(c)
|
||
#define SyisGraph(c) isgraph(c)
|
||
#define SyDigToHex(c) "0123456789ABCDEF"[c & 0x0F]
|
||
#define SyDigToInt(c) ((c < 0xc0 && SyisDigit(c))? (c - '0') : 0 )
|
||
#define SyCharToUpper(c) ((c < 0xc0 && SyisLower(c))? SyToUpper(c) : c)
|
||
#define SyCharToLower(c) ((c < 0xc0 && SyisUpper(c))? SyToLower(c) : c)
|
||
/* Remove white space/NUL byte from a raw string */
|
||
#define SyStringLeftTrim(RAW)\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[0] < 0xc0 && SyisSpace((RAW)->zString[0])){\
|
||
(RAW)->nByte--;\
|
||
(RAW)->zString++;\
|
||
}
|
||
#define SyStringLeftTrimSafe(RAW)\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[0] < 0xc0 && ((RAW)->zString[0] == 0 || SyisSpace((RAW)->zString[0]))){\
|
||
(RAW)->nByte--;\
|
||
(RAW)->zString++;\
|
||
}
|
||
#define SyStringRightTrim(RAW)\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[(RAW)->nByte - 1] < 0xc0 && SyisSpace((RAW)->zString[(RAW)->nByte - 1])){\
|
||
(RAW)->nByte--;\
|
||
}
|
||
#define SyStringRightTrimSafe(RAW)\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[(RAW)->nByte - 1] < 0xc0 && \
|
||
(( RAW)->zString[(RAW)->nByte - 1] == 0 || SyisSpace((RAW)->zString[(RAW)->nByte - 1]))){\
|
||
(RAW)->nByte--;\
|
||
}
|
||
|
||
#define SyStringFullTrim(RAW)\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[0] < 0xc0 && SyisSpace((RAW)->zString[0])){\
|
||
(RAW)->nByte--;\
|
||
(RAW)->zString++;\
|
||
}\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[(RAW)->nByte - 1] < 0xc0 && SyisSpace((RAW)->zString[(RAW)->nByte - 1])){\
|
||
(RAW)->nByte--;\
|
||
}
|
||
#define SyStringFullTrimSafe(RAW)\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[0] < 0xc0 && \
|
||
( (RAW)->zString[0] == 0 || SyisSpace((RAW)->zString[0]))){\
|
||
(RAW)->nByte--;\
|
||
(RAW)->zString++;\
|
||
}\
|
||
while((RAW)->nByte > 0 && (unsigned char)(RAW)->zString[(RAW)->nByte - 1] < 0xc0 && \
|
||
( (RAW)->zString[(RAW)->nByte - 1] == 0 || SyisSpace((RAW)->zString[(RAW)->nByte - 1]))){\
|
||
(RAW)->nByte--;\
|
||
}
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
/*
|
||
* An XML raw text,CDATA,tag name and son is parsed out and stored
|
||
* in an instance of the following structure.
|
||
*/
|
||
typedef struct SyXMLRawStr SyXMLRawStr;
|
||
struct SyXMLRawStr
|
||
{
|
||
const char *zString; /* Raw text [UTF-8 ENCODED EXCEPT CDATA] [NOT NULL TERMINATED] */
|
||
sxu32 nByte; /* Text length */
|
||
sxu32 nLine; /* Line number this text occurs */
|
||
};
|
||
/*
|
||
* Event callback signatures.
|
||
*/
|
||
typedef sxi32 (*ProcXMLStartTagHandler)(SyXMLRawStr * ,SyXMLRawStr *,sxu32,SyXMLRawStr *,void *);
|
||
typedef sxi32 (*ProcXMLTextHandler)(SyXMLRawStr *,void *);
|
||
typedef sxi32 (*ProcXMLEndTagHandler)(SyXMLRawStr * ,SyXMLRawStr *,void *);
|
||
typedef sxi32 (*ProcXMLPIHandler)(SyXMLRawStr *,SyXMLRawStr *,void *);
|
||
typedef sxi32 (*ProcXMLDoctypeHandler)(SyXMLRawStr *,void *);
|
||
typedef sxi32 (*ProcXMLSyntaxErrorHandler)(const char *,int,SyToken *,void *);
|
||
typedef sxi32 (*ProcXMLStartDocument)(void *);
|
||
typedef sxi32 (*ProcXMLNameSpaceStart)(SyXMLRawStr *,SyXMLRawStr *,void *);
|
||
typedef sxi32 (*ProcXMLNameSpaceEnd)(SyXMLRawStr *,void *);
|
||
typedef sxi32 (*ProcXMLEndDocument)(void *);
|
||
/* XML processing control flags */
|
||
#define SXML_ENABLE_NAMESPACE 0x01 /* Parse XML with namespace support enbaled */
|
||
#define SXML_ENABLE_QUERY 0x02 /* Not used */
|
||
#define SXML_OPTION_CASE_FOLDING 0x04 /* Controls whether case-folding is enabled for this XML parser */
|
||
#define SXML_OPTION_SKIP_TAGSTART 0x08 /* Specify how many characters should be skipped in the beginning of a tag name.*/
|
||
#define SXML_OPTION_SKIP_WHITE 0x10 /* Whether to skip values consisting of whitespace characters. */
|
||
#define SXML_OPTION_TARGET_ENCODING 0x20 /* Default encoding: UTF-8 */
|
||
/* XML error codes */
|
||
enum xml_err_code{
|
||
SXML_ERROR_NONE = 1,
|
||
SXML_ERROR_NO_MEMORY,
|
||
SXML_ERROR_SYNTAX,
|
||
SXML_ERROR_NO_ELEMENTS,
|
||
SXML_ERROR_INVALID_TOKEN,
|
||
SXML_ERROR_UNCLOSED_TOKEN,
|
||
SXML_ERROR_PARTIAL_CHAR,
|
||
SXML_ERROR_TAG_MISMATCH,
|
||
SXML_ERROR_DUPLICATE_ATTRIBUTE,
|
||
SXML_ERROR_JUNK_AFTER_DOC_ELEMENT,
|
||
SXML_ERROR_PARAM_ENTITY_REF,
|
||
SXML_ERROR_UNDEFINED_ENTITY,
|
||
SXML_ERROR_RECURSIVE_ENTITY_REF,
|
||
SXML_ERROR_ASYNC_ENTITY,
|
||
SXML_ERROR_BAD_CHAR_REF,
|
||
SXML_ERROR_BINARY_ENTITY_REF,
|
||
SXML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
|
||
SXML_ERROR_MISPLACED_XML_PI,
|
||
SXML_ERROR_UNKNOWN_ENCODING,
|
||
SXML_ERROR_INCORRECT_ENCODING,
|
||
SXML_ERROR_UNCLOSED_CDATA_SECTION,
|
||
SXML_ERROR_EXTERNAL_ENTITY_HANDLING
|
||
};
|
||
/* Each active XML SAX parser is represented by an instance
|
||
* of the following structure.
|
||
*/
|
||
typedef struct SyXMLParser SyXMLParser;
|
||
struct SyXMLParser
|
||
{
|
||
SyMemBackend *pAllocator; /* Memory backend */
|
||
void *pUserData; /* User private data forwarded varbatim by the XML parser
|
||
* as the last argument to the users callbacks.
|
||
*/
|
||
SyHash hns; /* Namespace hashtable */
|
||
SySet sToken; /* XML tokens */
|
||
SyLex sLex; /* Lexical analyzer */
|
||
sxi32 nFlags; /* Control flags */
|
||
/* User callbacks */
|
||
ProcXMLStartTagHandler xStartTag; /* Start element handler */
|
||
ProcXMLEndTagHandler xEndTag; /* End element handler */
|
||
ProcXMLTextHandler xRaw; /* Raw text/CDATA handler */
|
||
ProcXMLDoctypeHandler xDoctype; /* DOCTYPE handler */
|
||
ProcXMLPIHandler xPi; /* Processing instruction (PI) handler*/
|
||
ProcXMLSyntaxErrorHandler xError; /* Error handler */
|
||
ProcXMLStartDocument xStartDoc; /* StartDoc handler */
|
||
ProcXMLEndDocument xEndDoc; /* EndDoc handler */
|
||
ProcXMLNameSpaceStart xNameSpace; /* Namespace declaration handler */
|
||
ProcXMLNameSpaceEnd xNameSpaceEnd; /* End namespace declaration handler */
|
||
};
|
||
/*
|
||
* --------------
|
||
* Archive extractor:
|
||
* --------------
|
||
* Each open ZIP/TAR archive is identified by an instance of the following structure.
|
||
* That is, a process can open one or more archives and manipulates them in thread safe
|
||
* way by simply working with pointers to the following structure.
|
||
* Each entry in the archive is remembered in a hashtable.
|
||
* Lookup is very fast and entry with the same name are chained together.
|
||
*/
|
||
typedef struct SyArchiveEntry SyArchiveEntry;
|
||
typedef struct SyArchive SyArchive;
|
||
struct SyArchive
|
||
{
|
||
SyMemBackend *pAllocator; /* Memory backend */
|
||
SyArchiveEntry *pCursor; /* Cursor for linear traversal of archive entries */
|
||
SyArchiveEntry *pList; /* Pointer to the List of the loaded archive */
|
||
SyArchiveEntry **apHash; /* Hashtable for archive entry */
|
||
ProcRawStrCmp xCmp; /* Hash comparison function */
|
||
ProcHash xHash; /* Hash Function */
|
||
sxu32 nSize; /* Hashtable size */
|
||
sxu32 nEntry; /* Total number of entries in the zip/tar archive */
|
||
sxu32 nLoaded; /* Total number of entries loaded in memory */
|
||
sxu32 nCentralOfft; /* Central directory offset(ZIP only. Otherwise Zero) */
|
||
sxu32 nCentralSize; /* Central directory size(ZIP only. Otherwise Zero) */
|
||
void *pUserData; /* Upper layer private data */
|
||
sxu32 nMagic; /* Sanity check */
|
||
|
||
};
|
||
#define SXARCH_MAGIC 0xDEAD635A
|
||
#define SXARCH_INVALID(ARCH) (ARCH == 0 || ARCH->nMagic != SXARCH_MAGIC)
|
||
#define SXARCH_ENTRY_INVALID(ENTRY) (ENTRY == 0 || ENTRY->nMagic != SXARCH_MAGIC)
|
||
#define SyArchiveHashFunc(ARCH) (ARCH)->xHash
|
||
#define SyArchiveCmpFunc(ARCH) (ARCH)->xCmp
|
||
#define SyArchiveUserData(ARCH) (ARCH)->pUserData
|
||
#define SyArchiveSetUserData(ARCH,DATA) (ARCH)->pUserData = DATA
|
||
/*
|
||
* Each loaded archive record is identified by an instance
|
||
* of the following structure.
|
||
*/
|
||
struct SyArchiveEntry
|
||
{
|
||
sxu32 nByte; /* Contents size before compression */
|
||
sxu32 nByteCompr; /* Contents size after compression */
|
||
sxu32 nReadCount; /* Read counter */
|
||
sxu32 nCrc; /* Contents CRC32 */
|
||
Sytm sFmt; /* Last-modification time */
|
||
sxu32 nOfft; /* Data offset. */
|
||
sxu16 nComprMeth; /* Compression method 0 == stored/8 == deflated and so on (see appnote.txt)*/
|
||
sxu16 nExtra; /* Extra size if any */
|
||
SyString sFileName; /* entry name & length */
|
||
sxu32 nDup; /* Total number of entries with the same name */
|
||
SyArchiveEntry *pNextHash,*pPrevHash; /* Hash collision chains */
|
||
SyArchiveEntry *pNextName; /* Next entry with the same name */
|
||
SyArchiveEntry *pNext,*pPrev; /* Next and previous entry in the list */
|
||
sxu32 nHash; /* Hash of the entry name */
|
||
void *pUserData; /* User data */
|
||
sxu32 nMagic; /* Sanity check */
|
||
};
|
||
/*
|
||
* Extra flags for extending the file local header
|
||
*/
|
||
#define SXZIP_EXTRA_TIMESTAMP 0x001 /* Extended UNIX timestamp */
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
#ifndef PH7_DISABLE_HASH_FUNC
|
||
/* MD5 context */
|
||
typedef struct MD5Context MD5Context;
|
||
struct MD5Context {
|
||
sxu32 buf[4];
|
||
sxu32 bits[2];
|
||
unsigned char in[64];
|
||
};
|
||
/* SHA1 context */
|
||
typedef struct SHA1Context SHA1Context;
|
||
struct SHA1Context {
|
||
unsigned int state[5];
|
||
unsigned int count[2];
|
||
unsigned char buffer[64];
|
||
};
|
||
#endif /* PH7_DISABLE_HASH_FUNC */
|
||
/* PH7 private declaration */
|
||
/*
|
||
* Memory Objects.
|
||
* Internally, the PH7 virtual machine manipulates nearly all PHP values
|
||
* [i.e: string, int, float, resource, object, bool, null] as ph7_values structures.
|
||
* Each ph7_values struct may cache multiple representations (string, integer etc.)
|
||
* of the same value.
|
||
*/
|
||
struct ph7_value
|
||
{
|
||
ph7_real rVal; /* Real value */
|
||
union{
|
||
sxi64 iVal; /* Integer value */
|
||
void *pOther; /* Other values (Object, Array, Resource, Namespace, etc.) */
|
||
}x;
|
||
sxi32 iFlags; /* Control flags (see below) */
|
||
ph7_vm *pVm; /* Virtual machine that own this instance */
|
||
SyBlob sBlob; /* String values */
|
||
sxu32 nIdx; /* Index number of this entry in the global object allocator */
|
||
};
|
||
/* Allowed value types.
|
||
*/
|
||
#define MEMOBJ_STRING 0x001 /* Memory value is a UTF-8 string */
|
||
#define MEMOBJ_INT 0x002 /* Memory value is an integer */
|
||
#define MEMOBJ_REAL 0x004 /* Memory value is a real number */
|
||
#define MEMOBJ_BOOL 0x008 /* Memory value is a boolean */
|
||
#define MEMOBJ_NULL 0x020 /* Memory value is NULL */
|
||
#define MEMOBJ_HASHMAP 0x040 /* Memory value is a hashmap aka 'array' in the PHP jargon */
|
||
#define MEMOBJ_OBJ 0x080 /* Memory value is an object [i.e: class instance] */
|
||
#define MEMOBJ_RES 0x100 /* Memory value is a resource [User private data] */
|
||
#define MEMOBJ_REFERENCE 0x400 /* Memory value hold a reference (64-bit index) of another ph7_value */
|
||
/* Mask of all known types */
|
||
#define MEMOBJ_ALL (MEMOBJ_STRING|MEMOBJ_INT|MEMOBJ_REAL|MEMOBJ_BOOL|MEMOBJ_NULL|MEMOBJ_HASHMAP|MEMOBJ_OBJ|MEMOBJ_RES)
|
||
/* Scalar variables
|
||
* According to the PHP language reference manual
|
||
* Scalar variables are those containing an integer, float, string or boolean.
|
||
* Types array, object and resource are not scalar.
|
||
*/
|
||
#define MEMOBJ_SCALAR (MEMOBJ_STRING|MEMOBJ_INT|MEMOBJ_REAL|MEMOBJ_BOOL|MEMOBJ_NULL)
|
||
#define MEMOBJ_AUX (MEMOBJ_REFERENCE)
|
||
/*
|
||
* The following macro clear the current ph7_value type and replace
|
||
* it with the given one.
|
||
*/
|
||
#define MemObjSetType(OBJ,TYPE) ((OBJ)->iFlags = ((OBJ)->iFlags&~MEMOBJ_ALL)|TYPE)
|
||
/* ph7_value cast method signature */
|
||
typedef sxi32 (*ProcMemObjCast)(ph7_value *);
|
||
/* Forward reference */
|
||
typedef struct ph7_output_consumer ph7_output_consumer;
|
||
typedef struct ph7_user_func ph7_user_func;
|
||
typedef struct ph7_conf ph7_conf;
|
||
/*
|
||
* An instance of the following structure store the default VM output
|
||
* consumer and it's private data.
|
||
* Client-programs can register their own output consumer callback
|
||
* via the [PH7_VM_CONFIG_OUTPUT] configuration directive.
|
||
* Please refer to the official documentation for more information
|
||
* on how to register an output consumer callback.
|
||
*/
|
||
struct ph7_output_consumer
|
||
{
|
||
ProcConsumer xConsumer; /* VM output consumer routine */
|
||
void *pUserData; /* Third argument to xConsumer() */
|
||
ProcConsumer xDef; /* Default output consumer routine */
|
||
void *pDefData; /* Third argument to xDef() */
|
||
};
|
||
/*
|
||
* PH7 engine [i.e: ph7 instance] configuration is stored in
|
||
* an instance of the following structure.
|
||
* Please refer to the official documentation for more information
|
||
* on how to configure your ph7 engine instance.
|
||
*/
|
||
struct ph7_conf
|
||
{
|
||
ProcConsumer xErr; /* Compile-time error consumer callback */
|
||
void *pErrData; /* Third argument to xErr() */
|
||
SyBlob sErrConsumer; /* Default error consumer */
|
||
};
|
||
/*
|
||
* Signature of the C function responsible of expanding constant values.
|
||
*/
|
||
typedef void (*ProcConstant)(ph7_value *,void *);
|
||
/*
|
||
* Each registered constant [i.e: __TIME__, __DATE__, PHP_OS, INT_MAX, etc.] is stored
|
||
* in an instance of the following structure.
|
||
* Please refer to the official documentation for more information
|
||
* on how to create/install foreign constants.
|
||
*/
|
||
typedef struct ph7_constant ph7_constant;
|
||
struct ph7_constant
|
||
{
|
||
SyString sName; /* Constant name */
|
||
ProcConstant xExpand; /* Function responsible of expanding constant value */
|
||
void *pUserData; /* Last argument to xExpand() */
|
||
};
|
||
typedef struct ph7_aux_data ph7_aux_data;
|
||
/*
|
||
* Auxiliary data associated with each foreign function is stored
|
||
* in a stack of the following structure.
|
||
* Note that automatic tracked chunks are also stored in an instance
|
||
* of this structure.
|
||
*/
|
||
struct ph7_aux_data
|
||
{
|
||
void *pAuxData; /* Aux data */
|
||
};
|
||
/* Foreign functions signature */
|
||
typedef int (*ProchHostFunction)(ph7_context *,int,ph7_value **);
|
||
/*
|
||
* Each installed foreign function is recored in an instance of the following
|
||
* structure.
|
||
* Please refer to the official documentation for more information on how
|
||
* to create/install foreign functions.
|
||
*/
|
||
struct ph7_user_func
|
||
{
|
||
ph7_vm *pVm; /* VM that own this instance */
|
||
SyString sName; /* Foreign function name */
|
||
ProchHostFunction xFunc; /* Implementation of the foreign function */
|
||
void *pUserData; /* User private data [Refer to the official documentation for more information]*/
|
||
SySet aAux; /* Stack of auxiliary data [Refer to the official documentation for more information]*/
|
||
};
|
||
/*
|
||
* The 'context' argument for an installable function. A pointer to an
|
||
* instance of this structure is the first argument to the routines used
|
||
* implement the foreign functions.
|
||
*/
|
||
struct ph7_context
|
||
{
|
||
ph7_user_func *pFunc; /* Function information. */
|
||
ph7_value *pRet; /* Return value is stored here. */
|
||
SySet sVar; /* Container of dynamically allocated ph7_values
|
||
* [i.e: Garbage collection purposes.]
|
||
*/
|
||
SySet sChunk; /* Track dynamically allocated chunks [ph7_aux_data instance].
|
||
* [i.e: Garbage collection purposes.]
|
||
*/
|
||
ph7_vm *pVm; /* Virtual machine that own this context */
|
||
sxi32 iFlags; /* Call flags */
|
||
};
|
||
/*
|
||
* Each hashmap entry [i.e: array(4,5,6)] is recorded in an instance
|
||
* of the following structure.
|
||
*/
|
||
struct ph7_hashmap_node
|
||
{
|
||
ph7_hashmap *pMap; /* Hashmap that own this instance */
|
||
sxi32 iType; /* Node type */
|
||
union{
|
||
sxi64 iKey; /* Int key */
|
||
SyBlob sKey; /* Blob key */
|
||
}xKey;
|
||
sxi32 iFlags; /* Control flags */
|
||
sxu32 nHash; /* Key hash value */
|
||
sxu32 nValIdx; /* Value stored in this node */
|
||
ph7_hashmap_node *pNext,*pPrev; /* Link to other entries [i.e: linear traversal] */
|
||
ph7_hashmap_node *pNextCollide,*pPrevCollide; /* Collision chain */
|
||
};
|
||
/*
|
||
* Each active hashmap aka array in the PHP jargon is represented
|
||
* by an instance of the following structure.
|
||
*/
|
||
struct ph7_hashmap
|
||
{
|
||
ph7_vm *pVm; /* VM that own this instance */
|
||
ph7_hashmap_node **apBucket; /* Hash bucket */
|
||
ph7_hashmap_node *pFirst; /* First inserted entry */
|
||
ph7_hashmap_node *pLast; /* Last inserted entry */
|
||
ph7_hashmap_node *pCur; /* Current entry */
|
||
sxu32 nSize; /* Bucket size */
|
||
sxu32 nEntry; /* Total number of inserted entries */
|
||
sxu32 (*xIntHash)(sxi64); /* Hash function for int_keys */
|
||
sxu32 (*xBlobHash)(const void *,sxu32); /* Hash function for blob_keys */
|
||
sxi64 iNextIdx; /* Next available automatically assigned index */
|
||
sxi32 iRef; /* Reference count */
|
||
};
|
||
/* An instance of the following structure is the context
|
||
* for the FOREACH_STEP/FOREACH_INIT VM instructions.
|
||
* Those instructions are used to implement the 'foreach'
|
||
* statement.
|
||
* This structure is made available to these instructions
|
||
* as the P3 operand.
|
||
*/
|
||
struct ph7_foreach_info
|
||
{
|
||
SyString sKey; /* Key name. Empty otherwise*/
|
||
SyString sValue; /* Value name */
|
||
sxi32 iFlags; /* Control flags */
|
||
SySet aStep; /* Stack of steps [i.e: ph7_foreach_step instance] */
|
||
};
|
||
struct ph7_foreach_step
|
||
{
|
||
sxi32 iFlags; /* Control flags (see below) */
|
||
/* Iterate on those values */
|
||
union {
|
||
ph7_hashmap *pMap; /* Hashmap [i.e: array in the PHP jargon] iteration
|
||
* Ex: foreach(array(1,2,3) as $key=>$value){}
|
||
*/
|
||
ph7_class_instance *pThis; /* Class instance [i.e: object] iteration */
|
||
}xIter;
|
||
};
|
||
/* Foreach step control flags */
|
||
#define PH7_4EACH_STEP_HASHMAP 0x001 /* Hashmap iteration */
|
||
#define PH7_4EACH_STEP_OBJECT 0x002 /* Object iteration */
|
||
#define PH7_4EACH_STEP_KEY 0x004 /* Make Key available */
|
||
#define PH7_4EACH_STEP_REF 0x008 /* Pass value by reference not copy */
|
||
/*
|
||
* Each PH7 engine is identified by an instance of the following structure.
|
||
* Please refer to the official documentation for more information
|
||
* on how to configure your PH7 engine instance.
|
||
*/
|
||
struct ph7
|
||
{
|
||
SyMemBackend sAllocator; /* Low level memory allocation subsystem */
|
||
const ph7_vfs *pVfs; /* Underlying Virtual File System */
|
||
ph7_conf xConf; /* Configuration */
|
||
#if defined(PH7_ENABLE_THREADS)
|
||
const SyMutexMethods *pMethods; /* Mutex methods */
|
||
SyMutex *pMutex; /* Per-engine mutex */
|
||
#endif
|
||
ph7_vm *pVms; /* List of active VM */
|
||
sxi32 iVm; /* Total number of active VM */
|
||
ph7 *pNext,*pPrev; /* List of active engines */
|
||
sxu32 nMagic; /* Sanity check against misuse */
|
||
};
|
||
/* Code generation data structures */
|
||
typedef sxi32 (*ProcErrorGen)(void *,sxi32,sxu32,const char *,...);
|
||
typedef struct ph7_expr_node ph7_expr_node;
|
||
typedef struct ph7_expr_op ph7_expr_op;
|
||
typedef struct ph7_gen_state ph7_gen_state;
|
||
typedef struct GenBlock GenBlock;
|
||
typedef sxi32 (*ProcLangConstruct)(ph7_gen_state *);
|
||
typedef sxi32 (*ProcNodeConstruct)(ph7_gen_state *,sxi32);
|
||
/*
|
||
* Each supported operator [i.e: +, -, ==, *, %, >>, >=, new, etc.] is represented
|
||
* by an instance of the following structure.
|
||
* The PH7 parser does not use any external tools and is 100% handcoded.
|
||
* That is, the PH7 parser is thread-safe ,full reentrant, produce consistant
|
||
* compile-time errrors and at least 7 times faster than the standard PHP parser.
|
||
*/
|
||
struct ph7_expr_op
|
||
{
|
||
SyString sOp; /* String representation of the operator [i.e: "+","*","=="...] */
|
||
sxi32 iOp; /* Operator ID */
|
||
sxi32 iPrec; /* Operator precedence: 1 == Highest */
|
||
sxi32 iAssoc; /* Operator associativity (either left,right or non-associative) */
|
||
sxi32 iVmOp; /* VM OP code for this operator [i.e: PH7_OP_EQ,PH7_OP_LT,PH7_OP_MUL...]*/
|
||
};
|
||
/*
|
||
* Each expression node is parsed out and recorded
|
||
* in an instance of the following structure.
|
||
*/
|
||
struct ph7_expr_node
|
||
{
|
||
const ph7_expr_op *pOp; /* Operator ID or NULL if literal, constant, variable, function or class method call */
|
||
ph7_expr_node *pLeft; /* Left expression tree */
|
||
ph7_expr_node *pRight; /* Right expression tree */
|
||
SyToken *pStart; /* Stream of tokens that belong to this node */
|
||
SyToken *pEnd; /* End of token stream */
|
||
sxi32 iFlags; /* Node construct flags */
|
||
ProcNodeConstruct xCode; /* C routine responsible of compiling this node */
|
||
SySet aNodeArgs; /* Node arguments. Only used by postfix operators [i.e: function call]*/
|
||
ph7_expr_node *pCond; /* Condition: Only used by the ternary operator '?:' */
|
||
};
|
||
/* Node Construct flags */
|
||
#define EXPR_NODE_PRE_INCR 0x01 /* Pre-icrement/decrement [i.e: ++$i,--$j] node */
|
||
/*
|
||
* A block of instructions is recorded in an instance of the following structure.
|
||
* This structure is used only during compile-time and have no meaning
|
||
* during bytecode execution.
|
||
*/
|
||
struct GenBlock
|
||
{
|
||
ph7_gen_state *pGen; /* State of the code generator */
|
||
GenBlock *pParent; /* Upper block or NULL if global */
|
||
sxu32 nFirstInstr; /* First instruction to execute */
|
||
sxi32 iFlags; /* Block control flags (see below) */
|
||
SySet aJumpFix; /* Jump fixup (JumpFixup instance) */
|
||
void *pUserData; /* Upper layer private data */
|
||
/* The following two fields are used only when compiling
|
||
* the 'do..while()' language construct.
|
||
*/
|
||
sxu8 bPostContinue; /* TRUE when compiling the do..while() statement */
|
||
SySet aPostContFix; /* Post-continue jump fix */
|
||
};
|
||
/*
|
||
* Code generator state is remembered in an instance of the following
|
||
* structure. We put the information in this structure and pass around
|
||
* a pointer to this structure, rather than pass around all of the
|
||
* information separately. This helps reduce the number of arguments
|
||
* to generator functions.
|
||
* This structure is used only during compile-time and have no meaning
|
||
* during bytecode execution.
|
||
*/
|
||
struct ph7_gen_state
|
||
{
|
||
ph7_vm *pVm; /* VM that own this instance */
|
||
SyHash hLiteral; /* Constant string Literals table */
|
||
SyHash hNumLiteral; /* Numeric literals table */
|
||
SyHash hVar; /* Collected variable hashtable */
|
||
GenBlock *pCurrent; /* Current processed block */
|
||
GenBlock sGlobal; /* Global block */
|
||
ProcConsumer xErr; /* Error consumer callback */
|
||
void *pErrData; /* Third argument to xErr() */
|
||
SySet aLabel; /* Label table */
|
||
SySet aGoto; /* Gotos table */
|
||
SyBlob sWorker; /* General purpose working buffer */
|
||
SyBlob sErrBuf; /* Error buffer */
|
||
SyToken *pIn; /* Current processed token */
|
||
SyToken *pEnd; /* Last token in the stream */
|
||
sxu32 nErr; /* Total number of compilation error */
|
||
SyToken *pRawIn; /* Current processed raw token */
|
||
SyToken *pRawEnd; /* Last raw token in the stream */
|
||
SySet *pTokenSet; /* Token containers */
|
||
};
|
||
/* Forward references */
|
||
typedef struct ph7_vm_func_closure_env ph7_vm_func_closure_env;
|
||
typedef struct ph7_vm_func_static_var ph7_vm_func_static_var;
|
||
typedef struct ph7_vm_func_arg ph7_vm_func_arg;
|
||
typedef struct ph7_vm_func ph7_vm_func;
|
||
typedef struct VmFrame VmFrame;
|
||
/*
|
||
* Each collected function argument is recorded in an instance
|
||
* of the following structure.
|
||
* Note that as an extension, PH7 implements full type hinting
|
||
* which mean that any function can have it's own signature.
|
||
* Example:
|
||
* function foo(int $a,string $b,float $c,ClassInstance $d){}
|
||
* This is how the powerful function overloading mechanism is
|
||
* implemented.
|
||
* Note that as an extension, PH7 allow function arguments to have
|
||
* any complex default value associated with them unlike the standard
|
||
* PHP engine.
|
||
* Example:
|
||
* function foo(int $a = rand() & 1023){}
|
||
* now, when foo is called without arguments [i.e: foo()] the
|
||
* $a variable (first parameter) will be set to a random number
|
||
* between 0 and 1023 inclusive.
|
||
* Refer to the official documentation for more information on this
|
||
* mechanism and other extension introduced by the PH7 engine.
|
||
*/
|
||
struct ph7_vm_func_arg
|
||
{
|
||
SyString sName; /* Argument name */
|
||
SySet aByteCode; /* Compiled default value associated with this argument */
|
||
sxu32 nType; /* Type of this argument [i.e: array, int, string, float, object, etc.] */
|
||
SyString sClass; /* Class name if the argument expect a class instance [i.e: function foo(BaseClass $bar){} ] */
|
||
sxi32 iFlags; /* Configuration flags */
|
||
};
|
||
/*
|
||
* Each static variable is parsed out and remembered in an instance
|
||
* of the following structure.
|
||
* Note that as an extension, PH7 allow static variable have
|
||
* any complex default value associated with them unlike the standard
|
||
* PHP engine.
|
||
* Example:
|
||
* static $rand_str = 'PH7'.rand_str(3); // Concatenate 'PH7' with
|
||
* // a random three characters(English alphabet)
|
||
* var_dump($rand_str);
|
||
* //You should see something like this
|
||
* string(6 'PH7awt');
|
||
*/
|
||
struct ph7_vm_func_static_var
|
||
{
|
||
SyString sName; /* Static variable name */
|
||
SySet aByteCode; /* Compiled initialization expression */
|
||
sxu32 nIdx; /* Object index in the global memory object container */
|
||
};
|
||
/*
|
||
* Each imported variable from the outside closure environnment is recoded
|
||
* in an instance of the following structure.
|
||
*/
|
||
struct ph7_vm_func_closure_env
|
||
{
|
||
SyString sName; /* Imported variable name */
|
||
int iFlags; /* Control flags */
|
||
ph7_value sValue; /* Imported variable value */
|
||
sxu32 nIdx; /* Reference to the bounded variable if passed by reference
|
||
*[Example:
|
||
* $x = 1;
|
||
* $closure = function() use (&$x) { ++$x; }
|
||
* $closure();
|
||
*]
|
||
*/
|
||
};
|
||
/* Function configuration flags */
|
||
#define VM_FUNC_ARG_BY_REF 0x001 /* Argument passed by reference */
|
||
#define VM_FUNC_ARG_HAS_DEF 0x002 /* Argument has default value associated with it */
|
||
#define VM_FUNC_REF_RETURN 0x004 /* Return by reference */
|
||
#define VM_FUNC_CLASS_METHOD 0x008 /* VM function is in fact a class method */
|
||
#define VM_FUNC_CLOSURE 0x010 /* VM function is a closure */
|
||
#define VM_FUNC_ARG_IGNORE 0x020 /* Do not install argument in the current frame */
|
||
/*
|
||
* Each user defined function is parsed out and stored in an instance
|
||
* of the following structure.
|
||
* PH7 introduced some powerfull extensions to the PHP 5 programming
|
||
* language like function overloading, type hinting, complex default
|
||
* arguments values and many more.
|
||
* Please refer to the official documentation for more information.
|
||
*/
|
||
struct ph7_vm_func
|
||
{
|
||
SySet aArgs; /* Expected arguments (ph7_vm_func_arg instance) */
|
||
SySet aStatic; /* Static variable (ph7_vm_func_static_var instance) */
|
||
SyString sName; /* Function name */
|
||
SySet aByteCode; /* Compiled function body */
|
||
SySet aClosureEnv; /* Closure environment (ph7_vm_func_closure_env instace) */
|
||
sxi32 iFlags; /* VM function configuration */
|
||
SyString sSignature; /* Function signature used to implement function overloading
|
||
* (Refer to the official docuemntation for more information
|
||
* on this powerfull feature)
|
||
*/
|
||
void *pUserData; /* Upper layer private data associated with this instance */
|
||
ph7_vm_func *pNextName; /* Next VM function with the same name as this one */
|
||
};
|
||
/* Forward reference */
|
||
typedef struct ph7_builtin_constant ph7_builtin_constant;
|
||
typedef struct ph7_builtin_func ph7_builtin_func;
|
||
/*
|
||
* Each built-in foreign function (C function) is stored in an
|
||
* instance of the following structure.
|
||
* Please refer to the official documentation for more information
|
||
* on how to create/install foreign functions.
|
||
*/
|
||
struct ph7_builtin_func
|
||
{
|
||
const char *zName; /* Function name [i.e: strlen(), rand(), array_merge(), etc.]*/
|
||
ProchHostFunction xFunc; /* C routine performing the computation */
|
||
};
|
||
/*
|
||
* Each built-in foreign constant is stored in an instance
|
||
* of the following structure.
|
||
* Please refer to the official documentation for more information
|
||
* on how to create/install foreign constants.
|
||
*/
|
||
struct ph7_builtin_constant
|
||
{
|
||
const char *zName; /* Constant name */
|
||
ProcConstant xExpand; /* C routine responsible of expanding constant value*/
|
||
};
|
||
/* Forward reference */
|
||
typedef struct ph7_class_method ph7_class_method;
|
||
typedef struct ph7_class_attr ph7_class_attr;
|
||
/*
|
||
* Each class is parsed out and stored in an instance of the following structure.
|
||
* PH7 introduced powerfull extensions to the PHP 5 OO subsystems.
|
||
* Please refer to the official documentation for more information.
|
||
*/
|
||
struct ph7_class
|
||
{
|
||
ph7_class *pBase; /* Base class if any */
|
||
SyHash hDerived; /* Derived [child] classes */
|
||
SyString sName; /* Class full qualified name */
|
||
sxi32 iFlags; /* Class configuration flags [i.e: final, interface, abstract, etc.] */
|
||
SyHash hAttr; /* Class attributes [i.e: variables and constants] */
|
||
SyHash hMethod; /* Class methods */
|
||
sxu32 nLine; /* Line number on which this class was declared */
|
||
SySet aInterface; /* Implemented interface container */
|
||
ph7_class *pNextName; /* Next class [interface, abstract, etc.] with the same name */
|
||
};
|
||
/* Class configuration flags */
|
||
#define PH7_CLASS_FINAL 0x001 /* Class is final [cannot be extended] */
|
||
#define PH7_CLASS_INTERFACE 0x002 /* Class is interface */
|
||
#define PH7_CLASS_ABSTRACT 0x004 /* Class is abstract */
|
||
/* Class attribute/methods/constants protection levels */
|
||
#define PH7_CLASS_PROT_PUBLIC 1 /* public */
|
||
#define PH7_CLASS_PROT_PROTECTED 2 /* protected */
|
||
#define PH7_CLASS_PROT_PRIVATE 3 /* private */
|
||
/*
|
||
* each class attribute (variable, constants) is parsed out and stored
|
||
* in an instance of the following structure.
|
||
*/
|
||
struct ph7_class_attr
|
||
{
|
||
SyString sName; /* Atrribute name */
|
||
sxi32 iFlags; /* Attribute configuration [i.e: static, variable, constant, etc.] */
|
||
sxi32 iProtection; /* Protection level [i.e: public, private, protected] */
|
||
SySet aByteCode; /* Compiled attribute body */
|
||
sxu32 nIdx; /* Attribute index */
|
||
sxu32 nLine; /* Line number on which this attribute was defined */
|
||
};
|
||
/* Attribute configuration */
|
||
#define PH7_CLASS_ATTR_STATIC 0x001 /* Static attribute */
|
||
#define PH7_CLASS_ATTR_CONSTANT 0x002 /* Constant attribute */
|
||
#define PH7_CLASS_ATTR_ABSTRACT 0x004 /* Abstract method */
|
||
#define PH7_CLASS_ATTR_FINAL 0x008 /* Final method */
|
||
/*
|
||
* Each class method is parsed out and stored in an instance of the following
|
||
* structure.
|
||
* PH7 introduced some powerfull extensions to the PHP 5 programming
|
||
* language like function overloading,type hinting,complex default
|
||
* arguments and many more.
|
||
* Please refer to the official documentation for more information.
|
||
*/
|
||
struct ph7_class_method
|
||
{
|
||
ph7_vm_func sFunc; /* Compiled method body */
|
||
SyString sVmName; /* Automatically generated name assigned to this method.
|
||
* Typically this is "[class_name__method_name@random_string]"
|
||
*/
|
||
sxi32 iProtection; /* Protection level [i.e: public,private,protected] */
|
||
sxi32 iFlags; /* Methods configuration */
|
||
sxi32 iCloneDepth; /* Clone depth [Only used by the magic method __clone ] */
|
||
sxu32 nLine; /* Line on which this method was defined */
|
||
};
|
||
/*
|
||
* Each active object (class instance) is represented by an instance of
|
||
* the following structure.
|
||
*/
|
||
struct ph7_class_instance
|
||
{
|
||
ph7_vm *pVm; /* VM that own this instance */
|
||
ph7_class *pClass; /* Object is an instance of this class */
|
||
SyHash hAttr; /* Hashtable of active class members */
|
||
sxi32 iRef; /* Reference count */
|
||
sxi32 iFlags; /* Control flags */
|
||
};
|
||
/*
|
||
* A single instruction of the virtual machine has an opcode
|
||
* and as many as three operands.
|
||
* Each VM instruction resulting from compiling a PHP script
|
||
* is stored in an instance of the following structure.
|
||
*/
|
||
typedef struct VmInstr VmInstr;
|
||
struct VmInstr
|
||
{
|
||
sxu8 iOp; /* Operation to preform */
|
||
sxi32 iP1; /* First operand */
|
||
sxu32 iP2; /* Second operand (Often the jump destination) */
|
||
void *p3; /* Third operand (Often Upper layer private data) */
|
||
};
|
||
/* Each active class instance attribute is represented by an instance
|
||
* of the following structure.
|
||
*/
|
||
typedef struct VmClassAttr VmClassAttr;
|
||
struct VmClassAttr
|
||
{
|
||
ph7_class_attr *pAttr; /* Class attribute */
|
||
sxu32 nIdx; /* Memory object index */
|
||
};
|
||
/* Forward reference */
|
||
typedef struct VmRefObj VmRefObj;
|
||
/*
|
||
* Each catch [i.e catch(Exception $e){ } ] block is parsed out and stored
|
||
* in an instance of the following structure.
|
||
*/
|
||
typedef struct ph7_exception_block ph7_exception_block;
|
||
typedef struct ph7_exception ph7_exception;
|
||
struct ph7_exception_block
|
||
{
|
||
SyString sClass; /* Exception class name [i.e: Exception,MyException...] */
|
||
SyString sThis; /* Instance name [i.e: $e..] */
|
||
SySet sByteCode; /* Block compiled instructions */
|
||
};
|
||
/*
|
||
* Context for the exception mechanism.
|
||
*/
|
||
struct ph7_exception
|
||
{
|
||
ph7_vm *pVm; /* VM that own this exception */
|
||
SySet sEntry; /* Compiled 'catch' blocks (ph7_exception_block instance)
|
||
* container.
|
||
*/
|
||
VmFrame *pFrame; /* Frame that trigger the exception */
|
||
};
|
||
/* Forward reference */
|
||
typedef struct ph7_case_expr ph7_case_expr;
|
||
typedef struct ph7_switch ph7_switch;
|
||
/*
|
||
* Each compiled case block in a swicth statement is compiled
|
||
* and stored in an instance of the following structure.
|
||
*/
|
||
struct ph7_case_expr
|
||
{
|
||
SySet aByteCode; /* Compiled body of the case block */
|
||
sxu32 nStart; /* First instruction to execute */
|
||
};
|
||
/*
|
||
* Each compiled switch statement is parsed out and stored
|
||
* in an instance of the following structure.
|
||
*/
|
||
struct ph7_switch
|
||
{
|
||
SySet aCaseExpr; /* Compile case block */
|
||
sxu32 nOut; /* First instruction to execute after this statement */
|
||
sxu32 nDefault; /* First instruction to execute in the default block */
|
||
};
|
||
/* Assertion flags */
|
||
#define PH7_ASSERT_DISABLE 0x01 /* Disable assertion */
|
||
#define PH7_ASSERT_WARNING 0x02 /* Issue a warning for each failed assertion */
|
||
#define PH7_ASSERT_BAIL 0x04 /* Terminate execution on failed assertions */
|
||
#define PH7_ASSERT_QUIET_EVAL 0x08 /* Not used */
|
||
#define PH7_ASSERT_CALLBACK 0x10 /* Callback to call on failed assertions */
|
||
/*
|
||
* error_log() consumer function signature.
|
||
* Refer to the [PH7_VM_CONFIG_ERR_LOG_HANDLER] configuration directive
|
||
* for more information on how to register an error_log consumer().
|
||
*/
|
||
typedef void (*ProcErrLog)(const char *,int,const char *,const char *);
|
||
/*
|
||
* An instance of the following structure hold the bytecode instructions
|
||
* resulting from compiling a PHP script.
|
||
* This structure contains the complete state of the virtual machine.
|
||
*/
|
||
struct ph7_vm
|
||
{
|
||
SyMemBackend sAllocator; /* Memory backend */
|
||
#if defined(PH7_ENABLE_THREADS)
|
||
SyMutex *pMutex; /* Recursive mutex associated with VM. */
|
||
#endif
|
||
ph7 *pEngine; /* Interpreter that own this VM */
|
||
SySet aByteCode; /* Default bytecode container */
|
||
SySet *pByteContainer; /* Current bytecode container */
|
||
VmFrame *pFrame; /* Stack of active frames */
|
||
SyPRNGCtx sPrng; /* PRNG context */
|
||
SySet aMemObj; /* Object allocation table */
|
||
SySet aLitObj; /* Literals allocation table */
|
||
ph7_value *aOps; /* Operand stack */
|
||
SySet aFreeObj; /* Stack of free memory objects */
|
||
SyHash hClass; /* Compiled classes container */
|
||
SyHash hConstant; /* Host-application and user defined constants container */
|
||
SyHash hHostFunction; /* Host-application installable functions */
|
||
SyHash hFunction; /* Compiled functions */
|
||
SyHash hSuper; /* Superglobals hashtable */
|
||
SyHash hPDO; /* PDO installed drivers */
|
||
SyBlob sConsumer; /* Default VM consumer [i.e Redirect all VM output to this blob] */
|
||
SyBlob sWorker; /* General purpose working buffer */
|
||
SyBlob sArgv; /* $argv[] collector [refer to the [getopt()] implementation for more information] */
|
||
SySet aFiles; /* Stack of processed files */
|
||
SySet aPaths; /* Set of import paths */
|
||
SySet aIncluded; /* Set of included files */
|
||
SySet aOB; /* Stackable output buffers */
|
||
SySet aShutdown; /* Stack of shutdown user callbacks */
|
||
SySet aException; /* Stack of loaded exception */
|
||
SySet aIOstream; /* Installed IO stream container */
|
||
const ph7_io_stream *pDefStream; /* Default IO stream [i.e: typically this is the 'file://' stream] */
|
||
ph7_value sExec; /* Compiled script return value [Can be extracted via the PH7_VM_CONFIG_EXEC_VALUE directive]*/
|
||
ph7_value aExceptionCB[2]; /* Installed exception handler callbacks via [set_exception_handler()] */
|
||
ph7_value aErrCB[2]; /* Installed error handler callback via [set_error_handler()] */
|
||
void *pStdin; /* STDIN IO stream */
|
||
void *pStdout; /* STDOUT IO stream */
|
||
void *pStderr; /* STDERR IO stream */
|
||
int bErrReport; /* TRUE to report all runtime Error/Warning/Notice */
|
||
int nRecursionDepth; /* Current recursion depth */
|
||
int nMaxDepth; /* Maximum allowed recusion depth */
|
||
int nObDepth; /* OB depth */
|
||
int nExceptDepth; /* Exception depth */
|
||
int closure_cnt; /* Loaded closures counter */
|
||
int json_rc; /* JSON return status [refer to json_encode()/json_decode()]*/
|
||
sxu32 unique_id; /* Random number used to generate unique ID [refer to uniqid() for more info]*/
|
||
ProcErrLog xErrLog; /* error_log() consumer [refer to PH7_VM_CONFIG_ERR_LOG_HANDLER] */
|
||
sxu32 nOutputLen; /* Total number of generated output */
|
||
ph7_output_consumer sVmConsumer; /* Registered output consumer callback */
|
||
int iAssertFlags; /* Assertion flags */
|
||
ph7_value sAssertCallback; /* Callback to call on failed assertions */
|
||
VmRefObj **apRefObj; /* Hashtable of referenced object */
|
||
VmRefObj *pRefList; /* List of referenced memory objects */
|
||
sxu32 nRefSize; /* apRefObj[] size */
|
||
sxu32 nRefUsed; /* Total entries in apRefObj[] */
|
||
SySet aSelf; /* 'self' stack used for static member access [i.e: self::MyConstant] */
|
||
ph7_hashmap *pGlobal; /* $GLOBALS hashmap */
|
||
sxu32 nGlobalIdx; /* $GLOBALS index */
|
||
sxi32 iExitStatus; /* Script exit status */
|
||
ph7_gen_state sCodeGen; /* Code generator module */
|
||
ph7_vm *pNext,*pPrev; /* List of active VM's */
|
||
sxu32 nMagic; /* Sanity check against misuse */
|
||
};
|
||
/*
|
||
* Allowed value for ph7_vm.nMagic
|
||
*/
|
||
#define PH7_VM_INIT 0xFADE9512 /* VM correctly initialized */
|
||
#define PH7_VM_RUN 0xEA271285 /* VM ready to execute PH7 bytecode */
|
||
#define PH7_VM_EXEC 0xCAFE2DAD /* VM executing PH7 bytecode */
|
||
#define PH7_VM_STALE 0xBAD1DEAD /* Stale VM */
|
||
/*
|
||
* Error codes according to the PHP language reference manual.
|
||
*/
|
||
enum iErrCode
|
||
{
|
||
E_ERROR = 1, /* Fatal run-time errors. These indicate errors that can not be recovered
|
||
* from, such as a memory allocation problem. Execution of the script is
|
||
* halted.
|
||
* The only fatal error under PH7 is an out-of-memory. All others erros
|
||
* even a call to undefined function will not halt script execution.
|
||
*/
|
||
E_WARNING = 2, /* Run-time warnings (non-fatal errors). Execution of the script is not halted. */
|
||
E_PARSE = 4, /* Compile-time parse errors. Parse errors should only be generated by the parser.*/
|
||
E_NOTICE = 8, /* Run-time notices. Indicate that the script encountered something that could
|
||
* indicate an error, but could also happen in the normal course of running a script.
|
||
*/
|
||
E_CORE_WARNING = 16, /* Fatal errors that occur during PHP's initial startup. This is like an E_ERROR
|
||
* except it is generated by the core of PHP.
|
||
*/
|
||
E_USER_ERROR = 256, /* User-generated error message.*/
|
||
E_USER_WARNING = 512, /* User-generated warning message.*/
|
||
E_USER_NOTICE = 1024, /* User-generated notice message.*/
|
||
E_STRICT = 2048, /* Enable to have PHP suggest changes to your code which will ensure the best interoperability
|
||
* and forward compatibility of your code.
|
||
*/
|
||
E_RECOVERABLE_ERROR = 4096, /* Catchable fatal error. It indicates that a probably dangerous error occured, but did not
|
||
* leave the Engine in an unstable state. If the error is not caught by a user defined handle
|
||
* the application aborts as it was an E_ERROR.
|
||
*/
|
||
E_DEPRECATED = 8192, /* Run-time notices. Enable this to receive warnings about code that will not
|
||
* work in future versions.
|
||
*/
|
||
E_USER_DEPRECATED = 16384, /* User-generated warning message. */
|
||
E_ALL = 32767 /* All errors and warnings */
|
||
};
|
||
/*
|
||
* Each VM instruction resulting from compiling a PHP script is represented
|
||
* by one of the following OP codes.
|
||
* The program consists of a linear sequence of operations. Each operation
|
||
* has an opcode and 3 operands.Operands P1 is an integer.
|
||
* Operand P2 is an unsigned integer and operand P3 is a memory address.
|
||
* Few opcodes use all 3 operands.
|
||
*/
|
||
enum ph7_vm_op {
|
||
PH7_OP_DONE = 1, /* Done */
|
||
PH7_OP_HALT, /* Halt */
|
||
PH7_OP_LOAD, /* Load memory object */
|
||
PH7_OP_LOADC, /* Load constant */
|
||
PH7_OP_LOAD_IDX, /* Load array entry */
|
||
PH7_OP_LOAD_MAP, /* Load hashmap('array') */
|
||
PH7_OP_LOAD_LIST, /* Load list */
|
||
PH7_OP_LOAD_CLOSURE, /* Load closure */
|
||
PH7_OP_NOOP, /* NOOP */
|
||
PH7_OP_JMP, /* Unconditional jump */
|
||
PH7_OP_JZ, /* Jump on zero (FALSE jump) */
|
||
PH7_OP_JNZ, /* Jump on non-zero (TRUE jump) */
|
||
PH7_OP_POP, /* Stack POP */
|
||
PH7_OP_CAT, /* Concatenation */
|
||
PH7_OP_CVT_INT, /* Integer cast */
|
||
PH7_OP_CVT_STR, /* String cast */
|
||
PH7_OP_CVT_REAL, /* Float cast */
|
||
PH7_OP_CALL, /* Function call */
|
||
PH7_OP_UMINUS, /* Unary minus '-'*/
|
||
PH7_OP_UPLUS, /* Unary plus '+'*/
|
||
PH7_OP_BITNOT, /* Bitwise not '~' */
|
||
PH7_OP_LNOT, /* Logical not '!' */
|
||
PH7_OP_MUL, /* Multiplication '*' */
|
||
PH7_OP_DIV, /* Division '/' */
|
||
PH7_OP_MOD, /* Modulus '%' */
|
||
PH7_OP_ADD, /* Add '+' */
|
||
PH7_OP_SUB, /* Sub '-' */
|
||
PH7_OP_SHL, /* Left shift '<<' */
|
||
PH7_OP_SHR, /* Right shift '>>' */
|
||
PH7_OP_LT, /* Less than '<' */
|
||
PH7_OP_LE, /* Less or equal '<=' */
|
||
PH7_OP_GT, /* Greater than '>' */
|
||
PH7_OP_GE, /* Greater or equal '>=' */
|
||
PH7_OP_EQ, /* Equal '==' */
|
||
PH7_OP_NEQ, /* Not equal '!=' */
|
||
PH7_OP_TEQ, /* Type equal '===' */
|
||
PH7_OP_TNE, /* Type not equal '!==' */
|
||
PH7_OP_BAND, /* Bitwise and '&' */
|
||
PH7_OP_BXOR, /* Bitwise xor '^' */
|
||
PH7_OP_BOR, /* Bitwise or '|' */
|
||
PH7_OP_LAND, /* Logical and '&&','and' */
|
||
PH7_OP_LOR, /* Logical or '||','or' */
|
||
PH7_OP_LXOR, /* Logical xor 'xor' */
|
||
PH7_OP_STORE, /* Store Object */
|
||
PH7_OP_STORE_IDX, /* Store indexed object */
|
||
PH7_OP_STORE_IDX_REF,/* Store indexed object by reference */
|
||
PH7_OP_PULL, /* Stack pull */
|
||
PH7_OP_SWAP, /* Stack swap */
|
||
PH7_OP_YIELD, /* Stack yield */
|
||
PH7_OP_CVT_BOOL, /* Boolean cast */
|
||
PH7_OP_CVT_NUMC, /* Numeric (integer,real or both) type cast */
|
||
PH7_OP_INCR, /* Increment ++ */
|
||
PH7_OP_DECR, /* Decrement -- */
|
||
PH7_OP_SEQ, /* 'eq' String equal: Strict string comparison */
|
||
PH7_OP_SNE, /* 'ne' String not equal: Strict string comparison */
|
||
PH7_OP_NEW, /* new */
|
||
PH7_OP_CLONE, /* clone */
|
||
PH7_OP_ADD_STORE, /* Add and store '+=' */
|
||
PH7_OP_SUB_STORE, /* Sub and store '-=' */
|
||
PH7_OP_MUL_STORE, /* Mul and store '*=' */
|
||
PH7_OP_DIV_STORE, /* Div and store '/=' */
|
||
PH7_OP_MOD_STORE, /* Mod and store '%=' */
|
||
PH7_OP_CAT_STORE, /* Cat and store '.=' */
|
||
PH7_OP_SHL_STORE, /* Shift left and store '>>=' */
|
||
PH7_OP_SHR_STORE, /* Shift right and store '<<=' */
|
||
PH7_OP_BAND_STORE, /* Bitand and store '&=' */
|
||
PH7_OP_BOR_STORE, /* Bitor and store '|=' */
|
||
PH7_OP_BXOR_STORE, /* Bitxor and store '^=' */
|
||
PH7_OP_CONSUME, /* Consume VM output */
|
||
PH7_OP_LOAD_REF, /* Load reference */
|
||
PH7_OP_STORE_REF, /* Store a reference to a variable*/
|
||
PH7_OP_MEMBER, /* Class member run-time access */
|
||
PH7_OP_UPLINK, /* Run-Time frame link */
|
||
PH7_OP_CVT_NULL, /* NULL cast */
|
||
PH7_OP_CVT_ARRAY, /* Array cast */
|
||
PH7_OP_CVT_OBJ, /* Object cast */
|
||
PH7_OP_FOREACH_INIT, /* For each init */
|
||
PH7_OP_FOREACH_STEP, /* For each step */
|
||
PH7_OP_IS_A, /* Instanceof */
|
||
PH7_OP_LOAD_EXCEPTION,/* Load an exception */
|
||
PH7_OP_POP_EXCEPTION, /* POP an exception */
|
||
PH7_OP_THROW, /* Throw exception */
|
||
PH7_OP_SWITCH, /* Switch operation */
|
||
PH7_OP_ERR_CTRL /* Error control */
|
||
};
|
||
/* -- END-OF INSTRUCTIONS -- */
|
||
/*
|
||
* Expression Operators ID.
|
||
*/
|
||
enum ph7_expr_id {
|
||
EXPR_OP_NEW = 1, /* new */
|
||
EXPR_OP_CLONE, /* clone */
|
||
EXPR_OP_ARROW, /* -> */
|
||
EXPR_OP_DC, /* :: */
|
||
EXPR_OP_SUBSCRIPT, /* []: Subscripting */
|
||
EXPR_OP_FUNC_CALL, /* func_call() */
|
||
EXPR_OP_INCR, /* ++ */
|
||
EXPR_OP_DECR, /* -- */
|
||
EXPR_OP_BITNOT, /* ~ */
|
||
EXPR_OP_UMINUS, /* Unary minus */
|
||
EXPR_OP_UPLUS, /* Unary plus */
|
||
EXPR_OP_TYPECAST, /* Type cast [i.e: (int),(float),(string)...] */
|
||
EXPR_OP_ALT, /* @ */
|
||
EXPR_OP_INSTOF, /* instanceof */
|
||
EXPR_OP_LOGNOT, /* logical not ! */
|
||
EXPR_OP_MUL, /* Multiplication */
|
||
EXPR_OP_DIV, /* division */
|
||
EXPR_OP_MOD, /* Modulus */
|
||
EXPR_OP_ADD, /* Addition */
|
||
EXPR_OP_SUB, /* Substraction */
|
||
EXPR_OP_DOT, /* Concatenation */
|
||
EXPR_OP_SHL, /* Left shift */
|
||
EXPR_OP_SHR, /* Right shift */
|
||
EXPR_OP_LT, /* Less than */
|
||
EXPR_OP_LE, /* Less equal */
|
||
EXPR_OP_GT, /* Greater than */
|
||
EXPR_OP_GE, /* Greater equal */
|
||
EXPR_OP_EQ, /* Equal == */
|
||
EXPR_OP_NE, /* Not equal != <> */
|
||
EXPR_OP_TEQ, /* Type equal === */
|
||
EXPR_OP_TNE, /* Type not equal !== */
|
||
EXPR_OP_SEQ, /* String equal 'eq' */
|
||
EXPR_OP_SNE, /* String not equal 'ne' */
|
||
EXPR_OP_BAND, /* Biwise and '&' */
|
||
EXPR_OP_REF, /* Reference operator '&' */
|
||
EXPR_OP_XOR, /* bitwise xor '^' */
|
||
EXPR_OP_BOR, /* bitwise or '|' */
|
||
EXPR_OP_LAND, /* Logical and '&&','and' */
|
||
EXPR_OP_LOR, /* Logical or '||','or'*/
|
||
EXPR_OP_LXOR, /* Logical xor 'xor' */
|
||
EXPR_OP_QUESTY, /* Ternary operator '?' */
|
||
EXPR_OP_ASSIGN, /* Assignment '=' */
|
||
EXPR_OP_ADD_ASSIGN, /* Combined operator: += */
|
||
EXPR_OP_SUB_ASSIGN, /* Combined operator: -= */
|
||
EXPR_OP_MUL_ASSIGN, /* Combined operator: *= */
|
||
EXPR_OP_DIV_ASSIGN, /* Combined operator: /= */
|
||
EXPR_OP_MOD_ASSIGN, /* Combined operator: %= */
|
||
EXPR_OP_DOT_ASSIGN, /* Combined operator: .= */
|
||
EXPR_OP_AND_ASSIGN, /* Combined operator: &= */
|
||
EXPR_OP_OR_ASSIGN, /* Combined operator: |= */
|
||
EXPR_OP_XOR_ASSIGN, /* Combined operator: ^= */
|
||
EXPR_OP_SHL_ASSIGN, /* Combined operator: <<= */
|
||
EXPR_OP_SHR_ASSIGN, /* Combined operator: >>= */
|
||
EXPR_OP_COMMA /* Comma expression */
|
||
};
|
||
/*
|
||
* Very high level tokens.
|
||
*/
|
||
#define PH7_TOKEN_RAW 0x001 /* Raw text [i.e: HTML,XML...] */
|
||
#define PH7_TOKEN_PHP 0x002 /* PHP chunk */
|
||
/*
|
||
* Lexer token codes
|
||
* The following set of constants are the tokens recognized
|
||
* by the lexer when processing PHP input.
|
||
* Important: Token values MUST BE A POWER OF TWO.
|
||
*/
|
||
#define PH7_TK_INTEGER 0x0000001 /* Integer */
|
||
#define PH7_TK_REAL 0x0000002 /* Real number */
|
||
#define PH7_TK_NUM (PH7_TK_INTEGER|PH7_TK_REAL) /* Numeric token,either integer or real */
|
||
#define PH7_TK_KEYWORD 0x0000004 /* Keyword [i.e: while,for,if,foreach...] */
|
||
#define PH7_TK_ID 0x0000008 /* Alphanumeric or UTF-8 stream */
|
||
#define PH7_TK_DOLLAR 0x0000010 /* '$' Dollar sign */
|
||
#define PH7_TK_OP 0x0000020 /* Operator [i.e: +,*,/...] */
|
||
#define PH7_TK_OCB 0x0000040 /* Open curly brace'{' */
|
||
#define PH7_TK_CCB 0x0000080 /* Closing curly brace'}' */
|
||
#define PH7_TK_NSSEP 0x0000100 /* Namespace separator '\' */
|
||
#define PH7_TK_LPAREN 0x0000200 /* Left parenthesis '(' */
|
||
#define PH7_TK_RPAREN 0x0000400 /* Right parenthesis ')' */
|
||
#define PH7_TK_OSB 0x0000800 /* Open square bracket '[' */
|
||
#define PH7_TK_CSB 0x0001000 /* Closing square bracket ']' */
|
||
#define PH7_TK_DSTR 0x0002000 /* Double quoted string "$str" */
|
||
#define PH7_TK_SSTR 0x0004000 /* Single quoted string 'str' */
|
||
#define PH7_TK_HEREDOC 0x0008000 /* Heredoc <<< */
|
||
#define PH7_TK_NOWDOC 0x0010000 /* Nowdoc <<< */
|
||
#define PH7_TK_COMMA 0x0020000 /* Comma ',' */
|
||
#define PH7_TK_SEMI 0x0040000 /* Semi-colon ";" */
|
||
#define PH7_TK_BSTR 0x0080000 /* Backtick quoted string [i.e: Shell command `date`] */
|
||
#define PH7_TK_COLON 0x0100000 /* single Colon ':' */
|
||
#define PH7_TK_AMPER 0x0200000 /* Ampersand '&' */
|
||
#define PH7_TK_EQUAL 0x0400000 /* Equal '=' */
|
||
#define PH7_TK_ARRAY_OP 0x0800000 /* Array operator '=>' */
|
||
#define PH7_TK_OTHER 0x1000000 /* Other symbols */
|
||
/*
|
||
* PHP keyword.
|
||
* These words have special meaning in PHP. Some of them represent things which look like
|
||
* functions, some look like constants, and so on, but they're not, really: they are language constructs.
|
||
* You cannot use any of the following words as constants, class names, function or method names.
|
||
* Using them as variable names is generally OK, but could lead to confusion.
|
||
*/
|
||
#define PH7_TKWRD_EXTENDS 1 /* extends */
|
||
#define PH7_TKWRD_ENDSWITCH 2 /* endswitch */
|
||
#define PH7_TKWRD_SWITCH 3 /* switch */
|
||
#define PH7_TKWRD_PRINT 4 /* print */
|
||
#define PH7_TKWRD_INTERFACE 5 /* interface */
|
||
#define PH7_TKWRD_ENDDEC 6 /* enddeclare */
|
||
#define PH7_TKWRD_DECLARE 7 /* declare */
|
||
/* The number '8' is reserved for PH7_TK_ID */
|
||
#define PH7_TKWRD_REQONCE 9 /* require_once */
|
||
#define PH7_TKWRD_REQUIRE 10 /* require */
|
||
#define PH7_TKWRD_ELIF 0x4000000 /* elseif: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_ELSE 0x8000000 /* else: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_IF 13 /* if */
|
||
#define PH7_TKWRD_FINAL 14 /* final */
|
||
#define PH7_TKWRD_LIST 15 /* list */
|
||
#define PH7_TKWRD_STATIC 16 /* static */
|
||
#define PH7_TKWRD_CASE 17 /* case */
|
||
#define PH7_TKWRD_SELF 18 /* self */
|
||
#define PH7_TKWRD_FUNCTION 19 /* function */
|
||
#define PH7_TKWRD_NAMESPACE 20 /* namespace */
|
||
#define PH7_TKWRD_ENDIF 0x400000 /* endif: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_CLONE 0x80 /* clone: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_NEW 0x100 /* new: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_CONST 22 /* const */
|
||
#define PH7_TKWRD_THROW 23 /* throw */
|
||
#define PH7_TKWRD_USE 24 /* use */
|
||
#define PH7_TKWRD_ENDWHILE 0x800000 /* endwhile: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_WHILE 26 /* while */
|
||
#define PH7_TKWRD_EVAL 27 /* eval */
|
||
#define PH7_TKWRD_VAR 28 /* var */
|
||
#define PH7_TKWRD_ARRAY 0x200 /* array: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_ABSTRACT 29 /* abstract */
|
||
#define PH7_TKWRD_TRY 30 /* try */
|
||
#define PH7_TKWRD_AND 0x400 /* and: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_DEFAULT 31 /* default */
|
||
#define PH7_TKWRD_CLASS 32 /* class */
|
||
#define PH7_TKWRD_AS 33 /* as */
|
||
#define PH7_TKWRD_CONTINUE 34 /* continue */
|
||
#define PH7_TKWRD_EXIT 35 /* exit */
|
||
#define PH7_TKWRD_DIE 36 /* die */
|
||
#define PH7_TKWRD_ECHO 37 /* echo */
|
||
#define PH7_TKWRD_GLOBAL 38 /* global */
|
||
#define PH7_TKWRD_IMPLEMENTS 39 /* implements */
|
||
#define PH7_TKWRD_INCONCE 40 /* include_once */
|
||
#define PH7_TKWRD_INCLUDE 41 /* include */
|
||
#define PH7_TKWRD_EMPTY 42 /* empty */
|
||
#define PH7_TKWRD_INSTANCEOF 0x800 /* instanceof: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_ISSET 43 /* isset */
|
||
#define PH7_TKWRD_PARENT 44 /* parent */
|
||
#define PH7_TKWRD_PRIVATE 45 /* private */
|
||
#define PH7_TKWRD_ENDFOR 0x1000000 /* endfor: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_END4EACH 0x2000000 /* endforeach: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_FOR 48 /* for */
|
||
#define PH7_TKWRD_FOREACH 49 /* foreach */
|
||
#define PH7_TKWRD_OR 0x1000 /* or: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_PROTECTED 50 /* protected */
|
||
#define PH7_TKWRD_DO 51 /* do */
|
||
#define PH7_TKWRD_PUBLIC 52 /* public */
|
||
#define PH7_TKWRD_CATCH 53 /* catch */
|
||
#define PH7_TKWRD_RETURN 54 /* return */
|
||
#define PH7_TKWRD_UNSET 0x2000 /* unset: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_XOR 0x4000 /* xor: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_BREAK 55 /* break */
|
||
#define PH7_TKWRD_GOTO 56 /* goto */
|
||
#define PH7_TKWRD_BOOL 0x8000 /* bool: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_INT 0x10000 /* int: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_FLOAT 0x20000 /* float: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_STRING 0x40000 /* string: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_OBJECT 0x80000 /* object: MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_SEQ 0x100000 /* String string comparison operator: 'eq' equal MUST BE A POWER OF TWO */
|
||
#define PH7_TKWRD_SNE 0x200000 /* String string comparison operator: 'ne' not equal MUST BE A POWER OF TWO */
|
||
/* JSON encoding/decoding related definition */
|
||
enum json_err_code{
|
||
JSON_ERROR_NONE = 0, /* No error has occurred. */
|
||
JSON_ERROR_DEPTH, /* The maximum stack depth has been exceeded. */
|
||
JSON_ERROR_STATE_MISMATCH, /* Occurs with underflow or with the modes mismatch. */
|
||
JSON_ERROR_CTRL_CHAR, /* Control character error, possibly incorrectly encoded. */
|
||
JSON_ERROR_SYNTAX, /* Syntax error. */
|
||
JSON_ERROR_UTF8 /* Malformed UTF-8 characters */
|
||
};
|
||
/* The following constants can be combined to form options for json_encode(). */
|
||
#define JSON_HEX_TAG 0x01 /* All < and > are converted to \u003C and \u003E. */
|
||
#define JSON_HEX_AMP 0x02 /* All &s are converted to \u0026. */
|
||
#define JSON_HEX_APOS 0x04 /* All ' are converted to \u0027. */
|
||
#define JSON_HEX_QUOT 0x08 /* All " are converted to \u0022. */
|
||
#define JSON_FORCE_OBJECT 0x10 /* Outputs an object rather than an array */
|
||
#define JSON_NUMERIC_CHECK 0x20 /* Encodes numeric strings as numbers. */
|
||
#define JSON_BIGINT_AS_STRING 0x40 /* Not used */
|
||
#define JSON_PRETTY_PRINT 0x80 /* Use whitespace in returned data to format it.*/
|
||
#define JSON_UNESCAPED_SLASHES 0x100 /* Don't escape '/' */
|
||
#define JSON_UNESCAPED_UNICODE 0x200 /* Not used */
|
||
/* memobj.c function prototypes */
|
||
PH7_PRIVATE sxi32 PH7_MemObjDump(SyBlob *pOut,ph7_value *pObj,int ShowType,int nTab,int nDepth,int isRef);
|
||
PH7_PRIVATE const char * PH7_MemObjTypeDump(ph7_value *pVal);
|
||
PH7_PRIVATE sxi32 PH7_MemObjAdd(ph7_value *pObj1,ph7_value *pObj2,int bAddStore);
|
||
PH7_PRIVATE sxi32 PH7_MemObjCmp(ph7_value *pObj1,ph7_value *pObj2,int bStrict,int iNest);
|
||
PH7_PRIVATE sxi32 PH7_MemObjInitFromString(ph7_vm *pVm,ph7_value *pObj,const SyString *pVal);
|
||
PH7_PRIVATE sxi32 PH7_MemObjInitFromArray(ph7_vm *pVm,ph7_value *pObj,ph7_hashmap *pArray);
|
||
#if 0
|
||
/* Not used in the current release of the PH7 engine */
|
||
PH7_PRIVATE sxi32 PH7_MemObjInitFromReal(ph7_vm *pVm,ph7_value *pObj,ph7_real rVal);
|
||
#endif
|
||
PH7_PRIVATE sxi32 PH7_MemObjInitFromInt(ph7_vm *pVm,ph7_value *pObj,sxi64 iVal);
|
||
PH7_PRIVATE sxi32 PH7_MemObjInitFromBool(ph7_vm *pVm,ph7_value *pObj,sxi32 iVal);
|
||
PH7_PRIVATE sxi32 PH7_MemObjInit(ph7_vm *pVm,ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjStringAppend(ph7_value *pObj,const char *zData,sxu32 nLen);
|
||
#if 0
|
||
/* Not used in the current release of the PH7 engine */
|
||
PH7_PRIVATE sxi32 PH7_MemObjStringFormat(ph7_value *pObj,const char *zFormat,va_list ap);
|
||
#endif
|
||
PH7_PRIVATE sxi32 PH7_MemObjStore(ph7_value *pSrc,ph7_value *pDest);
|
||
PH7_PRIVATE sxi32 PH7_MemObjLoad(ph7_value *pSrc,ph7_value *pDest);
|
||
PH7_PRIVATE sxi32 PH7_MemObjRelease(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToNumeric(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjTryInteger(ph7_value *pObj);
|
||
PH7_PRIVATE ProcMemObjCast PH7_MemObjCastMethod(sxi32 iFlags);
|
||
PH7_PRIVATE sxi32 PH7_MemObjIsNumeric(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjIsEmpty(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToHashmap(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToObject(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToString(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToNull(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToReal(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToInteger(ph7_value *pObj);
|
||
PH7_PRIVATE sxi32 PH7_MemObjToBool(ph7_value *pObj);
|
||
PH7_PRIVATE sxi64 PH7_TokenValueToInt64(SyString *pData);
|
||
/* lex.c function prototypes */
|
||
PH7_PRIVATE sxi32 PH7_TokenizeRawText(const char *zInput,sxu32 nLen,SySet *pOut);
|
||
PH7_PRIVATE sxi32 PH7_TokenizePHP(const char *zInput,sxu32 nLen,sxu32 nLineStart,SySet *pOut);
|
||
/* vm.c function prototypes */
|
||
PH7_PRIVATE void PH7_VmReleaseContextValue(ph7_context *pCtx,ph7_value *pValue);
|
||
PH7_PRIVATE sxi32 PH7_VmInitFuncState(ph7_vm *pVm,ph7_vm_func *pFunc,const char *zName,sxu32 nByte,
|
||
sxi32 iFlags,void *pUserData);
|
||
PH7_PRIVATE sxi32 PH7_VmInstallUserFunction(ph7_vm *pVm,ph7_vm_func *pFunc,SyString *pName);
|
||
PH7_PRIVATE sxi32 PH7_VmCreateClassInstanceFrame(ph7_vm *pVm,ph7_class_instance *pObj);
|
||
PH7_PRIVATE sxi32 PH7_VmRefObjRemove(ph7_vm *pVm,sxu32 nIdx,SyHashEntry *pEntry,ph7_hashmap_node *pMapEntry);
|
||
PH7_PRIVATE sxi32 PH7_VmRefObjInstall(ph7_vm *pVm,sxu32 nIdx,SyHashEntry *pEntry,ph7_hashmap_node *pMapEntry,sxi32 iFlags);
|
||
PH7_PRIVATE sxi32 PH7_VmPushFilePath(ph7_vm *pVm,const char *zPath,int nLen,sxu8 bMain,sxi32 *pNew);
|
||
PH7_PRIVATE ph7_class * PH7_VmExtractClass(ph7_vm *pVm,const char *zName,sxu32 nByte,sxi32 iLoadable,sxi32 iNest);
|
||
PH7_PRIVATE sxi32 PH7_VmRegisterConstant(ph7_vm *pVm,const SyString *pName,ProcConstant xExpand,void *pUserData);
|
||
PH7_PRIVATE sxi32 PH7_VmInstallForeignFunction(ph7_vm *pVm,const SyString *pName,ProchHostFunction xFunc,void *pUserData);
|
||
PH7_PRIVATE sxi32 PH7_VmInstallClass(ph7_vm *pVm,ph7_class *pClass);
|
||
PH7_PRIVATE sxi32 PH7_VmBlobConsumer(const void *pSrc,unsigned int nLen,void *pUserData);
|
||
PH7_PRIVATE ph7_value * PH7_ReserveMemObj(ph7_vm *pVm);
|
||
PH7_PRIVATE ph7_value * PH7_ReserveConstObj(ph7_vm *pVm,sxu32 *pIndex);
|
||
PH7_PRIVATE sxi32 PH7_VmOutputConsume(ph7_vm *pVm,SyString *pString);
|
||
PH7_PRIVATE sxi32 PH7_VmOutputConsumeAp(ph7_vm *pVm,const char *zFormat,va_list ap);
|
||
PH7_PRIVATE sxi32 PH7_VmThrowErrorAp(ph7_vm *pVm,SyString *pFuncName,sxi32 iErr,const char *zFormat,va_list ap);
|
||
PH7_PRIVATE sxi32 PH7_VmThrowError(ph7_vm *pVm,SyString *pFuncName,sxi32 iErr,const char *zMessage);
|
||
PH7_PRIVATE void PH7_VmExpandConstantValue(ph7_value *pVal,void *pUserData);
|
||
PH7_PRIVATE sxi32 PH7_VmDump(ph7_vm *pVm,ProcConsumer xConsumer,void *pUserData);
|
||
PH7_PRIVATE sxi32 PH7_VmInit(ph7_vm *pVm,ph7 *pEngine);
|
||
PH7_PRIVATE sxi32 PH7_VmConfigure(ph7_vm *pVm,sxi32 nOp,va_list ap);
|
||
PH7_PRIVATE sxi32 PH7_VmByteCodeExec(ph7_vm *pVm);
|
||
PH7_PRIVATE sxi32 PH7_VmRelease(ph7_vm *pVm);
|
||
PH7_PRIVATE sxi32 PH7_VmReset(ph7_vm *pVm);
|
||
PH7_PRIVATE sxi32 PH7_VmMakeReady(ph7_vm *pVm);
|
||
PH7_PRIVATE sxu32 PH7_VmInstrLength(ph7_vm *pVm);
|
||
PH7_PRIVATE VmInstr * PH7_VmPopInstr(ph7_vm *pVm);
|
||
PH7_PRIVATE VmInstr * PH7_VmPeekInstr(ph7_vm *pVm);
|
||
PH7_PRIVATE VmInstr * PH7_VmPeekNextInstr(ph7_vm *pVm);
|
||
PH7_PRIVATE VmInstr *PH7_VmGetInstr(ph7_vm *pVm,sxu32 nIndex);
|
||
PH7_PRIVATE SySet * PH7_VmGetByteCodeContainer(ph7_vm *pVm);
|
||
PH7_PRIVATE sxi32 PH7_VmSetByteCodeContainer(ph7_vm *pVm,SySet *pContainer);
|
||
PH7_PRIVATE sxi32 PH7_VmEmitInstr(ph7_vm *pVm,sxi32 iOp,sxi32 iP1,sxu32 iP2,void *p3,sxu32 *pIndex);
|
||
PH7_PRIVATE sxu32 PH7_VmRandomNum(ph7_vm *pVm);
|
||
PH7_PRIVATE sxi32 PH7_VmCallClassMethod(ph7_vm *pVm,ph7_class_instance *pThis,ph7_class_method *pMethod,
|
||
ph7_value *pResult,int nArg,ph7_value **apArg);
|
||
PH7_PRIVATE sxi32 PH7_VmCallUserFunction(ph7_vm *pVm,ph7_value *pFunc,int nArg,ph7_value **apArg,ph7_value *pResult);
|
||
PH7_PRIVATE sxi32 PH7_VmCallUserFunctionAp(ph7_vm *pVm,ph7_value *pFunc,ph7_value *pResult,...);
|
||
PH7_PRIVATE sxi32 PH7_VmUnsetMemObj(ph7_vm *pVm,sxu32 nObjIdx,int bForce);
|
||
PH7_PRIVATE void PH7_VmRandomString(ph7_vm *pVm,char *zBuf,int nLen);
|
||
PH7_PRIVATE ph7_class * PH7_VmPeekTopClass(ph7_vm *pVm);
|
||
PH7_PRIVATE int PH7_VmIsCallable(ph7_vm *pVm,ph7_value *pValue,int CallInvoke);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE const ph7_io_stream * PH7_VmGetStreamDevice(ph7_vm *pVm,const char **pzDevice,int nByte);
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
PH7_PRIVATE int PH7_Utf8Read(
|
||
const unsigned char *z, /* First byte of UTF-8 character */
|
||
const unsigned char *zTerm, /* Pretend this byte is 0x00 */
|
||
const unsigned char **pzNext /* Write first byte past UTF-8 char here */
|
||
);
|
||
/* parse.c function prototypes */
|
||
PH7_PRIVATE int PH7_IsLangConstruct(sxu32 nKeyID,sxu8 bCheckFunc);
|
||
PH7_PRIVATE sxi32 PH7_ExprMakeTree(ph7_gen_state *pGen,SySet *pExprNode,ph7_expr_node **ppRoot);
|
||
PH7_PRIVATE sxi32 PH7_GetNextExpr(SyToken *pStart,SyToken *pEnd,SyToken **ppNext);
|
||
PH7_PRIVATE void PH7_DelimitNestedTokens(SyToken *pIn,SyToken *pEnd,sxu32 nTokStart,sxu32 nTokEnd,SyToken **ppEnd);
|
||
PH7_PRIVATE const ph7_expr_op * PH7_ExprExtractOperator(SyString *pStr,SyToken *pLast);
|
||
PH7_PRIVATE sxi32 PH7_ExprFreeTree(ph7_gen_state *pGen,SySet *pNodeSet);
|
||
/* compile.c function prototypes */
|
||
PH7_PRIVATE ProcNodeConstruct PH7_GetNodeHandler(sxu32 nNodeType);
|
||
PH7_PRIVATE sxi32 PH7_CompileLangConstruct(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_CompileVariable(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_CompileLiteral(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_CompileSimpleString(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_CompileString(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_CompileArray(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_CompileList(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_CompileAnnonFunc(ph7_gen_state *pGen,sxi32 iCompileFlag);
|
||
PH7_PRIVATE sxi32 PH7_InitCodeGenerator(ph7_vm *pVm,ProcConsumer xErr,void *pErrData);
|
||
PH7_PRIVATE sxi32 PH7_ResetCodeGenerator(ph7_vm *pVm,ProcConsumer xErr,void *pErrData);
|
||
PH7_PRIVATE sxi32 PH7_GenCompileError(ph7_gen_state *pGen,sxi32 nErrType,sxu32 nLine,const char *zFormat,...);
|
||
PH7_PRIVATE sxi32 PH7_CompileScript(ph7_vm *pVm,SyString *pScript,sxi32 iFlags);
|
||
/* constant.c function prototypes */
|
||
PH7_PRIVATE void PH7_RegisterBuiltInConstant(ph7_vm *pVm);
|
||
/* builtin.c function prototypes */
|
||
PH7_PRIVATE void PH7_RegisterBuiltInFunction(ph7_vm *pVm);
|
||
/* hashmap.c function prototypes */
|
||
PH7_PRIVATE ph7_hashmap * PH7_NewHashmap(ph7_vm *pVm,sxu32 (*xIntHash)(sxi64),sxu32 (*xBlobHash)(const void *,sxu32));
|
||
PH7_PRIVATE sxi32 PH7_HashmapCreateSuper(ph7_vm *pVm);
|
||
PH7_PRIVATE sxi32 PH7_HashmapRelease(ph7_hashmap *pMap,int FreeDS);
|
||
PH7_PRIVATE void PH7_HashmapUnref(ph7_hashmap *pMap);
|
||
PH7_PRIVATE sxi32 PH7_HashmapLookup(ph7_hashmap *pMap,ph7_value *pKey,ph7_hashmap_node **ppNode);
|
||
PH7_PRIVATE sxi32 PH7_HashmapInsert(ph7_hashmap *pMap,ph7_value *pKey,ph7_value *pVal);
|
||
PH7_PRIVATE sxi32 PH7_HashmapInsertByRef(ph7_hashmap *pMap,ph7_value *pKey,sxu32 nRefIdx);
|
||
PH7_PRIVATE sxi32 PH7_HashmapUnion(ph7_hashmap *pLeft,ph7_hashmap *pRight);
|
||
PH7_PRIVATE void PH7_HashmapUnlinkNode(ph7_hashmap_node *pNode,int bRestore);
|
||
PH7_PRIVATE sxi32 PH7_HashmapDup(ph7_hashmap *pSrc,ph7_hashmap *pDest);
|
||
PH7_PRIVATE sxi32 PH7_HashmapCmp(ph7_hashmap *pLeft,ph7_hashmap *pRight,int bStrict);
|
||
PH7_PRIVATE void PH7_HashmapResetLoopCursor(ph7_hashmap *pMap);
|
||
PH7_PRIVATE ph7_hashmap_node * PH7_HashmapGetNextEntry(ph7_hashmap *pMap);
|
||
PH7_PRIVATE void PH7_HashmapExtractNodeValue(ph7_hashmap_node *pNode,ph7_value *pValue,int bStore);
|
||
PH7_PRIVATE void PH7_HashmapExtractNodeKey(ph7_hashmap_node *pNode,ph7_value *pKey);
|
||
PH7_PRIVATE void PH7_RegisterHashmapFunctions(ph7_vm *pVm);
|
||
PH7_PRIVATE sxi32 PH7_HashmapDump(SyBlob *pOut,ph7_hashmap *pMap,int ShowType,int nTab,int nDepth);
|
||
PH7_PRIVATE sxi32 PH7_HashmapWalk(ph7_hashmap *pMap,int (*xWalk)(ph7_value *,ph7_value *,void *),void *pUserData);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE int PH7_HashmapValuesToSet(ph7_hashmap *pMap,SySet *pOut);
|
||
/* builtin.c function prototypes */
|
||
PH7_PRIVATE sxi32 PH7_InputFormat(int (*xConsumer)(ph7_context *,const char *,int,void *),
|
||
ph7_context *pCtx,const char *zIn,int nByte,int nArg,ph7_value **apArg,void *pUserData,int vf);
|
||
PH7_PRIVATE sxi32 PH7_ProcessCsv(const char *zInput,int nByte,int delim,int encl,
|
||
int escape,sxi32 (*xConsumer)(const char *,int,void *),void *pUserData);
|
||
PH7_PRIVATE sxi32 PH7_CsvConsumer(const char *zToken,int nTokenLen,void *pUserData);
|
||
PH7_PRIVATE sxi32 PH7_StripTagsFromString(ph7_context *pCtx,const char *zIn,int nByte,const char *zTaglist,int nTaglen);
|
||
PH7_PRIVATE sxi32 PH7_ParseIniString(ph7_context *pCtx,const char *zIn,sxu32 nByte,int bProcessSection);
|
||
#endif
|
||
/* oo.c function prototypes */
|
||
PH7_PRIVATE ph7_class * PH7_NewRawClass(ph7_vm *pVm,const SyString *pName,sxu32 nLine);
|
||
PH7_PRIVATE ph7_class_attr * PH7_NewClassAttr(ph7_vm *pVm,const SyString *pName,sxu32 nLine,sxi32 iProtection,sxi32 iFlags);
|
||
PH7_PRIVATE ph7_class_method * PH7_NewClassMethod(ph7_vm *pVm,ph7_class *pClass,const SyString *pName,sxu32 nLine,
|
||
sxi32 iProtection,sxi32 iFlags,sxi32 iFuncFlags);
|
||
PH7_PRIVATE ph7_class_method * PH7_ClassExtractMethod(ph7_class *pClass,const char *zName,sxu32 nByte);
|
||
PH7_PRIVATE ph7_class_attr * PH7_ClassExtractAttribute(ph7_class *pClass,const char *zName,sxu32 nByte);
|
||
PH7_PRIVATE sxi32 PH7_ClassInstallAttr(ph7_class *pClass,ph7_class_attr *pAttr);
|
||
PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass,ph7_class_method *pMeth);
|
||
PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen,ph7_class *pSub,ph7_class *pBase);
|
||
PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub,ph7_class *pBase);
|
||
PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain,ph7_class *pInterface);
|
||
PH7_PRIVATE ph7_class_instance * PH7_NewClassInstance(ph7_vm *pVm,ph7_class *pClass);
|
||
PH7_PRIVATE ph7_class_instance * PH7_CloneClassInstance(ph7_class_instance *pSrc);
|
||
PH7_PRIVATE sxi32 PH7_ClassInstanceCmp(ph7_class_instance *pLeft,ph7_class_instance *pRight,int bStrict,int iNest);
|
||
PH7_PRIVATE void PH7_ClassInstanceUnref(ph7_class_instance *pThis);
|
||
PH7_PRIVATE sxi32 PH7_ClassInstanceDump(SyBlob *pOut,ph7_class_instance *pThis,int ShowType,int nTab,int nDepth);
|
||
PH7_PRIVATE sxi32 PH7_ClassInstanceCallMagicMethod(ph7_vm *pVm,ph7_class *pClass,ph7_class_instance *pThis,const char *zMethod,
|
||
sxu32 nByte,const SyString *pAttrName);
|
||
PH7_PRIVATE ph7_value * PH7_ClassInstanceExtractAttrValue(ph7_class_instance *pThis,VmClassAttr *pAttr);
|
||
PH7_PRIVATE sxi32 PH7_ClassInstanceToHashmap(ph7_class_instance *pThis,ph7_hashmap *pMap);
|
||
PH7_PRIVATE sxi32 PH7_ClassInstanceWalk(ph7_class_instance *pThis,
|
||
int (*xWalk)(const char *,ph7_value *,void *),void *pUserData);
|
||
PH7_PRIVATE ph7_value * PH7_ClassInstanceFetchAttr(ph7_class_instance *pThis,const SyString *pName);
|
||
/* vfs.c */
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE void * PH7_StreamOpenHandle(ph7_vm *pVm,const ph7_io_stream *pStream,const char *zFile,
|
||
int iFlags,int use_include,ph7_value *pResource,int bPushInclude,int *pNew);
|
||
PH7_PRIVATE sxi32 PH7_StreamReadWholeFile(void *pHandle,const ph7_io_stream *pStream,SyBlob *pOut);
|
||
PH7_PRIVATE void PH7_StreamCloseHandle(const ph7_io_stream *pStream,void *pHandle);
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
PH7_PRIVATE const char * PH7_ExtractDirName(const char *zPath,int nByte,int *pLen);
|
||
PH7_PRIVATE sxi32 PH7_RegisterIORoutine(ph7_vm *pVm);
|
||
PH7_PRIVATE const ph7_vfs * PH7_ExportBuiltinVfs(void);
|
||
PH7_PRIVATE void * PH7_ExportStdin(ph7_vm *pVm);
|
||
PH7_PRIVATE void * PH7_ExportStdout(ph7_vm *pVm);
|
||
PH7_PRIVATE void * PH7_ExportStderr(ph7_vm *pVm);
|
||
/* lib.c function prototypes */
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE sxi32 SyXMLParserInit(SyXMLParser *pParser,SyMemBackend *pAllocator,sxi32 iFlags);
|
||
PH7_PRIVATE sxi32 SyXMLParserSetEventHandler(SyXMLParser *pParser,
|
||
void *pUserData,
|
||
ProcXMLStartTagHandler xStartTag,
|
||
ProcXMLTextHandler xRaw,
|
||
ProcXMLSyntaxErrorHandler xErr,
|
||
ProcXMLStartDocument xStartDoc,
|
||
ProcXMLEndTagHandler xEndTag,
|
||
ProcXMLPIHandler xPi,
|
||
ProcXMLEndDocument xEndDoc,
|
||
ProcXMLDoctypeHandler xDoctype,
|
||
ProcXMLNameSpaceStart xNameSpace,
|
||
ProcXMLNameSpaceEnd xNameSpaceEnd
|
||
);
|
||
PH7_PRIVATE sxi32 SyXMLProcess(SyXMLParser *pParser,const char *zInput,sxu32 nByte);
|
||
PH7_PRIVATE sxi32 SyXMLParserRelease(SyXMLParser *pParser);
|
||
PH7_PRIVATE sxi32 SyArchiveInit(SyArchive *pArch,SyMemBackend *pAllocator,ProcHash xHash,ProcRawStrCmp xCmp);
|
||
PH7_PRIVATE sxi32 SyArchiveRelease(SyArchive *pArch);
|
||
PH7_PRIVATE sxi32 SyArchiveResetLoopCursor(SyArchive *pArch);
|
||
PH7_PRIVATE sxi32 SyArchiveGetNextEntry(SyArchive *pArch,SyArchiveEntry **ppEntry);
|
||
PH7_PRIVATE sxi32 SyZipExtractFromBuf(SyArchive *pArch,const char *zBuf,sxu32 nLen);
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE sxi32 SyBinToHexConsumer(const void *pIn,sxu32 nLen,ProcConsumer xConsumer,void *pConsumerData);
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
#ifndef PH7_DISABLE_HASH_FUNC
|
||
PH7_PRIVATE sxu32 SyCrc32(const void *pSrc,sxu32 nLen);
|
||
PH7_PRIVATE void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len);
|
||
PH7_PRIVATE void MD5Final(unsigned char digest[16], MD5Context *ctx);
|
||
PH7_PRIVATE sxi32 MD5Init(MD5Context *pCtx);
|
||
PH7_PRIVATE sxi32 SyMD5Compute(const void *pIn,sxu32 nLen,unsigned char zDigest[16]);
|
||
PH7_PRIVATE void SHA1Init(SHA1Context *context);
|
||
PH7_PRIVATE void SHA1Update(SHA1Context *context,const unsigned char *data,unsigned int len);
|
||
PH7_PRIVATE void SHA1Final(SHA1Context *context, unsigned char digest[20]);
|
||
PH7_PRIVATE sxi32 SySha1Compute(const void *pIn,sxu32 nLen,unsigned char zDigest[20]);
|
||
#endif
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
PH7_PRIVATE sxi32 SyRandomness(SyPRNGCtx *pCtx,void *pBuf,sxu32 nLen);
|
||
PH7_PRIVATE sxi32 SyRandomnessInit(SyPRNGCtx *pCtx,ProcRandomSeed xSeed,void *pUserData);
|
||
PH7_PRIVATE sxu32 SyBufferFormat(char *zBuf,sxu32 nLen,const char *zFormat,...);
|
||
PH7_PRIVATE sxu32 SyBlobFormatAp(SyBlob *pBlob,const char *zFormat,va_list ap);
|
||
PH7_PRIVATE sxu32 SyBlobFormat(SyBlob *pBlob,const char *zFormat,...);
|
||
PH7_PRIVATE sxi32 SyProcFormat(ProcConsumer xConsumer,void *pData,const char *zFormat,...);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE const char *SyTimeGetMonth(sxi32 iMonth);
|
||
PH7_PRIVATE const char *SyTimeGetDay(sxi32 iDay);
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
PH7_PRIVATE sxi32 SyUriDecode(const char *zSrc,sxu32 nLen,ProcConsumer xConsumer,void *pUserData,int bUTF8);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE sxi32 SyUriEncode(const char *zSrc,sxu32 nLen,ProcConsumer xConsumer,void *pUserData);
|
||
#endif
|
||
PH7_PRIVATE sxi32 SyLexRelease(SyLex *pLex);
|
||
PH7_PRIVATE sxi32 SyLexTokenizeInput(SyLex *pLex,const char *zInput,sxu32 nLen,void *pCtxData,ProcSort xSort,ProcCmp xCmp);
|
||
PH7_PRIVATE sxi32 SyLexInit(SyLex *pLex,SySet *pSet,ProcTokenizer xTokenizer,void *pUserData);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE sxi32 SyBase64Decode(const char *zB64,sxu32 nLen,ProcConsumer xConsumer,void *pUserData);
|
||
PH7_PRIVATE sxi32 SyBase64Encode(const char *zSrc,sxu32 nLen,ProcConsumer xConsumer,void *pUserData);
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
PH7_PRIVATE sxi32 SyStrToReal(const char *zSrc,sxu32 nLen,void *pOutVal,const char **zRest);
|
||
PH7_PRIVATE sxi32 SyBinaryStrToInt64(const char *zSrc,sxu32 nLen,void *pOutVal,const char **zRest);
|
||
PH7_PRIVATE sxi32 SyOctalStrToInt64(const char *zSrc,sxu32 nLen,void *pOutVal,const char **zRest);
|
||
PH7_PRIVATE sxi32 SyHexStrToInt64(const char *zSrc,sxu32 nLen,void *pOutVal,const char **zRest);
|
||
PH7_PRIVATE sxi32 SyHexToint(sxi32 c);
|
||
PH7_PRIVATE sxi32 SyStrToInt64(const char *zSrc,sxu32 nLen,void *pOutVal,const char **zRest);
|
||
PH7_PRIVATE sxi32 SyStrToInt32(const char *zSrc,sxu32 nLen,void *pOutVal,const char **zRest);
|
||
PH7_PRIVATE sxi32 SyStrIsNumeric(const char *zSrc,sxu32 nLen,sxu8 *pReal,const char **pzTail);
|
||
PH7_PRIVATE SyHashEntry *SyHashLastEntry(SyHash *pHash);
|
||
PH7_PRIVATE sxi32 SyHashInsert(SyHash *pHash,const void *pKey,sxu32 nKeyLen,void *pUserData);
|
||
PH7_PRIVATE sxi32 SyHashForEach(SyHash *pHash,sxi32(*xStep)(SyHashEntry *,void *),void *pUserData);
|
||
PH7_PRIVATE SyHashEntry *SyHashGetNextEntry(SyHash *pHash);
|
||
PH7_PRIVATE sxi32 SyHashResetLoopCursor(SyHash *pHash);
|
||
PH7_PRIVATE sxi32 SyHashDeleteEntry2(SyHashEntry *pEntry);
|
||
PH7_PRIVATE sxi32 SyHashDeleteEntry(SyHash *pHash,const void *pKey,sxu32 nKeyLen,void **ppUserData);
|
||
PH7_PRIVATE SyHashEntry *SyHashGet(SyHash *pHash,const void *pKey,sxu32 nKeyLen);
|
||
PH7_PRIVATE sxi32 SyHashRelease(SyHash *pHash);
|
||
PH7_PRIVATE sxi32 SyHashInit(SyHash *pHash,SyMemBackend *pAllocator,ProcHash xHash,ProcCmp xCmp);
|
||
PH7_PRIVATE sxu32 SyStrHash(const void *pSrc,sxu32 nLen);
|
||
PH7_PRIVATE void *SySetAt(SySet *pSet,sxu32 nIdx);
|
||
PH7_PRIVATE void *SySetPop(SySet *pSet);
|
||
PH7_PRIVATE void *SySetPeek(SySet *pSet);
|
||
PH7_PRIVATE sxi32 SySetRelease(SySet *pSet);
|
||
PH7_PRIVATE sxi32 SySetReset(SySet *pSet);
|
||
PH7_PRIVATE sxi32 SySetResetCursor(SySet *pSet);
|
||
PH7_PRIVATE sxi32 SySetGetNextEntry(SySet *pSet,void **ppEntry);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE void * SySetPeekCurrentEntry(SySet *pSet);
|
||
#endif /* PH7_DISABLE_BUILTIN_FUNC */
|
||
PH7_PRIVATE sxi32 SySetTruncate(SySet *pSet,sxu32 nNewSize);
|
||
PH7_PRIVATE sxi32 SySetAlloc(SySet *pSet,sxi32 nItem);
|
||
PH7_PRIVATE sxi32 SySetPut(SySet *pSet,const void *pItem);
|
||
PH7_PRIVATE sxi32 SySetInit(SySet *pSet,SyMemBackend *pAllocator,sxu32 ElemSize);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE sxi32 SyBlobSearch(const void *pBlob,sxu32 nLen,const void *pPattern,sxu32 pLen,sxu32 *pOfft);
|
||
#endif
|
||
PH7_PRIVATE sxi32 SyBlobRelease(SyBlob *pBlob);
|
||
PH7_PRIVATE sxi32 SyBlobReset(SyBlob *pBlob);
|
||
PH7_PRIVATE sxi32 SyBlobCmp(SyBlob *pLeft,SyBlob *pRight);
|
||
PH7_PRIVATE sxi32 SyBlobDup(SyBlob *pSrc,SyBlob *pDest);
|
||
PH7_PRIVATE sxi32 SyBlobNullAppend(SyBlob *pBlob);
|
||
PH7_PRIVATE sxi32 SyBlobAppend(SyBlob *pBlob,const void *pData,sxu32 nSize);
|
||
PH7_PRIVATE sxi32 SyBlobReadOnly(SyBlob *pBlob,const void *pData,sxu32 nByte);
|
||
PH7_PRIVATE sxi32 SyBlobInit(SyBlob *pBlob,SyMemBackend *pAllocator);
|
||
PH7_PRIVATE sxi32 SyBlobInitFromBuf(SyBlob *pBlob,void *pBuffer,sxu32 nSize);
|
||
PH7_PRIVATE char *SyMemBackendStrDup(SyMemBackend *pBackend,const char *zSrc,sxu32 nSize);
|
||
PH7_PRIVATE void *SyMemBackendDup(SyMemBackend *pBackend,const void *pSrc,sxu32 nSize);
|
||
PH7_PRIVATE sxi32 SyMemBackendRelease(SyMemBackend *pBackend);
|
||
PH7_PRIVATE sxi32 SyMemBackendInitFromOthers(SyMemBackend *pBackend,const SyMemMethods *pMethods,ProcMemError xMemErr,void *pUserData);
|
||
PH7_PRIVATE sxi32 SyMemBackendInit(SyMemBackend *pBackend,ProcMemError xMemErr,void *pUserData);
|
||
PH7_PRIVATE sxi32 SyMemBackendInitFromParent(SyMemBackend *pBackend,SyMemBackend *pParent);
|
||
#if 0
|
||
/* Not used in the current release of the PH7 engine */
|
||
PH7_PRIVATE void *SyMemBackendPoolRealloc(SyMemBackend *pBackend,void *pOld,sxu32 nByte);
|
||
#endif
|
||
PH7_PRIVATE sxi32 SyMemBackendPoolFree(SyMemBackend *pBackend,void *pChunk);
|
||
PH7_PRIVATE void *SyMemBackendPoolAlloc(SyMemBackend *pBackend,sxu32 nByte);
|
||
PH7_PRIVATE sxi32 SyMemBackendFree(SyMemBackend *pBackend,void *pChunk);
|
||
PH7_PRIVATE void *SyMemBackendRealloc(SyMemBackend *pBackend,void *pOld,sxu32 nByte);
|
||
PH7_PRIVATE void *SyMemBackendAlloc(SyMemBackend *pBackend,sxu32 nByte);
|
||
#if defined(PH7_ENABLE_THREADS)
|
||
PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend,const SyMutexMethods *pMethods);
|
||
PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend);
|
||
#endif
|
||
PH7_PRIVATE sxu32 SyMemcpy(const void *pSrc,void *pDest,sxu32 nLen);
|
||
PH7_PRIVATE sxi32 SyMemcmp(const void *pB1,const void *pB2,sxu32 nSize);
|
||
PH7_PRIVATE void SyZero(void *pSrc,sxu32 nSize);
|
||
PH7_PRIVATE sxi32 SyStrnicmp(const char *zLeft,const char *zRight,sxu32 SLen);
|
||
PH7_PRIVATE sxi32 SyStrnmicmp(const void *pLeft, const void *pRight,sxu32 SLen);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE sxi32 SyStrncmp(const char *zLeft,const char *zRight,sxu32 nLen);
|
||
#endif
|
||
PH7_PRIVATE sxi32 SyByteListFind(const char *zSrc,sxu32 nLen,const char *zList,sxu32 *pFirstPos);
|
||
#ifndef PH7_DISABLE_BUILTIN_FUNC
|
||
PH7_PRIVATE sxi32 SyByteFind2(const char *zStr,sxu32 nLen,sxi32 c,sxu32 *pPos);
|
||
#endif
|
||
PH7_PRIVATE sxi32 SyByteFind(const char *zStr,sxu32 nLen,sxi32 c,sxu32 *pPos);
|
||
PH7_PRIVATE sxu32 SyStrlen(const char *zSrc);
|
||
#if defined(PH7_ENABLE_THREADS)
|
||
PH7_PRIVATE const SyMutexMethods *SyMutexExportMethods(void);
|
||
PH7_PRIVATE sxi32 SyMemBackendMakeThreadSafe(SyMemBackend *pBackend,const SyMutexMethods *pMethods);
|
||
PH7_PRIVATE sxi32 SyMemBackendDisbaleMutexing(SyMemBackend *pBackend);
|
||
#endif
|
||
#endif /* __PH7INT_H__ */
|
||
/*
|
||
* ----------------------------------------------------------
|
||
* File: vm.c
|
||
* MD5: fed926a5df137d2896badd8911a0b752
|
||
* ----------------------------------------------------------
|
||
*/
|
||
/*
|
||
* Symisc PH7: An embeddable bytecode compiler and a virtual machine for the PHP(5) programming language.
|
||
* Copyright (C) 2011-2012, Symisc Systems http://ph7.symisc.net/
|
||
* Version 2.1.4
|
||
* For information on licensing,redistribution of this file,and for a DISCLAIMER OF ALL WARRANTIES
|
||
* please contact Symisc Systems via:
|
||
* legal@symisc.net
|
||
* licensing@symisc.net
|
||
* contact@symisc.net
|
||
* or visit:
|
||
* http://ph7.symisc.net/
|
||
*/
|
||
/* $SymiscID: vm.c v1.4 FreeBSD 2012-09-10 00:06 stable <chm@symisc.net> $ */
|
||
#ifndef PH7_AMALGAMATION
|
||
#include "ph7int.h"
|
||
#endif
|
||
/*
|
||
* The code in this file implements execution method of the PH7 Virtual Machine.
|
||
* The PH7 compiler (implemented in 'compiler.c' and 'parse.c') generates a bytecode program
|
||
* which is then executed by the virtual machine implemented here to do the work of the PHP
|
||
* statements.
|
||
* PH7 bytecode programs are similar in form to assembly language. The program consists
|
||
* of a linear sequence of operations .Each operation has an opcode and 3 operands.
|
||
* Operands P1 and P2 are integers where the first is signed while the second is unsigned.
|
||
* Operand P3 is an arbitrary pointer specific to each instruction. The P2 operand is usually
|
||
* the jump destination used by the OP_JMP,OP_JZ,OP_JNZ,... instructions.
|
||
* Opcodes will typically ignore one or more operands. Many opcodes ignore all three operands.
|
||
* Computation results are stored on a stack. Each entry on the stack is of type ph7_value.
|
||
* PH7 uses the ph7_value object to represent all values that can be stored in a PHP variable.
|
||
* Since PHP uses dynamic typing for the values it stores. Values stored in ph7_value objects
|
||
* can be integers,floating point values,strings,arrays,class instances (object in the PHP jargon)
|
||
* and so on.
|
||
* Internally,the PH7 virtual machine manipulates nearly all PHP values as ph7_values structures.
|
||
* Each ph7_value may cache multiple representations(string,integer etc.) of the same value.
|
||
* An implicit conversion from one type to the other occurs as necessary.
|
||
* Most of the code in this file is taken up by the [VmByteCodeExec()] function which does
|
||
* the work of interpreting a PH7 bytecode program. But other routines are also provided
|
||
* to help in building up a program instruction by instruction. Also note that sepcial
|
||
* functions that need access to the underlying virtual machine details such as [die()],
|
||
* [func_get_args()],[call_user_func()],[ob_start()] and many more are implemented here.
|
||
*/
|
||
/*
|
||
* Each active virtual machine frame is represented by an instance
|
||
* of the following structure.
|
||
* VM Frame hold local variables and other stuff related to function call.
|
||
*/
|
||
struct VmFrame
|
||
{
|
||
VmFrame *pParent; /* Parent frame or NULL if global scope */
|
||
void *pUserData; /* Upper layer private data associated with this frame */
|
||
ph7_class_instance *pThis; /* Current class instance [i.e: the '$this' variable].NULL otherwise */
|
||
SySet sLocal; /* Local variables container (VmSlot instance) */
|
||
ph7_vm *pVm; /* VM that own this frame */
|
||
SyHash hVar; /* Variable hashtable for fast lookup */
|
||
SySet sArg; /* Function arguments container */
|
||
SySet sRef; /* Local reference table (VmSlot instance) */
|
||
sxi32 iFlags; /* Frame configuration flags (See below)*/
|
||
sxu32 iExceptionJump; /* Exception jump destination */
|
||
};
|
||
#define VM_FRAME_EXCEPTION 0x01 /* Special Exception frame */
|
||
#define VM_FRAME_THROW 0x02 /* An exception was thrown */
|
||
#define VM_FRAME_CATCH 0x04 /* Catch frame */
|
||
/*
|
||
* When a user defined variable is released (via manual unset($x) or garbage collected)
|
||
* memory object index is stored in an instance of the following structure and put
|
||
* in the free object table so that it can be reused again without allocating
|
||
* a new memory object.
|
||
*/
|
||
typedef struct VmSlot VmSlot;
|
||
struct VmSlot
|
||
{
|
||
sxu32 nIdx; /* Index in pVm->aMemObj[] */
|
||
void *pUserData; /* Upper-layer private data */
|
||
};
|
||
/*
|
||
* An entry in the reference table is represented by an instance of the
|
||
* follwoing table.
|
||
* The implementation of the reference mechanism in the PH7 engine
|
||
* differ greatly from the one used by the zend engine. That is,
|
||
* the reference implementation is consistent,solid and it's
|
||
* behavior resemble the C++ reference mechanism.
|
||
* Refer to the official for more information on this powerful
|
||
* extension.
|
||
*/
|
||
struct VmRefObj
|
||
{
|
||
SySet aReference; /* Table of references to this memory object */
|
||
SySet aArrEntries; /* Foreign hashmap entries [i.e: array(&$a) ] */
|
||
sxu32 nIdx; /* Referenced object index */
|
||
sxi32 iFlags; /* Configuration flags */
|
||
VmRefObj *pNextCollide,*pPrevCollide; /* Collision link */
|
||
VmRefObj *pNext,*pPrev; /* List of all referenced objects */
|
||
};
|
||
#define VM_REF_IDX_KEEP 0x001 /* Do not restore the memory object to the free list */
|
||
/*
|
||
* Output control buffer entry.
|
||
* Refer to the implementation of [ob_start()] for more information.
|
||
*/
|
||
typedef struct VmObEntry VmObEntry;
|
||
struct VmObEntry
|
||
{
|
||
ph7_value sCallback; /* User defined callback */
|
||
SyBlob sOB; /* Output buffer consumer */
|
||
};
|
||
/*
|
||
* Each installed shutdown callback (registered using [register_shutdown_function()] )
|
||
* is stored in an instance of the following structure.
|
||
* Refer to the implementation of [register_shutdown_function(()] for more information.
|
||
*/
|
||
typedef struct VmShutdownCB VmShutdownCB;
|
||
struct VmShutdownCB
|
||
{
|
||
ph7_value sCallback; /* Shutdown callback */
|
||
ph7_value aArg[10]; /* Callback arguments (10 maximum arguments) */
|
||
int nArg; /* Total number of given arguments */
|
||
};
|
||
/* Uncaught exception code value */
|
||
#define PH7_EXCEPTION -255
|
||
/*
|
||
* Each parsed URI is recorded and stored in an instance of the following structure.
|
||
* This structure and it's related routines are taken verbatim from the xHT project
|
||
* [A modern embeddable HTTP engine implementing all the RFC2616 methods]
|
||
* the xHT project is developed internally by Symisc Systems.
|
||
*/
|
||
typedef struct SyhttpUri SyhttpUri;
|
||
struct SyhttpUri
|
||
{
|
||
SyString sHost; /* Hostname or IP address */
|
||
SyString sPort; /* Port number */
|
||
SyString sPath; /* Mandatory resource path passed verbatim (Not decoded) */
|
||
SyString sQuery; /* Query part */
|
||
SyString sFragment; /* Fragment part */
|
||
SyString sScheme; /* Scheme */
|
||
SyString sUser; /* Username */
|
||
SyString sPass; /* Password */
|
||
SyString sRaw; /* Raw URI */
|
||
};
|
||
/*
|
||
* An instance of the following structure is used to record all MIME headers seen
|
||
* during a HTTP interaction.
|
||
* This structure and it's related routines are taken verbatim from the xHT project
|
||
* [A modern embeddable HTTP engine implementing all the RFC2616 methods]
|
||
* the xHT project is developed internally by Symisc Systems.
|
||
*/
|
||
typedef struct SyhttpHeader SyhttpHeader;
|
||
struct SyhttpHeader
|
||
{
|
||
SyString sName; /* Header name [i.e:"Content-Type","Host","User-Agent"]. NOT NUL TERMINATED */
|
||
SyString sValue; /* Header values [i.e: "text/html"]. NOT NUL TERMINATED */
|
||
};
|
||
/*
|
||
* Supported HTTP methods.
|
||
*/
|
||
#define HTTP_METHOD_GET 1 /* GET */
|
||
#define HTTP_METHOD_HEAD 2 /* HEAD */
|
||
#define HTTP_METHOD_POST 3 /* POST */
|
||
#define HTTP_METHOD_PUT 4 /* PUT */
|
||
#define HTTP_METHOD_OTHR 5 /* Other HTTP methods [i.e: DELETE,TRACE,OPTIONS...]*/
|
||
/*
|
||
* Supported HTTP protocol version.
|
||
*/
|
||
#define HTTP_PROTO_10 1 /* HTTP/1.0 */
|
||
#define HTTP_PROTO_11 2 /* HTTP/1.1 */
|
||
/*
|
||
* Register a constant and it's associated expansion callback so that
|
||
* it can be expanded from the target PHP program.
|
||
* The constant expansion mechanism under PH7 is extremely powerful yet
|
||
* simple and work as follows:
|
||
* Each registered constant have a C procedure associated with it.
|
||
* This procedure known as the constant expansion callback is responsible
|
||
* of expanding the invoked constant to the desired value,for example:
|
||
* The C procedure associated with the "__PI__" constant expands to 3.14 (the value of PI).
|
||
* The "__OS__" constant procedure expands to the name of the host Operating Systems
|
||
* (Windows,Linux,...) and so on.
|
||
* Please refer to the official documentation for additional information.
|
||
*/
|
||
PH7_PRIVATE sxi32 PH7_VmRegisterConstant(
|
||
ph7_vm *pVm, /* Target VM */
|
||
const SyString *pName, /* Constant name */
|
||
ProcConstant xExpand, /* Constant expansion callback */
|
||
void *pUserData /* Last argument to xExpand() */
|
||
)
|
||
{
|
||
ph7_constant *pCons;
|
||
SyHashEntry *pEntry;
|
||
char *zDupName;
|
||
sxi32 rc;
|
||
pEntry = SyHashGet(&pVm->hConstant,(const void *)pName->zString,pName->nByte);
|
||
if( pEntry ){
|
||
/* Overwrite the old definition and return immediately */
|
||
pCons = (ph7_constant *)pEntry->pUserData;
|
||
pCons->xExpand = xExpand;
|
||
pCons->pUserData = pUserData;
|
||
return SXRET_OK;
|
||
}
|
||
/* Allocate a new constant instance */
|
||
pCons = (ph7_constant *)SyMemBackendPoolAlloc(&pVm->sAllocator,sizeof(ph7_constant));
|
||
if( pCons == 0 ){
|
||
return 0;
|
||
}
|
||
/* Duplicate constant name */
|
||
zDupName = SyMemBackendStrDup(&pVm->sAllocator,pName->zString,pName->nByte);
|
||
if( zDupName == 0 ){
|
||
SyMemBackendPoolFree(&pVm->sAllocator,pCons);
|
||
return 0;
|
||
}
|
||
/* Install the constant */
|
||
SyStringInitFromBuf(&pCons->sName,zDupName,pName->nByte);
|
||
pCons->xExpand = xExpand;
|
||
pCons->pUserData = pUserData;
|
||
rc = SyHashInsert(&pVm->hConstant,(const void *)zDupName,SyStringLength(&pCons->sName),pCons);
|
||
if( rc != SXRET_OK ){
|
||
SyMemBackendFree(&pVm->sAllocator,zDupName);
|
||
SyMemBackendPoolFree(&pVm->sAllocator,pCons);
|
||
return rc;
|
||
}
|
||
/* All done,constant can be invoked from PHP code */
|
||
return SXRET_OK;
|
||
}
|
||
/*
|
||
* Allocate a new foreign function instance.
|
||
* This function return SXRET_OK on success. Any other
|
||
* return value indicates failure.
|
||
* Please refer to the official documentation for an introduction to
|
||
* the foreign function mechanism.
|
||
*/
|
||
static sxi32 PH7_NewForeignFunction(
|
||
ph7_vm *pVm, /* Target VM */
|
||
const SyString *pName, /* Foreign function name */
|
||
ProchHostFunction xFunc, /* Foreign function implementation */
|
||
void *pUserData, /* Foreign function private data */
|
||
ph7_user_func **ppOut /* OUT: VM image of the foreign function */
|
||
)
|
||
{
|
||
ph7_user_func *pFunc;
|
||
char *zDup;
|
||
/* Allocate a new user function */
|
||
pFunc = (ph7_user_func *)SyMemBackendPoolAlloc(&pVm->sAllocator,sizeof(ph7_user_func));
|
||
if( pFunc == 0 ){
|
||
return SXERR_MEM;
|
||
}
|
||
/* Duplicate function name */
|
||
zDup = SyMemBackendStrDup(&pVm->sAllocator,pName->zString,pName->nByte);
|
||
if( zDup == 0 ){
|
||
SyMemBackendPoolFree(&pVm->sAllocator,pFunc);
|
||
return SXERR_MEM;
|
||
}
|
||
/* Zero the structure */
|
||
SyZero(pFunc,sizeof(ph7_user_func));
|
||
/* Initialize structure fields */
|
||
SyStringInitFromBuf(&pFunc->sName,zDup,pName->nByte);
|
||
pFunc->pVm = pVm;
|
||
pFunc->xFunc = xFunc;
|
||
pFunc->pUserData = pUserData;
|
||
SySetInit(&pFunc->aAux,&pVm->sAllocator,sizeof(ph7_aux_data));
|
||
/* Write a pointer to the new function */
|
||
*ppOut = pFunc;
|
||
return SXRET_OK;
|
||
}
|
||
/*
|
||
* Install a foreign function and it's associated callback so that
|
||
* it can be invoked from the target PHP code.
|
||
* This function return SXRET_OK on successful registration. Any other
|
||
* return value indicates failure.
|
||
* Please refer to the official documentation for an introduction to
|
||
* the foreign function mechanism.
|
||
*/
|
||
PH7_PRIVATE sxi32 PH7_VmInstallForeignFunction(
|
||
ph7_vm *pVm, /* Target VM */
|
||
const SyString *pName, /* Foreign function name */
|
||
ProchHostFunction xFunc, /* Foreign function implementation */
|
||
void *pUserData /* Foreign function private data */
|
||
)
|
||
{
|
||
ph7_user_func *pFunc;
|
||
SyHashEntry *pEntry;
|
||
sxi32 rc;
|
||
/* Overwrite any previously registered function with the same name */
|
||
pEntry = SyHashGet(&pVm->hHostFunction,pName->zString,pName->nByte);
|
||
if( pEntry ){
|
||
pFunc = (ph7_user_func *)pEntry->pUserData;
|
||
pFunc->pUserData = pUserData;
|
||
pFunc->xFunc = xFunc;
|
||
SySetReset(&pFunc->aAux);
|
||
return SXRET_OK;
|
||
}
|
||
/* Create a new user function */
|
||
rc = PH7_NewForeignFunction(&(*pVm),&(*pName),xFunc,pUserData,&pFunc);
|
||
if( rc != SXRET_OK ){
|
||
return rc;
|
||
}
|
||
/* Install the function in the corresponding hashtable */
|
||
rc = SyHashInsert(&pVm->hHostFunction,SyStringData(&pFunc->sName),pName->nByte,pFunc);
|
||
if( rc != SXRET_OK ){
|
||
SyMemBackendFree(&pVm->sAllocator,(void *)SyStringData(&pFunc->sName));
|
||
SyMemBackendPoolFree(&pVm->sAllocator,pFunc);
|
||
return rc;
|
||
}
|
||
/* User function successfully installed */
|
||
return SXRET_OK;
|
||
}
|
||
/*
|
||
* Initialize a VM function.
|
||
*/
|
||
PH7_PRIVATE sxi32 PH7_VmInitFuncState(
|
||
ph7_vm *pVm, /* Target VM */
|
||
ph7_vm_func *pFunc, /* Target Fucntion */
|
||
const char *zName, /* Function name */
|
||
sxu32 nByte, /* zName length */
|
||
sxi32 iFlags, /* Configuration flags */
|
||
void *pUserData /* Function private data */
|
||
)
|
||
{
|
||
/* Zero the structure */
|
||
SyZero(pFunc,sizeof(ph7_vm_func));
|
||
/* Initialize structure fields */
|
||
/* Arguments container */
|
||
SySetInit(&pFunc->aArgs,&pVm->sAllocator,sizeof(ph7_vm_func_arg));
|
||
/* Static variable container */
|
||
SySetInit(&pFunc->aStatic,&pVm->sAllocator,sizeof(ph7_vm_func_static_var));
|
||
/* Bytecode container */
|
||
SySetInit(&pFunc->aByteCode,&pVm->sAllocator,sizeof(VmInstr));
|
||
/* Preallocate some instruction slots */
|
||
SySetAlloc(&pFunc->aByteCode,0x10);
|
||
/* Closure environment */
|
||
SySetInit(&pFunc->aClosureEnv,&pVm->sAllocator,sizeof(ph7_vm_func_closure_env));
|
||
pFunc->iFlags = iFlags;
|
||
pFunc->pUserData = pUserData;
|
||
SyStringInitFromBuf(&pFunc->sName,zName,nByte);
|
||
return SXRET_OK;
|
||
}
|
||
/*
|
||
* Install a user defined function in the corresponding VM container.
|
||
*/
|
||
PH7_PRIVATE sxi32 PH7_VmInstallUserFunction(
|
||
ph7_vm *pVm, /* Target VM */
|
||
ph7_vm_func *pFunc, /* Target function */
|
||
SyString *pName /* Function name */
|
||
)
|
||
{
|
||
SyHashEntry *pEntry;
|
||
sxi32 rc;
|
||
if( pName == 0 ){
|
||
/* Use the built-in name */
|
||
pName = &pFunc->sName;
|
||
}
|
||
/* Check for duplicates (functions with the same name) first */
|
||
pEntry = SyHashGet(&pVm->hFunction,pName->zString,pName->nByte);
|
||
if( pEntry ){
|
||
ph7_vm_func *pLink = (ph7_vm_func *)pEntry->pUserData;
|
||
if( pLink != pFunc ){
|
||
/* Link */
|
||
pFunc->pNextName = pLink;
|
||
pEntry->pUserData = pFunc;
|
||
}
|
||
return SXRET_OK;
|
||
}
|
||
/* First time seen */
|
||
pFunc->pNextName = 0;
|
||
rc = SyHashInsert(&pVm->hFunction,pName->zString,pName->nByte,pFunc);
|
||
return rc;
|
||