Code formatting

This commit is contained in:
Rafal Kupiec 2018-07-12 17:24:46 +02:00
parent 03bfd2203c
commit d898cd1e36
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
15 changed files with 24070 additions and 24526 deletions

990
api.c

File diff suppressed because it is too large Load Diff

4787
builtin.c

File diff suppressed because it is too large Load Diff

3355
compile.c

File diff suppressed because it is too large Load Diff

1034
constant.c

File diff suppressed because it is too large Load Diff

2720
hashmap.c

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,7 @@
/* /*
* Display an error message and exit. * Display an error message and exit.
*/ */
static void Fatal(const char *zMsg) static void Fatal(const char *zMsg) {
{
puts(zMsg); puts(zMsg);
/* Shutdown the library */ /* Shutdown the library */
ph7_lib_shutdown(); ph7_lib_shutdown();
@ -54,8 +53,7 @@ static const char zBanner[] = {
/* /*
* Display the banner,a help message and exit. * Display the banner,a help message and exit.
*/ */
static void Help(void) static void Help(void) {
{
puts(zBanner); puts(zBanner);
puts("ph7 [-h|-r|-d] path/to/php_file [script args]"); puts("ph7 [-h|-r|-d] path/to/php_file [script args]");
puts("\t-d: Dump PH7 byte-code instructions"); puts("\t-d: Dump PH7 byte-code instructions");
@ -65,17 +63,17 @@ static void Help(void)
exit(0); exit(0);
} }
#ifdef __WINNT__ #ifdef __WINNT__
#include <Windows.h> #include <Windows.h>
#else #else
/* Assume UNIX */ /* Assume UNIX */
#include <unistd.h> #include <unistd.h>
#endif #endif
/* /*
* The following define is used by the UNIX built and have * The following define is used by the UNIX built and have
* no particular meaning on windows. * no particular meaning on windows.
*/ */
#ifndef STDOUT_FILENO #ifndef STDOUT_FILENO
#define STDOUT_FILENO 1 #define STDOUT_FILENO 1
#endif #endif
/* /*
* VM output consumer callback. * VM output consumer callback.
@ -86,19 +84,18 @@ static void Help(void)
* This function is registered later via a call to ph7_vm_config() * This function is registered later via a call to ph7_vm_config()
* with a configuration verb set to: PH7_VM_CONFIG_OUTPUT. * with a configuration verb set to: PH7_VM_CONFIG_OUTPUT.
*/ */
static int Output_Consumer(const void *pOutput,unsigned int nOutputLen,void *pUserData /* Unused */) static int Output_Consumer(const void *pOutput, unsigned int nOutputLen, void *pUserData /* Unused */) {
{
#ifdef __WINNT__ #ifdef __WINNT__
BOOL rc; BOOL rc;
rc = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),pOutput,(DWORD)nOutputLen,0,0); rc = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pOutput, (DWORD)nOutputLen, 0, 0);
if( !rc ){ if(!rc) {
/* Abort processing */ /* Abort processing */
return PH7_ABORT; return PH7_ABORT;
} }
#else #else
ssize_t nWr; ssize_t nWr;
nWr = write(STDOUT_FILENO,pOutput,nOutputLen); nWr = write(STDOUT_FILENO, pOutput, nOutputLen);
if( nWr < 0 ){ if(nWr < 0) {
/* Abort processing */ /* Abort processing */
return PH7_ABORT; return PH7_ABORT;
} }
@ -109,8 +106,7 @@ static int Output_Consumer(const void *pOutput,unsigned int nOutputLen,void *pUs
/* /*
* Main program: Compile and execute the PHP file. * Main program: Compile and execute the PHP file.
*/ */
int main(int argc,char **argv) int main(int argc, char **argv) {
{
ph7 *pEngine; /* PH7 engine */ ph7 *pEngine; /* PH7 engine */
ph7_vm *pVm; /* Compiled PHP program */ ph7_vm *pVm; /* Compiled PHP program */
int dump_vm = 0; /* Dump VM instructions if TRUE */ int dump_vm = 0; /* Dump VM instructions if TRUE */
@ -118,31 +114,31 @@ int main(int argc,char **argv)
int n; /* Script arguments */ int n; /* Script arguments */
int rc; int rc;
/* Process interpreter arguments first*/ /* Process interpreter arguments first*/
for(n = 1 ; n < argc ; ++n ){ for(n = 1 ; n < argc ; ++n) {
int c; int c;
if( argv[n][0] != '-' ){ if(argv[n][0] != '-') {
/* No more interpreter arguments */ /* No more interpreter arguments */
break; break;
} }
c = argv[n][1]; c = argv[n][1];
if( c == 'd' || c == 'D' ){ if(c == 'd' || c == 'D') {
/* Dump byte-code instructions */ /* Dump byte-code instructions */
dump_vm = 1; dump_vm = 1;
}else if( c == 'r' || c == 'R' ){ } else if(c == 'r' || c == 'R') {
/* Report run-time errors */ /* Report run-time errors */
err_report = 1; err_report = 1;
}else{ } else {
/* Display a help message and exit */ /* Display a help message and exit */
Help(); Help();
} }
} }
if( n >= argc ){ if(n >= argc) {
puts("Missing PHP file to compile"); puts("Missing PHP file to compile");
Help(); Help();
} }
/* Allocate a new PH7 engine instance */ /* Allocate a new PH7 engine instance */
rc = ph7_init(&pEngine); rc = ph7_init(&pEngine);
if( rc != PH7_OK ){ if(rc != PH7_OK) {
/* /*
* If the supplied memory subsystem is so sick that we are unable * If the supplied memory subsystem is so sick that we are unable
* to allocate a tiny chunk of memory,there is no much we can do here. * to allocate a tiny chunk of memory,there is no much we can do here.
@ -152,7 +148,7 @@ int main(int argc,char **argv)
/* Set an error log consumer callback. This callback [Output_Consumer()] will /* Set an error log consumer callback. This callback [Output_Consumer()] will
* redirect all compile-time error messages to STDOUT. * redirect all compile-time error messages to STDOUT.
*/ */
ph7_config(pEngine,PH7_CONFIG_ERR_OUTPUT, ph7_config(pEngine, PH7_CONFIG_ERR_OUTPUT,
Output_Consumer, /* Error log consumer */ Output_Consumer, /* Error log consumer */
0 /* NULL: Callback Private data */ 0 /* NULL: Callback Private data */
); );
@ -163,12 +159,12 @@ int main(int argc,char **argv)
&pVm, /* OUT: Compiled PHP program */ &pVm, /* OUT: Compiled PHP program */
0 /* IN: Compile flags */ 0 /* IN: Compile flags */
); );
if( rc != PH7_OK ){ /* Compile error */ if(rc != PH7_OK) { /* Compile error */
if( rc == PH7_IO_ERR ){ if(rc == PH7_IO_ERR) {
Fatal("IO error while opening the target file"); Fatal("IO error while opening the target file");
}else if( rc == PH7_VM_ERR ){ } else if(rc == PH7_VM_ERR) {
Fatal("VM initialization error"); Fatal("VM initialization error");
}else{ } else {
/* Compile-time error, your output (STDOUT) should display the error messages */ /* Compile-time error, your output (STDOUT) should display the error messages */
Fatal("Compile error"); Fatal("Compile error");
} }
@ -183,20 +179,20 @@ int main(int argc,char **argv)
Output_Consumer, /* Output Consumer callback */ Output_Consumer, /* Output Consumer callback */
0 /* Callback private data */ 0 /* Callback private data */
); );
if( rc != PH7_OK ){ if(rc != PH7_OK) {
Fatal("Error while installing the VM output consumer callback"); Fatal("Error while installing the VM output consumer callback");
} }
/* Register script agruments so we can access them later using the $argv[] /* Register script agruments so we can access them later using the $argv[]
* array from the compiled PHP program. * array from the compiled PHP program.
*/ */
for( n = n + 1; n < argc ; ++n ){ for(n = n + 1; n < argc ; ++n) {
ph7_vm_config(pVm,PH7_VM_CONFIG_ARGV_ENTRY,argv[n]/* Argument value */); ph7_vm_config(pVm, PH7_VM_CONFIG_ARGV_ENTRY, argv[n]/* Argument value */);
} }
if( err_report ){ if(err_report) {
/* Report script run-time errors */ /* Report script run-time errors */
ph7_vm_config(pVm,PH7_VM_CONFIG_ERR_REPORT); ph7_vm_config(pVm, PH7_VM_CONFIG_ERR_REPORT);
} }
if( dump_vm ){ if(dump_vm) {
/* Dump PH7 byte-code instructions */ /* Dump PH7 byte-code instructions */
ph7_vm_dump_v2(pVm, ph7_vm_dump_v2(pVm,
Output_Consumer, /* Dump consumer callback */ Output_Consumer, /* Dump consumer callback */
@ -207,7 +203,7 @@ int main(int argc,char **argv)
* And finally, execute our program. Note that your output (STDOUT in our case) * And finally, execute our program. Note that your output (STDOUT in our case)
* should display the result. * should display the result.
*/ */
ph7_vm_exec(pVm,0); ph7_vm_exec(pVm, 0);
/* All done, cleanup the mess left behind. /* All done, cleanup the mess left behind.
*/ */
ph7_vm_release(pVm); ph7_vm_release(pVm);

462
lexer.c
View File

@ -10,7 +10,7 @@
* or visit: * or visit:
* http://ph7.symisc.net/ * http://ph7.symisc.net/
*/ */
/* $SymiscID: lex.c v2.8 Ubuntu-linux 2012-07-13 01:21 stable <chm@symisc.net> $ */ /* $SymiscID: lex.c v2.8 Ubuntu-linux 2012-07-13 01:21 stable <chm@symisc.net> $ */
#include "ph7int.h" #include "ph7int.h"
/* /*
* This file implement an efficient hand-coded,thread-safe and full-reentrant * This file implement an efficient hand-coded,thread-safe and full-reentrant
@ -23,20 +23,19 @@ static sxu32 KeywordCode(const char *z, int n);
* Get a single low-level token from the input file. Update the stream pointer so that * Get a single low-level token from the input file. Update the stream pointer so that
* it points to the first character beyond the extracted token. * it points to the first character beyond the extracted token.
*/ */
static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void *pCtxData) static sxi32 TokenizePHP(SyStream *pStream, SyToken *pToken, void *pUserData, void *pCtxData) {
{
SyString *pStr; SyString *pStr;
sxi32 rc; sxi32 rc;
/* Ignore leading white spaces */ /* Ignore leading white spaces */
while( pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisSpace(pStream->zText[0]) ){ while(pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisSpace(pStream->zText[0])) {
/* Advance the stream cursor */ /* Advance the stream cursor */
if( pStream->zText[0] == '\n' ){ if(pStream->zText[0] == '\n') {
/* Update line counter */ /* Update line counter */
pStream->nLine++; pStream->nLine++;
} }
pStream->zText++; pStream->zText++;
} }
if( pStream->zText >= pStream->zEnd ){ if(pStream->zText >= pStream->zEnd) {
/* End of input reached */ /* End of input reached */
return SXERR_EOF; return SXERR_EOF;
} }
@ -44,8 +43,8 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
pToken->nLine = pStream->nLine; pToken->nLine = pStream->nLine;
pToken->pUserData = 0; pToken->pUserData = 0;
pStr = &pToken->sData; pStr = &pToken->sData;
SyStringInitFromBuf(pStr,pStream->zText,0); SyStringInitFromBuf(pStr, pStream->zText, 0);
if( pStream->zText[0] >= 0xc0 || SyisAlpha(pStream->zText[0]) || pStream->zText[0] == '_' ){ if(pStream->zText[0] >= 0xc0 || SyisAlpha(pStream->zText[0]) || pStream->zText[0] == '_') {
/* The following code fragment is taken verbatim from the xPP source tree. /* The following code fragment is taken verbatim from the xPP source tree.
* xPP is a modern embeddable macro processor with advanced features useful for * xPP is a modern embeddable macro processor with advanced features useful for
* application seeking for a production quality,ready to use macro processor. * application seeking for a production quality,ready to use macro processor.
@ -56,23 +55,23 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
const unsigned char *zIn; const unsigned char *zIn;
sxu32 nKeyword; sxu32 nKeyword;
/* Isolate UTF-8 or alphanumeric stream */ /* Isolate UTF-8 or alphanumeric stream */
if( pStream->zText[0] < 0xc0 ){ if(pStream->zText[0] < 0xc0) {
pStream->zText++; pStream->zText++;
} }
for(;;){ for(;;) {
zIn = pStream->zText; zIn = pStream->zText;
if( zIn[0] >= 0xc0 ){ if(zIn[0] >= 0xc0) {
zIn++; zIn++;
/* UTF-8 stream */ /* UTF-8 stream */
while( zIn < pStream->zEnd && ((zIn[0] & 0xc0) == 0x80) ){ while(zIn < pStream->zEnd && ((zIn[0] & 0xc0) == 0x80)) {
zIn++; zIn++;
} }
} }
/* Skip alphanumeric stream */ /* Skip alphanumeric stream */
while( zIn < pStream->zEnd && zIn[0] < 0xc0 && (SyisAlphaNum(zIn[0]) || zIn[0] == '_') ){ while(zIn < pStream->zEnd && zIn[0] < 0xc0 && (SyisAlphaNum(zIn[0]) || zIn[0] == '_')) {
zIn++; zIn++;
} }
if( zIn == pStream->zText ){ if(zIn == pStream->zText) {
/* Not an UTF-8 or alphanumeric stream */ /* Not an UTF-8 or alphanumeric stream */
break; break;
} }
@ -80,46 +79,46 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
pStream->zText = zIn; pStream->zText = zIn;
} }
/* Record token length */ /* Record token length */
pStr->nByte = (sxu32)((const char *)pStream->zText-pStr->zString); pStr->nByte = (sxu32)((const char *)pStream->zText - pStr->zString);
nKeyword = KeywordCode(pStr->zString,(int)pStr->nByte); nKeyword = KeywordCode(pStr->zString, (int)pStr->nByte);
if( nKeyword != PH7_TK_ID ){ if(nKeyword != PH7_TK_ID) {
if( nKeyword & if(nKeyword &
(PH7_TKWRD_NEW|PH7_TKWRD_CLONE|PH7_TKWRD_AND|PH7_TKWRD_XOR|PH7_TKWRD_OR|PH7_TKWRD_INSTANCEOF) ){ (PH7_TKWRD_NEW | PH7_TKWRD_CLONE | PH7_TKWRD_AND | PH7_TKWRD_XOR | PH7_TKWRD_OR | PH7_TKWRD_INSTANCEOF)) {
/* Alpha stream operators [i.e: new,clone,and,instanceof,eq,ne,or,xor],save the operator instance for later processing */ /* Alpha stream operators [i.e: new,clone,and,instanceof,eq,ne,or,xor],save the operator instance for later processing */
pToken->pUserData = (void *)PH7_ExprExtractOperator(pStr,0); pToken->pUserData = (void *)PH7_ExprExtractOperator(pStr, 0);
/* Mark as an operator */ /* Mark as an operator */
pToken->nType = PH7_TK_ID|PH7_TK_OP; pToken->nType = PH7_TK_ID | PH7_TK_OP;
}else{ } else {
/* We are dealing with a keyword [i.e: while,foreach,class...],save the keyword ID */ /* We are dealing with a keyword [i.e: while,foreach,class...],save the keyword ID */
pToken->nType = PH7_TK_KEYWORD; pToken->nType = PH7_TK_KEYWORD;
pToken->pUserData = SX_INT_TO_PTR(nKeyword); pToken->pUserData = SX_INT_TO_PTR(nKeyword);
} }
}else{ } else {
/* A simple identifier */ /* A simple identifier */
pToken->nType = PH7_TK_ID; pToken->nType = PH7_TK_ID;
} }
}else{ } else {
sxi32 c; sxi32 c;
/* Non-alpha stream */ /* Non-alpha stream */
if( pStream->zText[0] == '#' || if(pStream->zText[0] == '#' ||
( pStream->zText[0] == '/' && &pStream->zText[1] < pStream->zEnd && pStream->zText[1] == '/') ){ (pStream->zText[0] == '/' && &pStream->zText[1] < pStream->zEnd && pStream->zText[1] == '/')) {
pStream->zText++; pStream->zText++;
/* Inline comments */ /* Inline comments */
while( pStream->zText < pStream->zEnd && pStream->zText[0] != '\n' ){ while(pStream->zText < pStream->zEnd && pStream->zText[0] != '\n') {
pStream->zText++; pStream->zText++;
} }
/* Tell the upper-layer to ignore this token */ /* Tell the upper-layer to ignore this token */
return SXERR_CONTINUE; return SXERR_CONTINUE;
}else if( pStream->zText[0] == '/' && &pStream->zText[1] < pStream->zEnd && pStream->zText[1] == '*' ){ } else if(pStream->zText[0] == '/' && &pStream->zText[1] < pStream->zEnd && pStream->zText[1] == '*') {
pStream->zText += 2; pStream->zText += 2;
/* Block comment */ /* Block comment */
while( pStream->zText < pStream->zEnd ){ while(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '*' ){ if(pStream->zText[0] == '*') {
if( &pStream->zText[1] >= pStream->zEnd || pStream->zText[1] == '/' ){ if(&pStream->zText[1] >= pStream->zEnd || pStream->zText[1] == '/') {
break; break;
} }
} }
if( pStream->zText[0] == '\n' ){ if(pStream->zText[0] == '\n') {
pStream->nLine++; pStream->nLine++;
} }
pStream->zText++; pStream->zText++;
@ -127,116 +126,128 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
pStream->zText += 2; pStream->zText += 2;
/* Tell the upper-layer to ignore this token */ /* Tell the upper-layer to ignore this token */
return SXERR_CONTINUE; return SXERR_CONTINUE;
}else if( SyisDigit(pStream->zText[0]) ){ } else if(SyisDigit(pStream->zText[0])) {
pStream->zText++; pStream->zText++;
/* Decimal digit stream */ /* Decimal digit stream */
while( pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0]) ){ while(pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0])) {
pStream->zText++; pStream->zText++;
} }
/* Mark the token as integer until we encounter a real number */ /* Mark the token as integer until we encounter a real number */
pToken->nType = PH7_TK_INTEGER; pToken->nType = PH7_TK_INTEGER;
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
c = pStream->zText[0]; c = pStream->zText[0];
if( c == '.' ){ if(c == '.') {
/* Real number */ /* Real number */
pStream->zText++; pStream->zText++;
while( pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0]) ){ while(pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0])) {
pStream->zText++; pStream->zText++;
} }
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
c = pStream->zText[0]; c = pStream->zText[0];
if( c=='e' || c=='E' ){ if(c == 'e' || c == 'E') {
pStream->zText++; pStream->zText++;
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
c = pStream->zText[0]; c = pStream->zText[0];
if( (c =='+' || c=='-') && &pStream->zText[1] < pStream->zEnd && if((c == '+' || c == '-') && &pStream->zText[1] < pStream->zEnd &&
pStream->zText[1] < 0xc0 && SyisDigit(pStream->zText[1]) ){ pStream->zText[1] < 0xc0 && SyisDigit(pStream->zText[1])) {
pStream->zText++; pStream->zText++;
} }
while( pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0]) ){ while(pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0])) {
pStream->zText++; pStream->zText++;
} }
} }
} }
} }
pToken->nType = PH7_TK_REAL; pToken->nType = PH7_TK_REAL;
}else if( c=='e' || c=='E' ){ } else if(c == 'e' || c == 'E') {
SXUNUSED(pUserData); /* Prevent compiler warning */ SXUNUSED(pUserData); /* Prevent compiler warning */
SXUNUSED(pCtxData); SXUNUSED(pCtxData);
pStream->zText++; pStream->zText++;
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
c = pStream->zText[0]; c = pStream->zText[0];
if( (c =='+' || c=='-') && &pStream->zText[1] < pStream->zEnd && if((c == '+' || c == '-') && &pStream->zText[1] < pStream->zEnd &&
pStream->zText[1] < 0xc0 && SyisDigit(pStream->zText[1]) ){ pStream->zText[1] < 0xc0 && SyisDigit(pStream->zText[1])) {
pStream->zText++; pStream->zText++;
} }
while( pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0]) ){ while(pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisDigit(pStream->zText[0])) {
pStream->zText++; pStream->zText++;
} }
} }
pToken->nType = PH7_TK_REAL; pToken->nType = PH7_TK_REAL;
}else if( c == 'x' || c == 'X' ){ } else if(c == 'x' || c == 'X') {
/* Hex digit stream */ /* Hex digit stream */
pStream->zText++; pStream->zText++;
while( pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisHex(pStream->zText[0]) ){ while(pStream->zText < pStream->zEnd && pStream->zText[0] < 0xc0 && SyisHex(pStream->zText[0])) {
pStream->zText++; pStream->zText++;
} }
}else if(c == 'b' || c == 'B' ){ } else if(c == 'b' || c == 'B') {
/* Binary digit stream */ /* Binary digit stream */
pStream->zText++; pStream->zText++;
while( pStream->zText < pStream->zEnd && (pStream->zText[0] == '0' || pStream->zText[0] == '1') ){ while(pStream->zText < pStream->zEnd && (pStream->zText[0] == '0' || pStream->zText[0] == '1')) {
pStream->zText++; pStream->zText++;
} }
} }
} }
/* Record token length */ /* Record token length */
pStr->nByte = (sxu32)((const char *)pStream->zText-pStr->zString); pStr->nByte = (sxu32)((const char *)pStream->zText - pStr->zString);
return SXRET_OK; return SXRET_OK;
} }
c = pStream->zText[0]; c = pStream->zText[0];
pStream->zText++; /* Advance the stream cursor */ pStream->zText++; /* Advance the stream cursor */
/* Assume we are dealing with an operator*/ /* Assume we are dealing with an operator*/
pToken->nType = PH7_TK_OP; pToken->nType = PH7_TK_OP;
switch(c){ switch(c) {
case '$': pToken->nType = PH7_TK_DOLLAR; break; case '$':
case '{': pToken->nType = PH7_TK_OCB; break; pToken->nType = PH7_TK_DOLLAR;
case '}': pToken->nType = PH7_TK_CCB; break; break;
case '(': pToken->nType = PH7_TK_LPAREN; break; case '{':
case '[': pToken->nType |= PH7_TK_OSB; break; /* Bitwise operation here,since the square bracket token '[' pToken->nType = PH7_TK_OCB;
break;
case '}':
pToken->nType = PH7_TK_CCB;
break;
case '(':
pToken->nType = PH7_TK_LPAREN;
break;
case '[':
pToken->nType |= PH7_TK_OSB;
break; /* Bitwise operation here,since the square bracket token '['
* is a potential operator [i.e: subscripting] */ * is a potential operator [i.e: subscripting] */
case ']': pToken->nType = PH7_TK_CSB; break; case ']':
pToken->nType = PH7_TK_CSB;
break;
case ')': { case ')': {
SySet *pTokSet = pStream->pSet; SySet *pTokSet = pStream->pSet;
/* Assemble type cast operators [i.e: (int),(float),(bool)...] */ /* Assemble type cast operators [i.e: (int),(float),(bool)...] */
if( pTokSet->nUsed >= 2 ){ if(pTokSet->nUsed >= 2) {
SyToken *pTmp; SyToken *pTmp;
/* Peek the last recongnized token */ /* Peek the last recongnized token */
pTmp = (SyToken *)SySetPeek(pTokSet); pTmp = (SyToken *)SySetPeek(pTokSet);
if( pTmp->nType & PH7_TK_KEYWORD ){ if(pTmp->nType & PH7_TK_KEYWORD) {
sxi32 nID = SX_PTR_TO_INT(pTmp->pUserData); sxi32 nID = SX_PTR_TO_INT(pTmp->pUserData);
if( (sxu32)nID & (PH7_TKWRD_ARRAY|PH7_TKWRD_INT|PH7_TKWRD_FLOAT|PH7_TKWRD_STRING|PH7_TKWRD_OBJECT|PH7_TKWRD_BOOL|PH7_TKWRD_UNSET) ){ if((sxu32)nID & (PH7_TKWRD_ARRAY | PH7_TKWRD_INT | PH7_TKWRD_FLOAT | PH7_TKWRD_STRING | PH7_TKWRD_OBJECT | PH7_TKWRD_BOOL | PH7_TKWRD_UNSET)) {
pTmp = (SyToken *)SySetAt(pTokSet,pTokSet->nUsed - 2); pTmp = (SyToken *)SySetAt(pTokSet, pTokSet->nUsed - 2);
if( pTmp->nType & PH7_TK_LPAREN ){ if(pTmp->nType & PH7_TK_LPAREN) {
/* Merge the three tokens '(' 'TYPE' ')' into a single one */ /* Merge the three tokens '(' 'TYPE' ')' into a single one */
const char * zTypeCast = "(int)"; const char *zTypeCast = "(int)";
if( nID & PH7_TKWRD_FLOAT ){ if(nID & PH7_TKWRD_FLOAT) {
zTypeCast = "(float)"; zTypeCast = "(float)";
}else if( nID & PH7_TKWRD_BOOL ){ } else if(nID & PH7_TKWRD_BOOL) {
zTypeCast = "(bool)"; zTypeCast = "(bool)";
}else if( nID & PH7_TKWRD_STRING ){ } else if(nID & PH7_TKWRD_STRING) {
zTypeCast = "(string)"; zTypeCast = "(string)";
}else if( nID & PH7_TKWRD_ARRAY ){ } else if(nID & PH7_TKWRD_ARRAY) {
zTypeCast = "(array)"; zTypeCast = "(array)";
}else if( nID & PH7_TKWRD_OBJECT ){ } else if(nID & PH7_TKWRD_OBJECT) {
zTypeCast = "(object)"; zTypeCast = "(object)";
}else if( nID & PH7_TKWRD_UNSET ){ } else if(nID & PH7_TKWRD_UNSET) {
zTypeCast = "(unset)"; zTypeCast = "(unset)";
} }
/* Reflect the change */ /* Reflect the change */
pToken->nType = PH7_TK_OP; pToken->nType = PH7_TK_OP;
SyStringInitFromBuf(&pToken->sData,zTypeCast,SyStrlen(zTypeCast)); SyStringInitFromBuf(&pToken->sData, zTypeCast, SyStrlen(zTypeCast));
/* Save the instance associated with the type cast operator */ /* Save the instance associated with the type cast operator */
pToken->pUserData = (void *)PH7_ExprExtractOperator(&pToken->sData,0); pToken->pUserData = (void *)PH7_ExprExtractOperator(&pToken->sData, 0);
/* Remove the two previous tokens */ /* Remove the two previous tokens */
pTokSet->nUsed -= 2; pTokSet->nUsed -= 2;
return SXRET_OK; return SXRET_OK;
@ -247,151 +258,157 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
pToken->nType = PH7_TK_RPAREN; pToken->nType = PH7_TK_RPAREN;
break; break;
} }
case '\'':{ case '\'': {
/* Single quoted string */ /* Single quoted string */
pStr->zString++; pStr->zString++;
while( pStream->zText < pStream->zEnd ){ while(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '\'' ){ if(pStream->zText[0] == '\'') {
if( pStream->zText[-1] != '\\' ){ if(pStream->zText[-1] != '\\') {
break; break;
}else{ } else {
const unsigned char *zPtr = &pStream->zText[-2]; const unsigned char *zPtr = &pStream->zText[-2];
sxi32 i = 1; sxi32 i = 1;
while( zPtr > pStream->zInput && zPtr[0] == '\\' ){ while(zPtr > pStream->zInput && zPtr[0] == '\\') {
zPtr--; zPtr--;
i++; i++;
} }
if((i&1)==0){ if((i & 1) == 0) {
break; break;
} }
} }
} }
if( pStream->zText[0] == '\n' ){ if(pStream->zText[0] == '\n') {
pStream->nLine++; pStream->nLine++;
} }
pStream->zText++; pStream->zText++;
} }
/* Record token length and type */ /* Record token length and type */
pStr->nByte = (sxu32)((const char *)pStream->zText-pStr->zString); pStr->nByte = (sxu32)((const char *)pStream->zText - pStr->zString);
pToken->nType = PH7_TK_SSTR; pToken->nType = PH7_TK_SSTR;
/* Jump the trailing single quote */ /* Jump the trailing single quote */
pStream->zText++; pStream->zText++;
return SXRET_OK; return SXRET_OK;
} }
case '"':{ case '"': {
sxi32 iNest; sxi32 iNest;
/* Double quoted string */ /* Double quoted string */
pStr->zString++; pStr->zString++;
while( pStream->zText < pStream->zEnd ){ while(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '{' && &pStream->zText[1] < pStream->zEnd && pStream->zText[1] == '$'){ if(pStream->zText[0] == '{' && &pStream->zText[1] < pStream->zEnd && pStream->zText[1] == '$') {
iNest = 1; iNest = 1;
pStream->zText++; pStream->zText++;
/* TICKET 1433-40: Hnadle braces'{}' in double quoted string where everything is allowed */ /* TICKET 1433-40: Hnadle braces'{}' in double quoted string where everything is allowed */
while(pStream->zText < pStream->zEnd ){ while(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '{' ){ if(pStream->zText[0] == '{') {
iNest++; iNest++;
}else if (pStream->zText[0] == '}' ){ } else if(pStream->zText[0] == '}') {
iNest--; iNest--;
if( iNest <= 0 ){ if(iNest <= 0) {
pStream->zText++; pStream->zText++;
break; break;
} }
}else if( pStream->zText[0] == '\n' ){ } else if(pStream->zText[0] == '\n') {
pStream->nLine++; pStream->nLine++;
} }
pStream->zText++; pStream->zText++;
} }
if( pStream->zText >= pStream->zEnd ){ if(pStream->zText >= pStream->zEnd) {
break; break;
} }
} }
if( pStream->zText[0] == '"' ){ if(pStream->zText[0] == '"') {
if( pStream->zText[-1] != '\\' ){ if(pStream->zText[-1] != '\\') {
break; break;
}else{ } else {
const unsigned char *zPtr = &pStream->zText[-2]; const unsigned char *zPtr = &pStream->zText[-2];
sxi32 i = 1; sxi32 i = 1;
while( zPtr > pStream->zInput && zPtr[0] == '\\' ){ while(zPtr > pStream->zInput && zPtr[0] == '\\') {
zPtr--; zPtr--;
i++; i++;
} }
if((i&1)==0){ if((i & 1) == 0) {
break; break;
} }
} }
} }
if( pStream->zText[0] == '\n' ){ if(pStream->zText[0] == '\n') {
pStream->nLine++; pStream->nLine++;
} }
pStream->zText++; pStream->zText++;
} }
/* Record token length and type */ /* Record token length and type */
pStr->nByte = (sxu32)((const char *)pStream->zText-pStr->zString); pStr->nByte = (sxu32)((const char *)pStream->zText - pStr->zString);
pToken->nType = PH7_TK_DSTR; pToken->nType = PH7_TK_DSTR;
/* Jump the trailing quote */ /* Jump the trailing quote */
pStream->zText++; pStream->zText++;
return SXRET_OK; return SXRET_OK;
} }
case '`':{ case '`': {
/* Backtick quoted string */ /* Backtick quoted string */
pStr->zString++; pStr->zString++;
while( pStream->zText < pStream->zEnd ){ while(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '`' && pStream->zText[-1] != '\\' ){ if(pStream->zText[0] == '`' && pStream->zText[-1] != '\\') {
break; break;
} }
if( pStream->zText[0] == '\n' ){ if(pStream->zText[0] == '\n') {
pStream->nLine++; pStream->nLine++;
} }
pStream->zText++; pStream->zText++;
} }
/* Record token length and type */ /* Record token length and type */
pStr->nByte = (sxu32)((const char *)pStream->zText-pStr->zString); pStr->nByte = (sxu32)((const char *)pStream->zText - pStr->zString);
pToken->nType = PH7_TK_BSTR; pToken->nType = PH7_TK_BSTR;
/* Jump the trailing backtick */ /* Jump the trailing backtick */
pStream->zText++; pStream->zText++;
return SXRET_OK; return SXRET_OK;
} }
case '\\': pToken->nType = PH7_TK_NSSEP; break; case '\\':
pToken->nType = PH7_TK_NSSEP;
break;
case ':': case ':':
if( pStream->zText < pStream->zEnd && pStream->zText[0] == ':' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == ':') {
/* Current operator: '::' */ /* Current operator: '::' */
pStream->zText++; pStream->zText++;
}else{ } else {
pToken->nType = PH7_TK_COLON; /* Single colon */ pToken->nType = PH7_TK_COLON; /* Single colon */
} }
break; break;
case ',': pToken->nType |= PH7_TK_COMMA; break; /* Comma is also an operator */ case ',':
case ';': pToken->nType = PH7_TK_SEMI; break; pToken->nType |= PH7_TK_COMMA;
break; /* Comma is also an operator */
case ';':
pToken->nType = PH7_TK_SEMI;
break;
/* Handle combined operators [i.e: +=,===,!=== ...] */ /* Handle combined operators [i.e: +=,===,!=== ...] */
case '=': case '=':
pToken->nType |= PH7_TK_EQUAL; pToken->nType |= PH7_TK_EQUAL;
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '=' ){ if(pStream->zText[0] == '=') {
pToken->nType &= ~PH7_TK_EQUAL; pToken->nType &= ~PH7_TK_EQUAL;
/* Current operator: == */ /* Current operator: == */
pStream->zText++; pStream->zText++;
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: === */ /* Current operator: === */
pStream->zText++; pStream->zText++;
} }
}else if( pStream->zText[0] == '>' ){ } else if(pStream->zText[0] == '>') {
/* Array operator: => */ /* Array operator: => */
pToken->nType = PH7_TK_ARRAY_OP; pToken->nType = PH7_TK_ARRAY_OP;
pStream->zText++; pStream->zText++;
}else{ } else {
/* TICKET 1433-0010: Reference operator '=&' */ /* TICKET 1433-0010: Reference operator '=&' */
const unsigned char *zCur = pStream->zText; const unsigned char *zCur = pStream->zText;
sxu32 nLine = 0; sxu32 nLine = 0;
while( zCur < pStream->zEnd && zCur[0] < 0xc0 && SyisSpace(zCur[0]) ){ while(zCur < pStream->zEnd && zCur[0] < 0xc0 && SyisSpace(zCur[0])) {
if( zCur[0] == '\n' ){ if(zCur[0] == '\n') {
nLine++; nLine++;
} }
zCur++; zCur++;
} }
if( zCur < pStream->zEnd && zCur[0] == '&' ){ if(zCur < pStream->zEnd && zCur[0] == '&') {
/* Current operator: =& */ /* Current operator: =& */
pToken->nType &= ~PH7_TK_EQUAL; pToken->nType &= ~PH7_TK_EQUAL;
SyStringInitFromBuf(pStr,"=&",sizeof("=&")-1); SyStringInitFromBuf(pStr, "=&", sizeof("=&") - 1);
/* Update token stream */ /* Update token stream */
pStream->zText = &zCur[1]; pStream->zText = &zCur[1];
pStream->nLine += nLine; pStream->nLine += nLine;
@ -400,10 +417,10 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
} }
break; break;
case '!': case '!':
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: != */ /* Current operator: != */
pStream->zText++; pStream->zText++;
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: !== */ /* Current operator: !== */
pStream->zText++; pStream->zText++;
} }
@ -411,12 +428,12 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
break; break;
case '&': case '&':
pToken->nType |= PH7_TK_AMPER; pToken->nType |= PH7_TK_AMPER;
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '&' ){ if(pStream->zText[0] == '&') {
pToken->nType &= ~PH7_TK_AMPER; pToken->nType &= ~PH7_TK_AMPER;
/* Current operator: && */ /* Current operator: && */
pStream->zText++; pStream->zText++;
}else if( pStream->zText[0] == '=' ){ } else if(pStream->zText[0] == '=') {
pToken->nType &= ~PH7_TK_AMPER; pToken->nType &= ~PH7_TK_AMPER;
/* Current operator: &= */ /* Current operator: &= */
pStream->zText++; pStream->zText++;
@ -424,106 +441,106 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
} }
break; break;
case '|': case '|':
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '|' ){ if(pStream->zText[0] == '|') {
/* Current operator: || */ /* Current operator: || */
pStream->zText++; pStream->zText++;
}else if( pStream->zText[0] == '=' ){ } else if(pStream->zText[0] == '=') {
/* Current operator: |= */ /* Current operator: |= */
pStream->zText++; pStream->zText++;
} }
} }
break; break;
case '+': case '+':
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '+' ){ if(pStream->zText[0] == '+') {
/* Current operator: ++ */ /* Current operator: ++ */
pStream->zText++; pStream->zText++;
}else if( pStream->zText[0] == '=' ){ } else if(pStream->zText[0] == '=') {
/* Current operator: += */ /* Current operator: += */
pStream->zText++; pStream->zText++;
} }
} }
break; break;
case '-': case '-':
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '-' ){ if(pStream->zText[0] == '-') {
/* Current operator: -- */ /* Current operator: -- */
pStream->zText++; pStream->zText++;
}else if( pStream->zText[0] == '=' ){ } else if(pStream->zText[0] == '=') {
/* Current operator: -= */ /* Current operator: -= */
pStream->zText++; pStream->zText++;
}else if( pStream->zText[0] == '>' ){ } else if(pStream->zText[0] == '>') {
/* Current operator: -> */ /* Current operator: -> */
pStream->zText++; pStream->zText++;
} }
} }
break; break;
case '*': case '*':
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: *= */ /* Current operator: *= */
pStream->zText++; pStream->zText++;
} }
break; break;
case '/': case '/':
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: /= */ /* Current operator: /= */
pStream->zText++; pStream->zText++;
} }
break; break;
case '%': case '%':
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: %= */ /* Current operator: %= */
pStream->zText++; pStream->zText++;
} }
break; break;
case '^': case '^':
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '=' ){ if(pStream->zText[0] == '=') {
/* Current operator: ^= */ /* Current operator: ^= */
pStream->zText++; pStream->zText++;
}else if( pStream->zText[0] == '^' ){ } else if(pStream->zText[0] == '^') {
/* Current operator: ^^ */ /* Current operator: ^^ */
pStream->zText++; pStream->zText++;
} }
} }
break; break;
case '.': case '.':
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: .= */ /* Current operator: .= */
pStream->zText++; pStream->zText++;
} }
break; break;
case '<': case '<':
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '<' ){ if(pStream->zText[0] == '<') {
/* Current operator: << */ /* Current operator: << */
pStream->zText++; pStream->zText++;
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '=' ){ if(pStream->zText[0] == '=') {
/* Current operator: <<= */ /* Current operator: <<= */
pStream->zText++; pStream->zText++;
} }
} }
}else if( pStream->zText[0] == '>' ){ } else if(pStream->zText[0] == '>') {
/* Current operator: <> */ /* Current operator: <> */
pStream->zText++; pStream->zText++;
}else if( pStream->zText[0] == '=' ){ } else if(pStream->zText[0] == '=') {
/* Current operator: <= */ /* Current operator: <= */
pStream->zText++; pStream->zText++;
} }
} }
break; break;
case '>': case '>':
if( pStream->zText < pStream->zEnd ){ if(pStream->zText < pStream->zEnd) {
if( pStream->zText[0] == '>' ){ if(pStream->zText[0] == '>') {
/* Current operator: >> */ /* Current operator: >> */
pStream->zText++; pStream->zText++;
if( pStream->zText < pStream->zEnd && pStream->zText[0] == '=' ){ if(pStream->zText < pStream->zEnd && pStream->zText[0] == '=') {
/* Current operator: >>= */ /* Current operator: >>= */
pStream->zText++; pStream->zText++;
} }
}else if( pStream->zText[0] == '=' ){ } else if(pStream->zText[0] == '=') {
/* Current operator: >= */ /* Current operator: >= */
pStream->zText++; pStream->zText++;
} }
@ -532,21 +549,21 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
default: default:
break; break;
} }
if( pStr->nByte <= 0 ){ if(pStr->nByte <= 0) {
/* Record token length */ /* Record token length */
pStr->nByte = (sxu32)((const char *)pStream->zText-pStr->zString); pStr->nByte = (sxu32)((const char *)pStream->zText - pStr->zString);
} }
if( pToken->nType & PH7_TK_OP ){ if(pToken->nType & PH7_TK_OP) {
const ph7_expr_op *pOp; const ph7_expr_op *pOp;
/* Check if the extracted token is an operator */ /* Check if the extracted token is an operator */
pOp = PH7_ExprExtractOperator(pStr,(SyToken *)SySetPeek(pStream->pSet)); pOp = PH7_ExprExtractOperator(pStr, (SyToken *)SySetPeek(pStream->pSet));
if( pOp == 0 ){ if(pOp == 0) {
/* Not an operator */ /* Not an operator */
pToken->nType &= ~PH7_TK_OP; pToken->nType &= ~PH7_TK_OP;
if( pToken->nType <= 0 ){ if(pToken->nType <= 0) {
pToken->nType = PH7_TK_OTHER; pToken->nType = PH7_TK_OTHER;
} }
}else{ } else {
/* Save the instance associated with this operator for later processing */ /* Save the instance associated with this operator for later processing */
pToken->pUserData = (void *)pOp; pToken->pUserData = (void *)pOp;
} }
@ -556,7 +573,7 @@ static sxi32 TokenizePHP(SyStream *pStream,SyToken *pToken,void *pUserData,void
return SXRET_OK; return SXRET_OK;
} }
static sxu32 KeywordCode(const char *z, int n){ static sxu32 KeywordCode(const char *z, int n) {
typedef struct { typedef struct {
char *token; char *token;
int value; int value;
@ -649,18 +666,17 @@ static sxu32 KeywordCode(const char *z, int n){
* Tokenize a raw PHP input. * Tokenize a raw PHP input.
* This is the public tokenizer called by most code generator routines. * This is the public tokenizer called by most code generator routines.
*/ */
PH7_PRIVATE sxi32 PH7_TokenizePHP(const char *zInput,sxu32 nLen,sxu32 nLineStart,SySet *pOut) PH7_PRIVATE sxi32 PH7_TokenizePHP(const char *zInput, sxu32 nLen, sxu32 nLineStart, SySet *pOut) {
{
SyLex sLexer; SyLex sLexer;
sxi32 rc; sxi32 rc;
/* Initialize the lexer */ /* Initialize the lexer */
rc = SyLexInit(&sLexer,&(*pOut),TokenizePHP,0); rc = SyLexInit(&sLexer, &(*pOut), TokenizePHP, 0);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
sLexer.sStream.nLine = nLineStart; sLexer.sStream.nLine = nLineStart;
/* Tokenize input */ /* Tokenize input */
rc = SyLexTokenizeInput(&sLexer,zInput,nLen,0,0,0); rc = SyLexTokenizeInput(&sLexer, zInput, nLen, 0, 0, 0);
/* Release the lexer */ /* Release the lexer */
SyLexRelease(&sLexer); SyLexRelease(&sLexer);
/* Tokenization result */ /* Tokenization result */
@ -711,11 +727,10 @@ PH7_PRIVATE sxi32 PH7_TokenizePHP(const char *zInput,sxu32 nLen,sxu32 nLineStart
* 3. <? echo 'this is the simplest, an SGML processing instruction'; ?> * 3. <? echo 'this is the simplest, an SGML processing instruction'; ?>
* <?= expression ?> This is a shortcut for "<? echo expression ?>" * <?= expression ?> This is a shortcut for "<? echo expression ?>"
*/ */
PH7_PRIVATE sxi32 PH7_TokenizeRawText(const char *zInput,sxu32 nLen,SySet *pOut) PH7_PRIVATE sxi32 PH7_TokenizeRawText(const char *zInput, sxu32 nLen, SySet *pOut) {
{
const char *zEnd = &zInput[nLen]; const char *zEnd = &zInput[nLen];
const char *zIn = zInput; const char *zIn = zInput;
const char *zCur,*zCurEnd; const char *zCur, *zCurEnd;
SyString sCtag = { 0, 0 }; /* Closing tag */ SyString sCtag = { 0, 0 }; /* Closing tag */
SyToken sToken; SyToken sToken;
SyString sDoc; SyString sDoc;
@ -729,54 +744,54 @@ PH7_PRIVATE sxi32 PH7_TokenizeRawText(const char *zInput,sxu32 nLen,SySet *pOut)
iNest = 0; iNest = 0;
sDoc.nByte = 0; sDoc.nByte = 0;
sDoc.zString = ""; /* cc warning */ sDoc.zString = ""; /* cc warning */
for(;;){ for(;;) {
if( zIn >= zEnd ){ if(zIn >= zEnd) {
/* End of input reached */ /* End of input reached */
break; break;
} }
sToken.nLine = nLine; sToken.nLine = nLine;
zCur = zIn; zCur = zIn;
zCurEnd = 0; zCurEnd = 0;
while( zIn < zEnd ){ while(zIn < zEnd) {
if( zIn[0] == '<' ){ if(zIn[0] == '<') {
const char *zTmp = zIn; /* End of raw input marker */ const char *zTmp = zIn; /* End of raw input marker */
zIn++; zIn++;
if( zIn < zEnd ){ if(zIn < zEnd) {
if( zIn[0] == '?' ){ if(zIn[0] == '?') {
zIn++; zIn++;
if( (sxu32)(zEnd - zIn) >= sizeof("php")-1 && SyStrnicmp(zIn,"php",sizeof("php")-1) == 0 ){ if((sxu32)(zEnd - zIn) >= sizeof("php") - 1 && SyStrnicmp(zIn, "php", sizeof("php") - 1) == 0) {
/* opening tag: <?php */ /* opening tag: <?php */
zIn += sizeof("php")-1; zIn += sizeof("php") - 1;
} }
/* Look for the closing tag '?>' */ /* Look for the closing tag '?>' */
SyStringInitFromBuf(&sCtag,"?>",sizeof("?>")-1); SyStringInitFromBuf(&sCtag, "?>", sizeof("?>") - 1);
zCurEnd = zTmp; zCurEnd = zTmp;
break; break;
} }
} }
}else{ } else {
if( zIn[0] == '\n' ){ if(zIn[0] == '\n') {
nLine++; nLine++;
} }
zIn++; zIn++;
} }
} /* While(zIn < zEnd) */ } /* While(zIn < zEnd) */
if( zCurEnd == 0 ){ if(zCurEnd == 0) {
zCurEnd = zIn; zCurEnd = zIn;
} }
/* Save the raw token */ /* Save the raw token */
SyStringInitFromBuf(&sToken.sData,zCur,zCurEnd - zCur); SyStringInitFromBuf(&sToken.sData, zCur, zCurEnd - zCur);
sToken.nType = PH7_TOKEN_RAW; sToken.nType = PH7_TOKEN_RAW;
rc = SySetPut(&(*pOut),(const void *)&sToken); rc = SySetPut(&(*pOut), (const void *)&sToken);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
if( zIn >= zEnd ){ if(zIn >= zEnd) {
break; break;
} }
/* Ignore leading white space */ /* Ignore leading white space */
while( zIn < zEnd && (unsigned char)zIn[0] < 0xc0 && SyisSpace(zIn[0]) ){ while(zIn < zEnd && (unsigned char)zIn[0] < 0xc0 && SyisSpace(zIn[0])) {
if( zIn[0] == '\n' ){ if(zIn[0] == '\n') {
nLine++; nLine++;
} }
zIn++; zIn++;
@ -784,112 +799,111 @@ PH7_PRIVATE sxi32 PH7_TokenizeRawText(const char *zInput,sxu32 nLen,SySet *pOut)
/* Delimit the PHP chunk */ /* Delimit the PHP chunk */
sToken.nLine = nLine; sToken.nLine = nLine;
zCur = zIn; zCur = zIn;
while( (sxu32)(zEnd - zIn) >= sCtag.nByte ){ while((sxu32)(zEnd - zIn) >= sCtag.nByte) {
const char *zPtr; const char *zPtr;
if( SyMemcmp(zIn,sCtag.zString,sCtag.nByte) == 0 && iNest < 1 ){ if(SyMemcmp(zIn, sCtag.zString, sCtag.nByte) == 0 && iNest < 1) {
break; break;
} }
for(;;){ for(;;) {
if( zIn[0] != '/' || (zIn[1] != '*' && zIn[1] != '/') /* && sCtag.nByte >= 2 */ ){ if(zIn[0] != '/' || (zIn[1] != '*' && zIn[1] != '/') /* && sCtag.nByte >= 2 */) {
break; break;
} }
zIn += 2; zIn += 2;
if( zIn[-1] == '/' ){ if(zIn[-1] == '/') {
/* Inline comment */ /* Inline comment */
while( zIn < zEnd && zIn[0] != '\n' ){ while(zIn < zEnd && zIn[0] != '\n') {
zIn++; zIn++;
} }
if( zIn >= zEnd ){ if(zIn >= zEnd) {
zIn--; zIn--;
} }
}else{ } else {
/* Block comment */ /* Block comment */
while( (sxu32)(zEnd-zIn) >= sizeof("*/") - 1 ){ while((sxu32)(zEnd - zIn) >= sizeof("*/") - 1) {
if( zIn[0] == '*' && zIn[1] == '/' ){ if(zIn[0] == '*' && zIn[1] == '/') {
zIn += 2; zIn += 2;
break; break;
} }
if( zIn[0] == '\n' ){ if(zIn[0] == '\n') {
nLine++; nLine++;
} }
zIn++; zIn++;
} }
} }
} }
if( zIn[0] == '\n' ){ if(zIn[0] == '\n') {
nLine++; nLine++;
if( iNest > 0 ){ if(iNest > 0) {
zIn++; zIn++;
while( zIn < zEnd && (unsigned char)zIn[0] < 0xc0 && SyisSpace(zIn[0]) && zIn[0] != '\n' ){ while(zIn < zEnd && (unsigned char)zIn[0] < 0xc0 && SyisSpace(zIn[0]) && zIn[0] != '\n') {
zIn++; zIn++;
} }
zPtr = zIn; zPtr = zIn;
while( zIn < zEnd ){ while(zIn < zEnd) {
if( (unsigned char)zIn[0] >= 0xc0 ){ if((unsigned char)zIn[0] >= 0xc0) {
/* UTF-8 stream */ /* UTF-8 stream */
zIn++; zIn++;
SX_JMP_UTF8(zIn,zEnd); SX_JMP_UTF8(zIn, zEnd);
}else if( !SyisAlphaNum(zIn[0]) && zIn[0] != '_' ){ } else if(!SyisAlphaNum(zIn[0]) && zIn[0] != '_') {
break; break;
}else{ } else {
zIn++; zIn++;
} }
} }
if( (sxu32)(zIn - zPtr) == sDoc.nByte && SyMemcmp(sDoc.zString,zPtr,sDoc.nByte) == 0 ){ if((sxu32)(zIn - zPtr) == sDoc.nByte && SyMemcmp(sDoc.zString, zPtr, sDoc.nByte) == 0) {
iNest = 0; iNest = 0;
} }
continue; continue;
} }
}else if ( (sxu32)(zEnd - zIn) >= sizeof("<<<") && zIn[0] == '<' && zIn[1] == '<' && zIn[2] == '<' && iNest < 1){ } else if((sxu32)(zEnd - zIn) >= sizeof("<<<") && zIn[0] == '<' && zIn[1] == '<' && zIn[2] == '<' && iNest < 1) {
zIn += sizeof("<<<")-1; zIn += sizeof("<<<") - 1;
while( zIn < zEnd && (unsigned char)zIn[0] < 0xc0 && SyisSpace(zIn[0]) && zIn[0] != '\n' ){ while(zIn < zEnd && (unsigned char)zIn[0] < 0xc0 && SyisSpace(zIn[0]) && zIn[0] != '\n') {
zIn++; zIn++;
} }
if( zIn[0] == '"' || zIn[0] == '\'' ){ if(zIn[0] == '"' || zIn[0] == '\'') {
zIn++; zIn++;
} }
zPtr = zIn; zPtr = zIn;
while( zIn < zEnd ){ while(zIn < zEnd) {
if( (unsigned char)zIn[0] >= 0xc0 ){ if((unsigned char)zIn[0] >= 0xc0) {
/* UTF-8 stream */ /* UTF-8 stream */
zIn++; zIn++;
SX_JMP_UTF8(zIn,zEnd); SX_JMP_UTF8(zIn, zEnd);
}else if( !SyisAlphaNum(zIn[0]) && zIn[0] != '_' ){ } else if(!SyisAlphaNum(zIn[0]) && zIn[0] != '_') {
break; break;
}else{ } else {
zIn++; zIn++;
} }
} }
SyStringInitFromBuf(&sDoc,zPtr,zIn-zPtr); SyStringInitFromBuf(&sDoc, zPtr, zIn - zPtr);
SyStringFullTrim(&sDoc); SyStringFullTrim(&sDoc);
if( sDoc.nByte > 0 ){ if(sDoc.nByte > 0) {
iNest++; iNest++;
} }
continue; continue;
} }
zIn++; zIn++;
if(zIn >= zEnd) {
if ( zIn >= zEnd )
break; break;
} }
if( (sxu32)(zEnd - zIn) < sCtag.nByte ){ }
if((sxu32)(zEnd - zIn) < sCtag.nByte) {
zIn = zEnd; zIn = zEnd;
} }
if( zCur < zIn ){ if(zCur < zIn) {
/* Save the PHP chunk for later processing */ /* Save the PHP chunk for later processing */
sToken.nType = PH7_TOKEN_PHP; sToken.nType = PH7_TOKEN_PHP;
SyStringInitFromBuf(&sToken.sData,zCur,zIn-zCur); SyStringInitFromBuf(&sToken.sData, zCur, zIn - zCur);
SyStringRightTrim(&sToken.sData); /* Trim trailing white spaces */ SyStringRightTrim(&sToken.sData); /* Trim trailing white spaces */
rc = SySetPut(&(*pOut),(const void *)&sToken); rc = SySetPut(&(*pOut), (const void *)&sToken);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
} }
if( zIn < zEnd ){ if(zIn < zEnd) {
/* Jump the trailing closing tag */ /* Jump the trailing closing tag */
zIn += sCtag.nByte; zIn += sCtag.nByte;
} }
} /* For(;;) */ } /* For(;;) */
return SXRET_OK; return SXRET_OK;
} }

4287
lib.c

File diff suppressed because it is too large Load Diff

724
memobj.c

File diff suppressed because it is too large Load Diff

450
oop.c
View File

@ -10,7 +10,7 @@
* or visit: * or visit:
* http://ph7.symisc.net/ * http://ph7.symisc.net/
*/ */
/* $SymiscID: oo.c v1.9 FeeBSD 2012-07-17 03:44 devel <chm@symisc.net> $ */ /* $SymiscID: oo.c v1.9 FeeBSD 2012-07-17 03:44 devel <chm@symisc.net> $ */
#include "ph7int.h" #include "ph7int.h"
/* /*
* This file implement an Object Oriented (OO) subsystem for the PH7 engine. * This file implement an Object Oriented (OO) subsystem for the PH7 engine.
@ -19,29 +19,28 @@
* Create an empty class. * Create an empty class.
* Return a pointer to a raw class (ph7_class instance) on success. NULL otherwise. * Return a pointer to a raw class (ph7_class instance) on success. NULL otherwise.
*/ */
PH7_PRIVATE ph7_class * PH7_NewRawClass(ph7_vm *pVm,const SyString *pName,sxu32 nLine) PH7_PRIVATE ph7_class *PH7_NewRawClass(ph7_vm *pVm, const SyString *pName, sxu32 nLine) {
{
ph7_class *pClass; ph7_class *pClass;
char *zName; char *zName;
/* Allocate a new instance */ /* Allocate a new instance */
pClass = (ph7_class *)SyMemBackendPoolAlloc(&pVm->sAllocator,sizeof(ph7_class)); pClass = (ph7_class *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(ph7_class));
if( pClass == 0 ){ if(pClass == 0) {
return 0; return 0;
} }
/* Zero the structure */ /* Zero the structure */
SyZero(pClass,sizeof(ph7_class)); SyZero(pClass, sizeof(ph7_class));
/* Duplicate class name */ /* Duplicate class name */
zName = SyMemBackendStrDup(&pVm->sAllocator,pName->zString,pName->nByte); zName = SyMemBackendStrDup(&pVm->sAllocator, pName->zString, pName->nByte);
if( zName == 0 ){ if(zName == 0) {
SyMemBackendPoolFree(&pVm->sAllocator,pClass); SyMemBackendPoolFree(&pVm->sAllocator, pClass);
return 0; return 0;
} }
/* Initialize fields */ /* Initialize fields */
SyStringInitFromBuf(&pClass->sName,zName,pName->nByte); SyStringInitFromBuf(&pClass->sName, zName, pName->nByte);
SyHashInit(&pClass->hMethod,&pVm->sAllocator,0,0); SyHashInit(&pClass->hMethod, &pVm->sAllocator, 0, 0);
SyHashInit(&pClass->hAttr,&pVm->sAllocator,0,0); SyHashInit(&pClass->hAttr, &pVm->sAllocator, 0, 0);
SyHashInit(&pClass->hDerived,&pVm->sAllocator,0,0); SyHashInit(&pClass->hDerived, &pVm->sAllocator, 0, 0);
SySetInit(&pClass->aInterface,&pVm->sAllocator,sizeof(ph7_class *)); SySetInit(&pClass->aInterface, &pVm->sAllocator, sizeof(ph7_class *));
pClass->nLine = nLine; pClass->nLine = nLine;
/* All done */ /* All done */
return pClass; return pClass;
@ -50,25 +49,24 @@ PH7_PRIVATE ph7_class * PH7_NewRawClass(ph7_vm *pVm,const SyString *pName,sxu32
* Allocate and initialize a new class attribute. * Allocate and initialize a new class attribute.
* Return a pointer to the class attribute on success. NULL otherwise. * Return a pointer to the class attribute on success. NULL otherwise.
*/ */
PH7_PRIVATE ph7_class_attr * PH7_NewClassAttr(ph7_vm *pVm,const SyString *pName,sxu32 nLine,sxi32 iProtection,sxi32 iFlags) PH7_PRIVATE ph7_class_attr *PH7_NewClassAttr(ph7_vm *pVm, const SyString *pName, sxu32 nLine, sxi32 iProtection, sxi32 iFlags) {
{
ph7_class_attr *pAttr; ph7_class_attr *pAttr;
char *zName; char *zName;
pAttr = (ph7_class_attr *)SyMemBackendPoolAlloc(&pVm->sAllocator,sizeof(ph7_class_attr)); pAttr = (ph7_class_attr *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(ph7_class_attr));
if( pAttr == 0 ){ if(pAttr == 0) {
return 0; return 0;
} }
/* Zero the structure */ /* Zero the structure */
SyZero(pAttr,sizeof(ph7_class_attr)); SyZero(pAttr, sizeof(ph7_class_attr));
/* Duplicate attribute name */ /* Duplicate attribute name */
zName = SyMemBackendStrDup(&pVm->sAllocator,pName->zString,pName->nByte); zName = SyMemBackendStrDup(&pVm->sAllocator, pName->zString, pName->nByte);
if( zName == 0 ){ if(zName == 0) {
SyMemBackendPoolFree(&pVm->sAllocator,pAttr); SyMemBackendPoolFree(&pVm->sAllocator, pAttr);
return 0; return 0;
} }
/* Initialize fields */ /* Initialize fields */
SySetInit(&pAttr->aByteCode,&pVm->sAllocator,sizeof(VmInstr)); SySetInit(&pAttr->aByteCode, &pVm->sAllocator, sizeof(VmInstr));
SyStringInitFromBuf(&pAttr->sName,zName,pName->nByte); SyStringInitFromBuf(&pAttr->sName, zName, pName->nByte);
pAttr->iProtection = iProtection; pAttr->iProtection = iProtection;
pAttr->nIdx = SXU32_HIGH; pAttr->nIdx = SXU32_HIGH;
pAttr->iFlags = iFlags; pAttr->iFlags = iFlags;
@ -81,9 +79,8 @@ PH7_PRIVATE ph7_class_attr * PH7_NewClassAttr(ph7_vm *pVm,const SyString *pName,
* This function associate with the newly created method an automatically generated * This function associate with the newly created method an automatically generated
* random unique name. * random unique name.
*/ */
PH7_PRIVATE ph7_class_method * PH7_NewClassMethod(ph7_vm *pVm,ph7_class *pClass,const SyString *pName,sxu32 nLine, PH7_PRIVATE ph7_class_method *PH7_NewClassMethod(ph7_vm *pVm, ph7_class *pClass, const SyString *pName, sxu32 nLine,
sxi32 iProtection,sxi32 iFlags,sxi32 iFuncFlags) sxi32 iProtection, sxi32 iFlags, sxi32 iFuncFlags) {
{
ph7_class_method *pMeth; ph7_class_method *pMeth;
SyHashEntry *pEntry; SyHashEntry *pEntry;
SyString *pNamePtr; SyString *pNamePtr;
@ -91,39 +88,39 @@ PH7_PRIVATE ph7_class_method * PH7_NewClassMethod(ph7_vm *pVm,ph7_class *pClass,
char *zName; char *zName;
sxu32 nByte; sxu32 nByte;
/* Allocate a new class method instance */ /* Allocate a new class method instance */
pMeth = (ph7_class_method *)SyMemBackendPoolAlloc(&pVm->sAllocator,sizeof(ph7_class_method)); pMeth = (ph7_class_method *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(ph7_class_method));
if( pMeth == 0 ){ if(pMeth == 0) {
return 0; return 0;
} }
/* Zero the structure */ /* Zero the structure */
SyZero(pMeth,sizeof(ph7_class_method)); SyZero(pMeth, sizeof(ph7_class_method));
/* Check for an already installed method with the same name */ /* Check for an already installed method with the same name */
pEntry = SyHashGet(&pClass->hMethod,(const void *)pName->zString,pName->nByte); pEntry = SyHashGet(&pClass->hMethod, (const void *)pName->zString, pName->nByte);
if( pEntry == 0 ){ if(pEntry == 0) {
/* Associate an unique VM name to this method */ /* Associate an unique VM name to this method */
nByte = sizeof(zSalt) + pName->nByte + SyStringLength(&pClass->sName)+sizeof(char)*7/*[[__'\0'*/; nByte = sizeof(zSalt) + pName->nByte + SyStringLength(&pClass->sName) + sizeof(char) * 7/*[[__'\0'*/;
zName = (char *)SyMemBackendAlloc(&pVm->sAllocator,nByte); zName = (char *)SyMemBackendAlloc(&pVm->sAllocator, nByte);
if( zName == 0 ){ if(zName == 0) {
SyMemBackendPoolFree(&pVm->sAllocator,pMeth); SyMemBackendPoolFree(&pVm->sAllocator, pMeth);
return 0; return 0;
} }
pNamePtr = &pMeth->sVmName; pNamePtr = &pMeth->sVmName;
/* Generate a random string */ /* Generate a random string */
PH7_VmRandomString(&(*pVm),zSalt,sizeof(zSalt)); PH7_VmRandomString(&(*pVm), zSalt, sizeof(zSalt));
pNamePtr->nByte = SyBufferFormat(zName,nByte,"[__%z@%z_%.*s]",&pClass->sName,pName,sizeof(zSalt),zSalt); pNamePtr->nByte = SyBufferFormat(zName, nByte, "[__%z@%z_%.*s]", &pClass->sName, pName, sizeof(zSalt), zSalt);
pNamePtr->zString = zName; pNamePtr->zString = zName;
}else{ } else {
/* Method is condidate for 'overloading' */ /* Method is condidate for 'overloading' */
ph7_class_method *pCurrent = (ph7_class_method *)pEntry->pUserData; ph7_class_method *pCurrent = (ph7_class_method *)pEntry->pUserData;
pNamePtr = &pMeth->sVmName; pNamePtr = &pMeth->sVmName;
/* Use the same VM name */ /* Use the same VM name */
SyStringDupPtr(pNamePtr,&pCurrent->sVmName); SyStringDupPtr(pNamePtr, &pCurrent->sVmName);
zName = (char *)pNamePtr->zString; zName = (char *)pNamePtr->zString;
} }
if( iProtection != PH7_CLASS_PROT_PUBLIC ){ if(iProtection != PH7_CLASS_PROT_PUBLIC) {
if( (pName->nByte == sizeof("__construct") - 1 && SyMemcmp(pName->zString,"__construct",sizeof("__construct") - 1 ) == 0) if((pName->nByte == sizeof("__construct") - 1 && SyMemcmp(pName->zString, "__construct", sizeof("__construct") - 1) == 0)
|| (pName->nByte == sizeof("__destruct") - 1 && SyMemcmp(pName->zString,"__destruct",sizeof("__destruct") - 1 ) == 0) || (pName->nByte == sizeof("__destruct") - 1 && SyMemcmp(pName->zString, "__destruct", sizeof("__destruct") - 1) == 0)
|| SyStringCmp(pName,&pClass->sName,SyMemcmp) == 0 ){ || SyStringCmp(pName, &pClass->sName, SyMemcmp) == 0) {
/* Switch to public visibility when dealing with constructor/destructor */ /* Switch to public visibility when dealing with constructor/destructor */
iProtection = PH7_CLASS_PROT_PUBLIC; iProtection = PH7_CLASS_PROT_PUBLIC;
} }
@ -132,20 +129,19 @@ PH7_PRIVATE ph7_class_method * PH7_NewClassMethod(ph7_vm *pVm,ph7_class *pClass,
pMeth->iProtection = iProtection; pMeth->iProtection = iProtection;
pMeth->iFlags = iFlags; pMeth->iFlags = iFlags;
pMeth->nLine = nLine; pMeth->nLine = nLine;
PH7_VmInitFuncState(&(*pVm),&pMeth->sFunc,&zName[sizeof(char)*4/*[__@*/+SyStringLength(&pClass->sName)], PH7_VmInitFuncState(&(*pVm), &pMeth->sFunc, &zName[sizeof(char) * 4/*[__@*/ + SyStringLength(&pClass->sName)],
pName->nByte,iFuncFlags|VM_FUNC_CLASS_METHOD,pClass); pName->nByte, iFuncFlags | VM_FUNC_CLASS_METHOD, pClass);
return pMeth; return pMeth;
} }
/* /*
* Check if the given name have a class method associated with it. * Check if the given name have a class method associated with it.
* Return the desired method [i.e: ph7_class_method instance] on success. NULL otherwise. * Return the desired method [i.e: ph7_class_method instance] on success. NULL otherwise.
*/ */
PH7_PRIVATE ph7_class_method * PH7_ClassExtractMethod(ph7_class *pClass,const char *zName,sxu32 nByte) PH7_PRIVATE ph7_class_method *PH7_ClassExtractMethod(ph7_class *pClass, const char *zName, sxu32 nByte) {
{
SyHashEntry *pEntry; SyHashEntry *pEntry;
/* Perform a hash lookup */ /* Perform a hash lookup */
pEntry = SyHashGet(&pClass->hMethod,(const void *)zName,nByte); pEntry = SyHashGet(&pClass->hMethod, (const void *)zName, nByte);
if( pEntry == 0 ){ if(pEntry == 0) {
/* No such entry */ /* No such entry */
return 0; return 0;
} }
@ -156,12 +152,11 @@ PH7_PRIVATE ph7_class_method * PH7_ClassExtractMethod(ph7_class *pClass,const ch
* Check if the given name is a class attribute. * Check if the given name is a class attribute.
* Return the desired attribute [i.e: ph7_class_attr instance] on success.NULL otherwise. * Return the desired attribute [i.e: ph7_class_attr instance] on success.NULL otherwise.
*/ */
PH7_PRIVATE ph7_class_attr * PH7_ClassExtractAttribute(ph7_class *pClass,const char *zName,sxu32 nByte) PH7_PRIVATE ph7_class_attr *PH7_ClassExtractAttribute(ph7_class *pClass, const char *zName, sxu32 nByte) {
{
SyHashEntry *pEntry; SyHashEntry *pEntry;
/* Perform a hash lookup */ /* Perform a hash lookup */
pEntry = SyHashGet(&pClass->hAttr,(const void *)zName,nByte); pEntry = SyHashGet(&pClass->hAttr, (const void *)zName, nByte);
if( pEntry == 0 ){ if(pEntry == 0) {
/* No such entry */ /* No such entry */
return 0; return 0;
} }
@ -172,22 +167,20 @@ PH7_PRIVATE ph7_class_attr * PH7_ClassExtractAttribute(ph7_class *pClass,const c
* Install a class attribute in the corresponding container. * Install a class attribute in the corresponding container.
* Return SXRET_OK on success. Any other return value indicates failure. * Return SXRET_OK on success. Any other return value indicates failure.
*/ */
PH7_PRIVATE sxi32 PH7_ClassInstallAttr(ph7_class *pClass,ph7_class_attr *pAttr) PH7_PRIVATE sxi32 PH7_ClassInstallAttr(ph7_class *pClass, ph7_class_attr *pAttr) {
{
SyString *pName = &pAttr->sName; SyString *pName = &pAttr->sName;
sxi32 rc; sxi32 rc;
rc = SyHashInsert(&pClass->hAttr,(const void *)pName->zString,pName->nByte,pAttr); rc = SyHashInsert(&pClass->hAttr, (const void *)pName->zString, pName->nByte, pAttr);
return rc; return rc;
} }
/* /*
* Install a class method in the corresponding container. * Install a class method in the corresponding container.
* Return SXRET_OK on success. Any other return value indicates failure. * Return SXRET_OK on success. Any other return value indicates failure.
*/ */
PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass,ph7_class_method *pMeth) PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass, ph7_class_method *pMeth) {
{
SyString *pName = &pMeth->sFunc.sName; SyString *pName = &pMeth->sFunc.sName;
sxi32 rc; sxi32 rc;
rc = SyHashInsert(&pClass->hMethod,(const void *)pName->zString,pName->nByte,pMeth); rc = SyHashInsert(&pClass->hMethod, (const void *)pName->zString, pName->nByte, pMeth);
return rc; return rc;
} }
/* /*
@ -231,72 +224,70 @@ PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass,ph7_class_method *pMe
* Any other return value indicates failure and the upper layer must generate an appropriate * Any other return value indicates failure and the upper layer must generate an appropriate
* error message. * error message.
*/ */
PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen,ph7_class *pSub,ph7_class *pBase) PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen, ph7_class *pSub, ph7_class *pBase) {
{
ph7_class_method *pMeth; ph7_class_method *pMeth;
ph7_class_attr *pAttr; ph7_class_attr *pAttr;
SyHashEntry *pEntry; SyHashEntry *pEntry;
SyString *pName; SyString *pName;
sxi32 rc; sxi32 rc;
/* Install in the derived hashtable */ /* Install in the derived hashtable */
rc = SyHashInsert(&pBase->hDerived,(const void *)SyStringData(&pSub->sName),SyStringLength(&pSub->sName),pSub); rc = SyHashInsert(&pBase->hDerived, (const void *)SyStringData(&pSub->sName), SyStringLength(&pSub->sName), pSub);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
/* Copy public/protected attributes from the base class */ /* Copy public/protected attributes from the base class */
SyHashResetLoopCursor(&pBase->hAttr); SyHashResetLoopCursor(&pBase->hAttr);
while((pEntry = SyHashGetNextEntry(&pBase->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pBase->hAttr)) != 0) {
/* Make sure the private attributes are not redeclared in the subclass */ /* Make sure the private attributes are not redeclared in the subclass */
pAttr = (ph7_class_attr *)pEntry->pUserData; pAttr = (ph7_class_attr *)pEntry->pUserData;
pName = &pAttr->sName; pName = &pAttr->sName;
if( (pEntry = SyHashGet(&pSub->hAttr,(const void *)pName->zString,pName->nByte)) != 0 ){ if((pEntry = SyHashGet(&pSub->hAttr, (const void *)pName->zString, pName->nByte)) != 0) {
if( pAttr->iProtection == PH7_CLASS_PROT_PRIVATE && if(pAttr->iProtection == PH7_CLASS_PROT_PRIVATE &&
((ph7_class_attr *)pEntry->pUserData)->iProtection != PH7_CLASS_PROT_PUBLIC ){ ((ph7_class_attr *)pEntry->pUserData)->iProtection != PH7_CLASS_PROT_PUBLIC) {
/* Cannot redeclare private attribute */ /* Cannot redeclare private attribute */
PH7_GenCompileError(&(*pGen),E_WARNING,((ph7_class_attr *)pEntry->pUserData)->nLine, PH7_GenCompileError(&(*pGen), E_WARNING, ((ph7_class_attr *)pEntry->pUserData)->nLine,
"Private attribute '%z::%z' redeclared inside child class '%z'", "Private attribute '%z::%z' redeclared inside child class '%z'",
&pBase->sName,pName,&pSub->sName); &pBase->sName, pName, &pSub->sName);
} }
continue; continue;
} }
/* Install the attribute */ /* Install the attribute */
if( pAttr->iProtection != PH7_CLASS_PROT_PRIVATE ){ if(pAttr->iProtection != PH7_CLASS_PROT_PRIVATE) {
rc = SyHashInsert(&pSub->hAttr,(const void *)pName->zString,pName->nByte,pAttr); rc = SyHashInsert(&pSub->hAttr, (const void *)pName->zString, pName->nByte, pAttr);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
} }
} }
SyHashResetLoopCursor(&pBase->hMethod); SyHashResetLoopCursor(&pBase->hMethod);
while((pEntry = SyHashGetNextEntry(&pBase->hMethod)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pBase->hMethod)) != 0) {
/* Make sure the private/final methods are not redeclared in the subclass */ /* Make sure the private/final methods are not redeclared in the subclass */
pMeth = (ph7_class_method *)pEntry->pUserData; pMeth = (ph7_class_method *)pEntry->pUserData;
pName = &pMeth->sFunc.sName; pName = &pMeth->sFunc.sName;
if( (pEntry = SyHashGet(&pSub->hMethod,(const void *)pName->zString,pName->nByte)) != 0 ){ if((pEntry = SyHashGet(&pSub->hMethod, (const void *)pName->zString, pName->nByte)) != 0) {
if( pMeth->iFlags & PH7_CLASS_ATTR_FINAL ){ if(pMeth->iFlags & PH7_CLASS_ATTR_FINAL) {
/* Cannot Overwrite final method */ /* Cannot Overwrite final method */
rc = PH7_GenCompileError(&(*pGen),E_ERROR,((ph7_class_method *)pEntry->pUserData)->nLine, rc = PH7_GenCompileError(&(*pGen), E_ERROR, ((ph7_class_method *)pEntry->pUserData)->nLine,
"Cannot Overwrite final method '%z:%z' inside child class '%z'", "Cannot Overwrite final method '%z:%z' inside child class '%z'",
&pBase->sName,pName,&pSub->sName); &pBase->sName, pName, &pSub->sName);
if( rc == SXERR_ABORT ){ if(rc == SXERR_ABORT) {
return SXERR_ABORT; return SXERR_ABORT;
} }
} }
continue; continue;
}else{ } else {
if( pMeth->iFlags & PH7_CLASS_ATTR_ABSTRACT ){ if(pMeth->iFlags & PH7_CLASS_ATTR_ABSTRACT) {
/* Abstract method must be defined in the child class */ /* Abstract method must be defined in the child class */
PH7_GenCompileError(&(*pGen),E_WARNING,pMeth->nLine, PH7_GenCompileError(&(*pGen), E_WARNING, pMeth->nLine,
"Abstract method '%z:%z' must be defined inside child class '%z'", "Abstract method '%z:%z' must be defined inside child class '%z'",
&pBase->sName,pName,&pSub->sName); &pBase->sName, pName, &pSub->sName);
continue; continue;
} }
} }
/* Install the method */ /* Install the method */
if( pMeth->iProtection != PH7_CLASS_PROT_PRIVATE ){ if(pMeth->iProtection != PH7_CLASS_PROT_PRIVATE) {
rc = SyHashInsert(&pSub->hMethod,(const void *)pName->zString,pName->nByte,pMeth); rc = SyHashInsert(&pSub->hMethod, (const void *)pName->zString, pName->nByte, pMeth);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
} }
@ -319,39 +310,38 @@ PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_gen_state *pGen,ph7_class *pSub,ph7_class
* Any other return value indicates failure and the upper layer must generate an appropriate * Any other return value indicates failure and the upper layer must generate an appropriate
* error message. * error message.
*/ */
PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub,ph7_class *pBase) PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub, ph7_class *pBase) {
{
ph7_class_method *pMeth; ph7_class_method *pMeth;
ph7_class_attr *pAttr; ph7_class_attr *pAttr;
SyHashEntry *pEntry; SyHashEntry *pEntry;
SyString *pName; SyString *pName;
sxi32 rc; sxi32 rc;
/* Install in the derived hashtable */ /* Install in the derived hashtable */
SyHashInsert(&pBase->hDerived,(const void *)SyStringData(&pSub->sName),SyStringLength(&pSub->sName),pSub); SyHashInsert(&pBase->hDerived, (const void *)SyStringData(&pSub->sName), SyStringLength(&pSub->sName), pSub);
SyHashResetLoopCursor(&pBase->hAttr); SyHashResetLoopCursor(&pBase->hAttr);
/* Copy constants */ /* Copy constants */
while((pEntry = SyHashGetNextEntry(&pBase->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pBase->hAttr)) != 0) {
/* Make sure the constants are not redeclared in the subclass */ /* Make sure the constants are not redeclared in the subclass */
pAttr = (ph7_class_attr *)pEntry->pUserData; pAttr = (ph7_class_attr *)pEntry->pUserData;
pName = &pAttr->sName; pName = &pAttr->sName;
if( SyHashGet(&pSub->hAttr,(const void *)pName->zString,pName->nByte) == 0 ){ if(SyHashGet(&pSub->hAttr, (const void *)pName->zString, pName->nByte) == 0) {
/* Install the constant in the subclass */ /* Install the constant in the subclass */
rc = SyHashInsert(&pSub->hAttr,(const void *)pName->zString,pName->nByte,pAttr); rc = SyHashInsert(&pSub->hAttr, (const void *)pName->zString, pName->nByte, pAttr);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
} }
} }
SyHashResetLoopCursor(&pBase->hMethod); SyHashResetLoopCursor(&pBase->hMethod);
/* Copy methods signature */ /* Copy methods signature */
while((pEntry = SyHashGetNextEntry(&pBase->hMethod)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pBase->hMethod)) != 0) {
/* Make sure the method are not redeclared in the subclass */ /* Make sure the method are not redeclared in the subclass */
pMeth = (ph7_class_method *)pEntry->pUserData; pMeth = (ph7_class_method *)pEntry->pUserData;
pName = &pMeth->sFunc.sName; pName = &pMeth->sFunc.sName;
if( SyHashGet(&pSub->hMethod,(const void *)pName->zString,pName->nByte) == 0 ){ if(SyHashGet(&pSub->hMethod, (const void *)pName->zString, pName->nByte) == 0) {
/* Install the method */ /* Install the method */
rc = SyHashInsert(&pSub->hMethod,(const void *)pName->zString,pName->nByte,pMeth); rc = SyHashInsert(&pSub->hMethod, (const void *)pName->zString, pName->nByte, pMeth);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
} }
@ -374,29 +364,28 @@ PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub,ph7_class *pBase)
* Any other return value indicates failure and the upper layer must generate an appropriate * Any other return value indicates failure and the upper layer must generate an appropriate
* error message. * error message.
*/ */
PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain,ph7_class *pInterface) PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface) {
{
ph7_class_attr *pAttr; ph7_class_attr *pAttr;
SyHashEntry *pEntry; SyHashEntry *pEntry;
SyString *pName; SyString *pName;
sxi32 rc; sxi32 rc;
/* First off,copy all constants declared inside the interface */ /* First off,copy all constants declared inside the interface */
SyHashResetLoopCursor(&pInterface->hAttr); SyHashResetLoopCursor(&pInterface->hAttr);
while((pEntry = SyHashGetNextEntry(&pInterface->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pInterface->hAttr)) != 0) {
/* Point to the constant declaration */ /* Point to the constant declaration */
pAttr = (ph7_class_attr *)pEntry->pUserData; pAttr = (ph7_class_attr *)pEntry->pUserData;
pName = &pAttr->sName; pName = &pAttr->sName;
/* Make sure the attribute is not redeclared in the main class */ /* Make sure the attribute is not redeclared in the main class */
if( SyHashGet(&pMain->hAttr,pName->zString,pName->nByte) == 0 ){ if(SyHashGet(&pMain->hAttr, pName->zString, pName->nByte) == 0) {
/* Install the attribute */ /* Install the attribute */
rc = SyHashInsert(&pMain->hAttr,pName->zString,pName->nByte,pAttr); rc = SyHashInsert(&pMain->hAttr, pName->zString, pName->nByte, pAttr);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
return rc; return rc;
} }
} }
} }
/* Install in the interface container */ /* Install in the interface container */
SySetPut(&pMain->aInterface,(const void *)&pInterface); SySetPut(&pMain->aInterface, (const void *)&pInterface);
/* TICKET 1433-49/1: Symisc eXtension /* TICKET 1433-49/1: Symisc eXtension
* A class may not implemnt all declared interface methods,so there * A class may not implemnt all declared interface methods,so there
* is no need for a method installer loop here. * is no need for a method installer loop here.
@ -482,39 +471,37 @@ PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain,ph7_class *pInterface)
* }; * };
* Refer to the official documentation for more information. * Refer to the official documentation for more information.
*/ */
static ph7_class_instance * NewClassInstance(ph7_vm *pVm,ph7_class *pClass) static ph7_class_instance *NewClassInstance(ph7_vm *pVm, ph7_class *pClass) {
{
ph7_class_instance *pThis; ph7_class_instance *pThis;
/* Allocate a new instance */ /* Allocate a new instance */
pThis = (ph7_class_instance *)SyMemBackendPoolAlloc(&pVm->sAllocator,sizeof(ph7_class_instance)); pThis = (ph7_class_instance *)SyMemBackendPoolAlloc(&pVm->sAllocator, sizeof(ph7_class_instance));
if( pThis == 0 ){ if(pThis == 0) {
return 0; return 0;
} }
/* Zero the structure */ /* Zero the structure */
SyZero(pThis,sizeof(ph7_class_instance)); SyZero(pThis, sizeof(ph7_class_instance));
/* Initialize fields */ /* Initialize fields */
pThis->iRef = 1; pThis->iRef = 1;
pThis->pVm = pVm; pThis->pVm = pVm;
pThis->pClass = pClass; pThis->pClass = pClass;
SyHashInit(&pThis->hAttr,&pVm->sAllocator,0,0); SyHashInit(&pThis->hAttr, &pVm->sAllocator, 0, 0);
return pThis; return pThis;
} }
/* /*
* Wrapper around the NewClassInstance() function defined above. * Wrapper around the NewClassInstance() function defined above.
* See the block comment above for more information. * See the block comment above for more information.
*/ */
PH7_PRIVATE ph7_class_instance * PH7_NewClassInstance(ph7_vm *pVm,ph7_class *pClass) PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass) {
{
ph7_class_instance *pNew; ph7_class_instance *pNew;
sxi32 rc; sxi32 rc;
pNew = NewClassInstance(&(*pVm),&(*pClass)); pNew = NewClassInstance(&(*pVm), &(*pClass));
if( pNew == 0 ){ if(pNew == 0) {
return 0; return 0;
} }
/* Associate a private VM frame with this class instance */ /* Associate a private VM frame with this class instance */
rc = PH7_VmCreateClassInstanceFrame(&(*pVm),pNew); rc = PH7_VmCreateClassInstanceFrame(&(*pVm), pNew);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
SyMemBackendPoolFree(&pVm->sAllocator,pNew); SyMemBackendPoolFree(&pVm->sAllocator, pNew);
return 0; return 0;
} }
return pNew; return pNew;
@ -523,11 +510,10 @@ PH7_PRIVATE ph7_class_instance * PH7_NewClassInstance(ph7_vm *pVm,ph7_class *pCl
* Extract the value of a class instance [i.e: Object in the PHP jargon] attribute. * Extract the value of a class instance [i.e: Object in the PHP jargon] attribute.
* This function never fail. * This function never fail.
*/ */
static ph7_value * ExtractClassAttrValue(ph7_vm *pVm,VmClassAttr *pAttr) static ph7_value *ExtractClassAttrValue(ph7_vm *pVm, VmClassAttr *pAttr) {
{
/* Extract the value */ /* Extract the value */
ph7_value *pValue; ph7_value *pValue;
pValue = (ph7_value *)SySetAt(&pVm->aMemObj,pAttr->nIdx); pValue = (ph7_value *)SySetAt(&pVm->aMemObj, pAttr->nIdx);
return pValue; return pValue;
} }
/* /*
@ -614,8 +600,7 @@ static ph7_value * ExtractClassAttrValue(ph7_vm *pVm,VmClassAttr *pAttr)
* ) * )
* ) * )
*/ */
PH7_PRIVATE ph7_class_instance * PH7_CloneClassInstance(ph7_class_instance *pSrc) PH7_PRIVATE ph7_class_instance *PH7_CloneClassInstance(ph7_class_instance *pSrc) {
{
ph7_class_instance *pClone; ph7_class_instance *pClone;
ph7_class_method *pMethod; ph7_class_method *pMethod;
SyHashEntry *pEntry2; SyHashEntry *pEntry2;
@ -624,41 +609,41 @@ PH7_PRIVATE ph7_class_instance * PH7_CloneClassInstance(ph7_class_instance *pSrc
sxi32 rc; sxi32 rc;
/* Allocate a new instance */ /* Allocate a new instance */
pVm = pSrc->pVm; pVm = pSrc->pVm;
pClone = NewClassInstance(pVm,pSrc->pClass); pClone = NewClassInstance(pVm, pSrc->pClass);
if( pClone == 0 ){ if(pClone == 0) {
return 0; return 0;
} }
/* Associate a private VM frame with this class instance */ /* Associate a private VM frame with this class instance */
rc = PH7_VmCreateClassInstanceFrame(pVm,pClone); rc = PH7_VmCreateClassInstanceFrame(pVm, pClone);
if( rc != SXRET_OK ){ if(rc != SXRET_OK) {
SyMemBackendPoolFree(&pVm->sAllocator,pClone); SyMemBackendPoolFree(&pVm->sAllocator, pClone);
return 0; return 0;
} }
/* Duplicate object values */ /* Duplicate object values */
SyHashResetLoopCursor(&pSrc->hAttr); SyHashResetLoopCursor(&pSrc->hAttr);
SyHashResetLoopCursor(&pClone->hAttr); SyHashResetLoopCursor(&pClone->hAttr);
while((pEntry = SyHashGetNextEntry(&pSrc->hAttr)) != 0 && (pEntry2 = SyHashGetNextEntry(&pClone->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pSrc->hAttr)) != 0 && (pEntry2 = SyHashGetNextEntry(&pClone->hAttr)) != 0) {
VmClassAttr *pSrcAttr = (VmClassAttr *)pEntry->pUserData; VmClassAttr *pSrcAttr = (VmClassAttr *)pEntry->pUserData;
VmClassAttr *pDestAttr = (VmClassAttr *)pEntry2->pUserData; VmClassAttr *pDestAttr = (VmClassAttr *)pEntry2->pUserData;
/* Duplicate non-static attribute */ /* Duplicate non-static attribute */
if( (pSrcAttr->pAttr->iFlags & (PH7_CLASS_ATTR_STATIC|PH7_CLASS_ATTR_CONSTANT)) == 0 ){ if((pSrcAttr->pAttr->iFlags & (PH7_CLASS_ATTR_STATIC | PH7_CLASS_ATTR_CONSTANT)) == 0) {
ph7_value *pvSrc,*pvDest; ph7_value *pvSrc, *pvDest;
pvSrc = ExtractClassAttrValue(pVm,pSrcAttr); pvSrc = ExtractClassAttrValue(pVm, pSrcAttr);
pvDest = ExtractClassAttrValue(pVm,pDestAttr); pvDest = ExtractClassAttrValue(pVm, pDestAttr);
if( pvSrc && pvDest ){ if(pvSrc && pvDest) {
PH7_MemObjStore(pvSrc,pvDest); PH7_MemObjStore(pvSrc, pvDest);
} }
} }
} }
/* call the __clone method on the cloned object if available */ /* call the __clone method on the cloned object if available */
pMethod = PH7_ClassExtractMethod(pClone->pClass,"__clone",sizeof("__clone")-1); pMethod = PH7_ClassExtractMethod(pClone->pClass, "__clone", sizeof("__clone") - 1);
if( pMethod ){ if(pMethod) {
if( pMethod->iCloneDepth < 16 ){ if(pMethod->iCloneDepth < 16) {
pMethod->iCloneDepth++; pMethod->iCloneDepth++;
PH7_VmCallClassMethod(pVm,pClone,pMethod,0,0,0); PH7_VmCallClassMethod(pVm, pClone, pMethod, 0, 0, 0);
}else{ } else {
/* Nesting limit reached */ /* Nesting limit reached */
PH7_VmThrowError(pVm,0,PH7_CTX_ERR,"Object clone limit reached,no more call to __clone()"); PH7_VmThrowError(pVm, 0, PH7_CTX_ERR, "Object clone limit reached,no more call to __clone()");
} }
/* Reset the cursor */ /* Reset the cursor */
pMethod->iCloneDepth = 0; pMethod->iCloneDepth = 0;
@ -672,13 +657,12 @@ PH7_PRIVATE ph7_class_instance * PH7_CloneClassInstance(ph7_class_instance *pSrc
* This routine is invoked as soon as there are no other references to a particular * This routine is invoked as soon as there are no other references to a particular
* class instance. * class instance.
*/ */
static void PH7_ClassInstanceRelease(ph7_class_instance *pThis) static void PH7_ClassInstanceRelease(ph7_class_instance *pThis) {
{
ph7_class_method *pDestr; ph7_class_method *pDestr;
SyHashEntry *pEntry; SyHashEntry *pEntry;
ph7_class *pClass; ph7_class *pClass;
ph7_vm *pVm; ph7_vm *pVm;
if( pThis->iFlags & CLASS_INSTANCE_DESTROYED ){ if(pThis->iFlags & CLASS_INSTANCE_DESTROYED) {
/* /*
* Already destroyed,return immediately. * Already destroyed,return immediately.
* This could happend if someone perform unset($this) in the destructor body. * This could happend if someone perform unset($this) in the destructor body.
@ -690,33 +674,32 @@ static void PH7_ClassInstanceRelease(ph7_class_instance *pThis)
/* Invoke any defined destructor if available */ /* Invoke any defined destructor if available */
pVm = pThis->pVm; pVm = pThis->pVm;
pClass = pThis->pClass; pClass = pThis->pClass;
pDestr = PH7_ClassExtractMethod(pClass,"__destruct",sizeof("__destruct")-1); pDestr = PH7_ClassExtractMethod(pClass, "__destruct", sizeof("__destruct") - 1);
if( pDestr ){ if(pDestr) {
/* Invoke the destructor */ /* Invoke the destructor */
pThis->iRef = 2; /* Prevent garbage collection */ pThis->iRef = 2; /* Prevent garbage collection */
PH7_VmCallClassMethod(pVm,pThis,pDestr,0,0,0); PH7_VmCallClassMethod(pVm, pThis, pDestr, 0, 0, 0);
} }
/* Release non-static attributes */ /* Release non-static attributes */
SyHashResetLoopCursor(&pThis->hAttr); SyHashResetLoopCursor(&pThis->hAttr);
while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0) {
VmClassAttr *pVmAttr = (VmClassAttr *)pEntry->pUserData; VmClassAttr *pVmAttr = (VmClassAttr *)pEntry->pUserData;
if( (pVmAttr->pAttr->iFlags & (PH7_CLASS_ATTR_STATIC|PH7_CLASS_ATTR_CONSTANT)) == 0 ){ if((pVmAttr->pAttr->iFlags & (PH7_CLASS_ATTR_STATIC | PH7_CLASS_ATTR_CONSTANT)) == 0) {
PH7_VmUnsetMemObj(pVm,pVmAttr->nIdx,TRUE); PH7_VmUnsetMemObj(pVm, pVmAttr->nIdx, TRUE);
} }
SyMemBackendPoolFree(&pVm->sAllocator,pVmAttr); SyMemBackendPoolFree(&pVm->sAllocator, pVmAttr);
} }
/* Release the whole structure */ /* Release the whole structure */
SyHashRelease(&pThis->hAttr); SyHashRelease(&pThis->hAttr);
SyMemBackendPoolFree(&pVm->sAllocator,pThis); SyMemBackendPoolFree(&pVm->sAllocator, pThis);
} }
/* /*
* Decrement the reference count of a class instance [i.e Object in the PHP jargon]. * Decrement the reference count of a class instance [i.e Object in the PHP jargon].
* If the reference count reaches zero,release the whole instance. * If the reference count reaches zero,release the whole instance.
*/ */
PH7_PRIVATE void PH7_ClassInstanceUnref(ph7_class_instance *pThis) PH7_PRIVATE void PH7_ClassInstanceUnref(ph7_class_instance *pThis) {
{
pThis->iRef--; pThis->iRef--;
if( pThis->iRef < 1 ){ if(pThis->iRef < 1) {
/* No more reference to this instance */ /* No more reference to this instance */
PH7_ClassInstanceRelease(&(*pThis)); PH7_ClassInstanceRelease(&(*pThis));
} }
@ -798,21 +781,20 @@ PH7_PRIVATE void PH7_ClassInstanceUnref(ph7_class_instance *pThis)
* This function return 0 if the objects are equals according to the comprison rules defined above. * This function return 0 if the objects are equals according to the comprison rules defined above.
* Any other return values indicates difference. * Any other return values indicates difference.
*/ */
PH7_PRIVATE sxi32 PH7_ClassInstanceCmp(ph7_class_instance *pLeft,ph7_class_instance *pRight,int bStrict,int iNest) PH7_PRIVATE sxi32 PH7_ClassInstanceCmp(ph7_class_instance *pLeft, ph7_class_instance *pRight, int bStrict, int iNest) {
{ SyHashEntry *pEntry, *pEntry2;
SyHashEntry *pEntry,*pEntry2; ph7_value sV1, sV2;
ph7_value sV1,sV2;
sxi32 rc; sxi32 rc;
if( iNest > 31 ){ if(iNest > 31) {
/* Nesting limit reached */ /* Nesting limit reached */
PH7_VmThrowError(pLeft->pVm,0,PH7_CTX_ERR,"Nesting limit reached: Infinite recursion?"); PH7_VmThrowError(pLeft->pVm, 0, PH7_CTX_ERR, "Nesting limit reached: Infinite recursion?");
return 1; return 1;
} }
/* Comparison is performed only if the objects are instance of the same class */ /* Comparison is performed only if the objects are instance of the same class */
if( pLeft->pClass != pRight->pClass ){ if(pLeft->pClass != pRight->pClass) {
return 1; return 1;
} }
if( bStrict ){ if(bStrict) {
/* /*
* According to the PHP language reference manual: * According to the PHP language reference manual:
* when using the identity operator (===), object variables * when using the identity operator (===), object variables
@ -828,31 +810,31 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceCmp(ph7_class_instance *pLeft,ph7_class_insta
* in a simple manner, namely: Two object instances are equal if they have * in a simple manner, namely: Two object instances are equal if they have
* the same attributes and values, and are instances of the same class. * the same attributes and values, and are instances of the same class.
*/ */
if( pLeft == pRight ){ if(pLeft == pRight) {
/* Same instance,don't bother processing,object are equals */ /* Same instance,don't bother processing,object are equals */
return 0; return 0;
} }
SyHashResetLoopCursor(&pLeft->hAttr); SyHashResetLoopCursor(&pLeft->hAttr);
SyHashResetLoopCursor(&pRight->hAttr); SyHashResetLoopCursor(&pRight->hAttr);
PH7_MemObjInit(pLeft->pVm,&sV1); PH7_MemObjInit(pLeft->pVm, &sV1);
PH7_MemObjInit(pLeft->pVm,&sV2); PH7_MemObjInit(pLeft->pVm, &sV2);
sV1.nIdx = sV2.nIdx = SXU32_HIGH; sV1.nIdx = sV2.nIdx = SXU32_HIGH;
while((pEntry = SyHashGetNextEntry(&pLeft->hAttr)) != 0 && (pEntry2 = SyHashGetNextEntry(&pRight->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pLeft->hAttr)) != 0 && (pEntry2 = SyHashGetNextEntry(&pRight->hAttr)) != 0) {
VmClassAttr *p1 = (VmClassAttr *)pEntry->pUserData; VmClassAttr *p1 = (VmClassAttr *)pEntry->pUserData;
VmClassAttr *p2 = (VmClassAttr *)pEntry2->pUserData; VmClassAttr *p2 = (VmClassAttr *)pEntry2->pUserData;
/* Compare only non-static attribute */ /* Compare only non-static attribute */
if( (p1->pAttr->iFlags & (PH7_CLASS_ATTR_CONSTANT|PH7_CLASS_ATTR_STATIC)) == 0 ){ if((p1->pAttr->iFlags & (PH7_CLASS_ATTR_CONSTANT | PH7_CLASS_ATTR_STATIC)) == 0) {
ph7_value *pL,*pR; ph7_value *pL, *pR;
pL = ExtractClassAttrValue(pLeft->pVm,p1); pL = ExtractClassAttrValue(pLeft->pVm, p1);
pR = ExtractClassAttrValue(pRight->pVm,p2); pR = ExtractClassAttrValue(pRight->pVm, p2);
if( pL && pR ){ if(pL && pR) {
PH7_MemObjLoad(pL,&sV1); PH7_MemObjLoad(pL, &sV1);
PH7_MemObjLoad(pR,&sV2); PH7_MemObjLoad(pR, &sV2);
/* Compare the two values now */ /* Compare the two values now */
rc = PH7_MemObjCmp(&sV1,&sV2,bStrict,iNest+1); rc = PH7_MemObjCmp(&sV1, &sV2, bStrict, iNest + 1);
PH7_MemObjRelease(&sV1); PH7_MemObjRelease(&sV1);
PH7_MemObjRelease(&sV2); PH7_MemObjRelease(&sV2);
if( rc != 0 ){ if(rc != 0) {
/* Not equals */ /* Not equals */
return rc; return rc;
} }
@ -871,60 +853,59 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceCmp(ph7_class_instance *pLeft,ph7_class_insta
* This function SXRET_OK on success. Any other return value including * This function SXRET_OK on success. Any other return value including
* SXERR_LIMIT(infinite recursion) indicates failure. * SXERR_LIMIT(infinite recursion) indicates failure.
*/ */
PH7_PRIVATE sxi32 PH7_ClassInstanceDump(SyBlob *pOut,ph7_class_instance *pThis,int ShowType,int nTab,int nDepth) PH7_PRIVATE sxi32 PH7_ClassInstanceDump(SyBlob *pOut, ph7_class_instance *pThis, int ShowType, int nTab, int nDepth) {
{
SyHashEntry *pEntry; SyHashEntry *pEntry;
ph7_value *pValue; ph7_value *pValue;
sxi32 rc; sxi32 rc;
int i; int i;
if( nDepth > 31 ){ if(nDepth > 31) {
static const char zInfinite[] = "Nesting limit reached: Infinite recursion?"; static const char zInfinite[] = "Nesting limit reached: Infinite recursion?";
/* Nesting limit reached..halt immediately*/ /* Nesting limit reached..halt immediately*/
SyBlobAppend(&(*pOut),zInfinite,sizeof(zInfinite)-1); SyBlobAppend(&(*pOut), zInfinite, sizeof(zInfinite) - 1);
if( ShowType ){ if(ShowType) {
SyBlobAppend(&(*pOut),")",sizeof(char)); SyBlobAppend(&(*pOut), ")", sizeof(char));
} }
return SXERR_LIMIT; return SXERR_LIMIT;
} }
rc = SXRET_OK; rc = SXRET_OK;
if( !ShowType ){ if(!ShowType) {
SyBlobAppend(&(*pOut),"Object(",sizeof("Object(")-1); SyBlobAppend(&(*pOut), "Object(", sizeof("Object(") - 1);
} }
/* Append class name */ /* Append class name */
SyBlobFormat(&(*pOut),"%z) {",&pThis->pClass->sName); SyBlobFormat(&(*pOut), "%z) {", &pThis->pClass->sName);
#ifdef __WINNT__ #ifdef __WINNT__
SyBlobAppend(&(*pOut),"\r\n",sizeof("\r\n")-1); SyBlobAppend(&(*pOut), "\r\n", sizeof("\r\n") - 1);
#else #else
SyBlobAppend(&(*pOut),"\n",sizeof(char)); SyBlobAppend(&(*pOut), "\n", sizeof(char));
#endif #endif
/* Dump object attributes */ /* Dump object attributes */
SyHashResetLoopCursor(&pThis->hAttr); SyHashResetLoopCursor(&pThis->hAttr);
while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0){ while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0) {
VmClassAttr *pVmAttr = (VmClassAttr *)pEntry->pUserData; VmClassAttr *pVmAttr = (VmClassAttr *)pEntry->pUserData;
if((pVmAttr->pAttr->iFlags & (PH7_CLASS_ATTR_CONSTANT|PH7_CLASS_ATTR_STATIC)) == 0 ){ if((pVmAttr->pAttr->iFlags & (PH7_CLASS_ATTR_CONSTANT | PH7_CLASS_ATTR_STATIC)) == 0) {
/* Dump non-static/constant attribute only */ /* Dump non-static/constant attribute only */
for( i = 0 ; i < nTab ; i++ ){ for(i = 0 ; i < nTab ; i++) {
SyBlobAppend(&(*pOut)," ",sizeof(char)); SyBlobAppend(&(*pOut), " ", sizeof(char));
} }
pValue = ExtractClassAttrValue(pThis->pVm,pVmAttr); pValue = ExtractClassAttrValue(pThis->pVm, pVmAttr);
if( pValue ){ if(pValue) {
SyBlobFormat(&(*pOut),"['%z'] =>",&pVmAttr->pAttr->sName); SyBlobFormat(&(*pOut), "['%z'] =>", &pVmAttr->pAttr->sName);
#ifdef __WINNT__ #ifdef __WINNT__
SyBlobAppend(&(*pOut),"\r\n",sizeof("\r\n")-1); SyBlobAppend(&(*pOut), "\r\n", sizeof("\r\n") - 1);
#else #else
SyBlobAppend(&(*pOut),"\n",sizeof(char)); SyBlobAppend(&(*pOut), "\n", sizeof(char));
#endif #endif
rc = PH7_MemObjDump(&(*pOut),pValue,ShowType,nTab+1,nDepth,0); rc = PH7_MemObjDump(&(*pOut), pValue, ShowType, nTab + 1, nDepth, 0);
if( rc == SXERR_LIMIT ){ if(rc == SXERR_LIMIT) {
break; break;
} }
} }
} }
} }
for( i = 0 ; i < nTab ; i++ ){ for(i = 0 ; i < nTab ; i++) {
SyBlobAppend(&(*pOut)," ",sizeof(char)); SyBlobAppend(&(*pOut), " ", sizeof(char));
} }
SyBlobAppend(&(*pOut),"}",sizeof(char)); SyBlobAppend(&(*pOut), "}", sizeof(char));
return rc; return rc;
} }
/* /*
@ -975,31 +956,30 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceCallMagicMethod(
const char *zMethod, /* Magic method name [i.e: __toString()]*/ const char *zMethod, /* Magic method name [i.e: __toString()]*/
sxu32 nByte, /* zMethod length*/ sxu32 nByte, /* zMethod length*/
const SyString *pAttrName /* Attribute name */ const SyString *pAttrName /* Attribute name */
) ) {
{ ph7_value *apArg[2] = { 0, 0 };
ph7_value *apArg[2] = { 0 , 0 };
ph7_class_method *pMeth; ph7_class_method *pMeth;
ph7_value sAttr; /* cc warning */ ph7_value sAttr; /* cc warning */
sxi32 rc; sxi32 rc;
int nArg; int nArg;
/* Make sure the magic method is available */ /* Make sure the magic method is available */
pMeth = PH7_ClassExtractMethod(&(*pClass),zMethod,nByte); pMeth = PH7_ClassExtractMethod(&(*pClass), zMethod, nByte);
if( pMeth == 0 ){ if(pMeth == 0) {
/* No such method,return immediately */ /* No such method,return immediately */
return SXERR_NOTFOUND; return SXERR_NOTFOUND;
} }
nArg = 0; nArg = 0;
/* Copy arguments */ /* Copy arguments */
if( pAttrName ){ if(pAttrName) {
PH7_MemObjInitFromString(pVm,&sAttr,pAttrName); PH7_MemObjInitFromString(pVm, &sAttr, pAttrName);
sAttr.nIdx = SXU32_HIGH; /* Mark as constant */ sAttr.nIdx = SXU32_HIGH; /* Mark as constant */
apArg[0] = &sAttr; apArg[0] = &sAttr;
nArg = 1; nArg = 1;
} }
/* Call the magic method now */ /* Call the magic method now */
rc = PH7_VmCallClassMethod(pVm,&(*pThis),pMeth,0,nArg,apArg); rc = PH7_VmCallClassMethod(pVm, &(*pThis), pMeth, 0, nArg, apArg);
/* Clean up */ /* Clean up */
if( pAttrName ){ if(pAttrName) {
PH7_MemObjRelease(&sAttr); PH7_MemObjRelease(&sAttr);
} }
return rc; return rc;
@ -1008,11 +988,10 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceCallMagicMethod(
* Extract the value of a class instance [i.e: Object in the PHP jargon]. * Extract the value of a class instance [i.e: Object in the PHP jargon].
* This function is simply a wrapper on ExtractClassAttrValue(). * This function is simply a wrapper on ExtractClassAttrValue().
*/ */
PH7_PRIVATE ph7_value * PH7_ClassInstanceExtractAttrValue(ph7_class_instance *pThis,VmClassAttr *pAttr) PH7_PRIVATE ph7_value *PH7_ClassInstanceExtractAttrValue(ph7_class_instance *pThis, VmClassAttr *pAttr) {
{
/* Extract the attribute value */ /* Extract the attribute value */
ph7_value *pValue; ph7_value *pValue;
pValue = ExtractClassAttrValue(pThis->pVm,pAttr); pValue = ExtractClassAttrValue(pThis->pVm, pAttr);
return pValue; return pValue;
} }
/* /*
@ -1044,8 +1023,7 @@ PH7_PRIVATE ph7_value * PH7_ClassInstanceExtractAttrValue(ph7_class_instance *pT
* value unlike the standard PHP engine. * value unlike the standard PHP engine.
* This is a very powerful feature that you have to look at. * This is a very powerful feature that you have to look at.
*/ */
PH7_PRIVATE sxi32 PH7_ClassInstanceToHashmap(ph7_class_instance *pThis,ph7_hashmap *pMap) PH7_PRIVATE sxi32 PH7_ClassInstanceToHashmap(ph7_class_instance *pThis, ph7_hashmap *pMap) {
{
SyHashEntry *pEntry; SyHashEntry *pEntry;
SyString *pAttrName; SyString *pAttrName;
VmClassAttr *pAttr; VmClassAttr *pAttr;
@ -1053,18 +1031,18 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceToHashmap(ph7_class_instance *pThis,ph7_hashm
ph7_value sName; ph7_value sName;
/* Reset the loop cursor */ /* Reset the loop cursor */
SyHashResetLoopCursor(&pThis->hAttr); SyHashResetLoopCursor(&pThis->hAttr);
PH7_MemObjInitFromString(pThis->pVm,&sName,0); PH7_MemObjInitFromString(pThis->pVm, &sName, 0);
while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0) {
/* Point to the current attribute */ /* Point to the current attribute */
pAttr = (VmClassAttr *)pEntry->pUserData; pAttr = (VmClassAttr *)pEntry->pUserData;
/* Extract attribute value */ /* Extract attribute value */
pValue = ExtractClassAttrValue(pThis->pVm,pAttr); pValue = ExtractClassAttrValue(pThis->pVm, pAttr);
if( pValue ){ if(pValue) {
/* Build attribute name */ /* Build attribute name */
pAttrName = &pAttr->pAttr->sName; pAttrName = &pAttr->pAttr->sName;
PH7_MemObjStringAppend(&sName,pAttrName->zString,pAttrName->nByte); PH7_MemObjStringAppend(&sName, pAttrName->zString, pAttrName->nByte);
/* Perform the insertion */ /* Perform the insertion */
PH7_HashmapInsert(pMap,&sName,pValue); PH7_HashmapInsert(pMap, &sName, pValue);
/* Reset the string cursor */ /* Reset the string cursor */
SyBlobReset(&sName.sBlob); SyBlobReset(&sName.sBlob);
} }
@ -1083,10 +1061,9 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceToHashmap(ph7_class_instance *pThis,ph7_hashm
*/ */
PH7_PRIVATE sxi32 PH7_ClassInstanceWalk( PH7_PRIVATE sxi32 PH7_ClassInstanceWalk(
ph7_class_instance *pThis, /* Target object */ ph7_class_instance *pThis, /* Target object */
int (*xWalk)(const char *,ph7_value *,void *), /* Walker callback */ int (*xWalk)(const char *, ph7_value *, void *), /* Walker callback */
void *pUserData /* Last argument to xWalk() */ void *pUserData /* Last argument to xWalk() */
) ) {
{
SyHashEntry *pEntry; /* Hash entry */ SyHashEntry *pEntry; /* Hash entry */
VmClassAttr *pAttr; /* Pointer to the attribute */ VmClassAttr *pAttr; /* Pointer to the attribute */
ph7_value *pValue; /* Attribute value */ ph7_value *pValue; /* Attribute value */
@ -1094,19 +1071,19 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceWalk(
int rc; int rc;
/* Reset the loop cursor */ /* Reset the loop cursor */
SyHashResetLoopCursor(&pThis->hAttr); SyHashResetLoopCursor(&pThis->hAttr);
PH7_MemObjInit(pThis->pVm,&sValue); PH7_MemObjInit(pThis->pVm, &sValue);
/* Start the walk process */ /* Start the walk process */
while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0 ){ while((pEntry = SyHashGetNextEntry(&pThis->hAttr)) != 0) {
/* Point to the current attribute */ /* Point to the current attribute */
pAttr = (VmClassAttr *)pEntry->pUserData; pAttr = (VmClassAttr *)pEntry->pUserData;
/* Extract attribute value */ /* Extract attribute value */
pValue = ExtractClassAttrValue(pThis->pVm,pAttr); pValue = ExtractClassAttrValue(pThis->pVm, pAttr);
if( pValue ){ if(pValue) {
PH7_MemObjLoad(pValue,&sValue); PH7_MemObjLoad(pValue, &sValue);
/* Invoke the supplied callback */ /* Invoke the supplied callback */
rc = xWalk(SyStringData(&pAttr->pAttr->sName),&sValue,pUserData); rc = xWalk(SyStringData(&pAttr->pAttr->sName), &sValue, pUserData);
PH7_MemObjRelease(&sValue); PH7_MemObjRelease(&sValue);
if( rc != PH7_OK){ if(rc != PH7_OK) {
/* User callback request an operation abort */ /* User callback request an operation abort */
return SXERR_ABORT; return SXERR_ABORT;
} }
@ -1123,23 +1100,22 @@ PH7_PRIVATE sxi32 PH7_ClassInstanceWalk(
* will return NULL in case someone (host-application code) try to extract * will return NULL in case someone (host-application code) try to extract
* a static/constant attribute. * a static/constant attribute.
*/ */
PH7_PRIVATE ph7_value * PH7_ClassInstanceFetchAttr(ph7_class_instance *pThis,const SyString *pName) PH7_PRIVATE ph7_value *PH7_ClassInstanceFetchAttr(ph7_class_instance *pThis, const SyString *pName) {
{
SyHashEntry *pEntry; SyHashEntry *pEntry;
VmClassAttr *pAttr; VmClassAttr *pAttr;
/* Query the attribute hashtable */ /* Query the attribute hashtable */
pEntry = SyHashGet(&pThis->hAttr,(const void *)pName->zString,pName->nByte); pEntry = SyHashGet(&pThis->hAttr, (const void *)pName->zString, pName->nByte);
if( pEntry == 0 ){ if(pEntry == 0) {
/* No such attribute */ /* No such attribute */
return 0; return 0;
} }
/* Point to the class atrribute */ /* Point to the class atrribute */
pAttr = (VmClassAttr *)pEntry->pUserData; pAttr = (VmClassAttr *)pEntry->pUserData;
/* Check if we are dealing with a static/constant attribute */ /* Check if we are dealing with a static/constant attribute */
if( pAttr->pAttr->iFlags & (PH7_CLASS_ATTR_CONSTANT|PH7_CLASS_ATTR_STATIC) ){ if(pAttr->pAttr->iFlags & (PH7_CLASS_ATTR_CONSTANT | PH7_CLASS_ATTR_STATIC)) {
/* Access is forbidden */ /* Access is forbidden */
return 0; return 0;
} }
/* Return the attribute value */ /* Return the attribute value */
return ExtractClassAttrValue(pThis->pVm,pAttr); return ExtractClassAttrValue(pThis->pVm, pAttr);
} }

965
parser.c

File diff suppressed because it is too large Load Diff

224
ph7.h
View File

@ -47,7 +47,7 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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> $ */ /* $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 */ #include <stdarg.h> /* needed for the definition of va_list */
/* /*
* Compile time engine version, signature, identification in the symisc source tree * Compile time engine version, signature, identification in the symisc source tree
@ -95,10 +95,6 @@
* contact@symisc.net * contact@symisc.net
*/ */
#define PH7_COPYRIGHT "Copyright (C) Symisc Systems 2011-2012, http://ph7.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 */ /* Forward declaration to public objects */
typedef struct ph7_io_stream ph7_io_stream; typedef struct ph7_io_stream ph7_io_stream;
typedef struct ph7_context ph7_context; typedef struct ph7_context ph7_context;
@ -198,7 +194,7 @@ typedef unsigned long long int sxu64; /* 64 bits(8 bytes) unsigned int64 */
#define MAP_FILE 0 #define MAP_FILE 0
#endif #endif
/* Signature of the consumer routine */ /* Signature of the consumer routine */
typedef int (*ProcConsumer)(const void *,unsigned int,void *); typedef int (*ProcConsumer)(const void *, unsigned int, void *);
/* Forward reference */ /* Forward reference */
typedef struct SyMutexMethods SyMutexMethods; typedef struct SyMutexMethods SyMutexMethods;
typedef struct SyMemMethods SyMemMethods; typedef struct SyMemMethods SyMemMethods;
@ -207,8 +203,7 @@ typedef struct syiovec syiovec;
typedef struct SyMutex SyMutex; typedef struct SyMutex SyMutex;
typedef struct Sytm Sytm; typedef struct Sytm Sytm;
/* Scatter and gather array. */ /* Scatter and gather array. */
struct syiovec struct syiovec {
{
#if defined (__WINNT__) #if defined (__WINNT__)
/* Same fields type and offset as WSABUF structure defined one winsock2 header */ /* Same fields type and offset as WSABUF structure defined one winsock2 header */
unsigned long nLen; unsigned long nLen;
@ -218,14 +213,12 @@ struct syiovec
unsigned long nLen; unsigned long nLen;
#endif #endif
}; };
struct SyString struct SyString {
{
const char *zString; /* Raw string (may not be null terminated) */ const char *zString; /* Raw string (may not be null terminated) */
unsigned int nByte; /* Raw string length */ unsigned int nByte; /* Raw string length */
}; };
/* Time structure. */ /* Time structure. */
struct Sytm struct Sytm {
{
int tm_sec; /* seconds (0 - 60) */ int tm_sec; /* seconds (0 - 60) */
int tm_min; /* minutes (0 - 59) */ int tm_min; /* minutes (0 - 59) */
int tm_hour; /* hours (0 - 23) */ int tm_hour; /* hours (0 - 23) */
@ -267,10 +260,9 @@ struct Sytm
(pSYTM)->tm_zone = 0; (pSYTM)->tm_zone = 0;
/* Dynamic memory allocation methods. */ /* Dynamic memory allocation methods. */
struct SyMemMethods struct SyMemMethods {
{ void *(*xAlloc)(unsigned int); /* [Required:] Allocate a memory chunk */
void * (*xAlloc)(unsigned int); /* [Required:] Allocate a memory chunk */ void *(*xRealloc)(void *, unsigned int); /* [Required:] Re-allocate a memory chunk */
void * (*xRealloc)(void *,unsigned int); /* [Required:] Re-allocate a memory chunk */
void (*xFree)(void *); /* [Required:] Release a memory chunk */ void (*xFree)(void *); /* [Required:] Release a memory chunk */
unsigned int (*xChunkSize)(void *); /* [Optional:] Return chunk size */ unsigned int (*xChunkSize)(void *); /* [Optional:] Return chunk size */
int (*xInit)(void *); /* [Optional:] Initialization callback */ int (*xInit)(void *); /* [Optional:] Initialization callback */
@ -280,11 +272,10 @@ struct SyMemMethods
/* Out of memory callback signature. */ /* Out of memory callback signature. */
typedef int (*ProcMemError)(void *); typedef int (*ProcMemError)(void *);
/* Mutex methods. */ /* Mutex methods. */
struct SyMutexMethods struct SyMutexMethods {
{
int (*xGlobalInit)(void); /* [Optional:] Global mutex initialization */ int (*xGlobalInit)(void); /* [Optional:] Global mutex initialization */
void (*xGlobalRelease)(void); /* [Optional:] Global Release callback () */ void (*xGlobalRelease)(void); /* [Optional:] Global Release callback () */
SyMutex * (*xNew)(int); /* [Required:] Request a new mutex */ SyMutex *(*xNew)(int); /* [Required:] Request a new mutex */
void (*xRelease)(SyMutex *); /* [Optional:] Release a mutex */ void (*xRelease)(SyMutex *); /* [Optional:] Release a mutex */
void (*xEnter)(SyMutex *); /* [Required:] Enter mutex */ void (*xEnter)(SyMutex *); /* [Required:] Enter mutex */
int (*xTryEnter)(SyMutex *); /* [Optional:] Try to enter a mutex */ int (*xTryEnter)(SyMutex *); /* [Optional:] Try to enter a mutex */
@ -492,53 +483,52 @@ typedef sxi64 ph7_int64;
* Developers wishing to implement the vfs methods can contact symisc systems to obtain * Developers wishing to implement the vfs methods can contact symisc systems to obtain
* the PH7 VFS C/C++ Specification manual. * the PH7 VFS C/C++ Specification manual.
*/ */
struct ph7_vfs struct ph7_vfs {
{
const char *zName; /* Underlying VFS name [i.e: FreeBSD/Linux/Windows...] */ const char *zName; /* Underlying VFS name [i.e: FreeBSD/Linux/Windows...] */
int iVersion; /* Current VFS structure version [default 2] */ int iVersion; /* Current VFS structure version [default 2] */
/* Directory functions */ /* Directory functions */
int (*xChdir)(const char *); /* Change directory */ int (*xChdir)(const char *); /* Change directory */
int (*xChroot)(const char *); /* Change the root directory */ int (*xChroot)(const char *); /* Change the root directory */
int (*xGetcwd)(ph7_context *); /* Get the current working directory */ int (*xGetcwd)(ph7_context *); /* Get the current working directory */
int (*xMkdir)(const char *,int,int); /* Make directory */ int (*xMkdir)(const char *, int, int); /* Make directory */
int (*xRmdir)(const char *); /* Remove directory */ int (*xRmdir)(const char *); /* Remove directory */
int (*xIsdir)(const char *); /* Tells whether the filename is a directory */ int (*xIsdir)(const char *); /* Tells whether the filename is a directory */
int (*xRename)(const char *,const char *); /* Renames a file or directory */ int (*xRename)(const char *, const char *); /* Renames a file or directory */
int (*xRealpath)(const char *,ph7_context *); /* Return canonicalized absolute pathname*/ int (*xRealpath)(const char *, ph7_context *); /* Return canonicalized absolute pathname*/
/* Systems functions */ /* Systems functions */
int (*xSleep)(unsigned int); /* Delay execution in microseconds */ int (*xSleep)(unsigned int); /* Delay execution in microseconds */
int (*xUnlink)(const char *); /* Deletes a file */ int (*xUnlink)(const char *); /* Deletes a file */
int (*xFileExists)(const char *); /* Checks whether a file or directory exists */ int (*xFileExists)(const char *); /* Checks whether a file or directory exists */
int (*xChmod)(const char *,int); /* Changes file mode */ int (*xChmod)(const char *, int); /* Changes file mode */
int (*xChown)(const char *,const char *); /* Changes file owner */ int (*xChown)(const char *, const char *); /* Changes file owner */
int (*xChgrp)(const char *,const char *); /* Changes file group */ int (*xChgrp)(const char *, const char *); /* Changes file group */
ph7_int64 (*xFreeSpace)(const char *); /* Available space on filesystem or disk partition */ 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(*xTotalSpace)(const char *); /* Total space on filesystem or disk partition */
ph7_int64 (*xFileSize)(const char *); /* Gets file size */ ph7_int64(*xFileSize)(const char *); /* Gets file size */
ph7_int64 (*xFileAtime)(const char *); /* Gets last access time of file */ ph7_int64(*xFileAtime)(const char *); /* Gets last access time of file */
ph7_int64 (*xFileMtime)(const char *); /* Gets file modification time */ ph7_int64(*xFileMtime)(const char *); /* Gets file modification time */
ph7_int64 (*xFileCtime)(const char *); /* Gets inode change time of file */ 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 (*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 (*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 (*xIsfile)(const char *); /* Tells whether the filename is a regular file */
int (*xIslink)(const char *); /* Tells whether the filename is a symbolic link */ 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 (*xReadable)(const char *); /* Tells whether a file exists and is readable */
int (*xWritable)(const char *); /* Tells whether the filename is writable */ int (*xWritable)(const char *); /* Tells whether the filename is writable */
int (*xExecutable)(const char *); /* Tells whether the filename is executable */ 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 (*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 (*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 (*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 (*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 */ int (*xMmap)(const char *, void **, ph7_int64 *); /* Read-only memory map of the whole file */
void (*xUnmap)(void *,ph7_int64); /* Unmap a memory view */ void (*xUnmap)(void *, ph7_int64); /* Unmap a memory view */
int (*xLink)(const char *,const char *,int); /* Create hard or symbolic link */ int (*xLink)(const char *, const char *, int); /* Create hard or symbolic link */
int (*xUmask)(int); /* Change the current umask */ int (*xUmask)(int); /* Change the current umask */
void (*xTempDir)(ph7_context *); /* Get path of the temporary directory */ void (*xTempDir)(ph7_context *); /* Get path of the temporary directory */
unsigned int (*xProcessId)(void); /* Get running process ID */ unsigned int (*xProcessId)(void); /* Get running process ID */
int (*xUid)(void); /* user ID of the process */ int (*xUid)(void); /* user ID of the process */
int (*xGid)(void); /* group ID of the process */ int (*xGid)(void); /* group ID of the process */
void (*xUsername)(ph7_context *); /* Running username */ void (*xUsername)(ph7_context *); /* Running username */
int (*xExec)(const char *,ph7_context *); /* Execute an external program */ int (*xExec)(const char *, ph7_context *); /* Execute an external program */
}; };
/* Current PH7 IO stream structure version. */ /* Current PH7 IO stream structure version. */
#define PH7_IO_STREAM_VERSION 1 #define PH7_IO_STREAM_VERSION 1
@ -587,24 +577,23 @@ struct ph7_vfs
* Developers wishing to implement their own IO stream devices must understand and follow * 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). * The PH7 IO Stream C/C++ specification manual (http://ph7.symisc.net/io_stream_spec.html).
*/ */
struct ph7_io_stream struct ph7_io_stream {
{
const char *zName; /* Underlying stream name [i.e: file/http/zip/php,..] */ const char *zName; /* Underlying stream name [i.e: file/http/zip/php,..] */
int iVersion; /* IO stream structure version [default 1]*/ int iVersion; /* IO stream structure version [default 1]*/
int (*xOpen)(const char *,int,ph7_value *,void **); /* Open handle*/ int (*xOpen)(const char *, int, ph7_value *, void **); /* Open handle*/
int (*xOpenDir)(const char *,ph7_value *,void **); /* Open directory handle */ int (*xOpenDir)(const char *, ph7_value *, void **); /* Open directory handle */
void (*xClose)(void *); /* Close file handle */ void (*xClose)(void *); /* Close file handle */
void (*xCloseDir)(void *); /* Close directory handle */ void (*xCloseDir)(void *); /* Close directory handle */
ph7_int64 (*xRead)(void *,void *,ph7_int64); /* Read from the open stream */ ph7_int64(*xRead)(void *, void *, ph7_int64); /* Read from the open stream */
int (*xReadDir)(void *,ph7_context *); /* Read entry from directory handle */ int (*xReadDir)(void *, ph7_context *); /* Read entry from directory handle */
ph7_int64 (*xWrite)(void *,const void *,ph7_int64); /* Write to the open stream */ 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 (*xSeek)(void *, ph7_int64, int); /* Seek on the open stream */
int (*xLock)(void *,int); /* Lock/Unlock the open stream */ int (*xLock)(void *, int); /* Lock/Unlock the open stream */
void (*xRewindDir)(void *); /* Rewind directory handle */ void (*xRewindDir)(void *); /* Rewind directory handle */
ph7_int64 (*xTell)(void *); /* Current position of the stream read/write pointer */ 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 (*xTrunc)(void *, ph7_int64); /* Truncates the open stream to a given length */
int (*xSync)(void *); /* Flush open stream data */ int (*xSync)(void *); /* Flush open stream data */
int (*xStat)(void *,ph7_value *,ph7_value *); /* Stat an open stream handle */ int (*xStat)(void *, ph7_value *, ph7_value *); /* Stat an open stream handle */
}; };
/* /*
* C-API-REF: Please refer to the official documentation for interfaces * C-API-REF: Please refer to the official documentation for interfaces
@ -612,85 +601,85 @@ struct ph7_io_stream
*/ */
/* Engine Handling Interfaces */ /* Engine Handling Interfaces */
PH7_APIEXPORT int ph7_init(ph7 **ppEngine); PH7_APIEXPORT int ph7_init(ph7 **ppEngine);
PH7_APIEXPORT int ph7_config(ph7 *pEngine,int nConfigOp,...); PH7_APIEXPORT int ph7_config(ph7 *pEngine, int nConfigOp, ...);
PH7_APIEXPORT int ph7_release(ph7 *pEngine); PH7_APIEXPORT int ph7_release(ph7 *pEngine);
/* Compile Interfaces */ /* Compile Interfaces */
PH7_APIEXPORT int ph7_compile(ph7 *pEngine,const char *zSource,int nLen,ph7_vm **ppOutVm); 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_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); PH7_APIEXPORT int ph7_compile_file(ph7 *pEngine, const char *zFilePath, ph7_vm **ppOutVm, int iFlags);
/* Virtual Machine Handling Interfaces */ /* Virtual Machine Handling Interfaces */
PH7_APIEXPORT int ph7_vm_config(ph7_vm *pVm,int iConfigOp,...); 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_exec(ph7_vm *pVm, int *pExitStatus);
PH7_APIEXPORT int ph7_vm_reset(ph7_vm *pVm); PH7_APIEXPORT int ph7_vm_reset(ph7_vm *pVm);
PH7_APIEXPORT int ph7_vm_release(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); PH7_APIEXPORT int ph7_vm_dump_v2(ph7_vm *pVm, int (*xConsumer)(const void *, unsigned int, void *), void *pUserData);
/* In-process Extending Interfaces */ /* 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_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_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_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); PH7_APIEXPORT int ph7_delete_constant(ph7_vm *pVm, const char *zName);
/* Foreign Function Parameter Values */ /* Foreign Function Parameter Values */
PH7_APIEXPORT int ph7_value_to_int(ph7_value *pValue); PH7_APIEXPORT int ph7_value_to_int(ph7_value *pValue);
PH7_APIEXPORT int ph7_value_to_bool(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 ph7_int64 ph7_value_to_int64(ph7_value *pValue);
PH7_APIEXPORT double ph7_value_to_double(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 const char *ph7_value_to_string(ph7_value *pValue, int *pLen);
PH7_APIEXPORT void * ph7_value_to_resource(ph7_value *pValue); PH7_APIEXPORT void *ph7_value_to_resource(ph7_value *pValue);
PH7_APIEXPORT int ph7_value_compare(ph7_value *pLeft,ph7_value *pRight,int bStrict); PH7_APIEXPORT int ph7_value_compare(ph7_value *pLeft, ph7_value *pRight, int bStrict);
/* Setting The Result Of A Foreign Function */ /* Setting The Result Of A Foreign Function */
PH7_APIEXPORT int ph7_result_int(ph7_context *pCtx,int iValue); 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_int64(ph7_context *pCtx, ph7_int64 iValue);
PH7_APIEXPORT int ph7_result_bool(ph7_context *pCtx,int iBool); 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_double(ph7_context *pCtx, double Value);
PH7_APIEXPORT int ph7_result_null(ph7_context *pCtx); 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(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_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_value(ph7_context *pCtx, ph7_value *pValue);
PH7_APIEXPORT int ph7_result_resource(ph7_context *pCtx,void *pUserData); PH7_APIEXPORT int ph7_result_resource(ph7_context *pCtx, void *pUserData);
/* Call Context Handling Interfaces */ /* Call Context Handling Interfaces */
PH7_APIEXPORT int ph7_context_output(ph7_context *pCtx,const char *zString,int nLen); 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_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(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 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 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 int ph7_context_random_string(ph7_context *pCtx, char *zBuf, int nBuflen);
PH7_APIEXPORT void * ph7_context_user_data(ph7_context *pCtx); 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 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_peek_aux_data(ph7_context *pCtx);
PH7_APIEXPORT void * ph7_context_pop_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 unsigned int ph7_context_result_buf_length(ph7_context *pCtx);
PH7_APIEXPORT const char * ph7_function_name(ph7_context *pCtx); PH7_APIEXPORT const char *ph7_function_name(ph7_context *pCtx);
/* Call Context Memory Management Interfaces */ /* 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_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_realloc_chunk(ph7_context *pCtx, void *pChunk, unsigned int nByte);
PH7_APIEXPORT void ph7_context_free_chunk(ph7_context *pCtx,void *pChunk); PH7_APIEXPORT void ph7_context_free_chunk(ph7_context *pCtx, void *pChunk);
/* On Demand Dynamically Typed Value Object allocation interfaces */ /* On Demand Dynamically Typed Value Object allocation interfaces */
PH7_APIEXPORT ph7_value * ph7_new_scalar(ph7_vm *pVm); PH7_APIEXPORT ph7_value *ph7_new_scalar(ph7_vm *pVm);
PH7_APIEXPORT ph7_value * ph7_new_array(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 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_scalar(ph7_context *pCtx);
PH7_APIEXPORT ph7_value * ph7_context_new_array(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); PH7_APIEXPORT void ph7_context_release_value(ph7_context *pCtx, ph7_value *pValue);
/* Dynamically Typed Value Object Management Interfaces */ /* Dynamically Typed Value Object Management Interfaces */
PH7_APIEXPORT int ph7_value_int(ph7_value *pVal,int iValue); 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_int64(ph7_value *pVal, ph7_int64 iValue);
PH7_APIEXPORT int ph7_value_bool(ph7_value *pVal,int iBool); 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_null(ph7_value *pVal);
PH7_APIEXPORT int ph7_value_double(ph7_value *pVal,double Value); 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(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_string_format(ph7_value *pVal, const char *zFormat, ...);
PH7_APIEXPORT int ph7_value_reset_string_cursor(ph7_value *pVal); 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_resource(ph7_value *pVal, void *pUserData);
PH7_APIEXPORT int ph7_value_release(ph7_value *pVal); 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 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_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_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_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 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 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 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 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 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_int(ph7_value *pVal);
PH7_APIEXPORT int ph7_value_is_float(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_bool(ph7_value *pVal);
@ -705,14 +694,11 @@ PH7_APIEXPORT int ph7_value_is_resource(ph7_value *pVal);
PH7_APIEXPORT int ph7_value_is_empty(ph7_value *pVal); PH7_APIEXPORT int ph7_value_is_empty(ph7_value *pVal);
/* Global Library Management Interfaces */ /* Global Library Management Interfaces */
PH7_APIEXPORT int ph7_lib_init(void); PH7_APIEXPORT int ph7_lib_init(void);
PH7_APIEXPORT int ph7_lib_config(int nConfigOp,...); PH7_APIEXPORT int ph7_lib_config(int nConfigOp, ...);
PH7_APIEXPORT int ph7_lib_shutdown(void); PH7_APIEXPORT int ph7_lib_shutdown(void);
PH7_APIEXPORT int ph7_lib_is_threadsafe(void); PH7_APIEXPORT int ph7_lib_is_threadsafe(void);
PH7_APIEXPORT const char * ph7_lib_version(void); PH7_APIEXPORT const char *ph7_lib_version(void);
PH7_APIEXPORT const char * ph7_lib_signature(void); PH7_APIEXPORT const char *ph7_lib_signature(void);
PH7_APIEXPORT const char * ph7_lib_ident(void); PH7_APIEXPORT const char *ph7_lib_ident(void);
PH7_APIEXPORT const char * ph7_lib_copyright(void); PH7_APIEXPORT const char *ph7_lib_copyright(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _PH7_H_ */ #endif /* _PH7_H_ */

828
ph7int.h

File diff suppressed because it is too large Load Diff

4677
vfs.c

File diff suppressed because it is too large Load Diff

7937
vm.c

File diff suppressed because it is too large Load Diff