Aer Interpreter Source
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1857 lines
87 KiB

/*
* 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__
#define PH7_PRIVATE
#include "ph7.h"
#ifdef __WINNT__
#include <windows.h>
#else
#include <dlfcn.h>
#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 0x7FFFFFFFFFFFFFFFLL
#define SXU64_HIGH 0xFFFFFFFFFFFFFFFFUL
#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
/*
* --------------
* 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 errors 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-increment/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() */
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 environment 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 documentation 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; /* Attribute 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) */
sxu32 iLine; /* Line number */
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 switch 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 hDBAL; /* DBAL 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 aModules; /* Set of loaded modules */
SySet aFiles; /* Stack of processed files */
SySet aPaths; /* Set of import paths */
SySet aIncluded; /* Set of included files */
SySet aOB; /* Stackable output buffers */
SySet aAutoLoad; /* Stack of class autoload callbacks */
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 recursion 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 errors
* 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 ocurred, 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 '&&' */
PH7_OP_LOR, /* Logical or '||' */
PH7_OP_LXOR, /* Logical 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_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_BAND, /* Bitwise and '&' */
EXPR_OP_REF, /* Reference operator '&' */
EXPR_OP_XOR, /* bitwise xor '^' */
EXPR_OP_BOR, /* bitwise or '|' */
EXPR_OP_LAND, /* Logical and '&&' */
EXPR_OP_LOR, /* Logical or '||' */
EXPR_OP_LXOR, /* Logical 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_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 */
/* 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_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_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_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 */
/* 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 */
};
/* 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 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__ */